deblock-a.asm
上传用户:hjq518
上传日期:2021-12-09
资源大小:5084k
文件大小:13k
源码类别:

Audio

开发平台:

Visual C++

  1. ;*****************************************************************************
  2. ;* deblock-a.asm: h264 encoder library
  3. ;*****************************************************************************
  4. ;* Copyright (C) 2005 x264 project
  5. ;*
  6. ;* Authors: Loren Merritt <lorenm@u.washington.edu>
  7. ;*
  8. ;* This program is free software; you can redistribute it and/or modify
  9. ;* it under the terms of the GNU General Public License as published by
  10. ;* the Free Software Foundation; either version 2 of the License, or
  11. ;* (at your option) any later version.
  12. ;*
  13. ;* This program is distributed in the hope that it will be useful,
  14. ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16. ;* GNU General Public License for more details.
  17. ;*
  18. ;* You should have received a copy of the GNU General Public License
  19. ;* along with this program; if not, write to the Free Software
  20. ;* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
  21. ;*****************************************************************************
  22. BITS 64
  23. %include "amd64inc.asm"
  24. SECTION .rodata align=16
  25. pb_01: times 16 db 0x01
  26. pb_3f: times 16 db 0x3f
  27. pb_ff: times 16 db 0xff
  28. SECTION .text
  29. cglobal x264_deblock_v_luma_sse2
  30. cglobal x264_deblock_h_luma_sse2
  31. cglobal x264_deblock_v_chroma_mmxext
  32. cglobal x264_deblock_h_chroma_mmxext
  33. cglobal x264_deblock_v_chroma_intra_mmxext
  34. cglobal x264_deblock_h_chroma_intra_mmxext
  35. ; expands to [base],...,[base+7*stride]
  36. %define PASS8ROWS(base, base3, stride, stride3) 
  37.     [base], [base+stride], [base+stride*2], [base3], 
  38.     [base3+stride], [base3+stride*2], [base3+stride3], [base3+stride*4]
  39. ; in: 8 rows of 4 bytes in %1..%8
  40. ; out: 4 rows of 8 bytes in mm0..mm3
  41. %macro TRANSPOSE4x8_LOAD 8
  42.     movd       mm0, %1
  43.     movd       mm2, %2
  44.     movd       mm1, %3
  45.     movd       mm3, %4
  46.     punpcklbw  mm0, mm2
  47.     punpcklbw  mm1, mm3
  48.     movq       mm2, mm0
  49.     punpcklwd  mm0, mm1
  50.     punpckhwd  mm2, mm1
  51.     movd       mm4, %5
  52.     movd       mm6, %6
  53.     movd       mm5, %7
  54.     movd       mm7, %8
  55.     punpcklbw  mm4, mm6
  56.     punpcklbw  mm5, mm7
  57.     movq       mm6, mm4
  58.     punpcklwd  mm4, mm5
  59.     punpckhwd  mm6, mm5
  60.     movq       mm1, mm0
  61.     movq       mm3, mm2
  62.     punpckldq  mm0, mm4
  63.     punpckhdq  mm1, mm4
  64.     punpckldq  mm2, mm6
  65.     punpckhdq  mm3, mm6
  66. %endmacro
  67. ; in: 4 rows of 8 bytes in mm0..mm3
  68. ; out: 8 rows of 4 bytes in %1..%8
  69. %macro TRANSPOSE8x4_STORE 8
  70.     movq       mm4, mm0
  71.     movq       mm5, mm1
  72.     movq       mm6, mm2
  73.     punpckhdq  mm4, mm4
  74.     punpckhdq  mm5, mm5
  75.     punpckhdq  mm6, mm6
  76.     punpcklbw  mm0, mm1
  77.     punpcklbw  mm2, mm3
  78.     movq       mm1, mm0
  79.     punpcklwd  mm0, mm2
  80.     punpckhwd  mm1, mm2
  81.     movd       %1,  mm0
  82.     punpckhdq  mm0, mm0
  83.     movd       %2,  mm0
  84.     movd       %3,  mm1
  85.     punpckhdq  mm1, mm1
  86.     movd       %4,  mm1
  87.     punpckhdq  mm3, mm3
  88.     punpcklbw  mm4, mm5
  89.     punpcklbw  mm6, mm3
  90.     movq       mm5, mm4
  91.     punpcklwd  mm4, mm6
  92.     punpckhwd  mm5, mm6
  93.     movd       %5,  mm4
  94.     punpckhdq  mm4, mm4
  95.     movd       %6,  mm4
  96.     movd       %7,  mm5
  97.     punpckhdq  mm5, mm5
  98.     movd       %8,  mm5
  99. %endmacro
  100. %macro SBUTTERFLY 4
  101.     movq       %4, %2
  102.     punpckl%1  %2, %3
  103.     punpckh%1  %4, %3
  104. %endmacro
  105. ; in: 8 rows of 8 (only the middle 6 pels are used) in %1..%8
  106. ; out: 6 rows of 8 in [%9+0*16] .. [%9+5*16]
  107. %macro TRANSPOSE6x8_MEM 9
  108.     movq  mm0, %1
  109.     movq  mm1, %3
  110.     movq  mm2, %5
  111.     movq  mm3, %7
  112.     SBUTTERFLY bw, mm0, %2, mm4
  113.     SBUTTERFLY bw, mm1, %4, mm5
  114.     SBUTTERFLY bw, mm2, %6, mm6
  115.     movq  [%9+0x10], mm5
  116.     SBUTTERFLY bw, mm3, %8, mm7
  117.     SBUTTERFLY wd, mm0, mm1, mm5
  118.     SBUTTERFLY wd, mm2, mm3, mm1
  119.     punpckhdq mm0, mm2
  120.     movq  [%9+0x00], mm0
  121.     SBUTTERFLY wd, mm4, [%9+0x10], mm3
  122.     SBUTTERFLY wd, mm6, mm7, mm2
  123.     SBUTTERFLY dq, mm4, mm6, mm0
  124.     SBUTTERFLY dq, mm5, mm1, mm7
  125.     punpckldq mm3, mm2
  126.     movq  [%9+0x10], mm5
  127.     movq  [%9+0x20], mm7
  128.     movq  [%9+0x30], mm4
  129.     movq  [%9+0x40], mm0
  130.     movq  [%9+0x50], mm3
  131. %endmacro
  132. ; out: %4 = |%1-%2|>%3
  133. ; clobbers: %5
  134. %macro DIFF_GT 6
  135.     mov%1   %6, %3
  136.     mov%1   %5, %2
  137.     psubusb %6, %2
  138.     psubusb %5, %3
  139.     por     %5, %6
  140.     psubusb %5, %4
  141. %endmacro
  142. %macro DIFF_GT_MMX 5
  143.     DIFF_GT q, %1, %2, %3, %4, %5
  144. %endmacro
  145. %macro DIFF_GT_SSE2 5
  146.     DIFF_GT dqa, %1, %2, %3, %4, %5
  147. %endmacro
  148. ; in: mm0=p1 mm1=p0 mm2=q0 mm3=q1 %1=alpha-1 %2=beta-1
  149. ; out: mm5=beta-1, mm7=mask
  150. ; clobbers: mm4,mm6
  151. %macro LOAD_MASK_MMX 2
  152.     movd     mm4, %1
  153.     movd     mm5, %2
  154.     pshufw   mm4, mm4, 0
  155.     pshufw   mm5, mm5, 0
  156.     packuswb mm4, mm4  ; 8x alpha-1
  157.     packuswb mm5, mm5  ; 8x beta-1
  158.     DIFF_GT_MMX  mm1, mm2, mm4, mm7, mm6 ; |p0-q0| > alpha-1
  159.     DIFF_GT_MMX  mm0, mm1, mm5, mm4, mm6 ; |p1-p0| > beta-1
  160.     por      mm7, mm4
  161.     DIFF_GT_MMX  mm3, mm2, mm5, mm4, mm6 ; |q1-q0| > beta-1
  162.     por      mm7, mm4
  163.     pxor     mm6, mm6
  164.     pcmpeqb  mm7, mm6
  165. %endmacro
  166. %macro LOAD_MASK_SSE2 2
  167.     movd     xmm4, %1
  168.     movd     xmm5, %2
  169.     pshuflw  xmm4, xmm4, 0
  170.     pshuflw  xmm5, xmm5, 0
  171.     punpcklqdq xmm4, xmm4
  172.     punpcklqdq xmm5, xmm5
  173.     packuswb xmm4, xmm4  ; 16x alpha-1
  174.     packuswb xmm5, xmm5  ; 16x beta-1
  175.     DIFF_GT_SSE2  xmm1, xmm2, xmm4, xmm7, xmm6 ; |p0-q0| > alpha-1
  176.     DIFF_GT_SSE2  xmm0, xmm1, xmm5, xmm4, xmm6 ; |p1-p0| > beta-1
  177.     por      xmm7, xmm4
  178.     DIFF_GT_SSE2  xmm3, xmm2, xmm5, xmm4, xmm6 ; |q1-q0| > beta-1
  179.     por      xmm7, xmm4
  180.     pxor     xmm6, xmm6
  181.     pcmpeqb  xmm7, xmm6
  182. %endmacro
  183. ; in: mm0=p1 mm1=p0 mm2=q0 mm3=q1 mm7=(tc&mask)
  184. ; out: mm1=p0' mm2=q0'
  185. ; clobbers: mm0,3-6
  186. %macro DEBLOCK_P0_Q0 2
  187.     ; a = q0^p0^((p1-q1)>>2)
  188.     mov%1   %2m4, %2m0
  189.     psubb   %2m4, %2m3
  190.     psrlw   %2m4, 2
  191.     pxor    %2m4, %2m1
  192.     pxor    %2m4, %2m2
  193.     ; b = p0^(q1>>2)
  194.     psrlw   %2m3, 2
  195.     pand    %2m3, [pb_3f GLOBAL]
  196.     mov%1   %2m5, %2m1
  197.     pxor    %2m5, %2m3
  198.     ; c = q0^(p1>>2)
  199.     psrlw   %2m0, 2
  200.     pand    %2m0, [pb_3f GLOBAL]
  201.     mov%1   %2m6, %2m2
  202.     pxor    %2m6, %2m0
  203.     ; d = (c^b) & ~(b^a) & 1
  204.     pxor    %2m6, %2m5
  205.     pxor    %2m5, %2m4
  206.     pandn   %2m5, %2m6
  207.     pand    %2m5, [pb_01 GLOBAL]
  208.     ; delta = (((q0 - p0 ) << 2) + (p1 - q1) + 4) >> 3
  209.     ;       = (avg(q0, p1>>2) + (d&a))
  210.     ;       - (avg(p0, q1>>2) + (d^(d&a)))
  211.     pavgb   %2m0, %2m2
  212.     pand    %2m4, %2m5
  213.     paddusb %2m0, %2m4
  214.     pavgb   %2m3, %2m1
  215.     pxor    %2m4, %2m5
  216.     paddusb %2m3, %2m4
  217.     ; p0 += clip(delta, -tc0, tc0)
  218.     ; q0 -= clip(delta, -tc0, tc0)
  219.     mov%1   %2m4, %2m0
  220.     psubusb %2m0, %2m3
  221.     psubusb %2m3, %2m4
  222.     pminub  %2m0, %2m7
  223.     pminub  %2m3, %2m7
  224.     paddusb %2m1, %2m0
  225.     paddusb %2m2, %2m3
  226.     psubusb %2m1, %2m3
  227.     psubusb %2m2, %2m0
  228. %endmacro
  229. %macro DEBLOCK_P0_Q0_MMX 0
  230.     DEBLOCK_P0_Q0 q, m
  231. %endmacro
  232. %macro DEBLOCK_P0_Q0_SSE2 0
  233.     DEBLOCK_P0_Q0 dqa, xm
  234. %endmacro
  235. ; in: mm1=p0 mm2=q0
  236. ;     %1=p1 %2=q2 %3=[q2] %4=[q1] %5=tc0 %6=tmp
  237. ; out: [q1] = clip( (q2+((p0+q0+1)>>1))>>1, q1-tc0, q1+tc0 )
  238. ; clobbers: q2, tmp, tc0
  239. %macro LUMA_Q1_SSE2 6
  240.     movdqa  %6, xmm1
  241.     pavgb   %6, xmm2
  242.     pavgb   %2, %6             ; avg(p2,avg(p0,q0))
  243.     pxor    %6, %3
  244.     pand    %6, [pb_01 GLOBAL] ; (p2^avg(p0,q0))&1
  245.     psubusb %2, %6             ; (p2+((p0+q0+1)>>1))>>1
  246.     movdqa  %6, %1
  247.     psubusb %6, %5
  248.     paddusb %5, %1
  249.     pmaxub  %2, %6
  250.     pminub  %2, %5
  251.     movdqa  %4, %2
  252. %endmacro
  253. SECTION .text
  254. ALIGN 16
  255. ;-----------------------------------------------------------------------------
  256. ;   void x264_deblock_v_luma_sse2( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
  257. ;-----------------------------------------------------------------------------
  258. x264_deblock_v_luma_sse2:
  259.     ; rdi = pix
  260.     movsxd rsi, esi ; stride
  261.     dec    edx      ; alpha-1
  262.     dec    ecx      ; beta-1
  263.     movd   xmm8, [r8] ; tc0
  264.     mov    r8,  rdi
  265.     sub    r8,  rsi
  266.     sub    r8,  rsi
  267.     sub    r8,  rsi ; pix-3*stride
  268.     movdqa  xmm0, [r8+rsi]    ; p1
  269.     movdqa  xmm1, [r8+2*rsi]  ; p0
  270.     movdqa  xmm2, [rdi]       ; q0
  271.     movdqa  xmm3, [rdi+rsi]   ; q1
  272.     LOAD_MASK_SSE2  edx, ecx
  273.     punpcklbw xmm8, xmm8
  274.     punpcklbw xmm8, xmm8 ; xmm8 = 4x tc0[3], 4x tc0[2], 4x tc0[1], 4x tc0[0]
  275.     movdqa  xmm9, [pb_ff GLOBAL]
  276.     pcmpeqb xmm9, xmm8
  277.     pandn   xmm9, xmm7
  278.     pand    xmm8, xmm9
  279.     movdqa  xmm3, [r8] ; p2
  280.     DIFF_GT_SSE2  xmm1, xmm3, xmm5, xmm6, xmm7 ; |p2-p0| > beta-1
  281.     pandn   xmm6, xmm9
  282.     pcmpeqb xmm6, xmm9
  283.     pand    xmm6, xmm9
  284.     movdqa  xmm7, [pb_01 GLOBAL]
  285.     pand    xmm7, xmm6
  286.     pand    xmm6, xmm8
  287.     paddb   xmm7, xmm8
  288.     LUMA_Q1_SSE2  xmm0, xmm3, [r8], [r8+rsi], xmm6, xmm4
  289.     movdqa  xmm4, [rdi+2*rsi] ; q2
  290.     DIFF_GT_SSE2  xmm2, xmm4, xmm5, xmm6, xmm3 ; |q2-q0| > beta-1
  291.     pandn   xmm6, xmm9
  292.     pcmpeqb xmm6, xmm9
  293.     pand    xmm6, xmm9
  294.     pand    xmm8, xmm6
  295.     pand    xmm6, [pb_01 GLOBAL]
  296.     paddb   xmm7, xmm6
  297.     movdqa  xmm3, [rdi+rsi]
  298.     LUMA_Q1_SSE2  xmm3, xmm4, [rdi+2*rsi], [rdi+rsi], xmm8, xmm6
  299.     DEBLOCK_P0_Q0_SSE2
  300.     movdqa  [r8+2*rsi], xmm1
  301.     movdqa  [rdi], xmm2
  302.     ret
  303. ALIGN 16
  304. ;-----------------------------------------------------------------------------
  305. ;   void x264_deblock_h_luma_sse2( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
  306. ;-----------------------------------------------------------------------------
  307. x264_deblock_h_luma_sse2:
  308.     movsxd r10, esi
  309.     lea    r11, [r10+r10*2]
  310.     lea    rax, [rdi-4]
  311.     lea    r9,  [rdi-4+r11]
  312.     %define pix_tmp rsp-104 ; 16x6 for the buffer + 8 for x264_deblock_v_luma_sse2's return address
  313.     ; transpose 6x16 -> tmp space
  314.     TRANSPOSE6x8_MEM  PASS8ROWS(rax, r9, r10, r11), pix_tmp
  315.     lea    rax, [rax+r10*8]
  316.     lea    r9,  [r9 +r10*8]
  317.     TRANSPOSE6x8_MEM  PASS8ROWS(rax, r9, r10, r11), pix_tmp+8
  318.     ; vertical filter
  319.     ; alpha, beta, tc0 are still in edx, ecx, r8
  320.     ; don't backup rax, r9, r10, r11 because x264_deblock_v_luma_sse2 doesn't use them
  321.     lea    rdi, [pix_tmp+0x30]
  322.     mov    esi, 0x10
  323.     call   x264_deblock_v_luma_sse2
  324.     ; transpose 16x4 -> original space  (only the middle 4 rows were changed by the filter)
  325.     add    rax, 2
  326.     add    r9,  2
  327.     movq   mm0, [pix_tmp+0x18]
  328.     movq   mm1, [pix_tmp+0x28]
  329.     movq   mm2, [pix_tmp+0x38]
  330.     movq   mm3, [pix_tmp+0x48]
  331.     TRANSPOSE8x4_STORE  PASS8ROWS(rax, r9, r10, r11)
  332.     shl    r10, 3
  333.     sub    rax, r10
  334.     sub    r9,  r10
  335.     shr    r10, 3
  336.     movq   mm0, [pix_tmp+0x10]
  337.     movq   mm1, [pix_tmp+0x20]
  338.     movq   mm2, [pix_tmp+0x30]
  339.     movq   mm3, [pix_tmp+0x40]
  340.     TRANSPOSE8x4_STORE  PASS8ROWS(rax, r9, r10, r11)
  341.     ret
  342. %macro CHROMA_V_START 0
  343.     ; rdi = pix
  344.     movsxd rsi, esi ; stride
  345.     dec    edx      ; alpha-1
  346.     dec    ecx      ; beta-1
  347.     mov    rax, rdi
  348.     sub    rax, rsi
  349.     sub    rax, rsi
  350. %endmacro
  351. %macro CHROMA_H_START 0
  352.     movsxd rsi, esi
  353.     dec    edx
  354.     dec    ecx
  355.     sub    rdi, 2
  356.     lea    r9, [rsi+rsi*2]
  357.     mov    rax, rdi
  358.     add    rdi, r9
  359. %endmacro
  360. ALIGN 16
  361. ;-----------------------------------------------------------------------------
  362. ;   void x264_deblock_v_chroma_mmxext( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
  363. ;-----------------------------------------------------------------------------
  364. x264_deblock_v_chroma_mmxext:
  365.     CHROMA_V_START
  366.     movq  mm0, [rax]
  367.     movq  mm1, [rax+rsi]
  368.     movq  mm2, [rdi]
  369.     movq  mm3, [rdi+rsi]
  370.     LOAD_MASK_MMX  edx, ecx
  371.     movd       mm6, [r8] ; tc0
  372.     punpcklbw  mm6, mm6
  373.     pand       mm7, mm6
  374.     DEBLOCK_P0_Q0_MMX
  375.     movq  [rax+rsi], mm1
  376.     movq  [rdi], mm2
  377.     ret
  378. ALIGN 16
  379. ;-----------------------------------------------------------------------------
  380. ;   void x264_deblock_h_chroma_mmxext( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
  381. ;-----------------------------------------------------------------------------
  382. x264_deblock_h_chroma_mmxext:
  383.     CHROMA_H_START
  384.     TRANSPOSE4x8_LOAD  PASS8ROWS(rax, rdi, rsi, r9)
  385.     movq  [rsp-8], mm0
  386.     movq  [rsp-16], mm3
  387.     LOAD_MASK_MMX  edx, ecx
  388.     movd       mm6, [r8] ; tc0
  389.     punpcklbw  mm6, mm6
  390.     pand       mm7, mm6
  391.     DEBLOCK_P0_Q0_MMX
  392.     movq  mm0, [rsp-8]
  393.     movq  mm3, [rsp-16]
  394.     TRANSPOSE8x4_STORE PASS8ROWS(rax, rdi, rsi, r9)
  395.     ret
  396. ; in: %1=p0 %2=p1 %3=q1
  397. ; out: p0 = (p0 + q1 + 2*p1 + 2) >> 2
  398. %macro CHROMA_INTRA_P0 3
  399.     movq    mm4, %1
  400.     pxor    mm4, %3
  401.     pand    mm4, [pb_01 GLOBAL] ; mm4 = (p0^q1)&1
  402.     pavgb   %1,  %3
  403.     psubusb %1,  mm4
  404.     pavgb   %1,  %2             ; dst = avg(p1, avg(p0,q1) - ((p0^q1)&1))
  405. %endmacro
  406. %macro CHROMA_INTRA_BODY 0
  407.     LOAD_MASK_MMX edx, ecx
  408.     movq   mm5, mm1
  409.     movq   mm6, mm2
  410.     CHROMA_INTRA_P0  mm1, mm0, mm3
  411.     CHROMA_INTRA_P0  mm2, mm3, mm0
  412.     psubb  mm1, mm5
  413.     psubb  mm2, mm6
  414.     pand   mm1, mm7
  415.     pand   mm2, mm7
  416.     paddb  mm1, mm5
  417.     paddb  mm2, mm6
  418. %endmacro
  419. ALIGN 16
  420. ;-----------------------------------------------------------------------------
  421. ;   void x264_deblock_v_chroma_intra_mmxext( uint8_t *pix, int stride, int alpha, int beta )
  422. ;-----------------------------------------------------------------------------
  423. x264_deblock_v_chroma_intra_mmxext:
  424.     CHROMA_V_START
  425.     movq  mm0, [rax]
  426.     movq  mm1, [rax+rsi]
  427.     movq  mm2, [rdi]
  428.     movq  mm3, [rdi+rsi]
  429.     CHROMA_INTRA_BODY
  430.     movq  [rax+rsi], mm1
  431.     movq  [rdi], mm2
  432.     ret
  433. ALIGN 16
  434. ;-----------------------------------------------------------------------------
  435. ;   void x264_deblock_h_chroma_intra_mmxext( uint8_t *pix, int stride, int alpha, int beta )
  436. ;-----------------------------------------------------------------------------
  437. x264_deblock_h_chroma_intra_mmxext:
  438.     CHROMA_H_START
  439.     TRANSPOSE4x8_LOAD  PASS8ROWS(rax, rdi, rsi, r9)
  440.     CHROMA_INTRA_BODY
  441.     TRANSPOSE8x4_STORE PASS8ROWS(rax, rdi, rsi, r9)
  442.     ret