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

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. /*************************************************************************
  2. This software module was originally developed by 
  3. Chuang Gu (chuanggu@microsoft.com), Microsoft Corporation
  4. (date: Augest, 1997)
  5. and also edited by
  6. David B. Shu (dbshu@hrl.com), Hughes Electronics/HRL Laboratories
  7. in the course of development of the MPEG-4 Video (ISO/IEC 14496-2). 
  8. This software module is an implementation of a part of one or more MPEG-4 Video tools 
  9. as specified by the MPEG-4 Video. 
  10. ISO/IEC gives users of the MPEG-4 Video free license to this software module or modifications 
  11. thereof for use in hardware or software products claiming conformance to the MPEG-4 Video. 
  12. Those intending to use this software module in hardware or software products are advised that its use may infringe existing patents. 
  13. The original developer of this software module and his/her company, 
  14. the subsequent editors and their companies, 
  15. and ISO/IEC have no liability for use of this software module or modifications thereof in an implementation. 
  16. Copyright is not released for non MPEG-4 Video conforming products. 
  17. Microsoft retains full right to use the code for his/her own purpose, 
  18. assign or donate the code to a third party and to inhibit third parties from using the code for non <MPEG standard> conforming products. 
  19. This copyright notice must be included in all copies or derivative works. 
  20. Copyright (c) 1996, 1997.
  21. Module Name:
  22. sptdec.cpp
  23. Abstract:
  24. Sprite decoder.
  25. Revision History:
  26. *************************************************************************/
  27. #include <stdio.h>
  28. #include <fstream.h>
  29. #include <math.h>
  30. #include "typeapi.h"
  31. #include "codehead.h"
  32. #include "entropy/bitstrm.hpp"
  33. #include "entropy/entropy.hpp"
  34. #include "entropy/huffman.hpp"
  35. #include "global.hpp"
  36. #include "mode.hpp"
  37. #include "vopses.hpp"
  38. #include "vopsedec.hpp"
  39. #ifdef __MFC_
  40. #ifdef _DEBUG
  41. #undef THIS_FILE
  42. static char BASED_CODE THIS_FILE[] = __FILE__;
  43. #endif
  44. #define new DEBUG_NEW    
  45. #endif // __MFC_
  46. #ifdef __PC_COMPILER_
  47. #define IOSBINARY ios::binary
  48. #else
  49. #define IOSBINARY ios::bin
  50. #endif // __PC_COMPILER_
  51. Int CVideoObjectDecoder::decodeSpt ()
  52. {
  53. //David Shu: please insert your stuff in this function
  54. assert (m_vopmd.vopPredType == SPRITE);
  55. if (m_iNumOfPnts > 0)
  56. decodeWarpPoints ();
  57. // Begin: modified by Hughes   4/9/98
  58. if (m_sptMode != BASIC_SPRITE)
  59. decodeSpritePieces  ();
  60. // End: modified by Hughes   4/9/98
  61. if (m_iNumOfPnts > 0) {
  62. CRct rctWarp = (m_volmd.fAUsage != RECTANGLE)? m_rctCurrVOPY : CRct (0, 0, m_ivolWidth, m_ivolHeight);
  63.         if(m_iNumOfPnts==2 || m_iNumOfPnts==3) {
  64. FastAffineWarp (rctWarp, rctWarp / 2, m_uiWarpingAccuracy, m_iNumOfPnts);
  65.         }
  66.         else {
  67. CPerspective2D perspYA (m_iNumOfPnts, m_rgstSrcQ, m_rgstDstQ, m_uiWarpingAccuracy);
  68. warpYA (perspYA, rctWarp, m_uiWarpingAccuracy);
  69. CSiteD rgstSrcQUV [4], rgstDstQUV [4];
  70. for (Int i = 0; i < m_iNumOfPnts; i++) {
  71. rgstSrcQUV [i] = (m_rgstSrcQ [i] - CSiteD (0.5, 0.5)) / 2;
  72. rgstDstQUV [i] = (m_rgstDstQ [i] - CSiteD (0.5, 0.5)) / 2;
  73. }
  74. CPerspective2D perspUV (m_iNumOfPnts, rgstSrcQUV, rgstDstQUV, m_uiWarpingAccuracy);
  75. warpUV (perspUV, rctWarp / 2, m_uiWarpingAccuracy);
  76. }
  77. }
  78. return TRUE;
  79. }
  80. Void CVideoObjectDecoder::decodeWarpPoints ()
  81. {
  82. assert (m_iNumOfPnts > 0);
  83. // Dest corner points MV decoding
  84. Int rgiU [4], rgiV [4], rgiDU [4], rgiDV [4];
  85. Int rgiWrpPnt0Del [2];
  86. CInBitStream* pibstrmWrpPt0 = m_pentrdecSet->m_pentrdecWrpPnt -> bitstream ();
  87. Int j;
  88. for (j = 0; j < m_iNumOfPnts; j++) { 
  89. for (UInt iXorY = 0; iXorY < 2; iXorY++) {
  90. Long lSz = m_pentrdecSet->m_pentrdecWrpPnt->decodeSymbol();
  91. Int iSign = pibstrmWrpPt0->peekBits (1); //get the sign
  92. if (iSign == 1)
  93. rgiWrpPnt0Del[iXorY] = pibstrmWrpPt0->getBits (lSz);
  94. else {
  95. Int iAbsWrpPnt0Del = ~(pibstrmWrpPt0->getBits (lSz)); //get the magnitude
  96. Int iMask = ~(0xFFFFFFFF << lSz); //mask out the irrelavent bits
  97. rgiWrpPnt0Del[iXorY] = -1 * (iAbsWrpPnt0Del & iMask); //masking and signing
  98. }
  99. assert (rgiWrpPnt0Del[iXorY] >= -16383 && rgiWrpPnt0Del[iXorY] <= 16383);
  100. Int iMarker = pibstrmWrpPt0->getBits(1);
  101. assert(iMarker==1);
  102. }
  103. rgiDU [j] = rgiWrpPnt0Del[0];
  104. rgiDV [j] = rgiWrpPnt0Del[1];
  105. }
  106. // create Src VOP bounding box
  107. switch (m_iNumOfPnts) {
  108. case 1: 
  109. m_rgstSrcQ [0] = CSiteD (m_rctCurrVOPY.left, m_rctCurrVOPY.top);
  110. break;
  111. case 2: 
  112. m_rgstSrcQ [0] = CSiteD (m_rctCurrVOPY.left, m_rctCurrVOPY.top);
  113. m_rgstSrcQ [1] = CSiteD (m_rctCurrVOPY.right, m_rctCurrVOPY.top);
  114. break;
  115. case 3:
  116. m_rgstSrcQ [0] = CSiteD (m_rctCurrVOPY.left, m_rctCurrVOPY.top);
  117. m_rgstSrcQ [1] = CSiteD (m_rctCurrVOPY.right, m_rctCurrVOPY.top);
  118. m_rgstSrcQ [2] = CSiteD (m_rctCurrVOPY.left, m_rctCurrVOPY.bottom);
  119. break;
  120. case 4:
  121. m_rgstSrcQ [0] = CSiteD (m_rctCurrVOPY.left, m_rctCurrVOPY.top);
  122. m_rgstSrcQ [1] = CSiteD (m_rctCurrVOPY.right, m_rctCurrVOPY.top);
  123. m_rgstSrcQ [2] = CSiteD (m_rctCurrVOPY.left, m_rctCurrVOPY.bottom);
  124. m_rgstSrcQ [3] = CSiteD (m_rctCurrVOPY.right, m_rctCurrVOPY.bottom);
  125. break;
  126. }
  127. // Dest corner points reconstruction 
  128. rgiU [0] = rgiDU [0]; rgiV [0] = rgiDV [0];
  129. rgiU [1] = rgiDU [1] + rgiU [0]; rgiV [1] = rgiDV [1] + rgiV [0];
  130. rgiU [2] = rgiDU [2] + rgiU [0]; rgiV [2] = rgiDV [2] + rgiV [0];
  131. rgiU [3] = rgiDU [3] + rgiU [2] + rgiU [1] - rgiU [0]; rgiV [3] = rgiDV [3] + rgiV [2] + rgiV [1] - rgiV [0];
  132. for (j = 0; j < m_iNumOfPnts; j++) {
  133. m_rgstDstQ [j].x = (rgiU [j] + 2 * m_rgstSrcQ [j].x) / 2.0;
  134. m_rgstDstQ [j].y = (rgiV [j] + 2 * m_rgstSrcQ [j].y) / 2.0;
  135. }
  136. }
  137. Void CVideoObjectDecoder::decodeInitSprite ()
  138. // decode initial sprite piece and initialize MB status array
  139. {
  140. Int iMod = m_rctSpt.width % MB_SIZE;
  141. Int iSptWidth = (iMod > 0) ? m_rctSpt.width + MB_SIZE - iMod : m_rctSpt.width;
  142. iMod = m_rctSpt.height () % MB_SIZE;
  143. Int iSptHeight = (iMod > 0) ? m_rctSpt.height () + MB_SIZE - iMod : m_rctSpt.height ();
  144. // Begin: modified by Hughes   4/9/98
  145. // m_rctSptExp = m_pvopcRefQ1->whereY();
  146. if (m_sptMode == BASIC_SPRITE)
  147. {
  148.         m_rctCurrVOPY = CRct (0, 0, iSptWidth, iSptHeight);
  149.         m_rctCurrVOPUV = m_rctCurrVOPY.downSampleBy2 ();
  150.         decode ();
  151. if (m_iNumOfPnts > 0) {
  152. swapRefQ1toSpt ();
  153. changeSizeofCurrQ (m_rctDisplayWindow);
  154. }
  155. m_pbitstrmIn->flush (8);
  156. return ;
  157. }
  158. // end:  modified by Hughes   4/9/98
  159. m_rctSptQ =  CRct (0, 0, iSptWidth, iSptHeight) ;  //  save sprite object information
  160. Int iNumMBX = iSptWidth / MB_SIZE; //for the whole sprite
  161. Int iNumMBY = iSptHeight / MB_SIZE;//for the whole sprite
  162. m_ppPieceMBstatus = new SptMBstatus* [iNumMBY]; 
  163. m_ppUpdateMBstatus = new SptMBstatus* [iNumMBY];
  164. // dshu: [v071]  Begin of modification
  165. Int iNumMB = iNumMBX * iNumMBY;
  166. m_rgmbmdSprite = new CMBMode [iNumMB];
  167. // dshu: [v071] end of modification
  168. m_rgmbmdSpt = new CMBMode* [iNumMBY]; 
  169. m_rgpmbmCurr_Spt = new MacroBlockMemory** [iNumMBY];
  170. // Begin: modified by Hughes   4/9/98
  171. Int iMBY;
  172. // Int iMBX, iMBY;
  173. // end:  modified by Hughes   4/9/98
  174. Int iMB, iBlk;
  175. Int nBlk = (m_volmd.fAUsage == EIGHT_BIT) ? 10 : 6;
  176. // Allocate MB hole status array and reconstructed MB  array
  177. for (iMBY = 0; iMBY < iNumMBY; iMBY++) {
  178. m_ppPieceMBstatus[iMBY] = new SptMBstatus [iNumMBX];
  179. m_ppUpdateMBstatus[iMBY] = new SptMBstatus [iNumMBX];
  180. m_rgmbmdSpt[iMBY] = new CMBMode [iNumMBX];
  181. m_rgpmbmCurr_Spt[iMBY] = new MacroBlockMemory* [iNumMBX];
  182. for (iMB = 0; iMB < iNumMBX; iMB++) {
  183. m_rgpmbmCurr_Spt[iMBY][iMB] = new MacroBlockMemory;
  184. m_rgpmbmCurr_Spt[iMBY][iMB]->rgblkm = new BlockMemory [nBlk];
  185. for (iBlk = 0; iBlk < nBlk; iBlk++) {
  186. (m_rgpmbmCurr_Spt[iMBY][iMB]->rgblkm) [iBlk] = new Int [(BLOCK_SIZE << 1) - 1];
  187. }
  188. // Begin: modified by Hughes   4/9/98
  189. m_ppPieceMBstatus[iMBY][iMB] = NOT_DONE;
  190. m_ppUpdateMBstatus[iMBY][iMB] = NOT_DONE;
  191. // end:  modified by Hughes   4/9/98
  192. }
  193. }
  194. // Begin: modified by Hughes   4/9/98
  195. CRct rctSptQ48 = m_pvopcRefQ1->whereY();
  196. m_pvopcSptQ = new CVOPU8YUVBA (m_volmd.fAUsage, rctSptQ48);
  197. m_pvopcSptQ -> shift (m_rctSpt.left, m_rctSpt.top); // change to absolute value in sprite coordinates
  198. m_pbitstrmIn->flush ();
  199. m_tPiece = 0;
  200. m_rctCurrVOPY = m_rctSptQ;
  201. m_rctCurrVOPUV = m_rctCurrVOPY.downSampleBy2 ();
  202. if (m_volmd.fAUsage != RECTANGLE) {
  203. m_iNumMBRef = iNumMB;
  204. m_iNumMBXRef = iNumMBX;
  205. m_iNumMBYRef = iNumMBY;
  206. m_iOffsetForPadY = m_rctRefFrameY.offset (m_rctCurrVOPY.left, m_rctCurrVOPY.top);
  207. m_iOffsetForPadUV = m_rctRefFrameUV.offset (m_rctCurrVOPUV.left, m_rctCurrVOPUV.top);
  208. m_rctRefVOPY1 = m_rctCurrVOPY;
  209. m_rctRefVOPY1.expand (EXPANDY_REFVOP);
  210. m_rctRefVOPUV1 = m_rctCurrVOPUV;
  211. m_rctRefVOPUV1.expand (EXPANDUV_REFVOP);
  212. m_pvopcRefQ1->setBoundRct (m_rctRefVOPY1);
  213. }
  214. /*
  215. m_tPiece = -1;
  216. decode ();
  217. // dshu: begin of modification
  218. // delete the following statement
  219. // m_rctSptPieceY = m_rctCurrVOPY; //for non-rectangular only becomes known now
  220. // dshu: end of modification
  221. m_tPiece = 0;
  222. m_iStepI = m_vopmd.intStepI ;
  223. // ensure byte alignment; 9/16/97
  224. m_pbitstrmIn->flush (8);
  225.     
  226. // dshu: begin of modification
  227. // m_pvopcSptQ = new CVOPU8YUVBA (*m_pvopcRefQ1);
  228. // m_pvopcSptQ -> shift (m_rctSptPieceY.left, m_rctSptPieceY.top); 
  229. m_pvopcSptQ = new CVOPU8YUVBA (m_volmd.fAUsage, m_rctSptExp);
  230. m_pvopcSptQ -> shift (m_rctSpt.left, m_rctSpt.top);   // change to absolute value in sprite coordinates
  231. PiecePut(*m_pvopcRefQ1, *m_pvopcSptQ, m_rctSptPieceY);
  232. // dshu: end of modification
  233. //m_pvopcSptQ->vdlDump("c:\SptQ.vdl");
  234. //wchen: temporally out due to memory problem
  235. CMBMode* pmbmd = m_rgmbmdRef;
  236. IntraPredDirection* Spreddir;
  237. IntraPredDirection* preddir;
  238. // initialize  MB hole status array
  239. // dshu: begin of modification
  240. // Int iMB_left = m_rctSptPieceY.left / MB_SIZE;
  241. // Int iMB_right = m_rctSptPieceY.right / MB_SIZE;
  242. // Int iMB_top = m_rctSptPieceY.top / MB_SIZE;
  243. // Int iMB_bottom = m_rctSptPieceY.bottom / MB_SIZE;
  244. // MBs are based on vector, not on absolute value in sprite coordinates
  245. Int iMB_left = m_iPieceXoffset;
  246. Int iMB_right = m_iPieceXoffset + m_iPieceWidth;
  247. Int iMB_top = m_iPieceYoffset;
  248. Int iMB_bottom = m_iPieceYoffset + m_iPieceHeight;
  249. // dshu: end of modification
  250. for (iMBY = 0; iMBY < iNumMBY; iMBY++) 
  251. for (iMBX = 0; iMBX < iNumMBX; iMBX++) {
  252. if ((iMBX >= iMB_left && iMBX < iMB_right) && (iMBY >= iMB_top && iMBY < iMB_bottom)) 
  253. {
  254. m_ppPieceMBstatus[iMBY][iMBX] = PIECE_DONE;
  255. m_rgmbmdSpt[iMBY][iMBX] = CMBMode (*pmbmd);
  256. m_rgmbmdSprite[iMBX + iNumMBX * iMBY] = CMBMode (*pmbmd);  // dshu: [v071]  added to store mbmd array for sprite
  257. Spreddir = m_rgmbmdSpt[iMBY][iMBX].m_preddir;
  258. preddir = (*pmbmd).m_preddir;
  259. memcpy (Spreddir, preddir, 10  * sizeof (IntraPredDirection));
  260. pmbmd++;
  261. }
  262. else
  263. m_ppPieceMBstatus[iMBY][iMBX] = NOT_DONE;
  264. m_ppUpdateMBstatus[iMBY][iMBX] = NOT_DONE;
  265. }
  266. */
  267. // End: modified by Hughes   4/9/98
  268. m_oldSptXmitMode = PIECE;
  269. m_vopmd.SpriteXmitMode = PAUSE;
  270. }
  271. Void CVideoObjectDecoder::decodeSpritePieces  ()
  272. // decode sprite pieces
  273. {
  274. if ( m_vopmd.SpriteXmitMode == STOP)
  275. return;
  276. m_vopmd.SpriteXmitMode = m_oldSptXmitMode;
  277. CRct rctCurrVOPY = m_rctCurrVOPY; //caching for warping
  278. do {
  279. decodeOneSpritePiece ();
  280. } while (( m_vopmd.SpriteXmitMode != STOP) && ( m_vopmd.SpriteXmitMode != PAUSE));
  281. // dshu: [v071]  Begin of modification
  282. m_rctCurrVOPY = rctCurrVOPY;  //    restore for warping
  283. if (m_volmd.fAUsage != RECTANGLE)
  284. padSprite() ;  //    final padding just before warping 
  285. // dshu: [v071] end of modification
  286. if ( m_vopmd.SpriteXmitMode == STOP) {
  287. // dshu: begin of modification
  288. Int iNumMBX = m_rctSptQ.width / MB_SIZE; 
  289. Int iNumMBY = m_rctSptQ.height () / MB_SIZE;
  290. Int nBlk = (m_volmd.fAUsage == EIGHT_BIT) ? 10 : 6;
  291. for (Int iMBY = 0; iMBY < iNumMBY; iMBY++){
  292. for (Int iMB = 0; iMB < iNumMBX; iMB++) {
  293. for (Int iBlk = 0; iBlk < nBlk; iBlk++)
  294. delete [] (m_rgpmbmCurr_Spt[iMBY][iMB]->rgblkm) [iBlk];
  295. delete [] m_rgpmbmCurr_Spt [iMBY][iMB]->rgblkm;
  296. delete [] m_rgpmbmCurr_Spt [iMBY][iMB];
  297. }
  298. delete [] m_ppPieceMBstatus[iMBY] ; 
  299. delete [] m_ppUpdateMBstatus[iMBY] ;  
  300. delete [] m_rgmbmdSpt[iMBY] ;
  301. delete [] m_rgpmbmCurr_Spt[iMBY];
  302. }
  303. delete [] m_ppPieceMBstatus ; 
  304. delete [] m_ppUpdateMBstatus ;  
  305. delete [] m_rgmbmdSpt ;
  306. delete [] m_rgpmbmCurr_Spt;
  307. delete [] m_rgmbmdSprite ;    // dshu: [v071] 
  308. // dshu: end of modification
  309. //wchen: can you just delete double points like this?
  310. //temporarilly removed 
  311. // delete [] m_ppPieceMBstatus ;
  312. // delete [] m_ppUpdateMBstatus ;
  313. }
  314. //restore since it was changed during decoding to I/P
  315. m_vopmd.vopPredType = SPRITE;
  316. //restore for warping
  317. // m_rctCurrVOPY = rctCurrVOPY;   // dshu: [v071];   move to location of one statement before padSprite()
  318. // ensure byte alignment
  319. m_pbitstrmIn->flush (8);
  320. }
  321. //wchen: moved decode piece part from vopsedec.cpp -- decode ()
  322. Int CVideoObjectDecoder::decodeOneSpritePiece ()
  323. {
  324. //wchen: the part deals with stop and pause stay in decode ()
  325. assert (m_vopmd.SpriteXmitMode != STOP && m_vopmd.SpriteXmitMode != PAUSE);
  326. m_rctSptPieceY = decodeVOSHead ();
  327. if (m_vopmd.SpriteXmitMode == STOP || m_vopmd.SpriteXmitMode == PAUSE)
  328. return TRUE;
  329. else if (m_vopmd.SpriteXmitMode == PIECE ) //faking the paramters to fool vopmbdec
  330. m_vopmd.vopPredType = IVOP;
  331. else 
  332. m_vopmd.vopPredType = PVOP;
  333. // dshu: begin of modification
  334. // m_pvopcRefQ1 -> shift (m_rctSptPieceY.left, m_rctSptPieceY.top);
  335. // PieceOverlay(*m_pvopcSptQ, *m_pvopcRefQ1,  m_rctSptPieceY);   // extract reference
  336. // m_pvopcRefQ1 -> shift (-m_rctSptPieceY.left, -m_rctSptPieceY.top); // restore the m_pvopcRefQ1 to zero offset
  337. // dshu: end of modification
  338. // dshu: begin of modification
  339. //copy to Q0 via SptP
  340. // CVOPU8YUVBA* pvopcSptP = new CVOPU8YUVBA (*m_pvopcSptQ, m_volmd.fAUsage, m_rctSptPieceY);  // extract reference
  341. // m_pvopcRefQ0->overlay (*pvopcSptP);
  342. // delete pvopcSptP;
  343. PieceGet(*m_pvopcRefQ1, *m_pvopcSptQ, m_rctSptPieceY);
  344. // dshu: end of modification
  345. //always to that since the rect keeps changing
  346. //internally, every piece starts from (0, 0)
  347. m_rctCurrVOPY  = CRct(0,0, m_rctSptPieceY.width, m_rctSptPieceY.height());
  348. m_rctCurrVOPUV = m_rctCurrVOPY.downSampleBy2 ();
  349. setRefStartingPointers ();
  350. computeVOPMembers ();
  351. decodeVOP ();
  352. //delete ac/dc pred stuff
  353. Int nBlk = (m_volmd.fAUsage == EIGHT_BIT) ? 10 : 6;
  354. delete [] m_rgblkmCurrMB;
  355. m_rgblkmCurrMB = NULL;
  356. for (Int iMB = 0; iMB < m_iNumMBX; iMB++) {
  357. for (Int iBlk = 0; iBlk < nBlk; iBlk++) {
  358. delete [] (m_rgpmbmAbove [iMB]->rgblkm) [iBlk];
  359. delete [] (m_rgpmbmCurr  [iMB]->rgblkm) [iBlk];
  360. }
  361. delete [] m_rgpmbmAbove [iMB]->rgblkm;
  362. delete m_rgpmbmAbove [iMB];
  363. delete [] m_rgpmbmCurr [iMB]->rgblkm;
  364. delete m_rgpmbmCurr [iMB];
  365. }
  366. delete [] m_rgpmbmAbove;
  367. m_rgpmbmAbove = NULL;
  368. delete [] m_rgpmbmCurr;
  369. m_rgpmbmCurr = NULL;
  370. // Place the decoded sprite piece into sprite buffer.
  371. // Please notice that initial piece is offset by a vector like any VOP;
  372. // the rest of sprite pieces have zero offset, thus require shifting to be placed into buffer.
  373. // shift back to absolutes in sprite coordinates for overlaying
  374. // dshu: begin of modification
  375. // m_pvopcRefQ1 -> shift (m_rctSptPieceY.left, m_rctSptPieceY.top);
  376. // m_pvopcSptQ -> overlay (*m_pvopcRefQ1, m_rctSptPieceY);
  377. PiecePut(*m_pvopcRefQ1, *m_pvopcSptQ, m_rctSptPieceY);
  378. // PieceOverlay(*m_pvopcRefQ1, *m_pvopcSptQ, m_rctSptPieceY);
  379. // restore the m_pvopcRefQ1 to zero offset
  380. // m_pvopcRefQ1 -> shift (-m_rctSptPieceY.left, -m_rctSptPieceY.top);
  381. // dshu: end of modification
  382. return TRUE;
  383. }
  384. CRct CVideoObjectDecoder::decodeVOSHead ()
  385. {
  386. m_oldSptXmitMode = m_vopmd.SpriteXmitMode;
  387. m_vopmd.SpriteXmitMode = (SptXmitMode) m_pbitstrmIn -> getBits (NUMBITS_SPRITE_XMIT_MODE);
  388. if (( m_vopmd.SpriteXmitMode != STOP) &&( m_vopmd.SpriteXmitMode != PAUSE)) {
  389. Int stepToBeDeCoded = m_pbitstrmIn -> getBits (NUMBITS_VOP_QUANTIZER);
  390. if (m_vopmd.SpriteXmitMode == UPDATE) 
  391. m_vopmd.intStep = stepToBeDeCoded;
  392. else
  393. m_vopmd.intStepI = stepToBeDeCoded;
  394. m_iPieceWidth = m_pbitstrmIn -> getBits (NUMBITS_SPRITE_MB_OFFSET);
  395. m_iPieceHeight = m_pbitstrmIn -> getBits (NUMBITS_SPRITE_MB_OFFSET);
  396. // Begin: modified by Hughes   4/9/98
  397. /* Int iMarker = wmay */ m_pbitstrmIn -> getBits (MARKER_BIT);
  398. // End: modified by Hughes   4/9/98
  399. m_iPieceXoffset = m_pbitstrmIn -> getBits (NUMBITS_SPRITE_MB_OFFSET);
  400. m_iPieceYoffset = m_pbitstrmIn -> getBits (NUMBITS_SPRITE_MB_OFFSET);
  401. //wchen: changed to absolute value in sprite coordinates
  402. Int left  = (m_iPieceXoffset * MB_SIZE) + m_rctSpt.left;
  403. Int top = (m_iPieceYoffset * MB_SIZE)  + m_rctSpt.top;
  404. Int right = left + m_iPieceWidth * MB_SIZE ;
  405. Int bottom = top + m_iPieceHeight * MB_SIZE ;
  406. return CRct (left, top, right, bottom);
  407. }
  408. else
  409. return CRct();
  410. }