aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnton Khirnov <anton@khirnov.net>2011-08-28 17:21:56 +0200
committerAnton Khirnov <anton@khirnov.net>2011-09-04 13:12:00 +0200
commit575ec4e17d4e9824bc015651dc99f0c778402866 (patch)
tree2dfbc9e25fefadd39cd2a0094f8351ec4d769f4d
parent6361c5e1e61033259e91b480f23ae81bed775c8b (diff)
downloadffmpeg-575ec4e17d4e9824bc015651dc99f0c778402866.tar.gz
avconv: add a context for options.
Move stream maps to it. Eventually all non-global options should be stored in it.
-rw-r--r--avconv.c79
1 files changed, 56 insertions, 23 deletions
diff --git a/avconv.c b/avconv.c
index 92273f1ce7..d1b99cdce1 100644
--- a/avconv.c
+++ b/avconv.c
@@ -100,9 +100,6 @@ static const OptionDef options[];
static const char *last_asked_format = NULL;
static AVDictionary *ts_scale;
-static StreamMap *stream_maps = NULL;
-static int nb_stream_maps;
-
static AVDictionary *codec_names;
/* first item specifies output metadata, second is input */
@@ -317,6 +314,42 @@ static int nb_output_streams = 0;
static OutputFile *output_files = NULL;
static int nb_output_files = 0;
+typedef struct OptionsContext {
+ /* output options */
+ StreamMap *stream_maps;
+ int nb_stream_maps;
+} OptionsContext;
+
+static void reset_options(OptionsContext *o)
+{
+ const OptionDef *po = options;
+
+ /* all OPT_SPEC and OPT_STRING can be freed in generic way */
+ while (po->name) {
+ void *dst = (uint8_t*)o + po->u.off;
+
+ if (po->flags & OPT_SPEC) {
+ SpecifierOpt **so = dst;
+ int i, *count = (int*)(so + 1);
+ for (i = 0; i < *count; i++) {
+ av_freep(&(*so)[i].specifier);
+ if (po->flags & OPT_STRING)
+ av_freep(&(*so)[i].u.str);
+ }
+ av_freep(so);
+ *count = 0;
+ } else if (po->flags & OPT_OFFSET && po->flags & OPT_STRING)
+ av_freep(dst);
+ po++;
+ }
+
+ av_freep(&o->stream_maps);
+
+ memset(o, 0, sizeof(*o));
+ uninit_opts();
+ init_opts();
+}
+
#if CONFIG_AVFILTER
static int configure_video_filters(InputStream *ist, OutputStream *ost)
@@ -2609,7 +2642,7 @@ static int opt_codec_tag(const char *opt, const char *arg)
return 0;
}
-static int opt_map(const char *opt, const char *arg)
+static int opt_map(OptionsContext *o, const char *opt, const char *arg)
{
StreamMap *m = NULL;
int i, negative = 0, file_idx;
@@ -2654,8 +2687,8 @@ static int opt_map(const char *opt, const char *arg)
}
if (negative)
/* disable some already defined maps */
- for (i = 0; i < nb_stream_maps; i++) {
- m = &stream_maps[i];
+ for (i = 0; i < o->nb_stream_maps; i++) {
+ m = &o->stream_maps[i];
if (check_stream_specifier(input_files[m->file_index].ctx,
input_files[m->file_index].ctx->streams[m->stream_index],
*p == ':' ? p + 1 : p) > 0)
@@ -2666,8 +2699,9 @@ static int opt_map(const char *opt, const char *arg)
if (check_stream_specifier(input_files[file_idx].ctx, input_files[file_idx].ctx->streams[i],
*p == ':' ? p + 1 : p) <= 0)
continue;
- stream_maps = grow_array(stream_maps, sizeof(*stream_maps), &nb_stream_maps, nb_stream_maps + 1);
- m = &stream_maps[nb_stream_maps - 1];
+ o->stream_maps = grow_array(o->stream_maps, sizeof(*o->stream_maps),
+ &o->nb_stream_maps, o->nb_stream_maps + 1);
+ m = &o->stream_maps[o->nb_stream_maps - 1];
m->file_index = file_idx;
m->stream_index = i;
@@ -2896,7 +2930,7 @@ static void add_input_streams(AVFormatContext *ic)
}
}
-static int opt_input_file(const char *opt, const char *filename)
+static int opt_input_file(OptionsContext *o, const char *opt, const char *filename)
{
AVFormatContext *ic;
AVInputFormat *file_iformat = NULL;
@@ -3039,8 +3073,8 @@ static int opt_input_file(const char *opt, const char *filename)
av_dict_free(&opts[i]);
av_freep(&opts);
av_dict_free(&codec_names);
- uninit_opts();
- init_opts();
+
+ reset_options(o);
return 0;
}
@@ -3405,6 +3439,7 @@ static int read_avserver_streams(AVFormatContext *s, const char *filename)
static void opt_output_file(void *optctx, const char *filename)
{
+ OptionsContext *o = optctx;
AVFormatContext *oc;
int i, err;
AVOutputFormat *file_oformat;
@@ -3448,7 +3483,7 @@ static void opt_output_file(void *optctx, const char *filename)
print_error(filename, err);
exit_program(1);
}
- } else if (!nb_stream_maps) {
+ } else if (!o->nb_stream_maps) {
/* pick the "best" stream of each type */
#define NEW_STREAM(type, index)\
if (index >= 0) {\
@@ -3496,8 +3531,8 @@ static void opt_output_file(void *optctx, const char *filename)
}
/* do something with data? */
} else {
- for (i = 0; i < nb_stream_maps; i++) {
- StreamMap *map = &stream_maps[i];
+ for (i = 0; i < o->nb_stream_maps; i++) {
+ StreamMap *map = &o->stream_maps[i];
if (map->disabled)
continue;
@@ -3665,16 +3700,13 @@ static void opt_output_file(void *optctx, const char *filename)
metadata_global_autocopy = 1;
metadata_streams_autocopy = 1;
metadata_chapters_autocopy = 1;
- av_freep(&stream_maps);
- nb_stream_maps = 0;
av_freep(&streamid_map);
nb_streamid_map = 0;
av_dict_free(&codec_names);
av_freep(&forced_key_frames);
- uninit_opts();
- init_opts();
+ reset_options(o);
}
/* same option as mencoder */
@@ -4014,11 +4046,11 @@ static const OptionDef options[] = {
/* main options */
#include "cmdutils_common_opts.h"
{ "f", HAS_ARG, {(void*)opt_format}, "force format", "fmt" },
- { "i", HAS_ARG, {(void*)opt_input_file}, "input file name", "filename" },
+ { "i", HAS_ARG | OPT_FUNC2, {(void*)opt_input_file}, "input file name", "filename" },
{ "y", OPT_BOOL, {(void*)&file_overwrite}, "overwrite output files" },
{ "c", HAS_ARG, {(void*)opt_codec}, "codec name", "codec" },
{ "codec", HAS_ARG, {(void*)opt_codec}, "codec name", "codec" },
- { "map", HAS_ARG | OPT_EXPERT, {(void*)opt_map}, "set input stream mapping", "file.stream[:syncfile.syncstream]" },
+ { "map", HAS_ARG | OPT_EXPERT | OPT_FUNC2, {(void*)opt_map}, "set input stream mapping", "file.stream[:syncfile.syncstream]" },
{ "map_metadata", HAS_ARG | OPT_EXPERT, {(void*)opt_map_metadata}, "set metadata information of outfile from infile",
"outfile[,metadata]:infile[,metadata]" },
{ "map_chapters", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&chapters_input_file}, "set chapters mapping", "input_file_index" },
@@ -4123,8 +4155,11 @@ static const OptionDef options[] = {
int main(int argc, char **argv)
{
+ OptionsContext o = { 0 };
int64_t ti;
+ reset_options(&o);
+
av_log_set_flags(AV_LOG_SKIP_REPEATED);
avcodec_register_all();
@@ -4138,12 +4173,10 @@ int main(int argc, char **argv)
avio_set_interrupt_cb(decode_interrupt_cb);
- init_opts();
-
show_banner();
/* parse options */
- parse_options(NULL, argc, argv, options, opt_output_file);
+ parse_options(&o, argc, argv, options, opt_output_file);
if(nb_output_files <= 0 && nb_input_files == 0) {
show_usage();