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 <jamrial@gmail.com>
This commit is contained in:
James Almer
2025-10-18 20:28:46 -03:00
parent 6879c8ee5d
commit 7ac1b410e1

View File

@@ -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 */