📄 video_dec_api.c
字号:
#endif /*__VIDEO_EDITOR__*/
{
#ifndef __L1_STANDALONE__
result = video_dec_seek_by_frame(comm_init_input->start_frame_no, comm_init_input->video_dec_callback, KAL_TRUE);
#else /*__L1_STANDALONE__*/
result = video_dec_seek(50, comm_init_input->video_dec_callback);
#endif /*__L1_STANDALONE__*/
if (result != MEDIA_STATUS_OK)
{
VIDEO_ASSERT(0);
return result;
}
}
}
else
{
/* clip initialize */
kal_uint32 frame_length;
kal_uint32 prev_frame_duration;
kal_uint8 *frame_addr;
/* check whether media file is legal or not */
result = video_dec_clip_check_media_file(g_video_dec_info_ptr->pMp4Parser,
g_video_dec_info_ptr->pstFSAL, 0xffffffff);
if (result != MEDIA_STATUS_OK)
{
VIDEO_ASSERT(0);
return result;
}
/* direcly decode here, but not seek like normal decode initailize */
/* prepare parameter and buffer */
g_video_dec_info_ptr->seek_frame_number = 1;
g_video_dec_info_ptr->seek_result_frame_number = 1;
g_video_dec_info_ptr->prepare_frames_no = 0;
g_video_dec_info_ptr->hdr_parse_frames_no = 0;
g_video_dec_info_ptr->dec_frames_no = 0;
video_dec_clr_buffer(g_video_dec_info_ptr->prepare_frames_no, g_video_dec_info_ptr->prepare_frames_no + 1);
result = video_dec_put_frame_to_buffer();
if (result != MEDIA_STATUS_OK)
{
VIDEO_ASSERT(0);
return result;
}
/* get frame and start to decode */
result = video_dec_get_next_frame(&frame_addr, &frame_length, &prev_frame_duration);
if (result != MEDIA_STATUS_OK)
{
VIDEO_ASSERT(0);
return result;
}
/* decode the first frame and write to register */
result = mpeg4_decode_start((kal_uint8 *)g_video_dec_info_ptr->VOS,
(g_video_dec_info_ptr->decode_type == DECODE_TYPE_H263),
frame_addr,
frame_length,
KAL_TRUE);
if (result != MEDIA_STATUS_OK)
{
VIDEO_ASSERT(0);
return result;
}
mpeg4_decode_write_register();
}
}
else /* video_file_get_decode_type() == DECODE_TYPE_UNKNOW*/
{
g_video_dec_info_ptr->incall = comm_init_input->incall;
g_video_dec_info_ptr->audio_enable = comm_init_input->audio_enable;
video_dec_struct_init(g_video_dec_info_ptr, DECODE_TYPE_UNKNOW, NULL, 0);
video_dec_disable_irq();
video_dec_stop_av();
/* 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_TRUE)
{
/* response not support to clip initailize */
g_video_dec_status.VIDEO_STATUS = VIDEO_DEC_NOT_SUPPORT;
VIDEO_ASSERT(0);
return VIDEO_ERROR;
}
ASSERT(comm_init_input->video_dec_callback != NULL);
#if defined(__VIDEO_EDITOR__)
if (g_video_dec_status.scenario == VIDEO_SCENARIO_EDITOR)
{
comm_init_input->video_dec_callback(VIDEO_EDITOR_DEC_EVENT_NO_TRACK);
}
else
#endif /*__VIDEO_EDITOR__*/
{
/* response this instead of normal seek done message */
comm_init_input->video_dec_callback(VIDEO_DEC_EVENT_NO_TRACK);
}
}
return MEDIA_STATUS_OK;
}
/* This function initialize the video decode module.
* @param init_input MP4DEC_INIT_STRUCT
* @param max_width maximum width that application wishes ti support
* @param max_height maximum height that application wishes ti support
* @return Media status, which is based MEDIA_STATUS_CODE structure.
*/
MEDIA_STATUS_CODE video_decoder_initialize(MP4DEC_INIT_STRUCT * init_input, kal_uint32 max_width, kal_uint32 max_height)
{
MEDIA_STATUS_CODE result;
MP4DEC_COMM_INIT_STRUCT comm_init_input;
/* prepare parameter and calls common initialize */
comm_init_input.pstMp4Parser = init_input->pstMp4Parser;
comm_init_input.pstFSAL = init_input->pstFSAL;
comm_init_input.start_frame_no = init_input->start_frame_no;
comm_init_input.video_dec_callback = init_input->video_dec_callback;
comm_init_input.max_width = max_width;
comm_init_input.max_height = max_height;
comm_init_input.incall = KAL_FALSE; /*Not in-coming call*/
comm_init_input.audio_enable = KAL_TRUE; /*audio dsp intr enable*/
result = video_dec_comm_initialize(&comm_init_input);
if (result != MEDIA_STATUS_OK)
{
VIDEO_ASSERT(0);
return result;
}
/* set play back time base as 0 */
MP4_SetPlaybackTimerBase(vid_get_audio_parser(), 0, KAL_TRUE);
#ifdef VIDEO_DEC_YUV_MODE
{
/* open file for YUV mode */
FSAL_Status FSAL_STATUS;
kal_wchar store_name[20]=L"x:\\dec_out.yuv";
store_name[0] = FS_GetDrive(FS_DRIVE_V_NORMAL, 1, FS_NO_ALT_DRIVE);
/*store_name[0] = FS_GetDrive(FS_DRIVE_V_REMOVABLE, 1, FS_NO_ALT_DRIVE);*/
FSAL_STATUS = FSAL_Open(&FSAL_VIDEO_YUV_FILE, store_name, FSAL_WRITE);
if (FSAL_STATUS != FSAL_OK)
{
ASSERT(0);
}
}
#endif /*VIDEO_DEC_YUV_MODE*/
return MEDIA_STATUS_OK;
}
/* Open the video decode process.
* When call "video_dec_initialize" API, this function is also called.
* @param pstMp4Parser The handle of mp4 parser
* @param pstFSAL The handle of file abstract layer
* @return Media status, which is based MEDIA_STATUS_CODE structure.
*/
MEDIA_STATUS_CODE video_dec_open(STMp4Parser * pstMp4Parser,
STFSAL * pstFSAL,
kal_uint32 max_width,
kal_uint32 max_height)
{
kal_uint32 savedMask;
VIDEO_DEC_BUFFER_CB_STRUCT cb_info;
g_video_dec_status.running = KAL_TRUE;
#if ( defined(MT6219) || defined(MT6226) || defined(MT6227) || defined(MT6226M) )
g_video_enc_info_ptr = NULL;
#endif /*(MT6219, MT6226, MT6227, MT6226M)*/
/* get decoder information memory */
g_video_dec_info_ptr = (VIDEO_DEC_STRUCT *)extmem_get_buffer(sizeof(VIDEO_DEC_STRUCT));
/* Initialize buffer and AV setting according to different scenario */
#if defined(__VIDEO_EDITOR__)
if (g_video_dec_status.scenario == VIDEO_SCENARIO_EDITOR)
{
cb_info.scenario = VIDEO_DEC_BUFFER_SCENARIO_EDITOR;
cb_info.callback = &g_video_dec_info_ptr->video_dec_callback;
cb_info.event_id = VIDEO_EDITOR_DEC_EVENT_BUFFER_EMPTY;
video_dec_config_buffer(cb_info);
}
else
#endif /*__VIDEO_EDITOR__*/
{
cb_info.scenario = VIDEO_DEC_BUFFER_SCENARIO_FILE;
cb_info.callback = &g_video_dec_info_ptr->video_dec_callback;
cb_info.event_id = VIDEO_DEC_EVENT_BUFFER_EMPTY;
video_dec_config_buffer(cb_info);
}
/* Initialize mpeg4 decode memory (hardware, frame buffer ...)*/
mpeg4_decode_init(max_width, max_height);
/* store the max width and height for the current application. (clip play has this input)*/
g_video_dec_info_ptr->max_width = max_width;
g_video_dec_info_ptr->max_height = max_height;
g_video_dec_info_ptr->play_speed = 100;
g_video_dec_info_ptr->hdr_parse_frames_no = 0;
g_video_dec_info_ptr->dec_frames_no = 0;
g_video_dec_info_ptr->pMp4Parser = pstMp4Parser;
g_video_dec_info_ptr->pstFSAL = pstFSAL;
g_video_dec_info_ptr->force_deblock_disable = KAL_FALSE;
g_video_dec_info_ptr->seek_by_time = KAL_FALSE;
g_video_dec_info_ptr->seek_time = 0;
g_video_dec_info_ptr->current_play_time = 0;
g_video_dec_info_ptr->display_enable = KAL_TRUE;
g_video_dec_info_ptr->prev_display_enable = KAL_FALSE;
g_video_dec_status.VIDEO_STATUS = VIDEO_DEC_OK;
g_video_dec_status.FSAL_STATUS = FSAL_OK;
g_video_dec_status.PARSE_STATUS = MP4_PARSER_OK;
if (g_video_dec_gpt_refresh_handle== 0)
GPTI_GetHandle(&g_video_dec_gpt_refresh_handle);
savedMask = SaveAndSetIRQMask();
DRV_Reg(DRVPDN_CON3) &= ~(DRVPDN_CON3_MP4 | DRVPDN_CON3_DCT | DRVPDN_CON3_JPEG);
RestoreIRQMask(savedMask);
g_video_dec_info_ptr->stage = VIDEO_DEC_STAGE_OPEN;
return MEDIA_STATUS_OK;
}
/* Init the video decode av information.
* When call "video_dec_initialize" API, this function is also called.
* @param b_audio_enable enable audio or not
* @return Media status, which is based MEDIA_STATUS_CODE structure.
*/
MEDIA_STATUS_CODE video_dec_init_av(kal_bool b_audio_enable)
{
kal_uint32 video_timebase;
kal_uint32 dsp_timescale;
kal_uint32 audio_playback_delay;
/* Get video and audio(DSP) time base */
g_video_dec_status.PARSE_STATUS = MP4_GetMediaTimeScale(g_video_dec_info_ptr->pMp4Parser, &video_timebase, MP4_TRACK_VIDEO);
if ((g_video_dec_status.PARSE_STATUS != MP4_PARSER_OK) && (g_video_dec_status.PARSE_STATUS!=MP4_PARSER_NO_SUCH_TRACK))
{
VIDEO_ASSERT(0);
g_video_dec_info_ptr = NULL;
return MP4_PARSER_ERROR;
}
dsp_timescale = Media_A2V_GetAudioInterruptTimeScaleFxdPnt(
MP4_Audio_Type_To_Media_Format(MP4_GetAudioType(g_video_dec_info_ptr->pMp4Parser)), MP4_Audio_GetFreqIndex(g_video_dec_info_ptr->pMp4Parser));
audio_playback_delay = Media_A2V_GetAudioPlaybackDelay(
MP4_Audio_Type_To_Media_Format(MP4_GetAudioType(g_video_dec_info_ptr->pMp4Parser)));
/* Initialize buffer and AV setting according to different scenario */
#if defined(__VIDEO_EDITOR__)
if (g_video_dec_status.scenario == VIDEO_SCENARIO_EDITOR)
{
video_dec_set_av_timebase(VIDEO_DEC_AV_COMMON, video_timebase, dsp_timescale, audio_playback_delay);
}
else
#endif /*__VIDEO_EDITOR__*/
{
if (b_audio_enable == KAL_TRUE)
{
video_dec_set_av_timebase(VIDEO_DEC_AV_AUDIO, video_timebase, dsp_timescale, audio_playback_delay);
}
else
{
video_dec_set_av_timebase(VIDEO_DEC_AV_GPT, video_timebase, dsp_timescale, audio_playback_delay);
}
}
return MEDIA_STATUS_OK;
}
/* Common play function for play and clip play
* @param audio_frame_no The related audio frame that related to seek video frame. If audio is not enable, don't care "audio_frame_no" parameter!!
* @param video_dec_callback video callback function when driver want to notify MED or upper layer.
* @param incall it is incall(clip_play) or not(play)
* @return Media status, which is based MEDIA_STATUS_CODE structure.
*/
static MEDIA_STATUS_CODE video_dec_comm_play(kal_uint32 * audio_frame_no, void (*video_dec_callback)(kal_uint8 event),
kal_bool incall)
{
kal_uint32 frame_length;
kal_uint32 prev_frame_duration;
kal_uint8 *frame_addr;
kal_uint32 savedMask;
kal_uint32 frame_duration = 0;
MEDIA_STATUS_CODE result;
kal_uint64 seek_time_video_scale_based; //Should change as kal_uint64
kal_uint64 audio_decode_time; //Should change as kal_uint64
kal_uint32 audio_frame_number;
kal_uint64 decode_time;
kal_uint64 current_play_time;
kal_uint8 recheck_count;
kal_bool audio_exist = KAL_TRUE;
kal_bool video_play = KAL_TRUE;
kal_bool audio_end = KAL_FALSE;
/* The time is already set by seek function */
current_play_time = g_video_dec_info_ptr->current_play_time;
g_video_dec_info_ptr->video_dec_callback = video_dec_callback;
/*To guarantee all decode process is done*/
video_dec_internal_stop();
if (incall)
{
/* display the first initialize frame for clip play */
/* but upper layer use seek first before clip play, so this may be removed ?? */
video_dec_display();
}
/* seek done always set video end as false, so this is not called just after seek done */
if ((g_video_dec_info_ptr->video_end == KAL_TRUE) ||
(g_video_dec_info_ptr->dec_frames_no == g_video_dec_info_ptr->total_frames_in_file))
{
/*Video end, only audio*/
g_video_dec_info_ptr->seek_by_time = KAL_TRUE;
g_video_dec_info_ptr->video_end = KAL_TRUE;
/* seek time is got from current time. seek time is in common base */
g_video_dec_info_ptr->seek_time = VIDEO_ANYBASE_TO_COMMBASE(current_play_time, 1000);
}
/* seek_by_time is true when 1. previous seek to video end. 2. previous check video end set it as true */
if (g_video_dec_info_ptr->seek_by_time == KAL_TRUE)
{
/* seek_by_time is happened when video end */
g_video_dec_info_ptr->video_end = KAL_TRUE;
/* both seek time and audio time in common base */
if (g_video_dec_info_ptr->seek_time < g_video_dec_info_ptr->audio_duration)
{
/* seek time is longer than video duration , but shorter than audio duration */
/*Pure audio seek, get audio frame no according to seek time */
kal_uint64 seek_time_ms;
seek_time_ms = VIDEO_ANYBASE_TO_MS(g_video_dec_info_ptr->seek_time, VIDEO_COMMON_TIME_BASE);
g_video_dec_info_ptr->seek_by_time = KAL_FALSE;
g_video_dec_status.PARSE_STATUS =
MP4_Audio_TimeToSampleNo(g_video_dec_info_ptr->pMp4Parser, seek_time_ms, /*Unit: ms*/
audio_frame_no);
if (g_video_dec_status.PARSE_STATUS != MP4_PARSER_OK)
{
VIDEO_ASSERT(0);
return MP4_PARSER_ERROR;
}
#if defined(__VIDEO_EDITOR__)
if (g_video_dec_status.scenario == VIDEO_SCENARIO_EDITOR)
{
ASSERT(0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -