History

libavcodec/x86/vvc: Add AVX2 DMVR SAD functions for VVC

Implements AVX2 DMVR (decoder-side motion vector refinement) SAD functions. DMVR SAD is only calculated if w >= 8, h >= 8, and w * h > 128. To reduce complexity, SAD is only calculated on even rows. This is calculated for all video bitdepths, but the values passed to the function are always 16bit (even if the original video bitdepth is 8). The AVX2 implementation uses min/max/sub. Additionally this changes parameters dx and dy from int to intptr_t. This allows dx & dy to be used as pointer offsets without needing to use movsxd. Benchmarks ( AMD 7940HS ) Before: BQTerrace_1920x1080_60_10_420_22_RA.vvc | 106.0 | Chimera_8bit_1080P_1000_frames.vvc | 204.3 | NovosobornayaSquare_1920x1080.bin | 197.3 | RitualDance_1920x1080_60_10_420_37_RA.266 | 174.0 | After: BQTerrace_1920x1080_60_10_420_22_RA.vvc | 109.3 | Chimera_8bit_1080P_1000_frames.vvc | 216.0 | NovosobornayaSquare_1920x1080.bin | 204.0| RitualDance_1920x1080_60_10_420_37_RA.266 | 181.7 |

Stone Chen committed 2 years ago

Commit 0e52a4e1 parent 3146b773 files · +140 −0Browse files

Showing the changes to libavcodec (3 of 3 files). Show all

Unified · Split

3 files
  1. libavcodec/x86/vvc/Makefile +1 −0
  2. libavcodec/x86/vvc/vvc_sad.asm +133 −0
  3. libavcodec/x86/vvc/vvcdsp_init.c +6 −0
