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.

2145 lines
65 KiB

  1. /* File: sv_h263_pred.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. #define _SLIBDEBUG_
  20. */
  21. #include "sv_h263.h"
  22. #include "proto.h"
  23. #ifndef USE_C
  24. #include "perr.h"
  25. #endif
  26. #ifdef _SLIBDEBUG_
  27. #include "sc_debug.h"
  28. #define _DEBUG_ 0 /* detailed debuging statements */
  29. #define _VERBOSE_ 1 /* show progress */
  30. #define _VERIFY_ 0 /* verify correct operation */
  31. #define _WARN_ 1 /* warnings about strange behavior */
  32. #endif
  33. static int roundtab[] = {0,0,0,1,1,1,1,1,1,1,1,1,1,1,2,2};
  34. static void FindForwLumPredPB(SvH263CompressInfo_t *H263Info,
  35. unsigned char *prev_ipol, int x_curr, int y_curr,
  36. H263_MotionVector *fr, short *pred, int TRD, int TRB,
  37. int bdx, int bdy, int bs, int comp);
  38. void FindBiDirLumPredPB(short *recon_P, H263_MotionVector *fr, short *pred, int TRD,
  39. int TRB, int bdx, int bdy, int nh, int nv);
  40. void BiDirLumPredPB(H263_MB_Structure *recon_P, H263_MotionVector *fr,
  41. H263_MB_Structure *pred, int TRD, int TRB, int bdx, int bdy);
  42. void FindBiDirChrPredPB(H263_MB_Structure *recon_P, int dx, int dy,
  43. H263_MB_Structure *pred);
  44. void FindBiDirLimits(int vec, int *start, int *stop, int nhv);
  45. void FindBiDirChromaLimits(int vec, int *start, int *stop);
  46. void BiDirPredBlock(int xstart, int xstop, int ystart, int ystop,
  47. int xvec, int yvec, short *recon, short *pred, int bl);
  48. static void DoPredChrom_P(SvH263CompressInfo_t *H263Info,
  49. int x_curr, int y_curr, int dx, int dy,
  50. H263_PictImage *curr, H263_PictImage *prev,
  51. H263_MB_Structure *pred_error);
  52. static void FindPred(SvH263CompressInfo_t *H263Info,
  53. int x, int y, H263_MotionVector *fr, unsigned char *prev,
  54. short *pred, int bs, int comp);
  55. static void FindPredOBMC(SvH263CompressInfo_t *H263Info,
  56. int x, int y, H263_MotionVector *MV[5][H263_MBR+1][H263_MBC+2],
  57. unsigned char *prev, short *pred, int comp, int PB);
  58. static void ReconLumBlock_P(SvH263CompressInfo_t *H263Info,
  59. int x, int y, H263_MotionVector *fr,
  60. unsigned char *prev, short *data, int bs, int comp);
  61. static void ReconChromBlock_P(SvH263CompressInfo_t *H263Info,
  62. int x_curr, int y_curr, int dx, int dy,
  63. H263_PictImage *prev, H263_MB_Structure *data);
  64. static void FindChromBlock_P(SvH263CompressInfo_t *H263Info,
  65. int x_curr, int y_curr, int dx, int dy,
  66. H263_PictImage *prev, H263_MB_Structure *data);
  67. /**********************************************************************
  68. *
  69. * Name: Predict_P
  70. * Description: Predicts P macroblock in advanced or normal
  71. * mode
  72. *
  73. * Input: pointers to current and previous frames
  74. * and previous interpolated image,
  75. * position and motion vector array
  76. * Returns: pointer to MB_Structure of data to be coded
  77. * Side effects: allocates memory to MB_Structure
  78. *
  79. ***********************************************************************/
  80. void sv_H263PredictP(SvH263CompressInfo_t *H263Info,
  81. H263_PictImage *curr_image, H263_PictImage *prev_image,
  82. unsigned char *prev_ipol, int x, int y,
  83. H263_MotionVector *MV[6][H263_MBR+1][H263_MBC+2], int PB,
  84. H263_MB_Structure *pred_error)
  85. {
  86. short curr[16][16];
  87. short pred[16][16];
  88. H263_MotionVector *fr0,*fr1,*fr2,*fr3,*fr4;
  89. int sum, dx, dy;
  90. int xmb, ymb;
  91. #ifdef USE_C
  92. int m,n;
  93. #endif
  94. xmb = x/H263_MB_SIZE+1;
  95. ymb = y/H263_MB_SIZE+1;
  96. fr0 = MV[0][ymb][xmb];
  97. fr1 = MV[1][ymb][xmb];
  98. fr2 = MV[2][ymb][xmb];
  99. fr3 = MV[3][ymb][xmb];
  100. fr4 = MV[4][ymb][xmb];
  101. /* Find MB in current image */
  102. sv_H263FindMB(H263Info, x, y, curr_image->lum, curr);
  103. /* Find prediction based on half pel MV */
  104. if (H263Info->advanced) {
  105. FindPredOBMC(H263Info, x, y, MV, prev_ipol, &pred[0][0], 0, PB);
  106. FindPredOBMC(H263Info, x, y, MV, prev_ipol, &pred[0][8], 1, PB);
  107. FindPredOBMC(H263Info, x, y, MV, prev_ipol, &pred[8][0], 2, PB);
  108. FindPredOBMC(H263Info, x, y, MV, prev_ipol, &pred[8][8], 3, PB);
  109. }
  110. else
  111. FindPred(H263Info, x, y, fr0, prev_ipol, &pred[0][0], 16, 0);
  112. /* Do the actual prediction */
  113. if (fr0->Mode == H263_MODE_INTER || fr0->Mode == H263_MODE_INTER_Q) {
  114. #ifndef USE_C
  115. sv_H263Sub256_S(&(curr[0][0]), &(pred[0][0]), &(pred_error->lum[0][0]), 16);
  116. #else
  117. for (n = 0; n < H263_MB_SIZE; n++)
  118. for (m = 0; m < H263_MB_SIZE; m++)
  119. pred_error->lum[n][m] = curr[n][m] - pred[n][m];
  120. #endif
  121. dx = 2*fr0->x + fr0->x_half;
  122. dy = 2*fr0->y + fr0->y_half;
  123. dx = ( dx % 4 == 0 ? dx >> 1 : (dx>>1)|1 );
  124. dy = ( dy % 4 == 0 ? dy >> 1 : (dy>>1)|1 );
  125. DoPredChrom_P(H263Info, x, y, dx, dy, curr_image, prev_image, pred_error);
  126. }
  127. else if (fr0->Mode == H263_MODE_INTER4V) {
  128. #ifndef USE_C
  129. sv_H263Sub256_S(&(curr[0][0]), &(pred[0][0]), &(pred_error->lum[0][0]), 16);
  130. #else
  131. for (n = 0; n < H263_MB_SIZE; n++)
  132. for (m = 0; m < H263_MB_SIZE; m++)
  133. pred_error->lum[n][m] = curr[n][m] - pred[n][m];
  134. #endif
  135. sum = 2*fr1->x + fr1->x_half + 2*fr2->x + fr2->x_half +
  136. 2*fr3->x + fr3->x_half + 2*fr4->x + fr4->x_half ;
  137. dx = sign(sum)*(roundtab[abs(sum)%16] + (abs(sum)/16)*2);
  138. sum = 2*fr1->y + fr1->y_half + 2*fr2->y + fr2->y_half +
  139. 2*fr3->y + fr3->y_half + 2*fr4->y + fr4->y_half;
  140. dy = sign(sum)*(roundtab[abs(sum)%16] + (abs(sum)/16)*2);
  141. DoPredChrom_P(H263Info, x, y, dx, dy, curr_image, prev_image, pred_error);
  142. }
  143. else
  144. {
  145. _SlibDebug(_WARN_, printf("Illegal Mode in Predict_P (pred.c)\n") );
  146. }
  147. return;
  148. }
  149. #ifdef USE_C /* replaced by svH263Ierr16 */
  150. int sv_H263SADMBinteger(short *ii, short *act_block, int h_length, int min_sofar, int max_rtn)
  151. {
  152. int i, sad = 0;
  153. short *kk;
  154. kk = act_block;
  155. i = 16;
  156. while (i--) {
  157. sad += (abs(*ii - *kk ) +
  158. abs(*(ii+1 ) - *(kk+1) ) +
  159. abs(*(ii+2) - *(kk+2) ) +
  160. abs(*(ii+3 ) - *(kk+3) ) +
  161. abs(*(ii+4) - *(kk+4) ) +
  162. abs(*(ii+5 ) - *(kk+5) ) +
  163. abs(*(ii+6) - *(kk+6) ) +
  164. abs(*(ii+7 ) - *(kk+7) ) +
  165. abs(*(ii+8) - *(kk+8) ) +
  166. abs(*(ii+9 ) - *(kk+9) ) +
  167. abs(*(ii+10) - *(kk+10)) +
  168. abs(*(ii+11) - *(kk+11)) +
  169. abs(*(ii+12) - *(kk+12)) +
  170. abs(*(ii+13) - *(kk+13)) +
  171. abs(*(ii+14) - *(kk+14)) +
  172. abs(*(ii+15) - *(kk+15)) );
  173. /* min_sofar = INT_MAX always */
  174. if (sad > min_sofar) return INT_MAX;
  175. ii += h_length;
  176. kk += 16;
  177. }
  178. return sad;
  179. }
  180. #endif
  181. /***********************************************************************
  182. *
  183. * Name: Predict_B
  184. * Description: Predicts the B macroblock in PB-frame prediction
  185. *
  186. * Input: pointers to current frame, previous recon. frame,
  187. * pos. in image, MV-data, reconstructed macroblock
  188. * from image ahead
  189. * Returns: pointer to differential MB data after prediction
  190. * Side effects: allocates memory to MB_structure
  191. *
  192. ***********************************************************************/
  193. void sv_H263PredictB(SvH263CompressInfo_t *H263Info,
  194. H263_PictImage *curr_image, H263_PictImage *prev_image,
  195. unsigned char *prev_ipol,int x, int y,
  196. H263_MotionVector *MV[5][H263_MBR+1][H263_MBC+2],
  197. H263_MB_Structure *recon_P, int TRD,int TRB,
  198. H263_MB_Structure *p_err, H263_MB_Structure *pred)
  199. {
  200. int i,j,k;
  201. int sad, sad_min=INT_MAX, bdx=0, bdy=0;
  202. int start_x, start_y, end_x, end_y ;
  203. short curr[16][16];
  204. H263_MotionVector *f[5];
  205. int xvec, yvec, mvx, mvy;
  206. #ifndef USE_C
  207. unsigned char *curCr, *curCb ;
  208. #endif
  209. for(k=0; k<=4; k++) f[k]=MV[k][y/H263_MB_SIZE+1][x/H263_MB_SIZE+1];
  210. /* Find MB in current image */
  211. sv_H263FindMB(H263Info, x, y, curr_image->lum, curr);
  212. if(f[0]->Mode == H263_MODE_INTER4V) { /* Mode INTER4V */
  213. FindForwLumPredPB(H263Info, prev_ipol,x,y,f[1],&pred->lum[0][0],TRD,TRB,0,0,8,0);
  214. FindForwLumPredPB(H263Info, prev_ipol,x,y,f[2],&pred->lum[0][8],TRD,TRB,0,0,8,1);
  215. FindForwLumPredPB(H263Info, prev_ipol,x,y,f[3],&pred->lum[8][0],TRD,TRB,0,0,8,2);
  216. FindForwLumPredPB(H263Info, prev_ipol,x,y,f[4],&pred->lum[8][8],TRD,TRB,0,0,8,3);
  217. #ifndef USE_C
  218. sad_min = sv_H263Ierr16_S(&curr[0][0],&pred->lum[0][0], 16, INT_MAX, INT_MAX);
  219. #else
  220. sad_min = sv_H263SADMBinteger(&curr[0][0],&pred->lum[0][0], 16, INT_MAX, INT_MAX);
  221. #endif
  222. sad_min -= H263_PREF_PBDELTA_NULL_VEC;
  223. bdx = bdy = 0;
  224. /* Find forward prediction */
  225. /* Luma */
  226. for (j = -H263_DEF_PBDELTA_WIN; j <= H263_DEF_PBDELTA_WIN; j++) {
  227. for (i = -H263_DEF_PBDELTA_WIN; i <= H263_DEF_PBDELTA_WIN; i++) {
  228. if(i != 0 || j != 0) {
  229. FindForwLumPredPB(H263Info, prev_ipol,x,y,f[1],&pred->lum[0][0],TRD,TRB,i,j,8,0);
  230. FindForwLumPredPB(H263Info, prev_ipol,x,y,f[2],&pred->lum[0][8],TRD,TRB,i,j,8,1);
  231. FindForwLumPredPB(H263Info, prev_ipol,x,y,f[3],&pred->lum[8][0],TRD,TRB,i,j,8,2);
  232. FindForwLumPredPB(H263Info, prev_ipol,x,y,f[4],&pred->lum[8][8],TRD,TRB,i,j,8,3);
  233. #ifndef USE_C
  234. sad = sv_H263Ierr16_S(&curr[0][0],&pred->lum[0][0], 16, sad_min, INT_MAX);
  235. #else
  236. sad = sv_H263SADMBinteger(&curr[0][0],&pred->lum[0][0], 16, sad_min, INT_MAX);
  237. #endif
  238. if (sad < sad_min) { sad_min = sad; bdx = i; bdy = j; }
  239. }
  240. }
  241. }
  242. FindForwLumPredPB(H263Info, prev_ipol,x,y,f[1],&pred->lum[0][0],TRD,TRB,bdx,bdy,8,0);
  243. FindForwLumPredPB(H263Info, prev_ipol,x,y,f[2],&pred->lum[0][8],TRD,TRB,bdx,bdy,8,1);
  244. FindForwLumPredPB(H263Info, prev_ipol,x,y,f[3],&pred->lum[8][0],TRD,TRB,bdx,bdy,8,2);
  245. FindForwLumPredPB(H263Info, prev_ipol,x,y,f[4],&pred->lum[8][8],TRD,TRB,bdx,bdy,8,3);
  246. /* chroma vectors are sum of B luma vectors divided and rounded */
  247. xvec = yvec = 0;
  248. for (k = 1; k <= 4; k++) {
  249. xvec += TRB*(2*f[k]->x + f[k]->x_half)/TRD + bdx;
  250. yvec += TRB*(2*f[k]->y + f[k]->y_half)/TRD + bdy;
  251. }
  252. /* round values according to TABLE 16/H.263 */
  253. i = sign(xvec)*(roundtab[abs(xvec)%16] + (abs(xvec)/16)*2);
  254. j = sign(yvec)*(roundtab[abs(yvec)%16] + (abs(yvec)/16)*2);
  255. FindChromBlock_P(H263Info, x, y, i, j, prev_image, pred);
  256. /* Find bidirectional prediction */
  257. FindBiDirLumPredPB(&recon_P->lum[0][0],f[1],&pred->lum[0][0],TRD,TRB,bdx,bdy,0,0);
  258. FindBiDirLumPredPB(&recon_P->lum[0][8],f[2],&pred->lum[0][8],TRD,TRB,bdx,bdy,1,0);
  259. FindBiDirLumPredPB(&recon_P->lum[8][0],f[3],&pred->lum[8][0],TRD,TRB,bdx,bdy,0,1);
  260. FindBiDirLumPredPB(&recon_P->lum[8][8],f[4],&pred->lum[8][8],TRD,TRB,bdx,bdy,1,1);
  261. /* chroma vectors are sum of B luma vectors divided and rounded */
  262. xvec = yvec = 0;
  263. for (k = 1; k <= 4; k++) {
  264. mvx = 2*f[k]->x + f[k]->x_half;
  265. mvy = 2*f[k]->y + f[k]->y_half;
  266. xvec += bdx == 0 ? (TRB-TRD) * mvx / TRD : TRB * mvx / TRD + bdx - mvx;
  267. yvec += bdy == 0 ? (TRB-TRD) * mvy / TRD : TRB * mvy / TRD + bdy - mvy;
  268. }
  269. /* round values according to TABLE 16/H.263 */
  270. i = sign(xvec)*(roundtab[abs(xvec)%16] + (abs(xvec)/16)*2);
  271. j = sign(yvec)*(roundtab[abs(yvec)%16] + (abs(yvec)/16)*2);
  272. FindBiDirChrPredPB(recon_P, i, j, pred);
  273. }
  274. else { /* Mode INTER or INTER_Q */
  275. if( f[0]->Mode==H263_MODE_INTRA || f[0]->Mode==H263_MODE_INTRA_Q ||
  276. (f[0]->x==0 && f[0]->y==0 && f[0]->x_half==0 && f[0]->y_half==0))
  277. bdx = bdy = 0;
  278. else{
  279. /* Find forward prediction */
  280. FindForwLumPredPB(H263Info, prev_ipol,x,y,f[0],&pred->lum[0][0],TRD,TRB,0,0,16,0);
  281. #ifndef USE_C
  282. sad_min = sv_H263Ierr16_S(&curr[0][0],&pred->lum[0][0], 16, INT_MAX, INT_MAX);
  283. #else
  284. sad_min = sv_H263SADMBinteger(&curr[0][0],&pred->lum[0][0], 16, INT_MAX, INT_MAX);
  285. #endif
  286. sad_min -= H263_PREF_PBDELTA_NULL_VEC;
  287. bdx = bdy = 0;
  288. start_x = start_y = -H263_DEF_PBDELTA_WIN;
  289. end_x = end_y = H263_DEF_PBDELTA_WIN;
  290. /* To keep things simple I turn off PB delta vectors at the edges */
  291. if(!H263Info->mv_outside_frame) {
  292. if (x == 0 || x == H263Info->pels - H263_MB_SIZE) start_x = end_x = 0;
  293. if (y == 0 || y == H263Info->lines - H263_MB_SIZE) start_y = end_y = 0;
  294. }
  295. for (j = start_y; j <= end_y; j++) {
  296. for (i = start_x; i <= end_x; i++) {
  297. if(i || j) {
  298. FindForwLumPredPB(H263Info, prev_ipol,x,y,f[0],&pred->lum[0][0],
  299. TRD,TRB,i,j,16,0);
  300. #ifndef USE_C
  301. sad = sv_H263Ierr16_S(&curr[0][0],&pred->lum[0][0], 16, sad_min, INT_MAX);
  302. #else
  303. sad = sv_H263SADMBinteger(&curr[0][0],&pred->lum[0][0], 16, sad_min, INT_MAX);
  304. #endif
  305. if (sad < sad_min) { sad_min = sad; bdx = i; bdy = j; }
  306. }
  307. }
  308. }
  309. }
  310. FindForwLumPredPB(H263Info, prev_ipol,x,y,f[0],&pred->lum[0][0],TRD,TRB, bdx,bdy,16,0);
  311. xvec = 4 * (TRB*(2*f[0]->x + f[0]->x_half) / TRD + bdx);
  312. yvec = 4 * (TRB*(2*f[0]->y + f[0]->y_half) / TRD + bdy);
  313. /* round values according to TABLE 16/H.263 */
  314. i = sign(xvec)*(roundtab[abs(xvec)%16] + (abs(xvec)/16)*2);
  315. j = sign(yvec)*(roundtab[abs(yvec)%16] + (abs(yvec)/16)*2);
  316. FindChromBlock_P(H263Info, x, y, i, j, prev_image, pred);
  317. /* Find bidirectional prediction */
  318. BiDirLumPredPB(recon_P, f[0], pred, TRD, TRB, bdx, bdy);
  319. /* chroma vectors */
  320. mvx = 2*f[0]->x + f[0]->x_half;
  321. xvec = bdx == 0 ? (TRB-TRD) * mvx / TRD : TRB * mvx / TRD + bdx - mvx;
  322. xvec *= 4;
  323. mvy = 2*f[0]->y + f[0]->y_half;
  324. yvec = bdy == 0 ? (TRB-TRD) * mvy / TRD : TRB * mvy / TRD + bdy - mvy;
  325. yvec *= 4;
  326. /* round values according to TABLE 16/H.263 */
  327. i = sign(xvec)*(roundtab[abs(xvec)%16] + (abs(xvec)/16)*2);
  328. j = sign(yvec)*(roundtab[abs(yvec)%16] + (abs(yvec)/16)*2);
  329. FindBiDirChrPredPB(recon_P, i, j, pred);
  330. }
  331. /* store PB-deltas */
  332. MV[5][y/H263_MB_SIZE+1][x/H263_MB_SIZE+1]->x = (short)bdx; /* is in half pel format */
  333. MV[5][y/H263_MB_SIZE+1][x/H263_MB_SIZE+1]->y = (short)bdy;
  334. MV[5][y/H263_MB_SIZE+1][x/H263_MB_SIZE+1]->x_half = 0;
  335. MV[5][y/H263_MB_SIZE+1][x/H263_MB_SIZE+1]->y_half = 0;
  336. #ifndef USE_C
  337. /* Do the actual prediction */
  338. curCr = curr_image->lum + x + y*H263Info->pels ;
  339. sv_H263Sub16_S(curCr, &(pred->lum[0][0]), &(p_err->lum[0][0]), H263Info->pels) ;
  340. y >>= 1; x >>= 1;
  341. curCr = curr_image->Cr + x + y*H263Info->cpels ;
  342. curCb = curr_image->Cb + x + y*H263Info->cpels ;
  343. sv_H263Sub8_S(curCr, &(pred->Cr[0][0]), &(p_err->Cr[0][0]), H263Info->cpels);
  344. sv_H263Sub8_S(curCb, &(pred->Cb[0][0]), &(p_err->Cb[0][0]), H263Info->cpels);
  345. #else
  346. /* Do the actual prediction */
  347. for (j = 0; j < H263_MB_SIZE; j++)
  348. for (i = 0; i < H263_MB_SIZE; i++)
  349. p_err->lum[j][i] =
  350. *(curr_image->lum+x+i + (y+j)*H263Info->pels) - pred->lum[j][i];
  351. y >>= 1;
  352. x >>= 1;
  353. for (j = 0; j < H263_MB_SIZE>>1; j++)
  354. for (i = 0; i < H263_MB_SIZE>>1; i++) {
  355. p_err->Cr[j][i] = *(curr_image->Cr+x+i + (y+j)*H263Info->cpels) - pred->Cr[j][i];
  356. p_err->Cb[j][i] = *(curr_image->Cb+x+i + (y+j)*H263Info->cpels) - pred->Cb[j][i];
  357. }
  358. #endif
  359. return ;
  360. }
  361. /***********************************************************************
  362. *
  363. * Name: MB_Recon_B
  364. * Description: Reconstructs the B macroblock in PB-frame
  365. * prediction
  366. *
  367. * Input: pointers previous recon. frame, pred. diff.,
  368. * pos. in image, MV-data, reconstructed macroblock
  369. * from image ahead
  370. * Returns: pointer to reconstructed MB data
  371. * Side effects: allocates memory to MB_structure
  372. *
  373. ***********************************************************************/
  374. void sv_H263MBReconB(SvH263CompressInfo_t *H263Info,
  375. H263_PictImage *prev_image, H263_MB_Structure *diff,
  376. unsigned char *prev_ipol,int x, int y,
  377. H263_MotionVector *MV[5][H263_MBR+1][H263_MBC+2],
  378. H263_MB_Structure *recon_P,int TRD, int TRB,
  379. H263_MB_Structure *recon_B,H263_MB_Structure *pred)
  380. {
  381. #if 1
  382. int j;
  383. unsigned qword *dpc ;
  384. unsigned UNALIGNED qword *dpa, *dpb;
  385. dpc = (unsigned qword *) &(recon_B->lum[0][0]);
  386. dpb = (unsigned qword *) &(pred->lum[0][0]);
  387. dpa = (unsigned qword *) &(diff->lum[0][0]);
  388. for (j = 0; j < 12; j++) {
  389. *dpc++ = *dpb++ + *dpa++ ;
  390. *dpc++ = *dpb++ + *dpa++ ;
  391. *dpc++ = *dpb++ + *dpa++ ;
  392. *dpc++ = *dpb++ + *dpa++ ;
  393. *dpc++ = *dpb++ + *dpa++ ;
  394. *dpc++ = *dpb++ + *dpa++ ;
  395. *dpc++ = *dpb++ + *dpa++ ;
  396. *dpc++ = *dpb++ + *dpa++ ;
  397. }
  398. #else
  399. int j,k;
  400. int dx, dy, bdx, bdy, mvx, mvy, xvec, yvec;
  401. H263_MotionVector *f[5];
  402. for (k = 0; k <= 4; k++)
  403. f[k] = MV[k][y/H263_MB_SIZE+1][x/H263_MB_SIZE+1];
  404. bdx = MV[5][y/H263_MB_SIZE+1][x/H263_MB_SIZE+1]->x;
  405. bdy = MV[5][y/H263_MB_SIZE+1][x/H263_MB_SIZE+1]->y;
  406. if (f[0]->Mode == H263_MODE_INTER4V) { /* Mode INTER4V */
  407. /* Find forward prediction */
  408. /* Luma */
  409. FindForwLumPredPB(H263Info, prev_ipol,x,y,f[1],&pred->lum[0][0],TRD,TRB,bdx,bdy,8,0);
  410. FindForwLumPredPB(H263Info, prev_ipol,x,y,f[2],&pred->lum[0][8],TRD,TRB,bdx,bdy,8,1);
  411. FindForwLumPredPB(H263Info, prev_ipol,x,y,f[3],&pred->lum[8][0],TRD,TRB,bdx,bdy,8,2);
  412. FindForwLumPredPB(H263Info, prev_ipol,x,y,f[4],&pred->lum[8][8],TRD,TRB,bdx,bdy,8,3);
  413. /* chroma vectors are sum of B luma vectors divided and rounded */
  414. xvec = yvec = 0;
  415. for (k = 1; k <= 4; k++) {
  416. xvec += TRB*(2*f[k]->x + f[k]->x_half)/TRD + bdx;
  417. yvec += TRB*(2*f[k]->y + f[k]->y_half)/TRD + bdy;
  418. }
  419. /* round values according to TABLE 16/H.263 */
  420. dx = sign(xvec)*(roundtab[abs(xvec)%16] + (abs(xvec)/16)*2);
  421. dy = sign(yvec)*(roundtab[abs(yvec)%16] + (abs(yvec)/16)*2);
  422. FindChromBlock_P(H263Info, x, y, dx, dy, prev_image, pred);
  423. /* Find bidirectional prediction */
  424. FindBiDirLumPredPB(&recon_P->lum[0][0], f[1], &pred->lum[0][0],
  425. TRD, TRB, bdx, bdy, 0, 0);
  426. FindBiDirLumPredPB(&recon_P->lum[0][8], f[2], &pred->lum[0][8],
  427. TRD, TRB, bdx, bdy, 1, 0);
  428. FindBiDirLumPredPB(&recon_P->lum[8][0], f[3], &pred->lum[8][0],
  429. TRD, TRB, bdx, bdy, 0, 1);
  430. FindBiDirLumPredPB(&recon_P->lum[8][8], f[4], &pred->lum[8][8],
  431. TRD, TRB, bdx, bdy, 1, 1);
  432. /* chroma vectors are sum of B luma vectors divided and rounded */
  433. xvec = yvec = 0;
  434. for (k = 1; k <= 4; k++) {
  435. mvx = 2*f[k]->x + f[k]->x_half;
  436. mvy = 2*f[k]->y + f[k]->y_half;
  437. xvec += bdx == 0 ? (TRB-TRD) * mvx / TRD : TRB * mvx / TRD + bdx - mvx;
  438. yvec += bdy == 0 ? (TRB-TRD) * mvy / TRD : TRB * mvy / TRD + bdy - mvy;
  439. }
  440. /* round values according to TABLE 16/H.263 */
  441. dx = sign(xvec)*(roundtab[abs(xvec)%16] + (abs(xvec)/16)*2);
  442. dy = sign(yvec)*(roundtab[abs(yvec)%16] + (abs(yvec)/16)*2);
  443. FindBiDirChrPredPB(recon_P, dx, dy, pred);
  444. }
  445. else { /* Mode INTER or INTER_Q */
  446. /* Find forward prediction */
  447. FindForwLumPredPB(H263Info, prev_ipol,x,y,f[0],&pred->lum[0][0],TRD,TRB,
  448. bdx,bdy,16,0);
  449. xvec = 4 * (TRB*(2*f[0]->x + f[0]->x_half) / TRD + bdx);
  450. yvec = 4 * (TRB*(2*f[0]->y + f[0]->y_half) / TRD + bdy);
  451. /* round values according to TABLE 16/H.263 */
  452. dx = sign(xvec)*(roundtab[abs(xvec)%16] + (abs(xvec)/16)*2);
  453. dy = sign(yvec)*(roundtab[abs(yvec)%16] + (abs(yvec)/16)*2);
  454. FindChromBlock_P(H263Info, x, y, dx, dy, prev_image, pred);
  455. /* Find bidirectional prediction */
  456. BiDirLumPredPB(recon_P, f[0], pred, TRD, TRB, bdx, bdy);
  457. /* chroma vectors */
  458. mvx = 2*f[0]->x + f[0]->x_half;
  459. xvec = bdx == 0 ? (TRB-TRD) * mvx / TRD : TRB * mvx / TRD + bdx - mvx;
  460. xvec *= 4;
  461. mvy = 2*f[0]->y + f[0]->y_half;
  462. yvec = bdy == 0 ? (TRB-TRD) * mvy / TRD : TRB * mvy / TRD + bdy - mvy;
  463. yvec *= 4;
  464. /* round values according to TABLE 16/H.263 */
  465. dx = sign(xvec)*(roundtab[abs(xvec)%16] + (abs(xvec)/16)*2);
  466. dy = sign(yvec)*(roundtab[abs(yvec)%16] + (abs(yvec)/16)*2);
  467. FindBiDirChrPredPB(recon_P, dx, dy, pred);
  468. }
  469. /* Reconstruction */
  470. for (j = 0; j < H263_MB_SIZE; j++)
  471. for (k = 0; k < H263_MB_SIZE; k++)
  472. recon_B->lum[j][k] = pred->lum[j][k] + diff->lum[j][k];
  473. for (j = 0; j < H263_MB_SIZE>>1; j++)
  474. for (k = 0; k < H263_MB_SIZE>>1; k++) {
  475. recon_B->Cr[j][k] = pred->Cr[j][k] + diff->Cr[j][k];
  476. recon_B->Cb[j][k] = pred->Cb[j][k] + diff->Cb[j][k];
  477. }
  478. #endif
  479. return ;
  480. }
  481. /**********************************************************************
  482. *
  483. * Name: FindForwLumPredPB
  484. * Description: Finds the forward luma prediction in PB-frame
  485. * pred.
  486. *
  487. * Input: pointer to prev. recon. frame, current positon,
  488. * MV structure and pred. structure to fill
  489. *
  490. ***********************************************************************/
  491. static void FindForwLumPredPB(SvH263CompressInfo_t *H263Info,
  492. unsigned char *prev_ipol, int x_curr, int y_curr,
  493. H263_MotionVector *fr, short *pred, int TRD, int TRB,
  494. int bdx, int bdy, int bs, int comp)
  495. {
  496. int i,j,i2,j2;
  497. int xvec,yvec,lx2;
  498. unsigned char *ptn ;
  499. lx2 = ((H263Info->mv_outside_frame ? H263Info->pels + (H263Info->long_vectors?64:32) : H263Info->pels)) * 2;
  500. /* Luma */
  501. xvec = (TRB)*(2*fr->x + fr->x_half)/TRD + bdx;
  502. yvec = (TRB)*(2*fr->y + fr->y_half)/TRD + bdy;
  503. x_curr = (x_curr + ((comp&1)<<3)) * 2 + xvec;
  504. y_curr = (y_curr + ((comp&2)<<2)) * 2 + yvec;
  505. x_curr += (y_curr * lx2) ;
  506. ptn = prev_ipol + x_curr ;
  507. lx2 = (lx2 << 1) ;
  508. #ifdef USE_C
  509. for (j = j2 = 0; j < bs; j++, j2 += lx2)
  510. for (i = i2 = 0; i < bs; i++, i2 += 2)
  511. *(pred+i+j*16) = *(ptn + i2 + j2);
  512. #else
  513. if(bs == 16) {
  514. sv_H263Intpix16_S(ptn, pred, lx2, 16) ;
  515. }
  516. else {
  517. for (j = j2 = 0; j < bs; j++, j2 += lx2)
  518. for (i = i2 = 0; i < bs; i++, i2 += 2)
  519. *(pred+i+j*16) = *(ptn + i2 + j2);
  520. }
  521. #endif
  522. return;
  523. }
  524. /**********************************************************************
  525. *
  526. * Name: FindBiDirLumPredPB
  527. * Description: Finds the bi-dir. luma prediction in PB-frame
  528. * prediction
  529. *
  530. * Input: pointer to future recon. data, current positon,
  531. * MV structure and pred. structure to fill
  532. *
  533. ***********************************************************************/
  534. void FindBiDirLumPredPB(short *recon_P, H263_MotionVector *fr, short *pred, int TRD,
  535. int TRB, int bdx, int bdy, int nh, int nv)
  536. {
  537. int xstart,xstop,ystart,ystop;
  538. int xvec,yvec, mvx, mvy;
  539. mvx = 2*fr->x + fr->x_half;
  540. mvy = 2*fr->y + fr->y_half;
  541. xvec = (bdx == 0 ? (TRB-TRD) * mvx / TRD : TRB * mvx / TRD + bdx - mvx);
  542. yvec = (bdy == 0 ? (TRB-TRD) * mvy / TRD : TRB * mvy / TRD + bdy - mvy);
  543. /* Luma */
  544. FindBiDirLimits(xvec,&xstart,&xstop,nh);
  545. FindBiDirLimits(yvec,&ystart,&ystop,nv);
  546. BiDirPredBlock(xstart,xstop,ystart,ystop,xvec,yvec, recon_P,pred,16);
  547. return;
  548. }
  549. void BiDirLumPredPB(H263_MB_Structure *recon_P, H263_MotionVector *fr,
  550. H263_MB_Structure *pred,int TRD,int TRB,int bdx,int bdy)
  551. {
  552. int xstart,xstop,ystart,ystop;
  553. int xvec,yvec, mvx, mvy;
  554. mvx = 2*fr->x + fr->x_half;
  555. mvy = 2*fr->y + fr->y_half;
  556. xvec = (bdx == 0 ? (TRB-TRD) * mvx / TRD : TRB * mvx / TRD + bdx - mvx);
  557. yvec = (bdy == 0 ? (TRB-TRD) * mvy / TRD : TRB * mvy / TRD + bdy - mvy);
  558. /* Luma */
  559. FindBiDirLimits(xvec,&xstart,&xstop,0);
  560. FindBiDirLimits(yvec,&ystart,&ystop,0);
  561. BiDirPredBlock(xstart,xstop,ystart,ystop,xvec,yvec, &recon_P->lum[0][0],
  562. &pred->lum[0][0],16);
  563. FindBiDirLimits(xvec,&xstart,&xstop,1);
  564. FindBiDirLimits(yvec,&ystart,&ystop,0);
  565. BiDirPredBlock(xstart,xstop,ystart,ystop,xvec,yvec, &recon_P->lum[0][8],
  566. &pred->lum[0][8],16);
  567. FindBiDirLimits(xvec,&xstart,&xstop,0);
  568. FindBiDirLimits(yvec,&ystart,&ystop,1);
  569. BiDirPredBlock(xstart,xstop,ystart,ystop,xvec,yvec, &recon_P->lum[8][0],
  570. &pred->lum[8][0],16);
  571. FindBiDirLimits(xvec,&xstart,&xstop,1);
  572. FindBiDirLimits(yvec,&ystart,&ystop,1);
  573. BiDirPredBlock(xstart,xstop,ystart,ystop,xvec,yvec, &recon_P->lum[8][8],
  574. &pred->lum[8][8],16);
  575. return;
  576. }
  577. /**********************************************************************
  578. *
  579. * Name: FindBiDirChrPredPB
  580. * Description: Finds the bi-dir. chroma prediction in PB-frame
  581. * prediction
  582. *
  583. * Input: pointer to future recon. data, current positon,
  584. * MV structure and pred. structure to fill
  585. *
  586. ***********************************************************************/
  587. void FindBiDirChrPredPB(H263_MB_Structure *recon_P, int dx, int dy,
  588. H263_MB_Structure *pred)
  589. {
  590. int xstart,xstop,ystart,ystop;
  591. FindBiDirChromaLimits(dx,&xstart,&xstop);
  592. FindBiDirChromaLimits(dy,&ystart,&ystop);
  593. BiDirPredBlock(xstart,xstop,ystart,ystop,dx,dy,
  594. &recon_P->Cb[0][0], &pred->Cb[0][0],8);
  595. BiDirPredBlock(xstart,xstop,ystart,ystop,dx,dy,
  596. &recon_P->Cr[0][0], &pred->Cr[0][0],8);
  597. return;
  598. }
  599. void FindBiDirLimits(int vec, int *start, int *stop, int nhv)
  600. {
  601. /* limits taken from C loop in section G5 in H.263 */
  602. *start = mmax(0,(-vec+1)/2 - nhv*8);
  603. *stop = mmin(7,15-(vec+1)/2 - nhv*8);
  604. return;
  605. }
  606. void FindBiDirChromaLimits(int vec, int *start, int *stop)
  607. {
  608. /* limits taken from C loop in section G5 in H.263 */
  609. *start = mmax(0,(-vec+1)/2);
  610. *stop = mmin(7,7-(vec+1)/2);
  611. return;
  612. }
  613. #if 1
  614. void BiDirPredBlock(int xstart, int xstop, int ystart, int ystop,
  615. int xvec, int yvec, short *recon, short *pred, int bl)
  616. {
  617. int i,j,pel;
  618. int xint, yint;
  619. int xh, yh;
  620. register short *ptn, *ptnd;
  621. xint = xvec>>1;
  622. xh = xvec - (xint << 1);
  623. yint = yvec>>1;
  624. yh = yvec - (yint << 1);
  625. ptn = recon + ystart*bl + xint + yint * bl;
  626. ptnd = pred + ystart*bl ;
  627. if (!xh && !yh) {
  628. for (j=ystart; j <= ystop; j++) {
  629. for (i=xstart; i <= xstop; i++) {
  630. /* *(ptnd + i) = (sv_H263lim255r_S(pel) + *(ptnd + i))>>1; */
  631. *(ptnd + i) = ( *(ptn + i) + *(ptnd + i) )>>1;
  632. }
  633. ptn += bl; ptnd += bl;
  634. }
  635. }
  636. else if (!xh && yh) {
  637. yh *= bl ;
  638. for (j=ystart; j <= ystop; j++) {
  639. for (i=xstart; i <= xstop; i++) {
  640. pel = (*(ptn + i) + *(ptn + i + yh) + 1)>>1;
  641. *(ptnd + i) = (pel + *(ptnd + i))>>1;
  642. }
  643. ptn += bl; ptnd += bl;
  644. }
  645. }
  646. else if (xh && !yh) {
  647. for (j=ystart; j <= ystop; j++) {
  648. for (i=xstart; i <= xstop; i++) {
  649. pel = (*(ptn + i) + *(ptn + i + xh) + 1)>>1;
  650. *(ptnd + i) = (pel + *(ptnd + i))>>1;
  651. }
  652. ptn += bl; ptnd += bl;
  653. }
  654. }
  655. else { /* xh && yh */
  656. yh *= bl ;
  657. for (j=ystart; j <= ystop; j++) {
  658. for (i=xstart; i <= xstop; i++) {
  659. pel = (*(ptn + i) + *(ptn + i + yh) +
  660. *(ptn + i + xh) + *(ptn + i + yh + xh)+2)>>2;
  661. *(ptnd + i) = (pel + *(ptnd + i))>>1;
  662. }
  663. ptn += bl; ptnd += bl;
  664. }
  665. }
  666. return;
  667. }
  668. #else
  669. void BiDirPredBlock(int xstart, int xstop, int ystart, int ystop,
  670. int xvec, int yvec, int *recon, int *pred, int bl)
  671. {
  672. int i,j,pel;
  673. int xint, yint;
  674. int xh, yh;
  675. xint = xvec>>1;
  676. xh = xvec - 2*xint;
  677. yint = yvec>>1;
  678. yh = yvec - 2*yint;
  679. if (!xh && !yh) {
  680. for (j = ystart; j <= ystop; j++) {
  681. for (i = xstart; i <= xstop; i++) {
  682. pel = *(recon +(j+yint)*bl + i+xint);
  683. #ifndef USE_C
  684. *(pred + j*bl + i) = (sv_H263lim255r_S(pel)) + *(pred + j*bl + i))>>1;
  685. #else
  686. *(pred + j*bl + i) = (mmin(255,mmax(0,pel)) + *(pred + j*bl + i))>>1;
  687. #endif
  688. }
  689. }
  690. }
  691. else if (!xh && yh) {
  692. for (j = ystart; j <= ystop; j++) {
  693. for (i = xstart; i <= xstop; i++) {
  694. pel = (*(recon +(j+yint)*bl + i+xint) +
  695. *(recon +(j+yint+yh)*bl + i+xint) + 1)>>1;
  696. *(pred + j*bl + i) = (pel + *(pred + j*bl + i))>>1;
  697. }
  698. }
  699. }
  700. else if (xh && !yh) {
  701. for (j = ystart; j <= ystop; j++) {
  702. for (i = xstart; i <= xstop; i++) {
  703. pel = (*(recon +(j+yint)*bl + i+xint) +
  704. *(recon +(j+yint)*bl + i+xint+xh) + 1)>>1;
  705. *(pred + j*bl + i) = (pel + *(pred + j*bl + i))>>1;
  706. }
  707. }
  708. }
  709. else { /* xh && yh */
  710. for (j = ystart; j <= ystop; j++) {
  711. for (i = xstart; i <= xstop; i++) {
  712. pel = (*(recon +(j+yint)*bl + i+xint) +
  713. *(recon +(j+yint+yh)*bl + i+xint) +
  714. *(recon +(j+yint)*bl + i+xint+xh) +
  715. *(recon +(j+yint+yh)*bl + i+xint+xh)+2)>>2;
  716. *(pred + j*bl + i) = (pel + *(pred + j*bl + i))>>1;
  717. }
  718. }
  719. }
  720. return;
  721. }
  722. #endif
  723. /**********************************************************************
  724. *
  725. * Name: DoPredChrom_P
  726. * Description: Does the chrominance prediction for P-frames
  727. *
  728. * Input: motionvectors for each field,
  729. * current position in image,
  730. * pointers to current and previos image,
  731. * pointer to pred_error array,
  732. * (int) field: 1 if field coding
  733. *
  734. * Side effects: fills chrom-array in pred_error structure
  735. *
  736. ***********************************************************************/
  737. static void DoPredChrom_P(SvH263CompressInfo_t *H263Info,
  738. int x_curr, int y_curr, int dx, int dy,
  739. H263_PictImage *curr, H263_PictImage *prev,
  740. H263_MB_Structure *pred_error)
  741. {
  742. int ofy, lx;
  743. int xh, yh, ofyy;
  744. register short *ptnr, *ptnb;
  745. unsigned char *preCr, *preCb, *curCr, *curCb;
  746. int x, y, ofx;
  747. #ifdef USE_C
  748. int ydiff,pel,m,n;
  749. #endif
  750. lx = (H263Info->mv_outside_frame ? H263Info->pels/2 + (H263Info->long_vectors?32:16) : H263Info->pels/2);
  751. x = x_curr>>1;
  752. y = y_curr>>1;
  753. xh = dx & 1;
  754. yh = dy & 1;
  755. ptnr = &(pred_error->Cr[0][0]) ;
  756. ptnb = &(pred_error->Cb[0][0]) ;
  757. ofy = (y + (dy >> 1))*lx + x + (dx >> 1) ;
  758. preCr = prev->Cr + ofy;
  759. preCb = prev->Cb + ofy ;
  760. ofx = x + y * H263Info->cpels ;
  761. curCr = curr->Cr + ofx ;
  762. curCb = curr->Cb + ofx ;
  763. if (!xh && !yh) {
  764. #ifndef USE_C
  765. sv_H263SubCpy_S(curCr, preCr, ptnr, H263Info->cpels, lx) ;
  766. sv_H263SubCpy_S(curCb, preCb, ptnb, H263Info->cpels, lx) ;
  767. #else
  768. ofx = H263Info->cpels - 8;
  769. ydiff = lx - 8;
  770. n = 8 ;
  771. while(n--) {
  772. m = 8 ;
  773. while(m--) {
  774. *(ptnr++) = (short)(*(curCr++) - *(preCr++));
  775. *(ptnb++) = (short)(*(curCb++) - *(preCb++));
  776. };
  777. preCr += ydiff ;
  778. preCb += ydiff ;
  779. curCr += ofx ;
  780. curCb += ofx ;
  781. };
  782. #endif
  783. }
  784. else if (!xh && yh) {
  785. ofyy = yh * lx ;
  786. #ifndef USE_C
  787. sv_H263Sub2Cpy_S(curCr, preCr, preCr + ofyy, ptnr, H263Info->cpels, lx) ;
  788. sv_H263Sub2Cpy_S(curCb, preCb, preCb + ofyy, ptnb, H263Info->cpels, lx) ;
  789. #else
  790. ofx = H263Info->cpels - 8;
  791. ydiff = lx - 8;
  792. n = 8 ;
  793. while(n--) {
  794. m = 8 ;
  795. while(m--) {
  796. *(ptnr++) = (short)(*(curCr++) - ((*(preCr + ofyy) + *(preCr++) + 1)>>1));
  797. *(ptnb++) = (short)(*(curCb++) - ((*(preCb + ofyy) + *(preCb++) + 1)>>1));
  798. };
  799. preCr += ydiff ;
  800. preCb += ydiff ;
  801. curCr += ofx ;
  802. curCb += ofx ;
  803. };
  804. #endif
  805. }
  806. else if (xh && !yh) {
  807. #ifndef USE_C
  808. sv_H263Sub2Cpy_S(curCr, preCr, preCr + xh, ptnr, H263Info->cpels, lx) ;
  809. sv_H263Sub2Cpy_S(curCb, preCb, preCb + xh, ptnb, H263Info->cpels, lx) ;
  810. #else
  811. ofx = H263Info->cpels - 8;
  812. ydiff = lx - 8;
  813. n = 8 ;
  814. while(n--) {
  815. m = 8 ;
  816. while(m--) {
  817. *(ptnr++) = (short)(*(curCr++) - ((*(preCr + xh) + *(preCr++) + 1)>>1));
  818. *(ptnb++) = (short)(*(curCb++) - ((*(preCb + xh) + *(preCb++) + 1)>>1));
  819. };
  820. preCr += ydiff ;
  821. preCb += ydiff ;
  822. curCr += ofx ;
  823. curCb += ofx ;
  824. };
  825. #endif
  826. }
  827. else { /* xh && yh */
  828. ofyy = yh * lx ;
  829. #ifndef USE_C
  830. sv_H263Sub4Cpy_S(curCr, preCr, preCr + xh, preCr + ofyy,
  831. preCr + xh + ofyy, ptnr, H263Info->cpels, lx) ;
  832. sv_H263Sub4Cpy_S(curCb, preCb, preCb + xh, preCb + ofyy,
  833. preCb + xh + ofyy, ptnb, H263Info->cpels, lx) ;
  834. #else
  835. ofx = H263Info->cpels - 8;
  836. ydiff = lx - 8;
  837. n = 8 ;
  838. while(n--) {
  839. m = 8 ;
  840. while(m--) {
  841. pel = (short)(*(preCr + xh) + *(preCr + ofyy) +
  842. *(preCr + xh + ofyy) + *(preCr++) + 2)>>2;
  843. *(ptnr++) = (short)(*(curCr++) - pel);
  844. pel = (short)(*(preCb + xh) + *(preCb + ofyy)+
  845. *(preCb + xh + ofyy) + *(preCb++) + 2)>>2;
  846. *(ptnb++) = (short)(*(curCb++) - pel);
  847. };
  848. preCr += ydiff ;
  849. preCb += ydiff ;
  850. curCr += ofx ;
  851. curCb += ofx ;
  852. };
  853. #endif
  854. }
  855. return;
  856. }
  857. /**********************************************************************
  858. *
  859. * Name: FindHalfPel
  860. * Description: Find the optimal half pel prediction
  861. *
  862. * Input: position, vector, array with current data
  863. * pointer to previous interpolated luminance,
  864. *
  865. * Returns:
  866. *
  867. ***********************************************************************/
  868. void sv_H263FindHalfPel(SvH263CompressInfo_t *H263Info,
  869. int x, int y, H263_MotionVector *fr, unsigned char *prev,
  870. unsigned char *curr, int bs, int comp)
  871. {
  872. int m, n;
  873. int start_x, start_y, stop_x, stop_y, new_x, new_y, lx;
  874. int AE, AE_min;
  875. int m2, n2, lx2, lx4, n16;
  876. unsigned char *ptn, *ptnn, *cur ;
  877. int curX,curY,minX,minY;
  878. cur = curr + x + y * H263Info->pels;
  879. start_x = -1; stop_x = 1;
  880. start_y = -1; stop_y = 1;
  881. new_x = x + fr->x;
  882. new_y = y + fr->y;
  883. new_x += ((comp&1)<<3);
  884. new_y += ((comp&2)<<2);
  885. lx = (H263Info->mv_outside_frame ? H263Info->pels + (H263Info->long_vectors?64:32) : H263Info->pels);
  886. /* Make sure that no addressing is outside the frame */
  887. if (!H263Info->mv_outside_frame) {
  888. if ((new_x) <= 0) start_x = 0;
  889. if ((new_y) <= 0) start_y = 0;
  890. if ((new_x) >= (H263Info->pels-bs)) stop_x = 0;
  891. if ((new_y) >= (H263Info->lines-bs)) stop_y = 0;
  892. }
  893. lx2 = (lx << 1);
  894. lx4 = (lx2 << 1);
  895. ptn = prev + (new_x<<1) + ((new_y<<1) * lx2);
  896. minX = minY =0;
  897. #ifdef USE_C
  898. AE_min = 0;
  899. for (n = n2 = 0; n < bs; n++, n2 += lx4) {
  900. n16 = n<<4;
  901. /* Find absolute error */
  902. for (m = m2 = 0; m < bs; m++, m2 += 2)
  903. AE_min += abs(*(ptn + m2 + n2) - *(cur + m + n * H263Info->pels));
  904. }
  905. for(curY=start_y;curY<=stop_y;curY++){
  906. for(curX=start_x; curX<=stop_x;curX++) {
  907. if(curX || curY) {
  908. ptnn = ptn + curY*lx2 + curX ;
  909. AE = 0;
  910. for (n = n2 = 0; n < bs; n++, n2 += lx4) {
  911. n16 = n<<4;
  912. /* Find absolute error */
  913. for (m = m2 = 0; m < bs; m++, m2 += 2)
  914. AE += abs(*(ptnn + m2 + n2) - *(cur + m + n * H263Info->pels));
  915. if(AE > AE_min) { AE = INT_MAX; break;}
  916. }
  917. /*
  918. * if (i == 0 && fr->x == 0 && fr->y == 0 && bs == 16)
  919. * AE -= PREF_NULL_VEC;
  920. */
  921. if (AE < AE_min) {
  922. AE_min = AE;
  923. minX = curX;
  924. minY = curY;
  925. }
  926. }
  927. }
  928. }
  929. #else
  930. if(bs == 16){
  931. AE_min = sv_H263HalfPerr16_S(cur, ptn, H263Info->pels, lx4, INT_MAX);
  932. for(curY=start_y;curY<=stop_y;curY++){
  933. for(curX=start_x; curX<=stop_x;curX++) {
  934. if(curX || curY) {
  935. ptnn = ptn + curY*lx2 + curX ;
  936. if((AE = sv_H263HalfPerr16_S(cur, ptnn, H263Info->pels,
  937. lx4, AE_min)) < AE_min) {
  938. AE_min = AE;
  939. minX = curX;
  940. minY = curY;
  941. } } } } }
  942. else if(bs == 8) {
  943. AE_min = sv_H263HalfPerr8_S(cur, ptn, H263Info->pels, lx4, INT_MAX);
  944. for(curY=start_y;curY<=stop_y;curY++){
  945. for(curX=start_x; curX<=stop_x;curX++) {
  946. if(curX || curY) {
  947. ptnn = ptn + curY*lx2 + curX ;
  948. if((AE = sv_H263HalfPerr8_S(cur, ptnn, H263Info->pels,
  949. lx4, AE_min)) < AE_min) {
  950. AE_min = AE;
  951. minX = curX;
  952. minY = curY;
  953. } } } } }
  954. else{
  955. AE_min = 0;
  956. for (n = n2 = 0; n < bs; n++, n2 += lx4) {
  957. n16 = n<<4;
  958. /* Find absolute error */
  959. for (m = m2 = 0; m < bs; m++, m2 += 2)
  960. AE_min += abs(*(ptn + m2 + n2) - *(cur + m + n * H263Info->pels));
  961. }
  962. for(curY=start_y;curY<=stop_y;curY++){
  963. for(curX=start_x; curX<=stop_x;curX++) {
  964. if(curX || curY) {
  965. ptnn = ptn + curY*lx2 + curX ;
  966. AE = 0;
  967. for (n = n2 = 0; n < bs; n++, n2 += lx4) {
  968. n16 = n<<4;
  969. /* Find absolute error */
  970. for (m = m2 = 0; m < bs; m++, m2 += 2)
  971. AE += abs(*(ptnn + m2 + n2) - *(cur + m + n * H263Info->pels));
  972. if(AE > AE_min) { AE = INT_MAX; break;}
  973. }
  974. /*
  975. * if (i == 0 && fr->x == 0 && fr->y == 0 && bs == 16)
  976. * AE -= PREF_NULL_VEC;
  977. */
  978. if (AE < AE_min) {
  979. AE_min = AE;
  980. minX = curX;
  981. minY = curY;
  982. } } } } }
  983. #endif
  984. /* Store optimal values */
  985. fr->min_error = (short)AE_min;
  986. fr->x_half = (short)minX;
  987. fr->y_half = (short)minY;
  988. return;
  989. }
  990. /**********************************************************************
  991. *
  992. * Name: AdvHalfPel
  993. * Description: Find the optimal half pel prediction for Advanced mode
  994. *
  995. * Input: position, vector, array with current data
  996. * pointer to previous interpolated luminance,
  997. *
  998. * Returns:
  999. *
  1000. ***********************************************************************/
  1001. #ifndef USE_C
  1002. void sv_H263AdvHalfPel(SvH263CompressInfo_t *H263Info, int x, int y,
  1003. H263_MotionVector *fr0, H263_MotionVector *fr1,
  1004. H263_MotionVector *fr2, H263_MotionVector *fr3,
  1005. H263_MotionVector *fr4,
  1006. unsigned char *prev, unsigned char *curr,
  1007. int bs, int comp)
  1008. {
  1009. int start_x, start_y, stop_x, stop_y, new_x, new_y, lx;
  1010. unsigned int AE, AE_min, minER1, minER2, minER3, minER4;
  1011. int lx2, lx4;
  1012. unsigned char *ptn, *ptnn, *cur ;
  1013. int curX,curY,minX,minY,minX1,minY1,minX2,minY2,minX3,minY3,minX4,minY4;
  1014. unsigned int error[4];
  1015. cur = curr + x + y * H263Info->pels;
  1016. start_x = -1; stop_x = 1;
  1017. start_y = -1; stop_y = 1;
  1018. new_x = x + fr0->x;
  1019. new_y = y + fr0->y;
  1020. new_x += ((comp&1)<<3);
  1021. new_y += ((comp&2)<<2);
  1022. lx = (H263Info->mv_outside_frame ? H263Info->pels + (H263Info->long_vectors?64:32) : H263Info->pels);
  1023. /* Make sure that no addressing is outside the frame */
  1024. if (!H263Info->mv_outside_frame) {
  1025. if ((new_x) <= 0) start_x = 0;
  1026. if ((new_y) <= 0) start_y = 0;
  1027. if ((new_x) >= (H263Info->pels-bs)) stop_x = 0;
  1028. if ((new_y) >= (H263Info->lines-bs)) stop_y = 0;
  1029. }
  1030. lx2 = (lx << 1);
  1031. lx4 = (lx2 << 1);
  1032. ptn = prev + (new_x<<1) + ((new_y<<1) * lx2);
  1033. minX=minY=minX1=minY1=minX2=minY2=minX3=minY3=minX4=minY4=0;
  1034. sv_H263HalfPerr4_S(cur, ptn, H263Info->pels, lx4, error);
  1035. AE_min = error[0] + error[1] + error[2] + error[3] ;
  1036. minER1 = error[0];
  1037. minER2 = error[1];
  1038. minER3 = error[2];
  1039. minER4 = error[3];
  1040. for(curY=start_y;curY<=stop_y;curY++){
  1041. for(curX=start_x; curX<=stop_x;curX++) {
  1042. if(curX || curY) {
  1043. ptnn = ptn + curY*lx2 + curX ;
  1044. sv_H263HalfPerr4_S(cur,ptnn,H263Info->pels,lx4,error);
  1045. AE = error[0] + error[1] + error[2] + error[3] ;
  1046. if(AE < AE_min) {
  1047. AE_min = AE;
  1048. minX = curX;
  1049. minY = curY;
  1050. }
  1051. if(error[0] < minER1) {
  1052. minER1 = error[0];
  1053. minX1 = curX;
  1054. minY1 = curY;
  1055. }
  1056. if(error[1] < minER2) {
  1057. minER2 = error[1];
  1058. minX2 = curX;
  1059. minY2 = curY;
  1060. }
  1061. if(error[2] < minER3) {
  1062. minER3 = error[2];
  1063. minX3 = curX;
  1064. minY3 = curY;
  1065. }
  1066. if(error[3] < minER4) {
  1067. minER4 = error[3];
  1068. minX4 = curX;
  1069. minY4 = curY;
  1070. }
  1071. }
  1072. }
  1073. }
  1074. /* Store optimal values */
  1075. fr0->min_error = (short)AE_min;
  1076. fr0->x_half = (short)minX;
  1077. fr0->y_half = (short)minY;
  1078. fr1->min_error = (short)minER1;
  1079. fr1->x_half = (short)minX1;
  1080. fr1->y_half = (short)minY1;
  1081. fr2->min_error = (short)minER2;
  1082. fr2->x_half = (short)minX2;
  1083. fr2->y_half = (short)minY2;
  1084. fr3->min_error = (short)minER3;
  1085. fr3->x_half = (short)minX3;
  1086. fr3->y_half = (short)minY3;
  1087. fr4->min_error = (short)minER4;
  1088. fr4->x_half = (short)minX4;
  1089. fr4->y_half = (short)minY4;
  1090. return;
  1091. }
  1092. #endif
  1093. /**********************************************************************
  1094. *
  1095. * Name: FindPred
  1096. * Description: Find the prediction block
  1097. *
  1098. * Input: position, vector, array for prediction
  1099. * pointer to previous interpolated luminance,
  1100. *
  1101. * Side effects: fills array with prediction
  1102. *
  1103. ***********************************************************************/
  1104. static void FindPred(SvH263CompressInfo_t *H263Info,
  1105. int x, int y, H263_MotionVector *fr, unsigned char *prev,
  1106. short *pred, int bs, int comp)
  1107. {
  1108. register int m, n, m2, n2;
  1109. int new_x, new_y, lx2;
  1110. unsigned char *ptn;
  1111. lx2 = ((H263Info->mv_outside_frame ? H263Info->pels + (H263Info->long_vectors?64:32) : H263Info->pels)) << 1;
  1112. new_x = ((x + fr->x + ((comp&1)<<3))<<1) + fr->x_half;
  1113. new_y = ((y + fr->y + ((comp&2)<<2))<<1) + fr->y_half;
  1114. new_x += (new_y * lx2) ;
  1115. lx2 = (lx2 << 1) ;
  1116. ptn = prev + new_x ;
  1117. /* Fill pred. data */
  1118. #ifndef USE_C
  1119. if(bs == 16) {
  1120. sv_H263Intpix16_S(ptn, pred, lx2, 16) ;
  1121. }
  1122. else {
  1123. for (n = n2 = 0; n < bs; n++, n2 += lx2)
  1124. for (m = m2 = 0; m < bs; m++, m2 += 2)
  1125. /* Find interpolated pixel-value */
  1126. *(pred+m+n*16) = (int) *(ptn + m2 + n2);
  1127. }
  1128. #else
  1129. for (n = n2 = 0; n < bs; n++, n2 += lx2)
  1130. for (m = m2 = 0; m < bs; m++, m2 += 2)
  1131. /* Find interpolated pixel-value */
  1132. *(pred+m+n*16) = (int) *(ptn + m2 + n2);
  1133. #endif
  1134. return ;
  1135. }
  1136. /**********************************************************************
  1137. *
  1138. * Name: FindPredOBMC
  1139. * Description: Find the OBMC prediction block
  1140. *
  1141. * Input: position, vector, array for prediction
  1142. * pointer to previous interpolated luminance,
  1143. *
  1144. * Returns:
  1145. * Side effects: fills array with prediction
  1146. *
  1147. ***********************************************************************/
  1148. static void FindPredOBMC(SvH263CompressInfo_t *H263Info, int x, int y,
  1149. H263_MotionVector *MV[6][H263_MBR+1][H263_MBC+2],
  1150. unsigned char *prev, short *pred, int comp, int PB)
  1151. {
  1152. register int m, n;
  1153. int pc,pt,pb,pr,pl;
  1154. int nxc,nxt,nxb,nxr,nxl;
  1155. int nyc,nyt,nyb,nyr,nyl;
  1156. int xit,xib,xir,xil;
  1157. int yit,yib,yir,yil;
  1158. int vect,vecb,vecr,vecl;
  1159. int c8,t8,l8,r8;
  1160. int ti8,li8,ri8;
  1161. int xmb, ymb, lx;
  1162. int m2, n2, lx2;
  1163. register int *omc, *omt, *omb, *omr, *oml ;
  1164. unsigned char *prevc, *prevt, *prevb, *prevr, *prevl;
  1165. H263_MotionVector *fc,*ft,*fb,*fr,*fl;
  1166. int Mc[8][8] = {
  1167. {4,5,5,5,5,5,5,4},
  1168. {5,5,5,5,5,5,5,5},
  1169. {5,5,6,6,6,6,5,5},
  1170. {5,5,6,6,6,6,5,5},
  1171. {5,5,6,6,6,6,5,5},
  1172. {5,5,6,6,6,6,5,5},
  1173. {5,5,5,5,5,5,5,5},
  1174. {4,5,5,5,5,5,5,4},
  1175. };
  1176. int Mt[8][8] = {
  1177. {1,1,1,1,1,1,1,1},
  1178. {0,0,1,1,1,1,0,0},
  1179. {0,0,0,0,0,0,0,0},
  1180. {0,0,0,0,0,0,0,0},
  1181. {0,0,0,0,0,0,0,0},
  1182. {0,0,0,0,0,0,0,0},
  1183. {0,0,0,0,0,0,0,0},
  1184. {0,0,0,0,0,0,0,0},
  1185. };
  1186. int Mb[8][8] = {
  1187. {0,0,0,0,0,0,0,0},
  1188. {0,0,0,0,0,0,0,0},
  1189. {0,0,0,0,0,0,0,0},
  1190. {0,0,0,0,0,0,0,0},
  1191. {0,0,0,0,0,0,0,0},
  1192. {0,0,0,0,0,0,0,0},
  1193. {0,0,1,1,1,1,0,0},
  1194. {1,1,1,1,1,1,1,1},
  1195. };
  1196. int Mr[8][8] = {
  1197. {0,0,0,0,0,0,0,1},
  1198. {0,0,0,0,0,0,1,1},
  1199. {0,0,0,0,0,0,1,1},
  1200. {0,0,0,0,0,0,1,1},
  1201. {0,0,0,0,0,0,1,1},
  1202. {0,0,0,0,0,0,1,1},
  1203. {0,0,0,0,0,0,1,1},
  1204. {0,0,0,0,0,0,0,1},
  1205. };
  1206. int Ml[8][8] = {
  1207. {1,0,0,0,0,0,0,0},
  1208. {1,1,0,0,0,0,0,0},
  1209. {1,1,0,0,0,0,0,0},
  1210. {1,1,0,0,0,0,0,0},
  1211. {1,1,0,0,0,0,0,0},
  1212. {1,1,0,0,0,0,0,0},
  1213. {1,1,0,0,0,0,0,0},
  1214. {1,0,0,0,0,0,0,0},
  1215. };
  1216. /*
  1217. int Mt[8][8] = {
  1218. {2,2,2,2,2,2,2,2},
  1219. {1,1,2,2,2,2,1,1},
  1220. {1,1,1,1,1,1,1,1},
  1221. {1,1,1,1,1,1,1,1},
  1222. {0,0,0,0,0,0,0,0},
  1223. {0,0,0,0,0,0,0,0},
  1224. {0,0,0,0,0,0,0,0},
  1225. {0,0,0,0,0,0,0,0},
  1226. };
  1227. int Mb[8][8] = {
  1228. {0,0,0,0,0,0,0,0},
  1229. {0,0,0,0,0,0,0,0},
  1230. {0,0,0,0,0,0,0,0},
  1231. {0,0,0,0,0,0,0,0},
  1232. {1,1,1,1,1,1,1,1},
  1233. {1,1,1,1,1,1,1,1},
  1234. {1,1,2,2,2,2,1,1},
  1235. {2,2,2,2,2,2,2,2},
  1236. };
  1237. int Mr[8][8] = {
  1238. {0,0,0,0,1,1,1,2},
  1239. {0,0,0,0,1,1,2,2},
  1240. {0,0,0,0,1,1,2,2},
  1241. {0,0,0,0,1,1,2,2},
  1242. {0,0,0,0,1,1,2,2},
  1243. {0,0,0,0,1,1,2,2},
  1244. {0,0,0,0,1,1,2,2},
  1245. {0,0,0,0,1,1,1,2},
  1246. };
  1247. int Ml[8][8] = {
  1248. {2,1,1,1,0,0,0,0},
  1249. {2,2,1,1,0,0,0,0},
  1250. {2,2,1,1,0,0,0,0},
  1251. {2,2,1,1,0,0,0,0},
  1252. {2,2,1,1,0,0,0,0},
  1253. {2,2,1,1,0,0,0,0},
  1254. {2,2,1,1,0,0,0,0},
  1255. {2,1,1,1,0,0,0,0},
  1256. };
  1257. */
  1258. xmb = x/H263_MB_SIZE+1;
  1259. ymb = y/H263_MB_SIZE+1;
  1260. lx = (H263Info->mv_outside_frame ? H263Info->pels + (H263Info->long_vectors?64:32) : H263Info->pels);
  1261. c8 = (MV[0][ymb][xmb]->Mode == H263_MODE_INTER4V ? 1 : 0);
  1262. t8 = (MV[0][ymb-1][xmb]->Mode == H263_MODE_INTER4V ? 1 : 0);
  1263. ti8 = (MV[0][ymb-1][xmb]->Mode == H263_MODE_INTRA ? 1 : 0);
  1264. ti8 = (MV[0][ymb-1][xmb]->Mode == H263_MODE_INTRA_Q ? 1 : ti8);
  1265. l8 = (MV[0][ymb][xmb-1]->Mode == H263_MODE_INTER4V ? 1 : 0);
  1266. li8 = (MV[0][ymb][xmb-1]->Mode == H263_MODE_INTRA ? 1 : 0);
  1267. li8 = (MV[0][ymb][xmb-1]->Mode == H263_MODE_INTRA_Q ? 1 : li8);
  1268. r8 = (MV[0][ymb][xmb+1]->Mode == H263_MODE_INTER4V ? 1 : 0);
  1269. ri8 = (MV[0][ymb][xmb+1]->Mode == H263_MODE_INTRA ? 1 : 0);
  1270. ri8 = (MV[0][ymb][xmb+1]->Mode == H263_MODE_INTRA_Q ? 1 : ri8);
  1271. if (PB) ti8 = li8 = ri8 = 0;
  1272. switch (comp+1) {
  1273. case 1:
  1274. vect = (ti8 ? (c8 ? 1 : 0) : (t8 ? 3 : 0));
  1275. yit = (ti8 ? ymb : ymb - 1);
  1276. xit = xmb;
  1277. vecb = (c8 ? 3 : 0) ; yib = ymb; xib = xmb;
  1278. vecl = (li8 ? (c8 ? 1 : 0) : (l8 ? 2 : 0));
  1279. yil = ymb;
  1280. xil = (li8 ? xmb : xmb-1);
  1281. vecr = (c8 ? 2 : 0) ; yir = ymb; xir = xmb;
  1282. /* edge handling */
  1283. if (ymb == 1) {
  1284. yit = ymb;
  1285. vect = (c8 ? 1 : 0);
  1286. }
  1287. if (xmb == 1) {
  1288. xil = xmb;
  1289. vecl = (c8 ? 1 : 0);
  1290. }
  1291. break;
  1292. case 2:
  1293. vect = (ti8 ? (c8 ? 2 : 0) : (t8 ? 4 : 0));
  1294. yit = (ti8 ? ymb : ymb-1);
  1295. xit = xmb;
  1296. vecb = (c8 ? 4 : 0) ; yib = ymb; xib = xmb;
  1297. vecl = (c8 ? 1 : 0) ; yil = ymb; xil = xmb;
  1298. vecr = (ri8 ? (c8 ? 2 : 0) : (r8 ? 1 : 0));
  1299. yir = ymb;
  1300. xir = (ri8 ? xmb : xmb+1);
  1301. /* edge handling */
  1302. if (ymb == 1) {
  1303. yit = ymb;
  1304. vect = (c8 ? 2 : 0);
  1305. }
  1306. if (xmb == H263Info->pels/16) {
  1307. xir = xmb;
  1308. vecr = (c8 ? 2 : 0);
  1309. }
  1310. break;
  1311. case 3:
  1312. vect = (c8 ? 1 : 0) ; yit = ymb ; xit = xmb;
  1313. vecb = (c8 ? 3 : 0) ; yib = ymb ; xib = xmb;
  1314. vecl = (li8 ? (c8 ? 3 : 0) : (l8 ? 4 : 0));
  1315. yil = ymb;
  1316. xil = (li8 ? xmb : xmb-1);
  1317. vecr = (c8 ? 4 : 0) ; yir = ymb ; xir = xmb;
  1318. /* edge handling */
  1319. if (xmb == 1) {
  1320. xil = xmb;
  1321. vecl = (c8 ? 3 : 0);
  1322. }
  1323. break;
  1324. case 4:
  1325. vect = (c8 ? 2 : 0) ; yit = ymb ; xit = xmb;
  1326. vecb = (c8 ? 4 : 0) ; yib = ymb ; xib = xmb;
  1327. vecl = (c8 ? 3 : 0) ; yil = ymb ; xil = xmb;
  1328. vecr = (ri8 ? (c8 ? 4 : 0) : (r8 ? 3 : 0));
  1329. yir = ymb;
  1330. xir = (ri8 ? xmb : xmb+1);
  1331. /* edge handling */
  1332. if (xmb == H263Info->pels/16) {
  1333. xir = xmb;
  1334. vecr = (c8 ? 4 : 0);
  1335. }
  1336. break;
  1337. default:
  1338. _SlibDebug(_WARN_, printf("Illegal block number in FindPredOBMC (pred.c)\n") );
  1339. return;
  1340. break;
  1341. }
  1342. fc = MV[c8 ? comp + 1: 0][ymb][xmb];
  1343. ft = MV[vect][yit][xit];
  1344. fb = MV[vecb][yib][xib];
  1345. fr = MV[vecr][yir][xir];
  1346. fl = MV[vecl][yil][xil];
  1347. nxc = 2*x + ((comp&1)<<4); nyc = 2*y + ((comp&2)<<3);
  1348. nxt = nxb = nxr = nxl = nxc;
  1349. nyt = nyb = nyr = nyl = nyc;
  1350. nxc += 2*fc->x + fc->x_half; nyc += 2*fc->y + fc->y_half;
  1351. nxt += 2*ft->x + ft->x_half; nyt += 2*ft->y + ft->y_half;
  1352. nxb += 2*fb->x + fb->x_half; nyb += 2*fb->y + fb->y_half;
  1353. nxr += 2*fr->x + fr->x_half; nyr += 2*fr->y + fr->y_half;
  1354. nxl += 2*fl->x + fl->x_half; nyl += 2*fl->y + fl->y_half;
  1355. #if 1
  1356. /* Fill pred. data */
  1357. lx2 = lx << 1 ;
  1358. omc = &Mc[0][0] ; omt = &Mt[0][0] ; omb = &Mb[0][0] ;
  1359. omr = &Mr[0][0] ; oml = &Ml[0][0] ;
  1360. prevc = prev + nxc + nyc*lx2;
  1361. prevt = prev + nxt + nyt*lx2;
  1362. prevb = prev + nxb + nyb*lx2;
  1363. prevr = prev + nxr + nyr*lx2;
  1364. prevl = prev + nxl + nyl*lx2;
  1365. lx2 <<= 1;
  1366. for (n = n2 = 0; n < 4; n++, n2+=lx2) {
  1367. /* Find interpolated pixel-value */
  1368. for (m = 0, m2=n2; m < 4; m++, m2+=2) {
  1369. pc = *(prevc + m2) * (*omc++);
  1370. pt = *(prevt + m2) << (*omt++);
  1371. pl = *(prevl + m2) << (*oml++);
  1372. *(pred + m + (n<<4)) = (pc+pt+pl+4)>>3;
  1373. }
  1374. omr += 4;
  1375. for (m = 4; m < 8; m++, m2+=2) {
  1376. pc = *(prevc + m2) * (*omc++);
  1377. pt = *(prevt + m2) << (*omt++);
  1378. pr = *(prevr + m2) << (*omr++);
  1379. *(pred + m + (n<<4)) = (pc+pt+pr+4)>>3;
  1380. }
  1381. oml += 4;
  1382. }
  1383. omb += 32;
  1384. for (n = 4; n < 8; n++, n2+=lx2) {
  1385. /* Find interpolated pixel-value */
  1386. for (m = 0, m2=n2; m < 4; m++, m2+=2) {
  1387. pc = *(prevc + m2) * (*omc++);
  1388. pb = *(prevb + m2) << (*omb++);
  1389. pl = *(prevl + m2) << (*oml++);
  1390. *(pred + m + (n<<4)) = (pc+pb+pl+4)>>3;
  1391. }
  1392. omr += 4;
  1393. for (m = 4; m < 8; m++, m2+=2) {
  1394. pc = *(prevc + m2) * (*omc++);
  1395. pb = *(prevb + m2) << (*omb++);
  1396. pr = *(prevr + m2) << (*omr++);
  1397. *(pred + m + (n<<4)) = (pc+pb+pr+4)>>3;
  1398. }
  1399. oml += 4;
  1400. }
  1401. #else /* original */
  1402. /* Fill pred. data */
  1403. lx2 = lx << 1 ;
  1404. omc = &Mc[0][0] ; omt = &Mt[0][0] ; omb = &Mb[0][0] ;
  1405. omr = &Mr[0][0] ; oml = &Ml[0][0] ;
  1406. for (n = n2 = 0; n < 8; n++,n2+=(lx2<<1)) {
  1407. for (m = 0, m2=n2; m < 8; m++, m2 += 2) {
  1408. /* Find interpolated pixel-value */
  1409. pc = *(prev + nxc + m2 + nyc*lx2) * (*omc++);
  1410. pt = *(prev + nxt + m2 + nyt*lx2) * (*omt++);
  1411. pb = *(prev + nxb + m2 + nyb*lx2) * (*omb++);
  1412. pr = *(prev + nxr + m2 + nyr*lx2) * (*omr++);
  1413. pl = *(prev + nxl + m2 + nyl*lx2) * (*oml++);
  1414. *(pred + m + n*16) = (pc+pt+pb+pr+pl+4)>>3;
  1415. }
  1416. }
  1417. #endif
  1418. return;
  1419. }
  1420. /**********************************************************************
  1421. *
  1422. * Name: ReconMacroblock_P
  1423. * Description: Reconstructs MB after quantization for P_images
  1424. *
  1425. * Input: pointers to current and previous image,
  1426. * current slice and mb, and which mode
  1427. * of prediction has been used
  1428. * Returns:
  1429. * Side effects:
  1430. *
  1431. ***********************************************************************/
  1432. void sv_H263MBReconP(SvH263CompressInfo_t *H263Info,
  1433. H263_PictImage *prev_image, unsigned char *prev_ipol,
  1434. H263_MB_Structure *diff, int x_curr, int y_curr,
  1435. H263_MotionVector *MV[6][H263_MBR+1][H263_MBC+2], int PB,
  1436. H263_MB_Structure *recon_data)
  1437. {
  1438. H263_MotionVector *fr0,*fr1,*fr2,*fr3,*fr4;
  1439. short pred[16][16];
  1440. int dx, dy, sum;
  1441. #ifdef USE_C
  1442. int i,j;
  1443. #endif
  1444. fr0 = MV[0][y_curr/H263_MB_SIZE+1][x_curr/H263_MB_SIZE+1];
  1445. if (H263Info->advanced) {
  1446. if (fr0->Mode == H263_MODE_INTER || fr0->Mode == H263_MODE_INTER_Q) {
  1447. FindPredOBMC(H263Info, x_curr, y_curr, MV, prev_ipol, &pred[0][0], 0, PB);
  1448. FindPredOBMC(H263Info, x_curr, y_curr, MV, prev_ipol, &pred[0][8], 1, PB);
  1449. FindPredOBMC(H263Info, x_curr, y_curr, MV, prev_ipol, &pred[8][0], 2, PB);
  1450. FindPredOBMC(H263Info, x_curr, y_curr, MV, prev_ipol, &pred[8][8], 3, PB);
  1451. #ifndef USE_C
  1452. sv_H263Add256_S(&(diff->lum[0][0]),&(pred[0][0]));
  1453. #else
  1454. for (j = 0; j < H263_MB_SIZE; j++)
  1455. for (i = 0; i < H263_MB_SIZE; i++)
  1456. diff->lum[j][i] += pred[j][i];
  1457. #endif
  1458. dx = 2*fr0->x + fr0->x_half;
  1459. dy = 2*fr0->y + fr0->y_half;
  1460. dx = ( dx % 4 == 0 ? dx >> 1 : (dx>>1)|1 );
  1461. dy = ( dy % 4 == 0 ? dy >> 1 : (dy>>1)|1 );
  1462. ReconChromBlock_P(H263Info, x_curr, y_curr, dx, dy, prev_image, diff);
  1463. }
  1464. else if (fr0->Mode == H263_MODE_INTER4V) { /* Inter 8x8 */
  1465. FindPredOBMC(H263Info, x_curr, y_curr, MV, prev_ipol, &pred[0][0], 0, PB);
  1466. FindPredOBMC(H263Info, x_curr, y_curr, MV, prev_ipol, &pred[0][8], 1, PB);
  1467. FindPredOBMC(H263Info, x_curr, y_curr, MV, prev_ipol, &pred[8][0], 2, PB);
  1468. FindPredOBMC(H263Info, x_curr, y_curr, MV, prev_ipol, &pred[8][8], 3, PB);
  1469. #ifndef USE_C
  1470. sv_H263Add256_S(&(diff->lum[0][0]),&(pred[0][0]));
  1471. #else
  1472. for (j = 0; j < H263_MB_SIZE; j++)
  1473. for (i = 0; i < H263_MB_SIZE; i++)
  1474. diff->lum[j][i] += pred[j][i];
  1475. #endif
  1476. fr1 = MV[1][y_curr/H263_MB_SIZE+1][x_curr/H263_MB_SIZE+1];
  1477. fr2 = MV[2][y_curr/H263_MB_SIZE+1][x_curr/H263_MB_SIZE+1];
  1478. fr3 = MV[3][y_curr/H263_MB_SIZE+1][x_curr/H263_MB_SIZE+1];
  1479. fr4 = MV[4][y_curr/H263_MB_SIZE+1][x_curr/H263_MB_SIZE+1];
  1480. sum = 2*fr1->x + fr1->x_half + 2*fr2->x + fr2->x_half +
  1481. 2*fr3->x + fr3->x_half + 2*fr4->x + fr4->x_half ;
  1482. dx = sign(sum)*(roundtab[abs(sum)%16] + (abs(sum)/16)*2);
  1483. sum = 2*fr1->y + fr1->y_half + 2*fr2->y + fr2->y_half +
  1484. 2*fr3->y + fr3->y_half + 2*fr4->y + fr4->y_half;
  1485. dy = sign(sum)*(roundtab[abs(sum)%16] + (abs(sum)/16)*2);
  1486. ReconChromBlock_P(H263Info, x_curr, y_curr, dx, dy, prev_image, diff);
  1487. }
  1488. }
  1489. else {
  1490. if (fr0->Mode == H263_MODE_INTER || fr0->Mode == H263_MODE_INTER_Q) {
  1491. /* Inter 16x16 */
  1492. ReconLumBlock_P(H263Info, x_curr,y_curr,fr0,prev_ipol,&diff->lum[0][0],16,0);
  1493. dx = 2*fr0->x + fr0->x_half;
  1494. dy = 2*fr0->y + fr0->y_half;
  1495. dx = ( dx % 4 == 0 ? dx >> 1 : (dx>>1)|1 );
  1496. dy = ( dy % 4 == 0 ? dy >> 1 : (dy>>1)|1 );
  1497. ReconChromBlock_P(H263Info, x_curr, y_curr, dx, dy, prev_image, diff);
  1498. }
  1499. }
  1500. memcpy(recon_data, diff, sizeof(H263_MB_Structure));
  1501. return ;
  1502. }
  1503. /**********************************************************************
  1504. *
  1505. * Name: ReconLumBlock_P
  1506. * Description: Reconstructs one block of luminance data
  1507. *
  1508. * Input: position, vector-data, previous image, data-block
  1509. * Returns:
  1510. * Side effects: reconstructs data-block
  1511. *
  1512. ***********************************************************************/
  1513. static void ReconLumBlock_P(SvH263CompressInfo_t *H263Info,
  1514. int x, int y, H263_MotionVector *fr,
  1515. unsigned char *prev, short *data, int bs, int comp)
  1516. {
  1517. int x1, y1, lx2;
  1518. unsigned char *ptn ;
  1519. #ifdef USE_C
  1520. int m,n;
  1521. #endif
  1522. lx2 = ((H263Info->mv_outside_frame ? H263Info->pels + (H263Info->long_vectors?64:32) : H263Info->pels)) << 1;
  1523. x1 = ((x + fr->x) << 1) + fr->x_half + ((comp&1)<<4) ;
  1524. y1 = ((y + fr->y) << 1) + fr->y_half + ((comp&2)<<3);
  1525. x1 += (y1 * lx2) ;
  1526. ptn = prev + x1 ;
  1527. #ifndef USE_C
  1528. sv_H263Add16Skp_S(ptn, data, (2 * lx2)) ;
  1529. #else
  1530. /* int m, n; */
  1531. lx2 = (lx2 <<1) - (bs << 1) ;
  1532. for (n = 0; n < bs; n++, ptn += lx2)
  1533. for (m = 0; m < bs; m++, ptn += 2)
  1534. *(data++) += (short)(*ptn);
  1535. #endif
  1536. return;
  1537. }
  1538. /**********************************************************************
  1539. *
  1540. * Name: ReconChromBlock_P
  1541. * Description: Reconstructs chrominance of one block in P frame
  1542. *
  1543. * Input: position, vector-data, previous image, data-block
  1544. * Returns:
  1545. * Side effects: reconstructs data-block
  1546. *
  1547. ***********************************************************************/
  1548. #ifndef USE_C
  1549. static void ReconChromBlock_P(SvH263CompressInfo_t *H263Info,
  1550. int x_curr, int y_curr, int dx, int dy,
  1551. H263_PictImage *prev, H263_MB_Structure *data)
  1552. {
  1553. int ofy, lx;
  1554. int xh, yh, ofyy, ydiff;
  1555. register short *ptnr, *ptnb;
  1556. unsigned char *preCr, *preCb;
  1557. lx = (H263Info->mv_outside_frame ? H263Info->pels/2 + (H263Info->long_vectors?32:16) : H263Info->pels/2);
  1558. xh = dx & 1;
  1559. yh = dy & 1;
  1560. ptnr = &(data->Cr[0][0]) ;
  1561. ptnb = &(data->Cb[0][0]) ;
  1562. ydiff = lx - 8 ;
  1563. ofy = ((y_curr>>1) + (dy >> 1))*lx + (x_curr>>1) + (dx >> 1) ;
  1564. preCr = prev->Cr + ofy;
  1565. preCb = prev->Cb + ofy ;
  1566. if (!xh && !yh) {
  1567. sv_H263Add_S(preCr, ptnr, preCb, ptnb, lx);
  1568. }
  1569. else if (!xh && yh) {
  1570. ofyy = yh * lx ;
  1571. sv_H263Avg2Add_S(preCr + ofyy, preCr, ptnr, preCb + ofyy, preCb, ptnb, lx);
  1572. }
  1573. else if (xh && !yh) {
  1574. sv_H263Avg2Add_S(preCr + xh, preCr, ptnr, preCb + xh, preCb, ptnb, lx);
  1575. }
  1576. else { /* xh && yh */
  1577. ofyy = yh * lx ;
  1578. sv_H263Avg4Add_S(preCr,preCr+xh,preCr+ofyy,preCr+xh+ofyy,ptnr,lx);
  1579. sv_H263Avg4Add_S(preCb,preCb+xh,preCb+ofyy,preCb+xh+ofyy,ptnb,lx);
  1580. }
  1581. return;
  1582. }
  1583. #else
  1584. static void ReconChromBlock_P(SvH263CompressInfo_t *H263Info,
  1585. int x_curr, int y_curr, int dx, int dy,
  1586. H263_PictImage *prev, H263_MB_Structure *data)
  1587. {
  1588. register int m,n;
  1589. int ofy, lx;
  1590. int xh, yh, ofyy, ydiff;
  1591. register short *ptnr, *ptnb;
  1592. unsigned char *preCr, *preCb;
  1593. lx = (H263Info->mv_outside_frame ? H263Info->pels/2 + (H263Info->long_vectors?32:16) : H263Info->pels/2);
  1594. xh = dx & 1;
  1595. yh = dy & 1;
  1596. ptnr = &(data->Cr[0][0]) ;
  1597. ptnb = &(data->Cb[0][0]) ;
  1598. ydiff = lx - 8 ;
  1599. ofy = ((y_curr>>1) + (dy >> 1))*lx + (x_curr>>1) + (dx >> 1) ;
  1600. preCr = prev->Cr + ofy;
  1601. preCb = prev->Cb + ofy ;
  1602. if (!xh && !yh) {
  1603. n = 8 ;
  1604. while(n--) {
  1605. m = 8 ;
  1606. while(m--) {
  1607. *(ptnr++) += (short) *(preCr++);
  1608. *(ptnb++) += (short) *(preCb++);
  1609. };
  1610. preCr += ydiff ;
  1611. preCb += ydiff ;
  1612. };
  1613. }
  1614. else if (!xh && yh) {
  1615. ofyy = yh * lx ;
  1616. n = 8 ;
  1617. while(n--) {
  1618. m = 8 ;
  1619. while(m--) {
  1620. *(ptnr++) += (short)(*(preCr + ofyy) + *(preCr++) + 1)>>1;
  1621. *(ptnb++) += (short)(*(preCb + ofyy) + *(preCb++) + 1)>>1;
  1622. };
  1623. preCr += ydiff ;
  1624. preCb += ydiff ;
  1625. };
  1626. }
  1627. else if (xh && !yh) {
  1628. n = 8 ;
  1629. while(n--) {
  1630. m = 8 ;
  1631. while(m--) {
  1632. *(ptnr++) += (short)(*(preCr + xh) + *(preCr++) + 1)>>1;
  1633. *(ptnb++) += (short)(*(preCb + xh) + *(preCb++) + 1)>>1;
  1634. };
  1635. preCr += ydiff ;
  1636. preCb += ydiff ;
  1637. };
  1638. }
  1639. else { /* xh && yh */
  1640. ofyy = yh * lx ;
  1641. n = 8 ;
  1642. while(n--){
  1643. m = 8 ;
  1644. while(m--) {
  1645. *(ptnr++) += (short)(*(preCr + xh) + *(preCr + ofyy) +
  1646. *(preCr + xh + ofyy) + *(preCr++) + 2)>>2;
  1647. *(ptnb++) += (short)(*(preCb + xh) + *(preCb + ofyy)+
  1648. *(preCb + xh + ofyy) + *(preCb++) + 2)>>2;
  1649. };
  1650. preCr += ydiff ;
  1651. preCb += ydiff ;
  1652. };
  1653. }
  1654. return;
  1655. }
  1656. #endif
  1657. /**********************************************************************
  1658. *
  1659. * Name: FindChromBlock_P
  1660. * Description: Finds chrominance of one block in P frame
  1661. *
  1662. * Input: position, vector-data, previous image, data-block
  1663. *
  1664. ***********************************************************************/
  1665. #ifndef USE_C
  1666. static void FindChromBlock_P(SvH263CompressInfo_t *H263Info, int x_curr, int y_curr, int dx, int dy,
  1667. H263_PictImage *prev, H263_MB_Structure *data)
  1668. {
  1669. register int m,n;
  1670. int ofy, lx;
  1671. int xh, yh, ofyy, ydiff;
  1672. register short *ptnr, *ptnb;
  1673. register unsigned char *preCr, *preCb;
  1674. lx = (H263Info->mv_outside_frame ? H263Info->pels/2 + (H263Info->long_vectors?32:16) : H263Info->pels/2);
  1675. xh = dx & 1;
  1676. yh = dy & 1;
  1677. ptnr = &(data->Cr[0][0]) ;
  1678. ptnb = &(data->Cb[0][0]) ;
  1679. ydiff = lx - 8 ;
  1680. ofy = ( (y_curr>>1) + (dy>>1)) * lx + (x_curr>>1) + (dx>>1) ;
  1681. preCr = prev->Cr + ofy;
  1682. preCb = prev->Cb + ofy ;
  1683. if (!xh && !yh) sv_H263Cpy_S(preCr, ptnr, preCb, ptnb, lx);
  1684. else if (!xh && yh) {
  1685. ofyy = yh * lx ;
  1686. n = 8 ;
  1687. while(n--) {
  1688. m = 8 ;
  1689. while(m--) {
  1690. *(ptnr++) = (short)(*(preCr + ofyy) + *(preCr++) + 1)>>1;
  1691. *(ptnb++) = (short)(*(preCb + ofyy) + *(preCb++) + 1)>>1;
  1692. };
  1693. preCr += ydiff ;
  1694. preCb += ydiff ;
  1695. };
  1696. }
  1697. else if (xh && !yh) {
  1698. n = 8 ;
  1699. while(n--) {
  1700. m = 8 ;
  1701. while(m--) {
  1702. *(ptnr++) = (short)(*(preCr + xh) + *(preCr++) + 1)>>1;
  1703. *(ptnb++) = (short)(*(preCb + xh) + *(preCb++) + 1)>>1;
  1704. };
  1705. preCr += ydiff ;
  1706. preCb += ydiff ;
  1707. };
  1708. }
  1709. else { /* xh && yh */
  1710. ofyy = yh * lx ;
  1711. sv_H263Avg4Cpy_S(preCr,preCr+xh,preCr+ofyy,preCr+xh+ofyy,ptnr,lx);
  1712. sv_H263Avg4Cpy_S(preCb,preCb+xh,preCb+ofyy,preCb+xh+ofyy,ptnb,lx);
  1713. }
  1714. return;
  1715. }
  1716. #else
  1717. void FindChromBlock_P(SvH263CompressInfo_t *H263Info, int x_curr, int y_curr, int dx, int dy,
  1718. H263_PictImage *prev, H263_MB_Structure *data)
  1719. {
  1720. register int m,n;
  1721. int ofy, lx;
  1722. int xh, yh, ofyy, ydiff;
  1723. register short *ptnr, *ptnb;
  1724. register unsigned char *preCr, *preCb;
  1725. lx = (H263Info->mv_outside_frame ? H263Info->pels/2 + (H263Info->long_vectors?32:16) : H263Info->pels/2);
  1726. xh = dx & 1;
  1727. yh = dy & 1;
  1728. ptnr = &(data->Cr[0][0]) ;
  1729. ptnb = &(data->Cb[0][0]) ;
  1730. ydiff = lx - 8 ;
  1731. ofy = ( (y_curr>>1) + (dy>>1)) * lx + (x_curr>>1) + (dx>>1) ;
  1732. preCr = prev->Cr + ofy;
  1733. preCb = prev->Cb + ofy ;
  1734. if (!xh && !yh) {
  1735. n = 8 ;
  1736. while(n--) {
  1737. m = 8;
  1738. while(m--) {
  1739. *(ptnr++) = (short) *(preCr++);
  1740. *(ptnb++) = (short) *(preCb++);
  1741. };
  1742. preCr += ydiff ;
  1743. preCb += ydiff ;
  1744. };
  1745. }
  1746. else if (!xh && yh) {
  1747. ofyy = yh * lx ;
  1748. n = 8 ;
  1749. while(n--) {
  1750. m = 8 ;
  1751. while(m--) {
  1752. *(ptnr++) = (short)(*(preCr + ofyy) + *(preCr++) + 1)>>1;
  1753. *(ptnb++) = (short)(*(preCb + ofyy) + *(preCb++) + 1)>>1;
  1754. };
  1755. preCr += ydiff ;
  1756. preCb += ydiff ;
  1757. };
  1758. }
  1759. else if (xh && !yh) {
  1760. n = 8 ;
  1761. while(n--) {
  1762. m = 8 ;
  1763. while(m--) {
  1764. *(ptnr++) = (short)(*(preCr + xh) + *(preCr++) + 1)>>1;
  1765. *(ptnb++) = (short)(*(preCb + xh) + *(preCb++) + 1)>>1;
  1766. };
  1767. preCr += ydiff ;
  1768. preCb += ydiff ;
  1769. };
  1770. }
  1771. else { /* xh && yh */
  1772. ofyy = yh * lx ;
  1773. n = 8 ;
  1774. while(n--){
  1775. m = 8 ;
  1776. while(m--) {
  1777. *(ptnr++) = (short)(*(preCr + xh) + *(preCr + ofyy) +
  1778. *(preCr + xh + ofyy) + *(preCr++) + 2)>>2;
  1779. *(ptnb++) = (short)(*(preCb + xh) + *(preCb + ofyy)+
  1780. *(preCb + xh + ofyy) + *(preCb++) + 2)>>2;
  1781. };
  1782. preCr += ydiff ;
  1783. preCb += ydiff ;
  1784. };
  1785. }
  1786. return;
  1787. }
  1788. #endif
  1789. /**********************************************************************
  1790. *
  1791. * Name: ChooseMode
  1792. * Description: chooses coding mode
  1793. *
  1794. * Input: pointer to original fram, min_error from
  1795. * integer pel search, DQUANT
  1796. * Returns: 1 for Inter, 0 for Intra
  1797. *
  1798. ***********************************************************************/
  1799. #ifndef USE_C
  1800. int sv_H263ChooseMode(SvH263CompressInfo_t *H263Info, unsigned char *curr,
  1801. int x_pos, int y_pos, int min_SAD, int *VARmb)
  1802. {
  1803. x_pos += (y_pos*H263Info->pels) ;
  1804. min_SAD -= 500;
  1805. if((*VARmb=sv_H263VAR_S((curr+x_pos), H263Info->pels, min_SAD)) < min_SAD)
  1806. return H263_MODE_INTRA;
  1807. else return H263_MODE_INTER;
  1808. }
  1809. #else
  1810. int sv_H263ChooseMode(SvH263CompressInfo_t *H263Info,
  1811. unsigned char *curr, int x_pos, int y_pos, int min_SAD)
  1812. {
  1813. register int m, n;
  1814. int xdiff = H263Info->pels - H263_MB_SIZE;
  1815. unsigned char *in;
  1816. int MB_mean = 0, A = 0;
  1817. x_pos = y_pos*H263Info->pels + x_pos ;
  1818. in = curr + x_pos;
  1819. m = H263_MB_SIZE;
  1820. while (m--) {
  1821. n = H263_MB_SIZE;
  1822. while (n--) MB_mean += *in++;
  1823. in += xdiff ;
  1824. };
  1825. MB_mean /= (H263_MB_SIZE*H263_MB_SIZE);
  1826. in = curr + x_pos;
  1827. m = H263_MB_SIZE;
  1828. while (m--) {
  1829. n = H263_MB_SIZE;
  1830. while (n--) A += abs( *(in++) - MB_mean );
  1831. in += xdiff ;
  1832. };
  1833. if (A < (min_SAD - 500))
  1834. return H263_MODE_INTRA;
  1835. else
  1836. return H263_MODE_INTER;
  1837. }
  1838. #endif
  1839. int sv_H263ModifyMode(int Mode, int dquant)
  1840. {
  1841. if (Mode == H263_MODE_INTRA) {
  1842. if(dquant!=0)
  1843. return H263_MODE_INTRA_Q;
  1844. else
  1845. return H263_MODE_INTRA;
  1846. }
  1847. else{
  1848. if(dquant!=0)
  1849. return H263_MODE_INTER_Q;
  1850. else
  1851. return Mode;
  1852. }
  1853. }
  1854.