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

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. /*************************************************************************
  2. This software module was originally developed by 
  3. Yoshihiro Kikuchi (TOSHIBA CORPORATION)
  4. Takeshi Nagai (TOSHIBA CORPORATION)
  5.     and edited by:
  6. Toshiaki Watanabe (TOSHIBA CORPORATION)
  7. Noboru Yamaguchi (TOSHIBA CORPORATION)
  8. and also edited by 
  9. Xuemin Chen (xchen@nlvl.com) Next Level System, Inc.
  10. Bob Eifrig (beifrig@nlvl.com) Next Level Systems, Inc.
  11.   in the course of development of the <MPEG-4 Video(ISO/IEC 14496-2)>. This
  12.   software module is an implementation of a part of one or more <MPEG-4 Video
  13.   (ISO/IEC 14496-2)> tools as specified by the <MPEG-4 Video(ISO/IEC 14496-2)
  14.   >. ISO/IEC gives users of the <MPEG-4 Video(ISO/IEC 14496-2)> free license
  15.   to this software module or modifications thereof for use in hardware or
  16.   software products claiming conformance to the <MPEG-4 Video(ISO/IEC 14496-2
  17.   )>. Those intending to use this software module in hardware or software
  18.   products are advised that its use may infringe existing patents. The
  19.   original developer of this software module and his/her company, the
  20.   subsequent editors and their companies, and ISO/IEC have no liability for
  21.   use of this software module or modifications thereof in an implementation.
  22.   Copyright is not released for non <MPEG-4 Video(ISO/IEC 14496-2)>
  23.   conforming products. TOSHIBA CORPORATION retains full right to use the code
  24.   for his/her own purpose, assign or donate the code to a third party and to
  25.   inhibit third parties from using the code for non <MPEG-4 Video(ISO/IEC
  26.   14496-2)> conforming products. This copyright notice must be included in
  27.   all copies or derivative works.
  28.   Copyright (c)1997.
  29. Revision History:
  30. May 9, 1999: tm5 rate control by DemoGraFX, duhoff@mediaone.net
  31. *************************************************************************/
  32. #include <stdio.h>
  33. #include <math.h>
  34. #include <stdlib.h>
  35. #include <iostream.h>
  36. #include "typeapi.h"
  37. #include "codehead.h"
  38. #include "entropy/bitstrm.hpp"
  39. #include "entropy/entropy.hpp"
  40. #include "entropy/huffman.hpp"
  41. #include "mode.hpp"
  42. #include "global.hpp"
  43. #include "vopses.hpp"
  44. #include "vopseenc.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. // inline functions
  53. inline Int clog2(Int a) {return ( ((a)<=0) ? 0 : (int) ceil( log10( (double) (a) ) / log10(2.0) ) );}
  54. Void CVideoObjectEncoder::VideoPacketResetVOP(
  55. )
  56. {
  57. m_iVPCounter = m_pbitstrmOut -> getCounter(); // reset coding bits counter
  58. assert(m_iNumMBX>0 && m_iNumMBY>0);
  59. m_numBitsVPMBnum = clog2 (m_iNumMBX * m_iNumMBY); // number of bits for macroblock_number
  60. m_numVideoPacket = 1; // reset number of video packet in a VOP
  61. m_iVPMBnum = 0; // start MB in the 1st VP
  62. }
  63. Void CVideoObjectEncoder::codeVideoPacketHeader (
  64. Int iMBX, Int iMBY, Int QuantScale
  65. )
  66. {
  67. m_iVPMBnum = VPMBnum(iMBX, iMBY);
  68. m_statsVOP.nBitsHead += codeVideoPacketHeader(QuantScale);
  69. }
  70. #if 0 // revised HEC for shape
  71. Int CVideoObjectEncoder::codeVideoPacketHeader (Int QuantScale)
  72. {
  73. #ifdef __TRACE_AND_STATS_
  74. m_pbitstrmOut->trace ("Video_Packet_Headern");
  75. #endif // __TRACE_AND_STATS_
  76. UInt nBits = 0;
  77. assert(m_iVPMBnum > 0 && m_iVPMBnum < m_iNumMBX * m_iNumMBY);
  78. assert(QuantScale > 0 && QuantScale < 32);
  79. m_pbitstrmOut->flush ();
  80. Int nBitsResyncMarker = NUMBITS_VP_RESYNC_MARKER;
  81. if(m_volmd.bShapeOnly==FALSE)
  82. {
  83. if(m_vopmd.vopPredType == PVOP)
  84. nBitsResyncMarker += (m_vopmd.mvInfoForward.uiFCode - 1);
  85. else if(m_vopmd.vopPredType == BVOP)
  86. nBitsResyncMarker += max(m_vopmd.mvInfoForward.uiFCode, m_vopmd.mvInfoBackward.uiFCode) - 1;
  87. }
  88. m_pbitstrmOut -> putBits (RESYNC_MARKER, nBitsResyncMarker, "resync_marker");
  89. m_pbitstrmOut -> putBits (m_iVPMBnum, m_numBitsVPMBnum, "VPH_macroblock_number");
  90. if(m_volmd.bShapeOnly==FALSE) {
  91. m_pbitstrmOut -> putBits (QuantScale, NUMBITS_VP_QUANTIZER, "VPH_quant_scale");
  92. }
  93. Bool HEC = ((++m_numVideoPacket) == 2); // use HEC in 2nd VP
  94. m_pbitstrmOut -> putBits (HEC, NUMBITS_VP_HEC, "VPH_header_extension_code");
  95. #ifdef __TRACE_AND_STATS_
  96. nBits += nBitsResyncMarker + m_numBitsVPMBnum + NUMBITS_VP_QUANTIZER + NUMBITS_VP_HEC;
  97. #endif // __TRACE_AND_STATS_
  98. if( HEC == TRUE ) {
  99. m_pbitstrmOut -> putBits ((Int) 0xFFFFFFFE, (UInt) m_nBitsModuloBase + 1, "VPH_Modulo_Time_Base");
  100. m_pbitstrmOut->putBits ((Int) 1, 1, "Marker"); // marker bit
  101. m_pbitstrmOut -> putBits (m_iVopTimeIncr, m_iNumBitsTimeIncr, "VPH_Time_Incr");
  102. m_pbitstrmOut->putBits ((Int) 1, 1, "Marker"); // marker bit
  103. m_pbitstrmOut -> putBits (m_vopmd.vopPredType, NUMBITS_VP_PRED_TYPE, "VPH_Pred_Type");
  104. #ifdef __TRACE_AND_STATS_
  105. nBits += m_nBitsModuloBase+1 + m_iNumBitsTimeIncr +2 + NUMBITS_VP_PRED_TYPE + NUMBITS_VP_INTRA_DC_SWITCH_THR;
  106. #endif // __TRACE_AND_STATS_
  107. if(m_volmd.bShapeOnly==FALSE) {
  108. m_pbitstrmOut -> putBits (m_vopmd.iIntraDcSwitchThr, NUMBITS_VP_INTRA_DC_SWITCH_THR, "VOP_DC_VLC_Switch");
  109. if(m_vopmd.vopPredType != IVOP) {
  110. m_pbitstrmOut -> putBits (m_vopmd.mvInfoForward.uiFCode, NUMBITS_VOP_FCODE, "VPH_Fcode_Forward");
  111. #ifdef __TRACE_AND_STATS_
  112. nBits += NUMBITS_VOP_FCODE;
  113. #endif // __TRACE_AND_STATS_
  114. if (m_vopmd.vopPredType == BVOP) {
  115. m_pbitstrmOut -> putBits (m_vopmd.mvInfoBackward.uiFCode, NUMBITS_VOP_FCODE, "VOP_Fcode_Backward");
  116. #ifdef __TRACE_AND_STATS_
  117. nBits += NUMBITS_VOP_FCODE;
  118. #endif // __TRACE_AND_STATS_
  119. }
  120. }
  121. }
  122. }
  123. return nBits;
  124. }
  125. #else
  126. Int CVideoObjectEncoder::codeVideoPacketHeader (Int QuantScale)
  127. {
  128. #ifdef __TRACE_AND_STATS_
  129. m_pbitstrmOut->trace ("Video_Packet_Headern");
  130. #endif // __TRACE_AND_STATS_
  131. UInt nBits = 0;
  132. assert(m_iVPMBnum > 0 && m_iVPMBnum < m_iNumMBX * m_iNumMBY);
  133. assert(QuantScale > 0 && QuantScale < 32);
  134. m_pbitstrmOut->flush ();
  135. Int nBitsResyncMarker = NUMBITS_VP_RESYNC_MARKER;
  136. Bool HEC = ((++m_numVideoPacket) == 2); // use HEC in 2nd VP
  137. if(m_volmd.bShapeOnly==FALSE)
  138. {
  139. if(m_vopmd.vopPredType == PVOP)
  140. nBitsResyncMarker += (m_vopmd.mvInfoForward.uiFCode - 1);
  141. else if(m_vopmd.vopPredType == BVOP)
  142. nBitsResyncMarker += max(m_vopmd.mvInfoForward.uiFCode, m_vopmd.mvInfoBackward.uiFCode) - 1;
  143. }
  144. m_pbitstrmOut -> putBits (RESYNC_MARKER, nBitsResyncMarker, "resync_marker");
  145. if(m_volmd.fAUsage != RECTANGLE) {
  146. m_pbitstrmOut -> putBits (HEC, NUMBITS_VP_HEC, "VPH_header_extension_code");
  147. if (HEC == TRUE && !(m_uiSprite == 1 && m_vopmd.vopPredType == IVOP)) {
  148. m_pbitstrmOut->putBits (m_rctCurrVOPY.width, NUMBITS_VOP_WIDTH, "VPH_VOP_Width");
  149. m_pbitstrmOut->putBits ((Int) 1, 1, "Marker"); // marker bit
  150. m_pbitstrmOut->putBits (m_rctCurrVOPY.height (), NUMBITS_VOP_HEIGHT, "VPH_VOP_Height");
  151. m_pbitstrmOut->putBits ((Int) 1, 1, "Marker"); // marker bit
  152. #ifdef __TRACE_AND_STATS_
  153. nBits += NUMBITS_VOP_WIDTH + NUMBITS_VOP_HEIGHT + 2;
  154. #endif // __TRACE_AND_STATS_
  155. if (m_rctCurrVOPY.left >= 0) {
  156. m_pbitstrmOut -> putBits (m_rctCurrVOPY.left, NUMBITS_VOP_HORIZONTAL_SPA_REF, "VPH_VOP_Hori_Ref");
  157. } else {
  158. m_pbitstrmOut -> putBits (m_rctCurrVOPY.left & 0x00001FFFF, NUMBITS_VOP_HORIZONTAL_SPA_REF, "VPH_VOP_Hori_Ref");
  159. }
  160. m_pbitstrmOut->putBits ((Int) 1, 1, "Marker"); // marker bit
  161. if (m_rctCurrVOPY.top >= 0) {
  162. m_pbitstrmOut -> putBits (m_rctCurrVOPY.top, NUMBITS_VOP_VERTICAL_SPA_REF, "VPH_VOP_Vert_Ref");
  163. } else {
  164. m_pbitstrmOut -> putBits (m_rctCurrVOPY.top & 0x00001FFFF, NUMBITS_VOP_VERTICAL_SPA_REF, "VPH_VOP_Vert_Ref");
  165. }
  166. m_pbitstrmOut->putBits ((Int) 1, 1, "Marker"); // marker bit
  167. #ifdef __TRACE_AND_STATS_
  168. nBits += NUMBITS_VOP_HORIZONTAL_SPA_REF + NUMBITS_VOP_VERTICAL_SPA_REF + 2;
  169. #endif // __TRACE_AND_STATS_
  170. }
  171. }
  172. m_pbitstrmOut -> putBits (m_iVPMBnum, m_numBitsVPMBnum, "VPH_macroblock_number");
  173. if(m_volmd.bShapeOnly==FALSE) {
  174. m_pbitstrmOut -> putBits (QuantScale, NUMBITS_VP_QUANTIZER, "VPH_quant_scale");
  175. }
  176. if(m_volmd.fAUsage == RECTANGLE)
  177. m_pbitstrmOut -> putBits (HEC, NUMBITS_VP_HEC, "VPH_header_extension_code");
  178. #ifdef __TRACE_AND_STATS_
  179. nBits += nBitsResyncMarker + m_numBitsVPMBnum + NUMBITS_VP_QUANTIZER + NUMBITS_VP_HEC;
  180. #endif // __TRACE_AND_STATS_
  181. if( HEC == TRUE ) {
  182. m_pbitstrmOut -> putBits ((Int) 0xFFFFFFFE, (UInt) m_nBitsModuloBase + 1, "VPH_Modulo_Time_Base");
  183. m_pbitstrmOut->putBits ((Int) 1, 1, "Marker"); // marker bit
  184. m_pbitstrmOut -> putBits (m_iVopTimeIncr, m_iNumBitsTimeIncr, "VPH_Time_Incr");
  185. m_pbitstrmOut->putBits ((Int) 1, 1, "Marker"); // marker bit
  186. m_pbitstrmOut -> putBits (m_vopmd.vopPredType, NUMBITS_VP_PRED_TYPE, "VPH_Pred_Type");
  187. #ifdef __TRACE_AND_STATS_
  188. nBits += m_nBitsModuloBase+1 + m_iNumBitsTimeIncr +2 + NUMBITS_VP_PRED_TYPE + NUMBITS_VP_INTRA_DC_SWITCH_THR;
  189. #endif // __TRACE_AND_STATS_
  190. if(m_volmd.fAUsage != RECTANGLE) {
  191. m_pbitstrmOut->putBits (m_volmd.bNoCrChange, 1, "VPH_VOP_CR_Change_Disable");
  192. #ifdef __TRACE_AND_STATS_
  193. nBits ++;
  194. #endif // __TRACE_AND_STATS_
  195. if (m_volmd.bShapeOnly==FALSE && m_vopmd.vopPredType != IVOP)  
  196. {  
  197. m_pbitstrmOut -> putBits (m_vopmd.bShapeCodingType, 1, "VPH_shape_coding_type");
  198. #ifdef __TRACE_AND_STATS_
  199. nBits ++;
  200. #endif // __TRACE_AND_STATS_
  201. }
  202. }
  203. if(m_volmd.bShapeOnly==FALSE) {
  204. m_pbitstrmOut -> putBits (m_vopmd.iIntraDcSwitchThr, NUMBITS_VP_INTRA_DC_SWITCH_THR, "VOP_DC_VLC_Switch");
  205. if(m_vopmd.vopPredType != IVOP) {
  206. m_pbitstrmOut -> putBits (m_vopmd.mvInfoForward.uiFCode, NUMBITS_VOP_FCODE, "VPH_Fcode_Forward");
  207. #ifdef __TRACE_AND_STATS_
  208. nBits += NUMBITS_VOP_FCODE;
  209. #endif // __TRACE_AND_STATS_
  210. if (m_vopmd.vopPredType == BVOP) {
  211. m_pbitstrmOut -> putBits (m_vopmd.mvInfoBackward.uiFCode, NUMBITS_VOP_FCODE, "VOP_Fcode_Backward");
  212. #ifdef __TRACE_AND_STATS_
  213. nBits += NUMBITS_VOP_FCODE;
  214. #endif // __TRACE_AND_STATS_
  215. }
  216. }
  217. }
  218. }
  219. return nBits;
  220. }
  221. #endif
  222. UInt CVideoObjectEncoder::encodeMVVP (const CMotionVector* pmv, const CMBMode* pmbmd, Int iMBX, Int iMBY)
  223. {
  224. Int iMBnum = iMBY * m_iNumMBX + iMBX;
  225. assert(iMBnum >= m_iVPMBnum);
  226. return encodeMV (pmv, pmbmd, bVPNoLeft(iMBnum, iMBX), bVPNoRightTop(iMBnum, iMBX), bVPNoTop(iMBnum),
  227. iMBX, iMBY);
  228. }
  229. //////////////////////////////////////////////////////////////////
  230. ////  The following functions are for Data partitioning mode  ////
  231. //////////////////////////////////////////////////////////////////
  232. Void CVideoObjectEncoder::encodeNSForPVOP_DP ()
  233. {
  234. assert( m_volmd.bDataPartitioning );
  235. assert( m_vopmd.vopPredType==PVOP );
  236. //assert(m_volmd.nBits==8);
  237. if (m_uiSprite == 0) //low latency: not motion esti
  238. motionEstPVOP ();
  239. // Rate Control
  240. if (m_uiRateControl == RC_MPEG4) {
  241. Double Ec = m_iMAD / (Double) (m_iNumMBY * m_iNumMBX * 16 * 16);
  242. m_statRC.setMad (Ec);
  243. if (m_statRC.noCodedFrame () >= RC_START_RATE_CONTROL) {
  244. UInt newQStep = m_statRC.updateQuanStepsize ();
  245. m_vopmd.intStepDiff = newQStep - m_vopmd.intStep; // DQUANT
  246. m_vopmd.intStep = newQStep;
  247. }
  248. cout << "t" << "Q:" << "ttt" << m_vopmd.intStep << "n";
  249. m_statRC.setQc (m_vopmd.intStep);
  250. }
  251. // MB rate control
  252. //Int iIndexofQ = 0;
  253. //Int rgiQ [4] = {-1, -2, 1, 2};
  254. // -----
  255. Int iMBX, iMBY;
  256. CoordI y = 0; 
  257. CMBMode* pmbmd = m_rgmbmd;
  258. Int iQPPrev = m_vopmd.intStep;
  259. CMotionVector* pmv = m_rgmv;
  260. PixelC* ppxlcRefY = (PixelC*) m_pvopcRefQ1->pixelsY () + m_iStartInRefToCurrRctY;
  261. PixelC* ppxlcRefU = (PixelC*) m_pvopcRefQ1->pixelsU () + m_iStartInRefToCurrRctUV;
  262. PixelC* ppxlcRefV = (PixelC*) m_pvopcRefQ1->pixelsV () + m_iStartInRefToCurrRctUV;
  263. PixelC* ppxlcOrigY = (PixelC*) m_pvopcOrig->pixelsBoundY ();
  264. PixelC* ppxlcOrigU = (PixelC*) m_pvopcOrig->pixelsBoundU ();
  265. PixelC* ppxlcOrigV = (PixelC*) m_pvopcOrig->pixelsBoundV ();
  266. Int iVPCounter = m_statsVOP.total();
  267. Int iVPtotal;
  268. m_iVPMBnum = 0;
  269. CStatistics m_statsVP;
  270. // DCT coefficient buffer for Data Partitioning mode
  271. Int*** iCoefQ_DP = new Int** [m_iNumMB];
  272. // Set not to output but count bitstream
  273. m_pbitstrmOut->SetDontSendBits(TRUE);
  274. Bool bRestartDelayedQP = TRUE;
  275. for (iMBY = 0; iMBY < m_iNumMBY; iMBY++, y += MB_SIZE) {
  276. PixelC* ppxlcRefMBY = ppxlcRefY;
  277. PixelC* ppxlcRefMBU = ppxlcRefU;
  278. PixelC* ppxlcRefMBV = ppxlcRefV;
  279. PixelC* ppxlcOrigMBY = ppxlcOrigY;
  280. PixelC* ppxlcOrigMBU = ppxlcOrigU;
  281. PixelC* ppxlcOrigMBV = ppxlcOrigV;
  282. CoordI x = 0; 
  283. for (iMBX = 0; iMBX < m_iNumMBX; iMBX++, x += MB_SIZE) {
  284. ////#ifdef __TRACE_AND_STATS_
  285. //// m_statsMB.reset ();
  286. //// m_pbitstrmOut->trace (CSite (iMBX, iMBY), "MB_X_Y");
  287. ////#endif // __TRACE_AND_STATS_
  288. m_statsMB.reset ();
  289. // MB rate control
  290. //pmbmd->m_intStepDelta = 0;
  291. //iIndexofQ = (iIndexofQ + 1) % 4;
  292. //if (!pmbmd ->m_bhas4MVForward && !pmbmd ->m_bSkip) {
  293. // if (pmbmd ->m_dctMd == INTRA)
  294. // pmbmd ->m_dctMd == INTRAQ;
  295. // else if (pmbmd ->m_dctMd == INTER)
  296. // pmbmd->m_dctMd = INTERQ;
  297. // pmbmd->m_intStepDelta = rgiQ [iIndexofQ];
  298. //}
  299. // -----
  300. pmbmd->m_stepSize = iQPPrev + pmbmd->m_intStepDelta;
  301. if(bRestartDelayedQP)
  302. pmbmd->m_stepSizeDelayed = pmbmd->m_stepSize;
  303. else
  304. pmbmd->m_stepSizeDelayed = iQPPrev;
  305. copyToCurrBuff (ppxlcOrigMBY, ppxlcOrigMBU, ppxlcOrigMBV, m_iFrameWidthY, m_iFrameWidthUV); 
  306. encodePVOPMB (
  307. ppxlcRefMBY, ppxlcRefMBU, ppxlcRefMBV,
  308. pmbmd, pmv,
  309. iMBX, iMBY,
  310. x, y
  311. );
  312. Int iVPlastMBnum = iMBY * m_iNumMBX + iMBX;
  313. // copy DCT coefficient to buffer
  314. iCoefQ_DP[iVPlastMBnum] = new Int* [6];
  315. Int iBlk;
  316. for (iBlk = 0; iBlk < 6; iBlk++) {
  317. iCoefQ_DP [iVPlastMBnum] [iBlk] = new Int [BLOCK_SQUARE_SIZE];
  318. for( Int t = 0; t < BLOCK_SQUARE_SIZE; t++ )
  319. iCoefQ_DP[iVPlastMBnum][iBlk][t] = m_rgpiCoefQ[iBlk][t];
  320. }
  321. if (!pmbmd->m_bSkip)
  322. {
  323. iQPPrev = pmbmd->m_stepSize;
  324. bRestartDelayedQP = FALSE;
  325. }
  326. pmbmd++;
  327. pmv += PVOP_MV_PER_REF_PER_MB;
  328. #ifdef __TRACE_AND_STATS_
  329. m_statsVOP += m_statsMB;
  330. #endif // __TRACE_AND_STATS_
  331. ppxlcRefMBY += MB_SIZE;
  332. ppxlcRefMBU += BLOCK_SIZE;
  333. ppxlcRefMBV += BLOCK_SIZE;
  334. ppxlcOrigMBY += MB_SIZE;
  335. ppxlcOrigMBU += BLOCK_SIZE;
  336. ppxlcOrigMBV += BLOCK_SIZE;
  337. iVPtotal = (int) m_statsVOP.total() - iVPCounter;
  338. if( iVPtotal > m_volmd.bVPBitTh || iVPlastMBnum == m_iNumMB-1 /* last MB in a VOP */) {
  339. // Set to output bitstream
  340. m_pbitstrmOut->SetDontSendBits(FALSE);
  341. // encode video packet
  342. iVPCounter = m_statsVOP.total();
  343. m_statsVP.reset();
  344. if( m_iVPMBnum > 0 )
  345. {
  346. m_statsVP.nBitsHead = codeVideoPacketHeader (m_rgmbmd[m_iVPMBnum].m_stepSize);
  347. bRestartDelayedQP = TRUE;
  348. }
  349. DataPartitioningMotionCoding(m_iVPMBnum, iVPlastMBnum, &m_statsVP, iCoefQ_DP);
  350. m_pbitstrmOut -> putBits (MOTION_MARKER, NUMBITS_DP_MOTION_MARKER, "motion_marker");
  351. m_statsVP.nBitsHead += NUMBITS_DP_MOTION_MARKER;
  352. DataPartitioningTextureCoding(m_iVPMBnum, iVPlastMBnum, &m_statsVP, iCoefQ_DP);
  353. //assert( iVPtotal + m_statsVP.nBitsHead == (int) m_statsVP.total() );
  354. m_iVPMBnum = iVPlastMBnum + 1;
  355. // Set not to output but count bitstream
  356. m_pbitstrmOut->SetDontSendBits(TRUE);
  357. }
  358. }
  359. MacroBlockMemory** ppmbmTemp = m_rgpmbmAbove;
  360. m_rgpmbmAbove = m_rgpmbmCurr;
  361. m_rgpmbmCurr  = ppmbmTemp;
  362. ppxlcRefY += m_iFrameWidthYxMBSize;
  363. ppxlcRefU += m_iFrameWidthUVxBlkSize;
  364. ppxlcRefV += m_iFrameWidthUVxBlkSize;
  365. ppxlcOrigY += m_iFrameWidthYxMBSize;
  366. ppxlcOrigU += m_iFrameWidthUVxBlkSize;
  367. ppxlcOrigV += m_iFrameWidthUVxBlkSize;
  368. }
  369. // delete CoefQ_DP
  370. for( Int iMB = 0; iMB < m_iNumMB; iMB++ )  {
  371. for (Int iBlk = 0; iBlk < 6; iBlk++) {
  372. delete [] iCoefQ_DP [iMB] [iBlk];
  373. }
  374. delete [] iCoefQ_DP[iMB];
  375. }
  376. delete [] iCoefQ_DP;
  377. // Set to output bitstream
  378. m_pbitstrmOut->SetDontSendBits(FALSE);
  379. }
  380. Void CVideoObjectEncoder::encodeNSForIVOP_DP ()
  381. {
  382. assert( m_volmd.bDataPartitioning );
  383. assert( m_vopmd.vopPredType==IVOP );
  384. //assert(m_volmd.nBits==8);
  385. // bug fix by toshiba 98-9-24 start
  386. //in case the IVOP is used as an ref for direct mode
  387. memset (m_rgmv, 0, m_iNumMB * PVOP_MV_PER_REF_PER_MB * sizeof (CMotionVector));
  388. // bug fix by toshiba 98-9-24 end
  389. CMBMode* pmbmd = m_rgmbmd;
  390. Int iQPPrev = m_vopmd.intStepI; //initialization
  391. PixelC* ppxlcRefY  = (PixelC*) m_pvopcRefQ1->pixelsY () + m_iStartInRefToCurrRctY;
  392. PixelC* ppxlcRefU  = (PixelC*) m_pvopcRefQ1->pixelsU () + m_iStartInRefToCurrRctUV;
  393. PixelC* ppxlcRefV  = (PixelC*) m_pvopcRefQ1->pixelsV () + m_iStartInRefToCurrRctUV;
  394. PixelC* ppxlcOrigY = (PixelC*) m_pvopcOrig->pixelsBoundY ();
  395. PixelC* ppxlcOrigU = (PixelC*) m_pvopcOrig->pixelsBoundU ();
  396. PixelC* ppxlcOrigV = (PixelC*) m_pvopcOrig->pixelsBoundV ();
  397. // MB rate control
  398. //Int iIndexofQ = 0;
  399. //Int rgiQ [4] = {-1, -2, 1, 2};
  400. // -----
  401. Int iMBX, iMBY;
  402. Int iVPCounter = m_statsVOP.total();
  403. Int iVPtotal;
  404. m_iVPMBnum = 0;
  405. CStatistics m_statsVP;
  406. // DCT coefficient buffer for Data Partitioning mode
  407. Int*** iCoefQ_DP = new Int** [m_iNumMB];
  408. // Set not to output but count bitstream
  409. m_pbitstrmOut->SetDontSendBits(TRUE);
  410. Bool bRestartDelayedQP = TRUE;
  411. for (iMBY = 0; iMBY < m_iNumMBY; iMBY++) {
  412. PixelC* ppxlcRefMBY  = ppxlcRefY;
  413. PixelC* ppxlcRefMBU  = ppxlcRefU;
  414. PixelC* ppxlcRefMBV  = ppxlcRefV;
  415. PixelC* ppxlcOrigMBY = ppxlcOrigY;
  416. PixelC* ppxlcOrigMBU = ppxlcOrigU;
  417. PixelC* ppxlcOrigMBV = ppxlcOrigV;
  418. for (iMBX = 0; iMBX < m_iNumMBX; iMBX++) {
  419. #ifdef __TRACE_AND_STATS_
  420. m_pbitstrmOut->trace (CSite (iMBX, iMBY), "MB_X_Y");
  421. #endif // __TRACE_AND_STATS_
  422. m_statsMB.reset ();
  423. // MB rate control
  424. //pmbmd->m_intStepDelta = 0;
  425. //iIndexofQ = (iIndexofQ + 1) % 4;
  426. //pmbmd->m_intStepDelta = rgiQ [iIndexofQ];
  427. // -----
  428. // bug fix by toshiba 98-9-24 start
  429. pmbmd->m_bSkip = FALSE; //reset for direct mode
  430. // bug fix by toshiba 98-9-24 end
  431. pmbmd->m_stepSize = iQPPrev + pmbmd->m_intStepDelta;
  432. if(bRestartDelayedQP)
  433. {
  434. pmbmd->m_stepSizeDelayed = pmbmd->m_stepSize;
  435. bRestartDelayedQP = FALSE;
  436. }
  437. else
  438. pmbmd->m_stepSizeDelayed = iQPPrev;
  439. iQPPrev = pmbmd->m_stepSize;
  440. if (pmbmd->m_intStepDelta == 0)
  441. pmbmd->m_dctMd = INTRA;
  442. else
  443. pmbmd->m_dctMd = INTRAQ;
  444. copyToCurrBuff (ppxlcOrigMBY, ppxlcOrigMBU, ppxlcOrigMBV, m_iFrameWidthY, m_iFrameWidthUV); 
  445. quantizeTextureIntraMB (iMBX, iMBY, pmbmd, ppxlcRefMBY, ppxlcRefMBU, ppxlcRefMBV, NULL);
  446. codeMBTextureHeadOfIVOP (pmbmd);
  447. sendDCTCoefOfIntraMBTexture (pmbmd);
  448. Int iVPlastMBnum = iMBY * m_iNumMBX + iMBX;
  449. // copy DCT coefficient to buffer
  450. iCoefQ_DP[iVPlastMBnum] = new Int* [6];
  451. Int iBlk;
  452. for (iBlk = 0; iBlk < 6; iBlk++) {
  453. iCoefQ_DP [iVPlastMBnum] [iBlk] = new Int [BLOCK_SQUARE_SIZE];
  454. for( Int t = 0; t < BLOCK_SQUARE_SIZE; t++ )
  455. iCoefQ_DP[iVPlastMBnum][iBlk][t] = m_rgpiCoefQ[iBlk][t];
  456. }
  457. pmbmd++;
  458. #ifdef __TRACE_AND_STATS_
  459. m_statsVOP   += m_statsMB;
  460. #endif // __TRACE_AND_STATS_
  461. ppxlcRefMBY  += MB_SIZE;
  462. ppxlcRefMBU  += BLOCK_SIZE;
  463. ppxlcRefMBV  += BLOCK_SIZE;
  464. ppxlcOrigMBY += MB_SIZE;
  465. ppxlcOrigMBU += BLOCK_SIZE;
  466. ppxlcOrigMBV += BLOCK_SIZE;
  467. iVPtotal = (int) m_statsVOP.total() - iVPCounter;
  468. if( iVPtotal > m_volmd.bVPBitTh || iVPlastMBnum == m_iNumMB-1 /* last MB in a VOP */) {
  469. // Set to output bitstream
  470. m_pbitstrmOut->SetDontSendBits(FALSE);
  471. // encode video packet
  472. iVPCounter = m_statsVOP.total();
  473. m_statsVP.reset();
  474. if( m_iVPMBnum > 0 )
  475. {
  476. m_statsVP.nBitsHead = codeVideoPacketHeader (m_rgmbmd[m_iVPMBnum].m_stepSize);
  477. bRestartDelayedQP = TRUE;
  478. }
  479. DataPartitioningMotionCoding(m_iVPMBnum, iVPlastMBnum, &m_statsVP, iCoefQ_DP);
  480. m_pbitstrmOut -> putBits (DC_MARKER, NUMBITS_DP_DC_MARKER, "DC_marker");
  481. m_statsVP.nBitsHead += NUMBITS_DP_DC_MARKER;
  482. DataPartitioningTextureCoding(m_iVPMBnum, iVPlastMBnum, &m_statsVP, iCoefQ_DP);
  483. //assert( iVPtotal + m_statsVP.nBitsHead == (int) m_statsVP.total() );
  484. m_iVPMBnum = iVPlastMBnum + 1;
  485. // Set not to output but count bitstream
  486. m_pbitstrmOut->SetDontSendBits(TRUE);
  487. }
  488. }
  489. MacroBlockMemory** ppmbmTemp = m_rgpmbmAbove;
  490. m_rgpmbmAbove = m_rgpmbmCurr;
  491. m_rgpmbmCurr  = ppmbmTemp;
  492. ppxlcRefY  += m_iFrameWidthYxMBSize;
  493. ppxlcRefU  += m_iFrameWidthUVxBlkSize;
  494. ppxlcRefV  += m_iFrameWidthUVxBlkSize;
  495. ppxlcOrigY += m_iFrameWidthYxMBSize;
  496. ppxlcOrigU += m_iFrameWidthUVxBlkSize;
  497. ppxlcOrigV += m_iFrameWidthUVxBlkSize;
  498. }
  499. // delete CoefQ_DP
  500. for( Int iMB = 0; iMB < m_iNumMB; iMB++ )  {
  501. for (Int iBlk = 0; iBlk < 6; iBlk++) {
  502. delete [] iCoefQ_DP [iMB] [iBlk];
  503. }
  504. delete [] iCoefQ_DP[iMB];
  505. }
  506. delete [] iCoefQ_DP;
  507. // Set to output bitstream
  508. m_pbitstrmOut->SetDontSendBits(FALSE);
  509. }
  510. Void CVideoObjectEncoder::DataPartitioningMotionCoding(Int iVPMBnum, Int iVPlastMBnum, CStatistics* m_statsVP, Int*** iCoefQ_DP)
  511. {
  512. assert( m_volmd.bDataPartitioning );
  513. Int iMBnum;
  514. CMBMode* pmbmd;
  515. CMotionVector* pmv = m_rgmv;
  516. Int iMBX, iMBY;
  517. for(iMBnum = iVPMBnum, pmbmd = m_rgmbmd+iVPMBnum, pmv = m_rgmv+iVPMBnum*PVOP_MV_PER_REF_PER_MB;
  518. iMBnum <= iVPlastMBnum; iMBnum++, pmbmd++, pmv+=PVOP_MV_PER_REF_PER_MB) {
  519. iMBX = iMBnum % m_iNumMBX;
  520. iMBY = iMBnum / m_iNumMBX;
  521. #ifdef __TRACE_AND_STATS_
  522. m_pbitstrmOut->trace (CSite (iMBX, iMBY), "Motion_MB_X_Y");
  523. #endif // __TRACE_AND_STATS_
  524. if( m_volmd.fAUsage != RECTANGLE ) {
  525. m_statsVP->nBitsShape += dumpCachedShapeBits_DP(iMBnum);
  526. }
  527. if (pmbmd -> m_rgTranspStatus [0] != ALL) {
  528. if( m_vopmd.vopPredType==PVOP ) {
  529. m_pbitstrmOut->putBits (pmbmd->m_bSkip, 1, "MB_Skip");
  530. m_statsVP->nBitsCOD++;
  531. }
  532. if (!pmbmd->m_bSkip) {
  533. UInt CBPC = (pmbmd->getCodedBlockPattern (U_BLOCK) << 1)
  534. | pmbmd->getCodedBlockPattern (V_BLOCK);
  535. //per defintion of H.263's CBPC 
  536. assert (CBPC >= 0 && CBPC <= 3);
  537. Int iMBtype; //per H.263's MBtype
  538. Int iSymbol;
  539. switch( m_vopmd.vopPredType ) {
  540. case PVOP:
  541. if (pmbmd->m_dctMd == INTRA || pmbmd->m_dctMd == INTRAQ)
  542. iMBtype = pmbmd->m_dctMd + 3;
  543. else
  544. iMBtype = (pmbmd -> m_dctMd - 2) | pmbmd -> m_bhas4MVForward << 1;
  545. assert (iMBtype >= 0 && iMBtype <= 4);
  546. #ifdef __TRACE_AND_STATS_
  547. m_pbitstrmOut->trace (iMBtype, "MB_MBtype");
  548. m_pbitstrmOut->trace (CBPC, "MB_CBPC");
  549. #endif // __TRACE_AND_STATS_
  550. m_statsVP->nBitsMCBPC += m_pentrencSet->m_pentrencMCBPCinter->encodeSymbol (iMBtype * 4 + CBPC, "MCBPC");
  551. break;
  552. case IVOP:
  553. iSymbol = 4 * pmbmd->m_dctMd + CBPC;
  554. assert (iSymbol >= 0 && iSymbol <= 7); //send MCBPC
  555. #ifdef __TRACE_AND_STATS_
  556. m_pbitstrmOut->trace (CBPC, "MB_CBPC");
  557. #endif // __TRACE_AND_STATS_
  558. m_statsVP->nBitsMCBPC += m_pentrencSet->m_pentrencMCBPCintra->encodeSymbol (iSymbol, "MB_MCBPC");
  559. break;
  560. default:
  561. assert(FALSE);
  562. }
  563. if ( m_vopmd.vopPredType == IVOP ) {
  564. if( pmbmd->m_dctMd == INTRAQ) {
  565. Int DQUANT = pmbmd->m_intStepDelta; //send DQUANT
  566. assert (DQUANT >= -2 && DQUANT <= 2);
  567. if (DQUANT != 0) {
  568. if (sign (DQUANT) == 1)
  569. m_pbitstrmOut->putBits (DQUANT + 1, 2, "MB_DQUANT");
  570. else
  571. m_pbitstrmOut->putBits (-1 - DQUANT, 2, "MB_DQUANT");
  572. m_statsVP->nBitsDQUANT += 2;
  573. }
  574. }  
  575. UInt iBlk = 0;
  576. for (iBlk = Y_BLOCK1; iBlk <= V_BLOCK; iBlk++) {
  577. UInt nBits = 0;
  578. #ifdef __TRACE_AND_STATS_
  579. m_pbitstrmOut->trace (iBlk, "BLK_NO");
  580. #endif // __TRACE_AND_STATS_
  581. if (iBlk < U_BLOCK)
  582. if (pmbmd -> m_rgTranspStatus [iBlk] == ALL) continue;
  583. Int* rgiCoefQ = iCoefQ_DP [iMBnum][iBlk - 1];
  584. #ifdef __TRACE_AND_STATS_
  585. m_pbitstrmOut->trace (rgiCoefQ[0], "IntraDC");
  586. #endif // __TRACE_AND_STATS_
  587. if (pmbmd->m_bCodeDcAsAc != TRUE) {
  588. nBits = sendIntraDC (rgiCoefQ, (BlockNum) iBlk);
  589. }
  590. switch (iBlk) {
  591. case U_BLOCK: 
  592. m_statsVP->nBitsCr += nBits;
  593. break;
  594. case V_BLOCK: 
  595. m_statsVP->nBitsCb += nBits;
  596. break;
  597. default:
  598. m_statsVP->nBitsY += nBits;
  599. }
  600. }
  601. }
  602. if (pmbmd->m_dctMd != INTRA && pmbmd->m_dctMd != INTRAQ) {
  603. if( m_volmd.fAUsage == RECTANGLE )
  604. m_statsVP->nBitsMV += encodeMVVP (pmv, pmbmd, iMBX, iMBY);
  605. else
  606. m_statsVP->nBitsMV += encodeMVWithShape (pmv, pmbmd, iMBX, iMBY);
  607. }
  608. }
  609. }
  610. }
  611. }
  612. Void CVideoObjectEncoder::DataPartitioningTextureCoding(Int iVPMBnum, Int iVPlastMBnum, CStatistics* m_statsVP, Int*** iCoefQ_DP)
  613. {
  614. assert( m_volmd.bDataPartitioning );
  615. Int iMBnum;
  616. CMBMode* pmbmd;
  617. CMotionVector* pmv = m_rgmv;
  618. Int iMBX, iMBY;
  619. for(iMBnum = iVPMBnum, pmbmd = m_rgmbmd+iVPMBnum, pmv = m_rgmv+iVPMBnum*PVOP_MV_PER_REF_PER_MB;
  620. iMBnum <= iVPlastMBnum; iMBnum++, pmbmd++, pmv+=PVOP_MV_PER_REF_PER_MB) {
  621. if (pmbmd->m_bSkip || pmbmd -> m_rgTranspStatus [0] == ALL)
  622. continue;
  623. iMBX = iMBnum % m_iNumMBX;
  624. iMBY = iMBnum / m_iNumMBX;
  625. #ifdef __TRACE_AND_STATS_
  626. m_pbitstrmOut->trace (CSite (iMBX, iMBY), "TextureHeader_MB_X_Y");
  627. #endif // __TRACE_AND_STATS_
  628. Int CBPY = 0;
  629. UInt cNonTrnspBlk = 0, iBlk;
  630. for (iBlk = (UInt) Y_BLOCK1; iBlk <= (UInt) Y_BLOCK4; iBlk++) {
  631. if (pmbmd->m_rgTranspStatus [iBlk] != ALL)
  632. cNonTrnspBlk++;
  633. }
  634. UInt iBitPos = 1;
  635. for (iBlk = (UInt) Y_BLOCK1; iBlk <= (UInt) Y_BLOCK4; iBlk++) {
  636. if (pmbmd->m_rgTranspStatus [iBlk] != ALL) {
  637. CBPY |= pmbmd->getCodedBlockPattern ((BlockNum) iBlk) << (cNonTrnspBlk - iBitPos);
  638. iBitPos++;
  639. }
  640. }
  641. assert (CBPY >= 0 && CBPY <= 15); //per defintion of H.263's CBPY 
  642. if (m_volmd.fAUsage == RECTANGLE)
  643. assert (cNonTrnspBlk==4); // Only all opaque is only supportedin DP mode at present
  644. if (pmbmd->m_dctMd == INTRA || pmbmd->m_dctMd == INTRAQ) {
  645. m_pbitstrmOut->putBits (pmbmd->m_bACPrediction, 1, "MB_ACPRED");
  646. m_statsVP->nBitsIntraPred++;
  647. #ifdef __TRACE_AND_STATS_
  648. m_pbitstrmOut->trace (cNonTrnspBlk, "MB_NumNonTranspBlks");
  649. m_pbitstrmOut->trace (CBPY, "MB_CBPY (I-style)");
  650. #endif // __TRACE_AND_STATS_
  651. switch (cNonTrnspBlk) {
  652. case 1:
  653. m_statsVP->nBitsCBPY += m_pentrencSet->m_pentrencCBPY1->encodeSymbol (CBPY, "MB_CBPY1");
  654. break;
  655. case 2:
  656. m_statsVP->nBitsCBPY += m_pentrencSet->m_pentrencCBPY2->encodeSymbol (CBPY, "MB_CBPY2");
  657. break;
  658. case 3:
  659. m_statsVP->nBitsCBPY += m_pentrencSet->m_pentrencCBPY3->encodeSymbol (CBPY, "MB_CBPY3");
  660. break;
  661. case 4:
  662. m_statsVP->nBitsCBPY += m_pentrencSet->m_pentrencCBPY->encodeSymbol (CBPY, "MB_CBPY");
  663. break;
  664. default:
  665. assert (FALSE);
  666. }
  667. m_statsVP->nIntraMB++;
  668. }
  669. else {
  670. #ifdef __TRACE_AND_STATS_
  671. m_pbitstrmOut->trace (cNonTrnspBlk, "MB_NumNonTranspBlks");
  672. m_pbitstrmOut->trace (CBPY, "MB_CBPY (P-style)");
  673. #endif // __TRACE_AND_STATS_
  674. switch (cNonTrnspBlk) {
  675. case 1:
  676. m_statsVP->nBitsCBPY += m_pentrencSet->m_pentrencCBPY1->encodeSymbol (1 - CBPY, "MB_CBPY1");
  677. break;
  678. case 2:
  679. m_statsVP->nBitsCBPY += m_pentrencSet->m_pentrencCBPY2->encodeSymbol (3 - CBPY, "MB_CBPY2");
  680. break;
  681. case 3:
  682. m_statsVP->nBitsCBPY += m_pentrencSet->m_pentrencCBPY3->encodeSymbol (7 - CBPY, "MB_CBPY3");
  683. break;
  684. case 4:
  685. m_statsVP->nBitsCBPY += m_pentrencSet->m_pentrencCBPY->encodeSymbol (15 - CBPY, "MB_CBPY");
  686. break;
  687. default:
  688. assert (FALSE);
  689. }
  690. }
  691. if ( m_vopmd.vopPredType != IVOP &&
  692. (pmbmd->m_dctMd == INTERQ || pmbmd->m_dctMd == INTRAQ)) {
  693. Int DQUANT = pmbmd->m_intStepDelta; //send DQUANT
  694. assert (DQUANT >= -2 && DQUANT <= 2);
  695. if (DQUANT != 0) {
  696. if (sign (DQUANT) == 1)
  697. m_pbitstrmOut->putBits (DQUANT + 1, 2, "MB_DQUANT");
  698. else
  699. m_pbitstrmOut->putBits (-1 - DQUANT, 2, "MB_DQUANT");
  700. m_statsVP->nBitsDQUANT += 2;
  701. }
  702. }  
  703. if (m_vopmd.vopPredType != IVOP &&
  704. (pmbmd->m_dctMd == INTRA || pmbmd->m_dctMd == INTRAQ)) {
  705. UInt iBlk = 0;
  706. for (iBlk = Y_BLOCK1; iBlk <= V_BLOCK; iBlk++) {
  707. UInt nBits = 0;
  708. #ifdef __TRACE_AND_STATS_
  709. m_pbitstrmOut->trace (iBlk, "BLK_NO");
  710. #endif // __TRACE_AND_STATS_
  711. if (iBlk < U_BLOCK)
  712. if (pmbmd -> m_rgTranspStatus [iBlk] == ALL) continue;
  713. //// Int* rgiCoefQ = m_rgpiCoefQ [iBlk - 1];
  714. Int* rgiCoefQ = iCoefQ_DP [iMBnum][iBlk - 1];
  715. #ifdef __TRACE_AND_STATS_
  716. //// m_pbitstrmOut->trace (rgiCoefQ, BLOCK_SQUARE_SIZE, "BLK_QUANTIZED_COEF");
  717. m_pbitstrmOut->trace (rgiCoefQ[0], "IntraDC");
  718. #endif // __TRACE_AND_STATS_
  719. //// Int iCoefStart = 0;
  720. if (pmbmd->m_bCodeDcAsAc != TRUE) {
  721. //// iCoefStart = 1;
  722. nBits = sendIntraDC (rgiCoefQ, (BlockNum) iBlk);
  723. }
  724. switch (iBlk) {
  725. case U_BLOCK: 
  726. m_statsVP->nBitsCr += nBits;
  727. break;
  728. case V_BLOCK: 
  729. m_statsVP->nBitsCb += nBits;
  730. break;
  731. default:
  732. m_statsVP->nBitsY += nBits;
  733. }
  734. }
  735. }
  736. }
  737. for(iMBnum = iVPMBnum, pmbmd = m_rgmbmd+iVPMBnum, pmv = m_rgmv+iVPMBnum*PVOP_MV_PER_REF_PER_MB;
  738. iMBnum <= iVPlastMBnum; iMBnum++, pmbmd++, pmv+=PVOP_MV_PER_REF_PER_MB) {
  739. if (pmbmd->m_bSkip || pmbmd -> m_rgTranspStatus [0] == ALL)
  740. continue;
  741. iMBX = iMBnum % m_iNumMBX;
  742. iMBY = iMBnum / m_iNumMBX;
  743. #ifdef __TRACE_AND_STATS_
  744. m_pbitstrmOut->trace (CSite (iMBX, iMBY), "TextureTcoef_MB_X_Y");
  745. #endif // __TRACE_AND_STATS_
  746. if (pmbmd->m_dctMd == INTRA || pmbmd->m_dctMd == INTRAQ) {
  747. UInt iBlk = 0;
  748. for (iBlk = Y_BLOCK1; iBlk <= V_BLOCK; iBlk++) {
  749. UInt nBits = 0;
  750. #ifdef __TRACE_AND_STATS_
  751. m_pbitstrmOut->trace (iBlk, "BLK_NO");
  752. #endif // __TRACE_AND_STATS_
  753. if (iBlk < U_BLOCK)
  754. if (pmbmd -> m_rgTranspStatus [iBlk] == ALL) continue;
  755. //// Int* rgiCoefQ = m_rgpiCoefQ [iBlk - 1];
  756. Int* rgiCoefQ = iCoefQ_DP [iMBnum][iBlk - 1];
  757. #ifdef __TRACE_AND_STATS_
  758. m_pbitstrmOut->trace (rgiCoefQ, BLOCK_SQUARE_SIZE, "BLK_QUANTIZED_COEF");
  759. #endif // __TRACE_AND_STATS_
  760. Int iCoefStart;
  761. if (pmbmd->m_bCodeDcAsAc != TRUE) {
  762. iCoefStart = 1;
  763. } else {
  764. iCoefStart = 0;
  765. }
  766. if (pmbmd->getCodedBlockPattern ((BlockNum) iBlk)) {
  767. Int* rgiZigzag = grgiStandardZigzag;
  768. if (pmbmd->m_bACPrediction)
  769. rgiZigzag = (pmbmd->m_preddir [iBlk - 1] == HORIZONTAL) ? grgiVerticalZigzag : grgiHorizontalZigzag;
  770. if( m_volmd.bReversibleVlc == TRUE )
  771. nBits += sendTCOEFIntraRVLC (rgiCoefQ, iCoefStart, rgiZigzag, FALSE);
  772. else
  773. nBits += sendTCOEFIntra (rgiCoefQ, iCoefStart, rgiZigzag);
  774. }
  775. switch (iBlk) {
  776. case U_BLOCK: 
  777. m_statsVP->nBitsCr += nBits;
  778. break;
  779. case V_BLOCK: 
  780. m_statsVP->nBitsCb += nBits;
  781. break;
  782. default:
  783. m_statsVP->nBitsY += nBits;
  784. }
  785. }
  786. } else {
  787. UInt nBits, iBlk = 0;
  788. for (iBlk = Y_BLOCK1; iBlk <= V_BLOCK; iBlk++) {
  789. #ifdef __TRACE_AND_STATS_
  790. m_pbitstrmOut->trace (iBlk, "BLK_NO");
  791. #endif // __TRACE_AND_STATS_
  792. if (iBlk < U_BLOCK)
  793. if (pmbmd -> m_rgTranspStatus [iBlk] == ALL) continue;
  794. if (pmbmd->getCodedBlockPattern ((BlockNum) iBlk)) {
  795. //// Int* rgiCoefQ = m_rgpiCoefQ [iBlk - 1];
  796. Int* rgiCoefQ = iCoefQ_DP [iMBnum][iBlk - 1];
  797. #ifdef __TRACE_AND_STATS_
  798. m_pbitstrmOut->trace (rgiCoefQ, BLOCK_SQUARE_SIZE, "BLK_QUANTIZED_COEF");
  799. #endif // __TRACE_AND_STATS_
  800. if( m_volmd.bReversibleVlc == TRUE )
  801. nBits = sendTCOEFInterRVLC (rgiCoefQ, 0, grgiStandardZigzag, FALSE);
  802. else
  803. nBits = sendTCOEFInter (rgiCoefQ, 0, grgiStandardZigzag);
  804. switch (iBlk) {
  805. case U_BLOCK: 
  806. m_statsVP->nBitsCr += nBits;
  807. break;
  808. case V_BLOCK: 
  809. m_statsVP->nBitsCb += nBits;
  810. break;
  811. default:
  812. m_statsVP->nBitsY += nBits;
  813. }
  814. }
  815. }
  816. }
  817. }
  818. }
  819. Void CVideoObjectEncoder::encodeNSForIVOP_WithShape_DP ()
  820. {
  821. assert( m_volmd.bDataPartitioning );
  822. assert( m_vopmd.vopPredType==IVOP );
  823. assert( m_volmd.fAUsage == ONE_BIT && m_volmd.bShapeOnly == FALSE );
  824. assert(m_volmd.nBits==8);
  825. //in case the IVOP is used as an ref for direct mode
  826. memset (m_rgmv, 0, m_iNumMB * PVOP_MV_PER_REF_PER_MB * sizeof (CMotionVector));
  827. //#ifdef __SHARP_FIX_
  828. memset (m_rgmvBY, 0, m_iNumMB * sizeof (CMotionVector));
  829. //#endif
  830. Int iMBX, iMBY;
  831. CMBMode* pmbmd = m_rgmbmd;
  832. Int iQPPrev = m_vopmd.intStepI; //initialization
  833. Int iVPCounter = m_statsVOP.total();
  834. Int iVPtotal;
  835. m_iVPMBnum = 0;
  836. CStatistics m_statsVP;
  837. // DCT coefficient buffer for Data Partitioning mode
  838. Int*** iCoefQ_DP = new Int** [m_iNumMB];
  839. // Set not to output but count bitstream
  840. // m_pbitstrmOut->SetDontSendBits(TRUE);
  841. PixelC* ppxlcRefY  = (PixelC*) m_pvopcRefQ1->pixelsY () + m_iStartInRefToCurrRctY;
  842. PixelC* ppxlcRefU  = (PixelC*) m_pvopcRefQ1->pixelsU () + m_iStartInRefToCurrRctUV;
  843. PixelC* ppxlcRefV  = (PixelC*) m_pvopcRefQ1->pixelsV () + m_iStartInRefToCurrRctUV;
  844. PixelC* ppxlcRefBY = (PixelC*) m_pvopcRefQ1->pixelsBY () + m_iStartInRefToCurrRctY;
  845. PixelC* ppxlcRefBUV = (PixelC*) m_pvopcRefQ1->pixelsBUV () + m_iStartInRefToCurrRctUV;
  846. PixelC *ppxlcRefA = (PixelC*) m_pvopcRefQ1->pixelsA () + m_iStartInRefToCurrRctY;
  847. PixelC* ppxlcOrigY = (PixelC*) m_pvopcOrig->pixelsBoundY ();
  848. PixelC* ppxlcOrigU = (PixelC*) m_pvopcOrig->pixelsBoundU ();
  849. PixelC* ppxlcOrigV = (PixelC*) m_pvopcOrig->pixelsBoundV ();
  850. PixelC* ppxlcOrigBY = (PixelC*) m_pvopcOrig->pixelsBoundBY ();
  851. PixelC* ppxlcOrigA = (PixelC*) m_pvopcOrig->pixelsBoundA ();
  852. Bool bRestartDelayedQP = TRUE;
  853. for (iMBY = 0; iMBY < m_iNumMBY; iMBY++) {
  854. PixelC* ppxlcRefMBY  = ppxlcRefY;
  855. PixelC* ppxlcRefMBU  = ppxlcRefU;
  856. PixelC* ppxlcRefMBV  = ppxlcRefV;
  857. PixelC* ppxlcRefMBBY = ppxlcRefBY;
  858. PixelC* ppxlcRefMBBUV = ppxlcRefBUV;
  859. PixelC* ppxlcRefMBA  = ppxlcRefA;
  860. PixelC* ppxlcOrigMBY = ppxlcOrigY;
  861. PixelC* ppxlcOrigMBU = ppxlcOrigU;
  862. PixelC* ppxlcOrigMBV = ppxlcOrigV;
  863. PixelC* ppxlcOrigMBBY = ppxlcOrigBY;
  864. PixelC* ppxlcOrigMBA = ppxlcOrigA;
  865. for (iMBX = 0; iMBX < m_iNumMBX; iMBX++) {
  866. #ifdef __TRACE_AND_STATS_
  867. m_pbitstrmOut->trace (CSite (iMBX, iMBY), "MB_X_Y");
  868. #endif // __TRACE_AND_STATS_
  869. pmbmd->m_stepSize = iQPPrev + pmbmd->m_intStepDelta;
  870. if(bRestartDelayedQP)
  871. pmbmd->m_stepSizeDelayed = pmbmd->m_stepSize;
  872. else
  873. pmbmd->m_stepSizeDelayed = iQPPrev;
  874. Int iVPlastMBnum = iMBY * m_iNumMBX + iMBX;
  875. // shape bitstream is set to shape cache
  876. m_pbitstrmShapeMBOut = m_pbitstrmShape_DP[iVPlastMBnum];
  877. m_statsMB.reset ();
  878. pmbmd->m_bSkip = FALSE; //reset for direct mode 
  879. pmbmd->m_bPadded=FALSE;
  880. copyToCurrBuffWithShape (
  881. ppxlcOrigMBY, ppxlcOrigMBU, ppxlcOrigMBV, 
  882. ppxlcOrigMBBY, ppxlcOrigMBA,
  883. m_iFrameWidthY, m_iFrameWidthUV
  884. );
  885. downSampleBY (m_ppxlcCurrMBBY, m_ppxlcCurrMBBUV); // downsample original BY now for LPE padding (using original shape)
  886. decideTransparencyStatus (pmbmd, m_ppxlcCurrMBBY);
  887. if (pmbmd -> m_rgTranspStatus [0] == PARTIAL) {
  888. LPEPadding (pmbmd);
  889. m_statsMB.nBitsShape += codeIntraShape (ppxlcRefMBBY, pmbmd, iMBX, iMBY);
  890. downSampleBY (m_ppxlcCurrMBBY, m_ppxlcCurrMBBUV);
  891. decideTransparencyStatus (pmbmd, m_ppxlcCurrMBBY); // need to modify it a little (NONE block won't change)
  892. }
  893. else
  894. m_statsMB.nBitsShape += codeIntraShape (ppxlcRefMBBY, pmbmd, iMBX, iMBY);
  895. if(m_volmd.bShapeOnly == FALSE) {
  896. // // Set not to output but count bitstream
  897. m_pbitstrmOut->SetDontSendBits(TRUE);
  898. if (pmbmd -> m_rgTranspStatus [0] != ALL) {
  899. pmbmd->m_stepSize = iQPPrev + pmbmd->m_intStepDelta;
  900. bRestartDelayedQP = FALSE;
  901. Int iQuantMax = (1<<m_volmd.uiQuantPrecision) - 1;
  902. assert (pmbmd->m_stepSize <= iQuantMax && pmbmd->m_stepSize > 0);
  903. iQPPrev = pmbmd->m_stepSize;
  904. if (pmbmd->m_intStepDelta == 0)
  905. pmbmd->m_dctMd = INTRA;
  906. else
  907. pmbmd->m_dctMd = INTRAQ;
  908. quantizeTextureIntraMB (iMBX, iMBY, pmbmd, ppxlcRefMBY, ppxlcRefMBU, ppxlcRefMBV, ppxlcRefMBA);
  909. codeMBTextureHeadOfIVOP (pmbmd);
  910. sendDCTCoefOfIntraMBTexture (pmbmd);
  911. // MC padding
  912. if (pmbmd -> m_rgTranspStatus [0] == PARTIAL)
  913. mcPadCurrMB (ppxlcRefMBY, ppxlcRefMBU, ppxlcRefMBV, ppxlcRefMBA);
  914. padNeighborTranspMBs (
  915. iMBX, iMBY,
  916. pmbmd,
  917. ppxlcRefMBY, ppxlcRefMBU, ppxlcRefMBV, ppxlcRefMBA
  918. );
  919. }
  920. else {
  921. padCurrAndTopTranspMBFromNeighbor (
  922. iMBX, iMBY,
  923. pmbmd,
  924. ppxlcRefMBY, ppxlcRefMBU, ppxlcRefMBV, ppxlcRefMBA
  925. );
  926. }
  927. // // Set to output bitstream
  928. m_pbitstrmOut->SetDontSendBits(FALSE);
  929. }
  930. // copy DCT coefficient to buffer
  931. iCoefQ_DP[iVPlastMBnum] = new Int* [6];
  932. Int iBlk;
  933. for (iBlk = 0; iBlk < 6; iBlk++) {
  934. iCoefQ_DP [iVPlastMBnum] [iBlk] = new Int [BLOCK_SQUARE_SIZE];
  935. for( Int t = 0; t < BLOCK_SQUARE_SIZE; t++ )
  936. iCoefQ_DP[iVPlastMBnum][iBlk][t] = m_rgpiCoefQ[iBlk][t];
  937. }
  938. ppxlcRefMBA += MB_SIZE;
  939. ppxlcOrigMBBY += MB_SIZE;
  940. ppxlcOrigMBA += MB_SIZE;
  941. pmbmd++;
  942. #ifdef __TRACE_AND_STATS_
  943. m_statsVOP   += m_statsMB;
  944. #endif // __TRACE_AND_STATS_
  945. ppxlcRefMBY  += MB_SIZE;
  946. ppxlcRefMBU  += BLOCK_SIZE;
  947. ppxlcRefMBV  += BLOCK_SIZE;
  948. ppxlcRefMBBY += MB_SIZE;
  949. ppxlcRefMBBUV += BLOCK_SIZE;
  950. ppxlcOrigMBY += MB_SIZE;
  951. ppxlcOrigMBU += BLOCK_SIZE;
  952. ppxlcOrigMBV += BLOCK_SIZE;
  953. iVPtotal = (int) m_statsVOP.total() - iVPCounter;
  954. if( iVPtotal > m_volmd.bVPBitTh || iVPlastMBnum == m_iNumMB-1 /* last MB in a VOP */) {
  955. // Set to output bitstream
  956. m_pbitstrmOut->SetDontSendBits(FALSE);
  957. // encode video packet
  958. iVPCounter = m_statsVOP.total();
  959. m_statsVP.reset();
  960. if( m_iVPMBnum > 0 )
  961. {
  962. m_statsVP.nBitsHead = codeVideoPacketHeader (m_rgmbmd[m_iVPMBnum].m_stepSize);
  963. bRestartDelayedQP = TRUE;
  964. }
  965. DataPartitioningMotionCoding(m_iVPMBnum, iVPlastMBnum, &m_statsVP, iCoefQ_DP);
  966. m_pbitstrmOut -> putBits (DC_MARKER, NUMBITS_DP_DC_MARKER, "DC_marker");
  967. m_statsVP.nBitsHead += NUMBITS_DP_DC_MARKER;
  968. DataPartitioningTextureCoding(m_iVPMBnum, iVPlastMBnum, &m_statsVP, iCoefQ_DP);
  969. assert( iVPtotal + m_statsVP.nBitsHead ==  m_statsVP.total() );
  970. m_iVPMBnum = iVPlastMBnum + 1;
  971. }
  972. }
  973. MacroBlockMemory** ppmbmTemp = m_rgpmbmAbove;
  974. m_rgpmbmAbove = m_rgpmbmCurr;
  975. m_rgpmbmCurr  = ppmbmTemp;
  976. ppxlcRefY  += m_iFrameWidthYxMBSize;
  977. ppxlcRefA  += m_iFrameWidthYxMBSize;
  978. ppxlcRefU  += m_iFrameWidthUVxBlkSize;
  979. ppxlcRefV  += m_iFrameWidthUVxBlkSize;
  980. ppxlcRefBY += m_iFrameWidthYxMBSize;
  981. ppxlcRefBUV += m_iFrameWidthUVxBlkSize;
  982. ppxlcOrigY += m_iFrameWidthYxMBSize;
  983. ppxlcOrigBY += m_iFrameWidthYxMBSize;
  984. ppxlcOrigA += m_iFrameWidthYxMBSize;
  985. ppxlcOrigU += m_iFrameWidthUVxBlkSize;
  986. ppxlcOrigV += m_iFrameWidthUVxBlkSize;
  987. }
  988. // delete CoefQ_DP
  989. for( Int iMB = 0; iMB < m_iNumMB; iMB++ )  {
  990. for (Int iBlk = 0; iBlk < 6; iBlk++) {
  991. delete [] iCoefQ_DP [iMB] [iBlk];
  992. }
  993. delete [] iCoefQ_DP[iMB];
  994. }
  995. delete [] iCoefQ_DP;
  996. // restore normal output stream
  997. m_pbitstrmShapeMBOut = m_pbitstrmOut;
  998. // Set to output bitstream
  999. m_pbitstrmOut->SetDontSendBits(FALSE);
  1000. }
  1001. Void CVideoObjectEncoder::encodeNSForPVOP_WithShape_DP ()
  1002. {
  1003. assert( m_volmd.bDataPartitioning );
  1004. assert( m_vopmd.vopPredType==PVOP );
  1005. assert( m_volmd.fAUsage == ONE_BIT && m_volmd.bShapeOnly == FALSE );
  1006. assert(m_volmd.nBits==8);
  1007. Int iMBX, iMBY;
  1008. motionEstPVOP_WithShape ();
  1009. // Rate Control
  1010. if (m_uiRateControl == RC_MPEG4) {
  1011. Double Ec = m_iMAD / (Double) (m_iNumMBY * m_iNumMBX * 16 * 16);
  1012. m_statRC.setMad (Ec);
  1013. if (m_statRC.noCodedFrame () >= RC_START_RATE_CONTROL) {
  1014. UInt newQStep = m_statRC.updateQuanStepsize ();
  1015. m_vopmd.intStepDiff = newQStep - m_vopmd.intStep; // DQUANT
  1016. m_vopmd.intStep = newQStep;
  1017. }
  1018. cout << "t" << "Q:" << "ttt" << m_vopmd.intStep << "n";
  1019. m_statRC.setQc (m_vopmd.intStep);
  1020. }
  1021. CoordI y = m_rctCurrVOPY.top; 
  1022. CMBMode* pmbmd = m_rgmbmd;
  1023. Int iQPPrev = m_vopmd.intStep;
  1024. Int iQPPrevAlpha = m_vopmd.intStepPAlpha;
  1025. CMotionVector* pmv = m_rgmv;
  1026. CMotionVector* pmvBY = m_rgmvBY;
  1027. Int iVPCounter = m_statsVOP.total();
  1028. Int iVPtotal;
  1029. m_iVPMBnum = 0;
  1030. CStatistics m_statsVP;
  1031. // DCT coefficient buffer for Data Partitioning mode
  1032. Int*** iCoefQ_DP = new Int** [m_iNumMB];
  1033. PixelC* ppxlcRefY = (PixelC*) m_pvopcRefQ1->pixelsY () + m_iStartInRefToCurrRctY;
  1034. PixelC* ppxlcRefU = (PixelC*) m_pvopcRefQ1->pixelsU () + m_iStartInRefToCurrRctUV;
  1035. PixelC* ppxlcRefV = (PixelC*) m_pvopcRefQ1->pixelsV () + m_iStartInRefToCurrRctUV;
  1036. PixelC* ppxlcRefBY = (PixelC*) m_pvopcRefQ1->pixelsBY () + m_iStartInRefToCurrRctY;
  1037. PixelC* ppxlcRefBUV = (PixelC*) m_pvopcRefQ1->pixelsBUV () + m_iStartInRefToCurrRctUV;
  1038. PixelC *ppxlcRefA = (PixelC*) m_pvopcRefQ1->pixelsA () + m_iStartInRefToCurrRctY;
  1039. PixelC* ppxlcOrigY = (PixelC*) m_pvopcOrig->pixelsBoundY ();
  1040. PixelC* ppxlcOrigU = (PixelC*) m_pvopcOrig->pixelsBoundU ();
  1041. PixelC* ppxlcOrigV = (PixelC*) m_pvopcOrig->pixelsBoundV ();
  1042. PixelC* ppxlcOrigBY = (PixelC*) m_pvopcOrig->pixelsBoundBY ();
  1043. PixelC* ppxlcOrigA = (PixelC*) m_pvopcOrig->pixelsBoundA ();
  1044. // Added for error resilient mode by Toshiba(1997-11-14)
  1045. Bool bCodeVPHeaderNext = FALSE; // needed only for OBMC
  1046. Int iTempVPMBnum = 0;
  1047. Int iCounter;
  1048. // End Toshiba(1997-11-14)
  1049. Bool bRestartDelayedQP = TRUE;
  1050. for (iMBY = 0; iMBY < m_iNumMBY; iMBY++, y += MB_SIZE) {
  1051. PixelC* ppxlcRefMBY = ppxlcRefY;
  1052. PixelC* ppxlcRefMBU = ppxlcRefU;
  1053. PixelC* ppxlcRefMBV = ppxlcRefV;
  1054. PixelC* ppxlcRefMBBY = ppxlcRefBY;
  1055. PixelC* ppxlcRefMBBUV = ppxlcRefBUV;
  1056. PixelC* ppxlcRefMBA = ppxlcRefA;
  1057. PixelC* ppxlcOrigMBY = ppxlcOrigY;
  1058. PixelC* ppxlcOrigMBU = ppxlcOrigU;
  1059. PixelC* ppxlcOrigMBV = ppxlcOrigV;
  1060. PixelC* ppxlcOrigMBBY = ppxlcOrigBY;
  1061. PixelC* ppxlcOrigMBA = ppxlcOrigA;
  1062. CoordI x = m_rctCurrVOPY.left;
  1063. #ifdef __TRACE_AND_STATS_
  1064. m_statsMB.reset ();
  1065. #endif // __TRACE_AND_STATS_
  1066. // initiate advance shape coding
  1067. // shape bitstream is set to shape cache
  1068. m_pbitstrmShapeMBOut = m_pbitstrmShape_DP[iMBY * m_iNumMBX];
  1069. // pmbmd->m_bPadded=FALSE;
  1070. // Added for error resilient mode by Toshiba(1997-11-14)
  1071. // The following operation is needed only for OBMC
  1072. // if( bCodeVPHeaderNext ) {
  1073. // iTempVPMBnum  = m_iVPMBnum;
  1074. // m_iVPMBnum = VPMBnum(0, iMBY);
  1075. // }
  1076. // End Toshiba(1997-11-14)
  1077. copyToCurrBuffJustShape (ppxlcOrigMBBY, m_iFrameWidthY);
  1078. // Modified for error resilient mode by Toshiba(1997-11-14)
  1079. ShapeMode shpmdColocatedMB;
  1080. if(m_vopmd.bShapeCodingType) {
  1081. shpmdColocatedMB = m_rgmbmdRef [
  1082. min (max (0, iMBY), m_iNumMBYRef - 1) * m_iNumMBXRef].m_shpmd;
  1083. encodePVOPMBJustShape(ppxlcRefMBBY, pmbmd, shpmdColocatedMB, pmv, pmvBY, x, y, 0, iMBY);
  1084. }
  1085. else {
  1086. m_statsMB.nBitsShape += codeIntraShape (ppxlcRefMBBY, pmbmd, 0, iMBY);
  1087. decideTransparencyStatus (pmbmd, m_ppxlcCurrMBBY); 
  1088. }
  1089. // if( bCodeVPHeaderNext )
  1090. // m_iVPMBnum = iTempVPMBnum;
  1091. // End Toshiba(1997-11-14)
  1092. if(pmbmd->m_bhas4MVForward)
  1093. padMotionVectors(pmbmd,pmv);
  1094. for (iMBX = 0; iMBX < m_iNumMBX; iMBX++, x += MB_SIZE) {
  1095. pmbmd->m_stepSize = iQPPrev + pmbmd->m_intStepDelta;
  1096. #ifdef __TRACE_AND_STATS_
  1097. m_pbitstrmOut->trace (CSite (iMBX, iMBY), "MB_X_Y (Texture)");
  1098. // shape quantization part
  1099. m_statsMB.reset ();
  1100. #endif // __TRACE_AND_STATS_
  1101. Int iVPlastMBnum = iMBY * m_iNumMBX + iMBX;
  1102. pmbmd->m_bPadded=FALSE;
  1103. if(iMBX<m_iNumMBX-1)
  1104. {
  1105. // shape bitstream is set to shape cache
  1106. m_pbitstrmShapeMBOut = m_pbitstrmShape_DP[iMBY * m_iNumMBX + iMBX + 1];
  1107. // Added for error resilient mode by Toshiba(1997-11-14)
  1108. // The following operation is needed only for OBMC
  1109. if( bCodeVPHeaderNext ) {
  1110. iTempVPMBnum  = m_iVPMBnum;
  1111. m_iVPMBnum = VPMBnum(iMBX+1, iMBY);
  1112. }
  1113. // End Toshiba(1997-11-14)
  1114. // code shape 1mb in advance
  1115. copyToCurrBuffJustShape (ppxlcOrigMBBY+MB_SIZE,m_iFrameWidthY);
  1116. // Modified for error resilient mode by Toshiba(1997-11-14)
  1117. if(m_vopmd.bShapeCodingType) {
  1118. shpmdColocatedMB = m_rgmbmdRef [
  1119. min (max (0, iMBX+1), m_iNumMBXRef-1) + 
  1120.   min (max (0, iMBY), m_iNumMBYRef-1) * m_iNumMBXRef
  1121. ].m_shpmd;
  1122. encodePVOPMBJustShape(
  1123. ppxlcRefMBBY+MB_SIZE, pmbmd+1,
  1124.  shpmdColocatedMB,
  1125.  pmv+PVOP_MV_PER_REF_PER_MB,
  1126.  pmvBY+1, x+MB_SIZE, y,
  1127.  iMBX+1, iMBY
  1128. );
  1129. }
  1130. else {
  1131. m_statsMB.nBitsShape
  1132. += codeIntraShape (
  1133. ppxlcRefMBBY+MB_SIZE,
  1134. pmbmd+1, iMBX+1, iMBY
  1135. );
  1136. decideTransparencyStatus (pmbmd+1,
  1137.  m_ppxlcCurrMBBY); 
  1138. }
  1139. // End Toshiba(1997-11-14)
  1140. // Added for error resilient mode by Toshiba(1997-11-14)
  1141. // The following operation is needed only for OBMC
  1142. if( bCodeVPHeaderNext )
  1143. m_iVPMBnum = iTempVPMBnum;
  1144. // End Toshiba(1997-11-14)
  1145. if((pmbmd+1)->m_bhas4MVForward)
  1146. padMotionVectors(pmbmd+1, pmv+PVOP_MV_PER_REF_PER_MB);
  1147. }
  1148. // Set not to output but count bitstream
  1149. m_pbitstrmOut->SetDontSendBits(TRUE);
  1150. // copy DCT coefficient to buffer
  1151. iCoefQ_DP[iVPlastMBnum] = new Int* [6];
  1152. Int iBlk;
  1153. for (iBlk = 0; iBlk < 6; iBlk++) {
  1154. iCoefQ_DP [iVPlastMBnum] [iBlk] = new Int [BLOCK_SQUARE_SIZE];
  1155. }
  1156. if(m_volmd.bShapeOnly==FALSE)
  1157. {
  1158. if (pmbmd -> m_rgTranspStatus [0] != ALL) {
  1159. // need to copy binary shape too since curr buff is future shape
  1160. copyToCurrBuffWithShape(ppxlcOrigMBY, ppxlcOrigMBU, ppxlcOrigMBV,
  1161. ppxlcRefMBBY, ppxlcOrigMBA, m_iFrameWidthY, m_iFrameWidthUV);
  1162. downSampleBY (m_ppxlcCurrMBBY, m_ppxlcCurrMBBUV);
  1163. encodePVOPMBTextureWithShape(ppxlcRefMBY, ppxlcRefMBU, ppxlcRefMBV, ppxlcRefMBA, pmbmd, pmv, iMBX, iMBY, x, y,
  1164. iQPPrev, iQPPrevAlpha, bRestartDelayedQP);
  1165. // copy DCT coefficient to buffer
  1166. for (iBlk = 0; iBlk < 6; iBlk++) {
  1167. for( Int t = 0; t < BLOCK_SQUARE_SIZE; t++ )
  1168. iCoefQ_DP[iVPlastMBnum][iBlk][t] = m_rgpiCoefQ[iBlk][t];
  1169. }
  1170. if (pmbmd -> m_rgTranspStatus [0] == PARTIAL)
  1171. mcPadCurrMB (ppxlcRefMBY, ppxlcRefMBU, ppxlcRefMBV, ppxlcRefMBA);
  1172. padNeighborTranspMBs (
  1173. iMBX, iMBY,
  1174. pmbmd,
  1175. ppxlcRefMBY, ppxlcRefMBU, ppxlcRefMBV, ppxlcRefMBA
  1176. );
  1177. }
  1178. else {
  1179. padCurrAndTopTranspMBFromNeighbor (
  1180. iMBX, iMBY,
  1181. pmbmd,
  1182. ppxlcRefMBY, ppxlcRefMBU, ppxlcRefMBV, ppxlcRefMBA
  1183. );
  1184. }
  1185. }
  1186. // Set to output bitstream
  1187. m_pbitstrmOut->SetDontSendBits(FALSE);
  1188. pmbmd++;
  1189. pmv += PVOP_MV_PER_REF_PER_MB;
  1190. pmvBY++;
  1191. ppxlcRefMBBY += MB_SIZE;
  1192. ppxlcRefMBA += MB_SIZE;
  1193. ppxlcRefMBBUV += BLOCK_SIZE;
  1194. ppxlcOrigMBBY += MB_SIZE;
  1195. ppxlcOrigMBA += MB_SIZE;
  1196. #ifdef __TRACE_AND_STATS_
  1197. m_statsVOP += m_statsMB;
  1198. #endif // __TRACE_AND_STATS_
  1199. ppxlcRefMBY += MB_SIZE;
  1200. ppxlcRefMBU += BLOCK_SIZE;
  1201. ppxlcRefMBV += BLOCK_SIZE;
  1202. ppxlcOrigMBY += MB_SIZE;
  1203. ppxlcOrigMBU += BLOCK_SIZE;
  1204. ppxlcOrigMBV += BLOCK_SIZE;
  1205. iVPtotal = (int) m_statsVOP.total() - iVPCounter;
  1206. if( bCodeVPHeaderNext || iVPlastMBnum == m_iNumMB-1 /* last MB in a VOP */) {
  1207. // Set to output bitstream
  1208. m_pbitstrmOut->SetDontSendBits(FALSE);
  1209. // encode video packet
  1210. iVPCounter = m_statsVOP.total();
  1211. m_statsVP.reset();
  1212. if( m_iVPMBnum > 0 )
  1213. {
  1214. m_statsVP.nBitsHead = codeVideoPacketHeader (m_rgmbmd[m_iVPMBnum].m_stepSize);
  1215. bRestartDelayedQP = TRUE;
  1216. }
  1217. DataPartitioningMotionCoding(m_iVPMBnum, iVPlastMBnum, &m_statsVP, iCoefQ_DP);
  1218. m_pbitstrmOut -> putBits (MOTION_MARKER, NUMBITS_DP_MOTION_MARKER, "motion_marker");
  1219. m_statsVP.nBitsHead += NUMBITS_DP_MOTION_MARKER;
  1220. DataPartitioningTextureCoding(m_iVPMBnum, iVPlastMBnum, &m_statsVP, iCoefQ_DP);
  1221. // assert( iVPtotal + m_statsVP.nBitsHead == (int) m_statsVP.total() );
  1222. m_iVPMBnum = iVPlastMBnum + 1;
  1223. }
  1224. // The following operation is needed only for OBMC
  1225. iCounter = m_statsVOP.total();
  1226. bCodeVPHeaderNext = iCounter - iVPCounter > m_volmd.bVPBitTh;
  1227. }
  1228. MacroBlockMemory** ppmbmTemp = m_rgpmbmAbove;
  1229. m_rgpmbmAbove = m_rgpmbmCurr;
  1230. m_rgpmbmCurr  = ppmbmTemp;
  1231. ppxlcRefY += m_iFrameWidthYxMBSize;
  1232. ppxlcRefU += m_iFrameWidthUVxBlkSize;
  1233. ppxlcRefV += m_iFrameWidthUVxBlkSize;
  1234. ppxlcRefBY += m_iFrameWidthYxMBSize;
  1235. ppxlcRefA += m_iFrameWidthYxMBSize;
  1236. ppxlcRefBUV += m_iFrameWidthUVxBlkSize;
  1237. ppxlcOrigY += m_iFrameWidthYxMBSize;
  1238. ppxlcOrigBY += m_iFrameWidthYxMBSize;
  1239. ppxlcOrigA += m_iFrameWidthYxMBSize;
  1240. ppxlcOrigU += m_iFrameWidthUVxBlkSize;
  1241. ppxlcOrigV += m_iFrameWidthUVxBlkSize;
  1242. }
  1243. // delete CoefQ_DP
  1244. for( Int iMB = 0; iMB < m_iNumMB; iMB++ )  {
  1245. for (Int iBlk = 0; iBlk < 6; iBlk++) {
  1246. delete [] iCoefQ_DP [iMB] [iBlk];
  1247. }
  1248. delete [] iCoefQ_DP[iMB];
  1249. }
  1250. delete [] iCoefQ_DP;
  1251. // restore normal output stream
  1252. m_pbitstrmShapeMBOut = m_pbitstrmOut;
  1253. // Set to output bitstream
  1254. m_pbitstrmOut->SetDontSendBits(FALSE);
  1255. }
  1256. //////////////////////////////////////////////////////////
  1257. ////  The following functions are for Reversible VLC  ////
  1258. //////////////////////////////////////////////////////////
  1259. UInt CVideoObjectEncoder::sendTCOEFIntraRVLC (const Int* rgiCoefQ, Int iStart, Int* rgiZigzag, Bool bDontSendBits)
  1260. {
  1261. assert( m_volmd.bDataPartitioning && m_volmd.bReversibleVlc );
  1262. Bool bIsFirstRun = TRUE;
  1263. Bool bIsLastRun = FALSE;
  1264. UInt uiCurrRun = 0;
  1265. UInt uiPrevRun = 0;
  1266. //Int  iCurrLevel = 0;
  1267. Int  iPrevLevel = 0;
  1268. //UInt uiCoefToStart = 0;
  1269. UInt numBits = 0;
  1270. for (Int j = iStart; j < BLOCK_SQUARE_SIZE; j++) {
  1271. if (rgiCoefQ [rgiZigzag [j]] == 0) // zigzag here
  1272. uiCurrRun++; // counting zeros
  1273. else {
  1274. if (!bIsFirstRun)
  1275. numBits += putBitsOfTCOEFIntraRVLC (uiPrevRun, iPrevLevel, bIsLastRun, bDontSendBits);
  1276. uiPrevRun = uiCurrRun;  // reset for next run
  1277. iPrevLevel = rgiCoefQ [rgiZigzag [j]]; 
  1278. uiCurrRun = 0;
  1279. bIsFirstRun = FALSE;
  1280. }
  1281. }
  1282. assert (uiPrevRun <= (BLOCK_SQUARE_SIZE - 1) - 1); // Some AC must be non-zero; at least for inter
  1283. bIsLastRun = TRUE;
  1284. numBits += putBitsOfTCOEFIntraRVLC (uiPrevRun, iPrevLevel, bIsLastRun, bDontSendBits);
  1285. return numBits;
  1286. }
  1287. UInt CVideoObjectEncoder::putBitsOfTCOEFIntraRVLC (UInt uiRun, Int iLevel, Bool bIsLastRun, Bool bDontSendBits)
  1288. {
  1289. assert(m_volmd.bDataPartitioning && m_volmd.bReversibleVlc );
  1290. UInt nBits = 0;
  1291. Long lVLCtableIndex;
  1292. if (bIsLastRun == FALSE) {
  1293. lVLCtableIndex = findVLCtableIndexOfNonLastEventIntraRVLC (bIsLastRun, uiRun, abs(iLevel));
  1294. if (lVLCtableIndex != NOT_IN_TABLE)  {
  1295. nBits += m_pentrencSet->m_pentrencDCTIntraRVLC->encodeSymbol(lVLCtableIndex, "Vlc_TCOEF_RVLC", bDontSendBits); // huffman encode 
  1296. if( !bDontSendBits )
  1297. m_pentrencSet->m_pentrencDCTIntraRVLC->bitstream()->putBits ((Char) invSignOf (iLevel), 1, "Sign_TCOEF_RVLC");
  1298. nBits++;
  1299. }
  1300. else
  1301. escapeEncodeRVLC (uiRun, iLevel, bIsLastRun, bDontSendBits);
  1302. }
  1303. else {
  1304. lVLCtableIndex = findVLCtableIndexOfLastEventIntraRVLC (bIsLastRun, uiRun, abs(iLevel));
  1305. if (lVLCtableIndex != NOT_IN_TABLE)  {
  1306. nBits += m_pentrencSet->m_pentrencDCTIntraRVLC->encodeSymbol(lVLCtableIndex, "Vlc_TCOEF_Last_RVLC", bDontSendBits); // huffman encode 
  1307. if( !bDontSendBits )
  1308. m_pentrencSet->m_pentrencDCTIntraRVLC->bitstream()->putBits ((Char) invSignOf (iLevel), 1, "Sign_TCOEF_Last_RVLC");
  1309. nBits++;
  1310. }
  1311. else
  1312. escapeEncodeRVLC (uiRun, iLevel, bIsLastRun, bDontSendBits);
  1313. }
  1314. return nBits;
  1315. }
  1316. Int CVideoObjectEncoder::findVLCtableIndexOfNonLastEventIntraRVLC (Bool bIsLastRun, UInt uiRun, UInt uiLevel)
  1317. {
  1318. assert( m_volmd.bDataPartitioning && m_volmd.bReversibleVlc );
  1319. assert (uiRun >= 0);
  1320. if (uiRun > 19 || (uiLevel > grgIfNotLastNumOfLevelAtRunIntraRVLC [uiRun]))
  1321. return NOT_IN_TABLE;
  1322. else {
  1323. UInt uiTableIndex = 0;
  1324. for (UInt i = 0; i < uiRun; i++)
  1325. uiTableIndex += grgIfNotLastNumOfLevelAtRunIntraRVLC [i];
  1326. uiTableIndex += uiLevel;
  1327. uiTableIndex--; // make it zero-based; see Table H13/H.263
  1328. return uiTableIndex;
  1329. }
  1330. }
  1331. Int CVideoObjectEncoder::findVLCtableIndexOfLastEventIntraRVLC (Bool bIsLastRun, UInt uiRun, UInt uiLevel)
  1332. {
  1333. assert( m_volmd.bDataPartitioning && m_volmd.bReversibleVlc );
  1334. assert (uiRun >= 0);
  1335. if (uiRun > 44 || (uiLevel > grgIfLastNumOfLevelAtRunIntraRVLC [uiRun]))
  1336. return NOT_IN_TABLE;
  1337. else {
  1338. UInt uiTableIndex = 0;
  1339. for (UInt i = 0; i < uiRun; i++)
  1340. uiTableIndex += grgIfLastNumOfLevelAtRunIntraRVLC [i];
  1341. uiTableIndex += uiLevel;
  1342. uiTableIndex += 102; // make it zero-based and 
  1343. return uiTableIndex; //correction of offset; see Table H13/H.263
  1344. }
  1345. }
  1346. UInt CVideoObjectEncoder::sendTCOEFInterRVLC (const Int* rgiCoefQ, Int iStart, Int* rgiZigzag, Bool bDontSendBits)
  1347. {
  1348. assert( m_volmd.bDataPartitioning && m_volmd.bReversibleVlc );
  1349. Bool bIsFirstRun = TRUE;
  1350. Bool bIsLastRun = FALSE;
  1351. UInt uiCurrRun = 0;
  1352. UInt uiPrevRun = 0;
  1353. //Int  iCurrLevel = 0;
  1354. Int  iPrevLevel = 0;
  1355. UInt numBits = 0;
  1356. for (Int j = iStart; j < BLOCK_SQUARE_SIZE; j++) {
  1357. if (rgiCoefQ [rgiZigzag [j]] == 0) // zigzag here
  1358. uiCurrRun++; // counting zeros
  1359. else {
  1360. if (!bIsFirstRun)
  1361. numBits += putBitsOfTCOEFInterRVLC (uiPrevRun, iPrevLevel, bIsLastRun, bDontSendBits);
  1362. uiPrevRun = uiCurrRun;  // reset for next run
  1363. iPrevLevel = rgiCoefQ [rgiZigzag [j]]; 
  1364. uiCurrRun = 0;
  1365. bIsFirstRun = FALSE;
  1366. }
  1367. }
  1368. assert (uiPrevRun <= (BLOCK_SQUARE_SIZE - 1)); // Some AC must be non-zero; at least for inter
  1369. bIsLastRun = TRUE;
  1370. numBits += putBitsOfTCOEFInterRVLC (uiPrevRun, iPrevLevel, bIsLastRun, bDontSendBits);
  1371. return numBits;
  1372. }
  1373. UInt CVideoObjectEncoder::putBitsOfTCOEFInterRVLC (UInt uiRun, Int iLevel, Bool bIsLastRun, Bool bDontSendBits)
  1374. {
  1375. assert( m_volmd.bDataPartitioning && m_volmd.bReversibleVlc );
  1376. UInt nBits = 0;
  1377. Long lVLCtableIndex;
  1378. if (bIsLastRun == FALSE) {
  1379. lVLCtableIndex = findVLCtableIndexOfNonLastEventInterRVLC (bIsLastRun, uiRun, abs(iLevel));
  1380. if (lVLCtableIndex != NOT_IN_TABLE)  {
  1381. nBits += m_pentrencSet->m_pentrencDCTRVLC->encodeSymbol(lVLCtableIndex, "Vlc_TCOEF_RVLC", bDontSendBits); // huffman encode 
  1382. if( !bDontSendBits )
  1383. m_pentrencSet->m_pentrencDCTRVLC->bitstream()->putBits ((Char) invSignOf (iLevel), 1, "Sign_TCOEF_RVLC");
  1384. nBits++;
  1385. }
  1386. else
  1387. escapeEncodeRVLC (uiRun, iLevel, bIsLastRun, bDontSendBits);
  1388. }
  1389. else {
  1390. lVLCtableIndex = findVLCtableIndexOfLastEventInterRVLC (bIsLastRun, uiRun, abs(iLevel));
  1391. if (lVLCtableIndex != NOT_IN_TABLE)  {
  1392. nBits += m_pentrencSet->m_pentrencDCTRVLC->encodeSymbol(lVLCtableIndex, "Vlc_TCOEF_Last_RVLC", bDontSendBits); // huffman encode 
  1393. if( !bDontSendBits )
  1394. m_pentrencSet->m_pentrencDCTRVLC->bitstream()->putBits ((Char) invSignOf (iLevel), 1, "Sign_TCOEF_Last_RVLC");
  1395. nBits++;
  1396. }
  1397. else
  1398. escapeEncodeRVLC (uiRun, iLevel, bIsLastRun, bDontSendBits);
  1399. }
  1400. return nBits;
  1401. }
  1402. Int CVideoObjectEncoder::findVLCtableIndexOfNonLastEventInterRVLC (Bool bIsLastRun, UInt uiRun, UInt uiLevel)
  1403. {
  1404. assert( m_volmd.bDataPartitioning && m_volmd.bReversibleVlc );
  1405. assert (uiRun >= 0);
  1406. if (uiRun > 38 || (uiLevel > grgIfNotLastNumOfLevelAtRunInterRVLC [uiRun]))
  1407. return NOT_IN_TABLE;
  1408. else {
  1409. UInt uiTableIndex = 0;
  1410. for (UInt i = 0; i < uiRun; i++)
  1411. uiTableIndex += grgIfNotLastNumOfLevelAtRunInterRVLC [i];
  1412. uiTableIndex += uiLevel;
  1413. uiTableIndex--; // make it zero-based; see Table H13/H.263
  1414. return uiTableIndex;
  1415. }
  1416. }
  1417. Int CVideoObjectEncoder::findVLCtableIndexOfLastEventInterRVLC (Bool bIsLastRun, UInt uiRun, UInt uiLevel)
  1418. {
  1419. assert( m_volmd.bDataPartitioning && m_volmd.bReversibleVlc );
  1420. assert (uiRun >= 0);
  1421. if (uiRun > 44 || (uiLevel > grgIfLastNumOfLevelAtRunInterRVLC [uiRun]))
  1422. return NOT_IN_TABLE;
  1423. else {
  1424. UInt uiTableIndex = 0;
  1425. for (UInt i = 0; i < uiRun; i++)
  1426. uiTableIndex += grgIfLastNumOfLevelAtRunInterRVLC [i];
  1427. uiTableIndex += uiLevel;
  1428. uiTableIndex += 102; // make it zero-based and 
  1429. return uiTableIndex; //correction of offset; see Table H13/H.263
  1430. }
  1431. }
  1432. UInt CVideoObjectEncoder::escapeEncodeRVLC (UInt uiRun, Int iLevel, Bool bIsLastRun, Bool bDontSendBits)
  1433. {
  1434. assert( m_volmd.bDataPartitioning && m_volmd.bReversibleVlc );
  1435. UInt nBits = 0;
  1436. Int iLevelAbs = abs (iLevel);
  1437. Char iLevelSign = (Char) invSignOf (iLevel);
  1438. nBits += m_pentrencSet->m_pentrencDCTRVLC->encodeSymbol(TCOEF_RVLC_ESCAPE, "FEsc_TCOEF_RVLC", bDontSendBits);
  1439. if( !bDontSendBits )
  1440. m_pentrencSet->m_pentrencDCTRVLC->bitstream()->putBits (1, 1, "FEsc1_TCOEF_RVLC");
  1441. nBits ++;
  1442. if( !bDontSendBits )
  1443. m_pentrencSet->m_pentrencDCTRVLC->bitstream()->putBits ((Char) bIsLastRun, 1, "Last_Esc_TCOEF_RVLC");
  1444. nBits ++;
  1445. assert (uiRun < BLOCK_SQUARE_SIZE);
  1446. if( !bDontSendBits )
  1447. m_pentrencSet->m_pentrencDCTRVLC->bitstream()->putBits (uiRun, NUMBITS_RVLC_ESC_RUN, "Run_Esc_TCOEF_RVLC");
  1448. nBits += NUMBITS_RVLC_ESC_RUN;
  1449. Int iLevelBits = 12; // = m_volmd.nBits;
  1450. Int iMaxAC = (1<<(iLevelBits - 1)) - 1;
  1451. assert (iLevelAbs <= iMaxAC && iLevelAbs > 0);
  1452. if( !bDontSendBits )
  1453. {
  1454. m_pentrencSet->m_pentrencDCTRVLC->bitstream()->putBits (1, 1, "Marker");
  1455. m_pentrencSet->m_pentrencDCTRVLC->bitstream()->putBits (iLevelAbs, iLevelBits - 1, "Level_Esc_TCOEF_RVLC");
  1456. m_pentrencSet->m_pentrencDCTRVLC->bitstream()->putBits (1, 1, "Marker");
  1457. }
  1458. nBits += iLevelBits - 1 + 2;
  1459. nBits += m_pentrencSet->m_pentrencDCTRVLC->encodeSymbol(TCOEF_RVLC_ESCAPE, "LEsc_TCOEF_RVLC", bDontSendBits);
  1460. if( !bDontSendBits )
  1461. m_pentrencSet->m_pentrencDCTRVLC->bitstream()->putBits (iLevelSign, 1, "Sign_LEsc_TCOEF_RVLC");
  1462. nBits ++;
  1463. return nBits;
  1464. }
  1465. Int CVideoObjectEncoder::dumpCachedShapeBits_DP(Int iMBnum)
  1466. {
  1467. Int ret;
  1468. #ifdef __TRACE_AND_STATS_
  1469. m_pbitstrmOut->trace("INSERTING PRE-ENCODED MB SHAPE STREAM HEREn");
  1470. m_pbitstrmOut->trace(m_pbitstrmOut->getCounter(),"Location Before");
  1471. #endif // __TRACE_AND_STATS_
  1472. m_pbitstrmOut->putBitStream(*m_pbitstrmShape_DP[iMBnum]);
  1473. ret = m_pbitstrmShape_DP[iMBnum]->getCounter();
  1474. #ifdef __TRACE_AND_STATS_
  1475. m_pbitstrmOut->trace(m_pbitstrmOut->getCounter(),"Location After");
  1476. #endif // __TRACE_AND_STATS_
  1477. m_pbitstrmShape_DP[iMBnum]->flush();
  1478. m_pbitstrmShape_DP[iMBnum]->resetAll();
  1479. return(ret);
  1480. }