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>
This commit is contained in:
205
cmdutils.c
205
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;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user