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

流媒体/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. 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. and also edited by
  10. Yoshihiro Kikuchi (TOSHIBA CORPORATION)
  11. Takeshi Nagai (TOSHIBA CORPORATION)
  12. Toshiaki Watanabe (TOSHIBA CORPORATION)
  13. Noboru Yamaguchi (TOSHIBA CORPORATION)
  14. in the course of development of the MPEG-4 Video (ISO/IEC 14496-2). 
  15. This software module is an implementation of a part of one or more MPEG-4 Video tools 
  16. as specified by the MPEG-4 Video. 
  17. ISO/IEC gives users of the MPEG-4 Video free license to this software module or modifications 
  18. thereof for use in hardware or software products claiming conformance to the MPEG-4 Video. 
  19. Those intending to use this software module in hardware or software products are advised that its use may infringe existing patents. 
  20. The original developer of this software module and his/her company, 
  21. the subsequent editors and their companies, 
  22. and ISO/IEC have no liability for use of this software module or modifications thereof in an implementation. 
  23. Copyright is not released for non MPEG-4 Video conforming products. 
  24. Microsoft retains full right to use the code for his/her own purpose, 
  25. assign or donate the code to a third party and to inhibit third parties from using the code for non <MPEG standard> conforming products. 
  26. This copyright notice must be included in all copies or derivative works. 
  27. Copyright (c) 1996, 1997.
  28. Module Name:
  29. MBenc.cpp
  30. Abstract:
  31. MacroBlock encoder
  32. Revision History:
  33. This software module was edited by
  34. Hiroyuki Katata (katata@imgsl.mkhar.sharp.co.jp), Sharp Corporation
  35. Norio Ito (norio@imgsl.mkhar.sharp.co.jp), Sharp Corporation
  36. Shuichi Watanabe (watanabe@imgsl.mkhar.sharp.co.jp), Sharp Corporation
  37. (date: October, 1997)
  38. for object based temporal scalability.
  39. Dec 20, 1997: Interlaced tools added by NextLevel Systems X.Chen, B. Eifrig
  40.         May. 9   1998:  add boundary by Hyundai Electronics 
  41.                                   Cheol-Soo Park (cspark@super5.hyundai.co.kr) 
  42. May 9, 1999: tm5 rate control by DemoGraFX, duhoff@mediaone.net
  43. NOTE:
  44. m_pvopfCurrQ holds the original data until it is texture quantized
  45. *************************************************************************/
  46. #include <stdlib.h>
  47. #include <math.h>
  48. #include <iostream.h>
  49. #include "typeapi.h"
  50. #include "codehead.h"
  51. #include "mode.hpp"
  52. #include "global.hpp"
  53. #include "entropy/bitstrm.hpp"
  54. #include "entropy/entropy.hpp"
  55. #include "entropy/huffman.hpp"
  56. #include "vopses.hpp"
  57. #include "vopseenc.hpp"
  58. #ifdef __MFC_
  59. #ifdef _DEBUG
  60. #undef THIS_FILE
  61. static char BASED_CODE THIS_FILE[] = __FILE__;
  62. #endif
  63. #define new DEBUG_NEW    
  64. #endif // __MFC_
  65. /*Void CVideoObjectEncoder::encodePVOPMBWithShape (
  66. PixelC* ppxlcRefMBY, PixelC* ppxlcRefMBU, PixelC* ppxlcRefMBV,
  67. PixelC* ppxlcRefMBA, PixelC* ppxlcRefBY,
  68. CMBMode* pmbmd, const CMotionVector* pmv, CMotionVector* pmvBY,
  69. ShapeMode shpmdColocatedMB,
  70. Int imbX, Int imbY,
  71. CoordI x, CoordI y, Int& iQPPrev)
  72. {
  73. encodePVOPMBJustShape(ppxlcRefBY,pmbmd,shpmdColocatedMB,pmv,pmvBY,x,y,imbX,imbY);
  74. dumpCachedShapeBits();
  75. encodePVOPMBTextureWithShape(ppxlcRefMBY,ppxlcRefMBU,ppxlcRefMBV,ppxlcRefMBA,pmbmd,
  76. pmv,imbX,imbY,x,y,iQPPrev);
  77. }*/
  78. Void CVideoObjectEncoder::encodePVOPMBJustShape(
  79. PixelC* ppxlcRefBY, CMBMode* pmbmd, ShapeMode shpmdColocatedMB,
  80. const CMotionVector* pmv, CMotionVector* pmvBY,
  81. CoordI x, CoordI y, Int imbX, Int imbY)
  82. {
  83. m_statsMB.nBitsShape += codeInterShape (
  84. ppxlcRefBY, m_pvopcRefQ0, pmbmd, shpmdColocatedMB,
  85. pmv, pmvBY, x, y, imbX, imbY
  86. );
  87. // change pmbmd to inter if all transparent
  88. decideTransparencyStatus (pmbmd, m_ppxlcCurrMBBY);
  89. }
  90. Void CVideoObjectEncoder::dumpCachedShapeBits()
  91. {
  92. #ifdef __TRACE_AND_STATS_
  93. m_pbitstrmOut->trace("INSERTING PRE-ENCODED MB SHAPE STREAM HEREn");
  94. m_pbitstrmOut->trace(m_pbitstrmOut->getCounter(),"Location Before");
  95. #endif // __TRACE_AND_STATS_
  96. m_pbitstrmOut->putBitStream(*m_pbitstrmShapeMBOut);
  97. #ifdef __TRACE_AND_STATS_
  98. m_pbitstrmOut->trace(m_pbitstrmOut->getCounter(),"Location After");
  99. #endif // __TRACE_AND_STATS_
  100. m_pbitstrmShapeMBOut->flush();
  101. m_pbitstrmShapeMBOut->resetAll();
  102. }
  103. Void CVideoObjectEncoder::encodePVOPMBTextureWithShape(
  104. PixelC* ppxlcRefMBY, PixelC* ppxlcRefMBU, PixelC* ppxlcRefMBV,
  105. PixelC* ppxlcRefMBA, CMBMode* pmbmd, const CMotionVector* pmv,
  106. Int imbX, Int imbY, CoordI x, CoordI y, Int& iQPPrev,
  107. Int &iQPPrevAlpha, Bool &bUseNewQPForVlcThr)
  108. {
  109. // update quantiser
  110. pmbmd->m_stepSize = iQPPrev + pmbmd->m_intStepDelta;
  111. if(bUseNewQPForVlcThr)
  112. pmbmd->m_stepSizeDelayed = pmbmd->m_stepSize;
  113. else
  114. pmbmd->m_stepSizeDelayed = iQPPrev;
  115. iQPPrev = pmbmd->m_stepSize;
  116. if (pmbmd -> m_dctMd == INTRA || pmbmd -> m_dctMd == INTRAQ) {
  117. if(pmbmd -> m_rgTranspStatus [0] == PARTIAL)
  118. LPEPadding (pmbmd);
  119. if (m_volmd.fAUsage == EIGHT_BIT) {
  120. // update alpha quant
  121. if(!m_volmd.bNoGrayQuantUpdate)
  122. {
  123. iQPPrevAlpha = (iQPPrev * m_vopmd.intStepPAlpha) / m_vopmd.intStep;
  124. if(iQPPrevAlpha<1)
  125. iQPPrevAlpha=1;
  126. }
  127. pmbmd->m_stepSizeAlpha = iQPPrevAlpha;
  128. }
  129. assert (pmbmd -> m_rgTranspStatus [0] != ALL);
  130. /*BBM// Added for Boundary by Hyundai(1998-5-9)
  131.                 if (m_vopmd.bInterlace && pmbmd -> m_rgTranspStatus [0] == PARTIAL)
  132.                         boundaryMacroBlockMerge (pmbmd);
  133. // End of Hyundai(1998-5-9)*/
  134. quantizeTextureIntraMB (imbX, imbY, pmbmd, ppxlcRefMBY, ppxlcRefMBU, ppxlcRefMBV, ppxlcRefMBA);
  135. codeMBTextureHeadOfPVOP (pmbmd);
  136. sendDCTCoefOfIntraMBTexture (pmbmd);
  137. if (m_volmd.fAUsage == EIGHT_BIT) {
  138. codeMBAlphaHeadOfPVOP (pmbmd);
  139. sendDCTCoefOfIntraMBAlpha (pmbmd);
  140. }
  141. /*BBM// Added for Boundary by Hyundai(1998-5-9)
  142.                 if (m_vopmd.bInterlace && pmbmd -> m_bMerged[0])
  143.                         mergedMacroBlockSplit (pmbmd, ppxlcRefMBY, ppxlcRefMBA);
  144. // End of Hyundai(1998-5-9)*/
  145. bUseNewQPForVlcThr = FALSE;
  146. }
  147. else { // INTER or skipped
  148. if (m_volmd.fAUsage == EIGHT_BIT) {
  149. // update alpha quant
  150. if(!m_volmd.bNoGrayQuantUpdate)
  151. iQPPrevAlpha = (iQPPrev * m_vopmd.intStepPAlpha) / m_vopmd.intStep;
  152. pmbmd->m_stepSizeAlpha = iQPPrevAlpha;
  153. }
  154. if (pmbmd -> m_rgTranspStatus [0] == PARTIAL) {
  155. CoordI xRefUV, yRefUV;
  156. // INTERLACE
  157. // new changes 
  158. if(pmbmd->m_bFieldMV) {
  159. CoordI xRefUV1, yRefUV1;
  160. mvLookupUV (pmbmd, pmv, xRefUV, yRefUV, xRefUV1, yRefUV1);
  161. motionCompFieldUV(m_ppxlcPredMBU, m_ppxlcPredMBV,
  162. m_pvopcRefQ0, x, y, xRefUV, yRefUV, pmbmd->m_bForwardTop);
  163. motionCompFieldUV(m_ppxlcPredMBU + BLOCK_SIZE, m_ppxlcPredMBV + BLOCK_SIZE,
  164. m_pvopcRefQ0, x, y, xRefUV1, yRefUV1, pmbmd->m_bForwardBottom);
  165. }
  166. else {
  167. // ~INTERLACE
  168. mvLookupUVWithShape (pmbmd, pmv, xRefUV, yRefUV);
  169. motionCompUV (m_ppxlcPredMBU, m_ppxlcPredMBV, m_pvopcRefQ0, x, y,
  170. xRefUV, yRefUV, m_vopmd.iRoundingControl,&m_rctRefVOPY0);
  171. }
  172. motionCompMBYEnc (pmv, pmbmd, imbX, imbY, x, y, &m_rctRefVOPY0);
  173. computeTextureErrorWithShape ();
  174. }
  175. else {
  176. // not partial
  177. CoordI xRefUV, yRefUV, xRefUV1, yRefUV1;
  178. mvLookupUV (pmbmd, pmv, xRefUV, yRefUV, xRefUV1, yRefUV1);
  179. // INTERLACE
  180. // new changes 
  181. if(pmbmd->m_bFieldMV) {
  182. motionCompFieldUV(m_ppxlcPredMBU, m_ppxlcPredMBV,
  183. m_pvopcRefQ0, x, y, xRefUV, yRefUV, pmbmd->m_bForwardTop);
  184. motionCompFieldUV(m_ppxlcPredMBU + BLOCK_SIZE, m_ppxlcPredMBV + BLOCK_SIZE,
  185. m_pvopcRefQ0, x, y, xRefUV1, yRefUV1, pmbmd->m_bForwardBottom);
  186. }
  187. else {
  188. // ~INTERLACE
  189. motionCompUV (m_ppxlcPredMBU, m_ppxlcPredMBV, m_pvopcRefQ0, x, y,
  190. xRefUV, yRefUV, m_vopmd.iRoundingControl, &m_rctRefVOPY0);
  191. }
  192. motionCompMBYEnc (pmv, pmbmd, imbX, imbY, x, y, &m_rctRefVOPY0);
  193. computeTextureError ();
  194. }
  195. Bool bSkip = pmbmd->m_bhas4MVForward ? (pmv [1].isZero () && pmv [2].isZero () && pmv [3].isZero () && pmv [4].isZero ())
  196. : (!pmbmd->m_bFieldMV && pmv->isZero()) ;
  197. /*BBM// Added for Boundary by Hyundai(1998-5-9)
  198. if (m_vopmd.bInterlace && pmbmd -> m_rgTranspStatus [0] == PARTIAL)
  199.                         boundaryMacroBlockMerge (pmbmd);
  200. // End of Hyundai(1998-5-9)*/
  201. if(!m_volmd.bAllowSkippedPMBs)
  202. bSkip = FALSE;
  203. quantizeTextureInterMB (pmbmd, pmv, ppxlcRefMBA, bSkip); // decide COD here
  204. codeMBTextureHeadOfPVOP (pmbmd);
  205. if (!pmbmd -> m_bSkip) {
  206. /*BBM// Added for Boundary by Hyundai(1998-5-9)
  207.             if (m_vopmd.bInterlace && pmbmd -> m_bMerged[0])
  208.                     swapTransparentModes (pmbmd, BBS);
  209. // End of Hyundai(1998-5-9)*/
  210. m_statsMB.nBitsMV += encodeMVWithShape (pmv, pmbmd, imbX, imbY);
  211. /*BBM// Added for Boundary by Hyundai(1998-5-9)
  212. if (m_vopmd.bInterlace && pmbmd -> m_bMerged[0])
  213. swapTransparentModes (pmbmd, BBM);
  214. // End of Hyundai(1998-5-9)*/
  215. sendDCTCoefOfInterMBTexture (pmbmd);
  216. // addErrorAndPredToCurrQ (ppxlcRefMBY, ppxlcRefMBU, ppxlcRefMBV); // delete by Hyundai, ok swinder
  217. }
  218. else
  219. assignPredToCurrQ (ppxlcRefMBY, ppxlcRefMBU, ppxlcRefMBV);
  220. if (m_volmd.fAUsage == EIGHT_BIT) {
  221. codeMBAlphaHeadOfPVOP (pmbmd);
  222. if (pmbmd -> m_CODAlpha == ALPHA_CODED) {
  223. sendDCTCoefOfInterMBAlpha (pmbmd);
  224. // addAlphaErrorAndPredToCurrQ (ppxlcRefMBA); // delete by Hyundai. ok swinder
  225. }
  226. else if(pmbmd -> m_CODAlpha == ALPHA_SKIPPED)
  227. assignAlphaPredToCurrQ (ppxlcRefMBA);
  228. }
  229. /*BBM// Added for Boundary by Hyundai(1998-5-9)
  230.                 if (m_vopmd.bInterlace && pmbmd -> m_bMerged[0])
  231.                         mergedMacroBlockSplit (pmbmd);
  232. // End of Hyundai(1998-5-9)*/
  233.         if (!pmbmd -> m_bSkip)
  234. {
  235. bUseNewQPForVlcThr = FALSE;
  236.             addErrorAndPredToCurrQ (ppxlcRefMBY, ppxlcRefMBU, ppxlcRefMBV);
  237. }
  238.         if (m_volmd.fAUsage == EIGHT_BIT && pmbmd -> m_CODAlpha == ALPHA_CODED)
  239.             addAlphaErrorAndPredToCurrQ (ppxlcRefMBA);
  240. }
  241. }
  242. Void CVideoObjectEncoder::encodePVOPMB (
  243. PixelC* ppxlcRefMBY, PixelC* ppxlcRefMBU, PixelC* ppxlcRefMBV,
  244. CMBMode* pmbmd, const CMotionVector* pmv,
  245. Int iMBX, Int iMBY,
  246. CoordI x, CoordI y
  247. )
  248. {
  249. // For Sprite update macroblock there is no motion compensation 
  250. if (m_uiSprite == 1 && m_vopmd.SpriteXmitMode != STOP) {
  251. if ( m_bSptMB_NOT_HOLE ) {
  252. m_iNumSptMB++ ;      
  253. CopyCurrQToPred(ppxlcRefMBY, ppxlcRefMBU, ppxlcRefMBV);
  254. computeTextureError ();
  255. Bool bSkip = pmbmd->m_bhas4MVForward ? (pmv [1].isZero () && pmv [2].isZero () && pmv [3].isZero () && pmv [4].isZero ())
  256.  : pmv->isZero ();
  257. quantizeTextureInterMB (pmbmd, pmv, NULL, bSkip); // decide COD here
  258. codeMBTextureHeadOfPVOP (pmbmd);
  259. if (!pmbmd -> m_bSkip) {
  260. sendDCTCoefOfInterMBTexture (pmbmd);
  261. addErrorAndPredToCurrQ (ppxlcRefMBY, ppxlcRefMBU, ppxlcRefMBV);
  262. }
  263. }
  264. else {
  265. pmbmd -> m_bSkip = TRUE;
  266. codeMBTextureHeadOfPVOP (pmbmd);
  267. }
  268. return;
  269. }
  270. if (pmbmd->m_dctMd == INTRA || pmbmd->m_dctMd == INTRAQ) {
  271. pmbmd->m_bSkip = FALSE; //in case use by direct mode in the future
  272. quantizeTextureIntraMB (iMBX, iMBY, pmbmd, ppxlcRefMBY, ppxlcRefMBU, ppxlcRefMBV, NULL);
  273. codeMBTextureHeadOfPVOP (pmbmd);
  274. sendDCTCoefOfIntraMBTexture (pmbmd);
  275. }
  276. else {
  277. CoordI xRefUV, yRefUV, xRefUV1, yRefUV1;
  278. mvLookupUV (pmbmd, pmv, xRefUV, yRefUV, xRefUV1, yRefUV1);
  279. // INTERLACE
  280. // pmbmd->m_rgTranspStatus[0] = NONE; // This a rectangular VOP 
  281. if(pmbmd->m_bFieldMV) {
  282. motionCompFieldUV(m_ppxlcPredMBU, m_ppxlcPredMBV,
  283. m_pvopcRefQ0, x, y, xRefUV, yRefUV, pmbmd->m_bForwardTop);
  284. motionCompFieldUV(m_ppxlcPredMBU + BLOCK_SIZE, m_ppxlcPredMBV + BLOCK_SIZE,
  285. m_pvopcRefQ0, x, y, xRefUV1, yRefUV1, pmbmd->m_bForwardBottom);
  286. }
  287. else 
  288. // ~INTERLACE
  289. motionCompUV (m_ppxlcPredMBU, m_ppxlcPredMBV, m_pvopcRefQ0, x, y,
  290. xRefUV, yRefUV, m_vopmd.iRoundingControl,&m_rctRefVOPY0);
  291. motionCompMBYEnc (pmv, pmbmd, iMBX, iMBY, x, y, &m_rctRefVOPY0);
  292. computeTextureError ();
  293. Bool bSkip = pmbmd->m_bhas4MVForward ? (pmv [1].isZero () && pmv [2].isZero () && pmv [3].isZero () && pmv [4].isZero ())
  294.             : (!pmbmd->m_bFieldMV && pmv->isZero());
  295. if(!m_volmd.bAllowSkippedPMBs)
  296. bSkip = FALSE;
  297. quantizeTextureInterMB (pmbmd, pmv, NULL, bSkip); // decide COD here
  298. codeMBTextureHeadOfPVOP (pmbmd);
  299. if (!pmbmd -> m_bSkip) {
  300. if(!(m_volmd.volType == ENHN_LAYER && m_vopmd.iRefSelectCode == 3))
  301. m_statsMB.nBitsMV += encodeMVVP (pmv, pmbmd, iMBX, iMBY);
  302. sendDCTCoefOfInterMBTexture (pmbmd);
  303. addErrorAndPredToCurrQ (ppxlcRefMBY, ppxlcRefMBU, ppxlcRefMBV);
  304. }
  305. else {
  306. assignPredToCurrQ (ppxlcRefMBY, ppxlcRefMBU, ppxlcRefMBV);
  307. }
  308. }
  309. }
  310. Void CVideoObjectEncoder::encodeBVOPMB (
  311. PixelC* ppxlcCurrQMBY, PixelC* ppxlcCurrQMBU, PixelC* ppxlcCurrQMBV,
  312. CMBMode* pmbmd, const CMotionVector* pmv, const CMotionVector* pmvBackward,
  313. const CMBMode* pmbmdRef, const CMotionVector* pmvRef,
  314. Int iMBX, Int iMBY,
  315. CoordI x, CoordI y
  316. )
  317. {
  318. motionCompAndDiff_BVOP_MB (pmv, pmvBackward, pmbmd, x, y, &m_rctRefVOPY0, &m_rctRefVOPY1);
  319. Bool bSkip;
  320. if (m_volmd.volType == ENHN_LAYER && m_vopmd.iRefSelectCode == 0 &&
  321.     pmbmd->m_mbType == FORWARD)
  322. bSkip = (pmv->m_vctTrueHalfPel.x ==0 && pmv->m_vctTrueHalfPel.y == 0);
  323. else if (pmbmd->m_mbType == DIRECT)
  324. bSkip = (pmbmd->m_vctDirectDeltaMV.x ==0 && pmbmd->m_vctDirectDeltaMV.y == 0);
  325. else 
  326. bSkip = FALSE;
  327. quantizeTextureInterMB (pmbmd, pmv, NULL, bSkip); // decide COD here; skip not allowed in non-direct mode
  328. codeMBTextureHeadOfBVOP (pmbmd);
  329. if (!pmbmd->m_bSkip) {
  330. m_statsMB.nBitsMV += encodeMVofBVOP (pmv, pmvBackward, pmbmd, iMBX, iMBY, pmvRef, pmbmdRef);
  331. sendDCTCoefOfInterMBTexture (pmbmd);
  332. addErrorAndPredToCurrQ (ppxlcCurrQMBY, ppxlcCurrQMBU, ppxlcCurrQMBV);
  333. }
  334. else
  335. assignPredToCurrQ (ppxlcCurrQMBY, ppxlcCurrQMBU, ppxlcCurrQMBV);
  336. }
  337. Void CVideoObjectEncoder::encodeBVOPMB_WithShape (
  338. PixelC* ppxlcCurrQMBY, PixelC* ppxlcCurrQMBU, PixelC* ppxlcCurrQMBV, PixelC* ppxlcCurrQMBA, PixelC* ppxlcCurrQBY,
  339. CMBMode* pmbmd, const CMotionVector* pmv, const CMotionVector* pmvBackward, 
  340. CMotionVector* pmvBY, ShapeMode shpmdColocatedMB,
  341. const CMBMode* pmbmdRef, const CMotionVector* pmvRef,
  342. Int iMBX, Int iMBY,
  343. CoordI x, CoordI y, Int &iQPPrev, Int &iQPPrevAlpha
  344. )
  345. {
  346. pmbmd->m_stepSize = iQPPrev;
  347. if(!m_volmd.bNoGrayQuantUpdate)
  348. {
  349. iQPPrevAlpha = (iQPPrev * m_vopmd.intStepBAlpha) / m_vopmd.intStepB;
  350. if(iQPPrevAlpha<1)
  351. iQPPrevAlpha=1;
  352. }
  353. pmbmd->m_stepSizeAlpha = iQPPrevAlpha;
  354. m_statsMB.nBitsShape += codeInterShape (
  355. ppxlcCurrQBY, 
  356. m_vopmd.fShapeBPredDir==B_FORWARD ? m_pvopcRefQ0 : m_pvopcRefQ1,
  357. pmbmd, shpmdColocatedMB,
  358. NULL, pmvBY, 
  359. x, y, 
  360. iMBX, iMBY
  361. );
  362. downSampleBY (m_ppxlcCurrMBBY, m_ppxlcCurrMBBUV);
  363. decideTransparencyStatus (pmbmd, m_ppxlcCurrMBBY); // change pmbmd to inter if all transparent
  364. /*BBM// Added for Boundary by Hyundai(1998-5-9)
  365. if (m_vopmd.bInterlace) initMergedMode (pmbmd);
  366. // End of Hyundai(1998-5-9)*/
  367. if (m_volmd.bShapeOnly == FALSE && pmbmd->m_rgTranspStatus [0] != ALL) {
  368. if (pmbmd->m_rgTranspStatus [0] == PARTIAL)
  369. motionCompAndDiff_BVOP_MB_WithShape (pmv, pmvBackward, pmbmd, x, y, &m_rctRefVOPY0, &m_rctRefVOPY1);
  370. else
  371. motionCompAndDiff_BVOP_MB (pmv, pmvBackward, pmbmd, x, y, &m_rctRefVOPY0, &m_rctRefVOPY1);
  372. Bool bSkip = FALSE;
  373. if (pmbmd->m_mbType == DIRECT) {
  374. if(pmvRef == NULL) //just to be safe
  375. pmbmd->m_vctDirectDeltaMV = pmv->m_vctTrueHalfPel;
  376. bSkip = (pmbmd->m_vctDirectDeltaMV.x == 0) && (pmbmd->m_vctDirectDeltaMV.y == 0);
  377. }
  378. if(m_volmd.fAUsage == EIGHT_BIT)
  379. motionCompAndDiffAlpha_BVOP_MB (
  380. pmv,
  381. pmvBackward, 
  382. pmbmd, 
  383. x, y,
  384. &m_rctRefVOPY0, &m_rctRefVOPY1
  385. );
  386. /*BBM// Added for Boundary by Hyundai(1998-5-9)
  387. if (m_vopmd.bInterlace && pmbmd -> m_rgTranspStatus [0] == PARTIAL)
  388.                         boundaryMacroBlockMerge (pmbmd);
  389. // End of Hyundai(1998-5-9)*/
  390. quantizeTextureInterMB (pmbmd, pmv, ppxlcCurrQMBA, bSkip); // decide COD here; skip not allowed in non-direct mode
  391. codeMBTextureHeadOfBVOP (pmbmd);
  392. if (!pmbmd -> m_bSkip) {
  393. m_statsMB.nBitsMV += encodeMVofBVOP (pmv, pmvBackward, pmbmd,
  394. iMBX, iMBY, pmvRef, pmbmdRef); // need to see the MB type to decide what MV to be sent
  395. sendDCTCoefOfInterMBTexture (pmbmd);
  396. //addErrorAndPredToCurrQ (ppxlcCurrQMBY, ppxlcCurrQMBU, ppxlcCurrQMBV); // delete by Hyundai, ok swinder
  397. }
  398. else
  399. assignPredToCurrQ (ppxlcCurrQMBY, ppxlcCurrQMBU, ppxlcCurrQMBV);
  400. if (m_volmd.fAUsage == EIGHT_BIT) {
  401. codeMBAlphaHeadOfBVOP (pmbmd);
  402. if (pmbmd -> m_CODAlpha == ALPHA_CODED) {
  403. sendDCTCoefOfInterMBAlpha (pmbmd);
  404. //addAlphaErrorAndPredToCurrQ (ppxlcCurrQMBA); // delete by Hyundai, ok swinder
  405. }
  406. else if(pmbmd -> m_CODAlpha == ALPHA_SKIPPED)
  407. assignAlphaPredToCurrQ (ppxlcCurrQMBA);
  408. }
  409. /*BBM// Added for Boundary by Hyundai(1998-5-9)
  410.                 if (m_vopmd.bInterlace && pmbmd -> m_bMerged[0])
  411.                         mergedMacroBlockSplit (pmbmd);
  412. // End of Hyundai(1998-5-9)*/
  413.         if (!pmbmd -> m_bSkip)
  414. addErrorAndPredToCurrQ (ppxlcCurrQMBY, ppxlcCurrQMBU, ppxlcCurrQMBV);
  415.         if (m_volmd.fAUsage == EIGHT_BIT && pmbmd -> m_CODAlpha == ALPHA_CODED)
  416.     addAlphaErrorAndPredToCurrQ (ppxlcCurrQMBA);
  417. }
  418. }
  419. Void CVideoObjectEncoder::codeMBTextureHeadOfIVOP (const CMBMode* pmbmd)
  420. {
  421. UInt CBPC = (pmbmd->getCodedBlockPattern (U_BLOCK) << 1)
  422. | pmbmd->getCodedBlockPattern (V_BLOCK);
  423. //per defintion of H.263's CBPC 
  424. assert (CBPC >= 0 && CBPC <= 3);
  425. Int CBPY = 0;
  426. UInt cNonTrnspBlk = 0, iBlk;
  427. for (iBlk = (UInt) Y_BLOCK1; iBlk <= (UInt) Y_BLOCK4; iBlk++) {
  428. if (pmbmd->m_rgTranspStatus [iBlk] != ALL)
  429. cNonTrnspBlk++;
  430. }
  431. UInt iBitPos = 1;
  432. for (iBlk = (UInt) Y_BLOCK1; iBlk <= (UInt) Y_BLOCK4; iBlk++) {
  433. if (pmbmd->m_rgTranspStatus [iBlk] != ALL) {
  434. CBPY |= pmbmd->getCodedBlockPattern ((BlockNum) iBlk) << (cNonTrnspBlk - iBitPos);
  435. iBitPos++;
  436. }
  437. }
  438. assert (CBPY >= 0 && CBPY <= 15); //per defintion of H.263's CBPY 
  439. Int iSymbol = 4 * pmbmd->m_dctMd + CBPC;
  440. assert (iSymbol >= 0 && iSymbol <= 7); //send MCBPC
  441. #ifdef __TRACE_AND_STATS_
  442. m_pbitstrmOut->trace (iSymbol, "MB_MCBPC");
  443. #endif // __TRACE_AND_STATS_
  444. m_statsMB.nBitsMCBPC += m_pentrencSet->m_pentrencMCBPCintra->encodeSymbol (iSymbol, "MB_MCBPC");
  445. //fprintf(stderr,"MCBPC = %dn",iSymbol);
  446. m_pbitstrmOut->putBits (pmbmd->m_bACPrediction, 1, "MB_ACPRED");
  447. m_statsMB.nBitsIntraPred++;
  448. //fprintf(stderr,"ACPred = %dn",pmbmd->m_bACPrediction);
  449. #ifdef __TRACE_AND_STATS_
  450. m_pbitstrmOut->trace (cNonTrnspBlk, "MB_NumNonTranspBlks");
  451. m_pbitstrmOut->trace (CBPY, "MB_CBPY (I-style)");
  452. #endif // __TRACE_AND_STATS_
  453. switch (cNonTrnspBlk) {
  454. case 1:
  455. m_statsMB.nBitsCBPY += m_pentrencSet->m_pentrencCBPY1->encodeSymbol (CBPY, "MB_CBPY");
  456. break;
  457. case 2:
  458. m_statsMB.nBitsCBPY += m_pentrencSet->m_pentrencCBPY2->encodeSymbol (CBPY, "MB_CBPY");
  459. break;
  460. case 3:
  461. m_statsMB.nBitsCBPY += m_pentrencSet->m_pentrencCBPY3->encodeSymbol (CBPY, "MB_CBPY");
  462. break;
  463. case 4:
  464. m_statsMB.nBitsCBPY += m_pentrencSet->m_pentrencCBPY->encodeSymbol (CBPY, "MB_CBPY");
  465. break;
  466. default:
  467. assert (FALSE);
  468. }
  469. //fprintf(stderr,"CBPY = %dn",CBPY);
  470. m_statsMB.nIntraMB++;
  471. if (pmbmd->m_dctMd == INTRAQ) {
  472. Int DQUANT = pmbmd->m_intStepDelta; //send DQUANT
  473. assert (DQUANT >= -2 && DQUANT <= 2);
  474. if (DQUANT != 0) {
  475. if (sign (DQUANT) == 1)
  476. m_pbitstrmOut->putBits (DQUANT + 1, 2, "MB_DQUANT");
  477. else
  478. m_pbitstrmOut->putBits (-1 - DQUANT, 2, "MB_DQUANT");
  479. m_statsMB.nBitsDQUANT += 2;
  480. }
  481. }
  482. // INTERLACE
  483. if(m_vopmd.bInterlace==TRUE) {
  484. m_pbitstrmOut->putBits (pmbmd->m_bFieldDCT, 1, "DCT_TYPE"); // send dct_type
  485. m_statsMB.nBitsInterlace += 1;
  486. }
  487. // ~INTERLACE
  488. }
  489. Void CVideoObjectEncoder::codeMBTextureHeadOfPVOP (const CMBMode* pmbmd)
  490. {
  491. UInt CBPC = (pmbmd->getCodedBlockPattern (U_BLOCK) << 1)
  492. | pmbmd->getCodedBlockPattern (V_BLOCK);
  493. //per defintion of H.263's CBPC 
  494. assert (CBPC >= 0 && CBPC <= 3);
  495. Int CBPY = 0;
  496. UInt cNonTrnspBlk = 0, iBlk;
  497. for (iBlk = (UInt) Y_BLOCK1; iBlk <= (UInt) Y_BLOCK4; iBlk++) {
  498. if (pmbmd->m_rgTranspStatus [iBlk] != ALL)
  499. cNonTrnspBlk++;
  500. }
  501. UInt iBitPos = 1;
  502. for (iBlk = (UInt) Y_BLOCK1; iBlk <= (UInt) Y_BLOCK4; iBlk++) {
  503. if (pmbmd->m_rgTranspStatus [iBlk] != ALL) {
  504. CBPY |= pmbmd->getCodedBlockPattern ((BlockNum) iBlk) << (cNonTrnspBlk - iBitPos);
  505. iBitPos++;
  506. }
  507. }
  508. assert (CBPY >= 0 && CBPY <= 15); //per defintion of H.263's CBPY 
  509. m_pbitstrmOut->putBits (pmbmd->m_bSkip, 1, "MB_Skip");
  510. m_statsMB.nBitsCOD++;
  511. if (pmbmd->m_bSkip)
  512. m_statsMB.nSkipMB++;
  513. else {
  514. Int iMBtype; //per H.263's MBtype
  515. if (pmbmd->m_dctMd == INTRA || pmbmd->m_dctMd == INTRAQ)
  516. iMBtype = pmbmd->m_dctMd + 3;
  517. else
  518. iMBtype = (pmbmd -> m_dctMd - 2) | pmbmd -> m_bhas4MVForward << 1;
  519. assert (iMBtype >= 0 && iMBtype <= 4);
  520. #ifdef __TRACE_AND_STATS_
  521. m_pbitstrmOut->trace (iMBtype, "MB_MBtype");
  522. m_pbitstrmOut->trace (CBPC, "MB_CBPC");
  523. #endif // __TRACE_AND_STATS_
  524. m_statsMB.nBitsMCBPC += m_pentrencSet->m_pentrencMCBPCinter->encodeSymbol (iMBtype * 4 + CBPC, "MCBPC");
  525. if (pmbmd->m_dctMd == INTRA || pmbmd->m_dctMd == INTRAQ) {
  526. m_pbitstrmOut->putBits (pmbmd->m_bACPrediction, 1, "MB_ACPRED");
  527. m_statsMB.nBitsIntraPred++;
  528. #ifdef __TRACE_AND_STATS_
  529. m_pbitstrmOut->trace (cNonTrnspBlk, "MB_NumNonTranspBlks");
  530. m_pbitstrmOut->trace (CBPY, "MB_CBPY (I-style)");
  531. #endif // __TRACE_AND_STATS_
  532. switch (cNonTrnspBlk) {
  533. case 1:
  534. m_statsMB.nBitsCBPY += m_pentrencSet->m_pentrencCBPY1->encodeSymbol (CBPY, "MB_CBPY");
  535. break;
  536. case 2:
  537. m_statsMB.nBitsCBPY += m_pentrencSet->m_pentrencCBPY2->encodeSymbol (CBPY, "MB_CBPY");
  538. break;
  539. case 3:
  540. m_statsMB.nBitsCBPY += m_pentrencSet->m_pentrencCBPY3->encodeSymbol (CBPY, "MB_CBPY");
  541. break;
  542. case 4:
  543. m_statsMB.nBitsCBPY += m_pentrencSet->m_pentrencCBPY->encodeSymbol (CBPY, "MB_CBPY");
  544. break;
  545. default:
  546. assert (FALSE);
  547. }
  548. m_statsMB.nIntraMB++;
  549. }
  550. else {
  551. #ifdef __TRACE_AND_STATS_
  552. m_pbitstrmOut->trace (cNonTrnspBlk, "MB_NumNonTranspBlks");
  553. m_pbitstrmOut->trace (CBPY, "MB_CBPY (P-style)");
  554. #endif // __TRACE_AND_STATS_
  555. switch (cNonTrnspBlk) {
  556. case 1:
  557. m_statsMB.nBitsCBPY += m_pentrencSet->m_pentrencCBPY1->encodeSymbol (1 - CBPY, "MB_CBPY");
  558. break;
  559. case 2:
  560. m_statsMB.nBitsCBPY += m_pentrencSet->m_pentrencCBPY2->encodeSymbol (3 - CBPY, "MB_CBPY");
  561. break;
  562. case 3:
  563. m_statsMB.nBitsCBPY += m_pentrencSet->m_pentrencCBPY3->encodeSymbol (7 - CBPY, "MB_CBPY");
  564. break;
  565. case 4:
  566. m_statsMB.nBitsCBPY += m_pentrencSet->m_pentrencCBPY->encodeSymbol (15 - CBPY, "MB_CBPY");
  567. break;
  568. default:
  569. assert (FALSE);
  570. }
  571. if(pmbmd ->m_bhas4MVForward)
  572. m_statsMB.nInter4VMB++;
  573. // INTERLACE
  574. else if (pmbmd-> m_bFieldMV)
  575. m_statsMB.nFieldForwardMB++;
  576. // ~INTERLACE
  577. else
  578. m_statsMB.nInterMB++;
  579. }
  580. if (pmbmd->m_dctMd == INTERQ || pmbmd->m_dctMd == INTRAQ) {
  581. Int DQUANT = pmbmd->m_intStepDelta; //send DQUANT
  582. assert (DQUANT >= -2 && DQUANT <= 2);
  583. if (DQUANT != 0) {
  584. if (sign (DQUANT) == 1)
  585. m_pbitstrmOut->putBits (DQUANT + 1, 2, "MB_DQUANT");
  586. else
  587. m_pbitstrmOut->putBits (-1 - DQUANT, 2, "MB_DQUANT");
  588. m_statsMB.nBitsDQUANT += 2;
  589. }
  590. }
  591. // INTERLACE
  592. if (m_vopmd.bInterlace == TRUE) {
  593. if((pmbmd->m_dctMd == INTRA) || (pmbmd->m_dctMd == INTRAQ) || (CBPC || CBPY)) {
  594. m_pbitstrmOut->putBits (pmbmd->m_bFieldDCT, 1, "DCT_Type");
  595. m_statsMB.nBitsInterlace += 1;
  596. }
  597. if((pmbmd->m_dctMd == INTER || pmbmd->m_dctMd == INTERQ )&&(pmbmd -> m_bhas4MVForward == FALSE)) {
  598. m_pbitstrmOut->putBits (pmbmd->m_bFieldMV, 1, "Field_Prediction");
  599. m_statsMB.nBitsInterlace += 1;
  600. if(pmbmd->m_bFieldMV) {
  601. m_pbitstrmOut->putBits (pmbmd->m_bForwardTop, 1, "Forward_Top_Field_Ref");
  602. m_pbitstrmOut->putBits (pmbmd->m_bForwardBottom, 1, "Forward_Bot_Field_Ref");
  603. m_statsMB.nBitsInterlace += 2;
  604. }
  605. }
  606. }
  607. // ~INTERLACE
  608. }
  609. }
  610. Void CVideoObjectEncoder::codeMBTextureHeadOfBVOP (const CMBMode* pmbmd)
  611. {
  612.   U8 uchCBPB = 0;
  613. if (pmbmd->m_bSkip) {
  614. if (m_volmd.volType == BASE_LAYER) {
  615. assert (pmbmd -> m_rgTranspStatus [0] != ALL);
  616. if (pmbmd->m_bColocatedMBSkip)
  617. return;
  618. }
  619. m_pbitstrmOut->putBits (1, 1, "MB_MODB");
  620. m_statsMB.nBitsMODB++;
  621. m_statsMB.nSkipMB++;
  622. if(m_volmd.volType == ENHN_LAYER && m_vopmd.iRefSelectCode == 0)
  623. return;
  624. }
  625. else {
  626. Int iCBPC = (pmbmd->getCodedBlockPattern (U_BLOCK) << 1) | 
  627.  pmbmd->getCodedBlockPattern (V_BLOCK); //per defintion of H.263's CBPC 
  628. assert (iCBPC >= 0 && iCBPC <= 3);
  629. Int iCBPY = 0;
  630. Int iNumNonTrnspBlk = 0, iBlk;
  631. for (iBlk = Y_BLOCK1; iBlk <= Y_BLOCK4; iBlk++) 
  632. iNumNonTrnspBlk += (pmbmd->m_rgTranspStatus [iBlk] != ALL);
  633. Int iBitPos = 1;
  634. for (iBlk = Y_BLOCK1; iBlk <= Y_BLOCK4; iBlk++) {
  635. if (pmbmd->m_rgTranspStatus [iBlk] != ALL) {
  636. iCBPY |= pmbmd->getCodedBlockPattern ((BlockNum) iBlk) << (iNumNonTrnspBlk - iBitPos);
  637. iBitPos++;
  638. }
  639. }
  640. assert (iCBPY >= 0 && iCBPY <= 15); //per defintion of H.263's CBPY 
  641. uchCBPB = (iCBPY << 2 | iCBPC) & 0x3F;
  642. if (uchCBPB == 0) {
  643. m_pbitstrmOut->putBits (1, 2, "MB_MODB");
  644. m_statsMB.nBitsMODB += 2;
  645. if (m_volmd.volType == BASE_LAYER || (m_volmd.volType == ENHN_LAYER && m_vopmd.iRefSelectCode != 0))
  646. m_statsMB.nBitsMBTYPE += m_pentrencSet->m_pentrencMbTypeBVOP->encodeSymbol (pmbmd->m_mbType, "MB_TYPE");
  647. else {
  648. Int iMbtypeBits =0;
  649. if(pmbmd->m_mbType == FORWARD) iMbtypeBits = 1;
  650. else if(pmbmd->m_mbType == INTERPOLATE) iMbtypeBits = 2;
  651. else if(pmbmd->m_mbType == BACKWARD) iMbtypeBits = 3;
  652. Int iMbtypeValue = 1;
  653. m_statsMB.nBitsMBTYPE += iMbtypeBits;
  654. m_pbitstrmOut->putBits (iMbtypeValue, iMbtypeBits, "MB_TYPE");
  655. }
  656. }
  657. else {
  658. m_pbitstrmOut->putBits (0, 2,"MB_MODB");
  659. m_statsMB.nBitsMODB += 2;
  660. //m_stat.nBitsMBTYPE += m_pentrencMbTypeBVOP->encodeSymbol (pmbmd->m_mbType, "MB_TYPE");
  661. if (m_volmd.volType == BASE_LAYER || (m_volmd.volType == ENHN_LAYER && m_vopmd.iRefSelectCode != 0))
  662. m_statsMB.nBitsMBTYPE += m_pentrencSet->m_pentrencMbTypeBVOP->encodeSymbol (pmbmd->m_mbType, "MB_TYPE");
  663. else {
  664. Int iMbtypeBits =0;
  665. if(pmbmd->m_mbType == FORWARD) iMbtypeBits = 1;
  666. else if(pmbmd->m_mbType == INTERPOLATE) iMbtypeBits = 2;
  667. else if(pmbmd->m_mbType == BACKWARD) iMbtypeBits = 3;
  668. Int iMbtypeValue = 1;
  669. m_statsMB.nBitsMBTYPE += iMbtypeBits;
  670. m_pbitstrmOut->putBits (iMbtypeValue, iMbtypeBits, "MB_TYPE");
  671. }
  672. m_pbitstrmOut -> putBits (uchCBPB, iNumNonTrnspBlk + 2, "MB_CBPB");
  673. m_statsMB.nBitsCBPB += iNumNonTrnspBlk + 2;
  674. }
  675. switch (pmbmd->m_mbType) {
  676. case FORWARD:
  677. m_statsMB.nForwardMB++;
  678. break;
  679. case BACKWARD:
  680. m_statsMB.nBackwardMB++;
  681. break;
  682. case DIRECT:
  683. m_statsMB.nDirectMB++;
  684. break;
  685. case INTERPOLATE:
  686. m_statsMB.nInterpolateMB++;
  687. break;
  688. default:
  689. assert (FALSE);
  690. }
  691. }
  692. if (pmbmd->m_mbType != DIRECT) {
  693. if (uchCBPB != 0) { //no need to send when MODB = 10
  694. Int DQUANT = pmbmd->m_intStepDelta; //send DQUANT
  695. assert (DQUANT == -2 || DQUANT == 2 || DQUANT == 0);
  696. if (DQUANT == 0) {
  697. m_pbitstrmOut->putBits ((Int) 0, (UInt) 1, "MB_DQUANT");
  698. m_statsMB.nBitsDQUANT += 1;
  699. }
  700. else {
  701. if (DQUANT == 2)
  702. m_pbitstrmOut->putBits (3, 2, "MB_DQUANT");
  703. else 
  704. m_pbitstrmOut->putBits (2, 2, "MB_DQUANT");
  705. m_statsMB.nBitsDQUANT += 2;
  706. }
  707. }
  708. }
  709. // INTERLACE
  710. if (pmbmd->m_bSkip) {
  711. if (m_vopmd.bInterlace && (pmbmd->m_mbType == DIRECT) && pmbmd->m_bFieldMV)
  712. m_statsMB.nFieldDirectMB++;
  713. } else if (m_vopmd.bInterlace) {
  714. if (uchCBPB) {
  715. m_pbitstrmOut->putBits((Int) pmbmd->m_bFieldDCT, 1, "DCT_TYPE");
  716. m_statsMB.nBitsInterlace++;
  717. }
  718. if (pmbmd->m_bFieldMV) {
  719. switch (pmbmd->m_mbType) {
  720. case FORWARD:
  721. m_pbitstrmOut->putBits(1, 1, "FIELD_PREDICTION");
  722. m_pbitstrmOut->putBits((Int)pmbmd->m_bForwardTop,    1, "FORWARD_TOP_FIELD_REFERENCE");
  723. m_pbitstrmOut->putBits((Int)pmbmd->m_bForwardBottom, 1, "FORWARD_BOTTOM_FIELD_REFERENCE");
  724. m_statsMB.nFieldForwardMB++;
  725. m_statsMB.nBitsInterlace += 3;
  726. break;
  727. case BACKWARD:
  728. m_pbitstrmOut->putBits(1, 1, "FIELD_PREDICTION");
  729. m_pbitstrmOut->putBits((Int)pmbmd->m_bBackwardTop,    1, "BACKWARD_TOP_FIELD_REFERENCE");
  730. m_pbitstrmOut->putBits((Int)pmbmd->m_bBackwardBottom, 1, "BACKWARD_BOTTOM_FIELD_REFERENCE");
  731. m_statsMB.nFieldBackwardMB++;
  732. m_statsMB.nBitsInterlace += 3;
  733. break;
  734. case INTERPOLATE:
  735. m_pbitstrmOut->putBits(1, 1, "FIELD_PREDICTION");
  736. m_pbitstrmOut->putBits((Int)pmbmd->m_bForwardTop,     1, "FORWARD_TOP_FIELD_REFERENCE");
  737. m_pbitstrmOut->putBits((Int)pmbmd->m_bForwardBottom,  1, "FORWARD_BOTTOM_FIELD_REFERENCE");
  738. m_pbitstrmOut->putBits((Int)pmbmd->m_bBackwardTop,    1, "BACKWARD_TOP_FIELD_REFERENCE");
  739. m_pbitstrmOut->putBits((Int)pmbmd->m_bBackwardBottom, 1, "BACKWARD_BOTTOM_FIELD_REFERENCE");
  740. m_statsMB.nFieldInterpolateMB++;
  741. m_statsMB.nBitsInterlace += 5;
  742. break;
  743. case DIRECT:
  744. m_statsMB.nFieldDirectMB++;
  745. break;
  746. }
  747. } else if (pmbmd->m_mbType != DIRECT) {
  748. m_pbitstrmOut->putBits(0, 1, "FIELD_PREDICTION");
  749. m_statsMB.nBitsInterlace++;
  750. }
  751. }
  752. // ~INTERLACE
  753. }
  754. Void CVideoObjectEncoder::copyToCurrBuffWithShape (
  755. const PixelC* ppxlcCurrY, const PixelC* ppxlcCurrU, const PixelC* ppxlcCurrV,
  756. const PixelC* ppxlcCurrBY, const PixelC* ppxlcCurrA,
  757. Int iWidthY, Int iWidthUV
  758. )
  759. {
  760. PixelC* ppxlcCurrMBY = m_ppxlcCurrMBY;
  761. PixelC* ppxlcCurrMBU = m_ppxlcCurrMBU;
  762. PixelC* ppxlcCurrMBV = m_ppxlcCurrMBV;
  763. PixelC* ppxlcCurrMBBY = m_ppxlcCurrMBBY;
  764. Int ic;
  765. for (ic = 0; ic < BLOCK_SIZE; ic++) {
  766. memcpy (ppxlcCurrMBY, ppxlcCurrY, MB_SIZE*sizeof(PixelC)); 
  767. memcpy (ppxlcCurrMBU, ppxlcCurrU, BLOCK_SIZE*sizeof(PixelC));
  768. memcpy (ppxlcCurrMBV, ppxlcCurrV, BLOCK_SIZE*sizeof(PixelC));
  769. memcpy (ppxlcCurrMBBY, ppxlcCurrBY, MB_SIZE*sizeof(PixelC));
  770. ppxlcCurrMBY += MB_SIZE; ppxlcCurrY += iWidthY;
  771. ppxlcCurrMBU += BLOCK_SIZE; ppxlcCurrU += iWidthUV;
  772. ppxlcCurrMBV += BLOCK_SIZE; ppxlcCurrV += iWidthUV;
  773. ppxlcCurrMBBY += MB_SIZE; ppxlcCurrBY += iWidthY;
  774. memcpy (ppxlcCurrMBY, ppxlcCurrY, MB_SIZE*sizeof(PixelC)); // two rows for Y
  775. memcpy (ppxlcCurrMBBY, ppxlcCurrBY, MB_SIZE*sizeof(PixelC));
  776. ppxlcCurrMBY += MB_SIZE; ppxlcCurrY += iWidthY;
  777. ppxlcCurrMBBY += MB_SIZE; ppxlcCurrBY += iWidthY;
  778. }
  779. if (m_volmd.fAUsage == EIGHT_BIT) {
  780. PixelC* ppxlcCurrMBA = m_ppxlcCurrMBA;
  781. for (ic = 0; ic < MB_SIZE; ic++) {
  782. memcpy (ppxlcCurrMBA, ppxlcCurrA, MB_SIZE*sizeof(PixelC));
  783. ppxlcCurrMBA += MB_SIZE; 
  784. ppxlcCurrA += iWidthY;
  785. }
  786. }
  787. }
  788. Void CVideoObjectEncoder::copyToCurrBuffJustShape(const PixelC* ppxlcCurrBY,
  789.   Int iWidthY)
  790. {
  791. PixelC* ppxlcCurrMBBY = m_ppxlcCurrMBBY;
  792. Int ic;
  793. for (ic = 0; ic < BLOCK_SIZE; ic++) {
  794. memcpy (ppxlcCurrMBBY, ppxlcCurrBY, MB_SIZE*sizeof(PixelC));
  795. ppxlcCurrMBBY += MB_SIZE; ppxlcCurrBY += iWidthY;
  796. memcpy (ppxlcCurrMBBY, ppxlcCurrBY, MB_SIZE*sizeof(PixelC));
  797. ppxlcCurrMBBY += MB_SIZE; ppxlcCurrBY += iWidthY;
  798. }
  799. }
  800. Void CVideoObjectEncoder::copyToCurrBuff (
  801. const PixelC* ppxlcCurrY, const PixelC* ppxlcCurrU, const PixelC* ppxlcCurrV,
  802. Int iWidthY, Int iWidthUV
  803. )
  804. {
  805. PixelC* ppxlcCurrMBY = m_ppxlcCurrMBY;
  806. PixelC* ppxlcCurrMBU = m_ppxlcCurrMBU;
  807. PixelC* ppxlcCurrMBV = m_ppxlcCurrMBV;
  808. Int ic;
  809. for (ic = 0; ic < BLOCK_SIZE; ic++) {
  810. memcpy (ppxlcCurrMBY, ppxlcCurrY, MB_SIZE*sizeof(PixelC));
  811. memcpy (ppxlcCurrMBU, ppxlcCurrU, BLOCK_SIZE*sizeof(PixelC));
  812. memcpy (ppxlcCurrMBV, ppxlcCurrV, BLOCK_SIZE*sizeof(PixelC));
  813. ppxlcCurrMBY += MB_SIZE; ppxlcCurrY += iWidthY;
  814. ppxlcCurrMBU += BLOCK_SIZE; ppxlcCurrU += iWidthUV;
  815. ppxlcCurrMBV += BLOCK_SIZE; ppxlcCurrV += iWidthUV;
  816. memcpy (ppxlcCurrMBY, ppxlcCurrY, MB_SIZE*sizeof(PixelC)); // two rows for Y
  817. ppxlcCurrMBY += MB_SIZE; ppxlcCurrY += iWidthY;
  818. }
  819. }
  820. // compute error signal
  821. Void CVideoObjectEncoder::computeTextureError ()
  822. {
  823. CoordI ix;
  824. // Y
  825. for (ix = 0; ix < MB_SQUARE_SIZE; ix++)
  826. m_ppxliErrorMBY [ix] = m_ppxlcCurrMBY [ix] - m_ppxlcPredMBY [ix];
  827. // UV
  828. for (ix = 0; ix < BLOCK_SQUARE_SIZE; ix++) {
  829. m_ppxliErrorMBU [ix] = m_ppxlcCurrMBU [ix] - m_ppxlcPredMBU [ix];
  830. m_ppxliErrorMBV [ix] = m_ppxlcCurrMBV [ix] - m_ppxlcPredMBV [ix];
  831. }
  832. // Alpha
  833. if(m_volmd.fAUsage==EIGHT_BIT)
  834. for (ix = 0; ix < MB_SQUARE_SIZE; ix++)
  835. m_ppxliErrorMBA [ix] = m_ppxlcCurrMBA [ix] - m_ppxlcPredMBA [ix];
  836. }
  837. Void CVideoObjectEncoder::computeTextureErrorWithShape ()
  838. {
  839. CoordI ix;
  840. // Y
  841. for (ix = 0; ix < MB_SQUARE_SIZE; ix++) {
  842. if (m_ppxlcCurrMBBY [ix] == transpValue)
  843. m_ppxliErrorMBY [ix] = 0; // zero padding
  844. else
  845. m_ppxliErrorMBY [ix] = m_ppxlcCurrMBY [ix] - m_ppxlcPredMBY [ix];
  846. }
  847. // UV
  848. for (ix = 0; ix < BLOCK_SQUARE_SIZE; ix++) {
  849. if (m_ppxlcCurrMBBUV [ix] == transpValue)
  850. m_ppxliErrorMBU [ix] = m_ppxliErrorMBV [ix] = 0;
  851. else {
  852. m_ppxliErrorMBU [ix] = m_ppxlcCurrMBU [ix] - m_ppxlcPredMBU [ix];
  853. m_ppxliErrorMBV [ix] = m_ppxlcCurrMBV [ix] - m_ppxlcPredMBV [ix];
  854. }
  855. }
  856. if(m_volmd.fAUsage==EIGHT_BIT)
  857. for (ix = 0; ix < MB_SQUARE_SIZE; ix++) {
  858. if (m_ppxlcCurrMBBY [ix] == transpValue)
  859. m_ppxliErrorMBA [ix] = 0; // zero padding
  860. else
  861. m_ppxliErrorMBA [ix] = m_ppxlcCurrMBA [ix] - m_ppxlcPredMBA [ix];
  862. }
  863. }
  864. Void CVideoObjectEncoder::computeAlphaError ()
  865. {
  866. CoordI ix;
  867. for (ix = 0; ix < MB_SQUARE_SIZE; ix++) {
  868. if (m_ppxlcCurrMBBY [ix] == transpValue)
  869. m_ppxliErrorMBA [ix] = 0; // zero padding
  870. else
  871. m_ppxliErrorMBA [ix] = m_ppxlcCurrMBA [ix] - m_ppxlcPredMBA [ix];
  872. }
  873. }
  874. Void CVideoObjectEncoder::quantizeTextureIntraMB (
  875. Int imbX, Int imbY,
  876. CMBMode* pmbmd, 
  877. PixelC* ppxlcCurrQMBY, PixelC* ppxlcCurrQMBU, PixelC* ppxlcCurrQMBV,
  878. PixelC* ppxlcCurrQMBA
  879. )
  880. {
  881. assert (pmbmd != NULL);
  882. assert (pmbmd -> m_dctMd == INTRA || pmbmd->m_dctMd == INTRAQ);
  883. assert (pmbmd -> m_rgTranspStatus [0] != ALL);
  884. Int iQP = pmbmd->m_stepSize;
  885. #ifdef __TRACE_AND_STATS_
  886. m_statsMB.nQMB++;
  887. m_statsMB.nQp += iQP;
  888. #endif // __TRACE_AND_STATS_
  889. Int iDcScalerY, iDcScalerC, iDcScalerA = 0;
  890. if (iQP <= 4)
  891. {
  892. iDcScalerY = 8;
  893. iDcScalerC = 8;
  894. }
  895. else if (iQP >= 5 && iQP <= 8)
  896. {
  897. iDcScalerY = 2 * iQP;
  898. iDcScalerC = (iQP + 13) / 2;
  899. }
  900. else if (iQP >= 9 && iQP <= 24)
  901. {
  902. iDcScalerY = iQP + 8;
  903. iDcScalerC = (iQP + 13) / 2;
  904. }
  905. else
  906. {
  907. iDcScalerY = 2 * iQP - 16;
  908. iDcScalerC = iQP - 6;
  909. }
  910. Int iQPA = 0;
  911. pmbmd->m_CODAlpha = ALPHA_CODED;
  912. if(m_volmd.fAUsage == EIGHT_BIT)
  913. {
  914. if (pmbmd -> m_stepSizeAlpha < 1)
  915. pmbmd -> m_stepSizeAlpha = 1;
  916. iQPA = pmbmd->m_stepSizeAlpha;
  917. if (iQPA <= 4)
  918. iDcScalerA = 8;
  919. else if (iQPA >= 5 && iQPA <= 8)
  920. iDcScalerA = 2 * iQPA;
  921. else if (iQPA >= 9 && iQPA <= 24)
  922. iDcScalerA = iQPA + 8;
  923. else
  924. iDcScalerA = 2 * iQPA - 16;
  925. if(pmbmd->m_rgTranspStatus [0] == NONE)
  926. {
  927. // need to test gray alpha vals
  928. // CODA = 1 if all==255, can't use TranspStatus, has to be 255
  929. Int i;
  930. Int iThresh = 256 - iQPA;
  931. pmbmd->m_CODAlpha = ALPHA_ALL255;
  932. for(i = 0; i<MB_SQUARE_SIZE; i++)
  933. if(m_ppxlcCurrMBA[i]<=iThresh)
  934. {
  935. pmbmd->m_CODAlpha = ALPHA_CODED;
  936. break;
  937. }
  938. if(pmbmd->m_CODAlpha == ALPHA_ALL255)
  939. {
  940. pxlcmemset(m_ppxlcCurrMBA, 255, MB_SQUARE_SIZE);
  941. PixelC *ppxlc = ppxlcCurrQMBA;
  942. for(i = 0; i<MB_SIZE; i++, ppxlc += m_iFrameWidthY)
  943. pxlcmemset(ppxlc, 255, MB_SIZE);
  944. }
  945. }
  946. }
  947. Int iCoefToStart;
  948. assert (pmbmd -> m_stepSizeDelayed > 0);
  949. if (pmbmd -> m_stepSizeDelayed >= grgiDCSwitchingThreshold [m_vopmd.iIntraDcSwitchThr])
  950. {
  951. pmbmd->m_bCodeDcAsAc = TRUE;
  952. //pmbmd->m_bCodeDcAsAcAlpha = TRUE; // decision should really be based on alpha quantiser
  953. iCoefToStart = 0;
  954. }
  955. else {
  956. pmbmd->m_bCodeDcAsAc = FALSE;
  957. //pmbmd->m_bCodeDcAsAcAlpha = FALSE;
  958. iCoefToStart = 1;
  959. }
  960. pmbmd->m_bCodeDcAsAcAlpha = FALSE;
  961. //for intra pred
  962. MacroBlockMemory* pmbmLeft = NULL;
  963. MacroBlockMemory* pmbmTop = NULL;
  964. MacroBlockMemory* pmbmLeftTop = NULL;
  965. CMBMode* pmbmdLeft = NULL;
  966. CMBMode* pmbmdTop = NULL;
  967. CMBMode* pmbmdLeftTop = NULL;  
  968. Int iMBnum = imbY * m_iNumMBX + imbX;
  969. if (!bVPNoTop(iMBnum)) {
  970. pmbmTop  = m_rgpmbmAbove [imbX];
  971. pmbmdTop = pmbmd - m_iNumMBX;
  972. }
  973. if (!bVPNoLeft(iMBnum, imbX)) {
  974. pmbmLeft  = m_rgpmbmCurr [imbX - 1];
  975. pmbmdLeft = pmbmd -  1;
  976. }
  977. if (!bVPNoLeftTop(iMBnum, imbX)) {
  978. pmbmLeftTop  = m_rgpmbmAbove [imbX - 1];
  979. pmbmdLeftTop = pmbmd - m_iNumMBX - 1;
  980. }
  981. // INTERLACE
  982. if((pmbmd->m_rgTranspStatus [0] == NONE)&&(m_vopmd.bInterlace == TRUE) ) {
  983. pmbmd->m_bFieldDCT = FrameFieldDCTDecideC(m_ppxlcCurrMBY);
  984. m_statsMB.nFieldDCTMB += (Int) pmbmd->m_bFieldDCT;
  985. }
  986. else
  987. pmbmd->m_bFieldDCT = 0;
  988. pmbmd->m_bSkip = FALSE; // for direct mode reference 
  989. // ~INTERLACE
  990. PixelC* rgchBlkDst = NULL;
  991. PixelC* rgchBlkSrc = NULL;
  992. Int iWidthDst, iWidthSrc;
  993. Int iDcScaler;
  994. Int* rgiCoefQ;
  995. Int iSumErr = 0; //sum of error to determine intra ac prediction
  996. Int iBlk;
  997. Int iBlkEnd;
  998. if(m_volmd.fAUsage == EIGHT_BIT)
  999. iBlkEnd = A_BLOCK4;
  1000. else
  1001. iBlkEnd = V_BLOCK;
  1002. for (iBlk = (Int) Y_BLOCK1; iBlk <= iBlkEnd; iBlk++) { // + 1 is because of the indexing
  1003. if (iBlk < (Int) U_BLOCK || iBlk > (Int) V_BLOCK) {
  1004. if(iBlk==A_BLOCK1)
  1005. iSumErr = 0; // start again for alpha
  1006. if (pmbmd -> m_rgTranspStatus [iBlk % 6] == ALL) // %6 hack!!
  1007. continue;
  1008. switch (iBlk) 
  1009. {
  1010. case (Y_BLOCK1): 
  1011. rgchBlkDst = ppxlcCurrQMBY;
  1012. rgchBlkSrc = m_ppxlcCurrMBY;
  1013. break;
  1014. case (Y_BLOCK2): 
  1015. rgchBlkDst = ppxlcCurrQMBY + BLOCK_SIZE;
  1016. rgchBlkSrc = m_ppxlcCurrMBY + BLOCK_SIZE;
  1017. break;
  1018. case (Y_BLOCK3): 
  1019. rgchBlkDst = ppxlcCurrQMBY + m_iFrameWidthYxBlkSize;
  1020. rgchBlkSrc = m_ppxlcCurrMBY + MB_SIZE * BLOCK_SIZE;
  1021. break;
  1022. case (Y_BLOCK4): 
  1023. rgchBlkDst = ppxlcCurrQMBY + m_iFrameWidthYxBlkSize + BLOCK_SIZE;
  1024. rgchBlkSrc = m_ppxlcCurrMBY + MB_SIZE * BLOCK_SIZE + BLOCK_SIZE;
  1025. break;
  1026. case (A_BLOCK1):
  1027. rgchBlkDst = ppxlcCurrQMBA;
  1028. rgchBlkSrc = m_ppxlcCurrMBA;
  1029. break;
  1030. case (A_BLOCK2):
  1031. rgchBlkDst = ppxlcCurrQMBA + BLOCK_SIZE;
  1032. rgchBlkSrc = m_ppxlcCurrMBA + BLOCK_SIZE;
  1033. break;
  1034. case (A_BLOCK3):
  1035. rgchBlkDst = ppxlcCurrQMBA + m_iFrameWidthYxBlkSize;
  1036. rgchBlkSrc = m_ppxlcCurrMBA + MB_SIZE * BLOCK_SIZE;
  1037. break;
  1038. case (A_BLOCK4):
  1039. rgchBlkDst = ppxlcCurrQMBA + m_iFrameWidthYxBlkSize + BLOCK_SIZE;
  1040. rgchBlkSrc = m_ppxlcCurrMBA + MB_SIZE * BLOCK_SIZE + BLOCK_SIZE;
  1041. break;
  1042. }
  1043. iWidthDst = m_iFrameWidthY;
  1044. iWidthSrc = MB_SIZE;
  1045. if(iBlk<=V_BLOCK)
  1046. iDcScaler = iDcScalerY; //m_rgiDcScalerY [iQP];
  1047. else
  1048. iDcScaler = iDcScalerA;
  1049. }
  1050. else {
  1051. iWidthDst = m_iFrameWidthUV;
  1052. iWidthSrc = BLOCK_SIZE;
  1053. rgchBlkDst = (iBlk == U_BLOCK) ? ppxlcCurrQMBU: ppxlcCurrQMBV;
  1054. rgchBlkSrc = (iBlk == U_BLOCK) ? m_ppxlcCurrMBU: m_ppxlcCurrMBV;
  1055. iDcScaler = iDcScalerC; //m_rgiDcScalerC [iQP];
  1056. }
  1057. if (m_volmd.nBits<=8) { // NBIT: not always valid when nBits>8
  1058. assert(iDcScaler > 0 && iDcScaler < 128);
  1059. }
  1060. rgiCoefQ = m_rgpiCoefQ [iBlk - 1];
  1061. iSumErr += quantizeIntraBlockTexture (
  1062. rgchBlkSrc,
  1063. iWidthSrc,
  1064. rgchBlkDst,
  1065. iWidthDst,
  1066. rgiCoefQ, 
  1067. (iBlk<=V_BLOCK ? iQP : iQPA), 
  1068. iDcScaler,
  1069. iBlk, //from here til last
  1070. pmbmLeft, 
  1071. pmbmTop, 
  1072. pmbmLeftTop, 
  1073. m_rgpmbmCurr [imbX],
  1074. pmbmdLeft, 
  1075. pmbmdTop, 
  1076. pmbmdLeftTop, 
  1077. pmbmd
  1078. ); //all for intra-pred
  1079. if(iBlk>=A_BLOCK1)
  1080. pmbmd->m_bACPredictionAlpha = (pmbmd->m_CODAlpha == ALPHA_CODED && iSumErr >= 0);
  1081. else
  1082. pmbmd->m_bACPrediction =(iSumErr >= 0);
  1083. /*BBM// Added for Boundary by Hyundai(1998-5-9)
  1084.         if (m_vopmd.bInterlace && pmbmd->m_bMerged [0]) {
  1085.                 Int iDstBlk = 0;
  1086.                 switch (iBlk) {
  1087.                         case (Y_BLOCK1):
  1088.                                 if (pmbmd->m_bMerged [1])       iDstBlk = (Int) Y_BLOCK2;
  1089.                                 else if (pmbmd->m_bMerged [3])  iDstBlk = (Int) Y_BLOCK3;
  1090.                                 else if (pmbmd->m_bMerged [5])  iDstBlk = (Int) Y_BLOCK4;
  1091.                                 break;
  1092.                         case (Y_BLOCK2):
  1093.                                 if (pmbmd->m_bMerged [4])       iDstBlk = (Int) Y_BLOCK4;
  1094.                                 else if (pmbmd->m_bMerged [6])  iDstBlk = (Int) Y_BLOCK3;
  1095.                                 break;
  1096.                         case (Y_BLOCK3):
  1097.                                 if (pmbmd->m_bMerged [2])       iDstBlk = (Int) Y_BLOCK4;
  1098.                                 break;
  1099.                         case (A_BLOCK1):
  1100.                                 if (pmbmd->m_bMerged [1])       iDstBlk = (Int) A_BLOCK2;
  1101.                                 else if (pmbmd->m_bMerged [3])  iDstBlk = (Int) A_BLOCK3;
  1102.                                 else if (pmbmd->m_bMerged [5])  iDstBlk = (Int) A_BLOCK4;
  1103.                                 break;
  1104.                         case (A_BLOCK2):
  1105.                                 if (pmbmd->m_bMerged [4])       iDstBlk = (Int) A_BLOCK4;
  1106.                                 else if (pmbmd->m_bMerged [6])  iDstBlk = (Int) A_BLOCK3;
  1107.                                 break;
  1108.                         case (A_BLOCK3):
  1109.                                 if (pmbmd->m_bMerged [2])       iDstBlk = (Int) A_BLOCK4;
  1110.                                 break;
  1111.                 }
  1112.                 if (iDstBlk) {
  1113.                         MacroBlockMemory* pmbmCurr = m_rgpmbmCurr [imbX];
  1114.                         pmbmCurr->rgblkm [iDstBlk-1][0] = pmbmCurr->rgblkm [iBlk-1][0];
  1115.                         for (UInt x = 1; x < (BLOCK_SIZE<<1)-1; x++)
  1116.                                 pmbmCurr->rgblkm [iDstBlk-1][x] = 0;
  1117.                 }
  1118.         }
  1119. // End of Hyundai(1998-5-9)*/
  1120. }
  1121. // INTERLACE
  1122. if ((pmbmd->m_rgTranspStatus [0] == NONE) && (m_vopmd.bInterlace == TRUE) && (pmbmd->m_bFieldDCT == TRUE))
  1123. fieldDCTtoFrameC(ppxlcCurrQMBY);
  1124. // ~INTERLACE
  1125. for (iBlk = (UInt) Y_BLOCK1; iBlk <= iBlkEnd; iBlk++) { // + 1 is because of the indexing
  1126. if (pmbmd->m_rgTranspStatus [iBlk % 6] == ALL) { // hack %6 ok if [6]==[0]
  1127. pmbmd->setCodedBlockPattern ((BlockNum) iBlk, FALSE);
  1128. continue;
  1129. }
  1130. rgiCoefQ = m_rgpiCoefQ [iBlk - 1];
  1131. if (iBlk < (Int) U_BLOCK) 
  1132. iDcScaler = iDcScalerY; //m_rgiDcScalerY [iQP];
  1133. else if(iBlk < (Int) A_BLOCK1)
  1134. iDcScaler = iDcScalerC; //m_rgiDcScalerC [iQP];
  1135. else
  1136. iDcScaler = iDcScalerA;
  1137. intraPred ((BlockNum) iBlk, pmbmd, rgiCoefQ,
  1138. (iBlk<=V_BLOCK ? iQP : iQPA), iDcScaler, m_rgblkmCurrMB [iBlk - 1], m_rgiQPpred [iBlk - 1]);
  1139. Bool bCoded = FALSE;
  1140. UInt i;
  1141. if(iBlk >=(Int) A_BLOCK1)
  1142. iCoefToStart = pmbmd->m_bCodeDcAsAcAlpha==TRUE ? 0 : 1;
  1143. for (i = iCoefToStart; i < BLOCK_SQUARE_SIZE; i++) {
  1144. if (rgiCoefQ [i] != 0) {
  1145. bCoded = TRUE;
  1146. break;
  1147. }
  1148. }
  1149. pmbmd->setCodedBlockPattern ((BlockNum) iBlk, bCoded);
  1150. }
  1151. }
  1152. Void CVideoObjectEncoder::quantizeTextureInterMB (CMBMode* pmbmd, 
  1153.   const CMotionVector* pmv, 
  1154.   PixelC *ppxlcCurrQMBA,
  1155.   Bool bSkip) //bSkip: tested mv is zero
  1156. {
  1157. assert (pmbmd != NULL);
  1158. assert (pmbmd -> m_dctMd == INTER || pmbmd -> m_dctMd == INTERQ);
  1159. assert (pmbmd->m_rgTranspStatus [0] != ALL);
  1160. Int iQuantMax = (1<<m_volmd.uiQuantPrecision) - 1;
  1161. if (pmbmd -> m_stepSize < 1)
  1162. pmbmd -> m_stepSize = 1;
  1163. else if (pmbmd -> m_stepSize > iQuantMax)
  1164. pmbmd -> m_stepSize = iQuantMax;
  1165. Int iQP = pmbmd->m_stepSize;
  1166. #ifdef __TRACE_AND_STATS_
  1167. m_statsMB.nQMB++;
  1168. m_statsMB.nQp += iQP;
  1169. #endif // __TRACE_AND_STATS_
  1170. // INTERLACE
  1171. if ((pmbmd->m_rgTranspStatus [0] == NONE) && (m_vopmd.bInterlace == TRUE)) {
  1172. pmbmd->m_bFieldDCT = FrameFieldDCTDecideI(m_ppxliErrorMBY);
  1173. m_statsMB.nFieldDCTMB += (Int) pmbmd->m_bFieldDCT;
  1174. }
  1175. else
  1176. pmbmd->m_bFieldDCT = 0;
  1177. Bool bMBCoded = FALSE;
  1178. // ~INTERLACE
  1179. Int iQPA = 0;
  1180. pmbmd->m_CODAlpha = ALPHA_CODED;
  1181. Int iBlkEnd = V_BLOCK;
  1182. if(m_volmd.fAUsage == EIGHT_BIT)
  1183. {
  1184. iBlkEnd = A_BLOCK4;
  1185. if (pmbmd -> m_stepSizeAlpha < 1)
  1186. pmbmd -> m_stepSizeAlpha = 1;
  1187. iQPA = pmbmd->m_stepSizeAlpha;
  1188. Int i, iThresh = 256 - iQPA;
  1189. pmbmd->m_CODAlpha = ALPHA_ALL255;
  1190. for(i = 0; i<MB_SQUARE_SIZE; i++)
  1191. if(m_ppxlcCurrMBA[i] <= iThresh)
  1192. {
  1193. pmbmd->m_CODAlpha = ALPHA_CODED;
  1194. break;
  1195. }
  1196. }
  1197. // Bool bSkip = pmbmd->m_bhas4MVForward ? (bSkipAllowed && pmv [1].isZero () && pmv [2].isZero () && pmv [3].isZero () && pmv [4].isZero ())
  1198. //  : bSkipAllowed && pmv->isZero ();
  1199. Int* rgiBlkCurrQ = m_ppxliErrorMBY;
  1200. Int* rgiCoefQ;
  1201. Int iWidthCurrQ;
  1202. Bool bSkipAlpha = TRUE;
  1203. for (UInt iBlk = (UInt) Y_BLOCK1; iBlk <= (UInt)iBlkEnd; iBlk++) { 
  1204. if (iBlk < (UInt) U_BLOCK || iBlk> (UInt) V_BLOCK) {
  1205. if (pmbmd -> m_rgTranspStatus [iBlk % 6] == ALL) 
  1206. continue;
  1207. switch (iBlk) 
  1208. {
  1209. case (Y_BLOCK1): 
  1210. rgiBlkCurrQ = m_ppxliErrorMBY;
  1211. break;
  1212. case (Y_BLOCK2): 
  1213. rgiBlkCurrQ = m_ppxliErrorMBY + BLOCK_SIZE;
  1214. break;
  1215. case (Y_BLOCK3): 
  1216. rgiBlkCurrQ = m_ppxliErrorMBY + MB_SIZE * BLOCK_SIZE;
  1217. break;
  1218. case (Y_BLOCK4): 
  1219. rgiBlkCurrQ = m_ppxliErrorMBY + MB_SIZE * BLOCK_SIZE + BLOCK_SIZE;
  1220. break;
  1221. case (A_BLOCK1): 
  1222. rgiBlkCurrQ = m_ppxliErrorMBA;
  1223. break;
  1224. case (A_BLOCK2): 
  1225. rgiBlkCurrQ = m_ppxliErrorMBA + BLOCK_SIZE;
  1226. break;
  1227. case (A_BLOCK3): 
  1228. rgiBlkCurrQ = m_ppxliErrorMBA + MB_SIZE * BLOCK_SIZE;
  1229. break;
  1230. case (A_BLOCK4): 
  1231. rgiBlkCurrQ = m_ppxliErrorMBA + MB_SIZE * BLOCK_SIZE + BLOCK_SIZE;
  1232. break;
  1233. }
  1234. iWidthCurrQ = MB_SIZE;
  1235. }
  1236. else {
  1237. iWidthCurrQ = BLOCK_SIZE;
  1238. rgiBlkCurrQ = (iBlk == U_BLOCK) ? m_ppxliErrorMBU: m_ppxliErrorMBV;
  1239. }
  1240. rgiCoefQ = m_rgpiCoefQ [iBlk - 1];
  1241. if(iBlk>=A_BLOCK1)
  1242. quantizeTextureInterBlock (rgiBlkCurrQ, iWidthCurrQ, rgiCoefQ, iQPA, TRUE);
  1243. else
  1244. quantizeTextureInterBlock (rgiBlkCurrQ, iWidthCurrQ, rgiCoefQ, iQP, FALSE);
  1245. Bool bCoded = FALSE;
  1246. UInt i;
  1247. for (i = 0; i < BLOCK_SQUARE_SIZE; i++) {
  1248. if (rgiCoefQ [i] != 0) {
  1249. bCoded = TRUE;
  1250. bMBCoded = TRUE;
  1251. break;
  1252. }
  1253. }
  1254. if(iBlk<A_BLOCK1)
  1255. bSkip = bSkip & !bCoded;
  1256. else
  1257. bSkipAlpha = bSkipAlpha & !bCoded;
  1258. pmbmd->setCodedBlockPattern ((BlockNum) iBlk, bCoded);
  1259. }
  1260. pmbmd->m_bSkip = bSkip; 
  1261. if(m_volmd.fAUsage == EIGHT_BIT)
  1262. {
  1263. if(bSkipAlpha == TRUE)
  1264. pmbmd->m_CODAlpha = ALPHA_SKIPPED;
  1265. else if(pmbmd->m_CODAlpha == ALPHA_ALL255)
  1266. {
  1267. PixelC *ppxlc = ppxlcCurrQMBA;
  1268. Int i;
  1269. for(i = 0; i<MB_SIZE; i++, ppxlc += m_iFrameWidthY)
  1270. pxlcmemset(ppxlc, 255, MB_SIZE);
  1271. }
  1272. }
  1273. // INTERLACE
  1274. if ((pmbmd->m_rgTranspStatus [0] == NONE)
  1275. &&(m_vopmd.bInterlace == TRUE) && (pmbmd->m_bFieldDCT == TRUE) 
  1276. && (bMBCoded == TRUE))
  1277. fieldDCTtoFrameI(m_ppxliErrorMBY);
  1278. // ~INTERLACE
  1279. }
  1280. Void CVideoObjectEncoder::sendDCTCoefOfInterMBTexture (const CMBMode* pmbmd) 
  1281. {
  1282. assert (pmbmd != NULL);
  1283. assert (pmbmd -> m_dctMd == INTER || pmbmd -> m_dctMd == INTERQ);
  1284. assert (pmbmd -> m_rgTranspStatus [0] != ALL);
  1285. UInt nBits, iBlk = 0;
  1286. for (iBlk = Y_BLOCK1; iBlk <= V_BLOCK; iBlk++) {
  1287. #ifdef __TRACE_AND_STATS_
  1288. m_pbitstrmOut->trace (iBlk, "BLK_NO");
  1289. #endif // __TRACE_AND_STATS_
  1290. if (iBlk < U_BLOCK)
  1291. if (pmbmd -> m_rgTranspStatus [iBlk] == ALL) continue;
  1292. if (pmbmd->getCodedBlockPattern ((BlockNum) iBlk)) {
  1293. Int* rgiCoefQ = m_rgpiCoefQ [iBlk - 1];
  1294. #ifdef __TRACE_AND_STATS_
  1295. m_pbitstrmOut->trace (rgiCoefQ, BLOCK_SQUARE_SIZE, "BLK_QUANTIZED_COEF");
  1296. #endif // __TRACE_AND_STATS_
  1297. // Modified for data partitioning mode by Toshiba(1998-1-16)
  1298. if(m_volmd.bDataPartitioning && m_volmd.bReversibleVlc && m_vopmd.vopPredType != BVOP)
  1299. nBits = sendTCOEFInterRVLC (rgiCoefQ, 0, grgiStandardZigzag, TRUE);
  1300. else
  1301. nBits = sendTCOEFInter (rgiCoefQ, 0,
  1302.                 m_vopmd.bAlternateScan ? grgiVerticalZigzag : grgiStandardZigzag);
  1303. // End Toshiba(1998-1-16)
  1304. switch (iBlk) {
  1305. case U_BLOCK: 
  1306. m_statsMB.nBitsCr += nBits;
  1307. break;
  1308. case V_BLOCK: 
  1309. m_statsMB.nBitsCb += nBits;
  1310. break;
  1311. default:
  1312. m_statsMB.nBitsY += nBits;
  1313. }
  1314. }
  1315. }
  1316. }
  1317. Void CVideoObjectEncoder::sendDCTCoefOfIntraMBTexture (const CMBMode* pmbmd) 
  1318. {
  1319. assert (pmbmd != NULL);
  1320. assert (pmbmd -> m_dctMd == INTRA || pmbmd -> m_dctMd == INTRAQ);
  1321. assert (pmbmd->m_rgTranspStatus [0] != ALL);
  1322. UInt iBlk = 0;
  1323. for (iBlk = Y_BLOCK1; iBlk <= V_BLOCK; iBlk++) {
  1324. UInt nBits = 0;
  1325. #ifdef __TRACE_AND_STATS_
  1326. m_pbitstrmOut->trace (iBlk, "BLK_NO");
  1327. #endif // __TRACE_AND_STATS_
  1328. if (iBlk < U_BLOCK)
  1329. if (pmbmd -> m_rgTranspStatus [iBlk] == ALL) continue;
  1330. Int* rgiCoefQ = m_rgpiCoefQ [iBlk - 1];
  1331. #ifdef __TRACE_AND_STATS_
  1332. m_pbitstrmOut->trace (rgiCoefQ, BLOCK_SQUARE_SIZE, "BLK_QUANTIZED_COEF");
  1333. #endif // __TRACE_AND_STATS_
  1334. Int iCoefStart = 0;
  1335. if (pmbmd->m_bCodeDcAsAc != TRUE) {
  1336. iCoefStart = 1;
  1337. nBits = sendIntraDC (rgiCoefQ, (BlockNum) iBlk);
  1338. }
  1339. if (pmbmd->getCodedBlockPattern ((BlockNum) iBlk)) {
  1340. Int* rgiZigzag = grgiStandardZigzag;
  1341.             if (m_vopmd.bAlternateScan)
  1342.                 rgiZigzag = grgiVerticalZigzag;
  1343.             else if (pmbmd->m_bACPrediction)
  1344. rgiZigzag = (pmbmd->m_preddir [iBlk - 1] == HORIZONTAL) ? grgiVerticalZigzag : grgiHorizontalZigzag;
  1345. // Modified for data partitioning mode by Toshiba(1998-1-16)
  1346. if(m_volmd.bDataPartitioning && m_volmd.bReversibleVlc && m_vopmd.vopPredType != BVOP)
  1347. nBits += sendTCOEFIntraRVLC (rgiCoefQ, iCoefStart, rgiZigzag, TRUE);
  1348. else
  1349. nBits += sendTCOEFIntra (rgiCoefQ, iCoefStart, rgiZigzag);
  1350. // End Toshiba(1998-1-16)
  1351. }
  1352. switch (iBlk) {
  1353. case U_BLOCK: 
  1354. m_statsMB.nBitsCr += nBits;
  1355. break;
  1356. case V_BLOCK: 
  1357. m_statsMB.nBitsCb += nBits;
  1358. break;
  1359. default:
  1360. m_statsMB.nBitsY += nBits;
  1361. }
  1362. }
  1363. }
  1364. UInt CVideoObjectEncoder::sumAbsCurrMB ()
  1365. {
  1366. PixelC* ppxlcCurrMBY = m_ppxlcCurrMBY;
  1367. UInt uisumAbs = 0;
  1368. Int ic;
  1369. for (ic = 0; ic < MB_SQUARE_SIZE; ic++) {
  1370. uisumAbs += ppxlcCurrMBY [ic];
  1371. }
  1372. return uisumAbs;
  1373. }
  1374. Void CVideoObjectEncoder::codeMBAlphaHeadOfIVOP (const CMBMode* pmbmd)
  1375. {
  1376. // get CBPA
  1377. Int CBPA = 0;
  1378. UInt cNonTrnspBlk = 0, iBlk;
  1379. for (iBlk = (UInt) A_BLOCK1; iBlk <= (UInt) A_BLOCK4; iBlk++) {
  1380. if (pmbmd->m_rgTranspStatus [iBlk - 6] != ALL)
  1381. cNonTrnspBlk++;
  1382. }
  1383. UInt iBitPos = 1;
  1384. for (iBlk = (UInt) A_BLOCK1; iBlk <= (UInt) A_BLOCK4; iBlk++) {
  1385. if (pmbmd->m_rgTranspStatus [iBlk - 6] != ALL) {
  1386. CBPA |= pmbmd->getCodedBlockPattern ((BlockNum) iBlk) << (cNonTrnspBlk - iBitPos);
  1387. iBitPos++;
  1388. }
  1389. }
  1390. assert (CBPA >= 0 && CBPA <= 15);
  1391. Int iCODA = 0;
  1392. if(pmbmd->m_CODAlpha==ALPHA_ALL255)
  1393. iCODA = 1;
  1394. m_pbitstrmOut->putBits(iCODA, 1, "MB_CODA");
  1395. m_statsMB.nBitsCODA++;
  1396. if(iCODA)
  1397. return;
  1398. m_pbitstrmOut->putBits (pmbmd->m_bACPredictionAlpha, 1, "MB_ACPRED_ALPHA");
  1399. m_statsMB.nBitsIntraPred++;
  1400. #ifdef __TRACE_AND_STATS_
  1401. m_pbitstrmOut->trace (CBPA, "MB_CBPA");
  1402. #endif // __TRACE_AND_STATS_
  1403. switch (cNonTrnspBlk) {
  1404. case 1:
  1405. m_statsMB.nBitsCBPA += m_pentrencSet->m_pentrencCBPY1->encodeSymbol (1 - CBPA, "MB_CBPA");
  1406. break;
  1407. case 2:
  1408. m_statsMB.nBitsCBPA += m_pentrencSet->m_pentrencCBPY2->encodeSymbol (3 - CBPA, "MB_CBPA");
  1409. break;
  1410. case 3:
  1411. m_statsMB.nBitsCBPA += m_pentrencSet->m_pentrencCBPY3->encodeSymbol (7 - CBPA, "MB_CBPA");
  1412. break;
  1413. case 4:
  1414. m_statsMB.nBitsCBPA += m_pentrencSet->m_pentrencCBPY->encodeSymbol (15 - CBPA, "MB_CBPA");
  1415. break;
  1416. default:
  1417. assert (FALSE);
  1418. }
  1419. }
  1420. Void CVideoObjectEncoder::codeMBAlphaHeadOfPVOP (const CMBMode* pmbmd)
  1421. {
  1422. if(pmbmd -> m_dctMd == INTRA || pmbmd -> m_dctMd == INTRAQ)
  1423. codeMBAlphaHeadOfIVOP(pmbmd);
  1424. else
  1425. {
  1426. // get CBPA
  1427. Int CBPA = 0;
  1428. UInt cNonTrnspBlk = 0, iBlk;
  1429. for (iBlk = (UInt) A_BLOCK1; iBlk <= (UInt) A_BLOCK4; iBlk++) {
  1430. if (pmbmd->m_rgTranspStatus [iBlk - 6] != ALL)
  1431. cNonTrnspBlk++;
  1432. }
  1433. UInt iBitPos = 1;
  1434. for (iBlk = (UInt) A_BLOCK1; iBlk <= (UInt) A_BLOCK4; iBlk++) {
  1435. if (pmbmd->m_rgTranspStatus [iBlk - 6] != ALL) {
  1436. CBPA |= pmbmd->getCodedBlockPattern ((BlockNum) iBlk) << (cNonTrnspBlk - iBitPos);
  1437. iBitPos++;
  1438. }
  1439. }
  1440. assert (CBPA >= 0 && CBPA <= 15);
  1441. if(pmbmd->m_CODAlpha==ALPHA_CODED)
  1442. {
  1443. m_pbitstrmOut->putBits(0, 2, "MB_CODA");
  1444. m_statsMB.nBitsCODA += 2;
  1445. }
  1446. else if(pmbmd->m_CODAlpha==ALPHA_ALL255)
  1447. {
  1448. m_pbitstrmOut->putBits(1, 2, "MB_CODA");
  1449. m_statsMB.nBitsCODA += 2;
  1450. return;
  1451. }
  1452. else // ALPHA_SKIPPED
  1453. {
  1454. m_pbitstrmOut->putBits(1, 1, "MB_CODA");
  1455. m_statsMB.nBitsCODA ++;
  1456. return;
  1457. }
  1458. #ifdef __TRACE_AND_STATS_
  1459. m_pbitstrmOut->trace (CBPA, "MB_CBPA");
  1460. #endif // __TRACE_AND_STATS_
  1461. switch (cNonTrnspBlk) {
  1462. case 1:
  1463. m_statsMB.nBitsCBPA += m_pentrencSet->m_pentrencCBPY1->encodeSymbol (1 - CBPA, "MB_CBPA");
  1464. break;
  1465. case 2:
  1466. m_statsMB.nBitsCBPA += m_pentrencSet->m_pentrencCBPY2->encodeSymbol (3 - CBPA, "MB_CBPA");
  1467. break;
  1468. case 3:
  1469. m_statsMB.nBitsCBPA += m_pentrencSet->m_pentrencCBPY3->encodeSymbol (7 - CBPA, "MB_CBPA");
  1470. break;
  1471. case 4:
  1472. m_statsMB.nBitsCBPA += m_pentrencSet->m_pentrencCBPY->encodeSymbol (15 - CBPA, "MB_CBPA");
  1473. break;
  1474. default:
  1475. assert (FALSE);
  1476. }
  1477. }
  1478. }
  1479. Void CVideoObjectEncoder::sendDCTCoefOfIntraMBAlpha (const CMBMode* pmbmd)
  1480. {
  1481. assert (pmbmd != NULL);
  1482. assert (pmbmd -> m_dctMd == INTRA || pmbmd -> m_dctMd == INTRAQ);
  1483. assert (pmbmd->m_rgTranspStatus [0] != ALL);
  1484. if(pmbmd->m_CODAlpha != ALPHA_CODED)
  1485. return;
  1486. UInt iBlk;
  1487. for (iBlk = A_BLOCK1; iBlk <= A_BLOCK4; iBlk++) {
  1488. UInt nBits = 0;
  1489. #ifdef __TRACE_AND_STATS_
  1490. m_pbitstrmOut->trace (iBlk, "ALPHA_BLK_NO");
  1491. #endif // __TRACE_AND_STATS_
  1492. if (pmbmd -> m_rgTranspStatus [iBlk - 6 ] == ALL)
  1493. continue;
  1494. Int* rgiCoefQ = m_rgpiCoefQ [iBlk - 1];
  1495. #ifdef __TRACE_AND_STATS_
  1496. m_pbitstrmOut->trace (rgiCoefQ, BLOCK_SQUARE_SIZE, "BLK_QUANTIZED_COEF");
  1497. #endif // __TRACE_AND_STATS_
  1498. Int iCoefStart = 0;
  1499. if (pmbmd->m_bCodeDcAsAcAlpha != TRUE) {
  1500. iCoefStart = 1;
  1501. nBits = sendIntraDC (rgiCoefQ, (BlockNum) iBlk);
  1502. }
  1503. if (pmbmd->getCodedBlockPattern ((BlockNum) iBlk)) {
  1504. Int* rgiZigzag = grgiStandardZigzag;
  1505. if (pmbmd->m_bACPredictionAlpha)
  1506. rgiZigzag = (pmbmd->m_preddir [iBlk - 1] == HORIZONTAL) ? grgiVerticalZigzag : grgiHorizontalZigzag;
  1507. nBits += sendTCOEFIntra (rgiCoefQ, iCoefStart, rgiZigzag);
  1508. }
  1509. m_statsMB.nBitsA += nBits;
  1510. }
  1511. }
  1512. Void CVideoObjectEncoder::sendDCTCoefOfInterMBAlpha (const CMBMode* pmbmd)
  1513. {
  1514. assert (pmbmd != NULL);
  1515. assert (pmbmd -> m_dctMd == INTER || pmbmd -> m_dctMd == INTERQ);
  1516. assert (pmbmd -> m_rgTranspStatus [0] != ALL);
  1517. assert (pmbmd -> m_CODAlpha == ALPHA_CODED);
  1518. UInt nBits, iBlk = 0;
  1519. for (iBlk = A_BLOCK1; iBlk <= A_BLOCK4; iBlk++) {
  1520. #ifdef __TRACE_AND_STATS_
  1521. m_pbitstrmOut->trace (iBlk, "BLK_NO");
  1522. #endif // __TRACE_AND_STATS_
  1523. if (pmbmd -> m_rgTranspStatus [iBlk - 6] == ALL) continue;
  1524. if (pmbmd->getCodedBlockPattern ((BlockNum) iBlk)) {
  1525. Int* rgiCoefQ = m_rgpiCoefQ [iBlk - 1];
  1526. #ifdef __TRACE_AND_STATS_
  1527. m_pbitstrmOut->trace (rgiCoefQ, BLOCK_SQUARE_SIZE, "BLK_QUANTIZED_COEF");
  1528. #endif // __TRACE_AND_STATS_
  1529. nBits = sendTCOEFInter (rgiCoefQ, 0, grgiStandardZigzag);
  1530. m_statsMB.nBitsA += nBits;
  1531. }
  1532. }
  1533. }
  1534. Void CVideoObjectEncoder::codeMBAlphaHeadOfBVOP (const CMBMode* pmbmd)
  1535. {
  1536. // get CBPA
  1537. Int CBPA = 0;
  1538. UInt cNonTrnspBlk = 0, iBlk;
  1539. for (iBlk = (UInt) A_BLOCK1; iBlk <= (UInt) A_BLOCK4; iBlk++) {
  1540. if (pmbmd->m_rgTranspStatus [iBlk - 6] != ALL)
  1541. cNonTrnspBlk++;
  1542. }
  1543. UInt iBitPos = 1;
  1544. for (iBlk = (UInt) A_BLOCK1; iBlk <= (UInt) A_BLOCK4; iBlk++) {
  1545. if (pmbmd->m_rgTranspStatus [iBlk - 6] != ALL) {
  1546. CBPA |= pmbmd->getCodedBlockPattern ((BlockNum) iBlk) << (cNonTrnspBlk - iBitPos);
  1547. iBitPos++;
  1548. }
  1549. }
  1550. assert (CBPA >= 0 && CBPA <= 15);
  1551. if(pmbmd->m_CODAlpha==ALPHA_CODED)
  1552. {
  1553. m_pbitstrmOut->putBits(0, 2, "MB_CODBA");
  1554. m_statsMB.nBitsCODA += 2;
  1555. }
  1556. else if(pmbmd->m_CODAlpha==ALPHA_ALL255)
  1557. {
  1558. m_pbitstrmOut->putBits(1, 2, "MB_CODBA");
  1559. m_statsMB.nBitsCODA += 2;
  1560. return;
  1561. }
  1562. else // ALPHA_SKIPPED
  1563. {
  1564. m_pbitstrmOut->putBits(1, 1, "MB_CODBA");
  1565. m_statsMB.nBitsCODA ++;
  1566. return;
  1567. }
  1568. #ifdef __TRACE_AND_STATS_
  1569. m_pbitstrmOut->trace (CBPA, "MB_CBPBA");
  1570. #endif // __TRACE_AND_STATS_
  1571. switch (cNonTrnspBlk) {
  1572. case 1:
  1573. m_statsMB.nBitsCBPA += m_pentrencSet->m_pentrencCBPY1->encodeSymbol (1 - CBPA, "MB_CBPA");
  1574. break;
  1575. case 2:
  1576. m_statsMB.nBitsCBPA += m_pentrencSet->m_pentrencCBPY2->encodeSymbol (3 - CBPA, "MB_CBPA");
  1577. break;
  1578. case 3:
  1579. m_statsMB.nBitsCBPA += m_pentrencSet->m_pentrencCBPY3->encodeSymbol (7 - CBPA, "MB_CBPA");
  1580. break;
  1581. case 4:
  1582. m_statsMB.nBitsCBPA += m_pentrencSet->m_pentrencCBPY->encodeSymbol (15 - CBPA, "MB_CBPA");
  1583. break;
  1584. default:
  1585. assert (FALSE);
  1586. }
  1587. }