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

Symbian

开发平台:

Visual C++

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