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