📄 vid_avi.c
字号:
*
*****************************************************************************/
kal_int32 med_avi_close_play_array(void)
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
return med_avi_close_play_internal();
}
/*****************************************************************************
* FUNCTION
* med_avi_open_play_internal
* DESCRIPTION
*
* PARAMETERS
* avi_info_p [?]
* filename [IN]
* data_p [?]
* data_size [IN]
* RETURNS
*
*****************************************************************************/
static kal_int32 med_avi_open_play_internal(
med_avi_info_struct *avi_info_p,
const kal_wchar *filename,
kal_char *data_p,
kal_int32 data_size)
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
kal_uint32 data_dword;
FSAL_Status ret;
kal_bool is_file_opened;
kal_int32 error_cause;
med_avi_stream_header_struct stream_header;
kal_int32 cur_pos;
kal_int32 chunk_size;
kal_uint32 file_size;
kal_uint32 file_pos;
kal_uint32 idx_count;
kal_uint32 aud_idx;
kal_uint32 vid_idx;
kal_uint32 idx_id;
kal_uint32 i;
kal_uint32 start_time;
kal_uint32 current_time;
kal_uint32 elapse_time;
med_avi_index_struct idx_data;
med_avi_index_struct *idx_p;
kal_uint32 max_idx_count;
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
kal_prompt_trace(MOD_MED, "[MED AVI] med_avi_open_play_internal()");
kal_get_time(&start_time);
/* init */
med_avi_p->vid_frame_idx = 0;
med_avi_p->vid_total_frame = 0;
med_avi_p->aud_total_frame = 0;
med_avi_p->aud_frame_idx = 0;
med_avi_p->aud_remain_len = 0;
med_avi_p->is_valid_aud = KAL_FALSE;
memset((void*)&med_avi_p->file_header, 0, sizeof(med_avi_file_header_struct));
memset((void*)&med_avi_p->video_stream_header, 0, sizeof(med_avi_stream_header_struct));
memset((void*)&med_avi_p->audio_stream_header, 0, sizeof(med_avi_stream_header_struct));
is_file_opened = KAL_FALSE;
/* allocate buffer */
med_avi_p->vid_fsal_buf_p = (kal_char*) med_alloc_ext_mem(MED_AVI_VID_FSAL_BUF_SIZE);
ASSERT(med_avi_p->vid_fsal_buf_p != 0);
med_avi_p->aud_fsal_buf_p = (kal_char*) med_alloc_ext_mem(MED_AVI_AUD_FSAL_BUF_SIZE);
ASSERT(med_avi_p->aud_fsal_buf_p != 0);
med_avi_p->vid_idx_list_buf_p = (med_avi_index_struct*) med_alloc_ext_mem(MED_AVI_FSAL_IDX_BUF_SIZE);
ASSERT(med_avi_p->vid_idx_list_buf_p != 0);
med_avi_p->aud_idx_list_buf_p = (med_avi_index_struct*) med_alloc_ext_mem(MED_AVI_FSAL_IDX_BUF_SIZE);
ASSERT(med_avi_p->aud_idx_list_buf_p != 0);
/* TODO: add parse timeout protection */
/* open resource, create FSAL */
if (filename != NULL)
{
/* open from file - vid */
ret = FSAL_Open(&med_avi_p->vid_fsal_cntx, (void*)filename, FSAL_READ);
/* open from file - aud */
ret = FSAL_Open(&med_avi_p->aud_fsal_cntx, (void*)filename, FSAL_READ);
FSAL_SetBuffer(&med_avi_p->vid_fsal_cntx, MED_AVI_VID_FSAL_BUF_SIZE, (kal_uint8*) med_avi_p->vid_fsal_buf_p);
FSAL_SetBuffer(&med_avi_p->aud_fsal_cntx, MED_AVI_AUD_FSAL_BUF_SIZE, (kal_uint8*) med_avi_p->aud_fsal_buf_p);
}
else
{
/* open from memory */
FSAL_Direct_SetRamFileSize(&med_avi_p->vid_fsal_cntx, data_size);
ret = FSAL_Open(&med_avi_p->vid_fsal_cntx, (void*)data_p, FSAL_ROMFILE);
FSAL_Direct_SetRamFileSize(&med_avi_p->aud_fsal_cntx, data_size);
ret = FSAL_Open(&med_avi_p->aud_fsal_cntx, (void*)data_p, FSAL_ROMFILE);
FSAL_SetBuffer(&med_avi_p->vid_fsal_cntx, MED_AVI_VID_FSAL_BUF_SIZE, (kal_uint8*) med_avi_p->vid_fsal_buf_p);
FSAL_SetBuffer(&med_avi_p->aud_fsal_cntx, MED_AVI_AUD_FSAL_BUF_SIZE, (kal_uint8*) med_avi_p->aud_fsal_buf_p);
}
if (ret != FSAL_OK)
{
error_cause = MED_RES_OPEN_FILE_FAIL;
goto error;
}
else
{
is_file_opened = KAL_TRUE;
}
FSAL_GetFileSize(&med_avi_p->vid_fsal_cntx, &file_size);
if (file_size == 0)
{
error_cause = MED_RES_BAD_FORMAT;
goto error;
}
/*
* [AVI File Format] for MJPEG
*
* RIFF.4.AVI .
* LIST.4.hdlr.avih.4.(file header)
* LIST.4.strl.strh.4.(video header)
* .strf.4.(video format)
* LIST.4.strl.strh.4.(audio header)
* .strf.4.(audio format)
* JUNK.4.(junk)
* LIST.4.movi.xxdb.4.(video data)
* xxdc.4.(video data)
* xxwb.4.(audio data)
* ind1.4.(list data)
*/
/* read RIFF header and get size */
FETCH_AND_CHECK_TAG(&data_dword, MED_AVI_TAG_RIFF);
FETCH_SIZE();
med_avi_p->riff_size = chunk_size;
/* read AVI type */
FETCH_AND_CHECK_TAG(&data_dword, MED_AVI_TAG_AVI);
while (1)
{
/* avoid decode too long */
kal_get_time(¤t_time);
kal_prompt_trace(MOD_MED, "[MED AVI] cur time: %d, start_time: %d", current_time, start_time);
if (current_time >= start_time)
{
elapse_time = current_time - start_time;
}
else
{
/* wrap around case */
elapse_time = current_time - (0xFFFFFFFF - 1 - start_time);
}
if (elapse_time > MED_AVI_MAX_PARSING_TIME)
{
error_cause = MED_RES_VIDEO_FILE_TOO_LARGE;
goto error;
}
FSAL_GetCurPos(&med_avi_p->vid_fsal_cntx, &file_pos);
if (file_pos >= file_size)
{
/* teminate condition */
break;
}
/* read LIST or JUNK */
FETCH_TAG(&data_dword);
if (IS_TAG_MATCH(&data_dword, MED_AVI_TAG_LIST))
{
/* LIST */
FETCH_SIZE();
/* read tag */
FETCH_TAG(&data_dword);
if (IS_TAG_MATCH(&data_dword, MED_AVI_TAG_HEADER_LIST))
{
kal_prompt_trace(MOD_MED, "[MED AVI] parse file header");
/* avhi */
FETCH_AND_CHECK_TAG(&data_dword, MED_AVI_TAG_AVI_HEADER);
FETCH_SIZE();
FETCH_DATA(&med_avi_p->file_header, sizeof(med_avi_file_header_struct));
GOTO_NEXT_CHUNK();
kal_prompt_trace(MOD_MED, "[MED AVI] parse file header - done");
}
else if (IS_TAG_MATCH(&data_dword, MED_AVI_TAG_STREAM_LIST))
{
/* strl readed */
/* read strh */
FETCH_AND_CHECK_TAG(&data_dword, MED_AVI_TAG_STREAM_HEADER);
FETCH_SIZE();
FETCH_DATA(&stream_header, sizeof(med_avi_stream_header_struct));
if (IS_TAG_MATCH(&stream_header.fcc_type, MED_AVI_TAG_STREAM_TYPE_VID))
{
kal_prompt_trace(MOD_MED, "[MED AVI] parse vid header");
MAKE_UPPER(&stream_header.fcc_hdlr);
if (IS_TAG_NOT_MATCH(&stream_header.fcc_hdlr, MED_AVI_TAG_MJPG))
{
error_cause = MED_RES_BAD_FORMAT;
goto error;
}
/* video type */
memcpy(
(char*)&med_avi_p->video_stream_header,
&stream_header,
sizeof(med_avi_stream_header_struct));
GOTO_NEXT_CHUNK();
/* read video strh */
FETCH_AND_CHECK_TAG(&data_dword, MED_AVI_TAG_STREAM_FORMAT);
FETCH_SIZE();
FETCH_DATA(&med_avi_p->video_format_header, sizeof(med_avi_video_format_header_struct));
GOTO_NEXT_CHUNK();
kal_prompt_trace(MOD_MED, "[MED AVI] parse vid header - done");
}
else if (IS_TAG_MATCH(&stream_header.fcc_type, MED_AVI_TAG_STREAM_TYPE_AUD))
{
kal_prompt_trace(MOD_MED, "[MED AVI] parse aud header");
/* audio type */
memcpy(
(char*)&med_avi_p->audio_stream_header,
&stream_header,
sizeof(med_avi_stream_header_struct));
GOTO_NEXT_CHUNK();
/* read audio strh */
FETCH_AND_CHECK_TAG(&data_dword, MED_AVI_TAG_STREAM_FORMAT);
FETCH_SIZE();
FETCH_DATA(&med_avi_p->audio_format_header, sizeof(med_avi_audio_format_header_struct));
if (med_avi_p->audio_format_header.format == MED_AVI_AUD_FORMAT_WAV_PCM)
{
kal_prompt_trace(MOD_MED, "[MED AVI] aud:on");
med_avi_p->is_valid_aud = KAL_TRUE;
}
else
{
kal_prompt_trace(MOD_MED, "[MED AVI] aud:off");
med_avi_p->is_valid_aud = KAL_FALSE;
}
GOTO_NEXT_CHUNK();
kal_prompt_trace(MOD_MED, "[MED AVI] parse aud header - done");
}
else
{
/* unknow fourCC type */
}
}
else if (IS_TAG_MATCH(&data_dword, MED_AVI_TAG_MOVI))
{
kal_prompt_trace(MOD_MED, "[MED AVI] parse movi");
/* movi - skip when parsing */
GOTO_NEXT_CHUNK();
/* idx1 */
FETCH_AND_CHECK_TAG(&data_dword, MED_AVI_TAG_IDX1);
FETCH_SIZE();
/* calc a and v buffer can put how many idx struct */
max_idx_count = MED_AVI_FSAL_IDX_BUF_SIZE/sizeof(med_avi_index_struct);
idx_count = chunk_size / sizeof(med_avi_index_struct);
aud_idx = 0;
vid_idx = 0;
for (i = 0; i < idx_count; i++)
{
FETCH_DATA(&idx_data, sizeof(med_avi_index_struct));
idx_id = idx_data.chunk_id & 0xFFFF0000;
if (idx_id == 0x62770000) /* 00wb */
{
if (med_avi_p->is_valid_aud)
{
if (aud_idx >= max_idx_count)
{
error_cause = MED_RES_VIDEO_FILE_TOO_LARGE;
goto error;
}
/* wb - audio */
memcpy(&med_avi_p->aud_idx_list_buf_p[aud_idx], &idx_data, sizeof(med_avi_index_struct));
aud_idx++;
}
}
else if (idx_id == 0x62640000) /* 00db */
{
if (vid_idx >= max_idx_count)
{
error_cause = MED_RES_VIDEO_FILE_TOO_LARGE;
goto error;
}
/* db - video */
memcpy(&med_avi_p->vid_idx_list_buf_p[vid_idx], &idx_data, sizeof(med_avi_index_struct));
vid_idx++;
}
else if (idx_id == 0x63640000) /* 00dc */
{
if (vid_idx >= max_idx_count)
{
error_cause = MED_RES_VIDEO_FILE_TOO_LARGE;
goto error;
}
/* dc - video */
memcpy(&med_avi_p->vid_idx_list_buf_p[vid_idx], &idx_data, sizeof(med_avi_index_struct));
vid_idx++;
}
}
med_avi_p->vid_total_frame = vid_idx;
med_avi_p->aud_total_frame = aud_idx;
/* load into index catch */
GOTO_NEXT_CHUNK();
kal_prompt_trace(MOD_MED, "[MED AVI] parse movi - done");
}
else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -