apedec: do not buffer decoded samples over AVPackets
authorRafaël Carré <funman@videolan.org>
Tue, 27 Aug 2013 15:35:49 +0000 (17:35 +0200)
committerReinhard Tartler <siretart@tauware.de>
Sun, 1 Jun 2014 00:07:52 +0000 (20:07 -0400)
Only consume an AVPacket when all the samples have been read.

When the rate of samples output is limited (by the default value
of max_samples), consuming the first packet immediately will cause
timing problems:

- The first packet with PTS 0 will output 4608 samples and be
consumed entirely
- The second packet with PTS 64 will output the remaining samples
(typically, a lot, that's why max_samples exist) until the decoded
samples of the first packet have been exhausted, at which point the
samples of the second packet will be decoded and output when
av_decode_frame is called with the next packet).

That means there's a PTS jump since the first packet is 'decoded'
immediately, which can be seen with avplay or mplayer: the timing
jumps immediately to 6.2s (which is the size of a packet).

Sample: http://streams.videolan.org/issues/6348/Goldwave-MAClib.ape

Bug-Debian: http://bugs.debian.org/744901
Signed-off-by: Justin Ruggles <justin.ruggles@gmail.com>
(cherry picked from commit 91d4cfb8127f1de6c4ad173a30fffe584700046d)
Signed-off-by: Reinhard Tartler <siretart@tauware.de>
libavcodec/apedec.c

index 0abf05b..745b14c 100644 (file)
@@ -822,7 +822,6 @@ static int ape_decode_frame(AVCodecContext *avctx, void *data,
     int16_t *samples;
     int i, ret;
     int blockstodecode;
-    int bytes_used = 0;
 
     /* this should never be negative, but bad things will happen if it is, so
        check it just to make sure. */
@@ -877,7 +876,6 @@ static int ape_decode_frame(AVCodecContext *avctx, void *data,
             return AVERROR_INVALIDDATA;
         }
 
-        bytes_used = buf_size;
     }
 
     if (!s->data) {
@@ -920,7 +918,7 @@ static int ape_decode_frame(AVCodecContext *avctx, void *data,
     *got_frame_ptr   = 1;
     *(AVFrame *)data = s->frame;
 
-    return bytes_used;
+    return (s->samples == 0) ? buf_size : 0;
 }
 
 static void ape_flush(AVCodecContext *avctx)