PR #25477 opened by Kilian (lusoris) URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25477 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25477.patch
This patch addresses GCC 14.4.0 and 16.2.1 -Wstack-usage diagnostics against -Wstack-usage=122880 in libavcodec/ffv1enc.c, with slice storage declared in libavcodec/ffv1.h. Result: warnings in this file go from 1 to 0 with GCC 14.4.0 and with GCC 16.2.1. What the patch does: - `avcodec/ffv1enc: move float remap scratch to slice state`: allocates multiplier and score tables once per slice for 32-bit remapping, adds an allocation failure path and frees the tables on close; score resets remain per optimizer iteration. Behaviour change: per-slice heap allocations can fail; remap calculations are unchanged when allocation succeeds. Base: FFmpeg master 46f23be8b1. Testing: - GCC 14.4.0 (`--enable-gpl --enable-vulkan`) and GCC 16.2.1 (`--enable-gpl --enable-vulkan --enable-vaapi --enable-libdrm --enable-nvenc`), targets all, alltools, examples, testprogs and checkasm: master 46f23be8b1 shows 1 -Wstack-usage warning in libavcodec/ffv1enc.c with each compiler; with this patch there are none and no new ones. - FATE with GCC 16.2.1: 31 tests whose name contains `ffv1` ran, and all 31 pass on master and with this patch. The 11 `ffv1` `vsynth_lena` tests were left out of this run because my local FATE sample copy has no lena image. Split out of #25111 so that each part reaches the reviewers for its area. >From f442ad6c8438de6966b99cdfe81f4c99d2f5924a Mon Sep 17 00:00:00 2001 From: lusoris <[email protected]> Date: Thu, 15 Oct 2026 22:06:35 +0200 Subject: [PATCH] avcodec/ffv1enc: move float remap scratch to slice state GCC 14.4.0 and 16.2.1 report -Wstack-usage against FFmpeg's default -Wstack-usage=122880 limit. The float remap multiplier and score tables occupy large automatic arrays. Allocate them once per slice for 32-bit remapping and free them on close. Keep the score table reset for each optimizer iteration, leaving remap calculations unchanged when allocation succeeds. Signed-off-by: lusoris <[email protected]> --- libavcodec/ffv1.h | 7 +++++++ libavcodec/ffv1enc.c | 13 +++++++++++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/libavcodec/ffv1.h b/libavcodec/ffv1.h index 012b92ec212..614a00a1c38 100644 --- a/libavcodec/ffv1.h +++ b/libavcodec/ffv1.h @@ -68,6 +68,12 @@ typedef struct PlaneContext { VlcState *vlc_state; } PlaneContext; +typedef struct FFV1FloatRemapState { + /* Large encoder scratch reused by every frame of a slice. */ + int mul[11][1025]; + float score[1025][23]; +} FFV1FloatRemapState; + #define MAX_SLICES 1024 typedef struct FFV1SliceContext { @@ -104,6 +110,7 @@ typedef struct FFV1SliceContext { struct { uint64_t rc_stat[256][2]; uint64_t (*rc_stat2[MAX_QUANT_TABLES])[32][2]; + FFV1FloatRemapState *float_remap_state; }; }; int remap_count[4]; diff --git a/libavcodec/ffv1enc.c b/libavcodec/ffv1enc.c index 1d18f10f05f..5ba7e08638c 100644 --- a/libavcodec/ffv1enc.c +++ b/libavcodec/ffv1enc.c @@ -1072,6 +1072,11 @@ static av_cold int encode_init_internal(AVCodecContext *avctx) } av_assert0(s->remap_mode >= 0); if (s->remap_mode) { + if (s->bits_per_raw_sample == 32) { + sc->float_remap_state = av_malloc(sizeof(*sc->float_remap_state)); + if (!sc->float_remap_state) + return AVERROR(ENOMEM); + } for (int p = 0; p < 1 + 2*s->chroma_planes + s->transparency ; p++) { if (s->bits_per_raw_sample == 32) { sc->unit[p] = av_malloc_array(sc->slice_width, sc->slice_height * sizeof(**sc->unit)); @@ -1520,19 +1525,21 @@ static void encode_float32_remap(FFV1Context *f, FFV1SliceContext *sc, const int bruteforce_count = ((int[]){ 0, 0, 0, 1, 1, 1})[f->remap_optimizer]; const int stair_mode = ((int[]){ 0, 0, 0, 1, 0, 0})[f->remap_optimizer]; const int magic_log2 = ((int[]){ 1, 1, 1, 1, 0, 0})[f->remap_optimizer]; + int (*const mul_all)[1025] = sc->float_remap_state->mul; + float (*const score_tab_all)[23] = sc->float_remap_state->score; for (int p= 0; p < 1 + 2*f->chroma_planes + f->transparency; p++) { int best_log2_mul_count = 0; float score_sum[11] = {0}; - int mul_all[11][1025]; for (int log2_mul_count= 0; log2_mul_count <= max_log2_mul_count; log2_mul_count += log2_mul_count_step) { - float score_tab_all[1025][23] = {0}; int64_t last_val = -1; int *mul_tab = mul_all[log2_mul_count]; int last_mul_index = -1; int mul_count = 1 << log2_mul_count; + memset(score_tab_all, 0, 1025 * sizeof(*score_tab_all)); + score_sum[log2_mul_count] = 2 * log2_mul_count; if (magic_log2) score_sum[log2_mul_count] = av_float2int((float)mul_count * mul_count); @@ -1605,6 +1612,7 @@ static void encode_float32_remap(FFV1Context *f, FFV1SliceContext *sc, encode_float32_remap_segment(sc, p, 1<<best_log2_mul_count, mul_all[best_log2_mul_count], 1, 1); } + } static int encode_float32_rgb_frame(FFV1Context *f, FFV1SliceContext *sc, @@ -2051,6 +2059,7 @@ static av_cold int encode_close(AVCodecContext *avctx) av_freep(&sc->unit[p]); av_freep(&sc->bitmap[p]); } + av_freep(&sc->float_remap_state); } av_freep(&avctx->stats_out); -- 2.54.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