libavcodec/x86/vvc/Makefile+1−0
@@ -5,4 +5,5 @@ OBJS-$(CONFIG_VVC_DECODER) += x86/vvc/vvcdsp_init.o \ · 4 unmodified lines
5 x86/h26x/h2656dsp.o5 x86/h26x/h2656dsp.o
6X86ASM-OBJS-$(CONFIG_VVC_DECODER) += x86/vvc/vvc_alf.o \6X86ASM-OBJS-$(CONFIG_VVC_DECODER) += x86/vvc/vvc_alf.o \
7 x86/vvc/vvc_mc.o \7 x86/vvc/vvc_mc.o \
8 x86/vvc/vvc_sad.o \
8 x86/h26x/h2656_inter.o9 x86/h26x/h2656_inter.o
libavcodec/x86/vvc/vvc_sad.asm+133−0
@@ -0,0 +1,133 @@
1; /*
2; * Provide SIMD DMVR SAD functions for VVC decoding
3; *
4; * Copyright (c) 2024 Stone Chen
5; *
6; * This file is part of FFmpeg.
7; *
8; * FFmpeg is free software; you can redistribute it and/or
9; * modify it under the terms of the GNU Lesser General Public
10; * License as published by the Free Software Foundation; either
11; * version 2.1 of the License, or (at your option) any later version.
12; *
13; * FFmpeg is distributed in the hope that it will be useful,
14; * but WITHOUT ANY WARRANTY; without even the implied warranty of
15; * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16; * Lesser General Public License for more details.
17; *
18; * You should have received a copy of the GNU Lesser General Public
19; * License along with FFmpeg; if not, write to the Free Software
20; * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21; */
22
23%include "libavutil/x86/x86util.asm"
24%define MAX_PB_SIZE 128
25%define ROWS 2
26
27SECTION_RODATA
28
29pw_1: times 2 dw 1
30
31; DMVR SAD is only calculated on even rows to reduce complexity
32SECTION .text
33
34%macro MIN_MAX_SAD 3
35 pminuw %3, %2, %1
36 pmaxuw %1, %2, %1
37 psubusw %1, %1, %3
38%endmacro
39
40%macro HORIZ_ADD 3 ; xm0, xm1, m1
41 vextracti128 %1, %3, q0001 ; 3 2 1 0
42 paddd %1, %2 ; xm0 (7 + 3) (6 + 2) (5 + 1) (4 + 0)
43 pshufd %2, %1, q0032 ; xm1 - - (7 + 3) (6 + 2)
44 paddd %1, %1, %2 ; xm0 _ _ (5 1 7 3) (4 0 6 2)
45 pshufd %2, %1, q0001 ; xm1 _ _ (5 1 7 3) (5 1 7 3)
46 paddd %1, %1, %2 ; (01234567)
47%endmacro
48
49%if ARCH_X86_64
50%if HAVE_AVX2_EXTERNAL
51
52INIT_YMM avx2
53
54cglobal vvc_sad, 6, 9, 5, src1, src2, dx, dy, block_w, block_h, off1, off2, row_idx
55 movsxdifnidn dxq, dxd
56 movsxdifnidn dyq, dyd
57
58 sub dxq, 2
59 sub dyq, 2
60
61 mov off1q, 2
62 mov off2q, 2
63
64 add off1q, dyq
65 sub off2q, dyq
66
67 shl off1q, 7
68 shl off2q, 7
69
70 add off1q, dxq
71 sub off2q, dxq
72
73 lea src1q, [src1q + off1q * 2 + 2 * 2]
74 lea src2q, [src2q + off2q * 2 + 2 * 2]
75
76 pxor m3, m3
77 vpbroadcastd m4, [pw_1]
78
79 cmp block_wd, 16
80 jge vvc_sad_16_128
81
82 vvc_sad_8:
83 .loop_height:
84 movu xm0, [src1q]
85 vinserti128 m0, [src1q + MAX_PB_SIZE * ROWS * 2], 1
86 movu xm1, [src2q]
87 vinserti128 m1, [src2q + MAX_PB_SIZE * ROWS * 2], 1
88
89 MIN_MAX_SAD m1, m0, m2
90 pmaddwd m1, m4
91 paddd m3, m1
92
93 add src1q, 2 * MAX_PB_SIZE * ROWS * 2
94 add src2q, 2 * MAX_PB_SIZE * ROWS * 2
95
96 sub block_hd, 4
97 jg .loop_height
98
99 HORIZ_ADD xm0, xm3, m3
100 movd eax, xm0
101 RET
102
103 vvc_sad_16_128:
104 sar block_wd, 4
105 .loop_height:
106 mov off1q, src1q
107 mov off2q, src2q
108 mov row_idxd, block_wd
109
110 .loop_width:
111 movu m0, [src1q]
112 movu m1, [src2q]
113 MIN_MAX_SAD m1, m0, m2
114 pmaddwd m1, m4
115 paddd m3, m1
116
117 add src1q, 32
118 add src2q, 32
119 dec row_idxd
120 jg .loop_width
121
122 lea src1q, [off1q + ROWS * MAX_PB_SIZE * 2]
123 lea src2q, [off2q + ROWS * MAX_PB_SIZE * 2]
124
125 sub block_hd, 2
126 jg .loop_height
127
128 HORIZ_ADD xm0, xm3, m3
129 movd eax, xm0
130 RET
131
132%endif
133%endif
libavcodec/x86/vvc/vvcdsp_init.c+6−0
@@ -311,6 +311,9 @@ ALF_FUNCS(16, 12, avx2) · 310 unmodified lines
311 c->alf.filter[CHROMA] = ff_vvc_alf_filter_chroma_##bd##_avx2; \311 c->alf.filter[CHROMA] = ff_vvc_alf_filter_chroma_##bd##_avx2; \
312 c->alf.classify = ff_vvc_alf_classify_##bd##_avx2; \312 c->alf.classify = ff_vvc_alf_classify_##bd##_avx2; \
313} while (0)313} while (0)
314
315int ff_vvc_sad_avx2(const int16_t *src0, const int16_t *src1, int dx, int dy, int block_w, int block_h);
316#define SAD_INIT() c->inter.sad = ff_vvc_sad_avx2
314#endif317#endif
315 318
316void ff_vvc_dsp_init_x86(VVCDSPContext *const c, const int bd)319void ff_vvc_dsp_init_x86(VVCDSPContext *const c, const int bd)
@@ -327,6 +330,7 @@ void ff_vvc_dsp_init_x86(VVCDSPContext *const c, const int bd) · 10 unmodified lines
327 ALF_INIT(8);330 ALF_INIT(8);
328 AVG_INIT(8, avx2);331 AVG_INIT(8, avx2);
329 MC_LINKS_AVX2(8);332 MC_LINKS_AVX2(8);
333 SAD_INIT();
330 }334 }
331 break;335 break;
332 case 10:336 case 10:
@@ -338,6 +342,7 @@ void ff_vvc_dsp_init_x86(VVCDSPContext *const c, const int bd) · 5 unmodified lines
338 AVG_INIT(10, avx2);342 AVG_INIT(10, avx2);
339 MC_LINKS_AVX2(10);343 MC_LINKS_AVX2(10);
340 MC_LINKS_16BPC_AVX2(10);344 MC_LINKS_16BPC_AVX2(10);
345 SAD_INIT();
341 }346 }
342 break;347 break;
343 case 12:348 case 12:
@@ -349,6 +354,7 @@ void ff_vvc_dsp_init_x86(VVCDSPContext *const c, const int bd) · 5 unmodified lines
349 AVG_INIT(12, avx2);354 AVG_INIT(12, avx2);
350 MC_LINKS_AVX2(12);355 MC_LINKS_AVX2(12);
351 MC_LINKS_16BPC_AVX2(12);356 MC_LINKS_16BPC_AVX2(12);
357 SAD_INIT();
352 }358 }
353 break;359 break;
354 default:360 default:

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t