Mmxdeblo.c
上传用户:dangjiwu
上传日期:2013-07-19
资源大小:42019k
文件大小:11k
源码类别:

Symbian

开发平台:

Visual C++

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