diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2011-07-14 20:44:58 +0200 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2011-07-14 20:44:58 +0200 |
commit | 5dc6bd86f0f5cfffb44b47e6e916119f26b12091 (patch) | |
tree | 968252b8209375cdca411921e37bd6c9db66b487 /cmdutils.c | |
parent | 1885824b20a493d25db4b8e5397666e3a68f45f2 (diff) | |
parent | 6cb11979295ae5d3b9bad0965cbd6a06d9c9783b (diff) | |
download | ffmpeg-5dc6bd86f0f5cfffb44b47e6e916119f26b12091.tar.gz |
Merge remote-tracking branch 'qatar/master'
* qatar/master:
APIchanges: fill in missing hashes and dates.
Add an APIChanges entry and bump minor versions for recent changes.
ffmpeg: print the low bitrate warning after the codec is openend.
doxygen: Move function documentation into the macro generating the function.
doxygen: Make sure parameter names match between .c and .h files.
h264: move fill_decode_neighbors()/fill_decode_caches() to h264_mvpred.h
H.264: Add more x86 assembly for 10-bit H.264 predict functions
lavf: fix invalid reads in avformat_find_stream_info()
cmdutils: replace opt_default with opt_default2() and remove set_context_opts
ffmpeg: use new avcodec_open2 and avformat_find_stream_info API.
ffplay: use new avcodec_open2 and avformat_find_stream_info API.
cmdutils: store all codec options in one dict instead of video/audio/sub
ffmpeg: check experimental flag after codec is opened.
ffmpeg: do not set GLOBAL_HEADER flag in the options context
Conflicts:
cmdutils.c
doc/APIchanges
ffmpeg.c
ffplay.c
libavcodec/version.h
libavformat/version.h
libswscale/swscale_unscaled.c
Merged-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'cmdutils.c')
-rw-r--r-- | cmdutils.c | 205 |
1 files changed, 119 insertions, 86 deletions
diff --git a/cmdutils.c b/cmdutils.c index b40817480e..d52895008d 100644 --- a/cmdutils.c +++ b/cmdutils.c @@ -49,13 +49,10 @@ #include <sys/resource.h> #endif -const char **opt_names; -const char **opt_values; -static int opt_name_count; AVCodecContext *avcodec_opts[AVMEDIA_TYPE_NB]; AVFormatContext *avformat_opts; struct SwsContext *sws_opts; -AVDictionary *format_opts, *video_opts, *audio_opts, *sub_opts; +AVDictionary *format_opts, *codec_opts; static const int this_year = 2011; @@ -81,17 +78,8 @@ void uninit_opts(void) sws_freeContext(sws_opts); sws_opts = NULL; #endif - for (i = 0; i < opt_name_count; i++) { - av_freep(&opt_names[i]); - av_freep(&opt_values[i]); - } - av_freep(&opt_names); - av_freep(&opt_values); - opt_name_count = 0; av_dict_free(&format_opts); - av_dict_free(&video_opts); - av_dict_free(&audio_opts); - av_dict_free(&sub_opts); + av_dict_free(&codec_opts); } void log_callback_help(void* ptr, int level, const char* fmt, va_list vl) @@ -297,20 +285,14 @@ unknown_opt: } #define FLAGS (o->type == FF_OPT_TYPE_FLAGS) ? AV_DICT_APPEND : 0 -#define SET_PREFIXED_OPTS(ch, flag, output) \ - if (opt[0] == ch && avcodec_opts[0] && (o = av_opt_find(avcodec_opts[0], opt+1, NULL, flag, 0)))\ - av_dict_set(&output, opt+1, arg, FLAGS); -static int opt_default2(const char *opt, const char *arg) +int opt_default(const char *opt, const char *arg) { const AVOption *o; - if ((o = av_opt_find(avcodec_opts[0], opt, NULL, 0, AV_OPT_SEARCH_CHILDREN))) { - if (o->flags & AV_OPT_FLAG_VIDEO_PARAM) - av_dict_set(&video_opts, opt, arg, FLAGS); - if (o->flags & AV_OPT_FLAG_AUDIO_PARAM) - av_dict_set(&audio_opts, opt, arg, FLAGS); - if (o->flags & AV_OPT_FLAG_SUBTITLE_PARAM) - av_dict_set(&sub_opts, opt, arg, FLAGS); - } else if ((o = av_opt_find(avformat_opts, opt, NULL, 0, AV_OPT_SEARCH_CHILDREN))) + if ((o = av_opt_find(avcodec_opts[0], opt, NULL, 0, AV_OPT_SEARCH_CHILDREN)) || + ((opt[0] == 'v' || opt[0] == 'a' || opt[0] == 's') && + (o = av_opt_find(avcodec_opts[0], opt+1, NULL, 0, 0)))) + av_dict_set(&codec_opts, opt, arg, FLAGS); + else if ((o = av_opt_find(avformat_opts, opt, NULL, 0, AV_OPT_SEARCH_CHILDREN))) av_dict_set(&format_opts, opt, arg, FLAGS); else if ((o = av_opt_find(sws_opts, opt, NULL, 0, AV_OPT_SEARCH_CHILDREN))) { // XXX we only support sws_flags, not arbitrary sws options @@ -321,18 +303,13 @@ static int opt_default2(const char *opt, const char *arg) } } - if (!o) { - SET_PREFIXED_OPTS('v', AV_OPT_FLAG_VIDEO_PARAM, video_opts) - SET_PREFIXED_OPTS('a', AV_OPT_FLAG_AUDIO_PARAM, audio_opts) - SET_PREFIXED_OPTS('s', AV_OPT_FLAG_SUBTITLE_PARAM, sub_opts) - } - if (o) return 0; fprintf(stderr, "Unrecognized option '%s'\n", opt); return AVERROR_OPTION_NOT_FOUND; } - +#if 0 +<<<<<<< HEAD int opt_default(const char *opt, const char *arg){ int type; int ret= 0; @@ -408,6 +385,70 @@ int opt_default(const char *opt, const char *arg){ return 0; } +||||||| merged common ancestors +int opt_default(const char *opt, const char *arg){ + int type; + int ret= 0; + const AVOption *o= NULL; + int opt_types[]={AV_OPT_FLAG_VIDEO_PARAM, AV_OPT_FLAG_AUDIO_PARAM, 0, AV_OPT_FLAG_SUBTITLE_PARAM, 0}; + + for(type=0; *avcodec_opts && type<AVMEDIA_TYPE_NB && ret>= 0; type++){ + const AVOption *o2 = av_opt_find(avcodec_opts[0], opt, NULL, opt_types[type], 0); + if(o2) + ret = av_set_string3(avcodec_opts[type], opt, arg, 1, &o); + } + if(!o && avformat_opts) + ret = av_set_string3(avformat_opts, opt, arg, 1, &o); + if(!o && sws_opts) + ret = av_set_string3(sws_opts, opt, arg, 1, &o); + if(!o){ + if (opt[0] == 'a' && avcodec_opts[AVMEDIA_TYPE_AUDIO]) + ret = av_set_string3(avcodec_opts[AVMEDIA_TYPE_AUDIO], opt+1, arg, 1, &o); + else if(opt[0] == 'v' && avcodec_opts[AVMEDIA_TYPE_VIDEO]) + ret = av_set_string3(avcodec_opts[AVMEDIA_TYPE_VIDEO], opt+1, arg, 1, &o); + else if(opt[0] == 's' && avcodec_opts[AVMEDIA_TYPE_SUBTITLE]) + ret = av_set_string3(avcodec_opts[AVMEDIA_TYPE_SUBTITLE], opt+1, arg, 1, &o); + } + if (o && ret < 0) { + fprintf(stderr, "Invalid value '%s' for option '%s'\n", arg, opt); + exit(1); + } + if (!o) { + AVCodec *p = NULL; + AVOutputFormat *oformat = NULL; + while ((p=av_codec_next(p))){ + const AVClass *c = p->priv_class; + if(c && av_opt_find(&c, opt, NULL, 0, 0)) + break; + } + if (!p) { + while ((oformat = av_oformat_next(oformat))) { + const AVClass *c = oformat->priv_class; + if (c && av_opt_find(&c, opt, NULL, 0, 0)) + break; + } + } + } + + if ((ret = opt_default2(opt, arg)) < 0) + return ret; + +// av_log(NULL, AV_LOG_ERROR, "%s:%s: %f 0x%0X\n", opt, arg, av_get_double(avcodec_opts, opt, NULL), (int)av_get_int(avcodec_opts, opt, NULL)); + + //FIXME we should always use avcodec_opts, ... for storing options so there will not be any need to keep track of what i set over this + opt_values= av_realloc(opt_values, sizeof(void*)*(opt_name_count+1)); + opt_values[opt_name_count]= o ? NULL : av_strdup(arg); + opt_names= av_realloc(opt_names, sizeof(void*)*(opt_name_count+1)); + opt_names[opt_name_count++]= o ? o->name : av_strdup(opt); + + if ((*avcodec_opts && avcodec_opts[0]->debug) || (avformat_opts && avformat_opts->debug)) + av_log_set_level(AV_LOG_DEBUG); + return 0; +} + +======= +>>>>>>> qatar/master +#endif int opt_loglevel(const char *opt, const char *arg) { const struct { const char *name; int level; } log_levels[] = { @@ -456,59 +497,6 @@ int opt_timelimit(const char *opt, const char *arg) return 0; } -static void *alloc_priv_context(int size, const AVClass *class) -{ - void *p = av_mallocz(size); - if (p) { - *(const AVClass **)p = class; - av_opt_set_defaults(p); - } - return p; -} - -void set_context_opts(void *ctx, void *opts_ctx, int flags, AVCodec *codec) -{ - int i; - void *priv_ctx=NULL; - if(!strcmp("AVCodecContext", (*(AVClass**)ctx)->class_name)){ - AVCodecContext *avctx= ctx; - if(codec && codec->priv_class){ - if(!avctx->priv_data && codec->priv_data_size) - avctx->priv_data= alloc_priv_context(codec->priv_data_size, codec->priv_class); - priv_ctx= avctx->priv_data; - } - } else if (!strcmp("AVFormatContext", (*(AVClass**)ctx)->class_name)) { - AVFormatContext *avctx = ctx; - if (avctx->oformat && avctx->oformat->priv_class) { - priv_ctx = avctx->priv_data; - } else if (avctx->iformat && avctx->iformat->priv_class) { - priv_ctx = avctx->priv_data; - } - } - - for(i=0; i<opt_name_count; i++){ - char buf[256]; - const AVOption *opt; - const char *str; - if (priv_ctx) { - if (av_find_opt(priv_ctx, opt_names[i], NULL, flags, flags)) { - if (av_set_string3(priv_ctx, opt_names[i], opt_values[i], 1, NULL) < 0) { - fprintf(stderr, "Invalid value '%s' for option '%s'\n", - opt_values[i], opt_names[i]); - exit(1); - } - } else - goto global; - } else { - global: - str = av_get_string(opts_ctx, opt_names[i], &opt, buf, sizeof(buf)); - /* if an option with name opt_names[i] is present in opts_ctx then str is non-NULL */ - if (str && ((opt->flags & flags) == flags)) - av_set_string3(ctx, opt_names[i], str, 1, NULL); - } - } -} - void print_error(const char *filename, int err) { char errbuf[128]; @@ -934,3 +922,48 @@ FILE *get_preset_file(char *filename, size_t filename_size, return f; } + +AVDictionary *filter_codec_opts(AVDictionary *opts, enum CodecID codec_id, int encoder) +{ + AVDictionary *ret = NULL; + AVDictionaryEntry *t = NULL; + AVCodec *codec = encoder ? avcodec_find_encoder(codec_id) : avcodec_find_decoder(codec_id); + int flags = encoder ? AV_OPT_FLAG_ENCODING_PARAM : AV_OPT_FLAG_DECODING_PARAM; + char prefix = 0; + + if (!codec) + return NULL; + + switch (codec->type) { + case AVMEDIA_TYPE_VIDEO: prefix = 'v'; flags |= AV_OPT_FLAG_VIDEO_PARAM; break; + case AVMEDIA_TYPE_AUDIO: prefix = 'a'; flags |= AV_OPT_FLAG_AUDIO_PARAM; break; + case AVMEDIA_TYPE_SUBTITLE: prefix = 's'; flags |= AV_OPT_FLAG_SUBTITLE_PARAM; break; + } + + while (t = av_dict_get(opts, "", t, AV_DICT_IGNORE_SUFFIX)) { + if (av_opt_find(avcodec_opts[0], t->key, NULL, flags, 0) || + (codec && codec->priv_class && av_opt_find(&codec->priv_class, t->key, NULL, flags, 0))) + av_dict_set(&ret, t->key, t->value, 0); + else if (t->key[0] == prefix && av_opt_find(avcodec_opts[0], t->key+1, NULL, flags, 0)) + av_dict_set(&ret, t->key+1, t->value, 0); + } + return ret; +} + +AVDictionary **setup_find_stream_info_opts(AVFormatContext *s) +{ + int i; + AVDictionary **opts; + + if (!s->nb_streams) + return NULL; + opts = av_mallocz(s->nb_streams * sizeof(*opts)); + if (!opts) { + av_log(NULL, AV_LOG_ERROR, "Could not alloc memory for stream options.\n"); + return NULL; + } + for (i = 0; i < s->nb_streams; i++) + opts[i] = filter_codec_opts(codec_opts, s->streams[i]->codec->codec_id, 0); + return opts; +} + |