[FFmpeg-cvslog] r19763 - trunk/libavcodec/wmaprodec.c

faust3 subversion
Sat Sep 5 12:07:55 CEST 2009


Author: faust3
Date: Sat Sep  5 12:07:55 2009
New Revision: 19763

Log:
reduce output buffer needs
(fixes playback of some multichannel files)

Modified:
   trunk/libavcodec/wmaprodec.c

Modified: trunk/libavcodec/wmaprodec.c
==============================================================================
--- trunk/libavcodec/wmaprodec.c	Sat Sep  5 11:56:06 2009	(r19762)
+++ trunk/libavcodec/wmaprodec.c	Sat Sep  5 12:07:55 2009	(r19763)
@@ -194,11 +194,13 @@ typedef struct WMAProDecodeCtx {
     int              frame_offset;                  ///< frame offset in the bit reservoir
     int              subframe_offset;               ///< subframe offset in the bit reservoir
     uint8_t          packet_loss;                   ///< set in case of bitstream error
+    uint8_t          output_buffer_full;            ///< flag indicating that the output buffer is full
 
     /* frame decode state */
     uint32_t         frame_num;                     ///< current frame number (not used for decoding)
     GetBitContext    gb;                            ///< bitstream reader context
     int              buf_bit_size;                  ///< buffer size in bits
+    float*           samples_start;                 ///< start samplebuffer pointer
     float*           samples;                       ///< current samplebuffer pointer
     float*           samples_end;                   ///< maximum samplebuffer pointer
     uint8_t          drc_gain;                      ///< gain for the DRC tool
@@ -1256,9 +1258,13 @@ static int decode_frame(WMAProDecodeCtx 
 
     /** check for potential output buffer overflow */
     if (s->num_channels * s->samples_per_frame > s->samples_end - s->samples) {
-        av_log(s->avctx, AV_LOG_ERROR,
-               "not enough space for the output samples\n");
-        s->packet_loss = 1;
+        /** return an error if no frame could be decoded at all */
+        if (s->samples_start == s->samples) {
+            av_log(s->avctx, AV_LOG_ERROR,
+                   "not enough space for the output samples\n");
+            s->packet_loss = 1;
+        } else
+            s->output_buffer_full = 1;
         return 0;
     }
 
@@ -1451,12 +1457,13 @@ static int decode_packet(AVCodecContext 
     int packet_sequence_number;
 
     s->samples      = data;
+    s->samples_start = data;
     s->samples_end  = (float*)((int8_t*)data + *data_size);
-    s->buf_bit_size = buf_size << 3;
-
-
     *data_size = 0;
 
+    if (!s->output_buffer_full) {
+    s->buf_bit_size = buf_size << 3;
+
     /** sanity check for the buffer length */
     if (buf_size < avctx->block_align)
         return 0;
@@ -1498,8 +1505,15 @@ static int decode_packet(AVCodecContext 
     }
 
     s->packet_loss = 0;
+
+    } else {
+        /** continue decoding */
+        s->output_buffer_full = 0;
+        more_frames = decode_frame(s);
+    }
+
     /** decode the rest of the packet */
-    while (!s->packet_loss && more_frames &&
+    while (!s->packet_loss && !s->output_buffer_full && more_frames &&
            remaining_bits(s, gb) > s->log2_frame_size) {
         int frame_size = show_bits(gb, s->log2_frame_size);
 
@@ -1517,7 +1531,8 @@ static int decode_packet(AVCodecContext 
             more_frames = 0;
     }
 
-    if (!s->packet_loss && remaining_bits(s, gb) > 0) {
+    if (!s->output_buffer_full && !s->packet_loss &&
+        remaining_bits(s, gb) > 0) {
         /** save the rest of the data so that it can be decoded
             with the next packet */
         save_bits(s, gb, remaining_bits(s, gb), 0);
@@ -1525,7 +1540,7 @@ static int decode_packet(AVCodecContext 
 
     *data_size = (int8_t *)s->samples - (int8_t *)data;
 
-    return avctx->block_align;
+    return (s->output_buffer_full)?0: avctx->block_align;
 }
 
 /**



More information about the ffmpeg-cvslog mailing list