diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2013-03-12 21:26:13 +0100 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2013-03-12 21:34:24 +0100 |
commit | d64b8540751bf8debab4ebcfad6ff87c61d3c19d (patch) | |
tree | a275f8c86ca44c3fa3743b91702b3f8c8f9fbcff /ffmpeg_opt.c | |
parent | 212b89f8b426d78e1be8be45daaa6604fd0f35c4 (diff) | |
parent | 666fe5da47d127074be7f0e2bac93db6af8b4a30 (diff) | |
download | ffmpeg-d64b8540751bf8debab4ebcfad6ff87c61d3c19d.tar.gz |
Merge commit '666fe5da47d127074be7f0e2bac93db6af8b4a30'
* commit '666fe5da47d127074be7f0e2bac93db6af8b4a30':
atomic: Exclude the unsupported implementation headers from checkheaders
avconv: do not silently ignore unused codec AVOptions.
Conflicts:
ffmpeg_opt.c
Merged-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'ffmpeg_opt.c')
-rw-r--r-- | ffmpeg_opt.c | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/ffmpeg_opt.c b/ffmpeg_opt.c index 196ab3c477..6b3ef3bbd3 100644 --- a/ffmpeg_opt.c +++ b/ffmpeg_opt.c @@ -151,6 +151,24 @@ static void init_options(OptionsContext *o, int is_input) o->chapters_input_file = INT_MAX; } +/* return a copy of the input with the stream specifiers removed from the keys */ +static AVDictionary *strip_specifiers(AVDictionary *dict) +{ + AVDictionaryEntry *e = NULL; + AVDictionary *ret = NULL; + + while ((e = av_dict_get(dict, "", e, AV_DICT_IGNORE_SUFFIX))) { + char *p = strchr(e->key, ':'); + + if (p) + *p = 0; + av_dict_set(&ret, e->key, e->value, 0); + if (p) + *p = ':'; + } + return ret; +} + static int opt_sameq(void *optctx, const char *opt, const char *arg) { av_log(NULL, AV_LOG_ERROR, "Option '%s' was removed. " @@ -705,6 +723,8 @@ static int open_input_file(OptionsContext *o, const char *filename) int64_t timestamp; uint8_t buf[128]; AVDictionary **opts; + AVDictionary *unused_opts = NULL; + AVDictionaryEntry *e = NULL; int orig_nb_streams; // number of streams before avformat_find_stream_info char * video_codec_name = NULL; char * audio_codec_name = NULL; @@ -831,6 +851,39 @@ static int open_input_file(OptionsContext *o, const char *filename) f->nb_streams = ic->nb_streams; f->rate_emu = o->rate_emu; + /* check if all codec options have been used */ + unused_opts = strip_specifiers(o->g->codec_opts); + for (i = f->ist_index; i < nb_input_streams; i++) { + e = NULL; + while ((e = av_dict_get(input_streams[i]->opts, "", e, + AV_DICT_IGNORE_SUFFIX))) + av_dict_set(&unused_opts, e->key, NULL, 0); + } + + e = NULL; + while ((e = av_dict_get(unused_opts, "", e, AV_DICT_IGNORE_SUFFIX))) { + const AVClass *class = avcodec_get_class(); + const AVOption *option = av_opt_find(&class, e->key, NULL, 0, + AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ); + if (!option) + continue; + if (!(option->flags & AV_OPT_FLAG_DECODING_PARAM)) { + av_log(NULL, AV_LOG_ERROR, "Codec AVOption %s (%s) specified for " + "input file #%d (%s) is not a decoding option.\n", e->key, + option->help ? option->help : "", nb_input_files - 1, + filename); + exit(1); + } + + av_log(NULL, AV_LOG_WARNING, "Codec AVOption %s (%s) specified for " + "input file #%d (%s) has not been used for any stream. The most " + "likely reason is either wrong type (e.g. a video option with " + "no video streams) or that it is a private option of some decoder " + "which was not actually used for any stream.\n", e->key, + option->help ? option->help : "", nb_input_files - 1, filename); + } + av_dict_free(&unused_opts); + for (i = 0; i < o->nb_dump_attachment; i++) { int j; @@ -1452,6 +1505,8 @@ static int open_output_file(OptionsContext *o, const char *filename) OutputFile *of; OutputStream *ost; InputStream *ist; + AVDictionary *unused_opts = NULL; + AVDictionaryEntry *e = NULL; if (configure_complex_filters() < 0) { av_log(NULL, AV_LOG_FATAL, "Error configuring filters.\n"); @@ -1701,6 +1756,40 @@ loop_end: of->shortest = o->shortest; av_dict_copy(&of->opts, o->g->format_opts, 0); + + /* check if all codec options have been used */ + unused_opts = strip_specifiers(o->g->codec_opts); + for (i = of->ost_index; i < nb_output_streams; i++) { + e = NULL; + while ((e = av_dict_get(output_streams[i]->opts, "", e, + AV_DICT_IGNORE_SUFFIX))) + av_dict_set(&unused_opts, e->key, NULL, 0); + } + + e = NULL; + while ((e = av_dict_get(unused_opts, "", e, AV_DICT_IGNORE_SUFFIX))) { + const AVClass *class = avcodec_get_class(); + const AVOption *option = av_opt_find(&class, e->key, NULL, 0, + AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ); + if (!option) + continue; + if (!(option->flags & AV_OPT_FLAG_ENCODING_PARAM)) { + av_log(NULL, AV_LOG_ERROR, "Codec AVOption %s (%s) specified for " + "output file #%d (%s) is not an encoding option.\n", e->key, + option->help ? option->help : "", nb_output_files - 1, + filename); + exit(1); + } + + av_log(NULL, AV_LOG_WARNING, "Codec AVOption %s (%s) specified for " + "output file #%d (%s) has not been used for any stream. The most " + "likely reason is either wrong type (e.g. a video option with " + "no video streams) or that it is a private option of some encoder " + "which was not actually used for any stream.\n", e->key, + option->help ? option->help : "", nb_output_files - 1, filename); + } + av_dict_free(&unused_opts); + /* check filename in case of an image number is expected */ if (oc->oformat->flags & AVFMT_NEEDNUMBER) { if (!av_filename_number_test(oc->filename)) { |