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.

545 lines
17 KiB

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