]> git.sesse.net Git - ffmpeg/blob - libavcodec/x86/hevc_deblock.asm
Merge commit 'ed9b2a5178d7a7c5a95694da3a808af327f36aff'
[ffmpeg] / libavcodec / x86 / hevc_deblock.asm
1 ;*****************************************************************************
2 ;* SSE2-optimized HEVC deblocking code
3 ;*****************************************************************************
4 ;* Copyright (C) 2013 VTT
5 ;*
6 ;* Authors: Seppo Tomperi <seppo.tomperi@vtt.fi>
7 ;*
8 ;* This file is part of FFmpeg.
9 ;*
10 ;* FFmpeg is free software; you can redistribute it and/or
11 ;* modify it under the terms of the GNU Lesser General Public
12 ;* License as published by the Free Software Foundation; either
13 ;* version 2.1 of the License, or (at your option) any later version.
14 ;*
15 ;* FFmpeg is distributed in the hope that it will be useful,
16 ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18 ;* Lesser General Public License for more details.
19 ;*
20 ;* You should have received a copy of the GNU Lesser General Public
21 ;* License along with FFmpeg; if not, write to the Free Software
22 ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 ;******************************************************************************
24
25 %include "libavutil/x86/x86util.asm"
26
27 SECTION_RODATA
28
29 cextern pw_1023
30 %define pw_pixel_max_10 pw_1023
31 pw_pixel_max_12: times 8 dw ((1 << 12)-1)
32 pw_m2:           times 8 dw -2
33 pd_1 :           times 4 dd  1
34
35 cextern pw_4
36 cextern pw_8
37 cextern pw_m1
38
39 SECTION .text
40 INIT_XMM sse2
41
42 ; expands to [base],...,[base+7*stride]
43 %define PASS8ROWS(base, base3, stride, stride3) \
44     [base], [base+stride], [base+stride*2], [base3], \
45     [base3+stride], [base3+stride*2], [base3+stride3], [base3+stride*4]
46
47 ; in: 8 rows of 4 bytes in %4..%11
48 ; out: 4 rows of 8 words in m0..m3
49 %macro TRANSPOSE4x8B_LOAD 8
50     movd             m0, %1
51     movd             m2, %2
52     movd             m1, %3
53     movd             m3, %4
54
55     punpcklbw        m0, m2
56     punpcklbw        m1, m3
57     punpcklwd        m0, m1
58
59     movd             m4, %5
60     movd             m6, %6
61     movd             m5, %7
62     movd             m3, %8
63
64     punpcklbw        m4, m6
65     punpcklbw        m5, m3
66     punpcklwd        m4, m5
67
68     punpckhdq        m2, m0, m4
69     punpckldq        m0, m4
70
71     pxor             m5, m5
72     punpckhbw        m1, m0, m5
73     punpcklbw        m0, m5
74     punpckhbw        m3, m2, m5
75     punpcklbw        m2, m5
76 %endmacro
77
78 ; in: 4 rows of 8 words in m0..m3
79 ; out: 8 rows of 4 bytes in %1..%8
80 %macro TRANSPOSE8x4B_STORE 8
81     packuswb         m0, m2
82     packuswb         m1, m3
83     SBUTTERFLY bw, 0, 1, 2
84     SBUTTERFLY wd, 0, 1, 2
85
86     movd             %1, m0
87     pshufd           m0, m0, 0x39
88     movd             %2, m0
89     pshufd           m0, m0, 0x39
90     movd             %3, m0
91     pshufd           m0, m0, 0x39
92     movd             %4, m0
93
94     movd             %5, m1
95     pshufd           m1, m1, 0x39
96     movd             %6, m1
97     pshufd           m1, m1, 0x39
98     movd             %7, m1
99     pshufd           m1, m1, 0x39
100     movd             %8, m1
101 %endmacro
102
103 ; in: 8 rows of 4 words in %4..%11
104 ; out: 4 rows of 8 words in m0..m3
105 %macro TRANSPOSE4x8W_LOAD 8
106     movq             m0, %1
107     movq             m2, %2
108     movq             m1, %3
109     movq             m3, %4
110
111     punpcklwd        m0, m2
112     punpcklwd        m1, m3
113     punpckhdq        m2, m0, m1
114     punpckldq        m0, m1
115
116     movq             m4, %5
117     movq             m6, %6
118     movq             m5, %7
119     movq             m3, %8
120
121     punpcklwd        m4, m6
122     punpcklwd        m5, m3
123     punpckhdq        m6, m4, m5
124     punpckldq        m4, m5
125
126     punpckhqdq       m1, m0, m4
127     punpcklqdq       m0, m4
128     punpckhqdq       m3, m2, m6
129     punpcklqdq       m2, m6
130
131 %endmacro
132
133 ; in: 4 rows of 8 words in m0..m3
134 ; out: 8 rows of 4 words in %1..%8
135 %macro TRANSPOSE8x4W_STORE 9
136     TRANSPOSE4x4W     0, 1, 2, 3, 4
137
138     pxor             m5, m5; zeros reg
139     CLIPW            m0, m5, %9
140     CLIPW            m1, m5, %9
141     CLIPW            m2, m5, %9
142     CLIPW            m3, m5, %9
143
144     movq             %1, m0
145     movhps           %2, m0
146     movq             %3, m1
147     movhps           %4, m1
148     movq             %5, m2
149     movhps           %6, m2
150     movq             %7, m3
151     movhps           %8, m3
152 %endmacro
153
154 ; in: 8 rows of 8 bytes in %1..%8
155 ; out: 8 rows of 8 words in m0..m7
156 %macro TRANSPOSE8x8B_LOAD 8
157     movq             m7, %1
158     movq             m2, %2
159     movq             m1, %3
160     movq             m3, %4
161
162     punpcklbw        m7, m2
163     punpcklbw        m1, m3
164     punpcklwd        m3, m7, m1
165     punpckhwd        m7, m1
166
167     movq             m4, %5
168     movq             m6, %6
169     movq             m5, %7
170     movq            m15, %8
171
172     punpcklbw        m4, m6
173     punpcklbw        m5, m15
174     punpcklwd        m9, m4, m5
175     punpckhwd        m4, m5
176
177     punpckldq        m1, m3, m9;  0, 1
178     punpckhdq        m3, m9;  2, 3
179
180     punpckldq        m5, m7, m4;  4, 5
181     punpckhdq        m7, m4;  6, 7
182
183     pxor            m13, m13
184
185     punpcklbw        m0, m1, m13; 0 in 16 bit
186     punpckhbw        m1, m13; 1 in 16 bit
187
188     punpcklbw        m2, m3, m13; 2
189     punpckhbw        m3, m13; 3
190
191     punpcklbw        m4, m5, m13; 4
192     punpckhbw        m5, m13; 5
193
194     punpcklbw        m6, m7, m13; 6
195     punpckhbw        m7, m13; 7
196 %endmacro
197
198
199 ; in: 8 rows of 8 words in m0..m8
200 ; out: 8 rows of 8 bytes in %1..%8
201 %macro TRANSPOSE8x8B_STORE 8
202     packuswb         m0, m4
203     packuswb         m1, m5
204     packuswb         m2, m6
205     packuswb         m3, m7
206     TRANSPOSE2x4x4B   0, 1, 2, 3, 4
207
208     movq             %1, m0
209     movhps           %2, m0
210     movq             %3, m1
211     movhps           %4, m1
212     movq             %5, m2
213     movhps           %6, m2
214     movq             %7, m3
215     movhps           %8, m3
216 %endmacro
217
218 ; in: 8 rows of 8 words in %1..%8
219 ; out: 8 rows of 8 words in m0..m7
220 %macro TRANSPOSE8x8W_LOAD 8
221     movdqu           m0, %1
222     movdqu           m1, %2
223     movdqu           m2, %3
224     movdqu           m3, %4
225     movdqu           m4, %5
226     movdqu           m5, %6
227     movdqu           m6, %7
228     movdqu           m7, %8
229     TRANSPOSE8x8W     0, 1, 2, 3, 4, 5, 6, 7, 8
230 %endmacro
231
232 ; in: 8 rows of 8 words in m0..m8
233 ; out: 8 rows of 8 words in %1..%8
234 %macro TRANSPOSE8x8W_STORE 9
235     TRANSPOSE8x8W     0, 1, 2, 3, 4, 5, 6, 7, 8
236
237     pxor             m8, m8
238     CLIPW            m0, m8, %9
239     CLIPW            m1, m8, %9
240     CLIPW            m2, m8, %9
241     CLIPW            m3, m8, %9
242     CLIPW            m4, m8, %9
243     CLIPW            m5, m8, %9
244     CLIPW            m6, m8, %9
245     CLIPW            m7, m8, %9
246
247     movdqu           %1, m0
248     movdqu           %2, m1
249     movdqu           %3, m2
250     movdqu           %4, m3
251     movdqu           %5, m4
252     movdqu           %6, m5
253     movdqu           %7, m6
254     movdqu           %8, m7
255 %endmacro
256
257
258 ; in: %2 clobbered
259 ; out: %1
260 ; mask in m11
261 ; clobbers m10
262 %macro MASKED_COPY 2
263     pand             %2, m11 ; and mask
264     pandn           m10, m11, %1; and -mask
265     por              %2, m10
266     mova             %1, %2
267 %endmacro
268
269 ; in: %2 clobbered
270 ; out: %1
271 ; mask in %3, will be clobbered
272 %macro MASKED_COPY2 3
273     pand             %2, %3 ; and mask
274     pandn            %3, %1; and -mask
275     por              %2, %3
276     mova             %1, %2
277 %endmacro
278
279 ALIGN 16
280 ; input in m0 ... m3 and tcs in r2. Output in m1 and m2
281 %macro CHROMA_DEBLOCK_BODY 1
282     psubw            m4, m2, m1; q0 - p0
283     psubw            m5, m0, m3; p1 - q1
284     psllw            m4, 2; << 2
285     paddw            m5, m4;
286
287     ;tc calculations
288     movq             m6, [tcq]; tc0
289     punpcklwd        m6, m6
290     pshufd           m6, m6, 0xA0; tc0, tc1
291 %if cpuflag(ssse3)
292     psignw           m4, m6, [pw_m1]; -tc0, -tc1
293 %else
294     pmullw           m4, m6, [pw_m1]; -tc0, -tc1
295 %endif
296     ;end tc calculations
297
298     paddw            m5, [pw_4]; +4
299     psraw            m5, 3; >> 3
300
301 %if %1 > 8
302     psllw            m4, %1-8; << (BIT_DEPTH - 8)
303     psllw            m6, %1-8; << (BIT_DEPTH - 8)
304 %endif
305     pmaxsw           m5, m4
306     pminsw           m5, m6
307     paddw            m1, m5; p0 + delta0
308     psubw            m2, m5; q0 - delta0
309 %endmacro
310
311 ; input in m0 ... m7, beta in r2 tcs in r3. Output in m1...m6
312 %macro LUMA_DEBLOCK_BODY 2
313     psllw            m9, m2, 1; *2
314     psubw           m10, m1, m9
315     paddw           m10, m3
316     ABS1            m10, m11 ; 0dp0, 0dp3 , 1dp0, 1dp3
317
318     psllw            m9, m5, 1; *2
319     psubw           m11, m6, m9
320     paddw           m11, m4
321     ABS1            m11, m13 ; 0dq0, 0dq3 , 1dq0, 1dq3
322
323     ;beta calculations
324 %if %1 > 8
325     shl             betaq, %1 - 8
326 %endif
327     movd            m13, betad
328     SPLATW          m13, m13, 0
329     ;end beta calculations
330
331     paddw            m9, m10, m11;   0d0, 0d3  ,  1d0, 1d3
332
333     pshufhw         m14, m9, 0x0f ;0b00001111;  0d3 0d3 0d0 0d0 in high
334     pshuflw         m14, m14, 0x0f ;0b00001111;  1d3 1d3 1d0 1d0 in low
335
336     pshufhw          m9, m9, 0xf0 ;0b11110000; 0d0 0d0 0d3 0d3
337     pshuflw          m9, m9, 0xf0 ;0b11110000; 1d0 1d0 1d3 1d3
338
339     paddw           m14, m9; 0d0+0d3, 1d0+1d3
340
341     ;compare
342     pcmpgtw         m15, m13, m14
343     movmskps        r13, m15 ;filtering mask 0d0 + 0d3 < beta0 (bit 2 or 3) , 1d0 + 1d3 < beta1 (bit 0 or 1)
344     test            r13, r13
345     je              .bypassluma
346
347     ;weak / strong decision compare to beta_2
348     psraw           m15, m13, 2;   beta >> 2
349     psllw            m8, m9, 1;
350     pcmpgtw         m15, m8; (d0 << 1) < beta_2, (d3 << 1) < beta_2
351     movmskps        r6, m15;
352     ;end weak / strong decision
353
354     ; weak filter nd_p/q calculation
355     pshufd           m8, m10, 0x31
356     psrld            m8, 16
357     paddw            m8, m10
358     movd            r7d, m8
359     pshufd           m8, m8, 0x4E
360     movd            r8d, m8
361
362     pshufd           m8, m11, 0x31
363     psrld            m8, 16
364     paddw            m8, m11
365     movd            r9d, m8
366     pshufd           m8, m8, 0x4E
367     movd           r10d, m8
368     ; end calc for weak filter
369
370     ; filtering mask
371     mov             r11, r13
372     shr             r11, 3
373     movd            m15, r11d
374     and             r13, 1
375     movd            m11, r13d
376     shufps          m11, m15, 0
377     shl             r11, 1
378     or              r13, r11
379
380     pcmpeqd         m11, [pd_1]; filtering mask
381
382     ;decide between strong and weak filtering
383     ;tc25 calculations
384     mov            r11d, [tcq];
385 %if %1 > 8
386     shl             r11, %1 - 8
387 %endif
388     movd             m8, r11d; tc0
389     mov             r3d, [tcq+4];
390 %if %1 > 8
391     shl              r3, %1 - 8
392 %endif
393     add            r11d, r3d; tc0 + tc1
394     jz             .bypassluma
395     movd             m9, r3d; tc1
396     punpcklwd        m8, m8
397     punpcklwd        m9, m9
398     shufps           m8, m9, 0; tc0, tc1
399     mova             m9, m8
400     psllw            m8, 2; tc << 2
401     pavgw            m8, m9; tc25 = ((tc * 5 + 1) >> 1)
402     ;end tc25 calculations
403
404     ;----beta_3 comparison-----
405     psubw           m12, m0, m3;      p3 - p0
406     ABS1            m12, m14; abs(p3 - p0)
407
408     psubw           m15, m7, m4;      q3 - q0
409     ABS1            m15, m14; abs(q3 - q0)
410
411     paddw           m12, m15; abs(p3 - p0) + abs(q3 - q0)
412
413     pshufhw         m12, m12, 0xf0 ;0b11110000;
414     pshuflw         m12, m12, 0xf0 ;0b11110000;
415
416     psraw           m13, 3; beta >> 3
417     pcmpgtw         m13, m12;
418     movmskps        r11, m13;
419     and             r6, r11; strong mask , beta_2 and beta_3 comparisons
420     ;----beta_3 comparison end-----
421     ;----tc25 comparison---
422     psubw           m12, m3, m4;      p0 - q0
423     ABS1            m12, m14; abs(p0 - q0)
424
425     pshufhw         m12, m12, 0xf0 ;0b11110000;
426     pshuflw         m12, m12, 0xf0 ;0b11110000;
427
428     pcmpgtw          m8, m12; tc25 comparisons
429     movmskps        r11, m8;
430     and             r6, r11; strong mask, beta_2, beta_3 and tc25 comparisons
431     ;----tc25 comparison end---
432     mov             r11, r6;
433     shr             r11, 1;
434     and             r6, r11; strong mask, bits 2 and 0
435
436     pmullw          m14, m9, [pw_m2]; -tc * 2
437     paddw            m9, m9
438
439     and             r6, 5; 0b101
440     mov             r11, r6; strong mask
441     shr             r6, 2;
442     movd            m12, r6d; store to xmm for mask generation
443     shl             r6, 1
444     and             r11, 1
445     movd            m10, r11d; store to xmm for mask generation
446     or              r6, r11; final strong mask, bits 1 and 0
447     jz      .weakfilter
448
449     shufps          m10, m12, 0
450     pcmpeqd         m10, [pd_1]; strong mask
451
452     mova            m13, [pw_4]; 4 in every cell
453     pand            m11, m10; combine filtering mask and strong mask
454     paddw           m12, m2, m3;          p1 +   p0
455     paddw           m12, m4;          p1 +   p0 +   q0
456     mova            m10, m12; copy
457     paddw           m12, m12;       2*p1 + 2*p0 + 2*q0
458     paddw           m12, m1;   p2 + 2*p1 + 2*p0 + 2*q0
459     paddw           m12, m5;   p2 + 2*p1 + 2*p0 + 2*q0 + q1
460     paddw           m12, m13;  p2 + 2*p1 + 2*p0 + 2*q0 + q1 + 4
461     psraw           m12, 3;  ((p2 + 2*p1 + 2*p0 + 2*q0 + q1 + 4) >> 3)
462     psubw           m12, m3; ((p2 + 2*p1 + 2*p0 + 2*q0 + q1 + 4) >> 3) - p0
463     pmaxsw          m12, m14
464     pminsw          m12, m9; av_clip( , -2 * tc, 2 * tc)
465     paddw           m12, m3; p0'
466
467     paddw           m15, m1, m10; p2 + p1 + p0 + q0
468     psrlw           m13, 1; 2 in every cell
469     paddw           m15, m13; p2 + p1 + p0 + q0 + 2
470     psraw           m15, 2;  (p2 + p1 + p0 + q0 + 2) >> 2
471     psubw           m15, m2;((p2 + p1 + p0 + q0 + 2) >> 2) - p1
472     pmaxsw          m15, m14
473     pminsw          m15, m9; av_clip( , -2 * tc, 2 * tc)
474     paddw           m15, m2; p1'
475
476     paddw            m8, m1, m0;     p3 +   p2
477     paddw            m8, m8;   2*p3 + 2*p2
478     paddw            m8, m1;   2*p3 + 3*p2
479     paddw            m8, m10;  2*p3 + 3*p2 + p1 + p0 + q0
480     paddw           m13, m13
481     paddw            m8, m13;  2*p3 + 3*p2 + p1 + p0 + q0 + 4
482     psraw            m8, 3;   (2*p3 + 3*p2 + p1 + p0 + q0 + 4) >> 3
483     psubw            m8, m1; ((2*p3 + 3*p2 + p1 + p0 + q0 + 4) >> 3) - p2
484     pmaxsw           m8, m14
485     pminsw           m8, m9; av_clip( , -2 * tc, 2 * tc)
486     paddw            m8, m1; p2'
487     MASKED_COPY      m1, m8
488
489     paddw            m8, m3, m4;         p0 +   q0
490     paddw            m8, m5;         p0 +   q0 +   q1
491     paddw            m8, m8;       2*p0 + 2*q0 + 2*q1
492     paddw            m8, m2;  p1 + 2*p0 + 2*q0 + 2*q1
493     paddw            m8, m6;  p1 + 2*p0 + 2*q0 + 2*q1 + q2
494     paddw            m8, m13; p1 + 2*p0 + 2*q0 + 2*q1 + q2 + 4
495     psraw            m8, 3;  (p1 + 2*p0 + 2*q0 + 2*q1 + q2 + 4) >>3
496     psubw            m8, m4;
497     pmaxsw           m8, m14
498     pminsw           m8, m9; av_clip( , -2 * tc, 2 * tc)
499     paddw            m8, m4; q0'
500     MASKED_COPY      m2, m15
501
502     paddw           m15, m3, m4;   p0 + q0
503     paddw           m15, m5;   p0 + q0 + q1
504     mova            m10, m15;
505     paddw           m15, m6;   p0 + q0 + q1 + q2
506     psrlw           m13, 1; 2 in every cell
507     paddw           m15, m13;  p0 + q0 + q1 + q2 + 2
508     psraw           m15, 2;   (p0 + q0 + q1 + q2 + 2) >> 2
509     psubw           m15, m5; ((p0 + q0 + q1 + q2 + 2) >> 2) - q1
510     pmaxsw          m15, m14
511     pminsw          m15, m9; av_clip( , -2 * tc, 2 * tc)
512     paddw           m15, m5; q1'
513
514     paddw           m13, m7;      q3 + 2
515     paddw           m13, m6;      q3 +  q2 + 2
516     paddw           m13, m13;   2*q3 + 2*q2 + 4
517     paddw           m13, m6;    2*q3 + 3*q2 + 4
518     paddw           m13, m10;   2*q3 + 3*q2 + q1 + q0 + p0 + 4
519     psraw           m13, 3;    (2*q3 + 3*q2 + q1 + q0 + p0 + 4) >> 3
520     psubw           m13, m6;  ((2*q3 + 3*q2 + q1 + q0 + p0 + 4) >> 3) - q2
521     pmaxsw          m13, m14
522     pminsw          m13, m9; av_clip( , -2 * tc, 2 * tc)
523     paddw           m13, m6; q2'
524
525     MASKED_COPY      m6, m13
526     MASKED_COPY      m5, m15
527     MASKED_COPY      m4, m8
528     MASKED_COPY      m3, m12
529
530 .weakfilter:
531     not             r6; strong mask -> weak mask
532     and             r6, r13; final weak filtering mask, bits 0 and 1
533     jz             .store
534
535     ; weak filtering mask
536     mov             r11, r6
537     shr             r11, 1
538     movd            m12, r11d
539     and             r6, 1
540     movd            m11, r6d
541     shufps          m11, m12, 0
542     pcmpeqd         m11, [pd_1]; filtering mask
543
544     mov             r13, betaq
545     shr             r13, 1;
546     add             betaq, r13
547     shr             betaq, 3; ((beta + (beta >> 1)) >> 3))
548
549     mova            m13, [pw_8]
550     psubw           m12, m4, m3 ; q0 - p0
551     psllw           m10, m12, 3; 8 * (q0 - p0)
552     paddw           m12, m10 ; 9 * (q0 - p0)
553
554     psubw           m10, m5, m2 ; q1 - p1
555     psllw            m8, m10, 1; 2 * ( q1 - p1 )
556     paddw           m10, m8; 3 * ( q1 - p1 )
557     psubw           m12, m10; 9 * (q0 - p0) - 3 * ( q1 - p1 )
558     paddw           m12, m13; + 8
559     psraw           m12, 4; >> 4 , delta0
560     PABSW           m13, m12; abs(delta0)
561
562
563     psllw           m10, m9, 2; 8 * tc
564     paddw           m10, m9; 10 * tc
565     pcmpgtw         m10, m13
566     pand            m11, m10
567
568     psraw            m9, 1;   tc * 2 -> tc
569     psraw           m14, 1; -tc * 2 -> -tc
570
571     pmaxsw          m12, m14
572     pminsw          m12, m9;  av_clip(delta0, -tc, tc)
573
574     psraw            m9, 1;   tc -> tc / 2
575 %if cpuflag(ssse3)
576     psignw          m14, m9, [pw_m1]; -tc / 2
577 %else
578     pmullw          m14, m9, [pw_m1]; -tc / 2
579 %endif
580
581     pavgw           m15, m1, m3;   (p2 + p0 + 1) >> 1
582     psubw           m15, m2;  ((p2 + p0 + 1) >> 1) - p1
583     paddw           m15, m12; ((p2 + p0 + 1) >> 1) - p1 + delta0
584     psraw           m15, 1;   (((p2 + p0 + 1) >> 1) - p1 + delta0) >> 1
585     pmaxsw          m15, m14
586     pminsw          m15, m9; av_clip(deltap1, -tc/2, tc/2)
587     paddw           m15, m2; p1'
588
589     ;beta calculations
590     movd            m10, betad
591     SPLATW          m10, m10, 0
592
593     movd            m13, r7d; 1dp0 + 1dp3
594     movd             m8, r8d; 0dp0 + 0dp3
595     punpcklwd        m8, m8
596     punpcklwd       m13, m13
597     shufps          m13, m8, 0;
598     pcmpgtw          m8, m10, m13
599     pand             m8, m11
600     ;end beta calculations
601     MASKED_COPY2     m2, m15, m8; write p1'
602
603     pavgw            m8, m6, m4;   (q2 + q0 + 1) >> 1
604     psubw            m8, m5;  ((q2 + q0 + 1) >> 1) - q1
605     psubw            m8, m12; ((q2 + q0 + 1) >> 1) - q1 - delta0)
606     psraw            m8, 1;   ((q2 + q0 + 1) >> 1) - q1 - delta0) >> 1
607     pmaxsw           m8, m14
608     pminsw           m8, m9; av_clip(deltaq1, -tc/2, tc/2)
609     paddw            m8, m5; q1'
610
611     movd            m13, r9d;
612     movd            m15, r10d;
613     punpcklwd       m15, m15
614     punpcklwd       m13, m13
615     shufps          m13, m15, 0; dq0 + dq3
616
617     pcmpgtw         m10, m13; compare to ((beta+(beta>>1))>>3)
618     pand            m10, m11
619     MASKED_COPY2     m5, m8, m10; write q1'
620
621     paddw           m15, m3, m12 ; p0 + delta0
622     MASKED_COPY      m3, m15
623
624     psubw            m8, m4, m12 ; q0 - delta0
625     MASKED_COPY      m4, m8
626 %endmacro
627
628 ;-----------------------------------------------------------------------------
629 ; void ff_hevc_v_loop_filter_chroma(uint8_t *_pix, ptrdiff_t _stride, int32_t *tc,
630 ;                                   uint8_t *_no_p, uint8_t *_no_q);
631 ;-----------------------------------------------------------------------------
632 %macro LOOP_FILTER_CHROMA 0
633 cglobal hevc_v_loop_filter_chroma_8, 3, 5, 7, pix, stride, tc, pix0, r3stride
634     sub            pixq, 2
635     lea       r3strideq, [3*strideq]
636     mov           pix0q, pixq
637     add            pixq, r3strideq
638     TRANSPOSE4x8B_LOAD  PASS8ROWS(pix0q, pixq, strideq, r3strideq)
639     CHROMA_DEBLOCK_BODY 8
640     TRANSPOSE8x4B_STORE PASS8ROWS(pix0q, pixq, strideq, r3strideq)
641     RET
642
643 cglobal hevc_v_loop_filter_chroma_10, 3, 5, 7, pix, stride, tc, pix0, r3stride
644     sub            pixq, 4
645     lea       r3strideq, [3*strideq]
646     mov           pix0q, pixq
647     add            pixq, r3strideq
648     TRANSPOSE4x8W_LOAD  PASS8ROWS(pix0q, pixq, strideq, r3strideq)
649     CHROMA_DEBLOCK_BODY 10
650     TRANSPOSE8x4W_STORE PASS8ROWS(pix0q, pixq, strideq, r3strideq), [pw_pixel_max_10]
651     RET
652
653 cglobal hevc_v_loop_filter_chroma_12, 3, 5, 7, pix, stride, tc, pix0, r3stride
654     sub            pixq, 4
655     lea       r3strideq, [3*strideq]
656     mov           pix0q, pixq
657     add            pixq, r3strideq
658     TRANSPOSE4x8W_LOAD  PASS8ROWS(pix0q, pixq, strideq, r3strideq)
659     CHROMA_DEBLOCK_BODY 12
660     TRANSPOSE8x4W_STORE PASS8ROWS(pix0q, pixq, strideq, r3strideq), [pw_pixel_max_12]
661     RET
662
663 ;-----------------------------------------------------------------------------
664 ; void ff_hevc_h_loop_filter_chroma(uint8_t *_pix, ptrdiff_t _stride, int32_t *tc,
665 ;                                   uint8_t *_no_p, uint8_t *_no_q);
666 ;-----------------------------------------------------------------------------
667 cglobal hevc_h_loop_filter_chroma_8, 3, 4, 7, pix, stride, tc, pix0
668     mov           pix0q, pixq
669     sub           pix0q, strideq
670     sub           pix0q, strideq
671     movq             m0, [pix0q];    p1
672     movq             m1, [pix0q+strideq]; p0
673     movq             m2, [pixq];    q0
674     movq             m3, [pixq+strideq]; q1
675     pxor             m5, m5; zeros reg
676     punpcklbw        m0, m5
677     punpcklbw        m1, m5
678     punpcklbw        m2, m5
679     punpcklbw        m3, m5
680     CHROMA_DEBLOCK_BODY  8
681     packuswb         m1, m2
682     movh[pix0q+strideq], m1
683     movhps       [pixq], m1
684     RET
685
686 cglobal hevc_h_loop_filter_chroma_10, 3, 4, 7, pix, stride, tc, pix0
687     mov          pix0q, pixq
688     sub          pix0q, strideq
689     sub          pix0q, strideq
690     movu            m0, [pix0q];    p1
691     movu            m1, [pix0q+strideq]; p0
692     movu            m2, [pixq];    q0
693     movu            m3, [pixq+strideq]; q1
694     CHROMA_DEBLOCK_BODY 10
695     pxor            m5, m5; zeros reg
696     CLIPW           m1, m5, [pw_pixel_max_10]
697     CLIPW           m2, m5, [pw_pixel_max_10]
698     movu [pix0q+strideq], m1
699     movu        [pixq], m2
700     RET
701
702 cglobal hevc_h_loop_filter_chroma_12, 3, 4, 7, pix, stride, tc, pix0
703     mov          pix0q, pixq
704     sub          pix0q, strideq
705     sub          pix0q, strideq
706     movu            m0, [pix0q];    p1
707     movu            m1, [pix0q+strideq]; p0
708     movu            m2, [pixq];    q0
709     movu            m3, [pixq+strideq]; q1
710     CHROMA_DEBLOCK_BODY 12
711     pxor            m5, m5; zeros reg
712     CLIPW           m1, m5, [pw_pixel_max_12]
713     CLIPW           m2, m5, [pw_pixel_max_12]
714     movu [pix0q+strideq], m1
715     movu        [pixq], m2
716     RET
717 %endmacro
718
719 INIT_XMM sse2
720 LOOP_FILTER_CHROMA
721 INIT_XMM avx
722 LOOP_FILTER_CHROMA
723
724 %if ARCH_X86_64
725 %macro LOOP_FILTER_LUMA 0
726 ;-----------------------------------------------------------------------------
727 ; void ff_hevc_v_loop_filter_luma(uint8_t *_pix, ptrdiff_t _stride, int beta,
728 ;                                 int32_t *tc, uint8_t *_no_p, uint8_t *_no_q);
729 ;-----------------------------------------------------------------------------
730 cglobal hevc_v_loop_filter_luma_8, 4, 14, 16, pix, stride, beta, tc, pix0, src3stride
731     sub            pixq, 4
732     lea           pix0q, [3 * r1]
733     mov     src3strideq, pixq
734     add            pixq, pix0q
735     TRANSPOSE8x8B_LOAD  PASS8ROWS(src3strideq, pixq, r1, pix0q)
736     LUMA_DEBLOCK_BODY 8, v
737 .store:
738     TRANSPOSE8x8B_STORE PASS8ROWS(src3strideq, pixq, r1, pix0q)
739 .bypassluma:
740     RET
741
742 cglobal hevc_v_loop_filter_luma_10, 4, 14, 16, pix, stride, beta, tc, pix0, src3stride
743     sub            pixq, 8
744     lea           pix0q, [3 * strideq]
745     mov     src3strideq, pixq
746     add            pixq, pix0q
747     TRANSPOSE8x8W_LOAD  PASS8ROWS(src3strideq, pixq, strideq, pix0q)
748     LUMA_DEBLOCK_BODY 10, v
749 .store:
750     TRANSPOSE8x8W_STORE PASS8ROWS(src3strideq, pixq, r1, pix0q), [pw_pixel_max_10]
751 .bypassluma:
752     RET
753
754 cglobal hevc_v_loop_filter_luma_12, 4, 14, 16, pix, stride, beta, tc, pix0, src3stride
755     sub            pixq, 8
756     lea           pix0q, [3 * strideq]
757     mov     src3strideq, pixq
758     add            pixq, pix0q
759     TRANSPOSE8x8W_LOAD  PASS8ROWS(src3strideq, pixq, strideq, pix0q)
760     LUMA_DEBLOCK_BODY 12, v
761 .store:
762     TRANSPOSE8x8W_STORE PASS8ROWS(src3strideq, pixq, r1, pix0q), [pw_pixel_max_12]
763 .bypassluma:
764     RET
765
766 ;-----------------------------------------------------------------------------
767 ; void ff_hevc_h_loop_filter_luma(uint8_t *_pix, ptrdiff_t _stride, int beta,
768 ;                                 int32_t *tc, uint8_t *_no_p, uint8_t *_no_q);
769 ;-----------------------------------------------------------------------------
770 cglobal hevc_h_loop_filter_luma_8, 4, 14, 16, pix, stride, beta, tc, pix0, src3stride
771     lea     src3strideq, [3 * strideq]
772     mov           pix0q, pixq
773     sub           pix0q, src3strideq
774     sub           pix0q, strideq
775     movq             m0, [pix0q];               p3
776     movq             m1, [pix0q +     strideq]; p2
777     movq             m2, [pix0q + 2 * strideq]; p1
778     movq             m3, [pix0q + src3strideq]; p0
779     movq             m4, [pixq];                q0
780     movq             m5, [pixq +     strideq];  q1
781     movq             m6, [pixq + 2 * strideq];  q2
782     movq             m7, [pixq + src3strideq];  q3
783     pxor             m8, m8
784     punpcklbw        m0, m8
785     punpcklbw        m1, m8
786     punpcklbw        m2, m8
787     punpcklbw        m3, m8
788     punpcklbw        m4, m8
789     punpcklbw        m5, m8
790     punpcklbw        m6, m8
791     punpcklbw        m7, m8
792     LUMA_DEBLOCK_BODY 8, h
793 .store:
794     packuswb          m1, m2
795     packuswb          m3, m4
796     packuswb          m5, m6
797     movh   [pix0q +     strideq], m1
798     movhps [pix0q + 2 * strideq], m1
799     movh   [pix0q + src3strideq], m3
800     movhps [pixq               ], m3
801     movh   [pixq  +     strideq], m5
802     movhps [pixq  + 2 * strideq], m5
803 .bypassluma:
804     RET
805
806 cglobal hevc_h_loop_filter_luma_10, 4, 14, 16, pix, stride, beta, tc, pix0, src3stride
807     lea                  src3strideq, [3 * strideq]
808     mov                        pix0q, pixq
809     sub                        pix0q, src3strideq
810     sub                        pix0q, strideq
811     movdqu                        m0, [pix0q];               p3
812     movdqu                        m1, [pix0q +     strideq]; p2
813     movdqu                        m2, [pix0q + 2 * strideq]; p1
814     movdqu                        m3, [pix0q + src3strideq]; p0
815     movdqu                        m4, [pixq];                q0
816     movdqu                        m5, [pixq  +     strideq]; q1
817     movdqu                        m6, [pixq  + 2 * strideq]; q2
818     movdqu                        m7, [pixq  + src3strideq]; q3
819     LUMA_DEBLOCK_BODY             10, h
820 .store:
821     pxor                          m8, m8; zeros reg
822     CLIPW                         m1, m8, [pw_pixel_max_10]
823     CLIPW                         m2, m8, [pw_pixel_max_10]
824     CLIPW                         m3, m8, [pw_pixel_max_10]
825     CLIPW                         m4, m8, [pw_pixel_max_10]
826     CLIPW                         m5, m8, [pw_pixel_max_10]
827     CLIPW                         m6, m8, [pw_pixel_max_10]
828     movdqu     [pix0q +     strideq], m1;  p2
829     movdqu     [pix0q + 2 * strideq], m2;  p1
830     movdqu     [pix0q + src3strideq], m3;  p0
831     movdqu     [pixq               ], m4;  q0
832     movdqu     [pixq  +     strideq], m5;  q1
833     movdqu     [pixq  + 2 * strideq], m6;  q2
834 .bypassluma:
835     RET
836
837 cglobal hevc_h_loop_filter_luma_12, 4, 14, 16, pix, stride, beta, tc, pix0, src3stride
838     lea                  src3strideq, [3 * strideq]
839     mov                        pix0q, pixq
840     sub                        pix0q, src3strideq
841     sub                        pix0q, strideq
842     movdqu                        m0, [pix0q];               p3
843     movdqu                        m1, [pix0q +     strideq]; p2
844     movdqu                        m2, [pix0q + 2 * strideq]; p1
845     movdqu                        m3, [pix0q + src3strideq]; p0
846     movdqu                        m4, [pixq];                q0
847     movdqu                        m5, [pixq  +     strideq]; q1
848     movdqu                        m6, [pixq  + 2 * strideq]; q2
849     movdqu                        m7, [pixq  + src3strideq]; q3
850     LUMA_DEBLOCK_BODY             12, h
851 .store:
852     pxor                          m8, m8; zeros reg
853     CLIPW                         m1, m8, [pw_pixel_max_12]
854     CLIPW                         m2, m8, [pw_pixel_max_12]
855     CLIPW                         m3, m8, [pw_pixel_max_12]
856     CLIPW                         m4, m8, [pw_pixel_max_12]
857     CLIPW                         m5, m8, [pw_pixel_max_12]
858     CLIPW                         m6, m8, [pw_pixel_max_12]
859     movdqu     [pix0q +     strideq], m1;  p2
860     movdqu     [pix0q + 2 * strideq], m2;  p1
861     movdqu     [pix0q + src3strideq], m3;  p0
862     movdqu     [pixq               ], m4;  q0
863     movdqu     [pixq  +     strideq], m5;  q1
864     movdqu     [pixq  + 2 * strideq], m6;  q2
865 .bypassluma:
866     RET
867
868 %endmacro
869
870 INIT_XMM sse2
871 LOOP_FILTER_LUMA
872 INIT_XMM ssse3
873 LOOP_FILTER_LUMA
874 INIT_XMM avx
875 LOOP_FILTER_LUMA
876 %endif