📄 mp3dec_common.c
字号:
/*//////////////////////////////////////////////////////////////////////////////
//
// INTEL CORPORATION PROPRIETARY INFORMATION
// This software is supplied under the terms of a license agreement or
// nondisclosure agreement with Intel Corporation and may not be copied
// or disclosed except in accordance with the terms of that agreement.
// Copyright(c) 2003-2007 Intel Corporation. All Rights Reserved.
//
*/
#include "mp3dec_own.h"
/*
// Functions in this file.
//
// Ipp32s mp3dec_SetAllocTable(MP3Dec *state)
// Ipp32s mp3dec_GetSynch(sDecoderContext* DC)
// Ipp32s main_data_slots(sDecoderContext* DC)
// Ipp32s mp3dec_ReadMainData(sDecoderContext* DC)
*/
#define HDR_VERSION(x) ((x & 0x80000) >> 19)
#define HDR_LAYER(x) (4 - ((x & 0x60000) >> 17))
#define HDR_ERRPROTECTION(x) (1 - ((x & 0x10000) >> 16))
#define HDR_BITRADEINDEX(x) ((x & 0x0f000) >> 12)
#define HDR_SAMPLINGFREQ(x) ((x & 0x00c00) >> 10)
#define HDR_PADDING(x) ((x & 0x00200) >> 9)
#define HDR_EXTENSION(x) ((x & 0x00100) >> 8)
#define HDR_MODE(x) ((x & 0x000c0) >> 6)
#define HDR_MODEEXT(x) ((x & 0x00030) >> 4)
#define HDR_COPYRIGHT(x) ((x & 0x00008) >> 3)
#define HDR_ORIGINAL(x) ((x & 0x00004) >> 2)
#define HDR_EMPH(x) ((x & 0x00003))
/* MPEG-1 12-bit code embedded in the audio bitstream that identifies
the start of a frame (p.20 ISO/IEC 11172-3) */
static Ipp32u SYNC_WORD = 0xffe;
#define MP3DEC_END_OF_BUFFER(BS) \
((((((BS)->pCurrent_dword) - ((BS)->pBuffer)) * 32 + \
(BS)->init_nBit_offset - ((BS)->nBit_offset)) <= \
(BS)->nDataLen * 8 - 8) ? 0 : 1)
#define MAX_FRAME_LEN 1800
/******************************************************************************
// Name:
// mp3dec_main_data_slots
//
// Description:
// calculate number of bytes beetween two successive frames minus length of
// (header & side info)
// Input Arguments:
// DC - point to Decoder context
//
// Returns:
// number of bytes beetween two successive frames minus length of
// (header & side info)
//
******************************************************************************/
static Ipp32s mp3dec_main_data_slots(Ipp32s stereo, Ipp32s header_id, Ipp32s header_protectionBit)
{
Ipp32s nSlots = 0;
if (header_id == 1) {
if (stereo == 1)
nSlots -= 17;
else
nSlots -= 32;
}
if (header_id == 0) {
if (stereo == 1)
nSlots -= 9;
else
nSlots -= 17;
}
if (header_protectionBit)
nSlots -= 2;
return nSlots;
}
static Ipp32s mp3dec_SynchCheckCRC(MP3Dec_com *state, Ipp32s MP3Header)
{
IppMP3FrameHeader *header = &(state->header);
sBitsreamBuffer *BS = &state->m_StreamData;
Ipp32s crc_nbits;
Ipp32u crc, crc_check;
if (header->layer == 3) {
if (header->id == 1) {
if (header->mode == 0x3)
crc_nbits = 136;
else
crc_nbits = 256;
} else {
if (header->mode == 0x3)
crc_nbits = 72;
else
crc_nbits = 136;
}
} else {
Ipp32s jsbound, stereo;
jsbound = 32;
stereo = (header->mode == 0x3) ? 1 : 2;
if (header->mode == 0x01) {
jsbound = (header->modeExt + 1) * 4;
}
crc_nbits = (jsbound << (stereo + 1)) + ((32 - jsbound) << 2);
}
bs_save(BS);
GET_BITS(BS, crc_check, 16, Ipp32s);
bs_CRC_reset(&crc);
bs_CRC_update_imm(MP3Header, 16, &crc);
bs_CRC_update_bs(BS, crc_nbits, &crc);
bs_restore(BS);
if (crc != crc_check)
return 1;
return 0;
}
/*****************************************************************************
// Name:
// mp3dec_GetSynch
//
// Description:
// check the MP3 frame header and get information if the header is valid
//
// Input Arguments:
// DC - point to sDecoderContext structure
//
// Output Arguments:
// DC - point to sDecoderContext structure
//
// Returns:
// 1 - if the header is valid and supported
// -1 - if synchronization is lost
// -2 - if it is the end of stream
// -4 - if the header is not supported
//
******************************************************************************/
MP3Status mp3dec_GetSynch(MP3Dec_com *state)
{
Ipp32s MP3Header;
Ipp32u val, val_t;
Ipp32s start_db = state->decodedBytes;
IppMP3FrameHeader *header = &(state->header);
IppMP3FrameHeader *header_good = &(state->header_good);
sBitsreamBuffer *BS = &state->m_StreamData;
Ipp8u *ptrStart = (Ipp8u *)BS->pCurrent_dword + ((32 - BS->nBit_offset) >> 3);
Ipp32s buflen = BS->nDataLen;
Ipp32s cont_flag;
if (buflen <= (BS->pCurrent_dword - BS->pBuffer) * 4 || buflen < 4)
return MP3_NOT_FIND_SYNCWORD; // end of file
GET_BITS(BS, val, 24, Ipp32s);
state->decodedBytes += 3;
do {
cont_flag = 0;
for(;;) {
val <<= 8;
GET_BITS(BS, val_t, 8, Ipp32s);
val |= val_t;
state->decodedBytes++;
if (((val >> 20) & SYNC_WORD) == SYNC_WORD) {
MP3Header = val;
header->layer = HDR_LAYER(MP3Header);
header->samplingFreq = HDR_SAMPLINGFREQ(MP3Header);
header->bitRate = HDR_BITRADEINDEX(MP3Header);
header->emphasis = HDR_EMPH(MP3Header);
header->id = HDR_VERSION(MP3Header);
state->mpg25 = ((val >> 20) & 1) ? 0 : 2;
if (state->m_bInit) {
if ((header->samplingFreq == header_good->samplingFreq) &&
(header->samplingFreq != 3) &&
(header->layer == header_good->layer) &&
(header->id == header_good->id) &&
(state->mpg25 == state->mpg25_good) &&
(header->bitRate != 15) &&
(header->emphasis != 2)) {
break;
}
} else {
if ((header->samplingFreq != 3) &&
(header->layer != 4) &&
(header->bitRate != 15) &&
(header->emphasis != 2) &&
(((val >> 19) & 3) != 1)) {
break;
}
}
}
if (MP3DEC_END_OF_BUFFER(BS)) {
state->decodedBytes -= 3;
return MP3_NOT_FIND_SYNCWORD;
}
}
header->mode = HDR_MODE(MP3Header);
header->modeExt = HDR_MODEEXT(MP3Header);
header->copyright = HDR_COPYRIGHT(MP3Header);
header->originalCopy = HDR_ORIGINAL(MP3Header);
header->paddingBit = HDR_PADDING(MP3Header);
header->privateBit = HDR_EXTENSION(MP3Header);
header->protectionBit = HDR_ERRPROTECTION(MP3Header);
if (header->bitRate != 0) {
Ipp32s size = 0;
if (header->layer == 3) {
size = 72000 * (header->id + 1);
} else if (header->layer == 2) {
size = 72000 * 2;
} else if (header->layer == 1) {
size = 12000;
}
state->MP3nSlots =
size * mp3_bitrate[header->id][header->layer - 1][header->bitRate] /
mp3_frequency[header->id + state->mpg25][header->samplingFreq] + header->paddingBit;
if (header->layer == 1)
state->MP3nSlots *= 4;
state->MP3nSlots -= 4; /* header */
state->decodedBytes += state->MP3nSlots;
if (BS->nDataLen < state->decodedBytes - start_db +
((!state->m_bInit || state->synchro_mode) ? 3 : 0)) {
state->decodedBytes -= state->MP3nSlots + 4;
return MP3_NOT_ENOUGH_DATA;
}
if (!state->m_bInit || state->synchro_mode) {
Ipp32s next_header =
(ptrStart[state->decodedBytes - start_db + 0] << 16) |
(ptrStart[state->decodedBytes - start_db + 1] << 8) |
(ptrStart[state->decodedBytes - start_db + 2]);
if ((next_header ^ (MP3Header >> 8)) & 0xfffe0c) {
state->decodedBytes -= state->MP3nSlots;
if (MP3DEC_END_OF_BUFFER(BS)) {
state->decodedBytes -= 3;
return MP3_NOT_FIND_SYNCWORD;
}
cont_flag = 1;
continue;
}
}
if (header->protectionBit && header->layer != 2) {
if (mp3dec_SynchCheckCRC(state, MP3Header)) {
state->decodedBytes -= state->MP3nSlots;
cont_flag = 1;
continue;
}
}
} else {
Ipp32u ubuf, usyncbuf, good;
if (header->protectionBit && header->layer != 2) {
if (mp3dec_SynchCheckCRC(state, MP3Header)) {
cont_flag = 1;
continue;
}
}
bs_save(BS);
if (state->m_nBitrate != header->bitRate) { /* VBR is forbidden */
state->decodedBytes -= 3;
return MP3_BAD_STREAM;
}
usyncbuf = 0xffe000 | ((2 - state->mpg25) << 11) | (header->id << 11) | ((4 - header->layer) << 9) |
(header->samplingFreq << 2);
state->MP3nSlots = -2;
ubuf = 0;
good = 0;
while (MP3DEC_END_OF_BUFFER(BS) != 1) {
GET_BITS(BS, val, 8, Ipp32s);
ubuf = (ubuf << 8) | val;
if ((ubuf & 0xfffefc) == usyncbuf)
{
good = 1;
break;
}
state->MP3nSlots++;
}
bs_restore(BS);
if (good == 0) {
if (BS->nDataLen > (state->decodedBytes - start_db + MAX_FRAME_LEN)) {
if (MP3DEC_END_OF_BUFFER(BS)) {
state->decodedBytes -= 3;
return MP3_NOT_FIND_SYNCWORD;
}
cont_flag = 1;
continue;
} else {
state->decodedBytes -= 4;
return MP3_NOT_ENOUGH_DATA;
}
}
state->decodedBytes += (state->MP3nSlots);
}
} while (cont_flag);
state->m_nBitrate = header->bitRate;
state->stereo = (header->mode == 0x3) ? 1 : 2;
if (header->mode == 0x01) {
state->intensity = 0;
state->ms_stereo = 0;
if (header->modeExt & 0x1)
state->intensity = 1;
if (header->modeExt & 0x2)
state->ms_stereo = 1;
}
state->start_ptr = BS->pCurrent_dword;
state->start_offset = BS->nBit_offset;
if (header->protectionBit) {
bs_CRC_reset(&state->crc);
bs_CRC_update_imm(MP3Header, 16, &state->crc);
GET_BITS(BS, state->crc_check, 16, Ipp32s);
}
if (header->layer == 2) {
mp3_SetAllocTable(state->header.id,
state->mpg25,
state->header.layer,
state->header.bitRate,
state->header.samplingFreq,
state->stereo,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -