[PATCH 2/2] lavc/vvc: add AVX2 planar intra prediction
Gudikandula Samith via ffmpeg-devel <[email protected]> Sat, 25 Jul 2026 21:36:58 +0000
| Newsgroups | gmane.comp.video.ffmpeg.devel |
|---|---|
| Message-ID | <[email protected]> |
Implements pred_planar for x86-64 AVX2 at 8 bit. Benchmarks on AMD Ryzen 7 5825U: vvc_pred_planar_4x4_8_c: 52.8 vvc_pred_planar_4x4_8_avx2: 24.1 (2.16x) vvc_pred_planar_8x8_8_c: 208.3 vvc_pred_planar_8x8_8_avx2: 48.3 (4.31x) vvc_pred_planar_16x16_8_c: 778.0 vvc_pred_planar_16x16_8_avx2: 160.4 (4.80x) vvc_pred_planar_32x32_8_c: 2356.0 vvc_pred_planar_32x32_8_avx2: 580.3 (4.02x) vvc_pred_planar_64x64_8_c: 7414.0 vvc_pred_planar_64x64_8_avx2: 2185.9 (3.27x) Signed-off-by: Gudikandula Samith <[email protected]> --- libavcodec/x86/vvc/Makefile | 1 + libavcodec/x86/vvc/dsp_init.c | 13 ++ libavcodec/x86/vvc/intra.asm | 224 ++++++++++++++++++++++++++++++++++ 3 files changed, 238 insertions(+) create mode 100644 libavcodec/x86/vvc/intra.asm diff --git a/libavcodec/x86/vvc/Makefile b/libavcodec/x86/vvc/Makefile index 0cebfb4e9e..b24ea6e692 100644 --- a/libavcodec/x86/vvc/Makefile +++ b/libavcodec/x86/vvc/Makefile @@ -4,6 +4,7 @@ clean:: X86ASM-OBJS-$(CONFIG_VVC_DECODER) += x86/vvc/dsp_init.o \ x86/vvc/alf.o \ x86/vvc/dmvr.o \ + x86/vvc/intra.o \ x86/vvc/mc.o \ x86/vvc/of.o \ x86/vvc/sad.o \ diff --git a/libavcodec/x86/vvc/dsp_init.c b/libavcodec/x86/vvc/dsp_init.c index 6802294795..4f187e1eb1 100644 --- a/libavcodec/x86/vvc/dsp_init.c +++ b/libavcodec/x86/vvc/dsp_init.c @@ -292,6 +292,16 @@ void bf(ff_vvc_alf_filter_chroma, bd, opt)(uint8_t *dst, ptrdiff_t dst_stride, \ c->alf.classify = bf(vvc_alf_classify, bd, opt); \ } while (0) +#define INTRA_PROTOTYPE(bd, opt) \ +void ff_vvc_pred_planar_##bd##_##opt(uint8_t *src, const uint8_t *top, \ + const uint8_t *left, int w, int h, ptrdiff_t stride); + +INTRA_PROTOTYPE(8, avx2) + +#define INTRA_INIT(bd, opt) do { \ + c->intra.pred_planar = ff_vvc_pred_planar_##bd##_##opt; \ +} while (0) + #endif @@ -321,6 +331,9 @@ av_cold void ff_vvc_dsp_init_x86(VVCDSPContext *const c, const int bd) // filter ALF_INIT(8, avx2); SAO_INIT(8, avx2); + + // intra + INTRA_INIT(8, avx2); } #endif break; diff --git a/libavcodec/x86/vvc/intra.asm b/libavcodec/x86/vvc/intra.asm new file mode 100644 index 0000000000..c18c17193a --- /dev/null +++ b/libavcodec/x86/vvc/intra.asm @@ -0,0 +1,224 @@ +; /* +; * Provide SIMD planar intra prediction functions for VVC decoding +; * +; * Copyright (c) 2026 Gudikandula Samith <[email protected]> +; * +; * This file is part of FFmpeg. +; * +; * FFmpeg is free software; you can redistribute it and/or +; * modify it under the terms of the GNU Lesser General Public +; * License as published by the Free Software Foundation; either +; * version 2.1 of the License, or (at your option) any later version. +; * +; * FFmpeg is distributed in the hope that it will be useful, +; * but WITHOUT ANY WARRANTY; without even the implied warranty of +; * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +; * Lesser General Public License for more details. +; * +; * You should have received a copy of the GNU Lesser General Public +; * License along with FFmpeg; if not, write to the Free Software +; * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +; */ + +%include "libavutil/x86/x86util.asm" + +SECTION_RODATA 32 + +pw_wm1x_w4: dw 3, 2, 1, 0, 0, 0, 0, 0 +pw_xp1_w4: dw 1, 2, 3, 4, 0, 0, 0, 0 +pw_wm1x_w8: dw 7, 6, 5, 4, 3, 2, 1, 0 +pw_xp1_w8: dw 1, 2, 3, 4, 5, 6, 7, 8 +pw_wm1x_w16: dw 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 ; (w - 1 - x) +pw_xp1_w16: dw 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 ; (x + 1) +pw_wm1x_w32: dw 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, \ + 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 +pw_xp1_w32: dw 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, \ + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32 +pw_wm1x_w64: dw 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, \ + 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, \ + 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, \ + 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 +pw_xp1_w64: dw 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, \ + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, \ + 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, \ + 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64 + + +SECTION .text + +%if ARCH_X86_64 +%if HAVE_AVX2_EXTERNAL + +INIT_YMM avx2 + +; Per-row scalars, broadcast into vector registers: +; m8 = A = (h-1-y) +; m9 = B = (y+1) * left[h] +; m10 = C = left[y] +%macro ROW_CONSTANTS 0 + mov eax, r12d + sub eax, r11d ;A=(h-1-y) + movd xm8, eax + vpbroadcastw m8, xm8 + lea eax, [r11d+1] + imul eax, r10d ;B=(y+1)*left[h] + movd xm9, eax + vpbroadcastw m9, xm9 + movzx eax, byte [leftq+r11] + movd xm10, eax + vpbroadcastw m10, xm10 +%endmacro +; Block-constant setup shared by every width. +; %1 = logw (immediate), %2 = top[w] byte offset (=width) +%macro PLANAR_SETUP 2 + mov r13d, hd + bsr r6d, hd + lea r7d, [r6d +%1 +1] + mov r8d, hd + shl r8d, %1 ;size=w*h= h<<logw + movzx r9d, byte [topq + %2] + movzx r10d, byte [leftq +r13] + movd xm3, r9d + vpbroadcastw m3, xm3 + movd xm4, r8d + vpbroadcastd m4, xm4 + movd xm5, r6d + movd xm6, r7d + mov r12d, hd + dec r12d + xor r11d, r11d +%endmacro + +; Process 16 columns starting at column offset %3. +; %1 = (w-1-x) table, %2 = (x+1) table, %3 = column offset, %4 = logw immediate +%macro PLANAR16 4 + pmovzxbw m0, [topq+%3] + movu m1, [%1 + %3*2] + movu m2, [%2 + %3*2] + vpmullw m11, m0, m8 + vpaddw m11, m11, m9 + vpmullw m12, m1, m10 + vpmullw m2, m2, m3 + vpaddw m12, m12, m2 + pmovzxwd m13, xm11 + pmovzxwd m14, xm12 + vpslld m13, m13, %4 + vpslld m14, m14, xm5 + vpaddd m13, m13, m14 + vpaddd m13, m13, m4 + vpsrad m13, m13, xm6 + vextracti128 xm11, m11, 1 + vextracti128 xm12, m12, 1 + pmovzxwd m14, xm11 + pmovzxwd m15, xm12 + vpslld m14, m14, %4 + vpslld m15, m15, xm5 + vpaddd m14, m14, m15 + vpaddd m14, m14, m4 + vpsrad m14, m14, xm6 + packusdw m13, m13, m14 + vpermq m13, m13, 11011000b + packuswb m13, m13, m13 + vpermq m13, m13, 11011000b + movu [srcq + %3], xm13 +%endmacro + +; Process a narrow row of 4 or 8 columns (offset 0). +; %1 = (w-1-x) table, %2 = (x+1) table, %3 = logw immediate, %4 = store instruction +%macro PLANAR_NARROW 4 + pmovzxbw xm0, [topq] + movu xm1, [%1] + movu xm2, [%2] + vpmullw xm11, xm0, xm8 + vpaddw xm11, xm11, xm9 + vpmullw xm12, xm1, xm10 + vpmullw xm2, xm2, xm3 + vpaddw xm12, xm12, xm2 + pmovzxwd m13, xm11 + pmovzxwd m14, xm12 + vpslld m13, m13, %3 + vpslld m14, m14, xm5 + vpaddd m13, m13, m14 + vpaddd m13, m13, m4 + vpsrad m13, m13, xm6 + packusdw m13, m13, m13 + vpermq m13, m13, 11011000b + packuswb m13, m13, m13 + %4 [srcq], xm13 +%endmacro + +; void ff_vvc_pred_planar_8_avx2(uint8_t *src, const uint8_t *top, +; const uint8_t *left, int w, int h, +; ptrdiff_t stride); +cglobal vvc_pred_planar_8, 6, 14, 16, src, top, left, w, h, stride + cmp wd, 16 + je .w16 + cmp wd, 8 + je .w8 + cmp wd, 32 + je .w32 + cmp wd, 64 + je .w64 + ; fall through to width 4 + +.w4: + PLANAR_SETUP 2, 4 +.w4_row: + ROW_CONSTANTS + PLANAR_NARROW pw_wm1x_w4, pw_xp1_w4, 2, movd + add srcq, strideq + inc r11d + cmp r11d, hd + jl .w4_row + RET + +.w8: + PLANAR_SETUP 3, 8 +.w8_row: + ROW_CONSTANTS + PLANAR_NARROW pw_wm1x_w8, pw_xp1_w8, 3, movq + add srcq, strideq + inc r11d + cmp r11d, hd + jl .w8_row + RET + +.w16: + PLANAR_SETUP 4, 16 +.w16_row: + ROW_CONSTANTS + PLANAR16 pw_wm1x_w16, pw_xp1_w16, 0, 4 + add srcq, strideq + inc r11d + cmp r11d, hd + jl .w16_row + RET + +.w32: + PLANAR_SETUP 5, 32 +.w32_row: + ROW_CONSTANTS + PLANAR16 pw_wm1x_w32, pw_xp1_w32, 0, 5 + PLANAR16 pw_wm1x_w32, pw_xp1_w32, 16, 5 + add srcq, strideq + inc r11d + cmp r11d, hd + jl .w32_row + RET + +.w64: + PLANAR_SETUP 6, 64 +.w64_row: + ROW_CONSTANTS + PLANAR16 pw_wm1x_w64, pw_xp1_w64, 0, 6 + PLANAR16 pw_wm1x_w64, pw_xp1_w64, 16, 6 + PLANAR16 pw_wm1x_w64, pw_xp1_w64, 32, 6 + PLANAR16 pw_wm1x_w64, pw_xp1_w64, 48, 6 + add srcq, strideq + inc r11d + cmp r11d, hd + jl .w64_row + RET + +%endif +%endif -- 2.53.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]