Commit 2905e3ff authored by Michael Niedermayer's avatar Michael Niedermayer

Merge remote-tracking branch 'qatar/master'

* qatar/master:
  lavc: add opt_find to AVCodecContext class.
  h264: Complexify frame num gap shortening code
  intreadwrite.h: fix AV_RL32/AV_RB32 signedness.
  Fix decoding of mpegts streams with h264 video that does *NOT* have b frames
  Add minor bumps and APIChanges entries for lavf private options.
  ffmpeg: deprecate -vc and -tvstd
  ffmpeg: use new avformat_open_* API.
  ffserver: use new avformat_open_* API.
  ffprobe: use new avformat_open_* API.
  ffplay: use new avformat_open_* API.
  cmdutils: add opt_default2().
  dict: add AV_DICT_APPEND flag.
  lavf: add avformat_write_header() as a replacement for av_write_header().
  Deprecate av_open_input_* and remove their uses.
  lavf: add avformat_open_input() as a replacement for av_open_input_*
  AVOptions: add av_opt_find() as a replacement for av_find_opt.
  AVOptions: add av_opt_set_dict() mapping a dictionary struct to a context.
  ffmpeg: don't abuse a global for passing frame size from input to output
  ffmpeg: don't abuse a global for passing pixel format from input to output
  ffmpeg: initialise encoders earlier.

Conflicts:
	cmdutils.c
	doc/APIchanges
	ffmpeg.c
	ffplay.c
	ffprobe.c
	libavcodec/h264.c
	libavformat/avformat.h
	libavformat/utils.c
	libavformat/version.h
	libavutil/avutil.h
