mirror of https://git.ffmpeg.org/ffmpeg.git
avcodec/movtextenc: Don't copy data around unnecessarily
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@outlook.com>
This commit is contained in:
parent
e9a587af25
commit
4179c121c3
|
@ -22,7 +22,6 @@
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include "avcodec.h"
|
#include "avcodec.h"
|
||||||
#include "libavutil/opt.h"
|
#include "libavutil/opt.h"
|
||||||
#include "libavutil/avstring.h"
|
|
||||||
#include "libavutil/intreadwrite.h"
|
#include "libavutil/intreadwrite.h"
|
||||||
#include "libavutil/mem.h"
|
#include "libavutil/mem.h"
|
||||||
#include "libavutil/common.h"
|
#include "libavutil/common.h"
|
||||||
|
@ -170,7 +169,6 @@ static int mov_text_encode_close(AVCodecContext *avctx)
|
||||||
ff_ass_split_free(s->ass_ctx);
|
ff_ass_split_free(s->ass_ctx);
|
||||||
av_freep(&s->style_attributes);
|
av_freep(&s->style_attributes);
|
||||||
av_freep(&s->fonts);
|
av_freep(&s->fonts);
|
||||||
av_bprint_finalize(&s->buffer, NULL);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -183,6 +181,9 @@ static int encode_sample_description(AVCodecContext *avctx)
|
||||||
int font_names_total_len = 0;
|
int font_names_total_len = 0;
|
||||||
MovTextContext *s = avctx->priv_data;
|
MovTextContext *s = avctx->priv_data;
|
||||||
uint8_t buf[30], *p = buf;
|
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
|
// 0x00, 0x00, 0x00, 0x00, // uint32_t displayFlags
|
||||||
// 0x01, // int8_t horizontal-justification
|
// 0x01, // int8_t horizontal-justification
|
||||||
|
@ -306,19 +307,23 @@ static int encode_sample_description(AVCodecContext *avctx)
|
||||||
// };
|
// };
|
||||||
|
|
||||||
if (!av_bprint_is_complete(&s->buffer)) {
|
if (!av_bprint_is_complete(&s->buffer)) {
|
||||||
return AVERROR(ENOMEM);
|
ret = AVERROR(ENOMEM);
|
||||||
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
avctx->extradata_size = s->buffer.len;
|
avctx->extradata_size = s->buffer.len;
|
||||||
avctx->extradata = av_mallocz(avctx->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE);
|
avctx->extradata = av_mallocz(avctx->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE);
|
||||||
if (!avctx->extradata) {
|
if (!avctx->extradata) {
|
||||||
return AVERROR(ENOMEM);
|
ret = AVERROR(ENOMEM);
|
||||||
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(avctx->extradata, s->buffer.str, avctx->extradata_size);
|
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)
|
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;
|
MovTextContext *s = avctx->priv_data;
|
||||||
s->avctx = avctx;
|
s->avctx = avctx;
|
||||||
|
|
||||||
av_bprint_init(&s->buffer, 0, AV_BPRINT_SIZE_UNLIMITED);
|
|
||||||
|
|
||||||
s->ass_ctx = ff_ass_split(avctx->subtitle_header);
|
s->ass_ctx = ff_ass_split(avctx->subtitle_header);
|
||||||
if (!s->ass_ctx)
|
if (!s->ass_ctx)
|
||||||
return AVERROR_INVALIDDATA;
|
return AVERROR_INVALIDDATA;
|
||||||
|
@ -640,10 +643,14 @@ static int mov_text_encode_frame(AVCodecContext *avctx, unsigned char *buf,
|
||||||
ASSDialog *dialog;
|
ASSDialog *dialog;
|
||||||
int i, length;
|
int i, length;
|
||||||
|
|
||||||
|
if (bufsize < 3)
|
||||||
|
goto too_small;
|
||||||
|
|
||||||
s->text_pos = 0;
|
s->text_pos = 0;
|
||||||
s->count = 0;
|
s->count = 0;
|
||||||
s->box_flags = 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++) {
|
for (i = 0; i < sub->num_rects; i++) {
|
||||||
const char *ass = sub->rects[i]->ass;
|
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)
|
if (s->buffer.len > UINT16_MAX)
|
||||||
return AVERROR(ERANGE);
|
return AVERROR(ERANGE);
|
||||||
AV_WB16(buf, s->buffer.len);
|
AV_WB16(buf, s->buffer.len);
|
||||||
buf += 2;
|
|
||||||
|
|
||||||
for (size_t j = 0; j < box_count; j++)
|
for (size_t j = 0; j < box_count; j++)
|
||||||
box_types[j].encode(s);
|
box_types[j].encode(s);
|
||||||
|
|
||||||
if (!av_bprint_is_complete(&s->buffer))
|
|
||||||
return AVERROR(ENOMEM);
|
|
||||||
|
|
||||||
if (!s->buffer.len)
|
if (!s->buffer.len)
|
||||||
return 0;
|
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");
|
av_log(avctx, AV_LOG_ERROR, "Buffer too small for ASS event.\n");
|
||||||
return AVERROR_BUFFER_TOO_SMALL;
|
return AVERROR_BUFFER_TOO_SMALL;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(buf, s->buffer.str, s->buffer.len);
|
|
||||||
length = s->buffer.len + 2;
|
length = s->buffer.len + 2;
|
||||||
|
|
||||||
return length;
|
return length;
|
||||||
|
|
Loading…
Reference in New Issue