aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJyrki Vesterinen <jyrkive@nekonyansoft.com>2022-09-08 14:36:32 +0300
committerPaul B Mahol <onemda@gmail.com>2022-09-14 19:42:59 +0200
commit8fc2dedfe6e8fcc58dd052bf3b85cd4754133b17 (patch)
tree32966b2dc3789c37485e9223a2bfb42c83e2eb53
parenta5ce44f30108a0683a123354e52210a20026fb5c (diff)
downloadffmpeg-8fc2dedfe6e8fcc58dd052bf3b85cd4754133b17.tar.gz
avcodec/vorbisdec: don't use a flag to determine if frames have been output
If a developer using FFmpeg libraries seeks into an earlier position and calls avcodec_flush_buffers() afterwards as recommended, the Vorbis decoder will drop the next frame, since buffer flushing clears the first_frame flag. As a result, the audio samples the calling code receives may be ahead of the requested seek position, which is unacceptable in some use cases such as playing a looping sound effect. This commit records the presentation timestamp of the first frame and determines after that if the new frame is the first frame (possible after seeking to the start) by comparing its pts to the stored pts.
-rw-r--r--libavcodec/vorbisdec.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/libavcodec/vorbisdec.c b/libavcodec/vorbisdec.c
index 4d03947c49..38a5367be3 100644
--- a/libavcodec/vorbisdec.c
+++ b/libavcodec/vorbisdec.c
@@ -131,6 +131,7 @@ typedef struct vorbis_context_s {
FFTContext mdct[2];
uint8_t first_frame;
+ int64_t initial_pts;
uint32_t version;
uint8_t audio_channels;
uint32_t audio_samplerate;
@@ -1847,6 +1848,10 @@ static int vorbis_decode_frame(AVCodecContext *avctx, AVFrame *frame,
if (!vc->first_frame) {
vc->first_frame = 1;
+ vc->initial_pts = frame->pts;
+ }
+
+ if (frame->pts == vc->initial_pts) {
*got_frame_ptr = 0;
av_frame_unref(frame);
return buf_size;
@@ -1881,7 +1886,6 @@ static av_cold void vorbis_decode_flush(AVCodecContext *avctx)
sizeof(*vc->saved));
}
vc->previous_window = -1;
- vc->first_frame = 0;
}
const FFCodec ff_vorbis_decoder = {