mp4_producer_audio.c
来自「最新MTK手机软件源码」· C语言 代码 · 共 1,614 行 · 第 1/4 页
C
1,614 行
MP4_Producer_Status MP4_Produce_Trak_Audio(STMp4Producer *pstMp4Producer, kal_uint32 *puBoxSize, kal_uint32 uAudioDataOffset)
{
MP4_Producer_Status ret;
kal_uint32 uFilePos;
kal_uint32 uTkhdSize, uMdiaSize;
MP4_PRODUCER_CHECK_ARG(pstMp4Producer!=NULL);
MP4_PRODUCER_CHECK_ARG(puBoxSize!=NULL);
/* header */
if((ret=mp4_produce_box(pstMp4Producer, BOX_TYPE_TRAK, 0, &uFilePos))!=MP4_PRODUCER_OK)
return ret;
*puBoxSize = 8;
/* track header (tkhd) */
if((ret=mp4_produce_tkhd(pstMp4Producer, &uTkhdSize))!=MP4_PRODUCER_OK)
return ret;
*puBoxSize += uTkhdSize;
/* media information (mdia) */
if((ret=mp4_produce_mdia(pstMp4Producer, &uMdiaSize, uAudioDataOffset))!=MP4_PRODUCER_OK)
return ret;
*puBoxSize += uMdiaSize;
/* update box size */
if ((pstMp4Producer->eFSALErr=FSAL_Write_UINT_AT(pstMp4Producer->pstFSAL, *puBoxSize, uFilePos))!=FSAL_OK)
return MP4_PRODUCER_FILE_WRITE_ERROR;
return MP4_PRODUCER_OK;
}
MP4_Producer_Status MP4_Produce_MovieHeader(STMp4Producer *pstMp4Producer, kal_uint32 uAudioDataOffset)
{
MP4_Producer_Status ret;
kal_uint32 uFilePos;
kal_uint32 uBoxSize, uMvhdSize, uTrakSize;
/* header */
if((ret=mp4_produce_box(pstMp4Producer, BOX_TYPE_MOOV, 0, &uFilePos))!=MP4_PRODUCER_OK)
return ret;
uBoxSize = 8;
if((ret=mp4_produce_mvhd(pstMp4Producer, &uMvhdSize))!=MP4_PRODUCER_OK)
return ret;
uBoxSize += uMvhdSize;
if((ret=MP4_Produce_Trak_Audio(pstMp4Producer, &uTrakSize, uAudioDataOffset))!=MP4_PRODUCER_OK)
return ret;
uBoxSize += uTrakSize;
/* update box size */
if ((pstMp4Producer->eFSALErr=FSAL_Write_UINT_AT(pstMp4Producer->pstFSAL, uBoxSize, uFilePos))!=FSAL_OK)
return MP4_PRODUCER_FILE_WRITE_ERROR;
return MP4_PRODUCER_OK;
}
MP4_Producer_Status mp4_produce_mdat(STMp4Producer *pstMp4Producer)
{
return MP4_PRODUCER_OK;
}
MP4_Producer_Status MP4_Produce_Init(STMp4Producer *pstMp4Producer, STMp4SampleDataAudio *pstMp4SampleData, STFSAL *pstFSAL)
{
// MP4_Producer_Status ret;
MP4_PRODUCER_CHECK_ARG(pstMp4Producer!=NULL);
MP4_PRODUCER_CHECK_ARG(pstMp4SampleData!=NULL);
MP4_PRODUCER_CHECK_ARG(pstFSAL!=NULL);
pstMp4Producer->pstMp4SampleData = pstMp4SampleData;
pstMp4Producer->pstFSAL = pstFSAL;
pstMp4Producer->eCurTrack = MP4_TRACK_AUDIO;
// if((ret=MP4_Produce_FileTypeBox(pstMp4Producer))!=MP4_PRODUCER_OK)
// return ret;
// if((ret=mp4_produce_mdat(pstMp4Producer))!=MP4_PRODUCER_OK)
// return ret;
// if((ret=MP4_Produce_MovieHeader(pstMp4Producer))!=MP4_PRODUCER_OK)
// return ret;
return MP4_PRODUCER_OK;
}
MP4_Producer_Status MP4_Produce_CalculateLimitedAudioFileSize(
STFSAL *pstFSAL, kal_uint32 uNumBytesLimit, kal_uint32 uMilliSecondsLimit,
kal_uint8 bAMRType, kal_uint32 *puResultBytes)
{
kal_uint32 uSpeechFrameLimit;
kal_uint32 uSpeechFrameCount;
kal_uint32 uAudioFileLen;
kal_uint32 uAMRFilePos;
FSAL_Status eFSALRet;
ASSERT(pstFSAL!=NULL);
ASSERT(puResultBytes!=NULL);
eFSALRet = FSAL_GetFileSize(pstFSAL, &uAudioFileLen);
if (eFSALRet!=FSAL_OK)
return MP4_PRODUCER_FILE_ACCESS_ERROR;
if (uAudioFileLen<8)
return MP4_PRODUCER_AUDIO_FILE_TOO_SMALL;
uAMRFilePos = 8;
*puResultBytes = 8;
uSpeechFrameLimit = uMilliSecondsLimit / 20;
uSpeechFrameCount = 0;
/* parse each audio frame */
while(uAMRFilePos < uAudioFileLen) {
unsigned char bFrameHeader;
unsigned char bFrameType;
unsigned char bFrameLength;
unsigned char bFQI;
eFSALRet = FSAL_Seek(pstFSAL, uAMRFilePos);
if(eFSALRet!=FSAL_OK)
{
return MP4_PRODUCER_FILE_SEEK_ERROR;
}
eFSALRet = FSAL_Read_Bytes(pstFSAL, &bFrameHeader, 1);
if(eFSALRet != FSAL_OK)
return MP4_PRODUCER_FILE_READ_ERROR;
bFrameType = (bFrameHeader >> 3)&0x0F;
bFQI = (bFrameHeader >> 2)&0x01;
if( bFQI == 0 )
{
return MP4_PRODUCER_AMR_FQI_INVALID;
}
// ASSERT(bFQI==1);
// After this line, bFQI is no more valid and hence can be used as temporary variable.
if (bAMRType==0)
bFQI = 8; /* AMR */
else
bFQI = 9; /* AMR-WB */
if (bFrameType <= bFQI) {
bFrameLength = (lenSpeechBitsAMR[bFrameType] + 7) / 8;
} else if (bFrameType == 15) {
bFrameLength = 0;
} else {
return MP4_PRODUCER_AMR_FRAME_INVALID;
}
uAMRFilePos += (bFrameLength + 1);
uSpeechFrameCount++;
if (uAMRFilePos > uNumBytesLimit)
break;
if (uSpeechFrameCount > uSpeechFrameLimit)
break;
/* Handle the case for partial frame */
if (uAMRFilePos > uAudioFileLen)
break;
*puResultBytes += (bFrameLength + 1);
}
return MP4_PRODUCER_OK;
}
#ifdef WIN32_UNIT_TEST
#define mu_run_test(test) \
do { \
char *message; \
printf("Doing: %s\n", #test); \
message = test(); tests_run++; \
if (message) return message; \
} while (0)
extern int tests_run;
int tests_run = 0;
/* No Speech Frame */
const unsigned char amr_file_1[8] = {
/* 8 bytes file header */
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
};
/* One Speech Frame */
const unsigned char amr_file_2[22] = {
/* 8 bytes file header */
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
/* 5.15kbps: 1 byte frame header 13 bytes frame data */
0x0C, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13
};
/* Two Speech Frame */
const unsigned char amr_file_3[36] = {
/* 8 bytes file header */
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
/* 5.15kbps: 1 byte frame header 13 bytes frame data */
0x0C, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
/* 5.15kbps: 1 byte frame header 13 bytes frame data */
0x0C, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
};
/* File Size Less Than 8 */
const unsigned char amr_file_4[7] = {
1, 2, 3, 4, 5, 6, 7
};
/* File With Invalid FQI */
const unsigned char amr_file_5[9] = {
/* 8 bytes file header */
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
/* invalid frame header */
0
};
/* File With Invalid Frame Header */
const unsigned char amr_file_6[9] = {
/* 8 bytes file header */
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
/* invalid frame header */
0x74
};
/* File with partial frame */
const unsigned char amr_file_7[32] = {
/* 8 bytes file header */
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
/* 5.15kbps: 1 byte frame header 13 bytes frame data */
0x0C, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
/* 5.15kbps: 1 byte frame header 13 bytes frame data */
0x0C, 1, 2, 3, 4, 5, 6, 7, 8, 9
};
STFSAL stFSAL;
FSAL_Status eFSALStatus;
kal_uint32 uResultBytes;
MP4_Producer_Status eMp4ProducerStatus;
static char* mu_CalculateLimitedAudioFileSize_1(void)
{
FSAL_Direct_SetRamFileSize(&stFSAL, sizeof(amr_file_1));
eFSALStatus = FSAL_Open(&stFSAL, (void*)amr_file_1, FSAL_ROMFILE);
ASSERT(eFSALStatus == FSAL_OK);
eMp4ProducerStatus = MP4_Produce_CalculateLimitedAudioFileSize(&stFSAL, 0, 0, 0, &uResultBytes);
ASSERT(eMp4ProducerStatus == MP4_PRODUCER_OK);
ASSERT(uResultBytes == 8);
eMp4ProducerStatus = MP4_Produce_CalculateLimitedAudioFileSize(&stFSAL, 7, 0, 0, &uResultBytes);
ASSERT(eMp4ProducerStatus == MP4_PRODUCER_OK);
ASSERT(uResultBytes == 8);
eMp4ProducerStatus = MP4_Produce_CalculateLimitedAudioFileSize(&stFSAL, 8, 0, 0, &uResultBytes);
ASSERT(eMp4ProducerStatus == MP4_PRODUCER_OK);
ASSERT(uResultBytes == 8);
eMp4ProducerStatus = MP4_Produce_CalculateLimitedAudioFileSize(&stFSAL, 9, 0, 0, &uResultBytes);
ASSERT(eMp4ProducerStatus == MP4_PRODUCER_OK);
ASSERT(uResultBytes == 8);
eFSALStatus = FSAL_Close(&stFSAL);
ASSERT(eFSALStatus == FSAL_OK);
return NULL;
}
static char* mu_CalculateLimitedAudioFileSize_2(void)
{
FSAL_Direct_SetRamFileSize(&stFSAL, sizeof(amr_file_2));
eFSALStatus = FSAL_Open(&stFSAL, (void*)amr_file_2, FSAL_ROMFILE);
ASSERT(eFSALStatus == FSAL_OK);
eMp4ProducerStatus = MP4_Produce_CalculateLimitedAudioFileSize(&stFSAL, 0, 0, 0, &uResultBytes);
ASSERT(eMp4ProducerStatus == MP4_PRODUCER_OK);
ASSERT(uResultBytes == 8);
eMp4ProducerStatus = MP4_Produce_CalculateLimitedAudioFileSize(&stFSAL, 7, 0, 0, &uResultBytes);
ASSERT(eMp4ProducerStatus == MP4_PRODUCER_OK);
ASSERT(uResultBytes == 8);
eMp4ProducerStatus = MP4_Produce_CalculateLimitedAudioFileSize(&stFSAL, 8, 0, 0, &uResultBytes);
ASSERT(eMp4ProducerStatus == MP4_PRODUCER_OK);
ASSERT(uResultBytes == 8);
eMp4ProducerStatus = MP4_Produce_CalculateLimitedAudioFileSize(&stFSAL, 9, 0, 0, &uResultBytes);
ASSERT(eMp4ProducerStatus == MP4_PRODUCER_OK);
ASSERT(uResultBytes == 8);
eMp4ProducerStatus = MP4_Produce_CalculateLimitedAudioFileSize(&stFSAL, 21, 0, 0, &uResultBytes);
ASSERT(eMp4ProducerStatus == MP4_PRODUCER_OK);
ASSERT(uResultBytes == 8);
eMp4ProducerStatus = MP4_Produce_CalculateLimitedAudioFileSize(&stFSAL, 22, 0, 0, &uResultBytes);
ASSERT(eMp4ProducerStatus == MP4_PRODUCER_OK);
ASSERT(uResultBytes == 8);
eMp4ProducerStatus = MP4_Produce_CalculateLimitedAudioFileSize(&stFSAL, 22, 20, 0, &uResultBytes);
ASSERT(eMp4ProducerStatus == MP4_PRODUCER_OK);
ASSERT(uResultBytes == 22);
eMp4ProducerStatus = MP4_Produce_CalculateLimitedAudioFileSize(&stFSAL, 22, 40, 0, &uResultBytes);
ASSERT(eMp4ProducerStatus == MP4_PRODUCER_OK);
ASSERT(uResultBytes == 22);
eFSALStatus = FSAL_Close(&stFSAL);
ASSERT(eFSALStatus == FSAL_OK);
return NULL;
}
static char* mu_CalculateLimitedAudioFileSize_3(void)
{
FSAL_Direct_SetRamFileSize(&stFSAL, sizeof(amr_file_3));
eFSALStatus = FSAL_Open(&stFSAL, (void*)amr_file_3, FSAL_ROMFILE);
ASSERT(eFSALStatus == FSAL_OK);
eMp4ProducerStatus = MP4_Produce_CalculateLimitedAudioFileSize(&stFSAL, 36, 40, 0, &uResultBytes);
ASSERT(eMp4ProducerStatus == MP4_PRODUCER_OK);
ASSERT(uResultBytes == 36);
eMp4ProducerStatus = MP4_Produce_CalculateLimitedAudioFileSize(&stFSAL, 36, 80, 0, &uResultBytes);
ASSERT(eMp4ProducerStatus == MP4_PRODUCER_OK);
ASSERT(uResultBytes == 36);
eMp4ProducerStatus = MP4_Produce_CalculateLimitedAudioFileSize(&stFSAL, 72, 80, 0, &uResultBytes);
ASSERT(eMp4ProducerStatus == MP4_PRODUCER_OK);
ASSERT(uResultBytes == 36);
eMp4ProducerStatus = MP4_Produce_CalculateLimitedAudioFileSize(&stFSAL, 35, 40, 0, &uResultBytes);
ASSERT(eMp4ProducerStatus == MP4_PRODUCER_OK);
ASSERT(uResultBytes == 22);
eFSALStatus = FSAL_Close(&stFSAL);
ASSERT(eFSALStatus == FSAL_OK);
return NULL;
}
static char* mu_CalculateLimitedAudioFileSize_4(void)
{
FSAL_Direct_SetRamFileSize(&stFSAL, sizeof(amr_file_4));
eFSALStatus = FSAL_Open(&stFSAL, (void*)amr_file_4, FSAL_ROMFILE);
ASSERT(eFSALStatus == FSAL_OK);
eMp4ProducerStatus = MP4_Produce_CalculateLimitedAudioFileSize(&stFSAL, 36, 40, 0, &uResultBytes);
ASSERT(eMp4ProducerStatus == MP4_PRODUCER_AUDIO_FILE_TOO_SMALL);
eFSALStatus = FSAL_Close(&stFSAL);
ASSERT(eFSALStatus == FSAL_OK);
return NULL;
}
static char* mu_CalculateLimitedAudioFileSize_5(void)
{
FSAL_Direct_SetRamFileSize(&stFSAL, sizeof(amr_file_5));
eFSALStatus = FSAL_Open(&stFSAL, (void*)amr_file_5, FSAL_ROMFILE);
ASSERT(eFSALStatus == FSAL_OK);
eMp4ProducerStatus = MP4_Produce_CalculateLimitedAudioFileSize(&stFSAL, 36, 40, 0, &uResultBytes);
ASSERT(eMp4ProducerStatus == MP4_PRODUCER_AMR_FQI_INVALID);
eFSALStatus = FSAL_Close(&stFSAL);
ASSERT(eFSALStatus == FSAL_OK);
return NULL;
}
static char* mu_CalculateLimitedAudioFileSize_6(void)
{
FSAL_Direct_SetRamFileSize(&stFSAL, sizeof(amr_file_6));
eFSALStatus = FSAL_Open(&stFSAL, (void*)amr_file_6, FSAL_ROMFILE);
ASSERT(eFSALStatus == FSAL_OK);
eMp4ProducerStatus = MP4_Produce_CalculateLimitedAudioFileSize(&stFSAL, 36, 40, 0, &uResultBytes);
ASSERT(eMp4ProducerStatus == MP4_PRODUCER_AMR_FRAME_INVALID);
eFSALStatus = FSAL_Close(&stFSAL);
ASSERT(eFSALStatus == FSAL_OK);
return NULL;
}
static char* mu_CalculateLimitedAudioFileSize_7(void)
{
FSAL_Direct_SetRamFileSize(&stFSAL, sizeof(amr_file_7));
eFSALStatus = FSAL_Open(&stFSAL, (void*)amr_file_7, FSAL_ROMFILE);
ASSERT(eFSALStatus == FSAL_OK);
eMp4ProducerStatus = MP4_Produce_CalculateLimitedAudioFileSize(&stFSAL, 36, 40, 0, &uResultBytes);
ASSERT(eMp4ProducerStatus == MP4_PRODUCER_OK);
ASSERT(uResultBytes == 22);
eFSALStatus = FSAL_Close(&stFSAL);
ASSERT(eFSALStatus == FSAL_OK);
return NULL;
}
static char * all_tests() {
mu_run_test(mu_CalculateLimitedAudioFileSize_1);
mu_run_test(mu_CalculateLimitedAudioFileSize_2);
mu_run_test(mu_CalculateLimitedAudioFileSize_3);
mu_run_test(mu_CalculateLimitedAudioFileSize_4);
mu_run_test(mu_CalculateLimitedAudioFileSize_5);
mu_run_test(mu_CalculateLimitedAudioFileSize_6);
mu_run_test(mu_CalculateLimitedAudioFileSize_7);
return 0;
}
int main(int argc, char **argv)
{
char *result = all_tests();
if (result != 0) {
printf("Failed at: %s\n", result);
} else {
printf("ALL TESTS PASSED\n");
}
printf("Tests run: %d\n", tests_run);
return (result != 0);
}
#endif
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?