7 assert(p_base+p_bits<=32);
16 header_parser(
const t_uint8 p_header[4]) : m_bitptr(0)
18 memcpy(m_header,p_header,4);
20 unsigned read(
unsigned p_bits)
34 static const uint16 bitrate_table_l1v1[16] = { 0, 32, 64, 96,128,160,192,224,256,288,320,352,384,416,448, 0};
35 static const uint16 bitrate_table_l2v1[16] = { 0, 32, 48, 56, 64, 80, 96,112,128,160,192,224,256,320,384, 0};
36 static const uint16 bitrate_table_l3v1[16] = { 0, 32, 40, 48, 56, 64, 80, 96,112,128,160,192,224,256,320, 0};
37 static const uint16 bitrate_table_l1v2[16] = { 0, 32, 48, 56, 64, 80, 96,112,128,144,160,176,192,224,256, 0};
38 static const uint16 bitrate_table_l23v2[16] = { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96,112,128,144,160, 0};
50 enum {MPEG_LAYER_1 = 3, MPEG_LAYER_2 = 2, MPEG_LAYER_3 = 1};
51 enum {_MPEG_1 = 3, _MPEG_2 = 2, _MPEG_25 = 0};
53 header_parser parser(p_header);
54 if (parser.read(11) != 0x7FF)
return false;
55 unsigned mpeg_version = parser.read(2);
56 unsigned layer = parser.read(2);
57 unsigned protection = parser.read(1);
58 unsigned bitrate_index = parser.read(4);
59 unsigned sample_rate_index = parser.read(2);
60 if (sample_rate_index == 3)
return false;
61 unsigned paddingbit = parser.read(1);
64 unsigned channel_mode = parser.read(2);
70 unsigned bitrate = 0,sample_rate = 0;
77 paddingdelta = paddingbit ? 1 : 0;
97 paddingdelta = paddingbit ? 1 : 0;
114 paddingdelta = paddingbit ? 4 : 0;
131 if (bitrate == 0)
return false;
134 if (sample_rate == 0)
return false;
167 p_info.
m_bytes = ( bitrate * (1000/8) * p_info.
m_duration ) / sample_rate + paddingdelta;
171 p_info.
m_crc = protection == 0;
179 if (!decode(fr))
return 0;
194 if (frameSize < info.
m_bytes)
return false;
195 if (!info.
m_crc)
return true;
201 enum { CRC16_POLYNOMIAL = 0x8005 };
204 for (i = 0; i < 8; i++) {
207 if (((crc ^ value) & 0x10000)) crc ^= CRC16_POLYNOMIAL;
217 frameData[4] = (
t_uint8)(crc >> 8);
218 frameData[5] = (
t_uint8)(crc & 0xFF);
225 for (
t_size i = 6; i < sideInfoLen; i++) {
243 sideInfoLen = (info.
m_channels == 1) ? 4 + 17 : 4 + 32;
245 sideInfoLen = (info.
m_channels == 1) ? 4 + 9 : 4 + 17;
250 PFC_ASSERT( sideInfoLen <= frameSize );
257 if (frameSize < 4)
return false;
void read(const service_ptr_t< file > &p_file, abort_callback &p_abort, pfc::string_base &p_out, bool &is_utf8)
bool ValidateFrameCRC(const t_uint8 *frameData, t_size frameSize)
t_uint16 ExtractFrameCRC(const t_uint8 *frameData, t_size frameSize, TMPEGFrameInfo const &frameInfo)
Assumes valid frame with CRC (frameInfo.m_crc set, frameInfo.m_bytes <= frameSize).
static const uint16 sample_rate_table[]
static t_uint16 grabFrameCRC(const t_uint8 *frameData, t_size sideInfoLen)
static const uint16 bitrate_table_l2v1[16]
void info(const char *p_message)
static t_size extract_bits(const t_uint8 *p_buffer, t_size p_base, t_size p_count)
static unsigned extract_header_bits(const t_uint8 p_header[4], unsigned p_base, unsigned p_bits)
unsigned QueryMPEGFrameSize(const t_uint8 p_header[4])
static const uint16 bitrate_table_l3v1[16]
static const uint16 bitrate_table_l23v2[16]
t_uint16 CalculateFrameCRC(const t_uint8 *frameData, t_size frameSize, TMPEGFrameInfo const &frameInfo)
Assumes valid frame with CRC (frameInfo.m_crc set, frameInfo.m_bytes <= frameSize).
bool IsSameStream(TMPEGFrameInfo const &p_frame1, TMPEGFrameInfo const &p_frame2)
static t_uint32 CRC_update(unsigned value, t_uint32 crc)
bool ParseMPEGFrameHeader(TMPEGFrameInfo &p_info, const t_uint8 p_header[4])
void RecalculateFrameCRC(t_uint8 *frameData, t_size frameSize, TMPEGFrameInfo const &frameInfo)
Assumes valid frame with CRC (frameInfo.m_crc set, frameInfo.m_bytes <= frameSize).
static const uint16 bitrate_table_l1v1[16]
static const uint16 bitrate_table_l1v2[16]