[FFmpeg-devel] [PATCH 5/5] avcodec/bsf/vvc_mp4toannexb: Don't realloc when creating new extradata
Andreas Rheinhardt
andreas.rheinhardt at outlook.com
Sun Feb 18 04:44:27 EET 2024
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.rheinhardt at 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
More information about the ffmpeg-devel
mailing list