Commit 039267f1 authored by Anton Khirnov's avatar Anton Khirnov

avconv: move metadata to options context.

It is now possible to set metadata on streams and chapters.
parent 33f75d72
...@@ -145,7 +145,6 @@ static float mux_preload= 0.5; ...@@ -145,7 +145,6 @@ static float mux_preload= 0.5;
static float mux_max_delay= 0.7; static float mux_max_delay= 0.7;
static int file_overwrite = 0; static int file_overwrite = 0;
static AVDictionary *metadata;
static int do_benchmark = 0; static int do_benchmark = 0;
static int do_hex_dump = 0; static int do_hex_dump = 0;
static int do_pkt_dump = 0; static int do_pkt_dump = 0;
...@@ -324,6 +323,9 @@ typedef struct OptionsContext { ...@@ -324,6 +323,9 @@ typedef struct OptionsContext {
int64_t recording_time; int64_t recording_time;
uint64_t limit_filesize; uint64_t limit_filesize;
SpecifierOpt *metadata;
int nb_metadata;
} OptionsContext; } OptionsContext;
#define MATCH_PER_STREAM_OPT(name, type, outvar, fmtctx, st)\ #define MATCH_PER_STREAM_OPT(name, type, outvar, fmtctx, st)\
...@@ -2552,21 +2554,6 @@ static int opt_frame_aspect_ratio(const char *opt, const char *arg) ...@@ -2552,21 +2554,6 @@ static int opt_frame_aspect_ratio(const char *opt, const char *arg)
return 0; return 0;
} }
static int opt_metadata(const char *opt, const char *arg)
{
char *mid= strchr(arg, '=');
if(!mid){
fprintf(stderr, "Missing =\n");
exit_program(1);
}
*mid++= 0;
av_dict_set(&metadata, arg, mid, 0);
return 0;
}
static int opt_qscale(const char *opt, const char *arg) static int opt_qscale(const char *opt, const char *arg)
{ {
video_qscale = parse_number_or_die(opt, arg, OPT_FLOAT, 0, 255); video_qscale = parse_number_or_die(opt, arg, OPT_FLOAT, 0, 255);
...@@ -2735,7 +2722,7 @@ static int opt_map(OptionsContext *o, const char *opt, const char *arg) ...@@ -2735,7 +2722,7 @@ static int opt_map(OptionsContext *o, const char *opt, const char *arg)
static void parse_meta_type(char *arg, char *type, int *index) static void parse_meta_type(char *arg, char *type, int *index)
{ {
if (*arg == ':') { if (*arg) {
*type = *(++arg); *type = *(++arg);
switch (*arg) { switch (*arg) {
case 'g': case 'g':
...@@ -2764,11 +2751,11 @@ static int opt_map_metadata(OptionsContext *o, const char *opt, const char *arg) ...@@ -2764,11 +2751,11 @@ static int opt_map_metadata(OptionsContext *o, const char *opt, const char *arg)
m = &o->meta_data_maps[o->nb_meta_data_maps - 1][1]; m = &o->meta_data_maps[o->nb_meta_data_maps - 1][1];
m->file = strtol(arg, &p, 0); m->file = strtol(arg, &p, 0);
parse_meta_type(p, &m->type, &m->index); parse_meta_type(*p ? p + 1 : p, &m->type, &m->index);
m1 = &o->meta_data_maps[o->nb_meta_data_maps - 1][0]; m1 = &o->meta_data_maps[o->nb_meta_data_maps - 1][0];
if (p = strchr(opt, ':')) if (p = strchr(opt, ':'))
parse_meta_type(p, &m1->type, &m1->index); parse_meta_type(p + 1, &m1->type, &m1->index);
else else
m1->type = 'g'; m1->type = 'g';
...@@ -3517,10 +3504,6 @@ static void opt_output_file(void *optctx, const char *filename) ...@@ -3517,10 +3504,6 @@ static void opt_output_file(void *optctx, const char *filename)
} }
} }
av_dict_copy(&oc->metadata, metadata, 0);
av_dict_free(&metadata);
output_files = grow_array(output_files, sizeof(*output_files), &nb_output_files, nb_output_files + 1); output_files = grow_array(output_files, sizeof(*output_files), &nb_output_files, nb_output_files + 1);
output_files[nb_output_files - 1].ctx = oc; output_files[nb_output_files - 1].ctx = oc;
output_files[nb_output_files - 1].ost_index = nb_output_streams - oc->nb_streams; output_files[nb_output_files - 1].ost_index = nb_output_streams - oc->nb_streams;
...@@ -3646,6 +3629,47 @@ static void opt_output_file(void *optctx, const char *filename) ...@@ -3646,6 +3629,47 @@ static void opt_output_file(void *optctx, const char *filename)
av_dict_copy(&output_streams[i].st->metadata, ist->st->metadata, AV_DICT_DONT_OVERWRITE); av_dict_copy(&output_streams[i].st->metadata, ist->st->metadata, AV_DICT_DONT_OVERWRITE);
} }
/* process manually set metadata */
for (i = 0; i < o->nb_metadata; i++) {
AVDictionary **m;
char type, *val;
int index = 0;
val = strchr(o->metadata[i].u.str, '=');
if (!val) {
av_log(NULL, AV_LOG_ERROR, "No '=' character in metadata string %s.\n",
o->metadata[i].u.str);
exit_program(1);
}
*val++ = 0;
parse_meta_type(o->metadata[i].specifier, &type, &index);
switch (type) {
case 'g':
m = &oc->metadata;
break;
case 's':
if (index < 0 || index >= oc->nb_streams) {
av_log(NULL, AV_LOG_ERROR, "Invalid stream index %d in metadata specifier.\n", index);
exit_program(1);
}
m = &oc->streams[i]->metadata;
break;
case 'c':
if (index < 0 || index >= oc->nb_chapters) {
av_log(NULL, AV_LOG_ERROR, "Invalid chapter index %d in metadata specifier.\n", index);
exit_program(1);
}
m = &oc->chapters[i]->metadata;
break;
default:
av_log(NULL, AV_LOG_ERROR, "Invalid metadata specifier %s.\n", o->metadata[i].specifier);
exit_program(1);
}
av_dict_set(m, o->metadata[i].u.str, *val ? val : NULL, 0);
}
frame_rate = (AVRational){0, 0}; frame_rate = (AVRational){0, 0};
frame_width = 0; frame_width = 0;
frame_height = 0; frame_height = 0;
...@@ -4011,7 +4035,7 @@ static const OptionDef options[] = { ...@@ -4011,7 +4035,7 @@ static const OptionDef options[] = {
{ "ss", HAS_ARG | OPT_TIME | OPT_OFFSET, {.off = OFFSET(start_time)}, "set the start time offset", "time_off" }, { "ss", HAS_ARG | OPT_TIME | OPT_OFFSET, {.off = OFFSET(start_time)}, "set the start time offset", "time_off" },
{ "itsoffset", HAS_ARG | OPT_TIME | OPT_OFFSET, {.off = OFFSET(input_ts_offset)}, "set the input ts offset", "time_off" }, { "itsoffset", HAS_ARG | OPT_TIME | OPT_OFFSET, {.off = OFFSET(input_ts_offset)}, "set the input ts offset", "time_off" },
{ "itsscale", HAS_ARG | OPT_DOUBLE | OPT_SPEC, {.off = OFFSET(ts_scale)}, "set the input ts scale", "scale" }, { "itsscale", HAS_ARG | OPT_DOUBLE | OPT_SPEC, {.off = OFFSET(ts_scale)}, "set the input ts scale", "scale" },
{ "metadata", HAS_ARG, {(void*)opt_metadata}, "add metadata", "string=string" }, { "metadata", HAS_ARG | OPT_STRING | OPT_SPEC, {.off = OFFSET(metadata)}, "add metadata", "string=string" },
{ "dframes", OPT_INT | HAS_ARG, {(void*)&max_frames[AVMEDIA_TYPE_DATA]}, "set the number of data frames to record", "number" }, { "dframes", OPT_INT | HAS_ARG, {(void*)&max_frames[AVMEDIA_TYPE_DATA]}, "set the number of data frames to record", "number" },
{ "benchmark", OPT_BOOL | OPT_EXPERT, {(void*)&do_benchmark}, { "benchmark", OPT_BOOL | OPT_EXPERT, {(void*)&do_benchmark},
"add timings for benchmarking" }, "add timings for benchmarking" },
......
...@@ -160,14 +160,26 @@ interpreted as UTC. ...@@ -160,14 +160,26 @@ interpreted as UTC.
If the year-month-day part is not specified it takes the current If the year-month-day part is not specified it takes the current
year-month-day. year-month-day.
@item -metadata @var{key}=@var{value} @item -metadata[:metadata_specifier] @var{key}=@var{value}
Set a metadata key/value pair. Set a metadata key/value pair.
An optional @var{metadata_specifier} may be given to set metadata
on streams or chapters. See @code{-map_metadata} documentation for
details.
This option overrides metadata set with @code{-map_metadata}. It is
also possible to delete metadata by using an empty value.
For example, for setting the title in the output file: For example, for setting the title in the output file:
@example @example
avconv -i in.avi -metadata title="my title" out.flv avconv -i in.avi -metadata title="my title" out.flv
@end example @end example
To set the language of the second stream:
@example
avconv -i INPUT -metadata:s:1 language=eng OUTPUT
@end example
@item -v @var{number} @item -v @var{number}
Set the logging verbosity level. Set the logging verbosity level.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment