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