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.

983 lines
30 KiB

  1. /* File: sv_h261_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. /*************************************************************
  19. This file does much of the motion estimation and compensation.
  20. *************************************************************/
  21. /*
  22. #define USE_C
  23. #define _SLIBDEBUG_
  24. */
  25. #include <stdio.h>
  26. #include <stdlib.h>
  27. #include <math.h>
  28. #include "sv_intrn.h"
  29. #include "SC_err.h"
  30. #include "sv_h261.h"
  31. #include "proto.h"
  32. #ifdef _SLIBDEBUG_
  33. #define _DEBUG_ 0 /* detailed debuging statements */
  34. #define _VERBOSE_ 0 /* show progress */
  35. #define _VERIFY_ 1 /* verify correct operation */
  36. #define _WARN_ 0 /* warnings about strange behavior */
  37. #endif
  38. #define Abs(value) ( (value < 0) ? (-value) : value)
  39. /*
  40. #define MEBUFSIZE 1024
  41. int MeVAR[MEBUFSIZE];
  42. int MeVAROR[MEBUFSIZE];
  43. int MeMWOR[MEBUFSIZE];
  44. int MeX[MEBUFSIZE];
  45. int MeY[MEBUFSIZE];
  46. int MeVal[MEBUFSIZE];
  47. int MeOVal[MEBUFSIZE];
  48. int PreviousMeOVal[MEBUFSIZE];
  49. */
  50. /*
  51. ** Function: CrawlMotionEstimation()
  52. ** Purpose: Does motion estimation on all aligned
  53. ** 16x16 blocks in two memory structures.
  54. */
  55. void CrawlMotionEstimation(SvH261Info_t *H261, unsigned char *pm,
  56. unsigned char *rm, unsigned char *cm)
  57. {
  58. const int SearchLimit=H261->ME_search, Threshold=H261->ME_threshold;
  59. const int height=H261->YHeight, width=H261->YWidth;
  60. const int ylimit=height-16, xlimit=width-16;
  61. unsigned char *pptr, *cptr;
  62. register int x, y, xd, yd;
  63. int MeN, MV;
  64. int i, j, val;
  65. int VAROR, MWOR;
  66. unsigned char *cptr2;
  67. _SlibDebug(_VERBOSE_,
  68. printf("CrawlMotionEstimation(H261=0x%p, %p, %p, %p) In\n",
  69. H261, pm, rm, cm) );
  70. for(MeN=0, y=0; y<height; y+=16)
  71. {
  72. cptr=cm + (y * width);
  73. pptr=rm + (y * width);
  74. _SlibDebug(_VERIFY_ && ((int)cptr)%8,
  75. printf("FastBME() cm Not quad word aligned\n") );
  76. for(x=0; x<width; x+=16, MeN++,cptr+=16,pptr+=16)
  77. {
  78. xd=yd=0;
  79. #ifdef USE_C
  80. MV = blockdiff16_C(cptr, pptr, width,400000);
  81. #else
  82. MV = blockdiff16(cptr, pptr, width,400000);
  83. #endif
  84. _SlibDebug(_DEBUG_, printf("First MV=%d\n",MV) );
  85. H261->PreviousMeOVal[MeN] = H261->MeOVal[MeN];
  86. H261->MeOVal[MeN] = MV;
  87. if (MV >= Threshold)
  88. {
  89. int d=0, MVnew, bestxd, bestyd, lastxd, lastyd;
  90. #ifdef USE_C
  91. #define bd(nxd, nyd) {MVnew=blockdiff16_C(cptr, pptr+nxd+(nyd*width), width, MV); \
  92. if (MVnew<MV) {bestxd=nxd; bestyd=nyd; MV=MVnew;} \
  93. _SlibDebug(_DEBUG_, printf("MVnew=%d x=%d y=%d\n",MVnew,nxd,nyd) );}
  94. #else
  95. #define bd(nxd, nyd) {MVnew=blockdiff16(cptr, pptr+nxd+(nyd*width), width, MV); \
  96. if (MVnew<MV) {bestxd=nxd; bestyd=nyd; MV=MVnew;} \
  97. _SlibDebug(_DEBUG_, printf("MVnew=%d x=%d y=%d\n",MVnew,nxd,nyd) );}
  98. #endif
  99. lastxd=0;
  100. lastyd=0;
  101. while (MV >= Threshold &&
  102. xd>-SearchLimit && xd<SearchLimit &&
  103. yd>-SearchLimit && yd<SearchLimit)
  104. {
  105. bestxd=xd;
  106. bestyd=yd;
  107. _SlibDebug(_DEBUG_, printf("xd=%d yd=%d d=%d MV=%d\n",xd, yd, d, MV));
  108. switch (d) /* d is a vector for movement */
  109. {
  110. case -4: /* moved down & right */
  111. if (x+xd<xlimit)
  112. {
  113. bd(xd+1, yd-1);
  114. bd(xd+1, yd);
  115. if (y+yd<ylimit)
  116. {
  117. bd(xd+1, yd+1);
  118. bd(xd, yd+1);
  119. bd(xd-1, yd+1);
  120. }
  121. }
  122. else if (y+yd<ylimit)
  123. {
  124. bd(xd, yd+1);
  125. bd(xd-1, yd+1);
  126. }
  127. break;
  128. case -3: /* moved down */
  129. if (y+yd>0)
  130. {
  131. bd(xd-1, yd-1);
  132. bd(xd, yd-1);
  133. bd(xd+1, yd-1);
  134. }
  135. break;
  136. case -2: /* moved up & right */
  137. if (x+xd<xlimit)
  138. {
  139. bd(xd+1, yd+1);
  140. bd(xd+1, yd);
  141. if (y+yd>0)
  142. {
  143. bd(xd+1, yd-1);
  144. bd(xd, yd-1);
  145. bd(xd-1, yd-1);
  146. }
  147. }
  148. else if (y+yd>0)
  149. {
  150. bd(xd, yd-1);
  151. bd(xd-1, yd-1);
  152. }
  153. break;
  154. case -1: /* moved left */
  155. if (x+xd>0)
  156. {
  157. if (y+yd > 0)
  158. bd(xd-1, yd-1);
  159. bd(xd-1, yd);
  160. bd(xd-1, yd+1);
  161. }
  162. break;
  163. case 0: /* no movement */
  164. if (x+xd<=0) /* at left edge */
  165. {
  166. if (y+yd<=0) /* at top-left corner */
  167. {
  168. bd(xd+1, yd);
  169. bd(xd+1, yd+1);
  170. bd(xd, yd+1);
  171. }
  172. else if (y+yd>=ylimit) /* at bottom-left corner */
  173. {
  174. bd(xd+1, yd);
  175. bd(xd+1, yd-1);
  176. bd(xd, yd-1);
  177. }
  178. else /* at left edge, y within limits */
  179. {
  180. bd(xd, yd+1);
  181. bd(xd, yd-1);
  182. bd(xd+1, yd-1);
  183. bd(xd+1, yd);
  184. bd(xd+1, yd+1);
  185. }
  186. }
  187. else if (x+xd>=xlimit) /* at right edge */
  188. {
  189. if (y+yd<=0) /* at top-right corner */
  190. {
  191. bd(xd-1, yd);
  192. bd(xd-1, yd+1);
  193. bd(xd, yd+1);
  194. }
  195. else if (y+yd>=ylimit) /* at bottom-right corner */
  196. {
  197. bd(xd-1, yd);
  198. bd(xd-1, yd-1);
  199. bd(xd, yd-1);
  200. }
  201. else /* at right edge, y within limits */
  202. {
  203. bd(xd, yd+1);
  204. bd(xd, yd-1);
  205. bd(xd-1, yd-1);
  206. bd(xd-1, yd);
  207. bd(xd-1, yd+1);
  208. }
  209. }
  210. else if (y+yd<=0) /* at top edge, x within limits */
  211. {
  212. bd(xd-1, yd);
  213. bd(xd+1, yd);
  214. bd(xd-1, yd+1);
  215. bd(xd, yd+1);
  216. bd(xd+1, yd+1);
  217. }
  218. else if (y+yd>=ylimit) /* at bottom edge, x within limits */
  219. {
  220. bd(xd-1, yd);
  221. bd(xd+1, yd);
  222. bd(xd-1, yd-1);
  223. bd(xd, yd-1);
  224. bd(xd+1, yd-1);
  225. }
  226. else /* within all limits */
  227. {
  228. bd(xd-1, yd);
  229. bd(xd+1, yd);
  230. bd(xd-1, yd-1);
  231. bd(xd-1, yd+1);
  232. bd(xd+1, yd-1);
  233. bd(xd+1, yd+1);
  234. bd(xd, yd-1);
  235. bd(xd, yd+1);
  236. }
  237. break;
  238. case 1: /* moved right */
  239. if (x+xd<xlimit)
  240. {
  241. if (y+yd > 0)
  242. bd(xd+1, yd-1);
  243. bd(xd+1, yd);
  244. bd(xd+1, yd+1);
  245. }
  246. break;
  247. case 2: /* moved down & left */
  248. if (x+xd>0)
  249. {
  250. if (y+yd > 0)
  251. bd(xd-1, yd-1);
  252. bd(xd-1, yd);
  253. if (y+yd<ylimit)
  254. {
  255. bd(xd-1, yd+1);
  256. bd(xd, yd+1);
  257. bd(xd+1, yd+1);
  258. }
  259. }
  260. else if (y+yd<ylimit)
  261. {
  262. bd(xd, yd+1);
  263. bd(xd+1, yd+1);
  264. }
  265. break;
  266. case 3: /* moved down */
  267. if (y+yd<ylimit)
  268. {
  269. bd(xd-1, yd+1);
  270. bd(xd, yd+1);
  271. bd(xd+1, yd+1);
  272. }
  273. break;
  274. case 4: /* moved down & right */
  275. if (x+xd>0)
  276. {
  277. bd(xd-1, yd);
  278. bd(xd-1, yd+1);
  279. if (y+yd>0)
  280. {
  281. bd(xd-1, yd-1);
  282. bd(xd, yd-1);
  283. bd(xd+1, yd-1);
  284. }
  285. }
  286. else if (y+yd>0)
  287. {
  288. bd(xd, yd-1);
  289. bd(xd+1, yd-1);
  290. }
  291. break;
  292. default:
  293. _SlibDebug(_VERIFY_,
  294. printf("Illegal movement: d = %d\n", d) );
  295. }
  296. if (bestxd==xd && bestyd==yd) /* found closest motion vector */
  297. break;
  298. lastxd=xd;
  299. lastyd=yd;
  300. xd=bestxd;
  301. yd=bestyd;
  302. d = (xd-lastxd) + 3*(yd-lastyd); /* calculate the movement */
  303. }
  304. }
  305. H261->MeX[MeN] = xd;
  306. H261->MeY[MeN] = yd;
  307. H261->MeVal[MeN] = MV;
  308. H261->MeVAR[MeN] = MV;
  309. _SlibDebug(_DEBUG_ && (xd || yd),
  310. printf("New MeN=%d x=%d y=%d MX=%d MY=%d MV=%d\n",
  311. MeN, x, y, xd, yd, MV) );
  312. #if 1
  313. for(cptr2 = cptr, MWOR=0, i=0; i<16; i++)
  314. {
  315. for(j=0; j<16; j++)
  316. MWOR += *cptr2++;
  317. cptr2 += width-16;
  318. }
  319. MWOR /= 256;
  320. H261->MeMWOR[MeN] = MWOR;
  321. for(cptr2 = cptr, VAROR=0, i=0; i<16; i++)
  322. {
  323. for (j=0; j<16; j++)
  324. {
  325. val=*cptr2++ - MWOR; if (val>0) VAROR += val; else VAROR -= val;
  326. }
  327. cptr2 += width-16;
  328. }
  329. H261->MeVAROR[MeN] = VAROR;
  330. _SlibDebug(_DEBUG_,
  331. printf("x=%d y=%d MV=%d MWOR=%d VAROR=%d\n", x, y, MV, MWOR, VAROR) );
  332. #if 0
  333. for(cptr2 = cptr, MWOR=0, i=0; i<16; i++)
  334. {
  335. for(j=0; j<16; j++)
  336. MWOR += *cptr2++;
  337. cptr2 += width-16;
  338. }
  339. MWOR /= 256;
  340. H261->MeMWOR[MeN] = MV/10; /* MWOR; */
  341. for(cptr2 = cptr, VAROR=0, i=0; i<16; i++)
  342. {
  343. for (j=0; j<16; j++)
  344. {
  345. val=*cptr2++ - MWOR; if (val>0) VAROR += val; else VAROR -= val;
  346. }
  347. cptr2 += width-16;
  348. }
  349. H261->MeVAROR[MeN] = MV; /* VAROR; */
  350. _SlibDebug(_DEBUG_,
  351. printf("x=%d y=%d MV=%d MWOR=%d VAROR=%d\n", x, y, MV, MWOR, VAROR) );
  352. #endif
  353. #else
  354. H261->MeMWOR[MeN] = 0;
  355. H261->MeVAROR[MeN] = 0;
  356. #endif
  357. }
  358. }
  359. _SlibDebug(_DEBUG_, printf("CrawlMotionEstimation() Out\n") );
  360. }
  361. /*
  362. ** Function: BruteMotionEstimation()
  363. ** Purpose: Does a brute-force motion estimation on all aligned
  364. ** 16x16 blocks in two memory structures.
  365. */
  366. void BruteMotionEstimation(SvH261Info_t *H261, unsigned char *rm,
  367. unsigned char *rrm, unsigned char *cm)
  368. {
  369. const int SearchLimit=H261->ME_search, Threshold=H261->ME_threshold/8;
  370. const int YHeight=H261->YHeight, YWidth=H261->YWidth;
  371. const int YHeight16=YHeight-16, YWidth16=YWidth-16;
  372. unsigned char *bptr, *cptr, *baseptr;
  373. register int MeN, i, j, x, y, px, py;
  374. int MX, MY, MV, val;
  375. int VAR, VAROR, MWOR;
  376. const int jump = YWidth;
  377. unsigned char data;
  378. _SlibDebug(_VERBOSE_,
  379. printf("BruteMotionEstimation(H261=0x%p, %p, %p, %p) In\n",
  380. H261, rm, rrm, cm) );
  381. _SlibDebug(_VERIFY_ && ((int)cm)%8,
  382. printf("FastBME() cm Not quad aligned\n") );
  383. for(MeN=0, y=0; y<YHeight; y+=16)
  384. {
  385. baseptr=cm + (y * YWidth);
  386. for(x=0; x<YWidth; x+=16, MeN++,baseptr+=16)
  387. {
  388. MX=MY=0;
  389. bptr = rrm + x + (y * YWidth);
  390. #if 1
  391. #ifdef USE_C
  392. MV = fblockdiff16_C(baseptr, bptr, YWidth, 65536) / 4;
  393. #else
  394. MV = blockdiff16(baseptr, bptr, YWidth, 65536) / 4;
  395. #endif
  396. #else
  397. #ifdef USE_C
  398. MV = fblockdiff16_sub_C(baseptr, bptr, jump);
  399. #else
  400. MV = fblockdiff16_sub(baseptr, bptr, jump);
  401. #endif
  402. #endif
  403. H261->PreviousMeOVal[MeN] = H261->MeOVal[MeN];
  404. H261->MeOVal[MeN] = MV*4;
  405. _SlibDebug(_DEBUG_, printf("[00]MX %d MY %d MV %d\n",MX,MY,MV) );
  406. if (MV >= Threshold)
  407. {
  408. int Xl, Xh, Yl, Yh;
  409. /* MV = 362182; */
  410. Xl = ((x-SearchLimit)/2)*2;
  411. Xh = ((x+SearchLimit)/2)*2;
  412. Yl = ((y-SearchLimit)/2)*2;
  413. Yh = ((y+SearchLimit)/2)*2;
  414. if (Xl < 0) Xl = 0;
  415. if (Xh > YWidth16) Xh = YWidth16;
  416. if (Yl < 0) Yl = 0;
  417. if (Yh > YHeight16) Yh = YHeight16;
  418. for (px=Xl; px<=Xh && MV >= Threshold; px +=2)
  419. {
  420. bptr = rrm + px + (Yl * YWidth);
  421. for (py=Yl; py<=Yh && MV >= Threshold; py += 2, bptr+=YWidth*2)
  422. {
  423. _SlibDebug(_DEBUG_, printf("blockdiff16_sub(%p, %p, %d, %d)\n",
  424. baseptr,bptr,YWidth,MV) );
  425. #ifdef USE_C
  426. val = blockdiff16_sub_C(baseptr, bptr, jump, MV);
  427. #else
  428. val = blockdiff16_sub(baseptr, bptr, jump, MV);
  429. #endif
  430. _SlibDebug(_DEBUG_, printf("blockdiff16_sub() Out val=%d\n", val) );
  431. if (val < MV)
  432. {
  433. MV = val;
  434. MX = px - x;
  435. MY = py - y;
  436. }
  437. }
  438. }
  439. px = MX + x;
  440. py = MY + y;
  441. MV = 65536;
  442. Xl = px - 1;
  443. Xh = px + 1;
  444. Yl = py - 1;
  445. Yh = py + 1;
  446. if (Xl < 0) Xl = 0;
  447. if (Xh > YWidth16) Xh = YWidth16;
  448. if (Yl < 0) Yl = 0;
  449. if (Yh > YHeight16) Yh = YHeight16;
  450. for (px=Xl; px<=Xh && MV>=Threshold; px++)
  451. {
  452. bptr = rrm + px + (Yl * YWidth);
  453. for (py=Yl; py<=Yh && MV>=Threshold; py++, bptr+=YWidth)
  454. {
  455. #ifdef USE_C
  456. val = blockdiff16_C(baseptr, bptr, YWidth, MV);
  457. #else
  458. val = blockdiff16(baseptr, bptr, YWidth, MV);
  459. #endif
  460. if (val < MV)
  461. {
  462. MV = val;
  463. MX = px - x;
  464. MY = py - y;
  465. }
  466. }
  467. }
  468. }
  469. _SlibDebug(_DEBUG_, printf("MeN=%d x=%d y=%d MX=%d MY=%d MV=%d\n",
  470. MeN, x, y, MX, MY, MV) );
  471. H261->MeX[MeN] = MX;
  472. H261->MeY[MeN] = MY;
  473. H261->MeVal[MeN] = MV;
  474. bptr = rrm + MX + x + ((MY+y) * YWidth);
  475. cptr = baseptr;
  476. for(VAR=0, MWOR=0, i=0; i<16; i++)
  477. {
  478. for(j=0; j<16; j++)
  479. {
  480. MWOR += (data=*cptr++);
  481. val = *bptr++ - data;
  482. VAR += (val > 0) ? val : -val;
  483. }
  484. bptr += YWidth16;
  485. cptr += YWidth16;
  486. }
  487. H261->MeVAR[MeN] = VAR;
  488. MWOR /= 256;
  489. H261->MeMWOR[MeN] = MWOR;
  490. cptr = baseptr;
  491. for(VAROR=0, i=0; i<16; i++)
  492. {
  493. for (j=0; j<16; j++)
  494. {
  495. val=*cptr++ - MWOR; if (val>0) VAROR += val; else VAROR -= val;
  496. }
  497. cptr += YWidth16;
  498. }
  499. H261->MeVAROR[MeN] = VAROR;
  500. }
  501. }
  502. _SlibDebug(_DEBUG_, printf("BruteMotionEstimation() Out\n") );
  503. }
  504. /*
  505. * logarithmetic search block matching
  506. *
  507. * blk: top left pel of (16*h) block
  508. * h: height of block
  509. * lx: distance (in bytes) of vertically adjacent pels in ref,blk
  510. * org: top left pel of source reference picture
  511. * ref: top left pel of reconstructed reference picture
  512. * i0,j0: center of search window
  513. * sx,sy: half widths of search window
  514. * xmax,ymax: right/bottom limits of search area
  515. * iminp,jminp: pointers to where the result is stored
  516. * result is given as half pel offset from ref(0,0)
  517. * i.e. NOT relative to (i0,j0)
  518. */
  519. void Logsearch(SvH261Info_t *H261, unsigned char *rm, unsigned char *rrm, unsigned char *cm)
  520. {
  521. const int SearchLimit=H261->ME_search, Threshold=H261->ME_threshold/8;
  522. const int YHeight=H261->YHeight, YWidth=H261->YWidth;
  523. const int YHeight16=YHeight-16, YWidth16=YWidth-16;
  524. unsigned char *bptr, *cptr, *baseptr;
  525. register int MeN, i, j, x, y, px, py;
  526. int MX, MY, MV, val;
  527. int VAR, VAROR, MWOR;
  528. const int jump = YWidth;
  529. unsigned char data;
  530. int bsx,bsy,ijk;
  531. int srched_loc[33][33] ;
  532. struct five_loc{int x ; int y ;} ij[5] ;
  533. _SlibDebug(_VERBOSE_,
  534. printf("BruteMotionEstimation(H261=0x%p, %p, %p, %p) In\n",
  535. H261, rm, rrm, cm) );
  536. _SlibDebug(_VERIFY_ && ((int)cm)%8,
  537. printf("FastBME() cm Not quad aligned\n") );
  538. for(MeN=0, y=0; y<YHeight; y+=16)
  539. {
  540. baseptr=cm + (y * YWidth);
  541. for(x=0; x<YWidth; x+=16, MeN++,baseptr+=16)
  542. {
  543. MX=MY=0;
  544. bptr = rrm + x + (y * YWidth);
  545. #if 1
  546. #ifdef USE_C
  547. MV = blockdiff16_C(baseptr, bptr, YWidth, 65536) / 4;
  548. #else
  549. MV = blockdiff16(baseptr, bptr, YWidth, 65536) / 4;
  550. #endif
  551. #else
  552. #ifdef USE_C
  553. MV = fblockdiff16_sub_C(baseptr, bptr, jump);
  554. #else
  555. MV = fblockdiff16_sub(baseptr, bptr, jump);
  556. #endif
  557. #endif
  558. H261->PreviousMeOVal[MeN] = H261->MeOVal[MeN];
  559. H261->MeOVal[MeN] = MV*4;
  560. _SlibDebug(_DEBUG_, printf("[00]MX %d MY %d MV %d\n",MX,MY,MV) );
  561. if (MV >= Threshold)
  562. {
  563. int Xl, Xh, Yl, Yh;
  564. Xl = x-SearchLimit;
  565. Xh = x+SearchLimit;
  566. Yl = y-SearchLimit;
  567. Yh = y+SearchLimit;
  568. if (Xl < 0) Xl = 0;
  569. if (Xh > YWidth16) Xh = YWidth16;
  570. if (Yl < 0) Yl = 0;
  571. if (Yh > YHeight16) Yh = YHeight16;
  572. /* x-y step size */
  573. if(SearchLimit > 8) bsx = bsy = 8 ;
  574. else if(SearchLimit > 4) bsx = bsy = 4 ;
  575. else bsx = bsy = 2 ;
  576. /* initialized searched locations */
  577. for(i=0;i<33;i++)
  578. for(j=0;j<33;j++) srched_loc[i][j] = 0 ;
  579. /* The center of the seach window */
  580. i = x;
  581. j = y;
  582. /* reduce window size by half until the window is 3x3 */
  583. for(;bsx > 1;bsx /= 2, bsy /= 2){
  584. /* five searched locations for each step */
  585. ij[0].x = i ; ij[0].y = j ;
  586. ij[1].x = i - bsx ; ij[1].y = j ;
  587. ij[2].x = i + bsx ; ij[2].y = j ;
  588. ij[3].x = i ; ij[3].y = j - bsy;
  589. ij[4].x = i ; ij[4].y = j + bsy;
  590. /* search */
  591. for(ijk = 0; ijk < 5; ijk++) {
  592. if(ij[ijk].x>=Xl && ij[ijk].x<=Xh &&
  593. ij[ijk].y>=Yl && ij[ijk].y<=Yh &&
  594. srched_loc[ij[ijk].x - x + 16][ij[ijk].y - y + 16] == 0)
  595. {
  596. #ifdef USE_C
  597. val = fblockdiff16_sub_C(baseptr, rrm +ij[ijk].x+ij[ijk].y*YWidth, jump);
  598. #else
  599. val = fblockdiff16_sub(baseptr, rrm +ij[ijk].x+ij[ijk].y*YWidth, jump);
  600. #endif
  601. srched_loc[ij[ijk].x - x + 16][ij[ijk].y - y + 16] = 1 ;
  602. if(val<MV)
  603. {
  604. MV = val ;
  605. MX = ij[ijk].x - x;
  606. MY = ij[ijk].y - y;
  607. }
  608. }
  609. }
  610. /* if the best point was found, stop the search */
  611. if(MV == 0 ) break ;
  612. else { /* else, go to next step */
  613. i = MX + x;
  614. j = MY + y;
  615. }
  616. }
  617. px = MX + x;
  618. py = MY + y;
  619. MV = 65536;
  620. Xl = px - 1;
  621. Xh = px + 1;
  622. Yl = py -1;
  623. Yh = py + 1;
  624. if (Xl < 0) Xl = 0;
  625. if (Xh > YWidth16) Xh = YWidth16;
  626. if (Yl < 0) Yl = 0;
  627. if (Yh > YHeight16) Yh = YHeight16;
  628. for (px=Xl; px<=Xh && MV>=Threshold; px++)
  629. {
  630. bptr = rrm + px + (Yl * YWidth);
  631. for (py=Yl; py<=Yh && MV>=Threshold; py++, bptr+=YWidth)
  632. {
  633. #ifdef USE_C
  634. val = blockdiff16_C(baseptr, bptr, YWidth, MV);
  635. #else
  636. val = blockdiff16(baseptr, bptr, YWidth, MV);
  637. #endif
  638. if (val < MV)
  639. {
  640. MV = val;
  641. MX = px - x;
  642. MY = py - y;
  643. }
  644. }
  645. }
  646. }
  647. _SlibDebug(_DEBUG_, printf("MeN=%d x=%d y=%d MX=%d MY=%d MV=%d\n",
  648. MeN, x, y, MX, MY, MV) );
  649. H261->MeX[MeN] = MX;
  650. H261->MeY[MeN] = MY;
  651. H261->MeVal[MeN] = MV;
  652. bptr = rrm + MX + x + ((MY+y) * YWidth);
  653. cptr = baseptr;
  654. for(VAR=0, MWOR=0, i=0; i<16; i++)
  655. {
  656. for(j=0; j<16; j++)
  657. {
  658. MWOR += (data=*cptr++);
  659. val = *bptr++ - data;
  660. VAR += (val > 0) ? val : -val;
  661. }
  662. bptr += YWidth16;
  663. cptr += YWidth16;
  664. }
  665. H261->MeVAR[MeN] = VAR;
  666. MWOR /= 256;
  667. H261->MeMWOR[MeN] = MWOR;
  668. cptr = baseptr;
  669. for(VAROR=0, i=0; i<16; i++)
  670. {
  671. for (j=0; j<16; j++)
  672. {
  673. val=*cptr++ - MWOR; if (val>0) VAROR += val; else VAROR -= val;
  674. }
  675. cptr += YWidth16;
  676. }
  677. H261->MeVAROR[MeN] = VAROR;
  678. }
  679. }
  680. _SlibDebug(_DEBUG_, printf("BruteMotionEstimation() Out\n") );
  681. }
  682. #if 0
  683. /*************** This is the original BME *********************/
  684. /*
  685. ** Function: FastBME()
  686. ** Purpose: Does a fast brute-force motion estimation with two indexes
  687. ** into two memory structures. The motion estimation has a
  688. ** short-circuit abort to speed up calculation.
  689. */
  690. void FastBME(SvH261Info_t *H261, int rx, int ry,
  691. unsigned char *rm, unsigned char *rrm,
  692. int cx, int cy, unsigned char *cm, int MeN)
  693. {
  694. int px,py;
  695. int MX, MY, MV, OMV;
  696. int Xl, Xh, Yl, Yh;
  697. int VAR, VAROR, MWOR;
  698. int i,j,data,val;
  699. unsigned char *bptr,*cptr;
  700. unsigned char *baseptr;
  701. int count = 0;
  702. const int jump = 2*H261->YWidth;
  703. _SlibDebug(_DEBUG_, printf("FastBME(H261=0x%p) YWidth=%d YHeight=%d\n",
  704. H261,H261->YWidth,H261->YHeight) );
  705. MX=MY=MV=0;
  706. bptr=rm + rx + (ry * H261->YWidth);
  707. baseptr=cm + cx + (cy * H261->YWidth);
  708. _SlibDebug(_VERIFY_ && ((int)baseptr)%8,
  709. printf(((int)baseptr)%8, "FastBME() baseptr Not quad aligned\n") );
  710. cptr=baseptr;
  711. #ifdef USE_C
  712. MV = fblockdiff16_sub_C(baseptr, bptr, H261->YWidth);
  713. #else
  714. MV = fblockdiff16_sub(baseptr, bptr, jump);
  715. #endif
  716. OMV=MV*4;
  717. _SlibDebug(_DEBUG_, printf("[00]MX %d MY %d MV %d\n",MX,MY,MV) );
  718. cptr = baseptr;
  719. px=rx;
  720. py=ry;
  721. if(OMV > H261->MotionThreshold)
  722. {
  723. MV = 362182;
  724. Xl = ((rx-H261->SearchLimit)/2)*2;
  725. Xh = ((rx+H261->SearchLimit)/2)*2;
  726. Yl = ((ry-H261->SearchLimit)/2)*2;
  727. Yh = ((ry+H261->SearchLimit)/2)*2;
  728. Xl = (Xl < 0) ? 0 : Xl;
  729. Xh = (Xh > H261->YWidth-16) ? (H261->YWidth-16) : Xh;
  730. Yl = (Yl < 0) ? 0 : Yl;
  731. Yh = (Yh > H261->YHeight-16) ? (H261->YHeight-16) : Yh;
  732. for(px=Xl; px <=Xh ; px += 2) {
  733. for(py=Yl; py <=Yh; py += 2) {
  734. bptr = rm + px + (py * H261->YWidth);
  735. _SlibDebug(_DEBUG_, printf("blockdiff16_sub(%p, %p, %d, %d)\n",
  736. baseptr,bptr,H261->YWidth,MV) );
  737. #ifdef USE_C
  738. val = blockdiff16_sub_C(baseptr, bptr, H261->YWidth);
  739. #else
  740. val = blockdiff16_sub(baseptr, bptr, jump, MV);
  741. #endif
  742. _SlibDebug(_DEBUG_, printf("blockdiff16_sub() Out val=%d\n",val));
  743. if (val < MV)
  744. {
  745. MV = val;
  746. MX = px - rx;
  747. MY = py - ry;
  748. }
  749. }
  750. }
  751. px = MX + rx;
  752. py = MY + ry;
  753. bptr = rrm + px +(py*H261->YWidth);
  754. MV = 232141;
  755. Xl = px -1;
  756. Xh = px +1;
  757. Yl = py -1;
  758. Yh = py +1;
  759. Xl = (Xl < 0) ? 0 : Xl;
  760. Xh = (Xh > (H261->YWidth-16)) ? (H261->YWidth-16) : Xh;
  761. Yl = (Yl < 0) ? 0 : Yl;
  762. Yh = (Yh > (H261->YHeight-16)) ? (H261->YHeight-16) : Yh;
  763. count = 0;
  764. for(px=Xl;px<=Xh;px++) {
  765. for(py=Yl;py<=Yh;py++) {
  766. bptr = rrm + px + (py * H261->YWidth);
  767. #ifdef USE_C
  768. val = blockdiff16_C(baseptr, bptr, H261->YWidth);
  769. #else
  770. val = blockdiff16(baseptr, bptr, H261->YWidth,MV);
  771. #endif
  772. if (val < MV)
  773. {
  774. MV = val;
  775. MX = px - rx;
  776. MY = py - ry;
  777. }
  778. }
  779. }
  780. }
  781. bptr = rm + (MX+rx) + ((MY+ry) * H261->YWidth);
  782. cptr = baseptr;
  783. for(VAR=0,MWOR=0,i=0;i<16;i++)
  784. {
  785. for(j=0;j<16;j++)
  786. {
  787. data = *bptr - *cptr;
  788. VAR += Abs(data);
  789. MWOR += *cptr;
  790. bptr++;
  791. cptr++;
  792. }
  793. bptr += (H261->YWidth - 16);
  794. cptr += (H261->YWidth - 16);
  795. }
  796. MWOR = MWOR/256;
  797. VAR = VAR;
  798. cptr = baseptr;
  799. for(VAROR=0,i=0;i<16;i++)
  800. {
  801. for(j=0;j<16;j++)
  802. {
  803. VAROR += Abs(*cptr-MWOR);
  804. cptr++;
  805. }
  806. cptr += (H261->YWidth - 16);
  807. }
  808. /* VAROR = VAROR; */
  809. _SlibDebug(_DEBUG_, printf("\n Pos %d MX %d MY %d", MeN, MX, MY) );
  810. H261->MeVAR[MeN] = VAR;
  811. H261->MeVAROR[MeN] = VAROR;
  812. H261->MeMWOR[MeN] = MWOR;
  813. H261->MeX[MeN] = MX;
  814. H261->MeY[MeN] = MY;
  815. H261->MeVal[MeN] = MV;
  816. H261->PreviousMeOVal[MeN] = H261->MeOVal[MeN];
  817. H261->MeOVal[MeN] = OMV;
  818. _SlibDebug(_DEBUG_, printf("FastBME() Out\n") );
  819. }
  820. /*
  821. ** Function: BruteMotionEstimation2()
  822. ** Purpose: Does a brute-force motion estimation on all aligned
  823. ** 16x16 blocks in two memory structures.
  824. */
  825. void BruteMotionEstimation2(SvH261Info_t *H261, unsigned char *pmem,
  826. unsigned char *recmem, unsigned char *fmem)
  827. {
  828. BEGIN("BruteMotionEstimation2");
  829. const int YHeight=H261->YHeight, YWidth=H261->YWidth;
  830. int x,y,MeN;
  831. _SlibDebug(_DEBUG_, printf("BruteMotionEstimation(H261=0x%p,%p,%p,%p) In\n",
  832. H261, pmem, recmem, fmem) );
  833. for(MeN=0,y=0; y<YHeight; y+=16)
  834. for(x=0; x<YWidth; x+=16, MeN++)
  835. FastBME(H261,x,y,pmem,recmem, x,y,fmem,MeN);
  836. _SlibDebug(_DEBUG_, printf("BruteMotionEstimation2() Out\n") );
  837. }
  838. #endif
  839. int blockdiff16_C(unsigned char* ptr1, unsigned char *ptr2, int Jump, int mv)
  840. {
  841. int Sum=0, Pixel_diff, i, j, inc=Jump-16;
  842. _SlibDebug(_DEBUG_,
  843. printf("blockdiff16_C(ptr1=%p, ptr2=%p, Jump=%d, MV=%d)\n",
  844. ptr1, ptr2, Jump, mv) );
  845. for(j=0;j<16;j++) {
  846. for(i=0;i<16;i++) {
  847. Pixel_diff = (*ptr1++ - *ptr2++);
  848. Sum += Abs(Pixel_diff);
  849. }
  850. _SlibDebug(_DEBUG_, printf ("Sum: %d MV: %d \n" , Sum, mv) );
  851. if (Sum > mv)
  852. break;
  853. ptr1 += inc;
  854. ptr2 += inc;
  855. }
  856. return(Sum);
  857. }
  858. int blockdiff16_sub_C(unsigned char* ptr1, unsigned char *ptr2,
  859. int Jump, int mv)
  860. {
  861. int Sum=0, Pixel_diff, i,j,inc=2*Jump-16;
  862. _SlibDebug(_DEBUG_,
  863. printf("blockdiff16_sub_C(ptr1=%p, ptr2=%p, Jump=%d, MV=%d)\n",
  864. ptr1, ptr2, Jump, mv) );
  865. for(j=0; j<8; j++) {
  866. for(i=0; i<8; i++) {
  867. Pixel_diff = (*ptr1 - *ptr2);
  868. ptr1 += 2;
  869. ptr2 += 2;
  870. Sum += Abs(Pixel_diff);
  871. }
  872. _SlibDebug(_DEBUG_, printf("Sum: %d MV: %d \n", Sum, mv) );
  873. if (Sum > mv)
  874. break;
  875. ptr1 += inc;
  876. ptr2 += inc;
  877. }
  878. _SlibDebug(_DEBUG_, printf("blockdiff16_sub_C() Out\n") );
  879. return(Sum);
  880. }
  881. /*
  882. ** Function: fblockdiff16_sub_C
  883. ** Purpose: First blcok diff.
  884. */
  885. int fblockdiff16_sub_C(unsigned char* ptr1, unsigned char *ptr2,
  886. int Jump)
  887. {
  888. int Sum=0, Pixel_diff, i,j, inc=2*Jump-16;
  889. _SlibDebug(_DEBUG_,
  890. printf("fblockdiff16_sub_C(ptr1=%p, ptr2=%p, Jump=%d)\n",
  891. ptr1, ptr2, Jump) );
  892. for(j=0; j<8; j++) {
  893. for(i=0; i<8; i++) {
  894. Pixel_diff = (*ptr1 - *ptr2);
  895. ptr1 += 2;
  896. ptr2 += 2;
  897. Sum += Abs(Pixel_diff);
  898. }
  899. ptr1 += inc;
  900. ptr2 += inc;
  901. }
  902. return(Sum);
  903. }