mpa_frame_header.cpp
上传用户:dangjiwu
上传日期:2013-07-19
资源大小:42019k
文件大小:6k
源码类别:

Symbian

开发平台:

Visual C++

  1. /*============================================================================*
  2.  *
  3.  * (c) 1995-2002 RealNetworks, Inc. Patents pending. All rights reserved.
  4.  *
  5.  *============================================================================*/
  6.  
  7. #include "mpa_frame_header.h"
  8. #include "hxassert.h"
  9. //#include "debug.h"
  10. #define MPA_VERSION_MASK 0x18
  11. #define MPA_VERSION_SHIFT 3
  12. #define MPA_LAYER_MASK 0x06
  13. #define MPA_LAYER_SHIFT 1
  14. #define MPA_CRC_MASK 0x01
  15. #define MPA_BITRATE_MASK 0xf0
  16. #define MPA_BITRATE_SHIFT 4
  17. #define MPA_SMPLRATE_MASK 0x0c
  18. #define MPA_SMPLRATE_SHIFT 2
  19. #define MPA_PAD_MASK 0x02
  20. #define MPA_PAD_SHIFT 1
  21. #define MPA_CHNLMODE_MASK 0xc0
  22. #define MPA_CHNLMODE_SHIFT 6
  23. #define MPA_CHNLMODEEX_MASK 0x30
  24. #define MPA_CHNLMODEEX_SHIFT 4
  25. static const short k_bitRateTable[][16] = 
  26. {
  27.     // MPEG 1 Layer 1
  28.     { -1, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, -1},
  29.     // MPEG 1 Layer 2
  30.     { -1, 32, 48, 56, 64,  80,  96,  112, 128, 160, 192, 224, 256, 320, 384, -1},
  31.     // MPEG 1 Layer 3
  32.     { -1, 32, 40, 48, 56,  64,  80,  96,  112, 128, 160, 192, 224, 256, 320, -1},
  33.     // MPEG 2 and 2.5 Layer 1
  34.     { -1, 32, 48, 56, 64,  80,  96,  112, 128, 144, 160, 176, 192, 224, 256, -1},
  35.     // MPEG 2 and 2.5 Layer 2 & 3
  36.     { -1, 8,  16, 24, 32,  40,  48,  56,  64,  80,  96,  112, 128, 144, 160, -1}
  37. };
  38. //
  39. // for finding vertical row from k_bitRateTable to use
  40. // for determining bitrate for given version/layer combo
  41. //
  42. static const signed char k_brIndexTable[4][4] = 
  43. {
  44.     // Reserved, Layer III, Layer II, Layer I
  45.     {  -1      , 4        , 4       , 3 },       // MPEG2.5
  46.     {  -1      , -1       , -1      , -1},       // Reserved
  47.     {  -1      , 4        , 4       , 3 },       // MPEG2
  48.     {  -1      , 2        , 1       , 0 }        // MPEG1
  49. };      
  50.   
  51. //
  52. // sample rates for MPEG1; values for MPEG2 and 2.5 are derived from 
  53. // these using shift table (i.e., we divide by 2 once for MPEG2 and twice
  54. // for MPEG2.5)
  55. //
  56. static const int k_smplRateTable[4] = 
  57.     44100, 48000, 32000, -1 
  58. };
  59. static const char k_srShiftTable[4] = 
  60. {
  61.  // MPEG2.5 , Reserved, MPEG2, MPEG1
  62.     2       , 0       , 1    , 0
  63. };       
  64. bool MPAFrameHeader::IsSync(const unsigned char* p)
  65. {
  66.     // frame sync = 11 bits all set to 1
  67.     return (0xff == *p && 0xe0 == (*(p+1) & 0xe0) );
  68. }
  69. template<typename T>
  70. inline bool IndexInRange(int i, T& array)
  71. {         
  72.     return (i >= 0 && i < sizeof(array)/sizeof(array[0]));
  73. }
  74. template<typename T>
  75. inline bool IndexInRange( int x, int y, T& array ){
  76.     return (IndexInRange( x, array) && IndexInRange(y,array[0]));
  77. }
  78. bool MPAFrameHeader::Unpack(const unsigned char* p)
  79. {
  80.     if (!IsSync(p))
  81.     {
  82. return false;
  83.     }
  84.     // version and layer
  85.     m_version = (p[1] & MPA_VERSION_MASK) >> MPA_VERSION_SHIFT;
  86.     m_layer   = (p[1] & MPA_LAYER_MASK)   >> MPA_LAYER_SHIFT;
  87.     if( m_version == MPA_VERSION_RESERVED || m_layer == MPA_LAYER_RESERVED)
  88.     {
  89.         return false;
  90.     }
  91.     // does 16 bit CRC follow this header
  92.     m_hasCRC     = !(p[1] & MPA_CRC_MASK);
  93.     // find bitrate for this frame
  94.     HX_ASSERT( IndexInRange(m_version, m_layer, k_brIndexTable) ); // version and layer are 2 bits (max 3)
  95.     int brVertIndex = k_brIndexTable[m_version][m_layer];
  96.     int brHorIndex = (p[2] & MPA_BITRATE_MASK) >> MPA_BITRATE_SHIFT;
  97.     if(-1 == brVertIndex || -1 == brHorIndex)
  98.     {
  99.         return false;
  100.     }
  101.     HX_ASSERT(IndexInRange( brVertIndex, brHorIndex, k_bitRateTable ) );
  102.     
  103.     // bitrate
  104.     m_bitRate = k_bitRateTable[brVertIndex][brHorIndex];
  105.     if(-1 == m_bitRate)
  106.     {
  107.         return false;
  108.     }
  109.     m_bitRate *= 1000;
  110.     
  111.     // find sample rate for this frame
  112.     TInt sampleRateIndex = (p[2] & MPA_SMPLRATE_MASK) >> MPA_SMPLRATE_SHIFT;
  113.     HX_ASSERT(IndexInRange( sampleRateIndex, k_smplRateTable )); // sampleRateIndex is 2 bits (max 3)
  114.     
  115.     // sample rate
  116.     m_sampleRate = k_smplRateTable[sampleRateIndex];
  117.     if( -1 == m_sampleRate)
  118.     {
  119.         return false;
  120.     }
  121.     
  122.     HX_ASSERT(IndexInRange(m_version, k_srShiftTable)); // version is 2 bits (max 3)
  123.   
  124.     m_sampleRate >>= k_srShiftTable[m_version];
  125.     
  126.     // is this frame padded
  127.     m_pad = (p[2] & MPA_PAD_MASK) >> MPA_PAD_SHIFT;
  128.     // stereo, joint stereo, dual channel, single channel
  129.     m_chnlMode   = (p[3] & MPA_CHNLMODE_MASK) >> MPA_CHNLMODE_SHIFT;
  130.     // joint stereo extension
  131.     m_chnlModeEx = (p[3] & MPA_CHNLMODEEX_MASK) >> MPA_CHNLMODEEX_SHIFT;    
  132.     
  133.     // now we can determine frame size
  134.     ComputeFrameSize();
  135.     m_channels = (m_chnlMode == 3) ? 1 : 2;
  136.     m_samplesPerFrame = MPA_SAMPLES_PER_FRAME;
  137.     if(m_version != MPA_VERSION1)
  138.     {
  139.         m_samplesPerFrame /= 2;
  140.     }
  141.     m_samplesPerFrame *= m_channels;
  142.     
  143.     return true;
  144. #if(0)
  145. // output frame stats in format similar to mpg123
  146. void MPAFrameHeader::DumpFrameInfo() const
  147. {
  148.     //
  149.     char* version[] = {"2.5", "undefined", "2", "1"};
  150.     char* layer[] = {"undefined", "III", "II", "I"};
  151.     char* channel_mode[] = {"stereo", "joint-stereo", "dual-channel", "single-channel"};
  152.     char* channel_ex[] = {"", "intensity", "ms", "intensity ms"};
  153.     DPRINTF(D_INFO, (" MPEG %s layer %s, %d kbits/s %d Hz %s %s %d bytesn",
  154.      version[m_version], layer[m_layer],
  155.      m_bitRate/1000, m_sampleRate, 
  156.      channel_mode[m_chnlMode], 
  157.      channel_ex[m_chnlModeEx],
  158.      m_frameSize));
  159. }
  160. #endif
  161. void MPAFrameHeader::ComputeFrameSize()
  162. {
  163.     if (m_layer == MPA_LAYER1)
  164.     {
  165. m_frameSize = (12 * m_bitRate / m_sampleRate + m_pad) * 4;
  166.     }
  167.     else
  168.     {
  169. int mult = 144;
  170. if (m_version == MPA_VERSION2 || m_version == MPA_VERSION25)
  171.         {
  172.     mult /= 2;
  173.         }
  174. m_frameSize = (mult * m_bitRate) / m_sampleRate + m_pad;
  175.     }
  176. }