idct_sse2.cpp
上传用户:xjjlds
上传日期:2015-12-05
资源大小:22823k
文件大小:17k
源码类别:

多媒体编程

开发平台:

Visual C++

  1. #include "stdafx.h"
  2. #include "libmpeg2.h"
  3. // Intel's SSE2 implementation of iDCT
  4. // AP-945
  5. // http://cache-www.intel.com/cd/00/00/01/76/17680_w_idct.pdf
  6. #define BITS_INV_ACC 4 // 4 or 5 for IEEE
  7. #define SHIFT_INV_ROW 16 - BITS_INV_ACC
  8. #define SHIFT_INV_COL 1 + BITS_INV_ACC
  9. const short RND_INV_ROW = 1024 * (6 - BITS_INV_ACC); //1 << (SHIFT_INV_ROW-1)
  10. const short RND_INV_COL = 16 * (BITS_INV_ACC - 3); // 1 << (SHIFT_INV_COL-1)
  11. const short RND_INV_CORR = RND_INV_COL - 1; // correction -1.0 and round
  12. __declspec(align(16)) short M128_one_corr[8] = {1,1,1,1,1,1,1,1};
  13. __declspec(align(16)) short M128_round_inv_row[8] = {RND_INV_ROW, 0, RND_INV_ROW, 0, RND_INV_ROW, 0, RND_INV_ROW, 0};
  14. __declspec(align(16)) short M128_round_inv_col[8] = {RND_INV_COL, RND_INV_COL, RND_INV_COL, RND_INV_COL, RND_INV_COL, RND_INV_COL, RND_INV_COL, RND_INV_COL};
  15. __declspec(align(16)) short M128_round_inv_corr[8]= {RND_INV_CORR, RND_INV_CORR, RND_INV_CORR, RND_INV_CORR, RND_INV_CORR, RND_INV_CORR, RND_INV_CORR, RND_INV_CORR};
  16. __declspec(align(16)) short M128_tg_1_16[8] = {13036, 13036, 13036, 13036, 13036, 13036, 13036, 13036}; // tg * (2<<16) + 0.5
  17. __declspec(align(16)) short M128_tg_2_16[8] = {27146, 27146, 27146, 27146, 27146, 27146, 27146, 27146}; // tg * (2<<16) + 0.5
  18. __declspec(align(16)) short M128_tg_3_16[8] = {-21746, -21746, -21746, -21746, -21746, -21746, -21746, -21746}; // tg * (2<<16) + 0.5
  19. __declspec(align(16)) short M128_cos_4_16[8] = {-19195, -19195, -19195, -19195, -19195, -19195, -19195, -19195};// cos * (2<<16) + 0.5
  20. //-----------------------------------------------------------------------------
  21. // Table for rows 0,4 - constants are multiplied on cos_4_16
  22. //movq -> w13 w12 w09 w08 w05 w04 w01 w00
  23. // w15 w14 w11 w10 w07 w06 w03 w02
  24. // w29 w28 w25 w24 w21 w20 w17 w16
  25. // w31 w30 w27 w26 w23 w22 w19 w18
  26. __declspec(align(16)) short M128_tab_i_04[] = 
  27. {
  28. 16384, 21407, 16384, 8867, //movq -> w05 w04 w01 w00
  29. 16384, -8867, 16384, -21407, // w13 w12 w09 w08
  30. 16384, 8867, -16384, -21407, // w07 w06 w03 w02
  31. -16384, 21407, 16384, -8867, // w15 w14 w11 w10
  32. 22725, 19266, 19266, -4520, // w21 w20 w17 w16
  33. 12873, -22725, 4520, -12873, // w29 w28 w25 w24
  34. 12873, 4520, -22725, -12873, // w23 w22 w19 w18
  35. 4520, 19266, 19266, -22725  // w31 w30 w27 w26
  36. };
  37. // Table for rows 1,7 - constants are multiplied on cos_1_16
  38. __declspec(align(16)) short M128_tab_i_17[] =
  39. {
  40. 22725, 29692, 22725, 12299, //movq -> w05 w04 w01 w00
  41. 22725, -12299, 22725, -29692, // w13 w12 w09 w08
  42. 22725, 12299, -22725, -29692, // w07 w06 w03 w02
  43. -22725, 29692, 22725, -12299, // w15 w14 w11 w10
  44. 31521, 26722, 26722, -6270, // w21 w20 w17 w16
  45. 17855, -31521, 6270, -17855, // w29 w28 w25 w24
  46. 17855, 6270, -31521, -17855, // w23 w22 w19 w18
  47. 6270, 26722, 26722, -31521 // w31 w30 w27 w26
  48. };
  49. // Table for rows 2,6 - constants are multiplied on cos_2_16
  50. __declspec(align(16)) short M128_tab_i_26[] =
  51. {
  52. 21407, 27969, 21407, 11585, //movq -> w05 w04 w01 w00
  53. 21407, -11585, 21407, -27969, // w13 w12 w09 w08
  54. 21407, 11585, -21407, -27969, // w07 w06 w03 w02
  55. -21407, 27969, 21407, -11585, // w15 w14 w11 w10
  56. 29692, 25172, 25172, -5906, // w21 w20 w17 w16
  57. 16819, -29692, 5906, -16819, // w29 w28 w25 w24
  58. 16819, 5906, -29692, -16819, // w23 w22 w19 w18
  59. 5906, 25172, 25172, -29692 // w31 w30 w27 w26
  60. };
  61. // Table for rows 3,5 - constants are multiplied on cos_3_16
  62. __declspec(align(16)) short M128_tab_i_35[] = 
  63. {
  64. 19266, 25172, 19266, 10426, //movq -> w05 w04 w01 w00
  65. 19266, -10426, 19266, -25172, // w13 w12 w09 w08
  66. 19266, 10426, -19266, -25172, // w07 w06 w03 w02
  67. -19266, 25172, 19266, -10426, // w15 w14 w11 w10
  68. 26722, 22654, 22654, -5315, // w21 w20 w17 w16
  69. 15137, -26722, 5315, -15137, // w29 w28 w25 w24
  70. 15137, 5315, -26722, -15137, // w23 w22 w19 w18
  71. 5315, 22654, 22654, -26722 // w31 w30 w27 w26
  72. };
  73. //-----------------------------------------------------------------------------
  74. /*
  75. ;=============================================================================
  76. ;=============================================================================
  77. ;=============================================================================
  78. ;
  79. ; Inverse DCT
  80. ;
  81. ;-----------------------------------------------------------------------------
  82. ;
  83. ; This implementation calculates iDCT-2D by a row-column method.
  84. ; On the first stage the iDCT-1D is calculated for each row with use
  85. ; direct algorithm, on the second stage the calculation is executed
  86. ; at once for four columns with use of scaled iDCT-1D algorithm.
  87. ; Base R&Y algorithm for iDCT-1D is modified for second stage.
  88. ;
  89. ;=============================================================================
  90. ;-----------------------------------------------------------------------------
  91. ;
  92. ; The first stage - inverse DCTs of rows
  93. ;
  94. ;-----------------------------------------------------------------------------
  95. ; The 8-point inverse DCT direct algorithm
  96. ;-----------------------------------------------------------------------------
  97. ;
  98. ; static const short w[32] = {
  99. ; FIX(cos_4_16), FIX(cos_2_16), FIX(cos_4_16), FIX(cos_6_16),
  100. ; FIX(cos_4_16), FIX(cos_6_16), -FIX(cos_4_16), -FIX(cos_2_16),
  101. ; FIX(cos_4_16), -FIX(cos_6_16), -FIX(cos_4_16), FIX(cos_2_16),
  102. ; FIX(cos_4_16), -FIX(cos_2_16), FIX(cos_4_16), -FIX(cos_6_16),
  103. ; FIX(cos_1_16), FIX(cos_3_16), FIX(cos_5_16), FIX(cos_7_16),
  104. ; FIX(cos_3_16), -FIX(cos_7_16), -FIX(cos_1_16), -FIX(cos_5_16),
  105. ; FIX(cos_5_16), -FIX(cos_1_16), FIX(cos_7_16), FIX(cos_3_16),
  106. ; FIX(cos_7_16), -FIX(cos_5_16), FIX(cos_3_16), -FIX(cos_1_16) };
  107. ;
  108. ; #define DCT_8_INV_ROW(x, y)
  109. ; {
  110. ; int a0, a1, a2, a3, b0, b1, b2, b3;
  111. ;
  112. ; a0 = x[0] * w[ 0] + x[2] * w[ 1] + x[4] * w[ 2] + x[6] * w[ 3];
  113. ; a1 = x[0] * w[ 4] + x[2] * w[ 5] + x[4] * w[ 6] + x[6] * w[ 7];
  114. ; a2 = x[0] * w[ 8] + x[2] * w[ 9] + x[4] * w[10] + x[6] * w[11];
  115. ; a3 = x[0] * w[12] + x[2] * w[13] + x[4] * w[14] + x[6] * w[15];
  116. ; b0 = x[1] * w[16] + x[3] * w[17] + x[5] * w[18] + x[7] * w[19];
  117. ; b1 = x[1] * w[20] + x[3] * w[21] + x[5] * w[22] + x[7] * w[23];
  118. ; b2 = x[1] * w[24] + x[3] * w[25] + x[5] * w[26] + x[7] * w[27];
  119. ; b3 = x[1] * w[28] + x[3] * w[29] + x[5] * w[30] + x[7] * w[31];
  120. ;
  121. ; y[0] = SHIFT_ROUND ( a0 + b0 );
  122. ; y[1] = SHIFT_ROUND ( a1 + b1 );
  123. ; y[2] = SHIFT_ROUND ( a2 + b2 );
  124. ; y[3] = SHIFT_ROUND ( a3 + b3 );
  125. ; y[4] = SHIFT_ROUND ( a3 - b3 );
  126. ; y[5] = SHIFT_ROUND ( a2 - b2 );
  127. ; y[6] = SHIFT_ROUND ( a1 - b1 );
  128. ; y[7] = SHIFT_ROUND ( a0 - b0 );
  129. ; }
  130. ;
  131. ;-----------------------------------------------------------------------------
  132. ;
  133. ; In this implementation the outputs of the iDCT-1D are multiplied
  134. ; for rows 0,4 - on cos_4_16,
  135. ; for rows 1,7 - on cos_1_16,
  136. ; for rows 2,6 - on cos_2_16,
  137. ; for rows 3,5 - on cos_3_16
  138. ; and are shifted to the left for rise of accuracy
  139. ;
  140. ; For used constants
  141. ; FIX(float_const) = (short) (float_const * (1<<15) + 0.5)
  142. ;
  143. ;-----------------------------------------------------------------------------
  144. ;-----------------------------------------------------------------------------
  145. ;
  146. ; The second stage - inverse DCTs of columns
  147. ;
  148. ; The inputs are multiplied
  149. ; for rows 0,4 - on cos_4_16,
  150. ; for rows 1,7 - on cos_1_16,
  151. ; for rows 2,6 - on cos_2_16,
  152. ; for rows 3,5 - on cos_3_16
  153. ; and are shifted to the left for rise of accuracy
  154. ;
  155. ;-----------------------------------------------------------------------------
  156. ;
  157. ; The 8-point scaled inverse DCT algorithm (26a8m)
  158. ;
  159. ;-----------------------------------------------------------------------------
  160. ;
  161. ; #define DCT_8_INV_COL(x, y)
  162. ; {
  163. ; short t0, t1, t2, t3, t4, t5, t6, t7;
  164. ; short tp03, tm03, tp12, tm12, tp65, tm65;
  165. ; short tp465, tm465, tp765, tm765;
  166. ;
  167. ; tp765 = x[1] + x[7] * tg_1_16;
  168. ; tp465 = x[1] * tg_1_16 - x[7];
  169. ; tm765 = x[5] * tg_3_16 + x[3];
  170. ; tm465 = x[5] - x[3] * tg_3_16;
  171. ;
  172. ; t7 = tp765 + tm765;
  173. ; tp65 = tp765 - tm765;
  174. ; t4 = tp465 + tm465;
  175. ; tm65 = tp465 - tm465;
  176. ;
  177. ; t6 = ( tp65 + tm65 ) * cos_4_16;
  178. ; t5 = ( tp65 - tm65 ) * cos_4_16;
  179. ;
  180. ; tp03 = x[0] + x[4];
  181. ; tp12 = x[0] - x[4];
  182. ;
  183. ; tm03 = x[2] + x[6] * tg_2_16;
  184. ; tm12 = x[2] * tg_2_16 - x[6];
  185. ;
  186. ; t0 = tp03 + tm03;
  187. ; t3 = tp03 - tm03;
  188. ; t1 = tp12 + tm12;
  189. ; t2 = tp12 - tm12;
  190. ;
  191. ; y[0] = SHIFT_ROUND ( t0 + t7 );
  192. ; y[7] = SHIFT_ROUND ( t0 - t7 );
  193. ; y[1] = SHIFT_ROUND ( t1 + t6 );
  194. ; y[6] = SHIFT_ROUND ( t1 - t6 );
  195. ; y[2] = SHIFT_ROUND ( t2 + t5 );
  196. ; y[5] = SHIFT_ROUND ( t2 - t5 );
  197. ; y[3] = SHIFT_ROUND ( t3 + t4 );
  198. ; y[4] = SHIFT_ROUND ( t3 - t4 );
  199. ; }
  200. ;
  201. ;-----------------------------------------------------------------------------
  202. */
  203. //xmm7 = round_inv_row
  204. #define DCT_8_INV_ROW __asm{ 
  205. __asm pshuflw xmm0, xmm0, 0xD8 
  206. __asm pshufd xmm1, xmm0, 0 
  207. __asm pmaddwd xmm1, [esi] 
  208. __asm pshufd xmm3, xmm0, 0x55 
  209. __asm pshufhw xmm0, xmm0, 0xD8 
  210. __asm pmaddwd xmm3, [esi+32] 
  211. __asm pshufd xmm2, xmm0, 0xAA 
  212. __asm pshufd xmm0, xmm0, 0xFF 
  213. __asm pmaddwd xmm2, [esi+16] 
  214. __asm pshufhw xmm4, xmm4, 0xD8 
  215. __asm paddd xmm1, M128_round_inv_row 
  216. __asm pshuflw xmm4, xmm4, 0xD8 
  217. __asm pmaddwd xmm0, [esi+48] 
  218. __asm pshufd xmm5, xmm4, 0 
  219. __asm pshufd xmm6, xmm4, 0xAA 
  220. __asm pmaddwd xmm5, [ecx] 
  221. __asm paddd xmm1, xmm2 
  222. __asm movdqa xmm2, xmm1 
  223. __asm pshufd xmm7, xmm4, 0x55 
  224. __asm pmaddwd xmm6, [ecx+16] 
  225. __asm paddd xmm0, xmm3 
  226. __asm pshufd xmm4, xmm4, 0xFF 
  227. __asm psubd xmm2, xmm0 
  228. __asm pmaddwd xmm7, [ecx+32] 
  229. __asm paddd xmm0, xmm1 
  230. __asm psrad xmm2, 12 
  231. __asm paddd xmm5, M128_round_inv_row 
  232. __asm pmaddwd xmm4, [ecx+48] 
  233. __asm paddd xmm5, xmm6 
  234. __asm movdqa xmm6, xmm5 
  235. __asm psrad xmm0, 12 
  236. __asm pshufd xmm2, xmm2, 0x1B 
  237. __asm packssdw xmm0, xmm2 
  238. __asm paddd xmm4, xmm7 
  239. __asm psubd xmm6, xmm4 
  240. __asm paddd xmm4, xmm5 
  241. __asm psrad xmm6, 12 
  242. __asm psrad xmm4, 12 
  243. __asm pshufd xmm6, xmm6, 0x1B 
  244. __asm packssdw xmm4, xmm6 
  245. }
  246. #define DCT_8_INV_COL_8 __asm{ 
  247. __asm movdqa xmm1, XMMWORD PTR M128_tg_3_16 
  248. __asm movdqa xmm2, xmm0 
  249. __asm movdqa xmm3, XMMWORD PTR [edx+3*16] 
  250. __asm pmulhw xmm0, xmm1 
  251. __asm pmulhw xmm1, xmm3 
  252. __asm movdqa xmm5, XMMWORD PTR M128_tg_1_16 
  253. __asm movdqa xmm6, xmm4 
  254. __asm pmulhw xmm4, xmm5 
  255. __asm paddsw xmm0, xmm2 
  256. __asm pmulhw xmm5, [edx+1*16] 
  257. __asm paddsw xmm1, xmm3 
  258. __asm movdqa xmm7, XMMWORD PTR [edx+6*16] 
  259. __asm paddsw xmm0, xmm3 
  260. __asm movdqa xmm3, XMMWORD PTR M128_tg_2_16 
  261. __asm psubsw xmm2, xmm1 
  262. __asm pmulhw xmm7, xmm3 
  263. __asm movdqa xmm1, xmm0 
  264. __asm pmulhw xmm3, [edx+2*16] 
  265. __asm psubsw xmm5, xmm6 
  266. __asm paddsw xmm4, [edx+1*16] 
  267. __asm paddsw xmm0, xmm4 
  268. __asm paddsw xmm0, XMMWORD PTR M128_one_corr 
  269. __asm psubsw xmm4, xmm1 
  270. __asm movdqa xmm6, xmm5 
  271. __asm psubsw xmm5, xmm2 
  272. __asm paddsw xmm5, XMMWORD PTR M128_one_corr 
  273. __asm paddsw xmm6, xmm2 
  274. __asm movdqa [edx+7*16], xmm0 
  275. __asm movdqa xmm1, xmm4 
  276. __asm movdqa xmm0, XMMWORD PTR M128_cos_4_16 
  277. __asm paddsw xmm4, xmm5 
  278. __asm movdqa xmm2, XMMWORD PTR M128_cos_4_16 
  279. __asm pmulhw xmm2, xmm4 
  280. __asm movdqa [edx+3*16], xmm6 
  281. __asm psubsw xmm1, xmm5 
  282. __asm paddsw xmm7, [edx+2*16] 
  283. __asm psubsw xmm3, [edx+6*16] 
  284. __asm movdqa xmm6, [edx] 
  285. __asm pmulhw xmm0, xmm1 
  286. __asm movdqa xmm5, [edx+4*16] 
  287. __asm paddsw xmm5, xmm6 
  288. __asm psubsw xmm6, [edx+4*16] 
  289. __asm paddsw xmm4, xmm2 
  290. __asm por xmm4, XMMWORD PTR M128_one_corr 
  291. __asm paddsw xmm0, xmm1 
  292. __asm por xmm0, XMMWORD PTR M128_one_corr 
  293. __asm movdqa xmm2, xmm5 
  294. __asm paddsw xmm5, xmm7 
  295. __asm movdqa xmm1, xmm6 
  296. __asm paddsw xmm5, XMMWORD PTR M128_round_inv_col 
  297. __asm psubsw xmm2, xmm7 
  298. __asm movdqa xmm7, [edx+7*16] 
  299. __asm paddsw xmm6, xmm3 
  300. __asm paddsw xmm6, XMMWORD PTR M128_round_inv_col 
  301. __asm paddsw xmm7, xmm5 
  302. __asm psraw xmm7, SHIFT_INV_COL 
  303. __asm psubsw xmm1, xmm3 
  304. __asm paddsw xmm1, XMMWORD PTR M128_round_inv_corr 
  305. __asm movdqa xmm3, xmm6 
  306. __asm paddsw xmm2, XMMWORD PTR M128_round_inv_corr 
  307. __asm paddsw xmm6, xmm4 
  308. __asm movdqa [edx], xmm7 
  309. __asm psraw xmm6, SHIFT_INV_COL 
  310. __asm movdqa xmm7, xmm1 
  311. __asm paddsw xmm1, xmm0 
  312. __asm movdqa [edx+1*16], xmm6 
  313. __asm psraw xmm1, SHIFT_INV_COL 
  314. __asm movdqa xmm6, [edx+3*16] 
  315. __asm psubsw xmm7, xmm0 
  316. __asm psraw xmm7, SHIFT_INV_COL 
  317. __asm movdqa [edx+2*16], xmm1 
  318. __asm psubsw xmm5, [edx+7*16] 
  319. __asm psraw xmm5, SHIFT_INV_COL 
  320. __asm movdqa [edx+7*16], xmm5 
  321. __asm psubsw xmm3, xmm4 
  322. __asm paddsw xmm6, xmm2 
  323. __asm psubsw xmm2, [edx+3*16] 
  324. __asm psraw xmm6, SHIFT_INV_COL 
  325. __asm psraw xmm2, SHIFT_INV_COL 
  326. __asm movdqa [edx+3*16], xmm6 
  327. __asm psraw xmm3, SHIFT_INV_COL 
  328. __asm movdqa [edx+4*16], xmm2 
  329. __asm movdqa [edx+5*16], xmm7 
  330. __asm movdqa [edx+6*16], xmm3 
  331. }
  332. //assumes src and destination are aligned on a 16-byte boundary
  333. static void idct_M128ASM(short* src)
  334. {
  335. ASSERT(((DWORD)src & 0xf) == 0); //aligned on 16-byte boundary
  336. __asm mov edx, src
  337. __asm movdqa xmm0, XMMWORD PTR[edx] //row 1
  338. __asm lea esi, M128_tab_i_04
  339. __asm movdqa xmm4, XMMWORD PTR[edx+16*2] //row 3
  340. __asm lea ecx, M128_tab_i_26
  341. DCT_8_INV_ROW; //Row 1, tab_i_04 and Row 3, tab_i_26
  342. __asm movdqa XMMWORD PTR[edx], xmm0
  343. __asm movdqa XMMWORD PTR[edx+16*2], xmm4
  344. __asm movdqa xmm0, XMMWORD PTR[edx+16*4] //row 5
  345. //__asm lea esi, M128_tab_i_04
  346. __asm movdqa xmm4, XMMWORD PTR[edx+16*6] //row 7
  347. //__asm lea ecx, M128_tab_i_26
  348. DCT_8_INV_ROW; //Row 5, tab_i_04 and Row 7, tab_i_26
  349. __asm movdqa XMMWORD PTR[edx+16*4], xmm0
  350. __asm movdqa XMMWORD PTR[edx+16*6], xmm4
  351. __asm movdqa xmm0, XMMWORD PTR[edx+16*3] //row 4
  352. __asm lea esi, M128_tab_i_35
  353. __asm movdqa xmm4, XMMWORD PTR[edx+16*1] //row 2
  354. __asm lea ecx, M128_tab_i_17
  355. DCT_8_INV_ROW; //Row 4, tab_i_35 and Row 2, tab_i_17
  356. __asm movdqa XMMWORD PTR[edx+16*3], xmm0
  357. __asm movdqa XMMWORD PTR[edx+16*1], xmm4
  358. __asm movdqa xmm0, XMMWORD PTR[edx+16*5] //row 6
  359. //__asm lea esi, M128_tab_i_35
  360. __asm movdqa xmm4, XMMWORD PTR[edx+16*7] //row 8
  361. //__asm lea ecx, M128_tab_i_17
  362. DCT_8_INV_ROW; //Row 6, tab_i_35 and Row 8, tab_i_17
  363. //__asm movdqa XMMWORD PTR[edx+80], xmm0
  364. //__asm movdqa xmm0, XMMWORD PTR [edx+80] /* 0 /* x5 */
  365. //__asm movdqa XMMWORD PTR[edx+16*7], xmm4
  366. //__asm movdqa xmm4, XMMWORD PTR [edx+7*16]/* 4 ; x7 */
  367. DCT_8_INV_COL_8
  368. // __asm emms
  369. }
  370. /////////////
  371. #define CLIP(x) (x < 0 ? 0 : x > 255 ? 255 : x)
  372. void mpeg2_idct_copy_sse2(int16_t* block, uint8_t* dest, const int stride)
  373. {
  374. idct_M128ASM(block);
  375. /*
  376.     for(int i = 0; i < 8; i++)
  377. {
  378. dest[0] = CLIP(block[0]);
  379. dest[1] = CLIP(block[1]);
  380. dest[2] = CLIP(block[2]);
  381. dest[3] = CLIP(block[3]);
  382. dest[4] = CLIP(block[4]);
  383. dest[5] = CLIP(block[5]);
  384. dest[6] = CLIP(block[6]);
  385. dest[7] = CLIP(block[7]);
  386. memset(block, 0, sizeof(short)*8);
  387. dest += stride;
  388. block += 8;
  389.     }
  390. */
  391. __asm
  392. {
  393. mov esi, block
  394. mov edi, dest
  395. mov edx, stride
  396. lea ecx, [edx+edx]
  397. movdqa xmm0, [esi+16*0]
  398. movdqa xmm1, [esi+16*1]
  399. movdqa xmm2, [esi+16*2]
  400. movdqa xmm3, [esi+16*3]
  401. movdqa xmm4, [esi+16*4]
  402. movdqa xmm5, [esi+16*5]
  403. movdqa xmm6, [esi+16*6]
  404. movdqa xmm7, [esi+16*7]
  405. packuswb xmm0, xmm1
  406. packuswb xmm2, xmm3
  407. packuswb xmm4, xmm5
  408. packuswb xmm6, xmm7
  409. movlps [edi], xmm0
  410. movhps [edi+edx], xmm0
  411. add edi, ecx
  412. movlps [edi], xmm2
  413. movhps [edi+edx], xmm2
  414. add edi, ecx
  415. movlps [edi], xmm4
  416. movhps [edi+edx], xmm4
  417. add edi, ecx
  418. movlps [edi], xmm6
  419. movhps [edi+edx], xmm6
  420. xorps xmm7, xmm7
  421. movdqa [esi+16*0], xmm7
  422. movdqa [esi+16*1], xmm7
  423. movdqa [esi+16*2], xmm7
  424. movdqa [esi+16*3], xmm7
  425. movdqa [esi+16*4], xmm7
  426. movdqa [esi+16*5], xmm7
  427. movdqa [esi+16*6], xmm7
  428. movdqa [esi+16*7], xmm7
  429. }
  430. }
  431. void mpeg2_idct_add_sse2(const int last, int16_t* block, uint8_t* dest, const int stride)
  432. {
  433. idct_M128ASM(block);
  434. /*
  435.     for(int i = 0; i < 8; i++)
  436. {
  437. dest[0] = CLIP(block[0] + dest[0]);
  438. dest[1] = CLIP(block[1] + dest[1]);
  439. dest[2] = CLIP(block[2] + dest[2]);
  440. dest[3] = CLIP(block[3] + dest[3]);
  441. dest[4] = CLIP(block[4] + dest[4]);
  442. dest[5] = CLIP(block[5] + dest[5]);
  443. dest[6] = CLIP(block[6] + dest[6]);
  444. dest[7] = CLIP(block[7] + dest[7]);
  445. memset(block, 0, sizeof(short)*8);
  446. dest += stride;
  447. block += 8;
  448.     }
  449. */
  450. __asm
  451. {
  452. mov esi, block
  453. mov edi, dest
  454. mov ecx, 4
  455. mov edx, stride
  456. xorps xmm7, xmm7
  457. mpeg2_idct_add_sse2_loop:
  458. movdqa xmm0, [esi]
  459. movdqa xmm1, [esi+16]
  460. movlps xmm2, [edi]
  461. punpcklbw xmm2, xmm7
  462. paddsw xmm0, xmm2
  463. movlps xmm2, [edi+edx]
  464. punpcklbw xmm2, xmm7
  465. paddsw xmm1, xmm2
  466. packuswb xmm0, xmm1
  467. movdqa [esi], xmm7
  468. movdqa [esi+16], xmm7
  469. movlps [edi], xmm0
  470. movhps [edi+edx], xmm0
  471. lea esi, [esi+16*2]
  472. lea edi, [edi+edx*2]
  473. dec ecx
  474. jnz mpeg2_idct_add_sse2_loop
  475. }
  476. }
  477. void mpeg2_idct_init_sse2()
  478. {
  479. }