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>
Sat, 3 May 2014 16:06:08 +0000 (12:06 -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 61eecfe..ddfebaa 100644 (file)
@@ -833,7 +833,6 @@ static int ape_decode_frame(AVCodecContext *avctx, void *data,
     int32_t *sample24;
     int i, ch, 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. */
@@ -889,7 +888,6 @@ static int ape_decode_frame(AVCodecContext *avctx, void *data,
             return AVERROR_INVALIDDATA;
         }
 
-        bytes_used = avpkt->size;
     }
 
     if (!s->data) {
@@ -958,7 +956,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) ? avpkt->size : 0;
 }
 
 static void ape_flush(AVCodecContext *avctx)