Browse code

Merge commit '77bd1bc73a1946b0f0ce09a7cbb242a65e138d06'

* commit '77bd1bc73a1946b0f0ce09a7cbb242a65e138d06':
avconv: use new options parser.

Conflicts:
ffmpeg.c
ffmpeg.h
ffmpeg_opt.c

Merged-by: Michael Niedermayer <michaelni@gmx.at>

Michael Niedermayer authored on 2012/12/20 10:38:02
Showing 5 changed files
... ...
@@ -568,6 +568,7 @@ static void finish_group(OptionParseContext *octx, int group_idx,
568 568
 #if CONFIG_SWSCALE
569 569
     g->sws_opts    = sws_opts;
570 570
 #endif
571
+    g->swr_opts    = swr_opts;
571 572
     g->codec_opts  = codec_opts;
572 573
     g->format_opts = format_opts;
573 574
 
... ...
@@ -576,6 +577,7 @@ static void finish_group(OptionParseContext *octx, int group_idx,
576 576
 #if CONFIG_SWSCALE
577 577
     sws_opts    = NULL;
578 578
 #endif
579
+    swr_opts    = NULL;
579 580
     init_opts();
580 581
 
581 582
     memset(&octx->cur_group, 0, sizeof(octx->cur_group));
... ...
@@ -635,6 +637,8 @@ void uninit_parse_context(OptionParseContext *octx)
635 635
 #if CONFIG_SWSCALE
636 636
             sws_freeContext(l->groups[j].sws_opts);
637 637
 #endif
638
+            if(CONFIG_SWRESAMPLE)
639
+                swr_free(&l->groups[j].swr_opts);
638 640
         }
639 641
         av_freep(&l->groups);
640 642
     }
... ...
@@ -254,6 +254,7 @@ typedef struct OptionGroup {
254 254
     AVDictionary *codec_opts;
255 255
     AVDictionary *format_opts;
256 256
     struct SwsContext *sws_opts;
257
+    struct SwrContext *swr_opts;
257 258
 } OptionGroup;
258 259
 
259 260
 /**
... ...
@@ -3152,22 +3152,13 @@ static void log_callback_null(void *ptr, int level, const char *fmt, va_list vl)
3152 3152
 {
3153 3153
 }
3154 3154
 
3155
-static void parse_cpuflags(int argc, char **argv, const OptionDef *options)
3156
-{
3157
-    int idx = locate_option(argc, argv, options, "cpuflags");
3158
-    if (idx && argv[idx + 1])
3159
-        opt_cpuflags(NULL, "cpuflags", argv[idx + 1]);
3160
-}
3161
-
3162 3155
 int main(int argc, char **argv)
3163 3156
 {
3164
-    OptionsContext o = { 0 };
3157
+    int ret;
3165 3158
     int64_t ti;
3166 3159
 
3167 3160
     atexit(exit_program);
3168 3161
 
3169
-    reset_options(&o, 0);
3170
-
3171 3162
     setvbuf(stderr,NULL,_IONBF,0); /* win32 runtime needs this */
3172 3163
 
3173 3164
     av_log_set_flags(AV_LOG_SKIP_REPEATED);
... ...
@@ -3192,10 +3183,10 @@ int main(int argc, char **argv)
3192 3192
 
3193 3193
     term_init();
3194 3194
 
3195
-    parse_cpuflags(argc, argv, options);
3196
-
3197
-    /* parse options */
3198
-    parse_options(&o, argc, argv, options, opt_output_file);
3195
+    /* parse options and open all input/output files */
3196
+    ret = ffmpeg_parse_options(argc, argv);
3197
+    if (ret < 0)
3198
+        exit(1);
3199 3199
 
3200 3200
     if (nb_output_files <= 0 && nb_input_files == 0) {
3201 3201
         show_usage();
... ...
@@ -71,6 +71,8 @@ typedef struct {
71 71
 } AudioChannelMap;
72 72
 
73 73
 typedef struct OptionsContext {
74
+    OptionGroup *g;
75
+
74 76
     /* input/output options */
75 77
     int64_t start_time;
76 78
     const char *format;
... ...
@@ -413,4 +415,6 @@ int configure_output_filter(FilterGraph *fg, OutputFilter *ofilter, AVFilterInOu
413 413
 int ist_in_filtergraph(FilterGraph *fg, InputStream *ist);
414 414
 FilterGraph *init_simple_filtergraph(InputStream *ist, OutputStream *ost);
415 415
 
416
+int ffmpeg_parse_options(int argc, char **argv);
417
+
416 418
 #endif /* FFMPEG_H */
... ...
@@ -95,10 +95,9 @@ static int intra_dc_precision = 8;
95 95
 static int do_psnr            = 0;
96 96
 static int input_sync;
97 97
 
98
-void reset_options(OptionsContext *o, int is_input)
98
+static void uninit_options(OptionsContext *o, int is_input)
99 99
 {
100 100
     const OptionDef *po = options;
101
-    OptionsContext bak= *o;
102 101
     int i;
103 102
 
104 103
     /* all OPT_SPEC and OPT_STRING can be freed in generic way */
... ...
@@ -126,9 +125,16 @@ void reset_options(OptionsContext *o, int is_input)
126 126
     av_freep(&o->audio_channel_maps);
127 127
     av_freep(&o->streamid_map);
128 128
 
129
+    if (!is_input)
130
+        o->recording_time = INT64_MAX;
131
+}
132
+
133
+static void init_options(OptionsContext *o, int is_input)
134
+{
135
+    OptionsContext bak= *o;
129 136
     memset(o, 0, sizeof(*o));
130 137
 
131
-    if (is_input) {
138
+    if (!is_input) {
132 139
         o->recording_time = bak.recording_time;
133 140
         if (o->recording_time != INT64_MAX)
134 141
             av_log(NULL, AV_LOG_WARNING,
... ...
@@ -139,12 +145,8 @@ void reset_options(OptionsContext *o, int is_input)
139 139
     o->mux_max_delay  = 0.7;
140 140
     o->limit_filesize = UINT64_MAX;
141 141
     o->chapters_input_file = INT_MAX;
142
-
143
-    uninit_opts();
144
-    init_opts();
145 142
 }
146 143
 
147
-
148 144
 static int opt_frame_crop(void *optctx, const char *opt, const char *arg)
149 145
 {
150 146
     av_log(NULL, AV_LOG_FATAL, "Option '%s' has been removed, use the crop filter instead\n", opt);
... ...
@@ -567,7 +569,7 @@ static void add_input_streams(OptionsContext *o, AVFormatContext *ic)
567 567
         ist->file_index = nb_input_files;
568 568
         ist->discard = 1;
569 569
         st->discard  = AVDISCARD_ALL;
570
-        ist->opts = filter_codec_opts(codec_opts, ist->st->codec->codec_id, ic, st, choose_decoder(o, ic, st));
570
+        ist->opts = filter_codec_opts(o->g->codec_opts, ist->st->codec->codec_id, ic, st, choose_decoder(o, ic, st));
571 571
 
572 572
         ist->ts_scale = 1.0;
573 573
         MATCH_PER_STREAM_OPT(ts_scale, dbl, ist->ts_scale, ic, st);
... ...
@@ -692,9 +694,8 @@ static void dump_attachment(AVStream *st, const char *filename)
692 692
     avio_close(out);
693 693
 }
694 694
 
695
-static int opt_input_file(void *optctx, const char *opt, const char *filename)
695
+static int open_input_file(OptionsContext *o, const char *filename)
696 696
 {
697
-    OptionsContext *o = optctx;
698 697
     AVFormatContext *ic;
699 698
     AVInputFormat *file_iformat = NULL;
700 699
     int err, i, ret;
... ...
@@ -727,7 +728,7 @@ static int opt_input_file(void *optctx, const char *opt, const char *filename)
727 727
     }
728 728
     if (o->nb_audio_sample_rate) {
729 729
         snprintf(buf, sizeof(buf), "%d", o->audio_sample_rate[o->nb_audio_sample_rate - 1].u.i);
730
-        av_dict_set(&format_opts, "sample_rate", buf, 0);
730
+        av_dict_set(&o->g->format_opts, "sample_rate", buf, 0);
731 731
     }
732 732
     if (o->nb_audio_channels) {
733 733
         /* because we set audio_channels based on both the "ac" and
... ...
@@ -738,7 +739,7 @@ static int opt_input_file(void *optctx, const char *opt, const char *filename)
738 738
                         AV_OPT_SEARCH_FAKE_OBJ)) {
739 739
             snprintf(buf, sizeof(buf), "%d",
740 740
                      o->audio_channels[o->nb_audio_channels - 1].u.i);
741
-            av_dict_set(&format_opts, "channels", buf, 0);
741
+            av_dict_set(&o->g->format_opts, "channels", buf, 0);
742 742
         }
743 743
     }
744 744
     if (o->nb_frame_rates) {
... ...
@@ -747,15 +748,15 @@ static int opt_input_file(void *optctx, const char *opt, const char *filename)
747 747
         if (file_iformat && file_iformat->priv_class &&
748 748
             av_opt_find(&file_iformat->priv_class, "framerate", NULL, 0,
749 749
                         AV_OPT_SEARCH_FAKE_OBJ)) {
750
-            av_dict_set(&format_opts, "framerate",
750
+            av_dict_set(&o->g->format_opts, "framerate",
751 751
                         o->frame_rates[o->nb_frame_rates - 1].u.str, 0);
752 752
         }
753 753
     }
754 754
     if (o->nb_frame_sizes) {
755
-        av_dict_set(&format_opts, "video_size", o->frame_sizes[o->nb_frame_sizes - 1].u.str, 0);
755
+        av_dict_set(&o->g->format_opts, "video_size", o->frame_sizes[o->nb_frame_sizes - 1].u.str, 0);
756 756
     }
757 757
     if (o->nb_frame_pix_fmts)
758
-        av_dict_set(&format_opts, "pixel_format", o->frame_pix_fmts[o->nb_frame_pix_fmts - 1].u.str, 0);
758
+        av_dict_set(&o->g->format_opts, "pixel_format", o->frame_pix_fmts[o->nb_frame_pix_fmts - 1].u.str, 0);
759 759
 
760 760
     MATCH_PER_TYPE_OPT(codec_names, str,    video_codec_name, ic, "v");
761 761
     MATCH_PER_TYPE_OPT(codec_names, str,    audio_codec_name, ic, "a");
... ...
@@ -771,19 +772,19 @@ static int opt_input_file(void *optctx, const char *opt, const char *filename)
771 771
     ic->interrupt_callback = int_cb;
772 772
 
773 773
     /* open the input file with generic avformat function */
774
-    err = avformat_open_input(&ic, filename, file_iformat, &format_opts);
774
+    err = avformat_open_input(&ic, filename, file_iformat, &o->g->format_opts);
775 775
     if (err < 0) {
776 776
         print_error(filename, err);
777 777
         exit(1);
778 778
     }
779
-    assert_avoptions(format_opts);
779
+    assert_avoptions(o->g->format_opts);
780 780
 
781 781
     /* apply forced codec ids */
782 782
     for (i = 0; i < ic->nb_streams; i++)
783 783
         choose_decoder(o, ic, ic->streams[i]);
784 784
 
785 785
     /* Set AVCodecContext options for avformat_find_stream_info */
786
-    opts = setup_find_stream_info_opts(ic, codec_opts);
786
+    opts = setup_find_stream_info_opts(ic, o->g->codec_opts);
787 787
     orig_nb_streams = ic->nb_streams;
788 788
 
789 789
     /* If not enough info to get the stream parameters, we decode the
... ...
@@ -840,7 +841,6 @@ static int opt_input_file(void *optctx, const char *opt, const char *filename)
840 840
         av_dict_free(&opts[i]);
841 841
     av_freep(&opts);
842 842
 
843
-    reset_options(o, 1);
844 843
     return 0;
845 844
 }
846 845
 
... ...
@@ -937,7 +937,7 @@ static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, e
937 937
         AVIOContext *s = NULL;
938 938
         char *buf = NULL, *arg = NULL, *preset = NULL;
939 939
 
940
-        ost->opts  = filter_codec_opts(codec_opts, ost->enc->id, oc, st, ost->enc);
940
+        ost->opts  = filter_codec_opts(o->g->codec_opts, ost->enc->id, oc, st, ost->enc);
941 941
 
942 942
         MATCH_PER_STREAM_OPT(presets, str, preset, oc, st);
943 943
         if (preset && (!(ret = get_preset_file_2(preset, ost->enc->name, &s)))) {
... ...
@@ -1008,10 +1008,10 @@ static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, e
1008 1008
     if (oc->oformat->flags & AVFMT_GLOBALHEADER)
1009 1009
         st->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
1010 1010
 
1011
-    av_opt_get_int(sws_opts, "sws_flags", 0, &ost->sws_flags);
1012
-    av_opt_get_int   (swr_opts, "filter_type"  , 0, &ost->swr_filter_type);
1013
-    av_opt_get_int   (swr_opts, "dither_method", 0, &ost->swr_dither_method);
1014
-    av_opt_get_double(swr_opts, "dither_scale" , 0, &ost->swr_dither_scale);
1011
+    av_opt_get_int(o->g->sws_opts, "sws_flags", 0, &ost->sws_flags);
1012
+    av_opt_get_int   (o->g->swr_opts, "filter_type"  , 0, &ost->swr_filter_type);
1013
+    av_opt_get_int   (o->g->swr_opts, "dither_method", 0, &ost->swr_dither_method);
1014
+    av_opt_get_double(o->g->swr_opts, "dither_scale" , 0, &ost->swr_dither_scale);
1015 1015
 
1016 1016
     ost->source_index = source_index;
1017 1017
     if (source_index >= 0) {
... ...
@@ -1434,9 +1434,8 @@ static int configure_complex_filters(void)
1434 1434
     return 0;
1435 1435
 }
1436 1436
 
1437
-void opt_output_file(void *optctx, const char *filename)
1437
+static int open_output_file(OptionsContext *o, const char *filename)
1438 1438
 {
1439
-    OptionsContext *o = optctx;
1440 1439
     AVFormatContext *oc;
1441 1440
     int i, j, err;
1442 1441
     AVOutputFormat *file_oformat;
... ...
@@ -1620,7 +1619,7 @@ loop_end:
1620 1620
         ost = output_streams[i];
1621 1621
 
1622 1622
         if (   ost->stream_copy
1623
-            && (e = av_dict_get(codec_opts, "flags", NULL, AV_DICT_IGNORE_SUFFIX))
1623
+            && (e = av_dict_get(o->g->codec_opts, "flags", NULL, AV_DICT_IGNORE_SUFFIX))
1624 1624
             && (!e->key[5] || check_stream_specifier(oc, ost->st, e->key+6)))
1625 1625
             if (av_opt_set(ost->st->codec, "flags", e->value, 0) < 0)
1626 1626
                 exit(1);
... ...
@@ -1673,7 +1672,7 @@ loop_end:
1673 1673
     output_files[nb_output_files - 1]->start_time     = o->start_time;
1674 1674
     output_files[nb_output_files - 1]->limit_filesize = o->limit_filesize;
1675 1675
     output_files[nb_output_files - 1]->shortest       = o->shortest;
1676
-    av_dict_copy(&output_files[nb_output_files - 1]->opts, format_opts, 0);
1676
+    av_dict_copy(&output_files[nb_output_files - 1]->opts, o->g->format_opts, 0);
1677 1677
 
1678 1678
     /* check filename in case of an image number is expected */
1679 1679
     if (oc->oformat->flags & AVFMT_NEEDNUMBER) {
... ...
@@ -1798,7 +1797,7 @@ loop_end:
1798 1798
         }
1799 1799
     }
1800 1800
 
1801
-    reset_options(o, 0);
1801
+    return 0;
1802 1802
 }
1803 1803
 
1804 1804
 static int opt_target(void *optctx, const char *opt, const char *arg)
... ...
@@ -1853,22 +1852,23 @@ static int opt_target(void *optctx, const char *opt, const char *arg)
1853 1853
         opt_video_codec(o, "c:v", "mpeg1video");
1854 1854
         opt_audio_codec(o, "c:a", "mp2");
1855 1855
         parse_option(o, "f", "vcd", options);
1856
+        av_dict_set(&o->g->codec_opts, "b:v", arg, 0);
1856 1857
 
1857 1858
         parse_option(o, "s", norm == PAL ? "352x288" : "352x240", options);
1858 1859
         parse_option(o, "r", frame_rates[norm], options);
1859
-        opt_default(NULL, "g", norm == PAL ? "15" : "18");
1860
+        av_dict_set(&o->g->codec_opts, "g", norm == PAL ? "15" : "18", 0);
1860 1861
 
1861
-        opt_default(NULL, "b:v", "1150000");
1862
-        opt_default(NULL, "maxrate", "1150000");
1863
-        opt_default(NULL, "minrate", "1150000");
1864
-        opt_default(NULL, "bufsize", "327680"); // 40*1024*8;
1862
+        av_dict_set(&o->g->codec_opts, "b:v", "1150000", 0);
1863
+        av_dict_set(&o->g->codec_opts, "maxrate", "1150000", 0);
1864
+        av_dict_set(&o->g->codec_opts, "minrate", "1150000", 0);
1865
+        av_dict_set(&o->g->codec_opts, "bufsize", "327680", 0); // 40*1024*8;
1865 1866
 
1866
-        opt_default(NULL, "b:a", "224000");
1867
+        av_dict_set(&o->g->codec_opts, "b:a", "224000", 0);
1867 1868
         parse_option(o, "ar", "44100", options);
1868 1869
         parse_option(o, "ac", "2", options);
1869 1870
 
1870
-        opt_default(NULL, "packetsize", "2324");
1871
-        opt_default(NULL, "muxrate", "1411200"); // 2352 * 75 * 8;
1871
+        av_dict_set(&o->g->format_opts, "packetsize", "2324", 0);
1872
+        av_dict_set(&o->g->format_opts, "muxrate", "1411200", 0); // 2352 * 75 * 8;
1872 1873
 
1873 1874
         /* We have to offset the PTS, so that it is consistent with the SCR.
1874 1875
            SCR starts at 36000, but the first two packs contain only padding
... ...
@@ -1885,18 +1885,18 @@ static int opt_target(void *optctx, const char *opt, const char *arg)
1885 1885
         parse_option(o, "s", norm == PAL ? "480x576" : "480x480", options);
1886 1886
         parse_option(o, "r", frame_rates[norm], options);
1887 1887
         parse_option(o, "pix_fmt", "yuv420p", options);
1888
-        opt_default(NULL, "g", norm == PAL ? "15" : "18");
1888
+        av_dict_set(&o->g->codec_opts, "g", norm == PAL ? "15" : "18", 0);
1889 1889
 
1890
-        opt_default(NULL, "b:v", "2040000");
1891
-        opt_default(NULL, "maxrate", "2516000");
1892
-        opt_default(NULL, "minrate", "0"); // 1145000;
1893
-        opt_default(NULL, "bufsize", "1835008"); // 224*1024*8;
1894
-        opt_default(NULL, "scan_offset", "1");
1890
+        av_dict_set(&o->g->codec_opts, "b:v", "2040000", 0);
1891
+        av_dict_set(&o->g->codec_opts, "maxrate", "2516000", 0);
1892
+        av_dict_set(&o->g->codec_opts, "minrate", "0", 0); // 1145000;
1893
+        av_dict_set(&o->g->codec_opts, "bufsize", "1835008", 0); // 224*1024*8;
1894
+        av_dict_set(&o->g->codec_opts, "scan_offset", "1", 0);
1895 1895
 
1896
-        opt_default(NULL, "b:a", "224000");
1896
+        av_dict_set(&o->g->codec_opts, "b:a", "224000", 0);
1897 1897
         parse_option(o, "ar", "44100", options);
1898 1898
 
1899
-        opt_default(NULL, "packetsize", "2324");
1899
+        av_dict_set(&o->g->format_opts, "packetsize", "2324", 0);
1900 1900
 
1901 1901
     } else if (!strcmp(arg, "dvd")) {
1902 1902
 
... ...
@@ -1907,17 +1907,17 @@ static int opt_target(void *optctx, const char *opt, const char *arg)
1907 1907
         parse_option(o, "s", norm == PAL ? "720x576" : "720x480", options);
1908 1908
         parse_option(o, "r", frame_rates[norm], options);
1909 1909
         parse_option(o, "pix_fmt", "yuv420p", options);
1910
-        opt_default(NULL, "g", norm == PAL ? "15" : "18");
1910
+        av_dict_set(&o->g->codec_opts, "g", norm == PAL ? "15" : "18", 0);
1911 1911
 
1912
-        opt_default(NULL, "b:v", "6000000");
1913
-        opt_default(NULL, "maxrate", "9000000");
1914
-        opt_default(NULL, "minrate", "0"); // 1500000;
1915
-        opt_default(NULL, "bufsize", "1835008"); // 224*1024*8;
1912
+        av_dict_set(&o->g->codec_opts, "b:v", "6000000", 0);
1913
+        av_dict_set(&o->g->codec_opts, "maxrate", "9000000", 0);
1914
+        av_dict_set(&o->g->codec_opts, "minrate", "0", 0); // 1500000;
1915
+        av_dict_set(&o->g->codec_opts, "bufsize", "1835008", 0); // 224*1024*8;
1916 1916
 
1917
-        opt_default(NULL, "packetsize", "2048");  // from www.mpucoder.com: DVD sectors contain 2048 bytes of data, this is also the size of one pack.
1918
-        opt_default(NULL, "muxrate", "10080000"); // from mplex project: data_rate = 1260000. mux_rate = data_rate * 8
1917
+        av_dict_set(&o->g->format_opts, "packetsize", "2048", 0);  // from www.mpucoder.com: DVD sectors contain 2048 bytes of data, this is also the size of one pack.
1918
+        av_dict_set(&o->g->format_opts, "muxrate", "10080000", 0); // from mplex project: data_rate = 1260000. mux_rate = data_rate * 8
1919 1919
 
1920
-        opt_default(NULL, "b:a", "448000");
1920
+        av_dict_set(&o->g->codec_opts, "b:a", "448000", 0);
1921 1921
         parse_option(o, "ar", "48000", options);
1922 1922
 
1923 1923
     } else if (!strncmp(arg, "dv", 2)) {
... ...
@@ -1975,6 +1975,26 @@ static int opt_data_frames(void *optctx, const char *opt, const char *arg)
1975 1975
     return parse_option(o, "frames:d", arg, options);
1976 1976
 }
1977 1977
 
1978
+static int opt_default_new(OptionsContext *o, const char *opt, const char *arg)
1979
+{
1980
+    int ret;
1981
+    AVCodecContext *cbak = codec_opts;
1982
+    AVCodecContext *fbak = format_opts;
1983
+    codec_opts = NULL;
1984
+    format_opts = NULL;
1985
+
1986
+    ret = opt_default(NULL, opt, arg);
1987
+
1988
+    av_dict_copy(&o->g->codec_opts , codec_opts, 0);
1989
+    av_dict_copy(&o->g->format_opts, format_opts, 0);
1990
+    av_dict_free(&codec_opts);
1991
+    av_dict_free(&format_opts);
1992
+    codec_opts = cbak;
1993
+    format_opts = fbak;
1994
+
1995
+    return ret;
1996
+}
1997
+
1978 1998
 static int opt_preset(void *optctx, const char *opt, const char *arg)
1979 1999
 {
1980 2000
     OptionsContext *o = optctx;
... ...
@@ -1992,7 +2012,7 @@ static int opt_preset(void *optctx, const char *opt, const char *arg)
1992 1992
         }else
1993 1993
             av_log(NULL, AV_LOG_FATAL, "File for preset '%s' not found\n", arg);
1994 1994
         exit(1);
1995
-}
1995
+    }
1996 1996
 
1997 1997
     while (fgets(line, sizeof(line), f)) {
1998 1998
         char *key = tmp_line, *value, *endptr;
... ...
@@ -2011,7 +2031,7 @@ static int opt_preset(void *optctx, const char *opt, const char *arg)
2011 2011
         else if (!strcmp(key, "vcodec")) opt_video_codec   (o, key, value);
2012 2012
         else if (!strcmp(key, "scodec")) opt_subtitle_codec(o, key, value);
2013 2013
         else if (!strcmp(key, "dcodec")) opt_data_codec    (o, key, value);
2014
-        else if (opt_default(NULL, key, value) < 0) {
2014
+        else if (opt_default_new(o, key, value) < 0) {
2015 2015
             av_log(NULL, AV_LOG_FATAL, "%s: Invalid option or argument: '%s', parsed as '%s' = '%s'\n",
2016 2016
                    filename, line, key, value);
2017 2017
             exit(1);
... ...
@@ -2037,9 +2057,11 @@ static int opt_bitrate(void *optctx, const char *opt, const char *arg)
2037 2037
     OptionsContext *o = optctx;
2038 2038
     if(!strcmp(opt, "b")){
2039 2039
         av_log(NULL, AV_LOG_WARNING, "Please use -b:a or -b:v, -b is ambiguous\n");
2040
-        return parse_option(o, "b:v", arg, options);
2040
+        av_dict_set(&o->g->codec_opts, "b:v", arg, 0);
2041
+        return 0;
2041 2042
     }
2042
-    return opt_default(optctx, opt, arg);
2043
+    av_dict_set(&o->g->codec_opts, opt, arg, 0);
2044
+    return 0;
2043 2045
 }
2044 2046
 
2045 2047
 static int opt_qscale(void *optctx, const char *opt, const char *arg)
... ...
@@ -2062,10 +2084,11 @@ static int opt_profile(void *optctx, const char *opt, const char *arg)
2062 2062
     OptionsContext *o = optctx;
2063 2063
     if(!strcmp(opt, "profile")){
2064 2064
         av_log(NULL, AV_LOG_WARNING, "Please use -profile:a or -profile:v, -profile is ambiguous\n");
2065
-        return parse_option(o, "profile:v", arg, options);
2065
+        av_dict_set(&o->g->codec_opts, "profile:v", arg, 0);
2066
+        return 0;
2066 2067
     }
2067
-    return opt_default(optctx, opt, arg);
2068
-
2068
+    av_dict_set(&o->g->codec_opts, opt, arg, 0);
2069
+    return 0;
2069 2070
 }
2070 2071
 
2071 2072
 static int opt_video_filters(void *optctx, const char *opt, const char *arg)
... ...
@@ -2105,9 +2128,9 @@ static int opt_timecode(void *optctx, const char *opt, const char *arg)
2105 2105
     char *tcr = av_asprintf("timecode=%s", arg);
2106 2106
     int ret = parse_option(o, "metadata:g", tcr, options);
2107 2107
     if (ret >= 0)
2108
-        ret = opt_default(optctx, "gop_timecode", arg);
2108
+        ret = av_dict_set(&o->g->codec_opts, "gop_timecode", arg, 0);
2109 2109
     av_free(tcr);
2110
-    return ret;
2110
+    return 0;
2111 2111
 }
2112 2112
 
2113 2113
 static int opt_channel_layout(void *optctx, const char *opt, const char *arg)
... ...
@@ -2235,6 +2258,94 @@ void show_usage(void)
2235 2235
     av_log(NULL, AV_LOG_INFO, "\n");
2236 2236
 }
2237 2237
 
2238
+enum OptGroup {
2239
+    GROUP_OUTFILE,
2240
+    GROUP_INFILE,
2241
+};
2242
+
2243
+static const OptionGroupDef groups[] = {
2244
+    [GROUP_OUTFILE] = { "output file",  NULL },
2245
+    [GROUP_INFILE]  = { "input file",   "i"  },
2246
+    { 0 },
2247
+};
2248
+
2249
+static int open_files(OptionGroupList *l, const char *inout,
2250
+                      int (*open_file)(OptionsContext*, const char*))
2251
+{
2252
+    int i, ret;
2253
+
2254
+    for (i = 0; i < l->nb_groups; i++) {
2255
+        OptionGroup *g = &l->groups[i];
2256
+        OptionsContext o;
2257
+
2258
+        init_options(&o, !strcmp(inout, "input"));
2259
+        o.g = g;
2260
+
2261
+        ret = parse_optgroup(&o, g);
2262
+        if (ret < 0) {
2263
+            av_log(NULL, AV_LOG_ERROR, "Error parsing options for %s file "
2264
+                   "%s.\n", inout, g->arg);
2265
+            return ret;
2266
+        }
2267
+
2268
+        av_log(NULL, AV_LOG_DEBUG, "Opening an %s file: %s.\n", inout, g->arg);
2269
+        ret = open_file(&o, g->arg);
2270
+        uninit_options(&o, !strcmp(inout, "input"));
2271
+        if (ret < 0) {
2272
+            av_log(NULL, AV_LOG_ERROR, "Error opening %s file %s.\n",
2273
+                   inout, g->arg);
2274
+            return ret;
2275
+        }
2276
+        av_log(NULL, AV_LOG_DEBUG, "Successfully openened the file.\n");
2277
+    }
2278
+
2279
+    return 0;
2280
+}
2281
+
2282
+int ffmpeg_parse_options(int argc, char **argv)
2283
+{
2284
+    OptionParseContext octx;
2285
+    uint8_t error[128];
2286
+    int ret;
2287
+
2288
+    memset(&octx, 0, sizeof(octx));
2289
+
2290
+    /* split the commandline into an internal representation */
2291
+    ret = split_commandline(&octx, argc, argv, options, groups);
2292
+    if (ret < 0) {
2293
+        av_log(NULL, AV_LOG_FATAL, "Error splitting the argument list: ");
2294
+        goto fail;
2295
+    }
2296
+
2297
+    /* apply global options */
2298
+    ret = parse_optgroup(NULL, &octx.global_opts);
2299
+    if (ret < 0) {
2300
+        av_log(NULL, AV_LOG_FATAL, "Error parsing global options: ");
2301
+        goto fail;
2302
+    }
2303
+
2304
+    /* open input files */
2305
+    ret = open_files(&octx.groups[GROUP_INFILE], "input", open_input_file);
2306
+    if (ret < 0) {
2307
+        av_log(NULL, AV_LOG_FATAL, "Error opening input files: ");
2308
+        goto fail;
2309
+    }
2310
+
2311
+    /* open output files */
2312
+    ret = open_files(&octx.groups[GROUP_OUTFILE], "output", open_output_file);
2313
+    if (ret < 0) {
2314
+        av_log(NULL, AV_LOG_FATAL, "Error opening output files: ");
2315
+        goto fail;
2316
+    }
2317
+
2318
+fail:
2319
+    uninit_parse_context(&octx);
2320
+    if (ret < 0) {
2321
+        av_strerror(ret, error, sizeof(error));
2322
+        av_log(NULL, AV_LOG_FATAL, "%s\n", error);
2323
+    }
2324
+    return ret;
2325
+}
2238 2326
 
2239 2327
 static int opt_progress(void *optctx, const char *opt, const char *arg)
2240 2328
 {
... ...
@@ -2259,8 +2370,6 @@ const OptionDef options[] = {
2259 2259
 #include "cmdutils_common_opts.h"
2260 2260
     { "f",              HAS_ARG | OPT_STRING | OPT_OFFSET,           { .off       = OFFSET(format) },
2261 2261
         "force format", "fmt" },
2262
-    { "i",              HAS_ARG | OPT_PERFILE,                       { .func_arg = opt_input_file },
2263
-        "input file name", "filename" },
2264 2262
     { "y",              OPT_BOOL,                                    {              &file_overwrite },
2265 2263
         "overwrite output files" },
2266 2264
     { "n",              OPT_BOOL,                                    {              &no_file_overwrite },
... ...
@@ -2515,7 +2624,5 @@ const OptionDef options[] = {
2515 2515
     { "dn", OPT_BOOL | OPT_VIDEO | OPT_OFFSET, { .off = OFFSET(data_disable) },
2516 2516
         "disable data" },
2517 2517
 
2518
-    { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, { .func_arg = opt_default },
2519
-        "generic catch all option", "" },
2520 2518
     { NULL, },
2521 2519
 };