mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
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:
commit
2905e3ff64
84
cmdutils.c
84
cmdutils.c
@ -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().
|
||||
|
||||
|
38
ffmpeg.c
38
ffmpeg.c
@ -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;
|
||||
|
||||
|
16
ffprobe.c
16
ffprobe.c
@ -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) {
|
||||
|
39
ffserver.c
39
ffserver.c
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
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) {
|
||||
if ( (s->iformat && s->iformat->flags & AVFMT_NOFILE) ||
|
||||
(!s->iformat && (s->iformat = av_probe_input_format(&pd, 0))))
|
||||
return 0;
|
||||
|
||||
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 (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 still no format found, error */
|
||||
if (!fmt) {
|
||||
err = AVERROR_INVALIDDATA;
|
||||
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
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user