[FFmpeg-devel] [PATCH 7/7] avcodec/movtextenc: Don't copy data around unnecessarily
Andreas Rheinhardt
andreas.rheinhardt at outlook.com
Sun Feb 18 03:43:08 EET 2024
Using av_bprint_init_for_buffer() avoids copying data
into the internal AVBPrint buffer (or worse: to allocate
a temporary buffer in case the internal buffer does not
suffice).
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt at outlook.com>
---
libavcodec/movtextenc.c | 33 ++++++++++++++++++---------------
1 file changed, 18 insertions(+), 15 deletions(-)
diff --git a/libavcodec/movtextenc.c b/libavcodec/movtextenc.c
index 7aa74d7c9d..fd8c7dc9f7 100644
--- a/libavcodec/movtextenc.c
+++ b/libavcodec/movtextenc.c
@@ -22,7 +22,6 @@
#include <stdarg.h>
#include "avcodec.h"
#include "libavutil/opt.h"
-#include "libavutil/avstring.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/mem.h"
#include "libavutil/common.h"
@@ -170,7 +169,6 @@ static int mov_text_encode_close(AVCodecContext *avctx)
ff_ass_split_free(s->ass_ctx);
av_freep(&s->style_attributes);
av_freep(&s->fonts);
- av_bprint_finalize(&s->buffer, NULL);
return 0;
}
@@ -183,6 +181,9 @@ static int encode_sample_description(AVCodecContext *avctx)
int font_names_total_len = 0;
MovTextContext *s = avctx->priv_data;
uint8_t buf[30], *p = buf;
+ int ret;
+
+ av_bprint_init(&s->buffer, 0, INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE + 1);
// 0x00, 0x00, 0x00, 0x00, // uint32_t displayFlags
// 0x01, // int8_t horizontal-justification
@@ -306,19 +307,23 @@ static int encode_sample_description(AVCodecContext *avctx)
// };
if (!av_bprint_is_complete(&s->buffer)) {
- return AVERROR(ENOMEM);
+ ret = AVERROR(ENOMEM);
+ goto fail;
}
avctx->extradata_size = s->buffer.len;
avctx->extradata = av_mallocz(avctx->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE);
if (!avctx->extradata) {
- return AVERROR(ENOMEM);
+ ret = AVERROR(ENOMEM);
+ goto fail;
}
memcpy(avctx->extradata, s->buffer.str, avctx->extradata_size);
- av_bprint_clear(&s->buffer);
+ ret = 0;
+fail:
+ av_bprint_finalize(&s->buffer, NULL);
- return 0;
+ return ret;
}
static av_cold int mov_text_encode_init(AVCodecContext *avctx)
@@ -327,8 +332,6 @@ static av_cold int mov_text_encode_init(AVCodecContext *avctx)
MovTextContext *s = avctx->priv_data;
s->avctx = avctx;
- av_bprint_init(&s->buffer, 0, AV_BPRINT_SIZE_UNLIMITED);
-
s->ass_ctx = ff_ass_split(avctx->subtitle_header);
if (!s->ass_ctx)
return AVERROR_INVALIDDATA;
@@ -640,10 +643,14 @@ static int mov_text_encode_frame(AVCodecContext *avctx, unsigned char *buf,
ASSDialog *dialog;
int i, length;
+ if (bufsize < 3)
+ goto too_small;
+
s->text_pos = 0;
s->count = 0;
s->box_flags = 0;
- av_bprint_clear(&s->buffer);
+
+ av_bprint_init_for_buffer(&s->buffer, buf + 2, bufsize - 2);
for (i = 0; i < sub->num_rects; i++) {
const char *ass = sub->rects[i]->ass;
@@ -663,23 +670,19 @@ static int mov_text_encode_frame(AVCodecContext *avctx, unsigned char *buf,
if (s->buffer.len > UINT16_MAX)
return AVERROR(ERANGE);
AV_WB16(buf, s->buffer.len);
- buf += 2;
for (size_t j = 0; j < box_count; j++)
box_types[j].encode(s);
- if (!av_bprint_is_complete(&s->buffer))
- return AVERROR(ENOMEM);
-
if (!s->buffer.len)
return 0;
- if (s->buffer.len > bufsize - 3) {
+ if (!av_bprint_is_complete(&s->buffer)) {
+too_small:
av_log(avctx, AV_LOG_ERROR, "Buffer too small for ASS event.\n");
return AVERROR_BUFFER_TOO_SMALL;
}
- memcpy(buf, s->buffer.str, s->buffer.len);
length = s->buffer.len + 2;
return length;
--
2.34.1
More information about the ffmpeg-devel
mailing list