* 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/parseutils.h" | ||||
| #include "libavutil/pixdesc.h" | #include "libavutil/pixdesc.h" | ||||
| #include "libavutil/eval.h" | #include "libavutil/eval.h" | ||||
| #include "libavutil/dict.h" | |||||
| #include "libavutil/opt.h" | #include "libavutil/opt.h" | ||||
| #include "cmdutils.h" | #include "cmdutils.h" | ||||
| #include "version.h" | #include "version.h" | ||||
| @@ -54,6 +55,7 @@ static int opt_name_count; | |||||
| AVCodecContext *avcodec_opts[AVMEDIA_TYPE_NB]; | AVCodecContext *avcodec_opts[AVMEDIA_TYPE_NB]; | ||||
| AVFormatContext *avformat_opts; | AVFormatContext *avformat_opts; | ||||
| struct SwsContext *sws_opts; | struct SwsContext *sws_opts; | ||||
| AVDictionary *format_opts, *video_opts, *audio_opts, *sub_opts; | |||||
| static const int this_year = 2011; | static const int this_year = 2011; | ||||
| @@ -86,6 +88,10 @@ void uninit_opts(void) | |||||
| av_freep(&opt_names); | av_freep(&opt_names); | ||||
| av_freep(&opt_values); | av_freep(&opt_values); | ||||
| opt_name_count = 0; | 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) | 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 opt_default(const char *opt, const char *arg){ | ||||
| int type; | int type; | ||||
| int ret= 0; | int ret= 0; | ||||
| @@ -322,7 +365,7 @@ int opt_default(const char *opt, const char *arg){ | |||||
| goto out; | goto out; | ||||
| for(type=0; *avcodec_opts && type<AVMEDIA_TYPE_NB && ret>= 0; type++){ | 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) | if(o2) | ||||
| ret = av_set_string3(avcodec_opts[type], opt, arg, 1, &o); | 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); | exit(1); | ||||
| } | } | ||||
| if (!o) { | if (!o) { | ||||
| //<<<<<<< HEAD | |||||
| fprintf(stderr, "Unrecognized option '%s'\n", opt); | fprintf(stderr, "Unrecognized option '%s'\n", opt); | ||||
| exit(1); | 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: | 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)); | // 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)); | 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 AVCodecContext *avcodec_opts[AVMEDIA_TYPE_NB]; | ||||
| extern AVFormatContext *avformat_opts; | extern AVFormatContext *avformat_opts; | ||||
| extern struct SwsContext *sws_opts; | extern struct SwsContext *sws_opts; | ||||
| extern AVDictionary *format_opts, *video_opts, *audio_opts, *sub_opts; | |||||
| /** | /** | ||||
| * Initialize the cmdutils option system, in particular | * 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() | 2011-06-12 - xxxxxxx - lavfi 2.16.0 - avfilter_graph_parse() | ||||
| Change avfilter_graph_parse() signature. | 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 | 2011-06-xx - xxxxxxx - lavu 51.6.0 - opt.h | ||||
| Add av_opt_flag_is_set(). | Add av_opt_flag_is_set(). | ||||
| @@ -2261,6 +2261,8 @@ static int transcode(AVFormatContext **output_files, | |||||
| abort(); | abort(); | ||||
| } | } | ||||
| } else { | } else { | ||||
| if (!ost->enc) | |||||
| ost->enc = avcodec_find_encoder(ost->st->codec->codec_id); | |||||
| switch(codec->codec_type) { | switch(codec->codec_type) { | ||||
| case AVMEDIA_TYPE_AUDIO: | case AVMEDIA_TYPE_AUDIO: | ||||
| ost->fifo= av_fifo_alloc(1024); | ost->fifo= av_fifo_alloc(1024); | ||||
| @@ -2272,7 +2274,7 @@ static int transcode(AVFormatContext **output_files, | |||||
| if (icodec->lowres) | if (icodec->lowres) | ||||
| codec->sample_rate >>= 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}; | codec->time_base = (AVRational){1, codec->sample_rate}; | ||||
| if (!codec->channels) | if (!codec->channels) | ||||
| codec->channels = icodec->channels; | codec->channels = icodec->channels; | ||||
| @@ -2287,6 +2289,10 @@ static int transcode(AVFormatContext **output_files, | |||||
| ost->resample_channels = icodec->channels; | ost->resample_channels = icodec->channels; | ||||
| break; | break; | ||||
| case AVMEDIA_TYPE_VIDEO: | 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) { | if (ost->st->codec->pix_fmt == PIX_FMT_NONE) { | ||||
| fprintf(stderr, "Video pixel format is unknown, stream cannot be encoded\n"); | fprintf(stderr, "Video pixel format is unknown, stream cannot be encoded\n"); | ||||
| ffmpeg_exit(1); | ffmpeg_exit(1); | ||||
| @@ -2297,6 +2303,10 @@ static int transcode(AVFormatContext **output_files, | |||||
| if (ost->video_resample) { | if (ost->video_resample) { | ||||
| codec->bits_per_raw_sample= frame_bits_per_raw_sample; | 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_height = icodec->height; | ||||
| ost->resample_width = icodec->width; | ost->resample_width = icodec->width; | ||||
| ost->resample_pix_fmt= icodec->pix_fmt; | ost->resample_pix_fmt= icodec->pix_fmt; | ||||
| @@ -2305,9 +2315,9 @@ static int transcode(AVFormatContext **output_files, | |||||
| if (!ost->frame_rate.num) | if (!ost->frame_rate.num) | ||||
| ost->frame_rate = ist->st->r_frame_rate.num ? ist->st->r_frame_rate : (AVRational){25,1}; | 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}; | 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) { | if (ost->encoding_needed) { | ||||
| AVCodec *codec = ost->enc; | AVCodec *codec = ost->enc; | ||||
| AVCodecContext *dec = input_streams[ost->source_index].st->codec; | AVCodecContext *dec = input_streams[ost->source_index].st->codec; | ||||
| if (!codec) | |||||
| codec = avcodec_find_encoder(ost->st->codec->codec_id); | |||||
| if (!codec) { | if (!codec) { | ||||
| snprintf(error, sizeof(error), "Encoder (codec id %d) not found for output stream #%d.%d", | 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); | 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]) | if(!input_codecs[nb_input_codecs-1]) | ||||
| input_codecs[nb_input_codecs-1] = avcodec_find_decoder(dec->codec_id); | 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]); | 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 = ic->streams[i]->r_frame_rate.num; | ||||
| rfps_base = ic->streams[i]->r_frame_rate.den; | rfps_base = ic->streams[i]->r_frame_rate.den; | ||||
| if (dec->lowres) { | if (dec->lowres) { | ||||
| dec->flags |= CODEC_FLAG_EMU_EDGE; | 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) | if(me_threshold) | ||||
| dec->debug |= FF_DEBUG_MV; | 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].ctx = ic; | ||||
| input_files[nb_input_files - 1].ist_index = nb_input_streams - ic->nb_streams; | input_files[nb_input_files - 1].ist_index = nb_input_streams - ic->nb_streams; | ||||
| video_channel = 0; | |||||
| top_field_first = -1; | top_field_first = -1; | ||||
| video_channel = 0; | |||||
| frame_rate = (AVRational){0, 0}; | frame_rate = (AVRational){0, 0}; | ||||
| frame_pix_fmt = PIX_FMT_NONE; | |||||
| frame_height = 0; | |||||
| frame_width = 0; | |||||
| audio_sample_rate = 0; | audio_sample_rate = 0; | ||||
| audio_channels = 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; | video_enc->bits_per_raw_sample = frame_bits_per_raw_sample; | ||||
| st->sample_aspect_ratio = video_enc->sample_aspect_ratio; | st->sample_aspect_ratio = video_enc->sample_aspect_ratio; | ||||
| choose_pixel_fmt(st, codec); | |||||
| if (intra_only) | if (intra_only) | ||||
| video_enc->gop_size = 0; | video_enc->gop_size = 0; | ||||
| if (video_qscale || same_quality) { | 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); | set_context_opts(oc, avformat_opts, AV_OPT_FLAG_ENCODING_PARAM, NULL); | ||||
| frame_rate = (AVRational){0, 0}; | frame_rate = (AVRational){0, 0}; | ||||
| frame_width = 0; | |||||
| frame_height = 0; | |||||
| audio_sample_rate = 0; | audio_sample_rate = 0; | ||||
| audio_channels = 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) | static int open_input_file(AVFormatContext **fmt_ctx_ptr, const char *filename) | ||||
| { | { | ||||
| int err, i; | 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); | print_error(filename, err); | ||||
| return 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 */ | /* fill the streams in the format context */ | ||||
| if ((err = av_find_stream_info(fmt_ctx)) < 0) { | if ((err = av_find_stream_info(fmt_ctx)) < 0) { | ||||
| @@ -205,7 +205,7 @@ typedef struct FFStream { | |||||
| char filename[1024]; /* stream filename */ | char filename[1024]; /* stream filename */ | ||||
| struct FFStream *feed; /* feed we are using (can be null if | struct FFStream *feed; /* feed we are using (can be null if | ||||
| coming from file) */ | coming from file) */ | ||||
| AVFormatParameters *ap_in; /* input parameters */ | |||||
| AVDictionary *in_opts; /* input parameters */ | |||||
| AVInputFormat *ifmt; /* if non NULL, force input format */ | AVInputFormat *ifmt; /* if non NULL, force input format */ | ||||
| AVOutputFormat *fmt; | AVOutputFormat *fmt; | ||||
| IPAddressACL *acl; | IPAddressACL *acl; | ||||
| @@ -2126,7 +2126,7 @@ static int open_input_stream(HTTPContext *c, const char *info) | |||||
| { | { | ||||
| char buf[128]; | char buf[128]; | ||||
| char input_filename[1024]; | char input_filename[1024]; | ||||
| AVFormatContext *s; | |||||
| AVFormatContext *s = NULL; | |||||
| int buf_size, i, ret; | int buf_size, i, ret; | ||||
| int64_t stream_pos; | int64_t stream_pos; | ||||
| @@ -2157,8 +2157,7 @@ static int open_input_stream(HTTPContext *c, const char *info) | |||||
| return -1; | return -1; | ||||
| /* open stream */ | /* 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); | http_log("could not open %s: %d\n", input_filename, ret); | ||||
| return -1; | 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.preload = (int)(0.5*AV_TIME_BASE); | ||||
| c->fmt_ctx.max_delay = (int)(0.7*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"); | http_log("Error writing output header\n"); | ||||
| return -1; | return -1; | ||||
| } | } | ||||
| @@ -2709,11 +2707,14 @@ static int http_receive_data(HTTPContext *c) | |||||
| } | } | ||||
| } else { | } else { | ||||
| /* We have a header in our hands that contains useful data */ | /* We have a header in our hands that contains useful data */ | ||||
| AVFormatContext *s = NULL; | |||||
| AVFormatContext *s = avformat_alloc_context(); | |||||
| AVIOContext *pb; | AVIOContext *pb; | ||||
| AVInputFormat *fmt_in; | AVInputFormat *fmt_in; | ||||
| int i; | int i; | ||||
| if (!s) | |||||
| goto fail; | |||||
| /* use feed output format name to find corresponding input format */ | /* use feed output format name to find corresponding input format */ | ||||
| fmt_in = av_find_input_format(feed->fmt->name); | fmt_in = av_find_input_format(feed->fmt->name); | ||||
| if (!fmt_in) | if (!fmt_in) | ||||
| @@ -2723,7 +2724,8 @@ static int http_receive_data(HTTPContext *c) | |||||
| 0, NULL, NULL, NULL, NULL); | 0, NULL, NULL, NULL, NULL); | ||||
| pb->seekable = 0; | 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); | av_free(pb); | ||||
| goto fail; | goto fail; | ||||
| } | } | ||||
| @@ -3442,8 +3444,7 @@ static int rtp_new_av_stream(HTTPContext *c, | |||||
| /* XXX: close stream */ | /* XXX: close stream */ | ||||
| goto fail; | goto fail; | ||||
| } | } | ||||
| av_set_parameters(ctx, NULL); | |||||
| if (av_write_header(ctx) < 0) { | |||||
| if (avformat_write_header(ctx, NULL) < 0) { | |||||
| fail: | fail: | ||||
| if (h) | if (h) | ||||
| url_close(h); | url_close(h); | ||||
| @@ -3597,28 +3598,25 @@ static void extract_mpeg4_header(AVFormatContext *infile) | |||||
| static void build_file_streams(void) | static void build_file_streams(void) | ||||
| { | { | ||||
| FFStream *stream, *stream_next; | FFStream *stream, *stream_next; | ||||
| AVFormatContext *infile; | |||||
| int i, ret; | int i, ret; | ||||
| /* gather all streams */ | /* gather all streams */ | ||||
| for(stream = first_stream; stream != NULL; stream = stream_next) { | for(stream = first_stream; stream != NULL; stream = stream_next) { | ||||
| AVFormatContext *infile = NULL; | |||||
| stream_next = stream->next; | stream_next = stream->next; | ||||
| if (stream->stream_type == STREAM_TYPE_LIVE && | if (stream->stream_type == STREAM_TYPE_LIVE && | ||||
| !stream->feed) { | !stream->feed) { | ||||
| /* the stream comes from a file */ | /* the stream comes from a file */ | ||||
| /* try to open the file */ | /* try to open the file */ | ||||
| /* open stream */ | /* open stream */ | ||||
| stream->ap_in = av_mallocz(sizeof(AVFormatParameters)); | |||||
| if (stream->fmt && !strcmp(stream->fmt->name, "rtp")) { | if (stream->fmt && !strcmp(stream->fmt->name, "rtp")) { | ||||
| /* specific case : if transport stream output to RTP, | /* specific case : if transport stream output to RTP, | ||||
| we use a raw transport stream reader */ | 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); | 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); | http_log("Could not open '%s': %d\n", stream->feed_filename, ret); | ||||
| /* remove stream (no need to spend more time on it) */ | /* remove stream (no need to spend more time on it) */ | ||||
| fail: | fail: | ||||
| @@ -3678,10 +3676,10 @@ static void build_feed_streams(void) | |||||
| if (avio_check(feed->feed_filename, AVIO_FLAG_READ) > 0) { | if (avio_check(feed->feed_filename, AVIO_FLAG_READ) > 0) { | ||||
| /* See if it matches */ | /* See if it matches */ | ||||
| AVFormatContext *s; | |||||
| AVFormatContext *s = NULL; | |||||
| int matches = 0; | 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 */ | /* Now see if it matches */ | ||||
| if (s->nb_streams == feed->nb_streams) { | if (s->nb_streams == feed->nb_streams) { | ||||
| matches = 1; | matches = 1; | ||||
| @@ -3767,8 +3765,7 @@ static void build_feed_streams(void) | |||||
| s->oformat = feed->fmt; | s->oformat = feed->fmt; | ||||
| s->nb_streams = feed->nb_streams; | s->nb_streams = feed->nb_streams; | ||||
| s->streams = feed->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"); | http_log("Container doesn't supports the required parameters\n"); | ||||
| exit(1); | exit(1); | ||||
| } | } | ||||
| @@ -3944,7 +3941,7 @@ static int ffserver_opt_default(const char *opt, const char *arg, | |||||
| AVCodecContext *avctx, int type) | AVCodecContext *avctx, int type) | ||||
| { | { | ||||
| int ret = 0; | 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) | if(o) | ||||
| ret = av_set_string3(avctx, opt, arg, 1, NULL); | ret = av_set_string3(avctx, opt, arg, 1, NULL); | ||||
| return ret; | 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); | init_get_bits(&s->gb, ptr, bit_length); | ||||
| ff_h264_decode_seq_parameter_set(h); | 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; | s->low_delay=1; | ||||
| if(avctx->has_b_frames < 2) | if(avctx->has_b_frames < 2) | ||||
| @@ -37,6 +37,25 @@ static const char* context_to_name(void* ptr) { | |||||
| return "NULL"; | 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 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 | #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 | //these names are too long to be readable | ||||
| @@ -457,7 +476,7 @@ static const AVOption options[]={ | |||||
| #undef D | #undef D | ||||
| #undef DEFAULT | #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){ | void avcodec_get_context_defaults2(AVCodecContext *s, enum AVMediaType codec_type){ | ||||
| int flags=0; | 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; | iformat = movie->format_name ? av_find_input_format(movie->format_name) : NULL; | ||||
| movie->format_ctx = 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, | 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; | return ret; | ||||
| } | } | ||||
| if ((ret = av_find_stream_info(movie->format_ctx)) < 0) | 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) | if (v->n_segments == 0) | ||||
| continue; | continue; | ||||
| if (!(v->ctx = avformat_alloc_context())) { | |||||
| ret = AVERROR(ENOMEM); | |||||
| goto fail; | |||||
| } | |||||
| v->index = i; | v->index = i; | ||||
| v->needed = 1; | v->needed = 1; | ||||
| v->parent = s; | v->parent = s; | ||||
| @@ -491,8 +496,8 @@ static int applehttp_read_header(AVFormatContext *s, AVFormatParameters *ap) | |||||
| NULL, 0, 0); | NULL, 0, 0); | ||||
| if (ret < 0) | if (ret < 0) | ||||
| goto fail; | 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) | if (ret < 0) | ||||
| goto fail; | goto fail; | ||||
| v->stream_offset = stream_offset; | v->stream_offset = stream_offset; | ||||
| @@ -247,8 +247,8 @@ typedef struct AVFormatParameters { | |||||
| attribute_deprecated unsigned int mpeg2ts_compute_pcr:1; | attribute_deprecated unsigned int mpeg2ts_compute_pcr:1; | ||||
| attribute_deprecated unsigned int initial_pause:1; /**< Do not begin to play the stream | attribute_deprecated unsigned int initial_pause:1; /**< Do not begin to play the stream | ||||
| immediately (RTSP only). */ | immediately (RTSP only). */ | ||||
| attribute_deprecated unsigned int prealloced_context:1; | |||||
| #endif | #endif | ||||
| unsigned int prealloced_context:1; | |||||
| } AVFormatParameters; | } AVFormatParameters; | ||||
| //! Demuxer will use avio_open, no opened file should be provided by the caller. | //! 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 | #if FF_API_FLAG_RTP_HINT | ||||
| #define AVFMT_FLAG_RTP_HINT 0x0040 ///< Deprecated, use the -movflags rtphint muxer specific AVOption instead | #define AVFMT_FLAG_RTP_HINT 0x0040 ///< Deprecated, use the -movflags rtphint muxer specific AVOption instead | ||||
| #endif | #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_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_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. | #define AVFMT_FLAG_KEEP_SIDE_DATA 0x40000 ///< Dont merge side data but keep it seperate. | ||||
| int loop_input; | int loop_input; | ||||
| /** | /** | ||||
| @@ -1054,11 +1056,13 @@ int av_probe_input_buffer(AVIOContext *pb, AVInputFormat **fmt, | |||||
| const char *filename, void *logctx, | const char *filename, void *logctx, | ||||
| unsigned int offset, unsigned int max_probe_size); | unsigned int offset, unsigned int max_probe_size); | ||||
| #if FF_API_FORMAT_PARAMETERS | |||||
| /** | /** | ||||
| * Allocate all the structures needed to read an input stream. | * Allocate all the structures needed to read an input stream. | ||||
| * This does not open the needed codecs for decoding the stream[s]. | * 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, | AVIOContext *pb, const char *filename, | ||||
| AVInputFormat *fmt, AVFormatParameters *ap); | 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 | * @param ap Additional parameters needed when opening the file | ||||
| * (NULL if default). | * (NULL if default). | ||||
| * @return 0 if OK, AVERROR_xxx otherwise | * @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, | AVInputFormat *fmt, | ||||
| int buf_size, | int buf_size, | ||||
| AVFormatParameters *ap); | 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); | 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 | * 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); | attribute_deprecated int av_set_parameters(AVFormatContext *s, AVFormatParameters *ap); | ||||
| #endif | |||||
| /** | /** | ||||
| * Split a URL string into components. | * Split a URL string into components. | ||||
| @@ -1393,6 +1426,24 @@ void av_url_split(char *proto, int proto_size, | |||||
| char *path, int path_size, | char *path, int path_size, | ||||
| const char *url); | 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 | * Allocate the stream private data and write the stream header to an | ||||
| * output media file. | * output media file. | ||||
| @@ -1401,8 +1452,11 @@ void av_url_split(char *proto, int proto_size, | |||||
| * | * | ||||
| * @param s media file handle | * @param s media file handle | ||||
| * @return 0 if OK, AVERROR_xxx on error | * @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. | * 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))) | if (!(sub_demuxer = av_probe_input_format2(&pd, 1, &score))) | ||||
| goto error; | 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); | av_read_packet(ast->sub_ctx, &ast->sub_pkt); | ||||
| *st->codec = *ast->sub_ctx->streams[0]->codec; | *st->codec = *ast->sub_ctx->streams[0]->codec; | ||||
| ast->sub_ctx->streams[0]->codec->extradata = NULL; | ast->sub_ctx->streams[0]->codec->extradata = NULL; | ||||
| @@ -1393,7 +1397,7 @@ static int avi_read_close(AVFormatContext *s) | |||||
| if (ast) { | if (ast) { | ||||
| if (ast->sub_ctx) { | if (ast->sub_ctx) { | ||||
| av_freep(&ast->sub_ctx->pb); | 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(ast->sub_buffer); | ||||
| av_free_packet(&ast->sub_pkt); | av_free_packet(&ast->sub_pkt); | ||||
| @@ -33,6 +33,33 @@ static const char* format_to_name(void* ptr) | |||||
| else return "NULL"; | 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 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 | #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 | //these names are too long to be readable | ||||
| @@ -75,6 +102,7 @@ static const AVClass av_format_context_class = { | |||||
| .item_name = format_to_name, | .item_name = format_to_name, | ||||
| .option = options, | .option = options, | ||||
| .version = LIBAVUTIL_VERSION_INT, | .version = LIBAVUTIL_VERSION_INT, | ||||
| .opt_find = opt_find, | |||||
| }; | }; | ||||
| static void avformat_get_context_defaults(AVFormatContext *s) | static void avformat_get_context_defaults(AVFormatContext *s) | ||||
| @@ -523,7 +523,7 @@ rdt_new_context (void) | |||||
| { | { | ||||
| PayloadContext *rdt = av_mallocz(sizeof(PayloadContext)); | 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; | return rdt; | ||||
| } | } | ||||
| @@ -539,7 +539,7 @@ rdt_free_context (PayloadContext *rdt) | |||||
| av_freep(&rdt->rmst[i]); | av_freep(&rdt->rmst[i]); | ||||
| } | } | ||||
| if (rdt->rmctx) | if (rdt->rmctx) | ||||
| av_close_input_stream(rdt->rmctx); | |||||
| av_close_input_file(rdt->rmctx); | |||||
| av_freep(&rdt->mlti_data); | av_freep(&rdt->mlti_data); | ||||
| av_freep(&rdt->rmst); | av_freep(&rdt->rmst); | ||||
| av_free(rdt); | 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"); | "Failed to fix invalid RTSP-MS/ASF min_pktsize\n"); | ||||
| init_packetizer(&pb, buf, len); | init_packetizer(&pb, buf, len); | ||||
| if (rt->asf_ctx) { | if (rt->asf_ctx) { | ||||
| av_close_input_stream(rt->asf_ctx); | |||||
| av_close_input_file(rt->asf_ctx); | |||||
| rt->asf_ctx = NULL; | 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) | if (ret < 0) | ||||
| return ret; | return ret; | ||||
| av_dict_copy(&s->metadata, rt->asf_ctx->metadata, 0); | 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); | ffio_fdopen(&rtpctx->pb, handle); | ||||
| } else | } else | ||||
| ffio_open_dyn_packet_buf(&rtpctx->pb, packet_size); | ffio_open_dyn_packet_buf(&rtpctx->pb, packet_size); | ||||
| ret = av_write_header(rtpctx); | |||||
| ret = avformat_write_header(rtpctx, NULL); | |||||
| if (ret) { | if (ret) { | ||||
| if (handle) { | if (handle) { | ||||
| @@ -52,7 +52,7 @@ static int sap_read_close(AVFormatContext *s) | |||||
| { | { | ||||
| struct SAPState *sap = s->priv_data; | struct SAPState *sap = s->priv_data; | ||||
| if (sap->sdp_ctx) | if (sap->sdp_ctx) | ||||
| av_close_input_stream(sap->sdp_ctx); | |||||
| av_close_input_file(sap->sdp_ctx); | |||||
| if (sap->ann_fd) | if (sap->ann_fd) | ||||
| ffurl_close(sap->ann_fd); | ffurl_close(sap->ann_fd); | ||||
| av_freep(&sap->sdp); | av_freep(&sap->sdp); | ||||
| @@ -156,9 +156,8 @@ static int sap_read_header(AVFormatContext *s, | |||||
| goto fail; | goto fail; | ||||
| } | } | ||||
| sap->sdp_ctx->max_delay = s->max_delay; | 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) | if (ret < 0) | ||||
| goto fail; | goto fail; | ||||
| if (sap->sdp_ctx->ctx_flags & AVFMTCTX_NOHEADER) | if (sap->sdp_ctx->ctx_flags & AVFMTCTX_NOHEADER) | ||||
| @@ -28,6 +28,7 @@ | |||||
| #include "libavcodec/raw.h" | #include "libavcodec/raw.h" | ||||
| #include "libavutil/opt.h" | #include "libavutil/opt.h" | ||||
| #include "libavutil/dict.h" | #include "libavutil/dict.h" | ||||
| #include "libavutil/pixdesc.h" | |||||
| #include "metadata.h" | #include "metadata.h" | ||||
| #include "id3v2.h" | #include "id3v2.h" | ||||
| #include "libavutil/avstring.h" | #include "libavutil/avstring.h" | ||||
| @@ -393,6 +394,47 @@ static int set_codec_from_probe_data(AVFormatContext *s, AVStream *st, AVProbeDa | |||||
| /************************************************************/ | /************************************************************/ | ||||
| /* input media file */ | /* 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. | * 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) | AVInputFormat *fmt, AVFormatParameters *ap) | ||||
| { | { | ||||
| int err; | int err; | ||||
| AVDictionary *opts; | |||||
| AVFormatContext *ic; | AVFormatContext *ic; | ||||
| AVFormatParameters default_ap; | AVFormatParameters default_ap; | ||||
| @@ -408,6 +451,7 @@ int av_open_input_stream(AVFormatContext **ic_ptr, | |||||
| ap=&default_ap; | ap=&default_ap; | ||||
| memset(ap, 0, sizeof(default_ap)); | memset(ap, 0, sizeof(default_ap)); | ||||
| } | } | ||||
| opts = convert_format_parameters(ap); | |||||
| if(!ap->prealloced_context) | if(!ap->prealloced_context) | ||||
| ic = avformat_alloc_context(); | ic = avformat_alloc_context(); | ||||
| @@ -417,63 +461,15 @@ int av_open_input_stream(AVFormatContext **ic_ptr, | |||||
| err = AVERROR(ENOMEM); | err = AVERROR(ENOMEM); | ||||
| goto fail; | goto fail; | ||||
| } | } | ||||
| ic->iformat = fmt; | |||||
| ic->pb = pb; | 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; | return err; | ||||
| } | } | ||||
| #endif | |||||
| int av_demuxer_open(AVFormatContext *ic, AVFormatParameters *ap){ | int av_demuxer_open(AVFormatContext *ic, AVFormatParameters *ap){ | ||||
| int err; | int err; | ||||
| @@ -562,68 +558,124 @@ int av_probe_input_buffer(AVIOContext *pb, AVInputFormat **fmt, | |||||
| return ret; | return ret; | ||||
| } | } | ||||
| #if FF_API_FORMAT_PARAMETERS | |||||
| int av_open_input_file(AVFormatContext **ic_ptr, const char *filename, | int av_open_input_file(AVFormatContext **ic_ptr, const char *filename, | ||||
| AVInputFormat *fmt, | AVInputFormat *fmt, | ||||
| int buf_size, | int buf_size, | ||||
| AVFormatParameters *ap) | AVFormatParameters *ap) | ||||
| { | { | ||||
| int err; | 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; | 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; | 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; | 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; | 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) | 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); | av_close_input_stream(s); | ||||
| if (pb) | if (pb) | ||||
| avio_close(pb); | avio_close(pb); | ||||
| @@ -2722,6 +2775,7 @@ AVChapter *ff_new_chapter(AVFormatContext *s, int id, AVRational time_base, int6 | |||||
| /************************************************************/ | /************************************************************/ | ||||
| /* output media file */ | /* output media file */ | ||||
| #if FF_API_FORMAT_PARAMETERS | |||||
| int av_set_parameters(AVFormatContext *s, AVFormatParameters *ap) | int av_set_parameters(AVFormatContext *s, AVFormatParameters *ap) | ||||
| { | { | ||||
| if (s->oformat->priv_data_size > 0) { | if (s->oformat->priv_data_size > 0) { | ||||
| @@ -2737,6 +2791,7 @@ int av_set_parameters(AVFormatContext *s, AVFormatParameters *ap) | |||||
| return 0; | return 0; | ||||
| } | } | ||||
| #endif | |||||
| int avformat_alloc_output_context2(AVFormatContext **avctx, AVOutputFormat *oformat, | int avformat_alloc_output_context2(AVFormatContext **avctx, AVOutputFormat *oformat, | ||||
| const char *format, const char *filename) | const char *format, const char *filename) | ||||
| @@ -2834,15 +2889,29 @@ static int validate_codec_tag(AVFormatContext *s, AVStream *st) | |||||
| return 1; | return 1; | ||||
| } | } | ||||
| #if FF_API_FORMAT_PARAMETERS | |||||
| int av_write_header(AVFormatContext *s) | 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; | 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 | // some sanity checks | ||||
| if (s->nb_streams == 0 && !(s->oformat->flags & AVFMT_NOSTREAMS)) { | if (s->nb_streams == 0 && !(s->oformat->flags & AVFMT_NOSTREAMS)) { | ||||
| av_log(s, AV_LOG_ERROR, "no streams\n"); | 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++) { | for(i=0;i<s->nb_streams;i++) { | ||||
| @@ -2852,7 +2921,8 @@ int av_write_header(AVFormatContext *s) | |||||
| case AVMEDIA_TYPE_AUDIO: | case AVMEDIA_TYPE_AUDIO: | ||||
| if(st->codec->sample_rate<=0){ | if(st->codec->sample_rate<=0){ | ||||
| av_log(s, AV_LOG_ERROR, "sample rate not set\n"); | av_log(s, AV_LOG_ERROR, "sample rate not set\n"); | ||||
| return AVERROR(EINVAL); | |||||
| ret = AVERROR(EINVAL); | |||||
| goto fail; | |||||
| } | } | ||||
| if(!st->codec->block_align) | if(!st->codec->block_align) | ||||
| st->codec->block_align = st->codec->channels * | st->codec->block_align = st->codec->channels * | ||||
| @@ -2861,15 +2931,18 @@ int av_write_header(AVFormatContext *s) | |||||
| case AVMEDIA_TYPE_VIDEO: | case AVMEDIA_TYPE_VIDEO: | ||||
| if(st->codec->time_base.num<=0 || st->codec->time_base.den<=0){ //FIXME audio too? | 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"); | 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)){ | if((st->codec->width<=0 || st->codec->height<=0) && !(s->oformat->flags & AVFMT_NODIMENSIONS)){ | ||||
| av_log(s, AV_LOG_ERROR, "dimensions not set\n"); | 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)){ | 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"); | av_log(s, AV_LOG_ERROR, "Aspect ratio mismatch between encoder and muxer layer\n"); | ||||
| return AVERROR(EINVAL); | |||||
| ret = AVERROR(EINVAL); | |||||
| goto fail; | |||||
| } | } | ||||
| break; | break; | ||||
| } | } | ||||
| @@ -2886,7 +2959,8 @@ int av_write_header(AVFormatContext *s) | |||||
| av_log(s, AV_LOG_ERROR, | av_log(s, AV_LOG_ERROR, | ||||
| "Tag %s/0x%08x incompatible with output codec id '%d'\n", | "Tag %s/0x%08x incompatible with output codec id '%d'\n", | ||||
| tagbuf, st->codec->codec_tag, st->codec->codec_id); | tagbuf, st->codec->codec_tag, st->codec->codec_id); | ||||
| return AVERROR_INVALIDDATA; | |||||
| ret = AVERROR_INVALIDDATA; | |||||
| goto fail; | |||||
| } | } | ||||
| }else | }else | ||||
| st->codec->codec_tag= av_codec_get_tag(s->oformat->codec_tag, st->codec->codec_id); | 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) { | if (!s->priv_data && s->oformat->priv_data_size > 0) { | ||||
| s->priv_data = av_mallocz(s->oformat->priv_data_size); | 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 */ | /* set muxer identification string */ | ||||
| @@ -2911,7 +2993,7 @@ int av_write_header(AVFormatContext *s) | |||||
| if(s->oformat->write_header){ | if(s->oformat->write_header){ | ||||
| ret = s->oformat->write_header(s); | ret = s->oformat->write_header(s); | ||||
| if (ret < 0) | if (ret < 0) | ||||
| return ret; | |||||
| goto fail; | |||||
| } | } | ||||
| /* init PTS generation */ | /* init PTS generation */ | ||||
| @@ -2930,12 +3012,22 @@ int av_write_header(AVFormatContext *s) | |||||
| break; | break; | ||||
| } | } | ||||
| if (den != AV_NOPTS_VALUE) { | 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); | av_frac_init(&st->pts, 0, 0, den); | ||||
| } | } | ||||
| } | } | ||||
| if (options) { | |||||
| av_dict_free(options); | |||||
| *options = tmp; | |||||
| } | |||||
| return 0; | return 0; | ||||
| fail: | |||||
| av_dict_free(&tmp); | |||||
| return ret; | |||||
| } | } | ||||
| //FIXME merge with compute_pkt_fields | //FIXME merge with compute_pkt_fields | ||||
| @@ -24,8 +24,8 @@ | |||||
| #include "libavutil/avutil.h" | #include "libavutil/avutil.h" | ||||
| #define LIBAVFORMAT_VERSION_MAJOR 53 | #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, \ | #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ | ||||
| LIBAVFORMAT_VERSION_MINOR, \ | LIBAVFORMAT_VERSION_MINOR, \ | ||||
| @@ -40,7 +40,7 @@ | |||||
| #define AV_VERSION(a, b, c) AV_VERSION_DOT(a, b, c) | #define AV_VERSION(a, b, c) AV_VERSION_DOT(a, b, c) | ||||
| #define LIBAVUTIL_VERSION_MAJOR 51 | #define LIBAVUTIL_VERSION_MAJOR 51 | ||||
| #define LIBAVUTIL_VERSION_MINOR 8 | |||||
| #define LIBAVUTIL_VERSION_MINOR 9 | |||||
| #define LIBAVUTIL_VERSION_MICRO 0 | #define LIBAVUTIL_VERSION_MICRO 0 | ||||
| #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ | #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ | ||||
| @@ -63,6 +63,9 @@ | |||||
| #ifndef FF_API_GET_BITS_PER_SAMPLE_FMT | #ifndef FF_API_GET_BITS_PER_SAMPLE_FMT | ||||
| #define FF_API_GET_BITS_PER_SAMPLE_FMT (LIBAVUTIL_VERSION_MAJOR < 52) | #define FF_API_GET_BITS_PER_SAMPLE_FMT (LIBAVUTIL_VERSION_MAJOR < 52) | ||||
| #endif | #endif | ||||
| #ifndef FF_API_FIND_OPT | |||||
| #define FF_API_FIND_OPT (LIBAVUTIL_VERSION_MAJOR < 52) | |||||
| #endif | |||||
| /** | /** | ||||
| * Return the LIBAVUTIL_VERSION_INT constant. | * Return the LIBAVUTIL_VERSION_INT constant. | ||||
| @@ -19,6 +19,7 @@ | |||||
| */ | */ | ||||
| #include <strings.h> | #include <strings.h> | ||||
| #include "avstring.h" | |||||
| #include "dict.h" | #include "dict.h" | ||||
| #include "internal.h" | #include "internal.h" | ||||
| #include "mem.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; | AVDictionary *m = *pm; | ||||
| AVDictionaryEntry *tag = av_dict_get(m, key, NULL, flags); | AVDictionaryEntry *tag = av_dict_get(m, key, NULL, flags); | ||||
| char *oldval = NULL; | |||||
| if(!m) | if(!m) | ||||
| m = *pm = av_mallocz(sizeof(*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(tag) { | ||||
| if (flags & AV_DICT_DONT_OVERWRITE) | if (flags & AV_DICT_DONT_OVERWRITE) | ||||
| return 0; | return 0; | ||||
| av_free(tag->value); | |||||
| if (flags & AV_DICT_APPEND) | |||||
| oldval = tag->value; | |||||
| else | |||||
| av_free(tag->value); | |||||
| av_free(tag->key); | av_free(tag->key); | ||||
| *tag = m->elems[--m->count]; | *tag = m->elems[--m->count]; | ||||
| } else { | } 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 ); | m->elems[m->count].key = av_strdup(key ); | ||||
| if (flags & AV_DICT_DONT_STRDUP_VAL) { | if (flags & AV_DICT_DONT_STRDUP_VAL) { | ||||
| m->elems[m->count].value = value; | 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 | } else | ||||
| m->elems[m->count].value = av_strdup(value); | m->elems[m->count].value = av_strdup(value); | ||||
| m->count++; | m->count++; | ||||
| @@ -29,6 +29,8 @@ | |||||
| #define AV_DICT_DONT_STRDUP_KEY 4 | #define AV_DICT_DONT_STRDUP_KEY 4 | ||||
| #define AV_DICT_DONT_STRDUP_VAL 8 | #define AV_DICT_DONT_STRDUP_VAL 8 | ||||
| #define AV_DICT_DONT_OVERWRITE 16 ///< Don't overwrite existing entries. | #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 { | typedef struct { | ||||
| char *key; | char *key; | ||||
| @@ -229,11 +229,11 @@ union unaligned_16 { uint16_t l; } __attribute__((packed)) av_alias; | |||||
| #endif | #endif | ||||
| #ifndef AV_RB32 | #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 | #endif | ||||
| #ifndef AV_WB32 | #ifndef AV_WB32 | ||||
| # define AV_WB32(p, d) do { \ | # define AV_WB32(p, d) do { \ | ||||
| @@ -245,11 +245,11 @@ union unaligned_16 { uint16_t l; } __attribute__((packed)) av_alias; | |||||
| #endif | #endif | ||||
| #ifndef AV_RL32 | #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 | #endif | ||||
| #ifndef AV_WL32 | #ifndef AV_WL32 | ||||
| # define AV_WL32(p, d) do { \ | # define AV_WL32(p, d) do { \ | ||||
| @@ -70,6 +70,13 @@ typedef struct { | |||||
| * can be NULL of course | * can be NULL of course | ||||
| */ | */ | ||||
| int parent_log_context_offset; | 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; | } AVClass; | ||||
| /* av_log API */ | /* av_log API */ | ||||
| @@ -29,7 +29,9 @@ | |||||
| #include "avstring.h" | #include "avstring.h" | ||||
| #include "opt.h" | #include "opt.h" | ||||
| #include "eval.h" | #include "eval.h" | ||||
| #include "dict.h" | |||||
| #if FF_API_FIND_OPT | |||||
| //FIXME order them and do a bin search | //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) | 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; | return NULL; | ||||
| } | } | ||||
| #endif | |||||
| const AVOption *av_next_option(void *obj, const AVOption *last) | 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) | 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; | void *dst; | ||||
| if (o_out) | if (o_out) | ||||
| *o_out= o; | *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 av_set_string3(void *obj, const char *name, const char *val, int alloc, const AVOption **o_out) | ||||
| { | { | ||||
| int ret; | 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) | if (o_out) | ||||
| *o_out = o; | *o_out = o; | ||||
| if (!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; | 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) | if (o_named && o_named->type == FF_OPT_TYPE_CONST) | ||||
| d= o_named->default_val.dbl; | d= o_named->default_val.dbl; | ||||
| else if (!strcmp(buf, "default")) d= o->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 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; | void *dst; | ||||
| uint8_t *bin; | uint8_t *bin; | ||||
| int len, i; | 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) | 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; | void *dst; | ||||
| if (!o || (o->offset<=0 && o->type != FF_OPT_TYPE_CONST)) | if (!o || (o->offset<=0 && o->type != FF_OPT_TYPE_CONST)) | ||||
| goto error; | goto error; | ||||
| @@ -538,6 +541,45 @@ void av_opt_free(void *obj) | |||||
| av_freep((uint8_t *)obj + o->offset); | 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 | #ifdef TEST | ||||
| #undef printf | #undef printf | ||||
| @@ -29,6 +29,7 @@ | |||||
| #include "rational.h" | #include "rational.h" | ||||
| #include "avutil.h" | #include "avutil.h" | ||||
| #include "dict.h" | |||||
| enum AVOptionType{ | enum AVOptionType{ | ||||
| FF_OPT_TYPE_FLAGS, | FF_OPT_TYPE_FLAGS, | ||||
| @@ -91,6 +92,7 @@ typedef struct AVOption { | |||||
| const char *unit; | const char *unit; | ||||
| } AVOption; | } AVOption; | ||||
| #if FF_API_FIND_OPT | |||||
| /** | /** | ||||
| * Look for an option in obj. Look only for the options which | * Look for an option in obj. Look only for the options which | ||||
| * have the flags set as specified in mask and flags (that is, | * 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 | * @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 | * @return a pointer to the option found, or NULL if no option | ||||
| * has been found | * 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); | 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. | * 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); | 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 */ | #endif /* AVUTIL_OPT_H */ | ||||