diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index c12d4ebf55..3667e723d6 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -3330,6 +3330,10 @@ void avcodec_get_context_defaults(AVCodecContext *s); * we WILL change its arguments and name a few times! */ void avcodec_get_context_defaults2(AVCodecContext *s, enum AVMediaType); +/** THIS FUNCTION IS NOT YET PART OF THE PUBLIC API! + * we WILL change its arguments and name a few times! */ +int avcodec_get_context_defaults3(AVCodecContext *s, AVCodec *codec); + /** * Allocate an AVCodecContext and set its fields to default values. The * resulting struct can be deallocated by simply calling av_free(). @@ -3343,6 +3347,10 @@ AVCodecContext *avcodec_alloc_context(void); * we WILL change its arguments and name a few times! */ AVCodecContext *avcodec_alloc_context2(enum AVMediaType); +/** THIS FUNCTION IS NOT YET PART OF THE PUBLIC API! + * we WILL change its arguments and name a few times! */ +AVCodecContext *avcodec_alloc_context3(AVCodec *codec); + /** * Copy the settings of the source AVCodecContext into the destination * AVCodecContext. The resulting destination codec context will be diff --git a/libavcodec/options.c b/libavcodec/options.c index d55d4fde26..6a6ac78e28 100644 --- a/libavcodec/options.c +++ b/libavcodec/options.c @@ -467,6 +467,36 @@ void avcodec_get_context_defaults2(AVCodecContext *s, enum AVMediaType codec_typ s->reordered_opaque= AV_NOPTS_VALUE; } +int avcodec_get_context_defaults3(AVCodecContext *s, AVCodec *codec){ + avcodec_get_context_defaults2(s, codec ? codec->type : AVMEDIA_TYPE_UNKNOWN); + if(codec && codec->priv_data_size){ + if(!s->priv_data){ + s->priv_data= av_mallocz(codec->priv_data_size); + if (!s->priv_data) { + return AVERROR(ENOMEM); + } + } + if(codec->priv_class){ + *(AVClass**)s->priv_data= codec->priv_class; + av_opt_set_defaults(s->priv_data); + } + } + return 0; +} + +AVCodecContext *avcodec_alloc_context3(AVCodec *codec){ + AVCodecContext *avctx= av_malloc(sizeof(AVCodecContext)); + + if(avctx==NULL) return NULL; + + if(avcodec_get_context_defaults3(avctx, codec) < 0){ + av_free(avctx); + return NULL; + } + + return avctx; +} + AVCodecContext *avcodec_alloc_context2(enum AVMediaType codec_type){ AVCodecContext *avctx= av_malloc(sizeof(AVCodecContext)); diff --git a/libavcodec/utils.c b/libavcodec/utils.c index ad80f0f4a3..7edff412ec 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -471,11 +471,17 @@ int attribute_align_arg avcodec_open(AVCodecContext *avctx, AVCodec *codec) goto end; if (codec->priv_data_size > 0) { + if(!avctx->priv_data){ avctx->priv_data = av_mallocz(codec->priv_data_size); if (!avctx->priv_data) { ret = AVERROR(ENOMEM); goto end; } + if(codec->priv_class){ //this can be droped once all user apps use avcodec_get_context_defaults3() + *(AVClass**)avctx->priv_data= codec->priv_class; + av_opt_set_defaults(avctx->priv_data); + } + } } else { avctx->priv_data = NULL; }