Browse code

avconv: print an error on applying options of the wrong type.

I.e. input options to output files or vice versa.

Anton Khirnov authored on 2013/02/20 16:02:16
Showing 3 changed files
... ...
@@ -1864,8 +1864,8 @@ enum OptGroup {
1864 1864
 };
1865 1865
 
1866 1866
 static const OptionGroupDef groups[] = {
1867
-    [GROUP_OUTFILE] = { "output file",  NULL },
1868
-    [GROUP_INFILE]  = { "input file",   "i"  },
1867
+    [GROUP_OUTFILE] = { "output file",  NULL, OPT_OUTPUT },
1868
+    [GROUP_INFILE]  = { "input file",   "i",  OPT_INPUT },
1869 1869
 };
1870 1870
 
1871 1871
 static int open_files(OptionGroupList *l, const char *inout,
... ...
@@ -1951,38 +1951,49 @@ fail:
1951 1951
 const OptionDef options[] = {
1952 1952
     /* main options */
1953 1953
 #include "cmdutils_common_opts.h"
1954
-    { "f",              HAS_ARG | OPT_STRING | OPT_OFFSET,           { .off       = OFFSET(format) },
1954
+    { "f",              HAS_ARG | OPT_STRING | OPT_OFFSET |
1955
+                        OPT_INPUT | OPT_OUTPUT,                      { .off       = OFFSET(format) },
1955 1956
         "force format", "fmt" },
1956 1957
     { "y",              OPT_BOOL,                                    {              &file_overwrite },
1957 1958
         "overwrite output files" },
1958
-    { "c",              HAS_ARG | OPT_STRING | OPT_SPEC,             { .off       = OFFSET(codec_names) },
1959
+    { "c",              HAS_ARG | OPT_STRING | OPT_SPEC |
1960
+                        OPT_INPUT | OPT_OUTPUT,                      { .off       = OFFSET(codec_names) },
1959 1961
         "codec name", "codec" },
1960
-    { "codec",          HAS_ARG | OPT_STRING | OPT_SPEC,             { .off       = OFFSET(codec_names) },
1962
+    { "codec",          HAS_ARG | OPT_STRING | OPT_SPEC |
1963
+                        OPT_INPUT | OPT_OUTPUT,                      { .off       = OFFSET(codec_names) },
1961 1964
         "codec name", "codec" },
1962
-    { "pre",            HAS_ARG | OPT_STRING | OPT_SPEC,             { .off       = OFFSET(presets) },
1965
+    { "pre",            HAS_ARG | OPT_STRING | OPT_SPEC |
1966
+                        OPT_OUTPUT,                                  { .off       = OFFSET(presets) },
1963 1967
         "preset name", "preset" },
1964
-    { "map",            HAS_ARG | OPT_EXPERT | OPT_PERFILE,          { .func_arg = opt_map },
1968
+    { "map",            HAS_ARG | OPT_EXPERT | OPT_PERFILE |
1969
+                        OPT_OUTPUT,                                  { .func_arg = opt_map },
1965 1970
         "set input stream mapping",
1966 1971
         "[-]input_file_id[:stream_specifier][,sync_file_id[:stream_specifier]]" },
1967
-    { "map_metadata",   HAS_ARG | OPT_STRING | OPT_SPEC,             { .off       = OFFSET(metadata_map) },
1972
+    { "map_metadata",   HAS_ARG | OPT_STRING | OPT_SPEC |
1973
+                        OPT_OUTPUT,                                  { .off       = OFFSET(metadata_map) },
1968 1974
         "set metadata information of outfile from infile",
1969 1975
         "outfile[,metadata]:infile[,metadata]" },
1970
-    { "map_chapters",   HAS_ARG | OPT_INT | OPT_EXPERT | OPT_OFFSET, { .off = OFFSET(chapters_input_file) },
1976
+    { "map_chapters",   HAS_ARG | OPT_INT | OPT_EXPERT | OPT_OFFSET |
1977
+                        OPT_OUTPUT,                                  { .off = OFFSET(chapters_input_file) },
1971 1978
         "set chapters mapping", "input_file_index" },
1972
-    { "t",              HAS_ARG | OPT_TIME | OPT_OFFSET,             { .off = OFFSET(recording_time) },
1979
+    { "t",              HAS_ARG | OPT_TIME | OPT_OFFSET | OPT_OUTPUT, { .off = OFFSET(recording_time) },
1973 1980
         "record or transcode \"duration\" seconds of audio/video",
1974 1981
         "duration" },
1975
-    { "fs",             HAS_ARG | OPT_INT64 | OPT_OFFSET,            { .off = OFFSET(limit_filesize) },
1982
+    { "fs",             HAS_ARG | OPT_INT64 | OPT_OFFSET | OPT_OUTPUT, { .off = OFFSET(limit_filesize) },
1976 1983
         "set the limit file size in bytes", "limit_size" },
1977
-    { "ss",             HAS_ARG | OPT_TIME | OPT_OFFSET,             { .off = OFFSET(start_time) },
1984
+    { "ss",             HAS_ARG | OPT_TIME | OPT_OFFSET |
1985
+                        OPT_INPUT | OPT_OUTPUT,                      { .off = OFFSET(start_time) },
1978 1986
         "set the start time offset", "time_off" },
1979
-    { "itsoffset",      HAS_ARG | OPT_TIME | OPT_OFFSET | OPT_EXPERT,{ .off = OFFSET(input_ts_offset) },
1987
+    { "itsoffset",      HAS_ARG | OPT_TIME | OPT_OFFSET |
1988
+                        OPT_EXPERT | OPT_INPUT,                      { .off = OFFSET(input_ts_offset) },
1980 1989
         "set the input ts offset", "time_off" },
1981
-    { "itsscale",       HAS_ARG | OPT_DOUBLE | OPT_SPEC | OPT_EXPERT,{ .off = OFFSET(ts_scale) },
1990
+    { "itsscale",       HAS_ARG | OPT_DOUBLE | OPT_SPEC |
1991
+                        OPT_EXPERT | OPT_INPUT,                      { .off = OFFSET(ts_scale) },
1982 1992
         "set the input ts scale", "scale" },
1983
-    { "metadata",       HAS_ARG | OPT_STRING | OPT_SPEC,             { .off = OFFSET(metadata) },
1993
+    { "metadata",       HAS_ARG | OPT_STRING | OPT_SPEC | OPT_OUTPUT, { .off = OFFSET(metadata) },
1984 1994
         "add metadata", "string=string" },
1985
-    { "dframes",        HAS_ARG | OPT_PERFILE | OPT_EXPERT,          { .func_arg = opt_data_frames },
1995
+    { "dframes",        HAS_ARG | OPT_PERFILE | OPT_EXPERT |
1996
+                        OPT_OUTPUT,                                  { .func_arg = opt_data_frames },
1986 1997
         "set the number of data frames to record", "number" },
1987 1998
     { "benchmark",      OPT_BOOL | OPT_EXPERT,                       { &do_benchmark },
1988 1999
         "add timings for benchmarking" },
... ...
@@ -1992,9 +2003,10 @@ const OptionDef options[] = {
1992 1992
         "dump each input packet" },
1993 1993
     { "hex",            OPT_BOOL | OPT_EXPERT,                       { &do_hex_dump },
1994 1994
         "when dumping packets, also dump the payload" },
1995
-    { "re",             OPT_BOOL | OPT_EXPERT | OPT_OFFSET,          { .off = OFFSET(rate_emu) },
1995
+    { "re",             OPT_BOOL | OPT_EXPERT | OPT_OFFSET |
1996
+                        OPT_INPUT,                                   { .off = OFFSET(rate_emu) },
1996 1997
         "read input at native frame rate", "" },
1997
-    { "target",         HAS_ARG | OPT_PERFILE,                       { .func_arg = opt_target },
1998
+    { "target",         HAS_ARG | OPT_PERFILE | OPT_OUTPUT,          { .func_arg = opt_target },
1998 1999
         "specify target file type (\"vcd\", \"svcd\", \"dvd\","
1999 2000
         " \"dv\", \"dv50\", \"pal-vcd\", \"ntsc-svcd\", ...)", "type" },
2000 2001
     { "vsync",          HAS_ARG | OPT_EXPERT,                        { opt_vsync },
... ...
@@ -2007,57 +2019,71 @@ const OptionDef options[] = {
2007 2007
         "copy timestamps" },
2008 2008
     { "copytb",         OPT_BOOL | OPT_EXPERT,                       { &copy_tb },
2009 2009
         "copy input stream time base when stream copying" },
2010
-    { "shortest",       OPT_BOOL | OPT_EXPERT | OPT_OFFSET,          { .off = OFFSET(shortest) },
2010
+    { "shortest",       OPT_BOOL | OPT_EXPERT | OPT_OFFSET |
2011
+                        OPT_OUTPUT,                                  { .off = OFFSET(shortest) },
2011 2012
         "finish encoding within shortest input" },
2012 2013
     { "dts_delta_threshold", HAS_ARG | OPT_FLOAT | OPT_EXPERT,       { &dts_delta_threshold },
2013 2014
         "timestamp discontinuity delta threshold", "threshold" },
2014 2015
     { "xerror",         OPT_BOOL | OPT_EXPERT,                       { &exit_on_error },
2015 2016
         "exit on error", "error" },
2016
-    { "copyinkf",       OPT_BOOL | OPT_EXPERT | OPT_SPEC,            { .off = OFFSET(copy_initial_nonkeyframes) },
2017
+    { "copyinkf",       OPT_BOOL | OPT_EXPERT | OPT_SPEC |
2018
+                        OPT_OUTPUT,                                  { .off = OFFSET(copy_initial_nonkeyframes) },
2017 2019
         "copy initial non-keyframes" },
2018
-    { "frames",         OPT_INT64 | HAS_ARG | OPT_SPEC,              { .off = OFFSET(max_frames) },
2020
+    { "frames",         OPT_INT64 | HAS_ARG | OPT_SPEC | OPT_OUTPUT, { .off = OFFSET(max_frames) },
2019 2021
         "set the number of frames to record", "number" },
2020
-    { "tag",            OPT_STRING | HAS_ARG | OPT_SPEC | OPT_EXPERT,{ .off = OFFSET(codec_tags) },
2022
+    { "tag",            OPT_STRING | HAS_ARG | OPT_SPEC |
2023
+                        OPT_EXPERT | OPT_OUTPUT,                     { .off = OFFSET(codec_tags) },
2021 2024
         "force codec tag/fourcc", "fourcc/tag" },
2022
-    { "q",              HAS_ARG | OPT_EXPERT | OPT_DOUBLE | OPT_SPEC,{ .off = OFFSET(qscale) },
2025
+    { "q",              HAS_ARG | OPT_EXPERT | OPT_DOUBLE |
2026
+                        OPT_SPEC | OPT_OUTPUT,                       { .off = OFFSET(qscale) },
2023 2027
         "use fixed quality scale (VBR)", "q" },
2024
-    { "qscale",         HAS_ARG | OPT_EXPERT | OPT_DOUBLE | OPT_SPEC,{ .off = OFFSET(qscale) },
2028
+    { "qscale",         HAS_ARG | OPT_EXPERT | OPT_DOUBLE |
2029
+                        OPT_SPEC | OPT_OUTPUT,                       { .off = OFFSET(qscale) },
2025 2030
         "use fixed quality scale (VBR)", "q" },
2026
-    { "filter",         HAS_ARG | OPT_STRING | OPT_SPEC,             { .off = OFFSET(filters) },
2031
+    { "filter",         HAS_ARG | OPT_STRING | OPT_SPEC | OPT_OUTPUT, { .off = OFFSET(filters) },
2027 2032
         "set stream filterchain", "filter_list" },
2028 2033
     { "filter_complex", HAS_ARG | OPT_EXPERT,                        { .func_arg = opt_filter_complex },
2029 2034
         "create a complex filtergraph", "graph_description" },
2030 2035
     { "stats",          OPT_BOOL,                                    { &print_stats },
2031 2036
         "print progress report during encoding", },
2032
-    { "attach",         HAS_ARG | OPT_PERFILE | OPT_EXPERT,          { .func_arg = opt_attach },
2037
+    { "attach",         HAS_ARG | OPT_PERFILE | OPT_EXPERT |
2038
+                        OPT_OUTPUT,                                  { .func_arg = opt_attach },
2033 2039
         "add an attachment to the output file", "filename" },
2034
-    { "dump_attachment", HAS_ARG | OPT_STRING | OPT_SPEC |OPT_EXPERT,{ .off = OFFSET(dump_attachment) },
2040
+    { "dump_attachment", HAS_ARG | OPT_STRING | OPT_SPEC |
2041
+                         OPT_EXPERT | OPT_INPUT,                     { .off = OFFSET(dump_attachment) },
2035 2042
         "extract an attachment into a file", "filename" },
2036 2043
     { "cpuflags",       HAS_ARG | OPT_EXPERT,                        { .func_arg = opt_cpuflags },
2037 2044
         "set CPU flags mask", "mask" },
2038 2045
 
2039 2046
     /* video options */
2040
-    { "vframes",      OPT_VIDEO | HAS_ARG  | OPT_PERFILE,                        { .func_arg = opt_video_frames },
2047
+    { "vframes",      OPT_VIDEO | HAS_ARG  | OPT_PERFILE | OPT_OUTPUT,           { .func_arg = opt_video_frames },
2041 2048
         "set the number of video frames to record", "number" },
2042
-    { "r",            OPT_VIDEO | HAS_ARG  | OPT_STRING | OPT_SPEC,              { .off = OFFSET(frame_rates) },
2049
+    { "r",            OPT_VIDEO | HAS_ARG  | OPT_STRING | OPT_SPEC |
2050
+                      OPT_INPUT | OPT_OUTPUT,                                    { .off = OFFSET(frame_rates) },
2043 2051
         "set frame rate (Hz value, fraction or abbreviation)", "rate" },
2044
-    { "s",            OPT_VIDEO | HAS_ARG  | OPT_STRING | OPT_SPEC,              { .off = OFFSET(frame_sizes) },
2052
+    { "s",            OPT_VIDEO | HAS_ARG  | OPT_STRING | OPT_SPEC |
2053
+                      OPT_INPUT | OPT_OUTPUT,                                    { .off = OFFSET(frame_sizes) },
2045 2054
         "set frame size (WxH or abbreviation)", "size" },
2046
-    { "aspect",       OPT_VIDEO | HAS_ARG  | OPT_STRING | OPT_SPEC,              { .off = OFFSET(frame_aspect_ratios) },
2055
+    { "aspect",       OPT_VIDEO | HAS_ARG  | OPT_STRING | OPT_SPEC |
2056
+                      OPT_OUTPUT,                                                { .off = OFFSET(frame_aspect_ratios) },
2047 2057
         "set aspect ratio (4:3, 16:9 or 1.3333, 1.7777)", "aspect" },
2048
-    { "pix_fmt",      OPT_VIDEO | HAS_ARG | OPT_EXPERT  | OPT_STRING | OPT_SPEC, { .off = OFFSET(frame_pix_fmts) },
2058
+    { "pix_fmt",      OPT_VIDEO | HAS_ARG | OPT_EXPERT  | OPT_STRING | OPT_SPEC |
2059
+                      OPT_INPUT | OPT_OUTPUT,                                    { .off = OFFSET(frame_pix_fmts) },
2049 2060
         "set pixel format", "format" },
2050
-    { "vn",           OPT_VIDEO | OPT_BOOL  | OPT_OFFSET,                        { .off = OFFSET(video_disable) },
2061
+    { "vn",           OPT_VIDEO | OPT_BOOL  | OPT_OFFSET | OPT_OUTPUT,           { .off = OFFSET(video_disable) },
2051 2062
         "disable video" },
2052 2063
     { "vdt",          OPT_VIDEO | OPT_INT | HAS_ARG | OPT_EXPERT ,               { &video_discard },
2053 2064
         "discard threshold", "n" },
2054
-    { "rc_override",  OPT_VIDEO | HAS_ARG | OPT_EXPERT  | OPT_STRING | OPT_SPEC, { .off = OFFSET(rc_overrides) },
2065
+    { "rc_override",  OPT_VIDEO | HAS_ARG | OPT_EXPERT  | OPT_STRING | OPT_SPEC |
2066
+                      OPT_OUTPUT,                                                { .off = OFFSET(rc_overrides) },
2055 2067
         "rate control override for specific intervals", "override" },
2056
-    { "vcodec",       OPT_VIDEO | HAS_ARG  | OPT_PERFILE,                        { .func_arg = opt_video_codec },
2068
+    { "vcodec",       OPT_VIDEO | HAS_ARG  | OPT_PERFILE | OPT_INPUT |
2069
+                      OPT_OUTPUT,                                                { .func_arg = opt_video_codec },
2057 2070
         "force video codec ('copy' to copy stream)", "codec" },
2058
-    { "pass",         OPT_VIDEO | HAS_ARG | OPT_SPEC | OPT_INT,                  { .off = OFFSET(pass) },
2071
+    { "pass",         OPT_VIDEO | HAS_ARG | OPT_SPEC | OPT_INT | OPT_OUTPUT,     { .off = OFFSET(pass) },
2059 2072
         "select the pass number (1 or 2)", "n" },
2060
-    { "passlogfile",  OPT_VIDEO | HAS_ARG | OPT_STRING | OPT_EXPERT | OPT_SPEC,  { .off = OFFSET(passlogfiles) },
2073
+    { "passlogfile",  OPT_VIDEO | HAS_ARG | OPT_STRING | OPT_EXPERT | OPT_SPEC |
2074
+                      OPT_OUTPUT,                                                { .off = OFFSET(passlogfiles) },
2061 2075
         "select two pass log file name prefix", "prefix" },
2062 2076
 #if FF_API_DEINTERLACE
2063 2077
     { "deinterlace",  OPT_VIDEO | OPT_EXPERT ,                                   { .func_arg = opt_deinterlace },
... ...
@@ -2067,73 +2093,86 @@ const OptionDef options[] = {
2067 2067
         "dump video coding statistics to file" },
2068 2068
     { "vstats_file",  OPT_VIDEO | HAS_ARG | OPT_EXPERT ,                         { opt_vstats_file },
2069 2069
         "dump video coding statistics to file", "file" },
2070
-    { "vf",           OPT_VIDEO | HAS_ARG  | OPT_PERFILE,                        { .func_arg = opt_video_filters },
2070
+    { "vf",           OPT_VIDEO | HAS_ARG  | OPT_PERFILE | OPT_OUTPUT,           { .func_arg = opt_video_filters },
2071 2071
         "video filters", "filter list" },
2072
-    { "intra_matrix", OPT_VIDEO | HAS_ARG | OPT_EXPERT  | OPT_STRING | OPT_SPEC, { .off = OFFSET(intra_matrices) },
2072
+    { "intra_matrix", OPT_VIDEO | HAS_ARG | OPT_EXPERT  | OPT_STRING | OPT_SPEC |
2073
+                      OPT_OUTPUT,                                                { .off = OFFSET(intra_matrices) },
2073 2074
         "specify intra matrix coeffs", "matrix" },
2074
-    { "inter_matrix", OPT_VIDEO | HAS_ARG | OPT_EXPERT  | OPT_STRING | OPT_SPEC, { .off = OFFSET(inter_matrices) },
2075
+    { "inter_matrix", OPT_VIDEO | HAS_ARG | OPT_EXPERT  | OPT_STRING | OPT_SPEC |
2076
+                      OPT_OUTPUT,                                                { .off = OFFSET(inter_matrices) },
2075 2077
         "specify inter matrix coeffs", "matrix" },
2076
-    { "top",          OPT_VIDEO | HAS_ARG | OPT_EXPERT  | OPT_INT| OPT_SPEC,     { .off = OFFSET(top_field_first) },
2078
+    { "top",          OPT_VIDEO | HAS_ARG | OPT_EXPERT  | OPT_INT| OPT_SPEC |
2079
+                      OPT_OUTPUT,                                                { .off = OFFSET(top_field_first) },
2077 2080
         "top=1/bottom=0/auto=-1 field first", "" },
2078 2081
     { "dc",           OPT_VIDEO | OPT_INT | HAS_ARG | OPT_EXPERT ,               { &intra_dc_precision },
2079 2082
         "intra_dc_precision", "precision" },
2080
-    { "vtag",         OPT_VIDEO | HAS_ARG | OPT_EXPERT  | OPT_PERFILE,           { .func_arg = opt_video_tag },
2083
+    { "vtag",         OPT_VIDEO | HAS_ARG | OPT_EXPERT  | OPT_PERFILE |
2084
+                      OPT_OUTPUT,                                                { .func_arg = opt_video_tag },
2081 2085
         "force video tag/fourcc", "fourcc/tag" },
2082 2086
     { "qphist",       OPT_VIDEO | OPT_BOOL | OPT_EXPERT ,                        { &qp_hist },
2083 2087
         "show QP histogram" },
2084
-    { "force_fps",    OPT_VIDEO | OPT_BOOL | OPT_EXPERT  | OPT_SPEC,             { .off = OFFSET(force_fps) },
2088
+    { "force_fps",    OPT_VIDEO | OPT_BOOL | OPT_EXPERT  | OPT_SPEC |
2089
+                      OPT_OUTPUT,                                                { .off = OFFSET(force_fps) },
2085 2090
         "force the selected framerate, disable the best supported framerate selection" },
2086
-    { "streamid",     OPT_VIDEO | HAS_ARG | OPT_EXPERT | OPT_PERFILE,            { .func_arg = opt_streamid },
2091
+    { "streamid",     OPT_VIDEO | HAS_ARG | OPT_EXPERT | OPT_PERFILE |
2092
+                      OPT_OUTPUT,                                                { .func_arg = opt_streamid },
2087 2093
         "set the value of an outfile streamid", "streamIndex:value" },
2088
-    { "force_key_frames", OPT_VIDEO | OPT_STRING | HAS_ARG | OPT_EXPERT  | OPT_SPEC,
2089
-        { .off = OFFSET(forced_key_frames) }, "force key frames at specified timestamps", "timestamps" },
2094
+    { "force_key_frames", OPT_VIDEO | OPT_STRING | HAS_ARG | OPT_EXPERT |
2095
+                          OPT_SPEC | OPT_OUTPUT,                                 { .off = OFFSET(forced_key_frames) },
2096
+        "force key frames at specified timestamps", "timestamps" },
2090 2097
 
2091 2098
     /* audio options */
2092
-    { "aframes",        OPT_AUDIO | HAS_ARG  | OPT_PERFILE,                        { .func_arg = opt_audio_frames },
2099
+    { "aframes",        OPT_AUDIO | HAS_ARG  | OPT_PERFILE | OPT_OUTPUT,           { .func_arg = opt_audio_frames },
2093 2100
         "set the number of audio frames to record", "number" },
2094
-    { "aq",             OPT_AUDIO | HAS_ARG  | OPT_PERFILE,                        { .func_arg = opt_audio_qscale },
2101
+    { "aq",             OPT_AUDIO | HAS_ARG  | OPT_PERFILE | OPT_OUTPUT,           { .func_arg = opt_audio_qscale },
2095 2102
         "set audio quality (codec-specific)", "quality", },
2096
-    { "ar",             OPT_AUDIO | HAS_ARG  | OPT_INT | OPT_SPEC,                 { .off = OFFSET(audio_sample_rate) },
2103
+    { "ar",             OPT_AUDIO | HAS_ARG  | OPT_INT | OPT_SPEC |
2104
+                        OPT_INPUT | OPT_OUTPUT,                                    { .off = OFFSET(audio_sample_rate) },
2097 2105
         "set audio sampling rate (in Hz)", "rate" },
2098
-    { "ac",             OPT_AUDIO | HAS_ARG  | OPT_INT | OPT_SPEC,                 { .off = OFFSET(audio_channels) },
2106
+    { "ac",             OPT_AUDIO | HAS_ARG  | OPT_INT | OPT_SPEC |
2107
+                        OPT_INPUT | OPT_OUTPUT,                                    { .off = OFFSET(audio_channels) },
2099 2108
         "set number of audio channels", "channels" },
2100
-    { "an",             OPT_AUDIO | OPT_BOOL | OPT_OFFSET,                         { .off = OFFSET(audio_disable) },
2109
+    { "an",             OPT_AUDIO | OPT_BOOL | OPT_OFFSET | OPT_OUTPUT,            { .off = OFFSET(audio_disable) },
2101 2110
         "disable audio" },
2102
-    { "acodec",         OPT_AUDIO | HAS_ARG  | OPT_PERFILE,                        { .func_arg = opt_audio_codec },
2111
+    { "acodec",         OPT_AUDIO | HAS_ARG  | OPT_PERFILE |
2112
+                        OPT_INPUT | OPT_OUTPUT,                                    { .func_arg = opt_audio_codec },
2103 2113
         "force audio codec ('copy' to copy stream)", "codec" },
2104
-    { "atag",           OPT_AUDIO | HAS_ARG  | OPT_EXPERT | OPT_PERFILE,           { .func_arg = opt_audio_tag },
2114
+    { "atag",           OPT_AUDIO | HAS_ARG  | OPT_EXPERT | OPT_PERFILE |
2115
+                        OPT_OUTPUT,                                                { .func_arg = opt_audio_tag },
2105 2116
         "force audio tag/fourcc", "fourcc/tag" },
2106 2117
     { "vol",            OPT_AUDIO | HAS_ARG  | OPT_INT,                            { &audio_volume },
2107 2118
         "change audio volume (256=normal)" , "volume" },
2108
-    { "sample_fmt",     OPT_AUDIO | HAS_ARG  | OPT_EXPERT | OPT_SPEC | OPT_STRING, { .off = OFFSET(sample_fmts) },
2119
+    { "sample_fmt",     OPT_AUDIO | HAS_ARG  | OPT_EXPERT | OPT_SPEC |
2120
+                        OPT_STRING | OPT_INPUT | OPT_OUTPUT,                       { .off = OFFSET(sample_fmts) },
2109 2121
         "set sample format", "format" },
2110
-    { "channel_layout", OPT_AUDIO | HAS_ARG  | OPT_EXPERT | OPT_PERFILE,           { .func_arg = opt_channel_layout },
2122
+    { "channel_layout", OPT_AUDIO | HAS_ARG  | OPT_EXPERT | OPT_PERFILE |
2123
+                        OPT_INPUT | OPT_OUTPUT,                                    { .func_arg = opt_channel_layout },
2111 2124
         "set channel layout", "layout" },
2112
-    { "af",             OPT_AUDIO | HAS_ARG  | OPT_PERFILE,                        { .func_arg = opt_audio_filters },
2125
+    { "af",             OPT_AUDIO | HAS_ARG  | OPT_PERFILE | OPT_OUTPUT,           { .func_arg = opt_audio_filters },
2113 2126
         "audio filters", "filter list" },
2114 2127
 
2115 2128
     /* subtitle options */
2116
-    { "sn",     OPT_SUBTITLE | OPT_BOOL | OPT_OFFSET, { .off = OFFSET(subtitle_disable) },
2129
+    { "sn",     OPT_SUBTITLE | OPT_BOOL | OPT_OFFSET | OPT_OUTPUT, { .off = OFFSET(subtitle_disable) },
2117 2130
         "disable subtitle" },
2118
-    { "scodec", OPT_SUBTITLE | HAS_ARG  | OPT_PERFILE, { .func_arg = opt_subtitle_codec },
2131
+    { "scodec", OPT_SUBTITLE | HAS_ARG  | OPT_PERFILE | OPT_INPUT | OPT_OUTPUT, { .func_arg = opt_subtitle_codec },
2119 2132
         "force subtitle codec ('copy' to copy stream)", "codec" },
2120
-    { "stag",   OPT_SUBTITLE | HAS_ARG  | OPT_EXPERT  | OPT_PERFILE, { .func_arg = opt_subtitle_tag }
2133
+    { "stag",   OPT_SUBTITLE | HAS_ARG  | OPT_EXPERT  | OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_subtitle_tag }
2121 2134
         , "force subtitle tag/fourcc", "fourcc/tag" },
2122 2135
 
2123 2136
     /* grab options */
2124 2137
     { "isync", OPT_BOOL | OPT_EXPERT, { &input_sync }, "this option is deprecated and does nothing", "" },
2125 2138
 
2126 2139
     /* muxer options */
2127
-    { "muxdelay",   OPT_FLOAT | HAS_ARG | OPT_EXPERT | OPT_OFFSET, { .off = OFFSET(mux_max_delay) },
2140
+    { "muxdelay",   OPT_FLOAT | HAS_ARG | OPT_EXPERT | OPT_OFFSET | OPT_OUTPUT, { .off = OFFSET(mux_max_delay) },
2128 2141
         "set the maximum demux-decode delay", "seconds" },
2129
-    { "muxpreload", OPT_FLOAT | HAS_ARG | OPT_EXPERT | OPT_OFFSET, { .off = OFFSET(mux_preload) },
2142
+    { "muxpreload", OPT_FLOAT | HAS_ARG | OPT_EXPERT | OPT_OFFSET | OPT_OUTPUT, { .off = OFFSET(mux_preload) },
2130 2143
         "set the initial demux-decode delay", "seconds" },
2131 2144
 
2132
-    { "bsf", HAS_ARG | OPT_STRING | OPT_SPEC | OPT_EXPERT, { .off = OFFSET(bitstream_filters) },
2145
+    { "bsf", HAS_ARG | OPT_STRING | OPT_SPEC | OPT_EXPERT | OPT_OUTPUT, { .off = OFFSET(bitstream_filters) },
2133 2146
         "A comma-separated list of bitstream filters", "bitstream_filters" },
2134 2147
 
2135 2148
     /* data codec support */
2136
-    { "dcodec", HAS_ARG | OPT_DATA | OPT_PERFILE | OPT_EXPERT, { .func_arg = opt_data_codec },
2149
+    { "dcodec", HAS_ARG | OPT_DATA | OPT_PERFILE | OPT_EXPERT | OPT_INPUT | OPT_OUTPUT, { .func_arg = opt_data_codec },
2137 2150
         "force data codec ('copy' to copy stream)", "codec" },
2138 2151
 
2139 2152
     { NULL, },
... ...
@@ -351,6 +351,16 @@ int parse_optgroup(void *optctx, OptionGroup *g)
351 351
     for (i = 0; i < g->nb_opts; i++) {
352 352
         Option *o = &g->opts[i];
353 353
 
354
+        if (g->group_def->flags &&
355
+            !(g->group_def->flags & o->opt->flags)) {
356
+            av_log(NULL, AV_LOG_ERROR, "Option %s (%s) cannot be applied to "
357
+                   "%s %s -- you are trying to apply an input option to an "
358
+                   "output file or vice versa. Move this option before the "
359
+                   "file it belongs to.\n", o->key, o->opt->help,
360
+                   g->group_def->name, g->arg);
361
+            return AVERROR(EINVAL);
362
+        }
363
+
354 364
         av_log(NULL, AV_LOG_DEBUG, "Applying option %s (%s) with argument %s.\n",
355 365
                o->key, o->opt->help, o->val);
356 366
 
... ...
@@ -144,6 +144,8 @@ typedef struct OptionDef {
144 144
                                    an int containing element count in the array. */
145 145
 #define OPT_TIME  0x10000
146 146
 #define OPT_DOUBLE 0x20000
147
+#define OPT_INPUT  0x40000
148
+#define OPT_OUTPUT 0x80000
147 149
      union {
148 150
         void *dst_ptr;
149 151
         int (*func_arg)(void *, const char *, const char *);
... ...
@@ -224,6 +226,11 @@ typedef struct OptionGroupDef {
224 224
      * are terminated by a non-option argument (e.g. avconv output files)
225 225
      */
226 226
     const char *sep;
227
+    /**
228
+     * Option flags that must be set on each option that is
229
+     * applied to this group
230
+     */
231
+    int flags;
227 232
 } OptionGroupDef;
228 233
 
229 234
 typedef struct OptionGroup {