From b6a3f5f9ddb8d38f6fddf18d0a0984537dc7704c Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt Date: Sun, 18 May 2025 04:56:21 +0200 Subject: [PATCH 04/19] avcodec/mpegvideo_enc: Reduce stack usage Multiple PutBitContexts are used when encoding partitioned frames. When there are multiple candidates for macroblock types, multiple states (namely the state before encoding the current MB, the best state among the ones already tried and the current one) need to be kept; duplicates of the PutBitContexts are among this state. The temporary buffers for them are kept on the stack in encode_thread() and their size is quite generous (MAX_MB_SIZE - 3000 bytes). This commit uses tighter bounds, bringing the size of the pb2 buffer down to 15 bytes. Signed-off-by: Andreas Rheinhardt --- libavcodec/mpeg4videoenc.h | 12 ++++++++++++ libavcodec/mpegvideo_enc.c | 9 +++++---- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/libavcodec/mpeg4videoenc.h b/libavcodec/mpeg4videoenc.h index 815f16f073..4e20b8aaa0 100644 --- a/libavcodec/mpeg4videoenc.h +++ b/libavcodec/mpeg4videoenc.h @@ -27,6 +27,18 @@ #include "put_bits.h" +enum { + MAX_PB2_INTRA_SIZE = 1 /* ac_pred */ + 5 /* max cbpy len */ + + 2 /* dquant */ + 1 /* interlaced dct */ + + 4 * (8 /* longest luma dct_dc_size */ + + 9 /* longest dc diff */ + 1 /* marker */) + + 2 * (9 + 9 + 1), + MAX_PB2_INTER_SIZE = 5 /* max cbpy len */ + + 2 /* dquant */ + 1 /* interlaced_dct */ + 1, + MAX_PB2_MB_SIZE = (FFMAX(MAX_PB2_INTER_SIZE, MAX_PB2_INTRA_SIZE) + 7) / 8, + MAX_AC_TEX_MB_SIZE = 64 * 6 * 30 /* longest escape code */ / 8, +}; + typedef struct MPVEncContext MPVEncContext; void ff_set_mpeg4_time(MPVEncContext *s); diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c index 62a3a82ff3..8d3c003182 100644 --- a/libavcodec/mpegvideo_enc.c +++ b/libavcodec/mpegvideo_enc.c @@ -2978,14 +2978,15 @@ static int encode_thread(AVCodecContext *c, void *arg){ int i; MBBackup best_s = { 0 }, backup_s; uint8_t bit_buf[2][MAX_MB_BYTES]; - uint8_t bit_buf2[2][MAX_MB_BYTES]; - uint8_t bit_buf_tex[2][MAX_MB_BYTES]; + // + 2 because ff_copy_bits() overreads + uint8_t bit_buf2[2][MAX_PB2_MB_SIZE + 2]; + uint8_t bit_buf_tex[2][MAX_AC_TEX_MB_SIZE + 2]; PutBitContext pb[2], pb2[2], tex_pb[2]; for(i=0; i<2; i++){ init_put_bits(&pb [i], bit_buf [i], MAX_MB_BYTES); - init_put_bits(&pb2 [i], bit_buf2 [i], MAX_MB_BYTES); - init_put_bits(&tex_pb[i], bit_buf_tex[i], MAX_MB_BYTES); + init_put_bits(&pb2 [i], bit_buf2 [i], MAX_PB2_MB_SIZE); + init_put_bits(&tex_pb[i], bit_buf_tex[i], MAX_AC_TEX_MB_SIZE); } s->last_bits= put_bits_count(&s->pb); -- 2.45.2