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

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. /*************************************************************************
  2. This software module was originally developed by 
  3. Ming-Chieh Lee (mingcl@microsoft.com), Microsoft Corporation
  4. Wei-ge Chen (wchen@microsoft.com), Microsoft Corporation
  5. Bruce Lin (blin@microsoft.com), Microsoft Corporation
  6. Chuang Gu (chuanggu@microsoft.com), Microsoft Corporation
  7. Simon Winder (swinder@microsoft.com), Microsoft Corporation
  8. (date: March, 1996)
  9. and edited by
  10.         Wei Wu (weiwu@stallion.risc.rockwell.com) Rockwell Science Center
  11. and also edited by
  12. Yoshihiro Kikuchi (TOSHIBA CORPORATION)
  13. Takeshi Nagai (TOSHIBA CORPORATION)
  14. Toshiaki Watanabe (TOSHIBA CORPORATION)
  15. Noboru Yamaguchi (TOSHIBA CORPORATION)
  16. and also edited by
  17. David B. Shu (dbshu@hrl.com), Hughes Electronics/HRL Laboratories
  18. Marc Mongenet (Marc.Mongenet@epfl.ch), Swiss Federal Institute of Technology, Lausanne (EPFL)
  19. and also edited by
  20. Yoshinori Suzuki (Hitachi, Ltd.)
  21. in the course of development of the MPEG-4 Video (ISO/IEC 14496-2). 
  22. This software module is an implementation of a part of one or more MPEG-4 Video tools 
  23. as specified by the MPEG-4 Video. 
  24. ISO/IEC gives users of the MPEG-4 Video free license to this software module or modifications 
  25. thereof for use in hardware or software products claiming conformance to the MPEG-4 Video. 
  26. Those intending to use this software module in hardware or software products are advised that its use may infringe existing patents. 
  27. The original developer of this software module and his/her company, 
  28. the subsequent editors and their companies, 
  29. and ISO/IEC have no liability for use of this software module or modifications thereof in an implementation. 
  30. Copyright is not released for non MPEG-4 Video conforming products. 
  31. Microsoft retains full right to use the code for his/her own purpose, 
  32. assign or donate the code to a third party and to inhibit third parties from using the code for non <MPEG standard> conforming products. 
  33. This copyright notice must be included in all copies or derivative works. 
  34. Copyright (c) 1996, 1997.
  35. Module Name:
  36. vopSeEnc.hpp
  37. Abstract:
  38. Encoder for one VO.
  39. Revision History:
  40. Sept. 30, 1997: Error resilient tools added by Toshiba
  41. Dec.  11, 1997: Interlaced tools added by NextLevel Systems
  42. X. Chen, xchen@nlvl.com B. Eifrig, beifrig@nlvl.com
  43. Jun.  16, 1998: add Complexity Estimation syntax support
  44. Marc Mongenet (Marc.Mongenet@epfl.ch) - EPFL
  45. Jan.  28, 1999: Rounding control parameters added by Hitachi, Ltd.
  46. May    9, 1999: tm5 rate control by DemoGraFX, duhoff@mediaone.net
  47. *************************************************************************/
  48. #include <stdio.h>
  49. #include <iostream.h>
  50. #include <fstream.h>
  51. #include <math.h>
  52. #include <stdlib.h>
  53. #include "typeapi.h"
  54. #include "codehead.h"
  55. #include "global.hpp"
  56. #include "entropy/bitstrm.hpp"
  57. #include "entropy/entropy.hpp"
  58. #include "entropy/huffman.hpp"
  59. #include "mode.hpp"
  60. #include "dct.hpp"
  61. #include "tps_enhcbuf.hpp" // added by Sharp (98/2/12)
  62. #include "vopses.hpp"
  63. #include "vopseenc.hpp"
  64. #include "enhcbufenc.hpp" // added by Sharp (98/2/12)
  65. #include "cae.h" // Added for error resilient mode by Toshiba(1997-11-14)
  66. #ifdef __MFC_
  67. #ifdef _DEBUG
  68. #undef THIS_FILE
  69. static char BASED_CODE THIS_FILE[] = __FILE__;
  70. #endif
  71. #define new DEBUG_NEW    
  72. #endif // __MFC_
  73. CVideoObjectEncoder::~CVideoObjectEncoder ()
  74. {
  75. delete m_pvopcOrig;
  76. delete m_pvopcRefOrig1;
  77. delete m_pvopcRefOrig0;
  78. delete m_puciRefQZoom0;
  79. delete m_puciRefQZoom1;
  80. delete m_pfdct;
  81. delete [] m_rgdSNR;
  82. // bitstream stuff
  83. delete [] m_pchBitsBuffer; 
  84. delete m_pbitstrmOut;
  85. delete m_pentrencSet;
  86. delete [] m_pchShapeBitsBuffer;
  87. delete m_pbitstrmShape;
  88. // Added for data partitioning mode By Toshiba(1998-1-16:DP+RVLC)
  89. delete [] *m_pchShapeBitsBuffer_DP;
  90. delete [] *m_pbitstrmShape_DP;
  91. delete m_pchShapeBitsBuffer_DP;
  92. delete m_pbitstrmShape_DP;
  93. // End Toshiba(1998-1-16)
  94. // shape
  95. delete [] m_rgiSubBlkIndx16x16;
  96. delete [] m_rgiSSubBlkIndx16x16;
  97. delete [] m_rgiSubBlkIndx18x18;
  98. delete [] m_rgiSubBlkIndx20x20;
  99. delete [] m_rgiPxlIndx12x12;
  100. delete [] m_rgiPxlIndx8x8;
  101. // B-VOP MB buffer
  102. delete m_puciDirectPredMB;
  103. delete m_puciInterpPredMB;
  104. delete m_piiDirectErrorMB; 
  105. delete m_piiInterpErrorMB; 
  106. }
  107. CVideoObjectEncoder::CVideoObjectEncoder (
  108. UInt uiVOId, 
  109. VOLMode& volmd, 
  110. VOPMode& vopmd, 
  111. UInt nFirstFrame,
  112. UInt nLastFrame,
  113. Int iSessionWidth,
  114. Int iSessionHeight,
  115. UInt uiRateControl,
  116. UInt uiBudget,
  117. ostream* pstrmTrace, // trace outstream
  118. UInt uiWarpingAccuracy, // for sprite warping
  119. Int iNumOfPnts, // for sprite warping
  120. CSiteD** rgstDest, // for sprite warping destination
  121. SptMode SpriteMode, // sprite reconstruction mode
  122. CRct rctFrame, // sprite warping source
  123.     CRct rctSpt,      // rct sprite
  124. Int iMVFileUsage,
  125. Char* pchMVFileName
  126. ) :
  127. CVideoObject (),
  128. m_nFirstFrame (nFirstFrame), m_nLastFrame (nLastFrame), 
  129. m_iBufferSize (uiBudget), m_uiRateControl (uiRateControl),
  130. m_pvopcOrig (NULL),
  131. m_rgiSubBlkIndx16x16 (NULL),
  132. m_rgiSSubBlkIndx16x16 (NULL),
  133. m_rgiSubBlkIndx18x18 (NULL),
  134. m_rgiSubBlkIndx20x20 (NULL),
  135. m_rgiPxlIndx12x12 (NULL),
  136. m_rgiPxlIndx8x8 (NULL)
  137. {
  138. m_ivolWidth = iSessionWidth;
  139. m_ivolHeight = iSessionHeight;
  140. // sprite stuff
  141. if (iNumOfPnts >= 0) {
  142. m_uiSprite = 1;
  143. m_uiWarpingAccuracy = uiWarpingAccuracy;
  144. m_iNumOfPnts = iNumOfPnts;
  145. m_rgstSrcQ = new CSiteD [m_iNumOfPnts];
  146. m_rgstDstQ = new CSiteD [m_iNumOfPnts];
  147. m_rctSpt = rctSpt;
  148. //#ifdef __LOW_LATENCY_SPRITE_
  149. m_pprgstDest = rgstDest;
  150. m_sptMode = SpriteMode ;
  151. m_rctOrg =  rctFrame;
  152. m_rctDisplayWindow = m_rctOrg; //only used for sprite, will be combined with Org later
  153. }
  154. else 
  155. m_uiSprite = 0;
  156. m_pchBitsBuffer = new Char [iSessionWidth * iSessionHeight * 2]; //we think this is enof for 4:2:0; if crushes, increase the buffer
  157. m_pbitstrmOut = new COutBitStream (m_pchBitsBuffer, 0, pstrmTrace);
  158. m_pentrencSet = new CEntropyEncoderSet (*m_pbitstrmOut);
  159. // shape cache
  160. m_pchShapeBitsBuffer = new Char [MB_SIZE * MB_SIZE * 2]; // same as above
  161. m_pbitstrmShape = new COutBitStream (m_pchShapeBitsBuffer, 0, pstrmTrace);
  162. m_pbitstrmShapeMBOut = m_pbitstrmOut; // initially the output stream (only changes for inter)
  163. m_uiVOId = uiVOId;
  164. m_volmd = volmd;
  165. // NBIT: set right clip table
  166. setClipTab();
  167. Int iClockRate = m_volmd.iClockRate;
  168. assert (iClockRate >= 1 && iClockRate < 65536);
  169. for (m_iNumBitsTimeIncr = 1; m_iNumBitsTimeIncr < NUMBITS_TIME_RESOLUTION; m_iNumBitsTimeIncr++) {
  170. if (iClockRate == 1)
  171. break;
  172. iClockRate = (iClockRate >> 1);
  173. }
  174. m_vopmd = vopmd;
  175. // decideMVInfo ();                // MV search radius now varys with GOP
  176. m_vopmd.iRoundingControlEncSwitch = m_volmd.iInitialRoundingType;
  177. if(!m_volmd.bRoundingControlDisable)
  178. m_vopmd.iRoundingControlEncSwitch ^= 0x00000001;
  179. m_vopmd.iRoundingControl = m_vopmd.iRoundingControlEncSwitch;
  180. Int iMod = iSessionWidth % MB_SIZE;
  181. Int iSessionWidthRound = (iMod > 0) ? iSessionWidth + MB_SIZE - iMod : iSessionWidth;
  182. iMod = iSessionHeight % MB_SIZE;
  183. Int iSessionHeightRound = (iMod > 0) ? iSessionHeight + MB_SIZE - iMod : iSessionHeight;
  184. // Added for data partitioning mode By Toshiba(1998-1-16:DP+RVLC)
  185. Int iMB;
  186. Int iMBN = (iSessionWidthRound/MB_SIZE)*(iSessionHeightRound/MB_SIZE);
  187. m_pchShapeBitsBuffer_DP = new Char* [iMBN];
  188. m_pbitstrmShape_DP = new COutBitStream* [iMBN];
  189. for (iMB = 0; iMB < iMBN; iMB++) {
  190. m_pchShapeBitsBuffer_DP[iMB] = new Char [MB_SIZE * MB_SIZE * 2]; // same as above
  191. m_pbitstrmShape_DP[iMB] = new COutBitStream (m_pchShapeBitsBuffer_DP[iMB], 0, pstrmTrace);
  192. }
  193. // End Toshiba(1998-1-16:DP+RVLC)
  194. m_rctRefFrameY = CRct (
  195. -EXPANDY_REF_FRAME, -EXPANDY_REF_FRAME, 
  196. EXPANDY_REF_FRAME + iSessionWidthRound, EXPANDY_REF_FRAME + iSessionHeightRound
  197. );
  198. m_rctRefFrameUV = m_rctRefFrameY.downSampleBy2 ();
  199. m_pvopcOrig = new CVOPU8YUVBA (m_volmd.fAUsage, m_rctRefFrameY);
  200. m_pvopcRefOrig0 = new CVOPU8YUVBA (m_volmd.fAUsage, m_rctRefFrameY);
  201. m_pvopcRefOrig1 = new CVOPU8YUVBA (m_volmd.fAUsage, m_rctRefFrameY);
  202. allocateVOLMembers (iSessionWidthRound, iSessionHeightRound);
  203.     //#ifdef __LOW_LATENCY_SPRITE_
  204. // identify initial sprite piece
  205. if ((m_uiSprite == 1) && (m_sptMode != BASIC_SPRITE) ){
  206. initialSpritePiece (iSessionWidthRound, iSessionHeightRound);
  207. }
  208.     CRct rctFrameZoom = m_rctRefFrameY.upSampleBy2 ();
  209. m_puciRefQZoom0 = new CU8Image (rctFrameZoom);
  210. m_puciRefQZoom1 = new CU8Image (rctFrameZoom);
  211. m_pfdct = new CFwdBlockDCT(volmd.nBits);
  212. // B-VOP MB buffer
  213. m_puciDirectPredMB = new CU8Image (CRct (0, 0, MB_SIZE, MB_SIZE));
  214. m_puciInterpPredMB = new CU8Image (CRct (0, 0, MB_SIZE, MB_SIZE));
  215. m_ppxlcDirectPredMBY = (PixelC*) m_puciDirectPredMB->pixels (); 
  216. m_ppxlcInterpPredMBY = (PixelC*) m_puciInterpPredMB->pixels (); 
  217. m_piiDirectErrorMB = new CIntImage (CRct (0, 0, MB_SIZE, MB_SIZE)); 
  218. m_piiInterpErrorMB = new CIntImage (CRct (0, 0, MB_SIZE, MB_SIZE)); 
  219. m_ppxliDirectErrorMBY = (PixelI*) m_piiDirectErrorMB->pixels (); 
  220. m_ppxliInterpErrorMBY = (PixelI*) m_piiInterpErrorMB->pixels (); 
  221. // with shape
  222. if (m_volmd.fAUsage != RECTANGLE) {
  223. m_rgiSubBlkIndx16x16 = computeShapeSubBlkIndex (4, 16);
  224. m_rgiSSubBlkIndx16x16 = computeShapeSubBlkIndex (2, 16);
  225. m_rgiSubBlkIndx18x18 = computeShapeSubBlkIndex (4, 18);
  226. m_rgiSubBlkIndx20x20 = computeShapeSubBlkIndex (4, 20);
  227. m_rgiPxlIndx12x12 = new Int [8 * 8];
  228. Int* piPxl = m_rgiPxlIndx12x12;
  229. UInt i, j;
  230. for (i = 2; i < 10; i++)
  231. for (j = 2; j < 10; j++)
  232. *piPxl++ = i * 12 + j;
  233. m_rgiPxlIndx8x8 = new Int [4 * 4];
  234. piPxl = m_rgiPxlIndx8x8;
  235. for (i = 2; i < 6; i++)
  236. for (j = 2; j < 6; j++)
  237. *piPxl++ = i * 8 + j;
  238. }
  239. m_statsVOL.reset ();
  240. codeVOHead ();
  241. codeVOLHead (iSessionWidth, iSessionHeight);//, rctSprite);
  242. // Added for error resilient mode by Toshiba(1997-11-14): Moved (1998-1-16)
  243. g_iMaxHeading = MAXHEADING_ERR;
  244. g_iMaxMiddle = MAXMIDDLE_ERR;
  245. g_iMaxTrailing = MAXTRAILING_ERR;
  246. // End Toshiba(1997-11-14)
  247. m_statsVOL.nBitsStuffing += m_pbitstrmOut->flush ();
  248. m_statRC.resetSkipMode ();
  249. m_rgdSNR = (m_volmd.fAUsage == EIGHT_BIT) ? new Double [4] : new Double [3];
  250. // some fixed variables
  251. m_iFrameWidthZoomY = m_iFrameWidthY * 2;
  252. m_iFrameWidthZoomUV = m_iFrameWidthUV * 2;
  253. m_iFrameWidthZoomYx2Minus2MB = m_iFrameWidthY * 2 * 2 - 2 * MB_SIZE;
  254. m_iFrameWidthZoomYx2Minus2Blk = m_iFrameWidthY * 2 * 2 - 2 * BLOCK_SIZE;
  255. if (m_volmd.fAUsage == RECTANGLE) {
  256. m_rctCurrVOPY = CRct (0, 0, iSessionWidthRound, iSessionHeightRound);
  257. m_pvopcOrig->setBoundRct (m_rctCurrVOPY);
  258. m_rctCurrVOPUV = m_rctCurrVOPY.downSampleBy2 ();
  259. m_rctRefVOPY0 = m_rctCurrVOPY;
  260. m_rctRefVOPY0.expand (EXPANDY_REFVOP);
  261. m_rctRefVOPUV0 = m_rctRefVOPY0.downSampleBy2 ();
  262. m_rctRefVOPY1 = m_rctRefVOPY0;
  263. m_rctRefVOPUV1 = m_rctRefVOPUV0;
  264. m_rctRefVOPZoom0 = m_rctRefVOPY0.upSampleBy2 ();
  265. m_rctRefVOPZoom1 = m_rctRefVOPY1.upSampleBy2 ();
  266. m_pvopcRefOrig0->setBoundRct (m_rctRefVOPY0);
  267. m_pvopcRefOrig1->setBoundRct (m_rctRefVOPY1);
  268. // dshu: begin of modification
  269. if ((m_uiSprite == 0) || ((m_uiSprite == 1) && (m_sptMode == BASIC_SPRITE)) )
  270. // dshu: end of modification
  271. computeVOLConstMembers (); // these VOP members are the same for all frames
  272. }
  273. m_vopmd.SpriteXmitMode = STOP ;
  274.     // tentative solution for indicating the first Sprite VOP
  275.     tentativeFirstSpriteVop = 0;
  276. // Open motion vector file if used
  277. m_pchMVFileName = pchMVFileName;
  278. m_iMVFileUsage = iMVFileUsage;
  279. if (m_iMVFileUsage != 0) { // wmay - changed from =
  280. m_fMVFile = fopen(m_pchMVFileName, (m_iMVFileUsage == 1) ? "r" : "w");
  281. assert(m_fMVFile != NULL);
  282. m_iMVLineNo = 0;
  283. }
  284. }
  285. // for back/forward shape
  286. CVideoObjectEncoder::CVideoObjectEncoder (
  287. UInt uiVOId, 
  288. VOLMode& volmd, 
  289. VOPMode& vopmd,
  290. Int iSessionWidth,
  291. Int iSessionHeight
  292. ) :
  293. CVideoObject (),
  294. m_pvopcOrig (NULL),
  295. m_rgiSubBlkIndx16x16 (NULL),
  296. m_rgiSSubBlkIndx16x16 (NULL),
  297. m_rgiSubBlkIndx18x18 (NULL),
  298. m_rgiSubBlkIndx20x20 (NULL),
  299. m_rgiPxlIndx12x12 (NULL),
  300. m_rgiPxlIndx8x8 (NULL)
  301. {
  302. // sprite stuff
  303.      m_uiSprite = 0; // sprite off
  304. m_pchBitsBuffer = NULL;
  305. m_pbitstrmOut = NULL;
  306. m_pentrencSet = NULL;
  307.         // shape cache
  308. m_pchShapeBitsBuffer = NULL;
  309. m_pbitstrmShape = NULL;
  310. m_pbitstrmShapeMBOut = NULL;
  311. m_uiVOId = uiVOId;
  312. m_volmd = volmd;
  313. m_vopmd = vopmd;
  314. // decideMVInfo ();
  315. m_vopmd.iRoundingControl = 0;
  316. m_vopmd.iRoundingControlEncSwitch = 0;
  317. Int iMod = iSessionWidth % MB_SIZE;
  318. Int iSessionWidthRound = (iMod > 0) ? iSessionWidth + MB_SIZE - iMod : iSessionWidth;
  319. iMod = iSessionHeight % MB_SIZE;
  320. Int iSessionHeightRound = (iMod > 0) ? iSessionHeight + MB_SIZE - iMod : iSessionHeight;
  321. m_rctRefFrameY = CRct (
  322. -EXPANDY_REF_FRAME, -EXPANDY_REF_FRAME, 
  323. EXPANDY_REF_FRAME + iSessionWidthRound, EXPANDY_REF_FRAME + iSessionHeightRound
  324. );
  325. m_rctRefFrameUV = m_rctRefFrameY.downSampleBy2 ();
  326. m_pvopcOrig = new CVOPU8YUVBA (m_volmd.fAUsage, m_rctRefFrameY);
  327. m_pvopcRefOrig0 = new CVOPU8YUVBA (m_volmd.fAUsage, m_rctRefFrameY);
  328. m_pvopcRefOrig1 = new CVOPU8YUVBA (m_volmd.fAUsage, m_rctRefFrameY);
  329. allocateVOLMembers (iSessionWidth, iSessionHeight);
  330. CRct rctFrameZoom = m_rctRefFrameY.upSampleBy2 ();
  331. m_puciRefQZoom0 = new CU8Image (rctFrameZoom);
  332. m_puciRefQZoom1 = new CU8Image (rctFrameZoom);
  333. m_pfdct = new CFwdBlockDCT;
  334. // B-VOP MB buffer
  335. m_puciDirectPredMB = new CU8Image (CRct (0, 0, MB_SIZE, MB_SIZE));
  336. m_puciInterpPredMB = new CU8Image (CRct (0, 0, MB_SIZE, MB_SIZE));
  337. m_ppxlcDirectPredMBY = (PixelC*) m_puciDirectPredMB->pixels (); 
  338. m_ppxlcInterpPredMBY = (PixelC*) m_puciInterpPredMB->pixels (); 
  339. m_piiDirectErrorMB = new CIntImage (CRct (0, 0, MB_SIZE, MB_SIZE)); 
  340. m_piiInterpErrorMB = new CIntImage (CRct (0, 0, MB_SIZE, MB_SIZE)); 
  341. m_ppxliDirectErrorMBY = (PixelI*) m_piiDirectErrorMB->pixels (); 
  342. m_ppxliInterpErrorMBY = (PixelI*) m_piiInterpErrorMB->pixels (); 
  343. // with shape
  344. if (m_volmd.fAUsage != RECTANGLE) {
  345. m_rgiSubBlkIndx16x16 = computeShapeSubBlkIndex (4, 16);
  346. m_rgiSSubBlkIndx16x16 = computeShapeSubBlkIndex (2, 16);
  347. m_rgiSubBlkIndx18x18 = computeShapeSubBlkIndex (4, 18);
  348. m_rgiSubBlkIndx20x20 = computeShapeSubBlkIndex (4, 20);
  349. m_rgiPxlIndx12x12 = new Int [8 * 8];
  350. Int* piPxl = m_rgiPxlIndx12x12;
  351. UInt i, j;
  352. for (i = 2; i < 10; i++)
  353. for (j = 2; j < 10; j++)
  354. *piPxl++ = i * 12 + j;
  355. m_rgiPxlIndx8x8 = new Int [4 * 4];
  356. piPxl = m_rgiPxlIndx8x8;
  357. for (i = 2; i < 6; i++)
  358. for (j = 2; j < 6; j++)
  359. *piPxl++ = i * 8 + j;
  360. }
  361. m_statRC.resetSkipMode ();
  362. m_rgdSNR = (m_volmd.fAUsage == EIGHT_BIT) ? new Double [4] : new Double [3];
  363. // some fixed variables
  364. m_iFrameWidthZoomY = m_iFrameWidthY * 2;
  365. m_iFrameWidthZoomUV = m_iFrameWidthUV * 2;
  366. m_iFrameWidthZoomYx2Minus2MB = m_iFrameWidthY * 2 * 2 - 2 * MB_SIZE;
  367. m_iFrameWidthZoomYx2Minus2Blk = m_iFrameWidthY * 2 * 2 - 2 * BLOCK_SIZE;
  368. if (m_volmd.fAUsage == RECTANGLE) {
  369. m_rctCurrVOPY = CRct (0, 0, iSessionWidthRound, iSessionHeightRound);
  370. m_pvopcOrig->setBoundRct (m_rctCurrVOPY);
  371. m_rctCurrVOPUV = m_rctCurrVOPY.downSampleBy2 ();
  372. m_rctRefVOPY0 = m_rctCurrVOPY;
  373. m_rctRefVOPY0.expand (EXPANDY_REFVOP);
  374. m_rctRefVOPUV0 = m_rctRefVOPY0.downSampleBy2 ();
  375. m_rctRefVOPY1 = m_rctRefVOPY0;
  376. m_rctRefVOPUV1 = m_rctRefVOPUV0;
  377. m_rctRefVOPZoom0 = m_rctRefVOPY0.upSampleBy2 ();
  378. m_pvopcRefOrig0->setBoundRct (m_rctRefVOPY0);
  379. m_pvopcRefOrig1->setBoundRct (m_rctRefVOPY1);
  380. computeVOLConstMembers (); // these VOP members are the same for all frames
  381. }
  382. }
  383. Bool CVideoObjectEncoder::skipTest(Time t,VOPpredType vopPredType)
  384. {
  385. if (m_uiRateControl==RC_MPEG4) {
  386. if (!m_statRC.firstFrame ()) {// test whether we should skip this frame
  387. if (m_statRC.skipThisFrame ())
  388. return TRUE;
  389. else
  390. m_statRC.resetFirstFrame ();
  391. }
  392. return FALSE;
  393. }
  394. Void CVideoObjectEncoder::encode (
  395. Bool bVOPVisible, 
  396. Time t,
  397. VOPpredType vopPredType,
  398. const CVOPU8YUVBA* pvopfRefBaseLayer)
  399. {
  400. m_t = t;
  401. m_vopmd.vopPredType = vopPredType;
  402.     m_statsVOP.reset ();
  403. Bool bTemporalScalability = m_volmd.bTemporalScalability; // added by Sharp (98/2/10)
  404. Bool bPrevRefVopWasCoded = m_bCodedFutureRef;
  405. //__LOW_LATENCY_SPRITE_
  406. if (m_uiSprite == 1 && m_sptMode != BASIC_SPRITE && m_vopmd.SpriteXmitMode != STOP) {
  407. setRefStartingPointers (); // need to compute the starting pointers of the refVOP's (corresponding to the current Rct)
  408. computeVOPMembers ();
  409. m_iNumSptMB = 0;
  410. encodeVOP ();
  411. }
  412. else {
  413.     if (m_uiSprite == 1 && m_t>=0)
  414.     m_vopmd.vopPredType = SPRITE;
  415.     m_pbitstrmOut->reset ();
  416.     cout << "nVOP " << m_uiVOId << "n";
  417.     cout << "tVOL " << (int)m_volmd.volType << "n"; // added by Sharp (98/2/10)
  418. if(m_vopmd.vopPredType==IVOP || m_vopmd.vopPredType==PVOP)
  419. m_bCodedFutureRef = bVOPVisible; // flag used by bvop prediction
  420.     if(!bVOPVisible)
  421.     {
  422. #ifdef __TRACE_AND_STATS_
  423.     m_pbitstrmOut -> trace (m_t, "VOP_Time");
  424. #endif // __TRACE_AND_STATS_
  425.     codeNonCodedVOPHead ();
  426.     cout << "tTime..." << m_t << " (" << m_t/m_volmd.dFrameHz << " sec)" 
  427. << "ntNot coded.nn";
  428.     cout.flush ();
  429.     m_statsVOP.nBitsStuffing += m_pbitstrmOut->flush ();
  430. #ifdef __TRACE_AND_STATS_
  431.     m_statsVOP.dSNRY = m_statsVOP.dSNRU = m_statsVOP.dSNRV = 0;
  432.     m_statsVOP.print (TRUE);
  433.     m_statsVOL += m_statsVOP;
  434. #endif // __TRACE_AND_STATS_
  435.     }
  436. if(bPrevRefVopWasCoded) // only swap references if previous vop was coded
  437. {
  438. if (m_volmd.volType == BASE_LAYER)
  439. updateAllRefVOPs (); // update all reconstructed VOP's
  440. else if (!bTemporalScalability) { // modified by Sharp (98/2/10)
  441. if(m_volmd.volType == ENHN_LAYER && m_vopmd.vopPredType == PVOP)
  442. m_vopmd.iRefSelectCode = 3;
  443. else if(m_volmd.volType == ENHN_LAYER && m_vopmd.vopPredType == BVOP)
  444. m_vopmd.iRefSelectCode = 0;
  445. updateAllRefVOPs (pvopfRefBaseLayer); // for spatial scalability
  446. }
  447.      if (m_volmd.bOriginalForME) {
  448.      if (m_vopmd.vopPredType == PVOP || 
  449.      (m_volmd.volType == ENHN_LAYER && m_vopmd.vopPredType == BVOP && m_vopmd.iRefSelectCode == 0))
  450.      swapVOPU8Pointers (m_pvopcRefOrig0, m_pvopcRefOrig1);
  451.      }
  452. }
  453.     if (m_vopmd.vopPredType != BVOP) {
  454. if(bPrevRefVopWasCoded)
  455. {
  456. // swap zoomed ref images
  457. CU8Image *puciTmp = m_puciRefQZoom0;
  458. m_puciRefQZoom0 = m_puciRefQZoom1;
  459. m_puciRefQZoom1 = puciTmp;
  460. m_rctRefVOPZoom0 = m_rctRefVOPZoom1;
  461. }
  462.     m_vopmd.iSearchRangeBackward = 0;
  463. if(bPrevRefVopWasCoded)
  464. if ( !bTemporalScalability || m_volmd.volType == BASE_LAYER ) // added by Sharp (99/1/28)
  465. m_tPastRef = m_tFutureRef;
  466.     m_tDistanceBetwIPVOP = (m_t - m_tPastRef) / m_volmd.iTemporalRate;
  467.             m_tFutureRef = m_t;
  468.     m_iBCount = 0;
  469. if(m_vopmd.vopPredType == PVOP &&
  470. m_volmd.volType == ENHN_LAYER && m_vopmd.iRefSelectCode ==3)
  471. m_tPastRef = m_t;
  472.     if (m_vopmd.vopPredType == PVOP) {
  473. // swap rounding control 0 <-> 1 every coded PVOP
  474. if( bPrevRefVopWasCoded && !m_volmd.bRoundingControlDisable)
  475. m_vopmd.iRoundingControlEncSwitch ^= 0x00000001;
  476. m_vopmd.iRoundingControl = m_vopmd.iRoundingControlEncSwitch;
  477. m_rctRefVOPZoom0 = m_rctRefVOPY0.upSampleBy2 ();
  478. biInterpolateY (m_pvopcRefQ0, m_rctRefVOPY0, m_puciRefQZoom0,
  479. m_rctRefVOPZoom0, m_vopmd.iRoundingControl);
  480.     m_vopmd.iSearchRangeForward = 
  481. checkrange (m_volmd.iMVRadiusPerFrameAwayFromRef * (m_t - m_tPastRef) / m_volmd.iTemporalRate, 1, 1024);
  482.     } else
  483.     m_vopmd.iSearchRangeForward = 0;
  484.     } else {
  485. // BVOP, set rounding control to zero
  486. m_vopmd.iRoundingControl = 0;
  487. if (m_volmd.volType==ENHN_LAYER && m_vopmd.iRefSelectCode==0){
  488. m_tPastRef = m_tFutureRef;
  489. m_tFutureRef = m_t;
  490. }
  491. m_iBCount++;
  492. if (m_iBCount == 1 || (m_volmd.volType == ENHN_LAYER && m_vopmd.iRefSelectCode==0))
  493. {
  494. if(bPrevRefVopWasCoded)
  495. {
  496. m_rctRefVOPZoom1 = m_rctRefVOPY1.upSampleBy2 ();
  497. biInterpolateY (m_pvopcRefQ1,m_rctRefVOPY1,
  498. m_puciRefQZoom1, m_rctRefVOPZoom1, 0);
  499. }
  500. if (m_vopmd.iRoundingControlEncSwitch==1 // modified by Sharp (98/2/10) && // Need to re-compute because iRoundingControl was 1
  501. || (m_volmd.volType == ENHN_LAYER && m_vopmd.iRefSelectCode == 0) || bTemporalScalability) 
  502. {
  503. m_rctRefVOPZoom0 = m_rctRefVOPY0.upSampleBy2 ();
  504. biInterpolateY (m_pvopcRefQ0, m_rctRefVOPY0, m_puciRefQZoom0, m_rctRefVOPZoom0, 0);
  505. }
  506. }
  507. //m_vopmd.iSearchRangeForward = 15;
  508. //m_vopmd.iSearchRangeBackward = 15;
  509. m_vopmd.iSearchRangeForward = 
  510. checkrange ((m_t - m_tPastRef) * m_volmd.iMVRadiusPerFrameAwayFromRef / m_volmd.iTemporalRate, 1, 1024);
  511. m_vopmd.iSearchRangeBackward = 
  512. checkrange ((m_tFutureRef - m_t) * m_volmd.iMVRadiusPerFrameAwayFromRef / m_volmd.iTemporalRate, 1, 1024);
  513.     }
  514.     decideMVInfo();
  515.     m_statsVOP.nVOPs = 1;
  516.      if (m_volmd.fAUsage != RECTANGLE)
  517.      resetBYPlane ();
  518. if(!bVOPVisible)
  519. {
  520. if (m_vopmd.vopPredType != BVOP
  521. && m_volmd.fAUsage != RECTANGLE && bPrevRefVopWasCoded)
  522. {
  523. // give the current object a dummy size
  524. m_iNumMBX = m_iNumMBY = m_iNumMB = 1;
  525. saveShapeMode(); // save the previous reference vop shape mode
  526. }
  527. return;   // return if not coded
  528. }
  529.      // prepare for the current original data
  530.      // extend the currVOP size to multiples of MBSize, will put zero on extended pixels
  531.      if (m_volmd.fAUsage != RECTANGLE) {
  532.      if (m_uiSprite != 1) { // add by cgu to deal with vop-mc-left-top 12/5
  533.      findTightBoundingBox ();
  534.      findBestBoundingBox ();
  535. } else if (m_sptMode == BASIC_SPRITE) {
  536. Int iSpriteWidth =  m_rctSpt.right - m_rctSpt.left;
  537. if(iSpriteWidth%16)
  538. iSpriteWidth += 16 - (iSpriteWidth%16);
  539. Int iSpriteHeight =  m_rctSpt.bottom - m_rctSpt.top;
  540. if(iSpriteHeight%16)
  541. iSpriteHeight += 16 - (iSpriteHeight%16);
  542. m_pvopcOrig->setBoundRct (CRct (0, 0, iSpriteWidth, iSpriteHeight));
  543. }
  544. m_rctCurrVOPY = m_pvopcOrig->whereBoundY ();
  545. m_rctCurrVOPUV = m_pvopcOrig->whereBoundUV ();
  546. setRefStartingPointers (); // need to compute the starting pointers of the refVOP's (corresponding to the current Rct)
  547. computeVOPMembers ();
  548. // Modified for error resilient mode by Toshiba(1998-1-16)
  549. if (m_volmd.bVPBitTh < 0 || m_volmd.bShapeOnly==TRUE) {
  550. m_vopmd.bShapeCodingType = (m_vopmd.vopPredType == IVOP) ? 0 : 1;
  551. } else {
  552. m_vopmd.bShapeCodingType = (m_volmd.iBinaryAlphaRR<0)?1:((m_t % m_volmd.iBinaryAlphaRR)==0) ? 0 : 1;
  553. }
  554. // printf("vop_shape_coding_type=%dn",m_vopmd.bShapeCodingType);
  555. // End Toshiba(1998-1-16)
  556. }
  557. #ifdef __TRACE_AND_STATS_
  558.     m_pbitstrmOut -> trace (m_t, "VOP_Time");
  559. #endif // __TRACE_AND_STATS_
  560.     codeVOPHead ();
  561.     cout << "t" << "Time..." << m_t << " (" << m_t/m_volmd.dFrameHz << " sec)";
  562.     switch(vopPredType)
  563.     {
  564.     case IVOP:
  565.     cout << "tIVOP";
  566.      break;
  567.     case PVOP:
  568.      cout << "tPVOP (reference: t=" << m_tPastRef <<")";
  569.      break;
  570.     case BVOP:
  571.      cout << "tBVOP (past ref: t=" << m_tPastRef
  572.      << ", future ref: t=" << m_tFutureRef <<")";
  573.      break;
  574.     default:
  575.      break;
  576.     }
  577.     cout << "n";
  578.     cout.flush ();
  579.     encodeVOP ();
  580.     m_statsVOP.nBitsStuffing += m_pbitstrmOut->flush ();
  581. }
  582. #ifdef __TRACE_AND_STATS_
  583. if (m_vopmd.vopPredType == BVOP)
  584. computeSNRs (m_pvopcCurrQ);
  585. else
  586. computeSNRs (m_pvopcRefQ1);
  587. m_statsVOP.dSNRY = m_rgdSNR [0];
  588. m_statsVOP.dSNRU = m_rgdSNR [1];
  589. m_statsVOP.dSNRV = m_rgdSNR [2];
  590. if (m_volmd.fAUsage == EIGHT_BIT)
  591. m_statsVOP.dSNRA = m_rgdSNR [3];
  592. m_statsVOP.print (TRUE);
  593. m_statsVOL += m_statsVOP;
  594. #endif // __TRACE_AND_STATS_
  595. // rate control
  596. if (m_uiRateControl==RC_MPEG4) {
  597. assert (m_volmd.volType == BASE_LAYER); //don't no know to do RC for scalability yet
  598. #ifndef __TRACE_AND_STATS_
  599. cerr << "Compile flag __TRACE_AND_STATS_ required for stats for rate control." << endl;
  600. exit(1);
  601. #endif // __TRACE_AND_STATS_
  602. if (m_vopmd.vopPredType == IVOP) { // !!!! check whether CRct has been expanded
  603. Double dMad = 
  604. (m_pvopcOrig->getPlane (Y_PLANE)->sumAbs (m_rctCurrVOPY)) / 
  605. (Double) (m_rctCurrVOPY.area ());
  606. m_statRC.reset (
  607. m_nFirstFrame, 
  608. m_nLastFrame, 
  609. m_volmd.iTemporalRate, 
  610. m_iBufferSize, 
  611. dMad, 
  612. m_statsVOL.nBitsTotal,
  613. m_volmd.dFrameHz
  614. );
  615. }
  616. else if (m_vopmd.vopPredType == PVOP)
  617. m_statRC.updateRCModel (m_statsVOP.total (), m_statsVOP.head ());
  618. }
  619. // store the direct mode data (by swaping pointers)
  620. if (m_vopmd.vopPredType != BVOP) {
  621. if(m_volmd.fAUsage != RECTANGLE && bPrevRefVopWasCoded)
  622. saveShapeMode();
  623. CMBMode* pmbmdTmp = m_rgmbmd;
  624. m_rgmbmd = m_rgmbmdRef;
  625. m_rgmbmdRef = pmbmdTmp;
  626. CMotionVector* pmvTmp = m_rgmv;
  627. m_rgmv = m_rgmvRef;
  628. m_rgmvRef = pmvTmp;
  629. //wchen: should not only for pvop
  630. //if (m_vopmd.vopPredType == PVOP) 
  631. m_rgmvBackward = m_rgmv + BVOP_MV_PER_REF_PER_MB * m_iSessNumMB;
  632. #if 0 // Debugging .. use the same anchor VOPs as reference implementation
  633. static FILE *pfRefPicInputFile = NULL;
  634. if (pfRefPicInputFile == NULL) {
  635. pfRefPicInputFile = fopen("ref.yuv", "rb");
  636. assert(pfRefPicInputFile != NULL);
  637. }
  638. Int iLeadingPixels = m_t * m_rctPrevNoExpandY.area ();
  639. fseek (pfRefPicInputFile, iLeadingPixels + iLeadingPixels / 2, SEEK_SET); //4:2:0
  640. static Int iYDataHeight = m_rctPrevNoExpandY.height ();
  641. static Int iUVDataHeight = m_rctPrevNoExpandY.height () / 2;
  642. static Int iYFrmWidth = m_pvopcRefQ1->whereY ().width;
  643. static Int iUvFrmWidth = m_pvopcRefQ1->whereUV ().width;
  644. static Int nSkipYPixel = iYFrmWidth * EXPANDY_REF_FRAME + EXPANDY_REF_FRAME;
  645. static Int nSkipUvPixel = iUvFrmWidth * EXPANDUV_REF_FRAME + EXPANDUV_REF_FRAME;
  646. PixelC* ppxlcY = (PixelC*) m_pvopcRefQ1->pixelsY () + nSkipYPixel;
  647. PixelC* ppxlcU = (PixelC*) m_pvopcRefQ1->pixelsU () + nSkipUvPixel;
  648. PixelC* ppxlcV = (PixelC*) m_pvopcRefQ1->pixelsV () + nSkipUvPixel;
  649. for (CoordI y = 0; y < iYDataHeight; y++) {
  650. Int size = (Int) fread (ppxlcY, sizeof (U8), m_rctPrevNoExpandY.width, pfRefPicInputFile);
  651. if (size == 0)
  652. fprintf (stderr, "Unexpected end of filen");
  653. ppxlcY += iYFrmWidth;
  654. }
  655. for (y = 0; y < iUVDataHeight; y++) {
  656. Int size = (Int) fread (ppxlcU, sizeof (U8), m_rctPrevNoExpandY.width / 2, pfRefPicInputFile);
  657. if (size == 0)
  658. fprintf (stderr, "Unexpected end of filen");
  659. ppxlcU += iUvFrmWidth;
  660. }
  661. for (y = 0; y < iUVDataHeight; y++) {
  662. Int size = (Int) fread (ppxlcV, sizeof (U8), m_rctPrevNoExpandY.width / 2, pfRefPicInputFile);
  663. if (size == 0)
  664. fprintf (stderr, "Unexpected end of filen");
  665. ppxlcV += iUvFrmWidth;
  666. }
  667. #endif
  668. }
  669. if (m_volmd.fAUsage != RECTANGLE) {
  670. if (m_vopmd.vopPredType != BVOP) {
  671. m_iNumMBRef = m_iNumMB;
  672. m_iNumMBXRef = m_iNumMBX;
  673. m_iNumMBYRef = m_iNumMBY;
  674. m_iOffsetForPadY = m_rctRefFrameY.offset (m_rctCurrVOPY.left, m_rctCurrVOPY.top);
  675. m_iOffsetForPadUV = m_rctRefFrameUV.offset (m_rctCurrVOPUV.left, m_rctCurrVOPUV.top);
  676. m_rctPrevNoExpandY = m_rctCurrVOPY;
  677. m_rctPrevNoExpandUV = m_rctCurrVOPUV;
  678. m_rctRefVOPY1 = m_rctCurrVOPY;
  679. m_rctRefVOPY1.expand (EXPANDY_REFVOP);
  680. m_rctRefVOPUV1 = m_rctCurrVOPUV;
  681. m_rctRefVOPUV1.expand (EXPANDUV_REFVOP);
  682. m_pvopcRefQ1->setBoundRct (m_rctRefVOPY1);
  683. }
  684. // begin:  added by by Sharp (98/2/10)
  685. if ( bTemporalScalability && m_vopmd.vopPredType == BVOP ) {
  686. m_iBVOPOffsetForPadY = m_rctRefFrameY.offset (m_rctCurrVOPY.left, m_rctCurrVOPY.top);
  687. m_iBVOPOffsetForPadUV = m_rctRefFrameUV.offset (m_rctCurrVOPUV.left, m_rctCurrVOPUV.top);
  688. m_rctBVOPPrevNoExpandY = m_rctCurrVOPY;
  689. m_rctBVOPPrevNoExpandUV = m_rctCurrVOPUV;
  690. m_rctBVOPRefVOPY1 = m_rctCurrVOPY;
  691. m_rctBVOPRefVOPY1.expand (EXPANDY_REFVOP);
  692. m_rctBVOPRefVOPUV1 = m_rctCurrVOPUV;
  693. m_rctBVOPRefVOPUV1.expand (EXPANDUV_REFVOP);
  694. }
  695. // end: added by Sharp (98/2/10)
  696. //this is ac/dc pred stuff; clean the memory
  697. Int nBlk = (m_volmd.fAUsage == EIGHT_BIT) ? 10 : 6;
  698. delete [] m_rgblkmCurrMB;
  699. for (Int iMB = 0; iMB < m_iNumMBX; iMB++) {
  700. for (Int iBlk = 0; iBlk < nBlk; iBlk++) {
  701. delete [] (m_rgpmbmAbove [iMB]->rgblkm) [iBlk];
  702. delete [] (m_rgpmbmCurr  [iMB]->rgblkm) [iBlk];
  703. }
  704. delete [] m_rgpmbmAbove [iMB]->rgblkm;
  705. delete m_rgpmbmAbove [iMB];
  706. delete [] m_rgpmbmCurr [iMB]->rgblkm;
  707. delete m_rgpmbmCurr [iMB];
  708. }
  709. delete [] m_rgpmbmAbove;
  710. delete [] m_rgpmbmCurr;
  711. }
  712. // begin: added by Sharp (98/2/10)
  713. if ( bTemporalScalability && m_volmd.fAUsage == RECTANGLE ) {
  714. m_iBVOPOffsetForPadY = m_iOffsetForPadY;
  715. m_iBVOPOffsetForPadUV = m_iOffsetForPadUV;
  716. m_rctBVOPPrevNoExpandY = m_rctPrevNoExpandY;
  717. m_rctBVOPPrevNoExpandUV = m_rctPrevNoExpandUV;
  718. m_rctBVOPRefVOPY1 = m_rctRefVOPY1;
  719. m_rctBVOPRefVOPUV1 = m_rctRefVOPUV1;
  720. }
  721. // end: added by Sharp (98/2/10)
  722. // __LOW_LATENCY_SPRITE_
  723. if (m_uiSprite == 1 && m_sptMode != BASIC_SPRITE && m_vopmd.SpriteXmitMode != STOP)
  724. return;
  725.     if (m_vopmd.vopPredType != BVOP || m_volmd.volType == ENHN_LAYER) {
  726. repeatPadYOrA ((PixelC*) m_pvopcRefQ1->pixelsY () + m_iOffsetForPadY, m_pvopcRefQ1);
  727. repeatPadUV (m_pvopcRefQ1);
  728. if (m_volmd.fAUsage != RECTANGLE)       {
  729. if (m_volmd.fAUsage == EIGHT_BIT)
  730. repeatPadYOrA ((PixelC*) m_pvopcRefQ1->pixelsA () + m_iOffsetForPadY, m_pvopcRefQ1);
  731. }
  732. }
  733. if( m_volmd.volType == ENHN_LAYER && 
  734. m_vopmd.vopPredType == BVOP &&
  735. m_vopmd.iRefSelectCode == 0){
  736. repeatPadYOrA ((PixelC*) m_pvopcCurrQ->pixelsY () + m_iOffsetForPadY, m_pvopcCurrQ);
  737. repeatPadUV (m_pvopcCurrQ);
  738. }
  739. if (m_volmd.bOriginalForME) {
  740. if (m_vopmd.vopPredType == IVOP || m_vopmd.vopPredType == PVOP || 
  741.     (m_volmd.volType == ENHN_LAYER && m_vopmd.vopPredType == BVOP && m_vopmd.iRefSelectCode == 0))
  742. updateAllOrigRefVOPs (); // update all original reference (MotionEsti) VOP's
  743. }
  744. }
  745. Void CVideoObjectEncoder::codeVOHead ()
  746. {
  747. m_pbitstrmOut -> putBits (START_CODE_PREFIX, NUMBITS_START_CODE_PREFIX, "VOSH_Start_Code");
  748. m_pbitstrmOut -> putBits (SESSION_START_CODE, 8, "VOSH_Start_Code");
  749. // Just signal Advanced Simple Profile @ L2 for now
  750. m_pbitstrmOut -> putBits (0xF3, 8, "VOSH_Start_Code");
  751. m_pbitstrmOut -> putBits (START_CODE_PREFIX, NUMBITS_START_CODE_PREFIX, "VO_Start_Code");
  752. m_pbitstrmOut -> putBits (VISUAL_OBJ_START_CODE, 8, "Visual_Obj_Start_Code");
  753. m_pbitstrmOut -> putBits (0x09, 8, "Visual_Object_Id");
  754. m_pbitstrmOut -> putBits (START_CODE_PREFIX, NUMBITS_START_CODE_PREFIX, "VO_Start_Code");
  755. m_pbitstrmOut -> putBits (VO_START_CODE, NUMBITS_VO_START_CODE, "VO_Start_Code"); //plus 3 bits
  756. m_pbitstrmOut -> putBits (m_uiVOId, NUMBITS_VO_ID, "VO_Id");
  757. UInt uiNumBits = NUMBITS_START_CODE_PREFIX + NUMBITS_VO_START_CODE + NUMBITS_VO_ID;;
  758. m_statsVOL.nBitsHead += uiNumBits;
  759. cout << "VO Overhead" << "tt" << uiNumBits << "nn";
  760. cout.flush ();
  761. }
  762. Void CVideoObjectEncoder::codeVOLHead (Int iSessionWidth, Int iSessionHeight)
  763. {
  764. m_pbitstrmOut -> putBits (START_CODE_PREFIX, NUMBITS_START_CODE_PREFIX, "VOL_Start_Code");
  765. m_pbitstrmOut -> putBits (VOL_START_CODE, NUMBITS_VOL_START_CODE, "VOL_Start_Code"); //plus 4 bits
  766. m_pbitstrmOut -> putBits ((Int) (m_volmd.volType == ENHN_LAYER), NUMBITS_VOL_ID, "VOL_Id"); // by katata
  767. m_statsVOL.nBitsHead+=NUMBITS_START_CODE_PREFIX+NUMBITS_VOL_START_CODE+NUMBITS_VOL_ID;
  768. // Begin: modified by Hughes   4/9/98   per clause 2.1.7. in N2171 document
  769. m_pbitstrmOut -> putBits ((Int) 0, 1, "VOL_Random_Access"); //isn't this a system level flg?
  770. m_statsVOL.nBitsHead++;
  771. // End: modified by Hughes   4/9/98
  772. m_pbitstrmOut -> putBits ((Int) 4, 8, "VOL_Type_Indicator"); // Set to indicate MAIN profile.
  773. m_statsVOL.nBitsHead+=8;
  774. m_pbitstrmOut -> putBits ((Int) 0, 1, "VOL_Is_Object_Layer_Identifier"); //useless flag for now
  775. m_statsVOL.nBitsHead++;
  776. m_pbitstrmOut -> putBits ((Int) 1, 4, "aspect_ratio_info"); // square pix
  777. m_statsVOL.nBitsHead+=4;
  778. m_pbitstrmOut -> putBits (m_volmd.uiVolControlParameters, 1, "VOL_Control_Parameters"); //useless flag for now
  779. m_statsVOL.nBitsHead++;
  780. if(m_volmd.uiVolControlParameters)
  781. {
  782. m_pbitstrmOut -> putBits (m_volmd.uiChromaFormat, 2, "Chroma_Format");
  783. m_pbitstrmOut -> putBits (m_volmd.uiLowDelay, 1, "Low_Delay");
  784. m_pbitstrmOut -> putBits (m_volmd.uiVBVParams, 1, "VBV_Params");
  785. m_statsVOL.nBitsHead += 2 + 1 + 1;
  786. if(m_volmd.uiVBVParams)
  787. {
  788. UInt uiFirstHalfBitRate = (m_volmd.uiBitRate >> 15);
  789. UInt uiLatterHalfBitRate = (m_volmd.uiBitRate & 0x7fff);
  790. m_pbitstrmOut -> putBits (uiFirstHalfBitRate, 15, "FirstHalf_BitRate");
  791. m_pbitstrmOut -> putBits (1, 1, "Marker");
  792. m_pbitstrmOut -> putBits (uiLatterHalfBitRate, 15, "LatterHalf_BitRate");
  793. m_pbitstrmOut -> putBits (1, 1, "Marker");
  794. UInt uiFirstHalfVbvBufferSize = (m_volmd.uiVbvBufferSize >> 3);
  795. UInt uiLatterHalfVbvBufferSize = (m_volmd.uiVbvBufferSize & 7);
  796. m_pbitstrmOut -> putBits (uiFirstHalfVbvBufferSize, 15, "FirstHalf_VbvBufferSize");
  797. m_pbitstrmOut -> putBits (1, 1, "Marker");
  798. m_pbitstrmOut -> putBits (uiLatterHalfVbvBufferSize, 3, "LatterHalf_VbvBufferSize");
  799. UInt uiFirstHalfVbvBufferOccupany = (m_volmd.uiVbvBufferOccupany >> 15);
  800. UInt uiLatterHalfVbvBufferOccupany = (m_volmd.uiVbvBufferOccupany & 0x7fff);
  801. m_pbitstrmOut -> putBits (uiFirstHalfVbvBufferOccupany, 11, "FirstHalf_VbvBufferOccupany");
  802. m_pbitstrmOut -> putBits (1, 1, "Marker");
  803. m_pbitstrmOut -> putBits (uiLatterHalfVbvBufferOccupany, 15, "LatterHalf_VbvBufferOccupany");
  804. m_pbitstrmOut -> putBits (1, 1, "Marker");
  805. m_statsVOL.nBitsHead += 15 + 15 + 15 + 3 + 11 + 15;
  806. m_statsVOL.nBitsStuffing += 5;
  807. }
  808. }
  809. if(m_volmd.bShapeOnly==TRUE)
  810. {
  811. m_pbitstrmOut -> putBits ((Int) 2, NUMBITS_VOL_SHAPE, "VOL_Shape_Type");
  812. m_pbitstrmOut -> putBits (1, 1, "Marker");
  813. m_pbitstrmOut -> putBits (m_volmd.iClockRate, NUMBITS_TIME_RESOLUTION, "VOL_Time_Increment_Resolution"); 
  814. m_pbitstrmOut -> putBits (1, 1, "Marker");
  815. m_pbitstrmOut -> putBits (0, 1, "VOL_Fixed_Vop_Rate");
  816. m_pbitstrmOut -> putBits (0, 1, "VOL_resync_marker_disable");
  817. m_statsVOL.nBitsHead += NUMBITS_VOL_SHAPE + NUMBITS_TIME_RESOLUTION + 2;
  818. m_statsVOL.nBitsStuffing +=2;
  819. cout << "VOL Overhead" << "tt" << m_statsVOL.nBitsHead << "nn";
  820. cout.flush ();
  821. return;
  822. }
  823. else
  824. {
  825. Int iAUsage = (Int)m_volmd.fAUsage;
  826. if(iAUsage==2) // CD: 0 = rect, 1 = binary, 2 = shape only, 3 = grey alpha
  827. iAUsage = 3;
  828. m_pbitstrmOut -> putBits (iAUsage, NUMBITS_VOL_SHAPE, "VOL_Shape_Type");
  829. m_pbitstrmOut -> putBits (1, 1, "Marker");
  830. m_pbitstrmOut -> putBits (m_volmd.iClockRate, NUMBITS_TIME_RESOLUTION, "VOL_Time_Increment_Resolution"); 
  831. m_pbitstrmOut -> putBits (1, 1, "Marker");
  832. m_pbitstrmOut -> putBits (0, 1, "VOL_Fixed_Vop_Rate");
  833. m_statsVOL.nBitsHead += NUMBITS_VOL_SHAPE + NUMBITS_TIME_RESOLUTION + 1;
  834. if (m_volmd.fAUsage == RECTANGLE) {
  835. m_pbitstrmOut -> putBits (MARKER_BIT, 1, "Marker_Bit");
  836. m_statsVOL.nBitsStuffing ++;
  837. m_pbitstrmOut -> putBits (iSessionWidth, NUMBITS_VOP_WIDTH, "VOL_Width"); 
  838. m_pbitstrmOut -> putBits (MARKER_BIT, 1, "Marker_Bit");
  839. m_statsVOL.nBitsStuffing ++;
  840. m_pbitstrmOut -> putBits (iSessionHeight, NUMBITS_VOP_HEIGHT, "VOL_Height"); 
  841. m_pbitstrmOut -> putBits (MARKER_BIT, 1, "Marker_Bit");
  842. m_statsVOL.nBitsStuffing ++;
  843. m_statsVOL.nBitsHead += NUMBITS_VOP_WIDTH + NUMBITS_VOP_HEIGHT;
  844. }
  845. }
  846. m_pbitstrmOut -> putBits (m_vopmd.bInterlace, (UInt) 1, "VOL_interlace");
  847. m_statsVOL.nBitsHead++;
  848. m_pbitstrmOut -> putBits (m_volmd.bAdvPredDisable, (UInt) 1, "VOL_OBMC_Disable");
  849. m_statsVOL.nBitsHead++;
  850. // code sprite info
  851. m_pbitstrmOut -> putBits (m_uiSprite, NUMBITS_SPRITE_USAGE, "VOL_Sprite_Usage");
  852. m_statsVOL.nBitsHead += NUMBITS_SPRITE_USAGE;
  853. if (m_uiSprite == 1) {
  854. m_pbitstrmOut -> putBits (m_rctSpt.width, NUMBITS_SPRITE_HDIM, "SPRT_hdim");
  855. m_statsVOL.nBitsHead += NUMBITS_SPRITE_HDIM; 
  856. m_pbitstrmOut -> putBits (MARKER_BIT, 1, "Marker_Bit");
  857. m_statsVOL.nBitsStuffing ++;
  858. m_pbitstrmOut -> putBits (m_rctSpt.height (), NUMBITS_SPRITE_VDIM, "SPRT_vdim");
  859. m_statsVOL.nBitsHead += NUMBITS_SPRITE_VDIM;
  860. m_pbitstrmOut -> putBits (MARKER_BIT, 1, "Marker_Bit");
  861. m_statsVOL.nBitsStuffing ++;
  862. if (m_rctSpt.left >= 0) {
  863. m_pbitstrmOut -> putBits (m_rctSpt.left, NUMBITS_SPRITE_LEFT_EDGE, "SPRT_Left_Edge");
  864. } else {
  865. m_pbitstrmOut -> putBits (m_rctSpt.left & 0x00001FFFF, NUMBITS_SPRITE_LEFT_EDGE, "SPRT_Left_Edge");
  866. }
  867. m_statsVOL.nBitsHead += NUMBITS_SPRITE_LEFT_EDGE;
  868. m_pbitstrmOut -> putBits (MARKER_BIT, 1, "Marker_Bit");
  869. m_statsVOL.nBitsStuffing += 1;
  870. if (m_rctSpt.top >= 0) {
  871. m_pbitstrmOut -> putBits (m_rctSpt.top, NUMBITS_SPRITE_TOP_EDGE, "SPRT_Top_Edge");
  872. } else {
  873. m_pbitstrmOut -> putBits (m_rctSpt.top & 0x00001FFFF, NUMBITS_SPRITE_TOP_EDGE, "SPRT_Top_Edge");
  874. }
  875. m_statsVOL.nBitsHead += NUMBITS_SPRITE_TOP_EDGE; 
  876. m_pbitstrmOut -> putBits (MARKER_BIT, 1, "Marker_Bit");
  877. m_statsVOL.nBitsStuffing += 1;
  878. m_pbitstrmOut -> putBits (m_iNumOfPnts, NUMBITS_NUM_SPRITE_POINTS, "SPRT_Num_Pnt");
  879. m_statsVOL.nBitsHead += NUMBITS_NUM_SPRITE_POINTS;
  880. m_pbitstrmOut -> putBits (m_uiWarpingAccuracy, NUMBITS_WARPING_ACCURACY, "SPRT_Warping_Accuracy");
  881. m_statsVOL.nBitsHead += NUMBITS_WARPING_ACCURACY;
  882. Bool bLightChange = 0;
  883. m_pbitstrmOut -> putBits (bLightChange, 1, "SPRT_Brightness_Change");
  884. m_statsVOL.nBitsHead++;
  885. // Begin: modified by Hughes   4/9/98
  886. if (m_sptMode == BASIC_SPRITE)
  887. m_pbitstrmOut -> putBits (FALSE, 1, "Low_latency_sprite_enable");
  888. else
  889. m_pbitstrmOut -> putBits (TRUE, 1, "Low_latency_sprite_enable");
  890. m_statsVOL.nBitsHead++;
  891. // End: modified by Hughes   4/9/98
  892. }
  893. // NBIT
  894. m_pbitstrmOut -> putBits ((Int) m_volmd.bNot8Bit, 1, "VOL_NOT_8_BIT_VIDEO");
  895. m_statsVOL.nBitsHead++;
  896. if (m_volmd.bNot8Bit) {
  897. m_pbitstrmOut->putBits ((Int) m_volmd.uiQuantPrecision, 4, "QUANT_PRECISION");
  898. m_pbitstrmOut->putBits ((Int) m_volmd.nBits, 4, "BITS_PER_PIXEL");
  899. m_statsVOL.nBitsHead+=8;
  900. }
  901. if (m_volmd.fAUsage == EIGHT_BIT) {
  902. m_pbitstrmOut -> putBits (m_volmd.bNoGrayQuantUpdate, 1, "VOL_Disable_Gray_Q_Update");
  903. m_pbitstrmOut -> putBits (0, 1, "Composition_Method");
  904. m_pbitstrmOut -> putBits (1, 1, "Linear_Composition");
  905. m_statsVOL.nBitsHead+=3;
  906. }
  907. m_pbitstrmOut -> putBits ((Int) m_volmd.fQuantizer, 1, "VOL_Quant_Type"); 
  908. m_statsVOL.nBitsHead++;
  909. if (m_volmd.fQuantizer == Q_MPEG) {
  910. m_pbitstrmOut -> putBits (m_volmd.bLoadIntraMatrix, 1, "VOL_Load_Q_Matrix (intra)");
  911. m_statsVOL.nBitsHead++;
  912. if (m_volmd.bLoadIntraMatrix) {
  913. UInt i = 0;
  914. do {
  915. m_pbitstrmOut -> putBits (m_volmd.rgiIntraQuantizerMatrix [grgiStandardZigzag[i]], NUMBITS_QMATRIX, "VOL_Quant_Matrix(intra)");
  916. m_statsVOL.nBitsHead += NUMBITS_QMATRIX;
  917. } while (m_volmd.rgiIntraQuantizerMatrix [grgiStandardZigzag[i]] != 0 && ++i < BLOCK_SQUARE_SIZE);
  918. for (UInt j = i; j < BLOCK_SQUARE_SIZE; j++) {
  919. m_volmd.rgiIntraQuantizerMatrix [grgiStandardZigzag[j]] = m_volmd.rgiIntraQuantizerMatrix [grgiStandardZigzag[i - 1]];
  920. }
  921. }
  922. m_pbitstrmOut -> putBits (m_volmd.bLoadInterMatrix, 1, "VOL_Load_Q_Matrix (inter)");
  923. m_statsVOL.nBitsHead++;
  924. if (m_volmd.bLoadInterMatrix) {
  925. UInt i = 0;
  926. do {
  927. m_pbitstrmOut -> putBits (m_volmd.rgiInterQuantizerMatrix [grgiStandardZigzag[i]], NUMBITS_QMATRIX, "VOL_Quant_Matrix(intra)");
  928. m_statsVOL.nBitsHead += NUMBITS_QMATRIX;
  929. } while (m_volmd.rgiInterQuantizerMatrix [grgiStandardZigzag[i]] != 0 && ++i < BLOCK_SQUARE_SIZE);
  930. for (UInt j = i; j < BLOCK_SQUARE_SIZE; j++) {
  931. m_volmd.rgiInterQuantizerMatrix [grgiStandardZigzag[j]] = m_volmd.rgiInterQuantizerMatrix [grgiStandardZigzag[i - 1]];
  932. }
  933. }
  934. if (m_volmd.fAUsage == EIGHT_BIT) {
  935. m_pbitstrmOut -> putBits (m_volmd.bLoadIntraMatrixAlpha, 1, "VOL_Load_Alpha_Q_Matrix (intra)");
  936. m_statsVOL.nBitsHead++;
  937. if (m_volmd.bLoadIntraMatrixAlpha) {
  938. for (UInt i = 0; i < BLOCK_SQUARE_SIZE; i++) {
  939. m_pbitstrmOut -> putBits (m_volmd.rgiIntraQuantizerMatrixAlpha [grgiStandardZigzag[i]], NUMBITS_QMATRIX, "VOL_Alpha_Quant_Matrix(intra)");
  940. m_statsVOL.nBitsHead += NUMBITS_QMATRIX;
  941. }
  942. }
  943. m_pbitstrmOut -> putBits (m_volmd.bLoadInterMatrixAlpha, 1, "VOL_Load_Alpha_Q_Matrix (inter)");
  944. m_statsVOL.nBitsHead++;
  945. if (m_volmd.bLoadInterMatrixAlpha) {
  946. for (UInt i = 0; i < BLOCK_SQUARE_SIZE; i++) {
  947. m_pbitstrmOut -> putBits (m_volmd.rgiInterQuantizerMatrixAlpha [grgiStandardZigzag[i]], NUMBITS_QMATRIX, "VOL_Alpha_Quant_Matrix(inter)");
  948. m_statsVOL.nBitsHead += NUMBITS_QMATRIX;
  949. }
  950. }
  951. }
  952. }
  953. // START: Complexity Estimation syntax support - Marc Mongenet (EPFL) - 16 Jun 1998
  954. m_pbitstrmOut -> putBits (m_volmd.bComplexityEstimationDisable,
  955.   1, "complexity_estimation_disable");
  956. m_statsVOL.nBitsHead += 1;
  957. if (! m_volmd.bComplexityEstimationDisable) {
  958. m_volmd.iEstimationMethod = 0; // only known estimation method at now (18 Jun 1998)
  959. m_volmd.bShapeComplexityEstimationDisable =
  960.   !(m_volmd.bOpaque ||
  961. m_volmd.bTransparent ||
  962. m_volmd.bIntraCAE ||
  963. m_volmd.bInterCAE ||
  964. m_volmd.bNoUpdate ||
  965. m_volmd.bUpsampling);
  966. m_volmd.bTextureComplexityEstimationSet1Disable =
  967.   !(m_volmd.bIntraBlocks ||
  968. m_volmd.bInterBlocks ||
  969. m_volmd.bInter4vBlocks ||
  970. m_volmd.bNotCodedBlocks);
  971. m_volmd.bTextureComplexityEstimationSet2Disable =
  972.   !(m_volmd.bDCTCoefs ||
  973. m_volmd.bDCTLines ||
  974. m_volmd.bVLCSymbols ||
  975. m_volmd.bVLCBits);
  976. m_volmd.bMotionCompensationComplexityDisable =
  977.   !(m_volmd.bAPM ||
  978. m_volmd.bNPM ||
  979. m_volmd.bInterpolateMCQ ||
  980. m_volmd.bForwBackMCQ ||
  981. m_volmd.bHalfpel2 ||
  982. m_volmd.bHalfpel4);
  983. assert (m_volmd.iEstimationMethod == 0);
  984. m_pbitstrmOut -> putBits (m_volmd.iEstimationMethod, 2, "estimation_method");
  985. m_statsVOL.nBitsHead += 2;
  986. m_pbitstrmOut -> putBits (m_volmd.bShapeComplexityEstimationDisable,
  987.   1, "shape_complexity_estimation_disable");
  988. m_statsVOL.nBitsHead += 1;
  989. if (! m_volmd.bShapeComplexityEstimationDisable) {
  990. m_pbitstrmOut -> putBits (m_volmd.bOpaque, 1, "opaque");
  991. m_pbitstrmOut -> putBits (m_volmd.bTransparent, 1, "transparent");
  992. m_pbitstrmOut -> putBits (m_volmd.bIntraCAE, 1, "intra_cae");
  993. m_pbitstrmOut -> putBits (m_volmd.bInterCAE, 1, "inter_cae");
  994. m_pbitstrmOut -> putBits (m_volmd.bNoUpdate, 1, "no_update");
  995. m_pbitstrmOut -> putBits (m_volmd.bUpsampling, 1, "upsampling");
  996. m_statsVOL.nBitsHead += 6;
  997. }
  998. m_pbitstrmOut -> putBits (m_volmd.bTextureComplexityEstimationSet1Disable,
  999.   1, "texture_complexity_estimation_set_1_disable");
  1000. m_statsVOL.nBitsHead += 1;
  1001. if (! m_volmd.bTextureComplexityEstimationSet1Disable) {
  1002. m_pbitstrmOut -> putBits (m_volmd.bIntraBlocks, 1, "intra_blocks");
  1003. m_pbitstrmOut -> putBits (m_volmd.bInterBlocks, 1, "inter_blocks");
  1004. m_pbitstrmOut -> putBits (m_volmd.bInter4vBlocks, 1, "inter4v_blocks");
  1005. m_pbitstrmOut -> putBits (m_volmd.bNotCodedBlocks, 1, "not_coded_blocks");
  1006. m_statsVOL.nBitsHead += 4;
  1007. }
  1008. m_pbitstrmOut -> putBits (1, 1, "Marker_Bit");
  1009. m_statsVOL.nBitsStuffing ++;
  1010. m_pbitstrmOut -> putBits (m_volmd.bTextureComplexityEstimationSet2Disable,
  1011.   1, "texture_complexity_estimation_set_2_disable");
  1012. m_statsVOL.nBitsHead += 1;
  1013. if (! m_volmd.bTextureComplexityEstimationSet2Disable) {
  1014. m_pbitstrmOut -> putBits (m_volmd.bDCTCoefs, 1, "dct_coefs");
  1015. m_pbitstrmOut -> putBits (m_volmd.bDCTLines, 1, "dct_lines");
  1016. m_pbitstrmOut -> putBits (m_volmd.bVLCSymbols, 1, "vlc_symbols");
  1017. m_pbitstrmOut -> putBits (m_volmd.bVLCBits, 1, "vlc_bits");
  1018. m_statsVOL.nBitsHead += 4;
  1019. }
  1020. m_pbitstrmOut -> putBits (m_volmd.bMotionCompensationComplexityDisable,
  1021.   1, "motion_compensation_complexity_disable");
  1022. m_statsVOL.nBitsHead += 1;
  1023. if (! m_volmd.bMotionCompensationComplexityDisable) {
  1024. m_pbitstrmOut -> putBits (m_volmd.bAPM, 1, "apm");
  1025. m_pbitstrmOut -> putBits (m_volmd.bNPM, 1, "npm");
  1026. m_pbitstrmOut -> putBits (m_volmd.bInterpolateMCQ, 1, "interpolate_mc_q");
  1027. m_pbitstrmOut -> putBits (m_volmd.bForwBackMCQ, 1, "forw_back_mc_q");
  1028. m_pbitstrmOut -> putBits (m_volmd.bHalfpel2, 1, "halfpel2");
  1029. m_pbitstrmOut -> putBits (m_volmd.bHalfpel4, 1, "halfpel4");
  1030. m_statsVOL.nBitsHead += 6;
  1031. }
  1032. m_pbitstrmOut -> putBits (1, 1, "Marker_Bit");
  1033. m_statsVOL.nBitsStuffing ++;
  1034. }
  1035. // END: Complexity Estimation syntax support
  1036. m_pbitstrmOut -> putBits (0, 1, "VOL_resync_marker_disable");
  1037. m_statsVOL.nBitsHead ++;
  1038. // Modified by Toshiba(1998-4-7)
  1039. m_pbitstrmOut -> putBits (m_volmd.bDataPartitioning, 1, "VOL_data_partitioning");
  1040. m_statsVOL.nBitsHead ++;
  1041. if( m_volmd.bDataPartitioning )
  1042. {
  1043. m_pbitstrmOut -> putBits (m_volmd.bReversibleVlc, 1, "VOL_reversible_vlc");
  1044. m_statsVOL.nBitsHead ++;
  1045. }
  1046. // End Toshiba
  1047. m_pbitstrmOut -> putBits (m_volmd.volType == ENHN_LAYER, 1, "VOL_Scalability");
  1048. m_statsVOL.nBitsHead++;
  1049. if (m_volmd.volType == ENHN_LAYER) {
  1050. //#ifdef _Scalable_SONY_
  1051. m_pbitstrmOut -> putBits (m_volmd.iHierarchyType, 1, "VOL_Hierarchy_Type");
  1052. //#endif _Scalable_SONY_
  1053. m_pbitstrmOut -> putBits (0, 4, "VOL_Ref_Layer_Id");
  1054. m_pbitstrmOut -> putBits (0, 1, "VOL_Ref_Layer_Sampling_Dir");
  1055. /*Added*/
  1056. m_pbitstrmOut -> putBits (m_volmd.ihor_sampling_factor_n, 5, "VOL_Horizontal_Sampling_Factor"); //The vm is not very clear about this.
  1057. m_pbitstrmOut -> putBits (m_volmd.ihor_sampling_factor_m, 5, "VOL_Horizontal_Sampling_Factor_Ref"); //Always 1
  1058. m_pbitstrmOut -> putBits (m_volmd.iver_sampling_factor_n, 5, "VOL_Vertical_Sampling_Factor"); //The vm is not very clear about this.
  1059. m_pbitstrmOut -> putBits (m_volmd.iver_sampling_factor_m, 5, "VOL_Vertical_Sampling_Factor_Ref"); //Always 1
  1060. m_pbitstrmOut -> putBits (m_volmd.iEnhnType!=0?1:0, 1, "VOL_Ehnancement_Type"); // enhancement_type for scalability // modified by Sharp (98/3/24)
  1061. m_statsVOL.nBitsHead += 26;
  1062. }
  1063. // Begin: modified by Hughes   4/9/98   per clause 2.1.7. in N2171 document
  1064. // m_pbitstrmOut -> putBits ((Int) 0, 1, "VOL_Random_Access"); //isn't this a system level flg?
  1065. // m_statsVOL.nBitsHead++;
  1066. // End: modified by Hughes   4/9/98
  1067. cout << "VOL Overhead" << "tt" << m_statsVOL.nBitsHead << "nn";
  1068. cout.flush ();
  1069. }
  1070. //encode GOV header, modified by SONY 980212
  1071. Void CVideoObjectEncoder::codeGOVHead (Time t)
  1072. {
  1073. cout << "GOV Header (t=" << t << ")nn";
  1074. m_pbitstrmOut->reset ();
  1075. // Start code
  1076. m_pbitstrmOut -> putBits (START_CODE_PREFIX, NUMBITS_START_CODE_PREFIX, "GOV_Start_Code");
  1077. m_pbitstrmOut -> putBits (GOV_START_CODE, NUMBITS_GOV_START_CODE, "GOV_Start_Code");
  1078. m_statsVOL.nBitsHead += NUMBITS_START_CODE_PREFIX + NUMBITS_GOV_START_CODE;
  1079. // Time code
  1080. /*modified by SONY (98/03/30) */
  1081. /* Time tGOVCode = ((Int)(t * m_volmd.iClockRate / m_volmd.dFrameHz)) / m_volmd.iClockRate;*/
  1082. /*modified by SONY (98/03/30) End*/
  1083. /*              ORIGINAL
  1084. Time tGOVCode = ((Int)(t * m_volmd.iClockRate / m_volmd.dFrameHz) - m_volmd.iBbetweenP) / m_volmd.iClockRate;
  1085. */
  1086. // modified by swinder 980511
  1087. Time tGOVCode = (Time)(t / m_volmd.dFrameHz);
  1088. // this is because t is the source frame count and dFrameHz is the source frame rate,
  1089. // tGOVCode is therefore in seconds rounded down. I see no reason for clock rate to be
  1090. // used here - swinder
  1091. if(tGOVCode<0) tGOVCode=0;
  1092. Time tCodeHou = (tGOVCode / 3600)%24;
  1093. Time tCodeMin = (tGOVCode / 60) % 60;
  1094. Time tCodeSec = tGOVCode % 60;
  1095. m_pbitstrmOut -> putBits (tCodeHou, NUMBITS_GOV_TIMECODE_HOUR, "GOV_Time_Code_Hour");
  1096. m_statsVOL.nBitsHead += NUMBITS_GOV_TIMECODE_HOUR;
  1097. m_pbitstrmOut -> putBits (tCodeMin, NUMBITS_GOV_TIMECODE_MIN, "GOV_Time_Code_Min");
  1098. m_statsVOL.nBitsHead += NUMBITS_GOV_TIMECODE_MIN;
  1099. m_pbitstrmOut -> putBits (MARKER_BIT, 1, "Marker_Bit");
  1100. m_statsVOL.nBitsStuffing += 1;
  1101. m_pbitstrmOut -> putBits (tCodeSec, NUMBITS_GOV_TIMECODE_SEC, "GOV_Time_Code_Sec");
  1102. m_statsVOL.nBitsHead += NUMBITS_GOV_TIMECODE_SEC;
  1103. Int iClosedGOV;
  1104. if ((m_vopmd.vopPredType==IVOP)&&(m_volmd.iBbetweenP==0))
  1105. iClosedGOV=1;
  1106. else
  1107. iClosedGOV=0;
  1108. m_pbitstrmOut -> putBits (iClosedGOV, 1, "GOV_Closed");
  1109. m_statsVOL.nBitsHead += 1;
  1110. m_pbitstrmOut -> putBits (0, 1, "GOV_Broken_Link");
  1111. m_statsVOL.nBitsHead += 1;
  1112. m_statsVOL.nBitsStuffing += m_pbitstrmOut->flush ();
  1113. //m_pbitstrmOut -> putBits (15, 4, "byte_align");
  1114. //m_statsVOL.nBitsHead += 4;
  1115. m_tModuloBaseDisp = tGOVCode;
  1116. m_tModuloBaseDecd = tGOVCode;
  1117. }
  1118. //980212
  1119. Void CVideoObjectEncoder::codeVOPHeadInitial()
  1120. {
  1121. // Start code
  1122. m_pbitstrmOut -> putBits (START_CODE_PREFIX, NUMBITS_START_CODE_PREFIX, "VOP_Start_Code");
  1123. m_pbitstrmOut -> putBits (VOP_START_CODE, NUMBITS_VOP_START_CODE, "VOP_Start_Code");
  1124. m_statsVOP.nBitsHead += NUMBITS_START_CODE_PREFIX + NUMBITS_VOP_START_CODE;
  1125. // prediction type
  1126. m_pbitstrmOut -> putBits (m_vopmd.vopPredType, NUMBITS_VOP_PRED_TYPE, "VOP_Pred_Type");
  1127. m_statsVOP.nBitsHead += NUMBITS_VOP_PRED_TYPE;
  1128. // Time reference
  1129. Time tCurrSec = (Int)(m_t / m_volmd.dFrameHz); // current time in seconds
  1130. // Time tCurrSec = m_t / SOURCE_FRAME_RATE;     // current time in seconds
  1131. m_nBitsModuloBase = tCurrSec - (((m_vopmd.vopPredType != BVOP) ||
  1132. (m_vopmd.vopPredType == BVOP && m_volmd.volType == ENHN_LAYER )) ?
  1133. m_tModuloBaseDecd : m_tModuloBaseDisp);
  1134. assert(m_nBitsModuloBase<=31);
  1135. m_pbitstrmOut -> putBits ((Int) 0xFFFFFFFE, (UInt) m_nBitsModuloBase + 1, "VOP_Modulo_Time_Base");
  1136. m_statsVOP.nBitsHead += m_nBitsModuloBase + 1;
  1137. m_iVopTimeIncr = (Int)(m_t * m_volmd.iClockRate / m_volmd.dFrameHz - tCurrSec * m_volmd.iClockRate);
  1138. // m_iVopTimeIncr = m_t * m_volmd.iClockRate / SOURCE_FRAME_RATE - tCurrSec * m_volmd.iClockRate;
  1139. m_pbitstrmOut->putBits ((Int) 1, 1, "Marker"); // marker bit Added for error resilient mode by Toshiba(1997-11-14)
  1140. m_statsVOP.nBitsStuffing ++;
  1141. m_pbitstrmOut -> putBits (m_iVopTimeIncr, m_iNumBitsTimeIncr, "VOP_Time_Incr");
  1142. m_statsVOP.nBitsHead += m_iNumBitsTimeIncr;// Modified for error resilient mode by Toshiba(1997-11-14)
  1143. m_pbitstrmOut->putBits ((Int) 1, 1, "Marker"); // marker bit
  1144. m_statsVOP.nBitsStuffing ++;
  1145. if ( m_vopmd.vopPredType != BVOP ||
  1146. (m_vopmd.vopPredType == BVOP && m_volmd.volType == ENHN_LAYER ))
  1147. { //update modulo time base
  1148. m_tModuloBaseDisp = m_tModuloBaseDecd; //of the most recently displayed I/Pvop
  1149. m_tModuloBaseDecd = tCurrSec; //of the most recently decoded I/Pvop
  1150. }
  1151. }
  1152. Void CVideoObjectEncoder::codeNonCodedVOPHead ()
  1153. {
  1154. codeVOPHeadInitial();
  1155. m_pbitstrmOut -> putBits (0, 1, "VOP_Coded");
  1156. m_statsVOP.nBitsHead++;
  1157. }
  1158. Void CVideoObjectEncoder::codeVOPHead ()
  1159. {
  1160. codeVOPHeadInitial();
  1161. m_pbitstrmOut -> putBits (1, 1, "VOP_Coded");
  1162. m_statsVOP.nBitsHead++;
  1163. if(m_volmd.bShapeOnly==FALSE)
  1164. {
  1165. if (m_vopmd.vopPredType == PVOP) {
  1166. m_pbitstrmOut -> putBits (m_vopmd.iRoundingControl, 1, "VOP_Rounding_Type");
  1167. m_statsVOP.nBitsHead++;
  1168. }
  1169. }
  1170. if (m_volmd.fAUsage != RECTANGLE) {
  1171. if (!(m_uiSprite == 1 && m_vopmd.vopPredType == IVOP)) {
  1172. m_pbitstrmOut->putBits (m_rctCurrVOPY.width, NUMBITS_VOP_WIDTH, "VOP_Width");
  1173. m_pbitstrmOut->putBits ((Int) 1, 1, "Marker"); // marker bit
  1174. m_pbitstrmOut->putBits (m_rctCurrVOPY.height (), NUMBITS_VOP_HEIGHT, "VOP_Height");
  1175. m_pbitstrmOut->putBits ((Int) 1, 1, "Marker"); // marker bit
  1176. m_statsVOP.nBitsHead += NUMBITS_VOP_WIDTH + NUMBITS_VOP_HEIGHT;
  1177. m_statsVOP.nBitsStuffing += 2;
  1178. if (m_rctCurrVOPY.left >= 0) {
  1179. m_pbitstrmOut -> putBits (m_rctCurrVOPY.left, NUMBITS_VOP_HORIZONTAL_SPA_REF, "VOP_Hori_Ref");
  1180. } else {
  1181. m_pbitstrmOut -> putBits (m_rctCurrVOPY.left & 0x00001FFFF, NUMBITS_VOP_HORIZONTAL_SPA_REF, "VOP_Hori_Ref");
  1182. }
  1183. m_pbitstrmOut->putBits ((Int) 1, 1, "Marker"); // marker bit
  1184. if (m_rctCurrVOPY.top >= 0) {
  1185. m_pbitstrmOut -> putBits (m_rctCurrVOPY.top, NUMBITS_VOP_VERTICAL_SPA_REF, "VOP_Vert_Ref");
  1186. } else {
  1187. m_pbitstrmOut -> putBits (m_rctCurrVOPY.top & 0x00001FFFF, NUMBITS_VOP_VERTICAL_SPA_REF, "VOP_Vert_Ref");
  1188. }
  1189. m_statsVOP.nBitsHead += NUMBITS_VOP_HORIZONTAL_SPA_REF + NUMBITS_VOP_VERTICAL_SPA_REF;
  1190. m_statsVOP.nBitsStuffing += 1;
  1191. }
  1192. if ( m_volmd.volType == ENHN_LAYER && m_volmd.iEnhnType == 1 ) {
  1193. m_pbitstrmOut->putBits (1, 1, "Background Composition");
  1194. m_statsVOP.nBitsHead++;
  1195. }
  1196. // begin: added by Sharp (98/3/24)
  1197. else if ( m_volmd.volType == ENHN_LAYER && m_volmd.iEnhnType == 2 ) {
  1198. m_pbitstrmOut->putBits (0, 1, "Background Composition");
  1199. m_statsVOP.nBitsHead++;
  1200. }
  1201. // end: added by Sharp (98/3/24)
  1202. m_pbitstrmOut->putBits (m_volmd.bNoCrChange, 1, "VOP_CR_Change_Disable");
  1203. m_statsVOP.nBitsHead++;
  1204.         // tentative solution for normal sprite bitstream exchange
  1205. m_pbitstrmOut->putBits (0, 1, "VOP_Constant_Alpha");
  1206. m_statsVOP.nBitsHead++;
  1207. }
  1208. // START: Complexity Estimation syntax support - Marc Mongenet (EPFL) - 15 Jun 1998
  1209. if (! m_volmd.bComplexityEstimationDisable) {
  1210. assert (m_volmd.iEstimationMethod == 0);
  1211. // In real life the following values should be estimated by the encoder,
  1212. // but this is only a syntax support so arbitrary complexity values are assigned.
  1213. m_vopmd.iOpaque = 77;
  1214. m_vopmd.iTransparent = 97;
  1215. m_vopmd.iIntraCAE = 114;
  1216. m_vopmd.iInterCAE = 99;
  1217. m_vopmd.iNoUpdate = 32;
  1218. m_vopmd.iUpsampling = 32;
  1219. m_vopmd.iIntraBlocks = 171;
  1220. m_vopmd.iNotCodedBlocks = 171;
  1221. m_vopmd.iDCTCoefs = 215;
  1222. m_vopmd.iDCTLines = 187;
  1223. m_vopmd.iVLCSymbols = 187;
  1224. m_vopmd.iVLCBits = 10;
  1225. m_vopmd.iInterBlocks = 77;
  1226. m_vopmd.iInter4vBlocks = 111;
  1227. m_vopmd.iAPM = 110;
  1228. m_vopmd.iNPM = 103;
  1229. m_vopmd.iForwBackMCQ = 101;
  1230. m_vopmd.iHalfpel2 = 110;
  1231. m_vopmd.iHalfpel4 = 101;
  1232. m_vopmd.iInterpolateMCQ = 116;
  1233. if (m_vopmd.vopPredType == IVOP ||
  1234. m_vopmd.vopPredType == PVOP ||
  1235. m_vopmd.vopPredType == BVOP)
  1236. {
  1237. if (m_volmd.bOpaque) {
  1238. m_pbitstrmOut -> putBits (codedDCECS (m_vopmd.iOpaque, 8), 8, "dcecs_opaque");
  1239. m_statsVOP.nBitsHead += 8;
  1240. }
  1241. if (m_volmd.bTransparent) {
  1242. m_pbitstrmOut -> putBits (codedDCECS (m_vopmd.iTransparent, 8), 8, "dcecs_transparent");
  1243. m_statsVOP.nBitsHead += 8;
  1244. }
  1245. if (m_volmd.bIntraCAE) {
  1246. m_pbitstrmOut -> putBits (codedDCECS (m_vopmd.iIntraCAE, 8), 8 , "dcecs_intra_cae");
  1247. m_statsVOP.nBitsHead += 8;
  1248. }
  1249. if (m_volmd.bInterCAE) {
  1250. m_pbitstrmOut -> putBits (codedDCECS (m_vopmd.iInterCAE, 8), 8 , "dcecs_inter_cae");
  1251. m_statsVOP.nBitsHead += 8;
  1252. }
  1253. if (m_volmd.bNoUpdate) {
  1254. m_pbitstrmOut -> putBits (codedDCECS (m_vopmd.iNoUpdate, 8), 8 , "dcecs_no_update");
  1255. m_statsVOP.nBitsHead += 8;
  1256. }
  1257. if (m_volmd.bUpsampling) {
  1258. m_pbitstrmOut -> putBits (codedDCECS (m_vopmd.iUpsampling, 8), 8 , "dcecs_upsampling");
  1259. m_statsVOP.nBitsHead += 8;
  1260. }
  1261. }
  1262. if (m_volmd.bIntraBlocks) {
  1263. m_pbitstrmOut -> putBits (codedDCECS (m_vopmd.iIntraBlocks, 8), 8 , "dcecs_intra_blocks");
  1264. m_statsVOP.nBitsHead += 8;
  1265. }
  1266. if (m_volmd.bNotCodedBlocks) {
  1267. m_pbitstrmOut -> putBits (codedDCECS (m_vopmd.iNotCodedBlocks, 8), 8 , "dcecs_not_coded_blocks");
  1268. m_statsVOP.nBitsHead += 8;
  1269. }
  1270. if (m_volmd.bDCTCoefs) {
  1271. m_pbitstrmOut -> putBits (codedDCECS (m_vopmd.iDCTCoefs, 8), 8 , "dcecs_dct_coefs");
  1272. m_statsVOP.nBitsHead += 8;
  1273. }
  1274. if (m_volmd.bDCTLines) {
  1275. m_pbitstrmOut -> putBits (codedDCECS (m_vopmd.iDCTLines, 8), 8 , "dcecs_dct_lines");
  1276. m_statsVOP.nBitsHead += 8;
  1277. }
  1278. if (m_volmd.bVLCSymbols) {
  1279. m_pbitstrmOut -> putBits (codedDCECS (m_vopmd.iVLCSymbols, 8), 8 , "dcecs_vlc_symbols");
  1280. m_statsVOP.nBitsHead += 8;
  1281. }
  1282. if (m_volmd.bVLCBits) {
  1283. m_pbitstrmOut -> putBits (codedDCECS (m_vopmd.iVLCBits, 4), 4, "dcecs_vlc_bits");
  1284. m_statsVOP.nBitsHead += 4;
  1285. }
  1286. if (m_vopmd.vopPredType == PVOP ||
  1287. m_vopmd.vopPredType == BVOP ||
  1288. m_vopmd.vopPredType == SPRITE)
  1289. {
  1290. if (m_volmd.bInterBlocks) {
  1291. m_pbitstrmOut -> putBits (codedDCECS (m_vopmd.iInterBlocks, 8), 8 , "dcecs_inter_blocks");
  1292. m_statsVOP.nBitsHead += 8;
  1293. }
  1294. if (m_volmd.bInter4vBlocks) {
  1295. m_pbitstrmOut -> putBits (codedDCECS (m_vopmd.iInter4vBlocks, 8), 8 , "dcecs_inter4v_blocks");
  1296. m_statsVOP.nBitsHead += 8;
  1297. }
  1298. if (m_volmd.bAPM) {
  1299. m_pbitstrmOut -> putBits (codedDCECS (m_vopmd.iAPM, 8), 8 , "dcecs_apm");
  1300. m_statsVOP.nBitsHead += 8;
  1301. }
  1302. if (m_volmd.bNPM) {
  1303. m_pbitstrmOut -> putBits (codedDCECS (m_vopmd.iNPM, 8), 8 , "dcecs_npm");
  1304. m_statsVOP.nBitsHead += 8;
  1305. }
  1306. if (m_volmd.bForwBackMCQ) {
  1307. m_pbitstrmOut -> putBits (codedDCECS (m_vopmd.iForwBackMCQ, 8), 8 , "dcecs_forw_back_mc_q");
  1308. m_statsVOP.nBitsHead += 8;
  1309. }
  1310. if (m_volmd.bHalfpel2) {
  1311. m_pbitstrmOut -> putBits (codedDCECS (m_vopmd.iHalfpel2, 8), 8 , "dcecs_halfpel2");
  1312. m_statsVOP.nBitsHead += 8;
  1313. }
  1314. if (m_volmd.bHalfpel4) {
  1315. m_pbitstrmOut -> putBits (codedDCECS (m_vopmd.iHalfpel4, 8), 8 , "dcecs_halfpel4");
  1316. m_statsVOP.nBitsHead += 8;
  1317. }
  1318. }
  1319. if (m_vopmd.vopPredType == BVOP ||
  1320. m_vopmd.vopPredType == SPRITE)
  1321. {
  1322. if (m_volmd.bInterpolateMCQ) {
  1323. m_pbitstrmOut -> putBits (codedDCECS (m_vopmd.iInterpolateMCQ, 8), 8 , "dcecs_interpolate_mc_q");
  1324. m_statsVOP.nBitsHead += 8;
  1325. }
  1326. }
  1327. }
  1328. // END: Complexity Estimation syntax support
  1329. // Modified for error resilient mode by Toshiba(1998-1-16)
  1330. if(m_volmd.bShapeOnly==TRUE) {
  1331. VideoPacketResetVOP();
  1332. return;
  1333. }
  1334. // End Toshiba(1998-1-16)
  1335. m_pbitstrmOut->putBits (m_vopmd.iIntraDcSwitchThr, 3, "IntraDCSwitchThr");
  1336. m_statsVOP.nBitsHead+=3;
  1337. // INTERLACE_
  1338. //m_pbitstrmOut->putBits (m_vopmd.bInterlace, 1, "InterlaceEnable");
  1339. //m_statsVOP.nBitsHead++; 
  1340. if (m_vopmd.bInterlace == TRUE) {
  1341. m_pbitstrmOut->putBits (m_vopmd.bTopFieldFirst, 1, "Top_Field_First");
  1342. m_pbitstrmOut->putBits (m_vopmd.bAlternateScan, 1, "Alternate_Scan");
  1343. m_statsVOP.nBitsHead += 2; 
  1344. } else
  1345.         m_vopmd.bAlternateScan = FALSE;
  1346. // INTERLACE
  1347. if (m_vopmd.vopPredType == IVOP) {
  1348. m_pbitstrmOut -> putBits (m_vopmd.intStepI, m_volmd.uiQuantPrecision, "VOP_QUANT");
  1349. m_statsVOP.nBitsHead += m_volmd.uiQuantPrecision;
  1350. if(m_volmd.fAUsage == EIGHT_BIT)
  1351. {
  1352. m_pbitstrmOut -> putBits (m_vopmd.intStepIAlpha, NUMBITS_VOP_ALPHA_QUANTIZER, "VOP_GREY_QUANT");
  1353. m_statsVOP.nBitsHead += NUMBITS_VOP_ALPHA_QUANTIZER;
  1354. }
  1355. }
  1356. else if (m_vopmd.vopPredType == PVOP) {
  1357. m_pbitstrmOut -> putBits (m_vopmd.intStep, m_volmd.uiQuantPrecision, "VOP_QUANT");
  1358. m_statsVOP.nBitsHead += m_volmd.uiQuantPrecision;
  1359. if(m_volmd.fAUsage == EIGHT_BIT)
  1360. {
  1361. m_pbitstrmOut -> putBits (m_vopmd.intStepPAlpha, NUMBITS_VOP_ALPHA_QUANTIZER, "VOP_GREY_QUANT");
  1362. m_statsVOP.nBitsHead += NUMBITS_VOP_ALPHA_QUANTIZER;
  1363. }
  1364. m_pbitstrmOut -> putBits (m_vopmd.mvInfoForward.uiFCode, NUMBITS_VOP_FCODE, "VOP_Fcode_Forward");
  1365. m_statsVOP.nBitsHead += NUMBITS_VOP_FCODE;
  1366. }
  1367. else if (m_vopmd.vopPredType == BVOP) {
  1368. m_pbitstrmOut -> putBits (m_vopmd.intStepB, m_volmd.uiQuantPrecision, "VOP_QUANT");
  1369. m_statsVOP.nBitsHead += m_volmd.uiQuantPrecision;
  1370. if(m_volmd.fAUsage == EIGHT_BIT)
  1371. {
  1372. m_pbitstrmOut -> putBits (m_vopmd.intStepBAlpha, NUMBITS_VOP_ALPHA_QUANTIZER, "VOP_GREY_QUANT");
  1373. m_statsVOP.nBitsHead += NUMBITS_VOP_ALPHA_QUANTIZER;
  1374. }
  1375. m_pbitstrmOut -> putBits (m_vopmd.mvInfoForward.uiFCode, NUMBITS_VOP_FCODE, "VOP_Fcode_Forward");
  1376. m_statsVOP.nBitsHead += NUMBITS_VOP_FCODE;
  1377. m_pbitstrmOut -> putBits (m_vopmd.mvInfoBackward.uiFCode, NUMBITS_VOP_FCODE, "VOP_Fcode_Backward");
  1378. m_statsVOP.nBitsHead += NUMBITS_VOP_FCODE;
  1379. }
  1380. // Added for error resilient mode by Toshiba(1997-11-14)
  1381. if(m_volmd.volType != ENHN_LAYER){
  1382. if (m_volmd.fAUsage != RECTANGLE && m_vopmd.vopPredType != IVOP
  1383. && m_uiSprite != 1)  
  1384. {  
  1385. m_pbitstrmOut -> putBits (m_vopmd.bShapeCodingType, 1, "VOP_shape_coding_type");
  1386. m_statsVOP.nBitsHead++;
  1387. }
  1388. VideoPacketResetVOP();
  1389. }
  1390. else
  1391. {
  1392. ///// 97/12/22 start
  1393. if( m_volmd.iEnhnType != 0 ){ // modified by Sharp (98/3/24)
  1394. m_pbitstrmOut->putBits (m_vopmd.iLoadBakShape, 1, "load_backward_shape");
  1395. m_statsVOP.nBitsHead ++;
  1396. if(m_vopmd.iLoadBakShape){
  1397. delete rgpbfShape [1]->m_pvopcRefQ1;
  1398. // previous backward shape is saved to current forward shape
  1399. rgpbfShape [1]->m_pvopcRefQ1 = new CVOPU8YUVBA (*(rgpbfShape [0]->pvopcReconCurr()));
  1400. rgpbfShape [1]->m_rctCurrVOPY.left   = rgpbfShape [0]->m_rctCurrVOPY.left;
  1401. rgpbfShape [1]->m_rctCurrVOPY.right  = rgpbfShape [0]->m_rctCurrVOPY.right;
  1402. rgpbfShape [1]->m_rctCurrVOPY.top    = rgpbfShape [0]->m_rctCurrVOPY.top;
  1403. rgpbfShape [1]->m_rctCurrVOPY.bottom = rgpbfShape [0]->m_rctCurrVOPY.bottom;
  1404. rgpbfShape [0]->findTightBoundingBox ();
  1405. rgpbfShape [0]->findBestBoundingBox ();
  1406. rgpbfShape [0]->m_rctCurrVOPY  = rgpbfShape [0]->m_pvopcOrig->whereBoundY();
  1407. rgpbfShape [0]->m_rctCurrVOPUV = rgpbfShape [0]->m_pvopcOrig->whereBoundUV ();
  1408. rgpbfShape [0]->setRefStartingPointers ();
  1409. rgpbfShape [0]->compute_bfShapeMembers ();
  1410. // backward shape width/height, hori/vert reference
  1411. m_pbitstrmOut->putBits (rgpbfShape [0]->m_rctCurrVOPY.width, NUMBITS_VOP_WIDTH, "back_Width");
  1412. m_pbitstrmOut->putBits ((Int) 1, 1, "Marker"); // marker bit
  1413. m_statsVOP.nBitsStuffing ++;
  1414. m_pbitstrmOut->putBits (rgpbfShape [0]->m_rctCurrVOPY.height (), NUMBITS_VOP_HEIGHT, "back_Height");
  1415. m_pbitstrmOut->putBits ((Int) 1, 1, "Marker"); // marker bit
  1416. m_statsVOP.nBitsStuffing ++;
  1417. Int iSign = (rgpbfShape [0]->m_rctCurrVOPY.left < 0) ? 1 : 0;
  1418. m_pbitstrmOut->putBits (iSign, 1, "back_Hori_Ref_Sgn");
  1419. m_pbitstrmOut->putBits (abs (rgpbfShape [0]->m_rctCurrVOPY.left), NUMBITS_VOP_HORIZONTAL_SPA_REF - 1, "back_Hori_Ref");
  1420. m_pbitstrmOut->putBits ((Int) 1, 1, "Marker"); // marker bit
  1421. m_statsVOP.nBitsStuffing++;
  1422. iSign = (rgpbfShape [0]->m_rctCurrVOPY.top < 0) ? 1 : 0;
  1423. m_pbitstrmOut->putBits (iSign, 1, "back_Vert_Ref_Sgn");
  1424. m_pbitstrmOut->putBits (abs (rgpbfShape [0]->m_rctCurrVOPY.top), NUMBITS_VOP_VERTICAL_SPA_REF - 1, "back_Vert_Ref");
  1425. m_statsVOP.nBitsHead += NUMBITS_VOP_WIDTH + NUMBITS_VOP_HEIGHT 
  1426. + NUMBITS_VOP_HORIZONTAL_SPA_REF + NUMBITS_VOP_VERTICAL_SPA_REF;
  1427. rgpbfShape [0]->resetBYPlane ();
  1428. printf("================ backward shape codingn");
  1429. rgpbfShape [0]->m_volmd.bShapeOnly = TRUE;
  1430. rgpbfShape [0]->encodeNSForIVOP_WithShape ();
  1431. // backward shape coding
  1432. m_pbitstrmOut->putBits (m_vopmd.iLoadForShape, 1, "load_forward_shape");
  1433. m_statsVOP.nBitsHead++;
  1434. if(m_vopmd.iLoadForShape){
  1435. rgpbfShape [1]->findTightBoundingBox ();
  1436. rgpbfShape [1]->findBestBoundingBox ();
  1437. rgpbfShape [1]->m_rctCurrVOPY  = rgpbfShape [1]->m_pvopcOrig->whereBoundY ();
  1438. rgpbfShape [1]->m_rctCurrVOPUV = rgpbfShape [1]->m_pvopcOrig->whereBoundUV ();
  1439. rgpbfShape [1]->setRefStartingPointers ();
  1440. rgpbfShape [1]->compute_bfShapeMembers ();
  1441. // forward shape width/height, hori/vert reference
  1442. m_pbitstrmOut->putBits (rgpbfShape [1]->m_rctCurrVOPY.width, NUMBITS_VOP_WIDTH, "for_Width"); 
  1443. m_pbitstrmOut->putBits ((Int) 1, 1, "Marker"); // marker bit
  1444. m_statsVOP.nBitsStuffing ++;
  1445. m_pbitstrmOut->putBits (rgpbfShape [1]->m_rctCurrVOPY.height (), NUMBITS_VOP_HEIGHT, "for_Height");
  1446. m_pbitstrmOut->putBits ((Int) 1, 1, "Marker"); // marker bit
  1447. m_statsVOP.nBitsStuffing ++;
  1448. Int iSign = (rgpbfShape [1]->m_rctCurrVOPY.left < 0) ? 1 : 0;
  1449. m_pbitstrmOut->putBits (iSign, 1, "for_Hori_Ref_Sgn");
  1450. m_pbitstrmOut->putBits (abs (rgpbfShape [1]->m_rctCurrVOPY.left), NUMBITS_VOP_HORIZONTAL_SPA_REF - 1, "for_Hori_Ref");
  1451. m_pbitstrmOut->putBits ((Int) 1, 1, "Marker"); // marker bit
  1452. m_statsVOP.nBitsStuffing++;
  1453. iSign = (rgpbfShape [1]->m_rctCurrVOPY.top < 0) ? 1 : 0;
  1454. m_pbitstrmOut->putBits (iSign, 1, "for_Vert_Ref_Sgn");
  1455. m_pbitstrmOut->putBits (abs (rgpbfShape [1]->m_rctCurrVOPY.top), NUMBITS_VOP_VERTICAL_SPA_REF - 1, "for_Vert_Ref");
  1456. m_statsVOP.nBitsHead += NUMBITS_VOP_WIDTH + NUMBITS_VOP_HEIGHT 
  1457. + NUMBITS_VOP_HORIZONTAL_SPA_REF + NUMBITS_VOP_VERTICAL_SPA_REF;
  1458. rgpbfShape [1]->resetBYPlane ();
  1459. printf("================ forward shape codingn");
  1460. rgpbfShape [1]->m_volmd.bShapeOnly = TRUE;
  1461. rgpbfShape [1]->encodeNSForIVOP_WithShape ();
  1462. // forward shape coding
  1463. }
  1464. } // end of "if (m_vopmd.iLoadBakShape)"
  1465. } // end of "if (iEnhnType == 1)"
  1466. ///// 97/12/22 end
  1467. m_pbitstrmOut->putBits(m_vopmd.iRefSelectCode, 2, "RefSelectCode");
  1468. m_statsVOP.nBitsHead +=2;
  1469. }
  1470. // End Toshiba(1997-11-14)
  1471. }
  1472. Void CVideoObjectEncoder::decideMVInfo ()
  1473. {
  1474. assert (m_vopmd.iSearchRangeForward <= 1024); //seems a reasonable constraint
  1475. assert (m_vopmd.iSearchRangeBackward <= 1024); //seems a reasonable constraint
  1476. if(m_vopmd.iSearchRangeForward <= 16)
  1477. m_vopmd.mvInfoForward.uiFCode = 1;
  1478. else if(m_vopmd.iSearchRangeForward <= 32)
  1479. m_vopmd.mvInfoForward.uiFCode = 2;
  1480. else if(m_vopmd.iSearchRangeForward <= 64)
  1481. m_vopmd.mvInfoForward.uiFCode = 3;
  1482. else if(m_vopmd.iSearchRangeForward <= 128)
  1483. m_vopmd.mvInfoForward.uiFCode = 4;
  1484. else if(m_vopmd.iSearchRangeForward <= 256)
  1485. m_vopmd.mvInfoForward.uiFCode = 5;
  1486. else if(m_vopmd.iSearchRangeForward <= 512)
  1487. m_vopmd.mvInfoForward.uiFCode = 6;
  1488. else // 1024
  1489. m_vopmd.mvInfoForward.uiFCode = 7;
  1490. m_vopmd.mvInfoForward.uiRange = 1 << (m_vopmd.mvInfoForward.uiFCode + 4);
  1491. m_vopmd.mvInfoForward.uiScaleFactor = 1 << (m_vopmd.mvInfoForward.uiFCode - 1);
  1492. if ((UInt)m_vopmd.iSearchRangeForward == (m_vopmd.mvInfoForward.uiRange >> 1))
  1493. m_vopmd.iSearchRangeForward--; // avoid out of range half pel
  1494. if(m_vopmd.iSearchRangeBackward <= 16)
  1495. m_vopmd.mvInfoBackward.uiFCode = 1;
  1496. else if(m_vopmd.iSearchRangeBackward <= 32)
  1497. m_vopmd.mvInfoBackward.uiFCode = 2;
  1498. else if(m_vopmd.iSearchRangeBackward <= 64)
  1499. m_vopmd.mvInfoBackward.uiFCode = 3;
  1500. else if(m_vopmd.iSearchRangeBackward <= 128)
  1501. m_vopmd.mvInfoBackward.uiFCode = 4;
  1502. else if(m_vopmd.iSearchRangeBackward <= 256)
  1503. m_vopmd.mvInfoBackward.uiFCode = 5;
  1504. else if(m_vopmd.iSearchRangeBackward <= 512)
  1505. m_vopmd.mvInfoBackward.uiFCode = 6;
  1506. else // 1024
  1507. m_vopmd.mvInfoBackward.uiFCode = 7;
  1508. m_vopmd.mvInfoBackward.uiRange = 1 << (m_vopmd.mvInfoBackward.uiFCode + 4);
  1509. m_vopmd.mvInfoBackward.uiScaleFactor = 1 << (m_vopmd.mvInfoBackward.uiFCode - 1);
  1510. if ((UInt)m_vopmd.iSearchRangeBackward == (m_vopmd.mvInfoBackward.uiRange >> 1))
  1511. m_vopmd.iSearchRangeBackward--; // avoid out of range half pel
  1512. }
  1513. // START: Complexity Estimation syntax support - Marc Mongenet (EPFL) - 19 Jun 1998
  1514. Int CVideoObjectEncoder::codedDCECS (Int ioriginal, UInt uinb_bits)
  1515. {
  1516. ioriginal &= (1 << uinb_bits) - 1; // mask raw data
  1517. return ioriginal != 0 ? ioriginal : 1;
  1518. }
  1519. // END: Complexity Estimation syntax support
  1520. Void CVideoObjectEncoder::updateAllOrigRefVOPs ()
  1521. {
  1522. assert (m_vopmd.vopPredType != BVOP||(
  1523. m_vopmd.vopPredType == BVOP && m_volmd.volType == ENHN_LAYER && m_vopmd.iRefSelectCode == 0));
  1524. swapVOPU8Pointers (m_pvopcOrig, m_pvopcRefOrig1);
  1525. m_pvopcRefOrig1->setBoundRct (m_rctRefVOPY1);
  1526. m_pvopcOrig->setBoundRct (m_rctCurrVOPY);
  1527. repeatPadYOrA ((PixelC*) m_pvopcRefOrig1->pixelsY () + m_iOffsetForPadY, m_pvopcRefOrig1);
  1528. }
  1529. Void CVideoObjectEncoder::copyCurrToRefOrig1Y ()
  1530. {
  1531. m_pvopcRefOrig0->setAndExpandBoundRctOnly (m_pvopcOrig->whereBoundY (), EXPANDY_REFVOP); // will adjust the starting pixel pointer too
  1532. const PixelC* ppxlcOrigY = m_pvopcOrig->pixelsBoundY ();
  1533. PixelC* ppxlcRefOrig0Y = (PixelC*) m_pvopcRefOrig0->pixelsBoundY ();
  1534. for (CoordI y = 0; y < m_pvopcOrig->whereBoundY ().height (); y++) {
  1535. memcpy (ppxlcRefOrig0Y, ppxlcOrigY, m_pvopcOrig->whereBoundY ().width*sizeof(PixelC)); // NBIT: add sizeof(PixelC)
  1536. ppxlcOrigY += m_pvopcOrig->whereBoundY ().width;
  1537. ppxlcRefOrig0Y += m_pvopcRefOrig0->whereBoundY ().width;
  1538. }
  1539. }
  1540. Void CVideoObjectEncoder::findTightBoundingBox ()
  1541. {
  1542. const CRct& rctOrig = m_pvopcOrig->whereY ();
  1543. CoordI left = rctOrig.right - 1;
  1544. CoordI top = rctOrig.bottom - 1;
  1545. CoordI right = rctOrig.left;
  1546. CoordI bottom = rctOrig.top;
  1547. const PixelC* ppxlcBY = m_pvopcOrig->pixelsBY ();
  1548. for (CoordI y = rctOrig.top; y < rctOrig.bottom; y++) {
  1549. for (CoordI x = rctOrig.left; x < rctOrig.right; x++) {
  1550. if (*ppxlcBY != transpValue) {
  1551. left = min (left, x);
  1552. top = min (top, y);
  1553. right = max (right, x);
  1554. bottom = max (bottom, y);
  1555. }
  1556. ppxlcBY++;
  1557. }
  1558. }
  1559. right++;
  1560. bottom++;
  1561. if (left % 2 != 0)
  1562. left--;
  1563. if (top % 2 != 0)
  1564. top--;
  1565. m_pvopcOrig->setBoundRct (CRct (left, top, right, bottom));
  1566. }
  1567. Void CVideoObjectEncoder::findBestBoundingBox ()
  1568. {
  1569. CoordI iLeftCurr   = m_pvopcOrig->whereBoundY ().left;
  1570. CoordI iTopCurr    = m_pvopcOrig->whereBoundY ().top;
  1571. // Added for Chroma Subsampling by Hyundai(1998-5-9)
  1572.         if (m_vopmd.bInterlace) iTopCurr -= iTopCurr%4;
  1573. // End of Hyundai(1998-5-9)
  1574. CoordI iRightCurr  = m_pvopcOrig->whereBoundY ().right;
  1575. CoordI iBottomCurr = m_pvopcOrig->whereBoundY ().bottom;
  1576. CoordI iLeftMost   = max (iLeftCurr - MB_SIZE + 2, 0);
  1577. // Added for Chroma Subsampling by Hyundai(1998-5-9)
  1578.         Int iTopSkip = (m_vopmd.bInterlace) ? 4 : 2;
  1579. CoordI iTopMost = max (iTopCurr - MB_SIZE + iTopSkip, 0);
  1580. // End of Hyundai(1998-5-9)
  1581. // CoordI iTopMost = max (iTopCurr  - MB_SIZE + 2, 0); // delete by Hyundai //can't be negative
  1582. Int nNonTransparentMBMin = m_pvopcOrig->whereBoundY ().area (); //abitrary large number
  1583. Int iLeftOfBBox, iTopOfBBox; //control postions
  1584. Int iLeftBest = iLeftMost;
  1585. Int iTopBest  = iTopMost;
  1586. for (iLeftOfBBox = iLeftMost; iLeftOfBBox <= iLeftCurr; iLeftOfBBox += 2) {
  1587. // for (iTopOfBBox = iTopMost; iTopOfBBox <= iTopCurr; iTopOfBBox += 2) { // delete by Hyundai
  1588. // Added for Chroma Subsampling by Hyundai(1998-5-9)
  1589. for (iTopOfBBox = iTopMost; iTopOfBBox <= iTopCurr; iTopOfBBox += iTopSkip) {
  1590. // End of Hyundai(1998-5-9)
  1591. // counting for each control position
  1592. const PixelC* ppxlcBYMBRow = m_pvopcOrig->getPlane(BY_PLANE)->pixels (iLeftOfBBox, iTopOfBBox);
  1593. Int nNonTransparentMB = 0;
  1594. Bool bKeepCounting = TRUE;
  1595. Int iLeftOfMB, iTopOfMB;
  1596. for (iTopOfMB = iTopOfBBox; iTopOfMB < iBottomCurr; iTopOfMB += MB_SIZE) {
  1597. const PixelC* ppxlcBYMB = ppxlcBYMBRow;
  1598. for (iLeftOfMB = iLeftOfBBox; iLeftOfMB < iRightCurr; iLeftOfMB += MB_SIZE) {
  1599. const PixelC* ppxlcBY = ppxlcBYMB;
  1600. UInt nOpaquePixel = 0;
  1601. for (UInt iY = 0; iY < MB_SIZE; iY++) {
  1602. for (UInt iX = 0; iX < MB_SIZE; iX++) {
  1603. nOpaquePixel += *ppxlcBY++;
  1604. }
  1605. ppxlcBY += m_iFrameWidthY - MB_SIZE;
  1606. }
  1607. if (nOpaquePixel != 0)
  1608. nNonTransparentMB++;
  1609. if (nNonTransparentMB > nNonTransparentMBMin) {
  1610. bKeepCounting = FALSE;
  1611. break;
  1612. }
  1613. ppxlcBYMB += MB_SIZE;
  1614. }
  1615. if (!bKeepCounting)
  1616. break;
  1617. ppxlcBYMBRow += m_iFrameWidthYxMBSize;
  1618. }
  1619. if (nNonTransparentMB <= nNonTransparentMBMin) {
  1620. nNonTransparentMBMin = nNonTransparentMB;
  1621. iLeftBest = iLeftOfBBox;
  1622. iTopBest = iTopOfBBox;
  1623. }
  1624. }
  1625. }
  1626. m_pvopcOrig->setBoundRct (CRct (
  1627. iLeftBest, 
  1628. iTopBest, 
  1629. iLeftBest + ((iRightCurr - iLeftBest - 1) / MB_SIZE + 1) * MB_SIZE, 
  1630. iTopBest  + ((iBottomCurr - iTopBest - 1) / MB_SIZE + 1) * MB_SIZE
  1631. ));
  1632. }
  1633. Void CVideoObjectEncoder::computeSNRs (const CVOPU8YUVBA* pvopcCurrQ)
  1634. {
  1635. if (m_volmd.fAUsage == RECTANGLE) {
  1636. SNRYorA (m_pvopcOrig->pixelsBoundY (), pvopcCurrQ->pixelsY () + m_iStartInRefToCurrRctY, m_rgdSNR [0]);
  1637. SNRUV (pvopcCurrQ);
  1638. }
  1639. else {
  1640. SNRYorAWithShape (m_pvopcOrig->pixelsBoundY (), pvopcCurrQ->pixelsY () + m_iStartInRefToCurrRctY, m_rgdSNR [0]);
  1641. SNRUVWithShape (pvopcCurrQ);
  1642. if (m_volmd.fAUsage == EIGHT_BIT)
  1643. SNRYorAWithShape (m_pvopcOrig->pixelsBoundA (), pvopcCurrQ->pixelsA () + m_iStartInRefToCurrRctY, m_rgdSNR [3]);
  1644. }
  1645. }
  1646. Void CVideoObjectEncoder::SNRYorA (
  1647. const PixelC* ppxlcOrig, const PixelC* ppxlcRef1, // these two should point to the left-top of the rctOrig's bounding box 
  1648. Double& dSNR
  1649. )
  1650. {
  1651. CoordI x, y;
  1652. Int iSqrDiff = 0;
  1653. Double dMaxVal = (Double) ((1<<m_volmd.nBits)-1); // NBIT
  1654. for (y = 0; y < m_pvopcOrig->whereBoundY ().height (); y++) {
  1655. for (x = 0; x < m_pvopcOrig->whereBoundY ().width; x++) {
  1656. Int iDiff = ppxlcOrig [x] - ppxlcRef1 [x];
  1657. iSqrDiff += iDiff * iDiff;
  1658. }
  1659. ppxlcOrig += m_pvopcOrig->whereY ().width;
  1660. ppxlcRef1 += m_pvopcRefQ1->whereY ().width;
  1661. }
  1662. if (iSqrDiff == 0) 
  1663. dSNR = 1000000.0;
  1664. else
  1665. /* NBIT: change 255.0 to dMaxVal
  1666. dSNR = (log10 ((255.0 * 255.0 * m_pvopcOrig->whereBoundY ().area ()) / (Double) iSqrDiff) * 10.0);
  1667. */
  1668. dSNR = (log10 ((dMaxVal * dMaxVal * m_pvopcOrig->whereBoundY ().area ()) / (Double) iSqrDiff) * 10.0);
  1669. }
  1670. Void CVideoObjectEncoder::SNRUV (const CVOPU8YUVBA* pvopcCurrQ)
  1671. {
  1672. CoordI x, y;
  1673. Int iSqrDiffU = 0, iSqrDiffV = 0, iDiff;
  1674. Double dMaxVal = (Double) ((1<<m_volmd.nBits)-1); // NBIT
  1675. const PixelC* ppxlcOrigU = m_pvopcOrig->pixelsBoundU (); 
  1676. const PixelC* ppxlcOrigV = m_pvopcOrig->pixelsBoundV (); 
  1677. const PixelC* ppxlcRef1U = pvopcCurrQ->pixelsU () + m_iStartInRefToCurrRctUV;
  1678. const PixelC* ppxlcRef1V = pvopcCurrQ->pixelsV () + m_iStartInRefToCurrRctUV;
  1679. for (y = 0; y < m_pvopcOrig->whereBoundUV ().height (); y++) {
  1680. for (x = 0; x < m_pvopcOrig->whereBoundUV ().width; x++) {
  1681. iDiff = ppxlcOrigU [x] - ppxlcRef1U [x];
  1682. iSqrDiffU += iDiff * iDiff;
  1683. iDiff = ppxlcOrigV [x] - ppxlcRef1V [x];
  1684. iSqrDiffV += iDiff * iDiff;
  1685. }
  1686. ppxlcOrigU += m_pvopcOrig->whereUV ().width;
  1687. ppxlcRef1U += m_pvopcRefQ1->whereUV ().width;
  1688. ppxlcOrigV += m_pvopcOrig->whereUV ().width;
  1689. ppxlcRef1V += m_pvopcRefQ1->whereUV ().width;
  1690. }
  1691. if (iSqrDiffU == 0) 
  1692. m_rgdSNR [1] = 1000000.0;
  1693. else
  1694. /* NBIT: change 255.0 to dMaxVal
  1695. m_rgdSNR [1] = (log10 ((Double) (255.0 * 255.0 * m_pvopcOrig->whereBoundUV ().area ()) / (Double) iSqrDiffU) * 10.0);
  1696. */
  1697. m_rgdSNR [1] = (log10 ((Double) (dMaxVal * dMaxVal * m_pvopcOrig->whereBoundUV ().area ()) / (Double) iSqrDiffU) * 10.0);
  1698. if (iSqrDiffV == 0) 
  1699. m_rgdSNR [2] = 1000000.0;
  1700. else
  1701. /* NBIT: change 255.0 to dMaxVal
  1702. m_rgdSNR [2] = (log10 ((Double) (255.0 * 255.0 * m_pvopcOrig->whereBoundUV ().area ()) / (Double) iSqrDiffV) * 10.0);
  1703. */
  1704. m_rgdSNR [2] = (log10 ((Double) (dMaxVal * dMaxVal * m_pvopcOrig->whereBoundUV ().area ()) / (Double) iSqrDiffV) * 10.0);
  1705. }
  1706. Void CVideoObjectEncoder::SNRYorAWithShape (
  1707. const PixelC* ppxlcOrig, const PixelC* ppxlcRef1, // these two should point to the left-top of the rctOrig's bounding box 
  1708. Double& dSNR
  1709. )
  1710. {
  1711. CoordI x, y;
  1712. Int iSqrDiff = 0, iNumNonTransp = 0;
  1713. Double dMaxVal = (Double) ((1<<m_volmd.nBits)-1); // NBIT
  1714. const PixelC* ppxlcOrigBY = m_pvopcOrig->pixelsBoundBY ();
  1715. for (y = 0; y < m_pvopcOrig->whereBoundY ().height (); y++) {
  1716. for (x = 0; x < m_pvopcOrig->whereBoundY ().width; x++) {
  1717. if (ppxlcOrigBY [x] != transpValue) {
  1718. Int iDiff = ppxlcOrig [x] - ppxlcRef1 [x];
  1719. iSqrDiff += iDiff * iDiff;
  1720. iNumNonTransp++;
  1721. }
  1722. }
  1723. ppxlcOrig += m_pvopcOrig->whereY ().width;
  1724. ppxlcOrigBY += m_pvopcOrig->whereY ().width;
  1725. ppxlcRef1 += m_pvopcRefQ1->whereY ().width;
  1726. }
  1727. if (iSqrDiff == 0) 
  1728. dSNR = 1000000.0;
  1729. else
  1730. /* NBIT: change 255.0 to dMaxVal
  1731. dSNR = (log10 ((Double) (255.0 * 255.0 * iNumNonTransp) / (Double) iSqrDiff) * 10.0);
  1732. */
  1733. dSNR = (log10 ((Double) (dMaxVal * dMaxVal * iNumNonTransp) / (Double) iSqrDiff) * 10.0);
  1734. }
  1735. Void CVideoObjectEncoder::SNRUVWithShape (const CVOPU8YUVBA* pvopcCurrQ)
  1736. {
  1737. CoordI x, y;
  1738. Int iSqrDiffU = 0, iSqrDiffV = 0, iNumNonTransp = 0, iDiff;
  1739. Double dMaxVal = (Double) ((1<<m_volmd.nBits)-1); // NBIT
  1740. const PixelC* ppxlcOrigU = m_pvopcOrig->pixelsBoundU (); 
  1741. const PixelC* ppxlcOrigV = m_pvopcOrig->pixelsBoundV (); 
  1742. const PixelC* ppxlcRef1U = pvopcCurrQ->pixelsU () + m_iStartInRefToCurrRctUV;
  1743. const PixelC* ppxlcRef1V = pvopcCurrQ->pixelsV () + m_iStartInRefToCurrRctUV;
  1744. const PixelC* ppxlcOrigBUV = m_pvopcOrig->pixelsBoundBUV ();
  1745. for (y = 0; y < m_pvopcOrig->whereBoundUV ().height (); y++) {
  1746. for (x = 0; x < m_pvopcOrig->whereBoundUV ().width; x++) {
  1747. if (ppxlcOrigBUV [x] != transpValue) {
  1748. iDiff = ppxlcOrigU [x] - ppxlcRef1U [x];
  1749. iSqrDiffU += iDiff * iDiff;
  1750. iDiff = ppxlcOrigV [x] - ppxlcRef1V [x];
  1751. iSqrDiffV += iDiff * iDiff;
  1752. iNumNonTransp++;
  1753. }
  1754. }
  1755. ppxlcOrigBUV += m_pvopcOrig->whereUV ().width;
  1756. ppxlcOrigU += m_pvopcOrig->whereUV ().width;
  1757. ppxlcRef1U += m_pvopcRefQ1->whereUV ().width;
  1758. ppxlcOrigV += m_pvopcOrig->whereUV ().width;
  1759. ppxlcRef1V += m_pvopcRefQ1->whereUV ().width;
  1760. }
  1761. if (iSqrDiffU == 0) 
  1762. m_rgdSNR [1] = 1000000.0;
  1763. else
  1764. /* NBIT: change 255.0 to dMaxVal
  1765. m_rgdSNR [1] = (log10 ((Double) (255.0 * 255.0 * iNumNonTransp) / (Double) iSqrDiffU) * 10.0);
  1766. */
  1767. m_rgdSNR [1] = (log10 ((Double) (dMaxVal * dMaxVal * iNumNonTransp) / (Double) iSqrDiffU) * 10.0);
  1768. if (iSqrDiffV == 0) 
  1769. m_rgdSNR [2] = 1000000.0;
  1770. else
  1771. /* NBIT: change 255.0 to dMaxVal
  1772. m_rgdSNR [2] = (log10 ((Double) (255.0 * 255.0 * iNumNonTransp) / (Double) iSqrDiffV) * 10.0);
  1773. */
  1774. m_rgdSNR [2] = (log10 ((Double) (dMaxVal * dMaxVal * iNumNonTransp) / (Double) iSqrDiffV) * 10.0);
  1775. }
  1776. Void CVideoObjectEncoder::biInterpolateY (
  1777. const CVOPU8YUVBA* pvopcRefQ, const CRct& rctRefVOP,
  1778. CU8Image* puciRefQZoom, const CRct& rctRefVOPZoom, Int iRoundingControl
  1779. )
  1780. {
  1781. const PixelC* ppxliOrg = pvopcRefQ->pixelsBoundY ();
  1782. const PixelC* ppxliOrgBot;
  1783. PixelC* ppxliZoom = (PixelC*) puciRefQZoom->pixels (rctRefVOPZoom.left, rctRefVOPZoom.top);
  1784. PixelC* ppxliZoomBot;
  1785. ppxliOrgBot = ppxliOrg + m_iFrameWidthY;
  1786. ppxliZoomBot = ppxliZoom + m_iFrameWidthZoomY;
  1787. Int iHeightPrevMinus1 = rctRefVOP.height () - 1;
  1788. Int iWidthPrevMinus1 = rctRefVOP.width - 1;
  1789. CoordI x, y;
  1790. for (y = 0; y < iHeightPrevMinus1; y++) {
  1791. const PixelC* ppxliOrgRow = ppxliOrg;
  1792. const PixelC* ppxliOrgBotRow = ppxliOrgBot;
  1793. PixelC* ppxliZoomRow = ppxliZoom;
  1794. PixelC* ppxliZoomBotRow = ppxliZoomBot;
  1795. for (x = 0; x < iWidthPrevMinus1; x++, ppxliZoomRow += 2, ppxliZoomBotRow += 2) {
  1796. *ppxliZoomRow = *ppxliOrgRow;
  1797. *(ppxliZoomRow + 1) = (*ppxliOrgRow + *(ppxliOrgRow + 1) + 1 - iRoundingControl) >> 1;
  1798. *ppxliZoomBotRow = (*ppxliOrgRow + *ppxliOrgBotRow + 1 - iRoundingControl) >> 1;
  1799. *(ppxliZoomBotRow + 1) = 
  1800. (*ppxliOrgRow + *ppxliOrgBotRow + 
  1801. *(ppxliOrgRow++ + 1) + *(ppxliOrgBotRow++ + 1) + 2 - iRoundingControl
  1802. ) >> 2;
  1803. }
  1804. *ppxliZoomRow = *(ppxliZoomRow + 1) = *ppxliOrgRow;
  1805. *ppxliZoomBotRow = *(ppxliZoomBotRow + 1) = (*ppxliOrgRow++ + *ppxliOrgBotRow++ + 1 - iRoundingControl) / 2; // the last pixels of every row do not need average
  1806. ppxliOrg += m_iFrameWidthY;
  1807. ppxliOrgBot += m_iFrameWidthY;
  1808. ppxliZoom += m_iFrameWidthZoomY * 2;
  1809. ppxliZoomBot += m_iFrameWidthZoomY * 2;
  1810. }
  1811. PixelC* ppxliZoomLastLnToSec = ppxliZoom;
  1812. for (x = 0; x < iWidthPrevMinus1; x++, ppxliZoomLastLnToSec += 2) {
  1813. *ppxliZoomLastLnToSec = *ppxliOrg;
  1814. *(ppxliZoomLastLnToSec + 1) = (*ppxliOrg + *(ppxliOrg++ + 1) + 1 - iRoundingControl) >> 1;
  1815. }
  1816. *ppxliZoomLastLnToSec = *(ppxliZoomLastLnToSec + 1) = *ppxliOrg;
  1817. // NBIT: add sizeof(PixelC)
  1818. memcpy (ppxliZoomBot, ppxliZoom, rctRefVOPZoom.width*sizeof(PixelC));
  1819. }
  1820. Void CVideoObjectEncoder::swapSpatialScalabilityBVOP () //for Rectangular shape only
  1821. {
  1822. if (m_volmd.volType == BASE_LAYER ||
  1823.     !(m_volmd.volType == ENHN_LAYER && m_vopmd.vopPredType == BVOP && m_vopmd.iRefSelectCode == 0))
  1824. return;
  1825. swapVOPU8Pointers(m_pvopcCurrQ,m_pvopcRefQ1);
  1826. repeatPadYOrA ((PixelC*) m_pvopcRefQ1->pixelsY () + m_iOffsetForPadY, m_pvopcRefQ1);
  1827. repeatPadUV (m_pvopcRefQ1);
  1828. }
  1829. // begin: added by Sharp (98/2/10)
  1830. Void CVideoObjectEncoder::setPredType(VOPpredType vopPredType)
  1831. {
  1832. m_vopmd.vopPredType = vopPredType;
  1833. }
  1834. Void CVideoObjectEncoder::setRefSelectCode(Int refSelectCode)
  1835. {
  1836. m_vopmd.iRefSelectCode = refSelectCode;
  1837. }
  1838. /******************************************
  1839. *** class CEnhcBufferEncoder ***
  1840. ******************************************/
  1841. CEnhcBufferEncoder::CEnhcBufferEncoder (Int iSessionWidth, Int iSessionHeight)
  1842. : CEnhcBuffer (iSessionWidth, iSessionHeight)
  1843. {
  1844. }
  1845. Void CEnhcBufferEncoder::copyBuf (const CEnhcBufferEncoder& srcBuf)
  1846. {
  1847. m_iNumMBRef = srcBuf.m_iNumMBRef;
  1848. m_iNumMBXRef = srcBuf.m_iNumMBXRef;
  1849. m_iNumMBYRef = srcBuf.m_iNumMBYRef;
  1850. m_iOffsetForPadY = srcBuf.m_iOffsetForPadY;
  1851. m_iOffsetForPadUV = srcBuf.m_iOffsetForPadUV;
  1852. m_rctPrevNoExpandY = srcBuf.m_rctPrevNoExpandY;
  1853. m_rctPrevNoExpandUV = srcBuf.m_rctPrevNoExpandUV;
  1854. m_rctRefVOPY0 = srcBuf.m_rctRefVOPY0;
  1855. m_rctRefVOPUV0 = srcBuf.m_rctRefVOPUV0;
  1856. m_rctRefVOPY1 = srcBuf.m_rctRefVOPY1;
  1857. m_rctRefVOPUV1 = srcBuf.m_rctRefVOPUV1;
  1858. m_rctRefVOPZoom = srcBuf.m_rctRefVOPZoom; // 9/26 by Norio
  1859. m_bCodedFutureRef = srcBuf.m_bCodedFutureRef; // added by Sharp (99/1/26)
  1860. CMBMode* pmbmdRefSrc = srcBuf.m_rgmbmdRef;
  1861. CMBMode* pmbmdRef    = m_rgmbmdRef;
  1862. CMotionVector* pmvRefSrc = srcBuf.m_rgmvRef;
  1863. CMotionVector* pmvRef = m_rgmvRef;
  1864. // TPS FIX
  1865. Int iMaxIndex = max(PVOP_MV_PER_REF_PER_MB, 2*BVOP_MV_PER_REF_PER_MB);
  1866. for (Int iMB=0; iMB<m_iNumMBRef; iMB++){
  1867. *pmbmdRef = *pmbmdRefSrc;
  1868. pmbmdRef++;
  1869. pmbmdRefSrc++;
  1870. // TPS FIX
  1871. for (Int iVecIndex=0; iVecIndex<iMaxIndex; iVecIndex++ ){
  1872. *pmvRef = *pmvRefSrc;
  1873. pmvRef++;
  1874. pmvRefSrc++;
  1875. }
  1876. }
  1877. CVOPU8YUVBA* pvop = srcBuf.m_pvopcBuf;
  1878. delete m_pvopcBuf;
  1879. m_pvopcBuf = NULL;
  1880. m_pvopcBuf = new CVOPU8YUVBA( *pvop );
  1881. m_t = srcBuf.m_t;
  1882. }
  1883. Void CEnhcBufferEncoder::getBuf(const CVideoObjectEncoder* pvopc)  // get params from Base layer
  1884. {
  1885. // assert(pvopc->m_volmd.volType == BASE_LAYER);
  1886. CMBMode* pmbmdRef;
  1887. CMBMode* pmbmdRefSrc;
  1888. CMotionVector* pmvRef;
  1889. CMotionVector* pmvRefSrc;
  1890. m_bCodedFutureRef = pvopc->m_bCodedFutureRef; // added by Sharp (99/1/26)
  1891. if ( pvopc->m_vopmd.vopPredType != BVOP ){
  1892. pmbmdRef = m_rgmbmdRef;
  1893. pmbmdRefSrc = pvopc->m_rgmbmdRef;
  1894. pmvRef = m_rgmvRef;
  1895. pmvRefSrc = pvopc->m_rgmvRef;
  1896. // This part is stored in CVideoObjectEncoder::encode()
  1897. m_iNumMBRef = pvopc->m_iNumMBRef;
  1898. m_iNumMBXRef = pvopc->m_iNumMBXRef;
  1899. m_iNumMBYRef = pvopc->m_iNumMBYRef;
  1900. } else {
  1901. pmbmdRef = m_rgmbmdRef;
  1902. pmbmdRefSrc = pvopc->m_rgmbmd;
  1903. pmvRef = m_rgmvRef;
  1904. pmvRefSrc = pvopc->m_rgmv;
  1905. m_iNumMBRef = pvopc->m_iNumMB;
  1906. m_iNumMBXRef = pvopc->m_iNumMBX;
  1907. m_iNumMBYRef = pvopc->m_iNumMBY;
  1908. }
  1909. // TPS FIX
  1910. Int iMaxIndex = max(PVOP_MV_PER_REF_PER_MB, 2*BVOP_MV_PER_REF_PER_MB);
  1911. for (Int iMB=0; iMB<m_iNumMBRef; iMB++ ) {
  1912. *pmbmdRef = *pmbmdRefSrc;
  1913. pmbmdRef++;
  1914. pmbmdRefSrc++;
  1915. // TPS FIX
  1916. for (Int iVecIndex=0; iVecIndex<iMaxIndex; iVecIndex++ ){
  1917. *pmvRef = *pmvRefSrc;
  1918. pmvRef++;
  1919. pmvRefSrc++;
  1920. }
  1921. }
  1922. m_t = pvopc->m_t;
  1923. delete m_pvopcBuf;
  1924. m_pvopcBuf = NULL;
  1925. m_pvopcBuf = new CVOPU8YUVBA( *(pvopc->pvopcReconCurr()) );
  1926. if ( pvopc->m_vopmd.vopPredType != BVOP ) {
  1927. m_iOffsetForPadY = pvopc->m_iOffsetForPadY;
  1928. m_iOffsetForPadUV = pvopc->m_iOffsetForPadUV;
  1929. m_rctPrevNoExpandY = pvopc->m_rctPrevNoExpandY;
  1930. m_rctPrevNoExpandUV = pvopc->m_rctPrevNoExpandUV;
  1931. m_rctRefVOPY1 = pvopc->m_rctRefVOPY1;
  1932. m_rctRefVOPUV1 = pvopc->m_rctRefVOPUV1;
  1933. }
  1934. else {
  1935. m_iOffsetForPadY = pvopc->m_iBVOPOffsetForPadY;
  1936. m_iOffsetForPadUV = pvopc->m_iBVOPOffsetForPadUV;
  1937. m_rctPrevNoExpandY = pvopc->m_rctBVOPPrevNoExpandY;
  1938. m_rctPrevNoExpandUV = pvopc->m_rctBVOPPrevNoExpandUV;
  1939. m_rctRefVOPY1 = pvopc->m_rctBVOPRefVOPY1;
  1940. m_rctRefVOPUV1 = pvopc->m_rctBVOPRefVOPUV1;
  1941. }
  1942. }
  1943. Void CEnhcBufferEncoder::putBufToQ0(CVideoObjectEncoder* pvopc)  // store params to Enhancement layer pvopcRefQ0
  1944. {
  1945. assert(pvopc->m_volmd.volType == ENHN_LAYER);
  1946. delete pvopc->m_pvopcRefQ0;
  1947. pvopc->m_pvopcRefQ0 = NULL;
  1948. pvopc->m_pvopcRefQ0 = new CVOPU8YUVBA ( *m_pvopcBuf );
  1949. pvopc->m_tPastRef = m_t;
  1950. pvopc->m_bCodedFutureRef = m_bCodedFutureRef; // added by Sharp (99/1/26)
  1951. if ( pvopc->m_volmd.iEnhnType != 0  && //modified by Sharp (98/3/24)
  1952. (((pvopc->m_vopmd.iRefSelectCode == 1 || pvopc->m_vopmd.iRefSelectCode == 2) && pvopc->m_vopmd.vopPredType == PVOP) ||
  1953.  (pvopc->m_vopmd.iRefSelectCode == 3 && pvopc->m_vopmd.vopPredType == BVOP))
  1954. )
  1955. // if ( pvopc->m_volmd.iEnhnType == 1 )
  1956. {
  1957. CRct rctRefFrameYTemp = pvopc->m_rctRefFrameY;
  1958. CRct rctRefFrameUVTemp = pvopc->m_rctRefFrameUV;
  1959. rctRefFrameYTemp.expand(-EXPANDY_REF_FRAME);
  1960. rctRefFrameUVTemp.expand(-EXPANDY_REF_FRAME/2);
  1961. pvopc->m_pvopcRefQ0->addBYPlain(rctRefFrameYTemp, rctRefFrameUVTemp);
  1962. }
  1963. CMBMode* pmbmdRefSrc = m_rgmbmdRef;
  1964. CMBMode* pmbmdRef = pvopc->m_rgmbmdRef;
  1965. CMotionVector* pmvRefSrc = m_rgmvRef;
  1966. CMotionVector* pmvRef = pvopc->m_rgmvRef;
  1967. // This part is stored in CVideoObjectEncoder::encode()
  1968. pvopc->m_iNumMBRef = m_iNumMBRef;
  1969. pvopc->m_iNumMBXRef = m_iNumMBXRef;
  1970. pvopc->m_iNumMBYRef = m_iNumMBYRef;
  1971. // TPS FIX
  1972. Int iMaxIndex = max(PVOP_MV_PER_REF_PER_MB, 2*BVOP_MV_PER_REF_PER_MB);
  1973. for (Int iMB=0; iMB<m_iNumMBRef; iMB++ ) {
  1974. *pmbmdRef = *pmbmdRefSrc;
  1975. if ( pvopc->m_volmd.iEnhnType != 0  && // modified by Sharp (98/3/24)
  1976. (((pvopc->m_vopmd.iRefSelectCode == 1 || pvopc->m_vopmd.iRefSelectCode == 2) && pvopc->m_vopmd.vopPredType == PVOP) ||
  1977.  (pvopc->m_vopmd.iRefSelectCode == 3 && pvopc->m_vopmd.vopPredType == BVOP))
  1978. ) {
  1979. pmbmdRef->m_shpmd = ALL_OPAQUE;
  1980. }
  1981. pmbmdRef++;
  1982. pmbmdRefSrc++;
  1983. // TPS FIX
  1984. for (Int iVecIndex=0; iVecIndex<iMaxIndex; iVecIndex++ ){
  1985. *pmvRef = *pmvRefSrc;
  1986. pmvRef ++;
  1987. pmvRefSrc ++;
  1988. }
  1989. }
  1990. pvopc->saveShapeMode ();
  1991. // for padding operation
  1992. pvopc->m_iOffsetForPadY = m_iOffsetForPadY;
  1993. pvopc->m_iOffsetForPadUV = m_iOffsetForPadUV;
  1994. pvopc->m_rctPrevNoExpandY = m_rctPrevNoExpandY;
  1995. pvopc->m_rctPrevNoExpandUV = m_rctPrevNoExpandUV;
  1996. // This part is needed for storing RefQ0
  1997. pvopc->m_rctRefVOPY0 = m_rctRefVOPY1;
  1998. pvopc->m_rctRefVOPUV0 = m_rctRefVOPUV1;
  1999. pvopc->m_pvopcRefQ0->setBoundRct(m_rctRefVOPY1);
  2000. pvopc->repeatPadYOrA ((PixelC*) pvopc->m_pvopcRefQ0->pixelsY () + m_iOffsetForPadY, pvopc->m_pvopcRefQ0);
  2001. pvopc->repeatPadUV(pvopc->m_pvopcRefQ0);
  2002. if ( pvopc->m_volmd.fAUsage != RECTANGLE ){
  2003. if ( pvopc->m_volmd.fAUsage == EIGHT_BIT )
  2004. pvopc->repeatPadYOrA ((PixelC*) pvopc->m_pvopcRefQ0->pixelsA () + m_iOffsetForPadY, pvopc->m_pvopcRefQ0);
  2005. }
  2006. }
  2007. Void CEnhcBufferEncoder::putBufToQ1(CVideoObjectEncoder* pvopc)  // store params to Enhancement layer pvopcRefQ1
  2008. {
  2009. assert(pvopc->m_volmd.volType == ENHN_LAYER);
  2010. delete pvopc->m_pvopcRefQ1;
  2011. pvopc->m_pvopcRefQ1 = NULL;
  2012. pvopc->m_pvopcRefQ1 = new CVOPU8YUVBA ( *m_pvopcBuf );
  2013. pvopc->m_tFutureRef = m_t;
  2014. pvopc->m_bCodedFutureRef = m_bCodedFutureRef; // added by Sharp (99/1/26)
  2015. if ( pvopc->m_volmd.iEnhnType != 0  && // modified by Sharp (98/3/24)
  2016. (((pvopc->m_vopmd.iRefSelectCode == 1 || pvopc->m_vopmd.iRefSelectCode == 2) && pvopc->m_vopmd.vopPredType == PVOP) ||
  2017. ((pvopc->m_vopmd.iRefSelectCode == 1 || pvopc->m_vopmd.iRefSelectCode == 3) && pvopc->m_vopmd.vopPredType == BVOP)) // modified by Sharp (98/5/25)
  2018. )
  2019. // if ( pvopc->m_volmd.iEnhnType == 1 )
  2020. {
  2021. CRct rctRefFrameYTemp = pvopc->m_rctRefFrameY;
  2022. CRct rctRefFrameUVTemp = pvopc->m_rctRefFrameUV;
  2023. rctRefFrameYTemp.expand(-EXPANDY_REF_FRAME);
  2024. rctRefFrameUVTemp.expand(-EXPANDY_REF_FRAME/2);
  2025. pvopc->m_pvopcRefQ1->addBYPlain(rctRefFrameYTemp, rctRefFrameUVTemp);
  2026. }
  2027. // if ( pvopc->m_volmd.fAUsage != RECTANGLE ){
  2028. CMBMode* pmbmdRefSrc = m_rgmbmdRef;
  2029. CMBMode* pmbmdRef = pvopc->m_rgmbmdRef;
  2030. CMotionVector* pmvRefSrc = m_rgmvRef;
  2031. CMotionVector* pmvRef = pvopc->m_rgmvRef;
  2032. // This part is stored in CVideoObjectEncoder::encode()
  2033. pvopc->m_iNumMBRef = m_iNumMBRef;
  2034. pvopc->m_iNumMBXRef = m_iNumMBXRef;
  2035. pvopc->m_iNumMBYRef = m_iNumMBYRef;
  2036. // TPS FIX
  2037. Int iMaxIndex = max(PVOP_MV_PER_REF_PER_MB, 2*BVOP_MV_PER_REF_PER_MB);
  2038. for (Int iMB=0; iMB<m_iNumMBRef; iMB++ ) {
  2039. *pmbmdRef = *pmbmdRefSrc;
  2040. if ( pvopc->m_volmd.iEnhnType != 0 ) { // modified by Sharp (98/3/24)
  2041. pmbmdRef->m_shpmd = ALL_OPAQUE;
  2042. }
  2043. pmbmdRef++;
  2044. pmbmdRefSrc++;
  2045. // TPS FIX
  2046. for (Int iVecIndex=0; iVecIndex<iMaxIndex; iVecIndex++ ){
  2047. *pmvRef = *pmvRefSrc;
  2048. pmvRef ++;
  2049. pmvRefSrc++;
  2050. }
  2051. }
  2052. // for padding operation
  2053. pvopc->m_iOffsetForPadY = m_iOffsetForPadY;
  2054. pvopc->m_iOffsetForPadUV = m_iOffsetForPadUV;
  2055. pvopc->m_rctPrevNoExpandY = m_rctPrevNoExpandY;
  2056. pvopc->m_rctPrevNoExpandUV = m_rctPrevNoExpandUV;
  2057. // This part is needed for storing RefQ0
  2058. pvopc->m_rctRefVOPY1 = m_rctRefVOPY1;
  2059. pvopc->m_rctRefVOPUV1 = m_rctRefVOPUV1;
  2060. pvopc->m_pvopcRefQ1->setBoundRct(m_rctRefVOPY1);
  2061. // }
  2062. pvopc->repeatPadYOrA ((PixelC*) pvopc->m_pvopcRefQ1->pixelsY () + m_iOffsetForPadY, pvopc->m_pvopcRefQ1);
  2063. pvopc->repeatPadUV(pvopc->m_pvopcRefQ1);
  2064. if ( pvopc->m_volmd.fAUsage != RECTANGLE ){
  2065. if ( pvopc->m_volmd.fAUsage == EIGHT_BIT )
  2066. pvopc->repeatPadYOrA ((PixelC*) pvopc->m_pvopcRefQ1->pixelsA () + m_iOffsetForPadY, pvopc->m_pvopcRefQ1);
  2067. }
  2068. }
  2069. Void CVideoObjectEncoder::set_LoadShape(
  2070.     Int* ieFramebShape, Int* ieFramefShape, // frame number for back/forward shape
  2071.     const Int iRate,       // rate of base layer
  2072.     const Int ieFrame,       // current frame number
  2073.     const Int iFirstFrame,    // first frame number of sequence
  2074.     const Int iFirstFrameLoop // first frame number of the enhancement loop
  2075. )
  2076. {
  2077.   if(m_volmd.iEnhnType==0){
  2078.       m_vopmd.iLoadBakShape = 0;
  2079.       m_vopmd.iLoadForShape = 0; // do not care
  2080.       return;
  2081.   }
  2082.   if(ieFrame == iFirstFrameLoop){
  2083.     *ieFramefShape = ((ieFrame-iFirstFrame)/iRate)*iRate + iFirstFrame;
  2084.     *ieFramebShape = *ieFramefShape + iRate;
  2085. //    if(*ieFramefShape != iFirstFrame){
  2086.       m_vopmd.iLoadBakShape = 1;
  2087.       m_vopmd.iLoadForShape = 0;
  2088. // } else {
  2089. //      m_vopmd.iLoadBakShape = 1;
  2090. //      m_vopmd.iLoadForShape = 1;
  2091. // }
  2092.   }
  2093.   else{
  2094.       m_vopmd.iLoadBakShape = 0;
  2095.       m_vopmd.iLoadForShape = 0; // do not care
  2096.   }
  2097. }
  2098. Void CVideoObjectEncoder::BackgroundComposition(
  2099.     const Int width, Int height,
  2100.     const Int iFrame,   // current frame number
  2101.     const Int iPrev,   // previous base frame 
  2102.     const Int iNext,      // next     base frame 
  2103.     const CVOPU8YUVBA* pvopcBuffP1,
  2104.     const CVOPU8YUVBA* pvopcBuffP2,
  2105.     const CVOPU8YUVBA* pvopcBuffB1,
  2106.     const CVOPU8YUVBA* pvopcBuffB2,
  2107. const Char* pchReconYUVDir, Int iobj, const Char* pchPrefix, // for output file name // modified by Sharp (98/10/26)
  2108. FILE *pchfYUV  // added by Sharp (98/10/26)
  2109. )
  2110. {
  2111.     Void convertYuv(const CVOPU8YUVBA* pvopcSrc, PixelC* destY, PixelC* destU, PixelC* destV, Int width, Int height);
  2112.     Void convertSeg(const CVOPU8YUVBA* pvopcSrc, PixelC* destBY,PixelC* destBUV,              Int width, Int height,
  2113.     Int left, Int right, Int top, Int bottom
  2114.     );
  2115.     Void bg_comp_each(PixelC* curr, PixelC* prev, PixelC* next, PixelC* mask_curr, PixelC* mask_prev, PixelC* mask_next, 
  2116.       Int curr_t, Int prev_t, Int next_t, Int width, Int height, Int CoreMode); // modified by Sharp (98/3/24)
  2117.     Void inv_convertYuv(const CVOPU8YUVBA* pvopcSrc, PixelC* destY, PixelC* destU, PixelC* destV, Int width, Int height);
  2118.     Void write420_sep(Int num, char *name, PixelC* destY, PixelC* destU, PixelC* destV, Int width, Int height); // modified by Sharp (98/10/26)
  2119.     Void write420_jnt(FILE *pchfYUV, PixelC* destY, PixelC* destU, PixelC* destV, Int width, Int height); // added by Sharp (98/10/26)
  2120.     Void write_seg_test(Int num, char *name, PixelC* destY, Int width, Int height);
  2121.     PixelC* currY = new PixelC [width*height];
  2122.     PixelC* currU = new PixelC [width*height/4];
  2123.     PixelC* currV = new PixelC [width*height/4];
  2124.     PixelC* currBY  = new PixelC [width*height];
  2125.     PixelC* currBUV = new PixelC [width*height/4];
  2126.     PixelC* prevY = new PixelC [width*height];
  2127.     PixelC* prevU = new PixelC [width*height/4];
  2128.     PixelC* prevV = new PixelC [width*height/4];
  2129.     PixelC* prevBY  = new PixelC [width*height];
  2130.     PixelC* prevBUV = new PixelC [width*height/4];
  2131.     PixelC* nextY = new PixelC [width*height];
  2132.     PixelC* nextU = new PixelC [width*height/4];
  2133.     PixelC* nextV = new PixelC [width*height/4];
  2134.     PixelC* nextBY  = new PixelC [width*height];
  2135.     PixelC* nextBUV = new PixelC [width*height/4];
  2136.     // current frame
  2137.     convertYuv(pvopcReconCurr(), currY, currU, currV, width, height);
  2138.     if(pvopcReconCurr ()->pixelsBY () != NULL)
  2139.       convertSeg(pvopcReconCurr(), currBY, currBUV, width, height,
  2140.        m_rctCurrVOPY.left,
  2141.        m_rctCurrVOPY.right,
  2142.        m_rctCurrVOPY.top,
  2143.        m_rctCurrVOPY.bottom); /* forward shape */
  2144.     // previouse frame
  2145.     if(pvopcBuffB1 != NULL)
  2146.       convertYuv(pvopcBuffB1, prevY, prevU, prevV, width, height);
  2147.     else
  2148.       convertYuv(pvopcBuffP1, prevY, prevU, prevV, width, height);
  2149.     convertSeg(rgpbfShape [1]->pvopcReconCurr (), prevBY, prevBUV, width, height,
  2150.        rgpbfShape [1]->m_rctCurrVOPY.left,
  2151.        rgpbfShape [1]->m_rctCurrVOPY.right,
  2152.        rgpbfShape [1]->m_rctCurrVOPY.top,
  2153.        rgpbfShape [1]->m_rctCurrVOPY.bottom); /* forward shape */
  2154.  //   write_test(iPrev, "aaa", prevY, prevU, prevV, width, height);
  2155.  //   write_seg_test(iPrev, "aaa", prevBY, width, height);
  2156.     // next frame
  2157.     if(pvopcBuffB2 != NULL)
  2158.       convertYuv(pvopcBuffB2, nextY, nextU, nextV, width, height);
  2159.     else
  2160.       convertYuv(pvopcBuffP2, nextY, nextU, nextV, width, height);
  2161.     convertSeg(rgpbfShape [0]->pvopcReconCurr (), nextBY, nextBUV, width, height,
  2162.        rgpbfShape [0]->m_rctCurrVOPY.left,
  2163.        rgpbfShape [0]->m_rctCurrVOPY.right,
  2164.        rgpbfShape [0]->m_rctCurrVOPY.top,
  2165.        rgpbfShape [0]->m_rctCurrVOPY.bottom); /* backward shape */
  2166. //    write_test(iNext, "aaa", nextY, nextU, nextV, width, height);
  2167. //    write_seg_test(iNext, "aaa", nextBY, width, height);
  2168. // begin: modified by Sharp (98/3/24)
  2169.     bg_comp_each(currY, prevY, nextY, currBY,  prevBY,  nextBY,  iFrame, iPrev, iNext, width,   height, m_volmd.iEnhnType == 2);
  2170.     bg_comp_each(currU, prevU, nextU, currBUV, prevBUV, nextBUV, iFrame, iPrev, iNext, width/2, height/2, m_volmd.iEnhnType == 2);
  2171.     bg_comp_each(currV, prevV, nextV, currBUV, prevBUV, nextBUV, iFrame, iPrev, iNext, width/2, height/2, m_volmd.iEnhnType == 2);
  2172. // end: modified by Sharp (98/3/24)
  2173. //    inv_convertYuv(pvopcReconCurr(), currY, currU, currV, width, height);
  2174. #ifdef __OUT_ONE_FRAME_ // added by Sharp (98/10/26)
  2175. // write background compsition image
  2176. static Char pchYUV [100];
  2177. sprintf (pchYUV, "%s/%2.2d/%s.yuv", pchReconYUVDir, iobj, pchPrefix); // modified by Sharp (98/10/26)
  2178.     write420_sep(iFrame, pchYUV, currY, currU, currV, width, height); // modified by Sharp (98/10/26)
  2179. // begin: added by Sharp (98/9/27)
  2180. #else
  2181.     write420_jnt(pchfYUV, currY, currU, currV, width, height);
  2182. #endif
  2183. // end: added by Sharp (98/9/27)
  2184.     delete currY;
  2185.     delete currU;
  2186.     delete currV;
  2187.     delete currBY;
  2188.     delete currBUV;
  2189.     delete prevY;
  2190.     delete prevU;
  2191.     delete prevV;
  2192.     delete prevBY;
  2193.     delete prevBUV;
  2194.     delete nextY;
  2195.     delete nextU;
  2196.     delete nextV;
  2197.     delete nextBY;
  2198.     delete nextBUV;
  2199. }
  2200. // end: added by Sharp (98/2/10)