From patchwork Sat Aug 10 17:16:20 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Khirnov X-Patchwork-Id: 50970 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:612c:1ff2:b0:489:2eb3:e4c4 with SMTP id ks18csp530199vqb; Sat, 10 Aug 2024 10:26:13 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCUfHtvw85V/Nz0B3+Wb9Euca4KQMR+uufMdsoicotPsUtpPZZ3xWoDMk9+B30qRyE67Oo6c/gzMexj/7/IVwvWb3GOxI+Y3GCzsaA== X-Google-Smtp-Source: AGHT+IHkc39DIHs4/GBxxAinkodS/zKCpGWfm7eu0SEZ3zKwxwp62GPjkUOz9gRLkIPWqT64l7Nm X-Received: by 2002:a2e:a23b:0:b0:2ef:18b7:440a with SMTP id 38308e7fff4ca-2f1a6c67ca2mr34272171fa.22.1723310772889; Sat, 10 Aug 2024 10:26:12 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1723310772; cv=none; d=google.com; s=arc-20160816; b=Nh7ENFaJvkRQNFB1KCABfhPMBwIX7KZp+o3a18q4Ph/MVfwar4LJWaNMnsAQPGF44q gBE8l25HqIiLLlNaYIm7ROM6Ne3sNOCnwW/Vgsi1XtymIAOoZMTBAj+SCB9UoL3yenCg i+hj8J/3+drXxMakXbhYrdrbmjXczvEFaSWmzbTNDEkO2QTK4Q0llM2u+ceAsBxLxC7R GFsdU71hIzeX9F/YQxk57/xusEcnR0hbVMEkHz+dubWFM2SfdBuxF4k3/FJPam4HIuAU QnYC8AQ3r/vPQHT/hk9IhEEFtS9OT8ZoKcttfNk/ZDLfDMRLqa2tuRm2o//mzcvpUIHG ljzw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:reply-to:list-subscribe :list-help:list-post:list-archive:list-unsubscribe:list-id :precedence:subject:mime-version:references:in-reply-to:message-id :date:to:from:dkim-signature:delivered-to; bh=p2b+kXJ08nN6TlEDbyQ72X4HATszGy6KV4elYxmsV5c=; fh=YOA8vD9MJZuwZ71F/05pj6KdCjf6jQRmzLS+CATXUQk=; b=GzkuG97lbxCi2ZnHoGVIYCypZEjZmStLzSbAUq9evQw8Bg8THFcgInBEYBj+KLRFjz dxgcaWUZTfNoC+eHUU/uTMi5LPyt64GisLgYugliCu0UGLRIPaBITNIKgh7t4u70dvp9 hTtzrNHNU2zVEZ3YrbVh0wXo04iaFCv22EdDfn9FL7u1n+vsdZXSolekdcSzqeuSrjt6 um95MA/bqoNoK6lTxr1z/hG2701Iwqn5vKkD/NgjytXVNP1erhxRofsKja+kNBCcmczE EYi20YoH0otYIT0M5POuiX78QzLI0jB546I95NgUAazhaQYMMdBWcm/LQ92/bzUAi7Rb nNkg==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@khirnov.net header.s=mail header.b=nxW4bOtm; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id 38308e7fff4ca-2f292073ed6si5457591fa.610.2024.08.10.10.26.12; Sat, 10 Aug 2024 10:26:12 -0700 (PDT) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@khirnov.net header.s=mail header.b=nxW4bOtm; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id ED62568DA86; Sat, 10 Aug 2024 20:16:45 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail1.khirnov.net (quelana.khirnov.net [94.230.150.81]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id E6CDF68D93B for ; Sat, 10 Aug 2024 20:16:35 +0300 (EEST) Authentication-Results: mail1.khirnov.net; dkim=pass (2048-bit key; unprotected) header.d=khirnov.net header.i=@khirnov.net header.a=rsa-sha256 header.s=mail header.b=nxW4bOtm; dkim-atps=neutral Received: from localhost (mail1.khirnov.net [IPv6:::1]) by mail1.khirnov.net (Postfix) with ESMTP id 83D524DF6 for ; Sat, 10 Aug 2024 19:16:35 +0200 (CEST) Received: from mail1.khirnov.net ([IPv6:::1]) by localhost (mail1.khirnov.net [IPv6:::1]) (amavis, port 10024) with ESMTP id IHiJIxnDL2GC for ; Sat, 10 Aug 2024 19:16:34 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=khirnov.net; s=mail; t=1723310193; bh=AAoE9vXAbbKt3WBUWAfs8b9Tm5vrsFN0qshNd1CIWdU=; h=From:To:Subject:Date:In-Reply-To:References:From; b=nxW4bOtmx0bU59ia9uoCCF3El2SZHDNYskrFhDBPp9Np8HXrHV9UteX5kGzm5gWrt rNMHP2iwT+xN/+itar1J8Clmp9JJ+sAcOBPHMMQcCs/HOwsJjNps/f2ccYeBACFqhO LPWhfMj8elLebAzTDa0w9MLnMvJNIJVuvwCV+Y8Ky6zbfRSxiRvM5W/sLYoRSgdeXi +4mtBb+vBNDHpu7etxy5iCbymBzqYfrvXoCCGX2QBT7CrmKVWcOIhqQ/tCuq/VxJ2l GuhscPzpjE7Q9pk4IcQ7yueKuLk57oIY6l7W15wbhzfZUnGXrz0R7Mcm/EevV6tuY9 LErZpNCyedwGw== 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 mail1.khirnov.net (Postfix) with ESMTPS id E863C4DBC for ; Sat, 10 Aug 2024 19:16:32 +0200 (CEST) Received: from libav.khirnov.net (libav.khirnov.net [IPv6:::1]) by libav.khirnov.net (Postfix) with ESMTP id 6957C3A1E29 for ; Sat, 10 Aug 2024 19:16:26 +0200 (CEST) From: Anton Khirnov To: ffmpeg-devel@ffmpeg.org Date: Sat, 10 Aug 2024 19:16:20 +0200 Message-ID: <20240810171621.26757-5-anton@khirnov.net> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240810171621.26757-1-anton@khirnov.net> References: <20240810171621.26757-1-anton@khirnov.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 5/6] fftools/ffmpeg: use new stream specifier API in opt_match_per_stream*() 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 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: YTM46G5Atmdz Removes a lot of error checking code, as matching cannot fail. --- fftools/cmdutils.c | 8 ++ fftools/cmdutils.h | 6 +- fftools/ffmpeg.h | 16 +-- fftools/ffmpeg_demux.c | 87 ++++------------- fftools/ffmpeg_mux_init.c | 198 ++++++++++---------------------------- fftools/ffmpeg_opt.c | 32 +++--- 6 files changed, 105 insertions(+), 242 deletions(-) diff --git a/fftools/cmdutils.c b/fftools/cmdutils.c index b3f501bd56..f725c31c12 100644 --- a/fftools/cmdutils.c +++ b/fftools/cmdutils.c @@ -288,6 +288,14 @@ static int write_option(void *optctx, const OptionDef *po, const char *opt, goto finish; } sol->opt[sol->nb_opt - 1].specifier = str; + + if (po->flags & OPT_FLAG_PERSTREAM) { + ret = stream_specifier_parse(&sol->opt[sol->nb_opt - 1].stream_spec, + str, 0, NULL); + if (ret < 0) + goto finish; + } + dst = &sol->opt[sol->nb_opt - 1].u; } diff --git a/fftools/cmdutils.h b/fftools/cmdutils.h index f7005aabf9..9609c6c739 100644 --- a/fftools/cmdutils.h +++ b/fftools/cmdutils.h @@ -159,7 +159,11 @@ unsigned stream_specifier_match(const StreamSpecifier *ss, void stream_specifier_uninit(StreamSpecifier *ss); typedef struct SpecifierOpt { - char *specifier; /**< stream/chapter/program/... specifier */ + // original specifier or empty string + char *specifier; + // parsed specifier for OPT_FLAG_PERSTREAM options + StreamSpecifier stream_spec; + union { uint8_t *str; int i; diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h index 674ae340f2..3c5d933e17 100644 --- a/fftools/ffmpeg.h +++ b/fftools/ffmpeg.h @@ -859,14 +859,14 @@ void update_benchmark(const char *fmt, ...); const char *opt_match_per_type_str(const SpecifierOptList *sol, char mediatype); -int opt_match_per_stream_str(void *logctx, const SpecifierOptList *sol, - AVFormatContext *fc, AVStream *st, const char **out); -int opt_match_per_stream_int(void *logctx, const SpecifierOptList *sol, - AVFormatContext *fc, AVStream *st, int *out); -int opt_match_per_stream_int64(void *logctx, const SpecifierOptList *sol, - AVFormatContext *fc, AVStream *st, int64_t *out); -int opt_match_per_stream_dbl(void *logctx, const SpecifierOptList *sol, - AVFormatContext *fc, AVStream *st, double *out); +void opt_match_per_stream_str(void *logctx, const SpecifierOptList *sol, + AVFormatContext *fc, AVStream *st, const char **out); +void opt_match_per_stream_int(void *logctx, const SpecifierOptList *sol, + AVFormatContext *fc, AVStream *st, int *out); +void opt_match_per_stream_int64(void *logctx, const SpecifierOptList *sol, + AVFormatContext *fc, AVStream *st, int64_t *out); +void opt_match_per_stream_dbl(void *logctx, const SpecifierOptList *sol, + AVFormatContext *fc, AVStream *st, double *out); int muxer_thread(void *arg); int encoder_thread(void *arg); diff --git a/fftools/ffmpeg_demux.c b/fftools/ffmpeg_demux.c index e9a4b5c22a..039ee0c785 100644 --- a/fftools/ffmpeg_demux.c +++ b/fftools/ffmpeg_demux.c @@ -1084,12 +1084,8 @@ static int choose_decoder(const OptionsContext *o, void *logctx, { const char *codec_name = NULL; - int ret; - - ret = opt_match_per_stream_str(logctx, &o->codec_names, s, st, &codec_name); - if (ret < 0) - return ret; + opt_match_per_stream_str(logctx, &o->codec_names, s, st, &codec_name); if (codec_name) { int ret = find_codec(NULL, codec_name, st->codecpar->codec_type, 0, pcodec); if (ret < 0) @@ -1153,18 +1149,11 @@ static int add_display_matrix_to_stream(const OptionsContext *o, double rotation = DBL_MAX; int hflip = -1, vflip = -1; int hflip_set = 0, vflip_set = 0, rotation_set = 0; - int ret; int32_t *buf; - ret = opt_match_per_stream_dbl(ist, &o->display_rotations, ctx, st, &rotation); - if (ret < 0) - return ret; - ret = opt_match_per_stream_int(ist, &o->display_hflips, ctx, st, &hflip); - if (ret < 0) - return ret; - ret = opt_match_per_stream_int(ist, &o->display_vflips, ctx, st, &vflip); - if (ret < 0) - return ret; + opt_match_per_stream_dbl(ist, &o->display_rotations, ctx, st, &rotation); + opt_match_per_stream_int(ist, &o->display_hflips, ctx, st, &hflip); + opt_match_per_stream_int(ist, &o->display_vflips, ctx, st, &vflip); rotation_set = rotation != DBL_MAX; hflip_set = hflip != -1; @@ -1262,19 +1251,13 @@ static int ist_add(const OptionsContext *o, Demuxer *d, AVStream *st, AVDictiona ds->dec_opts.time_base = st->time_base; ds->ts_scale = 1.0; - ret = opt_match_per_stream_dbl(ist, &o->ts_scale, ic, st, &ds->ts_scale); - if (ret < 0) - return ret; + opt_match_per_stream_dbl(ist, &o->ts_scale, ic, st, &ds->ts_scale); ds->autorotate = 1; - ret = opt_match_per_stream_int(ist, &o->autorotate, ic, st, &ds->autorotate); - if (ret < 0) - return ret; + opt_match_per_stream_int(ist, &o->autorotate, ic, st, &ds->autorotate); ds->apply_cropping = CROP_ALL; - ret = opt_match_per_stream_str(ist, &o->apply_cropping, ic, st, &apply_cropping); - if (ret < 0) - return ret; + opt_match_per_stream_str(ist, &o->apply_cropping, ic, st, &apply_cropping); if (apply_cropping) { const AVOption opts[] = { { "apply_cropping", NULL, 0, AV_OPT_TYPE_INT, @@ -1300,9 +1283,7 @@ static int ist_add(const OptionsContext *o, Demuxer *d, AVStream *st, AVDictiona } } - ret = opt_match_per_stream_str(ist, &o->codec_tags, ic, st, &codec_tag); - if (ret < 0) - return ret; + opt_match_per_stream_str(ist, &o->codec_tags, ic, st, &codec_tag); if (codec_tag) { uint32_t tag = strtol(codec_tag, &next, 0); if (*next) { @@ -1319,15 +1300,9 @@ static int ist_add(const OptionsContext *o, Demuxer *d, AVStream *st, AVDictiona if (ret < 0) return ret; - ret = opt_match_per_stream_str(ist, &o->hwaccels, ic, st, &hwaccel); - if (ret < 0) - return ret; - - ret = opt_match_per_stream_str(ist, &o->hwaccel_output_formats, ic, st, + opt_match_per_stream_str(ist, &o->hwaccels, ic, st, &hwaccel); + opt_match_per_stream_str(ist, &o->hwaccel_output_formats, ic, st, &hwaccel_output_format); - if (ret < 0) - return ret; - if (!hwaccel_output_format && hwaccel && !strcmp(hwaccel, "cuvid")) { av_log(ist, AV_LOG_WARNING, "WARNING: defaulting hwaccel_output_format to cuda for compatibility " @@ -1385,9 +1360,7 @@ static int ist_add(const OptionsContext *o, Demuxer *d, AVStream *st, AVDictiona } } - ret = opt_match_per_stream_str(ist, &o->hwaccel_devices, ic, st, &hwaccel_device); - if (ret < 0) - return ret; + opt_match_per_stream_str(ist, &o->hwaccel_devices, ic, st, &hwaccel_device); if (hwaccel_device) { ds->dec_opts.hwaccel_device = av_strdup(hwaccel_device); if (!ds->dec_opts.hwaccel_device) @@ -1408,9 +1381,7 @@ static int ist_add(const OptionsContext *o, Demuxer *d, AVStream *st, AVDictiona } ds->reinit_filters = -1; - ret = opt_match_per_stream_int(ist, &o->reinit_filters, ic, st, &ds->reinit_filters); - if (ret < 0) - return ret; + opt_match_per_stream_int(ist, &o->reinit_filters, ic, st, &ds->reinit_filters); ist->user_set_discard = AVDISCARD_NONE; @@ -1420,9 +1391,7 @@ static int ist_add(const OptionsContext *o, Demuxer *d, AVStream *st, AVDictiona (o->data_disable && ist->st->codecpar->codec_type == AVMEDIA_TYPE_DATA)) ist->user_set_discard = AVDISCARD_ALL; - ret = opt_match_per_stream_str(ist, &o->discard, ic, st, &discard_str); - if (ret < 0) - return ret; + opt_match_per_stream_str(ist, &o->discard, ic, st, &discard_str); if (discard_str) { ret = av_opt_set(ist->st, "discard", discard_str, 0); if (ret < 0) { @@ -1444,9 +1413,7 @@ static int ist_add(const OptionsContext *o, Demuxer *d, AVStream *st, AVDictiona switch (par->codec_type) { case AVMEDIA_TYPE_VIDEO: - ret = opt_match_per_stream_str(ist, &o->frame_rates, ic, st, &framerate); - if (ret < 0) - return ret; + opt_match_per_stream_str(ist, &o->frame_rates, ic, st, &framerate); if (framerate) { ret = av_parse_video_rate(&ist->framerate, framerate); if (ret < 0) { @@ -1458,18 +1425,14 @@ static int ist_add(const OptionsContext *o, Demuxer *d, AVStream *st, AVDictiona #if FFMPEG_OPT_TOP ist->top_field_first = -1; - ret = opt_match_per_stream_int(ist, &o->top_field_first, ic, st, &ist->top_field_first); - if (ret < 0) - return ret; + opt_match_per_stream_int(ist, &o->top_field_first, ic, st, &ist->top_field_first); #endif break; case AVMEDIA_TYPE_AUDIO: { const char *ch_layout_str = NULL; - ret = opt_match_per_stream_str(ist, &o->audio_ch_layouts, ic, st, &ch_layout_str); - if (ret < 0) - return ret; + opt_match_per_stream_str(ist, &o->audio_ch_layouts, ic, st, &ch_layout_str); if (ch_layout_str) { AVChannelLayout ch_layout; ret = av_channel_layout_from_string(&ch_layout, ch_layout_str); @@ -1489,10 +1452,7 @@ static int ist_add(const OptionsContext *o, Demuxer *d, AVStream *st, AVDictiona } } else { int guess_layout_max = INT_MAX; - ret = opt_match_per_stream_int(ist, &o->guess_layout_max, ic, st, &guess_layout_max); - if (ret < 0) - return ret; - + opt_match_per_stream_int(ist, &o->guess_layout_max, ic, st, &guess_layout_max); guess_input_channel_layout(ist, par, guess_layout_max); } break; @@ -1501,13 +1461,8 @@ static int ist_add(const OptionsContext *o, Demuxer *d, AVStream *st, AVDictiona case AVMEDIA_TYPE_SUBTITLE: { const char *canvas_size = NULL; - ret = opt_match_per_stream_int(ist, &o->fix_sub_duration, ic, st, &ist->fix_sub_duration); - if (ret < 0) - return ret; - - ret = opt_match_per_stream_str(ist, &o->canvas_sizes, ic, st, &canvas_size); - if (ret < 0) - return ret; + opt_match_per_stream_int(ist, &o->fix_sub_duration, ic, st, &ist->fix_sub_duration); + opt_match_per_stream_str(ist, &o->canvas_sizes, ic, st, &canvas_size); if (canvas_size) { ret = av_parse_video_size(&par->width, &par->height, canvas_size); @@ -1537,9 +1492,7 @@ static int ist_add(const OptionsContext *o, Demuxer *d, AVStream *st, AVDictiona if (ist->st->sample_aspect_ratio.num) ist->par->sample_aspect_ratio = ist->st->sample_aspect_ratio; - ret = opt_match_per_stream_str(ist, &o->bitstream_filters, ic, st, &bsfs); - if (ret < 0) - return ret; + opt_match_per_stream_str(ist, &o->bitstream_filters, ic, st, &bsfs); if (bsfs) { ret = av_bsf_list_parse_str(bsfs, &ds->bsf); if (ret < 0) { diff --git a/fftools/ffmpeg_mux_init.c b/fftools/ffmpeg_mux_init.c index 2b3a4ddcf9..e84fa9719f 100644 --- a/fftools/ffmpeg_mux_init.c +++ b/fftools/ffmpeg_mux_init.c @@ -71,13 +71,10 @@ static int choose_encoder(const OptionsContext *o, AVFormatContext *s, { enum AVMediaType type = ost->type; const char *codec_name = NULL; - int ret; *enc = NULL; - ret = opt_match_per_stream_str(ost, &o->codec_names, s, ost->st, &codec_name); - if (ret < 0) - return ret; + opt_match_per_stream_str(ost, &o->codec_names, s, ost->st, &codec_name); if (type != AVMEDIA_TYPE_VIDEO && type != AVMEDIA_TYPE_AUDIO && @@ -419,17 +416,12 @@ static int ost_get_filters(const OptionsContext *o, AVFormatContext *oc, OutputStream *ost, char **dst) { const char *filters = NULL; - int ret; #if FFMPEG_OPT_FILTER_SCRIPT const char *filters_script = NULL; - ret = opt_match_per_stream_str(ost, &o->filter_scripts, oc, ost->st, &filters_script); - if (ret < 0) - return ret; + opt_match_per_stream_str(ost, &o->filter_scripts, oc, ost->st, &filters_script); #endif - ret = opt_match_per_stream_str(ost, &o->filters, oc, ost->st, &filters); - if (ret < 0) - return ret; + opt_match_per_stream_str(ost, &o->filters, oc, ost->st, &filters); if (!ost->enc) { if ( @@ -599,17 +591,13 @@ static int new_stream_video(Muxer *mux, const OptionsContext *o, st = ost->st; - ret = opt_match_per_stream_str(ost, &o->frame_rates, oc, st, &frame_rate); - if (ret < 0) - return ret; + opt_match_per_stream_str(ost, &o->frame_rates, oc, st, &frame_rate); if (frame_rate && av_parse_video_rate(&ost->frame_rate, frame_rate) < 0) { av_log(ost, AV_LOG_FATAL, "Invalid framerate value: %s\n", frame_rate); return AVERROR(EINVAL); } - ret = opt_match_per_stream_str(ost, &o->max_frame_rates, oc, st, &max_frame_rate); - if (ret < 0) - return ret; + opt_match_per_stream_str(ost, &o->max_frame_rates, oc, st, &max_frame_rate); if (max_frame_rate && av_parse_video_rate(&ost->max_frame_rate, max_frame_rate) < 0) { av_log(ost, AV_LOG_FATAL, "Invalid maximum framerate value: %s\n", max_frame_rate); return AVERROR(EINVAL); @@ -620,9 +608,7 @@ static int new_stream_video(Muxer *mux, const OptionsContext *o, return AVERROR(EINVAL); } - ret = opt_match_per_stream_str(ost, &o->frame_aspect_ratios, oc, st, &frame_aspect_ratio); - if (ret < 0) - return ret; + opt_match_per_stream_str(ost, &o->frame_aspect_ratios, oc, st, &frame_aspect_ratio); if (frame_aspect_ratio) { AVRational q; if (av_parse_ratio(&q, frame_aspect_ratio, 255, 0, NULL) < 0 || @@ -643,9 +629,7 @@ static int new_stream_video(Muxer *mux, const OptionsContext *o, int do_pass = 0; int i; - ret = opt_match_per_stream_str(ost, &o->frame_sizes, oc, st, &frame_size); - if (ret < 0) - return ret; + opt_match_per_stream_str(ost, &o->frame_sizes, oc, st, &frame_size); if (frame_size) { ret = av_parse_video_size(&video_enc->width, &video_enc->height, frame_size); if (ret < 0) { @@ -654,9 +638,7 @@ static int new_stream_video(Muxer *mux, const OptionsContext *o, } } - ret = opt_match_per_stream_str(ost, &o->frame_pix_fmts, oc, st, &frame_pix_fmt); - if (ret < 0) - return ret; + opt_match_per_stream_str(ost, &o->frame_pix_fmts, oc, st, &frame_pix_fmt); if (frame_pix_fmt && *frame_pix_fmt == '+') { *keep_pix_fmt = 1; if (!*++frame_pix_fmt) @@ -668,9 +650,7 @@ static int new_stream_video(Muxer *mux, const OptionsContext *o, return AVERROR(EINVAL); } - ret = opt_match_per_stream_str(ost, &o->intra_matrices, oc, st, &intra_matrix); - if (ret < 0) - return ret; + opt_match_per_stream_str(ost, &o->intra_matrices, oc, st, &intra_matrix); if (intra_matrix) { if (!(video_enc->intra_matrix = av_mallocz(sizeof(*video_enc->intra_matrix) * 64))) return AVERROR(ENOMEM); @@ -679,9 +659,7 @@ static int new_stream_video(Muxer *mux, const OptionsContext *o, if (ret < 0) return ret; } - ret = opt_match_per_stream_str(ost, &o->chroma_intra_matrices, oc, st, &chroma_intra_matrix); - if (ret < 0) - return ret; + opt_match_per_stream_str(ost, &o->chroma_intra_matrices, oc, st, &chroma_intra_matrix); if (chroma_intra_matrix) { uint16_t *p = av_mallocz(sizeof(*video_enc->chroma_intra_matrix) * 64); if (!p) @@ -691,9 +669,7 @@ static int new_stream_video(Muxer *mux, const OptionsContext *o, if (ret < 0) return ret; } - ret = opt_match_per_stream_str(ost, &o->inter_matrices, oc, st, &inter_matrix); - if (ret < 0) - return ret; + opt_match_per_stream_str(ost, &o->inter_matrices, oc, st, &inter_matrix); if (inter_matrix) { if (!(video_enc->inter_matrix = av_mallocz(sizeof(*video_enc->inter_matrix) * 64))) return AVERROR(ENOMEM); @@ -702,9 +678,7 @@ static int new_stream_video(Muxer *mux, const OptionsContext *o, return ret; } - ret = opt_match_per_stream_str(ost, &o->rc_overrides, oc, st, &p); - if (ret < 0) - return ret; + opt_match_per_stream_str(ost, &o->rc_overrides, oc, st, &p); for (i = 0; p; i++) { int start, end, q; int e = sscanf(p, "%d,%d,%d", &start, &end, &q); @@ -735,9 +709,7 @@ static int new_stream_video(Muxer *mux, const OptionsContext *o, video_enc->rc_override_count = i; /* two pass mode */ - ret = opt_match_per_stream_int(ost, &o->pass, oc, st, &do_pass); - if (ret < 0) - return ret; + opt_match_per_stream_int(ost, &o->pass, oc, st, &do_pass); if (do_pass) { if (do_pass & 1) video_enc->flags |= AV_CODEC_FLAG_PASS1; @@ -745,9 +717,7 @@ static int new_stream_video(Muxer *mux, const OptionsContext *o, video_enc->flags |= AV_CODEC_FLAG_PASS2; } - ret = opt_match_per_stream_str(ost, &o->passlogfiles, oc, st, &ost->logfile_prefix); - if (ret < 0) - return ret; + opt_match_per_stream_str(ost, &o->passlogfiles, oc, st, &ost->logfile_prefix); if (ost->logfile_prefix && !(ost->logfile_prefix = av_strdup(ost->logfile_prefix))) return AVERROR(ENOMEM); @@ -794,15 +764,11 @@ static int new_stream_video(Muxer *mux, const OptionsContext *o, } } - ret = opt_match_per_stream_int(ost, &o->force_fps, oc, st, &ost->force_fps); - if (ret < 0) - return ret; + opt_match_per_stream_int(ost, &o->force_fps, oc, st, &ost->force_fps); #if FFMPEG_OPT_TOP ost->top_field_first = -1; - ret = opt_match_per_stream_int(ost, &o->top_field_first, oc, st, &ost->top_field_first); - if (ret < 0) - return ret; + opt_match_per_stream_int(ost, &o->top_field_first, oc, st, &ost->top_field_first); if (ost->top_field_first >= 0) av_log(ost, AV_LOG_WARNING, "-top is deprecated, use the setfield filter instead\n"); #endif @@ -812,9 +778,7 @@ static int new_stream_video(Muxer *mux, const OptionsContext *o, #else *vsync_method = VSYNC_AUTO; #endif - ret = opt_match_per_stream_str(ost, &o->fps_mode, oc, st, &fps_mode); - if (ret < 0) - return ret; + opt_match_per_stream_str(ost, &o->fps_mode, oc, st, &fps_mode); if (fps_mode) { ret = parse_and_set_vsync(fps_mode, vsync_method, ost->file->index, ost->index, 0); if (ret < 0) @@ -872,40 +836,28 @@ static int new_stream_audio(Muxer *mux, const OptionsContext *o, int channels = 0; const char *layout = NULL; const char *sample_fmt = NULL; - int ret; - ret = opt_match_per_stream_int(ost, &o->audio_channels, oc, st, &channels); - if (ret < 0) - return ret; + opt_match_per_stream_int(ost, &o->audio_channels, oc, st, &channels); if (channels) { audio_enc->ch_layout.order = AV_CHANNEL_ORDER_UNSPEC; audio_enc->ch_layout.nb_channels = channels; } - ret = opt_match_per_stream_str(ost, &o->audio_ch_layouts, oc, st, &layout); - if (ret < 0) - return ret; + opt_match_per_stream_str(ost, &o->audio_ch_layouts, oc, st, &layout); if (layout && av_channel_layout_from_string(&audio_enc->ch_layout, layout) < 0) { av_log(ost, AV_LOG_FATAL, "Unknown channel layout: %s\n", layout); return AVERROR(EINVAL); } - ret = opt_match_per_stream_str(ost, &o->sample_fmts, oc, st, &sample_fmt); - if (ret < 0) - return ret; + opt_match_per_stream_str(ost, &o->sample_fmts, oc, st, &sample_fmt); if (sample_fmt && (audio_enc->sample_fmt = av_get_sample_fmt(sample_fmt)) == AV_SAMPLE_FMT_NONE) { av_log(ost, AV_LOG_FATAL, "Invalid sample format '%s'\n", sample_fmt); return AVERROR(EINVAL); } - ret = opt_match_per_stream_int(ost, &o->audio_sample_rate, oc, st, &audio_enc->sample_rate); - if (ret < 0) - return ret; - - ret = opt_match_per_stream_str(ost, &o->apad, oc, st, &ms->apad); - if (ret < 0) - return ret; + opt_match_per_stream_int(ost, &o->audio_sample_rate, oc, st, &audio_enc->sample_rate); + opt_match_per_stream_str(ost, &o->apad, oc, st, &ms->apad); } return 0; @@ -928,11 +880,8 @@ static int new_stream_subtitle(Muxer *mux, const OptionsContext *o, int input_props = 0, output_props = 0; const char *frame_size = NULL; - int ret; - ret = opt_match_per_stream_str(ost, &o->frame_sizes, mux->fc, st, &frame_size); - if (ret < 0) - return ret; + opt_match_per_stream_str(ost, &o->frame_sizes, mux->fc, st, &frame_size); if (frame_size) { int ret = av_parse_video_size(&subtitle_enc->width, &subtitle_enc->height, frame_size); if (ret < 0) { @@ -1211,13 +1160,8 @@ static int ost_add(Muxer *mux, const OptionsContext *o, enum AVMediaType type, if (ret < 0) goto fail; - ret = opt_match_per_stream_str(ost, &o->presets, oc, st, &preset); - if (ret < 0) - goto fail; - - ret = opt_match_per_stream_int(ost, &o->autoscale, oc, st, &autoscale); - if (ret < 0) - goto fail; + opt_match_per_stream_str(ost, &o->presets, oc, st, &preset); + opt_match_per_stream_int(ost, &o->autoscale, oc, st, &autoscale); if (preset && (!(ret = get_preset_file_2(preset, enc->codec->name, &s)))) { AVBPrint bprint; av_bprint_init(&bprint, 0, AV_BPRINT_SIZE_UNLIMITED); @@ -1248,14 +1192,12 @@ static int ost_add(Muxer *mux, const OptionsContext *o, enum AVMediaType type, goto fail; } - ret = opt_match_per_stream_str(ost, &o->enc_stats_pre, oc, st, &enc_stats_pre); - if (ret < 0) - goto fail; + opt_match_per_stream_str(ost, &o->enc_stats_pre, oc, st, &enc_stats_pre); if (enc_stats_pre && (type == AVMEDIA_TYPE_VIDEO || type == AVMEDIA_TYPE_AUDIO)) { const char *format = "{fidx} {sidx} {n} {t}"; - ret = opt_match_per_stream_str(ost, &o->enc_stats_pre_fmt, oc, st, &format); + opt_match_per_stream_str(ost, &o->enc_stats_pre_fmt, oc, st, &format); if (ret < 0) goto fail; @@ -1264,41 +1206,31 @@ static int ost_add(Muxer *mux, const OptionsContext *o, enum AVMediaType type, goto fail; } - ret = opt_match_per_stream_str(ost, &o->enc_stats_post, oc, st, &enc_stats_post); - if (ret < 0) - goto fail; + opt_match_per_stream_str(ost, &o->enc_stats_post, oc, st, &enc_stats_post); if (enc_stats_post && (type == AVMEDIA_TYPE_VIDEO || type == AVMEDIA_TYPE_AUDIO)) { const char *format = "{fidx} {sidx} {n} {t}"; - ret = opt_match_per_stream_str(ost, &o->enc_stats_post_fmt, oc, st, &format); - if (ret < 0) - goto fail; + opt_match_per_stream_str(ost, &o->enc_stats_post_fmt, oc, st, &format); ret = enc_stats_init(ost, &ost->enc_stats_post, 0, enc_stats_post, format); if (ret < 0) goto fail; } - ret = opt_match_per_stream_str(ost, &o->mux_stats, oc, st, &mux_stats); - if (ret < 0) - goto fail; + opt_match_per_stream_str(ost, &o->mux_stats, oc, st, &mux_stats); if (mux_stats && (type == AVMEDIA_TYPE_VIDEO || type == AVMEDIA_TYPE_AUDIO)) { const char *format = "{fidx} {sidx} {n} {t}"; - ret = opt_match_per_stream_str(ost, &o->mux_stats_fmt, oc, st, &format); - if (ret < 0) - goto fail; + opt_match_per_stream_str(ost, &o->mux_stats_fmt, oc, st, &format); ret = enc_stats_init(ost, &ms->stats, 0, mux_stats, format); if (ret < 0) goto fail; } - ret = opt_match_per_stream_str(ost, &o->enc_time_bases, oc, st, &enc_time_base); - if (ret < 0) - goto fail; + opt_match_per_stream_str(ost, &o->enc_time_bases, oc, st, &enc_time_base); if (enc_time_base && type == AVMEDIA_TYPE_SUBTITLE) av_log(ost, AV_LOG_WARNING, "-enc_time_base not supported for subtitles, ignoring\n"); @@ -1361,9 +1293,7 @@ static int ost_add(Muxer *mux, const OptionsContext *o, enum AVMediaType type, ost->bitexact = !!(ost->enc_ctx->flags & AV_CODEC_FLAG_BITEXACT); } - ret = opt_match_per_stream_str(ost, &o->time_bases, oc, st, &time_base); - if (ret < 0) - goto fail; + opt_match_per_stream_str(ost, &o->time_bases, oc, st, &time_base); if (time_base) { AVRational q; if (av_parse_ratio(&q, time_base, INT_MAX, 0, NULL) < 0 || @@ -1376,9 +1306,7 @@ static int ost_add(Muxer *mux, const OptionsContext *o, enum AVMediaType type, } ms->max_frames = INT64_MAX; - ret = opt_match_per_stream_int64(ost, &o->max_frames, oc, st, &ms->max_frames); - if (ret < 0) - return ret; + opt_match_per_stream_int64(ost, &o->max_frames, oc, st, &ms->max_frames); for (int i = 0; i < o->max_frames.nb_opt; i++) { char *p = o->max_frames.opt[i].specifier; if (!*p && type != AVMEDIA_TYPE_VIDEO) { @@ -1388,13 +1316,8 @@ static int ost_add(Muxer *mux, const OptionsContext *o, enum AVMediaType type, } ms->copy_prior_start = -1; - ret = opt_match_per_stream_int(ost, &o->copy_prior_start, oc, st, &ms->copy_prior_start); - if (ret < 0) - goto fail; - - ret = opt_match_per_stream_str(ost, &o->bitstream_filters, oc, st, &bsfs); - if (ret < 0) - goto fail; + opt_match_per_stream_int(ost, &o->copy_prior_start, oc, st, &ms->copy_prior_start); + opt_match_per_stream_str(ost, &o->bitstream_filters, oc, st, &bsfs); if (bsfs && *bsfs) { ret = av_bsf_list_parse_str(bsfs, &ms->bsf_ctx); if (ret < 0) { @@ -1403,9 +1326,7 @@ static int ost_add(Muxer *mux, const OptionsContext *o, enum AVMediaType type, } } - ret = opt_match_per_stream_str(ost, &o->codec_tags, oc, st, &codec_tag); - if (ret < 0) - goto fail; + opt_match_per_stream_str(ost, &o->codec_tags, oc, st, &codec_tag); if (codec_tag) { uint32_t tag = strtol(codec_tag, &next, 0); if (*next) { @@ -1419,9 +1340,7 @@ static int ost_add(Muxer *mux, const OptionsContext *o, enum AVMediaType type, ost->enc_ctx->codec_tag = tag; } - ret = opt_match_per_stream_dbl(ost, &o->qscale, oc, st, &qscale); - if (ret < 0) - return ret; + opt_match_per_stream_dbl(ost, &o->qscale, oc, st, &qscale); if (ost->enc_ctx && qscale >= 0) { ost->enc_ctx->flags |= AV_CODEC_FLAG_QSCALE; ost->enc_ctx->global_quality = FF_QP2LAMBDA * qscale; @@ -1431,38 +1350,26 @@ static int ost_add(Muxer *mux, const OptionsContext *o, enum AVMediaType type, int max_muxing_queue_size = 128; int muxing_queue_data_threshold = 50 * 1024 * 1024; - ret = opt_match_per_stream_int(ost, &o->max_muxing_queue_size, oc, st, - &max_muxing_queue_size); - if (ret < 0) - goto fail; - - ret = opt_match_per_stream_int(ost, &o->muxing_queue_data_threshold, - oc, st, &muxing_queue_data_threshold); - if (ret < 0) - goto fail; + opt_match_per_stream_int(ost, &o->max_muxing_queue_size, oc, st, + &max_muxing_queue_size); + opt_match_per_stream_int(ost, &o->muxing_queue_data_threshold, + oc, st, &muxing_queue_data_threshold); sch_mux_stream_buffering(mux->sch, mux->sch_idx, ms->sch_idx, max_muxing_queue_size, muxing_queue_data_threshold); } - ret = opt_match_per_stream_int(ost, &o->bits_per_raw_sample, oc, st, + opt_match_per_stream_int(ost, &o->bits_per_raw_sample, oc, st, &ost->bits_per_raw_sample); - if (ret < 0) - goto fail; - ret = opt_match_per_stream_int(ost, &o->fix_sub_duration_heartbeat, - oc, st, &ost->fix_sub_duration_heartbeat); - if (ret < 0) - goto fail; + opt_match_per_stream_int(ost, &o->fix_sub_duration_heartbeat, + oc, st, &ost->fix_sub_duration_heartbeat); if (oc->oformat->flags & AVFMT_GLOBALHEADER && ost->enc_ctx) ost->enc_ctx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER; - ret = opt_match_per_stream_int(ost, &o->copy_initial_nonkeyframes, - oc, st, &ms->copy_initial_nonkeyframes); - if (ret < 0) - goto fail; - + opt_match_per_stream_int(ost, &o->copy_initial_nonkeyframes, + oc, st, &ms->copy_initial_nonkeyframes); switch (type) { case AVMEDIA_TYPE_VIDEO: ret = new_stream_video (mux, o, ost, &keep_pix_fmt, &vsync_method); break; case AVMEDIA_TYPE_AUDIO: ret = new_stream_audio (mux, o, ost); break; @@ -3036,9 +2943,7 @@ static int set_dispositions(Muxer *mux, const OptionsContext *o) nb_streams[ost->type + 1]++; - ret = opt_match_per_stream_str(ost, &o->disposition, ctx, ost->st, &dispositions[i]); - if (ret < 0) - goto finish; + opt_match_per_stream_str(ost, &o->disposition, ctx, ost->st, &dispositions[i]); have_manual |= !!dispositions[i]; @@ -3183,12 +3088,9 @@ static int process_forced_keyframes(Muxer *mux, const OptionsContext *o) for (int i = 0; i < mux->of.nb_streams; i++) { OutputStream *ost = mux->of.streams[i]; const char *forced_keyframes = NULL; - int ret; - ret = opt_match_per_stream_str(ost, &o->forced_key_frames, - mux->fc, ost->st, &forced_keyframes); - if (ret < 0) - return ret; + opt_match_per_stream_str(ost, &o->forced_key_frames, + mux->fc, ost->st, &forced_keyframes); if (!(ost->type == AVMEDIA_TYPE_VIDEO && ost->enc_ctx && forced_keyframes)) diff --git a/fftools/ffmpeg_opt.c b/fftools/ffmpeg_opt.c index c32d3ddc55..f6df6ae952 100644 --- a/fftools/ffmpeg_opt.c +++ b/fftools/ffmpeg_opt.c @@ -101,6 +101,8 @@ static void uninit_options(OptionsContext *o) SpecifierOptList *so = dst; for (int i = 0; i < so->nb_opt; i++) { av_freep(&so->opt[i].specifier); + if (po->flags & OPT_FLAG_PERSTREAM) + stream_specifier_uninit(&so->opt[i].stream_spec); if (po->type == OPT_TYPE_STRING) av_freep(&so->opt[i].u.str); } @@ -164,22 +166,21 @@ const char *opt_match_per_type_str(const SpecifierOptList *sol, return NULL; } -static int opt_match_per_stream(void *logctx, enum OptionType type, - const SpecifierOptList *sol, - AVFormatContext *fc, AVStream *st) +static unsigned opt_match_per_stream(void *logctx, enum OptionType type, + const SpecifierOptList *sol, + AVFormatContext *fc, AVStream *st) { int matches = 0, match_idx = -1; av_assert0((type == sol->type) || !sol->nb_opt); for (int i = 0; i < sol->nb_opt; i++) { - const char *spec = sol->opt[i].specifier; - int ret = check_stream_specifier(fc, st, spec); - if (ret > 0) { + const StreamSpecifier *ss = &sol->opt[i].stream_spec; + + if (stream_specifier_match(ss, fc, st, logctx)) { match_idx = i; matches++; - } else if (ret < 0) - return ret; + } } if (matches > 1 && sol->opt_canon) { @@ -216,17 +217,12 @@ static int opt_match_per_stream(void *logctx, enum OptionType type, } #define OPT_MATCH_PER_STREAM(name, type, opt_type, m) \ -int opt_match_per_stream_ ## name(void *logctx, const SpecifierOptList *sol, \ - AVFormatContext *fc, AVStream *st, type *out) \ +void opt_match_per_stream_ ## name(void *logctx, const SpecifierOptList *sol, \ + AVFormatContext *fc, AVStream *st, type *out) \ { \ - int ret = opt_match_per_stream(logctx, opt_type, sol, fc, st); \ - \ - if (ret <= 0) \ - return ret; \ - \ - *out = sol->opt[ret - 1].u.m; \ - \ - return 0; \ + unsigned ret = opt_match_per_stream(logctx, opt_type, sol, fc, st); \ + if (ret > 0) \ + *out = sol->opt[ret - 1].u.m; \ } OPT_MATCH_PER_STREAM(str, const char *, OPT_TYPE_STRING, str);