]> git.sesse.net Git - ffmpeg/blob - libavcodec/x86/hevc_sao_10bit.asm
Merge commit '8bcadaacc2b8dc3c5d6569835a5ca20e62d3efca'
[ffmpeg] / libavcodec / x86 / hevc_sao_10bit.asm
1 ;******************************************************************************
2 ;* SIMD optimized SAO functions for HEVC 10/12bit decoding
3 ;*
4 ;* Copyright (c) 2013 Pierre-Edouard LEPERE
5 ;* Copyright (c) 2014 James Almer
6 ;*
7 ;* This file is part of FFmpeg.
8 ;*
9 ;* FFmpeg is free software; you can redistribute it and/or
10 ;* modify it under the terms of the GNU Lesser General Public
11 ;* License as published by the Free Software Foundation; either
12 ;* version 2.1 of the License, or (at your option) any later version.
13 ;*
14 ;* FFmpeg is distributed in the hope that it will be useful,
15 ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17 ;* Lesser General Public License for more details.
18 ;*
19 ;* You should have received a copy of the GNU Lesser General Public
20 ;* License along with FFmpeg; if not, write to the Free Software
21 ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 ;******************************************************************************
23
24 %include "libavutil/x86/x86util.asm"
25
26 SECTION_RODATA 32
27
28 pw_m2:     times 16 dw -2
29 pw_mask10: times 16 dw 0x03FF
30 pw_mask12: times 16 dw 0x0FFF
31 pb_eo:              db -1, 0, 1, 0, 0, -1, 0, 1, -1, -1, 1, 1, 1, -1, -1, 1
32 cextern pw_m1
33 cextern pw_1
34 cextern pw_2
35
36 SECTION .text
37
38 ;******************************************************************************
39 ;SAO Band Filter
40 ;******************************************************************************
41
42 %macro HEVC_SAO_BAND_FILTER_INIT 1
43     and            leftq, 31
44     movd             xm0, leftd
45     add            leftq, 1
46     and            leftq, 31
47     movd             xm1, leftd
48     add            leftq, 1
49     and            leftq, 31
50     movd             xm2, leftd
51     add            leftq, 1
52     and            leftq, 31
53     movd             xm3, leftd
54
55     SPLATW            m0, xm0
56     SPLATW            m1, xm1
57     SPLATW            m2, xm2
58     SPLATW            m3, xm3
59 %if mmsize > 16
60     SPLATW            m4, [offsetq + 2]
61     SPLATW            m5, [offsetq + 4]
62     SPLATW            m6, [offsetq + 6]
63     SPLATW            m7, [offsetq + 8]
64 %else
65     movq              m7, [offsetq + 2]
66     SPLATW            m4, m7, 0
67     SPLATW            m5, m7, 1
68     SPLATW            m6, m7, 2
69     SPLATW            m7, m7, 3
70 %endif
71
72 %if ARCH_X86_64
73     mova             m13, [pw_mask %+ %1]
74     pxor             m14, m14
75
76 %else ; ARCH_X86_32
77     mova  [rsp+mmsize*0], m0
78     mova  [rsp+mmsize*1], m1
79     mova  [rsp+mmsize*2], m2
80     mova  [rsp+mmsize*3], m3
81     mova  [rsp+mmsize*4], m4
82     mova  [rsp+mmsize*5], m5
83     mova  [rsp+mmsize*6], m6
84     mova              m1, [pw_mask %+ %1]
85     pxor              m0, m0
86     %assign MMSIZE mmsize
87     %define m14 m0
88     %define m13 m1
89     %define  m9 m2
90     %define  m8 m3
91 %endif ; ARCH
92 DEFINE_ARGS dst, src, dststride, srcstride, offset, height
93     mov          heightd, r7m
94 %endmacro
95
96 %macro HEVC_SAO_BAND_FILTER_COMPUTE 3
97     psraw             %2, %3, %1-5
98 %if ARCH_X86_64
99     pcmpeqw          m10, %2, m0
100     pcmpeqw          m11, %2, m1
101     pcmpeqw          m12, %2, m2
102     pcmpeqw           %2, m3
103     pand             m10, m4
104     pand             m11, m5
105     pand             m12, m6
106     pand              %2, m7
107     por              m10, m11
108     por              m12, %2
109     por              m10, m12
110     paddw             %3, m10
111 %else ; ARCH_X86_32
112     pcmpeqw           m4, %2, [rsp+MMSIZE*0]
113     pcmpeqw           m5, %2, [rsp+MMSIZE*1]
114     pcmpeqw           m6, %2, [rsp+MMSIZE*2]
115     pcmpeqw           %2, [rsp+MMSIZE*3]
116     pand              m4, [rsp+MMSIZE*4]
117     pand              m5, [rsp+MMSIZE*5]
118     pand              m6, [rsp+MMSIZE*6]
119     pand              %2, m7
120     por               m4, m5
121     por               m6, %2
122     por               m4, m6
123     paddw             %3, m4
124 %endif ; ARCH
125 %endmacro
126
127 ;void ff_hevc_sao_band_filter_<width>_<depth>_<opt>(uint8_t *_dst, uint8_t *_src, ptrdiff_t _stride_dst, ptrdiff_t _stride_src,
128 ;                                                   int16_t *sao_offset_val, int sao_left_class, int width, int height);
129 %macro HEVC_SAO_BAND_FILTER 3
130 cglobal hevc_sao_band_filter_%2_%1, 6, 6, 15, 7*mmsize*ARCH_X86_32, dst, src, dststride, srcstride, offset, left
131     HEVC_SAO_BAND_FILTER_INIT %1
132
133 align 16
134 .loop:
135 %if %2 == 8
136     movu              m8, [srcq]
137     HEVC_SAO_BAND_FILTER_COMPUTE %1, m9, m8
138     CLIPW             m8, m14, m13
139     movu          [dstq], m8
140 %endif
141
142 %assign i 0
143 %rep %3
144     mova              m8, [srcq + i]
145     HEVC_SAO_BAND_FILTER_COMPUTE %1, m9, m8
146     CLIPW             m8, m14, m13
147     mova      [dstq + i], m8
148
149     mova              m9, [srcq + i + mmsize]
150     HEVC_SAO_BAND_FILTER_COMPUTE %1, m8, m9
151     CLIPW             m9, m14, m13
152     mova      [dstq + i + mmsize], m9
153 %assign i i+mmsize*2
154 %endrep
155
156 %if %2 == 48
157 INIT_XMM cpuname
158     mova              m8, [srcq + i]
159     HEVC_SAO_BAND_FILTER_COMPUTE %1, m9, m8
160     CLIPW             m8, m14, m13
161     mova      [dstq + i], m8
162
163     mova              m9, [srcq + i + mmsize]
164     HEVC_SAO_BAND_FILTER_COMPUTE %1, m8, m9
165     CLIPW             m9, m14, m13
166     mova      [dstq + i + mmsize], m9
167 %if cpuflag(avx2)
168 INIT_YMM cpuname
169 %endif
170 %endif ; %1 == 48
171
172     add             dstq, dststrideq
173     add             srcq, srcstrideq
174     dec          heightd
175     jg .loop
176     REP_RET
177 %endmacro
178
179 %macro HEVC_SAO_BAND_FILTER_FUNCS 0
180 HEVC_SAO_BAND_FILTER 10,  8, 0
181 HEVC_SAO_BAND_FILTER 10, 16, 1
182 HEVC_SAO_BAND_FILTER 10, 32, 2
183 HEVC_SAO_BAND_FILTER 10, 48, 2
184 HEVC_SAO_BAND_FILTER 10, 64, 4
185
186 HEVC_SAO_BAND_FILTER 12,  8, 0
187 HEVC_SAO_BAND_FILTER 12, 16, 1
188 HEVC_SAO_BAND_FILTER 12, 32, 2
189 HEVC_SAO_BAND_FILTER 12, 48, 2
190 HEVC_SAO_BAND_FILTER 12, 64, 4
191 %endmacro
192
193 INIT_XMM sse2
194 HEVC_SAO_BAND_FILTER_FUNCS
195 INIT_XMM avx
196 HEVC_SAO_BAND_FILTER_FUNCS
197
198 %if HAVE_AVX2_EXTERNAL
199 INIT_XMM avx2
200 HEVC_SAO_BAND_FILTER 10,  8, 0
201 HEVC_SAO_BAND_FILTER 10, 16, 1
202 INIT_YMM avx2
203 HEVC_SAO_BAND_FILTER 10, 32, 1
204 HEVC_SAO_BAND_FILTER 10, 48, 1
205 HEVC_SAO_BAND_FILTER 10, 64, 2
206
207 INIT_XMM avx2
208 HEVC_SAO_BAND_FILTER 12,  8, 0
209 HEVC_SAO_BAND_FILTER 12, 16, 1
210 INIT_YMM avx2
211 HEVC_SAO_BAND_FILTER 12, 32, 1
212 HEVC_SAO_BAND_FILTER 12, 48, 1
213 HEVC_SAO_BAND_FILTER 12, 64, 2
214 %endif
215
216 ;******************************************************************************
217 ;SAO Edge Filter
218 ;******************************************************************************
219
220 %define MAX_PB_SIZE  64
221 %define PADDING_SIZE 32 ; AV_INPUT_BUFFER_PADDING_SIZE
222 %define EDGE_SRCSTRIDE 2 * MAX_PB_SIZE + PADDING_SIZE
223
224 %macro PMINUW 4
225 %if cpuflag(sse4)
226     pminuw            %1, %2, %3
227 %else
228     psubusw           %4, %2, %3
229     psubw             %1, %2, %4
230 %endif
231 %endmacro
232
233 %macro HEVC_SAO_EDGE_FILTER_INIT 0
234 %if WIN64
235     movsxd           eoq, dword eom
236 %elif ARCH_X86_64
237     movsxd           eoq, eod
238 %else
239     mov              eoq, r4m
240 %endif
241     lea            tmp2q, [pb_eo]
242     movsx      a_strideq, byte [tmp2q+eoq*4+1]
243     movsx      b_strideq, byte [tmp2q+eoq*4+3]
244     imul       a_strideq, EDGE_SRCSTRIDE >> 1
245     imul       b_strideq, EDGE_SRCSTRIDE >> 1
246     movsx           tmpq, byte [tmp2q+eoq*4]
247     add        a_strideq, tmpq
248     movsx           tmpq, byte [tmp2q+eoq*4+2]
249     add        b_strideq, tmpq
250 %endmacro
251
252 %macro HEVC_SAO_EDGE_FILTER_COMPUTE 0
253     PMINUW            m4, m1, m2, m6
254     PMINUW            m5, m1, m3, m7
255     pcmpeqw           m2, m4
256     pcmpeqw           m3, m5
257     pcmpeqw           m4, m1
258     pcmpeqw           m5, m1
259     psubw             m4, m2
260     psubw             m5, m3
261
262     paddw             m4, m5
263     pcmpeqw           m2, m4, [pw_m2]
264 %if ARCH_X86_64
265     pcmpeqw           m3, m4, m13
266     pcmpeqw           m5, m4, m0
267     pcmpeqw           m6, m4, m14
268     pcmpeqw           m7, m4, m15
269     pand              m2, m8
270     pand              m3, m9
271     pand              m5, m10
272     pand              m6, m11
273     pand              m7, m12
274 %else
275     pcmpeqw           m3, m4, [pw_m1]
276     pcmpeqw           m5, m4, m0
277     pcmpeqw           m6, m4, [pw_1]
278     pcmpeqw           m7, m4, [pw_2]
279     pand              m2, [rsp+MMSIZE*0]
280     pand              m3, [rsp+MMSIZE*1]
281     pand              m5, [rsp+MMSIZE*2]
282     pand              m6, [rsp+MMSIZE*3]
283     pand              m7, [rsp+MMSIZE*4]
284 %endif
285     paddw             m2, m3
286     paddw             m5, m6
287     paddw             m2, m7
288     paddw             m2, m1
289     paddw             m2, m5
290 %endmacro
291
292 ;void ff_hevc_sao_edge_filter_<width>_<depth>_<opt>(uint8_t *_dst, uint8_t *_src, ptrdiff_t stride_dst, int16_t *sao_offset_val,
293 ;                                                   int eo, int width, int height);
294 %macro HEVC_SAO_EDGE_FILTER 3
295 %if ARCH_X86_64
296 cglobal hevc_sao_edge_filter_%2_%1, 4, 9, 16, dst, src, dststride, offset, eo, a_stride, b_stride, height, tmp
297 %define tmp2q heightq
298     HEVC_SAO_EDGE_FILTER_INIT
299     mov          heightd, r6m
300     add        a_strideq, a_strideq
301     add        b_strideq, b_strideq
302
303 %else ; ARCH_X86_32
304 cglobal hevc_sao_edge_filter_%2_%1, 1, 6, 8, 5*mmsize, dst, src, dststride, a_stride, b_stride, height
305 %assign MMSIZE mmsize
306 %define eoq   srcq
307 %define tmpq  heightq
308 %define tmp2q dststrideq
309 %define offsetq heightq
310 %define m8 m1
311 %define m9 m2
312 %define m10 m3
313 %define m11 m4
314 %define m12 m5
315     HEVC_SAO_EDGE_FILTER_INIT
316     mov             srcq, srcm
317     mov          offsetq, r3m
318     mov       dststrideq, dststridem
319     add        a_strideq, a_strideq
320     add        b_strideq, b_strideq
321
322 %endif ; ARCH
323
324 %if cpuflag(avx2)
325     SPLATW            m8, [offsetq+2]
326     SPLATW            m9, [offsetq+4]
327     SPLATW           m10, [offsetq+0]
328     SPLATW           m11, [offsetq+6]
329     SPLATW           m12, [offsetq+8]
330 %else
331     movq             m10, [offsetq+0]
332     movd             m12, [offsetq+6]
333     SPLATW            m8, xm10, 1
334     SPLATW            m9, xm10, 2
335     SPLATW           m10, xm10, 0
336     SPLATW           m11, xm12, 0
337     SPLATW           m12, xm12, 1
338 %endif
339     pxor              m0, m0
340 %if ARCH_X86_64
341     mova             m13, [pw_m1]
342     mova             m14, [pw_1]
343     mova             m15, [pw_2]
344 %else
345     mov          heightd, r6m
346     mova  [rsp+mmsize*0], m8
347     mova  [rsp+mmsize*1], m9
348     mova  [rsp+mmsize*2], m10
349     mova  [rsp+mmsize*3], m11
350     mova  [rsp+mmsize*4], m12
351 %endif
352
353 align 16
354 .loop:
355
356 %if %2 == 8
357     mova              m1, [srcq]
358     movu              m2, [srcq+a_strideq]
359     movu              m3, [srcq+b_strideq]
360
361     HEVC_SAO_EDGE_FILTER_COMPUTE
362     CLIPW             m2, m0, [pw_mask %+ %1]
363     movu          [dstq], m2
364 %endif
365
366 %assign i 0
367 %rep %3
368     mova              m1, [srcq + i]
369     movu              m2, [srcq+a_strideq + i]
370     movu              m3, [srcq+b_strideq + i]
371     HEVC_SAO_EDGE_FILTER_COMPUTE
372     CLIPW             m2, m0, [pw_mask %+ %1]
373     mova      [dstq + i], m2
374
375     mova              m1, [srcq + i + mmsize]
376     movu              m2, [srcq+a_strideq + i + mmsize]
377     movu              m3, [srcq+b_strideq + i + mmsize]
378     HEVC_SAO_EDGE_FILTER_COMPUTE
379     CLIPW             m2, m0, [pw_mask %+ %1]
380     mova [dstq + i + mmsize], m2
381 %assign i i+mmsize*2
382 %endrep
383
384 %if %2 == 48
385 INIT_XMM cpuname
386     mova              m1, [srcq + i]
387     movu              m2, [srcq+a_strideq + i]
388     movu              m3, [srcq+b_strideq + i]
389     HEVC_SAO_EDGE_FILTER_COMPUTE
390     CLIPW             m2, m0, [pw_mask %+ %1]
391     mova              [dstq + i], m2
392
393     mova              m1, [srcq + i + mmsize]
394     movu              m2, [srcq+a_strideq + i + mmsize]
395     movu              m3, [srcq+b_strideq + i + mmsize]
396     HEVC_SAO_EDGE_FILTER_COMPUTE
397     CLIPW             m2, m0, [pw_mask %+ %1]
398     mova [dstq + i + mmsize], m2
399 %if cpuflag(avx2)
400 INIT_YMM cpuname
401 %endif
402 %endif
403
404     add             dstq, dststrideq
405     add             srcq, EDGE_SRCSTRIDE
406     dec          heightd
407     jg .loop
408     RET
409 %endmacro
410
411 INIT_XMM sse2
412 HEVC_SAO_EDGE_FILTER 10,  8, 0
413 HEVC_SAO_EDGE_FILTER 10, 16, 1
414 HEVC_SAO_EDGE_FILTER 10, 32, 2
415 HEVC_SAO_EDGE_FILTER 10, 48, 2
416 HEVC_SAO_EDGE_FILTER 10, 64, 4
417
418 HEVC_SAO_EDGE_FILTER 12,  8, 0
419 HEVC_SAO_EDGE_FILTER 12, 16, 1
420 HEVC_SAO_EDGE_FILTER 12, 32, 2
421 HEVC_SAO_EDGE_FILTER 12, 48, 2
422 HEVC_SAO_EDGE_FILTER 12, 64, 4
423
424 %if HAVE_AVX2_EXTERNAL
425 INIT_YMM avx2
426 HEVC_SAO_EDGE_FILTER 10, 32, 1
427 HEVC_SAO_EDGE_FILTER 10, 48, 1
428 HEVC_SAO_EDGE_FILTER 10, 64, 2
429
430 HEVC_SAO_EDGE_FILTER 12, 32, 1
431 HEVC_SAO_EDGE_FILTER 12, 48, 1
432 HEVC_SAO_EDGE_FILTER 12, 64, 2
433 %endif