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