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

多媒体编程

开发平台:

Visual C++

  1. /*****************************************************************
  2. |
  3. |      File: Ap4AdtsParser.c
  4. |
  5. |      AP4 - ADTS Parser
  6. |
  7. |      (c) 2005 Gilles Boccon-Gibod
  8. |      Author: Gilles Boccon-Gibod (bok@bok.net)
  9. |
  10.  ****************************************************************/
  11. /*----------------------------------------------------------------------
  12. |       includes
  13. +---------------------------------------------------------------------*/
  14. #include "Ap4BitStream.h"
  15. #include "Ap4AdtsParser.h"
  16. /*----------------------------------------------------------------------
  17. |       constants
  18. +---------------------------------------------------------------------*/
  19. #define AP4_ADTS_HEADER_SIZE 7
  20. #define AP4_ADTS_SYNC_MASK     0xFFF6 /* 12 sync bits plus 2 layer bits */
  21. #define AP4_ADTS_SYNC_PATTERN  0xFFF0 /* 12 sync bits=1 layer=0         */
  22. const unsigned long  
  23. AP4_AdtsSamplingFrequencyTable[16] =
  24. {
  25.     96000,
  26.     88200,
  27.     64000,
  28.     48000,
  29.     44100,
  30.     32000,
  31.     24000,
  32.     22050,
  33.     16000,
  34.     12000,
  35.     11025,
  36.     8000,
  37.     7350,
  38.     0,      /* Reserved */
  39.     0,      /* Reserved */
  40.     0       /* Escape code */
  41. };
  42. /*----------------------------------------------------------------------+
  43. |        AP4_AdtsHeader::AP4_AdtsHeader
  44. +----------------------------------------------------------------------*/
  45. AP4_AdtsHeader::AP4_AdtsHeader(const AP4_UI08* bytes)
  46. {
  47.     // fixed part
  48.     m_Id                     = ( bytes[1] & 0x08) >> 3;
  49.     m_ProtectionAbsent       =   bytes[1] & 0x01;
  50.     m_ProfileObjectType      = ( bytes[2] & 0xC0) >> 6;
  51.     m_SamplingFrequencyIndex = ( bytes[2] & 0x3C) >> 2;
  52.     m_ChannelConfiguration   = ((bytes[2] & 0x01) << 2) | 
  53.                                ((bytes[3] & 0xC0) >> 6);
  54.     // variable part
  55.     m_FrameLength = ((unsigned int)(bytes[3] & 0x03) << 11) |
  56.                     ((unsigned int)(bytes[4]       ) <<  3) |
  57.                     ((unsigned int)(bytes[5] & 0xE0) >>  5);
  58.     m_RawDataBlocks =               bytes[6] & 0x03;
  59. }
  60. /*----------------------------------------------------------------------+
  61. |        AP4_AdtsHeader::MatchFixed
  62. |
  63. |    Check that two fixed headers are the same
  64. |
  65. +----------------------------------------------------------------------*/
  66. bool
  67. AP4_AdtsHeader::MatchFixed(unsigned char* a, unsigned char* b)
  68. {
  69.     if (a[0]         ==  b[0] &&
  70.         a[1]         ==  b[1] &&
  71.         a[2]         ==  b[2] &&
  72.        (a[3] & 0xF0) == (b[3] & 0xF0)) {
  73.         return true;
  74.     } else {
  75.         return false;
  76.     }
  77. }
  78. /*----------------------------------------------------------------------+
  79. |        AP4_AdtsHeader::Check
  80. +----------------------------------------------------------------------*/
  81. AP4_Result
  82. AP4_AdtsHeader::Check()
  83. {
  84.     // check that the sampling frequency index is valid
  85.     if (m_SamplingFrequencyIndex >= 0xD) {
  86.         return AP4_FAILURE;
  87.     }
  88.     /* MPEG2 does not use all profiles */
  89.     if (m_Id == 1 && m_ProfileObjectType == 3) {
  90.         return AP4_FAILURE;
  91.     }
  92.     return AP4_SUCCESS;
  93. }
  94. /*----------------------------------------------------------------------+
  95. |        AP4_AdtsParser::AP4_AdtsParser
  96. +----------------------------------------------------------------------*/
  97. AP4_AdtsParser::AP4_AdtsParser()
  98. {
  99. }
  100. /*----------------------------------------------------------------------+
  101. |        AP4_AdtsParser::~AP4_AdtsParser
  102. +----------------------------------------------------------------------*/
  103. AP4_AdtsParser::~AP4_AdtsParser()
  104. {
  105. }
  106. /*----------------------------------------------------------------------+
  107. |        AP4_AdtsParser::Reset
  108. +----------------------------------------------------------------------*/
  109. AP4_Result
  110. AP4_AdtsParser::Reset()
  111. {
  112.     m_FrameCount = 0;
  113.     return AP4_SUCCESS;
  114. }
  115. /*----------------------------------------------------------------------+
  116. |        AP4_AdtsParser::Feed
  117. +----------------------------------------------------------------------*/
  118. AP4_Result
  119. AP4_AdtsParser::Feed(const AP4_UI08* buffer, 
  120.                      AP4_Size*       buffer_size,
  121.                      AP4_Flags       flags)
  122. {
  123.     AP4_Size free_space;
  124.     /* update flags */
  125.     m_Bits.m_Flags = flags;
  126.     /* possible shortcut */
  127.     if (buffer == NULL ||
  128.         buffer_size == NULL || 
  129.         *buffer_size == 0) {
  130.         return AP4_SUCCESS;
  131.     }
  132.     /* see how much data we can write */
  133.     free_space = m_Bits.GetBytesFree();
  134.     if (*buffer_size > free_space) *buffer_size = free_space;
  135.     /* write the data */
  136.     return m_Bits.WriteBytes(buffer, *buffer_size); 
  137. }
  138. /*----------------------------------------------------------------------+
  139. |        AP4_AdtsParser::FindHeader
  140. +----------------------------------------------------------------------*/
  141. AP4_Result
  142. AP4_AdtsParser::FindHeader(AP4_UI08* header)
  143. {
  144.    int          available = m_Bits.GetBytesAvailable();
  145.    unsigned int sync = 0;
  146.    long         nbr_skipped_bytes = 0;
  147.    /* look for the sync pattern */
  148.    while (available-- >= AP4_ADTS_HEADER_SIZE) {
  149.       sync = (m_Bits.ReadByte() << 8) | m_Bits.PeekByte();
  150.       if ((sync & AP4_ADTS_SYNC_MASK) == AP4_ADTS_SYNC_PATTERN) {
  151.          /* found a sync pattern, read the rest of the header */
  152.          header[0] = (sync >> 8) & 0xFF;
  153.          m_Bits.ReadBytes(&header[1], AP4_ADTS_HEADER_SIZE-1);
  154.          return AP4_SUCCESS;
  155.       } else {
  156.          ++ nbr_skipped_bytes;
  157.       }
  158.    }
  159.    return AP4_ERROR_NOT_ENOUGH_DATA;
  160. }
  161. /*----------------------------------------------------------------------+
  162. |        AP4_AdtsParser::FindFrame
  163. +----------------------------------------------------------------------*/
  164. AP4_Result
  165. AP4_AdtsParser::FindFrame(AP4_AacFrame& frame)
  166. {
  167.     unsigned int   available;
  168.     unsigned char  raw_header[AP4_ADTS_HEADER_SIZE];
  169.     AP4_Result     result;
  170.     /* align to the start of the next byte */
  171.     m_Bits.ByteAlign();
  172.     
  173.     /* find a frame header */
  174.     result = FindHeader(raw_header);
  175.     if (AP4_FAILED(result)) return result;
  176.     /* parse the header */
  177.     AP4_AdtsHeader adts_header(raw_header);
  178.     /* check the header */
  179.     result = adts_header.Check();
  180.     if (AP4_FAILED(result)) goto fail;
  181.     
  182.     /* check that we have enough data to peek at the next header */
  183.     available = AP4_ADTS_HEADER_SIZE + m_Bits.GetBytesAvailable();
  184.     if (m_Bits.m_Flags & AP4_BITSTREAM_FLAG_EOS) {
  185.         /* we're at the end of the stream, we only need the entire frame */
  186.         if (available < adts_header.m_FrameLength) {
  187.             return AP4_ERROR_NOT_ENOUGH_DATA;
  188.         } 
  189.     } else {
  190.         /* peek at the header of the next frame */
  191.         unsigned char peek_raw_header[AP4_ADTS_HEADER_SIZE];
  192.         if (available < adts_header.m_FrameLength+AP4_ADTS_HEADER_SIZE) {
  193.             return AP4_ERROR_NOT_ENOUGH_DATA;
  194.         } 
  195.         m_Bits.SkipBytes(adts_header.m_FrameLength-AP4_ADTS_HEADER_SIZE);
  196.         m_Bits.PeekBytes(peek_raw_header, AP4_ADTS_HEADER_SIZE);
  197.         m_Bits.SkipBytes(-((int)adts_header.m_FrameLength-AP4_ADTS_HEADER_SIZE));
  198.         /* check the header */
  199.         AP4_AdtsHeader peek_adts_header(peek_raw_header);
  200.         result = peek_adts_header.Check();
  201.         if (AP4_FAILED(result)) goto fail;
  202.         /* check that the fixed part of this header is the same as the */
  203.         /* fixed part of the previous header                           */
  204.         if (!AP4_AdtsHeader::MatchFixed(peek_raw_header, raw_header)) {
  205.             goto fail;
  206.         }
  207.     }
  208.     /* fill in the frame info */
  209.     frame.m_Info.m_Standard = (adts_header.m_Id == 1 ? 
  210.                             AP4_AAC_STANDARD_MPEG2 :
  211.                             AP4_AAC_STANDARD_MPEG4);
  212.     switch (adts_header.m_ProfileObjectType) {
  213.         case 0:
  214.             frame.m_Info.m_Profile = AP4_AAC_PROFILE_MAIN;
  215.             break;
  216.         case 1:
  217.             frame.m_Info.m_Profile = AP4_AAC_PROFILE_LC;
  218.             break;
  219.         case 2: 
  220.             frame.m_Info.m_Profile = AP4_AAC_PROFILE_SSR;
  221.             break;
  222.         case 3:
  223.             frame.m_Info.m_Profile = AP4_AAC_PROFILE_LTP;
  224.     }
  225.     frame.m_Info.m_FrameLength = adts_header.m_FrameLength-AP4_ADTS_HEADER_SIZE;
  226.     frame.m_Info.m_ChannelConfiguration = adts_header.m_ChannelConfiguration;
  227.     frame.m_Info.m_SamplingFrequencyIndex = adts_header.m_SamplingFrequencyIndex;
  228.     frame.m_Info.m_SamplingFrequency = AP4_AdtsSamplingFrequencyTable[adts_header.m_SamplingFrequencyIndex];
  229.     /* skip crc if present */
  230.     if (adts_header.m_ProtectionAbsent == 0) {
  231.         m_Bits.SkipBits(16);
  232.     } 
  233.     /* set the frame source */
  234.     frame.m_Source = &m_Bits;
  235.     return AP4_SUCCESS;
  236. fail:
  237.     /* skip the header and return (only skip the first byte in  */
  238.     /* case this was a false header that hides one just after)  */
  239.     //m_Bits.SkipBytes(-(AP4_ADTS_HEADER_SIZE-1));
  240.     return AP4_ERROR_CORRUPTED_BITSTREAM;
  241. }
  242. /*----------------------------------------------------------------------+
  243. |        AP4_AdtsParser::GetBytesFree
  244. +----------------------------------------------------------------------*/
  245. AP4_Size
  246. AP4_AdtsParser::GetBytesFree()
  247. {
  248. return (m_Bits.GetBytesFree());
  249. }
  250. /*----------------------------------------------------------------------+
  251. |        AP4_AdtsParser::GetBytesAvailable
  252. +----------------------------------------------------------------------*/
  253. AP4_Size
  254. AP4_AdtsParser::GetBytesAvailable()
  255. {
  256. return (m_Bits.GetBytesAvailable());
  257. }