From a4c940c86a46e817eea16d8535db383f9e19c25c Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Thu, 4 Apr 2024 10:51:53 +0200 Subject: [PATCH] fftools/ffmpeg_filter: move most of -apad logic to the muxer The decision whether -apad actually does anything is made based on muxer properties, and so more properly belongs there. Filtering code only receives the result. --- fftools/ffmpeg.h | 3 ++- fftools/ffmpeg_filter.c | 16 +++------------- fftools/ffmpeg_mux.c | 1 - fftools/ffmpeg_mux.h | 2 ++ fftools/ffmpeg_mux_init.c | 36 +++++++++++++++++++++++++++++------- 5 files changed, 36 insertions(+), 22 deletions(-) diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h index 8e773165da..26b42a3fcd 100644 --- a/fftools/ffmpeg.h +++ b/fftools/ffmpeg.h @@ -320,6 +320,8 @@ typedef struct OutputFilter { * this stores the output linklabel, if any */ uint8_t *linklabel; + char *apad; + enum AVMediaType type; atomic_uint_least64_t nb_frames_dup; @@ -581,7 +583,6 @@ typedef struct OutputStream { OutputFilter *filter; AVDictionary *encoder_opts; - char *apad; char *attachment_filename; diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c index 225fa4bda2..ec17e99494 100644 --- a/fftools/ffmpeg_filter.c +++ b/fftools/ffmpeg_filter.c @@ -969,6 +969,7 @@ void fg_free(FilterGraph **pfg) av_freep(&ofilter->linklabel); av_freep(&ofilter->name); + av_freep(&ofilter->apad); av_freep(&ofp->name); av_channel_layout_uninit(&ofp->ch_layout); av_freep(&fg->outputs[j]); @@ -1430,8 +1431,6 @@ static int configure_output_audio_filter(FilterGraph *fg, AVFilterGraph *graph, OutputFilter *ofilter, AVFilterInOut *out) { OutputFilterPriv *ofp = ofp_from_ofilter(ofilter); - OutputStream *ost = ofilter->ost; - OutputFile *of = ost->file; AVFilterContext *last_filter = out->filter_ctx; int pad_idx = out->pad_idx; AVBPrint args; @@ -1493,17 +1492,8 @@ static int configure_output_audio_filter(FilterGraph *fg, AVFilterGraph *graph, pad_idx = 0; } - if (ost->apad && of->shortest) { - int i; - - for (i = 0; i < of->nb_streams; i++) - if (of->streams[i]->st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) - break; - - if (i < of->nb_streams) { - AUTO_INSERT_FILTER("-apad", "apad", ost->apad); - } - } + if (ofilter->apad) + AUTO_INSERT_FILTER("-apad", "apad", ofilter->apad); snprintf(name, sizeof(name), "trim for output %s", ofp->name); ret = insert_trim(ofp->trim_start_us, ofp->trim_duration_us, diff --git a/fftools/ffmpeg_mux.c b/fftools/ffmpeg_mux.c index 557f08b3a5..6a64cba72d 100644 --- a/fftools/ffmpeg_mux.c +++ b/fftools/ffmpeg_mux.c @@ -815,7 +815,6 @@ static void ost_free(OutputStream **post) av_expr_free(ost->kf.pexpr); av_freep(&ost->logfile_prefix); - av_freep(&ost->apad); av_freep(&ost->attachment_filename); diff --git a/fftools/ffmpeg_mux.h b/fftools/ffmpeg_mux.h index f8b6f7a790..1e9ea35412 100644 --- a/fftools/ffmpeg_mux.h +++ b/fftools/ffmpeg_mux.h @@ -78,6 +78,8 @@ typedef struct MuxStream { #if FFMPEG_OPT_VSYNC_DROP int ts_drop; #endif + + char *apad; } MuxStream; typedef struct Muxer { diff --git a/fftools/ffmpeg_mux_init.c b/fftools/ffmpeg_mux_init.c index 6e19b98abd..a483fffa6e 100644 --- a/fftools/ffmpeg_mux_init.c +++ b/fftools/ffmpeg_mux_init.c @@ -828,6 +828,7 @@ static int new_stream_video(Muxer *mux, const OptionsContext *o, static int new_stream_audio(Muxer *mux, const OptionsContext *o, OutputStream *ost) { + MuxStream *ms = ms_from_ost(ost); AVFormatContext *oc = mux->fc; AVStream *st = ost->st; @@ -836,7 +837,6 @@ static int new_stream_audio(Muxer *mux, const OptionsContext *o, int channels = 0; char *layout = NULL; char *sample_fmt = NULL; - const char *apad = NULL; MATCH_PER_STREAM_OPT(audio_channels, i, channels, oc, st); if (channels) { @@ -859,12 +859,7 @@ static int new_stream_audio(Muxer *mux, const OptionsContext *o, MATCH_PER_STREAM_OPT(audio_sample_rate, i, audio_enc->sample_rate, oc, st); - MATCH_PER_STREAM_OPT(apad, str, apad, oc, st); - if (apad) { - ost->apad = av_strdup(apad); - if (!ost->apad) - return AVERROR(ENOMEM); - } + MATCH_PER_STREAM_OPT(apad, str, ms->apad, oc, st); } return 0; @@ -1890,6 +1885,33 @@ static int create_streams(Muxer *mux, const OptionsContext *o) } } + // handle -apad + if (mux->of.shortest) { + int have_video = 0; + + for (unsigned i = 0; i < mux->of.nb_streams; i++) + if (mux->of.streams[i]->type == AVMEDIA_TYPE_VIDEO) { + have_video = 1; + break; + } + + for (unsigned i = 0; have_video && i < mux->of.nb_streams; i++) { + MuxStream *ms = ms_from_ost(mux->of.streams[i]); + OutputFilter *ofilter = ms->ost.filter; + + if (ms->ost.type != AVMEDIA_TYPE_AUDIO || !ms->apad || !ofilter) + continue; + + ofilter->apad = av_strdup(ms->apad); + if (!ofilter->apad) + return AVERROR(ENOMEM); + } + } + for (unsigned i = 0; i < mux->of.nb_streams; i++) { + MuxStream *ms = ms_from_ost(mux->of.streams[i]); + ms->apad = NULL; + } + if (!oc->nb_streams && !(oc->oformat->flags & AVFMT_NOSTREAMS)) { av_dump_format(oc, nb_output_files - 1, oc->url, 1); av_log(mux, AV_LOG_ERROR, "Output file does not contain any stream\n");