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

流媒体/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. mc.cpp
  25. Abstract:
  26. Motion compensation routines (common for encoder and decoder).
  27. Revision History:
  28.     December 20, 1997   Interlaced tools added by NextLevel Systems (GI)
  29.                         X. Chen (xchen@nlvl.com) B. Eifrig (beifrig@nlvl.com)
  30. `
  31. *************************************************************************/
  32. #include <stdio.h>
  33. #include "typeapi.h"
  34. #include "codehead.h"
  35. #include "mode.hpp"
  36. #include "vopses.hpp"
  37. #include "global.hpp"
  38. #ifdef __MFC_
  39. #ifdef _DEBUG
  40. #undef THIS_FILE
  41. static char BASED_CODE THIS_FILE[] = __FILE__;
  42. #endif
  43. #define new DEBUG_NEW    
  44. #endif // __MFC_
  45. Void CVideoObject::limitMVRangeToExtendedBBFullPel (CoordI &x,CoordI &y,CRct *prct,Int iBlkSize)
  46. {
  47. if(prct==NULL)
  48. return;
  49. if(x < prct->left)
  50. x=prct->left;
  51. else if(x > (prct->right-iBlkSize))
  52. x=(prct->right-iBlkSize);
  53. if(y < prct->top)
  54. y=prct->top;
  55. else if(y > (prct->bottom-iBlkSize))
  56. y=(prct->bottom-iBlkSize);
  57. }
  58. Void CVideoObject::limitMVRangeToExtendedBBHalfPel (CoordI &x,CoordI &y,CRct *prct,Int iBlkSize)
  59. {
  60. if(prct==NULL)
  61. return;
  62. if(x < prct->left*2)
  63. x=prct->left*2;
  64. else if(x > (prct->right-iBlkSize)*2)
  65. x=(prct->right-iBlkSize)*2;
  66. if(y < prct->top*2)
  67. y=prct->top*2;
  68. else if(y > (prct->bottom-iBlkSize)*2)
  69. y=(prct->bottom-iBlkSize)*2;
  70. }
  71. Void CVideoObject::motionCompMB (
  72. PixelC* ppxlcPredMB,
  73. const PixelC* ppxlcRefLeftTop,
  74. const CMotionVector* pmv, const CMBMode* pmbmd, 
  75. Int imbX, Int imbY,
  76. CoordI x, CoordI y,
  77. Bool bSkipNonOBMC,
  78. Bool bAlphaMB,
  79. CRct *prctMVLimit
  80. )
  81. {
  82. if (!bAlphaMB && !m_volmd.bAdvPredDisable && !pmbmd->m_bFieldMV) {
  83. motionCompOverLap (
  84. ppxlcPredMB, ppxlcRefLeftTop,
  85. pmv, pmbmd,
  86. imbX, imbY,
  87. x, y,
  88. prctMVLimit
  89. );
  90. }
  91. else {
  92. if (bSkipNonOBMC)
  93. return;
  94. if (!pmbmd -> m_bhas4MVForward && !pmbmd -> m_bFieldMV)
  95. motionComp (
  96. ppxlcPredMB, ppxlcRefLeftTop,
  97. MB_SIZE, 
  98. x * 2 + pmv->trueMVHalfPel ().x, 
  99. y * 2 + pmv->trueMVHalfPel ().y ,
  100. m_vopmd.iRoundingControl,
  101. prctMVLimit
  102. );
  103. else if (pmbmd -> m_bFieldMV) {
  104. const CMotionVector* pmv16x8 = pmv+5;
  105. if(pmbmd->m_bForwardTop) {
  106. pmv16x8++;
  107. motionCompYField (
  108. ppxlcPredMB,
  109. ppxlcRefLeftTop+m_iFrameWidthY,
  110. x * 2 + pmv16x8->trueMVHalfPel ().x, 
  111. y * 2 + pmv16x8->trueMVHalfPel ().y 
  112. );
  113. pmv16x8++;
  114. }
  115. else {
  116. motionCompYField (
  117. ppxlcPredMB,
  118. ppxlcRefLeftTop,
  119. x * 2 + pmv16x8->trueMVHalfPel ().x, 
  120. y * 2 + pmv16x8->trueMVHalfPel ().y 
  121. );
  122. pmv16x8++;
  123. pmv16x8++;
  124. }
  125. if(pmbmd->m_bForwardBottom) {
  126. pmv16x8++;
  127. motionCompYField (
  128. ppxlcPredMB+MB_SIZE,
  129. ppxlcRefLeftTop+m_iFrameWidthY,
  130. x * 2 + pmv16x8->trueMVHalfPel ().x, 
  131. y * 2 + pmv16x8->trueMVHalfPel ().y 
  132. );
  133. }
  134. else {
  135. motionCompYField (
  136. ppxlcPredMB+MB_SIZE,
  137. ppxlcRefLeftTop,
  138. x * 2 + pmv16x8->trueMVHalfPel ().x, 
  139. y * 2 + pmv16x8->trueMVHalfPel ().y 
  140. );
  141. }
  142. }
  143. else {
  144. const CMotionVector* pmv8 = pmv;
  145. pmv8++;
  146. CoordI blkX = x + BLOCK_SIZE;
  147. CoordI blkY = y + BLOCK_SIZE;
  148. if (pmbmd->m_rgTranspStatus [Y_BLOCK1] != ALL)
  149. motionComp (
  150. ppxlcPredMB, ppxlcRefLeftTop,
  151. BLOCK_SIZE, 
  152. x * 2 + pmv8->trueMVHalfPel ().x, 
  153. y * 2 + pmv8->trueMVHalfPel ().y,
  154. m_vopmd.iRoundingControl,
  155. prctMVLimit
  156. );
  157. pmv8++;
  158. if (pmbmd->m_rgTranspStatus [Y_BLOCK2] != ALL)
  159. motionComp (
  160. ppxlcPredMB + OFFSET_BLK1, ppxlcRefLeftTop,
  161. BLOCK_SIZE, 
  162. blkX * 2 + pmv8->trueMVHalfPel ().x, 
  163. y * 2 + pmv8->trueMVHalfPel ().y,
  164. m_vopmd.iRoundingControl,
  165. prctMVLimit
  166. );
  167. pmv8++;
  168. if (pmbmd->m_rgTranspStatus [Y_BLOCK3] != ALL)
  169. motionComp (
  170. ppxlcPredMB + OFFSET_BLK2, ppxlcRefLeftTop,
  171. BLOCK_SIZE, 
  172. x * 2 + pmv8->trueMVHalfPel ().x, 
  173. blkY * 2 + pmv8->trueMVHalfPel ().y,
  174. m_vopmd.iRoundingControl,
  175. prctMVLimit
  176. );
  177. pmv8++;
  178. if (pmbmd->m_rgTranspStatus [Y_BLOCK4] != ALL)
  179. motionComp (
  180. ppxlcPredMB + OFFSET_BLK3, ppxlcRefLeftTop,
  181. BLOCK_SIZE, 
  182. blkX * 2 + pmv8->trueMVHalfPel ().x, 
  183. blkY * 2 + pmv8->trueMVHalfPel ().y,
  184. m_vopmd.iRoundingControl,
  185. prctMVLimit
  186. );
  187. }
  188. }
  189. }
  190. Void CVideoObject::motionComp (
  191. PixelC* ppxlcPred, // can be either Y or A
  192. const PixelC* ppxlcRefLeftTop, // point to left-top of the frame
  193. Int iSize, // either MB or BLOCK size
  194. CoordI xRef, CoordI yRef, // x + mvX, in half pel unit
  195. Int iRoundingControl,
  196. CRct *prctMVLimit // extended bounding box
  197. )
  198. {
  199. CoordI ix, iy;
  200. limitMVRangeToExtendedBBHalfPel(xRef,yRef,prctMVLimit,iSize);
  201. const PixelC* ppxlcRef = 
  202. ppxlcRefLeftTop + 
  203. ((yRef >> 1) + EXPANDY_REF_FRAME) * m_iFrameWidthY + (xRef >> 1) + EXPANDY_REF_FRAME;
  204. if(iSize==8 || iSize==16)
  205. {
  206. // optimisation
  207. if (!(yRef & 1)) {
  208. if (!(xRef & 1)) {
  209. Int iSz = iSize * sizeof(PixelC);
  210. for(iy = 0; iy < iSize; iy+=8)
  211. {
  212. memcpy (ppxlcPred, ppxlcRef, iSz);
  213. ppxlcRef += m_iFrameWidthY; ppxlcPred += MB_SIZE;
  214. memcpy (ppxlcPred, ppxlcRef, iSz);
  215. ppxlcRef += m_iFrameWidthY; ppxlcPred += MB_SIZE;
  216. memcpy (ppxlcPred, ppxlcRef, iSz);
  217. ppxlcRef += m_iFrameWidthY; ppxlcPred += MB_SIZE;
  218. memcpy (ppxlcPred, ppxlcRef, iSz);
  219. ppxlcRef += m_iFrameWidthY; ppxlcPred += MB_SIZE;
  220. memcpy (ppxlcPred, ppxlcRef, iSz);
  221. ppxlcRef += m_iFrameWidthY; ppxlcPred += MB_SIZE;
  222. memcpy (ppxlcPred, ppxlcRef, iSz);
  223. ppxlcRef += m_iFrameWidthY; ppxlcPred += MB_SIZE;
  224. memcpy (ppxlcPred, ppxlcRef, iSz);
  225. ppxlcRef += m_iFrameWidthY; ppxlcPred += MB_SIZE;
  226. memcpy (ppxlcPred, ppxlcRef, iSz);
  227. ppxlcRef += m_iFrameWidthY; ppxlcPred += MB_SIZE;
  228. }
  229. }
  230. else {
  231. PixelC pxlcT1,pxlcT2, *ppxlcDst;
  232. const PixelC *ppxlcSrc;
  233. Int iRndCtrl = 1 - iRoundingControl;
  234. for (iy = 0; iy < iSize; iy++){
  235. ppxlcDst = ppxlcPred;
  236. ppxlcSrc = ppxlcRef;
  237. for (ix = 0; ix < iSize; ix+=8) {
  238. ppxlcDst [0] = (ppxlcSrc[0] + (pxlcT1=ppxlcSrc[1]) + iRndCtrl) >> 1;
  239. ppxlcDst [1] = (pxlcT1 + (pxlcT2=ppxlcSrc[2]) + iRndCtrl) >> 1;
  240. ppxlcDst [2] = (pxlcT2 + (pxlcT1=ppxlcSrc[3]) + iRndCtrl) >> 1;
  241. ppxlcDst [3] = (pxlcT1 + (pxlcT2=ppxlcSrc[4]) + iRndCtrl) >> 1;
  242. ppxlcDst [4] = (pxlcT2 + (pxlcT1=ppxlcSrc[5]) + iRndCtrl) >> 1;
  243. ppxlcDst [5] = (pxlcT1 + (pxlcT2=ppxlcSrc[6]) + iRndCtrl) >> 1;
  244. ppxlcDst [6] = (pxlcT2 + (pxlcT1=ppxlcSrc[7]) + iRndCtrl) >> 1;
  245. ppxlcDst [7] = (pxlcT1 + ppxlcSrc[8] + iRndCtrl) >> 1;
  246. ppxlcDst += 8;
  247. ppxlcSrc += 8;
  248. }
  249. ppxlcRef += m_iFrameWidthY;
  250. ppxlcPred += MB_SIZE;
  251. }
  252. }
  253. }
  254. else {
  255. if (!(xRef & 1)) {
  256. Int iRndCtrl = 1 - iRoundingControl;
  257. const PixelC *ppxlcSrc, *ppxlcSrc2;
  258. PixelC *ppxlcDst;
  259. for (iy = 0; iy < iSize; iy++) {
  260. ppxlcDst = ppxlcPred;
  261. ppxlcSrc = ppxlcRef;
  262. ppxlcSrc2 = ppxlcRef + m_iFrameWidthY;
  263. for (ix = 0; ix < iSize; ix+=8) {
  264. ppxlcDst [0] = (ppxlcSrc [0] + ppxlcSrc2 [0] + iRndCtrl) >> 1;
  265. ppxlcDst [1] = (ppxlcSrc [1] + ppxlcSrc2 [1] + iRndCtrl) >> 1;
  266. ppxlcDst [2] = (ppxlcSrc [2] + ppxlcSrc2 [2] + iRndCtrl) >> 1;
  267. ppxlcDst [3] = (ppxlcSrc [3] + ppxlcSrc2 [3] + iRndCtrl) >> 1;
  268. ppxlcDst [4] = (ppxlcSrc [4] + ppxlcSrc2 [4] + iRndCtrl) >> 1;
  269. ppxlcDst [5] = (ppxlcSrc [5] + ppxlcSrc2 [5] + iRndCtrl) >> 1;
  270. ppxlcDst [6] = (ppxlcSrc [6] + ppxlcSrc2 [6] + iRndCtrl) >> 1;
  271. ppxlcDst [7] = (ppxlcSrc [7] + ppxlcSrc2 [7] + iRndCtrl) >> 1;
  272. ppxlcDst += 8;
  273. ppxlcSrc += 8;
  274. ppxlcSrc2 += 8;
  275. }
  276. ppxlcRef += m_iFrameWidthY;
  277. ppxlcPred += MB_SIZE;
  278. }
  279. }
  280. else {
  281. Int iRndCtrl = 2 - iRoundingControl;
  282. PixelC pxlcT1, pxlcT2, pxlcT3, pxlcT4, *ppxlcDst;
  283. const PixelC *ppxlcSrc, *ppxlcSrc2;
  284. for (iy = 0; iy < iSize; iy++) {
  285. ppxlcDst = ppxlcPred;
  286. ppxlcSrc = ppxlcRef;
  287. ppxlcSrc2 = ppxlcRef + m_iFrameWidthY;
  288. for (ix = 0; ix < iSize; ix+=8) {
  289. ppxlcDst [0] = (ppxlcSrc[0] + (pxlcT1=ppxlcSrc[1]) + ppxlcSrc2[0] + (pxlcT3=ppxlcSrc2[1]) + iRndCtrl) >> 2;
  290. ppxlcDst [1] = (pxlcT1 + (pxlcT2=ppxlcSrc[2]) + pxlcT3 + (pxlcT4=ppxlcSrc2[2]) + iRndCtrl) >> 2;
  291. ppxlcDst [2] = (pxlcT2 + (pxlcT1=ppxlcSrc[3]) + pxlcT4 + (pxlcT3=ppxlcSrc2[3]) + iRndCtrl) >> 2;
  292. ppxlcDst [3] = (pxlcT1 + (pxlcT2=ppxlcSrc[4]) + pxlcT3 + (pxlcT4=ppxlcSrc2[4]) + iRndCtrl) >> 2;
  293. ppxlcDst [4] = (pxlcT2 + (pxlcT1=ppxlcSrc[5]) + pxlcT4 + (pxlcT3=ppxlcSrc2[5]) + iRndCtrl) >> 2;
  294. ppxlcDst [5] = (pxlcT1 + (pxlcT2=ppxlcSrc[6]) + pxlcT3 + (pxlcT4=ppxlcSrc2[6]) + iRndCtrl) >> 2;
  295. ppxlcDst [6] = (pxlcT2 + (pxlcT1=ppxlcSrc[7]) + pxlcT4 + (pxlcT3=ppxlcSrc2[7]) + iRndCtrl) >> 2;
  296. ppxlcDst [7] = (pxlcT1 + ppxlcSrc[8] + pxlcT3 + ppxlcSrc2[8] + iRndCtrl) >> 2;
  297. ppxlcDst += 8;
  298. ppxlcSrc += 8;
  299. ppxlcSrc2 += 8;
  300. }
  301. ppxlcRef += m_iFrameWidthY;
  302. ppxlcPred += MB_SIZE;
  303. }
  304. }
  305. }
  306. }
  307. else {
  308. if (!(yRef & 1)) {
  309. if (!(xRef & 1)) {  //!bXSubPxl && !bYSubPxl
  310. for (iy = 0; iy < iSize; iy++) {
  311. memcpy (ppxlcPred, ppxlcRef, iSize*sizeof(PixelC));
  312. ppxlcRef += m_iFrameWidthY;
  313. ppxlcPred += MB_SIZE;
  314. }
  315. }
  316. else {  //bXSubPxl && !bYSubPxl
  317. for (iy = 0; iy < iSize; iy++){
  318. for (ix = 0; ix < iSize; ix++)
  319. ppxlcPred [ix] = (ppxlcRef [ix] + ppxlcRef [ix + 1] + 1 - iRoundingControl) >> 1;
  320. ppxlcRef += m_iFrameWidthY;
  321. ppxlcPred += MB_SIZE;
  322. }
  323. }
  324. }
  325. else {
  326. const PixelC* ppxlcRefBot;
  327. if (!(xRef & 1)) {  //!bXSubPxl&& bYSubPxl
  328. for (iy = 0; iy < iSize; iy++) {
  329. ppxlcRefBot = ppxlcRef + m_iFrameWidthY; //UPln -> pixels (xInt,yInt+1);
  330. for (ix = 0; ix < iSize; ix++) 
  331. ppxlcPred [ix] = (ppxlcRef [ix] + ppxlcRefBot [ix] + 1 - iRoundingControl) >> 1;
  332. ppxlcRef = ppxlcRefBot;
  333. ppxlcPred += MB_SIZE;
  334. }
  335. }
  336. else { // bXSubPxl && bYSubPxl
  337. for (iy = 0; iy < iSize; iy++) {
  338. ppxlcRefBot = ppxlcRef + m_iFrameWidthY; //UPln -> pixels (xInt,yInt+1);
  339. for (ix = 0; ix < iSize; ix++){
  340. ppxlcPred [ix] = (
  341. ppxlcRef [ix + 1] + ppxlcRef [ix] +
  342. ppxlcRefBot [ix + 1] + ppxlcRefBot [ix] + 2 - iRoundingControl
  343. ) >> 2;
  344. }
  345. ppxlcRef = ppxlcRefBot;
  346. ppxlcPred += MB_SIZE;
  347. }
  348. }
  349. }
  350. }
  351. }
  352. Void CVideoObject::motionCompDirectMode(                // Interlaced direct mode
  353. CoordI x, CoordI y,
  354.  CMBMode *pmbmd,   
  355. const CMotionVector *pmvRef,
  356.     CRct *prctMVLimitFwd, CRct *prctMVLimitBak,
  357. Int plane // plane=1 for grey scale, plane=0 for texture, 02-17-99
  358. )
  359. {
  360. Int* rgiMvRound = NULL;
  361. UInt uiDivisor = 0;
  362. Int xRefUVF,yRefUVF,xRefUVB,yRefUVB;
  363. // begin of new changes 10/21/98
  364. Int iMBX,iMBY;
  365. const CMBMode *pmbmdRef; 
  366. if(m_volmd.fAUsage != RECTANGLE)
  367. {
  368. iMBX=(x-m_rctCurrVOPY.left)/MB_SIZE;
  369. iMBY=(y-m_rctCurrVOPY.top)/MB_SIZE;
  370. pmbmdRef= m_rgmbmdRef +
  371. (iMBX+iMBY*m_iNumMBXRef);
  372. }
  373. else
  374. {
  375. iMBX=x/MB_SIZE;
  376. iMBY=y/MB_SIZE;
  377. pmbmdRef= m_rgmbmdRef +
  378. iMBX+iMBY*m_iNumMBXRef;
  379. }
  380. // end of new changes 10/21/98
  381. if (pmbmdRef->m_rgTranspStatus[0]==ALL) {
  382. static CMotionVector mvZero[5];
  383. pmvRef = mvZero;
  384. }
  385. if ((iMBX<m_iNumMBXRef && iMBX>=0 && iMBY<m_iNumMBYRef && iMBY>=0)&& // new change 10/21/98
  386. (pmbmdRef->m_bFieldMV&&pmbmdRef->m_rgTranspStatus[0]!=ALL)) {
  387. static I8 iTROffsetTop[] = {  0, 0,  1, 1, 0, 0, -1, -1 };
  388. static I8 iTROffsetBot[] = { -1, 0, -1, 0, 1, 0,  1,  0 };
  389. CoordI iXFwdTop, iXFwdBot, iXBakTop, iXBakBot;
  390. CoordI iYFwdTop, iYFwdBot, iYBakTop, iYBakBot;
  391. const CMotionVector *pmvRefTop, *pmvRefBot;
  392. Int iTopRefFldOffset = 0, iBotRefFldOffset = 0;
  393. Int iCode = (Int)(vopmd().bTopFieldFirst) << 2;
  394. pmbmd->m_bFieldMV = 1;  // set field direct mode for grey scale // new change 02-19-99
  395. assert((pmbmdRef->m_dctMd != INTRA) && (pmbmdRef->m_dctMd != INTRAQ));
  396. if (pmbmdRef->m_bForwardTop) {
  397. iCode |= 2;
  398. iTopRefFldOffset = 1;
  399. pmvRefTop = pmvRef + 6;
  400. } else
  401. pmvRefTop = pmvRef + 5;
  402. if (pmbmdRef->m_bForwardBottom) {
  403. iCode |= 1;
  404. iBotRefFldOffset = 1;
  405. pmvRefBot = pmvRef + 8;
  406. } else
  407. pmvRefBot = pmvRef + 7;
  408. Int iTempRefDTop = 2*(m_tFutureRef - m_tPastRef) + iTROffsetTop[iCode];
  409. Int iTempRefDBot = 2*(m_tFutureRef - m_tPastRef) + iTROffsetBot[iCode];
  410. Int iTempRefBTop = 2*(m_t          - m_tPastRef) + iTROffsetTop[iCode];
  411. Int iTempRefBBot = 2*(m_t          - m_tPastRef) + iTROffsetBot[iCode];
  412. assert(iTempRefDTop > 0); assert(iTempRefDBot > 0); assert(iTempRefBTop > 0); assert(iTempRefBBot > 0);
  413. // Find MVs for the top field
  414. iXFwdTop = (pmvRefTop->m_vctTrueHalfPel.x * iTempRefBTop) / iTempRefDTop + pmbmd->m_vctDirectDeltaMV.x;
  415. iYFwdTop = (pmvRefTop->m_vctTrueHalfPel.y * iTempRefBTop) / iTempRefDTop + pmbmd->m_vctDirectDeltaMV.y;
  416.         iXBakTop = pmbmd->m_vctDirectDeltaMV.x ? (iXFwdTop - pmvRefTop->m_vctTrueHalfPel.x) :
  417.             ((pmvRefTop->m_vctTrueHalfPel.x * (iTempRefBTop - iTempRefDTop)) / iTempRefDTop);
  418.         iYBakTop = pmbmd->m_vctDirectDeltaMV.y ? (iYFwdTop - pmvRefTop->m_vctTrueHalfPel.y) :
  419.             ((pmvRefTop->m_vctTrueHalfPel.y * (iTempRefBTop - iTempRefDTop)) / iTempRefDTop);
  420. // Find MVs for the bottom field
  421. iXFwdBot = (pmvRefBot->m_vctTrueHalfPel.x * iTempRefBBot) / iTempRefDBot + pmbmd->m_vctDirectDeltaMV.x;
  422. iYFwdBot = (pmvRefBot->m_vctTrueHalfPel.y * iTempRefBBot) / iTempRefDBot + pmbmd->m_vctDirectDeltaMV.y;
  423.         iXBakBot = pmbmd->m_vctDirectDeltaMV.x ? (iXFwdBot - pmvRefBot->m_vctTrueHalfPel.x) :
  424.             ((pmvRefBot->m_vctTrueHalfPel.x * (iTempRefBBot - iTempRefDBot)) / iTempRefDBot);
  425.         iYBakBot = pmbmd->m_vctDirectDeltaMV.y ? (iYFwdBot - pmvRefBot->m_vctTrueHalfPel.y) :
  426.             ((pmvRefBot->m_vctTrueHalfPel.y * (iTempRefBBot - iTempRefDBot)) / iTempRefDBot);
  427. // Motion compensate the top field forward
  428.         iXFwdTop += 2*x; iYFwdTop += 2*y;
  429.         limitMVRangeToExtendedBBHalfPel(iXFwdTop, iYFwdTop, prctMVLimitFwd, MB_SIZE);
  430. if (plane==0) {  // texture MC // new change 02-19-99
  431. motionCompYField(m_ppxlcPredMBY,
  432. m_pvopcRefQ0->pixelsY() + iTopRefFldOffset * m_iFrameWidthY, iXFwdTop, iYFwdTop);
  433. iXFwdTop -= 2*x; iYFwdTop -= 2*y;
  434. motionCompFieldUV(m_ppxlcPredMBU, m_ppxlcPredMBV, m_pvopcRefQ0, x, y,
  435. (iXFwdTop & 3) ? ((iXFwdTop >> 1) | 1) : (iXFwdTop >> 1),
  436. (iYFwdTop & 6) ? ((iYFwdTop >> 1) | 2) : (iYFwdTop >> 1), iTopRefFldOffset);
  437. }
  438. else {  // plane=1, grey scale MC // begin of new change 02-19-99
  439. motionCompYField(m_ppxlcPredMBA,
  440. m_pvopcRefQ0->pixelsA() + iTopRefFldOffset * m_iFrameWidthY, iXFwdTop, iYFwdTop);
  441. iXFwdTop -= 2*x; iYFwdTop -= 2*y;
  442. } // end of new change 02-19-99
  443. // Motion compensate the top field backward
  444.         iXBakTop += 2*x; iYBakTop += 2*y;
  445.         limitMVRangeToExtendedBBHalfPel(iXBakTop, iYBakTop, prctMVLimitBak, MB_SIZE);
  446. if (plane==0) {  // texture MC // new change 02-19-99
  447. motionCompYField(m_ppxlcPredMBBackY, m_pvopcRefQ1->pixelsY(), iXBakTop,  iYBakTop);
  448. iXBakTop -= 2*x; iYBakTop -= 2*y;
  449. motionCompFieldUV(m_ppxlcPredMBBackU, m_ppxlcPredMBBackV, m_pvopcRefQ1, x, y,
  450. (iXBakTop & 3) ? ((iXBakTop >> 1) | 1) : (iXBakTop >> 1),
  451. (iYBakTop & 6) ? ((iYBakTop >> 1) | 2) : (iYBakTop >> 1), 0);
  452. }
  453. else {  // plane=1, grey scale MC // begin of new change 02-19-99
  454. motionCompYField(m_ppxlcPredMBBackA, m_pvopcRefQ1->pixelsA(), iXBakTop,  iYBakTop);
  455. iXBakTop -= 2*x; iYBakTop -= 2*y;
  456. } // end of new change 02-19-99
  457. // Motion compensate the bottom field forward
  458.         iXFwdBot += 2*x; iYFwdBot += 2*y;
  459.         limitMVRangeToExtendedBBHalfPel(iXFwdBot, iYFwdBot, prctMVLimitFwd, MB_SIZE);
  460. if (plane==0) {  // texture MC // new change 02-19-99
  461. motionCompYField(m_ppxlcPredMBY + MB_SIZE,
  462. m_pvopcRefQ0->pixelsY() + iBotRefFldOffset * m_iFrameWidthY, iXFwdBot, iYFwdBot);
  463. iXFwdBot -= 2*x; iYFwdBot -= 2*y;
  464. motionCompFieldUV(m_ppxlcPredMBU + BLOCK_SIZE, m_ppxlcPredMBV + BLOCK_SIZE, m_pvopcRefQ0, x, y,
  465. (iXFwdBot & 3) ? ((iXFwdBot >> 1) | 1) : (iXFwdBot >> 1),
  466. (iYFwdBot & 6) ? ((iYFwdBot >> 1) | 2) : (iYFwdBot >> 1), iBotRefFldOffset);
  467. }
  468. else {  // plane=1, grey scale MC // begin of new change 02-19-99
  469. motionCompYField(m_ppxlcPredMBA + MB_SIZE,
  470. m_pvopcRefQ0->pixelsA() + iBotRefFldOffset * m_iFrameWidthY, iXFwdBot, iYFwdBot);
  471. iXFwdBot -= 2*x; iYFwdBot -= 2*y;
  472. } // end of new change 02-19-99
  473. // Motion compensate the bottom field backward
  474.         iXBakBot += 2*x; iYBakBot += 2*y;
  475.         limitMVRangeToExtendedBBHalfPel(iXBakBot, iYBakBot, prctMVLimitBak, MB_SIZE);
  476. if (plane==0) {  // texture MC // new change 02-19-99
  477. motionCompYField(m_ppxlcPredMBBackY + MB_SIZE, m_pvopcRefQ1->pixelsY() + m_iFrameWidthY,
  478. iXBakBot, iYBakBot);
  479.     iXBakBot -= 2*x; iYBakBot -= 2*y;
  480. motionCompFieldUV(m_ppxlcPredMBBackU + BLOCK_SIZE, m_ppxlcPredMBBackV + BLOCK_SIZE, m_pvopcRefQ1, x, y,
  481. (iXBakBot & 3) ? ((iXBakBot >> 1) | 1) : (iXBakBot >> 1),
  482. (iYBakBot & 6) ? ((iYBakBot >> 1) | 2) : (iYBakBot >> 1), 1);
  483. }
  484. else {  // plane=1, grey scale MC // begin of new change 02-19-99
  485. motionCompYField(m_ppxlcPredMBBackA + MB_SIZE, m_pvopcRefQ1->pixelsA() + m_iFrameWidthY,
  486. iXBakBot, iYBakBot);
  487.     iXBakBot -= 2*x; iYBakBot -= 2*y;
  488. } // end of new change 02-19-99
  489. } else {
  490. Int iTempRefD = m_tFutureRef - m_tPastRef;
  491. Int iTempRefB = m_t          - m_tPastRef;
  492. assert(iTempRefD > 0); assert(iTempRefB > 0);
  493. Int iChromaFwdX = 0, iChromaFwdY = 0, iChromaBakX = 0, iChromaBakY = 0;
  494. CVector vctFwd, vctBak;
  495. static I8 iBlkXOffset[] = { 0, 2*BLOCK_SIZE, 0, 2*BLOCK_SIZE };
  496. static I8 iBlkYOffset[] = { 0, 0, 2*BLOCK_SIZE, 2*BLOCK_SIZE };
  497. static Int iMBOffset[] = { 0, BLOCK_SIZE, MB_SIZE*BLOCK_SIZE, MB_SIZE*BLOCK_SIZE + BLOCK_SIZE };
  498. if ((pmbmdRef->m_dctMd == INTRA) || (pmbmdRef->m_dctMd == INTRAQ)) {
  499. static CMotionVector mvZero[5];
  500. pmvRef = mvZero;
  501. }
  502. if(iMBX<m_iNumMBXRef && iMBX>=0 && iMBY<m_iNumMBYRef && iMBY>=0) // new changes 10/21/98
  503. {
  504.    if (pmbmdRef -> m_bhas4MVForward) {
  505. for (Int iBlk = 0; iBlk < 4; iBlk++) {
  506. if(pmbmd->m_rgTranspStatus[iBlk+1]!=ALL) {
  507. vctFwd = (pmvRef[iBlk + 1].m_vctTrueHalfPel * iTempRefB) / iTempRefD + pmbmd->m_vctDirectDeltaMV;
  508. vctBak.x = pmbmd->m_vctDirectDeltaMV.x ? (vctFwd.x - pmvRef[iBlk + 1].m_vctTrueHalfPel.x) :
  509. ((pmvRef[iBlk + 1].m_vctTrueHalfPel.x * (iTempRefB - iTempRefD)) / iTempRefD);
  510. vctBak.y = pmbmd->m_vctDirectDeltaMV.y ? (vctFwd.y - pmvRef[iBlk + 1].m_vctTrueHalfPel.y) :
  511. ((pmvRef[iBlk + 1].m_vctTrueHalfPel.y * (iTempRefB - iTempRefD)) / iTempRefD);
  512. // rounding control is messed up here
  513. motionComp(m_ppxlcPredMBY + iMBOffset[iBlk], m_pvopcRefQ0->pixelsY(), BLOCK_SIZE,
  514. x * 2 + iBlkXOffset[iBlk] + vctFwd.x, y * 2 + iBlkYOffset[iBlk] + vctFwd.y, 0, prctMVLimitFwd);
  515. motionComp(m_ppxlcPredMBBackY + iMBOffset[iBlk], m_pvopcRefQ1->pixelsY(), BLOCK_SIZE,
  516. x * 2 + iBlkXOffset[iBlk] + vctBak.x, y * 2 + iBlkYOffset[iBlk] + vctBak.y, 0, prctMVLimitBak);
  517. iChromaFwdX += vctFwd.x;
  518. iChromaFwdY += vctFwd.y;
  519. iChromaBakX += vctBak.x;
  520. iChromaBakY += vctBak.y;
  521. uiDivisor += 4;
  522. }
  523. }
  524. switch (uiDivisor) {
  525. case 4:
  526. rgiMvRound = grgiMvRound4;
  527. break;
  528. case 8:
  529. rgiMvRound = grgiMvRound8;
  530. break;
  531. case 12:
  532. rgiMvRound = grgiMvRound12;
  533. break;
  534. case 16:
  535. rgiMvRound = grgiMvRound16;
  536. break;
  537. }
  538. xRefUVF = sign (iChromaFwdX) * (rgiMvRound [abs (iChromaFwdX) % uiDivisor] + (abs (iChromaFwdX) / uiDivisor) * 2);
  539. yRefUVF = sign (iChromaFwdY) * (rgiMvRound [abs (iChromaFwdY) % uiDivisor] + (abs (iChromaFwdY) / uiDivisor) * 2);
  540. xRefUVB = sign (iChromaBakX) * (rgiMvRound [abs (iChromaBakX) % uiDivisor] + (abs (iChromaBakX) / uiDivisor) * 2);
  541. yRefUVB = sign (iChromaBakY) * (rgiMvRound [abs (iChromaBakY) % uiDivisor] + (abs (iChromaBakY) / uiDivisor) * 2);
  542. }
  543. else // 16x16
  544. {
  545. vctFwd = (pmvRef[0].m_vctTrueHalfPel * iTempRefB) / iTempRefD + pmbmd->m_vctDirectDeltaMV;
  546. vctBak.x = pmbmd->m_vctDirectDeltaMV.x ? (vctFwd.x - pmvRef[0].m_vctTrueHalfPel.x) :
  547. ((pmvRef[0].m_vctTrueHalfPel.x * (iTempRefB - iTempRefD)) / iTempRefD);
  548. vctBak.y = pmbmd->m_vctDirectDeltaMV.y ? (vctFwd.y - pmvRef[0].m_vctTrueHalfPel.y) :
  549. ((pmvRef[0].m_vctTrueHalfPel.y * (iTempRefB - iTempRefD)) / iTempRefD);
  550. // rounding control is messed up here
  551. motionComp(m_ppxlcPredMBY, m_pvopcRefQ0->pixelsY(), MB_SIZE,
  552. x * 2 +  vctFwd.x, y * 2 +  vctFwd.y, 0, prctMVLimitFwd);
  553. motionComp(m_ppxlcPredMBBackY , m_pvopcRefQ1->pixelsY(), MB_SIZE,
  554. x * 2 +  vctBak.x, y * 2 +  vctBak.y, 0, prctMVLimitBak);
  555. xRefUVF = sign (vctFwd.x) * (grgiMvRound4  [abs (vctFwd.x) % 4] + (abs (vctFwd.x) / 4) * 2);
  556. yRefUVF = sign (vctFwd.y) * (grgiMvRound4  [abs (vctFwd.y) % 4] + (abs (vctFwd.y) / 4) * 2);
  557. xRefUVB = sign (vctBak.x) * (grgiMvRound4  [abs (vctBak.x) % 4] + (abs (vctBak.x) / 4) * 2);
  558. yRefUVB = sign (vctBak.y) * (grgiMvRound4  [abs (vctBak.y) % 4] + (abs (vctBak.y) / 4) * 2);
  559. }
  560. }
  561. // begin of new changes 10/21/98
  562. else
  563. {
  564. vctFwd = pmbmd->m_vctDirectDeltaMV;
  565. vctBak.x = pmbmd->m_vctDirectDeltaMV.x ? vctFwd.x :0;
  566. vctBak.y = pmbmd->m_vctDirectDeltaMV.y ? vctFwd.y :0;
  567. // rounding control is messed up here
  568. motionComp(m_ppxlcPredMBY, m_pvopcRefQ0->pixelsY(), MB_SIZE,
  569. x * 2 +  vctFwd.x, y * 2 +  vctFwd.y, 0, prctMVLimitFwd);
  570. motionComp(m_ppxlcPredMBBackY , m_pvopcRefQ1->pixelsY(), MB_SIZE,
  571. x * 2 +  vctBak.x, y * 2 +  vctBak.y, 0, prctMVLimitBak);
  572. xRefUVF = sign (vctFwd.x) * (grgiMvRound4  [abs (vctFwd.x) % 4] + (abs (vctFwd.x) / 4) * 2);
  573. yRefUVF = sign (vctFwd.y) * (grgiMvRound4  [abs (vctFwd.y) % 4] + (abs (vctFwd.y) / 4) * 2);
  574. xRefUVB = sign (vctBak.x) * (grgiMvRound4  [abs (vctBak.x) % 4] + (abs (vctBak.x) / 4) * 2);
  575. yRefUVB = sign (vctBak.y) * (grgiMvRound4  [abs (vctBak.y) % 4] + (abs (vctBak.y) / 4) * 2);
  576. }
  577. // end of new changes 10/21/98
  578. motionCompUV(m_ppxlcPredMBU, m_ppxlcPredMBV, m_pvopcRefQ0, x, y,
  579. xRefUVF,
  580. yRefUVF,0, prctMVLimitFwd);
  581. motionCompUV(m_ppxlcPredMBBackU, m_ppxlcPredMBBackV, m_pvopcRefQ1, x, y,
  582. xRefUVB,
  583. yRefUVB,0, prctMVLimitBak);
  584. }
  585. }
  586. Void CVideoObject::motionCompOneBVOPReference(
  587. CVOPU8YUVBA *pvopcPred,
  588. MBType type,
  589. CoordI x, CoordI y,
  590. const CMBMode *pmbmd,
  591. const CMotionVector *pmv,
  592. CRct *prctMVLimit
  593. )
  594. CVOPU8YUVBA *pvopcRef;
  595. Int topRef, botRef;
  596. if (type == BACKWARD) {
  597. pvopcRef = m_pvopcRefQ1;
  598. topRef = (Int)pmbmd->m_bBackwardTop;
  599. botRef = (Int)pmbmd->m_bBackwardBottom;
  600. } else {
  601. pvopcRef = m_pvopcRefQ0;
  602. topRef = (Int)pmbmd->m_bForwardTop;
  603. botRef = (Int)pmbmd->m_bForwardBottom;
  604. }
  605. if (pmbmd->m_bFieldMV) {
  606. const CMotionVector *pmvTop = pmv + 1 + topRef;
  607. const CMotionVector *pmvBot = pmv + 3 + botRef;
  608. assert((topRef & ~1) == 0); assert((botRef & ~1) == 0);
  609.         CoordI iMVX, iMVY;
  610.         iMVX = 2*x + pmvTop->m_vctTrueHalfPel.x;
  611.         iMVY = 2*y + pmvTop->m_vctTrueHalfPel.y;
  612.         limitMVRangeToExtendedBBHalfPel(iMVX, iMVY, prctMVLimit, MB_SIZE);
  613. motionCompYField((PixelC *)pvopcPred->pixelsY(), // Luma top field
  614. pvopcRef->pixelsY() + topRef * m_iFrameWidthY, iMVX, iMVY);
  615.  
  616.         iMVX -= 2*x; iMVY -= 2*y;
  617. motionCompFieldUV((PixelC *)pvopcPred->pixelsU(), // Chroma top field
  618. (PixelC *)pvopcPred->pixelsV(), pvopcRef, x, y,
  619. (iMVX & 3) ? ((iMVX >> 1) | 1) : (iMVX >> 1),
  620. (iMVY & 6) ? ((iMVY >> 1) | 2) : (iMVY >> 1), topRef);
  621.         iMVX = 2*x + pmvBot->m_vctTrueHalfPel.x;
  622.         iMVY = 2*y + pmvBot->m_vctTrueHalfPel.y;
  623.         limitMVRangeToExtendedBBHalfPel(iMVX, iMVY, prctMVLimit, MB_SIZE);
  624. motionCompYField((PixelC *)(pvopcPred->pixelsY()) + MB_SIZE, // Luma bottom field
  625. pvopcRef->pixelsY() + botRef * m_iFrameWidthY, iMVX, iMVY);
  626.         iMVX -= 2*x; iMVY -= 2*y;
  627. motionCompFieldUV((PixelC *)(pvopcPred->pixelsU()) + BLOCK_SIZE, // Chroma bottom field
  628. (PixelC *)(pvopcPred->pixelsV()) + BLOCK_SIZE, pvopcRef, x, y,
  629. (iMVX & 3) ? ((iMVX >> 1) | 1) : (iMVX >> 1),
  630. (iMVY & 6) ? ((iMVY >> 1) | 2) : (iMVY >> 1), botRef);
  631. } else { // rounding control is messed up here
  632. motionComp((PixelC *)pvopcPred->pixelsY(), pvopcRef->pixelsY(), MB_SIZE,
  633. x * 2 + pmv->trueMVHalfPel().x, y * 2 + pmv->trueMVHalfPel().y, 0, prctMVLimit);
  634. motionCompUV((PixelC *)pvopcPred->pixelsU(), (PixelC *)pvopcPred->pixelsV(), pvopcRef, x, y,
  635. (pmv->m_vctTrueHalfPel.x & 3) ? ((pmv->m_vctTrueHalfPel.x >> 1) | 1) :
  636. (pmv->m_vctTrueHalfPel.x >> 1),
  637. (pmv->m_vctTrueHalfPel.y & 3) ? ((pmv->m_vctTrueHalfPel.y >> 1) | 1) :
  638. (pmv->m_vctTrueHalfPel.y >> 1), 0, prctMVLimit);
  639. }
  640. }
  641. Void CVideoObject::motionCompYField (
  642. PixelC* ppxlcPred, // can be either Y or A
  643. const PixelC* ppxlcRefLeftTop, // point to left-top of the frame
  644. CoordI xRef, CoordI yRef // current coordinate system
  645. )
  646. {
  647. CoordI ix, iy;
  648. const PixelC* ppxlcRef = ppxlcRefLeftTop + 
  649. (((yRef >> 1) & ~1) + EXPANDY_REF_FRAME) * m_iFrameWidthY + (xRef >> 1) + EXPANDY_REF_FRAME;
  650. Int iRound = 1 - m_vopmd.iRoundingControl;
  651. Int iFieldStep = 2 * m_iFrameWidthY;
  652. if (!(yRef & 2)) {
  653. if (!(xRef & 1)) {  //!bXSubPxl && !bYSubPxl
  654. for (iy = 0; iy < MB_SIZE; iy+=2) {
  655. memcpy (ppxlcPred, ppxlcRef, MB_SIZE*sizeof(PixelC));
  656. ppxlcRef += iFieldStep;
  657. ppxlcPred += MB_SIZE*2;
  658. }
  659. }
  660. else {  //bXSubPxl && !bYSubPxl
  661. for (iy = 0; iy < MB_SIZE; iy+=2){
  662. for (ix = 0; ix < MB_SIZE; ix++)
  663. ppxlcPred [ix] = (ppxlcRef [ix] + ppxlcRef [ix + 1] + iRound) >> 1;
  664. ppxlcRef += iFieldStep;
  665. ppxlcPred += MB_SIZE*2;
  666. }
  667. }
  668. }
  669. else {
  670. const PixelC* ppxlcRefBot;
  671. if (!(xRef & 1)) {  //!bXSubPxl&& bYSubPxl
  672. for (iy = 0; iy < MB_SIZE; iy+=2) {
  673. ppxlcRefBot = ppxlcRef + iFieldStep; //UPln -> pixels (xInt,yInt+1);
  674. for (ix = 0; ix < MB_SIZE; ix++) 
  675. ppxlcPred [ix] = (ppxlcRef [ix] + ppxlcRefBot [ix] + iRound) >> 1;
  676. ppxlcRef = ppxlcRefBot;
  677. ppxlcPred += MB_SIZE*2;
  678. }
  679. }
  680. else { // bXSubPxl && bYSubPxl
  681. iRound++;
  682. for (iy = 0; iy < MB_SIZE; iy+=2) {
  683. ppxlcRefBot = ppxlcRef + iFieldStep; //UPln -> pixels (xInt,yInt+1);
  684. for (ix = 0; ix < MB_SIZE; ix++){
  685. ppxlcPred [ix] = (ppxlcRef [ix + 1] + ppxlcRef [ix] +
  686. ppxlcRefBot [ix + 1] + ppxlcRefBot [ix] + iRound) >> 2;
  687. }
  688. ppxlcRef = ppxlcRefBot;
  689. ppxlcPred += MB_SIZE*2;
  690. }
  691. }
  692. }
  693. }
  694. Void CVideoObject::motionCompFieldUV ( PixelC* ppxlcPredMBU, PixelC* ppxlcPredMBV,
  695.  const CVOPU8YUVBA* pvopcRef,
  696.  CoordI x, CoordI y, 
  697.  CoordI xRefUV, CoordI yRefUV,Int iRefFieldSelect
  698.  )
  699. {
  700. UInt ix, iy;
  701. // delete by Hyundai for Microsoft and MoMusys alignment
  702. //Int iPxLoc = ((((y + yRefUV) >> 1) & ~1) + EXPANDUV_REF_FRAME) * m_iFrameWidthUV + ((x + xRefUV) >> 1) + EXPANDUV_REF_FRAME;
  703. // insert by Hyundai for Microsoft and MoMusys alignment
  704. Int iPxLoc = (y/2 + ((yRefUV >> 1) & ~1) + EXPANDUV_REF_FRAME) * m_iFrameWidthUV + ((x + xRefUV) >> 1) + EXPANDUV_REF_FRAME;
  705. const PixelC* ppxlcPrevU = pvopcRef->pixelsU () + iPxLoc + iRefFieldSelect*m_iFrameWidthUV;
  706. const PixelC* ppxlcPrevV = pvopcRef->pixelsV () + iPxLoc + iRefFieldSelect*m_iFrameWidthUV;
  707. Int iRound = 1 - m_vopmd.iRoundingControl;
  708. Int iFieldStep = 2 * m_iFrameWidthUV;
  709. if (!(yRefUV & 2)) {
  710. if (!(xRefUV & 1)) {  //!bXSubPxl && !bYSubPxl
  711. for (iy = 0; iy < BLOCK_SIZE; iy+=2) {
  712. memcpy (ppxlcPredMBU, ppxlcPrevU, BLOCK_SIZE*sizeof(PixelC));
  713. memcpy (ppxlcPredMBV, ppxlcPrevV, BLOCK_SIZE*sizeof(PixelC));
  714. ppxlcPrevU += iFieldStep;
  715. ppxlcPrevV += iFieldStep;
  716. ppxlcPredMBU += 2*BLOCK_SIZE;
  717. ppxlcPredMBV += 2*BLOCK_SIZE;
  718. }
  719. }
  720. else {  //bXSubPxl && !bYSubPxl
  721. for (iy = 0; iy < BLOCK_SIZE; iy+=2) {
  722. for (ix = 0; ix < BLOCK_SIZE; ix++) {
  723. ppxlcPredMBU [ix] = (ppxlcPrevU [ix + 1] + ppxlcPrevU [ix] + iRound) >> 1;
  724. ppxlcPredMBV [ix] = (ppxlcPrevV [ix + 1] + ppxlcPrevV [ix] + iRound) >> 1;
  725. }
  726. ppxlcPrevU += iFieldStep;
  727. ppxlcPrevV += iFieldStep;
  728. ppxlcPredMBU += 2*BLOCK_SIZE;
  729. ppxlcPredMBV += 2*BLOCK_SIZE;
  730. }
  731. }
  732. }
  733. else {
  734. const PixelC* ppxlcPrevUBot; 
  735. const PixelC* ppxlcPrevVBot; 
  736. if (!(xRefUV & 1)) {  //!bXSubPxl&& bYSubPxl
  737. for (iy = 0; iy < BLOCK_SIZE; iy+=2) {
  738. ppxlcPrevUBot = ppxlcPrevU + iFieldStep;            //UPln -> pixels (xInt,yInt+1);
  739. ppxlcPrevVBot = ppxlcPrevV + iFieldStep;            //VPln -> pixels (xInt,yInt+1);
  740. for (ix = 0; ix < BLOCK_SIZE; ix++) {
  741. ppxlcPredMBU [ix] = (ppxlcPrevU [ix] + ppxlcPrevUBot [ix] + iRound) >> 1;
  742. ppxlcPredMBV [ix] = (ppxlcPrevV [ix] + ppxlcPrevVBot [ix] + iRound) >> 1;
  743. }
  744. ppxlcPredMBU += 2*BLOCK_SIZE;
  745. ppxlcPredMBV += 2*BLOCK_SIZE;
  746. ppxlcPrevU = ppxlcPrevUBot; 
  747. ppxlcPrevV = ppxlcPrevVBot; 
  748. }
  749. }
  750. else { // bXSubPxl && bYSubPxl
  751. iRound++;
  752. for (iy = 0; iy < BLOCK_SIZE; iy+=2){
  753. ppxlcPrevUBot = ppxlcPrevU + iFieldStep; //UPln -> pixels (xInt,yInt+1);
  754. ppxlcPrevVBot = ppxlcPrevV + iFieldStep; //VPln -> pixels (xInt,yInt+1);
  755. for (ix = 0; ix < BLOCK_SIZE; ix++){
  756. ppxlcPredMBU [ix] = (ppxlcPrevU [ix + 1] + ppxlcPrevU [ix] + 
  757. ppxlcPrevUBot [ix + 1] + ppxlcPrevUBot [ix] + iRound) >> 2;
  758. ppxlcPredMBV [ix] = (ppxlcPrevV [ix + 1] + ppxlcPrevV [ix] + 
  759. ppxlcPrevVBot [ix + 1] + ppxlcPrevVBot [ix] + iRound) >> 2;
  760. }
  761. ppxlcPredMBU += 2*BLOCK_SIZE;
  762. ppxlcPredMBV += 2*BLOCK_SIZE;
  763. ppxlcPrevU = ppxlcPrevUBot; 
  764. ppxlcPrevV = ppxlcPrevVBot; 
  765. }
  766. }
  767. }
  768. }
  769. // #endif // INTERLACE
  770. Void CVideoObject::motionCompUV (
  771. PixelC* ppxlcPredMBU, PixelC* ppxlcPredMBV,
  772. const CVOPU8YUVBA* pvopcRef,
  773. CoordI x, CoordI y, 
  774. CoordI xRefUV, CoordI yRefUV,
  775. Int iRoundingControl,
  776. CRct *prctMVLimit
  777. )
  778. {
  779. UInt ix, iy;
  780. CoordI iTmpX = x + xRefUV;
  781. CoordI iTmpY = y + yRefUV;
  782. limitMVRangeToExtendedBBFullPel (iTmpX,iTmpY,prctMVLimit,MB_SIZE);
  783. xRefUV = iTmpX - x;
  784. yRefUV = iTmpY - y;
  785. Int iPxLoc = (((y + yRefUV) >> 1) + EXPANDUV_REF_FRAME) * m_iFrameWidthUV + ((x + xRefUV) >> 1) + EXPANDUV_REF_FRAME;
  786. const PixelC* ppxlcPrevU = pvopcRef->pixelsU () + iPxLoc;
  787. const PixelC* ppxlcPrevV = pvopcRef->pixelsV () + iPxLoc;
  788. if (!(yRefUV & 1)) {
  789. if (!(xRefUV & 1)) {  //!bXSubPxl && !bYSubPxl
  790. for (iy = 0; iy < BLOCK_SIZE; iy++) {
  791. memcpy (ppxlcPredMBU, ppxlcPrevU, BLOCK_SIZE*sizeof(PixelC));
  792. memcpy (ppxlcPredMBV, ppxlcPrevV, BLOCK_SIZE*sizeof(PixelC));
  793. ppxlcPrevU += m_iFrameWidthUV;
  794. ppxlcPrevV += m_iFrameWidthUV;
  795. ppxlcPredMBU += BLOCK_SIZE;
  796. ppxlcPredMBV += BLOCK_SIZE;
  797. }
  798. }
  799. else {  //bXSubPxl && !bYSubPxl
  800. for (iy = 0; iy < BLOCK_SIZE; iy++) {
  801. for (ix = 0; ix < BLOCK_SIZE; ix++) {
  802. ppxlcPredMBU [ix] = (ppxlcPrevU [ix + 1] + ppxlcPrevU [ix] + 1 - iRoundingControl) >> 1;
  803. ppxlcPredMBV [ix] = (ppxlcPrevV [ix + 1] + ppxlcPrevV [ix] + 1 - iRoundingControl) >> 1;
  804. }
  805. ppxlcPrevU += m_iFrameWidthUV;
  806. ppxlcPrevV += m_iFrameWidthUV;
  807. ppxlcPredMBU += BLOCK_SIZE;
  808. ppxlcPredMBV += BLOCK_SIZE;
  809. }
  810. }
  811. }
  812. else {
  813. const PixelC* ppxlcPrevUBot; 
  814. const PixelC* ppxlcPrevVBot; 
  815. if (!(xRefUV & 1)) {  //!bXSubPxl&& bYSubPxl
  816. for (iy = 0; iy < BLOCK_SIZE; iy++) {
  817. ppxlcPrevUBot = ppxlcPrevU + m_iFrameWidthUV;            //UPln -> pixels (xInt,yInt+1);
  818. ppxlcPrevVBot = ppxlcPrevV + m_iFrameWidthUV;            //VPln -> pixels (xInt,yInt+1);
  819. for (ix = 0; ix < BLOCK_SIZE; ix++) {
  820. // ppxlcPredMBU [ix] = (ppxlcPrevU [ix] + ppxlcPrevUBot [ix] + 1) >> 1;
  821. // ppxlcPredMBV [ix] = (ppxlcPrevV [ix] + ppxlcPrevVBot [ix] + 1) >> 1;
  822. ppxlcPredMBU [ix] = (ppxlcPrevU [ix] + ppxlcPrevUBot [ix] + 1 - iRoundingControl) >> 1;
  823. ppxlcPredMBV [ix] = (ppxlcPrevV [ix] + ppxlcPrevVBot [ix] + 1 - iRoundingControl) >> 1;
  824. }
  825. ppxlcPredMBU += BLOCK_SIZE;
  826. ppxlcPredMBV += BLOCK_SIZE;
  827. ppxlcPrevU = ppxlcPrevUBot; 
  828. ppxlcPrevV = ppxlcPrevVBot; 
  829. }
  830. }
  831. else { // bXSubPxl && bYSubPxl
  832. for (iy = 0; iy < BLOCK_SIZE; iy++){
  833. ppxlcPrevUBot = ppxlcPrevU + m_iFrameWidthUV; //UPln -> pixels (xInt,yInt+1);
  834. ppxlcPrevVBot = ppxlcPrevV + m_iFrameWidthUV; //VPln -> pixels (xInt,yInt+1);
  835. for (ix = 0; ix < BLOCK_SIZE; ix++){
  836. /*
  837. ppxlcPredMBU [ix] = (
  838. ppxlcPrevU [ix + 1] + ppxlcPrevU [ix] + 
  839. ppxlcPrevUBot [ix + 1] + ppxlcPrevUBot [ix] + 2
  840. ) >> 2;
  841. ppxlcPredMBV [ix] = (
  842. ppxlcPrevV [ix + 1] + ppxlcPrevV [ix] + 
  843. ppxlcPrevVBot [ix + 1] + ppxlcPrevVBot [ix] + 2
  844. ) >> 2;
  845. */
  846. ppxlcPredMBU [ix] = (
  847. ppxlcPrevU [ix + 1] + ppxlcPrevU [ix] + 
  848. ppxlcPrevUBot [ix + 1] + ppxlcPrevUBot [ix] + 2 - iRoundingControl
  849. ) >> 2;
  850. ppxlcPredMBV [ix] = (
  851. ppxlcPrevV [ix + 1] + ppxlcPrevV [ix] + 
  852. ppxlcPrevVBot [ix + 1] + ppxlcPrevVBot [ix] + 2 - iRoundingControl
  853. ) >> 2;
  854. }
  855. ppxlcPredMBU += BLOCK_SIZE;
  856. ppxlcPredMBV += BLOCK_SIZE;
  857. ppxlcPrevU = ppxlcPrevUBot; 
  858. ppxlcPrevV = ppxlcPrevVBot; 
  859. }
  860. }
  861. }
  862. }
  863. UInt gOvrlpPredY [64];
  864. Void CVideoObject::motionCompOverLap (
  865. PixelC* ppxlcPredMB, 
  866. const PixelC* ppxlcRefLeftTop,
  867. const CMotionVector* pmv, // motion vector
  868. const CMBMode* pmbmd, // macroblk mode
  869. Int imbx, // current macroblk index
  870. Int imby, // current macroblk index
  871. CoordI x, // current coordinate system
  872. CoordI y, // current coordinate system
  873. CRct *prctMVLimit
  874. )
  875. {
  876. // Overlap Motion Comp use motion vector of current blk and motion vectors of neighboring blks.
  877. const CMotionVector *pmvC,*pmvT = NULL,*pmvB = NULL,*pmvR = NULL,*pmvL = NULL; // MVs of Cur, Top, Bot, Right and Left Blocks.
  878. const CMotionVector *pmvCurrMb,*pmvTopMb = NULL;
  879. const CMotionVector *pmvRightMb = NULL,*pmvLeftMb = NULL; // MVs of Cur, Top, Right and Left MacroBlocks.
  880. const CMBMode *pmbmdTopMb = NULL, *pmbmdRightMb = NULL, *pmbmdLeftMb = NULL; 
  881. // MVs of Cur, Top, Right and Left MacroBlocks.
  882. Bool bIntraT = FALSE, bIntraR = FALSE, bIntraL = FALSE; // flags of 4MV for Cur, Top, Right and Left MacroBlocks.
  883. Bool bLeftBndry, bRightBndry, bTopBndry;
  884. bLeftBndry = (imbx == 0);
  885. bRightBndry = (imbx == m_iNumMBX - 1);
  886. bTopBndry = (imby == 0);
  887. pmvCurrMb = pmv;
  888. // assign the neighboring blk's MVs to pmv[TBRLC]
  889. if (!bTopBndry) {
  890. pmbmdTopMb = pmbmd - m_iNumMBX; 
  891. bIntraT = (pmbmdTopMb->m_dctMd == INTRA || pmbmdTopMb->m_dctMd == INTRAQ);
  892. pmvTopMb = pmv - m_iNumOfTotalMVPerRow;
  893. }
  894. if (!bLeftBndry) {
  895. pmbmdLeftMb = pmbmd - 1;
  896. bIntraL = (pmbmdLeftMb->m_dctMd == INTRA || pmbmdLeftMb->m_dctMd == INTRAQ);
  897. pmvLeftMb = pmv - PVOP_MV_PER_REF_PER_MB;
  898. }
  899. if (!bRightBndry) {
  900. pmbmdRightMb = pmbmd + 1;
  901. bIntraR = (pmbmdRightMb->m_dctMd == INTRA || pmbmdRightMb->m_dctMd == INTRAQ);
  902. pmvRightMb = pmv + PVOP_MV_PER_REF_PER_MB;
  903. }
  904. UInt i;
  905. // assign the neighboring blk's MVs to pmv[TBRLC] 
  906. for (i = 1; i < 5; i++) {
  907. if (pmbmd->m_rgTranspStatus [i] == ALL)
  908. continue;
  909. pmvC = pmvCurrMb + i;
  910. switch (i) {
  911. case 1:
  912. if (pmbmd->m_rgTranspStatus [3] == ALL)
  913. pmvB = pmvCurrMb + 1;
  914. else
  915. pmvB = pmvCurrMb + 3;
  916. if (pmbmd->m_rgTranspStatus [2] == ALL)
  917. pmvR = pmvCurrMb + 1; 
  918. else
  919. pmvR = pmvCurrMb + 2; 
  920. if (bTopBndry || bIntraT || pmbmdTopMb->m_rgTranspStatus [3] == ALL)
  921. pmvT = pmvCurrMb + 1;
  922. else
  923. pmvT = pmvTopMb + 3;
  924. if (bLeftBndry || bIntraL || pmbmdLeftMb->m_rgTranspStatus [2] == ALL)
  925. pmvL = pmvCurrMb + 1;
  926. else
  927. pmvL = pmvLeftMb + 2;
  928. break;
  929. case 2:
  930. if (pmbmd->m_rgTranspStatus [4] == ALL)
  931. pmvB = pmvCurrMb + 2;
  932. else
  933. pmvB = pmvCurrMb + 4;
  934. if (pmbmd->m_rgTranspStatus [1] == ALL)
  935. pmvL = pmvCurrMb + 2;
  936. else
  937. pmvL = pmvCurrMb + 1;
  938. if (bTopBndry || bIntraT || pmbmdTopMb->m_rgTranspStatus [4] == ALL)
  939. pmvT = pmvCurrMb + 2;
  940. else
  941. pmvT = pmvTopMb + 4;      
  942. if (bRightBndry || bIntraR || pmbmdRightMb->m_rgTranspStatus [1] == ALL)
  943. pmvR = pmvCurrMb + 2;
  944. else
  945. pmvR = pmvRightMb + 1;
  946. break;
  947. case 3:
  948. if (pmbmd->m_rgTranspStatus [1] == ALL)
  949. pmvT = pmvCurrMb + 3;  
  950. else
  951. pmvT = pmvCurrMb + 1;
  952. pmvB = pmvCurrMb + 3; // use the current mv
  953. if (pmbmd->m_rgTranspStatus [4] == ALL)
  954. pmvR = pmvCurrMb + 3;
  955. else
  956. pmvR = pmvCurrMb + 4;
  957. if (bLeftBndry || bIntraL || pmbmdLeftMb->m_rgTranspStatus [4] == ALL)
  958. pmvL = pmvCurrMb + 3;
  959. else
  960. pmvL = pmvLeftMb + 4;
  961. break;
  962. case 4:
  963. if (pmbmd->m_rgTranspStatus [2] == ALL)
  964. pmvT = pmvCurrMb + 4;    
  965. else
  966. pmvT = pmvCurrMb + 2;
  967. pmvB = pmvCurrMb + 4;
  968. if (pmbmd->m_rgTranspStatus [3] == ALL)
  969. pmvL = pmvCurrMb + 4;  
  970. else
  971. pmvL = pmvCurrMb + 3;
  972. if (bRightBndry || bIntraR || pmbmdRightMb->m_rgTranspStatus [3] == ALL)
  973. pmvR = pmvCurrMb + 4;
  974. else
  975. pmvR = pmvRightMb + 3;
  976. break;
  977. default:
  978. assert (FALSE);
  979. }
  980. // Compute the top left corner's x,y coordinates of current block.
  981. UInt dxc = (((i - 1) & 1) << 3);
  982. UInt dyc = (((i - 1) & 2) << 2);
  983. UInt nxcY = (x + dxc) << 1; 
  984. UInt nycY = (y + dyc) << 1; 
  985. // Compute the corresponding positions on Ref frm, using 5 MVs.
  986. CoordI xRefC = nxcY + pmvC->m_vctTrueHalfPel.x, yRefC = nycY + pmvC->m_vctTrueHalfPel.y;
  987. CoordI xRefT = nxcY + pmvT->m_vctTrueHalfPel.x, yRefT = nycY + pmvT->m_vctTrueHalfPel.y;
  988. CoordI xRefB = nxcY + pmvB->m_vctTrueHalfPel.x, yRefB = nycY + pmvB->m_vctTrueHalfPel.y;
  989. CoordI xRefR = nxcY + pmvR->m_vctTrueHalfPel.x, yRefR = nycY + pmvR->m_vctTrueHalfPel.y;
  990. CoordI xRefL = nxcY + pmvL->m_vctTrueHalfPel.x, yRefL = nycY + pmvL->m_vctTrueHalfPel.y;
  991. // UInt nxcY = x + dxc;
  992. // UInt nycY = y + dyc;
  993. // // Compute the corresponding positions on Ref frm, using 5 MVs.
  994. // CoordI xRefC = ((nxcY + pmvC -> iMVX) << 1) + pmvC -> iHalfX, yRefC = ((nycY + pmvC -> iMVY) << 1) + pmvC -> iHalfY;
  995. // CoordI xRefT = ((nxcY + pmvT -> iMVX) << 1) + pmvT -> iHalfX, yRefT = ((nycY + pmvT -> iMVY) << 1) + pmvT -> iHalfY;
  996. //   CoordI xRefB = ((nxcY + pmvB -> iMVX) << 1) + pmvB -> iHalfX, yRefB = ((nycY + pmvB -> iMVY) << 1) + pmvB -> iHalfY;
  997. // CoordI xRefR = ((nxcY + pmvR -> iMVX) << 1) + pmvR -> iHalfX, yRefR = ((nycY + pmvR -> iMVY) << 1) + pmvR -> iHalfY;
  998. // CoordI xRefL = ((nxcY + pmvL -> iMVX) << 1) + pmvL -> iHalfX, yRefL = ((nycY + pmvL -> iMVY) << 1) + pmvL -> iHalfY;
  999. limitMVRangeToExtendedBBHalfPel (xRefC,yRefC,prctMVLimit,BLOCK_SIZE);
  1000. limitMVRangeToExtendedBBHalfPel (xRefT,yRefT,prctMVLimit,BLOCK_SIZE);
  1001. limitMVRangeToExtendedBBHalfPel (xRefB,yRefB,prctMVLimit,BLOCK_SIZE);
  1002. limitMVRangeToExtendedBBHalfPel (xRefR,yRefR,prctMVLimit,BLOCK_SIZE);
  1003. limitMVRangeToExtendedBBHalfPel (xRefL,yRefL,prctMVLimit,BLOCK_SIZE);
  1004. Bool bXSubPxlC = (xRefC & 1), bYSubPxlC = (yRefC & 1),
  1005.  bXSubPxlT = (xRefT & 1), bYSubPxlT = (yRefT & 1),
  1006.  bXSubPxlB = (xRefB & 1), bYSubPxlB = (yRefB & 1),
  1007.  bXSubPxlR = (xRefR & 1), bYSubPxlR = (yRefR & 1),
  1008.  bXSubPxlL = (xRefL & 1), bYSubPxlL = (yRefL & 1);
  1009. // 5 starting pos. in Zoomed Ref. Frames
  1010. const PixelC* ppxliPrevYC = ppxlcRefLeftTop + ((yRefC >> 1) + EXPANDY_REF_FRAME) * m_iFrameWidthY + (xRefC >> 1) + EXPANDY_REF_FRAME;
  1011. const PixelC* ppxliPrevYT = ppxlcRefLeftTop + ((yRefT >> 1) + EXPANDY_REF_FRAME) * m_iFrameWidthY + (xRefT >> 1) + EXPANDY_REF_FRAME;
  1012. const PixelC* ppxliPrevYB = ppxlcRefLeftTop + ((yRefB >> 1) + EXPANDY_REF_FRAME) * m_iFrameWidthY + (xRefB >> 1) + EXPANDY_REF_FRAME;
  1013. const PixelC* ppxliPrevYR = ppxlcRefLeftTop + ((yRefR >> 1) + EXPANDY_REF_FRAME) * m_iFrameWidthY + (xRefR >> 1) + EXPANDY_REF_FRAME;
  1014. const PixelC* ppxliPrevYL = ppxlcRefLeftTop + ((yRefL >> 1) + EXPANDY_REF_FRAME) * m_iFrameWidthY + (xRefL >> 1) + EXPANDY_REF_FRAME;
  1015. UInt *pWghtC, *pWghtT, *pWghtB, *pWghtR, *pWghtL;
  1016. pWghtC = (UInt*) gWghtC;
  1017. pWghtT = (UInt*) gWghtT;
  1018. pWghtB = (UInt*) gWghtB + 32;
  1019. pWghtR = (UInt*) gWghtR;
  1020. pWghtL = (UInt*) gWghtL;
  1021. UInt* uiOvrlpPredY = gOvrlpPredY;
  1022. if (bXSubPxlC && bYSubPxlC)
  1023. bilnrMCVH (uiOvrlpPredY, ppxliPrevYC, pWghtC, 0, 8, 0, 8, FALSE);
  1024. else if (bXSubPxlC && !bYSubPxlC)
  1025. bilnrMCH (uiOvrlpPredY, ppxliPrevYC, pWghtC, 0, 8, 0, 8, FALSE);
  1026. else if (!bXSubPxlC && bYSubPxlC)
  1027. bilnrMCV (uiOvrlpPredY, ppxliPrevYC, pWghtC, 0, 8, 0, 8, FALSE);
  1028. else // (!bXSubPxlC && !bYSubPxlC)
  1029. bilnrMC (uiOvrlpPredY, ppxliPrevYC, pWghtC, 0, 8, 0, 8, FALSE);
  1030. if (bXSubPxlT && bYSubPxlT)
  1031. bilnrMCVH (uiOvrlpPredY, ppxliPrevYT, pWghtT, 0, 8, 0, 4, TRUE);
  1032. else if (bXSubPxlT && !bYSubPxlT)
  1033. bilnrMCH (uiOvrlpPredY, ppxliPrevYT, pWghtT, 0, 8, 0, 4, TRUE);
  1034. else if (!bXSubPxlT && bYSubPxlT)
  1035. bilnrMCV (uiOvrlpPredY, ppxliPrevYT, pWghtT, 0, 8, 0, 4, TRUE);
  1036. else // (!bXSubPxlT && !bYSubPxlT)
  1037. bilnrMC (uiOvrlpPredY, ppxliPrevYT, pWghtT, 0, 8, 0, 4, TRUE);
  1038. if (bXSubPxlB && bYSubPxlB)
  1039. bilnrMCVH (&uiOvrlpPredY [32], ppxliPrevYB + (m_iFrameWidthY << 2), pWghtB, 0, 8, 4, 8, TRUE);
  1040. else if (bXSubPxlB && !bYSubPxlB)
  1041. bilnrMCH (&uiOvrlpPredY [32], ppxliPrevYB + (m_iFrameWidthY << 2), pWghtB, 0, 8, 4, 8, TRUE);
  1042. else if (!bXSubPxlB && bYSubPxlB)
  1043. bilnrMCV (&uiOvrlpPredY [32], ppxliPrevYB + (m_iFrameWidthY << 2), pWghtB, 0, 8, 4, 8, TRUE);
  1044. else // (!bXSubPxlB && !bYSubPxlB)
  1045. bilnrMC (&uiOvrlpPredY [32], ppxliPrevYB + (m_iFrameWidthY << 2), pWghtB, 0, 8, 4, 8, TRUE);
  1046. if (bXSubPxlR && bYSubPxlR)
  1047. bilnrMCVH (uiOvrlpPredY, ppxliPrevYR, pWghtR, 4, 8, 0, 8, TRUE);
  1048. else if (bXSubPxlR && !bYSubPxlR)
  1049. bilnrMCH (uiOvrlpPredY, ppxliPrevYR, pWghtR, 4, 8, 0, 8, TRUE);
  1050. else if (!bXSubPxlR && bYSubPxlR)
  1051. bilnrMCV (uiOvrlpPredY, ppxliPrevYR, pWghtR, 4, 8, 0, 8, TRUE);
  1052. else // (!bXSubPxlR && !bYSubPxlR)
  1053. bilnrMC (uiOvrlpPredY, ppxliPrevYR, pWghtR, 4, 8, 0, 8, TRUE);
  1054. if (bXSubPxlL && bYSubPxlL)
  1055. bilnrMCVH (uiOvrlpPredY, ppxliPrevYL, pWghtL, 0, 4, 0, 8, TRUE);
  1056. else if (bXSubPxlL && !bYSubPxlL)
  1057. bilnrMCH (uiOvrlpPredY, ppxliPrevYL, pWghtL, 0, 4, 0, 8, TRUE);
  1058. else if (!bXSubPxlL && bYSubPxlL)
  1059. bilnrMCV (uiOvrlpPredY, ppxliPrevYL, pWghtL, 0, 4, 0, 8, TRUE);
  1060. else // (!bXSubPxlL && !bYSubPxlL)
  1061. bilnrMC (uiOvrlpPredY, ppxliPrevYL, pWghtL, 0, 4, 0, 8, TRUE);
  1062. PixelC* ppxliPredY = ppxlcPredMB + dxc + dyc * MB_SIZE;  // Starting of Pred. Frame
  1063. for (UInt iy = 0; iy < BLOCK_SIZE; iy++){
  1064. for (UInt ix = 0; ix < BLOCK_SIZE; ix++)
  1065. *ppxliPredY++= (*uiOvrlpPredY++ + 4) >> 3;
  1066. ppxliPredY += BLOCK_SIZE;
  1067. }
  1068. }
  1069. }
  1070. Void CVideoObject::bilnrMCVH (UInt* PredY, const PixelC* ppxliPrevYC, UInt* pMWght, UInt xlow, UInt xhigh, UInt ylow, UInt yhigh, Bool bAdd)
  1071. {
  1072. const PixelC* ppxliPrevYCBot = ppxliPrevYC + m_iFrameWidthY;
  1073. if (bAdd)
  1074. for (UInt iy = ylow; iy < yhigh; iy++) {
  1075. for (UInt ix = xlow; ix < xhigh; ix++)
  1076. // PredY [ix] += ((UInt) (ppxliPrevYC [ix] + ppxliPrevYC [ix + 1] + ppxliPrevYCBot [ix] + ppxliPrevYCBot[ix+1] + 2) >> 2) * pMWght [ix];
  1077. PredY [ix] += ((UInt) (ppxliPrevYC [ix] + ppxliPrevYC [ix + 1] + ppxliPrevYCBot [ix] + ppxliPrevYCBot[ix+1] + 2 - m_vopmd.iRoundingControl) >> 2) * pMWght [ix];
  1078. ppxliPrevYC += m_iFrameWidthY;
  1079. ppxliPrevYCBot += m_iFrameWidthY;
  1080. PredY += BLOCK_SIZE;
  1081. pMWght += BLOCK_SIZE;
  1082. }
  1083. else
  1084. for (UInt iy = ylow; iy < yhigh; iy++) {
  1085. for (UInt ix = xlow; ix < xhigh; ix++)
  1086. // PredY [ix] = ((UInt) (ppxliPrevYC [ix] + ppxliPrevYC [ix + 1] + ppxliPrevYCBot [ix] + ppxliPrevYCBot[ix+1] + 2) >> 2) * pMWght [ix];
  1087. PredY [ix] = ((UInt) (ppxliPrevYC [ix] + ppxliPrevYC [ix + 1] + ppxliPrevYCBot [ix] + ppxliPrevYCBot[ix+1] + 2 - m_vopmd.iRoundingControl) >> 2) * pMWght [ix];
  1088. ppxliPrevYC += m_iFrameWidthY;
  1089. ppxliPrevYCBot += m_iFrameWidthY;
  1090. PredY += BLOCK_SIZE;
  1091. pMWght += BLOCK_SIZE;
  1092. }
  1093. }
  1094. Void CVideoObject::bilnrMCV (UInt* PredY, const PixelC* ppxliPrevYC, UInt* pMWght, UInt xlow, UInt xhigh, UInt ylow, UInt yhigh, Bool bAdd)
  1095. {
  1096. const PixelC* ppxliPrevYCBot = ppxliPrevYC + m_iFrameWidthY;
  1097. if (bAdd)
  1098. for (UInt iy = ylow; iy < yhigh; iy++) {
  1099. for (UInt ix = xlow; ix < xhigh; ix++)
  1100. // PredY [ix] += ((UInt) (ppxliPrevYC [ix] + ppxliPrevYCBot [ix] + 1) >> 1) * pMWght [ix];
  1101.   PredY [ix] += ((UInt) (ppxliPrevYC [ix] + ppxliPrevYCBot [ix] + 1 - m_vopmd.iRoundingControl) >> 1) * pMWght [ix];
  1102. ppxliPrevYC += m_iFrameWidthY;
  1103. ppxliPrevYCBot += m_iFrameWidthY;
  1104. PredY += BLOCK_SIZE;
  1105. pMWght += BLOCK_SIZE;
  1106. }
  1107. else
  1108. for (UInt iy = ylow; iy < yhigh; iy++) {
  1109. for (UInt ix = xlow; ix < xhigh; ix++)
  1110. // PredY [ix] = ((UInt) (ppxliPrevYC [ix] + ppxliPrevYCBot [ix] + 1) >> 1) * pMWght [ix];
  1111. PredY [ix] = ((UInt) (ppxliPrevYC [ix] + ppxliPrevYCBot [ix] + 1 - m_vopmd.iRoundingControl) >> 1) * pMWght [ix];
  1112. ppxliPrevYC += m_iFrameWidthY;
  1113. ppxliPrevYCBot += m_iFrameWidthY;
  1114. PredY += BLOCK_SIZE;
  1115. pMWght += BLOCK_SIZE;
  1116. }
  1117. }
  1118. Void CVideoObject::bilnrMCH (UInt* PredY, const PixelC* ppxliPrevYC, UInt* pMWght, UInt xlow, UInt xhigh, UInt ylow, UInt yhigh, Bool bAdd)
  1119. {
  1120. //PixelC* ppxliPrevYCBot = ppxliPrevYC + m_iFrameWidthY;
  1121. if (bAdd)
  1122. for (UInt iy = ylow; iy < yhigh; iy++) {
  1123. for (UInt ix = xlow; ix < xhigh; ix++)
  1124. // PredY [ix] += ((UInt) (ppxliPrevYC [ix] + ppxliPrevYC [ix + 1] + 1) >> 1) * pMWght [ix];
  1125. PredY [ix] += ((UInt) (ppxliPrevYC [ix] + ppxliPrevYC [ix + 1] + 1 - m_vopmd.iRoundingControl) >> 1) * pMWght [ix];
  1126. ppxliPrevYC += m_iFrameWidthY;
  1127. PredY += BLOCK_SIZE;
  1128. pMWght += BLOCK_SIZE;
  1129. }
  1130. else
  1131. for (UInt iy = ylow; iy < yhigh; iy++) {
  1132. for (UInt ix = xlow; ix < xhigh; ix++)
  1133. // PredY [ix] = ((UInt) (ppxliPrevYC [ix] + ppxliPrevYC [ix + 1] + 1) >> 1) * pMWght [ix];
  1134. PredY [ix] = ((UInt) (ppxliPrevYC [ix] + ppxliPrevYC [ix + 1] + 1 - m_vopmd.iRoundingControl) >> 1) * pMWght [ix];
  1135. ppxliPrevYC += m_iFrameWidthY;
  1136. PredY += BLOCK_SIZE;
  1137. pMWght += BLOCK_SIZE;
  1138. }
  1139. }
  1140. Void CVideoObject::bilnrMC (UInt* PredY, const PixelC* ppxliPrevYC, UInt* pMWght, UInt xlow, UInt xhigh, UInt ylow, UInt yhigh, Bool bAdd)
  1141. {
  1142. //PixelC* ppxliPrevYCBot = ppxliPrevYC + m_iFrameWidthY;
  1143. if (bAdd)
  1144. for (UInt iy = ylow; iy < yhigh; iy++) {
  1145. for (UInt ix = xlow; ix < xhigh; ix++)
  1146. PredY [ix] += (UInt) ppxliPrevYC [ix] * pMWght[ix];
  1147. ppxliPrevYC += m_iFrameWidthY;
  1148. PredY += BLOCK_SIZE;
  1149. pMWght += BLOCK_SIZE;
  1150. }
  1151. else
  1152. for (UInt iy = ylow; iy < yhigh; iy++) {
  1153. for (UInt ix = xlow; ix < xhigh; ix++)
  1154. PredY [ix] = (UInt) ppxliPrevYC [ix] * pMWght [ix];
  1155. ppxliPrevYC += m_iFrameWidthY;
  1156. PredY += BLOCK_SIZE;
  1157. pMWght += BLOCK_SIZE;
  1158. }
  1159. }
  1160. Void CVideoObject::motionCompBY (
  1161. PixelC* ppxlcPred, // can be either Y or A
  1162. const PixelC* ppxlcRefLeftTop,
  1163. CoordI iXRef, CoordI iYRef // x + mvX in full pel unit
  1164. )
  1165. {
  1166. CoordI iY;
  1167. const PixelC* ppxlcRef = ppxlcRefLeftTop + 
  1168. (iYRef + EXPANDY_REF_FRAME) * m_iFrameWidthY + iXRef + EXPANDY_REF_FRAME;
  1169.     // bugfix: use the proper bounding rect (!), 981028 mwi
  1170.     Int iLeftBound;
  1171.     Int iRightBound;
  1172.     Int iTopBound;
  1173.     Int iBottomBound;
  1174.     if (m_vopmd.vopPredType == BVOP && m_vopmd.fShapeBPredDir == B_BACKWARD) {
  1175.       iLeftBound = max(0,m_rctRefVOPY1.left - iXRef);
  1176.       iRightBound = max(0,m_rctRefVOPY1.right - iXRef);
  1177.       iTopBound = max(0,m_rctRefVOPY1.top - iYRef);
  1178.       iBottomBound = max(0,m_rctRefVOPY1.bottom - iYRef);
  1179.     }
  1180.     else {
  1181.       iLeftBound = max(0,m_rctRefVOPY0.left - iXRef);
  1182.       iRightBound = max(0,m_rctRefVOPY0.right - iXRef);
  1183.       iTopBound = max(0,m_rctRefVOPY0.top - iYRef);
  1184.       iBottomBound = max(0,m_rctRefVOPY0.bottom - iYRef);
  1185.     }
  1186.     // ~bugfix: use the proper bounding rect
  1187. iLeftBound = min(MC_BAB_SIZE,iLeftBound);
  1188. iRightBound = min(MC_BAB_SIZE,iRightBound);
  1189. iTopBound = min(MC_BAB_SIZE,iTopBound);
  1190. iBottomBound = min(MC_BAB_SIZE,iBottomBound);
  1191. Int iHeightMax = iBottomBound-iTopBound;
  1192. Int iWidthMax  = iRightBound-iLeftBound;
  1193. if (iHeightMax == MC_BAB_SIZE && iWidthMax == MC_BAB_SIZE) {
  1194. for (iY = 0; iY < MC_BAB_SIZE; iY++) {
  1195. memcpy (ppxlcPred, ppxlcRef, MC_BAB_SIZE*sizeof(PixelC));
  1196. ppxlcRef  += m_iFrameWidthY;
  1197. ppxlcPred += MC_BAB_SIZE;
  1198. }
  1199. } else if(iWidthMax == 0 || iHeightMax==0)
  1200. for (iY = 0; iY < MC_BAB_SIZE; iY++) {
  1201. memset (ppxlcPred, 0, MC_BAB_SIZE*sizeof(PixelC));
  1202. ppxlcPred += MC_BAB_SIZE;
  1203. }
  1204. else {
  1205. for (iY = 0; iY < MC_BAB_SIZE; iY++) {
  1206. if(iY<iTopBound || iY>=iBottomBound)
  1207. memset (ppxlcPred, 0, MC_BAB_SIZE*sizeof(PixelC));  // clear row
  1208. else
  1209. {
  1210. if(iLeftBound>0)
  1211. memset (ppxlcPred, 0, iLeftBound*sizeof(PixelC)); // clear left hand span
  1212. if(iRightBound<MC_BAB_SIZE)
  1213. memset (ppxlcPred+iRightBound, 0, (MC_BAB_SIZE-iRightBound)*sizeof(PixelC)); // right span
  1214. memcpy (ppxlcPred+iLeftBound, ppxlcRef+iLeftBound, iWidthMax*sizeof(PixelC)); // copy middle region
  1215. }
  1216. ppxlcRef += m_iFrameWidthY;
  1217. ppxlcPred += MC_BAB_SIZE;
  1218. }
  1219. }
  1220. }
  1221. Void CVideoObject::copyFromRefToCurrQ (
  1222. const CVOPU8YUVBA* pvopcRef, // reference VOP
  1223. CoordI x, CoordI y, 
  1224. PixelC* ppxlcCurrQMBY, PixelC* ppxlcCurrQMBU, PixelC* ppxlcCurrQMBV,
  1225. CRct *prctMVLimit
  1226. )
  1227. {
  1228. // needs limiting to reference area bounding box
  1229. limitMVRangeToExtendedBBFullPel(x,y,prctMVLimit,MB_SIZE);
  1230. Int iOffsetY = (y + EXPANDY_REF_FRAME) * m_iFrameWidthY + x + EXPANDY_REF_FRAME;
  1231. Int iOffsetUV = (y / 2 + EXPANDUV_REF_FRAME) * m_iFrameWidthUV + x / 2 + EXPANDUV_REF_FRAME;
  1232. const PixelC* ppxlcRefMBY = pvopcRef->pixelsY () + iOffsetY;
  1233. const PixelC* ppxlcRefMBU = pvopcRef->pixelsU () + iOffsetUV;
  1234. const PixelC* ppxlcRefMBV = pvopcRef->pixelsV () + iOffsetUV;
  1235. CoordI iY;
  1236. for (iY = 0; iY < BLOCK_SIZE; iY++) {
  1237. memcpy (ppxlcCurrQMBY, ppxlcRefMBY, MB_SIZE*sizeof(PixelC));
  1238. memcpy (ppxlcCurrQMBU, ppxlcRefMBU, BLOCK_SIZE*sizeof(PixelC));
  1239. memcpy (ppxlcCurrQMBV, ppxlcRefMBV, BLOCK_SIZE*sizeof(PixelC));
  1240. ppxlcCurrQMBY += m_iFrameWidthY; ppxlcRefMBY += m_iFrameWidthY;
  1241. ppxlcCurrQMBU += m_iFrameWidthUV; ppxlcRefMBU += m_iFrameWidthUV;
  1242. ppxlcCurrQMBV += m_iFrameWidthUV; ppxlcRefMBV += m_iFrameWidthUV;
  1243. memcpy (ppxlcCurrQMBY, ppxlcRefMBY, MB_SIZE*sizeof(PixelC));
  1244. ppxlcCurrQMBY += m_iFrameWidthY; ppxlcRefMBY += m_iFrameWidthY;
  1245. }
  1246. }
  1247. Void CVideoObject::copyFromRefToCurrQ_WithShape (
  1248. const CVOPU8YUVBA* pvopcRef, // reference VOP
  1249. CoordI x, CoordI y, 
  1250. PixelC* ppxlcCurrQMBY, PixelC* ppxlcCurrQMBU, PixelC* ppxlcCurrQMBV, PixelC* ppxlcCurrQMBBY
  1251. )
  1252. {
  1253. Int iOffsetY = (y + EXPANDY_REF_FRAME) * m_iFrameWidthY + x + EXPANDY_REF_FRAME;
  1254. Int iOffsetUV = (y / 2 + EXPANDUV_REF_FRAME) * m_iFrameWidthUV + x / 2 + EXPANDUV_REF_FRAME;
  1255. const PixelC* ppxlcRefMBY = pvopcRef->pixelsY () + iOffsetY;
  1256. const PixelC* ppxlcRefMBBY = pvopcRef->pixelsBY () + iOffsetY;
  1257. const PixelC* ppxlcRefMBU = pvopcRef->pixelsU () + iOffsetUV;
  1258. const PixelC* ppxlcRefMBV = pvopcRef->pixelsV () + iOffsetUV;
  1259. CoordI iY;
  1260. for (iY = 0; iY < BLOCK_SIZE; iY++) {
  1261. memcpy (ppxlcCurrQMBY, ppxlcRefMBY, MB_SIZE*sizeof(PixelC));
  1262. memcpy (ppxlcCurrQMBBY, ppxlcRefMBBY, MB_SIZE*sizeof(PixelC));
  1263. memcpy (ppxlcCurrQMBU, ppxlcRefMBU, BLOCK_SIZE*sizeof(PixelC));
  1264. memcpy (ppxlcCurrQMBV, ppxlcRefMBV, BLOCK_SIZE*sizeof(PixelC));
  1265. ppxlcCurrQMBY += m_iFrameWidthY; ppxlcRefMBY += m_iFrameWidthY;
  1266. ppxlcCurrQMBBY += m_iFrameWidthY; ppxlcRefMBBY += m_iFrameWidthY;
  1267. ppxlcCurrQMBU += m_iFrameWidthUV; ppxlcRefMBU += m_iFrameWidthUV;
  1268. ppxlcCurrQMBV += m_iFrameWidthUV; ppxlcRefMBV += m_iFrameWidthUV;
  1269. memcpy (ppxlcCurrQMBY, ppxlcRefMBY, MB_SIZE*sizeof(PixelC));
  1270. ppxlcCurrQMBY += m_iFrameWidthY; ppxlcRefMBY += m_iFrameWidthY;
  1271. memcpy (ppxlcCurrQMBBY, ppxlcRefMBBY, MB_SIZE*sizeof(PixelC));
  1272. ppxlcCurrQMBBY += m_iFrameWidthY; ppxlcRefMBBY += m_iFrameWidthY;
  1273. }
  1274. }
  1275. Void CVideoObject::copyAlphaFromRefToCurrQ (
  1276. const CVOPU8YUVBA* pvopcRef, // reference VOP
  1277. CoordI x, CoordI y, 
  1278. PixelC* ppxlcCurrQMBA,
  1279. CRct *prctMVLimit
  1280. )
  1281. {
  1282. // needs limiting to reference area bounding box
  1283. limitMVRangeToExtendedBBFullPel(x,y,prctMVLimit,MB_SIZE);
  1284. Int iOffsetY = (y + EXPANDY_REF_FRAME) * m_iFrameWidthY + x + EXPANDY_REF_FRAME;
  1285. const PixelC* ppxlcRefMBA = pvopcRef->pixelsA () + iOffsetY;
  1286. CoordI iY;
  1287. for (iY = 0; iY < MB_SIZE; iY++) {
  1288. memcpy (ppxlcCurrQMBA, ppxlcRefMBA, MB_SIZE*sizeof(PixelC));
  1289. ppxlcCurrQMBA += m_iFrameWidthY; 
  1290. ppxlcRefMBA += m_iFrameWidthY;
  1291. }
  1292. }