📄 mp4_parser_audio.c
字号:
unsigned int type;
if((ret=mp4_parse_box(pstMp4Parser, &size, &type))!=MP4_PARSER_OK)
return ret;
if(type==BOX_TYPE_ESDS) {
if((ret=mp4_parse_esds(pstMp4Parser, size))!=MP4_PARSER_OK)
return ret;
} else
return MP4_PARSER_PARSE_ERROR;
}
return MP4_PARSER_OK;
}
/*
DESCRIPTION
Parse AMR Specific Box.
INPUT
size: The size of AMR Specific Box excluding Box
RETURN
MP4_PARSER_OK: Successful
other values: Error
*/
static MP4_Parser_Status mp4_parse_damr(STMp4Parser *pstMp4Parser, long damr_size)
{
kal_uint16 mode_set;
kal_uint8 mode_change_period;
kal_uint8 bFramesPerSample;
MP4_PARSER_CHECK_ARG(pstMp4Parser!=NULL);
/* AMR Decoder Specific Structure */
if((pstMp4Parser->eFSALErr=FSAL_Skip_Bytes(pstMp4Parser->pstFSAL, 5))!=FSAL_OK)
return MP4_PARSER_FILE_SEEK_ERROR;
if((pstMp4Parser->eFSALErr=FSAL_Read_UINT16(pstMp4Parser->pstFSAL, &mode_set))!=FSAL_OK)
return MP4_PARSER_PARSE_ERROR;
if((pstMp4Parser->eFSALErr=FSAL_Read_Bytes(pstMp4Parser->pstFSAL, &mode_change_period, 1))!=FSAL_OK)
return MP4_PARSER_FILE_READ_ERROR;
if((pstMp4Parser->eFSALErr=FSAL_Read_Bytes(pstMp4Parser->pstFSAL, &bFramesPerSample, 1))!=FSAL_OK)
return MP4_PARSER_FILE_READ_ERROR;
damr_size-=9;
#if MP4_PARSER_VERBOSE
printf("mode_set=%0X, mode_change_period=%0X, frames_per_sample=%0X\n",
mode_set, mode_change_period, bFramesPerSample);
#endif
pstMp4Parser->bFramesPerSample = bFramesPerSample;
if((pstMp4Parser->eFSALErr=FSAL_Skip_Bytes(pstMp4Parser->pstFSAL, damr_size))!=FSAL_OK)
return MP4_PARSER_PARSE_ERROR;
return MP4_PARSER_OK;
}
kal_uint8 mp4_audio_amr_get_frame_per_sample(STMp4Parser *pstMp4Parser)
{
MP4_PARSER_CHECK_ARG(pstMp4Parser!=NULL);
return pstMp4Parser->bFramesPerSample;
}
/*
DESCRIPTION
Parse Sample Entry SAMR or SAWB.
INPUT
size: The size of Sample Entry SAMR or SAWB excluding Box
RETURN
MP4_PARSER_OK: Successful
other values: Error
*/
MP4_Parser_Status mp4_parse_samr(STMp4Parser *pstMp4Parser, long samr_size)
{
/* Sample Entry SAMR or SAWB is a leaf node. */
MP4_Parser_Status ret;
/* Audio Sample Entry */
kal_uint16 channelcount;
kal_uint16 samplesize;
kal_uint32 uSampleRate;
MP4_PARSER_CHECK_ARG(pstMp4Parser!=NULL);
/* Sample Entry */
if((pstMp4Parser->eFSALErr=FSAL_Skip_Bytes(pstMp4Parser->pstFSAL, 8))!=FSAL_OK)
return MP4_PARSER_PARSE_ERROR;
samr_size-=8;
/* Audio Sample Entry */
if((pstMp4Parser->eFSALErr=FSAL_Skip_Bytes(pstMp4Parser->pstFSAL, 8))!=FSAL_OK)
return MP4_PARSER_FILE_SEEK_ERROR;
if((pstMp4Parser->eFSALErr=FSAL_Read_UINT16(pstMp4Parser->pstFSAL, &channelcount))!=FSAL_OK)
return MP4_PARSER_PARSE_ERROR;
if((pstMp4Parser->eFSALErr=FSAL_Read_UINT16(pstMp4Parser->pstFSAL, &samplesize))!=FSAL_OK)
return MP4_PARSER_PARSE_ERROR;
if((pstMp4Parser->eFSALErr=FSAL_Skip_Bytes(pstMp4Parser->pstFSAL, 4))!=FSAL_OK)
return MP4_PARSER_PARSE_ERROR;
if((pstMp4Parser->eFSALErr=FSAL_Read_UINT(pstMp4Parser->pstFSAL, &uSampleRate))!=FSAL_OK)
return MP4_PARSER_FILE_READ_ERROR;
pstMp4Parser->bAudioSamplingFreqIndex = convertSamplingFreqToIndex(uSampleRate>>16);
samr_size-=20;
#if MP4_PARSER_VERBOSE
printf("channel=%u, samplesize=%u, samplerate=%u\n",
channelcount, samplesize, uSampleRate>>16);
#endif
/* AMRSpecificBox */
{
kal_uint32 size, type;
if((ret=mp4_parse_box(pstMp4Parser, &size, &type))!=MP4_PARSER_OK)
return ret;
if(type==BOX_TYPE_DAMR) {
if((ret=mp4_parse_damr(pstMp4Parser, size))!=MP4_PARSER_OK)
return ret;
} else
return MP4_PARSER_DAMR_BOX_EXPECTED;
}
return MP4_PARSER_OK;
}
/*
DESCRIPTION
Parse the AudioSpecificConfig of 14496-3.
INPUT
size: The size of the decoder specific info.
RETURN
MP4_PARSER_OK: Successful
other values: Error
*/
MP4_Parser_Status mp4_parse_decoder_config_14496_3(STMp4Parser *pstMp4Parser, long box_size)
{
MP4_Parser_Status ret;
kal_uint32 uBitCnt = 0;
/* Audio Specific Config */
kal_uint8 audioObjectType;
kal_uint8 samplingFreqIndex;
kal_uint32 samplingFreq;
/* GA Specific Config */
kal_uint8 frameLengthFlag;
kal_uint8 dependsOnCoreCoder;
kal_uint8 extensionFlag;
MP4_PARSER_CHECK_ARG(pstMp4Parser!=NULL);
/* Refer to 14496-3 Subpart 1 */
/* audio object type */
if((pstMp4Parser->eFSALErr=FSAL_Read_Bits(pstMp4Parser->pstFSAL, &uBitCnt, &audioObjectType, 5))!=FSAL_OK)
return MP4_PARSER_FILE_READ_ERROR;
if((pstMp4Parser->eFSALErr=FSAL_Read_Bits(pstMp4Parser->pstFSAL, &uBitCnt, &samplingFreqIndex, 4))!=FSAL_OK)
return MP4_PARSER_FILE_READ_ERROR;
if(samplingFreqIndex==0xf) {
kal_uint8 freq[3];
if((pstMp4Parser->eFSALErr=FSAL_Read_Bits(pstMp4Parser->pstFSAL, &uBitCnt, &freq[2], 8))!=FSAL_OK)
return MP4_PARSER_FILE_READ_ERROR;
if((pstMp4Parser->eFSALErr=FSAL_Read_Bits(pstMp4Parser->pstFSAL, &uBitCnt, &freq[1], 8))!=FSAL_OK)
return MP4_PARSER_FILE_READ_ERROR;
if((pstMp4Parser->eFSALErr=FSAL_Read_Bits(pstMp4Parser->pstFSAL, &uBitCnt, &freq[0], 8))!=FSAL_OK)
return MP4_PARSER_FILE_READ_ERROR;
samplingFreq = (freq[2]<<16) + (freq[1]<<8) + (freq[0]);
/* Refer to 14496-3 Subpart 4 */
samplingFreqIndex = convertSamplingFreqToIndex(samplingFreq);
} else if(samplingFreqIndex==0xc) {
/* Refer to 14496-3 Subpart 4 */
samplingFreqIndex = 0xb;
} else if(samplingFreqIndex==0xd || samplingFreqIndex==0xe) {
return MP4_PARSER_PARSE_ERROR;
}
if(samplingFreqIndex<=0x02) {
return MP4_PARSER_SAMPLING_FREQ_NOT_SUPPORT;
}
pstMp4Parser->bAudioSamplingFreqIndex = samplingFreqIndex;
/* channel configuration */
if((pstMp4Parser->eFSALErr=FSAL_Read_Bits(pstMp4Parser->pstFSAL, &uBitCnt, &(pstMp4Parser->bAudioChannelConfig), 4))!=FSAL_OK)
return MP4_PARSER_FILE_READ_ERROR;
if(pstMp4Parser->bAudioChannelConfig>0x02)
return MP4_PARSER_AUDIO_TOO_MANY_CHANNEL;
/* GA Specific Config */
/* Refer to 14496-3 Part 4 */
/* frame length flag */
if((pstMp4Parser->eFSALErr=FSAL_Read_Bits(pstMp4Parser->pstFSAL, &uBitCnt, &frameLengthFlag, 1))!=FSAL_OK)
return MP4_PARSER_FILE_READ_ERROR;
if(frameLengthFlag!=0)
return MP4_PARSER_960_120_IMDCT_NOT_SUPPORT;
/* depends on core coder */
if((pstMp4Parser->eFSALErr=FSAL_Read_Bits(pstMp4Parser->pstFSAL, &uBitCnt, &dependsOnCoreCoder, 1))!=FSAL_OK)
return MP4_PARSER_FILE_READ_ERROR;
if(dependsOnCoreCoder)
return MP4_PARSER_SCALABLE_STREAM_NOT_SUPPORT;
/* extension flag */
if((pstMp4Parser->eFSALErr=FSAL_Read_Bits(pstMp4Parser->pstFSAL, &uBitCnt, &extensionFlag, 1))!=FSAL_OK)
return MP4_PARSER_FILE_READ_ERROR;
if(pstMp4Parser->bAudioChannelConfig==0) {
/* parse program_config_element */
MP4_PARSER_FILE_GET_CUR_POS(pstMp4Parser->uAudioPCEFileOffset);
if((ret=mp4_parse_decoder_config_14496_3_pce(pstMp4Parser, &uBitCnt))!=MP4_PARSER_OK)
return ret;
}
box_size -= (uBitCnt+7)/8;
if((pstMp4Parser->eFSALErr=FSAL_Skip_Bytes(pstMp4Parser->pstFSAL, box_size))!=FSAL_OK)
return MP4_PARSER_PARSE_ERROR;
return MP4_PARSER_OK;
}
static void putbits(unsigned char *in, unsigned int *bitcnt, int data, int data_length)
{
int t,count;
MP4_PARSER_ASSERT_NO_RET_VAL(data_length>0 && data_length<=16);
t = *bitcnt;
if( (t & 0x7)== 0)
in[t>>3] = 0;
if( (t & 0x7) + data_length <= 8)
in[(t>>3)] |= (data << (8-((t&0x7) + data_length)));
else {
count = (t&7) + data_length;
in[(t>>3)] |= (data >> (data_length - 8 + (t&7)));
count -= 8;
if(count > 8) {
in[(t>>3)+1] = (unsigned char)((data >> (count-8))&0xFF);
in[(t>>3)+2] = (unsigned char)((data << (16-count))&0xFF);
} else {
in[(t>>3)+1] = (unsigned char)((data << (8-count))&0xFF);
}
}
*bitcnt += data_length;
}
/*
* Prepare only once for the whole stream.
*/
MP4_Parser_Status prepareADIFFrameHeader(STMp4Parser *pstMp4Parser)
{
kal_uint32 uBitCnt;
kal_uint32 uBitrate;
kal_uint8 *pbHeader;
MP4_PARSER_CHECK_ARG(pstMp4Parser!=NULL);
pbHeader = pstMp4Parser->pbADIFFrameHeader;
pstMp4Parser->uADIFHeaderReadOffset = 0;
if(pstMp4Parser->uAudioAvgBitrate) { /* constant bitrate */
uBitrate = pstMp4Parser->uAudioAvgBitrate;
} else {
uBitrate = pstMp4Parser->uAudioMaxBitrate;
}
/* adif_header */
uBitCnt = 0;
//uHeaderSize = 8 + pstMp4Parser->uAudioPCELength;
putbits(pbHeader, &uBitCnt, 0x4144, 16); /* adif_id: AD */
putbits(pbHeader, &uBitCnt, 0x4946, 16); /* adif_id: IF */
putbits(pbHeader, &uBitCnt, 0, 1); /* copyright id present */
putbits(pbHeader, &uBitCnt, 1, 1); /* original copy */
putbits(pbHeader, &uBitCnt, 0, 1); /* home */
putbits(pbHeader, &uBitCnt, 1, 1); /* bitstream type */
putbits(pbHeader, &uBitCnt, (uBitrate>>7) & 0xFFFF, 16); /* bit rate */
putbits(pbHeader, &uBitCnt, (uBitrate) & 0x7F, 7); /* bit rate */
putbits(pbHeader, &uBitCnt, 0x0, 4); /* number of program config elements */
MP4_PARSER_ASSERT(uBitCnt==63);
/* program_config_element */
{
kal_int32 iBitLeft;
kal_uint8 bPCE;
if ((pstMp4Parser->eFSALErr=FSAL_Seek(pstMp4Parser->pstFSAL, pstMp4Parser->uAudioPCEFileOffset))!=FSAL_OK)
return MP4_PARSER_FILE_SEEK_ERROR;
iBitLeft = pstMp4Parser->uAudioPCEBitLength;
while (iBitLeft > 0) {
if ((pstMp4Parser->eFSALErr=FSAL_Read(pstMp4Parser->pstFSAL, &bPCE, 1))!=FSAL_OK)
return MP4_PARSER_FILE_READ_ERROR;
if (iBitLeft<8)
putbits(pbHeader, &uBitCnt, bPCE, iBitLeft);
else
putbits(pbHeader, &uBitCnt, bPCE, 8);
iBitLeft -= 8;
}
}
/* byte alignment */
if (uBitCnt%8 != 0)
putbits(pbHeader, &uBitCnt, 0, 8-uBitCnt%8);
/* comment_field_bytes */
putbits(pbHeader, &uBitCnt, 0, 8);
MP4_PARSER_ASSERT(uBitCnt%8 == 0);
MP4_PARSER_ASSERT(uBitCnt<=ADIF_HEADER_SIZE*8);
pstMp4Parser->uADIFFrameHeaderLen = uBitCnt/8;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -