* 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>tags/n0.8
| @@ -38,6 +38,7 @@ | |||
| #include "libavutil/parseutils.h" | |||
| #include "libavutil/pixdesc.h" | |||
| #include "libavutil/eval.h" | |||
| #include "libavutil/dict.h" | |||
| #include "libavutil/opt.h" | |||
| #include "cmdutils.h" | |||
| #include "version.h" | |||
| @@ -54,6 +55,7 @@ static int opt_name_count; | |||
| AVCodecContext *avcodec_opts[AVMEDIA_TYPE_NB]; | |||
| AVFormatContext *avformat_opts; | |||
| struct SwsContext *sws_opts; | |||
| AVDictionary *format_opts, *video_opts, *audio_opts, *sub_opts; | |||
| static const int this_year = 2011; | |||
| @@ -86,6 +88,10 @@ void uninit_opts(void) | |||
| av_freep(&opt_names); | |||
| av_freep(&opt_values); | |||
| opt_name_count = 0; | |||
| av_dict_free(&format_opts); | |||
| av_dict_free(&video_opts); | |||
| av_dict_free(&audio_opts); | |||
| av_dict_free(&sub_opts); | |||
| } | |||
| void log_callback_help(void* ptr, int level, const char* fmt, va_list vl) | |||
| @@ -290,6 +296,43 @@ unknown_opt: | |||
| } | |||
| } | |||
| #define FLAGS (o->type == FF_OPT_TYPE_FLAGS) ? AV_DICT_APPEND : 0 | |||
| #define SET_PREFIXED_OPTS(ch, flag, output) \ | |||
| if (opt[0] == ch && avcodec_opts[0] && (o = av_opt_find(avcodec_opts[0], opt+1, NULL, flag, 0)))\ | |||
| av_dict_set(&output, opt+1, arg, FLAGS); | |||
| static int opt_default2(const char *opt, const char *arg) | |||
| { | |||
| const AVOption *o; | |||
| if ((o = av_opt_find(avcodec_opts[0], opt, NULL, 0, AV_OPT_SEARCH_CHILDREN))) { | |||
| if (o->flags & AV_OPT_FLAG_VIDEO_PARAM) | |||
| av_dict_set(&video_opts, opt, arg, FLAGS); | |||
| if (o->flags & AV_OPT_FLAG_AUDIO_PARAM) | |||
| av_dict_set(&audio_opts, opt, arg, FLAGS); | |||
| if (o->flags & AV_OPT_FLAG_SUBTITLE_PARAM) | |||
| av_dict_set(&sub_opts, opt, arg, FLAGS); | |||
| } else if ((o = av_opt_find(avformat_opts, opt, NULL, 0, AV_OPT_SEARCH_CHILDREN))) | |||
| av_dict_set(&format_opts, opt, arg, FLAGS); | |||
| else if ((o = av_opt_find(sws_opts, opt, NULL, 0, AV_OPT_SEARCH_CHILDREN))) { | |||
| // XXX we only support sws_flags, not arbitrary sws options | |||
| int ret = av_set_string3(sws_opts, opt, arg, 1, NULL); | |||
| if (ret < 0) { | |||
| av_log(NULL, AV_LOG_ERROR, "Error setting option %s.\n", opt); | |||
| return ret; | |||
| } | |||
| } | |||
| if (!o) { | |||
| SET_PREFIXED_OPTS('v', AV_OPT_FLAG_VIDEO_PARAM, video_opts) | |||
| SET_PREFIXED_OPTS('a', AV_OPT_FLAG_AUDIO_PARAM, audio_opts) | |||
| SET_PREFIXED_OPTS('s', AV_OPT_FLAG_SUBTITLE_PARAM, sub_opts) | |||
| } | |||
| if (o) | |||
| return 0; | |||
| fprintf(stderr, "Unrecognized option '%s'\n", opt); | |||
| return AVERROR_OPTION_NOT_FOUND; | |||
| } | |||
| int opt_default(const char *opt, const char *arg){ | |||
| int type; | |||
| int ret= 0; | |||
| @@ -322,7 +365,7 @@ int opt_default(const char *opt, const char *arg){ | |||
| goto out; | |||
| for(type=0; *avcodec_opts && type<AVMEDIA_TYPE_NB && ret>= 0; type++){ | |||
| const AVOption *o2 = av_find_opt(avcodec_opts[0], opt, NULL, opt_types[type], opt_types[type]); | |||
| const AVOption *o2 = av_opt_find(avcodec_opts[0], opt, NULL, opt_types[type], 0); | |||
| if(o2) | |||
| ret = av_set_string3(avcodec_opts[type], opt, arg, 1, &o); | |||
| } | |||
| @@ -345,11 +388,50 @@ int opt_default(const char *opt, const char *arg){ | |||
| exit(1); | |||
| } | |||
| if (!o) { | |||
| //<<<<<<< HEAD | |||
| fprintf(stderr, "Unrecognized option '%s'\n", opt); | |||
| exit(1); | |||
| /*||||||| merged common ancestors | |||
| AVCodec *p = NULL; | |||
| AVOutputFormat *oformat = NULL; | |||
| while ((p=av_codec_next(p))){ | |||
| const AVClass *c = p->priv_class; | |||
| if(c && av_find_opt(&c, opt, NULL, 0, 0)) | |||
| break; | |||
| } | |||
| if (!p) { | |||
| while ((oformat = av_oformat_next(oformat))) { | |||
| const AVClass *c = oformat->priv_class; | |||
| if (c && av_find_opt(&c, opt, NULL, 0, 0)) | |||
| break; | |||
| } | |||
| } | |||
| if(!p && !oformat){ | |||
| fprintf(stderr, "Unrecognized option '%s'\n", opt); | |||
| exit(1); | |||
| } | |||
| ======= | |||
| AVCodec *p = NULL; | |||
| AVOutputFormat *oformat = NULL; | |||
| while ((p=av_codec_next(p))){ | |||
| const AVClass *c = p->priv_class; | |||
| if(c && av_opt_find(&c, opt, NULL, 0, 0)) | |||
| break; | |||
| } | |||
| if (!p) { | |||
| while ((oformat = av_oformat_next(oformat))) { | |||
| const AVClass *c = oformat->priv_class; | |||
| if (c && av_opt_find(&c, opt, NULL, 0, 0)) | |||
| break; | |||
| } | |||
| } | |||
| >>>>>>> qatar/master*/ | |||
| } | |||
| out: | |||
| if ((ret = opt_default2(opt, arg)) < 0) | |||
| return ret; | |||
| // av_log(NULL, AV_LOG_ERROR, "%s:%s: %f 0x%0X\n", opt, arg, av_get_double(avcodec_opts, opt, NULL), (int)av_get_int(avcodec_opts, opt, NULL)); | |||
| opt_values= av_realloc(opt_values, sizeof(void*)*(opt_name_count+1)); | |||
| @@ -47,6 +47,7 @@ extern const char **opt_names; | |||
| extern AVCodecContext *avcodec_opts[AVMEDIA_TYPE_NB]; | |||
| extern AVFormatContext *avformat_opts; | |||
| extern struct SwsContext *sws_opts; | |||
| extern AVDictionary *format_opts, *video_opts, *audio_opts, *sub_opts; | |||
| /** | |||
| * Initialize the cmdutils option system, in particular | |||
| @@ -23,6 +23,16 @@ API changes, most recent first: | |||
| 2011-06-12 - xxxxxxx - lavfi 2.16.0 - avfilter_graph_parse() | |||
| Change avfilter_graph_parse() signature. | |||
| 2011-06-xx - xxxxxxx - lavf 53.2.0 - avformat.h | |||
| Add avformat_open_input and avformat_write_header(). | |||
| Deprecate av_open_input_stream, av_open_input_file, | |||
| AVFormatParameters and av_write_header. | |||
| 2011-06-xx - xxxxxxx - lavu 51.7.0 - opt.h | |||
| Add av_opt_set_dict() and av_opt_find(). | |||
| Deprecate av_find_opt(). | |||
| Add AV_DICT_APPEND flag. | |||
| 2011-06-xx - xxxxxxx - lavu 51.6.0 - opt.h | |||
| Add av_opt_flag_is_set(). | |||
| @@ -2261,6 +2261,8 @@ static int transcode(AVFormatContext **output_files, | |||
| abort(); | |||
| } | |||
| } else { | |||
| if (!ost->enc) | |||
| ost->enc = avcodec_find_encoder(ost->st->codec->codec_id); | |||
| switch(codec->codec_type) { | |||
| case AVMEDIA_TYPE_AUDIO: | |||
| ost->fifo= av_fifo_alloc(1024); | |||
| @@ -2272,7 +2274,7 @@ static int transcode(AVFormatContext **output_files, | |||
| if (icodec->lowres) | |||
| codec->sample_rate >>= icodec->lowres; | |||
| } | |||
| choose_sample_rate(ost->st, codec->codec); | |||
| choose_sample_rate(ost->st, ost->enc); | |||
| codec->time_base = (AVRational){1, codec->sample_rate}; | |||
| if (!codec->channels) | |||
| codec->channels = icodec->channels; | |||
| @@ -2287,6 +2289,10 @@ static int transcode(AVFormatContext **output_files, | |||
| ost->resample_channels = icodec->channels; | |||
| break; | |||
| case AVMEDIA_TYPE_VIDEO: | |||
| if (codec->pix_fmt == PIX_FMT_NONE) | |||
| codec->pix_fmt = icodec->pix_fmt; | |||
| choose_pixel_fmt(ost->st, ost->enc); | |||
| if (ost->st->codec->pix_fmt == PIX_FMT_NONE) { | |||
| fprintf(stderr, "Video pixel format is unknown, stream cannot be encoded\n"); | |||
| ffmpeg_exit(1); | |||
| @@ -2297,6 +2303,10 @@ static int transcode(AVFormatContext **output_files, | |||
| if (ost->video_resample) { | |||
| codec->bits_per_raw_sample= frame_bits_per_raw_sample; | |||
| } | |||
| if (!codec->width || !codec->height) { | |||
| codec->width = icodec->width; | |||
| codec->height = icodec->height; | |||
| } | |||
| ost->resample_height = icodec->height; | |||
| ost->resample_width = icodec->width; | |||
| ost->resample_pix_fmt= icodec->pix_fmt; | |||
| @@ -2305,9 +2315,9 @@ static int transcode(AVFormatContext **output_files, | |||
| if (!ost->frame_rate.num) | |||
| ost->frame_rate = ist->st->r_frame_rate.num ? ist->st->r_frame_rate : (AVRational){25,1}; | |||
| if (codec->codec && codec->codec->supported_framerates && !force_fps) { | |||
| int idx = av_find_nearest_q_idx(ost->frame_rate, codec->codec->supported_framerates); | |||
| ost->frame_rate = codec->codec->supported_framerates[idx]; | |||
| if (ost->enc && ost->enc->supported_framerates && !force_fps) { | |||
| int idx = av_find_nearest_q_idx(ost->frame_rate, ost->enc->supported_framerates); | |||
| ost->frame_rate = ost->enc->supported_framerates[idx]; | |||
| } | |||
| codec->time_base = (AVRational){ost->frame_rate.den, ost->frame_rate.num}; | |||
| @@ -2375,8 +2385,6 @@ static int transcode(AVFormatContext **output_files, | |||
| if (ost->encoding_needed) { | |||
| AVCodec *codec = ost->enc; | |||
| AVCodecContext *dec = input_streams[ost->source_index].st->codec; | |||
| if (!codec) | |||
| codec = avcodec_find_encoder(ost->st->codec->codec_id); | |||
| if (!codec) { | |||
| snprintf(error, sizeof(error), "Encoder (codec id %d) not found for output stream #%d.%d", | |||
| ost->st->codec->codec_id, ost->file_index, ost->index); | |||
| @@ -3397,17 +3405,12 @@ static int opt_input_file(const char *opt, const char *filename) | |||
| if(!input_codecs[nb_input_codecs-1]) | |||
| input_codecs[nb_input_codecs-1] = avcodec_find_decoder(dec->codec_id); | |||
| set_context_opts(dec, avcodec_opts[AVMEDIA_TYPE_VIDEO], AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM, input_codecs[nb_input_codecs-1]); | |||
| frame_height = dec->height; | |||
| frame_width = dec->width; | |||
| frame_pix_fmt = dec->pix_fmt; | |||
| rfps = ic->streams[i]->r_frame_rate.num; | |||
| rfps_base = ic->streams[i]->r_frame_rate.den; | |||
| if (dec->lowres) { | |||
| dec->flags |= CODEC_FLAG_EMU_EDGE; | |||
| frame_height >>= dec->lowres; | |||
| frame_width >>= dec->lowres; | |||
| dec->height = frame_height; | |||
| dec->width = frame_width; | |||
| dec->height >>= dec->lowres; | |||
| dec->width >>= dec->lowres; | |||
| } | |||
| if(me_threshold) | |||
| dec->debug |= FF_DEBUG_MV; | |||
| @@ -3452,9 +3455,12 @@ static int opt_input_file(const char *opt, const char *filename) | |||
| input_files[nb_input_files - 1].ctx = ic; | |||
| input_files[nb_input_files - 1].ist_index = nb_input_streams - ic->nb_streams; | |||
| video_channel = 0; | |||
| top_field_first = -1; | |||
| video_channel = 0; | |||
| frame_rate = (AVRational){0, 0}; | |||
| frame_pix_fmt = PIX_FMT_NONE; | |||
| frame_height = 0; | |||
| frame_width = 0; | |||
| audio_sample_rate = 0; | |||
| audio_channels = 0; | |||
| @@ -3578,8 +3584,6 @@ static void new_video_stream(AVFormatContext *oc, int file_idx) | |||
| video_enc->bits_per_raw_sample = frame_bits_per_raw_sample; | |||
| st->sample_aspect_ratio = video_enc->sample_aspect_ratio; | |||
| choose_pixel_fmt(st, codec); | |||
| if (intra_only) | |||
| video_enc->gop_size = 0; | |||
| if (video_qscale || same_quality) { | |||
| @@ -3985,6 +3989,8 @@ static int opt_output_file(const char *opt, const char *filename) | |||
| set_context_opts(oc, avformat_opts, AV_OPT_FLAG_ENCODING_PARAM, NULL); | |||
| frame_rate = (AVRational){0, 0}; | |||
| frame_width = 0; | |||
| frame_height = 0; | |||
| audio_sample_rate = 0; | |||
| audio_channels = 0; | |||
| @@ -262,18 +262,18 @@ static void show_format(AVFormatContext *fmt_ctx) | |||
| static int open_input_file(AVFormatContext **fmt_ctx_ptr, const char *filename) | |||
| { | |||
| int err, i; | |||
| AVFormatParameters fmt_params; | |||
| AVFormatContext *fmt_ctx; | |||
| memset(&fmt_params, 0, sizeof(fmt_params)); | |||
| fmt_params.prealloced_context = 1; | |||
| fmt_ctx = avformat_alloc_context(); | |||
| set_context_opts(fmt_ctx, avformat_opts, AV_OPT_FLAG_DECODING_PARAM, NULL); | |||
| AVFormatContext *fmt_ctx = NULL; | |||
| AVDictionaryEntry *t; | |||
| if ((err = av_open_input_file(&fmt_ctx, filename, iformat, 0, &fmt_params)) < 0) { | |||
| if ((err = avformat_open_input(&fmt_ctx, filename, iformat, &format_opts)) < 0) { | |||
| print_error(filename, err); | |||
| return err; | |||
| } | |||
| if ((t = av_dict_get(format_opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) { | |||
| av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key); | |||
| return AVERROR_OPTION_NOT_FOUND; | |||
| } | |||
| /* fill the streams in the format context */ | |||
| if ((err = av_find_stream_info(fmt_ctx)) < 0) { | |||
| @@ -205,7 +205,7 @@ typedef struct FFStream { | |||
| char filename[1024]; /* stream filename */ | |||
| struct FFStream *feed; /* feed we are using (can be null if | |||
| coming from file) */ | |||
| AVFormatParameters *ap_in; /* input parameters */ | |||
| AVDictionary *in_opts; /* input parameters */ | |||
| AVInputFormat *ifmt; /* if non NULL, force input format */ | |||
| AVOutputFormat *fmt; | |||
| IPAddressACL *acl; | |||
| @@ -2126,7 +2126,7 @@ static int open_input_stream(HTTPContext *c, const char *info) | |||
| { | |||
| char buf[128]; | |||
| char input_filename[1024]; | |||
| AVFormatContext *s; | |||
| AVFormatContext *s = NULL; | |||
| int buf_size, i, ret; | |||
| int64_t stream_pos; | |||
| @@ -2157,8 +2157,7 @@ static int open_input_stream(HTTPContext *c, const char *info) | |||
| return -1; | |||
| /* open stream */ | |||
| if ((ret = av_open_input_file(&s, input_filename, c->stream->ifmt, | |||
| buf_size, c->stream->ap_in)) < 0) { | |||
| if ((ret = avformat_open_input(&s, input_filename, c->stream->ifmt, &c->stream->in_opts)) < 0) { | |||
| http_log("could not open %s: %d\n", input_filename, ret); | |||
| return -1; | |||
| } | |||
| @@ -2268,8 +2267,7 @@ static int http_prepare_data(HTTPContext *c) | |||
| c->fmt_ctx.preload = (int)(0.5*AV_TIME_BASE); | |||
| c->fmt_ctx.max_delay = (int)(0.7*AV_TIME_BASE); | |||
| av_set_parameters(&c->fmt_ctx, NULL); | |||
| if (av_write_header(&c->fmt_ctx) < 0) { | |||
| if (avformat_write_header(&c->fmt_ctx, NULL) < 0) { | |||
| http_log("Error writing output header\n"); | |||
| return -1; | |||
| } | |||
| @@ -2709,11 +2707,14 @@ static int http_receive_data(HTTPContext *c) | |||
| } | |||
| } else { | |||
| /* We have a header in our hands that contains useful data */ | |||
| AVFormatContext *s = NULL; | |||
| AVFormatContext *s = avformat_alloc_context(); | |||
| AVIOContext *pb; | |||
| AVInputFormat *fmt_in; | |||
| int i; | |||
| if (!s) | |||
| goto fail; | |||
| /* use feed output format name to find corresponding input format */ | |||
| fmt_in = av_find_input_format(feed->fmt->name); | |||
| if (!fmt_in) | |||
| @@ -2723,7 +2724,8 @@ static int http_receive_data(HTTPContext *c) | |||
| 0, NULL, NULL, NULL, NULL); | |||
| pb->seekable = 0; | |||
| if (av_open_input_stream(&s, pb, c->stream->feed_filename, fmt_in, NULL) < 0) { | |||
| s->pb = pb; | |||
| if (avformat_open_input(&s, c->stream->feed_filename, fmt_in, NULL) < 0) { | |||
| av_free(pb); | |||
| goto fail; | |||
| } | |||
| @@ -3442,8 +3444,7 @@ static int rtp_new_av_stream(HTTPContext *c, | |||
| /* XXX: close stream */ | |||
| goto fail; | |||
| } | |||
| av_set_parameters(ctx, NULL); | |||
| if (av_write_header(ctx) < 0) { | |||
| if (avformat_write_header(ctx, NULL) < 0) { | |||
| fail: | |||
| if (h) | |||
| url_close(h); | |||
| @@ -3597,28 +3598,25 @@ static void extract_mpeg4_header(AVFormatContext *infile) | |||
| static void build_file_streams(void) | |||
| { | |||
| FFStream *stream, *stream_next; | |||
| AVFormatContext *infile; | |||
| int i, ret; | |||
| /* gather all streams */ | |||
| for(stream = first_stream; stream != NULL; stream = stream_next) { | |||
| AVFormatContext *infile = NULL; | |||
| stream_next = stream->next; | |||
| if (stream->stream_type == STREAM_TYPE_LIVE && | |||
| !stream->feed) { | |||
| /* the stream comes from a file */ | |||
| /* try to open the file */ | |||
| /* open stream */ | |||
| stream->ap_in = av_mallocz(sizeof(AVFormatParameters)); | |||
| if (stream->fmt && !strcmp(stream->fmt->name, "rtp")) { | |||
| /* specific case : if transport stream output to RTP, | |||
| we use a raw transport stream reader */ | |||
| stream->ap_in->mpeg2ts_raw = 1; | |||
| stream->ap_in->mpeg2ts_compute_pcr = 1; | |||
| av_dict_set(&stream->in_opts, "mpeg2ts_compute_pcr", "1", 0); | |||
| } | |||
| http_log("Opening file '%s'\n", stream->feed_filename); | |||
| if ((ret = av_open_input_file(&infile, stream->feed_filename, | |||
| stream->ifmt, 0, stream->ap_in)) < 0) { | |||
| if ((ret = avformat_open_input(&infile, stream->feed_filename, stream->ifmt, &stream->in_opts)) < 0) { | |||
| http_log("Could not open '%s': %d\n", stream->feed_filename, ret); | |||
| /* remove stream (no need to spend more time on it) */ | |||
| fail: | |||
| @@ -3678,10 +3676,10 @@ static void build_feed_streams(void) | |||
| if (avio_check(feed->feed_filename, AVIO_FLAG_READ) > 0) { | |||
| /* See if it matches */ | |||
| AVFormatContext *s; | |||
| AVFormatContext *s = NULL; | |||
| int matches = 0; | |||
| if (av_open_input_file(&s, feed->feed_filename, NULL, FFM_PACKET_SIZE, NULL) >= 0) { | |||
| if (avformat_open_input(&s, feed->feed_filename, NULL, NULL) >= 0) { | |||
| /* Now see if it matches */ | |||
| if (s->nb_streams == feed->nb_streams) { | |||
| matches = 1; | |||
| @@ -3767,8 +3765,7 @@ static void build_feed_streams(void) | |||
| s->oformat = feed->fmt; | |||
| s->nb_streams = feed->nb_streams; | |||
| s->streams = feed->streams; | |||
| av_set_parameters(s, NULL); | |||
| if (av_write_header(s) < 0) { | |||
| if (avformat_write_header(s, NULL) < 0) { | |||
| http_log("Container doesn't supports the required parameters\n"); | |||
| exit(1); | |||
| } | |||
| @@ -3944,7 +3941,7 @@ static int ffserver_opt_default(const char *opt, const char *arg, | |||
| AVCodecContext *avctx, int type) | |||
| { | |||
| int ret = 0; | |||
| const AVOption *o = av_find_opt(avctx, opt, NULL, type, type); | |||
| const AVOption *o = av_opt_find(avctx, opt, NULL, type, 0); | |||
| if(o) | |||
| ret = av_set_string3(avctx, opt, arg, 1, NULL); | |||
| return ret; | |||
| @@ -3784,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) | |||
| @@ -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; | |||
| } | |||
| // 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; | |||
| err = avformat_open_input(ic_ptr, filename, fmt, &opts); | |||
| *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; | |||
| err = avformat_open_input(ic_ptr, filename, fmt, &opts); | |||
| if (!fmt) { | |||
| /* guess format if no file can be opened */ | |||
| fmt = av_probe_input_format(pd, 0); | |||
| 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 ((ret = init_input(s, filename)) < 0) | |||
| goto fail; | |||
| /* check filename in case an image number is expected */ | |||
| if (s->iformat->flags & AVFMT_NEEDNUMBER) { | |||
| if (!av_filename_number_test(filename)) { | |||
| ret = AVERROR(EINVAL); | |||
| 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) { | |||
| } | |||
| 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; | |||
| } | |||
| } | |||
| /* if still no format found, error */ | |||
| if (!fmt) { | |||
| err = AVERROR_INVALIDDATA; | |||
| goto fail; | |||
| } | |||
| /* e.g. AVFMT_NOFILE formats will not have a AVIOContext */ | |||
| if (s->pb) | |||
| ff_id3v2_read(s, ID3v2_DEFAULT_MAGIC); | |||
| /* check filename in case an image number is expected */ | |||
| if (fmt->flags & AVFMT_NEEDNUMBER) { | |||
| if (!av_filename_number_test(filename)) { | |||
| err = AVERROR(EINVAL); | |||
| 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; | |||
| } | |||
| err = av_open_input_stream(ic_ptr, pb, filename, fmt, ap); | |||
| if (err) | |||
| goto fail; | |||
| *ps = s; | |||
| 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; | |||
| 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,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++; | |||
| @@ -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; | |||
| @@ -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 { \ | |||
| @@ -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 */ | |||