mcenc.cpp
上传用户:sun1608
上传日期:2007-02-02
资源大小:6116k
文件大小:31k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. /*************************************************************************
  2. This software module was originally developed by 
  3. Ming-Chieh Lee (mingcl@microsoft.com), Microsoft Corporation
  4. Bruce Lin (blin@microsoft.com), Microsoft Corporation
  5. Simon Winder (swinder@microsoft.com), Microsoft Corporation
  6. (date: June, 1997)
  7. and edited by
  8.         Wei Wu (weiwu@stallion.risc.rockwell.com) Rockwell Science Center
  9. in the course of development of the MPEG-4 Video (ISO/IEC 14496-2). 
  10. This software module is an implementation of a part of one or more MPEG-4 Video tools 
  11. as specified by the MPEG-4 Video. 
  12. ISO/IEC gives users of the MPEG-4 Video free license to this software module or modifications 
  13. thereof for use in hardware or software products claiming conformance to the MPEG-4 Video. 
  14. Those intending to use this software module in hardware or software products are advised that its use may infringe existing patents. 
  15. The original developer of this software module and his/her company, 
  16. the subsequent editors and their companies, 
  17. and ISO/IEC have no liability for use of this software module or modifications thereof in an implementation. 
  18. Copyright is not released for non MPEG-4 Video conforming products. 
  19. Microsoft retains full right to use the code for his/her own purpose, 
  20. assign or donate the code to a third party and to inhibit third parties from using the code for non <MPEG standard> conforming products. 
  21. This copyright notice must be included in all copies or derivative works. 
  22. Copyright (c) 1996, 1997.
  23. Module Name:
  24. mcenc.cpp
  25. Abstract:
  26. Motion compensation routines for encoder.
  27. Revision History:
  28. Dec 20, 1997: Interlaced tools added by NextLevel Systems
  29. *************************************************************************/
  30. #include <stdio.h>
  31. #include <math.h>
  32. #include <stdlib.h>
  33. #include <iostream.h>
  34. #include "typeapi.h"
  35. #include "codehead.h"
  36. #include "global.hpp"
  37. #include "entropy/bitstrm.hpp"
  38. #include "entropy/entropy.hpp"
  39. #include "entropy/huffman.hpp"
  40. #include "mode.hpp"
  41. #include "vopses.hpp"
  42. #include "vopseenc.hpp"
  43. #ifdef __MFC_
  44. #ifdef _DEBUG
  45. #undef THIS_FILE
  46. static char BASED_CODE THIS_FILE[] = __FILE__;
  47. #endif
  48. #define new DEBUG_NEW    
  49. #endif // __MFC_
  50. #define OFFSET_BLK1 8
  51. #define OFFSET_BLK2 128
  52. #define OFFSET_BLK3 136
  53. Void CVideoObjectEncoder::motionCompMBYEnc (
  54. const CMotionVector* pmv, const CMBMode* pmbmd, 
  55. Int imbX, Int imbY,
  56. CoordI x, CoordI y,
  57. CRct *prctMVLimit
  58. )
  59. {
  60. if (!m_volmd.bAdvPredDisable /* && pmbmd -> m_bhas4MVForward */ && !pmbmd->m_bFieldMV) {
  61. motionCompOverLapEncY (
  62. pmv, pmbmd,
  63. (imbX == 0), (imbX == m_iNumMBX - 1), (imbY == 0),
  64. x, y,
  65. prctMVLimit
  66. );
  67. }
  68. else {
  69. if (!pmbmd -> m_bhas4MVForward && !pmbmd -> m_bFieldMV)
  70. motionCompEncY (
  71. m_pvopcRefQ0->pixelsY (), 
  72. m_puciRefQZoom0->pixels (),
  73. m_ppxlcPredMBY, MB_SIZE, pmv, x, y,
  74. prctMVLimit
  75. );
  76. // INTERLACE
  77. else if (pmbmd -> m_bFieldMV) {
  78. const CMotionVector* pmvTop = pmv + 5 + pmbmd->m_bForwardTop;
  79. motionCompYField(m_ppxlcPredMBY,
  80. m_pvopcRefQ0->pixelsY () + pmbmd->m_bForwardTop * m_iFrameWidthY,
  81. 2*x + pmvTop->m_vctTrueHalfPel.x, 2*y + pmvTop->m_vctTrueHalfPel.y);
  82. const CMotionVector* pmvBottom = pmv + 7 + pmbmd->m_bForwardBottom;
  83. motionCompYField(m_ppxlcPredMBY + MB_SIZE,
  84. m_pvopcRefQ0->pixelsY () + pmbmd->m_bForwardBottom * m_iFrameWidthY,
  85. 2*x + pmvBottom->m_vctTrueHalfPel.x, 2*y + pmvBottom->m_vctTrueHalfPel.y);
  86. }
  87. // ~INTERLACE
  88. else {
  89. const CMotionVector* pmv8 = pmv;
  90. pmv8++;
  91. CoordI blkX = x + BLOCK_SIZE;
  92. CoordI blkY = y + BLOCK_SIZE;
  93. motionCompEncY (
  94. m_pvopcRefQ0->pixelsY (), 
  95. m_puciRefQZoom0->pixels (),
  96. m_ppxlcPredMBY, 
  97. BLOCK_SIZE, pmv8, x, y,
  98. prctMVLimit
  99. );
  100. pmv8++;
  101. motionCompEncY (
  102. m_pvopcRefQ0->pixelsY (), 
  103. m_puciRefQZoom0->pixels (),
  104. m_ppxlcPredMBY + OFFSET_BLK1, 
  105. BLOCK_SIZE, pmv8, blkX, y,
  106. prctMVLimit
  107. );
  108. pmv8++;
  109. motionCompEncY (
  110. m_pvopcRefQ0->pixelsY (), 
  111. m_puciRefQZoom0->pixels (),
  112. m_ppxlcPredMBY + OFFSET_BLK2, 
  113. BLOCK_SIZE, pmv8, x, blkY,
  114. prctMVLimit
  115. );
  116. pmv8++;
  117. motionCompEncY (
  118. m_pvopcRefQ0->pixelsY (), 
  119. m_puciRefQZoom0->pixels (),
  120. m_ppxlcPredMBY + OFFSET_BLK3, 
  121. BLOCK_SIZE, pmv8, blkX, blkY,
  122. prctMVLimit
  123. );
  124. }
  125. }
  126. if(m_volmd.fAUsage == EIGHT_BIT)
  127. motionCompMBAEnc (
  128. pmv, pmbmd,
  129. m_ppxlcPredMBA,
  130. m_pvopcRefQ0,
  131. x, y,
  132. m_vopmd.iRoundingControl,
  133. prctMVLimit,
  134. 0
  135. );
  136. }
  137. Void CVideoObjectEncoder::motionCompMBAEnc (
  138. const CMotionVector* pmv, const CMBMode* pmbmd, 
  139. PixelC *ppxlcPredMBA,
  140. CVOPU8YUVBA* pvopcRefQ,
  141. CoordI x, CoordI y,
  142. Int iRoundingControl,
  143. CRct *prctMVLimit,
  144. Int direction //12.22.98
  145. )
  146. {
  147. if (!pmbmd -> m_bhas4MVForward && !pmbmd -> m_bFieldMV) //12.22.98
  148. motionComp (
  149. ppxlcPredMBA,
  150. pvopcRefQ->pixelsA (), 
  151. MB_SIZE,
  152. x * 2 + pmv->trueMVHalfPel ().x, 
  153. y * 2 + pmv->trueMVHalfPel ().y ,
  154. iRoundingControl,
  155. prctMVLimit
  156. );
  157. // INTERLACE  12.22.98
  158. else if (pmbmd -> m_bFieldMV) {
  159. Int itmpref1,itmpref2;
  160. itmpref1=pmbmd->m_bForwardTop;
  161. itmpref2=pmbmd->m_bForwardBottom;
  162. if(m_vopmd.vopPredType==BVOP&&direction)
  163. {
  164. itmpref1=pmbmd->m_bBackwardTop;
  165. itmpref2=pmbmd->m_bBackwardBottom;
  166. }
  167. const CMotionVector* pmvTop,*pmvBottom;
  168. if(m_vopmd.vopPredType==BVOP)
  169. pmvTop = pmv + 1 + itmpref1;
  170. else
  171. pmvTop = pmv + 5 + itmpref1;
  172. motionCompYField(ppxlcPredMBA,
  173. pvopcRefQ->pixelsA () + itmpref1 * m_iFrameWidthY,
  174. 2*x + pmvTop->trueMVHalfPel ().x, 2*y + pmvTop->trueMVHalfPel ().y);
  175. if(m_vopmd.vopPredType==BVOP)
  176. pmvBottom = pmv + 3 + itmpref2;
  177. else
  178. pmvBottom = pmv + 7 + itmpref2;
  179. motionCompYField(ppxlcPredMBA + MB_SIZE,
  180. pvopcRefQ->pixelsA () + itmpref2 * m_iFrameWidthY,
  181. 2*x + pmvBottom->trueMVHalfPel ().x, 2*y + pmvBottom->trueMVHalfPel ().y);
  182. }
  183. // ~INTERLACE 12.22.98
  184. else {
  185. const CMotionVector* pmv8 = pmv;
  186. pmv8++;
  187. CoordI blkX = x + BLOCK_SIZE;
  188. CoordI blkY = y + BLOCK_SIZE;
  189. motionComp (
  190. ppxlcPredMBA,
  191. pvopcRefQ->pixelsA (),
  192. BLOCK_SIZE,
  193. x * 2 + pmv8->trueMVHalfPel ().x, 
  194. y * 2 + pmv8->trueMVHalfPel ().y,
  195. iRoundingControl,
  196. prctMVLimit
  197. );
  198. pmv8++;
  199. motionComp (
  200. ppxlcPredMBA + OFFSET_BLK1,
  201. pvopcRefQ->pixelsA (),   
  202. BLOCK_SIZE,
  203. blkX * 2 + pmv8->trueMVHalfPel ().x, 
  204. y * 2 + pmv8->trueMVHalfPel ().y,
  205. iRoundingControl,
  206. prctMVLimit
  207. );
  208. pmv8++;
  209. motionComp (
  210. ppxlcPredMBA + OFFSET_BLK2, 
  211. pvopcRefQ->pixelsA (), 
  212. BLOCK_SIZE,
  213. x * 2 + pmv8->trueMVHalfPel ().x, 
  214. blkY * 2 + pmv8->trueMVHalfPel ().y,
  215. iRoundingControl,
  216. prctMVLimit
  217. );
  218. pmv8++;
  219. motionComp (
  220. ppxlcPredMBA + OFFSET_BLK3,
  221. pvopcRefQ->pixelsA (),
  222. BLOCK_SIZE,
  223. blkX * 2 + pmv8->trueMVHalfPel ().x, 
  224. blkY * 2 + pmv8->trueMVHalfPel ().y,
  225. iRoundingControl,
  226. prctMVLimit
  227. );
  228. }
  229. }
  230. Void CVideoObjectEncoder::motionCompEncY (
  231. const PixelC* ppxlcRef, const PixelC* ppxlcRefZoom,
  232. PixelC* ppxlcPred,
  233. Int iSize, // either MB or BLOCK size
  234. const CMotionVector* pmv, // motion vector
  235. CoordI x, CoordI y, // current coordinate system
  236. CRct *prctMVLimit
  237. )
  238. {
  239. Int iUnit = sizeof(PixelC); // NBIT: for memcpy
  240. CoordI ix, iy;
  241.   Bool bXSubPxl, bYSubPxl;
  242.     CoordI xHalf = 2*x + pmv->m_vctTrueHalfPel.x;
  243.     CoordI yHalf = 2*y + pmv->m_vctTrueHalfPel.y;
  244. // CoordI xHalf = 2*(x + pmv->iMVX) + pmv->iHalfX;
  245. // CoordI yHalf = 2*(y + pmv->iMVY) + pmv->iHalfY;
  246. limitMVRangeToExtendedBBHalfPel(xHalf,yHalf,prctMVLimit,iSize);
  247. bXSubPxl = (xHalf&1);
  248. bYSubPxl = (yHalf&1);
  249. if (!bYSubPxl && !bXSubPxl) {
  250. const PixelC* ppxlcRefMB = ppxlcRef + m_rctRefFrameY.offset (xHalf>>1, yHalf>>1);
  251. for (iy = 0; iy < iSize; iy++) {
  252. memcpy (ppxlcPred, ppxlcRefMB, iSize*iUnit);
  253. ppxlcRefMB += m_iFrameWidthY;
  254. ppxlcPred += MB_SIZE;
  255. }
  256. }
  257. else {
  258. const PixelC* ppxlcPrevZoomY = ppxlcRefZoom
  259. + m_puciRefQZoom0->where ().offset (xHalf, yHalf);
  260. for (iy = 0; iy < iSize; iy++) {
  261. for (ix = 0; ix < iSize; ix++)
  262. ppxlcPred [ix] = ppxlcPrevZoomY [2 * ix]; 
  263. ppxlcPrevZoomY += m_iFrameWidthZoomY * 2;
  264. ppxlcPred += MB_SIZE;
  265. }
  266. }
  267. }
  268. Void CVideoObjectEncoder::motionCompOverLapEncY (
  269. const CMotionVector* pmv, // motion vector
  270. const CMBMode* pmbmd, // macroblk mode
  271. Bool bLeftBndry, Bool bRightBndry, Bool bTopBndry,
  272. CoordI x, // current coordinate system
  273. CoordI y, // current coordinate system
  274. CRct *prctMVLimit
  275. )
  276. {
  277. // Overlap Motion Comp use motion vector of current blk and motion vectors of neighboring blks.
  278. const CMotionVector *pmvC, *pmvT = NULL, *pmvB = NULL, *pmvR = NULL, *pmvL = NULL; // MVs of Cur, Top, Bot, Right and Left Blocks. 
  279. const CMotionVector *pmvCurrMb, *pmvTopMb, *pmvRightMb, *pmvLeftMb; // MVs of Cur, Top, Right and Left MacroBlocks.
  280. const CMBMode *pmbmdTopMb, *pmbmdRightMb, *pmbmdLeftMb; // MVs of Cur, Top, Right and Left MacroBlocks.
  281. Bool bIntraT, bIntraR, bIntraL; // flags of 4MV for Cur, Top, Right and Left MacroBlocks.
  282. pmvTopMb = NULL; // compile warning
  283. pmvRightMb = NULL;
  284. pmvLeftMb = NULL;
  285. pmbmdTopMb = NULL;
  286. pmbmdRightMb = NULL;
  287. pmbmdLeftMb = NULL;
  288. bIntraT = FALSE;
  289. bIntraR = FALSE;
  290. bIntraL = FALSE;
  291. pmvCurrMb = pmv;
  292. // assign values to bIntra[TRL] and pmv{TRL}Mb, when they are valid. 
  293. if (!bTopBndry) {
  294. pmbmdTopMb = pmbmd - m_iNumMBX; 
  295. bIntraT = (pmbmdTopMb->m_dctMd == INTRA || pmbmdTopMb->m_dctMd == INTRAQ);
  296. pmvTopMb = pmv - m_iNumOfTotalMVPerRow;
  297. }
  298. if (!bLeftBndry) {
  299. pmbmdLeftMb = pmbmd - 1;
  300. bIntraL = (pmbmdLeftMb->m_dctMd == INTRA || pmbmdLeftMb->m_dctMd == INTRAQ);
  301. pmvLeftMb = pmv - PVOP_MV_PER_REF_PER_MB;
  302. }
  303. if (!bRightBndry) {
  304. pmbmdRightMb = pmbmd + 1;
  305. bIntraR = (pmbmdRightMb->m_dctMd == INTRA || pmbmdRightMb->m_dctMd == INTRAQ);
  306. pmvRightMb = pmv + PVOP_MV_PER_REF_PER_MB;
  307. }
  308. UInt i;
  309. // assign the neighboring blk's MVs to pmv[TBRLC] 
  310. for (i = 1; i < 5; i++) {
  311. if (pmbmd->m_rgTranspStatus [i] == ALL)
  312. continue;
  313. pmvC = pmvCurrMb + i;
  314. switch (i) {
  315. case 1:
  316. if (pmbmd->m_rgTranspStatus [3] == ALL)
  317. pmvB = pmvCurrMb + 1;
  318. else
  319. pmvB = pmvCurrMb + 3;
  320. if (pmbmd->m_rgTranspStatus [2] == ALL)
  321. pmvR = pmvCurrMb + 1; 
  322. else
  323. pmvR = pmvCurrMb + 2; 
  324. if (bTopBndry || bIntraT || pmbmdTopMb->m_rgTranspStatus [3] == ALL)
  325. pmvT = pmvCurrMb + 1;
  326. else
  327. pmvT = pmvTopMb + 3;
  328. if (bLeftBndry || bIntraL || pmbmdLeftMb->m_rgTranspStatus [2] == ALL)
  329. pmvL = pmvCurrMb + 1;
  330. else
  331. pmvL = pmvLeftMb + 2;
  332. break;
  333. case 2:
  334. if (pmbmd->m_rgTranspStatus [4] == ALL)
  335. pmvB = pmvCurrMb + 2;
  336. else
  337. pmvB = pmvCurrMb + 4;
  338. if (pmbmd->m_rgTranspStatus [1] == ALL)
  339. pmvL = pmvCurrMb + 2;
  340. else
  341. pmvL = pmvCurrMb + 1;
  342. if (bTopBndry || bIntraT || pmbmdTopMb->m_rgTranspStatus [4] == ALL)
  343. pmvT = pmvCurrMb + 2;
  344. else
  345. pmvT = pmvTopMb + 4;      
  346. if (bRightBndry || bIntraR || pmbmdRightMb->m_rgTranspStatus [1] == ALL)
  347. pmvR = pmvCurrMb + 2;
  348. else
  349. pmvR = pmvRightMb + 1;
  350. break;
  351. case 3:
  352. if (pmbmd->m_rgTranspStatus [1] == ALL)
  353. pmvT = pmvCurrMb + 3;  
  354. else
  355. pmvT = pmvCurrMb + 1;
  356. pmvB = pmvCurrMb + 3; // use the current mv
  357. if (pmbmd->m_rgTranspStatus [4] == ALL)
  358. pmvR = pmvCurrMb + 3;
  359. else
  360. pmvR = pmvCurrMb + 4;
  361. if (bLeftBndry || bIntraL || pmbmdLeftMb->m_rgTranspStatus [4] == ALL)
  362. pmvL = pmvCurrMb + 3;
  363. else
  364. pmvL = pmvLeftMb + 4;
  365. break;
  366. case 4:
  367. if (pmbmd->m_rgTranspStatus [2] == ALL)
  368. pmvT = pmvCurrMb + 4;    
  369. else
  370. pmvT = pmvCurrMb + 2;
  371. pmvB = pmvCurrMb + 4;
  372. if (pmbmd->m_rgTranspStatus [3] == ALL)
  373. pmvL = pmvCurrMb + 4;  
  374. else
  375. pmvL = pmvCurrMb + 3;
  376. if (bRightBndry || bIntraR || pmbmdRightMb->m_rgTranspStatus [3] == ALL)
  377. pmvR = pmvCurrMb + 4;
  378. else
  379. pmvR = pmvRightMb + 3;
  380. break;
  381. default:
  382. assert (FALSE);
  383. }
  384. // Compute the top left corner's x,y coordinates of current block.
  385. UInt dxc = (((i - 1) & 1) << 3); 
  386. UInt dyc = (((i - 1) & 2) << 2);
  387. UInt nxcY = (x + dxc) << 1; 
  388. UInt nycY = (y + dyc) << 1; 
  389. // Compute the corresponding positions on Ref frm, using 5 MVs.
  390. CoordI xRefC = nxcY + pmvC->m_vctTrueHalfPel.x, yRefC = nycY + pmvC->m_vctTrueHalfPel.y;
  391. CoordI xRefT = nxcY + pmvT->m_vctTrueHalfPel.x, yRefT = nycY + pmvT->m_vctTrueHalfPel.y;
  392. CoordI xRefB = nxcY + pmvB->m_vctTrueHalfPel.x, yRefB = nycY + pmvB->m_vctTrueHalfPel.y;
  393. CoordI xRefR = nxcY + pmvR->m_vctTrueHalfPel.x, yRefR = nycY + pmvR->m_vctTrueHalfPel.y;
  394. CoordI xRefL = nxcY + pmvL->m_vctTrueHalfPel.x, yRefL = nycY + pmvL->m_vctTrueHalfPel.y;
  395. // UInt nxcY = x + dxc; 
  396. //   UInt nycY = y + dyc; 
  397. // // Compute the corresponding positions on Ref frm, using 5 MVs.
  398. // CoordI xRefC = ((nxcY + pmvC->iMVX) << 1) + pmvC->iHalfX, yRefC = ((nycY + pmvC->iMVY) << 1) + pmvC->iHalfY;
  399. // CoordI xRefT = ((nxcY + pmvT->iMVX) << 1) + pmvT->iHalfX, yRefT = ((nycY + pmvT->iMVY) << 1) + pmvT->iHalfY;
  400. // CoordI xRefB = ((nxcY + pmvB->iMVX) << 1) + pmvB->iHalfX, yRefB = ((nycY + pmvB->iMVY) << 1) + pmvB->iHalfY;
  401. // CoordI xRefR = ((nxcY + pmvR->iMVX) << 1) + pmvR->iHalfX, yRefR = ((nycY + pmvR->iMVY) << 1) + pmvR->iHalfY;
  402. // CoordI xRefL = ((nxcY + pmvL->iMVX) << 1) + pmvL->iHalfX, yRefL = ((nycY + pmvL->iMVY) << 1) + pmvL->iHalfY;
  403. limitMVRangeToExtendedBBHalfPel (xRefC,yRefC,prctMVLimit,BLOCK_SIZE);
  404. limitMVRangeToExtendedBBHalfPel (xRefT,yRefT,prctMVLimit,BLOCK_SIZE);
  405. limitMVRangeToExtendedBBHalfPel (xRefB,yRefB,prctMVLimit,BLOCK_SIZE);
  406. limitMVRangeToExtendedBBHalfPel (xRefR,yRefR,prctMVLimit,BLOCK_SIZE);
  407. limitMVRangeToExtendedBBHalfPel (xRefL,yRefL,prctMVLimit,BLOCK_SIZE);
  408. //PixelC* ppxlcPredY = ppxlcYMB + dxc + dyc * m_iWidthY;  // Starting of Pred. Frame
  409. PixelC* ppxlcPred = m_ppxlcPredMBY + dxc + dyc * MB_SIZE;  // Starting of Pred. Frame
  410. // 5 starting pos. in Zoomed Ref. Frames
  411. // m_ppxlcRefZoom0Y +  (xRefC, yRefC);
  412. const PixelC* ppxlcPrevZoomYC;
  413. const PixelC* ppxlcPrevZoomYT;
  414. const PixelC* ppxlcPrevZoomYB;
  415. const PixelC* ppxlcPrevZoomYR;
  416. const PixelC* ppxlcPrevZoomYL;
  417. ppxlcPrevZoomYC = m_puciRefQZoom0->pixels () + 
  418. (yRefC + EXPANDY_REF_FRAMEx2) * m_iFrameWidthZoomY +
  419. xRefC + EXPANDY_REF_FRAMEx2;
  420. ppxlcPrevZoomYT = m_puciRefQZoom0->pixels () + 
  421. (yRefT + EXPANDY_REF_FRAMEx2) * m_iFrameWidthZoomY +
  422. xRefT + EXPANDY_REF_FRAMEx2;
  423. ppxlcPrevZoomYB = m_puciRefQZoom0->pixels () + 
  424. (yRefB + EXPANDY_REF_FRAMEx2) * m_iFrameWidthZoomY +
  425. xRefB + EXPANDY_REF_FRAMEx2;
  426. ppxlcPrevZoomYR = m_puciRefQZoom0->pixels () + 
  427. (yRefR + EXPANDY_REF_FRAMEx2) * m_iFrameWidthZoomY +
  428. xRefR + EXPANDY_REF_FRAMEx2;
  429. ppxlcPrevZoomYL = m_puciRefQZoom0->pixels () + 
  430. (yRefL + EXPANDY_REF_FRAMEx2) * m_iFrameWidthZoomY +
  431. xRefL + EXPANDY_REF_FRAMEx2;
  432. UInt *pWghtC, *pWghtT, *pWghtB, *pWghtR, *pWghtL;
  433. pWghtC = (UInt*) gWghtC;
  434. pWghtT = (UInt*) gWghtT;
  435. pWghtB = (UInt*) gWghtB;
  436. pWghtR = (UInt*) gWghtR;
  437. pWghtL = (UInt*) gWghtL;
  438. for (UInt iy = 0; iy < BLOCK_SIZE; iy++) {
  439. for (UInt ix = 0; ix < BLOCK_SIZE; ix++) {
  440. *ppxlcPred++ = (
  441. *ppxlcPrevZoomYC * *pWghtC++ + 
  442. *ppxlcPrevZoomYT * *pWghtT++ + 
  443. *ppxlcPrevZoomYB * *pWghtB++ + 
  444. *ppxlcPrevZoomYR * *pWghtR++ + 
  445. *ppxlcPrevZoomYL * *pWghtL++ + 4
  446. ) >> 3;
  447. ppxlcPrevZoomYC += 2;
  448. ppxlcPrevZoomYT += 2;
  449. ppxlcPrevZoomYB += 2;
  450. ppxlcPrevZoomYR += 2;
  451. ppxlcPrevZoomYL += 2;
  452. }
  453. ppxlcPrevZoomYC += m_iFrameWidthZoomYx2Minus2Blk;
  454. ppxlcPrevZoomYT += m_iFrameWidthZoomYx2Minus2Blk;
  455. ppxlcPrevZoomYB += m_iFrameWidthZoomYx2Minus2Blk;
  456. ppxlcPrevZoomYR += m_iFrameWidthZoomYx2Minus2Blk;
  457. ppxlcPrevZoomYL += m_iFrameWidthZoomYx2Minus2Blk;
  458. ppxlcPred += BLOCK_SIZE;
  459. }
  460. }
  461. }
  462. // for B-VOP
  463. Void CVideoObjectEncoder::averagePredAndComputeErrorY()
  464. {
  465. Int ic;
  466. for (ic = 0; ic < MB_SQUARE_SIZE; ic++) {
  467. m_ppxlcPredMBY [ic] = (m_ppxlcPredMBY [ic] + m_ppxlcPredMBBackY [ic] + 1) >> 1;
  468. m_ppxliErrorMBY [ic] = m_ppxlcCurrMBY [ic] - m_ppxlcPredMBY [ic];
  469. }
  470. }
  471. //INTERLACE
  472. //new changes
  473. Void CVideoObjectEncoder::averagePredAndComputeErrorY_WithShape()
  474. {
  475. Int ic;
  476. for (ic = 0; ic < MB_SQUARE_SIZE; ic++) {
  477. if (m_ppxlcCurrMBBY [ic] == transpValue)
  478. m_ppxliErrorMBY [ic] = 0;
  479. else {
  480. m_ppxlcPredMBY [ic] = (m_ppxlcPredMBY [ic] + m_ppxlcPredMBBackY [ic] + 1) >> 1;
  481. m_ppxliErrorMBY [ic] = m_ppxlcCurrMBY [ic] - m_ppxlcPredMBY [ic];
  482. }
  483. }
  484. }
  485. // new changes
  486. //INTERLACE
  487. Void CVideoObjectEncoder::motionCompAndDiff_BVOP_MB (
  488. const CMotionVector* pmvForward, const CMotionVector* pmvBackward, 
  489.  CMBMode* pmbmd, 
  490. CoordI x, CoordI y,
  491. CRct *prctMVLimitForward,CRct *prctMVLimitBackward
  492. )
  493. {
  494.     if (m_vopmd.bInterlace) {           // Should work for both progressive and interlaced, but keep
  495.                                         // original code for now due to differences in direct mode.   Bob Eifrig
  496.     switch (pmbmd->m_mbType) {
  497.     case FORWARD:
  498.     motionCompOneBVOPReference(m_pvopcPredMB, FORWARD,  x, y, pmbmd, pmvForward, prctMVLimitForward);
  499.     computeTextureError();
  500.     break;
  501.     case BACKWARD:
  502.     motionCompOneBVOPReference(m_pvopcPredMB, BACKWARD, x, y, pmbmd, pmvBackward, prctMVLimitBackward);
  503.     computeTextureError();
  504.     break;
  505.     case DIRECT:
  506.     motionCompDirectMode(x, y, pmbmd,
  507.                 &m_rgmvRef[(PVOP_MV_PER_REF_PER_MB*(x + m_iNumMBX * y)) / MB_SIZE],
  508.                 prctMVLimitForward, prctMVLimitBackward,0);  // new change 02-19-99
  509.     averagePredAndComputeErrorY();
  510.     averagePredAndComputeErrorUV();
  511.     break;
  512.     case INTERPOLATE:
  513.     motionCompOneBVOPReference(m_pvopcPredMB,     FORWARD,  x, y, pmbmd, pmvForward, prctMVLimitForward);
  514.     motionCompOneBVOPReference(m_pvopcPredMBBack, BACKWARD, x, y, pmbmd, pmvBackward, prctMVLimitBackward);
  515.     averagePredAndComputeErrorY();
  516.     averagePredAndComputeErrorUV();
  517.     break;
  518.     }
  519.         return;
  520.     }
  521. if (pmbmd->m_mbType == DIRECT || pmbmd->m_mbType == INTERPOLATE) { // Y is done when doing motion estimation
  522. motionCompInterpAndError (pmvForward, pmvBackward, x, y,prctMVLimitForward,prctMVLimitBackward);
  523. CoordI xRefUVForward, yRefUVForward;
  524. mvLookupUVWithShape (pmbmd, pmvForward, xRefUVForward, yRefUVForward);
  525. motionCompUV (m_ppxlcPredMBU, m_ppxlcPredMBV, m_pvopcRefQ0, x, y, xRefUVForward, yRefUVForward, 0, prctMVLimitForward);
  526. CoordI xRefUVBackward, yRefUVBackward;
  527. mvLookupUVWithShape (pmbmd, pmvBackward, xRefUVBackward, yRefUVBackward);
  528. motionCompUV (m_ppxlcPredMBBackU, m_ppxlcPredMBBackV, m_pvopcRefQ1, x, y, xRefUVBackward, yRefUVBackward, 0, prctMVLimitBackward);
  529. averagePredAndComputeErrorUV ();
  530. }
  531. else { 
  532. const CMotionVector* pmv;
  533. const PixelC* ppxlcRef; // point to left-top of the reference VOP
  534. const PixelC* ppxlcRefZoom; // point to left-top of the reference VOP
  535. const CVOPU8YUVBA* pvopcRef;
  536. CRct *prctMVLimit;
  537. if (pmbmd->m_mbType == FORWARD) { // Y is done when doing motion estimation
  538. pmv = pmvForward;
  539. pvopcRef = m_pvopcRefQ0;
  540. ppxlcRef = m_pvopcRefQ0->pixelsY (); // point to left-top of the reference VOP
  541. ppxlcRefZoom = m_puciRefQZoom0->pixels (); // point to left-top of the reference VOP
  542. prctMVLimit=prctMVLimitForward;
  543. }
  544. else {
  545. pmv = pmvBackward;
  546. pvopcRef = m_pvopcRefQ1;
  547. ppxlcRef = m_pvopcRefQ1->pixelsY (); // point to left-top of the reference VOP
  548. ppxlcRefZoom = m_puciRefQZoom1->pixels (); // point to left-top of the reference VOP
  549. prctMVLimit=prctMVLimitBackward;
  550. }
  551. CoordI xRefUV, yRefUV;
  552. mvLookupUVWithShape (pmbmd, pmv, xRefUV, yRefUV);
  553. motionCompEncY (ppxlcRef, ppxlcRefZoom, m_ppxlcPredMBY, MB_SIZE, pmv, x, y,prctMVLimit);
  554. motionCompUV (m_ppxlcPredMBU, m_ppxlcPredMBV, pvopcRef, x, y, xRefUV, yRefUV, 0, prctMVLimit);
  555. computeTextureError ();
  556. }
  557. }
  558. Void CVideoObjectEncoder::motionCompAndDiff_BVOP_MB_WithShape (
  559. const CMotionVector* pmvForward, const CMotionVector* pmvBackward, 
  560.  CMBMode* pmbmd, 
  561. CoordI x, CoordI y,
  562. CRct *prctMVLimitForward,
  563. CRct *prctMVLimitBackward
  564. )
  565. {
  566. // INTERLACED
  567. // new changes
  568.     if (m_vopmd.bInterlace&&pmbmd->m_bFieldMV) {           // Should work for both progressive and interlaced, but keep
  569.                                         // original code for now due to differences in direct mode.   Bob Eifrig
  570.     switch (pmbmd->m_mbType) {
  571.     case FORWARD:
  572.     motionCompOneBVOPReference(m_pvopcPredMB, FORWARD,  x, y, pmbmd, pmvForward, prctMVLimitForward);
  573.     computeTextureErrorWithShape();
  574.     break;
  575.     case BACKWARD:
  576.     motionCompOneBVOPReference(m_pvopcPredMB, BACKWARD, x, y, pmbmd, pmvBackward, prctMVLimitBackward);
  577.     computeTextureErrorWithShape();
  578.     break;
  579.     case DIRECT:
  580.     motionCompDirectMode(x, y, pmbmd,
  581.                 &m_rgmvRef[(PVOP_MV_PER_REF_PER_MB*(x + m_iNumMBX * y)) / MB_SIZE],
  582.                 prctMVLimitForward, prctMVLimitBackward,0);   // new change 02-19-99
  583.     averagePredAndComputeErrorY_WithShape();
  584.     averagePredAndComputeErrorUV_WithShape();
  585.     break;
  586.     case INTERPOLATE:
  587.     motionCompOneBVOPReference(m_pvopcPredMB,     FORWARD,  x, y, pmbmd, pmvForward, prctMVLimitForward);
  588.     motionCompOneBVOPReference(m_pvopcPredMBBack, BACKWARD, x, y, pmbmd, pmvBackward, prctMVLimitBackward);
  589.     averagePredAndComputeErrorY_WithShape();
  590.     averagePredAndComputeErrorUV_WithShape();
  591.     break;
  592.     }
  593.         return;
  594.     }
  595. // INTERLACED
  596. // end of new changes
  597. if (pmbmd->m_mbType == DIRECT || pmbmd->m_mbType == INTERPOLATE) { // Y is done when doing motion estimation
  598. motionCompInterpAndError_WithShape (pmvForward, pmvBackward, x, y,prctMVLimitForward,prctMVLimitBackward);
  599. CoordI xRefUVForward, yRefUVForward;
  600. mvLookupUVWithShape (pmbmd, pmvForward, xRefUVForward, yRefUVForward);
  601. motionCompUV (m_ppxlcPredMBU, m_ppxlcPredMBV, m_pvopcRefQ0, x, y, xRefUVForward, yRefUVForward, 0, prctMVLimitForward);
  602. CoordI xRefUVBackward, yRefUVBackward;
  603. mvLookupUVWithShape (pmbmd, pmvBackward, xRefUVBackward, yRefUVBackward);
  604. motionCompUV (m_ppxlcPredMBBackU, m_ppxlcPredMBBackV, m_pvopcRefQ1, x, y, xRefUVBackward, yRefUVBackward, 0, prctMVLimitBackward);
  605. averagePredAndComputeErrorUV_WithShape ();
  606. }
  607. else { 
  608. const CMotionVector* pmv;
  609. const PixelC* ppxlcRef; // point to left-top of the reference VOP
  610. const PixelC* ppxlcRefZoom; // point to left-top of the reference VOP
  611. const CVOPU8YUVBA* pvopcRef;
  612. CRct *prctMVLimit;
  613. if (pmbmd->m_mbType == FORWARD) { // Y is done when doing motion estimation
  614. pmv = pmvForward;
  615. pvopcRef = m_pvopcRefQ0;
  616. ppxlcRef = m_pvopcRefQ0->pixelsY (); // point to left-top of the reference VOP
  617. ppxlcRefZoom = m_puciRefQZoom0->pixels (); // point to left-top of the reference VOP
  618. prctMVLimit = prctMVLimitForward;
  619. }
  620. else {
  621. pmv = pmvBackward;
  622. pvopcRef = m_pvopcRefQ1;
  623. ppxlcRef = m_pvopcRefQ1->pixelsY (); // point to left-top of the reference VOP
  624. ppxlcRefZoom = m_puciRefQZoom1->pixels (); // point to left-top of the reference VOP
  625. prctMVLimit = prctMVLimitBackward;
  626. }
  627. CoordI xRefUV, yRefUV;
  628. mvLookupUVWithShape (pmbmd, pmv, xRefUV, yRefUV);
  629. motionCompEncY (ppxlcRef, ppxlcRefZoom, m_ppxlcPredMBY, MB_SIZE, pmv, x, y,prctMVLimit);
  630. motionCompUV (m_ppxlcPredMBU, m_ppxlcPredMBV, pvopcRef, x, y, xRefUV, yRefUV, 0, prctMVLimit);
  631. computeTextureErrorWithShape ();
  632. }
  633. }
  634. Void CVideoObjectEncoder::motionCompAndDiffAlpha_BVOP_MB (
  635. const CMotionVector* pmvForward, const CMotionVector* pmvBackward, 
  636. const CMBMode* pmbmd, 
  637. CoordI x, CoordI y,
  638. CRct *prctMVLimitForward,CRct *prctMVLimitBackward
  639. )
  640. {
  641. if (pmbmd->m_mbType == DIRECT || pmbmd->m_mbType == INTERPOLATE) {
  642. motionCompMBAEnc (pmvForward, pmbmd, m_ppxlcPredMBA, m_pvopcRefQ0,
  643. x, y, 0, prctMVLimitForward,0);
  644. motionCompMBAEnc (pmvBackward, pmbmd, m_ppxlcPredMBBackA, m_pvopcRefQ1,
  645. x, y, 0, prctMVLimitBackward,1);
  646. // average predictions
  647. Int i;
  648. for(i = 0; i<MB_SQUARE_SIZE; i++)
  649. m_ppxlcPredMBA[i] = (m_ppxlcPredMBA[i] + m_ppxlcPredMBBackA[i] + 1)>>1;
  650. }
  651. else { 
  652. const CMotionVector* pmv;
  653. const PixelC* ppxlcRef; // point to left-top of the reference VOP
  654. CRct *prctMVLimit;
  655. if (pmbmd->m_mbType == FORWARD) {
  656. pmv = pmvForward;
  657. ppxlcRef = m_pvopcRefQ0->pixelsA (); // point to left-top of the reference VOP
  658. prctMVLimit = prctMVLimitForward;
  659. // 12.22.98 begin of changes
  660. if(m_vopmd.bInterlace&&pmbmd->m_bFieldMV)
  661. motionCompMBAEnc (pmvForward, pmbmd, m_ppxlcPredMBA, m_pvopcRefQ0,
  662. x, y, 0, prctMVLimitForward,0);
  663. // end of changes
  664. }
  665. else {
  666. pmv = pmvBackward;
  667. ppxlcRef = m_pvopcRefQ1->pixelsA (); // point to left-top of the reference VOP
  668. prctMVLimit = prctMVLimitBackward;
  669. // 12.22.98 begin of changes
  670. if(m_vopmd.bInterlace&&pmbmd->m_bFieldMV)
  671. motionCompMBAEnc (pmvBackward, pmbmd, m_ppxlcPredMBA, m_pvopcRefQ1,
  672. x, y, 0, prctMVLimitBackward,1);
  673. // end of changes
  674. }
  675. if((!m_vopmd.bInterlace||(m_vopmd.bInterlace&&!pmbmd->m_bFieldMV))) // 12.22.98 changes
  676. motionComp (
  677. m_ppxlcPredMBA,
  678. ppxlcRef,
  679. MB_SIZE, // MB size
  680. x * 2 + pmv->trueMVHalfPel ().x, 
  681. y * 2 + pmv->trueMVHalfPel ().y,
  682. 0,
  683. prctMVLimit
  684. );
  685. }
  686. computeAlphaError();
  687. }
  688. Void CVideoObjectEncoder::averagePredAndComputeErrorUV ()
  689. {
  690. Int i = 0;
  691. for (i = 0; i < BLOCK_SQUARE_SIZE; i++) {
  692. m_ppxlcPredMBU [i] = (m_ppxlcPredMBU [i] + m_ppxlcPredMBBackU [i] + 1) >> 1;
  693. m_ppxlcPredMBV [i] = (m_ppxlcPredMBV [i] + m_ppxlcPredMBBackV [i] + 1) >> 1;
  694. m_ppxliErrorMBU [i] = m_ppxlcCurrMBU [i] - m_ppxlcPredMBU [i];
  695. m_ppxliErrorMBV [i] = m_ppxlcCurrMBV [i] - m_ppxlcPredMBV [i];
  696. }
  697. }
  698. Void CVideoObjectEncoder::averagePredAndComputeErrorUV_WithShape ()
  699. {
  700. Int i = 0;
  701. for (i = 0; i < BLOCK_SQUARE_SIZE; i++) {
  702. if (m_ppxlcCurrMBBUV [i] == transpValue)
  703. m_ppxliErrorMBU [i] = m_ppxliErrorMBV [i] = 0;
  704. else {
  705. m_ppxlcPredMBU [i] = (m_ppxlcPredMBU [i] + m_ppxlcPredMBBackU [i] + 1) >> 1;
  706. m_ppxlcPredMBV [i] = (m_ppxlcPredMBV [i] + m_ppxlcPredMBBackV [i] + 1) >> 1;
  707. m_ppxliErrorMBU [i] = m_ppxlcCurrMBU [i] - m_ppxlcPredMBU [i];
  708. m_ppxliErrorMBV [i] = m_ppxlcCurrMBV [i] - m_ppxlcPredMBV [i];
  709. }
  710. }
  711. }
  712. // B-VOP ME/MC stuff
  713. Int CVideoObjectEncoder::interpolateAndDiffY (
  714. const CMotionVector* pmvForward, const CMotionVector* pmvBackward, 
  715. CoordI x, CoordI y,
  716. CRct *prctMVLimitForward,CRct *prctMVLimitBackward
  717. )
  718. {
  719. motionCompEncY (
  720. m_pvopcRefQ0->pixelsY (), 
  721. m_puciRefQZoom0->pixels (),
  722. m_ppxlcPredMBY, MB_SIZE, pmvForward, x, y,
  723. prctMVLimitForward
  724. );
  725. /*Int iLeft  = (x << 1) + pmvBackward->m_vctTrueHalfPel.x;
  726. Int iRight = (y << 1) + pmvBackward->m_vctTrueHalfPel.y;
  727. //make sure don't end up with a mv that points out of a frame; object-based not done
  728. if (!m_puciRefQZoom1->where ().includes (CRct (iLeft, iRight, iLeft + (MB_SIZE << 1), iRight + (MB_SIZE << 1))))
  729. return 1000000000;
  730. else*/
  731. motionCompEncY (
  732. m_pvopcRefQ1->pixelsY (), 
  733. m_puciRefQZoom1->pixels (),
  734. m_ppxlcPredMBBackY, MB_SIZE, pmvBackward, x, y,
  735. prctMVLimitBackward
  736. );
  737. Int ic;
  738. Int iSAD = 0;
  739. for (ic = 0; ic < MB_SQUARE_SIZE; ic++)
  740. iSAD += abs (m_ppxlcCurrMBY [ic] - ((m_ppxlcPredMBY [ic] + m_ppxlcPredMBBackY [ic] + 1) >> 1));
  741. return iSAD;
  742. }
  743. Int CVideoObjectEncoder::interpolateAndDiffY_WithShape (
  744. const CMotionVector* pmvForward, const CMotionVector* pmvBackward, 
  745. CoordI x, CoordI y,
  746. CRct *prctMVLimitForward,CRct *prctMVLimitBackward
  747. )
  748. {
  749. motionCompEncY (
  750. m_pvopcRefQ0->pixelsY (), 
  751. m_puciRefQZoom0->pixels (),
  752. m_ppxlcPredMBY, MB_SIZE, pmvForward, x, y,
  753. prctMVLimitForward
  754. );
  755. motionCompEncY (
  756. m_pvopcRefQ1->pixelsY (), 
  757. m_puciRefQZoom1->pixels (),
  758. m_ppxlcPredMBBackY, MB_SIZE, pmvBackward, x, y,
  759. prctMVLimitBackward
  760. );
  761. Int ic;
  762. Int iSAD = 0;
  763. for (ic = 0; ic < MB_SQUARE_SIZE; ic++) {
  764. if (m_ppxlcCurrMBBY [ic] != transpValue)
  765. iSAD += abs (m_ppxlcCurrMBY [ic] - ((m_ppxlcPredMBY [ic] + m_ppxlcPredMBBackY [ic] + 1) >> 1));
  766. }
  767. return iSAD;
  768. }
  769. Int CVideoObjectEncoder::interpolateAndDiffYField(
  770. const CMotionVector* pmvFwdTop,
  771. const CMotionVector* pmvFwdBot,
  772. const CMotionVector* pmvBakTop,
  773. const CMotionVector* pmvBakBot,
  774. CoordI x, CoordI y,
  775. CMBMode *pmbmd
  776. )
  777. {
  778. x <<= 1;
  779. y <<= 1;
  780. motionCompYField(m_ppxlcPredMBY,
  781. m_pvopcRefQ0->pixelsY () + pmbmd->m_bForwardTop * m_iFrameWidthY,
  782. x + pmvFwdTop->m_vctTrueHalfPel.x, y + pmvFwdTop->m_vctTrueHalfPel.y);
  783. motionCompYField(m_ppxlcPredMBY + MB_SIZE,
  784. m_pvopcRefQ0->pixelsY () + pmbmd->m_bForwardBottom * m_iFrameWidthY,
  785. x + pmvFwdBot->m_vctTrueHalfPel.x, y + pmvFwdBot->m_vctTrueHalfPel.y);
  786. motionCompYField(m_ppxlcPredMBBackY,
  787. m_pvopcRefQ1->pixelsY () + pmbmd->m_bBackwardTop * m_iFrameWidthY,
  788. x + pmvBakTop->m_vctTrueHalfPel.x, y + pmvBakTop->m_vctTrueHalfPel.y);
  789. motionCompYField(m_ppxlcPredMBBackY + MB_SIZE,
  790. m_pvopcRefQ1->pixelsY () + pmbmd->m_bBackwardBottom * m_iFrameWidthY,
  791. x + pmvBakBot->m_vctTrueHalfPel.x, y + pmvBakBot->m_vctTrueHalfPel.y);
  792. Int ic;
  793. Int iSAD = 0;
  794. // new changes by X. Chen
  795. if (pmbmd->m_rgTranspStatus[0]==NONE) {
  796. for (ic = 0; ic < MB_SQUARE_SIZE; ic++)
  797. iSAD += abs (m_ppxlcCurrMBY [ic] - ((m_ppxlcPredMBY [ic] + m_ppxlcPredMBBackY [ic] + 1) >> 1));
  798. } else if (pmbmd->m_rgTranspStatus[0]==PARTIAL) {
  799. for (ic = 0; ic < MB_SQUARE_SIZE; ic++) {
  800. if (m_ppxlcCurrMBBY [ic] != transpValue)
  801. iSAD += abs (m_ppxlcCurrMBY [ic] - ((m_ppxlcPredMBY [ic] + m_ppxlcPredMBBackY [ic] + 1) >> 1));
  802. }
  803. }
  804. // end of new changes
  805. return iSAD;
  806. }
  807. Void CVideoObjectEncoder::motionCompInterpAndError (
  808. const CMotionVector* pmvForward, const CMotionVector* pmvBackward, 
  809. CoordI x, CoordI y,
  810. CRct *prctMVLimitForward,CRct *prctMVLimitBackward
  811. )
  812. {
  813. motionCompEncY (
  814. m_pvopcRefQ0->pixelsY (), 
  815. m_puciRefQZoom0->pixels (),
  816. m_ppxlcPredMBY, MB_SIZE, pmvForward, x, y,
  817. prctMVLimitForward
  818. );
  819. motionCompEncY (
  820. m_pvopcRefQ1->pixelsY (), 
  821. m_puciRefQZoom1->pixels (),
  822. m_ppxlcPredMBBackY, MB_SIZE, pmvBackward, x, y,
  823. prctMVLimitBackward
  824. );
  825. Int ic;
  826. for (ic = 0; ic < MB_SQUARE_SIZE; ic++) {
  827. m_ppxlcPredMBY [ic] = (m_ppxlcPredMBY [ic] + m_ppxlcPredMBBackY [ic] + 1) >> 1;
  828. m_ppxliErrorMBY [ic] = m_ppxlcCurrMBY [ic] - m_ppxlcPredMBY [ic];
  829. }
  830. }
  831. Void CVideoObjectEncoder::motionCompInterpAndError_WithShape (
  832. const CMotionVector* pmvForward, const CMotionVector* pmvBackward, 
  833. CoordI x, CoordI y,
  834. CRct *prctMVLimitForward,CRct *prctMVLimitBackward
  835. )
  836. {
  837. motionCompEncY (
  838. m_pvopcRefQ0->pixelsY (), 
  839. m_puciRefQZoom0->pixels (),
  840. m_ppxlcPredMBY, MB_SIZE, pmvForward, x, y,
  841. prctMVLimitForward
  842. );
  843. motionCompEncY (
  844. m_pvopcRefQ1->pixelsY (), 
  845. m_puciRefQZoom1->pixels (),
  846. m_ppxlcPredMBBackY, MB_SIZE, pmvBackward, x, y,
  847. prctMVLimitBackward
  848. );
  849. Int ic;
  850. for (ic = 0; ic < MB_SQUARE_SIZE; ic++) {
  851. if (m_ppxlcCurrMBBY [ic] == transpValue){
  852. m_ppxlcPredMBY [ic] = (m_ppxlcPredMBY [ic] + m_ppxlcPredMBBackY [ic] + 1) >> 1;
  853. /*m_ppxlcPredMBY [ic] = */m_ppxliErrorMBY [ic] = 0;
  854. }
  855. else {
  856. m_ppxlcPredMBY [ic] = (m_ppxlcPredMBY [ic] + m_ppxlcPredMBBackY [ic] + 1) >> 1;
  857. m_ppxliErrorMBY [ic] = m_ppxlcCurrMBY [ic] - m_ppxlcPredMBY [ic];
  858. }
  859. }
  860. }