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

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. /*************************************************************************
  2. This software module was originally developed by 
  3. Ming-Chieh Lee (mingcl@microsoft.com), Microsoft Corporation
  4. Wei-ge Chen (wchen@microsoft.com), Microsoft Corporation
  5. Bruce Lin (blin@microsoft.com), Microsoft Corporation
  6. Chuang Gu (chuanggu@microsoft.com), Microsoft Corporation
  7. (date: March, 1996)
  8. and edited by
  9. Yoshihiro Kikuchi (TOSHIBA CORPORATION)
  10. Takeshi Nagai (TOSHIBA CORPORATION)
  11. Toshiaki Watanabe (TOSHIBA CORPORATION)
  12. Noboru Yamaguchi (TOSHIBA CORPORATION)
  13. in the course of development of the MPEG-4 Video (ISO/IEC 14496-2). 
  14. This software module is an implementation of a part of one or more MPEG-4 Video tools 
  15. as specified by the MPEG-4 Video. 
  16. ISO/IEC gives users of the MPEG-4 Video free license to this software module or modifications 
  17. thereof for use in hardware or software products claiming conformance to the MPEG-4 Video. 
  18. Those intending to use this software module in hardware or software products are advised that its use may infringe existing patents. 
  19. The original developer of this software module and his/her company, 
  20. the subsequent editors and their companies, 
  21. and ISO/IEC have no liability for use of this software module or modifications thereof in an implementation. 
  22. Copyright is not released for non MPEG-4 Video conforming products. 
  23. Microsoft retains full right to use the code for his/her own purpose, 
  24. assign or donate the code to a third party and to inhibit third parties from using the code for non MPEG-4 Video conforming products. 
  25. This copyright notice must be included in all copies or derivative works. 
  26. Copyright (c) 1996, 1997.
  27. Module Name:
  28. bitstrm.cpp
  29. Abstract:
  30. Classes for bitstream I/O.
  31. Revision History:
  32. *************************************************************************/
  33. #include <iostream.h>
  34. #include <stdio.h>
  35. #include <stdlib.h>
  36. #include "typeapi.h"
  37. #include "bitstrm.hpp"
  38. #include "inbits.h"
  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. UInt getbit (UInt data, UInt position, UInt num) // get the num-bit field of x starting from position p
  47. {
  48. return ((data >> (position + 1 - num)) & ~(~0 << num));
  49. }
  50. Void print_bit (UInt x, UInt num, UInt startPos) // print num bits starting from startPos
  51. {
  52. for (Int k = 0; k <= (Int) (num - startPos); k++) {
  53. UInt y = getbit (x, num, 1);
  54. printf ("%u ", y);
  55. x = x << 1;
  56. }
  57. printf ("n");
  58. }
  59. unsigned int bit_msk[33] =
  60. {
  61.   0x00000000, 0x00000001, 0x00000003, 0x00000007,
  62.   0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f,
  63.   0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff,
  64.   0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff,
  65.   0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff,
  66.   0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff,
  67.   0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff,
  68.   0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff,
  69.   0xffffffff
  70. };
  71. COutBitStream::COutBitStream (Char* pchBuffer, Int iBitPosition, ostream* pstrmTrace) : 
  72. m_pstrmTrace (pstrmTrace),
  73. m_chEncBuffer (0),
  74. m_uEncNumEmptyBits (8)
  75. {
  76. assert (iBitPosition < 8);
  77. assert (iBitPosition >= 0);
  78. m_iBitPosition = iBitPosition;
  79. m_pchBuffer = pchBuffer;
  80. m_lCounter = 0;
  81. m_pchBufferRun = m_pchBuffer;
  82. m_iBuffer = 0;
  83. // Added for Data Partitioning mode by Toshiba(1998-1-16)
  84. m_bDontSendBits = FALSE;
  85. // End Toshiba(1998-1-16)
  86. }
  87.  
  88. Void COutBitStream::reset () //but keep the byte buffer
  89. {
  90. // m_uEncNumEmptyBits = 8;
  91. // m_chEncBuffer = 0;
  92. m_pchBufferRun = m_pchBuffer;
  93. m_iBuffer = 0;
  94. }
  95. Void COutBitStream::resetAll ()
  96. {
  97. m_iBitPosition = 0;
  98. m_lCounter = 0;
  99. m_uEncNumEmptyBits = 8;
  100. m_chEncBuffer = 0;
  101. m_pchBufferRun = m_pchBuffer;
  102. m_iBuffer = 0;
  103. }
  104. Void COutBitStream::setBookmark ()
  105. {
  106. bookmark (1);
  107. }
  108. Void COutBitStream::gotoBookmark ()
  109. {
  110. bookmark (0);
  111. }
  112. Void COutBitStream::bookmark (Bool bSet)
  113. {
  114. static Bool bBookmarkOn = FALSE;
  115. static Int iBitPosition;
  116. static Int lCounter;
  117. static UInt uEncNumEmptyBits;
  118. static U8 chEncBuffer;
  119. static Char* pchBufferRun;
  120. static Int iBuffer;
  121. if (bSet) {
  122. iBitPosition = m_iBitPosition;
  123. lCounter = m_lCounter;
  124. uEncNumEmptyBits = m_uEncNumEmptyBits;
  125. chEncBuffer = m_chEncBuffer;
  126. pchBufferRun = m_pchBufferRun;
  127. iBuffer = m_iBuffer;
  128. bBookmarkOn = TRUE;
  129. }
  130. else {
  131. m_iBitPosition = iBitPosition;
  132. m_lCounter = lCounter;
  133. m_uEncNumEmptyBits = uEncNumEmptyBits;
  134. m_chEncBuffer = chEncBuffer;
  135. m_pchBufferRun = pchBufferRun;
  136. m_iBuffer = iBuffer;
  137. bBookmarkOn = FALSE;
  138. }
  139. }
  140. Void COutBitStream::putBitsC (Char cBits,Int iNOfBits)
  141. {
  142. putBits ((Int) cBits, (UInt) iNOfBits); 
  143. }
  144. Void COutBitStream::putBits (Int data, UInt numBits, const Char* rgchSymbolName)
  145. {
  146. assert (numBits < 100); //usually not that large
  147. if (numBits == 0) return;
  148. // Added for Data Partitioning mode by Toshiba(1998-1-16)
  149. if(m_bDontSendBits) return;
  150. // End Toshiba(1998-1-16)
  151. #ifdef __TRACE_AND_STATS_
  152. if (m_pstrmTrace != NULL && rgchSymbolName != NULL) {
  153. Char* rgchBinaryForm = new Char [numBits + 1];
  154. assert (rgchBinaryForm != NULL);
  155. m_pstrmTrace->width (20);
  156. (*m_pstrmTrace) << rgchSymbolName << ": ";
  157. Int iMask = 0xFFFFFFFF;
  158. iMask = iMask << numBits;
  159. iMask = ~iMask;
  160. Int iCleanData = data & iMask;
  161. //_itoa (iCleanData, rgchBinaryForm, 2); // win32 only
  162. Int iBit;
  163. iMask = 0x00000001;
  164. for (iBit = (Int) numBits - 1; iBit >= 0; iBit--) {
  165. rgchBinaryForm [iBit] = ((iCleanData & iMask) == 0) ? '0' : '1';
  166. iMask = iMask << 1;
  167. }
  168. rgchBinaryForm [numBits] = '';
  169. m_pstrmTrace->width (numBits);
  170. m_pstrmTrace->fill ('0');
  171. (*m_pstrmTrace) << rgchBinaryForm;
  172. m_pstrmTrace->fill (' ');
  173. (*m_pstrmTrace) << " @" << m_lCounter << 'n';
  174. m_pstrmTrace->flush ();
  175. delete rgchBinaryForm;
  176. }
  177. #endif // __TRACE_AND_STATS_
  178. if (m_uEncNumEmptyBits > numBits) { // not ready to put the data to buffer since it's not full
  179. m_uEncNumEmptyBits -= numBits;
  180. Char mskData = (0xFF >> (8 - numBits)) & data; 
  181. mskData = mskData << m_uEncNumEmptyBits;
  182. m_chEncBuffer = m_chEncBuffer ^ mskData;
  183.         m_lCounter += numBits;
  184. }
  185. else if (m_uEncNumEmptyBits == numBits) { // ready
  186. Char mskData = (0xFF >> (8 - numBits)) & data; 
  187. m_chEncBuffer = m_chEncBuffer ^ mskData;
  188. *m_pchBufferRun++ = m_chEncBuffer;
  189. m_iBuffer++;
  190. m_chEncBuffer = 0;
  191. m_uEncNumEmptyBits = 8;
  192.         m_lCounter += numBits;
  193. }
  194. else { // ready, but need to handle the leftover part
  195. UInt temp = getbit (data, numBits - 1, m_uEncNumEmptyBits);
  196. numBits -= m_uEncNumEmptyBits; // length of unhandled part
  197. m_chEncBuffer = m_chEncBuffer ^ temp;
  198.         m_lCounter += m_uEncNumEmptyBits;
  199. *m_pchBufferRun++ = m_chEncBuffer;
  200. m_iBuffer++;
  201. m_chEncBuffer = 0;
  202. m_uEncNumEmptyBits = 8;
  203. data = data ^ (temp << numBits);
  204. putBits (data, numBits);
  205. }
  206. }
  207. Void COutBitStream::putBits (Char *pBits, Int lNOfBits)
  208. {
  209.     assert(lNOfBits>=0);
  210.     while(lNOfBits>0)
  211.     {
  212.         if(lNOfBits>8)
  213.         {
  214.             putBitsC((Int)(*pBits),8);
  215.             lNOfBits-=8;
  216.             pBits++;
  217.         }
  218.         else
  219.         {
  220.             putBitsC((Int)(*pBits),(UInt)lNOfBits);
  221.             break;
  222.         }
  223.     }
  224. }
  225. Void COutBitStream::putBitStream(COutBitStream &cStrm)
  226. {
  227. cStrm.m_pchBufferRun[0]=cStrm.m_chEncBuffer >> cStrm.m_uEncNumEmptyBits;
  228. putBits(cStrm.m_pchBuffer,cStrm.m_lCounter);
  229. }
  230. Int COutBitStream::flush ()
  231. {
  232. Int nBits = 0;
  233. if (m_uEncNumEmptyBits != 8) {
  234. nBits = m_uEncNumEmptyBits;
  235. putBits ((Int) 0, (UInt) 1);
  236. putBits ((Int) 0xFFFF, nBits - 1);
  237. /*
  238. *m_pchBufferRun++ = m_chEncBuffer;
  239. m_iBuffer++;
  240. m_lCounter += m_uEncNumEmptyBits;
  241. nBits = m_uEncNumEmptyBits;
  242. m_uEncNumEmptyBits = 8;
  243. m_chEncBuffer = 0;
  244. */
  245. }
  246. else {
  247. nBits = 8;
  248. putBits ((Int) 0x007F, nBits);
  249. }
  250. return nBits;
  251. }
  252. Void COutBitStream::trace (const Char* rgchSymbolName)
  253. {
  254. if (m_pstrmTrace != NULL) {
  255. m_pstrmTrace->width (20);
  256. (*m_pstrmTrace) << rgchSymbolName;
  257. m_pstrmTrace->flush ();
  258. }
  259. }
  260. Void COutBitStream::trace (Int iValue, const Char* rgchSymbolName)
  261. {
  262. if (m_pstrmTrace != NULL) {
  263. m_pstrmTrace->width (20);
  264. (*m_pstrmTrace) << rgchSymbolName << "= ";
  265. (*m_pstrmTrace) << iValue << "n";
  266. m_pstrmTrace->flush ();
  267. }
  268. }
  269. Void COutBitStream::trace (UInt uiValue, const Char* rgchSymbolName)
  270. {
  271. if (m_pstrmTrace != NULL) {
  272. m_pstrmTrace->width (20);
  273. (*m_pstrmTrace) << rgchSymbolName << "= ";
  274. (*m_pstrmTrace) << uiValue << "n";
  275. m_pstrmTrace->flush ();
  276. }
  277. }
  278. Void COutBitStream::trace (Float fltValue, const Char* rgchSymbolName)
  279. {
  280. if (m_pstrmTrace != NULL) {
  281. m_pstrmTrace->width (20);
  282. (*m_pstrmTrace) << rgchSymbolName << "= ";
  283. (*m_pstrmTrace) << fltValue << "n";
  284. m_pstrmTrace->flush ();
  285. }
  286. }
  287. #ifndef __DOUBLE_PRECISION_
  288. Void COutBitStream::trace (Double dblValue, const Char* rgchSymbolName)
  289. {
  290. if (m_pstrmTrace != NULL) {
  291. m_pstrmTrace->width (20);
  292. (*m_pstrmTrace) << rgchSymbolName << "= ";
  293. (*m_pstrmTrace) << dblValue << "n";
  294. m_pstrmTrace->flush ();
  295. }
  296. }
  297. #endif
  298. Void COutBitStream::trace (const CMotionVector& mvValue, const Char* rgchSymbolName)
  299. {
  300. if (m_pstrmTrace != NULL) {
  301. m_pstrmTrace->width (20);
  302. (*m_pstrmTrace) << rgchSymbolName << "= ";
  303. (*m_pstrmTrace) << mvValue.iMVX + mvValue.iMVX + mvValue.iHalfX << ", ";
  304. (*m_pstrmTrace) << mvValue.iMVY + mvValue.iMVY + mvValue.iHalfY << "n ";
  305. m_pstrmTrace->flush ();
  306. }
  307. }
  308. Void COutBitStream::trace (const CVector2D& vctValue, const Char* rgchSymbolName)
  309. {
  310. if (m_pstrmTrace != NULL) {
  311. m_pstrmTrace->width (20);
  312. (*m_pstrmTrace) << rgchSymbolName << "= ";
  313. (*m_pstrmTrace) << vctValue.x << ", ";
  314. (*m_pstrmTrace) << vctValue.y << "n ";
  315. m_pstrmTrace->flush ();
  316. }
  317. }
  318. Void COutBitStream::trace (const CSite& stValue, const Char* rgchSymbolName)
  319. {
  320. if (m_pstrmTrace != NULL) {
  321. m_pstrmTrace->width (20);
  322. (*m_pstrmTrace) << rgchSymbolName << "= ";
  323. (*m_pstrmTrace) << stValue.x << ", ";
  324. (*m_pstrmTrace) << stValue.y << "n ";
  325. m_pstrmTrace->flush ();
  326. }
  327. }
  328. Void COutBitStream::trace (const CFloatImage* pfi, const Char* rgchSymbolName, CRct rct)
  329. {
  330. if (m_pstrmTrace == NULL)
  331. return;
  332. Int iValue;
  333. (*m_pstrmTrace) << rgchSymbolName << "= n";
  334. if (rct.valid ()) {
  335. for (CoordI iY = rct.top; iY < rct.bottom; iY++) {
  336. const PixelF* ppxlf = pfi->pixels (rct.left, iY);
  337. for (CoordI iX = rct.left; iX < rct.right; iX++) {
  338. iValue = (Int) *ppxlf;
  339. (*m_pstrmTrace) << iValue << " ";
  340. ppxlf++;
  341. }
  342. (*m_pstrmTrace) << "n";
  343. }
  344. }
  345. else {
  346. const PixelF* ppxlf = pfi->pixels ();
  347. for (CoordI iY = pfi->where ().top; iY < pfi->where ().bottom; iY++) {
  348. for (CoordI iX = pfi->where ().left; iX < pfi->where ().right; iX++) {
  349. iValue = (Int) *ppxlf;
  350. (*m_pstrmTrace) << iValue << " ";
  351. ppxlf++;
  352. }
  353. (*m_pstrmTrace) << "n";
  354. }
  355. }
  356. m_pstrmTrace->flush ();
  357. }
  358. Void COutBitStream::trace (const Float* ppxlf, UInt cElem, const Char* rgchSymbolName)
  359. {
  360. if (m_pstrmTrace == NULL)
  361. return;
  362. Int iValue;
  363. (*m_pstrmTrace) << rgchSymbolName << ": n";
  364. for (UInt iElem = 0; iElem < cElem; iElem++) {
  365. iValue = (Int) *ppxlf;
  366. (*m_pstrmTrace) << iValue << " ";
  367. ppxlf++;
  368. }
  369. (*m_pstrmTrace) << "n";
  370. m_pstrmTrace->flush ();
  371. }
  372. Void COutBitStream::trace (const Int* rgi, UInt cElem, const Char* rgchSymbolName)
  373. {
  374. if (m_pstrmTrace == NULL)
  375. return;
  376. (*m_pstrmTrace) << rgchSymbolName << ": n";
  377. for (UInt iElem = 0; iElem < cElem; iElem++) {
  378. (*m_pstrmTrace) << *rgi++ << " ";
  379. }
  380. (*m_pstrmTrace) << "n";
  381. m_pstrmTrace->flush ();
  382. }
  383. Void COutBitStream::trace (const PixelC* rgpxlc, Int cCol, Int cRow, const Char* rgchSymbolName) //this is for tracing shape buffers
  384. {
  385. if (m_pstrmTrace == NULL)
  386. return;
  387. (*m_pstrmTrace) << rgchSymbolName << ": n";
  388. for (Int iRow = -1; iRow < cRow; iRow++) {
  389. for (Int iCol = -1; iCol < cCol; iCol++) {
  390. if (iRow == -1)
  391. (*m_pstrmTrace) << "-";
  392. else if (iCol == -1) {
  393. m_pstrmTrace->width (2);
  394. (*m_pstrmTrace) << iRow << "|"; 
  395. }
  396. else
  397. (*m_pstrmTrace) << (*rgpxlc++ == MPEG4_OPAQUE); 
  398. }
  399. (*m_pstrmTrace) << "n";
  400. }
  401. m_pstrmTrace->flush ();
  402. }
  403. CInBitStream::CInBitStream (void) 
  404. {
  405.   m_pistrm = -1;
  406.   init();
  407. }
  408. CInBitStream::CInBitStream (int istrm)
  409. {
  410.   m_pistrm = istrm;
  411.   init();
  412. }
  413. CInBitStream::~CInBitStream() 
  414. {
  415.   if (m_pistrm >= 0) {
  416.     free(m_buffer);
  417.   };
  418. }
  419.   
  420. void CInBitStream::init (void) {
  421.   m_bookmark = 0;
  422.   m_buffer = NULL;
  423.   m_framebits = m_framebits_max = 0;
  424. }
  425. uint32_t CInBitStream::getBits (uint32_t numBits)
  426. {
  427.   uint32_t ret = peekBits(numBits);
  428.   flushbits(numBits);
  429.   return ret;
  430. }
  431. int CInBitStream::peekOneBit (uint32_t numBits)
  432. {
  433.   return peekBits(numBits) & 0x1;
  434. }
  435. int CInBitStream::peekBitsTillByteAlign (int &nBitsToPeek)
  436. {
  437.   nBitsToPeek = 8 - m_bitcnt;
  438.   return peekBits(nBitsToPeek);
  439. }
  440. int CInBitStream::peekBitsFromByteAlign (int nBitsToPeek) 
  441. {
  442.   int ret;
  443.   if (nBitsToPeek == 0) return 0;
  444.   setBookmark();
  445.   getBits((uint32_t)8 - m_bitcnt);
  446.   ret = peekBits(nBitsToPeek);
  447.   gotoBookmark();
  448.   return ret;
  449. }
  450. void CInBitStream::bookmark (Bool bSet) 
  451. {
  452.   if (bSet) setBookmark();
  453.   else gotoBookmark();
  454. }
  455. void CInBitStream::read_ifstream_buffer (void)
  456. {
  457.   int left, offset, ret;
  458.   if (m_buffer == NULL) {
  459.     m_buffer = (unsigned char *)malloc(8092);
  460.     m_orig_buflen = read(m_pistrm, m_buffer, 8092);
  461.     m_framebits = 0;
  462.     m_bitcnt = 0;
  463.     m_rdptr = m_buffer;
  464.   } else {
  465.     if (m_bookmark == 0) {
  466.       left = m_orig_buflen - (m_framebits / 8);
  467.       offset = m_orig_buflen - left;
  468.       memmove(m_buffer,
  469.       m_buffer + offset,
  470.       left);
  471.       ret = read(m_pistrm, m_buffer + left, m_orig_buflen - left);
  472.       m_orig_buflen = left + ret;
  473.       m_framebits = m_bitcnt;
  474.       m_rdptr = m_buffer;
  475.     } else {
  476.       left = m_orig_buflen - (m_bookmark_framebits / 8);
  477.       offset = m_orig_buflen - left;
  478.       memmove(m_buffer,
  479.       m_buffer + offset,
  480.       left);
  481.       ret = read(m_pistrm, m_buffer + offset, m_orig_buflen - left);
  482.       m_orig_buflen = left + ret;
  483.       int framebits_past, rdptr_past;
  484.       framebits_past = m_framebits - m_bookmark_framebits;
  485.       rdptr_past = m_rdptr - m_bookmark_rdptr;
  486.       m_framebits = m_bitcnt + framebits_past;
  487.       m_bookmark_framebits = m_bitcnt;
  488.       m_bookmark_rdptr = m_buffer;
  489.       m_rdptr = m_buffer + rdptr_past;
  490.     }
  491.   }
  492.   m_framebits_max = m_orig_buflen * 8;
  493. }
  494. void CInBitStream::set_buffer (unsigned char *bptr, 
  495.        uint32_t blen) 
  496. {
  497.   m_buffer = bptr;
  498.   m_rdptr = bptr;
  499.   m_bitcnt = 0;
  500.   m_framebits = 0;
  501.   m_orig_buflen = blen;
  502.   m_framebits_max = blen * 8;
  503.   m_bookmark = 0;
  504. }
  505. Void CInBitStream::flush (int nExtraBits) 
  506. {
  507.   if (m_bitcnt == 0) getBits((uint32_t)nExtraBits);
  508.   if (m_bitcnt != 0)
  509.     flushbits(8 - m_bitcnt);
  510. }