PR #22802 opened by mkver URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/22802 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/22802.patch
>From 2c300b12bf57e8492958ef551859061b7f8ba2ac Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <[email protected]> Date: Sun, 12 Apr 2026 12:53:22 +0200 Subject: [PATCH 1/3] avcodec/mpegvideo_dec: Use C version of h264chroma mc2 functions H.264 only uses these functions are only used with height 2 or 4 and the aarch64, arm and mips versions of them optimize based on this. Yet this is not true when these functions are used by the lowres code in mpegvideo_dec.c. So revert back to the C versions of these functions for mpegvideo_dec so that the H.264 decoder can still use fully optimized functions. Signed-off-by: Andreas Rheinhardt <[email protected]> --- libavcodec/h264chroma.c | 18 +++++++++++------- libavcodec/h264chroma.h | 5 +++++ libavcodec/h264chroma_template.c | 2 +- libavcodec/mpegvideo_dec.c | 6 ++++++ 4 files changed, 23 insertions(+), 8 deletions(-) diff --git a/libavcodec/h264chroma.c b/libavcodec/h264chroma.c index 0d152de59d..37ec09dfae 100644 --- a/libavcodec/h264chroma.c +++ b/libavcodec/h264chroma.c @@ -21,20 +21,24 @@ #include "h264chroma.h" #define BIT_DEPTH 8 +#define MC2_STATIC #include "h264chroma_template.c" +#undef MC2_STATIC #undef BIT_DEPTH #define BIT_DEPTH 16 +#define MC2_STATIC static #include "h264chroma_template.c" +#undef MC2_STATIC #undef BIT_DEPTH -#define SET_CHROMA(depth) \ - c->put_h264_chroma_pixels_tab[0] = put_h264_chroma_mc8_ ## depth ## _c; \ - c->put_h264_chroma_pixels_tab[1] = put_h264_chroma_mc4_ ## depth ## _c; \ - c->put_h264_chroma_pixels_tab[2] = put_h264_chroma_mc2_ ## depth ## _c; \ - c->avg_h264_chroma_pixels_tab[0] = avg_h264_chroma_mc8_ ## depth ## _c; \ - c->avg_h264_chroma_pixels_tab[1] = avg_h264_chroma_mc4_ ## depth ## _c; \ - c->avg_h264_chroma_pixels_tab[2] = avg_h264_chroma_mc2_ ## depth ## _c; \ +#define SET_CHROMA(depth) \ + c->put_h264_chroma_pixels_tab[0] = put_h264_chroma_mc8_ ## depth ## _c; \ + c->put_h264_chroma_pixels_tab[1] = put_h264_chroma_mc4_ ## depth ## _c; \ + c->put_h264_chroma_pixels_tab[2] = ff_put_h264_chroma_mc2_ ## depth ## _c; \ + c->avg_h264_chroma_pixels_tab[0] = avg_h264_chroma_mc8_ ## depth ## _c; \ + c->avg_h264_chroma_pixels_tab[1] = avg_h264_chroma_mc4_ ## depth ## _c; \ + c->avg_h264_chroma_pixels_tab[2] = ff_avg_h264_chroma_mc2_ ## depth ## _c; \ av_cold void ff_h264chroma_init(H264ChromaContext *c, int bit_depth) { diff --git a/libavcodec/h264chroma.h b/libavcodec/h264chroma.h index 9c81c18a76..80a82e4b25 100644 --- a/libavcodec/h264chroma.h +++ b/libavcodec/h264chroma.h @@ -39,4 +39,9 @@ void ff_h264chroma_init_mips(H264ChromaContext *c, int bit_depth); void ff_h264chroma_init_loongarch(H264ChromaContext *c, int bit_depth); void ff_h264chroma_init_riscv(H264ChromaContext *c, int bit_depth); +void ff_put_h264_chroma_mc2_8_c(uint8_t *dst, const uint8_t *src, + ptrdiff_t srcStride, int h, int x, int y); +void ff_avg_h264_chroma_mc2_8_c(uint8_t *dst, const uint8_t *src, + ptrdiff_t srcStride, int h, int x, int y); + #endif /* AVCODEC_H264CHROMA_H */ diff --git a/libavcodec/h264chroma_template.c b/libavcodec/h264chroma_template.c index b58be192cd..f6e6d4a2ec 100644 --- a/libavcodec/h264chroma_template.c +++ b/libavcodec/h264chroma_template.c @@ -26,7 +26,7 @@ #include "bit_depth_template.c" #define H264_CHROMA_MC(OPNAME, OP)\ -static void FUNCC(OPNAME ## h264_chroma_mc2)(uint8_t *_dst /*align 8*/, const uint8_t *_src /*align 1*/, ptrdiff_t stride, int h, int x, int y)\ +MC2_STATIC void FUNCC(ff_ ## OPNAME ## h264_chroma_mc2)(uint8_t *_dst /*align 8*/, const uint8_t *_src /*align 1*/, ptrdiff_t stride, int h, int x, int y)\ {\ pixel *dst = (pixel*)_dst;\ const pixel *src = (const pixel*)_src;\ diff --git a/libavcodec/mpegvideo_dec.c b/libavcodec/mpegvideo_dec.c index ad27180efd..6018e532df 100644 --- a/libavcodec/mpegvideo_dec.c +++ b/libavcodec/mpegvideo_dec.c @@ -101,6 +101,12 @@ av_cold int ff_mpv_decode_init(MpegEncContext *s, AVCodecContext *avctx) ff_mpv_idct_init(s); ff_h264chroma_init(&s->h264chroma, 8); //for lowres + // lowres may use the following width 2 functions with a height of 1, + // yet the H.264 decoder uses them with at least two rows. + // Override them with the C versions so that ASM functions can process + // two rows at a time. + s->h264chroma.avg_h264_chroma_pixels_tab[2] = ff_avg_h264_chroma_mc2_8_c; + s->h264chroma.put_h264_chroma_pixels_tab[2] = ff_put_h264_chroma_mc2_8_c; s->h264chroma.avg_h264_chroma_pixels_tab[3] = avg_h264_chroma_mc1; s->h264chroma.put_h264_chroma_pixels_tab[3] = put_h264_chroma_mc1; -- 2.52.0 >From 4397b35b0f2a0baa5b11daf0f8880e4b87d42731 Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <[email protected]> Date: Sun, 12 Apr 2026 13:08:03 +0200 Subject: [PATCH 2/3] avcodec/h264chroma: Fix incorrect alignment documentation Signed-off-by: Andreas Rheinhardt <[email protected]> --- libavcodec/h264chroma.h | 4 +++- libavcodec/h264chroma_template.c | 6 +++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/libavcodec/h264chroma.h b/libavcodec/h264chroma.h index 80a82e4b25..eab26ddd12 100644 --- a/libavcodec/h264chroma.h +++ b/libavcodec/h264chroma.h @@ -22,7 +22,9 @@ #include <stddef.h> #include <stdint.h> -typedef void (*h264_chroma_mc_func)(uint8_t *dst /*align 8*/, const uint8_t *src /*align 1*/, ptrdiff_t srcStride, int h, int x, int y); +typedef void (*h264_chroma_mc_func)(uint8_t *dst /* align width * (bit_depth+7)/8) */, + const uint8_t *src /* align (bit_depth+7)/8) */, + ptrdiff_t srcStride, int h, int x, int y); typedef struct H264ChromaContext { h264_chroma_mc_func put_h264_chroma_pixels_tab[4]; diff --git a/libavcodec/h264chroma_template.c b/libavcodec/h264chroma_template.c index f6e6d4a2ec..35470c054f 100644 --- a/libavcodec/h264chroma_template.c +++ b/libavcodec/h264chroma_template.c @@ -26,7 +26,7 @@ #include "bit_depth_template.c" #define H264_CHROMA_MC(OPNAME, OP)\ -MC2_STATIC void FUNCC(ff_ ## OPNAME ## h264_chroma_mc2)(uint8_t *_dst /*align 8*/, const uint8_t *_src /*align 1*/, ptrdiff_t stride, int h, int x, int y)\ +MC2_STATIC void FUNCC(ff_ ## OPNAME ## h264_chroma_mc2)(uint8_t *_dst, const uint8_t *_src, ptrdiff_t stride, int h, int x, int y)\ {\ pixel *dst = (pixel*)_dst;\ const pixel *src = (const pixel*)_src;\ @@ -65,7 +65,7 @@ MC2_STATIC void FUNCC(ff_ ## OPNAME ## h264_chroma_mc2)(uint8_t *_dst /*align 8* }\ }\ \ -static void FUNCC(OPNAME ## h264_chroma_mc4)(uint8_t *_dst /*align 8*/, const uint8_t *_src /*align 1*/, ptrdiff_t stride, int h, int x, int y)\ +static void FUNCC(OPNAME ## h264_chroma_mc4)(uint8_t *_dst, const uint8_t *_src, ptrdiff_t stride, int h, int x, int y)\ {\ pixel *dst = (pixel*)_dst;\ const pixel *src = (const pixel*)_src;\ @@ -110,7 +110,7 @@ static void FUNCC(OPNAME ## h264_chroma_mc4)(uint8_t *_dst /*align 8*/, const ui }\ }\ \ -static void FUNCC(OPNAME ## h264_chroma_mc8)(uint8_t *_dst /*align 8*/, const uint8_t *_src /*align 1*/, ptrdiff_t stride, int h, int x, int y)\ +static void FUNCC(OPNAME ## h264_chroma_mc8)(uint8_t *_dst, const uint8_t *_src, ptrdiff_t stride, int h, int x, int y)\ {\ pixel *dst = (pixel*)_dst;\ const pixel *src = (const pixel*)_src;\ -- 2.52.0 >From c606e77a4e0ece53253b37f41f6132a6a2766956 Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <[email protected]> Date: Sat, 11 Apr 2026 14:31:17 +0200 Subject: [PATCH 3/3] tests/checkasm/h264chroma: Use more realistic block sizes Signed-off-by: Andreas Rheinhardt <[email protected]> --- tests/checkasm/h264chroma.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/checkasm/h264chroma.c b/tests/checkasm/h264chroma.c index 732e992983..5115b8b3f1 100644 --- a/tests/checkasm/h264chroma.c +++ b/tests/checkasm/h264chroma.c @@ -53,6 +53,7 @@ static void check_chroma_mc(void) ff_h264chroma_init(&h, bit_depth); randomize_buffers(bit_depth); for (int size = 0; size < 3; size++) { + int block_size = 8 >> size; #define CHECK_CHROMA_MC(name) \ do { \ @@ -61,13 +62,13 @@ static void check_chroma_mc(void) for (int y = 0; y < 2; y++) { \ memcpy(dst0, src, 16 * 18 * SIZEOF_PIXEL); \ memcpy(dst1, src, 16 * 18 * SIZEOF_PIXEL); \ - call_ref(dst0, src, 16 * SIZEOF_PIXEL, 16, x, y); \ - call_new(dst1, src, 16 * SIZEOF_PIXEL, 16, x, y); \ + call_ref(dst0, src, 16 * SIZEOF_PIXEL, block_size, x, y); \ + call_new(dst1, src, 16 * SIZEOF_PIXEL, block_size, x, y); \ if (memcmp(dst0, dst1, 16 * 16 * SIZEOF_PIXEL)) { \ fprintf(stderr, #name "_%d: x:%i, y:%i\n", bit_depth, x, y); \ fail(); \ } \ - bench_new(dst1, src, 16 * SIZEOF_PIXEL, 16, x, y); \ + bench_new(dst1, src, 16 * SIZEOF_PIXEL, block_size, x, y); \ } \ } \ } \ -- 2.52.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
