📄 mp4_parser.c
字号:
/* creation_time */
if((pstMp4Parser->eFSALErr=FSAL_Skip_Bytes(pstMp4Parser->pstFSAL, 4))!=FSAL_OK)
return MP4_PARSER_PARSE_ERROR;
/* modification_time */
if((pstMp4Parser->eFSALErr=FSAL_Skip_Bytes(pstMp4Parser->pstFSAL, 4))!=FSAL_OK)
return MP4_PARSER_PARSE_ERROR;
if((pstMp4Parser->eFSALErr=FSAL_Read_UINT(pstMp4Parser->pstFSAL, &(pstMp4Parser->timescale)))!=FSAL_OK)
return MP4_PARSER_PARSE_ERROR;
if((pstMp4Parser->eFSALErr=FSAL_Read_UINT(pstMp4Parser->pstFSAL, &(pstMp4Parser->duration)))!=FSAL_OK)
return MP4_PARSER_PARSE_ERROR;
if((pstMp4Parser->eFSALErr=FSAL_Skip_Bytes(pstMp4Parser->pstFSAL, 76))!=FSAL_OK)
return MP4_PARSER_PARSE_ERROR;
if((pstMp4Parser->eFSALErr=FSAL_Read_UINT(pstMp4Parser->pstFSAL, &(pstMp4Parser->next_track_ID)))!=FSAL_OK)
return MP4_PARSER_PARSE_ERROR;
mvhd_size -= 100;
if((pstMp4Parser->eFSALErr=FSAL_Skip_Bytes(pstMp4Parser->pstFSAL, mvhd_size))!=FSAL_OK)
return MP4_PARSER_FILE_SEEK_ERROR;
pstMp4Parser->bHasMVHD = KAL_TRUE;
return MP4_PARSER_OK;
}
/*
DESCRIPTION
Parse the Track Header Box.
INPUT
size: The size of Track Header Box excluding Box
RETURN
MP4_PARSER_OK: Successful
other values: Error
*/
static MP4_Parser_Status mp4_parse_tkhd(STMp4Parser *pstMp4Parser, kal_int32 tkhd_size)
{
/* Track Header Box is a leaf node. */
kal_uint8 version;
kal_uint8 flags[3];
kal_uint32 creation_time;
kal_uint32 modification_time;
kal_uint32 track_ID;
kal_uint32 duration;
kal_uint32 width;
kal_uint32 height;
MP4_PARSER_CHECK_ARG(pstMp4Parser!=NULL);
if(tkhd_size<84)
return MP4_PARSER_PARSE_ERROR;
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(version==1) /* We do not support 64 bit values. */
return MP4_PARSER_64BIT_NOT_SUPPORT;
if((pstMp4Parser->eFSALErr=FSAL_Read_UINT(pstMp4Parser->pstFSAL, &creation_time))!=FSAL_OK)
return MP4_PARSER_PARSE_ERROR;
if((pstMp4Parser->eFSALErr=FSAL_Read_UINT(pstMp4Parser->pstFSAL, &modification_time))!=FSAL_OK)
return MP4_PARSER_PARSE_ERROR;
if((pstMp4Parser->eFSALErr=FSAL_Read_UINT(pstMp4Parser->pstFSAL, &track_ID))!=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, &duration))!=FSAL_OK)
return MP4_PARSER_PARSE_ERROR;
if((pstMp4Parser->eFSALErr=FSAL_Skip_Bytes(pstMp4Parser->pstFSAL, 52))!=FSAL_OK)
return MP4_PARSER_PARSE_ERROR;
if((pstMp4Parser->eFSALErr=FSAL_Read_UINT(pstMp4Parser->pstFSAL, &width))!=FSAL_OK)
return MP4_PARSER_PARSE_ERROR;
if((pstMp4Parser->eFSALErr=FSAL_Read_UINT(pstMp4Parser->pstFSAL, &height))!=FSAL_OK)
return MP4_PARSER_PARSE_ERROR;
#if MP4_PARSER_VERBOSE
printf("track_ID=%u, width=%u, height=%u\n", track_ID, width>>16, height>>16);
#endif
tkhd_size -= 84;
if((pstMp4Parser->eFSALErr=FSAL_Skip_Bytes(pstMp4Parser->pstFSAL, tkhd_size))!=FSAL_OK)
return MP4_PARSER_FILE_SEEK_ERROR;
pstMp4Parser->stMp4Track[pstMp4Parser->bCurTrack].bHasTKHD = KAL_TRUE;
return MP4_PARSER_OK;
}
/*
DESCRIPTION
Parse the Media Header Box.
INPUT
size: The size of Media Header Box excluding Box
RETURN
MP4_PARSER_OK: Successful
other values: Error
*/
static MP4_Parser_Status mp4_parse_mdhd(STMp4Parser *pstMp4Parser, kal_int32 mdhd_size)
{
/* Media Header Box is a leaf node. */
kal_uint8 version;
kal_uint8 flags[3];
kal_uint32 uTimeScale;
kal_uint32 uDuration;
MP4_PARSER_CHECK_ARG(pstMp4Parser!=NULL);
if (mdhd_size<24)
return MP4_PARSER_PARSE_ERROR;
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 (version==1) /* We do not support 64 bit values. */
return MP4_PARSER_64BIT_NOT_SUPPORT;
/* creation_time */
if ((pstMp4Parser->eFSALErr=FSAL_Skip_Bytes(pstMp4Parser->pstFSAL, 4))!=FSAL_OK)
return MP4_PARSER_PARSE_ERROR;
/* modification_time */
if ((pstMp4Parser->eFSALErr=FSAL_Skip_Bytes(pstMp4Parser->pstFSAL, 4))!=FSAL_OK)
return MP4_PARSER_PARSE_ERROR;
if ((pstMp4Parser->eFSALErr=FSAL_Read_UINT(pstMp4Parser->pstFSAL, &uTimeScale))!=FSAL_OK)
return MP4_PARSER_PARSE_ERROR;
if ((pstMp4Parser->eFSALErr=FSAL_Read_UINT(pstMp4Parser->pstFSAL, &uDuration))!=FSAL_OK)
return MP4_PARSER_PARSE_ERROR;
pstMp4Parser->stMp4Track[pstMp4Parser->bCurTrack].uMediaTimeScale = uTimeScale;
pstMp4Parser->stMp4Track[pstMp4Parser->bCurTrack].uMediaDuration = uDuration;
/* ISO-639-2/T language code */
if ((pstMp4Parser->eFSALErr=FSAL_Skip_Bytes(pstMp4Parser->pstFSAL, 4))!=FSAL_OK)
return MP4_PARSER_PARSE_ERROR;
mdhd_size -= 24;
if((pstMp4Parser->eFSALErr=FSAL_Skip_Bytes(pstMp4Parser->pstFSAL, mdhd_size))!=FSAL_OK)
return MP4_PARSER_FILE_SEEK_ERROR;
pstMp4Parser->stMp4Track[pstMp4Parser->bCurTrack].bHasMDHD = KAL_TRUE;
return MP4_PARSER_OK;
}
/*
DESCRIPTION
Parse the Handler Reference Box.
INPUT
size: The size of Handler Reference Box excluding Box
RETURN
MP4_PARSER_OK: Successful
other values: Error
*/
static MP4_Parser_Status mp4_parse_hdlr(STMp4Parser *pstMp4Parser, kal_int32 hdlr_size)
{
/* Handler Reference Box is a leaf node. */
kal_uint8 version;
kal_uint8 flags[3];
kal_uint32 *puHandlerType;
MP4_PARSER_CHECK_ARG(pstMp4Parser!=NULL);
if(hdlr_size<24)
return MP4_PARSER_PARSE_ERROR;
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_Skip_Bytes(pstMp4Parser->pstFSAL, 4))!=FSAL_OK)
return MP4_PARSER_PARSE_ERROR;
MP4_PARSER_ASSERT(pstMp4Parser->bCurTrack < MP4_NUM_TRACKS);
puHandlerType = &(pstMp4Parser->stMp4Track[pstMp4Parser->bCurTrack].handler_type);
if((pstMp4Parser->eFSALErr=FSAL_Read_UINT(pstMp4Parser->pstFSAL, puHandlerType))!=FSAL_OK)
return MP4_PARSER_PARSE_ERROR;
if (HDLR_TYPE_SOUN == *puHandlerType) {
pstMp4Parser->bAudioTrack = pstMp4Parser->bCurTrack;
} else if (HDLR_TYPE_VIDE == *puHandlerType) {
pstMp4Parser->bVideoTrack = pstMp4Parser->bCurTrack;
}
if((pstMp4Parser->eFSALErr=FSAL_Skip_Bytes(pstMp4Parser->pstFSAL, 12))!=FSAL_OK)
return MP4_PARSER_PARSE_ERROR;
hdlr_size -= 24;
if((pstMp4Parser->eFSALErr=FSAL_Skip_Bytes(pstMp4Parser->pstFSAL, hdlr_size))!=FSAL_OK)
return MP4_PARSER_FILE_SEEK_ERROR;
pstMp4Parser->stMp4Track[pstMp4Parser->bCurTrack].bHasHDLR = KAL_TRUE;
return MP4_PARSER_OK;
}
/*
DESCRIPTION
Parse Elementary Stream Descriptor(ESD) Box.
Refer to 14496-14 and 14496-1.
INPUT
size: The size of ESD Box excluding Box
RETURN
MP4_PARSER_OK: Successful
other values: Error
*/
MP4_Parser_Status mp4_parse_esds(STMp4Parser *pstMp4Parser, kal_int32 esds_size)
{
/* ESD Box is a leaf node. */
kal_uint8 version;
kal_uint8 flags[3];
/* ES Descriptor */
kal_uint16 ES_ID;
kal_uint8 flag;
/* Decoder COnfig Descriptor */
kal_uint8 objectTypeIndication;
kal_uint8 streamType;
kal_uint32 bufferSizeDB;
kal_uint32 maxBitrate;
kal_uint32 avgBitrate;
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;
esds_size -= 4;
/* ES_Descriptor */
{
MP4_Parser_Status ret;
kal_uint8 tag;
kal_uint32 size;
kal_uint32 pos1, pos2;
MP4_PARSER_FILE_GET_CUR_POS(pos1);
if((ret=mp4_parse_base_descriptor(pstMp4Parser, &tag, &size))!=MP4_PARSER_OK)
return ret;
MP4_PARSER_FILE_GET_CUR_POS(pos2);
esds_size -= pos2-pos1;
if(tag!=0x03) /* ES_DescrTag */
return MP4_PARSER_ES_DESCR_TAG_EXPECTED;
if((pstMp4Parser->eFSALErr=FSAL_Read_UINT16(pstMp4Parser->pstFSAL, &ES_ID))!=FSAL_OK)
return MP4_PARSER_PARSE_ERROR;
if((pstMp4Parser->eFSALErr=FSAL_Read_Bytes(pstMp4Parser->pstFSAL, &flag, 1))!=FSAL_OK)
return MP4_PARSER_FILE_READ_ERROR;
#if 0
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
#endif
esds_size -= 3;
}
/* DecoderConfigDescription */
{
MP4_Parser_Status ret;
kal_uint8 tag;
kal_uint32 size;
kal_uint32 pos1, pos2;
MP4_PARSER_FILE_GET_CUR_POS(pos1);
if((ret=mp4_parse_base_descriptor(pstMp4Parser, &tag, &size))!=MP4_PARSER_OK)
return ret;
MP4_PARSER_FILE_GET_CUR_POS(pos2);
esds_size -= (pos2-pos1);
if(tag!=0x04) /* DecoderConfigDescrTag */
return MP4_PARSER_PARSE_ERROR;
if((pstMp4Parser->eFSALErr=FSAL_Read_Bytes(pstMp4Parser->pstFSAL, &objectTypeIndication, 1))!=FSAL_OK)
return MP4_PARSER_FILE_READ_ERROR;
if((pstMp4Parser->eFSALErr=FSAL_Read_Bytes(pstMp4Parser->pstFSAL, &streamType, 1))!=FSAL_OK)
return MP4_PARSER_FILE_READ_ERROR;
streamType = (unsigned char)(streamType >> 2);
if((pstMp4Parser->eFSALErr=FSAL_Read_Bytes(pstMp4Parser->pstFSAL, (kal_uint8*)&bufferSizeDB, 3))!=FSAL_OK)
return MP4_PARSER_FILE_READ_ERROR;
if((pstMp4Parser->eFSALErr=FSAL_Read_UINT(pstMp4Parser->pstFSAL, &maxBitrate))!=FSAL_OK)
return MP4_PARSER_PARSE_ERROR;
if((pstMp4Parser->eFSALErr=FSAL_Read_UINT(pstMp4Parser->pstFSAL, &avgBitrate))!=FSAL_OK)
return MP4_PARSER_PARSE_ERROR;
esds_size -= 13;
}
/* DecoderSpecificInfo */
{
MP4_Parser_Status ret;
kal_uint8 tag;
kal_uint32 size;
kal_uint32 pos1, pos2;
MP4_PARSER_FILE_GET_CUR_POS(pos1);
if ((ret=mp4_parse_base_descriptor(pstMp4Parser, &tag, &size))!=MP4_PARSER_OK)
return ret;
MP4_PARSER_FILE_GET_CUR_POS(pos2);
esds_size -= pos2-pos1;
if (tag!=0x05) /* DecSpecificInfoTag */
return MP4_PARSER_PARSE_ERROR;
if (0x05==streamType) { /* streamType == Audio Stream */
if (0x40==objectTypeIndication) {
/* objectType == 14496-3 */
mp4_parse_decoder_config_14496_3(pstMp4Parser, size);
esds_size -= size;
pstMp4Parser->bAudioType = MP4_AUDIO_AAC;
pstMp4Parser->uAudioMaxBitrate = maxBitrate;
pstMp4Parser->uAudioAvgBitrate = avgBitrate;
} else if (objectTypeIndication==0xD0) {
/* amr produced by PacketVideo Author, not standard */
}
} else if (0x04==streamType) { /* streamType == Visual Stream */
if (0x20==objectTypeIndication) {
/* objectType == 14496-2 */
/* for video, the following is video-object-sequence */
pstMp4Parser->bVideoType = MP4_VIDEO_MPEG4;
MP4_PARSER_FILE_GET_CUR_POS(pstMp4Parser->uVOSOffset);
pstMp4Parser->uVOSSize = size;
#if 0
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
#endif
}
}
}
if((pstMp4Parser->eFSALErr=FSAL_Skip_Bytes(pstMp4Parser->pstFSAL, esds_size))!=FSAL_OK)
return MP4_PARSER_FILE_SEEK_ERROR;
return MP4_PARSER_OK;
}
/*
DESCRIPTION
Parse the Sample Description Box.
INPUT
size: The size of Sample Description Box excluding Box
RETURN
MP4_PARSER_OK: Successful
other values: Error
*/
static MP4_Parser_Status mp4_parse_stsd(STMp4Parser *pstMp4Parser, kal_int32 stsd_size)
{
/* Sample Description Box is a leaf node. */
kal_uint8 version;
kal_uint8 flags[3];
kal_uint32 entry_count;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -