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:
Michael Niedermayer
2011-07-14 20:44:58 +02:00
26 changed files with 941 additions and 626 deletions

View File

@ -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;
}