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

多媒体编程

开发平台:

Visual C++

  1. /*****************************************************************
  2. |
  3. |      File: Ap4BitStream.c
  4. |
  5. |      AP4 - Bit Streams
  6. |
  7. |      (c) 2004 Gilles Boccon-Gibod
  8. |      Author: Gilles Boccon-Gibod (bok@bok.net)
  9. |
  10.  ****************************************************************/
  11. /*----------------------------------------------------------------------
  12. |       For efficiency reasons, this bitstream library only handles
  13. |       data buffers that are a power of 2 in size
  14. +---------------------------------------------------------------------*/
  15. /*----------------------------------------------------------------------
  16. |       includes
  17. +---------------------------------------------------------------------*/
  18. #include "Ap4BitStream.h"
  19. /*----------------------------------------------------------------------
  20. |       AP4_BitStream::AP4_BitStream
  21. +---------------------------------------------------------------------*/
  22. AP4_BitStream::AP4_BitStream()
  23. {
  24.     m_Buffer = new AP4_UI08[AP4_BITSTREAM_BUFFER_SIZE];
  25.     Reset();
  26. }
  27. /*----------------------------------------------------------------------
  28. |       AP4_BitStream::~AP4_BitStream
  29. +---------------------------------------------------------------------*/
  30. AP4_BitStream::~AP4_BitStream()
  31. {
  32.     delete[] m_Buffer;
  33. }
  34. /*----------------------------------------------------------------------
  35. |       AP4_BitStream::Reset
  36. +---------------------------------------------------------------------*/
  37. AP4_Result
  38. AP4_BitStream::Reset()
  39. {
  40.     m_In         = 0;
  41.     m_Out        = 0;
  42.     m_BitsCached = 0;
  43.     m_Cache      = 0;
  44.     m_Flags      = 0;
  45.     return AP4_SUCCESS;
  46. }
  47. /*----------------------------------------------------------------------
  48. |       AP4_BitStream::ByteAlign
  49. +---------------------------------------------------------------------*/
  50. AP4_Result   
  51. AP4_BitStream::ByteAlign()
  52. {
  53.     unsigned int to_flush = m_BitsCached & 7;
  54.     if (to_flush > 0) SkipBits(to_flush);
  55.     return AP4_SUCCESS;
  56. }
  57. /*----------------------------------------------------------------------
  58. |       AP4_BitStream::GetContiguousBytesFree
  59. +---------------------------------------------------------------------*/
  60. AP4_Size
  61. AP4_BitStream::GetContiguousBytesFree()
  62. {
  63.     return 
  64.         (m_In < m_Out) ?
  65.         (m_Out - m_In - 1) :
  66.         (m_Out == 0 ? (AP4_BITSTREAM_BUFFER_SIZE - m_In - 1) :
  67.                       (AP4_BITSTREAM_BUFFER_SIZE - m_In));
  68. }
  69. /*----------------------------------------------------------------------
  70. |       AP4_BitStream_GetBytesFree
  71. +---------------------------------------------------------------------*/
  72. AP4_Size
  73. AP4_BitStream::GetBytesFree()
  74. {
  75.     return  
  76.         (m_In < m_Out) ? 
  77.         (m_Out - m_In - 1) : 
  78.         (AP4_BITSTREAM_BUFFER_SIZE  + (m_Out - m_In) - 1);
  79. }
  80. /*----------------------------------------------------------------------+
  81. |        AP4_BitStream::WriteBytes
  82. +----------------------------------------------------------------------*/
  83. AP4_Result
  84. AP4_BitStream::WriteBytes(const AP4_UI08* bytes, 
  85.                           AP4_Size        byte_count)
  86. {
  87.     /* check parameters */
  88.     if (byte_count == 0) return AP4_SUCCESS;
  89.     if (bytes == NULL) return AP4_ERROR_INVALID_PARAMETERS;
  90.     /* check that we have enough space */
  91.     if (GetBytesFree() < byte_count) {
  92.         return AP4_FAILURE;
  93.     }
  94.     /* write the bytes */
  95.     if (m_In < m_Out) {
  96.         memcpy(m_Buffer+m_In, bytes, byte_count);
  97.         AP4_BITSTREAM_POINTER_ADD(m_In, byte_count);
  98.     } else {
  99.         unsigned int chunk = AP4_BITSTREAM_BUFFER_SIZE - m_In;
  100.         if (chunk > byte_count) chunk = byte_count;
  101.         memcpy(m_Buffer+m_In, bytes, chunk);
  102.         AP4_BITSTREAM_POINTER_ADD(m_In, chunk);
  103.         if (chunk != byte_count) {
  104.             memcpy(m_Buffer+m_In, 
  105.                    bytes+chunk, byte_count-chunk);
  106.             AP4_BITSTREAM_POINTER_ADD(m_In, byte_count-chunk);
  107.         }
  108.     }
  109.     return AP4_SUCCESS;
  110. }
  111. /*----------------------------------------------------------------------
  112. |       AP4_BitStream_GetContiguousBytesAvailable
  113. +---------------------------------------------------------------------*/
  114. AP4_Size
  115. AP4_BitStream::GetContiguousBytesAvailable()
  116. {
  117.     return 
  118.         (m_Out <= m_In) ? 
  119.         (m_In - m_Out) :
  120.         (AP4_BITSTREAM_BUFFER_SIZE - m_Out);
  121. }
  122. /*----------------------------------------------------------------------
  123. |       AP4_BitStream::GetBytesAvailable
  124. +---------------------------------------------------------------------*/
  125. AP4_Size
  126. AP4_BitStream::GetBytesAvailable()
  127. {
  128.     return 
  129.         (m_Out <= m_In) ? 
  130.         (m_In - m_Out) :
  131.         (m_In + (AP4_BITSTREAM_BUFFER_SIZE - m_Out));
  132. }
  133. /*----------------------------------------------------------------------+
  134. |        AP4_BitStream::ReadBytes
  135. +----------------------------------------------------------------------*/
  136. AP4_Result
  137. AP4_BitStream::ReadBytes(AP4_UI08* bytes, 
  138.                          AP4_Size  byte_count)
  139. {
  140.    if (byte_count == 0 || bytes == NULL) {
  141.       return AP4_ERROR_INVALID_PARAMETERS;
  142.    }
  143.    /* Gets bytes from the cache */
  144.    ByteAlign();
  145.    while (m_BitsCached > 0 && byte_count > 0) {
  146.       *bytes = ReadBits(8);
  147.       ++ bytes;
  148.       -- byte_count;
  149.    }
  150.    /* Get other bytes */
  151.    if (byte_count > 0) {
  152.       if (m_Out < m_In) {
  153.          memcpy(bytes, m_Buffer + m_Out, byte_count);
  154.          AP4_BITSTREAM_POINTER_ADD(m_Out, byte_count);
  155.       } else {
  156.          unsigned int chunk = AP4_BITSTREAM_BUFFER_SIZE - m_Out;
  157.          if (chunk >= byte_count) chunk = byte_count;
  158.          memcpy(bytes, m_Buffer+m_Out, chunk);
  159.          AP4_BITSTREAM_POINTER_ADD(m_Out, chunk);
  160.          if (chunk != byte_count) {
  161.             memcpy(bytes+chunk, 
  162.                    m_Buffer+m_Out, 
  163.                    byte_count-chunk);
  164.             AP4_BITSTREAM_POINTER_ADD(m_Out, byte_count-chunk);
  165.          }
  166.       }
  167.    }
  168.    return AP4_SUCCESS;
  169. }
  170. /*----------------------------------------------------------------------+
  171. |        AP4_BitStream::PeekBytes
  172. +----------------------------------------------------------------------*/
  173. AP4_Result
  174. AP4_BitStream::PeekBytes(AP4_UI08* bytes, 
  175.                          AP4_Size  byte_count)
  176. {
  177.    int bits_cached_byte;
  178.    if (byte_count == 0 || bytes == NULL) {
  179.       return AP4_ERROR_INVALID_PARAMETERS;
  180.    }
  181.    /* Gets bytes from the cache */
  182.    bits_cached_byte = m_BitsCached & ~7;
  183.    while (bits_cached_byte > 0 && byte_count > 0) {
  184.       *bytes = (m_Cache >> bits_cached_byte) & 0xFF;
  185.       ++ bytes;
  186.       -- byte_count;
  187.       bits_cached_byte -= 8;
  188.    }
  189.    /* Get other bytes */
  190.    if (byte_count > 0) {
  191.       if (m_In > m_Out) {
  192.          memcpy(bytes, m_Buffer + m_Out, byte_count);
  193.       } else {
  194.          unsigned int out = m_Out;
  195.          unsigned int chunk = AP4_BITSTREAM_BUFFER_SIZE - out;
  196.          if (chunk >= byte_count) {
  197.             chunk = byte_count;
  198.          }
  199.          memcpy(bytes, m_Buffer+out, chunk);
  200.          AP4_BITSTREAM_POINTER_ADD(out, chunk);
  201.          if (chunk != byte_count) {
  202.             memcpy(bytes+chunk, 
  203.                    m_Buffer+out, 
  204.                    byte_count-chunk);
  205.          }
  206.       }
  207.    }
  208.    return AP4_SUCCESS;
  209. }
  210. /*----------------------------------------------------------------------+
  211. |        AP4_BitStream::SkipBytes
  212. +----------------------------------------------------------------------*/
  213. AP4_Result
  214. AP4_BitStream::SkipBytes(AP4_Size byte_count)
  215. {
  216.     AP4_BITSTREAM_POINTER_ADD(m_Out, byte_count);
  217.     return AP4_SUCCESS;
  218. }