AVCodecParameters.extradata is supposed to be allocated with av_malloc(); av_realloc() and its wrappers do not guarantee the proper alignment. Therefore parse the extradata twice: Once to check its validity and to determine the eventual size and a second time to actually write the new extradata.
(Of course, not reallocating the buffer is beneficial in itself.) Signed-off-by: Andreas Rheinhardt <andreas.rheinha...@outlook.com> --- libavcodec/bsf/vvc_mp4toannexb.c | 51 ++++++++++++++++---------------- 1 file changed, 25 insertions(+), 26 deletions(-) diff --git a/libavcodec/bsf/vvc_mp4toannexb.c b/libavcodec/bsf/vvc_mp4toannexb.c index bfb0338116..1879c1fab9 100644 --- a/libavcodec/bsf/vvc_mp4toannexb.c +++ b/libavcodec/bsf/vvc_mp4toannexb.c @@ -38,13 +38,11 @@ typedef struct VVCBSFContext { } VVCBSFContext; static int vvc_extradata_to_annexb_internal(void *logctx, GetByteContext *gb, - uint8_t **new_extradatap, + uint8_t *new_extradata, size_t *new_extradata_sizep) { int num_arrays = bytestream2_get_byte(gb); - uint8_t *new_extradata = NULL; size_t new_extradata_size = 0; - int ret; for (int i = 0; i < num_arrays; i++) { int cnt; @@ -55,15 +53,15 @@ static int vvc_extradata_to_annexb_internal(void *logctx, GetByteContext *gb, else cnt = bytestream2_get_be16(gb); - av_log(logctx, AV_LOG_DEBUG, "nalu_type %d cnt %d\n", type, cnt); + if (!new_extradata) + av_log(logctx, AV_LOG_DEBUG, "nalu_type %d cnt %d\n", type, cnt); if (!(type == VVC_OPI_NUT || type == VVC_DCI_NUT || type == VVC_VPS_NUT || type == VVC_SPS_NUT || type == VVC_PPS_NUT || type == VVC_PREFIX_SEI_NUT || type == VVC_SUFFIX_SEI_NUT)) { av_log(logctx, AV_LOG_ERROR, "Invalid NAL unit type in extradata: %d\n", type); - ret = AVERROR_INVALIDDATA; - goto fail; + return AVERROR_INVALIDDATA; } for (int j = 0; j < cnt; j++) { @@ -72,30 +70,21 @@ static int vvc_extradata_to_annexb_internal(void *logctx, GetByteContext *gb, if (!nalu_len || nalu_len > bytestream2_get_bytes_left(gb) || 4 + nalu_len > FFMIN(INT_MAX, SIZE_MAX) - AV_INPUT_BUFFER_PADDING_SIZE - new_extradata_size) { - ret = AVERROR_INVALIDDATA; - goto fail; + return AVERROR_INVALIDDATA; } - ret = av_reallocp(&new_extradata, new_extradata_size + nalu_len + 4 - + AV_INPUT_BUFFER_PADDING_SIZE); - if (ret < 0) - goto fail; - - AV_WB32(new_extradata + new_extradata_size, 1); // add the startcode - bytestream2_get_buffer(gb, new_extradata + new_extradata_size + 4, - nalu_len); + if (new_extradata) { + AV_WB32(new_extradata + new_extradata_size, 1); // add the startcode + bytestream2_get_bufferu(gb, new_extradata + new_extradata_size + 4, + nalu_len); + } else + bytestream2_skipu(gb, nalu_len); new_extradata_size += 4 + nalu_len; - memset(new_extradata + new_extradata_size, 0, - AV_INPUT_BUFFER_PADDING_SIZE); } } - *new_extradatap = new_extradata; *new_extradata_sizep = new_extradata_size; return 0; -fail: - av_freep(&new_extradata); - return ret; } static int vvc_extradata_to_annexb(AVBSFContext *ctx) @@ -193,10 +182,20 @@ static int vvc_extradata_to_annexb(AVBSFContext *ctx) max_picture_width, max_picture_height, avg_frame_rate); } - ret = vvc_extradata_to_annexb_internal(ctx, &gb, &new_extradata, - &new_extradata_size); - if (ret < 0) - return ret; + while (1) { + GetByteContext gb_bak = gb; + ret = vvc_extradata_to_annexb_internal(ctx, &gb, new_extradata, + &new_extradata_size); + if (ret < 0) + return ret; + if (new_extradata || !new_extradata_size) + break; + new_extradata = av_malloc(new_extradata_size + AV_INPUT_BUFFER_PADDING_SIZE); + if (!new_extradata) + return AVERROR(ENOMEM); + memset(new_extradata + new_extradata_size, 0, AV_INPUT_BUFFER_PADDING_SIZE); + gb = gb_bak; + } av_freep(&ctx->par_out->extradata); ctx->par_out->extradata = new_extradata; -- 2.34.1 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".