From 7ac1b410e12ff0952be49ad9aff0dba0f0406f8f Mon Sep 17 00:00:00 2001 From: James Almer Date: Sat, 18 Oct 2025 20:28:46 -0300 Subject: [PATCH] fftools/ffmpeg_filter: fix passing certain parameters to inputs bound to a filtergraph output Certain parameters, like calculated framerate, are unavailable when connecting the output of a filtergraph to the input of another. This fixes command lines like ffmpeg -lavfi "testsrc=rate=1:duration=1[out0]" -filter_complex "[out0]null[out1]" -map [out1] -y out.png Signed-off-by: James Almer --- fftools/ffmpeg_filter.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c index b9a51ad687..a23bcbda95 100644 --- a/fftools/ffmpeg_filter.c +++ b/fftools/ffmpeg_filter.c @@ -109,6 +109,9 @@ typedef struct InputFilterPriv { // used to hold submitted input AVFrame *frame; + // For inputs bound to a filtergraph output + OutputFilter *ofilter_src; + // source data type: AVMEDIA_TYPE_SUBTITLE for sub2video, // same as type otherwise enum AVMediaType type_src; @@ -928,6 +931,8 @@ static int ofilter_bind_ifilter(OutputFilter *ofilter, InputFilterPriv *ifp, if (!ofilter->output_name) return AVERROR(EINVAL); + ifp->ofilter_src = ofilter; + av_strlcatf(ofp->log_name, sizeof(ofp->log_name), "->%s", ofilter->output_name); return 0; @@ -2155,6 +2160,27 @@ static int ifilter_parameters_from_frame(InputFilter *ifilter, const AVFrame *fr return 0; } +static int ifilter_parameters_from_ofilter(InputFilter *ifilter, OutputFilter *ofilter) +{ + const OutputFilterPriv *ofp = ofp_from_ofilter(ofilter); + InputFilterPriv *ifp = ifp_from_ifilter(ifilter); + + if (!ifp->opts.framerate.num) { + ifp->opts.framerate = ofp->fps.framerate; + if (ifp->opts.framerate.num > 0 && ifp->opts.framerate.den > 0) + ifp->opts.flags |= IFILTER_FLAG_CFR; + } + + for (int i = 0; i < ofp->nb_side_data; i++) { + int ret = av_frame_side_data_clone(&ifp->side_data, &ifp->nb_side_data, + ofp->side_data[i], AV_FRAME_SIDE_DATA_FLAG_REPLACE); + if (ret < 0) + return ret; + } + + return 0; +} + int filtergraph_is_simple(const FilterGraph *fg) { const FilterGraphPriv *fgp = cfgp_from_cfg(fg); @@ -2935,6 +2961,14 @@ static int send_frame(FilterGraph *fg, FilterGraphThread *fgt, ret = ifilter_parameters_from_frame(ifilter, frame); if (ret < 0) return ret; + + /* Inputs bound to a filtergraph output will have some fields unset. + * Handle them here */ + if (ifp->ofilter_src) { + ret = ifilter_parameters_from_ofilter(ifilter, ifp->ofilter_src); + if (ret < 0) + return ret; + } } /* (re)init the graph if possible, otherwise buffer the frame and return */