From 47953c33ea8dc3b5da1903b0c5055043b82db3e7 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 22 May 2011 14:10:49 +0200 Subject: [PATCH 1/6] lavc: introduce avcodec_open2() as a replacement for avcodec_open(). Adds support for decoder-private options and makes setting other options simpler. (cherry picked from commit 0b950fe240936fa48fd41204bcfd04f35bbf39c3) Conflicts: libavcodec/avcodec.h Signed-off-by: Anton Khirnov --- ffprobe.c | 2 +- ffserver.c | 2 +- libavcodec/avcodec.h | 39 ++++++++++++++++++++++++++++++++++++++ libavcodec/mpegvideo_enc.c | 2 +- libavcodec/utils.c | 24 ++++++++++++++++++++++- libavcodec/version.h | 3 +++ libavfilter/vsrc_movie.c | 2 +- 7 files changed, 69 insertions(+), 5 deletions(-) diff --git a/ffprobe.c b/ffprobe.c index edda454cde..cb4a4c3106 100644 --- a/ffprobe.c +++ b/ffprobe.c @@ -291,7 +291,7 @@ static int open_input_file(AVFormatContext **fmt_ctx_ptr, const char *filename) if (!(codec = avcodec_find_decoder(stream->codec->codec_id))) { fprintf(stderr, "Unsupported codec with id %d for input stream %d\n", stream->codec->codec_id, stream->index); - } else if (avcodec_open(stream->codec, codec) < 0) { + } else if (avcodec_open2(stream->codec, codec, NULL) < 0) { fprintf(stderr, "Error while opening codec for input stream %d\n", stream->index); } diff --git a/ffserver.c b/ffserver.c index 65a97b20cc..179cac4d96 100644 --- a/ffserver.c +++ b/ffserver.c @@ -2116,7 +2116,7 @@ static void open_parser(AVFormatContext *s, int i) codec = avcodec_find_decoder(st->codec->codec_id); if (codec && (codec->capabilities & CODEC_CAP_PARSE_ONLY)) { st->codec->parse_only = 1; - if (avcodec_open(st->codec, codec) < 0) + if (avcodec_open2(st->codec, codec, NULL) < 0) st->codec->parse_only = 0; } } diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 0269892028..2dbdc86e6a 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -30,6 +30,7 @@ #include "libavutil/samplefmt.h" #include "libavutil/avutil.h" #include "libavutil/cpu.h" +#include "libavutil/dict.h" #include "libavcodec/version.h" @@ -3615,6 +3616,7 @@ int avcodec_default_execute(AVCodecContext *c, int (*func)(AVCodecContext *c2, v int avcodec_default_execute2(AVCodecContext *c, int (*func)(AVCodecContext *c2, void *arg2, int, int),void *arg, int *ret, int count); //FIXME func typedef +#if FF_API_AVCODEC_OPEN /** * Initialize the AVCodecContext to use the given AVCodec. Prior to using this * function the context has to be allocated. @@ -3641,8 +3643,45 @@ int avcodec_default_execute2(AVCodecContext *c, int (*func)(AVCodecContext *c2, * @param codec The codec to use within the context. * @return zero on success, a negative value on error * @see avcodec_alloc_context, avcodec_find_decoder, avcodec_find_encoder, avcodec_close + * + * @deprecated use avcodec_open2 */ +attribute_deprecated int avcodec_open(AVCodecContext *avctx, AVCodec *codec); +#endif + +/** + * Initialize the AVCodecContext to use the given AVCodec. Prior to using this + * function the context has to be allocated with avcodec_alloc_context(). + * + * The functions avcodec_find_decoder_by_name(), avcodec_find_encoder_by_name(), + * avcodec_find_decoder() and avcodec_find_encoder() provide an easy way for + * retrieving a codec. + * + * @warning This function is not thread safe! + * + * @code + * avcodec_register_all(); + * av_dict_set(&opts, "b", "2.5M", 0); + * codec = avcodec_find_decoder(CODEC_ID_H264); + * if (!codec) + * exit(1); + * + * context = avcodec_alloc_context(); + * + * if (avcodec_open(context, codec, opts) < 0) + * exit(1); + * @endcode + * + * @param avctx The context to initialize. + * @param options A dictionary filled with AVCodecContext and codec-private options. + * On return this object will be filled with options that were not found. + * + * @return zero on success, a negative value on error + * @see avcodec_alloc_context3(), avcodec_find_decoder(), avcodec_find_encoder(), + * av_dict_set(), av_opt_find(). + */ +int avcodec_open2(AVCodecContext *avctx, AVCodec *codec, AVDictionary **options); /** * Decode the audio frame of size avpkt->size from avpkt->data into samples. diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c index b5a1872eb1..51713a223f 100644 --- a/libavcodec/mpegvideo_enc.c +++ b/libavcodec/mpegvideo_enc.c @@ -972,7 +972,7 @@ static int estimate_best_b_count(MpegEncContext *s){ c->time_base= s->avctx->time_base; c->max_b_frames= s->max_b_frames; - if (avcodec_open(c, codec) < 0) + if (avcodec_open2(c, codec, NULL) < 0) return -1; for(i=0; imax_b_frames+2; i++){ diff --git a/libavcodec/utils.c b/libavcodec/utils.c index bbed7263ab..b264fe422e 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -32,6 +32,7 @@ #include "libavutil/audioconvert.h" #include "libavutil/imgutils.h" #include "libavutil/samplefmt.h" +#include "libavutil/dict.h" #include "avcodec.h" #include "dsputil.h" #include "libavutil/opt.h" @@ -467,9 +468,20 @@ AVFrame *avcodec_alloc_frame(void){ return pic; } +#if FF_API_AVCODEC_OPEN int attribute_align_arg avcodec_open(AVCodecContext *avctx, AVCodec *codec) +{ + return avcodec_open2(avctx, codec, NULL); +} +#endif + +int attribute_align_arg avcodec_open2(AVCodecContext *avctx, AVCodec *codec, AVDictionary **options) { int ret = 0; + AVDictionary *tmp = NULL; + + if (options) + av_dict_copy(&tmp, *options, 0); /* If there is a user-supplied mutex locking routine, call it. */ if (ff_lockmgr_cb) { @@ -496,14 +508,18 @@ int attribute_align_arg avcodec_open(AVCodecContext *avctx, AVCodec *codec) ret = AVERROR(ENOMEM); goto end; } - if(codec->priv_class){ //this can be droped once all user apps use avcodec_get_context_defaults3() + if (codec->priv_class) { *(AVClass**)avctx->priv_data= codec->priv_class; av_opt_set_defaults(avctx->priv_data); } } + if (codec->priv_class && (ret = av_opt_set_dict(avctx->priv_data, &tmp) < 0)) + goto free_and_end; } else { avctx->priv_data = NULL; } + if ((ret = av_opt_set_dict(avctx, &tmp)) < 0) + goto free_and_end; if(avctx->coded_width && avctx->coded_height) avcodec_set_dimensions(avctx, avctx->coded_width, avctx->coded_height); @@ -615,8 +631,14 @@ end: if (ff_lockmgr_cb) { (*ff_lockmgr_cb)(&codec_mutex, AV_LOCK_RELEASE); } + if (options) { + av_dict_free(options); + *options = tmp; + } + return ret; free_and_end: + av_dict_free(&tmp); av_freep(&avctx->priv_data); avctx->codec= NULL; goto end; diff --git a/libavcodec/version.h b/libavcodec/version.h index aded68e83e..f4a0ecd868 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -68,5 +68,8 @@ #ifndef FF_API_GET_PIX_FMT_NAME #define FF_API_GET_PIX_FMT_NAME (LIBAVCODEC_VERSION_MAJOR < 54) #endif +#ifndef FF_API_AVCODEC_OPEN +#define FF_API_AVCODEC_OPEN (LIBAVCODEC_VERSION_MAJOR < 54) +#endif #endif /* AVCODEC_VERSION_H */ diff --git a/libavfilter/vsrc_movie.c b/libavfilter/vsrc_movie.c index 7556fa2e9e..bd74f95545 100644 --- a/libavfilter/vsrc_movie.c +++ b/libavfilter/vsrc_movie.c @@ -139,7 +139,7 @@ static int movie_init(AVFilterContext *ctx) return AVERROR(EINVAL); } - if ((ret = avcodec_open(movie->codec_ctx, codec)) < 0) { + if ((ret = avcodec_open2(movie->codec_ctx, codec, NULL)) < 0) { av_log(ctx, AV_LOG_ERROR, "Failed to open codec\n"); return ret; } From 23f0d0f16bb2accc661ab8c135362ee75987c549 Mon Sep 17 00:00:00 2001 From: Baptiste Coudurier Date: Mon, 8 Aug 2011 23:41:50 -0700 Subject: [PATCH 2/6] lavc: fix parentheses placement in avcodec_open2(). Signed-off-by: Anton Khirnov (cherry picked from commit 1d36fb13b088f55ece155153fb6ca8ea278fc837) Signed-off-by: Anton Khirnov --- libavcodec/utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/utils.c b/libavcodec/utils.c index b264fe422e..5c19dd7d35 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -513,7 +513,7 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, AVCodec *codec, AVD av_opt_set_defaults(avctx->priv_data); } } - if (codec->priv_class && (ret = av_opt_set_dict(avctx->priv_data, &tmp) < 0)) + if (codec->priv_class && (ret = av_opt_set_dict(avctx->priv_data, &tmp)) < 0) goto free_and_end; } else { avctx->priv_data = NULL; From afe2726089a9f45d89e81217cd69505c14b94445 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 22 May 2011 19:24:59 +0200 Subject: [PATCH 3/6] lavf: add avformat_find_stream_info() It supports passing options to codecs. (cherry picked from commit a67c061e0f3b55ffcc96f336fc0998e44b86c8e4) Conflicts: libavformat/utils.c Signed-off-by: Anton Khirnov --- libavfilter/vsrc_movie.c | 2 +- libavformat/avformat.h | 27 +++++++++++++++++++++++++++ libavformat/utils.c | 18 +++++++++++++----- 3 files changed, 41 insertions(+), 6 deletions(-) diff --git a/libavfilter/vsrc_movie.c b/libavfilter/vsrc_movie.c index bd74f95545..b018ba7418 100644 --- a/libavfilter/vsrc_movie.c +++ b/libavfilter/vsrc_movie.c @@ -96,7 +96,7 @@ static int movie_init(AVFilterContext *ctx) "Failed to avformat_open_input '%s'\n", movie->file_name); return ret; } - if ((ret = av_find_stream_info(movie->format_ctx)) < 0) + if ((ret = avformat_find_stream_info(movie->format_ctx, NULL)) < 0) av_log(ctx, AV_LOG_WARNING, "Failed to find stream info\n"); // if seeking requested, we execute it diff --git a/libavformat/avformat.h b/libavformat/avformat.h index 8561a50c01..c11d650e85 100644 --- a/libavformat/avformat.h +++ b/libavformat/avformat.h @@ -1081,6 +1081,7 @@ int avformat_open_input(AVFormatContext **ps, const char *filename, AVInputForma */ AVFormatContext *avformat_alloc_context(void); +#if FF_API_FORMAT_PARAMETERS /** * Read packets of a media file to get stream information. This * is useful for file formats with no headers such as MPEG. This @@ -1093,8 +1094,34 @@ AVFormatContext *avformat_alloc_context(void); * @return >=0 if OK, AVERROR_xxx on error * @todo Let the user decide somehow what information is needed so that * we do not waste time getting stuff the user does not need. + * + * @deprecated use avformat_find_stream_info. */ int av_find_stream_info(AVFormatContext *ic); +#endif + +/** + * Read packets of a media file to get stream information. This + * is useful for file formats with no headers such as MPEG. This + * function also computes the real framerate in case of MPEG-2 repeat + * frame mode. + * The logical file position is not changed by this function; + * examined packets may be buffered for later processing. + * + * @param ic media file handle + * @param options If non-NULL, an ic.nb_streams long array of pointers to + * dictionaries, where i-th member contains options for + * codec corresponding to i-th stream. + * On return each dictionary will be filled with options that were not found. + * @return >=0 if OK, AVERROR_xxx on error + * + * @note this function isn't guaranteed to open all the codecs, so + * options being non-empty at return is a perfectly normal behavior. + * + * @todo Let the user decide somehow what information is needed so that + * we do not waste time getting stuff the user does not need. + */ +int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options); /** * Find the "best" stream in the file. diff --git a/libavformat/utils.c b/libavformat/utils.c index e3c7d4aa84..15fed3287a 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -2074,7 +2074,7 @@ static int has_decode_delay_been_guessed(AVStream *st) st->codec_info_nb_frames >= 6 + st->codec->has_b_frames; } -static int try_decode_frame(AVStream *st, AVPacket *avpkt) +static int try_decode_frame(AVStream *st, AVPacket *avpkt, AVDictionary **options) { int16_t *samples; AVCodec *codec; @@ -2085,7 +2085,7 @@ static int try_decode_frame(AVStream *st, AVPacket *avpkt) codec = avcodec_find_decoder(st->codec->codec_id); if (!codec) return -1; - ret = avcodec_open(st->codec, codec); + ret = avcodec_open2(st->codec, codec, options); if (ret < 0) return ret; } @@ -2204,12 +2204,20 @@ static int tb_unreliable(AVCodecContext *c){ return 0; } +#if FF_API_FORMAT_PARAMETERS int av_find_stream_info(AVFormatContext *ic) +{ + return avformat_find_stream_info(ic, NULL); +} +#endif + +int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options) { int i, count, ret, read_size, j; AVStream *st; AVPacket pkt1, *pkt; int64_t old_offset = avio_tell(ic->pb); + int orig_nb_streams = ic->nb_streams; // new streams might appear, no options for those for(i=0;inb_streams;i++) { AVCodec *codec; @@ -2246,12 +2254,12 @@ int av_find_stream_info(AVFormatContext *ic) /* Ensure that subtitle_header is properly set. */ if (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE && codec && !st->codec->codec) - avcodec_open(st->codec, codec); + avcodec_open2(st->codec, codec, options ? &options[i] : NULL); //try to just open decoders, in case this is enough to get parameters if(!has_codec_parameters(st->codec)){ if (codec && !st->codec->codec) - avcodec_open(st->codec, codec); + avcodec_open2(st->codec, codec, options ? &options[i] : NULL); } } @@ -2386,7 +2394,7 @@ int av_find_stream_info(AVFormatContext *ic) it takes longer and uses more memory. For MPEG-4, we need to decompress for QuickTime. */ if (!has_codec_parameters(st->codec) || !has_decode_delay_been_guessed(st)) - try_decode_frame(st, pkt); + try_decode_frame(st, pkt, (options && i <= orig_nb_streams )? &options[i] : NULL); st->codec_info_nb_frames++; count++; From e297459eb694490c25acc65bcf75ee1630bd34b6 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Thu, 14 Jul 2011 03:08:53 +0200 Subject: [PATCH 4/6] lavf: fix invalid reads in avformat_find_stream_info() (cherry picked from commit e358f7ee90fec591348ca05dff94ebaf4c1a098b) Conflicts: libavformat/utils.c Signed-off-by: Anton Khirnov --- libavformat/utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/utils.c b/libavformat/utils.c index 15fed3287a..d155599058 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -2394,7 +2394,7 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options) it takes longer and uses more memory. For MPEG-4, we need to decompress for QuickTime. */ if (!has_codec_parameters(st->codec) || !has_decode_delay_been_guessed(st)) - try_decode_frame(st, pkt, (options && i <= orig_nb_streams )? &options[i] : NULL); + try_decode_frame(st, pkt, (options && i < orig_nb_streams )? &options[i] : NULL); st->codec_info_nb_frames++; count++; From d6f763659c6115e91d2fa981faffdb041d93f7a4 Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Tue, 15 Nov 2011 22:33:49 +0000 Subject: [PATCH 5/6] lavf: fix multiplication overflow in avformat_find_stream_info() Converting to double before the multiplication rather than after avoids an integer overflow in some cases. Signed-off-by: Mans Rullgard (cherry picked from commit 52767d891c665ab1124fe4ce82d99b59673de7d2) Signed-off-by: Anton Khirnov --- libavformat/utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/utils.c b/libavformat/utils.c index d155599058..aa3ca5990b 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -2368,7 +2368,7 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options) for (i=1; iinfo->duration_error); i++) { int framerate= get_std_framerate(i); int ticks= lrintf(dur*framerate/(1001*12)); - double error= dur - ticks*1001*12/(double)framerate; + double error = dur - (double)ticks*1001*12 / framerate; st->info->duration_error[i] += error*error; } st->info->duration_count++; From 07624cfeaa8ea11d213032135fb56ffd5022b73a Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sat, 19 Nov 2011 08:51:26 +0100 Subject: [PATCH 6/6] Add a version bump and APIchanges entry for avcodec_open2 and avformat_find_stream_info. --- doc/APIchanges | 6 ++++++ libavcodec/version.h | 2 +- libavformat/version.h | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/doc/APIchanges b/doc/APIchanges index 79d9749373..165ea98392 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -13,6 +13,12 @@ libavutil: 2011-04-18 API changes, most recent first: +2011-07-10 - xxxxxxx - lavf 53.3.0 + Add avformat_find_stream_info(), deprecate av_find_stream_info(). + +2011-07-10 - xxxxxxx - lavc 53.6.0 + Add avcodec_open2(), deprecate avcodec_open(). + 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, diff --git a/libavcodec/version.h b/libavcodec/version.h index f4a0ecd868..44c9198125 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -21,7 +21,7 @@ #define AVCODEC_VERSION_H #define LIBAVCODEC_VERSION_MAJOR 53 -#define LIBAVCODEC_VERSION_MINOR 5 +#define LIBAVCODEC_VERSION_MINOR 6 #define LIBAVCODEC_VERSION_MICRO 0 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ diff --git a/libavformat/version.h b/libavformat/version.h index 3cc1718f2b..635b582e87 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -24,7 +24,7 @@ #include "libavutil/avutil.h" #define LIBAVFORMAT_VERSION_MAJOR 53 -#define LIBAVFORMAT_VERSION_MINOR 2 +#define LIBAVFORMAT_VERSION_MINOR 3 #define LIBAVFORMAT_VERSION_MICRO 0 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \