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: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
Michael Niedermayer 2011-06-18 04:40:18 +02:00
commit 2905e3ff64
26 changed files with 609 additions and 196 deletions

View File

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

View File

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

View File

@ -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().

View File

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

View File

@ -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;
AVFormatContext *fmt_ctx = NULL;
AVDictionaryEntry *t;
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);
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) {

View File

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

View File

@ -3784,8 +3784,8 @@ 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 ||
(h->sps.bitstream_restriction_flag && !h->sps.num_reorder_frames))
if (s->flags& CODEC_FLAG_LOW_DELAY ||
(h->sps.bitstream_restriction_flag && !h->sps.num_reorder_frames))
s->low_delay=1;
if(avctx->has_b_frames < 2)

View File

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

View File

@ -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)

View File

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

View File

@ -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.

View 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);

View File

@ -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)

View File

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

View File

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

View File

@ -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) {

View File

@ -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)

View File

@ -28,6 +28,7 @@
#include "libavcodec/raw.h"
#include "libavutil/opt.h"
#include "libavutil/dict.h"
#include "libavutil/pixdesc.h"
#include "metadata.h"
#include "id3v2.h"
#include "libavutil/avstring.h"
@ -393,6 +394,47 @@ static int set_codec_from_probe_data(AVFormatContext *s, AVStream *st, AVProbeDa
/************************************************************/
/* input media file */
#if FF_API_FORMAT_PARAMETERS
static AVDictionary *convert_format_parameters(AVFormatParameters *ap)
{
char buf[1024];
AVDictionary *opts = NULL;
if (ap->time_base.num) {
snprintf(buf, sizeof(buf), "%d/%d", ap->time_base.den, ap->time_base.num);
av_dict_set(&opts, "framerate", buf, 0);
}
if (ap->sample_rate) {
snprintf(buf, sizeof(buf), "%d", ap->sample_rate);
av_dict_set(&opts, "sample_rate", buf, 0);
}
if (ap->channels) {
snprintf(buf, sizeof(buf), "%d", ap->channels);
av_dict_set(&opts, "channels", buf, 0);
}
if (ap->width || ap->height) {
snprintf(buf, sizeof(buf), "%dx%d", ap->width, ap->height);
av_dict_set(&opts, "video_size", buf, 0);
}
if (ap->pix_fmt != PIX_FMT_NONE) {
av_dict_set(&opts, "pixel_format", av_get_pix_fmt_name(ap->pix_fmt), 0);
}
if (ap->channel) {
snprintf(buf, sizeof(buf), "%d", ap->channel);
av_dict_set(&opts, "channel", buf, 0);
}
if (ap->standard) {
av_dict_set(&opts, "standard", ap->standard, 0);
}
if (ap->mpeg2ts_compute_pcr) {
av_dict_set(&opts, "mpeg2ts_compute_pcr", "1", 0);
}
if (ap->initial_pause) {
av_dict_set(&opts, "initial_pause", "1", 0);
}
return opts;
}
/**
* Open a media file from an IO stream. 'fmt' must be specified.
*/
@ -401,6 +443,7 @@ int av_open_input_stream(AVFormatContext **ic_ptr,
AVInputFormat *fmt, AVFormatParameters *ap)
{
int err;
AVDictionary *opts;
AVFormatContext *ic;
AVFormatParameters default_ap;
@ -408,6 +451,7 @@ int av_open_input_stream(AVFormatContext **ic_ptr,
ap=&default_ap;
memset(ap, 0, sizeof(default_ap));
}
opts = convert_format_parameters(ap);
if(!ap->prealloced_context)
ic = avformat_alloc_context();
@ -417,63 +461,15 @@ int av_open_input_stream(AVFormatContext **ic_ptr,
err = AVERROR(ENOMEM);
goto fail;
}
ic->iformat = fmt;
ic->pb = pb;
ic->duration = AV_NOPTS_VALUE;
ic->start_time = AV_NOPTS_VALUE;
av_strlcpy(ic->filename, filename, sizeof(ic->filename));
/* allocate private data */
if (fmt->priv_data_size > 0) {
ic->priv_data = av_mallocz(fmt->priv_data_size);
if (!ic->priv_data) {
err = AVERROR(ENOMEM);
goto fail;
}
if (fmt->priv_class) {
*(const AVClass**)ic->priv_data= fmt->priv_class;
av_opt_set_defaults(ic->priv_data);
}
} else {
ic->priv_data = NULL;
}
err = avformat_open_input(ic_ptr, filename, fmt, &opts);
// e.g. AVFMT_NOFILE formats will not have a AVIOContext
if (ic->pb)
ff_id3v2_read(ic, ID3v2_DEFAULT_MAGIC);
if (!(ic->flags&AVFMT_FLAG_PRIV_OPT) && ic->iformat->read_header) {
err = ic->iformat->read_header(ic, ap);
if (err < 0)
goto fail;
}
if (!(ic->flags&AVFMT_FLAG_PRIV_OPT) && pb && !ic->data_offset)
ic->data_offset = avio_tell(ic->pb);
ic->raw_packet_buffer_remaining_size = RAW_PACKET_BUFFER_SIZE;
*ic_ptr = ic;
return 0;
fail:
if (ic) {
int i;
av_freep(&ic->priv_data);
for(i=0;i<ic->nb_streams;i++) {
AVStream *st = ic->streams[i];
if (st) {
av_free(st->priv_data);
av_free(st->codec->extradata);
av_free(st->codec);
av_free(st->info);
}
av_free(st);
}
}
av_free(ic);
*ic_ptr = NULL;
fail:
av_dict_free(&opts);
return err;
}
#endif
int av_demuxer_open(AVFormatContext *ic, AVFormatParameters *ap){
int err;
@ -562,68 +558,124 @@ int av_probe_input_buffer(AVIOContext *pb, AVInputFormat **fmt,
return ret;
}
#if FF_API_FORMAT_PARAMETERS
int av_open_input_file(AVFormatContext **ic_ptr, const char *filename,
AVInputFormat *fmt,
int buf_size,
AVFormatParameters *ap)
{
int err;
AVProbeData probe_data, *pd = &probe_data;
AVIOContext *pb = NULL;
void *logctx= ap && ap->prealloced_context ? *ic_ptr : NULL;
AVDictionary *opts = convert_format_parameters(ap);
pd->filename = "";
if (filename)
pd->filename = filename;
pd->buf = NULL;
pd->buf_size = 0;
if (!ap->prealloced_context)
*ic_ptr = NULL;
if (!fmt) {
/* guess format if no file can be opened */
fmt = av_probe_input_format(pd, 0);
err = avformat_open_input(ic_ptr, filename, fmt, &opts);
av_dict_free(&opts);
return err;
}
#endif
/* open input file and probe the format if necessary */
static int init_input(AVFormatContext *s, const char *filename)
{
int ret;
AVProbeData pd = {filename, NULL, 0};
if (s->pb) {
s->flags |= AVFMT_FLAG_CUSTOM_IO;
if (!s->iformat)
return av_probe_input_buffer(s->pb, &s->iformat, filename, s, 0, 0);
else if (s->iformat->flags & AVFMT_NOFILE)
return AVERROR(EINVAL);
return 0;
}
/* Do not open file if the format does not need it. XXX: specific
hack needed to handle RTSP/TCP */
if (!fmt || !(fmt->flags & AVFMT_NOFILE)) {
/* if no file needed do not try to open one */
if ((err=avio_open(&pb, filename, AVIO_FLAG_READ)) < 0) {
goto fail;
}
if (buf_size > 0) {
ffio_set_buf_size(pb, buf_size);
}
if (!fmt && (err = av_probe_input_buffer(pb, &fmt, filename, logctx, 0, logctx ? (*ic_ptr)->probesize : 0)) < 0) {
goto fail;
}
}
if ( (s->iformat && s->iformat->flags & AVFMT_NOFILE) ||
(!s->iformat && (s->iformat = av_probe_input_format(&pd, 0))))
return 0;
/* if still no format found, error */
if (!fmt) {
err = AVERROR_INVALIDDATA;
if ((ret = avio_open(&s->pb, filename, AVIO_FLAG_READ)) < 0)
return ret;
if (s->iformat)
return 0;
return av_probe_input_buffer(s->pb, &s->iformat, filename, s, 0, 0);
}
int avformat_open_input(AVFormatContext **ps, const char *filename, AVInputFormat *fmt, AVDictionary **options)
{
AVFormatContext *s = *ps;
int ret = 0;
AVFormatParameters ap = { 0 };
AVDictionary *tmp = NULL;
if (!s && !(s = avformat_alloc_context()))
return AVERROR(ENOMEM);
if (fmt)
s->iformat = fmt;
if (options)
av_dict_copy(&tmp, *options, 0);
if ((ret = av_opt_set_dict(s, &tmp)) < 0)
goto fail;
if ((ret = init_input(s, filename)) < 0)
goto fail;
}
/* check filename in case an image number is expected */
if (fmt->flags & AVFMT_NEEDNUMBER) {
if (s->iformat->flags & AVFMT_NEEDNUMBER) {
if (!av_filename_number_test(filename)) {
err = AVERROR(EINVAL);
ret = AVERROR(EINVAL);
goto fail;
}
}
err = av_open_input_stream(ic_ptr, pb, filename, fmt, ap);
if (err)
goto fail;
return 0;
fail:
av_freep(&pd->buf);
if (pb)
avio_close(pb);
if (ap && ap->prealloced_context)
av_free(*ic_ptr);
*ic_ptr = NULL;
return err;
s->duration = s->start_time = AV_NOPTS_VALUE;
av_strlcpy(s->filename, filename, sizeof(s->filename));
/* allocate private data */
if (s->iformat->priv_data_size > 0) {
if (!(s->priv_data = av_mallocz(s->iformat->priv_data_size))) {
ret = AVERROR(ENOMEM);
goto fail;
}
if (s->iformat->priv_class) {
*(const AVClass**)s->priv_data = s->iformat->priv_class;
av_opt_set_defaults(s->priv_data);
if ((ret = av_opt_set_dict(s->priv_data, &tmp)) < 0)
goto fail;
}
}
/* e.g. AVFMT_NOFILE formats will not have a AVIOContext */
if (s->pb)
ff_id3v2_read(s, ID3v2_DEFAULT_MAGIC);
if (!(s->flags&AVFMT_FLAG_PRIV_OPT) && s->iformat->read_header)
if ((ret = s->iformat->read_header(s, &ap)) < 0)
goto fail;
if (!(s->flags&AVFMT_FLAG_PRIV_OPT) && s->pb && !s->data_offset)
s->data_offset = avio_tell(s->pb);
s->raw_packet_buffer_remaining_size = RAW_PACKET_BUFFER_SIZE;
if (options) {
av_dict_free(options);
*options = tmp;
}
*ps = s;
return 0;
fail:
av_dict_free(&tmp);
if (s->pb && !(s->flags & AVFMT_FLAG_CUSTOM_IO))
avio_close(s->pb);
avformat_free_context(s);
*ps = NULL;
return ret;
}
/*******************************************************/
@ -2615,7 +2667,8 @@ void avformat_free_context(AVFormatContext *s)
void av_close_input_file(AVFormatContext *s)
{
AVIOContext *pb = s->iformat->flags & AVFMT_NOFILE ? NULL : s->pb;
AVIOContext *pb = (s->iformat->flags & AVFMT_NOFILE) || (s->flags & AVFMT_FLAG_CUSTOM_IO) ?
NULL : s->pb;
av_close_input_stream(s);
if (pb)
avio_close(pb);
@ -2722,6 +2775,7 @@ AVChapter *ff_new_chapter(AVFormatContext *s, int id, AVRational time_base, int6
/************************************************************/
/* output media file */
#if FF_API_FORMAT_PARAMETERS
int av_set_parameters(AVFormatContext *s, AVFormatParameters *ap)
{
if (s->oformat->priv_data_size > 0) {
@ -2737,6 +2791,7 @@ int av_set_parameters(AVFormatContext *s, AVFormatParameters *ap)
return 0;
}
#endif
int avformat_alloc_output_context2(AVFormatContext **avctx, AVOutputFormat *oformat,
const char *format, const char *filename)
@ -2834,15 +2889,29 @@ static int validate_codec_tag(AVFormatContext *s, AVStream *st)
return 1;
}
#if FF_API_FORMAT_PARAMETERS
int av_write_header(AVFormatContext *s)
{
int ret, i;
return avformat_write_header(s, NULL);
}
#endif
int avformat_write_header(AVFormatContext *s, AVDictionary **options)
{
int ret = 0, i;
AVStream *st;
AVDictionary *tmp = NULL;
if (options)
av_dict_copy(&tmp, *options, 0);
if ((ret = av_opt_set_dict(s, &tmp)) < 0)
goto fail;
// some sanity checks
if (s->nb_streams == 0 && !(s->oformat->flags & AVFMT_NOSTREAMS)) {
av_log(s, AV_LOG_ERROR, "no streams\n");
return AVERROR(EINVAL);
ret = AVERROR(EINVAL);
goto fail;
}
for(i=0;i<s->nb_streams;i++) {
@ -2852,7 +2921,8 @@ int av_write_header(AVFormatContext *s)
case AVMEDIA_TYPE_AUDIO:
if(st->codec->sample_rate<=0){
av_log(s, AV_LOG_ERROR, "sample rate not set\n");
return AVERROR(EINVAL);
ret = AVERROR(EINVAL);
goto fail;
}
if(!st->codec->block_align)
st->codec->block_align = st->codec->channels *
@ -2861,15 +2931,18 @@ int av_write_header(AVFormatContext *s)
case AVMEDIA_TYPE_VIDEO:
if(st->codec->time_base.num<=0 || st->codec->time_base.den<=0){ //FIXME audio too?
av_log(s, AV_LOG_ERROR, "time base not set\n");
return AVERROR(EINVAL);
ret = AVERROR(EINVAL);
goto fail;
}
if((st->codec->width<=0 || st->codec->height<=0) && !(s->oformat->flags & AVFMT_NODIMENSIONS)){
av_log(s, AV_LOG_ERROR, "dimensions not set\n");
return AVERROR(EINVAL);
ret = AVERROR(EINVAL);
goto fail;
}
if(av_cmp_q(st->sample_aspect_ratio, st->codec->sample_aspect_ratio)){
av_log(s, AV_LOG_ERROR, "Aspect ratio mismatch between encoder and muxer layer\n");
return AVERROR(EINVAL);
ret = AVERROR(EINVAL);
goto fail;
}
break;
}
@ -2886,7 +2959,8 @@ int av_write_header(AVFormatContext *s)
av_log(s, AV_LOG_ERROR,
"Tag %s/0x%08x incompatible with output codec id '%d'\n",
tagbuf, st->codec->codec_tag, st->codec->codec_id);
return AVERROR_INVALIDDATA;
ret = AVERROR_INVALIDDATA;
goto fail;
}
}else
st->codec->codec_tag= av_codec_get_tag(s->oformat->codec_tag, st->codec->codec_id);
@ -2899,8 +2973,16 @@ int av_write_header(AVFormatContext *s)
if (!s->priv_data && s->oformat->priv_data_size > 0) {
s->priv_data = av_mallocz(s->oformat->priv_data_size);
if (!s->priv_data)
return AVERROR(ENOMEM);
if (!s->priv_data) {
ret = AVERROR(ENOMEM);
goto fail;
}
if (s->oformat->priv_class) {
*(const AVClass**)s->priv_data= s->oformat->priv_class;
av_opt_set_defaults(s->priv_data);
if ((ret = av_opt_set_dict(s->priv_data, &tmp)) < 0)
goto fail;
}
}
/* set muxer identification string */
@ -2911,7 +2993,7 @@ int av_write_header(AVFormatContext *s)
if(s->oformat->write_header){
ret = s->oformat->write_header(s);
if (ret < 0)
return ret;
goto fail;
}
/* init PTS generation */
@ -2930,12 +3012,22 @@ int av_write_header(AVFormatContext *s)
break;
}
if (den != AV_NOPTS_VALUE) {
if (den <= 0)
return AVERROR_INVALIDDATA;
if (den <= 0) {
ret = AVERROR_INVALIDDATA;
goto fail;
}
av_frac_init(&st->pts, 0, 0, den);
}
}
if (options) {
av_dict_free(options);
*options = tmp;
}
return 0;
fail:
av_dict_free(&tmp);
return ret;
}
//FIXME merge with compute_pkt_fields

View File

@ -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, \

View File

@ -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.

View File

@ -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,7 +60,10 @@ int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags
if(tag) {
if (flags & AV_DICT_DONT_OVERWRITE)
return 0;
av_free(tag->value);
if (flags & AV_DICT_APPEND)
oldval = tag->value;
else
av_free(tag->value);
av_free(tag->key);
*tag = m->elems[--m->count];
} else {
@ -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++;

View File

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

View File

@ -229,11 +229,11 @@ union unaligned_16 { uint16_t l; } __attribute__((packed)) av_alias;
#endif
#ifndef AV_RB32
# define AV_RB32(x) \
((((const uint8_t*)(x))[0] << 24) | \
(((const uint8_t*)(x))[1] << 16) | \
(((const uint8_t*)(x))[2] << 8) | \
((const uint8_t*)(x))[3])
# define AV_RB32(x) \
(((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])
#endif
#ifndef AV_WB32
# define AV_WB32(p, d) do { \
@ -245,11 +245,11 @@ union unaligned_16 { uint16_t l; } __attribute__((packed)) av_alias;
#endif
#ifndef AV_RL32
# define AV_RL32(x) \
((((const uint8_t*)(x))[3] << 24) | \
(((const uint8_t*)(x))[2] << 16) | \
(((const uint8_t*)(x))[1] << 8) | \
((const uint8_t*)(x))[0])
# define AV_RL32(x) \
(((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])
#endif
#ifndef AV_WL32
# define AV_WL32(p, d) do { \

View File

@ -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 */

View File

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

View File

@ -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 */