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

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. /*************************************************************************
  2. This software module was originally developed by 
  3. Ming-Chieh Lee (mingcl@microsoft.com), Microsoft Corporation
  4. Wei-ge Chen (wchen@microsoft.com), Microsoft Corporation
  5. Bruce Lin (blin@microsoft.com), Microsoft Corporation
  6. Chuang Gu (chuanggu@microsoft.com), Microsoft Corporation
  7. (date: March, 1996)
  8. and edited by
  9.         Wei Wu (weiwu@stallion.risc.rockwell.com) Rockwell Science Center
  10. in the course of development of the MPEG-4 Video (ISO/IEC 14496-2). 
  11. This software module is an implementation of a part of one or more MPEG-4 Video tools 
  12. as specified by the MPEG-4 Video. 
  13. ISO/IEC gives users of the MPEG-4 Video free license to this software module or modifications 
  14. thereof for use in hardware or software products claiming conformance to the MPEG-4 Video. 
  15. Those intending to use this software module in hardware or software products are advised that its use may infringe existing patents. 
  16. The original developer of this software module and his/her company, 
  17. the subsequent editors and their companies, 
  18. and ISO/IEC have no liability for use of this software module or modifications thereof in an implementation. 
  19. Copyright is not released for non MPEG-4 Video conforming products. 
  20. Microsoft retains full right to use the code for his/her own purpose, 
  21. assign or donate the code to a third party and to inhibit third parties from using the code for non <MPEG standard> conforming products. 
  22. This copyright notice must be included in all copies or derivative works. 
  23. Copyright (c) 1996, 1997.
  24. Module Name:
  25. vopSes.cpp
  26. Abstract:
  27. Base class for the encoder for one VOP session.
  28. Revision History:
  29. December 20, 1997: Interlaced tools added by NextLevel Systems (GI)
  30.                         X.Chen (xchen@nlvl.com), B. Eifrig (beifrig@nlvl.com)
  31.         May. 9   1998:  add boundary by Hyundai Electronics 
  32.                                   Cheol-Soo Park (cspark@super5.hyundai.co.kr) 
  33.         May. 9   1998:  add field based unrestricted MC padding by Hyundai Electronics 
  34.                                   Cheol-Soo Park (cspark@super5.hyundai.co.kr) 
  35. *************************************************************************/
  36. #include <stdio.h>
  37. #include "typeapi.h"
  38. #include "basic.hpp"
  39. #include "header.h"
  40. #include "codehead.h"
  41. #include "mode.hpp"
  42. #include "dct.hpp"
  43. #include "cae.h"
  44. #include "vopses.hpp"
  45. #ifdef __MFC_
  46. #ifdef _DEBUG
  47. #undef THIS_FILE
  48. static char BASED_CODE THIS_FILE[] = __FILE__;
  49. #endif
  50. #define new DEBUG_NEW    
  51. #endif // __MFC_
  52. CVideoObject::~CVideoObject ()
  53. {
  54. delete m_pvopcCurrQ;
  55. delete m_pvopcRefQ0;
  56. delete m_pvopcRefQ1;       // modified by Shu 12/12/97
  57.    // wchen: unmodified 12/16/97
  58. delete m_pvopcCurrMB;
  59. delete m_pvopcPredMB;
  60. delete m_pvopiErrorMB;
  61. delete [] m_rgmbmd;
  62. delete [] m_rgmv;
  63. delete [] m_rgmvBY;
  64.     delete [] m_rgmvRef;
  65. delete m_pidct;
  66. Int nBlk = (m_volmd.fAUsage == EIGHT_BIT) ? 10 : 6;
  67. Int iBlk;
  68. for (iBlk = 0; iBlk < nBlk; iBlk++)
  69. delete [] m_rgpiCoefQ [iBlk];
  70. delete [] m_rgpiCoefQ;
  71. // delete m_pvopfCurrFilteredQ;
  72. // delete m_pdrtmdRef1;
  73. delete [] m_rgiQPpred;
  74. if (m_volmd.fAUsage == RECTANGLE) {
  75. Int nBlk = (m_volmd.fAUsage == EIGHT_BIT) ? 10 : 6;
  76. delete [] m_rgblkmCurrMB;
  77.         if (m_rgpmbmAbove != NULL)
  78.     for (Int iMB = 0; iMB < m_iNumMBX; iMB++) {
  79.     for (iBlk = 0; iBlk < nBlk; iBlk++) {
  80.     delete [] (m_rgpmbmAbove [iMB]->rgblkm) [iBlk];
  81.     delete [] (m_rgpmbmCurr  [iMB]->rgblkm) [iBlk];
  82.     }
  83.     delete [] m_rgpmbmAbove [iMB]->rgblkm;
  84.     delete m_rgpmbmAbove [iMB];
  85.     delete [] m_rgpmbmCurr [iMB]->rgblkm;
  86.     delete m_rgpmbmCurr [iMB];
  87.     }
  88. delete [] m_rgpmbmAbove;
  89. delete [] m_rgpmbmCurr;
  90. }
  91. // sprite
  92. if (m_uiSprite == 1) {
  93. delete [] m_rgstSrcQ;
  94. delete [] m_rgstDstQ;
  95. if (m_sptMode == BASIC_SPRITE)
  96. delete m_pvopcSptQ;
  97. }
  98. delete m_pbEmptyRowArray;
  99. /* NBIT: change
  100. m_rgiClipTab -= 400;
  101. */
  102. m_rgiClipTab -= m_iOffset;
  103. delete [] m_rgiClipTab;
  104. m_rgiClipTab = NULL;
  105. // shape
  106. if(m_rgshpmd!=NULL)
  107. delete m_rgshpmd;
  108. delete m_puciPredBAB;
  109. delete m_parcodec;
  110. delete [] m_ppxlcCurrMBBYDown4;
  111. delete [] m_ppxlcCurrMBBYDown2;
  112. delete [] m_ppxlcReconCurrBAB;
  113. delete [] m_ppxlcPredBABDown2;
  114. delete [] m_ppxlcPredBABDown4;
  115. }
  116. CVideoObject::CVideoObject ()
  117. {
  118. m_t = 0;
  119. m_iBCount = 0;
  120. m_tPastRef = 0;
  121. m_tFutureRef = 0;
  122. m_bCodedFutureRef = TRUE;
  123. m_rgmbmd = NULL;
  124. m_rgmv = NULL;
  125. m_rgmvBackward = NULL;
  126. m_rgmvBY = NULL;
  127. m_rgmbmdRef = NULL;
  128. m_rgmvRef = NULL;
  129. m_tModuloBaseDecd = 0;
  130. m_tModuloBaseDisp = 0;
  131. m_pvopcCurrQ = NULL;
  132. m_pvopcRefQ0 = NULL; 
  133. m_pvopcRefQ1 = NULL;
  134. m_puciPredBAB = NULL;
  135. m_ppxlcReconCurrBAB = NULL;
  136. m_parcodec = NULL;
  137. m_ppxlcCurrMBBYDown4 = NULL;
  138. m_ppxlcCurrMBBYDown2 = NULL;
  139. m_ppxlcPredBABDown4 = NULL;
  140. m_ppxlcPredBABDown2 = NULL;
  141. m_pvopcSptQ = NULL;
  142. m_uiSprite = 0;
  143. m_rgstSrcQ = NULL;
  144. m_rgstDstQ = NULL;
  145. m_iOffsetForPadY = 0;
  146. m_iOffsetForPadUV = 0;
  147. m_rgshpmd = NULL;
  148. m_pbEmptyRowArray = new Bool [MB_SIZE];
  149. /* NBIT: replaced by setClipTab() function
  150. m_rgiClipTab = new U8 [1024];
  151. m_rgiClipTab += 400;
  152. Int i;
  153. for (i = -400; i < 624; i++)
  154. m_rgiClipTab [i] = (i < 0) ? 0 : (i > 255) ? 255 : i;
  155. */
  156. }
  157. // NBIT: added function
  158. Void CVideoObject::setClipTab()
  159. {
  160. Int TabSize = 1<<(m_volmd.nBits+2);
  161. Int maxVal = (1<<m_volmd.nBits)-1;
  162. m_iOffset = TabSize/2;
  163. m_rgiClipTab = new PixelC [TabSize];
  164. m_rgiClipTab += m_iOffset;
  165. Int i;
  166. for (i = -m_iOffset; i < m_iOffset; i++)
  167. m_rgiClipTab [i] = (i < 0) ? 0 : (i > maxVal) ? maxVal : i;
  168. }
  169. Void CVideoObject::allocateVOLMembers (Int iSessionWidth, Int iSessionHeight)
  170. {
  171. m_pvopcCurrMB = new CVOPU8YUVBA (m_volmd.fAUsage, CRct (0, 0, MB_SIZE, MB_SIZE));
  172. m_ppxlcCurrMBY = (PixelC*) m_pvopcCurrMB->pixelsY ();
  173. m_ppxlcCurrMBU = (PixelC*) m_pvopcCurrMB->pixelsU ();
  174. m_ppxlcCurrMBV = (PixelC*) m_pvopcCurrMB->pixelsV ();
  175. m_ppxlcCurrMBBY = (PixelC*) m_pvopcCurrMB->pixelsBY ();
  176. m_ppxlcCurrMBBUV = (PixelC*) m_pvopcCurrMB->pixelsBUV ();
  177. m_ppxlcCurrMBA = (PixelC*) m_pvopcCurrMB->pixelsA ();
  178. m_pvopcPredMB = new CVOPU8YUVBA (m_volmd.fAUsage, CRct (0, 0, MB_SIZE, MB_SIZE));
  179. m_ppxlcPredMBY = (PixelC*) m_pvopcPredMB->pixelsY ();
  180. m_ppxlcPredMBU = (PixelC*) m_pvopcPredMB->pixelsU ();
  181. m_ppxlcPredMBV = (PixelC*) m_pvopcPredMB->pixelsV ();
  182. m_ppxlcPredMBA = (PixelC*) m_pvopcPredMB->pixelsA ();
  183. // B-VOP MB buffer data
  184. m_pvopcPredMBBack = new CVOPU8YUVBA (m_volmd.fAUsage, CRct (0, 0, MB_SIZE, MB_SIZE));
  185. m_ppxlcPredMBBackY = (PixelC*) m_pvopcPredMBBack->pixelsY ();
  186. m_ppxlcPredMBBackU = (PixelC*) m_pvopcPredMBBack->pixelsU ();
  187. m_ppxlcPredMBBackV = (PixelC*) m_pvopcPredMBBack->pixelsV ();
  188. m_ppxlcPredMBBackA = (PixelC*) m_pvopcPredMBBack->pixelsA ();
  189. m_pvopiErrorMB = new CVOPIntYUVBA (m_volmd.fAUsage, CRct (0, 0, MB_SIZE, MB_SIZE));
  190. m_ppxliErrorMBY = (PixelI*) m_pvopiErrorMB->getPlane (Y_PLANE)->pixels ();
  191. m_ppxliErrorMBU = (PixelI*) m_pvopiErrorMB->getPlane (U_PLANE)->pixels ();
  192. m_ppxliErrorMBV = (PixelI*) m_pvopiErrorMB->getPlane (V_PLANE)->pixels ();
  193. m_ppxliErrorMBA = (PixelI*) m_pvopiErrorMB->getPlane (A_PLANE)->pixels ();
  194. if (m_uiSprite == 0)
  195. m_pvopcCurrQ = new CVOPU8YUVBA (m_volmd.fAUsage, m_rctRefFrameY);
  196. else //for sprite m_rctRefFrameY is for whole sprite, m_rctOrg is the display window 
  197. // dshu: begin of modification
  198. // m_pvopcCurrQ = new CVOPU8YUVBA (m_volmd.fAUsage, m_rctDisplayWindow);
  199. {
  200. CRct rctCurrQ = CRct (
  201. -EXPANDY_REF_FRAME, -EXPANDY_REF_FRAME, 
  202. EXPANDY_REF_FRAME + m_rctDisplayWindow.width, EXPANDY_REF_FRAME + m_rctDisplayWindow.height()
  203. );
  204. m_pvopcCurrQ = new CVOPU8YUVBA (m_volmd.fAUsage, rctCurrQ);
  205. }
  206. // dshu: end of modification
  207.     assert (m_pvopcCurrQ != NULL);
  208. m_pvopcRefQ0 = new CVOPU8YUVBA (m_volmd.fAUsage, m_rctRefFrameY);
  209. assert (m_pvopcRefQ0 != NULL);
  210. m_pvopcRefQ1 = new CVOPU8YUVBA (m_volmd.fAUsage, m_rctRefFrameY);
  211. assert (m_pvopcRefQ1 != NULL);
  212. m_iFrameWidthY = m_pvopcRefQ0->whereY ().width;
  213. m_iFrameWidthUV = m_pvopcRefQ0->whereUV ().width;
  214. m_iFrameWidthYxMBSize = MB_SIZE * m_pvopcRefQ0->whereY ().width; 
  215. m_iFrameWidthYxBlkSize = BLOCK_SIZE * m_pvopcRefQ0->whereY ().width; 
  216. m_iFrameWidthUVxBlkSize = BLOCK_SIZE * m_pvopcRefQ0->whereUV ().width;
  217. // MB data
  218. Int nBlk = (m_volmd.fAUsage == EIGHT_BIT) ? 10 : 6;
  219. m_rgpiCoefQ = new Int* [nBlk];
  220. m_rgiQPpred = new Int [nBlk];
  221. Int iBlk;
  222. for (iBlk = 0; iBlk < nBlk; iBlk++)
  223. m_rgpiCoefQ [iBlk] = new Int [BLOCK_SQUARE_SIZE];
  224. /* NBIT: change
  225. m_pidct = new CInvBlockDCT;
  226. */
  227. m_pidct = new CInvBlockDCT(m_volmd.nBits);
  228. // motion vectors and MBMode
  229. Int iNumMBX = iSessionWidth / MB_SIZE; 
  230. if (iSessionWidth  % MB_SIZE != 0) //round up
  231. iNumMBX++;
  232. Int iNumMBY = iSessionHeight / MB_SIZE;
  233. if (iSessionHeight % MB_SIZE != 0) //deal with frational MB
  234. iNumMBY++;
  235. Int iNumMB = m_iSessNumMB = iNumMBX * iNumMBY;
  236. m_rgmbmd = new CMBMode [iNumMB];
  237. m_rgmv = new CMotionVector [max(PVOP_MV_PER_REF_PER_MB, 2*BVOP_MV_PER_REF_PER_MB) * iNumMB];
  238. m_rgmvBackward = m_rgmv + BVOP_MV_PER_REF_PER_MB * m_iSessNumMB;
  239. m_rgmvRef = new CMotionVector [max(PVOP_MV_PER_REF_PER_MB, 2*BVOP_MV_PER_REF_PER_MB) * iNumMB];
  240. m_rgmvBY = new CMotionVector [iNumMB]; // for shape
  241. m_rgmbmdRef = new CMBMode [iNumMB];
  242. if (m_volmd.volType == ENHN_LAYER)
  243. m_rgshpmd = new ShapeMode [iNumMB];
  244. // shape data
  245. if (m_volmd.fAUsage != RECTANGLE) {
  246. m_puciPredBAB = new CU8Image (CRct (0, 0, MC_BAB_SIZE, MC_BAB_SIZE));
  247. m_ppxlcReconCurrBAB = new PixelC [BAB_SIZE * BAB_SIZE];
  248. m_parcodec = new ArCodec;
  249. m_ppxlcCurrMBBYDown4 = new PixelC [8 * 8];
  250. m_ppxlcCurrMBBYDown2 = new PixelC [12 * 12];
  251. m_ppxlcPredBABDown4 = new PixelC [6*6];
  252. m_ppxlcPredBABDown2 = new PixelC [10*10];
  253. }
  254. }
  255. Void CVideoObject::computeVOLConstMembers ()
  256. {
  257. m_iOffsetForPadY = m_rctRefFrameY.offset (m_rctCurrVOPY.left, m_rctCurrVOPY.top);
  258. m_iOffsetForPadUV = m_rctRefFrameUV.offset (m_rctCurrVOPUV.left, m_rctCurrVOPUV.top);
  259. m_rctPrevNoExpandY = m_rctCurrVOPY;
  260. m_rctPrevNoExpandUV = m_rctCurrVOPUV;
  261. m_iVOPWidthY = m_rctCurrVOPY.width;
  262. m_iVOPWidthUV = m_rctCurrVOPUV.width;
  263. m_iNumMBX = m_iNumMBXRef = m_iVOPWidthY / MB_SIZE; 
  264. m_iNumMBY = m_iNumMBYRef = m_rctCurrVOPY.height () / MB_SIZE;
  265. m_iNumMB = m_iNumMBRef = m_iNumMBX * m_iNumMBY;
  266. m_iNumOfTotalMVPerRow = PVOP_MV_PER_REF_PER_MB * m_iNumMBX;
  267. setRefStartingPointers ();
  268. m_pvopcCurrQ->setBoundRct (m_rctCurrVOPY);
  269. m_pvopcRefQ0->setBoundRct (m_rctRefVOPY0);
  270. m_pvopcRefQ1->setBoundRct (m_rctRefVOPY1);
  271. Int iMB, iBlk;
  272. Int nBlk = (m_volmd.fAUsage == EIGHT_BIT) ? 10 : 6;
  273. m_rgblkmCurrMB = new BlockMemory [nBlk];
  274. m_rgpmbmAbove = new MacroBlockMemory* [m_iNumMBX];
  275. m_rgpmbmCurr  = new MacroBlockMemory* [m_iNumMBX];
  276. for (iMB = 0; iMB < m_iNumMBX; iMB++) {
  277. m_rgpmbmAbove [iMB] = new MacroBlockMemory;
  278. m_rgpmbmAbove [iMB]->rgblkm = new BlockMemory [nBlk];
  279. m_rgpmbmCurr  [iMB] = new MacroBlockMemory;
  280. m_rgpmbmCurr  [iMB]->rgblkm = new BlockMemory [nBlk];
  281. for (iBlk = 0; iBlk < nBlk; iBlk++) {
  282. (m_rgpmbmAbove [iMB]->rgblkm) [iBlk] = new Int [(BLOCK_SIZE << 1) - 1];
  283. (m_rgpmbmCurr  [iMB]->rgblkm) [iBlk] = new Int [(BLOCK_SIZE << 1) - 1];
  284. }
  285. }
  286. }
  287. Void CVideoObject::computeVOPMembers ()
  288. {
  289. m_iVOPWidthY = m_rctCurrVOPY.width;
  290. m_iVOPWidthUV = m_rctCurrVOPUV.width;
  291. m_iNumMBX = m_iVOPWidthY / MB_SIZE; 
  292. m_iNumMBY = m_rctCurrVOPY.height () / MB_SIZE;
  293. m_iNumMB = m_iNumMBX * m_iNumMBY;
  294. m_iNumOfTotalMVPerRow = PVOP_MV_PER_REF_PER_MB * m_iNumMBX;
  295. Int iMB, iBlk;
  296. Int nBlk = (m_volmd.fAUsage == EIGHT_BIT) ? 10 : 6;
  297. m_rgblkmCurrMB = new BlockMemory [nBlk];
  298. m_rgpmbmAbove = new MacroBlockMemory* [m_iNumMBX];
  299. m_rgpmbmCurr  = new MacroBlockMemory* [m_iNumMBX];
  300. for (iMB = 0; iMB < m_iNumMBX; iMB++) {
  301. m_rgpmbmAbove [iMB] = new MacroBlockMemory;
  302. m_rgpmbmAbove [iMB]->rgblkm = new BlockMemory [nBlk];
  303. m_rgpmbmCurr  [iMB] = new MacroBlockMemory;
  304. m_rgpmbmCurr  [iMB]->rgblkm = new BlockMemory [nBlk];
  305. for (iBlk = 0; iBlk < nBlk; iBlk++) {
  306. // BLOCK_SIZE*2-1 is 15 Ints for dc/ac prediction of coefficients
  307. (m_rgpmbmAbove [iMB]->rgblkm) [iBlk] = new Int [(BLOCK_SIZE << 1) - 1];
  308. (m_rgpmbmCurr  [iMB]->rgblkm) [iBlk] = new Int [(BLOCK_SIZE << 1) - 1];
  309. }
  310. }
  311. }
  312. Void CVideoObject::repeatPadYOrA (PixelC* ppxlcOldLeft, CVOPU8YUVBA* pvopcRef)
  313. {
  314. PixelC* ppxlcLeftTop = ppxlcOldLeft - EXPANDY_REFVOP * m_iFrameWidthY - EXPANDY_REFVOP;
  315. // point to the left top of the expanded bounding box (+- EXPANDY_REFVOP)
  316. const PixelC* ppxlcOldRight = ppxlcOldLeft + ((m_volmd.fAUsage == RECTANGLE)?m_ivolWidth:m_rctPrevNoExpandY.width) - 1; // modified by Sharp (99/1/14)
  317. // point to the right-top of the bounding box
  318. const PixelC* ppxlcOldTopLn = ppxlcOldLeft - EXPANDY_REFVOP;
  319. // point to the (left, top) - EXPANDY_REFVOP
  320. PixelC* ppxlcNewLeft = (PixelC*) ppxlcOldTopLn;
  321. PixelC* ppxlcNewRight = (PixelC*) ppxlcOldRight + 1;
  322. CoordI y;
  323. // begin:  modified by Sharp (99/1/14)
  324. Int PrevNoExpandY_height = (m_volmd.fAUsage == RECTANGLE)?m_ivolHeight:m_rctPrevNoExpandY.height ();
  325. for (y = 0; y < PrevNoExpandY_height; y++) { // x-direction interpolation
  326. // end: modified by Sharp
  327. for (Int i=0; i<EXPANDY_REFVOP; i++) {
  328. ppxlcNewLeft[i] = *ppxlcOldLeft;
  329. ppxlcNewRight[i] = *ppxlcOldRight;
  330. }
  331. ppxlcNewLeft += pvopcRef->whereY ().width;
  332. ppxlcNewRight += pvopcRef->whereY ().width;
  333. ppxlcOldLeft += pvopcRef->whereY ().width;
  334. ppxlcOldRight += pvopcRef->whereY ().width;
  335. }
  336. /* commented out due to fact of no field padding now
  337. // Added for field based unrestricted MC padding by Hyundai(1998-5-9)
  338.         if (m_vopmd.bInterlace) {      
  339. Int  iUnit = sizeof (PixelC); 
  340.                 Int     width = pvopcRef->whereY ().width;
  341.                 Int     iFieldSkip = 2*width;
  342.                 Int     iPadArea = (m_rctPrevNoExpandY.width + 2 * EXPANDY_REFVOP)*iUnit;
  343.                 const PixelC
  344.                         *ppxlcSrcTopFieldLn1 = ppxlcOldTopLn,
  345.                         *ppxlcSrcTopFieldLn2 = ppxlcNewLeft  - iFieldSkip,
  346.                         *ppxlcSrcBotFieldLn1 = ppxlcOldTopLn + width,
  347.                         *ppxlcSrcBotFieldLn2 = ppxlcNewLeft  - width;
  348.                 PixelC  *ppxlcDstTopFieldLn1 = ppxlcLeftTop,
  349.                         *ppxlcDstTopFieldLn2 = ppxlcNewLeft,
  350.                         *ppxlcDstBotFieldLn1 = ppxlcLeftTop + width,
  351.                         *ppxlcDstBotFieldLn2 = ppxlcNewLeft + width;
  352.                 for (y = 0; y < EXPANDY_REFVOP/2; y++) {
  353.                         memcpy (ppxlcDstTopFieldLn1, ppxlcSrcTopFieldLn1, iPadArea);
  354.                         memcpy (ppxlcDstTopFieldLn2, ppxlcSrcTopFieldLn2, iPadArea);
  355.                         memcpy (ppxlcDstBotFieldLn1, ppxlcSrcBotFieldLn1, iPadArea);
  356.                         memcpy (ppxlcDstBotFieldLn2, ppxlcSrcBotFieldLn2, iPadArea);
  357.                         ppxlcDstTopFieldLn1 += iFieldSkip;
  358.                         ppxlcDstTopFieldLn2 += iFieldSkip;
  359.                         ppxlcDstBotFieldLn1 += iFieldSkip;
  360.                         ppxlcDstBotFieldLn2 += iFieldSkip;
  361.                 }
  362.                 return;
  363.         }
  364. // End of Hyundai(1998-5-9)
  365. */
  366. const PixelC* ppxlcOldBotLn = ppxlcNewLeft - pvopcRef->whereY ().width;
  367. for (y = 0; y < EXPANDY_REFVOP; y++) {
  368. memcpy (ppxlcLeftTop, ppxlcOldTopLn, (m_rctPrevNoExpandY.width + 2 * EXPANDY_REFVOP)*sizeof(PixelC));
  369. memcpy (ppxlcNewLeft, ppxlcOldBotLn, (m_rctPrevNoExpandY.width + 2 * EXPANDY_REFVOP)*sizeof(PixelC));
  370. ppxlcNewLeft += pvopcRef->whereY ().width;
  371. ppxlcLeftTop += pvopcRef->whereY ().width;
  372. }
  373. }
  374. Void CVideoObject::repeatPadUV (CVOPU8YUVBA* pvopcRef)
  375. {
  376. const PixelC* ppxlcOldLeftU = pvopcRef->pixelsU () + m_iOffsetForPadUV; // point to the left-top of bounding box
  377. const PixelC* ppxlcOldLeftV = pvopcRef->pixelsV () + m_iOffsetForPadUV; // point to the left-top of bounding box
  378. PixelC* ppxlcLeftTopU = (PixelC*) ppxlcOldLeftU - EXPANDUV_REFVOP * m_iFrameWidthUV - EXPANDUV_REFVOP;
  379. PixelC* ppxlcLeftTopV = (PixelC*) ppxlcOldLeftV - EXPANDUV_REFVOP * m_iFrameWidthUV - EXPANDUV_REFVOP;
  380. // point to the left top of the expanded bounding box (+- EXPANDY_REFVOP)
  381. const PixelC* ppxlcOldRightU = ppxlcOldLeftU + ((m_volmd.fAUsage == RECTANGLE)?m_ivolWidth/2:m_rctPrevNoExpandUV.width) - 1; // modified by Sharp (99/1/14)
  382. const PixelC* ppxlcOldRightV = ppxlcOldLeftV + ((m_volmd.fAUsage == RECTANGLE)?m_ivolWidth/2:m_rctPrevNoExpandUV.width) - 1; // modified by Sharp (99/1/14)
  383. // point to the right-top of the bounding box
  384. const PixelC* ppxlcOldTopLnU = ppxlcOldLeftU - EXPANDUV_REFVOP;
  385. const PixelC* ppxlcOldTopLnV = ppxlcOldLeftV - EXPANDUV_REFVOP;
  386. // point to the (left, top) - EXPANDY_REFVOP
  387. PixelC* ppxlcNewLeftU = (PixelC*) ppxlcOldTopLnU;
  388. PixelC* ppxlcNewLeftV = (PixelC*) ppxlcOldTopLnV;
  389. PixelC* ppxlcNewRightU = (PixelC*) ppxlcOldRightU + 1;
  390. PixelC* ppxlcNewRightV = (PixelC*) ppxlcOldRightV + 1;
  391. CoordI y;
  392. // begin:  modified by Sharp (99/1/14)
  393. Int PrevNoExpandUV_height = (m_volmd.fAUsage == RECTANGLE)?m_ivolHeight/2:m_rctPrevNoExpandUV.height ();
  394. for (y = 0; y < PrevNoExpandUV_height; y++) { // x-direction interpolation
  395. // end:  modified by Sharp (99/1/14)
  396. for (Int i=0; i<EXPANDUV_REFVOP; i++) {
  397. ppxlcNewLeftU[i] = *ppxlcOldLeftU;
  398. ppxlcNewLeftV[i] = *ppxlcOldLeftV;
  399. ppxlcNewRightU[i] = *ppxlcOldRightU;
  400. ppxlcNewRightV[i] = *ppxlcOldRightV;
  401. }
  402. ppxlcNewLeftU += pvopcRef->whereUV ().width;
  403. ppxlcNewLeftV += pvopcRef->whereUV ().width;
  404. ppxlcNewRightU += pvopcRef->whereUV ().width;
  405. ppxlcNewRightV += pvopcRef->whereUV ().width;
  406. ppxlcOldLeftU += pvopcRef->whereUV ().width;
  407. ppxlcOldLeftV += pvopcRef->whereUV ().width;
  408. ppxlcOldRightU += pvopcRef->whereUV ().width;
  409. ppxlcOldRightV += pvopcRef->whereUV ().width;
  410. }
  411. /* no longer any field based padding
  412. // Added for field based unrestricted MC padding by Hyundai(1998-5-9)
  413.         if (m_vopmd.bInterlace) {
  414. Int iUnit = sizeof(PixelC);
  415.                 Int     width = pvopcRef->whereUV ().width;
  416.                 Int     iFieldSkip = 2*width;
  417.                 Int     iPadArea = (m_rctPrevNoExpandUV.width + 2 * EXPANDUV_REFVOP)*iUnit;
  418.                 const PixelC 
  419.                         *ppxlcSrcTopFieldLn1U = ppxlcOldTopLnU,
  420.                         *ppxlcSrcTopFieldLn2U = ppxlcNewLeftU  - iFieldSkip,
  421.                         *ppxlcSrcBotFieldLn1U = ppxlcOldTopLnU + width,
  422.                         *ppxlcSrcBotFieldLn2U = ppxlcNewLeftU  - width,
  423.                         *ppxlcSrcTopFieldLn1V = ppxlcOldTopLnV,
  424.                         *ppxlcSrcTopFieldLn2V = ppxlcNewLeftV  - iFieldSkip,
  425.                         *ppxlcSrcBotFieldLn1V = ppxlcOldTopLnV + width,
  426.                         *ppxlcSrcBotFieldLn2V = ppxlcNewLeftV  - width;
  427.                 PixelC  *ppxlcDstTopFieldLn1U = ppxlcLeftTopU,
  428.                         *ppxlcDstTopFieldLn2U = ppxlcNewLeftU,
  429.                         *ppxlcDstBotFieldLn1U = ppxlcLeftTopU + width,
  430.                         *ppxlcDstBotFieldLn2U = ppxlcNewLeftU + width,
  431.                         *ppxlcDstTopFieldLn1V = ppxlcLeftTopV,
  432.                         *ppxlcDstTopFieldLn2V = ppxlcNewLeftV,
  433.                         *ppxlcDstBotFieldLn1V = ppxlcLeftTopV + width,
  434.                         *ppxlcDstBotFieldLn2V = ppxlcNewLeftV + width;
  435.                 for (y = 0; y < EXPANDUV_REFVOP/2; y++) {
  436.                         memcpy (ppxlcDstTopFieldLn1U, ppxlcSrcTopFieldLn1U, iPadArea);
  437.                         memcpy (ppxlcDstTopFieldLn2U, ppxlcSrcTopFieldLn2U, iPadArea);
  438.                         memcpy (ppxlcDstBotFieldLn1U, ppxlcSrcBotFieldLn1U, iPadArea);
  439.                         memcpy (ppxlcDstBotFieldLn2U, ppxlcSrcBotFieldLn2U, iPadArea);
  440.                         memcpy (ppxlcDstTopFieldLn1V, ppxlcSrcTopFieldLn1V, iPadArea);
  441.                         memcpy (ppxlcDstTopFieldLn2V, ppxlcSrcTopFieldLn2V, iPadArea);
  442.                         memcpy (ppxlcDstBotFieldLn1V, ppxlcSrcBotFieldLn1V, iPadArea);
  443.                         memcpy (ppxlcDstBotFieldLn2V, ppxlcSrcBotFieldLn2V, iPadArea);
  444.                         ppxlcDstTopFieldLn1U += iFieldSkip;
  445.                         ppxlcDstTopFieldLn2U += iFieldSkip;
  446.                         ppxlcDstBotFieldLn1U += iFieldSkip;
  447.                         ppxlcDstBotFieldLn2U += iFieldSkip;
  448.                         ppxlcDstTopFieldLn1V += iFieldSkip;
  449.                         ppxlcDstTopFieldLn2V += iFieldSkip;
  450.                         ppxlcDstBotFieldLn1V += iFieldSkip;
  451.                         ppxlcDstBotFieldLn2V += iFieldSkip;
  452.                 }
  453.                 return;
  454.         }
  455. // End of Hyundai(1998-5-9)
  456. */
  457. const PixelC* ppxlcOldBotLnU = ppxlcNewLeftU - pvopcRef->whereUV ().width;
  458. const PixelC* ppxlcOldBotLnV = ppxlcNewLeftV - pvopcRef->whereUV ().width;
  459. for (y = 0; y < EXPANDUV_REFVOP; y++) {
  460. memcpy (ppxlcLeftTopU, ppxlcOldTopLnU, (m_rctPrevNoExpandUV.width + 2 * EXPANDUV_REFVOP)*sizeof(PixelC));
  461. memcpy (ppxlcLeftTopV, ppxlcOldTopLnV, (m_rctPrevNoExpandUV.width + 2 * EXPANDUV_REFVOP)*sizeof(PixelC));
  462. memcpy (ppxlcNewLeftU, ppxlcOldBotLnU, (m_rctPrevNoExpandUV.width + 2 * EXPANDUV_REFVOP)*sizeof(PixelC));
  463. memcpy (ppxlcNewLeftV, ppxlcOldBotLnV, (m_rctPrevNoExpandUV.width + 2 * EXPANDUV_REFVOP)*sizeof(PixelC));
  464. ppxlcNewLeftU += pvopcRef->whereUV ().width;
  465. ppxlcNewLeftV += pvopcRef->whereUV ().width;
  466. ppxlcLeftTopU += pvopcRef->whereUV ().width;
  467. ppxlcLeftTopV += pvopcRef->whereUV ().width;
  468. }
  469. }
  470. Void CVideoObject::saveShapeMode()
  471. {
  472. // called after reference frame encode/decode
  473. if(m_rgshpmd == NULL)
  474. {
  475. // first time
  476. m_iRefShpNumMBX = m_iNumMBX;
  477. m_iRefShpNumMBY = m_iNumMBY;
  478. m_rgshpmd = new ShapeMode [m_iNumMB];
  479. }
  480. else
  481. {
  482. // update if changed
  483. if(m_iRefShpNumMBX!=m_iNumMBXRef || m_iRefShpNumMBY != m_iNumMBYRef)
  484. {
  485. delete [] m_rgshpmd;
  486. m_rgshpmd = new ShapeMode [m_iNumMBRef];
  487. m_iRefShpNumMBX = m_iNumMBXRef;
  488. m_iRefShpNumMBY = m_iNumMBYRef;
  489. }
  490. // copy shape mode from previous ref to save
  491. Int i;
  492. for (i=0; i<m_iNumMBRef; i++ )
  493. m_rgshpmd[i] = m_rgmbmdRef[i].m_shpmd;
  494. }
  495. }
  496. Void CVideoObject::resetBYPlane ()
  497. {
  498. if (m_vopmd.vopPredType == PVOP || m_vopmd.vopPredType == IVOP) {
  499. PixelC* ppxlcBY = (PixelC*) m_pvopcRefQ1->pixelsBY ();
  500. memset (ppxlcBY, 0, m_pvopcRefQ1->whereY().area() * sizeof(PixelC));
  501. }
  502. else {
  503. PixelC* ppxlcBY = (PixelC*) m_pvopcCurrQ->pixelsBY ();
  504. memset (ppxlcBY, 0, m_pvopcCurrQ->whereY().area() * sizeof(PixelC));
  505. }
  506. }
  507. Void CVideoObject::updateAllRefVOPs ()
  508. // perform this after VOP prediction type decided and before encoding
  509. {
  510. if (m_vopmd.vopPredType != BVOP) {
  511. m_rctRefVOPY0 = m_rctRefVOPY1;
  512. swapVOPU8Pointers (m_pvopcRefQ0, m_pvopcRefQ1);
  513. }
  514. }
  515. // for spatial scalability
  516. Void CVideoObject::updateAllRefVOPs (const CVOPU8YUVBA* pvopcRefBaseLayer)
  517. {
  518. CVOPU8YUVBA *pvopcUpSampled = NULL;
  519. // Int fEnhancementLayer = 0;
  520. assert (m_volmd.volType == ENHN_LAYER);
  521. pvopcUpSampled = pvopcRefBaseLayer->upsampleForSpatialScalability (
  522. m_volmd.iver_sampling_factor_m,
  523. m_volmd.iver_sampling_factor_n,
  524. m_volmd.ihor_sampling_factor_m,
  525. m_volmd.ihor_sampling_factor_n,
  526. EXPANDY_REF_FRAME,
  527. EXPANDUV_REF_FRAME);
  528. if(m_vopmd.vopPredType == PVOP) {
  529. m_rctRefVOPY0 = m_rctRefVOPY1;
  530. swapVOPU8Pointers (m_pvopcRefQ0,pvopcUpSampled);
  531. m_pvopcRefQ0->setBoundRct(m_rctRefVOPY0);
  532. delete pvopcUpSampled;
  533. }
  534. else if(m_vopmd.vopPredType == BVOP){
  535. CRct tmp;
  536. tmp = m_rctRefVOPY0;
  537. m_rctRefVOPY0 = m_rctRefVOPY1;
  538. m_rctRefVOPY1 = tmp;
  539. swapVOPU8Pointers (m_pvopcRefQ0,m_pvopcRefQ1);
  540. swapVOPU8Pointers (m_pvopcRefQ1,pvopcUpSampled);
  541. m_pvopcRefQ0->setBoundRct(m_rctRefVOPY0);
  542. m_pvopcRefQ1->setBoundRct(m_rctRefVOPY1);
  543. delete pvopcUpSampled;
  544. }
  545. }
  546. Void CVideoObject::swapVOPU8Pointers (CVOPU8YUVBA*& pvopc0, CVOPU8YUVBA*& pvopc1)
  547. {
  548. CVOPU8YUVBA* pvopcTmp = pvopc0;
  549. pvopc0 = pvopc1;
  550. pvopc1 = pvopcTmp;
  551. }
  552. Void CVideoObject::swapVOPIntPointers (CVOPIntYUVBA*& pvopi0, CVOPIntYUVBA*& pvopi1)
  553. {
  554. CVOPIntYUVBA* pvopiTmp = pvopi0;
  555. pvopi0 = pvopi1;
  556. pvopi1 = pvopiTmp;
  557. }
  558. Void CVideoObject::setRefStartingPointers ()
  559. {
  560. m_iStartInRefToCurrRctY = m_rctRefFrameY.offset (m_rctCurrVOPY.left, m_rctCurrVOPY.top);
  561. m_iStartInRefToCurrRctUV = m_rctRefFrameUV.offset (m_rctCurrVOPUV.left, m_rctCurrVOPUV.top);
  562. }
  563. const CVOPU8YUVBA* CVideoObject::pvopcReconCurr () const
  564. {
  565. if (m_vopmd.vopPredType == SPRITE && m_iNumOfPnts > 0)
  566. return m_pvopcCurrQ;
  567. else if (m_vopmd.vopPredType == SPRITE && m_iNumOfPnts == 0) {
  568. if (m_sptMode != BASIC_SPRITE) 
  569. return m_pvopcSptQ;
  570. else 
  571. return m_pvopcRefQ1;
  572. }
  573. else if ((m_vopmd.vopPredType == BVOP && m_volmd.volType == BASE_LAYER) 
  574.  ||(m_vopmd.vopPredType == BVOP && m_vopmd.iRefSelectCode != 0))
  575. return m_pvopcCurrQ;
  576. else
  577. return m_pvopcRefQ1;
  578. }
  579. ////////// 97/12/22 start
  580. Void CVideoObject::compute_bfShapeMembers ()
  581. {
  582. m_iVOPWidthY = m_rctCurrVOPY.width;
  583. m_iVOPWidthUV = m_rctCurrVOPUV.width;
  584. m_iNumMBX = m_iVOPWidthY / MB_SIZE; 
  585. m_iNumMBY = m_rctCurrVOPY.height () / MB_SIZE;
  586. m_iNumMB = m_iNumMBX * m_iNumMBY;
  587. // m_iNumOfTotalMVPerRow = 5 * m_iNumMBX;
  588. //  wchen: changed to const as discussed with Bob.
  589. m_iNumOfTotalMVPerRow = PVOP_MV_PER_REF_PER_MB * m_iNumMBX;
  590. }
  591. Void CVideoObject::copyVOPU8YUVBA(CVOPU8YUVBA*& pvopc0, CVOPU8YUVBA*& pvopc1)
  592. {
  593. delete pvopc0;  pvopc0 = NULL;
  594. pvopc0 = new CVOPU8YUVBA (*pvopc1); /* i.e. pvopc0 = pvopc1; */
  595. }
  596. Void CVideoObject::copyVOPU8YUVBA(CVOPU8YUVBA*& pvopc0, CVOPU8YUVBA*& pvopc1, CVOPU8YUVBA*& pvopc2)
  597. {
  598. delete pvopc0;  pvopc0 = NULL;
  599. pvopc0 = (pvopc1 != NULL) ?
  600. new CVOPU8YUVBA (*pvopc1) : new CVOPU8YUVBA (*pvopc2);
  601. }
  602. ///// 97/12/22 end
  603. Void dumpNonCodedFrame(FILE* pfYUV, FILE* pfSeg, CRct& rct, UInt nBits)
  604. {
  605. Int iW = rct.width;
  606. Int iH = rct.height();
  607. Int i;
  608. PixelC pxlcVal = 1<<(nBits-1);
  609. PixelC *ppxlcPix = new PixelC [iW];
  610. pxlcmemset(ppxlcPix, pxlcVal, iW);
  611. for(i=0; i<iH; i++) // Y
  612. fwrite(ppxlcPix, sizeof(PixelC), iW, pfYUV);
  613. for(i=0; i<iH; i++) // UV
  614. fwrite(ppxlcPix, sizeof(PixelC), iW>>1, pfYUV);
  615. if(pfSeg!=NULL)
  616. {
  617. pxlcmemset(ppxlcPix, 0, iW);
  618. for(i=0; i<iH; i++) // A
  619. fwrite(ppxlcPix, sizeof(PixelC), iW, pfSeg);
  620. }
  621. delete ppxlcPix;
  622. }
  623. /*BBM// Added for Boundary by Hyundai(1998-5-9)
  624. Void CVideoObject::boundaryMacroBlockMerge (CMBMode* pmbmd)
  625. {
  626.         if ((pmbmd->m_rgTranspStatus[1] & pmbmd->m_rgTranspStatus[2]) == PARTIAL) {
  627.                 pmbmd->m_bMerged[1] = checkMergedStatus (7, 8, 7, 0);
  628.                 if (pmbmd->m_bMerged[1]) {
  629.                         pmbmd->m_rgTranspStatusBBM[2] = ALL;
  630.                         overlayBlocks (7, 8, 7, 0, pmbmd->m_dctMd);
  631.                 }
  632.         }
  633.         if ((pmbmd->m_rgTranspStatus[3] & pmbmd->m_rgTranspStatus[4]) == PARTIAL) {
  634.                 pmbmd->m_bMerged[2] = checkMergedStatus (7, 8, 15, 8);
  635.                 if (pmbmd->m_bMerged[2]) {
  636.                         pmbmd->m_rgTranspStatusBBM[4] = ALL;
  637.                         overlayBlocks (7, 8, 15, 8, pmbmd->m_dctMd);
  638.                 }
  639.         }
  640.         if (pmbmd->m_bMerged[1] | pmbmd->m_bMerged[2]) goto MERGE;
  641.         else {
  642.                 if ((pmbmd->m_rgTranspStatus[1] & pmbmd->m_rgTranspStatus[3]) == PARTIAL) {
  643.                         pmbmd->m_bMerged[3] = checkMergedStatus (7, 0, 7, 8);
  644.                         if (pmbmd->m_bMerged[3]) {
  645.                                 pmbmd->m_rgTranspStatusBBM[3] = ALL;
  646.                                 overlayBlocks (7, 0, 7, 8, pmbmd->m_dctMd);
  647.                         }
  648.                 }
  649.                 if ((pmbmd->m_rgTranspStatus[2] & pmbmd->m_rgTranspStatus[4]) == PARTIAL) {
  650.                         pmbmd->m_bMerged[4] = checkMergedStatus (15, 8, 7, 8);
  651.                         if (pmbmd->m_bMerged[4]) {
  652.                                 pmbmd->m_rgTranspStatusBBM[4] = ALL;
  653.                                 overlayBlocks (15, 8, 7, 8, pmbmd->m_dctMd);
  654.                         }
  655.                 }
  656.                 if (pmbmd->m_bMerged[3] | pmbmd->m_bMerged[4]) goto MERGE;
  657.                 else {
  658.                         if ((pmbmd->m_rgTranspStatus[1] & pmbmd->m_rgTranspStatus[4]) == PARTIAL) {
  659.                                 pmbmd->m_bMerged[5] = checkMergedStatus (7, 8, 7, 8);
  660.                                 if (pmbmd->m_bMerged[5]) {
  661.                                         pmbmd->m_rgTranspStatusBBM[4] = ALL;
  662.                                         overlayBlocks (7, 8, 7, 8, pmbmd->m_dctMd);
  663.                                 }
  664.                         }
  665.                         if ((pmbmd->m_rgTranspStatus[2] & pmbmd->m_rgTranspStatus[3]) == PARTIAL) {
  666.                                 pmbmd->m_bMerged[6] = checkMergedStatus (15, 0, 7, 8);
  667.                                 if (pmbmd->m_bMerged[6]) {
  668.                                         pmbmd->m_rgTranspStatusBBM[3] = ALL;
  669.                                         overlayBlocks (15, 0, 7, 8, pmbmd->m_dctMd);
  670.                                 }
  671.                         }
  672.                 }
  673.         }
  674. MERGE:
  675.         for (UInt x=1; x<7; x++)
  676.                 pmbmd->m_bMerged[0] |= pmbmd->m_bMerged[x];
  677.         if (pmbmd->m_bMerged[0])
  678.                 swapTransparentModes (pmbmd, BBM);
  679. }
  680. Void CVideoObject::isBoundaryMacroBlockMerged (CMBMode* pmbmd)
  681. {
  682.         if ((pmbmd->m_rgTranspStatus[1] & pmbmd->m_rgTranspStatus[2]) == PARTIAL) {
  683.                 pmbmd->m_bMerged[1] = checkMergedStatus (7, 8, 7, 0);
  684.                 if (pmbmd->m_bMerged[1])
  685.                         pmbmd->m_rgTranspStatusBBM[2] = ALL;
  686.         }
  687.         if ((pmbmd->m_rgTranspStatus[3] & pmbmd->m_rgTranspStatus[4]) == PARTIAL) {
  688.                 pmbmd->m_bMerged[2] = checkMergedStatus (7, 8, 15, 8);
  689.                 if (pmbmd->m_bMerged[2])
  690.                         pmbmd->m_rgTranspStatusBBM[4] = ALL;
  691.         }
  692.         if (pmbmd->m_bMerged[1] | pmbmd->m_bMerged[2]) goto MERGE;
  693.         else {
  694.                 if ((pmbmd->m_rgTranspStatus[1] & pmbmd->m_rgTranspStatus[3]) == PARTIAL) {
  695.                         pmbmd->m_bMerged[3] = checkMergedStatus (7, 0, 7, 8);
  696.                         if (pmbmd->m_bMerged[3])
  697.                                 pmbmd->m_rgTranspStatusBBM[3] = ALL;
  698.                 }
  699.                 if ((pmbmd->m_rgTranspStatus[2] & pmbmd->m_rgTranspStatus[4]) == PARTIAL) {
  700.                         pmbmd->m_bMerged[4] = checkMergedStatus (15, 8, 7, 8);
  701.                         if (pmbmd->m_bMerged[4])
  702.                                 pmbmd->m_rgTranspStatusBBM[4] = ALL;
  703.                 }
  704.                 if (pmbmd->m_bMerged[3] | pmbmd->m_bMerged[4]) goto MERGE;
  705.                 else {
  706.                         if ((pmbmd->m_rgTranspStatus[1] & pmbmd->m_rgTranspStatus[4]) == PARTIAL) {
  707.                                 pmbmd->m_bMerged[5] = checkMergedStatus (7, 8, 7, 8);
  708.                                 if (pmbmd->m_bMerged[5])
  709.                                         pmbmd->m_rgTranspStatusBBM[4] = ALL;
  710.                         }
  711.                         if ((pmbmd->m_rgTranspStatus[2] & pmbmd->m_rgTranspStatus[3]) == PARTIAL) {
  712.                                 pmbmd->m_bMerged[6] = checkMergedStatus (15, 0, 7, 8);
  713.                                 if (pmbmd->m_bMerged[6])
  714.                                         pmbmd->m_rgTranspStatusBBM[3] = ALL;
  715.                         }
  716.                 }
  717.         }
  718. MERGE:
  719.         for (UInt x=1; x<7; x++)
  720.                 pmbmd->m_bMerged[0] |= pmbmd->m_bMerged[x];
  721.         if (pmbmd->m_bMerged[0])
  722.                 swapTransparentModes (pmbmd, BBM);
  723. }
  724. Void CVideoObject::isBoundaryMacroBlockMerged (CMBMode* pmbmd, PixelC* ppxlcBY)
  725. {
  726.         if ((pmbmd->m_rgTranspStatus[1] & pmbmd->m_rgTranspStatus[2]) == PARTIAL) {
  727.                 pmbmd->m_bMerged[1] = checkMergedStatus (7, 8, 7, 0, ppxlcBY);
  728.                 if (pmbmd->m_bMerged[1])
  729.                         pmbmd->m_rgTranspStatusBBM[2] = ALL;
  730.         }
  731.         if ((pmbmd->m_rgTranspStatus[3] & pmbmd->m_rgTranspStatus[4]) == PARTIAL) {
  732.                 pmbmd->m_bMerged[2] = checkMergedStatus (7, 8, 15, 8, ppxlcBY);
  733.                 if (pmbmd->m_bMerged[2])
  734.                         pmbmd->m_rgTranspStatusBBM[4] = ALL;
  735.         }
  736.         if (pmbmd->m_bMerged[1] | pmbmd->m_bMerged[2]) goto MERGE;
  737.         else {
  738.                 if ((pmbmd->m_rgTranspStatus[1] & pmbmd->m_rgTranspStatus[3]) == PARTIAL) {
  739.                         pmbmd->m_bMerged[3] = checkMergedStatus (7, 0, 7, 8, ppxlcBY);
  740.                         if (pmbmd->m_bMerged[3])
  741.                                 pmbmd->m_rgTranspStatusBBM[3] = ALL;
  742.                 }
  743.                 if ((pmbmd->m_rgTranspStatus[2] & pmbmd->m_rgTranspStatus[4]) == PARTIAL) {
  744.                         pmbmd->m_bMerged[4] = checkMergedStatus (15, 8, 7, 8, ppxlcBY);
  745.                         if (pmbmd->m_bMerged[4])
  746.                                 pmbmd->m_rgTranspStatusBBM[4] = ALL;
  747.                 }
  748.                 if (pmbmd->m_bMerged[3] | pmbmd->m_bMerged[4]) goto MERGE;
  749.                 else {
  750.                         if ((pmbmd->m_rgTranspStatus[1] & pmbmd->m_rgTranspStatus[4]) == PARTIAL) {
  751.                                 pmbmd->m_bMerged[5] = checkMergedStatus (7, 8, 7, 8, ppxlcBY);
  752.                                 if (pmbmd->m_bMerged[5])
  753.                                         pmbmd->m_rgTranspStatusBBM[4] = ALL;
  754.                         }
  755.                         if ((pmbmd->m_rgTranspStatus[2] & pmbmd->m_rgTranspStatus[3]) == PARTIAL) {
  756.                                 pmbmd->m_bMerged[6] = checkMergedStatus (15, 0, 7, 8, ppxlcBY);
  757.                                 if (pmbmd->m_bMerged[6])
  758.                                         pmbmd->m_rgTranspStatusBBM[3] = ALL;
  759.                         }
  760.                 }
  761.         }
  762. MERGE: 
  763.         for (UInt x=1; x<7; x++)
  764.                 pmbmd->m_bMerged[0] |= pmbmd->m_bMerged[x];
  765.         if (pmbmd->m_bMerged[0])
  766.                 swapTransparentModes (pmbmd, BBM);
  767. }
  768. Void CVideoObject::overlayBlocks (UInt x1, UInt x2, UInt y1, UInt y2, DCTMode dctMd)
  769. {
  770.         UInt    pos1 = y1*MB_SIZE+x1,
  771.                 pos2 = y2*MB_SIZE+x2;
  772.         PixelC  *SB1 = m_ppxlcCurrMBBY+pos1,
  773.                 *SB2 = m_ppxlcCurrMBBY+pos2;
  774.  
  775.         if (dctMd == INTRA || dctMd == INTRAQ) {
  776.                 overlayBlocks (SB1, SB2, m_ppxlcCurrMBY+pos1, m_ppxlcCurrMBY+pos2);
  777.                 if (m_volmd.fAUsage == EIGHT_BIT)
  778.                         overlayBlocks (SB1, SB2, m_ppxlcCurrMBA+pos1, m_ppxlcCurrMBA+pos2);
  779.         }
  780.         else {
  781.                 overlayBlocks (SB2, m_ppxliErrorMBY+pos1, m_ppxliErrorMBY+pos2);
  782.                 if (m_volmd.fAUsage == EIGHT_BIT)
  783.                         overlayBlocks (SB2, m_ppxliErrorMBA+pos1, m_ppxliErrorMBA+pos2);
  784.         }
  785. }
  786. Void CVideoObject::overlayBlocks (PixelC* SB1, PixelC* SB2, PixelC* ppxlcB1, PixelC* ppxlcB2)
  787. {
  788.         UInt    x, y;
  789.         PixelC  *ppxlcS1, *ppxlcS2;
  790.  
  791.         for (y = 0, ppxlcS1 = SB1, ppxlcS2 = SB2; y < BLOCK_SIZE; y++) {
  792.                 for (x = 0; x < BLOCK_SIZE; x++, ppxlcS1--, ppxlcS2++, ppxlcB1--, ppxlcB2++)
  793.                         if (*ppxlcS2)
  794.                                 *ppxlcB1 = *ppxlcB2;
  795.                         else if (!*ppxlcS1) {
  796.                                 *ppxlcB1 += *ppxlcB2;
  797.                                 *ppxlcB1 >>= 1;
  798.                         }
  799.                 ppxlcS1 -= BLOCK_SIZE;
  800.                 ppxlcS2 += BLOCK_SIZE;
  801.                 ppxlcB1 -= BLOCK_SIZE;
  802.                 ppxlcB2 += BLOCK_SIZE;
  803.         }
  804. }
  805.  
  806. Void CVideoObject::overlayBlocks (PixelC* SB2, PixelI* ppxlcB1, PixelI* ppxlcB2)
  807. {
  808.         UInt    x, y;
  809.         PixelC  *ppxlcS2;
  810.  
  811.         for (y = 0, ppxlcS2 = SB2; y < BLOCK_SIZE; y++) {
  812.                 for (x = 0; x < BLOCK_SIZE; x++, ppxlcS2++, ppxlcB1--, ppxlcB2++)
  813.                         if (*ppxlcS2)
  814.                                 *ppxlcB1 = *ppxlcB2;
  815.                 ppxlcS2 += BLOCK_SIZE;
  816.                 ppxlcB1 -= BLOCK_SIZE;
  817.                 ppxlcB2 += BLOCK_SIZE;
  818.         }
  819. }
  820. Bool CVideoObject::checkMergedStatus (UInt x1, UInt x2, UInt y1, UInt y2)
  821. {
  822.         PixelC  *ppxlcS1 = m_ppxlcCurrMBBY + y1 * MB_SIZE + x1,
  823.                 *ppxlcS2 = m_ppxlcCurrMBBY + y2 * MB_SIZE + x2;
  824.  
  825.         for (UInt y = 0; y < BLOCK_SIZE; y++) {
  826.                 for (UInt x = 0; x < BLOCK_SIZE; x++, ppxlcS1--, ppxlcS2++)
  827.                         if (*ppxlcS1 && *ppxlcS2)
  828.                                 return FALSE;
  829.                 ppxlcS1 -= BLOCK_SIZE;
  830.                 ppxlcS2 += BLOCK_SIZE;
  831.         }
  832.         return TRUE;
  833. }
  834.  
  835. Bool CVideoObject::checkMergedStatus (UInt x1, UInt x2, UInt y1, UInt y2, PixelC* ppxlcBY)
  836. {
  837.         PixelC  *ppxlcS1 = ppxlcBY + y1 * MB_SIZE + x1,
  838.                 *ppxlcS2 = ppxlcBY + y2 * MB_SIZE + x2;
  839.  
  840.         for (UInt y = 0; y < BLOCK_SIZE; y++) {
  841.                 for (UInt x = 0; x < BLOCK_SIZE; x++, ppxlcS1--, ppxlcS2++)
  842.                         if (*ppxlcS1 && *ppxlcS2)
  843.                                 return FALSE;
  844.                 ppxlcS1 -= BLOCK_SIZE;
  845.                 ppxlcS2 += BLOCK_SIZE;
  846.         }
  847.         return TRUE;
  848. }
  849. Void CVideoObject::mergedMacroBlockSplit (CMBMode* pmbmd, PixelC* ppxlcRefMBY, PixelC* ppxlcRefMBA)
  850. {
  851.         Bool    isIntra = (pmbmd->m_dctMd==INTRA || pmbmd->m_dctMd==INTRAQ) ? TRUE : FALSE;
  852.  
  853.         swapTransparentModes (pmbmd, BBS);
  854.         if (pmbmd->m_bMerged[1])
  855.                 if (isIntra)
  856.                         splitTwoMergedBlocks (7, 8, 7, 0, ppxlcRefMBY, ppxlcRefMBA);
  857.                 else    splitTwoMergedBlocks (7, 8, 7, 0, m_ppxliErrorMBY, m_ppxliErrorMBA);
  858.         if (pmbmd->m_bMerged[2])
  859.                 if (isIntra)
  860.                         splitTwoMergedBlocks (7, 8, 15, 8, ppxlcRefMBY, ppxlcRefMBA);
  861.                 else    splitTwoMergedBlocks (7, 8, 15, 8, m_ppxliErrorMBY, m_ppxliErrorMBA);
  862.         if (pmbmd->m_bMerged[1] || pmbmd->m_bMerged[2]) goto SPLIT;
  863.         else {
  864.                 if (pmbmd->m_bMerged[3])
  865.                         if (isIntra)
  866.                                 splitTwoMergedBlocks (7, 0, 7, 8, ppxlcRefMBY, ppxlcRefMBA);
  867.                         else    splitTwoMergedBlocks (7, 0, 7, 8, m_ppxliErrorMBY, m_ppxliErrorMBA);
  868.                 if (pmbmd->m_bMerged[4])
  869.                         if (isIntra)
  870.                                 splitTwoMergedBlocks (15, 8, 7, 8, ppxlcRefMBY, ppxlcRefMBA);
  871.                         else    splitTwoMergedBlocks (15, 8, 7, 8, m_ppxliErrorMBY, m_ppxliErrorMBA);
  872.                 if (pmbmd->m_bMerged[3] || pmbmd->m_bMerged[4]) goto SPLIT;
  873.                 else {
  874.                         if (pmbmd->m_bMerged[5])
  875.                                 if (isIntra)
  876.                                         splitTwoMergedBlocks (7, 8, 7, 8, ppxlcRefMBY, ppxlcRefMBA);
  877.                                 else    splitTwoMergedBlocks (7, 8, 7, 8, m_ppxliErrorMBY, m_ppxliErrorMBA);
  878.                         if (pmbmd->m_bMerged[6])
  879.                                 if (isIntra)
  880.                                         splitTwoMergedBlocks(15, 0, 7, 8, ppxlcRefMBY, ppxlcRefMBA);
  881.                                 else    splitTwoMergedBlocks (15, 0, 7, 8, m_ppxliErrorMBY, m_ppxliErrorMBA);
  882.                 }
  883.         }
  884. SPLIT:
  885.         return;
  886. }
  887. Void CVideoObject::splitTwoMergedBlocks (UInt x1, UInt x2, UInt y1, UInt y2, PixelC* ppxlcIn1, PixelC* ppxlcIn2)
  888. {
  889.         UInt    SKIP = m_iFrameWidthY - BLOCK_SIZE,
  890.                 pos1 = y1 * m_iFrameWidthY + x1,
  891.                 pos2 = y2 * m_iFrameWidthY + x2,
  892.                 pos3 = y2 * MB_SIZE + x2;
  893.         PixelC  *ppxlcS2, *ppxlcB1, *ppxlcB2;
  894.  
  895.         ppxlcB1 = ppxlcIn1 + pos1;
  896.         ppxlcB2 = ppxlcIn1 + pos2;
  897.         ppxlcS2 = m_ppxlcCurrMBBY + pos3;
  898.         for (UInt y = 0; y < BLOCK_SIZE; y++) {
  899.                 for (UInt x = 0; x < BLOCK_SIZE; x++, ppxlcS2++, ppxlcB1--, ppxlcB2++)
  900.                         if (*ppxlcS2)
  901.                                 *ppxlcB2 = *ppxlcB1;
  902.                 ppxlcS2 += BLOCK_SIZE;
  903.                 ppxlcB1 -= SKIP;
  904.                 ppxlcB2 += SKIP;
  905.         }
  906.         if (m_volmd.fAUsage == EIGHT_BIT) {
  907.                 ppxlcB1 = ppxlcIn2 + pos1;
  908.                 ppxlcB2 = ppxlcIn2 + pos2;
  909.                 ppxlcS2 = m_ppxlcCurrMBBY + pos3;
  910.                 for (UInt y = 0; y < BLOCK_SIZE; y++) {
  911.                         for (UInt x = 0; x < BLOCK_SIZE; x++, ppxlcS2++, ppxlcB1--, ppxlcB2++)
  912.                                 if (*ppxlcS2)
  913.                                         *ppxlcB2 = *ppxlcB1;
  914.                         ppxlcS2 += BLOCK_SIZE;
  915.                         ppxlcB1 -= SKIP;
  916.                         ppxlcB2 += SKIP;
  917.                 }
  918.         }
  919. }
  920. Void CVideoObject::splitTwoMergedBlocks (UInt x1, UInt x2, UInt y1, UInt y2, PixelI* ppxlcIn1, PixelI* ppxlcIn2)
  921. {
  922.         UInt    pos1 = y1 * MB_SIZE + x1,
  923.                 pos2 = y2 * MB_SIZE + x2;
  924.         PixelC  *ppxlcS2;
  925.         PixelI  *ppxlcB1, *ppxlcB2;
  926.  
  927.         ppxlcB1 = ppxlcIn1 + pos1;
  928.         ppxlcB2 = ppxlcIn1 + pos2;
  929.         ppxlcS2 = m_ppxlcCurrMBBY + pos2;
  930.         for (UInt y = 0; y < BLOCK_SIZE; y++) {
  931.                 for (UInt x = 0; x < BLOCK_SIZE; x++, ppxlcS2++, ppxlcB1--, ppxlcB2++)
  932.                         if (*ppxlcS2)
  933.                                 *ppxlcB2 = *ppxlcB1;
  934.                 ppxlcS2 += BLOCK_SIZE;
  935.                 ppxlcB1 -= BLOCK_SIZE;
  936.                 ppxlcB2 += BLOCK_SIZE;
  937.         }
  938.         if (m_volmd.fAUsage == EIGHT_BIT) {
  939.                 ppxlcB1 = ppxlcIn2 + pos1;
  940.                 ppxlcB2 = ppxlcIn2 + pos2;
  941.                 ppxlcS2 = m_ppxlcCurrMBBY + pos2;
  942.                 for (UInt y = 0; y < BLOCK_SIZE; y++) {
  943.                         for (UInt x = 0; x < BLOCK_SIZE; x++, ppxlcS2++, ppxlcB1--, ppxlcB2++)
  944.                                 if (*ppxlcS2)
  945.                                         *ppxlcB2 = *ppxlcB1;
  946.                         ppxlcS2 += BLOCK_SIZE;
  947.                         ppxlcB1 -= BLOCK_SIZE;
  948.                         ppxlcB2 += BLOCK_SIZE;
  949.                 }
  950.         }
  951. }
  952.  
  953. Void CVideoObject::swapTransparentModes (CMBMode* pmbmd, Bool mode) {
  954.         TransparentStatus rgTranspStatusTmp[5];
  955.         memcpy (rgTranspStatusTmp, pmbmd->m_rgTranspStatusBBM, 5*sizeof(TransparentStatus));
  956.         memcpy (pmbmd->m_rgTranspStatusBBM, pmbmd->m_rgTranspStatus, 5*sizeof(TransparentStatus));
  957.         memcpy (pmbmd->m_rgTranspStatus, rgTranspStatusTmp, 5*sizeof(TransparentStatus));
  958. }
  959.  
  960. Void CVideoObject::setMergedTransparentModes (CMBMode* pmbmd) {
  961.         memcpy (pmbmd->m_rgTranspStatusBBM, pmbmd->m_rgTranspStatus, 11*sizeof(TransparentStatus));
  962. }
  963.  
  964. Void CVideoObject::initMergedMode (CMBMode* pmbmd) {
  965.         setMergedTransparentModes (pmbmd);
  966.         memset (pmbmd->m_bMerged, FALSE, 7*sizeof (Bool));
  967. }
  968. // End of Hyundai(1998-5-9)*/