Mmxdeblo.c
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:11k
源码类别:

Symbian

开发平台:

C/C++

  1. /* ***** BEGIN LICENSE BLOCK ***** 
  2.  * Version: RCSL 1.0/RPSL 1.0 
  3.  *  
  4.  * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. 
  5.  *      
  6.  * The contents of this file, and the files included with this file, are 
  7.  * subject to the current version of the RealNetworks Public Source License 
  8.  * Version 1.0 (the "RPSL") available at 
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed 
  10.  * the file under the RealNetworks Community Source License Version 1.0 
  11.  * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, 
  12.  * in which case the RCSL will apply. You may also obtain the license terms 
  13.  * directly from RealNetworks.  You may not use this file except in 
  14.  * compliance with the RPSL or, if you have a valid RCSL with RealNetworks 
  15.  * applicable to this file, the RCSL.  Please see the applicable RPSL or 
  16.  * RCSL for the rights, obligations and limitations governing use of the 
  17.  * contents of the file.  
  18.  *  
  19.  * This file is part of the Helix DNA Technology. RealNetworks is the 
  20.  * developer of the Original Code and owns the copyrights in the portions 
  21.  * it created. 
  22.  *  
  23.  * This file, and the files included with this file, is distributed and made 
  24.  * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  25.  * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  26.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS 
  27.  * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  28.  * 
  29.  * Technology Compatibility Kit Test Suite(s) Location: 
  30.  *    http://www.helixcommunity.org/content/tck 
  31.  * 
  32.  * Contributor(s): 
  33.  *  
  34.  * ***** END LICENSE BLOCK ***** */ 
  35. /*
  36. #ifdef __ICL
  37. #pragma message ("Attention: Intel Compiler")
  38. #else
  39. #pragma message ("Attention: Non Intel Compiler")
  40. #endif
  41. */
  42. //disable no emms warning
  43. #pragma warning(disable:4799)
  44. //#include <string.h>
  45. #include "dllindex.h"
  46. #include "h261defs.h"
  47. #include "h261func.h"
  48. #include "h263plus.h"
  49. #if defined(COMPILE_MMX)
  50. #if (_MSC_VER>=1100)
  51. // 4 * short  
  52. extern __int64  g_qp;
  53. extern __int64  g_max_qp; // max - pq
  54. extern __int64  g_max_2qp; // max - 2 * pq
  55. void ApplyHorizontalDeblockingFilterMMX( PIXEL * top, PIXEL * bottom, int offset)
  56. {
  57. //__m64 mm0, mm1, mm2, mm3, mm4, mm5, mm6;
  58.     PIXEL *next_to_top;
  59.     PIXEL *next_after_bottom;
  60.     top += 7*offset;
  61.     next_to_top = top - offset;
  62.     next_after_bottom = bottom + offset;
  63. //_m_empty();
  64. __asm {
  65. //unpack next_to_top -> short unsigned
  66. mov eax, next_to_top
  67. pxor mm7, mm7; // mm7 == 0
  68. movq mm0, [eax]
  69. mov eax, next_after_bottom;//--
  70. movq mm1, mm0
  71. punpcklbw mm0, mm7
  72. movq mm4, [eax];//--
  73. punpckhbw mm1, mm7
  74. movq mm5, mm4
  75. punpcklbw mm4, mm7
  76. mov ebx, bottom;//--
  77. //unpack next_after_bottom -> short unsigned
  78. punpckhbw mm5, mm7
  79. //
  80. //next_after_bottom - next_after_bottom
  81. psubw mm0, mm4
  82. psubw mm1, mm5
  83. //multiply mm0,mm1 by 3
  84. movq mm2, mm0
  85. movq mm3, mm1
  86. psllw mm2, 1
  87. psllw mm3, 1
  88. paddw mm0, mm2
  89. paddw mm1, mm3
  90. /* values * 8 */
  91. //unpack bottom -> short unsigned
  92. movq mm4, [ebx]
  93. mov ecx, top;//--
  94. movq mm5, mm4
  95. punpcklbw mm4, mm7
  96. movq mm2, [ecx];//--
  97. //
  98. punpckhbw mm5, mm7
  99. //
  100. //unpack top -> short unsigned
  101. movq mm3, mm2
  102. punpcklbw mm2, mm7
  103. punpckhbw mm3, mm7
  104. //
  105. //save top
  106. movq [ebx], mm2
  107. movq [ecx], mm3
  108. //bottom stays in mm4,mm5
  109. //top - bottom
  110. psubw mm2, mm4 
  111. psubw mm3, mm5 
  112. //multiply by 8
  113. psllw mm2, 3
  114. psllw mm3, 3
  115. //accumulate *3 - *8 
  116. psubw mm0, mm2
  117. psubw mm1, mm3
  118. //divide by 16
  119. psraw mm0, 4
  120. psraw mm1, 4
  121. /** DiffCutoff **/
  122. //cmp g_bBigDiffCutoffTable
  123. /** d = limit(-qp, 2*d, qp) - limit(-qp, d, qp) **/
  124. //d -> 2*d
  125. //single argument: d
  126. movq mm2, mm0
  127. movq mm3, mm1
  128. psllw mm0, 1;//--
  129. movq mm6, g_max_qp
  130. //
  131. //double argument: 2*d
  132. psllw mm1, 1
  133. /* limit to [-qp, +qp] */
  134. //add (max-qp) and saturate signed for upper limit
  135. paddsw mm0, mm6
  136. paddsw mm2, mm6
  137. movq mm7, g_max_2qp
  138. //
  139. paddsw mm1, mm6
  140. paddsw mm3, mm6
  141. //subtract (max-2qp) and saturate unsigned for lower limit
  142. psubusw mm0, mm7
  143. psubusw mm2, mm7
  144. movq mm6, g_qp
  145. //
  146. psubusw mm1, mm7
  147. psubusw mm3, mm7
  148. //correct: subtract (qp)
  149. psubw mm0, mm6
  150. psubw mm2, mm6
  151. psubw mm1, mm6
  152. psubw mm3, mm6
  153. //d = ... - ...
  154. psubw mm0, mm2
  155. psubw mm1, mm3
  156. //subtract from bottom
  157. //still in mm4,mm5
  158. psubw mm4, mm0
  159. psubw mm5, mm1
  160. paddw mm0, [ebx];//--
  161. //clip bottom
  162. packuswb mm4, mm5;//--
  163. //add to top
  164. paddw mm1, [ecx]
  165. movq [ebx], mm4;//--
  166. //clip top
  167. //convert word -> unsigned byte with saturation [0; 255]
  168. packuswb mm0, mm1
  169. //write back
  170. movq [ecx], mm0
  171. }
  172. }
  173. ////////////////////////////////////////////////////////////////////////////////
  174. void ApplyVerticalDeblockingFilterMMX( PIXEL * left, PIXEL * right, int offset)
  175. {
  176. //left[-1, 0, -1+offset, 0+offset, ..., -1+7*offset, 0+8*offset]
  177. //right[0, +1, 0+offset, +1+offset, ..., 0+7*offset, +1+8*offset]
  178. //get left[-1, -1+offset, -1+2*offset, -1+3*offset]
  179.     //PIXEL *next_to_top, *top, *bottom, *next_after_bottom;
  180. __int64 qw0, qw1;
  181. __int64 qw2, qw3;
  182. PIXEL *tleft_1, *t2left, *tright, *t2right;
  183. S32 ii;
  184.     left += 7;
  185. tleft_1 = left - 1;
  186. t2left = left;
  187. tright = right;
  188. t2right = right;
  189. //rearranging data into vectors of 8 bytes
  190. //arrange qw1 == h1h0 d1d0 f1f0 b1b0 and qw0 == g1g0 c1c0 e1e0 a1a0
  191. *((U32 *)&(((U16 *)&qw0)[0])) = *((U32 *)(tleft_1));//a
  192. tleft_1 += offset;
  193. *((U32 *)&(((U16 *)&qw1)[0])) = *((U32 *)(tleft_1));//b
  194. tleft_1 += offset;
  195. *((U32 *)&(((U16 *)&qw0)[2])) = *((U32 *)(tleft_1));//c
  196. tleft_1 += offset;
  197. *((U16 *)&(((U16 *)&qw1)[2])) = *((U16 *)(tleft_1));//d
  198. tleft_1 += offset;
  199. *((U16 *)&(((U16 *)&qw0)[1])) = *((U16 *)(tleft_1));//e
  200. tleft_1 += offset;
  201. *((U16 *)&(((U16 *)&qw1)[1])) = *((U16 *)(tleft_1));//f
  202. tleft_1 += offset;
  203. *((U16 *)&(((U16 *)&qw0)[3])) = *((U16 *)(tleft_1));//g
  204. tleft_1 += offset;
  205. *((U16 *)&(((U16 *)&qw1)[3])) = *((U16 *)(tleft_1));//h
  206. //arrange qw3 == h1h0 d1d0 f1f0 b1b0 and qw2 == g1g0 c1c0 e1e0 a1a0
  207. *((U32 *)&(((U16 *)&qw2)[0])) = *((U32 *)(tright));//a
  208. tright += offset;
  209. *((U32 *)&(((U16 *)&qw3)[0])) = *((U32 *)(tright));//b
  210. tright += offset;
  211. *((U32 *)&(((U16 *)&qw2)[2])) = *((U32 *)(tright));//c
  212. tright += offset;
  213. *((U16 *)&(((U16 *)&qw3)[2])) = *((U16 *)(tright));//d
  214. tright += offset;
  215. *((U16 *)&(((U16 *)&qw2)[1])) = *((U16 *)(tright));//e
  216. tright += offset;
  217. *((U16 *)&(((U16 *)&qw3)[1])) = *((U16 *)(tright));//f
  218. tright += offset;
  219. *((U16 *)&(((U16 *)&qw2)[3])) = *((U16 *)(tright));//g
  220. tright += offset;
  221. *((U16 *)&(((U16 *)&qw3)[3])) = *((U16 *)(tright));//h
  222. __asm {
  223. /////////////////////////////////////////////////
  224. movq mm0, [qw2]
  225. movq mm1, [qw3]
  226. movq mm4, mm0
  227. //mm1==h1h0d1d0f1f0b1b0 and mm0==g1g0c1c0e1e0a1a0
  228. // to 
  229. //mm4==h1g1h0g0d1c1d0c0 and mm0==f1e1f0e0b1a1b0a0
  230. punpcklbw mm0, mm1
  231. punpckhbw mm4, mm1
  232. //mm4==h1g1h0g0d1c1d0c0 and mm0==f1e1f0e0b1a1b0a0
  233. // to 
  234. //mm1==h1g1f1e1h0g0f0e0 and mm0==d1c1b1a1d0c0b0a0
  235. movq mm1, mm0
  236. punpcklwd mm0, mm4
  237. punpckhwd mm1, mm4
  238. //mm1==h1g1f1e1h0g0f0e0 and mm0==d1c1b1a1d0c0b0a0
  239. // to 
  240. //mm4==h1g1f1e1d1c1b1a1==next_after_bottom and mm0==h0g0f0e0d0c0b0a0==bottom
  241. movq mm4, mm0
  242. punpckldq mm0, mm1
  243. punpckhdq mm4, mm1
  244. movq [qw2], mm0;//save bottom
  245. /////////////////////////////////////////////////
  246. movq mm0, [qw0]
  247. movq mm1, [qw1]
  248. movq mm6, mm0
  249. //mm1==h1h0d1d0f1f0b1b0 and mm0==g1g0c1c0e1e0a1a0
  250. // to 
  251. //mm6==h1g1h0g0d1c1d0c0 and mm0==f1e1f0e0b1a1b0a0
  252. punpcklbw mm0, mm1
  253. punpckhbw mm6, mm1
  254. //mm6==h1g1h0g0d1c1d0c0 and mm0==f1e1f0e0b1a1b0a0
  255. // to 
  256. //mm1==h1g1f1e1h0g0f0e0 and mm0==d1c1b1a1d0c0b0a0
  257. movq mm1, mm0
  258. punpcklwd mm0, mm6
  259. punpckhwd mm1, mm6
  260. //mm1==h1g1f1e1h0g0f0e0 and mm0==d1c1b1a1d0c0b0a0
  261. // to 
  262. //mm6==h1g1f1e1d1c1b1a1==top and mm0==h0g0f0e0d0c0b0a0==next_to_top
  263. movq mm6, mm0
  264. punpckldq mm0, mm1
  265. punpckhdq mm6, mm1
  266. /////////////////////////////////////////////////
  267. //unpack next_to_top -> short unsigned -> mm0
  268. pxor mm7, mm7; // mm7 == 0
  269. //mov eax, next_after_bottom;//--
  270. movq mm1, mm0
  271. punpcklbw mm0, mm7
  272. //movq mm4, [eax];//--
  273. punpckhbw mm1, mm7
  274. movq mm5, mm4
  275. punpcklbw mm4, mm7
  276. //mov ebx, bottom;//--
  277. //unpack next_after_bottom -> short unsigned
  278. punpckhbw mm5, mm7
  279. //
  280. //next_after_bottom - next_after_bottom
  281. psubw mm0, mm4
  282. psubw mm1, mm5
  283. //multiply mm0,mm1 by 3
  284. movq mm2, mm0
  285. movq mm3, mm1
  286. psllw mm2, 1
  287. psllw mm3, 1
  288. paddw mm0, mm2
  289. paddw mm1, mm3
  290. /* values * 8 */
  291. //unpack bottom -> short unsigned
  292. movq mm4, [qw2]
  293. //movq mm4, [ebx]
  294. //mov ecx, top;//--
  295. movq mm5, mm4
  296. punpcklbw mm4, mm7
  297. //movq mm2, [ecx];//--
  298. //
  299. punpckhbw mm5, mm7
  300. //
  301. //unpack top -> short unsigned
  302. movq mm3, mm6
  303. punpcklbw mm6, mm7
  304. punpckhbw mm3, mm7
  305. //
  306. //save top
  307. movq [qw0], mm6
  308. movq [qw1], mm3
  309. //bottom stays in mm4,mm5
  310. //top - bottom
  311. psubw mm6, mm4 
  312. psubw mm3, mm5 
  313. //multiply by 8
  314. psllw mm6, 3
  315. psllw mm3, 3
  316. //accumulate *3 - *8 
  317. psubw mm0, mm6
  318. psubw mm1, mm3
  319. //divide by 16
  320. psraw mm0, 4
  321. psraw mm1, 4
  322. /** DiffCutoff **/
  323. //cmp g_bBigDiffCutoffTable
  324. /** d = limit(-qp, 2*d, qp) - limit(-qp, d, qp) **/
  325. //d -> 2*d
  326. //single argument: d
  327. movq mm2, mm0
  328. movq mm3, mm1
  329. psllw mm0, 1;//--
  330. movq mm6, g_max_qp
  331. //
  332. //double argument: 2*d
  333. psllw mm1, 1
  334. /* limit to [-qp, +qp] */
  335. //add (max-qp) and saturate signed for upper limit
  336. paddsw mm0, mm6
  337. paddsw mm2, mm6
  338. movq mm7, g_max_2qp
  339. //
  340. paddsw mm1, mm6
  341. paddsw mm3, mm6
  342. //subtract (max-2qp) and saturate unsigned for lower limit
  343. psubusw mm0, mm7
  344. psubusw mm2, mm7
  345. movq mm6, g_qp
  346. //
  347. psubusw mm1, mm7
  348. psubusw mm3, mm7
  349. //correct: subtract (qp)
  350. psubw mm0, mm6
  351. psubw mm2, mm6
  352. psubw mm1, mm6
  353. psubw mm3, mm6
  354. //d = ... - ...
  355. psubw mm0, mm2
  356. psubw mm1, mm3
  357. //subtract from bottom
  358. //still in mm4,mm5
  359. psubw mm4, mm0
  360. psubw mm5, mm1
  361. paddw mm0, [qw0];//--
  362. //clip bottom
  363. packuswb mm4, mm5;//--
  364. //add to top
  365. paddw mm1, [qw1]
  366. //write back bottom
  367. movq [qw0], mm4;//--
  368. //clip top
  369. //convert word -> unsigned byte with saturation [0; 255]
  370. packuswb mm0, mm1
  371. //write back top
  372. movq [qw1], mm0
  373. }
  374. //rearrange data back
  375. for(ii=0; ii<8; ii+=2, t2left+=offset, t2right+=offset) {
  376. *t2right = ((U8 *)&qw0)[ii];
  377. *t2left = ((U8 *)&qw1)[ii];
  378. //unroll loop
  379. t2left+=offset;
  380. t2right+=offset;
  381. *t2right = ((U8 *)&qw0)[ii+1];
  382. *t2left = ((U8 *)&qw1)[ii+1];
  383. }
  384. }
  385. #endif
  386. #endif
  387. //default no emms warning
  388. #pragma warning(default:4799)