summaryrefslogtreecommitdiff
path: root/cmdutils.c
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2011-07-14 20:44:58 +0200
committerMichael Niedermayer <michaelni@gmx.at>2011-07-14 20:44:58 +0200
commit5dc6bd86f0f5cfffb44b47e6e916119f26b12091 (patch)
tree968252b8209375cdca411921e37bd6c9db66b487 /cmdutils.c
parent1885824b20a493d25db4b8e5397666e3a68f45f2 (diff)
parent6cb11979295ae5d3b9bad0965cbd6a06d9c9783b (diff)
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.c205
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;
+}
+