Ap4BitStream.h
上传用户:xjjlds
上传日期:2015-12-05
资源大小:22823k
文件大小:9k
- /*****************************************************************
- |
- | File: Ap4BitStream.h
- |
- | AP4 - Bit Streams
- |
- | (c) 2005 Gilles Boccon-Gibod
- | Author: Gilles Boccon-Gibod (bok@bok.net)
- |
- ****************************************************************/
- #ifndef _AP4_BIT_STREAM_H_
- #define _AP4_BIT_STREAM_H_
- /*----------------------------------------------------------------------
- | includes
- +---------------------------------------------------------------------*/
- #include "Ap4Types.h"
- #include "Ap4Results.h"
- /*----------------------------------------------------------------------
- | constants
- +---------------------------------------------------------------------*/
- #define AP4_ERROR_BASE_BITSTREAM -10000
- /* the max frame size we can handle */
- #define AP4_BITSTREAM_BUFFER_SIZE 8192
- /* flags */
- #define AP4_BITSTREAM_FLAG_EOS 0x01
- /* error codes */
- #define AP4_ERROR_NOT_ENOUGH_DATA (AP4_ERROR_BASE_BITSTREAM - 0)
- #define AP4_ERROR_CORRUPTED_BITSTREAM (AP4_ERROR_BASE_BITSTREAM - 1)
- #define AP4_ERROR_NOT_ENOUGH_FREE_BUFFER (AP4_ERROR_BASE_BITSTREAM - 2)
- /*----------------------------------------------------------------------
- | types helpers
- +---------------------------------------------------------------------*/
- /* use long by default */
- typedef unsigned int AP4_BitsWord;
- #define AP4_WORD_BITS 32
- #define AP4_WORD_BYTES 4
- /*----------------------------------------------------------------------
- | types
- +---------------------------------------------------------------------*/
- class AP4_BitStream
- {
- public:
- // constructor and destructor
- AP4_BitStream();
- ~AP4_BitStream();
- // methods
- AP4_Result Reset();
- AP4_Size GetContiguousBytesFree();
- AP4_Size GetBytesFree();
- AP4_Result WriteBytes(const AP4_UI08* bytes, AP4_Size byte_count);
- AP4_Size GetContiguousBytesAvailable();
- AP4_Size GetBytesAvailable();
- AP4_UI08 ReadByte();
- AP4_Result ReadBytes(AP4_UI08* bytes, AP4_Size byte_count);
- AP4_UI08 PeekByte();
- AP4_Result PeekBytes(AP4_UI08* bytes, AP4_Size byte_count);
- int ReadBit();
- AP4_UI32 ReadBits(unsigned int bit_count);
- int PeekBit();
- AP4_UI32 PeekBits(unsigned int bit_count);
- AP4_Result SkipBytes(AP4_Size byte_count);
- void SkipBit();
- void SkipBits(unsigned int bit_count);
- AP4_Result ByteAlign();
- // members
- AP4_UI08* m_Buffer;
- unsigned int m_In;
- unsigned int m_Out;
- AP4_BitsWord m_Cache;
- unsigned int m_BitsCached;
- unsigned int m_Flags;
- private:
- // methods
- AP4_BitsWord ReadCache() const;
- };
-
- /*----------------------------------------------------------------------
- | macros
- +---------------------------------------------------------------------*/
- #define AP4_BIT_MASK(_n) ((1<<(_n))-1)
- #define AP4_BITSTREAM_POINTER_VAL(offset)
- ((offset)&(AP4_BITSTREAM_BUFFER_SIZE-1))
- #define AP4_BITSTREAM_POINTER_OFFSET(pointer, offset)
- (AP4_BITSTREAM_POINTER_VAL((pointer)+(offset)))
- #define AP4_BITSTREAM_POINTER_ADD(pointer, offset)
- ((pointer) = AP4_BITSTREAM_POINTER_OFFSET(pointer, offset))
- /*----------------------------------------------------------------------
- | AP4_BitStream::ReadCache
- +---------------------------------------------------------------------*/
- inline AP4_BitsWord
- AP4_BitStream::ReadCache() const
- {
- unsigned int pos = m_Out;
- AP4_BitsWord cache;
- #if AP4_WORD_BITS != 32
- #error unsupported word size /* 64 and other word size not yet implemented */
- #endif
- if (pos <= AP4_BITSTREAM_BUFFER_SIZE - AP4_WORD_BYTES) {
- unsigned char* out_ptr = &m_Buffer[pos];
- cache = (((AP4_BitsWord) out_ptr[0]) << 24)
- | (((AP4_BitsWord) out_ptr[1]) << 16)
- | (((AP4_BitsWord) out_ptr[2]) << 8)
- | (((AP4_BitsWord) out_ptr[3]) );
- } else {
- unsigned char* buf_ptr = m_Buffer;
- cache = (((AP4_BitsWord) buf_ptr[ pos ]) << 24)
- | (((AP4_BitsWord) buf_ptr[AP4_BITSTREAM_POINTER_OFFSET (pos, 1)]) << 16)
- | (((AP4_BitsWord) buf_ptr[AP4_BITSTREAM_POINTER_OFFSET (pos, 2)]) << 8)
- | (((AP4_BitsWord) buf_ptr[AP4_BITSTREAM_POINTER_OFFSET (pos, 3)]) );
- }
- return cache;
- }
- /*----------------------------------------------------------------------
- | AP4_BitStream::ReadBits
- +---------------------------------------------------------------------*/
- inline AP4_UI32
- AP4_BitStream::ReadBits(unsigned int n)
- {
- AP4_BitsWord result;
- if (m_BitsCached >= n) {
- /* we have enough bits in the cache to satisfy the request */
- m_BitsCached -= n;
- result = (m_Cache >> m_BitsCached) & AP4_BIT_MASK(n);
- } else {
- /* not enough bits in the cache */
- AP4_BitsWord word;
- /* read the next word */
- {
- word = ReadCache();
- m_Out = AP4_BITSTREAM_POINTER_OFFSET(m_Out, AP4_WORD_BYTES);
- }
- /* combine the new word and the cache, and update the state */
- {
- AP4_BitsWord cache = m_Cache & AP4_BIT_MASK(m_BitsCached);
- n -= m_BitsCached;
- m_BitsCached = AP4_WORD_BITS - n;
- result = (word >> m_BitsCached) | (cache << n);
- m_Cache = word;
- }
- }
- return result;
- }
- /*----------------------------------------------------------------------
- | AP4_BitStream::ReadBit
- +---------------------------------------------------------------------*/
- inline int
- AP4_BitStream::ReadBit()
- {
- AP4_BitsWord result;
- if (m_BitsCached == 0) {
- /* the cache is empty */
- /* read the next word into the cache */
- m_Cache = ReadCache();
- m_Out = AP4_BITSTREAM_POINTER_OFFSET(m_Out, AP4_WORD_BYTES);
- m_BitsCached = AP4_WORD_BITS - 1;
- /* return the first bit */
- result = m_Cache >> (AP4_WORD_BITS - 1);
- } else {
- /* get the bit from the cache */
- result = (m_Cache >> (--m_BitsCached)) & 1;
- }
- return result;
- }
- /*----------------------------------------------------------------------
- | AP4_BitStream::PeekBits
- +---------------------------------------------------------------------*/
- inline AP4_UI32
- AP4_BitStream::PeekBits(unsigned int n)
- {
- /* we have enough bits in the cache to satisfy the request */
- if (m_BitsCached >= n) {
- return (m_Cache >> (m_BitsCached - n)) & AP4_BIT_MASK(n);
- } else {
- /* not enough bits in the cache, read the next word */
- AP4_BitsWord word = ReadCache();
- /* combine the new word and the cache, and update the state */
- AP4_BitsWord cache = m_Cache & AP4_BIT_MASK(m_BitsCached);
- n -= m_BitsCached;
- return (word >> (AP4_WORD_BITS - n)) | (cache << n);
- }
- }
- /*----------------------------------------------------------------------
- | AP4_BitStream::PeekBit
- +---------------------------------------------------------------------*/
- inline int
- AP4_BitStream::PeekBit()
- {
- /* the cache is empty */
- if (m_BitsCached == 0) {
- /* read the next word into the cache */
- AP4_BitsWord cache = ReadCache();
- /* return the first bit */
- return cache >> (AP4_WORD_BITS - 1);
- } else {
- /* get the bit from the cache */
- return (m_Cache >> (m_BitsCached-1)) & 1;
- }
- }
- /*----------------------------------------------------------------------
- | AP4_BitStream::SkipBits
- +---------------------------------------------------------------------*/
- inline void
- AP4_BitStream::SkipBits(unsigned int n)
- {
- if (n <= m_BitsCached) {
- m_BitsCached -= n;
- } else {
- n -= m_BitsCached;
- while (n >= AP4_WORD_BITS) {
- m_Out = AP4_BITSTREAM_POINTER_OFFSET(m_Out, AP4_WORD_BYTES);
- n -= AP4_WORD_BITS;
- }
- if (n) {
- m_Cache = ReadCache();
- m_BitsCached = AP4_WORD_BITS-n;
- m_Out = AP4_BITSTREAM_POINTER_OFFSET(m_Out, AP4_WORD_BYTES);
- } else {
- m_BitsCached = 0;
- m_Cache = 0;
- }
- }
- }
- /*----------------------------------------------------------------------
- | AP4_BitStream::SkipBit
- +---------------------------------------------------------------------*/
- inline void
- AP4_BitStream::SkipBit()
- {
- if (m_BitsCached == 0) {
- m_Cache = ReadCache();
- m_Out = AP4_BITSTREAM_POINTER_OFFSET(m_Out, AP4_WORD_BYTES);
- m_BitsCached = AP4_WORD_BITS - 1;
- } else {
- --m_BitsCached;
- }
- }
- /*----------------------------------------------------------------------
- | AP4_BitStream::ReadByte
- +---------------------------------------------------------------------*/
- inline AP4_UI08
- AP4_BitStream::ReadByte()
- {
- SkipBits(m_BitsCached & 7);
- return ReadBits(8);
- }
- /*----------------------------------------------------------------------
- | AP4_BitStream::PeekByte
- +---------------------------------------------------------------------*/
- inline AP4_UI08
- AP4_BitStream::PeekByte()
- {
- int extra_bits = m_BitsCached & 7;
- int data = PeekBits(extra_bits + 8);
- int byte = data & 0xFF;
- return byte;
- }
- #endif // _AP4_BIT_STREAM_H_