PR #25480 opened by Kilian (lusoris) URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25480 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25480.patch
These patches address GCC 14.4.0 and 16.2.1 -Wstack-usage diagnostics against -Wstack-usage=122880 in VVC scaled prediction (libavcodec/vvc/inter_template.c) and in the VVC checkasm tests (tests/checkasm/vvc_alf.c, tests/checkasm/vvc_mc.c and tests/checkasm/vvc_sao.c). Result: warnings in these files go from 29 to 0 with GCC 14.4.0 and from 29 to 0 with GCC 16.2.1. What the patches do: - `avcodec/vvc: move scaled prediction scratch into the local context`: moves the large automatic intermediate array into enlarged, aligned local context storage (libavcodec/vvc/ctu.h) and changes internal DSP callback signatures (libavcodec/vvc/dsp.h, libavcodec/vvc/inter.c) to pass that storage through scaled prediction. - `tests/checkasm/vvc: move large scratch buffers to the heap`: moves large sample and pixel buffers in the ALF, MC and SAO checks to heap storage, asserts allocation success and frees the buffers after use; the SAO checks get explicit destination padding. Behaviour change: decoder scratch storage moves to the local context and internal callback signatures change; buffer dimensions and filtering calculations are unchanged. The test buffers use heap allocations; test cases and comparisons are unchanged. 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, with each compiler, 18 -Wstack-usage warnings in libavcodec/vvc/inter_template.c, 7 in tests/checkasm/vvc_mc.c, 2 in tests/checkasm/vvc_alf.c and 2 in tests/checkasm/vvc_sao.c; with these patches there are none and no new ones. - FATE with GCC 16.2.1, the 69 tests whose name contains `vvc`, including `checkasm-vvc_alf`, `checkasm-vvc_mc`, `checkasm-vvc_pred` and `checkasm-vvc_sao`: all 69 ran and pass on master and with these patches. Split out of #25111 so that each part reaches the reviewers for its area. >From 680caec8eac0755b00a6084f6f7df7c67a95e9c8 Mon Sep 17 00:00:00 2001 From: lusoris <[email protected]> Date: Thu, 15 Oct 2026 22:06:35 +0200 Subject: [PATCH 1/2] avcodec/vvc: move scaled prediction scratch into the local context GCC 14.4.0 and 16.2.1 report -Wstack-usage against FFmpeg's default -Wstack-usage=122880 limit. Scaled prediction uses a large automatic intermediate array. Move it to aligned local context storage and pass it through the scaled prediction DSP callbacks. Buffer dimensions and filtering calculations are unchanged. Signed-off-by: lusoris <[email protected]> --- libavcodec/vvc/ctu.h | 1 + libavcodec/vvc/dsp.h | 8 +++++--- libavcodec/vvc/inter.c | 11 ++++++----- libavcodec/vvc/inter_template.c | 32 ++++++++++++++++---------------- 4 files changed, 28 insertions(+), 24 deletions(-) diff --git a/libavcodec/vvc/ctu.h b/libavcodec/vvc/ctu.h index 59366a17569..d089fa4d8b9 100644 --- a/libavcodec/vvc/ctu.h +++ b/libavcodec/vvc/ctu.h @@ -443,6 +443,7 @@ typedef struct VVCLocalContext { struct { /* *2 for high bit depths */ DECLARE_ALIGNED(32, uint8_t, edge_emu_buffer)[EDGE_EMU_BUFFER_STRIDE * EDGE_EMU_BUFFER_STRIDE * 2]; + DECLARE_ALIGNED(32, int16_t, scaled_tmp)[EDGE_EMU_BUFFER_STRIDE * MAX_PB_SIZE]; DECLARE_ALIGNED(32, int16_t, tmp)[MAX_PB_SIZE * MAX_PB_SIZE]; DECLARE_ALIGNED(32, int16_t, tmp1)[MAX_PB_SIZE * MAX_PB_SIZE]; union { diff --git a/libavcodec/vvc/dsp.h b/libavcodec/vvc/dsp.h index 29cdd7e8f49..239ac9f5104 100644 --- a/libavcodec/vvc/dsp.h +++ b/libavcodec/vvc/dsp.h @@ -58,15 +58,17 @@ typedef struct VVCInterDSPContext { int denom, int wx, int ox, const int8_t *hf, const int8_t *vf, int width); void (*put_scaled[2 /* luma, chroma */][7 /* log2(width) - 1 */])( - int16_t *dst, const uint8_t *src, ptrdiff_t src_stride, int src_height, + int16_t *tmp, int16_t *dst, const uint8_t *src, ptrdiff_t src_stride, int src_height, int x, int y, int dx, int dy, int height, const int8_t *hf, const int8_t *vf, int width); void (*put_uni_scaled[2 /* luma, chroma */][7 /* log2(width) - 1 */])( - uint8_t *dst, const ptrdiff_t dst_stride, const uint8_t *src, ptrdiff_t src_stride, int src_height, + int16_t *tmp, uint8_t *dst, const ptrdiff_t dst_stride, const uint8_t *src, + ptrdiff_t src_stride, int src_height, int x, int y, int dx, int dy, int height, const int8_t *hf, const int8_t *vf, int width); void (*put_uni_w_scaled[2 /* luma, chroma */][7 /* log2(width) - 1 */])( - uint8_t *dst, const ptrdiff_t dst_stride, const uint8_t *src, ptrdiff_t src_stride, int src_height, + int16_t *tmp, uint8_t *dst, const ptrdiff_t dst_stride, const uint8_t *src, + ptrdiff_t src_stride, int src_height, int x, int y, int dx, int dy, int height, int denom, int wx, int ox, const int8_t *hf, const int8_t *vf, int width); diff --git a/libavcodec/vvc/inter.c b/libavcodec/vvc/inter.c index fe7ce722e5f..f75cff470aa 100644 --- a/libavcodec/vvc/inter.c +++ b/libavcodec/vvc/inter.c @@ -434,7 +434,8 @@ static void mc_scaled(VVCLocalContext *lc, int16_t *dst, const VVCRefPic *refp, scaled_ref_pos_and_step(lc, refp, mv, x_off, y_off, c_idx, &x, &y, &dx, &dy); emulated_edge_scaled(lc, &src, &src_stride, &src_height, refp->ref, x, y, dx, dy, block_w, block_h, is_chroma); - fc->vvcdsp.inter.put_scaled[is_chroma][idx](dst, src, src_stride, src_height, x, y, dx, dy, block_h, hf, vf, block_w); + fc->vvcdsp.inter.put_scaled[is_chroma][idx](lc->pred.scaled_tmp, dst, src, src_stride, + src_height, x, y, dx, dy, block_h, hf, vf, block_w); } static void mc_uni_scaled(VVCLocalContext *lc, uint8_t *dst, const ptrdiff_t dst_stride, const VVCRefPic *refp, @@ -457,11 +458,11 @@ static void mc_uni_scaled(VVCLocalContext *lc, uint8_t *dst, const ptrdiff_t dst emulated_edge_scaled(lc, &src, &src_stride, &src_height, refp->ref, x, y, dx, dy, block_w, block_h, is_chroma); if (derive_weight_uni(&denom, &wx, &ox, lc, mvf, c_idx)) { - fc->vvcdsp.inter.put_uni_w_scaled[is_chroma][idx](dst, dst_stride, src, src_stride, src_height, - x, y, dx, dy, block_h, denom, wx, ox, hf, vf, block_w); + fc->vvcdsp.inter.put_uni_w_scaled[is_chroma][idx](lc->pred.scaled_tmp, dst, dst_stride, + src, src_stride, src_height, x, y, dx, dy, block_h, denom, wx, ox, hf, vf, block_w); } else { - fc->vvcdsp.inter.put_uni_scaled[is_chroma][idx](dst, dst_stride, src, src_stride, src_height, - x, y, dx, dy, block_h, hf, vf, block_w); + fc->vvcdsp.inter.put_uni_scaled[is_chroma][idx](lc->pred.scaled_tmp, dst, dst_stride, + src, src_stride, src_height, x, y, dx, dy, block_h, hf, vf, block_w); } } diff --git a/libavcodec/vvc/inter_template.c b/libavcodec/vvc/inter_template.c index efa432d1fde..0287e6c2dac 100644 --- a/libavcodec/vvc/inter_template.c +++ b/libavcodec/vvc/inter_template.c @@ -24,12 +24,12 @@ #include "libavutil/imgutils.h" #define TMP_STRIDE EDGE_EMU_BUFFER_STRIDE -static void av_always_inline FUNC(put_scaled)(uint8_t *_dst, const ptrdiff_t _dst_stride, +static void av_always_inline FUNC(put_scaled)(int16_t *tmp_array, + uint8_t *_dst, const ptrdiff_t _dst_stride, const uint8_t *const _src, ptrdiff_t _src_stride, const int src_height, const int _x, const int _y, const int dx, const int dy, const int height, const int8_t *hf, const int8_t *vf, const int width, const int is_uni, const int is_chroma) { - int16_t tmp_array[TMP_STRIDE * MAX_PB_SIZE]; int16_t *tmp = tmp_array; pixel *dst = (pixel*)_dst; int16_t *dst16 = (int16_t*)_dst; @@ -81,44 +81,44 @@ static void av_always_inline FUNC(put_scaled)(uint8_t *_dst, const ptrdiff_t _ds } } -static void FUNC(put_luma_scaled)(int16_t *_dst, +static void FUNC(put_luma_scaled)(int16_t *tmp, int16_t *_dst, const uint8_t *_src, ptrdiff_t _src_stride, const int src_height, const int x, const int y, const int dx, const int dy, const int height, const int8_t *hf, const int8_t *vf, const int width) { - FUNC(put_scaled)((uint8_t *)_dst, MAX_PB_SIZE * sizeof(pixel), _src, _src_stride, src_height, x, y, dx, dy, height, hf, vf, width, 0, 0); + FUNC(put_scaled)(tmp, (uint8_t *)_dst, MAX_PB_SIZE * sizeof(pixel), _src, _src_stride, src_height, x, y, dx, dy, height, hf, vf, width, 0, 0); } -static void FUNC(put_chroma_scaled)(int16_t *_dst, +static void FUNC(put_chroma_scaled)(int16_t *tmp, int16_t *_dst, const uint8_t *_src, ptrdiff_t _src_stride, const int src_height, const int x, const int y, const int dx, const int dy, const int height, const int8_t *hf, const int8_t *vf, const int width) { - FUNC(put_scaled)((uint8_t *)_dst, MAX_PB_SIZE * sizeof(pixel), _src, _src_stride, src_height, x, y, dx, dy, height, hf, vf, width, 0, 1); + FUNC(put_scaled)(tmp, (uint8_t *)_dst, MAX_PB_SIZE * sizeof(pixel), _src, _src_stride, src_height, x, y, dx, dy, height, hf, vf, width, 0, 1); } -static void FUNC(put_uni_luma_scaled)(uint8_t *_dst, const ptrdiff_t _dst_stride, +static void FUNC(put_uni_luma_scaled)(int16_t *tmp, uint8_t *_dst, const ptrdiff_t _dst_stride, const uint8_t *_src, ptrdiff_t _src_stride, const int src_height, const int x, const int y, const int dx, const int dy, const int height, const int8_t *hf, const int8_t *vf, const int width) { - FUNC(put_scaled)(_dst, _dst_stride, _src, _src_stride, src_height, x, y, dx, dy, height, hf, vf, width, 1, 0); + FUNC(put_scaled)(tmp, _dst, _dst_stride, _src, _src_stride, src_height, x, y, dx, dy, height, hf, vf, width, 1, 0); } -static void FUNC(put_uni_chroma_scaled)(uint8_t *_dst, const ptrdiff_t _dst_stride, +static void FUNC(put_uni_chroma_scaled)(int16_t *tmp, uint8_t *_dst, const ptrdiff_t _dst_stride, const uint8_t *_src, ptrdiff_t _src_stride, const int src_height, const int x, const int y, const int dx, const int dy, const int height, const int8_t *hf, const int8_t *vf, const int width) { - FUNC(put_scaled)(_dst, _dst_stride, _src, _src_stride, src_height, x, y, dx, dy, height, hf, vf, width, 1, 1); + FUNC(put_scaled)(tmp, _dst, _dst_stride, _src, _src_stride, src_height, x, y, dx, dy, height, hf, vf, width, 1, 1); } -static void av_always_inline FUNC(put_uni_w_scaled)(uint8_t *_dst, const ptrdiff_t _dst_stride, +static void av_always_inline FUNC(put_uni_w_scaled)(int16_t *tmp_array, + uint8_t *_dst, const ptrdiff_t _dst_stride, const uint8_t *const _src, ptrdiff_t _src_stride, const int src_height, const int _x, const int _y, const int dx, const int dy, const int denom, const int wx, const int _ox, const int height, const int8_t *hf, const int8_t *vf, const int width, const int is_chroma) { - int16_t tmp_array[TMP_STRIDE * MAX_PB_SIZE]; int16_t *tmp = tmp_array; pixel *dst = (pixel*)_dst; const ptrdiff_t dst_stride = _dst_stride / sizeof(pixel); @@ -164,20 +164,20 @@ static void av_always_inline FUNC(put_uni_w_scaled)(uint8_t *_dst, const ptrdiff } } -static void FUNC(put_uni_luma_w_scaled)(uint8_t *_dst, const ptrdiff_t _dst_stride, +static void FUNC(put_uni_luma_w_scaled)(int16_t *tmp, uint8_t *_dst, const ptrdiff_t _dst_stride, const uint8_t *_src, ptrdiff_t _src_stride, const int src_height, const int x, const int y, const int dx, const int dy, const int denom, const int wx, const int ox, const int height, const int8_t *hf, const int8_t *vf, const int width) { - FUNC(put_uni_w_scaled)(_dst, _dst_stride, _src, _src_stride, src_height, x, y, dx, dy, denom, wx, ox, height, hf, vf, width, 0); + FUNC(put_uni_w_scaled)(tmp, _dst, _dst_stride, _src, _src_stride, src_height, x, y, dx, dy, denom, wx, ox, height, hf, vf, width, 0); } -static void FUNC(put_uni_chroma_w_scaled)(uint8_t *_dst, const ptrdiff_t _dst_stride, +static void FUNC(put_uni_chroma_w_scaled)(int16_t *tmp, uint8_t *_dst, const ptrdiff_t _dst_stride, const uint8_t *_src, ptrdiff_t _src_stride, const int src_height, const int x, const int y, const int dx, const int dy, const int denom, const int wx, const int ox, const int height, const int8_t *hf, const int8_t *vf, const int width) { - FUNC(put_uni_w_scaled)(_dst, _dst_stride, _src, _src_stride, src_height, x, y, dx, dy, denom, wx, ox, height, hf, vf, width, 1); + FUNC(put_uni_w_scaled)(tmp, _dst, _dst_stride, _src, _src_stride, src_height, x, y, dx, dy, denom, wx, ox, height, hf, vf, width, 1); } #undef TMP_STRIDE -- 2.54.0 >From cdec24494024e3eb57ae71ee11f2c4bc28a3841a Mon Sep 17 00:00:00 2001 From: lusoris <[email protected]> Date: Mon, 26 Oct 2026 11:24:39 +0100 Subject: [PATCH 2/2] tests/checkasm/vvc: move large scratch buffers to the heap GCC 14.4.0 and 16.2.1 report -Wstack-usage against FFmpeg's default -Wstack-usage=122880 limit in the VVC ALF, MC and SAO checks. Large automatic sample and pixel buffers increase their stack requirements. Move those buffers to heap storage, assert allocation success and free them after use. Keep the same test cases and comparisons, with explicit destination padding for the sample adaptive offset checks. Signed-off-by: lusoris <[email protected]> --- tests/checkasm/vvc_alf.c | 43 ++++++++++++---- tests/checkasm/vvc_mc.c | 107 +++++++++++++++++++++++++++++---------- tests/checkasm/vvc_sao.c | 66 ++++++++++++++++-------- 3 files changed, 157 insertions(+), 59 deletions(-) diff --git a/tests/checkasm/vvc_alf.c b/tests/checkasm/vvc_alf.c index fcb9ca0bc0d..dd637cede94 100644 --- a/tests/checkasm/vvc_alf.c +++ b/tests/checkasm/vvc_alf.c @@ -26,8 +26,10 @@ #include "libavcodec/vvc/data.h" #include "libavcodec/vvc/dsp.h" +#include "libavutil/avassert.h" #include "libavutil/common.h" #include "libavutil/intreadwrite.h" +#include "libavutil/mem.h" #include "libavutil/mem_internal.h" static const uint32_t pixel_mask[3] = { 0xffffffff, 0x03ff03ff, 0x0fff0fff }; @@ -76,10 +78,10 @@ static int get_alf_vb_pos(const int h, const int vb_pos_above) static void check_alf_filter(VVCDSPContext *c, const int bit_depth) { - LOCAL_ALIGNED_32(uint8_t, dst0, [DST_BUF_SIZE]); - LOCAL_ALIGNED_32(uint8_t, dst1, [DST_BUF_SIZE]); - LOCAL_ALIGNED_32(uint8_t, src0, [SRC_BUF_SIZE]); - LOCAL_ALIGNED_32(uint8_t, src1, [SRC_BUF_SIZE]); + uint8_t *dst0 = av_malloc(DST_BUF_SIZE); + uint8_t *dst1 = av_malloc(DST_BUF_SIZE); + uint8_t *src0 = av_malloc(SRC_BUF_SIZE); + uint8_t *src1 = av_malloc(SRC_BUF_SIZE); int16_t filter[LUMA_PARAMS_SIZE]; int16_t clip[LUMA_PARAMS_SIZE]; @@ -94,6 +96,8 @@ static void check_alf_filter(VVCDSPContext *c, const int bit_depth) declare_func(void, uint8_t *dst, ptrdiff_t dst_stride, const uint8_t *src, ptrdiff_t src_stride, int width, int height, const int16_t *filter, const int16_t *clip, const int vb_pos); + av_assert0(dst0 && dst1 && src0 && src1); + randomize_buffers(src0, src1, SRC_BUF_SIZE); randomize_buffers2(filter, LUMA_PARAMS_SIZE, 1); randomize_buffers2(clip, LUMA_PARAMS_SIZE, 0); @@ -129,17 +133,23 @@ static void check_alf_filter(VVCDSPContext *c, const int bit_depth) } } } + + av_free(dst0); + av_free(dst1); + av_free(src0); + av_free(src1); } static void check_alf_classify(VVCDSPContext *c, const int bit_depth) { - LOCAL_ALIGNED_32(int, class_idx0, [SRC_BUF_SIZE]); - LOCAL_ALIGNED_32(int, transpose_idx0, [SRC_BUF_SIZE]); - LOCAL_ALIGNED_32(int, class_idx1, [SRC_BUF_SIZE]); - LOCAL_ALIGNED_32(int, transpose_idx1, [SRC_BUF_SIZE]); - LOCAL_ALIGNED_32(uint8_t, src0, [SRC_BUF_SIZE]); - LOCAL_ALIGNED_32(uint8_t, src1, [SRC_BUF_SIZE]); - LOCAL_ALIGNED_32(int32_t, alf_gradient_tmp, [ALF_GRADIENT_SIZE * ALF_GRADIENT_SIZE * ALF_NUM_DIR]); + int *class_idx0 = av_malloc_array(SRC_BUF_SIZE, sizeof(*class_idx0)); + int *transpose_idx0 = av_malloc_array(SRC_BUF_SIZE, sizeof(*transpose_idx0)); + int *class_idx1 = av_malloc_array(SRC_BUF_SIZE, sizeof(*class_idx1)); + int *transpose_idx1 = av_malloc_array(SRC_BUF_SIZE, sizeof(*transpose_idx1)); + uint8_t *src0 = av_malloc(SRC_BUF_SIZE); + uint8_t *src1 = av_malloc(SRC_BUF_SIZE); + int32_t *alf_gradient_tmp = av_malloc_array(ALF_GRADIENT_SIZE * ALF_GRADIENT_SIZE * ALF_NUM_DIR, + sizeof(*alf_gradient_tmp)); ptrdiff_t stride = SRC_PIXEL_STRIDE * SIZEOF_PIXEL; int offset = (3 * SRC_PIXEL_STRIDE + 3) * SIZEOF_PIXEL; @@ -147,6 +157,9 @@ static void check_alf_classify(VVCDSPContext *c, const int bit_depth) declare_func(void, int *class_idx, int *transpose_idx, const uint8_t *src, ptrdiff_t src_stride, int width, int height, int vb_pos, int *gradient_tmp); + av_assert0(class_idx0 && transpose_idx0 && class_idx1 && transpose_idx1 && + src0 && src1 && alf_gradient_tmp); + randomize_buffers(src0, src1, SRC_BUF_SIZE); //Both picture size and virtual boundaries are 8-aligned. Classify is luma only, we only need to check 8-aligned sizes. @@ -173,6 +186,14 @@ static void check_alf_classify(VVCDSPContext *c, const int bit_depth) } } } + + av_free(class_idx0); + av_free(transpose_idx0); + av_free(class_idx1); + av_free(transpose_idx1); + av_free(src0); + av_free(src1); + av_free(alf_gradient_tmp); } void checkasm_check_vvc_alf(void) diff --git a/tests/checkasm/vvc_mc.c b/tests/checkasm/vvc_mc.c index d712cb81100..4ff5ec244b5 100644 --- a/tests/checkasm/vvc_mc.c +++ b/tests/checkasm/vvc_mc.c @@ -26,8 +26,10 @@ #include "libavcodec/vvc/data.h" #include "libavcodec/vvc/dsp.h" +#include "libavutil/avassert.h" #include "libavutil/common.h" #include "libavutil/intreadwrite.h" +#include "libavutil/mem.h" #include "libavutil/mem_internal.h" static const uint32_t pixel_mask[] = { 0xffffffff, 0x03ff03ff, 0x0fff0fff, 0x3fff3fff, 0xffffffff }; @@ -74,15 +76,17 @@ static const int sizes[] = { 2, 4, 8, 16, 32, 64, 128 }; static av_noinline void check_put_vvc_luma(void) { - LOCAL_ALIGNED_32(int16_t, dst0, [DST_BUF_SIZE / 2]); - LOCAL_ALIGNED_32(int16_t, dst1, [DST_BUF_SIZE / 2]); - LOCAL_ALIGNED_32(uint8_t, src0, [SRC_BUF_SIZE]); - LOCAL_ALIGNED_32(uint8_t, src1, [SRC_BUF_SIZE]); + int16_t *dst0 = av_malloc(DST_BUF_SIZE); + int16_t *dst1 = av_malloc(DST_BUF_SIZE); + uint8_t *src0 = av_malloc(SRC_BUF_SIZE); + uint8_t *src1 = av_malloc(SRC_BUF_SIZE); VVCDSPContext c; declare_func(void, int16_t *dst, const uint8_t *src, const ptrdiff_t src_stride, const int height, const int8_t *hf, const int8_t *vf, const int width); + av_assert0(dst0 && dst1 && src0 && src1); + for (int bit_depth = 8; bit_depth <= 12; bit_depth += 2) { randomize_pixels(src0, src1, SRC_BUF_SIZE); ff_vvc_dsp_init(&c, bit_depth); @@ -118,20 +122,27 @@ static av_noinline void check_put_vvc_luma(void) } } report("put_luma"); + + av_free(dst0); + av_free(dst1); + av_free(src0); + av_free(src1); } static av_noinline void check_put_vvc_luma_uni(void) { - LOCAL_ALIGNED_32(uint8_t, dst0, [DST_BUF_SIZE]); - LOCAL_ALIGNED_32(uint8_t, dst1, [DST_BUF_SIZE]); - LOCAL_ALIGNED_32(uint8_t, src0, [SRC_BUF_SIZE]); - LOCAL_ALIGNED_32(uint8_t, src1, [SRC_BUF_SIZE]); + uint8_t *dst0 = av_malloc(DST_BUF_SIZE); + uint8_t *dst1 = av_malloc(DST_BUF_SIZE); + uint8_t *src0 = av_malloc(SRC_BUF_SIZE); + uint8_t *src1 = av_malloc(SRC_BUF_SIZE); VVCDSPContext c; declare_func(void, uint8_t *dst, ptrdiff_t dststride, const uint8_t *src, ptrdiff_t srcstride, int height, const int8_t *hf, const int8_t *vf, int width); + av_assert0(dst0 && dst1 && src0 && src1); + for (int bit_depth = 8; bit_depth <= 12; bit_depth += 2) { ff_vvc_dsp_init(&c, bit_depth); randomize_pixels(src0, src1, SRC_BUF_SIZE); @@ -169,19 +180,26 @@ static av_noinline void check_put_vvc_luma_uni(void) } } report("put_uni_luma"); + + av_free(dst0); + av_free(dst1); + av_free(src0); + av_free(src1); } static av_noinline void check_put_vvc_chroma(void) { - LOCAL_ALIGNED_32(int16_t, dst0, [DST_BUF_SIZE / 2]); - LOCAL_ALIGNED_32(int16_t, dst1, [DST_BUF_SIZE / 2]); - LOCAL_ALIGNED_32(uint8_t, src0, [SRC_BUF_SIZE]); - LOCAL_ALIGNED_32(uint8_t, src1, [SRC_BUF_SIZE]); + int16_t *dst0 = av_malloc(DST_BUF_SIZE); + int16_t *dst1 = av_malloc(DST_BUF_SIZE); + uint8_t *src0 = av_malloc(SRC_BUF_SIZE); + uint8_t *src1 = av_malloc(SRC_BUF_SIZE); VVCDSPContext c; declare_func(void, int16_t *dst, const uint8_t *src, const ptrdiff_t src_stride, const int height, const int8_t *hf, const int8_t *vf, const int width); + av_assert0(dst0 && dst1 && src0 && src1); + for (int bit_depth = 8; bit_depth <= 12; bit_depth += 2) { randomize_pixels(src0, src1, SRC_BUF_SIZE); ff_vvc_dsp_init(&c, bit_depth); @@ -217,20 +235,27 @@ static av_noinline void check_put_vvc_chroma(void) } } report("put_chroma"); + + av_free(dst0); + av_free(dst1); + av_free(src0); + av_free(src1); } static av_noinline void check_put_vvc_chroma_uni(void) { - LOCAL_ALIGNED_32(uint8_t, dst0, [DST_BUF_SIZE]); - LOCAL_ALIGNED_32(uint8_t, dst1, [DST_BUF_SIZE]); - LOCAL_ALIGNED_32(uint8_t, src0, [SRC_BUF_SIZE]); - LOCAL_ALIGNED_32(uint8_t, src1, [SRC_BUF_SIZE]); + uint8_t *dst0 = av_malloc(DST_BUF_SIZE); + uint8_t *dst1 = av_malloc(DST_BUF_SIZE); + uint8_t *src0 = av_malloc(SRC_BUF_SIZE); + uint8_t *src1 = av_malloc(SRC_BUF_SIZE); VVCDSPContext c; declare_func(void, uint8_t *dst, ptrdiff_t dststride, const uint8_t *src, ptrdiff_t srcstride, int height, const int8_t *hf, const int8_t *vf, int width); + av_assert0(dst0 && dst1 && src0 && src1); + for (int bit_depth = 8; bit_depth <= 12; bit_depth += 2) { ff_vvc_dsp_init(&c, bit_depth); randomize_pixels(src0, src1, SRC_BUF_SIZE); @@ -268,6 +293,11 @@ static av_noinline void check_put_vvc_chroma_uni(void) } } report("put_uni_chroma"); + + av_free(dst0); + av_free(dst1); + av_free(src0); + av_free(src1); } #define AVG_SRC_BUF_SIZE (MAX_CTU_SIZE * MAX_CTU_SIZE) @@ -275,14 +305,16 @@ static av_noinline void check_put_vvc_chroma_uni(void) static av_noinline void check_avg(void) { - LOCAL_ALIGNED_32(int16_t, src00, [AVG_SRC_BUF_SIZE]); - LOCAL_ALIGNED_32(int16_t, src01, [AVG_SRC_BUF_SIZE]); - LOCAL_ALIGNED_32(int16_t, src10, [AVG_SRC_BUF_SIZE]); - LOCAL_ALIGNED_32(int16_t, src11, [AVG_SRC_BUF_SIZE]); - LOCAL_ALIGNED_32(uint8_t, dst0, [AVG_DST_BUF_SIZE]); - LOCAL_ALIGNED_32(uint8_t, dst1, [AVG_DST_BUF_SIZE]); + int16_t *src00 = av_malloc_array(AVG_SRC_BUF_SIZE, sizeof(*src00)); + int16_t *src01 = av_malloc_array(AVG_SRC_BUF_SIZE, sizeof(*src01)); + int16_t *src10 = av_malloc_array(AVG_SRC_BUF_SIZE, sizeof(*src10)); + int16_t *src11 = av_malloc_array(AVG_SRC_BUF_SIZE, sizeof(*src11)); + uint8_t *dst0 = av_malloc(AVG_DST_BUF_SIZE); + uint8_t *dst1 = av_malloc(AVG_DST_BUF_SIZE); VVCDSPContext c; + av_assert0(src00 && src01 && src10 && src11 && dst0 && dst1); + for (int bit_depth = 8; bit_depth <= 12; bit_depth += 2) { randomize_avg_src((uint8_t*)src00, (uint8_t*)src10, AVG_SRC_BUF_SIZE * sizeof(int16_t)); randomize_avg_src((uint8_t*)src01, (uint8_t*)src11, AVG_SRC_BUF_SIZE * sizeof(int16_t)); @@ -330,21 +362,30 @@ static av_noinline void check_avg(void) } } report("avg"); + + av_free(src00); + av_free(src01); + av_free(src10); + av_free(src11); + av_free(dst0); + av_free(dst1); } #define SR_RANGE 2 static av_noinline void check_dmvr(void) { - LOCAL_ALIGNED_32(uint16_t, dst0, [DST_BUF_SIZE]); - LOCAL_ALIGNED_32(uint16_t, dst1, [DST_BUF_SIZE]); - LOCAL_ALIGNED_32(uint8_t, src0, [SRC_BUF_SIZE]); - LOCAL_ALIGNED_32(uint8_t, src1, [SRC_BUF_SIZE]); + uint16_t *dst0 = av_malloc_array(DST_BUF_SIZE, sizeof(*dst0)); + uint16_t *dst1 = av_malloc_array(DST_BUF_SIZE, sizeof(*dst1)); + uint8_t *src0 = av_malloc(SRC_BUF_SIZE); + uint8_t *src1 = av_malloc(SRC_BUF_SIZE); const int dst_stride = MAX_PB_SIZE * sizeof(int16_t); VVCDSPContext c; declare_func(void, int16_t *dst, const uint8_t *src, ptrdiff_t src_stride, int height, intptr_t mx, intptr_t my, int width); + av_assert0(dst0 && dst1 && src0 && src1); + for (int bit_depth = 8; bit_depth <= 12; bit_depth += 2) { ff_vvc_dsp_init(&c, bit_depth); randomize_pixels(src0, src1, SRC_BUF_SIZE); @@ -388,6 +429,11 @@ static av_noinline void check_dmvr(void) } } report("dmvr"); + + av_free(dst0); + av_free(dst1); + av_free(src0); + av_free(src1); } #define BDOF_BLOCK_SIZE 16 @@ -435,10 +481,12 @@ static av_noinline void check_vvc_sad(void) { const int bit_depth = 10; VVCDSPContext c; - LOCAL_ALIGNED_32(uint16_t, src0, [MAX_CTU_SIZE * MAX_CTU_SIZE * 4]); - LOCAL_ALIGNED_32(uint16_t, src1, [MAX_CTU_SIZE * MAX_CTU_SIZE * 4]); + uint16_t *src0 = av_malloc_array(MAX_CTU_SIZE * MAX_CTU_SIZE * 4, sizeof(*src0)); + uint16_t *src1 = av_malloc_array(MAX_CTU_SIZE * MAX_CTU_SIZE * 4, sizeof(*src1)); declare_func(int, const int16_t *src0, const int16_t *src1, int dx, int dy, int block_w, int block_h); + av_assert0(src0 && src1); + ff_vvc_dsp_init(&c, bit_depth); randomize_pixels(src0, src1, MAX_CTU_SIZE * MAX_CTU_SIZE * 4); for (int h = 8; h <= 16; h *= 2) { @@ -466,6 +514,9 @@ static av_noinline void check_vvc_sad(void) } report("sad"); + + av_free(src0); + av_free(src1); } void checkasm_check_vvc_mc(void) diff --git a/tests/checkasm/vvc_sao.c b/tests/checkasm/vvc_sao.c index 4ad40684faf..1cc75c8bf84 100644 --- a/tests/checkasm/vvc_sao.c +++ b/tests/checkasm/vvc_sao.c @@ -21,7 +21,9 @@ #include <string.h> #include "checkasm.h" +#include "libavutil/avassert.h" #include "libavutil/intreadwrite.h" +#include "libavutil/mem.h" #include "libavutil/mem_internal.h" #include "libavcodec/vvc/dsp.h" @@ -33,6 +35,10 @@ static const uint32_t sao_size[] = {8, 16, 32, 48, 64, 80, 96, 112, 128}; #define SIZEOF_PIXEL ((bit_depth + 7) / 8) #define PIXEL_STRIDE (2*MAX_CTU_SIZE + AV_INPUT_BUFFER_PADDING_SIZE) //same with sao_edge src_stride #define BUF_SIZE (PIXEL_STRIDE * (MAX_CTU_SIZE+2) * 2) //+2 for top and bottom row, *2 for high bit depth +#define DST_BUF_W (CHECKASM_ROUND(MAX_CTU_SIZE, 64) + 64) +#define DST_BUF_H (MAX_CTU_SIZE + 32) +#define DST_RECT_BUF_SIZE (DST_BUF_H * DST_BUF_W + 64) +#define DST_RECT_OFFSET (DST_BUF_W * 16 + 64) #define OFFSET_THRESH (1 << (bit_depth - 5)) #define OFFSET_LENGTH 5 @@ -66,14 +72,19 @@ static const uint32_t sao_size[] = {8, 16, 32, 48, 64, 80, 96, 112, 128}; static void check_sao_band(VVCDSPContext *h, int bit_depth) { - PIXEL_RECT(dst0, MAX_CTU_SIZE, MAX_CTU_SIZE); - PIXEL_RECT(dst1, MAX_CTU_SIZE, MAX_CTU_SIZE); - LOCAL_ALIGNED_32(uint8_t, src0, [BUF_SIZE]); - LOCAL_ALIGNED_32(uint8_t, src1, [BUF_SIZE]); + uint16_t *dst0_buf = av_malloc_array(DST_RECT_BUF_SIZE, sizeof(*dst0_buf)); + uint16_t *dst1_buf = av_malloc_array(DST_RECT_BUF_SIZE, sizeof(*dst1_buf)); + uint8_t *dst0 = dst0_buf ? (uint8_t *)(dst0_buf + DST_RECT_OFFSET) : NULL; + uint8_t *dst1 = dst1_buf ? (uint8_t *)(dst1_buf + DST_RECT_OFFSET) : NULL; + const ptrdiff_t dst_stride = sizeof(*dst0_buf) * DST_BUF_W; + uint8_t *src0 = av_malloc(BUF_SIZE); + uint8_t *src1 = av_malloc(BUF_SIZE); int16_t offset_val[OFFSET_LENGTH]; const int left_class = rnd()%32; const int walign = 16; + av_assert0(dst0 && dst1 && src0 && src1); + for (int i = 0; i < FF_ARRAY_ELEMS(sao_size); i++) { const int block_size = sao_size[i]; const int prev_size = i > 0 ? sao_size[i - 1] : 0; @@ -86,28 +97,38 @@ static void check_sao_band(VVCDSPContext *h, int bit_depth) for (int w = prev_size + 4; w <= block_size; w += 4) { randomize_buffers(src0, src1, BUF_SIZE); randomize_buffers2(offset_val, OFFSET_LENGTH); - CLEAR_PIXEL_RECT(dst0); - CLEAR_PIXEL_RECT(dst1); + checkasm_clear(dst0_buf, DST_RECT_BUF_SIZE * sizeof(*dst0_buf)); + checkasm_clear(dst1_buf, DST_RECT_BUF_SIZE * sizeof(*dst1_buf)); - call_ref(dst0, src0, dst0_stride, stride, offset_val, left_class, w, block_size); - call_new(dst1, src1, dst1_stride, stride, offset_val, left_class, w, block_size); - checkasm_check_pixel_padded_align(dst0, dst0_stride, dst1, dst1_stride, w, block_size, "dst", walign, 1); + call_ref(dst0, src0, dst_stride, stride, offset_val, left_class, w, block_size); + call_new(dst1, src1, dst_stride, stride, offset_val, left_class, w, block_size); + checkasm_check_pixel_padded_align(dst0, dst_stride, dst1, dst_stride, w, block_size, "dst", walign, 1); } - bench_new(dst1, src1, dst1_stride, stride, offset_val, left_class, block_size, block_size); + bench_new(dst1, src1, dst_stride, stride, offset_val, left_class, block_size, block_size); } } + + av_free(dst0_buf); + av_free(dst1_buf); + av_free(src0); + av_free(src1); } static void check_sao_edge(VVCDSPContext *h, int bit_depth) { - PIXEL_RECT(dst0, MAX_CTU_SIZE, MAX_CTU_SIZE); - PIXEL_RECT(dst1, MAX_CTU_SIZE, MAX_CTU_SIZE); - LOCAL_ALIGNED_32(uint8_t, src0, [BUF_SIZE]); - LOCAL_ALIGNED_32(uint8_t, src1, [BUF_SIZE]); + uint16_t *dst0_buf = av_malloc_array(DST_RECT_BUF_SIZE, sizeof(*dst0_buf)); + uint16_t *dst1_buf = av_malloc_array(DST_RECT_BUF_SIZE, sizeof(*dst1_buf)); + uint8_t *dst0 = dst0_buf ? (uint8_t *)(dst0_buf + DST_RECT_OFFSET) : NULL; + uint8_t *dst1 = dst1_buf ? (uint8_t *)(dst1_buf + DST_RECT_OFFSET) : NULL; + const ptrdiff_t dst_stride = sizeof(*dst0_buf) * DST_BUF_W; + uint8_t *src0 = av_malloc(BUF_SIZE); + uint8_t *src1 = av_malloc(BUF_SIZE); int16_t offset_val[OFFSET_LENGTH]; const int eo = rnd()%4; const int walign = 16; + av_assert0(dst0 && dst1 && src0 && src1); + for (int i = 0; i < FF_ARRAY_ELEMS(sao_size); i++) { int block_size = sao_size[i]; int prev_size = i > 0 ? sao_size[i - 1] : 0; @@ -119,16 +140,21 @@ static void check_sao_edge(VVCDSPContext *h, int bit_depth) for (int w = prev_size + 4; w <= block_size; w += 4) { randomize_buffers(src0, src1, BUF_SIZE); randomize_buffers2(offset_val, OFFSET_LENGTH); - CLEAR_PIXEL_RECT(dst0); - CLEAR_PIXEL_RECT(dst1); + checkasm_clear(dst0_buf, DST_RECT_BUF_SIZE * sizeof(*dst0_buf)); + checkasm_clear(dst1_buf, DST_RECT_BUF_SIZE * sizeof(*dst1_buf)); - call_ref(dst0, src0 + offset, dst0_stride, offset_val, eo, w, block_size); - call_new(dst1, src1 + offset, dst1_stride, offset_val, eo, w, block_size); - checkasm_check_pixel_padded_align(dst0, dst0_stride, dst1, dst1_stride, w, block_size, "dst", walign, 1); + call_ref(dst0, src0 + offset, dst_stride, offset_val, eo, w, block_size); + call_new(dst1, src1 + offset, dst_stride, offset_val, eo, w, block_size); + checkasm_check_pixel_padded_align(dst0, dst_stride, dst1, dst_stride, w, block_size, "dst", walign, 1); } - bench_new(dst1, src1 + offset, dst1_stride, offset_val, eo, block_size, block_size); + bench_new(dst1, src1 + offset, dst_stride, offset_val, eo, block_size, block_size); } } + + av_free(dst0_buf); + av_free(dst1_buf); + av_free(src0); + av_free(src1); } void checkasm_check_vvc_sao(void) -- 2.54.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
