From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by master.gitmailbox.com (Postfix) with ESMTP id 0975C44C80 for ; Mon, 14 Nov 2022 15:15:03 +0000 (UTC) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 796F768BE34; Mon, 14 Nov 2022 17:14:31 +0200 (EET) Received: from mail0.khirnov.net (red.khirnov.net [176.97.15.12]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 8866E68BE1A for ; Mon, 14 Nov 2022 17:14:22 +0200 (EET) Received: from localhost (localhost [IPv6:::1]) by mail0.khirnov.net (Postfix) with ESMTP id 3126A2405EC for ; Mon, 14 Nov 2022 16:14:22 +0100 (CET) Received: from mail0.khirnov.net ([IPv6:::1]) by localhost (mail0.khirnov.net [IPv6:::1]) (amavisd-new, port 10024) with ESMTP id w9PwdQsXX6wi for ; Mon, 14 Nov 2022 16:14:21 +0100 (CET) Received: from libav.khirnov.net (libav.khirnov.net [IPv6:2a00:c500:561:201::7]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256 client-signature RSA-PSS (2048 bits) client-digest SHA256) (Client CN "libav.khirnov.net", Issuer "smtp.khirnov.net SMTP CA" (verified OK)) by mail0.khirnov.net (Postfix) with ESMTPS id 1C623240591 for ; Mon, 14 Nov 2022 16:14:19 +0100 (CET) Received: from libav.khirnov.net (libav.khirnov.net [IPv6:::1]) by libav.khirnov.net (Postfix) with ESMTP id BFB483A058F for ; Mon, 14 Nov 2022 16:14:18 +0100 (CET) From: Anton Khirnov To: ffmpeg-devel@ffmpeg.org Date: Mon, 14 Nov 2022 16:13:47 +0100 Message-Id: <20221114151350.5134-5-anton@khirnov.net> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20221114151350.5134-1-anton@khirnov.net> References: <20221114151350.5134-1-anton@khirnov.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 5/8] fftools/ffmpeg_mux_init: move validating codec avoptions to a separate function X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Archived-At: List-Archive: List-Post: --- fftools/ffmpeg.h | 2 +- fftools/ffmpeg_mux_init.c | 91 +++++++++++++++++++++------------------ fftools/ffmpeg_opt.c | 2 +- 3 files changed, 51 insertions(+), 44 deletions(-) diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h index ad53ad4ce8..b9262b373f 100644 --- a/fftools/ffmpeg.h +++ b/fftools/ffmpeg.h @@ -694,7 +694,7 @@ void assert_avoptions(AVDictionary *m); void assert_file_overwrite(const char *filename); char *file_read(const char *filename); -AVDictionary *strip_specifiers(AVDictionary *dict); +AVDictionary *strip_specifiers(const AVDictionary *dict); const AVCodec *find_codec_or_die(const char *name, enum AVMediaType type, int encoder); int parse_and_set_vsync(const char *arg, int *vsync_var, int file_idx, int st_idx, int is_global); diff --git a/fftools/ffmpeg_mux_init.c b/fftools/ffmpeg_mux_init.c index 150eb77ee2..7ccaf9da78 100644 --- a/fftools/ffmpeg_mux_init.c +++ b/fftools/ffmpeg_mux_init.c @@ -1725,14 +1725,60 @@ static int set_dispositions(OutputFile *of, AVFormatContext *ctx) return 0; } +static void validate_enc_avopt(const Muxer *mux, const AVDictionary *codec_avopt) +{ + const OutputFile *of = &mux->of; + + AVDictionary *unused_opts; + const AVDictionaryEntry *e; + + unused_opts = strip_specifiers(codec_avopt); + for (int i = 0; i < of->nb_streams; i++) { + e = NULL; + while ((e = av_dict_get(of->streams[i]->encoder_opts, "", e, + AV_DICT_IGNORE_SUFFIX))) + av_dict_set(&unused_opts, e->key, NULL, 0); + } + + e = NULL; + while ((e = av_dict_get(unused_opts, "", e, AV_DICT_IGNORE_SUFFIX))) { + const AVClass *class = avcodec_get_class(); + const AVOption *option = av_opt_find(&class, e->key, NULL, 0, + AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ); + const AVClass *fclass = avformat_get_class(); + const AVOption *foption = av_opt_find(&fclass, e->key, NULL, 0, + AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ); + if (!option || foption) + continue; + + if (!(option->flags & AV_OPT_FLAG_ENCODING_PARAM)) { + av_log(NULL, AV_LOG_ERROR, "Codec AVOption %s (%s) specified for " + "output file #%d (%s) is not an encoding option.\n", e->key, + option->help ? option->help : "", nb_output_files - 1, + mux->fc->url); + exit_program(1); + } + + // gop_timecode is injected by generic code but not always used + if (!strcmp(e->key, "gop_timecode")) + continue; + + av_log(NULL, AV_LOG_WARNING, "Codec AVOption %s (%s) specified for " + "output file #%d (%s) has not been used for any stream. The most " + "likely reason is either wrong type (e.g. a video option with " + "no video streams) or that it is a private option of some encoder " + "which was not actually used for any stream.\n", e->key, + option->help ? option->help : "", nb_output_files - 1, mux->fc->url); + } + av_dict_free(&unused_opts); +} + int of_open(const OptionsContext *o, const char *filename) { Muxer *mux; AVFormatContext *oc; int err; OutputFile *of; - AVDictionary *unused_opts = NULL; - const AVDictionaryEntry *e = NULL; int64_t recording_time = o->recording_time; int64_t stop_time = o->stop_time; @@ -1795,46 +1841,7 @@ int of_open(const OptionsContext *o, const char *filename) create_streams(mux, o); /* check if all codec options have been used */ - unused_opts = strip_specifiers(o->g->codec_opts); - for (int i = 0; i < of->nb_streams; i++) { - e = NULL; - while ((e = av_dict_get(of->streams[i]->encoder_opts, "", e, - AV_DICT_IGNORE_SUFFIX))) - av_dict_set(&unused_opts, e->key, NULL, 0); - } - - e = NULL; - while ((e = av_dict_get(unused_opts, "", e, AV_DICT_IGNORE_SUFFIX))) { - const AVClass *class = avcodec_get_class(); - const AVOption *option = av_opt_find(&class, e->key, NULL, 0, - AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ); - const AVClass *fclass = avformat_get_class(); - const AVOption *foption = av_opt_find(&fclass, e->key, NULL, 0, - AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ); - if (!option || foption) - continue; - - - if (!(option->flags & AV_OPT_FLAG_ENCODING_PARAM)) { - av_log(NULL, AV_LOG_ERROR, "Codec AVOption %s (%s) specified for " - "output file #%d (%s) is not an encoding option.\n", e->key, - option->help ? option->help : "", nb_output_files - 1, - filename); - exit_program(1); - } - - // gop_timecode is injected by generic code but not always used - if (!strcmp(e->key, "gop_timecode")) - continue; - - av_log(NULL, AV_LOG_WARNING, "Codec AVOption %s (%s) specified for " - "output file #%d (%s) has not been used for any stream. The most " - "likely reason is either wrong type (e.g. a video option with " - "no video streams) or that it is a private option of some encoder " - "which was not actually used for any stream.\n", e->key, - option->help ? option->help : "", nb_output_files - 1, filename); - } - av_dict_free(&unused_opts); + validate_enc_avopt(mux, o->g->codec_opts); /* set the decoding_needed flags and create simple filtergraphs */ for (int i = 0; i < of->nb_streams; i++) { diff --git a/fftools/ffmpeg_opt.c b/fftools/ffmpeg_opt.c index 0fd9d98f0f..5ab296828b 100644 --- a/fftools/ffmpeg_opt.c +++ b/fftools/ffmpeg_opt.c @@ -165,7 +165,7 @@ static int show_hwaccels(void *optctx, const char *opt, const char *arg) } /* return a copy of the input with the stream specifiers removed from the keys */ -AVDictionary *strip_specifiers(AVDictionary *dict) +AVDictionary *strip_specifiers(const AVDictionary *dict) { const AVDictionaryEntry *e = NULL; AVDictionary *ret = NULL; -- 2.35.1 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".