Browse code

avconv: use new options parser.

Anton Khirnov authored on 2012/06/09 04:35:16
Showing 3 changed files
... ...
@@ -2345,22 +2345,13 @@ static int64_t getmaxrss(void)
2345 2345
 #endif
2346 2346
 }
2347 2347
 
2348
-static void parse_cpuflags(int argc, char **argv, const OptionDef *options)
2349
-{
2350
-    int idx = locate_option(argc, argv, options, "cpuflags");
2351
-    if (idx && argv[idx + 1])
2352
-        opt_cpuflags(NULL, "cpuflags", argv[idx + 1]);
2353
-}
2354
-
2355 2348
 int main(int argc, char **argv)
2356 2349
 {
2357
-    OptionsContext o = { 0 };
2350
+    int ret;
2358 2351
     int64_t ti;
2359 2352
 
2360 2353
     atexit(exit_program);
2361 2354
 
2362
-    reset_options(&o);
2363
-
2364 2355
     av_log_set_flags(AV_LOG_SKIP_REPEATED);
2365 2356
     parse_loglevel(argc, argv, options);
2366 2357
 
... ...
@@ -2374,10 +2365,10 @@ int main(int argc, char **argv)
2374 2374
 
2375 2375
     show_banner();
2376 2376
 
2377
-    parse_cpuflags(argc, argv, options);
2378
-
2379
-    /* parse options */
2380
-    parse_options(&o, argc, argv, options, opt_output_file);
2377
+    /* parse options and open all input/output files */
2378
+    ret = avconv_parse_options(argc, argv);
2379
+    if (ret < 0)
2380
+        exit(1);
2381 2381
 
2382 2382
     if (nb_output_files <= 0 && nb_input_files == 0) {
2383 2383
         show_usage();
... ...
@@ -67,6 +67,8 @@ typedef struct MetadataMap {
67 67
 } MetadataMap;
68 68
 
69 69
 typedef struct OptionsContext {
70
+    OptionGroup *g;
71
+
70 72
     /* input/output options */
71 73
     int64_t start_time;
72 74
     const char *format;
... ...
@@ -361,4 +363,6 @@ int configure_output_filter(FilterGraph *fg, OutputFilter *ofilter, AVFilterInOu
361 361
 int ist_in_filtergraph(FilterGraph *fg, InputStream *ist);
362 362
 FilterGraph *init_simple_filtergraph(InputStream *ist, OutputStream *ost);
363 363
 
364
+int avconv_parse_options(int argc, char **argv);
365
+
364 366
 #endif /* AVCONV_H */
... ...
@@ -78,7 +78,7 @@ static int intra_dc_precision = 8;
78 78
 static int using_stdin        = 0;
79 79
 static int input_sync;
80 80
 
81
-void reset_options(OptionsContext *o)
81
+static void uninit_options(OptionsContext *o)
82 82
 {
83 83
     const OptionDef *po = options;
84 84
     int i;
... ...
@@ -107,19 +107,18 @@ void reset_options(OptionsContext *o)
107 107
     av_freep(&o->stream_maps);
108 108
     av_freep(&o->meta_data_maps);
109 109
     av_freep(&o->streamid_map);
110
+}
110 111
 
112
+static void init_options(OptionsContext *o)
113
+{
111 114
     memset(o, 0, sizeof(*o));
112 115
 
113 116
     o->mux_max_delay  = 0.7;
114 117
     o->recording_time = INT64_MAX;
115 118
     o->limit_filesize = UINT64_MAX;
116 119
     o->chapters_input_file = INT_MAX;
117
-
118
-    uninit_opts();
119
-    init_opts();
120 120
 }
121 121
 
122
-
123 122
 static double parse_frame_aspect_ratio(const char *arg)
124 123
 {
125 124
     int x = 0, y = 0;
... ...
@@ -449,7 +448,7 @@ static void add_input_streams(OptionsContext *o, AVFormatContext *ic)
449 449
         ist->file_index = nb_input_files;
450 450
         ist->discard = 1;
451 451
         st->discard  = AVDISCARD_ALL;
452
-        ist->opts = filter_codec_opts(codec_opts, ist->st->codec->codec_id, ic, st, NULL);
452
+        ist->opts = filter_codec_opts(o->g->codec_opts, ist->st->codec->codec_id, ic, st, NULL);
453 453
 
454 454
         ist->ts_scale = 1.0;
455 455
         MATCH_PER_STREAM_OPT(ts_scale, dbl, ist->ts_scale, ic, st);
... ...
@@ -545,9 +544,8 @@ static void dump_attachment(AVStream *st, const char *filename)
545 545
     avio_close(out);
546 546
 }
547 547
 
548
-static int opt_input_file(void *optctx, const char *opt, const char *filename)
548
+static int open_input_file(OptionsContext *o, const char *filename)
549 549
 {
550
-    OptionsContext *o = optctx;
551 550
     AVFormatContext *ic;
552 551
     AVInputFormat *file_iformat = NULL;
553 552
     int err, i, ret;
... ...
@@ -577,7 +575,7 @@ static int opt_input_file(void *optctx, const char *opt, const char *filename)
577 577
     }
578 578
     if (o->nb_audio_sample_rate) {
579 579
         snprintf(buf, sizeof(buf), "%d", o->audio_sample_rate[o->nb_audio_sample_rate - 1].u.i);
580
-        av_dict_set(&format_opts, "sample_rate", buf, 0);
580
+        av_dict_set(&o->g->format_opts, "sample_rate", buf, 0);
581 581
     }
582 582
     if (o->nb_audio_channels) {
583 583
         /* because we set audio_channels based on both the "ac" and
... ...
@@ -588,7 +586,7 @@ static int opt_input_file(void *optctx, const char *opt, const char *filename)
588 588
                         AV_OPT_SEARCH_FAKE_OBJ)) {
589 589
             snprintf(buf, sizeof(buf), "%d",
590 590
                      o->audio_channels[o->nb_audio_channels - 1].u.i);
591
-            av_dict_set(&format_opts, "channels", buf, 0);
591
+            av_dict_set(&o->g->format_opts, "channels", buf, 0);
592 592
         }
593 593
     }
594 594
     if (o->nb_frame_rates) {
... ...
@@ -597,33 +595,33 @@ static int opt_input_file(void *optctx, const char *opt, const char *filename)
597 597
         if (file_iformat && file_iformat->priv_class &&
598 598
             av_opt_find(&file_iformat->priv_class, "framerate", NULL, 0,
599 599
                         AV_OPT_SEARCH_FAKE_OBJ)) {
600
-            av_dict_set(&format_opts, "framerate",
600
+            av_dict_set(&o->g->format_opts, "framerate",
601 601
                         o->frame_rates[o->nb_frame_rates - 1].u.str, 0);
602 602
         }
603 603
     }
604 604
     if (o->nb_frame_sizes) {
605
-        av_dict_set(&format_opts, "video_size", o->frame_sizes[o->nb_frame_sizes - 1].u.str, 0);
605
+        av_dict_set(&o->g->format_opts, "video_size", o->frame_sizes[o->nb_frame_sizes - 1].u.str, 0);
606 606
     }
607 607
     if (o->nb_frame_pix_fmts)
608
-        av_dict_set(&format_opts, "pixel_format", o->frame_pix_fmts[o->nb_frame_pix_fmts - 1].u.str, 0);
608
+        av_dict_set(&o->g->format_opts, "pixel_format", o->frame_pix_fmts[o->nb_frame_pix_fmts - 1].u.str, 0);
609 609
 
610 610
     ic->flags |= AVFMT_FLAG_NONBLOCK;
611 611
     ic->interrupt_callback = int_cb;
612 612
 
613 613
     /* open the input file with generic libav function */
614
-    err = avformat_open_input(&ic, filename, file_iformat, &format_opts);
614
+    err = avformat_open_input(&ic, filename, file_iformat, &o->g->format_opts);
615 615
     if (err < 0) {
616 616
         print_error(filename, err);
617 617
         exit(1);
618 618
     }
619
-    assert_avoptions(format_opts);
619
+    assert_avoptions(o->g->format_opts);
620 620
 
621 621
     /* apply forced codec ids */
622 622
     for (i = 0; i < ic->nb_streams; i++)
623 623
         choose_decoder(o, ic, ic->streams[i]);
624 624
 
625 625
     /* Set AVCodecContext options for avformat_find_stream_info */
626
-    opts = setup_find_stream_info_opts(ic, codec_opts);
626
+    opts = setup_find_stream_info_opts(ic, o->g->codec_opts);
627 627
     orig_nb_streams = ic->nb_streams;
628 628
 
629 629
     /* If not enough info to get the stream parameters, we decode the
... ...
@@ -680,7 +678,6 @@ static int opt_input_file(void *optctx, const char *opt, const char *filename)
680 680
         av_dict_free(&opts[i]);
681 681
     av_freep(&opts);
682 682
 
683
-    reset_options(o);
684 683
     return 0;
685 684
 }
686 685
 
... ...
@@ -777,7 +774,7 @@ static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, e
777 777
         AVIOContext *s = NULL;
778 778
         char *buf = NULL, *arg = NULL, *preset = NULL;
779 779
 
780
-        ost->opts  = filter_codec_opts(codec_opts, ost->enc->id, oc, st, ost->enc);
780
+        ost->opts  = filter_codec_opts(o->g->codec_opts, ost->enc->id, oc, st, ost->enc);
781 781
 
782 782
         MATCH_PER_STREAM_OPT(presets, str, preset, oc, st);
783 783
         if (preset && (!(ret = get_preset_file_2(preset, ost->enc->name, &s)))) {
... ...
@@ -845,7 +842,7 @@ static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, e
845 845
     if (oc->oformat->flags & AVFMT_GLOBALHEADER)
846 846
         st->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
847 847
 
848
-    av_opt_get_int(sws_opts, "sws_flags", 0, &ost->sws_flags);
848
+    av_opt_get_int(o->g->sws_opts, "sws_flags", 0, &ost->sws_flags);
849 849
 
850 850
     ost->pix_fmts[0] = ost->pix_fmts[1] = AV_PIX_FMT_NONE;
851 851
 
... ...
@@ -1169,9 +1166,8 @@ static int configure_complex_filters(void)
1169 1169
     return 0;
1170 1170
 }
1171 1171
 
1172
-void opt_output_file(void *optctx, const char *filename)
1172
+static int open_output_file(OptionsContext *o, const char *filename)
1173 1173
 {
1174
-    OptionsContext *o = optctx;
1175 1174
     AVFormatContext *oc;
1176 1175
     int i, j, err;
1177 1176
     AVOutputFormat *file_oformat;
... ...
@@ -1378,7 +1374,7 @@ loop_end:
1378 1378
     output_files[nb_output_files - 1]->start_time     = o->start_time;
1379 1379
     output_files[nb_output_files - 1]->limit_filesize = o->limit_filesize;
1380 1380
     output_files[nb_output_files - 1]->shortest       = o->shortest;
1381
-    av_dict_copy(&output_files[nb_output_files - 1]->opts, format_opts, 0);
1381
+    av_dict_copy(&output_files[nb_output_files - 1]->opts, o->g->format_opts, 0);
1382 1382
 
1383 1383
     /* check filename in case of an image number is expected */
1384 1384
     if (oc->oformat->flags & AVFMT_NEEDNUMBER) {
... ...
@@ -1500,7 +1496,7 @@ loop_end:
1500 1500
         }
1501 1501
     }
1502 1502
 
1503
-    reset_options(o);
1503
+    return 0;
1504 1504
 }
1505 1505
 
1506 1506
 static int opt_target(void *optctx, const char *opt, const char *arg)
... ...
@@ -1858,6 +1854,94 @@ void show_usage(void)
1858 1858
     printf("\n");
1859 1859
 }
1860 1860
 
1861
+enum OptGroup {
1862
+    GROUP_OUTFILE,
1863
+    GROUP_INFILE,
1864
+};
1865
+
1866
+static const OptionGroupDef groups[] = {
1867
+    [GROUP_OUTFILE] = { "output file",  NULL },
1868
+    [GROUP_INFILE]  = { "input file",   "i"  },
1869
+    { 0 },
1870
+};
1871
+
1872
+static int open_files(OptionGroupList *l, const char *inout,
1873
+                      int (*open_file)(OptionsContext*, const char*))
1874
+{
1875
+    int i, ret;
1876
+
1877
+    for (i = 0; i < l->nb_groups; i++) {
1878
+        OptionGroup *g = &l->groups[i];
1879
+        OptionsContext o;
1880
+
1881
+        init_options(&o);
1882
+        o.g = g;
1883
+
1884
+        ret = parse_optgroup(&o, g);
1885
+        if (ret < 0) {
1886
+            av_log(NULL, AV_LOG_ERROR, "Error parsing options for %s file "
1887
+                   "%s.\n", inout, g->arg);
1888
+            return ret;
1889
+        }
1890
+
1891
+        av_log(NULL, AV_LOG_DEBUG, "Opening an %s file: %s.\n", inout, g->arg);
1892
+        ret = open_file(&o, g->arg);
1893
+        uninit_options(&o);
1894
+        if (ret < 0) {
1895
+            av_log(NULL, AV_LOG_ERROR, "Error opening %s file %s.\n",
1896
+                   inout, g->arg);
1897
+            return ret;
1898
+        }
1899
+        av_log(NULL, AV_LOG_DEBUG, "Successfully openened the file.\n");
1900
+    }
1901
+
1902
+    return 0;
1903
+}
1904
+
1905
+int avconv_parse_options(int argc, char **argv)
1906
+{
1907
+    OptionParseContext octx;
1908
+    uint8_t error[128];
1909
+    int ret;
1910
+
1911
+    memset(&octx, 0, sizeof(octx));
1912
+
1913
+    /* split the commandline into an internal representation */
1914
+    ret = split_commandline(&octx, argc, argv, options, groups);
1915
+    if (ret < 0) {
1916
+        av_log(NULL, AV_LOG_FATAL, "Error splitting the argument list: ");
1917
+        goto fail;
1918
+    }
1919
+
1920
+    /* apply global options */
1921
+    ret = parse_optgroup(NULL, &octx.global_opts);
1922
+    if (ret < 0) {
1923
+        av_log(NULL, AV_LOG_FATAL, "Error parsing global options: ");
1924
+        goto fail;
1925
+    }
1926
+
1927
+    /* open input files */
1928
+    ret = open_files(&octx.groups[GROUP_INFILE], "input", open_input_file);
1929
+    if (ret < 0) {
1930
+        av_log(NULL, AV_LOG_FATAL, "Error opening input files: ");
1931
+        goto fail;
1932
+    }
1933
+
1934
+    /* open output files */
1935
+    ret = open_files(&octx.groups[GROUP_OUTFILE], "output", open_output_file);
1936
+    if (ret < 0) {
1937
+        av_log(NULL, AV_LOG_FATAL, "Error opening output files: ");
1938
+        goto fail;
1939
+    }
1940
+
1941
+fail:
1942
+    uninit_parse_context(&octx);
1943
+    if (ret < 0) {
1944
+        av_strerror(ret, error, sizeof(error));
1945
+        av_log(NULL, AV_LOG_FATAL, "%s\n", error);
1946
+    }
1947
+    return ret;
1948
+}
1861 1949
 
1862 1950
 #define OFFSET(x) offsetof(OptionsContext, x)
1863 1951
 const OptionDef options[] = {
... ...
@@ -1865,8 +1949,6 @@ const OptionDef options[] = {
1865 1865
 #include "cmdutils_common_opts.h"
1866 1866
     { "f",              HAS_ARG | OPT_STRING | OPT_OFFSET,           { .off       = OFFSET(format) },
1867 1867
         "force format", "fmt" },
1868
-    { "i",              HAS_ARG | OPT_PERFILE,                       { .func_arg = opt_input_file },
1869
-        "input file name", "filename" },
1870 1868
     { "y",              OPT_BOOL,                                    {              &file_overwrite },
1871 1869
         "overwrite output files" },
1872 1870
     { "c",              HAS_ARG | OPT_STRING | OPT_SPEC,             { .off       = OFFSET(codec_names) },
... ...
@@ -2048,7 +2130,5 @@ const OptionDef options[] = {
2048 2048
     { "dcodec", HAS_ARG | OPT_DATA | OPT_PERFILE | OPT_EXPERT, { .func_arg = opt_data_codec },
2049 2049
         "force data codec ('copy' to copy stream)", "codec" },
2050 2050
 
2051
-    { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, { .func_arg = opt_default },
2052
-        "generic catch all option", "" },
2053 2051
     { NULL, },
2054 2052
 };