Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

764 lines
22 KiB

  1. /* File: sv_h263_me4.c */
  2. /*****************************************************************************
  3. ** Copyright (c) Digital Equipment Corporation, 1995, 1997 **
  4. ** **
  5. ** All Rights Reserved. Unpublished rights reserved under the copyright **
  6. ** laws of the United States. **
  7. ** **
  8. ** The software contained on this media is proprietary to and embodies **
  9. ** the confidential technology of Digital Equipment Corporation. **
  10. ** Possession, use, duplication or dissemination of the software and **
  11. ** media is authorized only pursuant to a valid written license from **
  12. ** Digital Equipment Corporation. **
  13. ** **
  14. ** RESTRICTED RIGHTS LEGEND Use, duplication, or disclosure by the U.S. **
  15. ** Government is subject to restrictions as set forth in Subparagraph **
  16. ** (c)(1)(ii) of DFARS 252.227-7013, or in FAR 52.227-19, as applicable. **
  17. ******************************************************************************/
  18. #include "sv_h263.h"
  19. #include "proto.h"
  20. #ifndef USE_C
  21. #include "perr.h"
  22. #endif
  23. #define THREEBYEIGHT .375
  24. #define THREEBYFOUR .75
  25. #define MINUSONEBYEIGHT -0.125
  26. #define FIVEBY32 0.15625
  27. #define FIFTEENBY16 0.9375
  28. #define MINUSTHREEBY32 -0.09375
  29. #define SEVENBY16 0.4375
  30. #define TWENTYONEBY32 0.65625
  31. /**********************************************************************
  32. *
  33. * Name: MotionEstimation
  34. * Description: Estimate all motionvectors for one MB
  35. *
  36. * Input: pointers to current an previous image,
  37. * pointers to current slice and current MB
  38. * Returns:
  39. * Side effects: motion vector information in MB changed
  40. *
  41. ***********************************************************************/
  42. void sv_H263ME_2levels_7_pihp(SvH263CompressInfo_t *H263Info,
  43. unsigned char *curr, unsigned char *prev, int x_curr,
  44. int y_curr, int xoff, int yoff, int seek_dist,
  45. H263_MotionVector *MV[6][H263_MBR+1][H263_MBC+2], int *SAD_0)
  46. {
  47. int Min_FRAME[5];
  48. H263_MotionVector MVFrame[5];
  49. unsigned char *aa,*ii;
  50. unsigned char *adv_search_area = NULL, *zero_area = NULL;
  51. int sxy,i,k,j,l;
  52. int ihigh,ilow,jhigh,jlow,h_length,v_length;
  53. int adv_ihigh,adv_ilow,adv_jhigh,adv_jlow,adv_h_length,adv_v_length;
  54. int xmax,ymax,block,sad,lx;
  55. int adv_x_curr, adv_y_curr,xvec,yvec;
  56. unsigned char *act_block_subs2, *search_area_subs2, *adv_search_area_subs2;
  57. int h_lenby2,v_lenby2,adv_h_lenby2,adv_v_lenby2;
  58. int xlevel1,ylevel1,sxylevel1;
  59. int xlevel1_block[4], ylevel1_block[4];
  60. /*
  61. int level0_x_curr,level0_y_curr,sxylevel0;
  62. */
  63. int start_x, start_y, stop_x, stop_y, new_x, new_y;
  64. int AE[5];
  65. H263_Point search[5];
  66. H263_Point half[5];
  67. int pym1,pxm1,pxp1,pyp1;
  68. int pym05,pxm05,pxp05,pyp05;
  69. int AE_minx, AE_miny, min_posx, min_posy, min_hposx, min_hposy;
  70. xmax = H263Info->pels;
  71. ymax = H263Info->lines;
  72. sxy = seek_dist;
  73. if (!H263Info->long_vectors) {
  74. /* Maximum normal search range centered around _zero-vector_ */
  75. sxy = mmin(15, sxy);
  76. }
  77. else {
  78. /* Maximum extended search range centered around _predictor_ */
  79. sxy = mmin(15 - (2*H263_DEF_8X8_WIN+1), sxy);
  80. /* NB! */
  81. /* It is only possible to transmit motion vectors within
  82. a 15x15 window around the motion vector predictor
  83. for any 8x8 or 16x16 block */
  84. /* The reason for the search window's reduction above with
  85. 2*DEF_8X8_WIN+1 is that the 8x8 search may change the MV
  86. predictor for some of the blocks within the macroblock. When we
  87. impose the limitation above, we are sure that any 8x8 vector we
  88. might find is possible to transmit */
  89. /* We have found that with OBMC, DEF_8X8_WIN should be quite small
  90. for two reasons: (i) a good filtering effect, and (ii) not too
  91. many bits used for transferring the vectors. As can be seen
  92. above this is also useful to avoid a large limitation on the MV
  93. search range */
  94. /* It is possible to make sure the motion vectors found are legal
  95. in other less limiting ways than above, but this would be more
  96. complicated as well as time-consuming. Any good suggestions for
  97. improvement is welcome, though */
  98. #ifdef USE_C
  99. xoff = mmin(16,mmax(-16,xoff));
  100. yoff = mmin(16,mmax(-16,yoff));
  101. #else
  102. xoff = sv_H263lim_S(xoff,-16,16);
  103. yoff = sv_H263lim_S(yoff,-16,16);
  104. #endif
  105. /* in case xoff or yoff is odd */
  106. xoff= 2 * ((xoff)>>1);
  107. yoff= 2 * ((yoff)>>1);
  108. /* There is no need to check if (xoff + x_curr) points outside
  109. the picture, since the Extended Motion Vector Range is
  110. always used together with the Unrestricted MV mode */
  111. }
  112. lx = (H263Info->mv_outside_frame ? H263Info->pels + (H263Info->long_vectors?64:32) : H263Info->pels);
  113. ilow = x_curr + xoff - sxy;
  114. ihigh = x_curr + xoff + sxy;
  115. jlow = y_curr + yoff - sxy;
  116. jhigh = y_curr + yoff + sxy;
  117. if (!H263Info->mv_outside_frame) {
  118. if (ilow<0) ilow = 0;
  119. if (ihigh>xmax-16) ihigh = xmax-16;
  120. if (jlow<0) jlow = 0;
  121. if (jhigh>ymax-16) jhigh = ymax-16;
  122. }
  123. h_length = ihigh - ilow + 16;
  124. v_length = jhigh - jlow + 16;
  125. /* subsampled version for ME level 1 */
  126. h_lenby2 = (h_length-1)>>1;
  127. v_lenby2 = (v_length-1)>>1;
  128. act_block_subs2 = sv_H263LoadSubs2Area(curr, x_curr, y_curr, 8, 8, H263Info->pels);
  129. search_area_subs2 = sv_H263LoadSubs2Area(prev, ilow, jlow, h_lenby2, v_lenby2, lx);
  130. for (k = 0; k < 5; k++) {
  131. Min_FRAME[k] = INT_MAX;
  132. MVFrame[k].x = 0;
  133. MVFrame[k].y = 0;
  134. MVFrame[k].x_half = 0;
  135. MVFrame[k].y_half = 0;
  136. }
  137. /* match for zero (or [xoff,yoff]) motion vector on subsampled images */
  138. ii = search_area_subs2 + ((x_curr+xoff-ilow)>>1) + ((y_curr+yoff-jlow)>>1)*h_lenby2;
  139. #ifdef USE_C
  140. Min_FRAME[0] = sv_H263MySADBlock(ii, act_block_subs2, h_lenby2, 8, Min_FRAME[0]);
  141. #else
  142. Min_FRAME[0] = sv_H263PError8x8_S(ii,act_block_subs2,h_lenby2,8,Min_FRAME[0]);
  143. #endif
  144. MVFrame[0].x = (short)xoff;
  145. MVFrame[0].y = (short)yoff;
  146. /*** Spiral search (+-7) on subsampled images ***/
  147. sxylevel1 = (sxy-1)>>1;
  148. for (l = 1; l <= sxylevel1; l++) {
  149. i = x_curr + xoff - 2*l;
  150. j = y_curr + yoff - 2*l;
  151. for (k = 0; k < 8*l; k++) {
  152. if (i>=ilow && i<=ihigh && j>=jlow && j<=jhigh) {
  153. /* 8x8 integer pel MV */
  154. ii = search_area_subs2 + ((i-ilow)>>1) + ((j-jlow)>>1)*h_lenby2;
  155. #ifdef USE_C
  156. sad = sv_H263MySADBlock(ii, act_block_subs2, h_lenby2, 8, Min_FRAME[0]);
  157. #else
  158. sad = sv_H263PError8x8_S(ii,act_block_subs2,h_lenby2,8,Min_FRAME[0]);
  159. #endif
  160. if (sad < Min_FRAME[0]) {
  161. MVFrame[0].x = i - x_curr;
  162. MVFrame[0].y = j - y_curr;
  163. Min_FRAME[0] = sad;
  164. }
  165. }
  166. if (k<2*l) i+=2;
  167. else if (k<4*l) j+=2;
  168. else if (k<6*l) i-=2;
  169. else j-=2;
  170. }
  171. }
  172. /* motion vectors after level1 */
  173. xlevel1=MVFrame[0].x;
  174. ylevel1=MVFrame[0].y;
  175. /* reset */
  176. Min_FRAME[0] = INT_MAX;
  177. MVFrame[0].x = 0;
  178. MVFrame[0].y = 0;
  179. /* Zero vector search*/
  180. if (x_curr-ilow < 0 || y_curr-jlow < 0 ||
  181. x_curr-ilow+H263_MB_SIZE > h_length || y_curr-jlow+H263_MB_SIZE > v_length) {
  182. /* in case the zero vector is outside the loaded area in search_area */
  183. zero_area = sv_H263LoadSubs2Area(prev, x_curr, y_curr, 8, 8, lx);
  184. #ifdef USE_C
  185. *SAD_0 = 4*sv_H263MySADBlock(zero_area, act_block_subs2, 8, 8, Min_FRAME[0]) -
  186. H263_PREF_NULL_VEC;
  187. #else
  188. *SAD_0 = 4*sv_H263PError8x8_S(zero_area, act_block_subs2, 8, 8, Min_FRAME[0]) -
  189. H263_PREF_NULL_VEC;
  190. #endif
  191. ScFree(zero_area);
  192. }
  193. else {
  194. /* the zero vector is within search_area */
  195. ii = search_area_subs2 + ((x_curr-ilow)>>1) + ((y_curr-jlow)>>1)*h_lenby2;
  196. #ifdef USE_C
  197. *SAD_0 = 4*sv_H263MySADBlock(ii, act_block_subs2, h_lenby2, 8, Min_FRAME[0]) -
  198. H263_PREF_NULL_VEC;
  199. #else
  200. *SAD_0 = 4*sv_H263PError8x8_S(ii, act_block_subs2, h_lenby2, 8, Min_FRAME[0]) -
  201. H263_PREF_NULL_VEC;
  202. #endif
  203. }
  204. /*** +-1 search on full-resolution images done by polynomial interpolation ***/
  205. start_x = -1;
  206. stop_x = 1;
  207. start_y = -1;
  208. stop_y = 1;
  209. new_x = x_curr + xlevel1;
  210. new_y = y_curr + ylevel1;
  211. /* Make sure that no addressing is outside the frame */
  212. if (!H263Info->mv_outside_frame) {
  213. if ((new_x) <= (ilow+1))
  214. start_x = 0;
  215. if ((new_y) <= (jlow+1))
  216. start_y = 0;
  217. if ((new_x) >= (ihigh-1))
  218. stop_x = 0;
  219. if ((new_y) >= (jhigh-1))
  220. stop_y = 0;
  221. }
  222. /* 1 */
  223. /* 2 0 3 */
  224. /* 4 */
  225. search[0].x = 0; search[0].y = 0;
  226. search[1].x = 0; search[1].y = (short)start_y;
  227. search[2].x = (short)start_x; search[2].y = 0;
  228. search[3].x = (short)stop_x; search[3].y = 0;
  229. search[4].x = 0; search[4].y = (short)stop_y;
  230. half[0].x = 0; half[0].y = 0;
  231. half[1].x = 0; half[1].y = (short)start_y;
  232. half[2].x = (short)start_x; half[2].y = 0;
  233. half[3].x = (short)stop_x; half[3].y = 0;
  234. half[4].x = 0; half[4].y = (short)stop_y;
  235. for (l = 0; l < 5 ; l++) {
  236. AE[l] = INT_MAX;
  237. i = new_x + 2*search[l].x;
  238. j = new_y + 2*search[l].y;
  239. /* 8x8 integer pel MV */
  240. ii = search_area_subs2 + ((i-ilow)>>1) + ((j-jlow)>>1)*h_lenby2;
  241. #ifdef USE_C
  242. AE[l] = sv_H263MySADBlock(ii, act_block_subs2, h_lenby2, 8, INT_MAX);
  243. #else
  244. AE[l] = sv_H263PEr8_init_S(ii, act_block_subs2, h_lenby2, 8);
  245. #endif
  246. }
  247. /* 1D polynomial interpolation along x and y respectively */
  248. AE_minx = AE[0];
  249. min_posx = 0;
  250. min_hposx = 0;
  251. pxm1 = (int)(THREEBYEIGHT * (double) AE[2]
  252. + THREEBYFOUR * (double) AE[0]
  253. + MINUSONEBYEIGHT * (double) AE[3]) ;
  254. if (pxm1<AE_minx) {
  255. AE_minx = pxm1;
  256. min_posx = 2;
  257. }
  258. pxp1 = (int)(MINUSONEBYEIGHT * (double) AE[2]
  259. + THREEBYFOUR * (double) AE[0]
  260. + THREEBYEIGHT * (double) AE[3]);
  261. if (pxp1<AE_minx) {
  262. AE_minx = pxp1;
  263. min_posx = 3;
  264. }
  265. switch(min_posx) {
  266. case 0: /* now check +- 1/2 */
  267. pxm05 = (int)( FIVEBY32 * (double) AE[2]
  268. + FIFTEENBY16 * (double) AE[0]
  269. + MINUSTHREEBY32 * (double) AE[3]);
  270. if (pxm05<AE_minx) {
  271. AE_minx = pxm05;
  272. min_hposx = 2;
  273. }
  274. pxp05 = (int)( MINUSTHREEBY32 * (double) AE[2]
  275. + FIFTEENBY16 * (double) AE[0]
  276. + FIVEBY32 * (double) AE[3]);
  277. if (pxp05<AE_minx) {
  278. AE_minx = pxp05;
  279. min_hposx = 3;
  280. }
  281. break;
  282. case 2: /* now check -3/2 -1/2 */
  283. pxp05 = (int)(FIVEBY32 * AE[2]
  284. + FIFTEENBY16 * AE[0]
  285. + MINUSTHREEBY32 * AE[3]);
  286. if (pxp05<AE_minx) {
  287. AE_minx = pxp05;
  288. min_hposx = 3;
  289. }
  290. break;
  291. case 3: /* now check +1/2 +3/2 */
  292. pxm05 = (int)( MINUSTHREEBY32 * (double)AE[2]
  293. + FIFTEENBY16 * (double)AE[0]
  294. + FIVEBY32 * (double)AE[3]);
  295. if (pxm05<AE_minx) {
  296. AE_minx = pxm05;
  297. min_hposx = 2;
  298. }
  299. break;
  300. }
  301. /* along y */
  302. AE_miny = AE[0];
  303. min_posy = 0;
  304. min_hposy = 0;
  305. pym1 = (int)(THREEBYEIGHT * (double)AE[1]
  306. + THREEBYFOUR * (double)AE[0]
  307. + MINUSONEBYEIGHT * (double)AE[4]);
  308. if (pym1<AE_miny) {
  309. AE_miny = pym1;
  310. min_posy = 1;
  311. }
  312. pyp1 = (int)( MINUSONEBYEIGHT * (double)AE[1]
  313. + THREEBYFOUR * (double)AE[0]
  314. + THREEBYEIGHT * (double)AE[4]);
  315. if (pyp1<AE_miny) {
  316. AE_miny = pyp1;
  317. min_posy = 4;
  318. }
  319. switch(min_posy) {
  320. case 0: /* +- 1/2 */
  321. pym05 = (int)( FIVEBY32 * (double)AE[1]
  322. + FIFTEENBY16 * (double)AE[0]
  323. + MINUSTHREEBY32 * (double)AE[4]);
  324. if (pym05<AE_miny) {
  325. AE_miny = pym05;
  326. min_hposy = 1;
  327. }
  328. pyp05 = (int)(MINUSTHREEBY32 * (double)AE[1]
  329. + FIFTEENBY16 * (double)AE[0]
  330. + FIVEBY32 * (double)AE[4]);
  331. if (pyp05<AE_miny) {
  332. AE_miny = pyp05;
  333. min_hposy = 4;
  334. }
  335. break;
  336. case 1: /* -3/2 -1/2 */
  337. pyp05 = (int)(FIVEBY32 * (double)AE[1]
  338. + FIFTEENBY16 * (double)AE[0]
  339. + MINUSTHREEBY32 * (double)AE[4]);
  340. if (pyp05<AE_miny) {
  341. AE_miny = pyp05;
  342. min_hposy = 4;
  343. }
  344. break;
  345. case 4: /* +1/2 +3/2 */
  346. pym05 = (int)( MINUSTHREEBY32 * (double)AE[1]
  347. + FIFTEENBY16 * (double)AE[0]
  348. + FIVEBY32 * (double)AE[4]);
  349. if (pym05<AE_miny) {
  350. AE_miny = pym05;
  351. min_hposy = 1;
  352. }
  353. break;
  354. }
  355. /* Store optimal values */
  356. Min_FRAME[0] = (AE_minx<AE_miny ? 4*AE_minx : 4*AE_miny);
  357. MVFrame[0].x = new_x + search[min_posx].x - x_curr;
  358. MVFrame[0].y = new_y + search[min_posy].y - y_curr;
  359. MVFrame[0].x_half = half[min_hposx].x;
  360. MVFrame[0].y_half = half[min_hposy].y;
  361. if (H263Info->advanced) {
  362. /* Center the 8x8 search around the 16x16 vector. This is
  363. different than in TMN5 where the 8x8 search is also a full
  364. search. The reasons for this is: (i) it is faster, and (ii) it
  365. generally gives better results because of a better OBMC
  366. filtering effect and less bits spent for vectors, and (iii) if
  367. the Extended MV Range is used, the search range around the
  368. motion vector predictor will be less limited */
  369. xvec = MVFrame[0].x;
  370. yvec = MVFrame[0].y;
  371. if (!H263Info->long_vectors) {
  372. if (xvec > 15 - H263_DEF_8X8_WIN) { xvec = 15 - H263_DEF_8X8_WIN ;}
  373. if (yvec > 15 - H263_DEF_8X8_WIN) { yvec = 15 - H263_DEF_8X8_WIN ;}
  374. if (xvec < -15 + H263_DEF_8X8_WIN) { xvec = -15 + H263_DEF_8X8_WIN ;}
  375. if (yvec < -15 + H263_DEF_8X8_WIN) { yvec = -15 + H263_DEF_8X8_WIN ;}
  376. }
  377. adv_x_curr = x_curr + xvec;
  378. adv_y_curr = y_curr + yvec;
  379. sxy = H263_DEF_8X8_WIN;
  380. adv_ilow = adv_x_curr - sxy;
  381. adv_ihigh = adv_x_curr + sxy;
  382. adv_jlow = adv_y_curr - sxy;
  383. adv_jhigh = adv_y_curr + sxy;
  384. adv_h_length = adv_ihigh - adv_ilow + 16;
  385. adv_v_length = adv_jhigh - adv_jlow + 16;
  386. /* BUG
  387. adv_h_lenby2 = (adv_h_length-1)>>1;
  388. adv_v_lenby2 = (adv_v_length-1)>>1;
  389. */
  390. adv_h_lenby2 = (adv_h_length)>>1;
  391. adv_v_lenby2 = (adv_v_length)>>1;
  392. /*
  393. adv_search_area_subs2 = sv_H263LoadSubs2Area(prev, adv_ilow, adv_jlow,
  394. adv_h_lenby2, adv_v_lenby2, lx);
  395. */
  396. adv_search_area_subs2 = sv_H263LoadSubs2Area(prev, adv_ilow, adv_jlow,
  397. adv_h_length, adv_v_length, lx);
  398. for (block = 0; block < 4; block++) {
  399. ii = adv_search_area_subs2 + ((adv_x_curr-adv_ilow)>>1) + ((block&1)<<2) +
  400. (((adv_y_curr-adv_jlow)>>1) + ((block&2)<<1) )*adv_h_lenby2;
  401. aa = act_block_subs2 + ((block&1)<<2) + ((block&2)<<1)*8;
  402. /*
  403. Min_FRAME[block+1] = sv_H263MySADSubBlock(ii,aa,adv_h_lenby2,Min_FRAME[block+1]);
  404. */
  405. Min_FRAME[block+1] = sv_H263MySADSubBlock(ii,aa,adv_h_length,Min_FRAME[block+1]);
  406. MVFrame[block+1].x = MVFrame[0].x;
  407. MVFrame[block+1].y = MVFrame[0].y;
  408. }
  409. /* Spiral search */
  410. sxylevel1 = (sxy-1)>>1;
  411. for (l = 1; l <= sxylevel1; l++) {
  412. i = adv_x_curr - 2*l;
  413. j = adv_y_curr - 2*l;
  414. for (k = 0; k < 8*l; k++) {
  415. if (i>=adv_ilow && i<=adv_ihigh && j>=adv_jlow && j<=adv_jhigh) {
  416. /* 8x8 integer pel MVs */
  417. for (block = 0; block < 4; block++) {
  418. ii = adv_search_area_subs2 + ((i-adv_ilow)>>1) + ((block&1)<<2) +
  419. (((j-adv_jlow)>>1) + ((block&2)<<1) )*adv_h_lenby2;
  420. aa = act_block_subs2 + ((block&1)<<2) + ((block&2)<<1)*8;
  421. /*
  422. sad = sv_H263MySADSubBlock(ii, aa, adv_h_lenby2, Min_FRAME[block+1]);
  423. */
  424. sad = sv_H263MySADSubBlock(ii, aa, adv_h_length, Min_FRAME[block+1]);
  425. if (sad < Min_FRAME[block+1]) {
  426. MVFrame[block+1].x = i - x_curr;
  427. MVFrame[block+1].y = j - y_curr;
  428. Min_FRAME[block+1] = sad;
  429. }
  430. }
  431. }
  432. if (k<2*l) i++;
  433. else if (k<4*l) j++;
  434. else if (k<6*l) i--;
  435. else j--;
  436. }
  437. }
  438. for (block = 0; block < 4; block++) {
  439. xlevel1_block[block] = MVFrame[block+1].x;
  440. ylevel1_block[block] = MVFrame[block+1].y;
  441. /* reset */
  442. Min_FRAME[block+1] = INT_MAX;
  443. MVFrame[block+1].x = 0;
  444. MVFrame[block+1].y = 0;
  445. }
  446. /* +-1 search on full resolution on full-resolution images */
  447. /* by polynomial interpolation */
  448. for (block = 0; block < 4; block++) {
  449. start_x = -1;
  450. stop_x = 1;
  451. start_y = -1;
  452. stop_y = 1;
  453. adv_x_curr = x_curr + xlevel1_block[block];
  454. adv_y_curr = y_curr + ylevel1_block[block];
  455. /* 1 */
  456. /* 2 0 3 */
  457. /* 4 */
  458. search[0].x = 0; search[0].y = 0;
  459. search[1].x = 0; search[1].y = (short)start_y;
  460. search[2].x = (short)start_x; search[2].y = 0;
  461. search[3].x = (short)stop_x; search[3].y = 0;
  462. search[4].x = 0; search[4].y = (short)stop_y;
  463. half[0].x = 0; half[0].y = 0;
  464. half[1].x = 0; half[1].y = (short)start_y;
  465. half[2].x = (short)start_x; half[2].y = 0;
  466. half[3].x = (short)stop_x; half[3].y = 0;
  467. half[4].x = 0; half[4].y = (short)stop_y;
  468. for (l = 0; l < 5 ; l++) {
  469. AE[l] = INT_MAX;
  470. i = adv_x_curr + 2*search[l].x;
  471. j = adv_y_curr + 2*search[l].y;
  472. /* 8x8 integer pel MV */
  473. ii = adv_search_area_subs2 + ((i-adv_ilow)>>1) + ((block&1)<<2) +
  474. (((j-adv_jlow)>>1) + ((block&2)<<1) )*adv_h_lenby2;
  475. aa = act_block_subs2 + ((block&1)<<2) + ((block&2)<<1)*8;
  476. /*
  477. AE[l] = sv_H263MySADSubBlock(ii, aa, adv_h_lenby2, INT_MAX);
  478. */
  479. AE[l] = sv_H263MySADSubBlock(ii, aa, adv_h_length, INT_MAX);
  480. }
  481. /* 1D polynomial interpolation along x and y respectively */
  482. AE_minx = AE[0];
  483. min_posx = 0;
  484. min_hposx = 0;
  485. pxm1 = (int)( THREEBYEIGHT * (double)AE[2]
  486. + THREEBYFOUR * (double)AE[0]
  487. + MINUSONEBYEIGHT * (double)AE[3]);
  488. if (pxm1<AE_minx) {
  489. AE_minx = pxm1;
  490. min_posx = 2;
  491. }
  492. pxp1 = (int)( MINUSONEBYEIGHT * (double)AE[2]
  493. + THREEBYFOUR * (double)AE[0]
  494. + THREEBYEIGHT * (double)AE[3]);
  495. if (pxp1<AE_minx) {
  496. AE_minx = pxp1;
  497. min_posx = 3;
  498. }
  499. switch(min_posx) {
  500. case 0: /* now check +- 1/2 */
  501. pxm05 = (int) (FIVEBY32 * (double)AE[2]
  502. + FIFTEENBY16 * (double)AE[0]
  503. + MINUSTHREEBY32 * (double)AE[3]);
  504. if (pxm05<AE_minx) {
  505. AE_minx = pxm05;
  506. min_hposx = 2;
  507. }
  508. pxp05 = (int)(MINUSTHREEBY32 * (double)AE[2]
  509. + FIFTEENBY16 * (double)AE[0]
  510. + FIVEBY32 * (double)AE[3]);
  511. if (pxp05<AE_minx) {
  512. AE_minx = pxp05;
  513. min_hposx = 3;
  514. }
  515. break;
  516. case 2: /* now check -3/2 -1/2 */
  517. pxp05 = (int)( FIVEBY32 * (double)AE[2]
  518. + FIFTEENBY16 * (double)AE[0]
  519. + MINUSTHREEBY32 * (double)AE[3]);
  520. if (pxp05<AE_minx) {
  521. AE_minx = pxp05;
  522. min_hposx = 3;
  523. }
  524. break;
  525. case 3: /* now check +1/2 +3/2 */
  526. pxm05 = (int)(MINUSTHREEBY32 * (double)AE[2]
  527. + FIFTEENBY16 * (double)AE[0]
  528. + FIVEBY32 * (double)AE[3]);
  529. if (pxm05<AE_minx) {
  530. AE_minx = pxm05;
  531. min_hposx = 2;
  532. }
  533. break;
  534. }
  535. /* along y */
  536. AE_miny = AE[0];
  537. min_posy = 0;
  538. min_hposy = 0;
  539. pym1 = (int)(THREEBYEIGHT * (double)AE[1]
  540. + THREEBYFOUR * (double)AE[0]
  541. + MINUSONEBYEIGHT * (double)AE[4]);
  542. if (pym1<AE_miny) {
  543. AE_miny = pym1;
  544. min_posy = 1;
  545. }
  546. pyp1 = (int)(MINUSONEBYEIGHT * (double)AE[1] +
  547. + THREEBYFOUR * (double)AE[0]
  548. + THREEBYEIGHT * (double)AE[4]);
  549. if (pyp1<AE_miny) {
  550. AE_miny = pyp1;
  551. min_posy = 4;
  552. }
  553. switch(min_posy) {
  554. case 0: /* +- 1/2 */
  555. pym05 = (int)(FIVEBY32 * (double)AE[1]
  556. + FIFTEENBY16 * (double)AE[0]
  557. + MINUSTHREEBY32 * (double)AE[4]);
  558. if (pym05<AE_miny) {
  559. AE_miny = pym05;
  560. min_hposy = 1;
  561. }
  562. pyp05 = (int)(MINUSTHREEBY32 * (double)AE[1]
  563. + FIFTEENBY16 * (double)AE[0]
  564. + FIVEBY32 * (double)AE[4]);
  565. if (pyp05<AE_miny) {
  566. AE_miny = pyp05;
  567. min_hposy = 4;
  568. }
  569. break;
  570. case 1: /* -3/2 -1/2 */
  571. pyp05 = (int)(FIVEBY32 * (double)AE[1]
  572. + FIFTEENBY16 * (double)AE[0]
  573. + MINUSTHREEBY32 * (double)AE[4]);
  574. if (pyp05<AE_miny) {
  575. AE_miny = pyp05;
  576. min_hposy = 4;
  577. }
  578. break;
  579. case 4: /* +1/2 +3/2 */
  580. pym05 = (int)(MINUSTHREEBY32 * (double)AE[1]
  581. + FIFTEENBY16 * (double)AE[0]
  582. + FIVEBY32 * (double)AE[4]);
  583. if (pym05<AE_miny) {
  584. AE_miny = pym05;
  585. min_hposy = 1;
  586. }
  587. break;
  588. }
  589. /* Store optimal values */
  590. Min_FRAME[block+1] = (AE_minx<AE_miny ? 4*AE_minx : 4*AE_miny);
  591. MVFrame[block+1].x = adv_x_curr + search[min_posx].x - x_curr;
  592. MVFrame[block+1].y = adv_y_curr + search[min_posy].y - y_curr;
  593. MVFrame[block+1].x_half = half[min_hposx].x;
  594. MVFrame[block+1].y_half = half[min_hposy].y;
  595. }
  596. }
  597. i = x_curr/H263_MB_SIZE+1;
  598. j = y_curr/H263_MB_SIZE+1;
  599. if (!H263Info->advanced) {
  600. MV[0][j][i]->x = MVFrame[0].x;
  601. MV[0][j][i]->y = MVFrame[0].y;
  602. MV[0][j][i]->x_half = MVFrame[0].x_half;
  603. MV[0][j][i]->y_half = MVFrame[0].y_half;
  604. MV[0][j][i]->min_error = (short)Min_FRAME[0];
  605. }
  606. else {
  607. for (k = 0; k < 5; k++) {
  608. MV[k][j][i]->x = MVFrame[k].x;
  609. MV[k][j][i]->y = MVFrame[k].y;
  610. MV[k][j][i]->x_half = MVFrame[k].x_half;
  611. MV[k][j][i]->y_half = MVFrame[k].y_half;
  612. MV[k][j][i]->min_error = (short)Min_FRAME[k];
  613. }
  614. }
  615. ScFree(act_block_subs2);
  616. ScFree(search_area_subs2);
  617. if (H263Info->advanced)
  618. ScFree(adv_search_area);
  619. return;
  620. }
  621.