forked from FFmpeg/FFmpeg
fftools/cmdutils: add a struct for a list of SpecifierOpt
Significantly simplifies the code dealing with OPT_SPEC.
This commit is contained in:
parent
5792382269
commit
0ba70a6792
6 changed files with 118 additions and 180 deletions
|
@ -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) {
|
||||
|
|
|
@ -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)
|
||||
|
|
200
fftools/ffmpeg.h
200
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,104 +194,56 @@ 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 *stream_groups;
|
||||
int nb_stream_groups;
|
||||
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 stream_groups;
|
||||
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 {
|
||||
|
@ -852,11 +790,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;\
|
||||
|
@ -868,10 +806,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;\
|
||||
}\
|
||||
}
|
||||
|
||||
|
|
|
@ -1388,28 +1388,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 */
|
||||
|
@ -1417,14 +1417,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");
|
||||
|
@ -1648,14 +1648,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;
|
||||
}
|
||||
|
|
|
@ -1363,8 +1363,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; i<o->nb_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;
|
||||
|
@ -2334,12 +2334,12 @@ end:
|
|||
static int of_add_groups(Muxer *mux, const OptionsContext *o)
|
||||
{
|
||||
/* process manually set groups */
|
||||
for (int i = 0; i < o->nb_stream_groups; i++) {
|
||||
for (int i = 0; i < o->stream_groups.nb_opt; i++) {
|
||||
const char *token;
|
||||
char *str, *ptr = NULL;
|
||||
int ret = 0;
|
||||
|
||||
str = av_strdup(o->stream_groups[i].u.str);
|
||||
str = av_strdup(o->stream_groups.opt[i].u.str);
|
||||
if (!str)
|
||||
return ret;
|
||||
|
||||
|
@ -2359,17 +2359,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;
|
||||
}
|
||||
|
||||
|
@ -2457,21 +2457,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;
|
||||
|
||||
|
@ -2480,7 +2480,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) {
|
||||
|
@ -2495,7 +2495,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
|
||||
|
@ -2522,10 +2522,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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2673,9 +2673,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 "
|
||||
|
@ -2684,7 +2684,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)
|
||||
|
|
|
@ -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++;
|
||||
|
|
Loading…
Add table
Reference in a new issue