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