From a96743a05c544d0fc0a41f301eaf3a2a839b61ba Mon Sep 17 00:00:00 2001 From: Timo Rothenpieler Date: Tue, 29 Sep 2020 23:19:23 +0200 Subject: avcodec/cuviddec: handle arbitrarily sized extradata --- libavcodec/cuviddec.c | 40 ++++++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 16 deletions(-) (limited to 'libavcodec/cuviddec.c') diff --git a/libavcodec/cuviddec.c b/libavcodec/cuviddec.c index bce584c9c6..a3d0bdd93c 100644 --- a/libavcodec/cuviddec.c +++ b/libavcodec/cuviddec.c @@ -88,7 +88,7 @@ typedef struct CuvidContext CUVIDDECODECAPS caps8, caps10, caps12; CUVIDPARSERPARAMS cuparseinfo; - CUVIDEOFORMATEX cuparse_ext; + CUVIDEOFORMATEX *cuparse_ext; CudaFunctions *cudl; CuvidFunctions *cvdl; @@ -684,6 +684,7 @@ static av_cold int cuvid_decode_end(AVCodecContext *avctx) av_buffer_unref(&ctx->hwdevice); av_freep(&ctx->key_frame); + av_freep(&ctx->cuparse_ext); cuvid_free_functions(&ctx->cvdl); @@ -793,6 +794,8 @@ static av_cold int cuvid_decode_init(AVCodecContext *avctx) CUVIDSOURCEDATAPACKET seq_pkt; CUcontext cuda_ctx = NULL; CUcontext dummy; + uint8_t *extradata; + uint32_t extradata_size; int ret = 0; enum AVPixelFormat pix_fmts[3] = { AV_PIX_FMT_CUDA, @@ -889,11 +892,8 @@ static av_cold int cuvid_decode_init(AVCodecContext *avctx) ctx->cudl = device_hwctx->internal->cuda_dl; memset(&ctx->cuparseinfo, 0, sizeof(ctx->cuparseinfo)); - memset(&ctx->cuparse_ext, 0, sizeof(ctx->cuparse_ext)); memset(&seq_pkt, 0, sizeof(seq_pkt)); - ctx->cuparseinfo.pExtVideoInfo = &ctx->cuparse_ext; - switch (avctx->codec->id) { #if CONFIG_H264_CUVID_DECODER case AV_CODEC_ID_H264: @@ -947,17 +947,25 @@ static av_cold int cuvid_decode_init(AVCodecContext *avctx) if (avctx->codec->bsfs) { const AVCodecParameters *par = avctx->internal->bsf->par_out; - ctx->cuparse_ext.format.seqhdr_data_length = par->extradata_size; - memcpy(ctx->cuparse_ext.raw_seqhdr_data, - par->extradata, - FFMIN(sizeof(ctx->cuparse_ext.raw_seqhdr_data), par->extradata_size)); + extradata = par->extradata; + extradata_size = par->extradata_size; } else if (avctx->extradata_size > 0) { - ctx->cuparse_ext.format.seqhdr_data_length = avctx->extradata_size; - memcpy(ctx->cuparse_ext.raw_seqhdr_data, - avctx->extradata, - FFMIN(sizeof(ctx->cuparse_ext.raw_seqhdr_data), avctx->extradata_size)); + extradata = avctx->extradata; + extradata_size = avctx->extradata_size; } + ctx->cuparse_ext = av_mallocz(sizeof(*ctx->cuparse_ext) + + FFMAX(extradata_size - sizeof(ctx->cuparse_ext->raw_seqhdr_data), 0)); + if (!ctx->cuparse_ext) { + ret = AVERROR(ENOMEM); + goto error; + } + + ctx->cuparse_ext->format.seqhdr_data_length = avctx->extradata_size; + memcpy(ctx->cuparse_ext->raw_seqhdr_data, extradata, extradata_size); + + ctx->cuparseinfo.pExtVideoInfo = ctx->cuparse_ext; + ctx->key_frame = av_mallocz(ctx->nb_surfaces * sizeof(int)); if (!ctx->key_frame) { ret = AVERROR(ENOMEM); @@ -986,8 +994,8 @@ static av_cold int cuvid_decode_init(AVCodecContext *avctx) if (ret < 0) goto error; - seq_pkt.payload = ctx->cuparse_ext.raw_seqhdr_data; - seq_pkt.payload_size = ctx->cuparse_ext.format.seqhdr_data_length; + seq_pkt.payload = ctx->cuparse_ext->raw_seqhdr_data; + seq_pkt.payload_size = ctx->cuparse_ext->format.seqhdr_data_length; if (seq_pkt.payload && seq_pkt.payload_size) { ret = CHECK_CU(ctx->cvdl->cuvidParseVideoData(ctx->cuparser, &seq_pkt)); @@ -1046,8 +1054,8 @@ static void cuvid_flush(AVCodecContext *avctx) if (ret < 0) goto error; - seq_pkt.payload = ctx->cuparse_ext.raw_seqhdr_data; - seq_pkt.payload_size = ctx->cuparse_ext.format.seqhdr_data_length; + seq_pkt.payload = ctx->cuparse_ext->raw_seqhdr_data; + seq_pkt.payload_size = ctx->cuparse_ext->format.seqhdr_data_length; if (seq_pkt.payload && seq_pkt.payload_size) { ret = CHECK_CU(ctx->cvdl->cuvidParseVideoData(ctx->cuparser, &seq_pkt)); -- cgit v1.2.3