Merged-by: 's avatarMichael Niedermayer <michaelni@gmx.at>
parents 44d1b408 78440c00
......@@ -38,6 +38,7 @@
#include "libavutil/parseutils.h"
#include "libavutil/pixdesc.h"
#include "libavutil/eval.h"
#include "libavutil/dict.h"
#include "libavutil/opt.h"
#include "cmdutils.h"
#include "version.h"
......@@ -54,6 +55,7 @@ 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;
static const int this_year = 2011;
......@@ -86,6 +88,10 @@ void uninit_opts(void)
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);
}
void log_callback_help(void* ptr, int level, const char* fmt, va_list vl)
......@@ -290,6 +296,43 @@ 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)
{
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)))
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
int ret = av_set_string3(sws_opts, opt, arg, 1, NULL);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Error setting option %s.\n", opt);
return ret;
}
}
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;
}
int opt_default(const char *opt, const char *arg){
int type;
int ret= 0;
......@@ -322,7 +365,7 @@ int opt_default(const char *opt, const char *arg){
goto out;
for(type=0; *avcodec_opts && type<AVMEDIA_TYPE_NB && ret>= 0; type++){
const AVOption *o2 = av_find_opt(avcodec_opts[0], opt, NULL, opt_types[type], opt_types[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);
}
......@@ -345,11 +388,50 @@ int opt_default(const char *opt, const char *arg){
exit(1);
}
if (!o) {
//<<<<<<< HEAD
fprintf(stderr, "Unrecognized option '%s'\n", opt);
exit(1);
/*||||||| merged common ancestors
AVCodec *p = NULL;
AVOutputFormat *oformat = NULL;
while ((p=av_codec_next(p))){
const AVClass *c = p->priv_class;
if(c && av_find_opt(&c, opt, NULL, 0, 0))
break;
}
if (!p) {
while ((oformat = av_oformat_next(oformat))) {
const AVClass *c = oformat->priv_class;
if (c && av_find_opt(&c, opt, NULL, 0, 0))
break;
}
}
if(!p && !oformat){
fprintf(stderr, "Unrecognized option '%s'\n", opt);
exit(1);
}
=======
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;
}
}
>>>>>>> qatar/master*/
}
out:
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));
opt_values= av_realloc(opt_values, sizeof(void*)*(opt_name_count+1));
......
......@@ -47,6 +47,7 @@ extern const char **opt_names;
extern AVCodecContext *avcodec_opts[AVMEDIA_TYPE_NB];
extern AVFormatContext *avformat_opts;
extern struct SwsContext *sws_opts;
extern AVDictionary *format_opts, *video_opts, *audio_opts, *sub_opts;
/**
* Initialize the cmdutils option system, in particular
......
......@@ -23,6 +23,16 @@ API changes, most recent first:
2011-06-12 - xxxxxxx - lavfi 2.16.0 - avfilter_graph_parse()
Change avfilter_graph_parse() signature.
2011-06-xx - xxxxxxx - lavf 53.2.0 - avformat.h
Add avformat_open_input and avformat_write_header().
Deprecate av_open_input_stream, av_open_input_file,
AVFormatParameters and av_write_header.
2011-06-xx - xxxxxxx - lavu 51.7.0 - opt.h
Add av_opt_set_dict() and av_opt_find().
Deprecate av_find_opt().
Add AV_DICT_APPEND flag.
2011-06-xx - xxxxxxx - lavu 51.6.0 - opt.h
Add av_opt_flag_is_set().
......
......@@ -2261,6 +2261,8 @@ static int transcode(AVFormatContext **output_files,
abort();
}
} else {
if (!ost->enc)
ost->enc = avcodec_find_encoder(ost->st->codec->codec_id);
switch(codec->codec_type) {
case AVMEDIA_TYPE_AUDIO:
ost->fifo= av_fifo_alloc(1024);
......@@ -2272,7 +2274,7 @@ static int transcode(AVFormatContext **output_files,
if (icodec->lowres)
codec->sample_rate >>= icodec->lowres;
}
choose_sample_rate(ost->st, codec->codec);
choose_sample_rate(ost->st, ost->enc);
codec->time_base = (AVRational){1, codec->sample_rate};
if (!codec->channels)
codec->channels = icodec->channels;
......@@ -2287,6 +2289,10 @@ static int transcode(AVFormatContext **output_files,
ost->resample_channels = icodec->channels;
break;
case AVMEDIA_TYPE_VIDEO:
if (codec->pix_fmt == PIX_FMT_NONE)
codec->pix_fmt = icodec->pix_fmt;
choose_pixel_fmt(ost->st, ost->enc);
if (ost->st->codec->pix_fmt == PIX_FMT_NONE) {
fprintf(stderr, "Video pixel format is unknown, stream cannot be encoded\n");
ffmpeg_exit(1);
......@@ -2297,6 +2303,10 @@ static int transcode(AVFormatContext **output_files,
if (ost->video_resample) {
codec->bits_per_raw_sample= frame_bits_per_raw_sample;
}
if (!codec->width || !codec->height) {
codec->width = icodec->width;
codec->height = icodec->height;
}
ost->resample_height = icodec->height;
ost->resample_width = icodec->width;
ost->resample_pix_fmt= icodec->pix_fmt;
......@@ -2305,9 +2315,9 @@ static int transcode(AVFormatContext **output_files,
if (!ost->frame_rate.num)
ost->frame_rate = ist->st->r_frame_rate.num ? ist->st->r_frame_rate : (AVRational){25,1};
if (codec->codec && codec->codec->supported_framerates && !force_fps) {
int idx = av_find_nearest_q_idx(ost->frame_rate, codec->codec->supported_framerates);
ost->frame_rate = codec->codec->supported_framerates[idx];
if (ost->enc && ost->enc->supported_framerates && !force_fps) {
int idx = av_find_nearest_q_idx(ost->frame_rate, ost->enc->supported_framerates);
ost->frame_rate = ost->enc->supported_framerates[idx];
}
codec->time_base = (AVRational){ost->frame_rate.den, ost->frame_rate.num};
......@@ -2375,8 +2385,6 @@ static int transcode(AVFormatContext **output_files,
if (ost->encoding_needed) {
AVCodec *codec = ost->enc;
AVCodecContext *dec = input_streams[ost->source_index].st->codec;
if (!codec)
codec = avcodec_find_encoder(ost->st->codec->codec_id);
if (!codec) {
snprintf(error, sizeof(error), "Encoder (codec id %d) not found for output stream #%d.%d",
ost->st->codec->codec_id, ost->file_index, ost->index);
......@@ -3397,17 +3405,12 @@ static int opt_input_file(const char *opt, const char *filename)
if(!input_codecs[nb_input_codecs-1])
input_codecs[nb_input_codecs-1] = avcodec_find_decoder(dec->codec_id);
set_context_opts(dec, avcodec_opts[AVMEDIA_TYPE_VIDEO], AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM, input_codecs[nb_input_codecs-1]);
frame_height = dec->height;
frame_width = dec->width;
frame_pix_fmt = dec->pix_fmt;
rfps = ic->streams[i]->r_frame_rate.num;
rfps_base = ic->streams[i]->r_frame_rate.den;
if (dec->lowres) {
dec->flags |= CODEC_FLAG_EMU_EDGE;
frame_height >>= dec->lowres;
frame_width >>= dec->lowres;
dec->height = frame_height;
dec->width = frame_width;
dec->height >>= dec->lowres;
dec->width >>= dec->lowres;
}
if(me_threshold)
dec->debug |= FF_DEBUG_MV;
......@@ -3452,9 +3455,12 @@ static int opt_input_file(const char *opt, const char *filename)
input_files[nb_input_files - 1].ctx = ic;
input_files[nb_input_files - 1].ist_index = nb_input_streams - ic->nb_streams;
video_channel = 0;
top_field_first = -1;
video_channel = 0;
frame_rate = (AVRational){0, 0};
frame_pix_fmt = PIX_FMT_NONE;
frame_height = 0;
frame_width = 0;
audio_sample_rate = 0;
audio_channels = 0;
......@@ -3578,8 +3584,6 @@ static void new_video_stream(AVFormatContext *oc, int file_idx)
video_enc->bits_per_raw_sample = frame_bits_per_raw_sample;
st->sample_aspect_ratio = video_enc->sample_aspect_ratio;
choose_pixel_fmt(st, codec);
if (intra_only)
video_enc->gop_size = 0;
if (video_qscale || same_quality) {
......@@ -3985,6 +3989,8 @@ static int opt_output_file(const char *opt, const char *filename)
set_context_opts(oc, avformat_opts, AV_OPT_FLAG_ENCODING_PARAM, NULL);
frame_rate = (AVRational){0, 0};
frame_width = 0;
frame_height = 0;
audio_sample_rate = 0;
audio_channels = 0;
......
......@@ -262,18 +262,18 @@ static void show_format(AVFormatContext *fmt_ctx)
static int open_input_file(AVFormatContext **fmt_ctx_ptr, const char *filename)
{
int err, i;
AVFormatParameters fmt_params;
AVFormatContext *fmt_ctx;
memset(&fmt_params, 0, sizeof(fmt_params));
fmt_params.prealloced_context = 1;
fmt_ctx = avformat_alloc_context();
set_context_opts(fmt_ctx, avformat_opts, AV_OPT_FLAG_DECODING_PARAM, NULL);
AVFormatContext *fmt_ctx = NULL;
AVDictionaryEntry *t;
if ((err = av_open_input_file(&fmt_ctx, filename, iformat, 0, &fmt_params)) < 0) {
if ((err = avformat_open_input(&fmt_ctx, filename, iformat, &format_opts)) < 0) {
print_error(filename, err);
return err;
}
if ((t = av_dict_get(format_opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
return AVERROR_OPTION_NOT_FOUND;
}
/* fill the streams in the format context */
if ((err = av_find_stream_info(fmt_ctx)) < 0) {
......
......@@ -205,7 +205,7 @@ typedef struct FFStream {
char filename[1024]; /* stream filename */
struct FFStream *feed; /* feed we are using (can be null if
coming from file) */
AVFormatParameters *ap_in; /* input parameters */
AVDictionary *in_opts; /* input parameters */
AVInputFormat *ifmt; /* if non NULL, force input format */
AVOutputFormat *fmt;
IPAddressACL *acl;
......@@ -2126,7 +2126,7 @@ static int open_input_stream(HTTPContext *c, const char *info)
{
char buf[128];
char input_filename[1024];
AVFormatContext *s;
AVFormatContext *s = NULL;
int buf_size, i, ret;
int64_t stream_pos;
......@@ -2157,8 +2157,7 @@ static int open_input_stream(HTTPContext *c, const char *info)
return -1;
/* open stream */
if ((ret = av_open_input_file(&s, input_filename, c->stream->ifmt,
buf_size, c->stream->ap_in)) < 0) {
if ((ret = avformat_open_input(&s, input_filename, c->stream->ifmt, &c->stream->in_opts)) < 0) {
http_log("could not open %s: %d\n", input_filename, ret);
return -1;
}
......@@ -2268,8 +2267,7 @@ static int http_prepare_data(HTTPContext *c)
c->fmt_ctx.preload = (int)(0.5*AV_TIME_BASE);
c->fmt_ctx.max_delay = (int)(0.7*AV_TIME_BASE);
av_set_parameters(&c->fmt_ctx, NULL);
if (av_write_header(&c->fmt_ctx) < 0) {
if (avformat_write_header(&c->fmt_ctx, NULL) < 0) {
http_log("Error writing output header\n");
return -1;
}
......@@ -2709,11 +2707,14 @@ static int http_receive_data(HTTPContext *c)
}
} else {
/* We have a header in our hands that contains useful data */
AVFormatContext *s = NULL;
AVFormatContext *s = avformat_alloc_context();
AVIOContext *pb;
AVInputFormat *fmt_in;
int i;
if (!s)
goto fail;
/* use feed output format name to find corresponding input format */
fmt_in = av_find_input_format(feed->fmt->name);
if (!fmt_in)
......@@ -2723,7 +2724,8 @@ static int http_receive_data(HTTPContext *c)
0, NULL, NULL, NULL, NULL);
pb->seekable = 0;
if (av_open_input_stream(&s, pb, c->stream->feed_filename, fmt_in, NULL) < 0) {
s->pb = pb;
if (avformat_open_input(&s, c->stream->feed_filename, fmt_in, NULL) < 0) {
av_free(pb);
goto fail;
}
......@@ -3442,8 +3444,7 @@ static int rtp_new_av_stream(HTTPContext *c,
/* XXX: close stream */
goto fail;
}
av_set_parameters(ctx, NULL);
if (av_write_header(ctx) < 0) {
if (avformat_write_header(ctx, NULL) < 0) {
fail:
if (h)
url_close(h);
......@@ -3597,28 +3598,25 @@ static void extract_mpeg4_header(AVFormatContext *infile)
static void build_file_streams(void)
{
FFStream *stream, *stream_next;
AVFormatContext *infile;
int i, ret;
/* gather all streams */
for(stream = first_stream; stream != NULL; stream = stream_next) {
AVFormatContext *infile = NULL;
stream_next = stream->next;
if (stream->stream_type == STREAM_TYPE_LIVE &&
!stream->feed) {
/* the stream comes from a file */
/* try to open the file */
/* open stream */
stream->ap_in = av_mallocz(sizeof(AVFormatParameters));
if (stream->fmt && !strcmp(stream->fmt->name, "rtp")) {
/* specific case : if transport stream output to RTP,
we use a raw transport stream reader */
stream->ap_in->mpeg2ts_raw = 1;
stream->ap_in->mpeg2ts_compute_pcr = 1;
av_dict_set(&stream->in_opts, "mpeg2ts_compute_pcr", "1", 0);
}
http_log("Opening file '%s'\n", stream->feed_filename);
if ((ret = av_open_input_file(&infile, stream->feed_filename,
stream->ifmt, 0, stream->ap_in)) < 0) {
if ((ret = avformat_open_input(&infile, stream->feed_filename, stream->ifmt, &stream->in_opts)) < 0) {
http_log("Could not open '%s': %d\n", stream->feed_filename, ret);
/* remove stream (no need to spend more time on it) */
fail:
......@@ -3678,10 +3676,10 @@ static void build_feed_streams(void)
if (avio_check(feed->feed_filename, AVIO_FLAG_READ) > 0) {
/* See if it matches */
AVFormatContext *s;
AVFormatContext *s = NULL;
int matches = 0;
if (av_open_input_file(&s, feed->feed_filename, NULL, FFM_PACKET_SIZE, NULL) >= 0) {
if (avformat_open_input(&s, feed->feed_filename, NULL, NULL) >= 0) {
/* Now see if it matches */
if (s->nb_streams == feed->nb_streams) {
matches = 1;
......@@ -3767,8 +3765,7 @@ static void build_feed_streams(void)
s->oformat = feed->fmt;
s->nb_streams = feed->nb_streams;
s->streams = feed->streams;
av_set_parameters(s, NULL);
if (av_write_header(s) < 0) {
if (avformat_write_header(s, NULL) < 0) {
http_log("Container doesn't supports the required parameters\n");
exit(1);
}
......@@ -3944,7 +3941,7 @@ static int ffserver_opt_default(const char *opt, const char *arg,
AVCodecContext *avctx, int type)
{
int ret = 0;
const AVOption *o = av_find_opt(avctx, opt, NULL, type, type);
const AVOption *o = av_opt_find(avctx, opt, NULL, type, 0);
if(o)
ret = av_set_string3(avctx, opt, arg, 1, NULL);
return ret;
......
......@@ -3784,7 +3784,7 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size){
init_get_bits(&s->gb, ptr, bit_length);
ff_h264_decode_seq_parameter_set(h);
if(s->flags& CODEC_FLAG_LOW_DELAY ||
if (s->flags& CODEC_FLAG_LOW_DELAY ||
(h->sps.bitstream_restriction_flag && !h->sps.num_reorder_frames))
s->low_delay=1;
......
......@@ -37,6 +37,25 @@ static const char* context_to_name(void* ptr) {
return "NULL";
}
static const AVOption *opt_find(void *obj, const char *name, const char *unit, int opt_flags, int search_flags)
{
AVCodecContext *s = obj;
AVCodec *c = NULL;
if (s->priv_data) {
if (s->codec->priv_class)
return av_opt_find(s->priv_data, name, unit, opt_flags, search_flags);
return NULL;
}
while ((c = av_codec_next(c))) {
const AVOption *o;
if (c->priv_class && (o = av_opt_find(&c->priv_class, name, unit, opt_flags, search_flags)))
return o;
}
return NULL;
}
#define OFFSET(x) offsetof(AVCodecContext,x)
#define DEFAULT 0 //should be NAN but it does not work as it is not a constant in glibc as required by ANSI/ISO C
//these names are too long to be readable
......@@ -457,7 +476,7 @@ static const AVOption options[]={
#undef D
#undef DEFAULT
static const AVClass av_codec_context_class = { "AVCodecContext", context_to_name, options, LIBAVUTIL_VERSION_INT, OFFSET(log_level_offset) };
static const AVClass av_codec_context_class = { "AVCodecContext", context_to_name, options, LIBAVUTIL_VERSION_INT, OFFSET(log_level_offset), .opt_find = opt_find};
void avcodec_get_context_defaults2(AVCodecContext *s, enum AVMediaType codec_type){
int flags=0;
......
......@@ -92,9 +92,9 @@ static int movie_init(AVFilterContext *ctx)
iformat = movie->format_name ? av_find_input_format(movie->format_name) : NULL;
movie->format_ctx = NULL;
if ((ret = av_open_input_file(&movie->format_ctx, movie->file_name, iformat, 0, NULL)) < 0) {
if ((ret = avformat_open_input(&movie->format_ctx, movie->file_name, iformat, NULL)) < 0) {
av_log(ctx, AV_LOG_ERROR,
"Failed to av_open_input_file '%s'\n", movie->file_name);
"Failed to avformat_open_input '%s'\n", movie->file_name);
return ret;
}
if ((ret = av_find_stream_info(movie->format_ctx)) < 0)
......
......@@ -473,6 +473,11 @@ static int applehttp_read_header(AVFormatContext *s, AVFormatParameters *ap)
if (v->n_segments == 0)
continue;
if (!(v->ctx = avformat_alloc_context())) {
ret = AVERROR(ENOMEM);
goto fail;
}
v->index = i;
v->needed = 1;
v->parent = s;
......@@ -491,8 +496,8 @@ static int applehttp_read_header(AVFormatContext *s, AVFormatParameters *ap)
NULL, 0, 0);
if (ret < 0)
goto fail;
ret = av_open_input_stream(&v->ctx, &v->pb, v->segments[0]->url,
in_fmt, NULL);
v->ctx->pb = &v->pb;
ret = avformat_open_input(&v->ctx, v->segments[0]->url, in_fmt, NULL);
if (ret < 0)
goto fail;
v->stream_offset = stream_offset;
......
......@@ -247,8 +247,8 @@ typedef struct AVFormatParameters {
attribute_deprecated unsigned int mpeg2ts_compute_pcr:1;
attribute_deprecated unsigned int initial_pause:1; /**< Do not begin to play the stream
immediately (RTSP only). */
attribute_deprecated unsigned int prealloced_context:1;
#endif
unsigned int prealloced_context:1;
} AVFormatParameters;
//! Demuxer will use avio_open, no opened file should be provided by the caller.
......@@ -751,10 +751,12 @@ typedef struct AVFormatContext {
#if FF_API_FLAG_RTP_HINT
#define AVFMT_FLAG_RTP_HINT 0x0040 ///< Deprecated, use the -movflags rtphint muxer specific AVOption instead
#endif
#define AVFMT_FLAG_MP4A_LATM 0x0080 ///< Enable RTP MP4A-LATM payload
#define AVFMT_FLAG_CUSTOM_IO 0x0080 ///< The caller has supplied a custom AVIOContext, don't avio_close() it.
#define AVFMT_FLAG_MP4A_LATM 0x8000 ///< Enable RTP MP4A-LATM payload
#define AVFMT_FLAG_SORT_DTS 0x10000 ///< try to interleave outputted packets by dts (using this flag can slow demuxing down)
#define AVFMT_FLAG_PRIV_OPT 0x20000 ///< Enable use of private options by delaying codec open (this could be made default once all code is converted)
#define AVFMT_FLAG_KEEP_SIDE_DATA 0x40000 ///< Dont merge side data but keep it seperate.
int loop_input;
/**
......@@ -1054,11 +1056,13 @@ int av_probe_input_buffer(AVIOContext *pb, AVInputFormat **fmt,
const char *filename, void *logctx,
unsigned int offset, unsigned int max_probe_size);
#if FF_API_FORMAT_PARAMETERS
/**
* Allocate all the structures needed to read an input stream.
* This does not open the needed codecs for decoding the stream[s].
* @deprecated use avformat_open_input instead.
*/
int av_open_input_stream(AVFormatContext **ic_ptr,
attribute_deprecated int av_open_input_stream(AVFormatContext **ic_ptr,
AVIOContext *pb, const char *filename,
AVInputFormat *fmt, AVFormatParameters *ap);
......@@ -1073,11 +1077,35 @@ int av_open_input_stream(AVFormatContext **ic_ptr,
* @param ap Additional parameters needed when opening the file
* (NULL if default).
* @return 0 if OK, AVERROR_xxx otherwise
*
* @deprecated use avformat_open_input instead.
*/
int av_open_input_file(AVFormatContext **ic_ptr, const char *filename,
attribute_deprecated int av_open_input_file(AVFormatContext **ic_ptr, const char *filename,
AVInputFormat *fmt,
int buf_size,
AVFormatParameters *ap);
#endif
/**
* Open an input stream and read the header. The codecs are not opened.
* The stream must be closed with av_close_input_file().
*
* @param ps Pointer to user-supplied AVFormatContext (allocated by avformat_alloc_context).
* May be a pointer to NULL, in which case an AVFormatContext is allocated by this
* function and written into ps.
* Note that a user-supplied AVFormatContext will be freed on failure.
* @param filename Name of the stream to open.
* @param fmt If non-NULL, this parameter forces a specific input format.
* Otherwise the format is autodetected.
* @param options A dictionary filled with AVFormatContext and demuxer-private options.
* On return this parameter will be destroyed and replaced with a dict containing
* options that were not found. May be NULL.
*
* @return 0 on success, a negative AVERROR on failure.
*
* @note If you want to use custom IO, preallocate the format context and set its pb field.
*/
int avformat_open_input(AVFormatContext **ps, const char *filename, AVInputFormat *fmt, AVDictionary **options);
int av_demuxer_open(AVFormatContext *ic, AVFormatParameters *ap);
......@@ -1365,7 +1393,12 @@ int64_t av_gen_search(AVFormatContext *s, int stream_index,
/**
* media file output
*/
#if FF_API_FORMAT_PARAMETERS
/**
* @deprecated pass the options to avformat_write_header directly.
*/
attribute_deprecated int av_set_parameters(AVFormatContext *s, AVFormatParameters *ap);
#endif
/**
* Split a URL string into components.
......@@ -1393,6 +1426,24 @@ void av_url_split(char *proto, int proto_size,
char *path, int path_size,
const char *url);
/**
* Allocate the stream private data and write the stream header to
* an output media file.
*
* @param s Media file handle, must be allocated with avformat_alloc_context().
* Its oformat field must be set to the desired output format;
* Its pb field must be set to an already openened AVIOContext.
* @param options An AVDictionary filled with AVFormatContext and muxer-private options.
* On return this parameter will be destroyed and replaced with a dict containing
* options that were not found. May be NULL.
*
* @return 0 on success, negative AVERROR on failure.
*
* @see av_opt_find, av_dict_set, avio_open, av_oformat_next.
*/
int avformat_write_header(AVFormatContext *s, AVDictionary **options);
#if FF_API_FORMAT_PARAMETERS
/**
* Allocate the stream private data and write the stream header to an
* output media file.
......@@ -1401,8 +1452,11 @@ void av_url_split(char *proto, int proto_size,
*
* @param s media file handle
* @return 0 if OK, AVERROR_xxx on error
*
* @deprecated use avformat_write_header.
*/
int av_write_header(AVFormatContext *s);
attribute_deprecated int av_write_header(AVFormatContext *s);
#endif
/**
* Write a packet to an output media file.
......
......@@ -800,7 +800,11 @@ static int read_gab2_sub(AVStream *st, AVPacket *pkt) {
if (!(sub_demuxer = av_probe_input_format2(&pd, 1, &score)))
goto error;
if (!av_open_input_stream(&ast->sub_ctx, pb, "", sub_demuxer, NULL)) {
if (!(ast->sub_ctx = avformat_alloc_context()))
goto error;
ast->sub_ctx->pb = pb;
if (!avformat_open_input(&ast->sub_ctx, "", sub_demuxer, NULL)) {
av_read_packet(ast->sub_ctx, &ast->sub_pkt);
*st->codec = *ast->sub_ctx->streams[0]->codec;
ast->sub_ctx->streams[0]->codec->extradata = NULL;
......@@ -1393,7 +1397,7 @@ static int avi_read_close(AVFormatContext *s)
if (ast) {
if (ast->sub_ctx) {
av_freep(&ast->sub_ctx->pb);
av_close_input_stream(ast->sub_ctx);
av_close_input_file(ast->sub_ctx);
}
av_free(ast->sub_buffer);
av_free_packet(&ast->sub_pkt);
......
......@@ -33,6 +33,33 @@ static const char* format_to_name(void* ptr)
else return "NULL";
}
static const AVOption *opt_find(void *obj, const char *name, const char *unit, int opt_flags, int search_flags)
{
AVFormatContext *s = obj;
AVInputFormat *ifmt = NULL;
AVOutputFormat *ofmt = NULL;
if (s->priv_data) {
if ((s->iformat && !s->iformat->priv_class) ||
(s->oformat && !s->oformat->priv_class))
return NULL;
return av_opt_find(s->priv_data, name, unit, opt_flags, search_flags);
}
while ((ifmt = av_iformat_next(ifmt))) {
const AVOption *o;
if (ifmt->priv_class && (o = av_opt_find(&ifmt->priv_class, name, unit, opt_flags, search_flags)))
return o;
}
while ((ofmt = av_oformat_next(ofmt))) {
const AVOption *o;
if (ofmt->priv_class && (o = av_opt_find(&ofmt->priv_class, name, unit, opt_flags, search_flags)))
return o;
}
return NULL;
}
#define OFFSET(x) offsetof(AVFormatContext,x)
#define DEFAULT 0 //should be NAN but it does not work as it is not a constant in glibc as required by ANSI/ISO C
//these names are too long to be readable
......@@ -75,6 +102,7 @@ static const AVClass av_format_context_class = {
.item_name = format_to_name,
.option = options,
.version = LIBAVUTIL_VERSION_INT,
.opt_find = opt_find,
};
static void avformat_get_context_defaults(AVFormatContext *s)
......
......@@ -523,7 +523,7 @@ rdt_new_context (void)
{
PayloadContext *rdt = av_mallocz(sizeof(PayloadContext));
av_open_input_stream(&rdt->rmctx, NULL, "", &ff_rdt_demuxer, NULL);
avformat_open_input(&rdt->rmctx, "", &ff_rdt_demuxer, NULL);
return rdt;
}
......@@ -539,7 +539,7 @@ rdt_free_context (PayloadContext *rdt)
av_freep(&rdt->rmst[i]);
}
if (rdt->rmctx)
av_close_input_stream(rdt->rmctx);
av_close_input_file(rdt->rmctx);
av_freep(&rdt->mlti_data);
av_freep(&rdt->rmst);
av_free(rdt);
......
......@@ -107,10 +107,13 @@ int ff_wms_parse_sdp_a_line(AVFormatContext *s, const char *p)
"Failed to fix invalid RTSP-MS/ASF min_pktsize\n");
init_packetizer(&pb, buf, len);
if (rt->asf_ctx) {
av_close_input_stream(rt->asf_ctx);
av_close_input_file(rt->asf_ctx);
rt->asf_ctx = NULL;
}
ret = av_open_input_stream(&rt->asf_ctx, &pb, "", &ff_asf_demuxer, NULL);
if (!(rt->asf_ctx = avformat_alloc_context()))
return AVERROR(ENOMEM);
rt->asf_ctx->pb = &pb;
ret = avformat_open_input(&rt->asf_ctx, "", &ff_asf_demuxer, NULL);
if (ret < 0)
return ret;
av_dict_copy(&s->metadata, rt->asf_ctx->metadata, 0);
......
......@@ -67,7 +67,7 @@ AVFormatContext *ff_rtp_chain_mux_open(AVFormatContext *s, AVStream *st,
ffio_fdopen(&rtpctx->pb, handle);
} else
ffio_open_dyn_packet_buf(&rtpctx->pb, packet_size);
ret = av_write_header(rtpctx);
ret = avformat_write_header(rtpctx, NULL);
if (ret) {
if (handle) {
......
......@@ -52,7 +52,7 @@ static int sap_read_close(AVFormatContext *s)
{
struct SAPState *sap = s->priv_data;
if (sap->sdp_ctx)
av_close_input_stream(sap->sdp_ctx);
av_close_input_file(sap->sdp_ctx);
if (sap->ann_fd)
ffurl_close(sap->ann_fd);
av_freep(&sap->sdp);
......@@ -156,9 +156,8 @@ static int sap_read_header(AVFormatContext *s,
goto fail;
}
sap->sdp_ctx->max_delay = s->max_delay;
ap->prealloced_context = 1;
ret = av_open_input_stream(&sap->sdp_ctx, &sap->sdp_pb, "temp.sdp",
infmt, ap);
sap->sdp_ctx->pb = &sap->sdp_pb;
ret = avformat_open_input(&sap->sdp_ctx, "temp.sdp", infmt, NULL);
if (ret < 0)
goto fail;
if (sap->sdp_ctx->ctx_flags & AVFMTCTX_NOHEADER)
......
This diff is collapsed.
......@@ -24,8 +24,8 @@
#include "libavutil/avutil.h"
#define LIBAVFORMAT_VERSION_MAJOR 53
#define LIBAVFORMAT_VERSION_MINOR 3
#define LIBAVFORMAT_VERSION_MICRO 1
#define LIBAVFORMAT_VERSION_MINOR 4
#define LIBAVFORMAT_VERSION_MICRO 0
#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
LIBAVFORMAT_VERSION_MINOR, \
......
......@@ -40,7 +40,7 @@
#define AV_VERSION(a, b, c) AV_VERSION_DOT(a, b, c)
#define LIBAVUTIL_VERSION_MAJOR 51
#define LIBAVUTIL_VERSION_MINOR 8
#define LIBAVUTIL_VERSION_MINOR 9
#define LIBAVUTIL_VERSION_MICRO 0
#define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \
......@@ -63,6 +63,9 @@
#ifndef FF_API_GET_BITS_PER_SAMPLE_FMT
#define FF_API_GET_BITS_PER_SAMPLE_FMT (LIBAVUTIL_VERSION_MAJOR < 52)
#endif
#ifndef FF_API_FIND_OPT
#define FF_API_FIND_OPT (LIBAVUTIL_VERSION_MAJOR < 52)
#endif
/**
* Return the LIBAVUTIL_VERSION_INT constant.
......
......@@ -19,6 +19,7 @@
*/
#include <strings.h>
#include "avstring.h"
#include "dict.h"
#include "internal.h"
#include "mem.h"
......@@ -51,6 +52,7 @@ int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags
{
AVDictionary *m = *pm;
AVDictionaryEntry *tag = av_dict_get(m, key, NULL, flags);
char *oldval = NULL;
if(!m)
m = *pm = av_mallocz(sizeof(*m));
......@@ -58,6 +60,9 @@ int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags
if(tag) {
if (flags & AV_DICT_DONT_OVERWRITE)
return 0;
if (flags & AV_DICT_APPEND)
oldval = tag->value;
else
av_free(tag->value);
av_free(tag->key);
*tag = m->elems[--m->count];
......@@ -75,6 +80,12 @@ int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags
m->elems[m->count].key = av_strdup(key );
if (flags & AV_DICT_DONT_STRDUP_VAL) {
m->elems[m->count].value = value;
} else if (oldval && flags & AV_DICT_APPEND) {
int len = strlen(oldval) + strlen(value) + 1;
if (!(oldval = av_realloc(oldval, len)))
return AVERROR(ENOMEM);
av_strlcat(oldval, value, len);
m->elems[m->count].value = oldval;
} else
m->elems[m->count].value = av_strdup(value);
m->count++;
......
......@@ -29,6 +29,8 @@
#define AV_DICT_DONT_STRDUP_KEY 4
#define AV_DICT_DONT_STRDUP_VAL 8
#define AV_DICT_DONT_OVERWRITE 16 ///< Don't overwrite existing entries.
#define AV_DICT_APPEND 32 /**< If the entry already exists, append to it. Note that no
delimiter is added, the strings are simply concatenated. */
typedef struct {
char *key;
......
......@@ -230,7 +230,7 @@ union unaligned_16 { uint16_t l; } __attribute__((packed)) av_alias;
#ifndef AV_RB32
# define AV_RB32(x) \
((((const uint8_t*)(x))[0] << 24) | \
(((uint32_t)((const uint8_t*)(x))[0] << 24) | \
(((const uint8_t*)(x))[1] << 16) | \
(((const uint8_t*)(x))[2] << 8) | \
((const uint8_t*)(x))[3])
......@@ -246,7 +246,7 @@ union unaligned_16 { uint16_t l; } __attribute__((packed)) av_alias;
#ifndef AV_RL32
# define AV_RL32(x) \
((((const uint8_t*)(x))[3] << 24) | \
(((uint32_t)((const uint8_t*)(x))[3] << 24) | \
(((const uint8_t*)(x))[2] << 16) | \
(((const uint8_t*)(x))[1] << 8) | \
((const uint8_t*)(x))[0])
......
......@@ -70,6 +70,13 @@ typedef struct {
* can be NULL of course
*/
int parent_log_context_offset;
/**
* A function for extended searching, e.g. in possible
* children objects.
*/
const struct AVOption* (*opt_find)(void *obj, const char *name, const char *unit,
int opt_flags, int search_flags);
} AVClass;
/* av_log API */
......
......@@ -29,7 +29,9 @@
#include "avstring.h"
#include "opt.h"
#include "eval.h"
#include "dict.h"
#if FF_API_FIND_OPT
//FIXME order them and do a bin search
const AVOption *av_find_opt(void *v, const char *name, const char *unit, int mask, int flags)
{
......@@ -41,6 +43,7 @@ const AVOption *av_find_opt(void *v, const char *name, const char *unit, int mas
}
return NULL;
}
#endif
const AVOption *av_next_option(void *obj, const AVOption *last)
{
......@@ -51,7 +54,7 @@ const AVOption *av_next_option(void *obj, const AVOption *last)
static int av_set_number2(void *obj, const char *name, double num, int den, int64_t intnum, const AVOption **o_out)
{
const AVOption *o= av_find_opt(obj, name, NULL, 0, 0);
const AVOption *o = av_opt_find(obj, name, NULL, 0, 0);
void *dst;
if (o_out)
*o_out= o;
......@@ -114,7 +117,7 @@ static int hexchar2int(char c) {
int av_set_string3(void *obj, const char *name, const char *val, int alloc, const AVOption **o_out)
{
int ret;
const AVOption *o= av_find_opt(obj, name, NULL, 0, 0);
const AVOption *o = av_opt_find(obj, name, NULL, 0, 0);
if (o_out)
*o_out = o;
if (!o)
......@@ -161,7 +164,7 @@ int av_set_string3(void *obj, const char *name, const char *val, int alloc, cons
buf[i]=0;
{
const AVOption *o_named= av_find_opt(obj, buf, o->unit, 0, 0);
const AVOption *o_named = av_opt_find(obj, buf, o->unit, 0, 0);
if (o_named && o_named->type == FF_OPT_TYPE_CONST)
d= o_named->default_val.dbl;
else if (!strcmp(buf, "default")) d= o->default_val.dbl;
......@@ -226,7 +229,7 @@ const AVOption *av_set_int(void *obj, const char *name, int64_t n)
*/
const char *av_get_string(void *obj, const char *name, const AVOption **o_out, char *buf, int buf_len)
{
const AVOption *o= av_find_opt(obj, name, NULL, 0, 0);
const AVOption *o = av_opt_find(obj, name, NULL, 0, 0);
void *dst;
uint8_t *bin;
int len, i;
......@@ -259,7 +262,7 @@ const char *av_get_string(void *obj, const char *name, const AVOption **o_out, c
static int av_get_number(void *obj, const char *name, const AVOption **o_out, double *num, int *den, int64_t *intnum)
{
const AVOption *o= av_find_opt(obj, name, NULL, 0, 0);
const AVOption *o = av_opt_find(obj, name, NULL, 0, 0);
void *dst;
if (!o || (o->offset<=0 && o->type != FF_OPT_TYPE_CONST))
goto error;
......@@ -538,6 +541,45 @@ void av_opt_free(void *obj)
av_freep((uint8_t *)obj + o->offset);
}
int av_opt_set_dict(void *obj, AVDictionary **options)
{
AVDictionaryEntry *t = NULL;
AVDictionary *tmp = NULL;
int ret = 0;
while ((t = av_dict_get(*options, "", t, AV_DICT_IGNORE_SUFFIX))) {
ret = av_set_string3(obj, t->key, t->value, 1, NULL);
if (ret == AVERROR_OPTION_NOT_FOUND)
av_dict_set(&tmp, t->key, t->value, 0);
else if (ret < 0) {
av_log(obj, AV_LOG_ERROR, "Error setting option %s to value %s.\n", t->key, t->value);
break;
}
ret = 0;
}
av_dict_free(options);
*options = tmp;
return ret;
}
const AVOption *av_opt_find(void *obj, const char *name, const char *unit,
int opt_flags, int search_flags)
{
AVClass *c = *(AVClass**)obj;
const AVOption *o = NULL;
if (c->opt_find && search_flags & AV_OPT_SEARCH_CHILDREN &&
(o = c->opt_find(obj, name, unit, opt_flags, search_flags)))
return o;
while (o = av_next_option(obj, o)) {
if (!strcmp(o->name, name) && (!unit || (o->unit && !strcmp(o->unit, unit))) &&
(o->flags & opt_flags) == opt_flags)
return o;
}
return NULL;
}
#ifdef TEST
#undef printf
......
......@@ -29,6 +29,7 @@
#include "rational.h"
#include "avutil.h"
#include "dict.h"
enum AVOptionType{
FF_OPT_TYPE_FLAGS,
......@@ -91,6 +92,7 @@ typedef struct AVOption {
const char *unit;
} AVOption;
#if FF_API_FIND_OPT
/**
* Look for an option in obj. Look only for the options which
* have the flags set as specified in mask and flags (that is,
......@@ -102,8 +104,12 @@ typedef struct AVOption {
* @param[in] unit the unit of the option to look for, or any if NULL
* @return a pointer to the option found, or NULL if no option
* has been found
*
* @deprecated use av_opt_find.
*/
attribute_deprecated
const AVOption *av_find_opt(void *obj, const char *name, const char *unit, int mask, int flags);
#endif
/**
* Set the field of obj with the given name to value.
......@@ -191,4 +197,46 @@ void av_opt_free(void *obj);
*/
int av_opt_flag_is_set(void *obj, const char *field_name, const char *flag_name);
/*
* Set all the options from a given dictionary on an object.
*
* @param obj a struct whose first element is a pointer to AVClass
* @param options options to process. This dictionary will be freed and replaced
* by a new one containing all options not found in obj.
* Of course this new dictionary needs to be freed by caller
* with av_dict_free().
*
* @return 0 on success, a negative AVERROR if some option was found in obj,
* but could not be set.
*
* @see av_dict_copy()
*/
int av_opt_set_dict(void *obj, struct AVDictionary **options);
#define AV_OPT_SEARCH_CHILDREN 0x0001 /**< Search in possible children of the
given object first. */
/**
* Look for an option in an object. Consider only options which
* have all the specified flags set.
*
* @param[in] obj A pointer to a struct whose first element is a
* pointer to an AVClass.
* @param[in] name The name of the option to look for.
* @param[in] unit When searching for named constants, name of the unit
* it belongs to.
* @param opt_flags Find only options with all the specified flags set (AV_OPT_FLAG).
* @param search_flags A combination of AV_OPT_SEARCH_*.
*
* @return A pointer to the option found, or NULL if no option
* was found.
*
* @note Options found with AV_OPT_SEARCH_CHILDREN flag may not be settable
* directly with av_set_string3(). Use special calls which take an options
* AVDictionary (e.g. avformat_open_input()) to set options found with this
* flag.
*/
const AVOption *av_opt_find(void *obj, const char *name, const char *unit,
int opt_flags, int search_flags);
#endif /* AVUTIL_OPT_H */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment