mpa_frame_header.cpp
上传用户:dangjiwu
上传日期:2013-07-19
资源大小:42019k
文件大小:6k
- /*============================================================================*
- *
- * (c) 1995-2002 RealNetworks, Inc. Patents pending. All rights reserved.
- *
- *============================================================================*/
-
- #include "mpa_frame_header.h"
- #include "hxassert.h"
- //#include "debug.h"
- #define MPA_VERSION_MASK 0x18
- #define MPA_VERSION_SHIFT 3
- #define MPA_LAYER_MASK 0x06
- #define MPA_LAYER_SHIFT 1
- #define MPA_CRC_MASK 0x01
- #define MPA_BITRATE_MASK 0xf0
- #define MPA_BITRATE_SHIFT 4
- #define MPA_SMPLRATE_MASK 0x0c
- #define MPA_SMPLRATE_SHIFT 2
- #define MPA_PAD_MASK 0x02
- #define MPA_PAD_SHIFT 1
- #define MPA_CHNLMODE_MASK 0xc0
- #define MPA_CHNLMODE_SHIFT 6
- #define MPA_CHNLMODEEX_MASK 0x30
- #define MPA_CHNLMODEEX_SHIFT 4
- static const short k_bitRateTable[][16] =
- {
- // MPEG 1 Layer 1
- { -1, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, -1},
- // MPEG 1 Layer 2
- { -1, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, -1},
- // MPEG 1 Layer 3
- { -1, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, -1},
- // MPEG 2 and 2.5 Layer 1
- { -1, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, -1},
- // MPEG 2 and 2.5 Layer 2 & 3
- { -1, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, -1}
- };
- //
- // for finding vertical row from k_bitRateTable to use
- // for determining bitrate for given version/layer combo
- //
- static const signed char k_brIndexTable[4][4] =
- {
- // Reserved, Layer III, Layer II, Layer I
- { -1 , 4 , 4 , 3 }, // MPEG2.5
- { -1 , -1 , -1 , -1}, // Reserved
- { -1 , 4 , 4 , 3 }, // MPEG2
- { -1 , 2 , 1 , 0 } // MPEG1
- };
-
- //
- // sample rates for MPEG1; values for MPEG2 and 2.5 are derived from
- // these using shift table (i.e., we divide by 2 once for MPEG2 and twice
- // for MPEG2.5)
- //
- static const int k_smplRateTable[4] =
- {
- 44100, 48000, 32000, -1
- };
- static const char k_srShiftTable[4] =
- {
- // MPEG2.5 , Reserved, MPEG2, MPEG1
- 2 , 0 , 1 , 0
- };
- bool MPAFrameHeader::IsSync(const unsigned char* p)
- {
- // frame sync = 11 bits all set to 1
- return (0xff == *p && 0xe0 == (*(p+1) & 0xe0) );
- }
- template<typename T>
- inline bool IndexInRange(int i, T& array)
- {
- return (i >= 0 && i < sizeof(array)/sizeof(array[0]));
- }
- template<typename T>
- inline bool IndexInRange( int x, int y, T& array ){
- return (IndexInRange( x, array) && IndexInRange(y,array[0]));
- }
- bool MPAFrameHeader::Unpack(const unsigned char* p)
- {
- if (!IsSync(p))
- {
- return false;
- }
- // version and layer
- m_version = (p[1] & MPA_VERSION_MASK) >> MPA_VERSION_SHIFT;
- m_layer = (p[1] & MPA_LAYER_MASK) >> MPA_LAYER_SHIFT;
- if( m_version == MPA_VERSION_RESERVED || m_layer == MPA_LAYER_RESERVED)
- {
- return false;
- }
- // does 16 bit CRC follow this header
- m_hasCRC = !(p[1] & MPA_CRC_MASK);
- // find bitrate for this frame
- HX_ASSERT( IndexInRange(m_version, m_layer, k_brIndexTable) ); // version and layer are 2 bits (max 3)
- int brVertIndex = k_brIndexTable[m_version][m_layer];
- int brHorIndex = (p[2] & MPA_BITRATE_MASK) >> MPA_BITRATE_SHIFT;
- if(-1 == brVertIndex || -1 == brHorIndex)
- {
- return false;
- }
- HX_ASSERT(IndexInRange( brVertIndex, brHorIndex, k_bitRateTable ) );
-
- // bitrate
- m_bitRate = k_bitRateTable[brVertIndex][brHorIndex];
- if(-1 == m_bitRate)
- {
- return false;
- }
- m_bitRate *= 1000;
-
- // find sample rate for this frame
- TInt sampleRateIndex = (p[2] & MPA_SMPLRATE_MASK) >> MPA_SMPLRATE_SHIFT;
- HX_ASSERT(IndexInRange( sampleRateIndex, k_smplRateTable )); // sampleRateIndex is 2 bits (max 3)
-
- // sample rate
- m_sampleRate = k_smplRateTable[sampleRateIndex];
- if( -1 == m_sampleRate)
- {
- return false;
- }
-
- HX_ASSERT(IndexInRange(m_version, k_srShiftTable)); // version is 2 bits (max 3)
-
- m_sampleRate >>= k_srShiftTable[m_version];
-
- // is this frame padded
- m_pad = (p[2] & MPA_PAD_MASK) >> MPA_PAD_SHIFT;
- // stereo, joint stereo, dual channel, single channel
- m_chnlMode = (p[3] & MPA_CHNLMODE_MASK) >> MPA_CHNLMODE_SHIFT;
- // joint stereo extension
- m_chnlModeEx = (p[3] & MPA_CHNLMODEEX_MASK) >> MPA_CHNLMODEEX_SHIFT;
-
- // now we can determine frame size
- ComputeFrameSize();
- m_channels = (m_chnlMode == 3) ? 1 : 2;
- m_samplesPerFrame = MPA_SAMPLES_PER_FRAME;
- if(m_version != MPA_VERSION1)
- {
- m_samplesPerFrame /= 2;
- }
- m_samplesPerFrame *= m_channels;
-
- return true;
- }
- #if(0)
- // output frame stats in format similar to mpg123
- void MPAFrameHeader::DumpFrameInfo() const
- {
- //
- char* version[] = {"2.5", "undefined", "2", "1"};
- char* layer[] = {"undefined", "III", "II", "I"};
- char* channel_mode[] = {"stereo", "joint-stereo", "dual-channel", "single-channel"};
- char* channel_ex[] = {"", "intensity", "ms", "intensity ms"};
- DPRINTF(D_INFO, (" MPEG %s layer %s, %d kbits/s %d Hz %s %s %d bytesn",
- version[m_version], layer[m_layer],
- m_bitRate/1000, m_sampleRate,
- channel_mode[m_chnlMode],
- channel_ex[m_chnlModeEx],
- m_frameSize));
- }
- #endif
- void MPAFrameHeader::ComputeFrameSize()
- {
- if (m_layer == MPA_LAYER1)
- {
- m_frameSize = (12 * m_bitRate / m_sampleRate + m_pad) * 4;
- }
- else
- {
- int mult = 144;
- if (m_version == MPA_VERSION2 || m_version == MPA_VERSION25)
- {
- mult /= 2;
- }
- m_frameSize = (mult * m_bitRate) / m_sampleRate + m_pad;
- }
- }