This way, if the AVCodecContext is allocated for a specific codec, the
caller doesn't need to store this codec separately and then pass it
again to avcodec_open2().
It also allows to set codec private options using av_opt_set_* before
opening the codec.
---
libavcodec/avcodec.h | 5 +++++
libavcodec/options.c | 1 +
libavcodec/utils.c | 11 ++++++-----
libavformat/utils.c | 8 +++++---
4 files changed, 17 insertions(+), 8 deletions(-)
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 29e4e6a..224f020 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -3517,6 +3517,11 @@ int avcodec_default_execute2(AVCodecContext *c, int
(*func)(AVCodecContext *c2,
* @endcode
*
* @param avctx The context to initialize.
+ * @param codec The codec to open this context for. If a non-NULL codec has
been
+ * previously passed to avcodec_alloc_context3() or
+ * avcodec_get_context_defaults3() for this context, then this
+ * parameter MUST be either NULL or equal to the previously passed
+ * codec.
* @param options A dictionary filled with AVCodecContext and codec-private
options.
* On return this object will be filled with options that were
not found.
*
diff --git a/libavcodec/options.c b/libavcodec/options.c
index 52fc664..eb80375 100644
--- a/libavcodec/options.c
+++ b/libavcodec/options.c
@@ -432,6 +432,7 @@ int avcodec_get_context_defaults3(AVCodecContext *s,
AVCodec *codec){
s->av_class = &av_codec_context_class;
s->codec_type = codec ? codec->type : AVMEDIA_TYPE_UNKNOWN;
+ s->codec = codec;
av_opt_set_defaults(s);
s->time_base = (AVRational){0,1};
diff --git a/libavcodec/utils.c b/libavcodec/utils.c
index 8978ed8..7c58655 100644
--- a/libavcodec/utils.c
+++ b/libavcodec/utils.c
@@ -630,6 +630,12 @@ int attribute_align_arg avcodec_open2(AVCodecContext
*avctx, AVCodec *codec, AVD
if (avcodec_is_open(avctx))
return 0;
+ if ((!codec && !avctx->codec) ||
+ (codec && avctx->codec && codec != avctx->codec))
+ return AVERROR(EINVAL);
+ if (!codec)
+ codec = avctx->codec;
+
if (avctx->extradata_size < 0 || avctx->extradata_size >=
FF_MAX_EXTRADATA_SIZE)
return AVERROR(EINVAL);
@@ -649,11 +655,6 @@ int attribute_align_arg avcodec_open2(AVCodecContext
*avctx, AVCodec *codec, AVD
goto end;
}
- if(avctx->codec || !codec) {
- ret = AVERROR(EINVAL);
- goto end;
- }
-
avctx->internal = av_mallocz(sizeof(AVCodecInternal));
if (!avctx->internal) {
ret = AVERROR(ENOMEM);
diff --git a/libavformat/utils.c b/libavformat/utils.c
index 017d1e0..2850a14 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -2009,7 +2009,9 @@ static int try_decode_frame(AVStream *st, AVPacket
*avpkt, AVDictionary **option
if (!avcodec_is_open(st->codec)) {
AVDictionary *thread_opt = NULL;
- codec = avcodec_find_decoder(st->codec->codec_id);
+ codec = st->codec->codec ? st->codec->codec :
+ avcodec_find_decoder(st->codec->codec_id);
+
if (!codec)
return -1;
@@ -2169,8 +2171,8 @@ int avformat_find_stream_info(AVFormatContext *ic,
AVDictionary **options)
st->parser->flags |= PARSER_FLAG_COMPLETE_FRAMES;
}
}
- assert(!st->codec->codec);
- codec = avcodec_find_decoder(st->codec->codec_id);
+ codec = st->codec->codec ? st->codec->codec :
+ avcodec_find_decoder(st->codec->codec_id);
/* force thread count to 1 since the h264 decoder will not extract SPS
* and PPS to extradata during multi-threaded decoding */
--
1.7.7.3
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel