📄 mp4_parser.c
字号:
MP4_PARSER_CHECK_ARG(pstMp4Parser!=NULL);
if((pstMp4Parser->eFSALErr=FSAL_Read_Bytes(pstMp4Parser->pstFSAL, &version, 1))!=FSAL_OK)
return MP4_PARSER_FILE_READ_ERROR;
if((pstMp4Parser->eFSALErr=FSAL_Read_Bytes(pstMp4Parser->pstFSAL, flags, 3))!=FSAL_OK)
return MP4_PARSER_FILE_READ_ERROR;
if((pstMp4Parser->eFSALErr=FSAL_Read_UINT(pstMp4Parser->pstFSAL, &entry_count))!=FSAL_OK)
return MP4_PARSER_PARSE_ERROR;
stsd_size -= 8;
if(entry_count>1)
return MP4_PARSER_EXTERNAL_DATA_REFERENCE;
else if(entry_count==1) {
/* The following may be Audio Sample Entry or Visual Sample Entry */
MP4_Parser_Status ret;
kal_uint32 size;
kal_uint32 type;
if((ret=mp4_parse_box(pstMp4Parser, &size, &type))!=MP4_PARSER_OK)
return ret;
stsd_size -= 8;
switch(type) {
case SAMPLE_FMT_MP4V:
if((ret=mp4_parse_mp4v(pstMp4Parser, size))!=MP4_PARSER_OK)
return ret;
break;
case SAMPLE_FMT_MP4A:
if((ret=mp4_parse_mp4a(pstMp4Parser, size))!=MP4_PARSER_OK)
return ret;
break;
case SAMPLE_FMT_SAMR:
pstMp4Parser->bAudioType = MP4_AUDIO_AMR;
if((ret=mp4_parse_samr(pstMp4Parser, size))!=MP4_PARSER_OK)
return ret;
break;
case SAMPLE_FMT_SAWB:
pstMp4Parser->bAudioType = MP4_AUDIO_AMR_WB;
if((ret=mp4_parse_samr(pstMp4Parser, size))!=MP4_PARSER_OK)
return ret;
break;
case SAMPLE_FMT_S263:
pstMp4Parser->bVideoType = MP4_VIDEO_H263;
if((ret=mp4_parse_s263(pstMp4Parser, size))!=MP4_PARSER_OK)
return ret;
break;
default:
if((pstMp4Parser->eFSALErr=FSAL_Skip_Bytes(pstMp4Parser->pstFSAL, size))!=FSAL_OK)
return MP4_PARSER_PARSE_ERROR;
}
stsd_size -= size;
}
if((pstMp4Parser->eFSALErr=FSAL_Skip_Bytes(pstMp4Parser->pstFSAL, stsd_size))!=FSAL_OK)
return MP4_PARSER_FILE_SEEK_ERROR;
pstMp4Parser->stMp4Track[pstMp4Parser->bCurTrack].bHasSTSD = KAL_TRUE;
return MP4_PARSER_OK;
}
/*
DESCRIPTION
Parse the Decoding Time To Sample Box.
INPUT
size: The size of Decoding Time To Sample Box excluding Box
RETURN
MP4_PARSER_OK: Successful
Other values: Parse error
*/
static MP4_Parser_Status mp4_parse_stts(STMp4Parser *pstMp4Parser, kal_int32 stts_size)
{
/* Decoding Time To Sample Box is a leaf node. */
kal_uint8 version;
kal_uint8 flags[3];
kal_uint32 entry_count;
MP4_PARSER_CHECK_ARG(pstMp4Parser!=NULL);
if((pstMp4Parser->eFSALErr=FSAL_Read_Bytes(pstMp4Parser->pstFSAL, &version, 1))!=FSAL_OK)
return MP4_PARSER_FILE_READ_ERROR;
if((pstMp4Parser->eFSALErr=FSAL_Read_Bytes(pstMp4Parser->pstFSAL, flags, 3))!=FSAL_OK)
return MP4_PARSER_FILE_READ_ERROR;
if((pstMp4Parser->eFSALErr=FSAL_Read_UINT(pstMp4Parser->pstFSAL, &entry_count))!=FSAL_OK)
return MP4_PARSER_PARSE_ERROR;
pstMp4Parser->stMp4Track[pstMp4Parser->bCurTrack].uTimeToSampleTableEntryCount = entry_count;
MP4_PARSER_FILE_GET_CUR_POS(pstMp4Parser->stMp4Track[pstMp4Parser->bCurTrack].uOffsetTimeToSampleTable);
stts_size-=8;
if((pstMp4Parser->eFSALErr=FSAL_Skip_Bytes(pstMp4Parser->pstFSAL, entry_count*8))!=FSAL_OK)
return MP4_PARSER_PARSE_ERROR;
stts_size -= (entry_count*8);
if((pstMp4Parser->eFSALErr=FSAL_Skip_Bytes(pstMp4Parser->pstFSAL, stts_size))!=FSAL_OK)
return MP4_PARSER_FILE_SEEK_ERROR;
pstMp4Parser->stMp4Track[pstMp4Parser->bCurTrack].bHasSTTS = KAL_TRUE;
/* Initilize STTS cache table */
pstMp4Parser->stMp4Track[pstMp4Parser->bCurTrack].uSTTSCacheTableEntryCount = 0;
pstMp4Parser->stMp4Track[pstMp4Parser->bCurTrack].uSTTSCacheTableStepSize = 0;
pstMp4Parser->stMp4Track[pstMp4Parser->bCurTrack].pSTTSCacheTable = NULL;
return MP4_PARSER_OK;
}
/*
DESCRIPTION
Parse the Sample To Chunk Box.
INPUT
size: The size of Sample To Chunk Box excluding Box
RETURN
MP4_PARSER_OK: Successful
Other values: Parse error
*/
static MP4_Parser_Status mp4_parse_stsc(STMp4Parser *pstMp4Parser, kal_int32 stsc_size)
{
/* Sample To Chunk Box is a leaf node. */
kal_uint8 version;
kal_uint8 flags[3];
kal_uint32 entry_count;
MP4_PARSER_CHECK_ARG(pstMp4Parser!=NULL);
if((pstMp4Parser->eFSALErr=FSAL_Read_Bytes(pstMp4Parser->pstFSAL, &version, 1))!=FSAL_OK)
return MP4_PARSER_FILE_READ_ERROR;
if((pstMp4Parser->eFSALErr=FSAL_Read_Bytes(pstMp4Parser->pstFSAL, flags, 3))!=FSAL_OK)
return MP4_PARSER_FILE_READ_ERROR;
/* entry_count */
if((pstMp4Parser->eFSALErr=FSAL_Read_UINT(pstMp4Parser->pstFSAL, &entry_count))!=FSAL_OK)
return MP4_PARSER_PARSE_ERROR;
pstMp4Parser->stMp4Track[pstMp4Parser->bCurTrack].uSampleToChunkEntryCount = entry_count;
MP4_PARSER_FILE_GET_CUR_POS(pstMp4Parser->stMp4Track[pstMp4Parser->bCurTrack].uOffsetSampleToChunkTable);
stsc_size-=8;
if((pstMp4Parser->eFSALErr=FSAL_Skip_Bytes(pstMp4Parser->pstFSAL, entry_count*12))!=FSAL_OK)
return MP4_PARSER_PARSE_ERROR;
stsc_size -= (entry_count*12);
if((pstMp4Parser->eFSALErr=FSAL_Skip_Bytes(pstMp4Parser->pstFSAL, stsc_size))!=FSAL_OK)
return MP4_PARSER_FILE_SEEK_ERROR;
pstMp4Parser->stMp4Track[pstMp4Parser->bCurTrack].bHasSTSC = KAL_TRUE;
/* Initilize STSC cache table */
pstMp4Parser->stMp4Track[pstMp4Parser->bCurTrack].uSTSCCacheTableEntryCount = 0;
pstMp4Parser->stMp4Track[pstMp4Parser->bCurTrack].uSTSCCacheTableStepSize = 0;
pstMp4Parser->stMp4Track[pstMp4Parser->bCurTrack].pSTSCCacheTable = NULL;
return MP4_PARSER_OK;
}
/*
DESCRIPTION
Parse the Sample Sizes Box.
INPUT
size: The size of Sample Sizes Box excluding Box
RETURN
MP4_PARSER_OK: Successful
other values: Error
*/
static MP4_Parser_Status mp4_parse_stsz(STMp4Parser *pstMp4Parser, kal_int32 stsz_size)
{
/* Sample Sizes Box is a leaf node. */
kal_uint8 version;
kal_uint8 flags[3];
kal_uint32 sample_size;
kal_uint32 sample_count;
MP4_PARSER_CHECK_ARG(pstMp4Parser!=NULL);
if((pstMp4Parser->eFSALErr=FSAL_Read_Bytes(pstMp4Parser->pstFSAL, &version, 1))!=FSAL_OK)
return MP4_PARSER_FILE_READ_ERROR;
if((pstMp4Parser->eFSALErr=FSAL_Read_Bytes(pstMp4Parser->pstFSAL, flags, 3))!=FSAL_OK)
return MP4_PARSER_FILE_READ_ERROR;
/* sample_size */
if((pstMp4Parser->eFSALErr=FSAL_Read_UINT(pstMp4Parser->pstFSAL, &sample_size))!=FSAL_OK)
return MP4_PARSER_PARSE_ERROR;
if(sample_size!=0) {
pstMp4Parser->stMp4Track[pstMp4Parser->bCurTrack].uConstantSampleSize = sample_size;
} else {
pstMp4Parser->stMp4Track[pstMp4Parser->bCurTrack].uConstantSampleSize = 0;
}
/* sample_count */
if((pstMp4Parser->eFSALErr=FSAL_Read_UINT(pstMp4Parser->pstFSAL, &sample_count))!=FSAL_OK)
return MP4_PARSER_PARSE_ERROR;
pstMp4Parser->stMp4Track[pstMp4Parser->bCurTrack].uSampleCount = sample_count;
pstMp4Parser->stMp4Track[pstMp4Parser->bCurTrack].bSampleCountUpdated = KAL_FALSE;
stsz_size-=12;
if(sample_size==0) {
MP4_PARSER_FILE_GET_CUR_POS(pstMp4Parser->stMp4Track[pstMp4Parser->bCurTrack].uOffsetSampleSizeTable);
if((pstMp4Parser->eFSALErr=FSAL_Skip_Bytes(pstMp4Parser->pstFSAL, sample_count*4))!=FSAL_OK)
return MP4_PARSER_PARSE_ERROR;
stsz_size -= (sample_count*4);
}
if((pstMp4Parser->eFSALErr=FSAL_Skip_Bytes(pstMp4Parser->pstFSAL, stsz_size))!=FSAL_OK)
return MP4_PARSER_FILE_SEEK_ERROR;
return MP4_PARSER_OK;
}
/*
DESCRIPTION
Parse the Chunk Offset Box.
INPUT
size: The size of Chunk Offset Box excluding Box
RETURN
MP4_PARSER_OK: Successful
other values: Error
*/
static MP4_Parser_Status mp4_parse_stco(STMp4Parser *pstMp4Parser, kal_int32 stco_size)
{
/* Chunk Offset Box is a leaf node. */
kal_uint8 version;
kal_uint8 flags[3];
kal_uint32 entry_count;
MP4_PARSER_CHECK_ARG(pstMp4Parser!=NULL);
if((pstMp4Parser->eFSALErr=FSAL_Read_Bytes(pstMp4Parser->pstFSAL, &version, 1))!=FSAL_OK)
return MP4_PARSER_FILE_READ_ERROR;
if((pstMp4Parser->eFSALErr=FSAL_Read_Bytes(pstMp4Parser->pstFSAL, flags, 3))!=FSAL_OK)
return MP4_PARSER_FILE_READ_ERROR;
/* entry_count */
if((pstMp4Parser->eFSALErr=FSAL_Read_UINT(pstMp4Parser->pstFSAL, &entry_count))!=FSAL_OK)
return MP4_PARSER_PARSE_ERROR;
pstMp4Parser->stMp4Track[pstMp4Parser->bCurTrack].uChunkCount = entry_count;
stco_size-=8;
MP4_PARSER_FILE_GET_CUR_POS(pstMp4Parser->stMp4Track[pstMp4Parser->bCurTrack].uOffsetChunkOffsetTable);
if((pstMp4Parser->eFSALErr=FSAL_Skip_Bytes(pstMp4Parser->pstFSAL, entry_count*4))!=FSAL_OK)
return MP4_PARSER_FILE_SEEK_ERROR;
stco_size-=(entry_count*4);
if((pstMp4Parser->eFSALErr=FSAL_Skip_Bytes(pstMp4Parser->pstFSAL, stco_size))!=FSAL_OK)
return MP4_PARSER_FILE_SEEK_ERROR;
pstMp4Parser->stMp4Track[pstMp4Parser->bCurTrack].bHasSTCO = KAL_TRUE;
return MP4_PARSER_OK;
}
/*
DESCRIPTION
Parse the Sync Sample Table Box.
INPUT
size: The size of Sync Sample Table Box excluding Box
RETURN
MP4_PARSER_OK: Successful
Other values: Parse error
*/
static MP4_Parser_Status mp4_parse_stss(STMp4Parser *pstMp4Parser, kal_int32 stss_size)
{
/* Sync Sample Table Box is a leaf node. */
kal_uint8 version;
kal_uint8 flags[3];
kal_uint32 entry_count;
MP4_PARSER_CHECK_ARG(pstMp4Parser!=NULL);
if((pstMp4Parser->eFSALErr=FSAL_Read_Bytes(pstMp4Parser->pstFSAL, &version, 1))!=FSAL_OK)
return MP4_PARSER_FILE_READ_ERROR;
if((pstMp4Parser->eFSALErr=FSAL_Read_Bytes(pstMp4Parser->pstFSAL, flags, 3))!=FSAL_OK)
return MP4_PARSER_FILE_READ_ERROR;
if((pstMp4Parser->eFSALErr=FSAL_Read_UINT(pstMp4Parser->pstFSAL, &entry_count))!=FSAL_OK)
return MP4_PARSER_PARSE_ERROR;
pstMp4Parser->stMp4Track[pstMp4Parser->bCurTrack].uSyncCount = entry_count;
stss_size-=8;
MP4_PARSER_FILE_GET_CUR_POS(pstMp4Parser->stMp4Track[pstMp4Parser->bCurTrack].uOffsetSyncSampleTable);
if((pstMp4Parser->eFSALErr=FSAL_Skip_Bytes(pstMp4Parser->pstFSAL, entry_count*4))!=FSAL_OK)
return MP4_PARSER_FILE_SEEK_ERROR;
stss_size-=(entry_count*4);
if((pstMp4Parser->eFSALErr=FSAL_Skip_Bytes(pstMp4Parser->pstFSAL, stss_size))!=FSAL_OK)
return MP4_PARSER_FILE_SEEK_ERROR;
/* Initilize STSS cache table */
pstMp4Parser->stMp4Track[pstMp4Parser->bCurTrack].uSTSSCacheTableEntryCount = 0;
pstMp4Parser->stMp4Track[pstMp4Parser->bCurTrack].uSTSSCacheTableStepSize = 0;
pstMp4Parser->stMp4Track[pstMp4Parser->bCurTrack].pSTSSCacheTable = NULL;
return MP4_PARSER_OK;
}
/*
DESCRIPTION
Parse the Sample Table Box.
INPUT
size: The size of Sample Table Box excluding Box
RETURN
MP4_PARSER_OK: Successful
other values: Error
*/
static MP4_Parser_Status mp4_parse_stbl(STMp4Parser *pstMp4Parser, kal_int32 stbl_size)
{
MP4_PARSER_CHECK_ARG(pstMp4Parser!=NULL);
/* look for possible nodes of stbl's direct childs */
while(stbl_size>0) {
MP4_Parser_Status ret;
kal_uint32 size;
kal_uint32 type;
if((ret=mp4_parse_box(pstMp4Parser, &size, &type))!=MP4_PARSER_OK)
return ret;
stbl_size-=8;
switch(type) {
case BOX_TYPE_STSD:
if((ret=mp4_parse_stsd(pstMp4Parser, size))!=MP4_PARSER_OK)
return ret;
break;
case BOX_TYPE_STTS:
if((ret=mp4_parse_stts(pstMp4Parser, size))!=MP4_PARSER_OK)
return ret;
break;
case BOX_TYPE_STSC:
if((ret=mp4_parse_stsc(pstMp4Parser, size))!=MP4_PARSER_OK)
return ret;
break;
case BOX_TYPE_STSZ:
if((ret=mp4_parse_stsz(pstMp4Parser, size))!=MP4_PARSER_OK)
return ret;
break;
case BOX_TYPE_STCO:
if((ret=mp4_parse_stco(pstMp4Parser, size))!=MP4_PARSER_OK)
return ret;
break;
case BOX_TYPE_STSS:
if((ret=mp4_parse_stss(pstMp4Parser, size))!=MP4_PARSER_OK)
return ret;
break;
default: /* unrecognized type, skip the box */
if((pstMp4Parser->eFSALErr=FSAL_Skip_Bytes(pstMp4Parser->pstFSAL, size))!=FSAL_OK)
return MP4_PARSER_FILE_SEEK_ERROR;
}
stbl_size-=size;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -