1
0
mirror of https://github.com/FFmpeg/FFmpeg.git synced 2025-08-04 22:03:09 +02:00

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 <andreas.rheinhardt@outlook.com>
This commit is contained in:
Andreas Rheinhardt
2025-05-18 04:56:21 +02:00
parent f887a2b006
commit 295abb1fdc
2 changed files with 17 additions and 4 deletions

View File

@ -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);

View File

@ -2979,14 +2979,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);