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