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

avcodec/ffv1: Only allocate fltmap* and bitmap when needed

This reduces memory requirements

Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
This commit is contained in:
Michael Niedermayer
2025-04-02 16:30:28 +02:00
parent b67cf79683
commit 06c00f9355
5 changed files with 44 additions and 13 deletions

View File

@@ -233,6 +233,10 @@ av_cold void ff_ffv1_close(FFV1Context *s)
av_freep(&sc->sample_buffer);
av_freep(&sc->sample_buffer32);
for(int p = 0; p < 4 ; p++) {
av_freep(&sc->fltmap[p]);
av_freep(&sc->fltmap32[p]);
}
av_refstruct_unref(&sc->plane);
}

View File

@@ -106,11 +106,10 @@ typedef struct FFV1SliceContext {
uint64_t (*rc_stat2[MAX_QUANT_TABLES])[32][2];
};
};
union {
uint16_t bitmap [4][65536]; //float encode
uint16_t fltmap [4][65536]; //halffloat encode & decode
uint32_t fltmap32[4][65536]; //float decode
};
uint16_t *bitmap [4]; //float encode
uint16_t *fltmap [4]; //halffloat encode & decode
uint32_t *fltmap32[4]; //float decode
struct Unit {
uint32_t val; //this is unneeded if you accept a dereference on each access
uint16_t ndx;

View File

@@ -326,7 +326,7 @@ static int decode_remap(FFV1Context *f, FFV1SliceContext *sc)
}
if (i - 1 >= end)
break;
if (j >= FF_ARRAY_ELEMS(sc->fltmap[p]))
if (j >= 65536 /*FF_ARRAY_ELEMS(sc->fltmap[p])*/)
return AVERROR_INVALIDDATA;
if (end <= 0xFFFF) {
sc->fltmap [p][j++] = i ^ ((i& 0x8000) ? 0 : flip);
@@ -387,6 +387,22 @@ static int decode_slice(AVCodecContext *c, void *arg)
y = sc->slice_y;
if (sc->remap) {
for(int p = 0; p < 1 + 2*f->chroma_planes + f->transparency ; p++) {
if (f->avctx->bits_per_raw_sample == 32) {
if (!sc->fltmap32[p]) {
sc->fltmap32[p] = av_malloc_array(65536, sizeof(*sc->fltmap32[p]));
if (!sc->fltmap32[p])
return AVERROR(ENOMEM);
}
} else {
if (!sc->fltmap[p]) {
sc->fltmap[p] = av_malloc_array(65536, sizeof(*sc->fltmap[p]));
if (!sc->fltmap[p])
return AVERROR(ENOMEM);
}
}
}
ret = decode_remap(f, sc);
if (ret < 0)
return ret;

View File

@@ -326,7 +326,7 @@ static void load_plane(FFV1Context *f, FFV1SliceContext *sc,
{
int x, y;
memset(sc->fltmap[remap_index], 0, sizeof(sc->fltmap[remap_index]));
memset(sc->fltmap[remap_index], 0, 65536 * sizeof(*sc->fltmap[remap_index]));
for (y = 0; y < h; y++) {
if (f->bits_per_raw_sample <= 8) {
@@ -1012,11 +1012,20 @@ static av_cold int encode_init_internal(AVCodecContext *avctx)
p->context_count = s->context_count[p->quant_table_index];
}
av_assert0(s->remap_mode >= 0);
if (s->remap_mode && s->bits_per_raw_sample == 32) {
if (s->remap_mode) {
for (int p = 0; p < 1 + 2*s->chroma_planes + s->transparency ; p++) {
sc->unit[p] = av_malloc_array(sc->slice_width, sc->slice_height * sizeof(**sc->unit));
if (!sc->unit[p])
return AVERROR(ENOMEM);
if (s->bits_per_raw_sample == 32) {
sc->unit[p] = av_malloc_array(sc->slice_width, sc->slice_height * sizeof(**sc->unit));
if (!sc->unit[p])
return AVERROR(ENOMEM);
sc->bitmap[p] = av_malloc_array(sc->slice_width * sc->slice_height, sizeof(*sc->bitmap[p]));
if (!sc->bitmap[p])
return AVERROR(ENOMEM);
} else {
sc->fltmap[p] = av_malloc_array(65536, sizeof(*sc->fltmap[p]));
if (!sc->fltmap[p])
return AVERROR(ENOMEM);
}
}
}
@@ -1821,8 +1830,10 @@ static av_cold int encode_close(AVCodecContext *avctx)
for (int j = 0; j < s->max_slice_count; j++) {
FFV1SliceContext *sc = &s->slices[j];
for(int p = 0; p<4; p++)
for(int p = 0; p<4; p++) {
av_freep(&sc->unit[p]);
av_freep(&sc->bitmap[p]);
}
}
av_freep(&avctx->stats_out);

View File

@@ -134,7 +134,8 @@ static void RENAME(load_rgb_frame)(FFV1Context *f, FFV1SliceContext *sc,
int x, y;
int transparency = f->transparency;
memset(sc->fltmap, 0, sizeof(sc->fltmap));
for (int p = 0; p<3 + transparency; p++)
memset(sc->fltmap[p], 0, 65536 * sizeof(**sc->fltmap));
for (y = 0; y < h; y++) {
for (x = 0; x < w; x++) {