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.

479 lines
16 KiB

  1. /* File: sv_h263_me2.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. /**********************************************************************
  24. *
  25. * Name: MotionEstimation
  26. * Description: Estimate all motionvectors for one MB
  27. *
  28. * Input: pointers to current an previous image,
  29. * pointers to current slice and current MB
  30. * Returns:
  31. * Side effects: motion vector imformation in MB changed
  32. *
  33. ***********************************************************************/
  34. void sv_H263ME_2levels_421_1(SvH263CompressInfo_t *H263Info,
  35. unsigned char *curr, unsigned char *prev, int x_curr,
  36. int y_curr, int xoff, int yoff, int seek_dist,
  37. H263_MotionVector *MV[6][H263_MBR+1][H263_MBC+2], int *SAD_0)
  38. {
  39. int Min_FRAME[5];
  40. H263_MotionVector MVFrame[5];
  41. unsigned char *act_block,*aa,*ii;
  42. unsigned char *search_area, *adv_search_area = NULL, *zero_area = NULL;
  43. int sxy,i,k,j,l;
  44. int ihigh,ilow,jhigh,jlow,h_length,v_length;
  45. int adv_ihigh,adv_ilow,adv_jhigh,adv_jlow,adv_h_length,adv_v_length;
  46. int xmax,ymax,block,sad,lx;
  47. int adv_x_curr, adv_y_curr,xvec,yvec;
  48. int h_lenby2,v_lenby2;
  49. unsigned char *act_block_subs2, *search_area_subs2;
  50. int xlevel1,ylevel1;
  51. int level1_x_curr,level1_y_curr;
  52. int level0_x_curr,level0_y_curr;
  53. xmax = H263Info->pels;
  54. ymax = H263Info->lines;
  55. sxy = seek_dist;
  56. if (!H263Info->long_vectors) {
  57. /* Maximum normal search range centered around _zero-vector_ */
  58. sxy = mmin(15, sxy);
  59. }
  60. else {
  61. /* Maximum extended search range centered around _predictor_ */
  62. sxy = mmin(15 - (2*H263_DEF_8X8_WIN+1), sxy);
  63. /* NB! */
  64. /* It is only possible to transmit motion vectors within
  65. a 15x15 window around the motion vector predictor
  66. for any 8x8 or 16x16 block */
  67. /* The reason for the search window's reduction above with
  68. 2*DEF_8X8_WIN+1 is that the 8x8 search may change the MV
  69. predictor for some of the blocks within the macroblock. When we
  70. impose the limitation above, we are sure that any 8x8 vector we
  71. might find is possible to transmit */
  72. /* We have found that with OBMC, DEF_8X8_WIN should be quite small
  73. for two reasons: (i) a good filtering effect, and (ii) not too
  74. many bits used for transferring the vectors. As can be seen
  75. above this is also useful to avoid a large limitation on the MV
  76. search range */
  77. /* It is possible to make sure the motion vectors found are legal
  78. in other less limiting ways than above, but this would be more
  79. complicated as well as time-consuming. Any good suggestions for
  80. improvement is welcome, though */
  81. #ifdef USE_C
  82. xoff = mmin(16,mmax(-16,xoff));
  83. yoff = mmin(16,mmax(-16,yoff));
  84. #else
  85. xoff = sv_H263lim_S(xoff,-16,16);
  86. yoff = sv_H263lim_S(yoff,-16,16);
  87. #endif
  88. /* in case xoff or yoff is odd */
  89. xoff= 2 * (xoff>>1);
  90. yoff= 2 * (yoff>>1);
  91. /* There is no need to check if (xoff + x_curr) points outside
  92. the picture, since the Extended Motion Vector Range is
  93. always used together with the Unrestricted MV mode */
  94. }
  95. lx = (H263Info->mv_outside_frame ? H263Info->pels + (H263Info->long_vectors?64:32) : H263Info->pels);
  96. ilow = x_curr + xoff - sxy;
  97. ihigh = x_curr + xoff + sxy;
  98. jlow = y_curr + yoff - sxy;
  99. jhigh = y_curr + yoff + sxy;
  100. if (!H263Info->mv_outside_frame) {
  101. if (ilow<0) ilow = 0;
  102. if (ihigh>xmax-16) ihigh = xmax-16;
  103. if (jlow<0) jlow = 0;
  104. if (jhigh>ymax-16) jhigh = ymax-16;
  105. }
  106. h_length = ihigh - ilow + 16;
  107. v_length = jhigh - jlow + 16;
  108. #if 1
  109. act_block = curr + x_curr + y_curr * H263Info->pels;
  110. search_area = prev + ilow + jlow * lx;
  111. #else
  112. act_block = svH263LoadArea(curr, x_curr, y_curr, 16, 16, H263Info->pels);
  113. search_area = svH263LoadArea(prev, ilow, jlow, h_length, v_length, lx);
  114. #endif
  115. /* subsampled version for ME level 1 */
  116. h_lenby2 = (h_length-1)>>1;
  117. v_lenby2 = (v_length-1)>>1;
  118. #if 1
  119. act_block_subs2 = H263Info->block_subs2;
  120. search_area_subs2 = H263Info->srch_area_subs2;
  121. sv_H263LdSubs2Area(curr, x_curr, y_curr, 8, 8, H263Info->pels, act_block_subs2, 8);
  122. sv_H263LdSubs2Area(prev, ilow, jlow, h_lenby2, v_lenby2, lx,
  123. search_area_subs2, H263_SRCH_RANGE);
  124. #else
  125. act_block_subs2 = sv_H263LoadSubs2Area(curr, x_curr, y_curr, 8, 8, H263Info->pels);
  126. search_area_subs2 = sv_H263LoadSubs2Area(prev, ilow, jlow, h_lenby2, v_lenby2, lx);
  127. #endif
  128. for (k = 0; k < 5; k++) {
  129. Min_FRAME[k] = INT_MAX;
  130. MVFrame[k].x = 0;
  131. MVFrame[k].y = 0;
  132. MVFrame[k].x_half = 0;
  133. MVFrame[k].y_half = 0;
  134. }
  135. /* match for zero (or [xoff,yoff]) motion vector on subsampled images */
  136. #ifndef USE_C
  137. ii = search_area_subs2 +
  138. ((x_curr+xoff-ilow)>>1) + ((y_curr+yoff-jlow)>>1)*H263_SRCH_RANGE;
  139. Min_FRAME[0] = sv_H263PEr8_init_S(ii,act_block_subs2,H263_SRCH_RANGE,8);
  140. #else
  141. ii = search_area_subs2 +
  142. ((x_curr+xoff-ilow)>>1) + ((y_curr+yoff-jlow)>>1)*H263_SRCH_RANGE;
  143. Min_FRAME[0] = sv_H263MySADBlock(ii,act_block_subs2,H263_SRCH_RANGE,8,INT_MAX);
  144. #endif
  145. MVFrame[0].x = (short)xoff;
  146. MVFrame[0].y = (short)yoff;
  147. /*** +-7 search on subsampled images: ***
  148. *** three-step +-4, +-2, +-1 ***/
  149. /* first step: +- 4 */
  150. /* sxylevel1 = 4; */
  151. i = x_curr + xoff - 8;
  152. j = y_curr + yoff - 8;
  153. for (k = 0; k < 32; k++) {
  154. if (i>=ilow && i<=ihigh && j>=jlow && j<=jhigh) {
  155. /* 8x8 integer pel MV */
  156. #ifndef USE_C
  157. ii = search_area_subs2+((i-ilow)>>1) + ((j-jlow)>>1)*H263_SRCH_RANGE;
  158. sad = sv_H263PError8x8_S(ii,act_block_subs2,H263_SRCH_RANGE,8,Min_FRAME[0]);
  159. #else
  160. ii = search_area_subs2+((i-ilow)>>1) + ((j-jlow)>>1)*H263_SRCH_RANGE;
  161. sad = sv_H263MySADBlock(ii,act_block_subs2,H263_SRCH_RANGE,8,Min_FRAME[0]);
  162. #endif
  163. if (sad < Min_FRAME[0]) {
  164. MVFrame[0].x = i - x_curr;
  165. MVFrame[0].y = j - y_curr;
  166. Min_FRAME[0] = sad;
  167. }
  168. }
  169. if (k<8) i+=2;
  170. else if (k<16) j+=2;
  171. else if (k<24) i-=2;
  172. else j-=2;
  173. }
  174. /* motion vectors after step1 - level1 */
  175. xlevel1=MVFrame[0].x;
  176. ylevel1=MVFrame[0].y;
  177. /* second step: +- 2 */
  178. /* sxylevel1 = 2; */
  179. level1_x_curr = x_curr + xlevel1;
  180. level1_y_curr = y_curr + ylevel1;
  181. i = level1_x_curr - 4;
  182. j = level1_y_curr - 4;
  183. for (k = 0; k < 16; k++) {
  184. if (i>=ilow && i<=ihigh && j>=jlow && j<=jhigh) {
  185. /* 8x8 integer pel MV */
  186. #ifndef USE_C
  187. ii = search_area_subs2+((i-ilow)>>1) + ((j-jlow)>>1) * H263_SRCH_RANGE;
  188. sad = sv_H263PError8x8_S(ii,act_block_subs2,H263_SRCH_RANGE,8,Min_FRAME[0]);
  189. #else
  190. ii = search_area_subs2+((i-ilow)>>1) + ((j-jlow)>>1) * H263_SRCH_RANGE;
  191. sad = sv_H263MySADBlock(ii,act_block_subs2,H263_SRCH_RANGE,8,Min_FRAME[0]);
  192. #endif
  193. if (sad < Min_FRAME[0]) {
  194. MVFrame[0].x = i - x_curr;
  195. MVFrame[0].y = j - y_curr;
  196. Min_FRAME[0] = sad;
  197. }
  198. }
  199. if (k<4) i+=2;
  200. else if (k<8) j+=2;
  201. else if (k<12) i-=2;
  202. else j-=2;
  203. }
  204. /* motion vectors after step2 - level1 */
  205. xlevel1=MVFrame[0].x;
  206. ylevel1=MVFrame[0].y;
  207. /* third step: +- 1 */
  208. /* sxylevel1 = 1; */
  209. level1_x_curr = x_curr + xlevel1;
  210. level1_y_curr = y_curr + ylevel1;
  211. i = level1_x_curr - 2;
  212. j = level1_y_curr - 2;
  213. for (k = 0; k < 8; k++) {
  214. if (i>=ilow && i<=ihigh && j>=jlow && j<=jhigh) {
  215. /* 8x8 integer pel MV */
  216. #ifndef USE_C
  217. ii = search_area_subs2+((i-ilow)>>1) + ((j-jlow)>>1) * H263_SRCH_RANGE;
  218. sad = sv_H263PError8x8_S(ii,act_block_subs2,H263_SRCH_RANGE,8,Min_FRAME[0]);
  219. #else
  220. ii = search_area_subs2+((i-ilow)>>1) + ((j-jlow)>>1) * H263_SRCH_RANGE;
  221. sad = sv_H263MySADBlock(ii,act_block_subs2,H263_SRCH_RANGE,8,Min_FRAME[0]);
  222. #endif
  223. if (sad < Min_FRAME[0]) {
  224. MVFrame[0].x = i - x_curr;
  225. MVFrame[0].y = j - y_curr;
  226. Min_FRAME[0] = sad;
  227. }
  228. }
  229. if (k<2) i+=2;
  230. else if (k<4) j+=2;
  231. else if (k<6) i-=2;
  232. else j-=2;
  233. }
  234. /* motion vectors after step3 - level1 */
  235. xlevel1=MVFrame[0].x;
  236. ylevel1=MVFrame[0].y;
  237. /* reset */
  238. Min_FRAME[0] = INT_MAX;
  239. MVFrame[0].x = 0;
  240. MVFrame[0].y = 0;
  241. /* Zero vector search*/
  242. if (x_curr-ilow < 0 || y_curr-jlow < 0 ||
  243. x_curr-ilow+H263_MB_SIZE > h_length || y_curr-jlow+H263_MB_SIZE > v_length) {
  244. /* in case the zero vector is outside the loaded area in search_area */
  245. #ifndef USE_C
  246. zero_area = prev + x_curr + y_curr * lx;
  247. *SAD_0 = sv_H263PError16x16_S(zero_area, act_block, lx, H263Info->pels, INT_MAX) -
  248. H263_PREF_NULL_VEC;
  249. #else
  250. zero_area = prev + x_curr + y_curr * lx;
  251. *SAD_0 = sv_H263SADMacroblock(zero_area, act_block, lx, H263Info->pels, INT_MAX) -
  252. H263_PREF_NULL_VEC;
  253. #endif
  254. }
  255. else {
  256. /* the zero vector is within search_area */
  257. #ifndef USE_C
  258. ii = search_area + (x_curr-ilow) + (y_curr-jlow)*lx;
  259. *SAD_0 = sv_H263PError16x16_S(ii, act_block, lx, H263Info->pels, INT_MAX) -
  260. H263_PREF_NULL_VEC;
  261. #else
  262. ii = search_area + (x_curr-ilow) + (y_curr-jlow)*lx;
  263. *SAD_0 = sv_H263SADMacroblock(ii, act_block, lx, H263Info->pels, INT_MAX) -
  264. H263_PREF_NULL_VEC;
  265. #endif
  266. }
  267. if (xoff == 0 && yoff == 0) {
  268. Min_FRAME[0] = *SAD_0;
  269. MVFrame[0].x = 0;
  270. MVFrame[0].y = 0;
  271. }
  272. if (xlevel1 == 0 && ylevel1 == 0) {
  273. Min_FRAME[0] = *SAD_0;
  274. MVFrame[0].x = 0;
  275. MVFrame[0].y = 0;
  276. }
  277. else {
  278. #ifndef USE_C
  279. ii = search_area + (x_curr+xlevel1-ilow) + (y_curr+ylevel1-jlow)*lx;
  280. sad = sv_H263PError16x16_S(ii, act_block, lx, H263Info->pels, Min_FRAME[0]) ;
  281. #else
  282. ii = search_area + (x_curr+xlevel1-ilow) + (y_curr+ylevel1-jlow)*lx;
  283. sad = sv_H263SADMacroblock(ii, act_block, lx, H263Info->pels, Min_FRAME[0]) ;
  284. #endif
  285. if (sad < Min_FRAME[0]) {
  286. MVFrame[0].x = (short)xlevel1;
  287. MVFrame[0].y = (short)ylevel1;
  288. Min_FRAME[0] = sad;
  289. }
  290. }
  291. /* NB: if xoff or yoff != 0, the Extended MV Range is used. If we
  292. allow the zero vector to be chosen prior to the half pel search
  293. in this case, the half pel search might lead to a
  294. non-transmittable vector (on the wrong side of zero). If SAD_0
  295. turns out to be the best SAD, the zero-vector will be chosen
  296. after half pel search instead. The zero-vector can be
  297. transmitted in all modes, no matter what the MV predictor is */
  298. /*** +-1 search on full-resolution images ***/
  299. level0_x_curr = x_curr + xlevel1;
  300. level0_y_curr = y_curr + ylevel1;
  301. /* sxylevel0=1; */
  302. i = level0_x_curr - 1;
  303. j = level0_y_curr - 1;
  304. for (k = 0; k < 8; k++) {
  305. if (i>=ilow && i<=ihigh && j>=jlow && j<=jhigh) {
  306. /* 16x16 integer pel MV */
  307. #ifndef USE_C
  308. ii = search_area + (i-ilow) + (j-jlow)*lx;
  309. sad = sv_H263PError16x16_S(ii, act_block, lx, H263Info->pels, Min_FRAME[0]) ;
  310. #else
  311. ii = search_area + (i-ilow) + (j-jlow)*lx;
  312. sad = sv_H263SADMacroblock(ii, act_block, lx, H263Info->pels, Min_FRAME[0]) ;
  313. #endif
  314. if (sad < Min_FRAME[0]) {
  315. MVFrame[0].x = i - x_curr;
  316. MVFrame[0].y = j - y_curr;
  317. Min_FRAME[0] = sad;
  318. }
  319. }
  320. if (k<2) i++;
  321. else if (k<4) j++;
  322. else if (k<6) i--;
  323. else j--;
  324. }
  325. if (H263Info->advanced) {
  326. xvec = MVFrame[0].x;
  327. yvec = MVFrame[0].y;
  328. if (!H263Info->long_vectors) {
  329. if (xvec > 15 - H263_DEF_8X8_WIN) { xvec = 15 - H263_DEF_8X8_WIN ;}
  330. if (yvec > 15 - H263_DEF_8X8_WIN) { yvec = 15 - H263_DEF_8X8_WIN ;}
  331. if (xvec < -15 + H263_DEF_8X8_WIN) { xvec = -15 + H263_DEF_8X8_WIN ;}
  332. if (yvec < -15 + H263_DEF_8X8_WIN) { yvec = -15 + H263_DEF_8X8_WIN ;}
  333. }
  334. adv_x_curr = x_curr + xvec;
  335. adv_y_curr = y_curr + yvec;
  336. sxy = H263_DEF_8X8_WIN;
  337. adv_ilow = adv_x_curr - sxy;
  338. adv_ihigh = adv_x_curr + sxy;
  339. adv_jlow = adv_y_curr - sxy;
  340. adv_jhigh = adv_y_curr + sxy;
  341. adv_h_length = adv_ihigh - adv_ilow + 16;
  342. adv_v_length = adv_jhigh - adv_jlow + 16;
  343. #if 1
  344. adv_search_area = prev + adv_ilow + adv_jlow * lx;
  345. #else
  346. adv_search_area = svH263LoadArea(prev, adv_ilow, adv_jlow,
  347. adv_h_length, adv_v_length, lx);
  348. #endif
  349. for (block = 0; block < 4; block++) {
  350. #ifndef USE_C
  351. ii = adv_search_area + (adv_x_curr-adv_ilow) + ((block&1)<<3) +
  352. (adv_y_curr-adv_jlow + ((block&2)<<2) )*lx;
  353. aa = act_block + ((block&1)<<3) + ((block&2)<<2)*H263Info->pels;
  354. Min_FRAME[block+1] = sv_H263PError8x8_S(ii,aa,lx,H263Info->pels,Min_FRAME[block+1]);
  355. #else
  356. ii = adv_search_area + (adv_x_curr-adv_ilow) + ((block&1)<<3) +
  357. (adv_y_curr-adv_jlow + ((block&2)<<2) )*lx;
  358. aa = act_block + ((block&1)<<3) + ((block&2)<<2)*H263Info->pels;
  359. Min_FRAME[block+1] = sv_H263MySADBlock(ii,aa,lx,H263Info->pels,Min_FRAME[block+1]);
  360. #endif
  361. MVFrame[block+1].x = MVFrame[0].x;
  362. MVFrame[block+1].y = MVFrame[0].y;
  363. }
  364. /* Spiral Full search */
  365. for (l = 1; l <= sxy; l++) {
  366. i = adv_x_curr - l;
  367. j = adv_y_curr - l;
  368. for (k = 0; k < 8*l; k++) {
  369. if (i>=adv_ilow && i<=adv_ihigh && j>=adv_jlow && j<=adv_jhigh) {
  370. /* 8x8 integer pel MVs */
  371. for (block = 0; block < 4; block++) {
  372. #ifndef USE_C
  373. ii = adv_search_area + (i-adv_ilow) + ((block&1)<<3) +
  374. (j-adv_jlow + ((block&2)<<2) )*lx;
  375. aa = act_block + ((block&1)<<3) + ((block&2)<<2)*H263Info->pels;
  376. sad = sv_H263PError8x8_S(ii, aa, lx, H263Info->pels, Min_FRAME[block+1]);
  377. #else
  378. ii = adv_search_area + (i-adv_ilow) + ((block&1)<<3) +
  379. (j-adv_jlow + ((block&2)<<2) )*lx;
  380. aa = act_block + ((block&1)<<3) + ((block&2)<<2)*H263Info->pels;
  381. sad = sv_H263MySADBlock(ii, aa, lx, H263Info->pels, Min_FRAME[block+1]);
  382. #endif
  383. if (sad < Min_FRAME[block+1]) {
  384. MVFrame[block+1].x = i - x_curr;
  385. MVFrame[block+1].y = j - y_curr;
  386. Min_FRAME[block+1] = sad;
  387. }
  388. }
  389. }
  390. if (k<2*l) i++;
  391. else if (k<4*l) j++;
  392. else if (k<6*l) i--;
  393. else j--;
  394. }
  395. }
  396. }
  397. i = x_curr/H263_MB_SIZE+1;
  398. j = y_curr/H263_MB_SIZE+1;
  399. if (!H263Info->advanced) {
  400. MV[0][j][i]->x = MVFrame[0].x;
  401. MV[0][j][i]->y = MVFrame[0].y;
  402. MV[0][j][i]->min_error = (short)Min_FRAME[0];
  403. }
  404. else {
  405. for (k = 0; k < 5; k++) {
  406. MV[k][j][i]->x = MVFrame[k].x;
  407. MV[k][j][i]->y = MVFrame[k].y;
  408. MV[k][j][i]->min_error = (short)Min_FRAME[k];
  409. }
  410. }
  411. #if 0
  412. ScFree(act_block);
  413. ScFree(search_area);
  414. ScFree(act_block_subs2);
  415. ScFree(search_area_subs2);
  416. if (H263Info->advanced) ScFree(adv_search_area);
  417. #endif
  418. return;
  419. }
  420.