home *** CD-ROM | disk | FTP | other *** search
/ Computer Shopper 275 / DPCS0111DVD.ISO / Toolkit / Audio-Visual / VirtualDub / Source / VirtualDub-1.9.10-src.7z / src / Meia / source / mpeg_idct_sse2.asm < prev    next >
Encoding:
Assembly Source File  |  2009-09-14  |  24.2 KB  |  893 lines

  1. ;    VirtualDub - Video processing and capture application
  2. ;    Copyright (C) 1998-2001 Avery Lee
  3. ;
  4. ;    This program is free software; you can redistribute it and/or modify
  5. ;    it under the terms of the GNU General Public License as published by
  6. ;    the Free Software Foundation; either version 2 of the License, or
  7. ;    (at your option) any later version.
  8. ;
  9. ;    This program is distributed in the hope that it will be useful,
  10. ;    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. ;    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. ;    GNU General Public License for more details.
  13. ;
  14. ;    You should have received a copy of the GNU General Public License
  15. ;    along with this program; if not, write to the Free Software
  16. ;    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17.  
  18. %define PROFILE 0
  19.  
  20. ;This code is based on the fragments from the Intel Application Note AP-922.
  21. ;
  22. ;Apologies to Intel; Adobe Acrobat screws up formatting royally.
  23. ;
  24. ;
  25. ;
  26. ;IEEE-1180 results:
  27. ;    pmse      mse       pme      me
  28. ;1    0.018000, 0.013742, 0.003100,-0.000083
  29. ;2    0.018600, 0.013573, 0.003300, 0.000217
  30. ;3    0.014100, 0.011441, 0.003900, 0.000106
  31. ;4    0.017900, 0.013700, 0.004500, 0.000056
  32. ;5    0.018300, 0.013623, 0.004900,-0.000239
  33. ;6    0.014000, 0.011439, 0.003600,-0.000117
  34.  
  35.  
  36.  
  37. ;=============================================================================
  38. ;
  39. ; These examples contain code fragments for first stage iDCT 8x8
  40. ; (for rows) and first stage DCT 8x8 (for columns)
  41. ;
  42. ;=============================================================================
  43.  
  44. BITS_INV_ACC    equ        4            ; 4 or 5 for IEEE
  45. SHIFT_INV_ROW    equ        16 - BITS_INV_ACC
  46. SHIFT_INV_COL    equ        1 + BITS_INV_ACC
  47. RND_INV_ROW        equ        1024 * (6 - BITS_INV_ACC) ; 1 << (SHIFT_INV_ROW-1)
  48. RND_INV_COL        equ        16 * (BITS_INV_ACC - 3) ; 1 << (SHIFT_INV_COL-1)
  49. RND_INV_CORR    equ        RND_INV_COL - 1 ; correction -1.0 and round
  50.  
  51.     segment    .rdata, align=16
  52.         Align    16
  53.  
  54. rounder            dw    4, 4, 4, 4
  55.                 dw    0,0,0,0
  56. round_inv_row    dd    RND_INV_ROW, RND_INV_ROW, RND_INV_ROW, RND_INV_ROW
  57. one_corr        dw    1, 1, 1, 1, 1, 1, 1, 1
  58.  
  59. round_inv_col    dw    RND_INV_COL, RND_INV_COL, RND_INV_COL, RND_INV_COL, RND_INV_COL, RND_INV_COL, RND_INV_COL, RND_INV_COL
  60. round_inv_corr    dw    RND_INV_CORR, RND_INV_CORR, RND_INV_CORR, RND_INV_CORR, RND_INV_CORR, RND_INV_CORR, RND_INV_CORR, RND_INV_CORR
  61. tg_1_16        dw    13036, 13036, 13036, 13036, 13036, 13036, 13036, 13036    ; tg * (2<<16)
  62. tg_2_16        dw    27146, 27146, 27146, 27146, 27146, 27146, 27146, 27146    ; tg * (2<<16)
  63. tg_3_16        dw    -21746, -21746, -21746, -21746, -21746, -21746, -21746, -21746    ; tg * (2<<16) - 1.0
  64. cos_4_16    dw    -19195, -19195, -19195, -19195, -19195, -19195, -19195, -19195    ; cos * (2<<16) - 1.0
  65. ocos_4_16    dw    23170, 23170, 23170, 23170, 23170, 23170, 23170, 23170    ; cos * (2<<15) + 0.5
  66. ucos_4_16    dw    46341, 46341, 46341, 46341, 46341, 46341, 46341, 46341    ; cos * (2<<16)
  67.  
  68. jump_tab    dd    tail_inter, tail_intra, tail_mjpeg,0
  69.  
  70.  
  71. ;=============================================================================
  72. ;
  73. ; The first stage iDCT 8x8 - inverse DCTs of rows
  74. ;
  75. ;-----------------------------------------------------------------------------
  76. ; The 8-point inverse DCT direct algorithm
  77. ;-----------------------------------------------------------------------------
  78. ;
  79. ; static const short w[32] = {
  80. ; FIX(cos_4_16), FIX(cos_2_16), FIX(cos_4_16), FIX(cos_6_16),
  81. ; FIX(cos_4_16), FIX(cos_6_16), -FIX(cos_4_16), -FIX(cos_2_16),
  82. ; FIX(cos_4_16), -FIX(cos_6_16), -FIX(cos_4_16), FIX(cos_2_16),
  83. ; FIX(cos_4_16), -FIX(cos_2_16), FIX(cos_4_16), -FIX(cos_6_16),
  84. ; FIX(cos_1_16), FIX(cos_3_16), FIX(cos_5_16), FIX(cos_7_16),
  85. ; FIX(cos_3_16), -FIX(cos_7_16), -FIX(cos_1_16), -FIX(cos_5_16),
  86. ; FIX(cos_5_16), -FIX(cos_1_16), FIX(cos_7_16), FIX(cos_3_16),
  87. ; FIX(cos_7_16), -FIX(cos_5_16), FIX(cos_3_16), -FIX(cos_1_16) };
  88. ;
  89. ; #define DCT_8_INV_ROW(x, y)
  90. ;{
  91. ; int a0, a1, a2, a3, b0, b1, b2, b3;
  92. ;
  93. ; a0 =x[0]*w[0]+x[2]*w[1]+x[4]*w[2]+x[6]*w[3];
  94. ; a1 =x[0]*w[4]+x[2]*w[5]+x[4]*w[6]+x[6]*w[7];
  95. ; a2 = x[0] * w[ 8] + x[2] * w[ 9] + x[4] * w[10] + x[6] * w[11];
  96. ; a3 = x[0] * w[12] + x[2] * w[13] + x[4] * w[14] + x[6] * w[15];
  97. ; b0 = x[1] * w[16] + x[3] * w[17] + x[5] * w[18] + x[7] * w[19];
  98. ; b1 = x[1] * w[20] + x[3] * w[21] + x[5] * w[22] + x[7] * w[23];
  99. ; b2 = x[1] * w[24] + x[3] * w[25] + x[5] * w[26] + x[7] * w[27];
  100. ; b3 = x[1] * w[28] + x[3] * w[29] + x[5] * w[30] + x[7] * w[31];
  101. ;
  102. ; y[0] = SHIFT_ROUND ( a0 + b0 );
  103. ; y[1] = SHIFT_ROUND ( a1 + b1 );
  104. ; y[2] = SHIFT_ROUND ( a2 + b2 );
  105. ; y[3] = SHIFT_ROUND ( a3 + b3 );
  106. ; y[4] = SHIFT_ROUND ( a3 - b3 );
  107. ; y[5] = SHIFT_ROUND ( a2 - b2 );
  108. ; y[6] = SHIFT_ROUND ( a1 - b1 );
  109. ; y[7] = SHIFT_ROUND ( a0 - b0 );
  110. ;}
  111. ;
  112. ;-----------------------------------------------------------------------------
  113. ;
  114. ; In this implementation the outputs of the iDCT-1D are multiplied
  115. ; for rows 0,4 - by cos_4_16,
  116. ; for rows 1,7 - by cos_1_16,
  117. ; for rows 2,6 - by cos_2_16,
  118. ; for rows 3,5 - by cos_3_16
  119. ; and are shifted to the left for better accuracy
  120. ;
  121. ; For the constants used,
  122. ; FIX(float_const) = (short) (float_const * (1<<15) + 0.5)
  123. ;
  124. ;=============================================================================
  125.  
  126.         align 16
  127.  
  128. ; Table for rows 0,4 - constants are multiplied by cos_4_16
  129. ; Table for rows 1,7 - constants are multiplied by cos_1_16
  130. ; Table for rows 2,6 - constants are multiplied by cos_2_16
  131. ; Table for rows 3,5 - constants are multiplied by cos_3_16
  132.  
  133. tabbase equ $
  134. tab_i_04_short    dw  16384,  21407,  16384,   8864,  16384,  -8867,  16384, -21407    ; w00 w01 w04 w05 w08 w09 w12 w13
  135.                 dw  22725,  19266,  19266,  -4525,  12873, -22725,   4520, -12873    ; w16 w17 w20 w21 w24 w25 w28 w29
  136. tab_i_17_short    dw  22725,  29692,  22725,  12295,  22725, -12299,  22725, -29692    ; w00 w01 w04 w05 w08 w09 w12 w13
  137.                 dw  31521,  26722,  26722,  -6271,  17855, -31521,   6270, -17855    ; w16 w17 w20 w21 w24 w25 w28 w29
  138. tab_i_26_short    dw  21407,  27969,  21407,  11587,  21407, -11585,  21407, -27969    ; w00 w01 w04 w05 w08 w09 w12 w13
  139.                 dw  29692,  25172,  25172,  -5902,  16819, -29692,   5906, -16819    ; w16 w17 w20 w21 w24 w25 w28 w29
  140. tab_i_35_short    dw  19266,  25172,  19266,  10426,  19266, -10426,  19266, -25172    ; w00 w01 w04 w05 w08 w09 w12 w13
  141.                 dw  26722,  22654,  22654,  -5312,  15137, -26722,   5315, -15137    ; w16 w17 w20 w21 w24 w25 w28 w29
  142.  
  143.  
  144. ; Table for rows 0,4 - constants are multiplied by cos_4_16
  145. ; Table for rows 1,7 - constants are multiplied by cos_1_16
  146. ; Table for rows 2,6 - constants are multiplied by cos_2_16
  147. ; Table for rows 3,5 - constants are multiplied by cos_3_16
  148.  
  149. tab_i_04    dw  16384,  21407, -16387, -21407,  16384,  -8867,  16384,  -8867    ; w00 w01 w06 w07 w08 w09 w14 w15
  150.             dw  16384,   8867,  16384,   8864, -16384,  21407,  16384, -21407    ; w02 w03 w04 w05 w10 w11 w12 w13
  151.             dw  22725,  19266, -22720, -12873,  12873, -22725,  19266, -22725    ; w16 w17 w22 w23 w24 w25 w30 w31
  152.             dw  12873,   4520,  19266,  -4525,   4520,  19266,   4520, -12873    ; w18 w19 w20 w21 w26 w27 w28 w29
  153. tab_i_17    dw  22725,  29692, -22729, -29692,  22725, -12299,  22725, -12299    ; w00 w01 w06 w07 w08 w09 w14 w15
  154.             dw  22725,  12299,  22725,  12295, -22725,  29692,  22725, -29692    ; w02 w03 w04 w05 w10 w11 w12 w13
  155.             dw  31521,  26722, -31520, -17855,  17855, -31521,  26722, -31521    ; w16 w17 w22 w23 w24 w25 w30 w31
  156.             dw  17855,   6270,  26722,  -6271,   6270,  26722,   6270, -17855    ; w18 w19 w20 w21 w26 w27 w28 w29
  157. tab_i_26    dw  21407,  27969, -21405, -27969,  21407, -11585,  21407, -11585    ; w00 w01 w06 w07 w08 w09 w14 w15
  158.             dw  21407,  11585,  21407,  11587, -21407,  27969,  21407, -27969    ; w02 w03 w04 w05 w10 w11 w12 w13
  159.             dw  29692,  25172, -29696, -16819,  16819, -29692,  25172, -29692    ; w16 w17 w22 w23 w24 w25 w30 w31
  160.             dw  16819,   5906,  25172,  -5902,   5906,  25172,   5906, -16819    ; w18 w19 w20 w21 w26 w27 w28 w29
  161. tab_i_35    dw  19266,  25172, -19266, -25172,  19266, -10426,  19266, -10426    ; w00 w01 w06 w07 w08 w09 w14 w15
  162.             dw  19266,  10426,  19266,  10426, -19266,  25172,  19266, -25172    ; w02 w03 w04 w05 w10 w11 w12 w13
  163.             dw  26722,  22654, -26725, -15137,  15137, -26722,  22654, -26722    ; w16 w17 w22 w23 w24 w25 w30 w31
  164.             dw  15137,   5315,  22654,  -5312,   5315,  22654,   5315, -15137    ; w18 w19 w20 w21 w26 w27 w28 w29
  165.  
  166. rowstart_tbl2    dd    dorow_7is
  167.         dd    dorow_6is
  168.         dd    dorow_5is
  169.         dd    dorow_4is
  170.         dd    dorow_3is
  171.         dd    dorow_2is
  172.         dd    dorow_1is
  173.         dd    dorow_0is
  174.         dd    do_dc_sse2
  175.  
  176. pos_tab    times     1 db (8*4)        ;pos 0:     DC only
  177.         times     1 db (7*4)        ;pos 1:     1 AC row
  178.         times     1 db (6*4)        ;pos 2:     2 AC rows
  179.         times     6 db (5*4)        ;pos 3-8:   3 AC rows
  180.         times     1 db (4*4)        ;pos 9:     4 AC rows
  181.         times    10 db (3*4)        ;pos 10-19: 5 AC rows
  182.         times     1 db (2*4)        ;pos 20:    6 AC rows
  183.         times    14 db (1*4)        ;pos 21-34:    7 AC rows
  184.         times    29 db (0*4)        ;pos 35-63: 8 AC rows
  185.  
  186.  
  187. ;-----------------------------------------------------------------------------
  188.  
  189. %macro DCT_8_INV_ROW_1_SSE2 3
  190. %%inp    equ        %1
  191. %%out    equ        %2
  192. %%table    equ        %3
  193.  
  194.         movdqa        xmm0, [%%inp]        ;xmm0 = x7 x5 x3 x1 x6 x4 x2 x0
  195.         pshufd        xmm1, xmm0, 00010001b    ;xmm1 = x2 x0 x6 x4 x2 x0 x6 x4
  196.         pshufd        xmm2, xmm0, 11101110b    ;xmm2 = x7 x5 x3 x1 x7 x5 x3 x1
  197.         pshufd        xmm3, xmm0, 10111011b    ;xmm3 = x3 x1 x7 x5 x3 x1 x7 x5
  198.         pshufd        xmm0, xmm0, 01000100b    ;xmm0 = x6 x4 x2 x0 x6 x4 x2 x0
  199.  
  200.         pmaddwd        xmm0, [%%table+00h]
  201.         pmaddwd        xmm1, [%%table+10h]
  202.         pmaddwd        xmm2, [%%table+20h]
  203.         pmaddwd        xmm3, [%%table+30h]
  204.  
  205.         paddd        xmm0, [edx + (round_inv_row - tabbase)]
  206.         paddd        xmm0, xmm1                ;xmm0 = y3 y2 y1 y0
  207.         paddd        xmm2, xmm3                ;xmm2 = y4 y5 y6 y7
  208.         movdqa        xmm1, xmm0
  209.         paddd        xmm0, xmm2                ;xmm0 = z3 z2 z1 z0
  210.         psubd        xmm1, xmm2                ;xmm1 = z4 z5 z6 z7
  211.         psrad        xmm0, SHIFT_INV_ROW
  212.         psrad        xmm1, SHIFT_INV_ROW
  213.         packssdw    xmm0, xmm1
  214.         pshufhw        xmm0, xmm0, 00011011b
  215.  
  216.         movdqa        [%%out], xmm0
  217. %endmacro
  218.  
  219. %macro DCT_8_INV_ROW_1_SSE2_SHORT 3
  220. .inp    equ        %1
  221. .out    equ        %2
  222. .table    equ        %3
  223.  
  224.         movdqa        xmm0, [.inp]        ;xmm0 = -- -- x3 x1 -- -- x2 x0
  225.         pshufd        xmm2, xmm0, 10101010b    ;xmm2 = x3 x1 x3 x1 x3 x1 x3 x1
  226.         pshufd        xmm0, xmm0, 00000000b    ;xmm0 = x2 x0 x2 x0 x2 x0 x2 x0
  227.         pmaddwd        xmm0, [.table+00h]    ;xmm0 = y3 y2 y1 y0
  228.         pmaddwd        xmm2, [.table+10h]    ;xmm2 = y4 y5 y6 y7
  229.         paddd        xmm0, [edx + (round_inv_row - tabbase)]
  230.         movdqa        xmm1, xmm0
  231.         paddd        xmm0, xmm2                ;xmm0 = z3 z2 z1 z0
  232.         psubd        xmm1, xmm2                ;xmm1 = z4 z5 z6 z7
  233.         psrad        xmm0, SHIFT_INV_ROW
  234.         psrad        xmm1, SHIFT_INV_ROW
  235.         packssdw    xmm0, xmm1
  236.         pshufhw        xmm0, xmm0, 00011011b
  237.  
  238.         movdqa        [.out], xmm0
  239. %endmacro
  240.  
  241.  
  242. ;=============================================================================
  243. ;
  244. ; The second stage iDCT 8x8 - inverse DCTs of columns
  245. ;
  246. ; The outputs are premultiplied
  247. ; for rows 0,4 - on cos_4_16,
  248. ; for rows 1,7 - on cos_1_16,
  249. ; for rows 2,6 - on cos_2_16,
  250. ; for rows 3,5 - on cos_3_16
  251. ; and are shifted to the left for rise of accuracy
  252. ;
  253. ;-----------------------------------------------------------------------------
  254. ;
  255. ; The 8-point scaled inverse DCT algorithm (26a8m)
  256. ;
  257. ;-----------------------------------------------------------------------------
  258. ;
  259. ;    // Reorder and prescale (implicit)
  260. ;
  261. ;    ev0 = co[0] / 2.0;
  262. ;    ev1 = co[2] / 2.0;
  263. ;    ev2 = co[4] / 2.0;
  264. ;    ev3 = co[6] / 2.0;
  265. ;    od0 = co[1] / 2.0;
  266. ;    od1 = co[3] / 2.0;
  267. ;    od2 = co[5] / 2.0;
  268. ;    od3 = co[7] / 2.0;
  269. ;
  270. ;    // 5) Apply D8T (implicit in row calculation).
  271. ;
  272. ;    tmp[0] = ev0*LAMBDA(4);
  273. ;    tmp[1] = ev2*LAMBDA(4);
  274. ;    tmp[2] = ev1*LAMBDA(2);
  275. ;    tmp[3] = ev3*LAMBDA(2);
  276. ;    tmp[4] = od0*LAMBDA(1);
  277. ;    tmp[5] = od3*LAMBDA(1);
  278. ;    tmp[6] = od1*LAMBDA(3);
  279. ;    tmp[7] = od2*LAMBDA(3);
  280. ;
  281. ;    // 4) Apply B8T.
  282. ;
  283. ;    double x0, x1, x2, x3, y0, y1, y2, y3;
  284. ;
  285. ;    x0 = tmp[0] + tmp[1];
  286. ;    x1 = tmp[0] - tmp[1];
  287. ;    x2 = tmp[2] + TAN(2)*tmp[3];
  288. ;    x3 = tmp[2]*TAN(2) - tmp[3];
  289. ;    y0 = tmp[4] + TAN(1)*tmp[5];
  290. ;    y1 = tmp[4]*TAN(1) - tmp[5];
  291. ;    y2 = tmp[6] + TAN(3)*tmp[7];
  292. ;    y3 = tmp[6]*TAN(3) - tmp[7];
  293. ;
  294. ;    // 3) Apply E8T.
  295. ;    //
  296. ;    //    1  0  1  0
  297. ;    //    0  1  0  1
  298. ;    //    0  1  0 -1
  299. ;    //    1  0 -1  0
  300. ;    //            1  0  1  0
  301. ;    //            1  0 -1  0
  302. ;    //            0  1  0  1
  303. ;    //            0  1  0 -1
  304. ;
  305. ;    double e0, e1, e2, e3, o0, o1, o2, o3;
  306. ;
  307. ;    e0 = x0 + x2;
  308. ;    e1 = x1 + x3;
  309. ;    e2 = x1 - x3;
  310. ;    e3 = x0 - x2;
  311. ;    o0 = y0 + y2;
  312. ;    o1 = y0 - y2;
  313. ;    o2 = y1 + y3;
  314. ;    o3 = y1 - y3;
  315. ;
  316. ;    // 2) Apply F8T.
  317. ;
  318. ;    double a, b;
  319. ;
  320. ;    a = (o1 + o2) * LAMBDA(4);
  321. ;    b = (o1 - o2) * LAMBDA(4);
  322. ;
  323. ;    o1 = a;
  324. ;    o2 = b;
  325. ;
  326. ;    // 6) Apply output butterfly (A8T).
  327. ;    //
  328. ;    // 1 0 0 0  1  0  0  0
  329. ;    // 0 1 0 0  0  1  0  0
  330. ;    // 0 0 1 0  0  0  1  0
  331. ;    // 0 0 0 1  0  0  0  1
  332. ;    // 0 0 0 1  0  0  0 -1
  333. ;    // 0 0 1 0  0  0 -1  0
  334. ;    // 0 1 0 0  0 -1  0  0
  335. ;    // 1 0 0 0 -1  0  0  0
  336. ;
  337. ;    out[0] = e0 + o0;
  338. ;    out[1] = e1 + o1;
  339. ;    out[2] = e2 + o2;
  340. ;    out[3] = e3 + o3;
  341. ;    out[4] = e3 - o3;
  342. ;    out[5] = e2 - o2;
  343. ;    out[6] = e1 - o1;
  344. ;    out[7] = e0 - o0;
  345. ;
  346. ;=============================================================================
  347. %macro DCT_8_INV_COL 2
  348. %define    .inp    %1
  349. %define    .out    %2
  350.  
  351. %define .x0    [.inp + 0*16]
  352. %define .x1    [.inp + 1*16]
  353. %define .x2    [.inp + 2*16]
  354. %define .x3    [.inp + 3*16]
  355. %define .x4    [.inp + 4*16]
  356. %define .x5    [.inp + 5*16]
  357. %define .x6    [.inp + 6*16]
  358. %define .x7    [.inp + 7*16]
  359. %define .y0    [.out + 0*16]
  360. %define .y1    [.out + 1*16]
  361. %define .y2    [.out + 2*16]
  362. %define .y3    [.out + 3*16]
  363. %define .y4    [.out + 4*16]
  364. %define .y5    [.out + 5*16]
  365. %define .y6    [.out + 6*16]
  366. %define .y7    [.out + 7*16]
  367.  
  368.     ;======= optimized    segment    .text
  369.  
  370.     ;ODD ELEMENTS
  371.  
  372.     movdqa    xmm0, [edx + (tg_1_16 - tabbase)]
  373.  
  374.     movdqa    xmm2, [edx + (tg_3_16 - tabbase)]
  375.     movdqa    xmm3,xmm0
  376.  
  377.     movdqa    xmm1,.x7
  378.     movdqa    xmm6,xmm2
  379.  
  380.     movdqa    xmm4,.x5
  381.     pmulhw    xmm0,xmm1
  382.  
  383.     movdqa    xmm5,.x1
  384.     pmulhw    xmm2,xmm4
  385.  
  386.     movdqa    xmm7,.x3
  387.     pmulhw    xmm3,xmm5
  388.  
  389.     pmulhw    xmm6,xmm7
  390.     paddw    xmm0,xmm5
  391.  
  392.     paddw    xmm2,xmm4
  393.     psubw    xmm6,xmm4
  394.  
  395.     paddw    xmm2,xmm7
  396.     psubw    xmm3,xmm1
  397.  
  398.     paddw    xmm0, [edx + (one_corr - tabbase)]
  399.     paddw    xmm6,xmm7
  400.  
  401.     ;E8T butterfly - odd elements
  402.  
  403.     movdqa    xmm1,xmm0
  404.     movdqa    xmm5,xmm3
  405.     paddw    xmm0,xmm2        ;xmm0 = o0 = y0 + y2
  406.     psubw    xmm1,xmm2        ;xmm1 = o1 = y0 - y2
  407.     paddw    xmm3,xmm6        ;xmm3 = o2 = y1 + y3
  408.     psubw    xmm5,xmm6        ;xmm5 = o3 = y1 - y3
  409.  
  410.     ;F8T stage - odd elements
  411.  
  412.     movdqa    xmm2,xmm1
  413.     paddw    xmm1,xmm3            ;[F8T] xmm1 = o1 + o2
  414.  
  415.     movdqa    xmm4,.x0            ;[B8T1] xmm3 = tmp[0]
  416.     psubw    xmm2,xmm3            ;[F8T] xmm2 = o1 - o2
  417.  
  418.     movdqa    xmm3,.x4
  419.     movdqa    xmm6,xmm2            ;[F8T]
  420.  
  421.     pmulhw    xmm2, [edx + (cos_4_16 - tabbase)]    ;[F8T]
  422.     movdqa    xmm7,xmm1            ;[F8T]
  423.  
  424.     pmulhw    xmm1, [edx + (cos_4_16 - tabbase)]    ;[F8T]
  425.     paddw    xmm3,xmm4            ;[B8T1] xmm3 = x0 = tmp[0] + tmp[1]
  426.  
  427.     paddw    xmm3, [edx + (round_inv_corr - tabbase)]    ;[E8T]
  428.     ;<v-pipe>
  429.  
  430.     psubw    xmm4,.x4            ;[B8T1] xmm4 = x1 = tmp[0] - tmp[1]
  431.     paddw    xmm2,xmm6            ;[F8T]
  432.  
  433.     por    xmm1, [one_corr]    ;[F8T]
  434.     ;<v-pipe>
  435.  
  436.     movdqa    xmm6,.x6            ;[B8T2] xmm7 = tmp[3]
  437.     paddw    xmm1,xmm7            ;[F8T] xmm1 = o1' = (o1 + o2)*LAMBDA(4)
  438.  
  439.     pmulhw    xmm6, [edx + (tg_2_16 - tabbase)]    ;xmm7 = tmp[3] * TAN(2)
  440.     ;<v-pipe>
  441.  
  442.     movdqa    xmm7, [edx + (one_corr - tabbase)]
  443.     ;<v-pipe>
  444.  
  445.     paddw    xmm4, [edx + (round_inv_col - tabbase)]    ;[out]
  446.     psubw    xmm2,xmm7            ;[F8T] xmm2 = o2' = (o1 - o2)*LAMBDA(4)
  447.  
  448.     paddw    xmm6,.x2            ;[B8T2] xmm7 = x2 = tmp[2] + tmp[3]*TAN(2)
  449.     paddw    xmm7,xmm3            ;[E8T]
  450.  
  451.     paddw    xmm7,xmm6            ;[E8T] xmm6 = e0 = x0+x2
  452.     psubw    xmm3,xmm6            ;[E8T] xmm3 = e3 = x0-x2
  453.  
  454.     ;output butterfly - 0 and 3
  455.  
  456.     movdqa    xmm6,xmm7        ;xmm7 = e0
  457.     paddw    xmm7,xmm0        ;xmm6 = e0 + o0
  458.  
  459.     psubw    xmm6,xmm0        ;xmm7 = e0 - o0
  460.     psraw    xmm7,SHIFT_INV_COL
  461.  
  462.     movdqa    xmm0,xmm3        ;xmm7 = e3 
  463.     psraw    xmm6,SHIFT_INV_COL
  464.  
  465.     movdqa    .y0,xmm7
  466.     paddw    xmm3,xmm5        ;xmm6 = e3 + o3
  467.  
  468.     movdqa    xmm7,.x2        ;[B8T] xmm6 = tmp[2]
  469.     psubw    xmm0,xmm5        ;[out] xmm7 = e3 - o3
  470.  
  471.     movdqa    .y7,xmm6
  472.     psraw    xmm3,SHIFT_INV_COL
  473.  
  474.     pmulhw    xmm7, [edx + (tg_2_16 - tabbase)]        ;[B8T] xmm6 = tmp[2] * TAN(2)
  475.     psraw    xmm0,SHIFT_INV_COL
  476.  
  477.     movdqa    .y3,xmm3
  478.     movdqa    xmm6,xmm4                ;[E8T]
  479.  
  480.     psubw    xmm6, [edx + (one_corr - tabbase)]
  481.     ;<v-pipe>
  482.  
  483.  
  484.     ;B8T stage - x3 element
  485.     ;
  486.     ;free registers: 03567
  487.  
  488.     psubw    xmm7,.x6                ;[B8T] xmm6 = x3 = tmp[2]*TAN(2) - tmp[3]
  489.     movdqa    xmm3,xmm1
  490.  
  491.     ;E8T stage - x1 and x3 elements
  492.  
  493.     movdqa    .y4,xmm0
  494.     paddw    xmm4,xmm7                ;[E8T] xmm4 = e1 = x1+x3
  495.  
  496.     psubw    xmm6,xmm7                ;[E8T] xmm7 = e2 = x1-x3
  497.     paddw    xmm3,xmm4                ;xmm3 = e1 + o1
  498.  
  499.     psubw    xmm4,xmm1                ;xmm4 = e1 - o1
  500.     psraw    xmm3,SHIFT_INV_COL
  501.  
  502.     movdqa    xmm5,xmm6                ;xmm6 = e2
  503.     psraw    xmm4,SHIFT_INV_COL
  504.  
  505.     paddw    xmm6,xmm2                ;xmm7 = e2 + o2
  506.     psubw    xmm5,xmm2                ;xmm6 = e2 - o2
  507.  
  508.     movdqa    .y1,xmm3
  509.     psraw    xmm6,SHIFT_INV_COL
  510.  
  511.     movdqa    .y6,xmm4
  512.     psraw    xmm5,SHIFT_INV_COL
  513.  
  514.     movdqa    .y2,xmm6
  515.  
  516.     movdqa    .y5,xmm5
  517.  
  518. %endmacro
  519.  
  520. ;-----------------------------------------------------------------------------
  521. ;
  522. ; The half 8-point scaled inverse DCT algorithm (26a8m)
  523. ;
  524. ;-----------------------------------------------------------------------------
  525. ;
  526. ;    // Reorder and prescale (implicit)
  527. ;
  528. ;    ev0 = co[0] / 2.0;
  529. ;    ev1 = co[2] / 2.0;
  530. ;    od0 = co[1] / 2.0;
  531. ;    od1 = co[3] / 2.0;
  532. ;
  533. ;    // 5) Apply D8T (implicit in row calculation).
  534. ;
  535. ;    tmp[0] = ev0*LAMBDA(4);
  536. ;    tmp[2] = ev1*LAMBDA(2);
  537. ;    tmp[4] = od0*LAMBDA(1);
  538. ;    tmp[6] = od1*LAMBDA(3);
  539. ;
  540. ;    // 4) Apply B8T.
  541. ;
  542. ;    double x0, x1, x2, x3, y0, y1, y2, y3;
  543. ;
  544. ;    x0 = tmp[0];
  545. ;    x1 = tmp[0];
  546. ;    x2 = tmp[2];
  547. ;    x3 = tmp[2]*TAN(2);
  548. ;    y0 = tmp[4];
  549. ;    y1 = tmp[4]*TAN(1);
  550. ;    y2 = tmp[6];
  551. ;    y3 = tmp[6]*TAN(3);
  552. ;
  553. ;    // 3) Apply E8T.
  554. ;    //
  555. ;    //    1  0  1  0
  556. ;    //    0  1  0  1
  557. ;    //    0  1  0 -1
  558. ;    //    1  0 -1  0
  559. ;    //            1  0  1  0
  560. ;    //            1  0 -1  0
  561. ;    //            0  1  0  1
  562. ;    //            0  1  0 -1
  563. ;
  564. ;    double e0, e1, e2, e3, o0, o1, o2, o3;
  565. ;
  566. ;    e0 = x0 + x2;
  567. ;    e1 = x1 + x3;
  568. ;    e2 = x1 - x3;
  569. ;    e3 = x0 - x2;
  570. ;    o0 = y0 + y2;
  571. ;    o1 = y0 - y2;
  572. ;    o2 = y1 + y3;
  573. ;    o3 = y1 - y3;
  574. ;
  575. ;    // 2) Apply F8T.
  576. ;
  577. ;    double a, b;
  578. ;
  579. ;    a = (o1 + o2) * LAMBDA(4);
  580. ;    b = (o1 - o2) * LAMBDA(4);
  581. ;
  582. ;    o1 = a;
  583. ;    o2 = b;
  584. ;
  585. ;    // 6) Apply output butterfly (A8T).
  586. ;    //
  587. ;    // 1 0 0 0  1  0  0  0
  588. ;    // 0 1 0 0  0  1  0  0
  589. ;    // 0 0 1 0  0  0  1  0
  590. ;    // 0 0 0 1  0  0  0  1
  591. ;    // 0 0 0 1  0  0  0 -1
  592. ;    // 0 0 1 0  0  0 -1  0
  593. ;    // 0 1 0 0  0 -1  0  0
  594. ;    // 1 0 0 0 -1  0  0  0
  595. ;
  596. ;    out[0] = e0 + o0;
  597. ;    out[1] = e1 + o1;
  598. ;    out[2] = e2 + o2;
  599. ;    out[3] = e3 + o3;
  600. ;    out[4] = e3 - o3;
  601. ;    out[5] = e2 - o2;
  602. ;    out[6] = e1 - o1;
  603. ;    out[7] = e0 - o0;
  604. ;
  605. ;=============================================================================
  606.  
  607. %macro DCT_8_INV_COL_SHORT 2
  608. %define    .inp    %1
  609. %define    .out    %2
  610.  
  611. %define .x0    [.inp + 0*16]
  612. %define .x1    [.inp + 1*16]
  613. %define .x2    [.inp + 2*16]
  614. %define .x3    [.inp + 3*16]
  615. %define .y0    [.out + 0*16]
  616. %define .y1    [.out + 1*16]
  617. %define .y2    [.out + 2*16]
  618. %define .y3    [.out + 3*16]
  619. %define .y4    [.out + 4*16]
  620. %define .y5    [.out + 5*16]
  621. %define .y6    [.out + 6*16]
  622. %define .y7    [.out + 7*16]
  623.  
  624.     ;======= optimized    segment    .text
  625.  
  626.     ;ODD ELEMENTS
  627.  
  628.     movdqa    xmm3, [edx + (tg_1_16 - tabbase)]
  629.  
  630.     movdqa    xmm0, .x1
  631.     movdqa    xmm6, [edx + (tg_3_16 - tabbase)]
  632.  
  633.     movdqa    xmm2, .x3
  634.     pmulhw    xmm3, xmm0
  635.  
  636.     pmulhw    xmm6, xmm2
  637.  
  638.     paddw    xmm0, [edx + (one_corr - tabbase)]
  639.     paddw    xmm6, xmm2
  640.  
  641.     ;E8T butterfly - odd elements
  642.  
  643.     movdqa    xmm1, xmm0
  644.     movdqa    xmm5, xmm3
  645.     paddw    xmm0, xmm2        ;xmm0 = o0 = y0 + y2
  646.     psubw    xmm1, xmm2        ;xmm1 = o1 = y0 - y2
  647.     paddw    xmm3, xmm6        ;xmm3 = o2 = y1 + y3
  648.     psubw    xmm5, xmm6        ;xmm5 = o3 = y1 - y3
  649.  
  650.     ;F8T stage - odd elements
  651.  
  652.     movdqa    xmm2, xmm1
  653.     paddw    xmm1, xmm3                    ;[F8T] xmm1 = o1 + o2
  654.  
  655.     movdqa    xmm4, .x0                    ;[B8T1] xmm4 = x0 = x1 = tmp[0]
  656.     psubw    xmm2, xmm3                    ;[F8T] xmm2 = o1 - o2
  657.  
  658.     movdqa    xmm6, xmm2                    ;[F8T]
  659.     movdqa    xmm7, xmm1                    ;[F8T]
  660.  
  661.     pmulhw    xmm2, [edx + (cos_4_16 - tabbase)]    ;[F8T]
  662.     movdqa    xmm3, xmm4                    ;[B8T1] xmm3 = x0 = x1 = tmp[0]
  663.  
  664.     pmulhw    xmm1, [edx + (cos_4_16 - tabbase)]    ;[F8T]
  665.  
  666.     paddw    xmm3, [edx + (round_inv_corr - tabbase)]    ;[E8T]
  667.     ;<v-pipe>
  668.  
  669.     paddw    xmm4, [edx + (round_inv_col - tabbase)]    ;[out]
  670.     paddw    xmm2, xmm6                    ;[F8T]
  671.  
  672.     por        xmm1, [edx + (one_corr - tabbase)]    ;[F8T]
  673.     ;<v-pipe>
  674.  
  675.     psubw    xmm2, [edx + (one_corr - tabbase)]        ;[F8T] xmm2 = o2' = (o1 - o2)*LAMBDA(4)
  676.     paddw    xmm1, xmm7                    ;[F8T] xmm1 = o1' = (o1 + o2)*LAMBDA(4)
  677.  
  678.     movdqa    xmm6, .x2                    ;[B8T2] xmm7 = x2 = tmp[2]
  679.     movdqa    xmm7, xmm4                    ;[E8T]
  680.  
  681.     paddw    xmm7, xmm6                    ;[E8T] xmm6 = e0 = x0+x2
  682.     psubw    xmm3, xmm6                    ;[E8T] xmm3 = e3 = x0-x2
  683.  
  684.     ;output butterfly - 0 and 3
  685.  
  686.     movdqa    xmm6, xmm7        ;xmm7 = e0
  687.     paddw    xmm7, xmm0        ;xmm6 = e0 + o0
  688.  
  689.     psubw    xmm6, xmm0        ;xmm7 = e0 - o0
  690.     psraw    xmm7, SHIFT_INV_COL
  691.  
  692.     movdqa    xmm0, xmm3        ;xmm7 = e3 
  693.     psraw    xmm6, SHIFT_INV_COL
  694.  
  695.     movdqa    .y0, xmm7
  696.     paddw    xmm3, xmm5        ;xmm6 = e3 + o3
  697.  
  698.     movdqa    xmm7, .x2        ;[B8T] xmm6 = tmp[2]
  699.     psubw    xmm0, xmm5        ;[out] xmm7 = e3 - o3
  700.  
  701.     movdqa    .y7, xmm6
  702.     psraw    xmm3, SHIFT_INV_COL
  703.  
  704.     pmulhw    xmm7, [edx + (tg_2_16 - tabbase)]        ;[B8T] xmm6 = x3 = tmp[2] * TAN(2)
  705.     psraw    xmm0, SHIFT_INV_COL
  706.  
  707.     movdqa    .y3, xmm3
  708.     movdqa    xmm6, xmm4                ;[E8T]
  709.  
  710.     psubw    xmm6, [edx + (one_corr - tabbase)]
  711.     ;<v-pipe>
  712.  
  713.  
  714.     ;B8T stage - x3 element
  715.     ;
  716.     ;free registers: 03567
  717.  
  718.     movdqa    xmm3, xmm1
  719.  
  720.     ;E8T stage - x1 and x3 elements
  721.  
  722.     movdqa    .y4, xmm0
  723.     paddw    xmm4, xmm7                ;[E8T] xmm4 = e1 = x1+x3
  724.  
  725.     psubw    xmm6, xmm7                ;[E8T] xmm7 = e2 = x1-x3
  726.     paddw    xmm3, xmm4                ;xmm3 = e1 + o1
  727.  
  728.     psubw    xmm4, xmm1                ;xmm4 = e1 - o1
  729.     psraw    xmm3, SHIFT_INV_COL
  730.  
  731.     movdqa    xmm5, xmm6                ;xmm6 = e2
  732.     psraw    xmm4, SHIFT_INV_COL
  733.  
  734.     paddw    xmm6, xmm2                ;xmm7 = e2 + o2
  735.     psubw    xmm5, xmm2                ;xmm6 = e2 - o2
  736.  
  737.     movdqa    .y1, xmm3
  738.     psraw    xmm6, SHIFT_INV_COL
  739.  
  740.     movdqa    .y6, xmm4
  741.     psraw    xmm5, SHIFT_INV_COL
  742.  
  743.     movdqa    .y2, xmm6
  744.  
  745.     movdqa    .y5, xmm5
  746. %endmacro
  747.  
  748.     segment    .text
  749.  
  750.     global _IDCT_sse2    
  751.  
  752.  
  753. _IDCT_sse2:
  754.     mov    ecx,[esp+20]
  755.     mov edx, tabbase
  756.     movzx    ecx,byte [pos_tab+ecx]
  757.  
  758.     mov    eax,[esp+4]
  759.     jmp    dword [rowstart_tbl2+ecx]
  760.  
  761.     align    16
  762. dorow_3is:
  763.     DCT_8_INV_ROW_1_SSE2_SHORT    eax+3*16, eax+3*16, edx + (tab_i_35_short - tabbase)
  764. dorow_2is:
  765.     DCT_8_INV_ROW_1_SSE2_SHORT    eax+2*16, eax+2*16, edx + (tab_i_26_short - tabbase)
  766. dorow_1is:
  767.     DCT_8_INV_ROW_1_SSE2_SHORT    eax+1*16, eax+1*16, edx + (tab_i_17_short - tabbase)
  768. dorow_0is:
  769.     DCT_8_INV_ROW_1_SSE2_SHORT    eax+0*16, eax+0*16, edx + (tab_i_04_short - tabbase)
  770.  
  771.     DCT_8_INV_COL_SHORT        eax, eax
  772.     mov    edx,[esp+16]
  773.     mov    eax,[esp+4]
  774.     mov    ecx,[esp+8]
  775.     jmp    dword [jump_tab + edx*4]
  776.  
  777.     align    16
  778. dorow_7is:
  779.         DCT_8_INV_ROW_1_SSE2    eax+7*16, eax+7*16, edx + (tab_i_17 - tabbase)
  780. dorow_6is:
  781.         DCT_8_INV_ROW_1_SSE2    eax+6*16, eax+6*16, edx + (tab_i_26 - tabbase)
  782. dorow_5is:
  783.         DCT_8_INV_ROW_1_SSE2    eax+5*16, eax+5*16, edx + (tab_i_35 - tabbase)
  784. dorow_4is:
  785.         DCT_8_INV_ROW_1_SSE2    eax+4*16, eax+4*16, edx + (tab_i_04 - tabbase)
  786.         DCT_8_INV_ROW_1_SSE2    eax+3*16, eax+3*16, edx + (tab_i_35 - tabbase)
  787.         DCT_8_INV_ROW_1_SSE2    eax+2*16, eax+2*16, edx + (tab_i_26 - tabbase)
  788.         DCT_8_INV_ROW_1_SSE2    eax+1*16, eax+1*16, edx + (tab_i_17 - tabbase)
  789.         DCT_8_INV_ROW_1_SSE2    eax+0*16, eax+0*16, edx + (tab_i_04 - tabbase)
  790.  
  791.     DCT_8_INV_COL        eax, eax
  792.  
  793.     mov    edx,[esp+16]
  794.     mov    eax,[esp+4]
  795.     mov    ecx,[esp+8]
  796.     jmp    dword [jump_tab + edx*4]
  797.  
  798.  
  799.  
  800.  
  801.     align 16
  802.  
  803. tail_intra:
  804.     mov        edx,-8*16
  805. intra_loop:
  806.     movdqa        xmm0,[eax+edx+8*16]
  807.     packuswb    xmm0,xmm0
  808.     movq        qword [ecx],xmm0
  809.     add        ecx,[esp+12]
  810.     add        edx,16
  811.     jne        intra_loop
  812. tail_mjpeg:
  813.     ret
  814.  
  815.     align        16
  816. tail_inter:
  817.     mov        edx,-8*16
  818.     pxor        xmm7,xmm7
  819. inter_loop:
  820.     movdqa        xmm0,[eax+edx+8*16]
  821.     movq        xmm2,qword [ecx]
  822.     punpcklbw    xmm2,xmm7
  823.     paddw        xmm0,xmm2
  824.     packuswb    xmm0,xmm0
  825.     movq        [ecx],mm0
  826.     add        ecx,[esp+12]
  827.     add        edx,16
  828.     jne        inter_loop
  829.     ret
  830.  
  831. ;--------------------------------------------------------------------------
  832.  
  833. do_dc_sse2:
  834.     pshufw        mm0,[eax],0
  835.     pxor        mm1,mm1
  836.     mov            edx,[esp+16]
  837.     paddw        mm0,qword [rounder]
  838.     mov            ecx,[esp+8]        ;ecx = dst
  839.     psraw        mm0,3
  840.     cmp            edx, 1
  841.     mov            eax,[esp+12]        ;eax = pitch
  842.     jb            do_ac_sse2
  843.     ja            do_dc_mjpeg
  844.     packuswb    mm0,mm0
  845.  
  846.     movq        [ecx],mm0        ;row 0
  847.     lea            edx,[eax+eax*2]
  848.     movq        [ecx+eax],mm0        ;row 1
  849.     add            edx,ecx
  850.     movq        [ecx+eax*2],mm0        ;row 2
  851.     lea            ecx,[ecx+eax*2]
  852.     movq        [edx],mm0        ;row 3
  853.     movq        [ecx+eax*2],mm0        ;row 4
  854.     movq        [edx+eax*2],mm0        ;row 5
  855.     movq        [ecx+eax*4],mm0        ;row 6
  856.     movq        [edx+eax*4],mm0        ;row 7
  857.     ret
  858.  
  859.     align        16
  860. do_ac_sse2:
  861.     psubw        mm1,mm0
  862.     packuswb    mm0,mm0            ;mm0 = adder
  863.     packuswb    mm1,mm1            ;mm1 = subtractor
  864.  
  865.     mov        edx,8
  866. do_ac_sse2.loop:
  867.     movq        mm2,[ecx]
  868.     paddusb        mm2,mm0
  869.     psubusb        mm2,mm1
  870.     movq        [ecx],mm2
  871.     add            ecx,eax
  872.     dec            edx
  873.     jne            do_ac_sse2.loop
  874.     ret
  875.  
  876. do_dc_mjpeg:
  877.     movq2dq        xmm0, mm0
  878.     pshufd        xmm0, xmm0, 0
  879.     movdqa        [ecx],xmm0            ;row 0
  880.     lea            edx,[eax+eax*2]
  881.     movdqa        [ecx+eax],xmm0        ;row 1
  882.     add            edx,ecx
  883.     movdqa        [ecx+eax*2],xmm0    ;row 2
  884.     lea            ecx,[ecx+eax*2]
  885.     movdqa        [edx],xmm0            ;row 3
  886.     movdqa        [ecx+eax*2],xmm0    ;row 4
  887.     movdqa        [edx+eax*2],xmm0    ;row 5
  888.     movdqa        [ecx+eax*4],xmm0    ;row 6
  889.     movdqa        [edx+eax*4],xmm0    ;row 7
  890.     ret
  891.  
  892.     end
  893.