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

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. #include "dllindex.h"
  36. #include "h261defs.h"
  37. #include "h261func.h"
  38. extern int  g_saveMbHor;      // Hold on to size of Mb array (used by distUmv and
  39. extern int  g_saveMbVert;     //  TryInter4V and its subroutines)
  40. extern int  g_saveUmvMode;    // Hold on to unrestrictedMv (used by RefineMotionVector)
  41. extern int  g_savePointOutside;   // Hold on to pointOutside (used by rmvDist)
  42. extern int  g_distPixels;     // Number of pixels used in squared error computations
  43. static const __int64 const_0x00ff00ff00ff00ff = 0x00ff00ff00ff00ff; //0 2 4 6
  44. static const __int64 const_0x000000ff000000ff = 0x000000ff000000ff;//0 4
  45. static const __int64 const_0x00ff000000ff0000 = 0x00ff000000ff0000;//2 6
  46. static const __int64 const_0x00ff00ff000000ff = 0x00ff00ff000000ff; //0  4 6 == shift 4 8 10
  47. static const __int64 const_0x0001000100010001 = 0x0001000100010001;
  48. static const __int64 const_0x0002000200020002 = 0x0002000200020002;
  49. /*-- mcomp.c -----------------------------------------------------------------------------------*/
  50. static void mc16pelsNoInterpolMMX( PIXEL *inpix, PIXEL *outpix, int hdim, int vSize )
  51. {
  52. __asm {
  53. mov ecx, vSize
  54. mov ebx, hdim
  55. mov esi, inpix
  56. neg ebx
  57. mov edi, outpix
  58. mc16pelsNoInterpolMMX_loop:
  59. add ebx, hdim
  60. dec ecx
  61. movq mm0, [esi + ebx]
  62. movq mm1, [esi + ebx + 8]
  63. movq [edi + ebx], mm0
  64. movq [edi + ebx + 8], mm1
  65. jg mc16pelsNoInterpolMMX_loop
  66. emms
  67.     }
  68. /*
  69.     union { // Copy words to speed up routine
  70.         PIXEL   *pix;
  71.         U32     *word;
  72.     } pIn, pOut;
  73.     pIn.pix = inpix;
  74.     pOut.pix = outpix;
  75.     while (vSize > 0) {
  76.         *(pOut.word + 0) = *(pIn.word + 0);
  77.         *(pOut.word + 1) = *(pIn.word + 1);
  78.         *(pOut.word + 2) = *(pIn.word + 2);
  79.         *(pOut.word + 3) = *(pIn.word + 3);
  80.         pIn.pix += hdim;
  81.         pOut.pix += hdim;
  82.         --vSize;
  83.     }
  84. */
  85. }
  86. static void mc8pelsNoInterpolMMX( PIXEL *inpix, PIXEL *outpix, int hdim, int vSize )
  87. {
  88. __asm {
  89. mov ecx, vSize
  90. mov ebx, hdim
  91. mov esi, inpix
  92. neg ebx
  93. mov edi, outpix
  94. mc8pelsNoInterpolMMX_loop:
  95. add ebx, hdim
  96. dec ecx
  97. movq mm0, [esi + ebx]
  98. movq [edi + ebx], mm0
  99. jg mc8pelsNoInterpolMMX_loop
  100. emms
  101.     }
  102. /*
  103. union { // Copy words to speed up routine
  104.         PIXEL   *pix;
  105.         U32     *word;
  106.     } pIn, pOut;
  107. pIn.pix = inpix;
  108.     pOut.pix = outpix;
  109.     while (vSize > 0) {
  110.         *(pOut.word + 0) = *(pIn.word + 0);
  111.         *(pOut.word + 1) = *(pIn.word + 1);
  112.         pIn.pix += hdim;
  113.         pOut.pix += hdim;
  114.         --vSize;
  115.     }
  116. */
  117. }
  118. static void mc4pelsNoInterpolMMX( PIXEL *inpix, PIXEL *outpix, int hdim, int vSize )
  119. {
  120. int rowcount = 0;
  121.     while (vSize > 0) {
  122.          *((U32 *)(outpix + rowcount)) = *((U32 *)(inpix + rowcount));
  123. rowcount +=  hdim;
  124. vSize--;
  125.     }
  126. }
  127. static void mc16pelsHorInterpolMMX( PIXEL const *inpix, PIXEL *outpix, int hdim, int vSize )
  128. {
  129. __asm {
  130. xor ebx, ebx
  131. mov ecx, vSize
  132. mov esi, inpix
  133. mov edi, outpix
  134. pxor mm0, mm0 ;// mm0 = 0
  135. movq mm7, const_0x0001000100010001
  136. mc16pelsHorInterpolMMX_loop:
  137. movq mm1, [esi + ebx]
  138. movq mm4, [esi + ebx +8]
  139. movq mm3, mm1 ;//save
  140. movq mm5, mm4 ;//save
  141. psrlq mm3, 8 ;//shift one byte
  142. movq mm2, mm1
  143. psllq mm4, 56 ;//shift 7 bytes, LSB is in top pos of mm4
  144. punpcklbw mm1, mm0 ;//expand lower 4 pix pos: + 0
  145. pxor mm3, mm4 ;//equivalent to read from +1
  146. punpckhbw mm2, mm0 ;//expand higher 4 pix pos: + 4
  147. movq mm4, mm3
  148. punpcklbw mm3, mm0 ;//expand lower 4 pix pos: + 1
  149. paddw mm1, mm7 ;//add 1
  150. punpckhbw mm4, mm0 ;//expand higher 4 pix pos: + 5
  151. paddw mm2, mm7 ;//add 1
  152. paddw mm1, mm3 ;//pos: +0/+1 add
  153. paddw mm2, mm4 ;//pos: +4/+5 add
  154. psrlw mm1, 1 ;//pos: +0/+1 /2
  155. movq mm6, mm5
  156. psrlw mm2, 1 ;//pos: +4/+5 /2
  157. packuswb mm1, mm2
  158. movq mm3, mm5 ;//save
  159. punpcklbw mm5, mm0 ;//expand lower 4 pix pos: + 8
  160. movq [edi + ebx], mm1
  161. punpckhbw mm6, mm0 ;//expand higher 4 pix pos: + 12
  162. movq mm4, [esi + ebx + 16]
  163. psrlq mm3, 8 ;//shift one byte
  164. paddw mm5, mm7 ;//add 1
  165. psllq mm4, 56 ;//shift 7 bytes, LSB is in top pos of mm4
  166. paddw mm6, mm7 ;//add 1
  167. pxor mm3, mm4 ;//equivalent to read from +9
  168. movq mm4, mm3
  169. punpcklbw mm3, mm0 ;//expand lower 4 pix pos: + 9
  170. punpckhbw mm4, mm0 ;//expand higher 4 pix pos: + 13
  171. paddw mm5, mm3 ;//pos: +8/+9 add
  172. paddw mm6, mm4 ;//pos: +12/+13 add
  173. psrlw mm5, 1 ;//pos: +8/+9 /2
  174. psrlw mm6, 1 ;//pos: +12/+13 /2
  175. packuswb mm5, mm6
  176. movq [edi + ebx + 8], mm5
  177. add ebx, hdim
  178. dec ecx
  179. jg mc16pelsHorInterpolMMX_loop
  180. emms
  181. }
  182. /*
  183.     while (vSize > 0) {
  184.         out[0] = (in[0] + in[1] + 1) >> 1;
  185.         out[1] = (in[1] + in[2] + 1) >> 1;
  186.         out[2] = (in[2] + in[3] + 1) >> 1;
  187.         out[3] = (in[3] + in[4] + 1) >> 1;
  188.         out[4] = (in[4] + in[5] + 1) >> 1;
  189.         out[5] = (in[5] + in[6] + 1) >> 1;
  190.         out[6] = (in[6] + in[7] + 1) >> 1;
  191.         out[7] = (in[7] + in[8] + 1) >> 1;
  192.         out[8] = (in[8] + in[9] + 1) >> 1;
  193.         out[9] = (in[9] + in[10] + 1) >> 1;
  194.         out[10] = (in[10] + in[11] + 1) >> 1;
  195.         out[11] = (in[11] + in[12] + 1) >> 1;
  196.         out[12] = (in[12] + in[13] + 1) >> 1;
  197.         out[13] = (in[13] + in[14] + 1) >> 1;
  198.         out[14] = (in[14] + in[15] + 1) >> 1;
  199.         out[15] = (in[15] + in[16] + 1) >> 1;
  200.         in += hdim;
  201.         out += hdim;
  202.         --vSize;
  203.     }
  204.     return;
  205. */
  206. }
  207. static void mc8pelsHorInterpolMMX( PIXEL const *inpix, PIXEL *outpix, int hdim, int vSize )
  208. {
  209. __asm {
  210. xor ebx, ebx
  211. mov ecx, vSize
  212. mov esi, inpix
  213. mov edi, outpix
  214. pxor mm0, mm0 ;// mm0 = 0
  215. movq mm7, const_0x0001000100010001
  216. mc8pelsHorInterpolMMX_loop:
  217. movq mm1, [esi + ebx]
  218. movq mm4, [esi + ebx +8]
  219. movq mm3, mm1
  220. psllq mm4, 56 ;//shift 7 bytes, LSB is in top pos of mm4
  221. movq mm2, mm1
  222. psrlq mm3, 8 ;//shift one byte
  223. punpcklbw mm1, mm0 ;//expand lower 4 pix
  224. pxor mm3, mm4 ;
  225. punpckhbw mm2, mm0 ;//expand higher 4 pix
  226. movq mm4, mm3
  227. punpcklbw mm3, mm0 ;//expand lower 4 pix
  228. paddw mm1, mm7
  229. punpckhbw mm4, mm0 ;//expand higher 4 pix
  230. paddw mm2, mm7
  231. paddw mm1, mm3
  232. paddw mm2, mm4
  233. psrlw mm1, 1
  234. psrlw mm2, 1
  235. packuswb mm1, mm2
  236. movq [edi + ebx], mm1
  237. add ebx, hdim
  238. dec ecx
  239. jg mc8pelsHorInterpolMMX_loop
  240. emms
  241. }
  242. /*
  243.     while (vSize > 0) {
  244.         out[0] = (in[0] + in[1] + 1) >> 1;
  245.         out[1] = (in[1] + in[2] + 1) >> 1;
  246.         out[2] = (in[2] + in[3] + 1) >> 1;
  247.         out[3] = (in[3] + in[4] + 1) >> 1;
  248.         out[4] = (in[4] + in[5] + 1) >> 1;
  249.         out[5] = (in[5] + in[6] + 1) >> 1;
  250.         out[6] = (in[6] + in[7] + 1) >> 1;
  251.         out[7] = (in[7] + in[8] + 1) >> 1;
  252.         in += hdim;
  253.         out += hdim;
  254.         --vSize;
  255.     }
  256.     return;
  257. */
  258. }
  259. static void mc4pelsHorInterpolMMX( PIXEL const *inpix, PIXEL *outpix, int hdim, int vSize )
  260. {
  261. __asm {
  262. xor ebx, ebx
  263. mov ecx, vSize
  264. mov esi, inpix
  265. mov edi, outpix
  266. pxor mm0, mm0 ;// mm0 = 0
  267. movq mm7, const_0x0001000100010001
  268. mc4pelsHorInterpolMMX_loop:
  269. movq mm1, [esi + ebx]
  270. movq mm3, mm1
  271. punpcklbw mm1, mm0 ;//expand lower 4 pix
  272. psrlq mm3, 8 ;//shift one byte
  273. punpcklbw mm3, mm0 ;//expand lower 4 pix
  274. paddw mm1, mm7
  275. paddw mm1, mm3
  276. psrlw mm1, 1
  277. packuswb mm1, mm0
  278. movd [edi + ebx], mm1
  279. add ebx, hdim
  280. dec ecx
  281. jg mc4pelsHorInterpolMMX_loop
  282. emms
  283. }
  284. /*
  285.     while (vSize > 0) {
  286.         out[0] = (in[0] + in[1] + 1) >> 1;
  287.         out[1] = (in[1] + in[2] + 1) >> 1;
  288.         out[2] = (in[2] + in[3] + 1) >> 1;
  289.         out[3] = (in[3] + in[4] + 1) >> 1;
  290.         in += hdim;
  291.         out += hdim;
  292.         --vSize;
  293.     }
  294.     return;
  295. */
  296. }
  297. static void mc16pelsVertInterpolMMX( PIXEL const *inpix, PIXEL *outpix, int hdim, int vSize )
  298. {
  299. __asm {
  300. xor ebx, ebx
  301. mov ecx, vSize
  302. mov esi, inpix
  303. mov edi, outpix
  304. sub edi, hdim ;//edi = output - hdim
  305. pxor mm0, mm0 ;// mm0 = 0
  306. movq mm7, const_0x0001000100010001
  307. mc16pelsVertInterpolMMX_loop:
  308. movq mm1, [esi + ebx]
  309. movq mm2, mm1
  310. movq mm5, [esi + ebx + 8]
  311. punpcklbw mm1, mm0 ;//expand lower 4 pix
  312. movq mm6, mm5
  313. punpckhbw mm2, mm0 ;//expand higher 4 pix
  314. add ebx, hdim
  315. punpcklbw mm5, mm0 ;//expand lower 4 pix
  316. paddw mm1, mm7
  317. punpckhbw mm6, mm0 ;//expand higher 4 pix
  318. movq mm3, [esi + ebx]
  319. paddw mm2, mm7
  320. movq mm4, mm3
  321. punpcklbw mm3, mm0 ;//expand lower 4 pix
  322. punpckhbw mm4, mm0 ;//expand higher 4 pix
  323. paddw mm1, mm3
  324. paddw mm2, mm4
  325. psrlw mm1, 1
  326. psrlw mm2, 1
  327. movq mm3, [esi + ebx + 8]
  328. packuswb mm1, mm2
  329. movq mm4, mm3
  330. movq [edi + ebx], mm1
  331. punpcklbw mm3, mm0 ;//expand lower 4 pix
  332. paddw mm5, mm7
  333. punpckhbw mm4, mm0 ;//expand higher 4 pix
  334. paddw mm6, mm7
  335. paddw mm5, mm3
  336. paddw mm6, mm4
  337. psrlw mm5, 1
  338. psrlw mm6, 1
  339. packuswb mm5, mm6
  340. dec ecx
  341. movq [edi + ebx + 8], mm5
  342. jg mc16pelsVertInterpolMMX_loop
  343. emms
  344. }
  345. /*
  346.     while (vSize > 0) {
  347.         out[0] = (in[0] + in[hdim+0] + 1) >> 1;
  348.         out[1] = (in[1] + in[hdim+1] + 1) >> 1;
  349.         out[2] = (in[2] + in[hdim+2] + 1) >> 1;
  350.         out[3] = (in[3] + in[hdim+3] + 1) >> 1;
  351.         out[4] = (in[4] + in[hdim+4] + 1) >> 1;
  352.         out[5] = (in[5] + in[hdim+5] + 1) >> 1;
  353.         out[6] = (in[6] + in[hdim+6] + 1) >> 1;
  354.         out[7] = (in[7] + in[hdim+7] + 1) >> 1;
  355.         out[8] = (in[8] + in[hdim+8] + 1) >> 1;
  356.         out[9] = (in[9] + in[hdim+9] + 1) >> 1;
  357.         out[10] = (in[10] + in[hdim+10] + 1) >> 1;
  358.         out[11] = (in[11] + in[hdim+11] + 1) >> 1;
  359.         out[12] = (in[12] + in[hdim+12] + 1) >> 1;
  360.         out[13] = (in[13] + in[hdim+13] + 1) >> 1;
  361.         out[14] = (in[14] + in[hdim+14] + 1) >> 1;
  362.         out[15] = (in[15] + in[hdim+15] + 1) >> 1;
  363.         in += hdim;
  364.         out += hdim;
  365.         --vSize;
  366.     }
  367.     return;
  368. */
  369. }
  370. static void mc8pelsVertInterpolMMX( PIXEL const *inpix, PIXEL *outpix, int hdim, int vSize )
  371. {
  372. __asm {
  373. xor ebx, ebx
  374. mov ecx, vSize
  375. mov esi, inpix
  376. mov edi, outpix
  377. sub edi, hdim ;//edi = output - hdim
  378. pxor mm0, mm0 ;// mm0 = 0
  379. movq mm7, const_0x0001000100010001
  380. mc8pelsVertInterpolMMX_loop:
  381. movq mm1, [esi + ebx]
  382. add ebx, hdim
  383. movq mm2, mm1
  384. punpcklbw mm1, mm0 ;//expand lower 4 pix
  385. movq mm3, [esi + ebx]
  386. punpckhbw mm2, mm0 ;//expand higher 4 pix
  387. movq mm4, mm3
  388. punpcklbw mm3, mm0 ;//expand lower 4 pix
  389. punpckhbw mm4, mm0 ;//expand higher 4 pix
  390. paddw mm1, mm7
  391. paddw mm2, mm7
  392. paddw mm1, mm3
  393. paddw mm2, mm4
  394. psrlw mm1, 1
  395. psrlw mm2, 1
  396. dec ecx
  397. packuswb mm1, mm2
  398. movq [edi + ebx], mm1
  399. jg mc8pelsVertInterpolMMX_loop
  400. emms
  401. }
  402. /*
  403.     while (vSize > 0) {
  404.         out[0] = (in[0] + in[hdim+0] + 1) >> 1;
  405.         out[1] = (in[1] + in[hdim+1] + 1) >> 1;
  406.         out[2] = (in[2] + in[hdim+2] + 1) >> 1;
  407.         out[3] = (in[3] + in[hdim+3] + 1) >> 1;
  408.         out[4] = (in[4] + in[hdim+4] + 1) >> 1;
  409.         out[5] = (in[5] + in[hdim+5] + 1) >> 1;
  410.         out[6] = (in[6] + in[hdim+6] + 1) >> 1;
  411.         out[7] = (in[7] + in[hdim+7] + 1) >> 1;
  412.         in += hdim;
  413.         out += hdim;
  414.         --vSize;
  415.     }
  416.     return;
  417. */
  418. }
  419. static void mc4pelsVertInterpolMMX( PIXEL const *inpix, PIXEL *outpix, int hdim, int vSize )
  420. {
  421. __asm {
  422. xor ebx, ebx
  423. mov ecx, vSize
  424. mov esi, inpix
  425. mov edi, outpix
  426. sub edi, hdim ;//edi = output - hdim
  427. pxor mm0, mm0 ;// mm0 = 0
  428. movq mm7, const_0x0001000100010001
  429. mc4pelsVertInterpolMMX_loop:
  430. movq mm1, [esi + ebx]
  431. punpcklbw mm1, mm0 ;//expand lower 4 pix
  432. add ebx, hdim
  433. movq mm3, [esi + ebx]
  434. punpcklbw mm3, mm0 ;//expand lower 4 pix
  435. paddw mm1, mm7
  436. paddw mm1, mm3
  437. psrlw mm1, 1
  438. packuswb mm1, mm0
  439. movd [edi + ebx], mm1
  440. dec ecx
  441. jg mc4pelsVertInterpolMMX_loop
  442. emms
  443. }
  444. /*
  445.     while (vSize > 0) {
  446.         out[0] = (in[0] + in[hdim+0] + 1) >> 1;
  447.         out[1] = (in[1] + in[hdim+1] + 1) >> 1;
  448.         out[2] = (in[2] + in[hdim+2] + 1) >> 1;
  449.         out[3] = (in[3] + in[hdim+3] + 1) >> 1;
  450.         in += hdim;
  451.         out += hdim;
  452.         --vSize;
  453.     }
  454.     return;
  455. */
  456. }
  457. static void mc16pels2DInterpolMMX( PIXEL const *inpix, PIXEL *outpix, int hdim, int vSize )
  458. {
  459. __asm {
  460. xor ebx, ebx
  461. mov edx, hdim ;//one row ahead
  462. mov ecx, vSize
  463. mov esi, inpix
  464. mov edi, outpix
  465. pxor mm0, mm0 ;// mm0 = 0
  466. movq mm7, const_0x0002000200020002
  467. mc16pels2DInterpolMMX_loop:
  468. movq mm1, [esi + ebx] ;//00
  469. movq mm6, [esi + ebx +8] ;//05
  470. movq mm5, mm1 ;//01
  471. movq mm2, mm1 ;//02
  472. psrlq mm5, 8 ;//shift one byte ;//06
  473. psllq mm6, 56 ;//shift 7 bytes, LSB is in top pos of mm4 ;//07
  474. punpcklbw mm1, mm0 ;//expand lower 4 pix ;//03
  475. pxor mm5, mm6 ; ;//08
  476. punpckhbw mm2, mm0 ;//expand higher 4 pix ;//04
  477. movq mm6, mm5 ;//09
  478. punpcklbw mm5, mm0 ;//expand lower 4 pix ;//10
  479. paddw mm1, mm7 ;//add 2 ;//12
  480. punpckhbw mm6, mm0 ;//expand higher 4 pix ;//11
  481. paddw mm2, mm7 ;//add 2 ;//12
  482. paddw mm1, mm5 ;//13
  483. movq mm3, [esi + edx] ;//15
  484. paddw mm2, mm6 ;//14
  485. movq mm5, mm3 ;//16
  486. movq mm4, mm3 ;//18
  487. punpcklbw mm3, mm0 ;//expand lower 4 pix ;//18
  488. movq mm6, [esi + edx + 8] ;//22
  489. psrlq mm5, 8 ;//shift one byte ;//23
  490. punpckhbw mm4, mm0 ;//expand higher 4 pix ;//19
  491. psllq mm6, 56 ;//shift 7 bytes, LSB is in top pos of mm4 ;//24
  492. paddw mm1, mm3 ;//20
  493. pxor mm5, mm6 ; ;//25
  494. paddw mm2, mm4 ;//21
  495. movq mm6, mm5 ;//26
  496. punpcklbw mm5, mm0 ;//expand lower 4 pix ;//27
  497. punpckhbw mm6, mm0 ;//expand higher 4 pix ;//28
  498. paddw mm1, mm5 ;//29
  499. paddw mm2, mm6 ;//30
  500. psrlw mm1, 2 ;//31
  501. psrlw mm2, 2 ;//32
  502. movq mm6, [esi + ebx + 16] ;//40
  503. packuswb mm1, mm2 ;//33
  504. psllq mm6, 56 ;//shift 7 bytes, LSB is in top pos of mm4 ;//42
  505. movq [edi + ebx], mm1 ;//34
  506. //-----------------//--------------//----------------
  507. movq mm1, [esi + ebx + 8] ;//35
  508. movq mm5, mm1 ;//36
  509. movq mm2, mm1 ;//37
  510. psrlq mm5, 8 ;//shift one byte ;//41
  511. punpcklbw mm1, mm0 ;//expand lower 4 pix ;//38
  512. pxor mm5, mm6 ; ;//43
  513. punpckhbw mm2, mm0 ;//expand higher 4 pix ;//39
  514. movq mm6, mm5 ;//44
  515. punpcklbw mm5, mm0 ;//expand lower 4 pix ;//45
  516. punpckhbw mm6, mm0 ;//expand higher 4 pix ;//46
  517. paddw mm1, mm7 ;//add 2 ;//47
  518. paddw mm2, mm7 ;//add 2 ;//48
  519. paddw mm1, mm5 ;//49
  520. paddw mm2, mm6 ;//50
  521. movq mm3, [esi + edx + 8] ;//51
  522. movq mm6, [esi + edx + 16] ;//58
  523. movq mm5, mm3 ;//52
  524. psllq mm6, 56 ;//shift 7 bytes, LSB is in top pos of mm4 ;//60
  525. movq mm4, mm3 ;//53
  526. psrlq mm5, 8 ;//shift one byte ;//59
  527. punpcklbw mm3, mm0 ;//expand lower 4 pix ;//54
  528. pxor mm5, mm6 ; ;//61
  529. punpckhbw mm4, mm0 ;//expand higher 4 pix ;//55
  530. paddw mm1, mm3 ;//56
  531. paddw mm2, mm4 ;//57
  532. movq mm6, mm5 ;//62
  533. punpcklbw mm5, mm0 ;//expand lower 4 pix ;//63
  534. punpckhbw mm6, mm0 ;//expand higher 4 pix ;//64
  535. paddw mm1, mm5 ;//65
  536. paddw mm2, mm6 ;//66
  537. psrlw mm1, 2 ;//67
  538. psrlw mm2, 2 ;//68
  539. add edx, hdim
  540. packuswb mm1, mm2 ;//69
  541. movq [edi + ebx + 8], mm1 ;//70
  542. add ebx, hdim
  543. dec ecx
  544. jg mc16pels2DInterpolMMX_loop
  545. emms
  546. }
  547. /*
  548.     while (vSize > 0) {
  549.         out[0] = (in[0] + in[1] + in[hdim+0] + in[hdim+1] + 2) >> 2;
  550.         out[1] = (in[1] + in[2] + in[hdim+1] + in[hdim+2] + 2) >> 2;
  551.         out[2] = (in[2] + in[3] + in[hdim+2] + in[hdim+3] + 2) >> 2;
  552.         out[3] = (in[3] + in[4] + in[hdim+3] + in[hdim+4] + 2) >> 2;
  553.         out[4] = (in[4] + in[5] + in[hdim+4] + in[hdim+5] + 2) >> 2;
  554.         out[5] = (in[5] + in[6] + in[hdim+5] + in[hdim+6] + 2) >> 2;
  555.         out[6] = (in[6] + in[7] + in[hdim+6] + in[hdim+7] + 2) >> 2;
  556.         out[7] = (in[7] + in[8] + in[hdim+7] + in[hdim+8] + 2) >> 2;
  557.         out[8] = (in[8] + in[9] + in[hdim+8] + in[hdim+9] + 2) >> 2;
  558.         out[9] = (in[9] + in[10] + in[hdim+9] + in[hdim+10] + 2) >> 2;
  559.         out[10] = (in[10] + in[11] + in[hdim+10] + in[hdim+11] + 2) >> 2;
  560.         out[11] = (in[11] + in[12] + in[hdim+11] + in[hdim+12] + 2) >> 2;
  561.         out[12] = (in[12] + in[13] + in[hdim+12] + in[hdim+13] + 2) >> 2;
  562.         out[13] = (in[13] + in[14] + in[hdim+13] + in[hdim+14] + 2) >> 2;
  563.         out[14] = (in[14] + in[15] + in[hdim+14] + in[hdim+15] + 2) >> 2;
  564.         out[15] = (in[15] + in[16] + in[hdim+15] + in[hdim+16] + 2) >> 2;
  565.         in += hdim;
  566.         out += hdim;
  567.         --vSize;
  568.     }
  569.     return;
  570. */
  571. }
  572. static void mc8pels2DInterpolMMX( PIXEL const *inpix, PIXEL *outpix, int hdim, int vSize )
  573. {
  574. __asm {
  575. xor ebx, ebx
  576. mov edx, hdim ;//one row ahead
  577. mov ecx, vSize
  578. mov esi, inpix
  579. mov edi, outpix
  580. pxor mm0, mm0 ;// mm0 = 0
  581. movq mm7, const_0x0002000200020002
  582. mc8pels2DInterpolMMX_loop:
  583. movq mm1, [esi + ebx]
  584. movq mm6, [esi + ebx +8]
  585. movq mm5, mm1
  586. movq mm2, mm1
  587. psrlq mm5, 8 ;//shift one byte
  588. punpcklbw mm1, mm0 ;//expand lower 4 pix
  589. psllq mm6, 56 ;//shift 7 bytes, LSB is in top pos of mm4
  590. punpckhbw mm2, mm0 ;//expand higher 4 pix
  591. pxor mm5, mm6 ;
  592. paddw mm1, mm7 ;//add 2
  593. movq mm6, mm5
  594. punpcklbw mm5, mm0 ;//expand lower 4 pix
  595. paddw mm2, mm7 ;//add 2
  596. punpckhbw mm6, mm0 ;//expand higher 4 pix
  597. paddw mm1, mm5
  598. paddw mm2, mm6
  599. movq mm3, [esi + edx]
  600. movq mm6, [esi + edx + 8]
  601. movq mm5, mm3
  602. movq mm4, mm3
  603. punpcklbw mm3, mm0 ;//expand lower 4 pix
  604. psrlq mm5, 8 ;//shift one byte
  605. punpckhbw mm4, mm0 ;//expand higher 4 pix
  606. psllq mm6, 56 ;//shift 7 bytes, LSB is in top pos of mm4
  607. paddw mm1, mm3
  608. pxor mm5, mm6 ;
  609. paddw mm2, mm4
  610. movq mm6, mm5
  611. punpcklbw mm5, mm0 ;//expand lower 4 pix
  612. punpckhbw mm6, mm0 ;//expand higher 4 pix
  613. paddw mm1, mm5
  614. paddw mm2, mm6
  615. psrlw mm1, 2
  616. psrlw mm2, 2
  617. add edx, hdim
  618. packuswb mm1, mm2
  619. movq [edi + ebx], mm1
  620. add ebx, hdim
  621. dec ecx
  622. jg mc8pels2DInterpolMMX_loop
  623. emms
  624. }
  625. /*
  626.     while (vSize > 0) {
  627.         out[0] = (in[0] + in[1] + in[hdim+0] + in[hdim+1] + 2) >> 2;
  628.         out[1] = (in[1] + in[2] + in[hdim+1] + in[hdim+2] + 2) >> 2;
  629.         out[2] = (in[2] + in[3] + in[hdim+2] + in[hdim+3] + 2) >> 2;
  630.         out[3] = (in[3] + in[4] + in[hdim+3] + in[hdim+4] + 2) >> 2;
  631.         out[4] = (in[4] + in[5] + in[hdim+4] + in[hdim+5] + 2) >> 2;
  632.         out[5] = (in[5] + in[6] + in[hdim+5] + in[hdim+6] + 2) >> 2;
  633.         out[6] = (in[6] + in[7] + in[hdim+6] + in[hdim+7] + 2) >> 2;
  634.         out[7] = (in[7] + in[8] + in[hdim+7] + in[hdim+8] + 2) >> 2;
  635.         in += hdim;
  636.         out += hdim;
  637.         --vSize;
  638.     }
  639.     return;
  640. */
  641. }
  642. static void mc4pels2DInterpolMMX( PIXEL const *inpix, PIXEL *outpix, int hdim, int vSize )
  643. {
  644. __asm {
  645. xor ebx, ebx
  646. mov edx, hdim ;//one row ahead
  647. mov ecx, vSize
  648. mov esi, inpix
  649. mov edi, outpix
  650. pxor mm0, mm0 ;// mm0 = 0
  651. movq mm7, const_0x0002000200020002
  652. mc4pels2DInterpolMMX_loop:
  653. movq mm1, [esi + ebx]
  654. movq mm5, mm1
  655. punpcklbw mm1, mm0 ;//expand lower 4 pix
  656. psrlq mm5, 8 ;//shift one byte
  657. punpcklbw mm5, mm0 ;//expand lower 4 pix
  658. paddw mm1, mm7 ;//add 2
  659. paddw mm1, mm5
  660. movq mm3, [esi + edx]
  661. movq mm5, mm3
  662. punpcklbw mm3, mm0 ;//expand lower 4 pix
  663. paddw mm1, mm3
  664. psrlq mm5, 8 ;//shift one byte
  665. punpcklbw mm5, mm0 ;//expand lower 4 pix
  666. paddw mm1, mm5
  667. psrlw mm1, 2
  668. packuswb mm1, mm0
  669. movd [edi + ebx], mm1
  670. add ebx, hdim
  671. add edx, hdim
  672. dec ecx
  673. jg mc4pels2DInterpolMMX_loop
  674. emms
  675. }
  676. /*
  677.     while (vSize > 0) {
  678.         out[0] = (in[0] + in[1] + in[hdim+0] + in[hdim+1] + 2) >> 2;
  679.         out[1] = (in[1] + in[2] + in[hdim+1] + in[hdim+2] + 2) >> 2;
  680.         out[2] = (in[2] + in[3] + in[hdim+2] + in[hdim+3] + 2) >> 2;
  681.         out[3] = (in[3] + in[4] + in[hdim+3] + in[hdim+4] + 2) >> 2;
  682.         in += hdim;
  683.         out += hdim;
  684.         --vSize;
  685.     }
  686.     return;
  687. */
  688. }
  689. // mc - Perform motion compensation for a hSize x vSize block
  690. void mcMMX( int hSize, int vSize, 
  691.                     PIXEL *in, PIXEL *out, int hdim,
  692.                     int mvX, int mvY    // Motion vector
  693.                     )
  694. {
  695.     int intX, intY, fracX, fracY;    
  696.     intX = mvX >> 1;    // Integer part of motion vector
  697.     intY = mvY >> 1;
  698.     fracX = mvX & 0x1;  // Fractional part of motion vector
  699.     fracY = mvY & 0x1;
  700.     in += intX + intY * hdim;
  701.     if (hSize != 16  &&  hSize != 8  &&  hSize != 4) {
  702.         H261ErrMsg("mc -- hSize not supported");
  703.         exit(0);
  704.     }
  705. //#define MMX_MC_TEST
  706. #ifdef MMX_MC_TEST
  707. {
  708. PIXEL in_org[17*352];
  709. PIXEL out_org[17*352];
  710. void mc( int hSize, int vSize, PIXEL in[], PIXEL out[], int hdim,int mvX, int mvY);
  711. int bError = 0;
  712. int row, col;
  713. for(row=0; row<vSize+1; row++) {
  714. for(col=0; col<hSize+1; col++) {
  715. in_org[row*hdim + col] = in[row*hdim + col];
  716. //out_org[row*hdim + col] = out[row*hdim + col];
  717. }
  718. }
  719. #endif
  720.     if (fracY == 0) {
  721.         if (fracX == 0) {
  722.             // No interpolation
  723.             if (hSize == 8) {
  724.                 mc8pelsNoInterpolMMX( in, out, hdim, vSize );
  725.             } else if (hSize == 16) {
  726.                 mc16pelsNoInterpolMMX( in, out, hdim, vSize );
  727.             } else {
  728.                 mc4pelsNoInterpolMMX( in, out, hdim, vSize );
  729.             }
  730.         } else {
  731.             // Horizontal interpolation
  732.             if (hSize == 8) {
  733.                 mc8pelsHorInterpolMMX( in, out, hdim, vSize );
  734.             } else if (hSize == 16) {
  735.                 mc16pelsHorInterpolMMX( in, out, hdim, vSize );
  736.             } else {
  737.                 mc4pelsHorInterpolMMX( in, out, hdim, vSize );
  738.             }
  739.         }
  740.     } else if (fracX == 0) {
  741.         // Vertical interpolation
  742.         if (hSize == 8) {
  743.             mc8pelsVertInterpolMMX( in, out, hdim, vSize );
  744.         } else if (hSize == 16) {
  745.             mc16pelsVertInterpolMMX( in, out, hdim, vSize );
  746.         } else {
  747.             mc4pelsVertInterpolMMX( in, out, hdim, vSize );
  748.         }
  749.     } else {    // Bilinear interpolation
  750.         if (hSize == 8) {
  751.             mc8pels2DInterpolMMX( in, out, hdim, vSize );
  752.         } else if (hSize == 16) {
  753.             mc16pels2DInterpolMMX( in, out, hdim, vSize );
  754.         } else {
  755.             mc4pels2DInterpolMMX( in, out, hdim, vSize );
  756.         }
  757.     }
  758. #ifdef MMX_MC_TEST
  759. mc(hSize,vSize, in_org - intX - intY * hdim, out_org, hdim, mvX, mvY );
  760. for(row=0; row<vSize; row++) {
  761. for(col=0; col<hSize; col++) {
  762. if(in_org[row*hdim + col] != in[row*hdim + col]) {
  763. bError = 1;
  764. }
  765. if(out_org[row*hdim + col] != out[row*hdim + col]) {
  766. bError = 1;
  767. }
  768. }
  769. }
  770. }
  771. #endif
  772.     return;
  773. }
  774. // averageBlock - compute average of two hSize*vSize pixel arrays
  775. void averageBlockMMX( PIXEL forPred[], int hSize, int vSize, int forOffset,
  776.                           PIXEL backPred[], int backOffset )
  777. {
  778.     int row, col;
  779. int nbPerRow = (hSize>>2) ;
  780. //do row size multiples of 4
  781. if(nbPerRow==2) {
  782. __asm {//8
  783. mov esi, forPred
  784. mov edi, backPred
  785. mov ecx, vSize
  786. pxor mm0, mm0; // mm0 = 0
  787. aver_8:
  788. movq mm1, [esi]
  789. movq mm3, [edi]
  790. movq mm2, mm1
  791. movq mm4, mm3
  792. punpcklbw mm1, mm0 ;// expand lower 4 pix
  793. punpckhbw mm2, mm0 ;// expand higher 4 pix
  794. punpcklbw mm3, mm0 ;// expand lower 4 pix
  795. punpckhbw mm4, mm0 ;// expand higher 4 pix
  796. paddw mm1, mm3
  797. paddw mm2, mm4
  798. psrlw mm1, 1
  799. psrlw mm2, 1
  800. packuswb mm1, mm2
  801. add edi, backOffset
  802. movq [esi], mm1
  803. add esi, forOffset
  804. dec ecx
  805. jg aver_8
  806. emms
  807. }
  808. } else if(nbPerRow>=4) {
  809. nbPerRow = 4;
  810. __asm {//16
  811. mov esi, forPred
  812. mov edi, backPred
  813. mov ecx, vSize
  814. pxor mm0, mm0; // mm0 = 0
  815. aver_16:
  816. movq mm1, [esi] ;//00
  817. movq mm5, [esi+8] ;//10
  818. movq mm2, mm1 ;//00
  819. punpcklbw mm1, mm0 ;// expand lower 4 pix ;//00
  820. movq mm6, mm5 ;//10
  821. punpckhbw mm2, mm0 ;// expand higher 4 pix ;//00
  822. movq mm3, [edi] ;//00
  823. punpcklbw mm5, mm0 ;// expand lower 4 pix ;//10
  824. movq mm4, mm3 ;//00
  825. punpckhbw mm6, mm0 ;// expand higher 4 pix ;//10
  826. movq mm7, [edi+8] ;//10
  827. punpcklbw mm3, mm0 ;// expand lower 4 pix ;//00
  828. punpckhbw mm4, mm0 ;// expand higher 4 pix ;//00
  829. paddw mm2, mm4 ;//00
  830. paddw mm1, mm3 ;//00
  831. movq mm4, mm7 ;//10
  832. punpcklbw mm7, mm0 ;// expand lower 4 pix ;//10
  833. punpckhbw mm4, mm0 ;// expand higher 4 pix ;//10
  834. paddw mm5, mm7 ;//10
  835. psrlw mm1, 1 ;//00
  836. paddw mm6, mm4 ;//10
  837. psrlw mm2, 1 ;//00
  838. psrlw mm5, 1 ;//10
  839. packuswb mm1, mm2 ;//00
  840. psrlw mm6, 1 ;//10
  841. packuswb mm5, mm6 ;//10
  842. movq [esi], mm1 ;//00
  843. add edi, backOffset
  844. movq [esi+8], mm5 ;//10
  845. add esi, forOffset
  846. dec ecx
  847. jg aver_16
  848. emms
  849. }
  850. } else if(nbPerRow==1) {
  851. __asm {//4
  852. mov esi, forPred
  853. mov edi, backPred
  854. mov ecx, vSize
  855. pxor mm0, mm0; // mm0 = 0
  856. aver_4:
  857. movq mm1, [esi]
  858. movq mm3, [edi]
  859. punpcklbw mm1, mm0 ;// expand lower 4 pix
  860. punpcklbw mm3, mm0 ;// expand lower 4 pix
  861. paddw mm1, mm3
  862. psrlw mm1, 1
  863. packuswb mm1, mm0
  864. add edi, backOffset
  865. movd [esi], mm1
  866. add esi, forOffset
  867. dec ecx
  868. jg aver_4
  869. emms
  870. }
  871. } else if(nbPerRow==3) {
  872. __asm {//12
  873. mov esi, forPred
  874. mov edi, backPred
  875. mov ecx, vSize
  876. pxor mm0, mm0; // mm0 = 0
  877. aver_12:
  878. movq mm1, [esi] ;//00
  879. movq mm5, [esi+8] ;//10
  880. movq mm2, mm1 ;//00
  881. punpcklbw mm1, mm0 ;// expand lower 4 pix ;//00
  882. punpckhbw mm2, mm0 ;// expand higher 4 pix ;//00
  883. movq mm3, [edi] ;//00
  884. punpcklbw mm5, mm0 ;// expand lower 4 pix ;//10
  885. movq mm4, mm3 ;//00
  886. punpcklbw mm3, mm0 ;// expand lower 4 pix ;//00
  887. punpckhbw mm4, mm0 ;// expand higher 4 pix ;//00
  888. movq mm7, [edi+8] ;//10
  889. paddw mm2, mm4 ;//00
  890. punpcklbw mm7, mm0 ;// expand lower 4 pix ;//10
  891. paddw mm1, mm3 ;//00
  892. psrlw mm2, 1 ;//00
  893. paddw mm5, mm7 ;//10
  894. psrlw mm1, 1 ;//00
  895. psrlw mm5, 1 ;//10
  896. packuswb mm1, mm2 ;//00
  897. packuswb mm5, mm0 ;//10
  898. movq [esi], mm1 ;//00
  899. add edi, backOffset
  900. movd [esi+8], mm5 ;//10
  901. add esi, forOffset
  902. dec ecx
  903. jg aver_12
  904. emms
  905. }
  906. }
  907.     for (row = 0; row < vSize; ++row) {
  908.         for (col = nbPerRow<<2; col < hSize; ++col) {//from smaller multiple of 4
  909.             forPred[col] = (forPred[col] + backPred[col]) >> 1;
  910.         }
  911.         forPred  += forOffset;
  912.         backPred += backOffset;
  913.     }
  914. }