📄 mp4_parser.c
字号:
/*****************************************************************************
* Copyright Statement:
* --------------------
* This software is protected by Copyright and the information contained
* herein is confidential. The software may not be copied and the information
* contained herein may not be used or disclosed except with the written
* permission of MediaTek Inc. (C) 2005
*
* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
*
* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
*
* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
*
*****************************************************************************/
/*******************************************************************************
*
* Filename:
* ---------
* mp4_parser.c
*
* Project:
* --------
* MAUI
*
* Description:
* ------------
* MPEG-4 Parser
*
* Author:
* -------
* -------
*
*==============================================================================
* HISTORY
* Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
*------------------------------------------------------------------------------
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
*------------------------------------------------------------------------------
* Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
*==============================================================================
*******************************************************************************/
#include "mp4_parser.h"
#define SHOW_4_HEX(str, data) \
printf("%s:%x%x%x%x(hex)\n", str, (data[0]), (data[1]), (data[2]), (data[3]));
#define SHOW_4_CHAR(str, data) \
printf("%s:%c%c%c%c(char)\n", str, (data[0]), (data[1]), (data[2]), (data[3]));
/*
DESCRIPTION
Parse the base class Box.
The file pointer advances after the base class Box.
OUTPUT
*size: The size of the box excluding Box
*type: The type of the box
RETURN
MP4_PARSER_OK: Successful
MP4_PARSER_64BIT_NOT_SUPPORT: We do not support 64-bit integers
MP4_PARSER_LARGER_31BIT_NOT_SUPPORT: We do not support numbers larger than 31 bits
*/
MP4_Parser_Status mp4_parse_box(STMp4Parser *pstMp4Parser, kal_uint32 *size, kal_uint32 *type)
{
MP4_PARSER_CHECK_ARG(pstMp4Parser!=NULL);
MP4_PARSER_CHECK_ARG(size!=NULL);
MP4_PARSER_CHECK_ARG(type!=NULL);
if((pstMp4Parser->eFSALErr=FSAL_Read_UINT(pstMp4Parser->pstFSAL, size))!=FSAL_OK)
return MP4_PARSER_FILE_READ_ERROR;
if((pstMp4Parser->eFSALErr=FSAL_Read_UINT(pstMp4Parser->pstFSAL, type))!=FSAL_OK)
return MP4_PARSER_FILE_READ_ERROR;
#if MP4_PARSER_VERBOSE
printf("type=%c%c%c%c size=%u\n",
(*type>>24) & 0xFF, (*type>>16) & 0xFF, (*type>>8) & 0xFF, *type & 0xFF, *size);
#endif
if(*size==1) { /* large size indication */
/* do not support large size */
/* res = fread(&largesize, 8, 1, fpMp4);
if(res!=1) break; */
return MP4_PARSER_64BIT_NOT_SUPPORT;
} else if (*size==0) {
kal_uint32 cur_pos;
// box extends to end of file
if ((pstMp4Parser->eFSALErr = FSAL_GetFileSize(pstMp4Parser->pstFSAL, size)) != FSAL_OK )
return MP4_PARSER_FILE_ACCESS_ERROR;
if ((pstMp4Parser->eFSALErr = FSAL_GetCurPos(pstMp4Parser->pstFSAL, &cur_pos)) != FSAL_OK )
return MP4_PARSER_FILE_ACCESS_ERROR;
if( *size <= cur_pos )
return MP4_PARSER_PARSE_ERROR;
*size -= cur_pos;
*size += 8; // add back the sizes of chunk ID and chunk size fields
}
/*
if (type == BOX_TYPE_UUID) {
unsigned char usertype[16];
res = fread(&usertype, 16, 1, fpMp4);
if(res!=1) break;
} */
/* Do not support size larger than 31 bits */
if((*size)&0x80000000)
return MP4_PARSER_LARGER_31BIT_NOT_SUPPORT;
*size -= 8;
return MP4_PARSER_OK;
}
/*
DESCRIPTION
Seek to the specified atom in the specified range.
The file pointer advances after the base class Box.
INPUT
uBoxType: The type of box to look for
uRange: Search inside the following uRange bytes
OUTPUT
*uSizeBox: The size of the box excluding Box
RETURN
MP4_PARSER_OK: Successful
other values: refer to mp4_parse_box
*/
MP4_Parser_Status mp4_seek_atom(STMp4Parser *pstMp4Parser, kal_uint32 uBoxType, kal_uint32 uRange, kal_uint32 *uSizeBox)
{
MP4_Parser_Status ret;
MP4_PARSER_CHECK_ARG(pstMp4Parser!=NULL);
MP4_PARSER_CHECK_ARG(uSizeBox!=NULL);
while(uRange > 0) {
kal_uint32 size;
kal_uint32 type;
if((ret=mp4_parse_box(pstMp4Parser, &size, &type))!=MP4_PARSER_OK)
return ret;
uRange -= 8;
if(type==uBoxType) {
*uSizeBox = size;
return MP4_PARSER_OK;
}
else { /* unrecognized type, skip the box */
if((pstMp4Parser->eFSALErr=FSAL_Skip_Bytes(pstMp4Parser->pstFSAL, size))!=FSAL_OK)
return MP4_PARSER_FILE_SEEK_ERROR;
}
uRange -= size;
}
if (uRange!=0)
return MP4_PARSER_PARSE_ERROR;
return MP4_PARSER_ATOM_NOT_FOUND;
}
/*
DESCRIPTION
Parse the base descriptor. (Refer to ISO 14496-1)
OUTPUT
*type: The type of the box
*size: The size of the box excluding Box
RETURN
MP4_PARSER_OK: Successful
Other values: Parse error
*/
static MP4_Parser_Status mp4_parse_base_descriptor(STMp4Parser *pstMp4Parser, kal_uint8 *tag, kal_uint32 *size)
{
kal_uint8 tmp;
MP4_PARSER_CHECK_ARG(pstMp4Parser!=NULL);
MP4_PARSER_CHECK_ARG(tag!=NULL);
MP4_PARSER_CHECK_ARG(size!=NULL);
if((pstMp4Parser->eFSALErr=FSAL_Read_Bytes(pstMp4Parser->pstFSAL, tag, 1))!=FSAL_OK)
return MP4_PARSER_FILE_READ_ERROR;
if((pstMp4Parser->eFSALErr=FSAL_Read_Bytes(pstMp4Parser->pstFSAL, &tmp, 1))!=FSAL_OK)
return MP4_PARSER_FILE_READ_ERROR;
*size = (tmp & 0x7F);
while(tmp&0x80) {
if((pstMp4Parser->eFSALErr=FSAL_Read_Bytes(pstMp4Parser->pstFSAL, &tmp, 1))!=FSAL_OK)
return MP4_PARSER_FILE_READ_ERROR;
*size = ((*size) << 7) + (tmp & 0x7F);
}
return MP4_PARSER_OK;
}
/*
DESCRIPTION
Parse the File Type Box.
INPUT
size: The size of File Type Box excluding Box
RETURN
MP4_PARSER_OK: Successful
Other values: Parse error
*/
static MP4_Parser_Status mp4_parse_ftyp(STMp4Parser *pstMp4Parser, kal_int32 ftyp_size)
{
/* File Type Box is a leaf node. */
kal_uint8 major_brand[4];
kal_uint8 minor_version[4];
/// kal_uint8 compatible_brand[4];
MP4_PARSER_CHECK_ARG(pstMp4Parser!=NULL);
if (ftyp_size<8)
return MP4_PARSER_PARSE_ERROR;
if ((pstMp4Parser->eFSALErr=FSAL_Read_Bytes(pstMp4Parser->pstFSAL, major_brand, 4))!=FSAL_OK)
return MP4_PARSER_FILE_READ_ERROR;
if ((pstMp4Parser->eFSALErr=FSAL_Read_Bytes(pstMp4Parser->pstFSAL, minor_version, 4))!=FSAL_OK)
return MP4_PARSER_FILE_READ_ERROR;
ftyp_size -= 8;
#if MP4_PARSER_VERBOSE
SHOW_4_CHAR("major_brand", major_brand);
SHOW_4_HEX("minor_version", minor_version);
#endif
/// Rey: Directly skip the compatible brand to avoid long response time if the size of ftyp is corrupted.
/*
for (i=0; i<ftyp_size/4; i++) {
if ((pstMp4Parser->eFSALErr=FSAL_Read_Bytes(pstMp4Parser->pstFSAL, compatible_brand, 4))!=FSAL_OK)
return MP4_PARSER_FILE_READ_ERROR;
#if MP4_PARSER_VERBOSE
SHOW_4_CHAR("compatible_brand", compatible_brand);
#endif
ftyp_size -= 4;
}
*/
if ((pstMp4Parser->eFSALErr=FSAL_Skip_Bytes(pstMp4Parser->pstFSAL, ftyp_size))!=FSAL_OK)
return MP4_PARSER_FILE_SEEK_ERROR;
return MP4_PARSER_OK;
}
/*
DESCRIPTION
Parse the Movie Header Box.
INPUT
size: The size of Movie Header Box excluding Box
RETURN
MP4_PARSER_OK: Successful
MP4_PARSER_PARSE_ERROR: Parse error
*/
static MP4_Parser_Status mp4_parse_mvhd(STMp4Parser *pstMp4Parser, kal_int32 mvhd_size)
{
/* Move Header Box is a leaf node. */
kal_uint8 version;
kal_uint8 flags[3];
MP4_PARSER_CHECK_ARG(pstMp4Parser!=NULL);
if(mvhd_size<100)
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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -