From patchwork Mon Dec 18 09:57:12 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Khirnov X-Patchwork-Id: 45217 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:1225:b0:181:818d:5e7f with SMTP id v37csp7222405pzf; Mon, 18 Dec 2023 02:00:05 -0800 (PST) X-Google-Smtp-Source: AGHT+IGXG6WfU66FQe3eAr7lXFpxVLSx1S9erJuPCouxG/+DOiTD/eOww/dgRRgl4XFxMcpLTyAS X-Received: by 2002:a50:aa94:0:b0:553:7945:c40d with SMTP id q20-20020a50aa94000000b005537945c40dmr9051edc.46.1702893604830; Mon, 18 Dec 2023 02:00:04 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1702893604; cv=none; d=google.com; s=arc-20160816; b=ccdbGskrtErDrd1sklqSckXNoJC0BmCbH9OMWRfxf1aHKFLrepizejK7bOqAnYE2JW PYJpQFYc2RqvIdjgAfuW5ZhKbIK4MB0EBf9D5T/wpcpzlzd8t1aZ1Sp9E+Q2HilBtXS1 6J95GJEPkxyehu5WFbNfTkFmGeN6RmUpJp+DT+LFXjXtdUXAp3C/KmAG9FWn6yd5fx8N bakZ3iEgTBxxnAS4DRSzrD/GOF7smw+l5nIFoDycxb/+8Z3XCamjn3q0MhT7MINiEOQM IC6GjKvE2GkPwV0d1pMbVXsAa850DyP0dwei+YifbPodR/lDXWEctpuBYkXVJ9rzB/fK UXDA== 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:delivered-to; bh=paKKt7B0SkH26kTSK3Vnp9Ts2s8rPPfhbb7+ysOjuOs=; fh=YOA8vD9MJZuwZ71F/05pj6KdCjf6jQRmzLS+CATXUQk=; b=Z4FIna0PsHtWaapB4iTzbgdER2LTvZqc23z9HS3xvDhMcQuT7afbnWklJaiTGQLkCn SLSZINy9O4t3kPk7ELLYb7VVco1CrCz+7skF3o71nNO3KFCY+t3REn3LiKk0KAtnye3D br1NmdDBRA9xnGr2VYi3Ra+CPUuXI3sP97y7pxWNJUY6SrhXYHu6yFPCSJumWug7OAMt zvfZ7eX9/rS7oKRWxjL34IKySuyV8bAhcQWcN6du6u1WmTUxJ12ITIgM9BRJ6xZHQvjd yiHXDg4CR4gLzJuvgUctGaQx31lXunbZBG8Xao1GesUDADZV6zm+Lko23cn1LpYSama8 xYEg== ARC-Authentication-Results: i=1; mx.google.com; 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 v25-20020a50a459000000b0054c4523f740si9710700edb.491.2023.12.18.02.00.04; Mon, 18 Dec 2023 02:00:04 -0800 (PST) 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; 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 80DEB68D2BC; Mon, 18 Dec 2023 11:58:15 +0200 (EET) 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 9A61368D204 for ; Mon, 18 Dec 2023 11:57:58 +0200 (EET) Received: from localhost (mail1.khirnov.net [IPv6:::1]) by mail1.khirnov.net (Postfix) with ESMTP id 053B51783 for ; Mon, 18 Dec 2023 10:57:55 +0100 (CET) Received: from mail1.khirnov.net ([IPv6:::1]) by localhost (mail1.khirnov.net [IPv6:::1]) (amavis, port 10024) with ESMTP id P7uh3DDz7g3f for ; Mon, 18 Dec 2023 10:57:54 +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 mail1.khirnov.net (Postfix) with ESMTPS id 75C941BA1 for ; Mon, 18 Dec 2023 10:57:51 +0100 (CET) Received: from libav.khirnov.net (libav.khirnov.net [IPv6:::1]) by libav.khirnov.net (Postfix) with ESMTP id 5FA1B3A07C3 for ; Mon, 18 Dec 2023 10:57:44 +0100 (CET) From: Anton Khirnov To: ffmpeg-devel@ffmpeg.org Date: Mon, 18 Dec 2023 10:57:12 +0100 Message-ID: <20231218095722.25879-10-anton@khirnov.net> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20231218095722.25879-1-anton@khirnov.net> References: <20231218095722.25879-1-anton@khirnov.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 10/20] fftools/cmdutils: add a struct for a list of SpecifierOpt 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: K5wiRS5WoDIK Significantly simplifies the code dealing with OPT_SPEC. --- fftools/cmdutils.c | 10 +- fftools/cmdutils.h | 9 +- fftools/ffmpeg.h | 197 +++++++++++++------------------------- fftools/ffmpeg_demux.c | 30 +++--- fftools/ffmpeg_mux_init.c | 32 +++---- fftools/ffmpeg_opt.c | 13 ++- 6 files changed, 115 insertions(+), 176 deletions(-) diff --git a/fftools/cmdutils.c b/fftools/cmdutils.c index a52c7c5ae4..f53c4b7aec 100644 --- a/fftools/cmdutils.c +++ b/fftools/cmdutils.c @@ -239,25 +239,23 @@ static int write_option(void *optctx, const OptionDef *po, const char *opt, * a global var*/ void *dst = po->flags & OPT_FLAG_OFFSET ? (uint8_t *)optctx + po->u.off : po->u.dst_ptr; - int *dstcount; double num; int ret; if (po->flags & OPT_FLAG_SPEC) { - SpecifierOpt **so = dst; + SpecifierOptList *sol = dst; char *p = strchr(opt, ':'); char *str; - dstcount = (int *)(so + 1); - ret = grow_array((void**)so, sizeof(**so), dstcount, *dstcount + 1); + ret = GROW_ARRAY(sol->opt, sol->nb_opt); if (ret < 0) return ret; str = av_strdup(p ? p + 1 : ""); if (!str) return AVERROR(ENOMEM); - (*so)[*dstcount - 1].specifier = str; - dst = &(*so)[*dstcount - 1].u; + sol->opt[sol->nb_opt - 1].specifier = str; + dst = &sol->opt[sol->nb_opt - 1].u; } if (po->type == OPT_TYPE_STRING) { diff --git a/fftools/cmdutils.h b/fftools/cmdutils.h index dc99573d80..8ef9a07e9e 100644 --- a/fftools/cmdutils.h +++ b/fftools/cmdutils.h @@ -114,6 +114,11 @@ typedef struct SpecifierOpt { } u; } SpecifierOpt; +typedef struct SpecifierOptList { + SpecifierOpt *opt; + int nb_opt; +} SpecifierOptList; + typedef struct OptionDef { const char *name; enum OptionType type; @@ -145,9 +150,7 @@ typedef struct OptionDef { #define OPT_FLAG_OFFSET (1 << 8) #define OPT_OFFSET (OPT_FLAG_OFFSET | OPT_PERFILE) -/* Option is to be stored in an array of SpecifierOpt. - Next element after the offset is an int containing element count in the - array. +/* Option is to be stored in a SpecifierOptList. Always use as OPT_SPEC in option definitions. */ #define OPT_FLAG_SPEC (1 << 9) #define OPT_SPEC (OPT_FLAG_SPEC | OPT_OFFSET) diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h index 33a29b316f..94f70f7efb 100644 --- a/fftools/ffmpeg.h +++ b/fftools/ffmpeg.h @@ -138,22 +138,14 @@ typedef struct OptionsContext { int seek_timestamp; const char *format; - SpecifierOpt *codec_names; - int nb_codec_names; - SpecifierOpt *audio_ch_layouts; - int nb_audio_ch_layouts; - SpecifierOpt *audio_channels; - int nb_audio_channels; - SpecifierOpt *audio_sample_rate; - int nb_audio_sample_rate; - SpecifierOpt *frame_rates; - int nb_frame_rates; - SpecifierOpt *max_frame_rates; - int nb_max_frame_rates; - SpecifierOpt *frame_sizes; - int nb_frame_sizes; - SpecifierOpt *frame_pix_fmts; - int nb_frame_pix_fmts; + SpecifierOptList codec_names; + SpecifierOptList audio_ch_layouts; + SpecifierOptList audio_channels; + SpecifierOptList audio_sample_rate; + SpecifierOptList frame_rates; + SpecifierOptList max_frame_rates; + SpecifierOptList frame_sizes; + SpecifierOptList frame_pix_fmts; /* input options */ int64_t input_ts_offset; @@ -166,18 +158,12 @@ typedef struct OptionsContext { int input_sync_ref; int find_stream_info; - SpecifierOpt *ts_scale; - int nb_ts_scale; - SpecifierOpt *dump_attachment; - int nb_dump_attachment; - SpecifierOpt *hwaccels; - int nb_hwaccels; - SpecifierOpt *hwaccel_devices; - int nb_hwaccel_devices; - SpecifierOpt *hwaccel_output_formats; - int nb_hwaccel_output_formats; - SpecifierOpt *autorotate; - int nb_autorotate; + SpecifierOptList ts_scale; + SpecifierOptList dump_attachment; + SpecifierOptList hwaccels; + SpecifierOptList hwaccel_devices; + SpecifierOptList hwaccel_output_formats; + SpecifierOptList autorotate; /* output options */ StreamMap *stream_maps; @@ -208,102 +194,55 @@ typedef struct OptionsContext { // keys are stream indices AVDictionary *streamid; - SpecifierOpt *metadata; - int nb_metadata; - SpecifierOpt *max_frames; - int nb_max_frames; - SpecifierOpt *bitstream_filters; - int nb_bitstream_filters; - SpecifierOpt *codec_tags; - int nb_codec_tags; - SpecifierOpt *sample_fmts; - int nb_sample_fmts; - SpecifierOpt *qscale; - int nb_qscale; - SpecifierOpt *forced_key_frames; - int nb_forced_key_frames; - SpecifierOpt *fps_mode; - int nb_fps_mode; - SpecifierOpt *force_fps; - int nb_force_fps; - SpecifierOpt *frame_aspect_ratios; - int nb_frame_aspect_ratios; - SpecifierOpt *display_rotations; - int nb_display_rotations; - SpecifierOpt *display_hflips; - int nb_display_hflips; - SpecifierOpt *display_vflips; - int nb_display_vflips; - SpecifierOpt *rc_overrides; - int nb_rc_overrides; - SpecifierOpt *intra_matrices; - int nb_intra_matrices; - SpecifierOpt *inter_matrices; - int nb_inter_matrices; - SpecifierOpt *chroma_intra_matrices; - int nb_chroma_intra_matrices; + SpecifierOptList metadata; + SpecifierOptList max_frames; + SpecifierOptList bitstream_filters; + SpecifierOptList codec_tags; + SpecifierOptList sample_fmts; + SpecifierOptList qscale; + SpecifierOptList forced_key_frames; + SpecifierOptList fps_mode; + SpecifierOptList force_fps; + SpecifierOptList frame_aspect_ratios; + SpecifierOptList display_rotations; + SpecifierOptList display_hflips; + SpecifierOptList display_vflips; + SpecifierOptList rc_overrides; + SpecifierOptList intra_matrices; + SpecifierOptList inter_matrices; + SpecifierOptList chroma_intra_matrices; #if FFMPEG_OPT_TOP - SpecifierOpt *top_field_first; - int nb_top_field_first; + SpecifierOptList top_field_first; #endif - SpecifierOpt *metadata_map; - int nb_metadata_map; - SpecifierOpt *presets; - int nb_presets; - SpecifierOpt *copy_initial_nonkeyframes; - int nb_copy_initial_nonkeyframes; - SpecifierOpt *copy_prior_start; - int nb_copy_prior_start; - SpecifierOpt *filters; - int nb_filters; - SpecifierOpt *filter_scripts; - int nb_filter_scripts; - SpecifierOpt *reinit_filters; - int nb_reinit_filters; - SpecifierOpt *fix_sub_duration; - int nb_fix_sub_duration; - SpecifierOpt *fix_sub_duration_heartbeat; - int nb_fix_sub_duration_heartbeat; - SpecifierOpt *canvas_sizes; - int nb_canvas_sizes; - SpecifierOpt *pass; - int nb_pass; - SpecifierOpt *passlogfiles; - int nb_passlogfiles; - SpecifierOpt *max_muxing_queue_size; - int nb_max_muxing_queue_size; - SpecifierOpt *muxing_queue_data_threshold; - int nb_muxing_queue_data_threshold; - SpecifierOpt *guess_layout_max; - int nb_guess_layout_max; - SpecifierOpt *apad; - int nb_apad; - SpecifierOpt *discard; - int nb_discard; - SpecifierOpt *disposition; - int nb_disposition; - SpecifierOpt *program; - int nb_program; - SpecifierOpt *time_bases; - int nb_time_bases; - SpecifierOpt *enc_time_bases; - int nb_enc_time_bases; - SpecifierOpt *autoscale; - int nb_autoscale; - SpecifierOpt *bits_per_raw_sample; - int nb_bits_per_raw_sample; - SpecifierOpt *enc_stats_pre; - int nb_enc_stats_pre; - SpecifierOpt *enc_stats_post; - int nb_enc_stats_post; - SpecifierOpt *mux_stats; - int nb_mux_stats; - SpecifierOpt *enc_stats_pre_fmt; - int nb_enc_stats_pre_fmt; - SpecifierOpt *enc_stats_post_fmt; - int nb_enc_stats_post_fmt; - SpecifierOpt *mux_stats_fmt; - int nb_mux_stats_fmt; + SpecifierOptList metadata_map; + SpecifierOptList presets; + SpecifierOptList copy_initial_nonkeyframes; + SpecifierOptList copy_prior_start; + SpecifierOptList filters; + SpecifierOptList filter_scripts; + SpecifierOptList reinit_filters; + SpecifierOptList fix_sub_duration; + SpecifierOptList fix_sub_duration_heartbeat; + SpecifierOptList canvas_sizes; + SpecifierOptList pass; + SpecifierOptList passlogfiles; + SpecifierOptList max_muxing_queue_size; + SpecifierOptList muxing_queue_data_threshold; + SpecifierOptList guess_layout_max; + SpecifierOptList apad; + SpecifierOptList discard; + SpecifierOptList disposition; + SpecifierOptList program; + SpecifierOptList time_bases; + SpecifierOptList enc_time_bases; + SpecifierOptList autoscale; + SpecifierOptList bits_per_raw_sample; + SpecifierOptList enc_stats_pre; + SpecifierOptList enc_stats_post; + SpecifierOptList mux_stats; + SpecifierOptList enc_stats_pre_fmt; + SpecifierOptList enc_stats_post_fmt; + SpecifierOptList mux_stats_fmt; } OptionsContext; typedef struct InputFilter { @@ -850,11 +789,11 @@ void update_benchmark(const char *fmt, ...); {\ int _ret, _matches = 0;\ SpecifierOpt *so;\ - for (int _i = 0; _i < o->nb_ ## name; _i++) {\ - char *spec = o->name[_i].specifier;\ + for (int _i = 0; _i < o->name.nb_opt; _i++) {\ + char *spec = o->name.opt[_i].specifier;\ if ((_ret = check_stream_specifier(fmtctx, st, spec)) > 0) {\ - outvar = o->name[_i].u.type;\ - so = &o->name[_i];\ + outvar = o->name.opt[_i].u.type;\ + so = &o->name.opt[_i];\ _matches++;\ } else if (_ret < 0)\ return _ret;\ @@ -866,10 +805,10 @@ void update_benchmark(const char *fmt, ...); #define MATCH_PER_TYPE_OPT(name, type, outvar, fmtctx, mediatype)\ {\ int i;\ - for (i = 0; i < o->nb_ ## name; i++) {\ - char *spec = o->name[i].specifier;\ + for (i = 0; i < o->name.nb_opt; i++) {\ + char *spec = o->name.opt[i].specifier;\ if (!strcmp(spec, mediatype))\ - outvar = o->name[i].u.type;\ + outvar = o->name.opt[i].u.type;\ }\ } diff --git a/fftools/ffmpeg_demux.c b/fftools/ffmpeg_demux.c index eca3de709c..6672113bca 100644 --- a/fftools/ffmpeg_demux.c +++ b/fftools/ffmpeg_demux.c @@ -1389,28 +1389,28 @@ int ifile_open(const OptionsContext *o, const char *filename, Scheduler *sch) ic = avformat_alloc_context(); if (!ic) return AVERROR(ENOMEM); - if (o->nb_audio_sample_rate) { - av_dict_set_int(&o->g->format_opts, "sample_rate", o->audio_sample_rate[o->nb_audio_sample_rate - 1].u.i, 0); + if (o->audio_sample_rate.nb_opt) { + av_dict_set_int(&o->g->format_opts, "sample_rate", o->audio_sample_rate.opt[o->audio_sample_rate.nb_opt - 1].u.i, 0); } - if (o->nb_audio_channels) { + if (o->audio_channels.nb_opt) { const AVClass *priv_class; if (file_iformat && (priv_class = file_iformat->priv_class) && av_opt_find(&priv_class, "ch_layout", NULL, 0, AV_OPT_SEARCH_FAKE_OBJ)) { char buf[32]; - snprintf(buf, sizeof(buf), "%dC", o->audio_channels[o->nb_audio_channels - 1].u.i); + snprintf(buf, sizeof(buf), "%dC", o->audio_channels.opt[o->audio_channels.nb_opt - 1].u.i); av_dict_set(&o->g->format_opts, "ch_layout", buf, 0); } } - if (o->nb_audio_ch_layouts) { + if (o->audio_ch_layouts.nb_opt) { const AVClass *priv_class; if (file_iformat && (priv_class = file_iformat->priv_class) && av_opt_find(&priv_class, "ch_layout", NULL, 0, AV_OPT_SEARCH_FAKE_OBJ)) { - av_dict_set(&o->g->format_opts, "ch_layout", o->audio_ch_layouts[o->nb_audio_ch_layouts - 1].u.str, 0); + av_dict_set(&o->g->format_opts, "ch_layout", o->audio_ch_layouts.opt[o->audio_ch_layouts.nb_opt - 1].u.str, 0); } } - if (o->nb_frame_rates) { + if (o->frame_rates.nb_opt) { const AVClass *priv_class; /* set the format-level framerate option; * this is important for video grabbers, e.g. x11 */ @@ -1418,14 +1418,14 @@ int ifile_open(const OptionsContext *o, const char *filename, Scheduler *sch) av_opt_find(&priv_class, "framerate", NULL, 0, AV_OPT_SEARCH_FAKE_OBJ)) { av_dict_set(&o->g->format_opts, "framerate", - o->frame_rates[o->nb_frame_rates - 1].u.str, 0); + o->frame_rates.opt[o->frame_rates.nb_opt - 1].u.str, 0); } } - if (o->nb_frame_sizes) { - av_dict_set(&o->g->format_opts, "video_size", o->frame_sizes[o->nb_frame_sizes - 1].u.str, 0); + if (o->frame_sizes.nb_opt) { + av_dict_set(&o->g->format_opts, "video_size", o->frame_sizes.opt[o->frame_sizes.nb_opt - 1].u.str, 0); } - if (o->nb_frame_pix_fmts) - av_dict_set(&o->g->format_opts, "pixel_format", o->frame_pix_fmts[o->nb_frame_pix_fmts - 1].u.str, 0); + if (o->frame_pix_fmts.nb_opt) + av_dict_set(&o->g->format_opts, "pixel_format", o->frame_pix_fmts.opt[o->frame_pix_fmts.nb_opt - 1].u.str, 0); MATCH_PER_TYPE_OPT(codec_names, str, video_codec_name, ic, "v"); MATCH_PER_TYPE_OPT(codec_names, str, audio_codec_name, ic, "a"); @@ -1649,14 +1649,14 @@ int ifile_open(const OptionsContext *o, const char *filename, Scheduler *sch) } av_dict_free(&unused_opts); - for (i = 0; i < o->nb_dump_attachment; i++) { + for (i = 0; i < o->dump_attachment.nb_opt; i++) { int j; for (j = 0; j < f->nb_streams; j++) { InputStream *ist = f->streams[j]; - if (check_stream_specifier(ic, ist->st, o->dump_attachment[i].specifier) == 1) { - ret = dump_attachment(ist, o->dump_attachment[i].u.str); + if (check_stream_specifier(ic, ist->st, o->dump_attachment.opt[i].specifier) == 1) { + ret = dump_attachment(ist, o->dump_attachment.opt[i].u.str); if (ret < 0) return ret; } diff --git a/fftools/ffmpeg_mux_init.c b/fftools/ffmpeg_mux_init.c index 52eca9f9d5..6e6e8b8b6a 100644 --- a/fftools/ffmpeg_mux_init.c +++ b/fftools/ffmpeg_mux_init.c @@ -1362,8 +1362,8 @@ static int ost_add(Muxer *mux, const OptionsContext *o, enum AVMediaType type, ms->max_frames = INT64_MAX; MATCH_PER_STREAM_OPT(max_frames, i64, ms->max_frames, oc, st); - for (i = 0; inb_max_frames; i++) { - char *p = o->max_frames[i].specifier; + for (i = 0; i < o->max_frames.nb_opt; i++) { + char *p = o->max_frames.opt[i].specifier; if (!*p && type != AVMEDIA_TYPE_VIDEO) { av_log(ost, AV_LOG_WARNING, "Applying unspecific -frames to non video streams, maybe you meant -vframes ?\n"); break; @@ -2018,17 +2018,17 @@ static int of_add_programs(Muxer *mux, const OptionsContext *o) { AVFormatContext *oc = mux->fc; /* process manually set programs */ - for (int i = 0; i < o->nb_program; i++) { + for (int i = 0; i < o->program.nb_opt; i++) { AVDictionary *dict = NULL; const AVDictionaryEntry *e; AVProgram *program; int ret, progid = i + 1; - ret = av_dict_parse_string(&dict, o->program[i].u.str, "=", ":", + ret = av_dict_parse_string(&dict, o->program.opt[i].u.str, "=", ":", AV_DICT_MULTIKEY); if (ret < 0) { av_log(mux, AV_LOG_ERROR, "Error parsing program specification %s\n", - o->program[i].u.str); + o->program.opt[i].u.str); return ret; } @@ -2116,21 +2116,21 @@ static int parse_meta_type(void *logctx, const char *arg, static int of_add_metadata(OutputFile *of, AVFormatContext *oc, const OptionsContext *o) { - for (int i = 0; i < o->nb_metadata; i++) { + for (int i = 0; i < o->metadata.nb_opt; i++) { AVDictionary **m; char type, *val; const char *stream_spec; int index = 0, ret = 0; - val = strchr(o->metadata[i].u.str, '='); + val = strchr(o->metadata.opt[i].u.str, '='); if (!val) { av_log(of, AV_LOG_FATAL, "No '=' character in metadata string %s.\n", - o->metadata[i].u.str); + o->metadata.opt[i].u.str); return AVERROR(EINVAL); } *val++ = 0; - ret = parse_meta_type(of, o->metadata[i].specifier, &type, &index, &stream_spec); + ret = parse_meta_type(of, o->metadata.opt[i].specifier, &type, &index, &stream_spec); if (ret < 0) return ret; @@ -2139,7 +2139,7 @@ static int of_add_metadata(OutputFile *of, AVFormatContext *oc, OutputStream *ost = of->streams[j]; if ((ret = check_stream_specifier(oc, oc->streams[j], stream_spec)) > 0) { #if FFMPEG_ROTATION_METADATA - if (!strcmp(o->metadata[i].u.str, "rotate")) { + if (!strcmp(o->metadata.opt[i].u.str, "rotate")) { char *tail; double theta = av_strtod(val, &tail); if (!*tail) { @@ -2154,7 +2154,7 @@ static int of_add_metadata(OutputFile *of, AVFormatContext *oc, "instead."); } else { #endif - av_dict_set(&oc->streams[j]->metadata, o->metadata[i].u.str, *val ? val : NULL, 0); + av_dict_set(&oc->streams[j]->metadata, o->metadata.opt[i].u.str, *val ? val : NULL, 0); #if FFMPEG_ROTATION_METADATA } #endif @@ -2181,10 +2181,10 @@ static int of_add_metadata(OutputFile *of, AVFormatContext *oc, m = &oc->programs[index]->metadata; break; default: - av_log(of, AV_LOG_FATAL, "Invalid metadata specifier %s.\n", o->metadata[i].specifier); + av_log(of, AV_LOG_FATAL, "Invalid metadata specifier %s.\n", o->metadata.opt[i].specifier); return AVERROR(EINVAL); } - av_dict_set(m, o->metadata[i].u.str, *val ? val : NULL, 0); + av_dict_set(m, o->metadata.opt[i].u.str, *val ? val : NULL, 0); } } @@ -2332,9 +2332,9 @@ static int copy_meta(Muxer *mux, const OptionsContext *o) int ret; /* copy metadata */ - for (int i = 0; i < o->nb_metadata_map; i++) { + for (int i = 0; i < o->metadata_map.nb_opt; i++) { char *p; - int in_file_index = strtol(o->metadata_map[i].u.str, &p, 0); + int in_file_index = strtol(o->metadata_map.opt[i].u.str, &p, 0); if (in_file_index >= nb_input_files) { av_log(mux, AV_LOG_FATAL, "Invalid input file index %d while " @@ -2343,7 +2343,7 @@ static int copy_meta(Muxer *mux, const OptionsContext *o) } ret = copy_metadata(mux, in_file_index >= 0 ? input_files[in_file_index]->ctx : NULL, - o->metadata_map[i].specifier, *p ? p + 1 : p, + o->metadata_map.opt[i].specifier, *p ? p + 1 : p, &metadata_global_manual, &metadata_streams_manual, &metadata_chapters_manual); if (ret < 0) diff --git a/fftools/ffmpeg_opt.c b/fftools/ffmpeg_opt.c index 6f997a803a..653f62770e 100644 --- a/fftools/ffmpeg_opt.c +++ b/fftools/ffmpeg_opt.c @@ -110,15 +110,14 @@ static void uninit_options(OptionsContext *o) void *dst = (uint8_t*)o + po->u.off; if (po->flags & OPT_FLAG_SPEC) { - SpecifierOpt **so = dst; - int i, *count = (int*)(so + 1); - for (i = 0; i < *count; i++) { - av_freep(&(*so)[i].specifier); + SpecifierOptList *so = dst; + for (int i = 0; i < so->nb_opt; i++) { + av_freep(&so->opt[i].specifier); if (po->type == OPT_TYPE_STRING) - av_freep(&(*so)[i].u.str); + av_freep(&so->opt[i].u.str); } - av_freep(so); - *count = 0; + av_freep(&so->opt); + so->nb_opt = 0; } else if (po->flags & OPT_FLAG_OFFSET && po->type == OPT_TYPE_STRING) av_freep(dst); po++;