📄 mm_play.c
字号:
dwTmp = PARSER_GetMovieEndPosition(__dwTimeBegin);
if ( dwTmp < __dwTimeEnd)
{
__dwTimeEnd = dwTmp;
}
}
// [3] Set Error if pre-scan AVI index table command fail
if (PARSER_QueryEvent(0, PARSER_EVENT_ERROR, FALSE))
{
// Do error procedure while AVI index table pre0scan fail
UTL_SetPreScanError(ERR_NOT_FIND_AVI_IDXTBL);
}
else
{
if (__bMMIndexTableOK == TRUE)
{
// If AVI index table pre-scan success.
UTL_Read_PreScan_Info(PRESCAN_MOTION_IDXTBL);
}
else
{
UTL_SetPreScanError(ERR_NOT_FIND_AVI_IDXTBL);
}
}
// [4] Set the stage to set play mode.
__bMMStage = MM_STAGE_SET_PLAYMODE;
break;
case MM_STAGE_PRESCAN_LAST_SCR:
// Calculate the desired range for source to send data during prescan the last SCR value
__dwTemp = __dwTimeEnd - (bPreScanCnt*JUMP_SECTOR_FOR_PRESCAN_LAST_SCR);
// LLY2.22, keep the start time while do last SCR prescan
__dwPreGetTime = OS_GetSysTimer();
// start position > file begining.
if (__dwTimeBegin < __dwTemp)
{
// Issue prescan last SCR command
UTL_PreScanAction(PRESCAN_LAST_SCR, __dwTemp, (__dwTemp+JUMP_SECTOR_FOR_PRESCAN_LAST_SCR));
// Set stage to polling prescan last SCR done
__bMMStage = MM_STAGE_POLLING_LAST_SCR_PRESCAN_DONE;
}
// start position <= file beginning < (start postion + jump range)
else if( (__dwTemp<=__dwTimeBegin) && ((__dwTemp+JUMP_SECTOR_FOR_PRESCAN_LAST_SCR)>__dwTimeBegin) )
{
// Issue prescan last SCR command
UTL_PreScanAction(PRESCAN_LAST_SCR, __dwTimeBegin, (__dwTemp+JUMP_SECTOR_FOR_PRESCAN_LAST_SCR));
// Set stage to polling prescan last SCR done
__bMMStage = MM_STAGE_POLLING_LAST_SCR_PRESCAN_DONE;
}
// start position is out-of the playback range
else
{
// Set error while can't find the last SCR value
UTL_SetPreScanError(ERR_NOT_FIND_LAST_SCR);
// Set the stage to start playback
__bMMStage = MM_STAGE_SET_PLAYMODE;
}
break;
case MM_STAGE_POLLING_LAST_SCR_PRESCAN_DONE:
// [1] Waiting until parser report prescan action done
if( !PARSER_QueryEvent(0, PARSER_EVENT_COMPLETED, FALSE) )
{
// LLY2.22, do time-out protection while waiting parser complete
// Notice: if 1st prescan last SCR procedure need plus "long seek time" (about 3 sec)
// others only need < 1 sec (default disable long seek issue.
if(OS_GetSysTimer()-__dwPreGetTime > TIME_FOR_LAST_SCR_PRESCAN)
{
DBG_Printf(DBG_THREAD_CHEERDVD, DBG_INFO_MM_INFOFTR, "SCR T-Out\n");
// Force to stop parser and servo first
HAL_ControlParser(HAL_PARSER_STOP, 0);
SrcFilter_Stop(__dwSFStreamID);
goto PRESCAN_LAST_SCR_FAIL;
}
break;
}
// [2] Stop servo first after pre-scan done.
SrcFilter_Stop(__dwSFStreamID);
// [3-1] If find the last SCR value
if( !PARSER_QueryEvent(0, PARSER_EVENT_ERROR, FALSE) )
{
UTL_Read_PreScan_Info(PRESCAN_LAST_SCR);
__bMMStage = MM_STAGE_SET_PLAYMODE;
}
// [3-2] If can't find the last SCR value, continue the pre-scan last SCR again.
else
{
PRESCAN_LAST_SCR_FAIL:
if(bPreScanCnt>=5)
{
// Set error while can't find the last SCR value
UTL_SetPreScanError(ERR_NOT_FIND_LAST_SCR);
// Set the stage to start playback
__bMMStage = MM_STAGE_SET_PLAYMODE;
}
else
{
bPreScanCnt++;
// Set the stage to prescan last SCR again
__bMMStage = MM_STAGE_PRESCAN_LAST_SCR;
}
}
break;
case MM_STAGE_SET_PLAYMODE:
// wyc1.10a-909, fix some AVI file don't show progress bar to 100% problem.
if (__bAttrPlayNew == ATTR_AVI)
{
OSD_Output(MSG_PROGRESS, 0, 1);
}
UTL_PlayItem(__wPlayItem, 0);
if(__bAttrPlay == ATTR_AVI)
{
__bMMStage = MM_STAGE_WAIT_PLAY;
}
else
{
__bMMStage = MM_STAGE_PLAYEND;
}
break;
// LLY0.95, wait play command
case MM_STAGE_WAIT_PLAY:
// If continue, issue playback command, and go to playend state.
if (__bDRMPlayState==DRM_PLAY_STATE_CONTINUE)
{
// If no copy protection file, issue play command directly
if (!__PARSER_gbl.BitsContent.fCopyProtection)
{
UTL_Start_PlayItem(0);
__bMMStage = MM_STAGE_PLAYEND;
}
#ifndef NO_DRM
else
{
__bDRMPlayState=UTL_DRM_StartPlayback();
if(__bDRMPlayState==DRM_PLAY_STATE_CONTINUE)
{
UTL_Start_PlayItem(0);
__bMMStage = MM_STAGE_PLAYEND;
}
else if(__bDRMPlayState==DRM_PLAY_STATE_ABORT)
{
__bMMStage = MM_STAGE_NONE;
// How to specify the stop @ current file & display "stop" ??
// If assign F/W key by KEY_STOP, it will stop @ 1st file of current directory.
// If assing F/W key by KEY_RETURN, it can stop @ current playing file
// but it will show "Return" on screen.
__bFWKey=KEY_RETURN;
}
}
#endif // #ifndef NO_DRM
}
// If abort, enter stop mode
else if(__bDRMPlayState==DRM_PLAY_STATE_ABORT)
{
__bMMStage = MM_STAGE_NONE;
__bFWKey=KEY_RETURN;
}
// LLY2.35, display message to info user that not supported audio/ video format
// while start to playback bitstream
// Notice: don't show this message to earily (ex. header prescan done)
// since it don't support A or V only,
// progress bar will continue go w/ this message
#ifndef NO_OUTPUT_INFO_FOR_UNKNOWN_AV_FORMAT
if(__bMMStage == MM_STAGE_PLAYEND)
{
if(__bVideoID == HAL_THROW_VIDEO)
{
strcpy(__bMsgString, "Not supported video format");
OSD_Output(MSG_STRING, 0, 10);
// LLY2.50, keep the starting time to show "un-support format OSD"
__dwPreGetTime=OS_GetSysTimer();
__bUnknownFormat=TRUE;
}
// LLY2.36, must check if exist audio stream first
if(__bASTNs>=1 && __bASTID == HAL_THROW_AUDIO)
{
strcpy(__bMsgString, "Not supported audio format");
OSD_Output(MSG_STRING, 0, 10);
// LLY2.50, keep the starting time to show "un-support format OSD"
__dwPreGetTime=OS_GetSysTimer();
__bUnknownFormat=TRUE;
}
}
#endif // #ifdef NO_OUTPUT_INFO_FOR_UNKNOWN_AV_FORMAT
break;
case MM_STAGE_PLAYEND:
// Enable Playback ready flag
__bPBReady=TRUE;
// LLY1.20, set motion stage as playback
__bMotionState = MOTION_STATE_PLAY;
// LLY1.20, continue to process char-base SPST if necessary
#ifdef SUPPORT_CHAR_SUBPICTURE
if ((__bAttrPlay == ATTR_AVI))
{
CHAR_SP_Trigger();
}
#endif // #ifdef SUPPORT_CHAR_SUBPICTURE
if (__btPlayEnd == TRUE)
{
#ifdef SUPPORT_PSNR_TEST
HAL_ReadInfo(HAL_INFO_VIDEO_REMAIN, &_dwMMTemp);
if(__dwDecodeCnt>=0x4B0)
{
__bMMStage=MM_STAGE_NEXT_ITEM;
DBG_Printf(DBG_THREAD_CHEERDVD, DBG_INFO_MM_INFOFTR,"Decode all frame complete !\n");
}
#else // #ifdef SUPPORT_PSNR_TEST
// wyc0.75, make time-out to 15s because our audio buffer can play about 10s when buffer full. So wait 15s for
// proc2 to decode these data when parser sent bits completed. Also wait audio remainder to 1000 because minimun
// audio remainder is about 700 in CT909 now.
if ((OS_GetSysTimer() - __dwBuffEmptyTime) < (_dwMMTriggerEmptyTime))
{
DWORD dwARem;
// wyc0.85, use video ramainder to judge if need to change files in CDROM-motion mode.
HAL_ReadInfo(HAL_INFO_VIDEO_REMAIN, &_dwMMTemp);
HAL_ReadInfo(HAL_INFO_AUDIO_REMAIN, &_dwMMTemp1);
// LLY1.21a, Choose differnt Audio Remain threshold for WMA
// Since, it depends on Block Align
if(__bAudioType == HAL_AUDIO_WMA)
{
HAL_ReadAM(HAL_AM_WMA_BLOCK_ALIGN, &__dwTemp); // *8 = BYTE unit
dwARem=__dwTemp*8/4;
}
else
{
dwARem=1024;
}
// wyc0.90, when play motion files, one of Audio or Video not empty, don't go next file.
// Because some file only have audio or video. and some files audio is longer than video.
// LLY2.30, only waiting audio buffer empty while normal play mode.
// Since, DSP will base on STC to skip audio stream during Fast mode
// If Fast mode to file end, video will empty, and STC stop update
// So, audio stop the data skip, then, we can't wait audio buffer empty.
if ((_dwMMTemp > 32) || ((__bModeCmd == KEY_PLAY) && (_dwMMTemp1 > dwARem)))
{
OS_YieldThread();
}
else
{
__bMMStage=MM_STAGE_NEXT_ITEM;
#ifdef MM_MOTION_DEBUG
DBG_Printf(DBG_THREAD_CHEERDVD, DBG_INFO_MM_INFOFTR,"A/V buffer empty\n");
#endif //MM_MOTION_DEBUG
}
}
else
{
__bMMStage=MM_STAGE_NEXT_ITEM;
#ifdef MM_MOTION_DEBUG
DBG_Printf(DBG_THREAD_CHEERDVD, DBG_INFO_MM_INFOFTR,"Time-out\n");
#endif //MM_MOTION_DEBUG
}
#endif //SUPPORT_PSNR_TEST
}
else
{
if(PARSER_QueryEvent(0,PARSER_EVENT_COMPLETED, TRUE))
{
#ifdef MM_MOTION_DEBUG
DBG_Printf(DBG_THREAD_CHEERDVD, DBG_INFO_MM_INFOFTR,"Parser report ending\n");
#endif //MM_MOTION_DEBUG
__btPlayEnd = TRUE;
__dwBuffEmptyTime = OS_GetSysTimer();
}
// LLY1.10 begin ...
// Add AVI error concealment mechanism while parser report error during playback
else if( (__bAttrPlay==ATTR_AVI) && PARSER_QueryEvent(0, PARSER_EVENT_MOVIE_ERROR, TRUE) )
{
DBG_Printf(DBG_THREAD_CHEERDVD, DBG_INFO_MM_INFOFTR,"AVI Err\n");
__dwBuffEmptyTime = OS_GetSysTimer();
__bMMStage=MM_STAGE_ERROR_CONCEAL;
}
OS_YieldThread();
}
break;
// LLY1.10, add new case for Error Concealment mechanism
case MM_STAGE_ERROR_CONCEAL:
{
extern WORD __wScanGap;
extern DWORD __dwScanBaseTime;
WORD wTemp;
// wait buffer empty then start the error concealment mechanism
if ((OS_GetSysTimer() - __dwBuffEmptyTime) < (_dwMMTriggerEmptyTime))
{
// wyc0.85, use video ramainder to judge if need to change files in CDROM-motion mode.
HAL_ReadInfo(HAL_INFO_VIDEO_REMAIN, &_dwMMTemp);
HAL_ReadInfo(HAL_INFO_AUDIO_REMAIN, &_dwMMTemp1);
// wyc0.90, when play motion files, one of Audio or Video not empty, don't go next file. Because some file only have audio or video.
// some files audio is longer than video.
// 8 is computed by 4*2, 4 is divide to DWORD. 2 is 1/2 video remainder.
if ((_dwMMTemp > 32) || (_dwMMTemp1 > 1024))
{
OS_YieldThread();
break;
}
else
{
#ifdef MM_MOTION_DEBUG
DBG_Printf(DBG_THREAD_CHEERDVD, DBG_INFO_MM_INFOFTR,"E_C: A/V buffer empty\n");
#endif //
}
}
else
{
#ifdef MM_MOTION_DEBUG
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -