📄 video_dec_api.c
字号:
//////////////////////////////////////////////////////////////////////////////////////
// **************** //
// Internal use //
// **************** //
//////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////
// //
// Refresh functions //
//////////////////////////////////////////////////////////////////
/* The refresh gpt timer callback function
* @param None
* @return None
*/
static void video_dec_refresh_callback(void * parameter)
{
/*Like video_dec_prev_display*/
GPTI_StopItem(g_video_dec_gpt_refresh_handle);
if (g_video_dec_info_ptr->path_type == VIDEO_DEC_IMG_PATH_HW)
{
#if ( defined(MT6219) || defined(MT6226) || defined(MT6227) || defined(MT6226M) )
if (IMGDMA_CheckBusy(IMGDMA_IBW2_CH, SCENARIO_MPEG_DECODE_ID) == KAL_FALSE)
{
video_dec_prev_display();
}
#else
/*MT6228, MT6229, MT6230*/
if (!IMGDMA_IBW2_IS_BUSY)
{
video_dec_prev_display();
}
#endif
}
if(g_video_dec_gpt_refresh_count > 0)
{
GPTI_StartItem(g_video_dec_gpt_refresh_handle, (VIDEO_MAX_GPT_REFRESH_TIME / 10), video_dec_refresh_callback, NULL);
g_video_dec_gpt_refresh_count--;
}
}
/* Start refresh function.
* @param None
* @return None
*/
void video_dec_start_refresh(void)
{
GPTI_StartItem(g_video_dec_gpt_refresh_handle, (VIDEO_MAX_GPT_REFRESH_TIME / 10), video_dec_refresh_callback, NULL);
g_video_dec_gpt_refresh_count = 0x0fffffff;
}
/* Stop refresh function.
* @param None
* @return None
*/
void video_dec_stop_refresh(void)
{
GPTI_StopItem(g_video_dec_gpt_refresh_handle);
}
/* Check whether it needs to be refresh. If yes, it will refresh automatically in this function
* @param None
* @return None
*/
void video_dec_check_refresh(kal_uint32 frame_time)
{
kal_uint32 refresh_count;
refresh_count = frame_time / VIDEO_MAX_GPT_REFRESH_TIME;
if((refresh_count>0) && (frame_time%VIDEO_MAX_GPT_REFRESH_TIME) <= VIDEO_MAX_GPT_REFRESH_GAURD_TIME)
refresh_count--;
if (refresh_count>0)
{
video_dec_start_refresh();
g_video_dec_gpt_refresh_count = refresh_count;
}
else
{
video_dec_stop_refresh();
}
}
///////////////////////////////////////////////////////////////////
// //
// Control functions //
//////////////////////////////////////////////////////////////////
/* In YUV mode. Store the decoded frame to file
* @param yuv_mem_addr decoded frame start address
* @param size data size
* @return None
*/
#ifdef VIDEO_DEC_YUV_MODE
static void video_dec_store_yuv_file(kal_uint32 yuv_mem_addr, kal_uint32 size)
{
FSAL_Status tmp_status;
tmp_status = FSAL_Write(&FSAL_VIDEO_YUV_FILE, (kal_uint8 *)yuv_mem_addr, size);
if (tmp_status != FSAL_OK)
{
VIDEO_ASSERT(0);
return;
}
}
#endif /*VIDEO_DEC_YUV_MODE*/
/* Initialize the VIDEO_DEC_STRUCT.
* @param dec_struct VIDEO_DEC_STRUCT structure
* @param dec_type DECODE_TYPE_MPEG4 or DECODE_TYPE_H263
* @param VOS the VOS data
* @param total_frame
* @return None
*/
static void video_dec_struct_init(VIDEO_DEC_STRUCT * dec_struct, DECODE_TYPE dec_type, MP4VIDEO_VOS_STRUCT * VOS,
kal_uint32 total_frame)
{
/*Initialize the frame info structure*/
dec_struct->decode_type = DECODE_TYPE_UNKNOW;
dec_struct->VOS = VOS;
dec_struct->decode_type = dec_type;
dec_struct->total_frames_in_file = total_frame;
dec_struct->stop_frame_no = total_frame;
dec_struct->prepare_frames_no = 0;
dec_struct->hdr_parse_frames_no = 0;
dec_struct->dec_frames_no = 0;
dec_struct->skip_frames = 0;
dec_struct->disp_lost_frames = 0;
dec_struct->prepare_recover = 0;
dec_struct->recover_start = 0;
dec_struct->pre_frame_duration = 0;
dec_struct->dec_state = VIDEO_DEC_STATE_UNKOWN;
dec_struct->is_non_coded = KAL_FALSE;
dec_struct->skip_check_isr_status = KAL_FALSE;
dec_struct->video_end = KAL_FALSE;
dec_struct->isr_error_event_happen = KAL_FALSE;
dec_struct->decode_error_frame_count_in_high_speed = 0;
}
/* Initialize get play time and set time parameter in video fiel
* @param None
* @return Media status, which is based MEDIA_STATUS_CODE structure.
*/
static MEDIA_STATUS_CODE video_dec_initialize_play_time(void)
{
kal_uint32 video_time_scale;
kal_uint32 audio_time_scale;
kal_uint32 video_duration;
kal_uint32 audio_duratoin;
/* Video time */
g_video_dec_status.PARSE_STATUS = MP4_GetMediaTimeScale(g_video_dec_info_ptr->pMp4Parser, &video_time_scale,
MP4_TRACK_VIDEO);
if (g_video_dec_status.PARSE_STATUS != MP4_PARSER_NO_SUCH_TRACK)
{
if (g_video_dec_status.PARSE_STATUS != MP4_PARSER_OK)
{
VIDEO_ASSERT(0);
return MP4_PARSER_ERROR;
}
g_video_dec_status.PARSE_STATUS =
MP4_GetMediaDuration(g_video_dec_info_ptr->pMp4Parser, &video_duration, MP4_TRACK_VIDEO);
if (g_video_dec_status.PARSE_STATUS != MP4_PARSER_NO_SUCH_TRACK)
{
if (g_video_dec_status.PARSE_STATUS != MP4_PARSER_OK)
{
VIDEO_ASSERT(0);
return MP4_PARSER_ERROR;
}
}
else
{
video_time_scale = 1;
video_duration = 0;
}
}
else
{
video_time_scale = 1;
video_duration = 0;
}
/* Audio time */
g_video_dec_status.PARSE_STATUS = MP4_GetMediaTimeScale(g_video_dec_info_ptr->pMp4Parser, &audio_time_scale,
MP4_TRACK_AUDIO);
if (g_video_dec_status.PARSE_STATUS != MP4_PARSER_NO_SUCH_TRACK)
{
if (g_video_dec_status.PARSE_STATUS != MP4_PARSER_OK)
{
VIDEO_ASSERT(0);
return MP4_PARSER_ERROR;
}
g_video_dec_status.PARSE_STATUS =
MP4_GetMediaDuration(g_video_dec_info_ptr->pMp4Parser, &audio_duratoin, MP4_TRACK_AUDIO);
if (g_video_dec_status.PARSE_STATUS != MP4_PARSER_NO_SUCH_TRACK)
{
if (g_video_dec_status.PARSE_STATUS != MP4_PARSER_OK)
{
VIDEO_ASSERT(0);
return MP4_PARSER_ERROR;
}
}
else
{
audio_duratoin = 0;
/*When no audio track, media task will insert mute in AMR fomat.The AMR time scale is 8000*/
audio_time_scale = Media_A2V_GetAudioInterruptTimeScale(
MP4_Audio_Type_To_Media_Format(MP4_GetAudioType(g_video_dec_info_ptr->pMp4Parser)),
MP4_Audio_GetFreqIndex(g_video_dec_info_ptr->pMp4Parser));
}
}
else
{
audio_duratoin = 0;
/*When no audio track, media task will insert mute in AMR fomat.The AMR time scale is 8000*/
audio_time_scale = Media_A2V_GetAudioInterruptTimeScale(
MP4_Audio_Type_To_Media_Format(MP4_GetAudioType(g_video_dec_info_ptr->pMp4Parser)),
MP4_Audio_GetFreqIndex(g_video_dec_info_ptr->pMp4Parser));
}
/* set tp video and audio parameters */
g_video_dec_info_ptr->video_time_scale = video_time_scale;
g_video_dec_info_ptr->audio_time_scale = audio_time_scale;
g_video_dec_info_ptr->audio_duration = VIDEO_ANYBASE_TO_MS(audio_duratoin, audio_time_scale);
g_video_dec_info_ptr->video_duration = VIDEO_ANYBASE_TO_MS(video_duration, video_time_scale);
/* translate to common base */
g_video_dec_info_ptr->audio_duration = VIDEO_ANYBASE_TO_COMMBASE(audio_duratoin, audio_time_scale);
g_video_dec_info_ptr->video_duration = VIDEO_ANYBASE_TO_COMMBASE(video_duration, video_time_scale);
if (g_video_dec_info_ptr->total_frames_in_file > 0)
{
g_video_dec_info_ptr->video_avg_frame_duration =
g_video_dec_info_ptr->video_duration / g_video_dec_info_ptr->total_frames_in_file;
}
else
{
g_video_dec_info_ptr->video_avg_frame_duration = 0;
}
return MEDIA_STATUS_OK;
}
/* Common initialize function for play and clip play
* Please run Mp4 parser first
* @param comm_init_input. MP4DEC_COMM_INIT_STRUCT type
* @return None
*/
static MEDIA_STATUS_CODE video_dec_comm_initialize(MP4DEC_COMM_INIT_STRUCT * comm_init_input)
{
kal_uint32 total_frames;
MP4VIDEO_VOS_STRUCT *VOS = NULL;
MEDIA_STATUS_CODE result;
/*Tricky to avoid Video display issue*/
VIDEO_MAX_GPT_REFRESH_TIME = VIDEO_MAX_GPT_REFRESH_TIME_DEF;
/* open and init resource first */
result = video_dec_open(comm_init_input->pstMp4Parser,
comm_init_input->pstFSAL,
comm_init_input->max_width,
comm_init_input->max_height);
if (result != MEDIA_STATUS_OK)
{
VIDEO_ASSERT(0);
return result;
}
if (video_file_get_decode_type() != DECODE_TYPE_UNKNOW)
{
/* init av setting */
result = video_dec_init_av(comm_init_input->audio_enable);
if (result != MEDIA_STATUS_OK)
{
VIDEO_ASSERT(0);
return result;
}
/* Get total frame no information from file and check it*/
g_video_dec_status.PARSE_STATUS = MP4_GetSampleCount(g_video_dec_info_ptr->pMp4Parser, MP4_TRACK_VIDEO,
&total_frames);
if (g_video_dec_status.PARSE_STATUS != MP4_PARSER_OK)
{
VIDEO_ASSERT(0);
return MP4_PARSER_ERROR;
}
if (total_frames == 0)
{
if (comm_init_input->incall == KAL_TRUE)
{
ASSERT(0);
}
#if defined(__VIDEO_EDITOR__)
if (g_video_dec_status.scenario == VIDEO_SCENARIO_EDITOR)
{
ASSERT(0);
}
else
#endif /*__VIDEO_EDITOR__*/
{
/* for files that total frame == 0, return complete directly */
comm_init_input->video_dec_callback(VIDEO_DEC_EVENT_COMPLETE);
}
return MEDIA_STATUS_OK;
}
/* check file type and VOS */
if (video_file_get_decode_type() != DECODE_TYPE_H263)
{
/* If it is not H263, VOS is needed */
result = video_file_get_vos_data(&VOS);
if (result != MEDIA_STATUS_OK)
{
VIDEO_ASSERT(0);
return result;
}
}
/* initailie decode globale variable parameters */
video_dec_disable_irq();
video_dec_stop_av();
video_dec_struct_init(g_video_dec_info_ptr, video_file_get_decode_type(), VOS, total_frames);
g_video_dec_info_ptr->lost_frames = 0;
g_video_dec_info_ptr->video_end = KAL_FALSE;
g_video_dec_info_ptr->resz_work_memory = 0;
g_video_dec_info_ptr->snapshot_resize_memory = 0;
g_video_dec_info_ptr->snapshot_imgdma_memory = 0;
g_video_dec_info_ptr->incall = comm_init_input->incall;
g_video_dec_info_ptr->audio_enable = comm_init_input->audio_enable;
/* initialize play time information */
result = video_dec_initialize_play_time();
if (result != MEDIA_STATUS_OK)
{
VIDEO_ASSERT(0);
return result;
}
if (comm_init_input->incall == KAL_FALSE)
{
/* decode initialize */
#if defined(__VIDEO_EDITOR__)
if (g_video_dec_status.scenario == VIDEO_SCENARIO_DECODE)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -