Commit 681025faf1 for ffmpeg
commit 681025faf1add6567b1f97d2f1037d0e764afd0f
Author: Jun Zhao <barryjzhao@tencent.com>
Date: Sun Nov 8 20:44:46 2026 +0800
avcodec/flac_parser: drop leftover headers when flushing at EOF
When the best header has no child, get_best_header() returns everything
from that header to the end of the FIFO. flac_parse() then frees the best
header but keeps best_header->next and leaves the FIFO undrained, so the
next flush call promotes a false sync found inside the frame just returned
and emits its leading bytes a second time as a junk packet, which the
decoder rejects.
When end_padded is set, no further input can arrive and the frame just
returned already consumed the rest of the FIFO. Free any remaining
headers and drain the FIFO.
Unlike 2d7eacee24, this covers false syncs whose blocking strategy agrees
with STREAMINFO, since that check cannot reject a fixed-blocksize false
sync in a fixed-blocksize stream.
Fixes: https://code.ffmpeg.org/FFmpeg/FFmpeg/issues/25857
See: https://code.ffmpeg.org/FFmpeg/FFmpeg/issues/25766
Signed-off-by: Jun Zhao <barryjzhao@tencent.com>
diff --git a/libavcodec/flac_parser.c b/libavcodec/flac_parser.c
index 8ee7439f7c..1dfe80505b 100644
--- a/libavcodec/flac_parser.c
+++ b/libavcodec/flac_parser.c
@@ -795,6 +795,21 @@ static int flac_parse(AVCodecParserContext *s, AVCodecContext *avctx,
fpc->headers->prev = NULL;
av_freep(&fpc->best_header);
fpc->nb_headers_buffered--;
+
+ /* Without a child, get_best_header() already returned everything
+ * from this header to the end of the FIFO. At EOF there can be no
+ * further frames, so any header still queued is a false sync inside
+ * that frame. Drop them and drain the FIFO, or the next flush emits
+ * part of the final frame a second time. */
+ if (fpc->end_padded) {
+ for (curr = fpc->headers; curr; curr = temp) {
+ temp = curr->next;
+ av_free(curr);
+ fpc->nb_headers_buffered--;
+ }
+ fpc->headers = NULL;
+ flac_fifo_drain(&fpc->fifo_buf, flac_fifo_size(&fpc->fifo_buf));
+ }
}
/* Find and score new headers. */