From 929a2ced9ba7811136bce86293ec0b0a098c66df Mon Sep 17 00:00:00 2001 From: Niklas Haas Date: Mon, 22 Sep 2025 15:38:06 +0200 Subject: [PATCH] fftools/ffmpeg_dec: decode the first frame synchronously In an ideal world, a filtergraph like `-i A -i B ... -filter_complex concat` would only keep resources in memory related to the file currently being output by the concat filter. So ideally, we'd open and fully decode A, then open and fully decode B, and so on. Practically, however, fftools wants to get one frame from each input file in order to initialize the filter graph (buffersrc parameters). So what happens currently is that fftools will request a single frame from each input A, B, etc that is plugged into the filtergraph. When using frame threading, the design of the decoder (ff_thread_receive_frame) is that it will not output any frames until we have received enough packets to saturate all threads. This, however, forces the decoder to buffer at least as many frames for each input file as we have threads, before outputting anything. By decoding the first frame synchronously, we avoid this issue and allow configuring the filter graph more quickly and without wasting excess resources on frames that will not (yet) be used. --- fftools/ffmpeg_dec.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/fftools/ffmpeg_dec.c b/fftools/ffmpeg_dec.c index 2f25265997..a76d4b1ae8 100644 --- a/fftools/ffmpeg_dec.c +++ b/fftools/ffmpeg_dec.c @@ -744,11 +744,14 @@ static int packet_decode(DecoderPriv *dp, AVPacket *pkt, AVFrame *frame) while (1) { FrameData *fd; unsigned outputs_mask = 1; + unsigned flags = 0; + if (!dp->dec.frames_decoded) + flags |= AV_CODEC_RECEIVE_FRAME_FLAG_SYNCHRONOUS; av_frame_unref(frame); update_benchmark(NULL); - ret = avcodec_receive_frame(dec, frame); + ret = avcodec_receive_frame2(dec, frame, flags); update_benchmark("decode_%s %s", type_desc, dp->parent_name); if (ret == AVERROR(EAGAIN)) {