Ap4BitStream.h
上传用户:xjjlds
上传日期:2015-12-05
资源大小:22823k
文件大小:9k
源码类别:

多媒体编程

开发平台:

Visual C++

  1. /*****************************************************************
  2. |
  3. |      File: Ap4BitStream.h
  4. |
  5. |      AP4 - Bit Streams
  6. |
  7. |      (c) 2005 Gilles Boccon-Gibod
  8. |      Author: Gilles Boccon-Gibod (bok@bok.net)
  9. |
  10.  ****************************************************************/
  11. #ifndef _AP4_BIT_STREAM_H_
  12. #define _AP4_BIT_STREAM_H_
  13. /*----------------------------------------------------------------------
  14. |       includes
  15. +---------------------------------------------------------------------*/
  16. #include "Ap4Types.h"
  17. #include "Ap4Results.h"
  18. /*----------------------------------------------------------------------
  19. |       constants
  20. +---------------------------------------------------------------------*/
  21. #define AP4_ERROR_BASE_BITSTREAM -10000
  22. /* the max frame size we can handle */
  23. #define AP4_BITSTREAM_BUFFER_SIZE  8192
  24. /* flags */
  25. #define AP4_BITSTREAM_FLAG_EOS 0x01
  26. /* error codes */
  27. #define AP4_ERROR_NOT_ENOUGH_DATA        (AP4_ERROR_BASE_BITSTREAM - 0)
  28. #define AP4_ERROR_CORRUPTED_BITSTREAM    (AP4_ERROR_BASE_BITSTREAM - 1)
  29. #define AP4_ERROR_NOT_ENOUGH_FREE_BUFFER (AP4_ERROR_BASE_BITSTREAM - 2)
  30. /*----------------------------------------------------------------------
  31. |       types helpers
  32. +---------------------------------------------------------------------*/
  33. /* use long by default */
  34. typedef unsigned int AP4_BitsWord;
  35. #define AP4_WORD_BITS  32
  36. #define AP4_WORD_BYTES 4
  37. /*----------------------------------------------------------------------
  38. |       types
  39. +---------------------------------------------------------------------*/
  40. class AP4_BitStream
  41. {
  42. public:
  43.     // constructor and destructor
  44.     AP4_BitStream();
  45.     ~AP4_BitStream();
  46.     // methods
  47.     AP4_Result   Reset();
  48.     AP4_Size     GetContiguousBytesFree();
  49.     AP4_Size     GetBytesFree();
  50.     AP4_Result   WriteBytes(const AP4_UI08* bytes, AP4_Size byte_count);
  51.     AP4_Size     GetContiguousBytesAvailable();
  52.     AP4_Size     GetBytesAvailable();
  53.     AP4_UI08     ReadByte();
  54.     AP4_Result   ReadBytes(AP4_UI08* bytes, AP4_Size byte_count);
  55.     AP4_UI08     PeekByte();
  56.     AP4_Result   PeekBytes(AP4_UI08* bytes, AP4_Size byte_count);
  57.     int          ReadBit();
  58.     AP4_UI32     ReadBits(unsigned int bit_count);
  59.     int          PeekBit();
  60.     AP4_UI32     PeekBits(unsigned int bit_count);
  61.     AP4_Result   SkipBytes(AP4_Size byte_count);
  62.     void         SkipBit();
  63.     void         SkipBits(unsigned int bit_count);
  64.     AP4_Result   ByteAlign();
  65.     // members
  66.     AP4_UI08*    m_Buffer;
  67.     unsigned int m_In;
  68.     unsigned int m_Out;
  69.     AP4_BitsWord m_Cache;
  70.     unsigned int m_BitsCached;
  71.     unsigned int m_Flags;
  72. private:
  73.     // methods
  74.     AP4_BitsWord ReadCache() const;
  75. };
  76.     
  77. /*----------------------------------------------------------------------
  78. |       macros
  79. +---------------------------------------------------------------------*/
  80. #define AP4_BIT_MASK(_n) ((1<<(_n))-1)
  81. #define AP4_BITSTREAM_POINTER_VAL(offset) 
  82.     ((offset)&(AP4_BITSTREAM_BUFFER_SIZE-1))
  83. #define AP4_BITSTREAM_POINTER_OFFSET(pointer, offset) 
  84.     (AP4_BITSTREAM_POINTER_VAL((pointer)+(offset)))
  85. #define AP4_BITSTREAM_POINTER_ADD(pointer, offset) 
  86.     ((pointer) = AP4_BITSTREAM_POINTER_OFFSET(pointer, offset))
  87. /*----------------------------------------------------------------------
  88. |       AP4_BitStream::ReadCache
  89. +---------------------------------------------------------------------*/
  90. inline AP4_BitsWord
  91. AP4_BitStream::ReadCache() const
  92. {
  93.    unsigned int pos = m_Out;
  94.    AP4_BitsWord cache;
  95. #if AP4_WORD_BITS != 32
  96. #error unsupported word size /* 64 and other word size not yet implemented */
  97. #endif
  98.    if (pos <= AP4_BITSTREAM_BUFFER_SIZE - AP4_WORD_BYTES) {
  99.       unsigned char* out_ptr = &m_Buffer[pos];
  100.       cache =   (((AP4_BitsWord) out_ptr[0]) << 24)
  101.               | (((AP4_BitsWord) out_ptr[1]) << 16)
  102.               | (((AP4_BitsWord) out_ptr[2]) <<  8)
  103.               | (((AP4_BitsWord) out_ptr[3])      );
  104.    } else {
  105.       unsigned char* buf_ptr = m_Buffer;
  106.       cache =   (((AP4_BitsWord) buf_ptr[                              pos    ]) << 24)
  107.               | (((AP4_BitsWord) buf_ptr[AP4_BITSTREAM_POINTER_OFFSET (pos, 1)]) << 16)
  108.               | (((AP4_BitsWord) buf_ptr[AP4_BITSTREAM_POINTER_OFFSET (pos, 2)]) <<  8)
  109.               | (((AP4_BitsWord) buf_ptr[AP4_BITSTREAM_POINTER_OFFSET (pos, 3)])      );
  110.    }
  111.    return cache;
  112. }
  113. /*----------------------------------------------------------------------
  114. |       AP4_BitStream::ReadBits
  115. +---------------------------------------------------------------------*/
  116. inline AP4_UI32
  117. AP4_BitStream::ReadBits(unsigned int n)
  118. {
  119.     AP4_BitsWord   result;
  120.     if (m_BitsCached >= n) {
  121.         /* we have enough bits in the cache to satisfy the request */
  122.         m_BitsCached -= n;
  123.         result = (m_Cache >> m_BitsCached) & AP4_BIT_MASK(n);
  124.     } else {
  125.         /* not enough bits in the cache */
  126.         AP4_BitsWord word;
  127.         /* read the next word */
  128.         {
  129.             word = ReadCache();
  130.             m_Out = AP4_BITSTREAM_POINTER_OFFSET(m_Out, AP4_WORD_BYTES);
  131.         }
  132.         /* combine the new word and the cache, and update the state */
  133.         {
  134.             AP4_BitsWord cache = m_Cache & AP4_BIT_MASK(m_BitsCached);
  135.             n -= m_BitsCached;
  136.             m_BitsCached = AP4_WORD_BITS - n;
  137.             result = (word >> m_BitsCached) | (cache << n);
  138.             m_Cache = word;
  139.         }
  140.     }
  141.     return result;
  142. }
  143. /*----------------------------------------------------------------------
  144. |       AP4_BitStream::ReadBit
  145. +---------------------------------------------------------------------*/
  146. inline int
  147. AP4_BitStream::ReadBit()
  148. {
  149.     AP4_BitsWord result;
  150.     if (m_BitsCached == 0) {
  151.         /* the cache is empty */
  152.         /* read the next word into the cache */
  153.         m_Cache = ReadCache();
  154.         m_Out = AP4_BITSTREAM_POINTER_OFFSET(m_Out, AP4_WORD_BYTES);
  155.         m_BitsCached = AP4_WORD_BITS - 1;
  156.         /* return the first bit */
  157.         result = m_Cache >> (AP4_WORD_BITS - 1);
  158.     } else {
  159.         /* get the bit from the cache */
  160.         result = (m_Cache >> (--m_BitsCached)) & 1;
  161.     }
  162.     return result;
  163. }
  164. /*----------------------------------------------------------------------
  165. |       AP4_BitStream::PeekBits
  166. +---------------------------------------------------------------------*/
  167. inline AP4_UI32
  168. AP4_BitStream::PeekBits(unsigned int n)
  169. {
  170.    /* we have enough bits in the cache to satisfy the request */
  171.    if (m_BitsCached >= n) {
  172.       return (m_Cache >> (m_BitsCached - n)) & AP4_BIT_MASK(n);
  173.    } else {
  174.       /* not enough bits in the cache, read the next word */
  175.       AP4_BitsWord word = ReadCache();
  176.       /* combine the new word and the cache, and update the state */
  177.       AP4_BitsWord   cache = m_Cache & AP4_BIT_MASK(m_BitsCached);
  178.       n -= m_BitsCached;
  179.       return (word >> (AP4_WORD_BITS - n)) | (cache << n);
  180.    }
  181. }
  182. /*----------------------------------------------------------------------
  183. |       AP4_BitStream::PeekBit
  184. +---------------------------------------------------------------------*/
  185. inline int
  186. AP4_BitStream::PeekBit()
  187. {
  188.    /* the cache is empty */
  189.    if (m_BitsCached == 0) {
  190.       /* read the next word into the cache */
  191.       AP4_BitsWord cache = ReadCache();
  192.       /* return the first bit */
  193.       return cache >> (AP4_WORD_BITS - 1);
  194.    } else {
  195.       /* get the bit from the cache */
  196.       return (m_Cache >> (m_BitsCached-1)) & 1;
  197.    }
  198. }
  199. /*----------------------------------------------------------------------
  200. |       AP4_BitStream::SkipBits
  201. +---------------------------------------------------------------------*/
  202. inline void
  203. AP4_BitStream::SkipBits(unsigned int n)
  204. {
  205.    if (n <= m_BitsCached) {
  206.       m_BitsCached -= n;
  207.    } else {
  208.       n -= m_BitsCached;
  209.       while (n >= AP4_WORD_BITS) {
  210.          m_Out = AP4_BITSTREAM_POINTER_OFFSET(m_Out, AP4_WORD_BYTES);
  211.          n -= AP4_WORD_BITS;
  212.       }
  213.       if (n) {
  214.          m_Cache = ReadCache();
  215.          m_BitsCached = AP4_WORD_BITS-n;
  216.          m_Out = AP4_BITSTREAM_POINTER_OFFSET(m_Out, AP4_WORD_BYTES);
  217.       } else {
  218.          m_BitsCached = 0;
  219.          m_Cache = 0;
  220.       }
  221.    }
  222. }
  223. /*----------------------------------------------------------------------
  224. |       AP4_BitStream::SkipBit
  225. +---------------------------------------------------------------------*/
  226. inline void
  227. AP4_BitStream::SkipBit()
  228. {
  229.    if (m_BitsCached == 0) {
  230.       m_Cache = ReadCache();
  231.       m_Out = AP4_BITSTREAM_POINTER_OFFSET(m_Out, AP4_WORD_BYTES);
  232.       m_BitsCached = AP4_WORD_BITS - 1;
  233.    } else {
  234.       --m_BitsCached;
  235.    }
  236. }
  237. /*----------------------------------------------------------------------
  238. |       AP4_BitStream::ReadByte
  239. +---------------------------------------------------------------------*/
  240. inline AP4_UI08
  241. AP4_BitStream::ReadByte()
  242. {
  243.    SkipBits(m_BitsCached & 7);
  244.    return ReadBits(8);
  245. }
  246. /*----------------------------------------------------------------------
  247. |       AP4_BitStream::PeekByte
  248. +---------------------------------------------------------------------*/
  249. inline AP4_UI08
  250. AP4_BitStream::PeekByte()
  251. {
  252.    int extra_bits = m_BitsCached & 7;
  253.    int data = PeekBits(extra_bits + 8);
  254.    int byte = data & 0xFF;
  255.    return byte;
  256. }
  257. #endif // _AP4_BIT_STREAM_H_