MPEG.c
上传用户:super_houu
上传日期:2008-09-21
资源大小:4099k
文件大小:17k
- /****************************************************************************************
- * Copyright (c) 2000 ZORAN Corporation, All Rights Reserved
- * THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF ZORAN CORPORATION
- *
- * File: $Workfile: MPEG.c $
- *
- * Description:
- * ============
- * MPEG Video Clip implementation
- *
- * Log:
- * ====
- ****************************************************************************************
- * Updates:
- ****************************************************************************************
- * $Log: /I76/I76_Common/I76_Reference/Playcore/Nav_Clips/MPEG.c $
- *
- * 31 04-04-03 14:06 Leslie
- * Set initical Drive MSF when start MPEG clip playback
- *
- * 30 04-03-12 17:44 Leslie
- * Cancel Scan if switch from Scan mode to Pause mode
- *
- * 29 04-03-04 14:06 Leslie
- * Fix playback stuck problem after switch from Scan mode to Play mode
- *
- * 28 04-03-03 19:08 Fwang
- * Fix video garbage when skip between MPEG clips after zoom.
- *
- * 27 04-02-25 17:39 Fwang
- * CPU scaling for MPEG clips.
- *
- * 26 1/25/04 8:21 Nmaurer
- * Add drv_ prefix to Drive routines
- *
- * 25 11/28/03 7:24p Leslie
- * Change order of DEC_SetDiskType() and DEC_Prepare_to_decode()
- *
- * 24 11/15/03 7:10p Leslie
- * Replace old Video API Low Level Files with new ones
- *
- * 23 11/11/03 12:51p Leslie
- * Fix the first time can't start MPEG DVD-ROM CLip playback after disc
- * loading
- *
- * 19 03-09-05 19:41 Leslie
- * Add sequence header detection for MPEG Clips
- *
- * 18 03-08-29 0:03 Leslie
- * Add support for DVD-ROM Clips discs
- * Code cleanup
- *
- * 17 03-08-06 18:20 Leonh
- * enable FF and FR when pause or stepf
- *
- * 16 03-08-04 21:04 Leonh
- * make mpeg ab repeat work ok
- *
- * 15 03-07-30 21:07 Leslie
- * Remove sequence header detection for MPEG Clips
- *
- * 14 03-07-29 19:47 Leslie
- * Set the right disc type for MPEG Clips
- *
- * 13 03-06-18 18:17 Leonh
- * use PTS as the mpeg current time display
- *
- * 12 03-06-17 10:38 Leonh
- * sovle the mpeg scan problem
- *
- * 11 03-05-30 10:14 Jerryc
- * fix flash card code.
- *
- * 10 03-05-29 18:02 Jerryc
- * support flash card.
- *
- * 9 03-05-19 13:42 Leslie
- * Add drive Play Mode
- *
- * 8 03-03-04 11:34 Jerryc
- * jerry cai, merge new nav clips lib
- *
- * 6 03-02-06 18:31 Leslie
- * Add MPEGClip_Pause function
- *
- * 5 03-02-06 14:26 Leslie
- * Enable MPEG clip
- * Support MPEG Clip Scan
- *
- * 4 03-02-02 17:30 Leslie
- *
- * 3 03-01-10 12:21 Leslie
- * Add wide-character strings support
- *
- * 2 03-01-09 12:30 Leslie
- *
- * 1 10/30/02 18:06 Rond
- *
- * 1 11/09/02 15:48 Atai
- *
- * 1 26/08/02 16:05 Nirm
- ****************************************************************************************/
- #include "Config.h" // Global Configuration - do not remove!
- #ifdef _DEBUG
- #undef IFTRACE
- #define IFTRACE if (gTraceNavigator)
- #include "DebugDbgMain.h"
- #endif
- #include "Includemath-macro.h"
- #include "DecoderDecoder.h"
- #include "DecoderDec_defs.h"
- #include "Decoderlow_levelDEC_LL_Def.h"
- #include "Decoderlow_levelDEC_LL_Api.h"
- #include "Drivedrv_api.h"
- #include "Drivedrv_defs.h"
- #include "LogoLogo.h"
- #include "PlaycoreCoremainCoreGDef.h"
- #include "PlaycoreAuxCacheAuxCache.h"
- #include "PlaycoreFileSysFileSystem.h"
- #include "Playcorenav_cddape_cd.h"
- #include "PlaycoreNav_ClipsMPEG.h"
- #include "PlaycoreNav_ClipsClip_Impl.h"
- #include "PlaycoreNav_ClipsGenericClip.h"
- #include "PlaycoreNav_ClipsNav_Clips.h"
- #include "PlaycoreNav_ClipsPE_Clips.h"
- #ifdef SUPPORT_FLASH_CARD
- #include "DriveFE_Manager.h"
- #endif
- /////////////////////////////////////////////////////////////////////////////
- // CONST Definition
- ////////////////////////////////////////////////////////////////////////////
- #define DRIVE_CLOCK_RATE 75L
- #define MPEG_SEARCH_ADDRESS_OFFSET 300L//4 s
- extern DWORD CurrLocationBackup;
- extern BYTE g_audio_sid;
- /////////////////////////////////////////////////////////////////////////////
- // General MPEG
- /////////////////////////////////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////////
- // Public Services
- #pragma argsused
- void MPEG_setPresentationTime(UINT8 uPresentationTime)
- {
- dbg_printf(("WARNING: MPEG_setPresentationTime() Failed: MPEG Video Clips cannot have a presentation time.n"));
- }
- /////////////////////////////////////////////////////////////////////////////
- // MPEG Video Clip
- /////////////////////////////////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////////
- // Forward Declarations of Virtual Methods
- BOOL MPEGClip_getExtendedInfo(const struct Clip_TAG *i_pThis,
- WORD i_pExtInfo_sc_handle);
- void MPEGClip_refresh(Clip *i_pThis);
- BOOL MPEGClip_play(Clip *i_pThis, const ClipMarker *i_pResumeMarker,
- BOOL bCacheOnly);
- void MPEG_scan(Clip *i_pThis, int iScanSpeed);
- void MPEGClip_pause(Clip *i_pThis, BOOL bEnable);
- UINT16 MPEGClip_getTime(const Clip *i_pThis);
- void MPEGClip_recordMarker(const Clip *i_pThis, ClipMarker *o_pMarker);
- /////////////////////////////////////////////////////////////////////////////
- // Const Factory
- // Valid Extenions List
- BEGIN_CLIP_VALID_EXTENSIONS_MAP(MPEG)
- CLIP_VALID_EXTENSIONS_ENTRY(L"MPG")
- CLIP_VALID_EXTENSIONS_ENTRY(L"MPE")
- CLIP_VALID_EXTENSIONS_ENTRY(L"VOB")
- CLIP_VALID_EXTENSIONS_ENTRY(L"DAT")
- CLIP_VALID_EXTENSIONS_ENTRY(L"MPEG")
- END_CLIP_VALID_EXTENSIONS_MAP()
- // Constant Attributes
- DECLARE_CLIP_CONST_ATTR(MPEG,
- DECLARE_CLIP_VTABLE(MPEGClip_getExtendedInfo,
- MPEGClip_play,//GenericClip_play,
- MPEGClip_pause,//GenericClip_pause,
- GenericClip_getStatus,
- GenericClip_abort,
- MPEGClip_recordMarker,//GenericClip_recordMarker,
- GenericClip_refresh,
- MPEGClip_getTime,
- GenericClip_digest,
- MPEG_scan//GenericClip_scan
- ),
- eClipType_MPEG,
- 0xC0, 0xE0, DEC_DISC_TYPE_MPEG,
- (eCA_Zoomable | eCA_Markable | eCA_Slowable | eCA_Scanable ),
- NULL
- )
- /////////////////////////////////////////////////////////////////////////////
- // Public Services
- BOOL MPEGClip_isKindOf(LPCWSTR i_pszFilename)
- {
- return GenericClip_isKindOf(i_pszFilename, CLIP_VALID_EXTENSIONS(MPEG));
- }
- void MPEGClip_construct(Clip *o_pThis, const FindData *i_pFileInfo)
- {
- GenericClip_construct(o_pThis, i_pFileInfo);
- o_pThis->m_pConstAttr= &CLIP_CONST_ATTR(MPEG);
- }
- /////////////////////////////////////////////////////////////////////////////
- // Virtual Methods
- BOOL MPEGClip_getExtendedInfo(const struct Clip_TAG *i_pThis,
- WORD i_pExtInfo_sc_handle)
- {
- DWORD dwStartLBA;
- ULONG ulBlocksCnt;
- ULONG cbPlaybackLength;
- UINT16 uTime;
- UINT32 SampleRate = 0;
- DEC_MuteOutput(MUTE_DETECT_REQUEST, MUTE_SETTING_ON);
- DEC_MuteSPDIF(MUTE_DETECT_REQUEST, MUTE_SETTING_ON);
-
- dwStartLBA= (i_pThis->m_cfiInfo).dwFileLocation;
- // Calculate the Playback Length (in Bytes)
- cbPlaybackLength= ( (i_pThis->m_cfiInfo).cbFileSize -
- (LOGICAL_BLOCK_SIZE * (dwStartLBA - (i_pThis->m_cfiInfo).dwFileLocation)) );
- ulBlocksCnt= ((cbPlaybackLength + LOGICAL_BLOCK_SIZE - 1) / LOGICAL_BLOCK_SIZE);
-
- DEC_Stop_DVP_ADP_cmd((UINT8)0);
- DEC_SetDiskType((i_pThis->m_pConstAttr)->m_eBitstreamType);
- // Prepare for decoding
- DEC_prepare_to_decode();
- DEC_SetSID( DEC_SID_TYPE_VIDEO, (BYTE)NoVideo);
-
- DEC_SetSID(DEC_SID_TYPE_AUDIO, (i_pThis->m_pConstAttr)->m_eAudioSID);
-
- PE_CD_CancelNotification(IFrame);
- //Inform the Decoder of the Playback-Range
- PE_Clips_SetPlaybackRange(dwStartLBA, ulBlocksCnt, UNLIMITED_FILE_SIZE);
-
- // Invoke playback of the Decoder & Drive
- // NOTE: The order of invocation is important, and must not be changed!
- DEC_PlaybackCommand(DEC_PLAYBACK_CMD_PLAY, NULL);
- //LX051703: Add AV Data mode for Play CD
- PE_Clips_Playback_Sectors(DRVCF_CDSPEED_MAX | DRVF_PLAY_CD_AV_DATA, dwStartLBA, ulBlocksCnt);
- gns.clips.iClipSamplingRate = DEC_Get_MPEG_Audio_SamplingRate();
- drv_abort_play();
- DEC_PlaybackCommand(DEC_PLAYBACK_CMD_STOP, NULL);
- DEC_MuteOutput(MUTE_DETECT_REQUEST, ((g_audio_sid == 0xFF)?MUTE_SETTING_ON:MUTE_SETTING_OFF));
- DEC_MuteSPDIF(MUTE_DETECT_REQUEST, MUTE_SETTING_OFF);
- return TRUE;
- }
- BOOL MPEGClip_play(Clip *i_pThis, const ClipMarker *i_pResumeMarker,
- BOOL bCacheOnly)
- {
- DWORD dwStartLBA;
- ULONG ulBlocksCnt, cbPlaybackLength;
- UINT16 uTime;
- dbg_printf(("GenericClip_play()n"));
- // Cached-playback is unsupported by default
- if (bCacheOnly)
- return FALSE;
- // No Logo for MPEG Bitstream
- Logo_selectSource(eFrame);
- Logo_display();
-
- if (NULL == i_pResumeMarker) {
- // Start at the beginning
- dwStartLBA= (i_pThis->m_cfiInfo).dwFileLocation;
- }
- else {
- // Playback is being resumed
- dwStartLBA= i_pResumeMarker->dwAddress;
- }
- // Calculate the Playback Length (in Bytes)
- cbPlaybackLength= ( (i_pThis->m_cfiInfo).cbFileSize -
- (LOGICAL_BLOCK_SIZE * (dwStartLBA - (i_pThis->m_cfiInfo).dwFileLocation)) );
- ulBlocksCnt= ((cbPlaybackLength + LOGICAL_BLOCK_SIZE - 1) / LOGICAL_BLOCK_SIZE);
- #ifndef MPEG_SCALING_BY_CPU
- // Kill any existing Zoom
- DEC_SetZoomScale(NO_ZOOM);
- #endif
- // Configure the Decoder to the appropriate Bitstream Type
- DEC_Stop_DVP_ADP_cmd((UINT8)0);
- DEC_SetDiskType((i_pThis->m_pConstAttr)->m_eBitstreamType);
- PE_CD_AutoDetectVideoSetting((i_pThis->m_pConstAttr)->m_eVideoSID, (i_pThis->m_cfiInfo).dwFileLocation, ulBlocksCnt);
- #ifdef MPEG_SCALING_BY_CPU
- DEC_EnableManualScaling(PROG_SCALER_MODE_CCRAM);
- // JG_0819_2004: FF/FB->PLAY/PAUSE need not to do scaling again
- if (NULL == i_pResumeMarker)
- gcst.mNeedScaling = TRUE;
- /* Set the scaler mode */
- DEC_SetViewMode(gps->view_mode);
- /* Set TV display aspect ratio */
- DEC_set_Display_AspectRatio(gps->tv_shape);
-
- #else
- DEC_DisableManualScaling();
- #endif
- // Prepare for decoding
- DEC_prepare_to_decode();
- DEC_SetSID(DEC_SID_TYPE_AUDIO, (i_pThis->m_pConstAttr)->m_eAudioSID);
- DEC_SetSID(DEC_SID_TYPE_VIDEO, (i_pThis->m_pConstAttr)->m_eVideoSID);
- // Select the appropriate Clock
- PE_Clips_SelectClock(eCT_Drive);
- uTime = (UINT16)( ((i_pThis->m_cfiInfo).dwFileLocation)/DRIVE_CLOCK_RATE);
-
- PE_CD_CancelNotification(IFrame);
- // Inform the Decoder of the Playback-Range
- PE_Clips_SetPlaybackRange(dwStartLBA, ulBlocksCnt, UNLIMITED_FILE_SIZE);
-
- // Invoke playback of the Decoder & Drive
- // NOTE: The order of invocation is important, and must not be changed!
- DEC_PlaybackCommand(DEC_PLAYBACK_CMD_PLAY, NULL);
- PE_CD_SetCurrentLocationLBN_Bakcup(dwStartLBA);
-
- //LX051703: Add AV Data mode for Play CD
- PE_Clips_Playback_Sectors(DRVCF_CDSPEED_1X | DRVF_PLAY_CD_AV_DATA, dwStartLBA, ulBlocksCnt);
-
- PE_Clips_EnableClock(TRUE, TRUE,uTime);
-
- return TRUE;
- }
- void MPEG_scan(Clip *i_pThis, int iScanSpeed)
- {
- DWORD dwCurrentAddress;
- dbg_printf(("MPEG Scann"));
- if((iScanSpeed!=0)&&(gcs.pstate==PST_SLOW)&&(gns.clips.iSlowSpeed>0))
- {
- PE_CD_SetSlowMotion(FALSE, 0);
- gcs.pstate = PST_PLAY;
- gns.clips.iSlowSpeed = 0;
- }
-
- if(iScanSpeed * gns.clips.iScanSpeed > 0)
- {
- gns.clips.iScanSpeed= ((iScanSpeed >= 0) ? iScanSpeed : (iScanSpeed - 1));
- return;
- }
- if ( iScanSpeed != 0 ){
- if ( PST_PLAY == gcs.pstate ||PST_SCAN == gcs.pstate ||PST_PAUSE== gcs.pstate ){
- DWORD dwPlaybackSize;
-
- CLEAR_COP_MASK(COP_ABREPEAT);
-
- gns.clips.iScanSpeed= ((iScanSpeed >= 0) ? iScanSpeed : (iScanSpeed - 1));
- // Start Scanning
- #ifndef SUPPORT_FLASH_CARD
- PE_CD_SetScan(TRUE, NoAudio, gns.clips.iScanSpeed);
- #endif
- gcs.pstate= PST_SCAN;
-
- dwCurrentAddress = PE_Clips_GetCurrLocation();
- dwPlaybackSize = (DWORD)(i_pThis->m_cfiInfo.cbFileSize >> 11) + 1 + (DWORD)(i_pThis->m_cfiInfo.dwFileLocation) - dwCurrentAddress;
- PE_CD_AbortPlayback(TRUE);
- #ifdef SUPPORT_FLASH_CARD
- // Start Scanning
- PE_CD_SetScan(TRUE, NoAudio, gns.clips.iScanSpeed);
- #endif
- // For AV Tracks only, request I-Frame notification
- PE_CD_RequestNotification(IFrame);
-
- // Prepare for decoding
- DEC_prepare_to_decode();
- DEC_SetSID(DEC_SID_TYPE_AUDIO, NoAudio);
- DEC_SetSID(DEC_SID_TYPE_VIDEO, 0xE0);
-
- // Inform the Decoder of the Playback-Range
- PE_Clips_SetPlaybackRange(dwCurrentAddress, dwPlaybackSize, UNLIMITED_FILE_SIZE);
- if(gns.clips.iScanSpeed < 0)
- CurrLocationBackup = dwCurrentAddress;
- else
- CurrLocationBackup = -1;
-
- // Invoke playback of the Decoder & Drive
- // NOTE: The order of invocation is important, and must not be changed!
- DEC_PlaybackCommand(DEC_PLAYBACK_CMD_REF_FRAME_ONLY, NULL);//jeanz_0319_2005 Reset right command
- //LX051703: Add AV Data mode for Play CD
- if (!PE_Clips_Playback_Sectors(DRVCF_CDSPEED_1X | DRVF_PLAY_CD_AV_DATA, dwCurrentAddress, dwPlaybackSize)) {
- dbg_printf(("WARNING: GenericClip_play() Failed [1]n"));
- return FALSE;
- }
- //cancel Trigger Bit notification
- PE_CD_CancelNotification(TriggerBit);
- // Engage the Error-Recovery mehcanism for I-Frame Display Miss
- //(g_pClipsNav->m_ErrorRecoveryInfo).uRetryCount= CLIPS_ERROR_RECOVERY_RETRY_COUNT;
-
- tr_printf(("Scanning-Speed: %d.n", gns.clips.iScanSpeed));
- }
-
- }else{
- ClipMarker mClipMarker;
- UINT16 uTime;
- SET_COP_MASK(COP_ABREPEAT);
- // Stop Scanning
- gns.clips.iScanSpeed = 0;
- #ifndef SUPPORT_FLASH_CARD
- PE_CD_SetScan(FALSE, (i_pThis->m_pConstAttr)->m_eAudioSID, gns.clips.iScanSpeed);
- #endif
- gcs.pstate = PST_PLAY;
- //dwCurrentAddress = PE_CD_GetDecoderCurrentLocationLBN();
- dwCurrentAddress = PE_Clips_GetCurrLocation();
- uTime = (UINT16)( (i_pThis->m_cfiInfo.dwFileLocation)/DRIVE_CLOCK_RATE);
- PE_CD_AbortPlayback(TRUE);
- #ifdef SUPPORT_FLASH_CARD
- PE_CD_SetScan(FALSE, (i_pThis->m_pConstAttr)->m_eAudioSID, gns.clips.iScanSpeed);
- #endif
- PE_Clips_EnableClock(TRUE, TRUE, uTime);
- PE_Clips_SelectClock(eCT_Drive);
-
- // Set the Marker.
- mClipMarker.dwAddress = dwCurrentAddress;
- mClipMarker.uTime = 0;
- mClipMarker.uClipNumer = gns.clips.uCurrPlaylistItem;
- dbg_printf(("Resume from %lx, file start address is %lxn", mClipMarker.dwAddress, i_pThis->m_cfiInfo.dwFileLocation));
- //Resume play from the current location.
- (i_pThis->m_pConstAttr->m_vtable.m_pfPlay)(i_pThis, &mClipMarker, FALSE);
- }
-
- return;
- }
- void MPEGClip_pause(Clip *i_pThis, BOOL bEnable)
- {
- dbg_printf(("GenericClip_pause(%d)n", bEnable));
- if (bEnable) {
- // Pause the Decoder
- //AngieHe_0909_2004:Cancel MPEG scan by another function.
- if ((PST_SCAN == gcs.pstate)||((PST_SLOW == gcs.pstate )&&(gns.clips.iSlowSpeed<0)))
- {
- MPEG_scan(i_pThis,0);
-
- //jeanz_0319_2005 Wait for DVP decoding.
- DEC_SetSID(DEC_SID_TYPE_AUDIO, NoAudio);//Mute audio.
- {
- UINT8 uPictureCnt;
- UINT16 uStatus2;
- UINT16 utry = 10000;
- // Extract the value of the Picture-Counter
- while (utry--)
- {
- uStatus2 = inport(I64_STATUS_2);
- uPictureCnt = (UINT8)((uStatus2 & (UINT16)DEC_LL_STATUS2_DEC_PIC_CNTR_MASK) >> DEC_LL_STATUS2_DEC_PIC_CNTR_SHIFT);
- if(uPictureCnt<2)
- usleep(100UL);
- else
- {
- printf("n****** Wait for the DVP to docoder the picture before pause.uPictureCnt = %d utry = %dn",uPictureCnt,utry);
- break;
- }
- }
- if(!utry)
- printf("n Time out to wait for the DVP decoder one Picture!!! n");
- }
- }
-
- DEC_PlaybackCommand(DEC_PLAYBACK_CMD_PAUSE, NULL);
- DEC_SetSID(DEC_SID_TYPE_AUDIO, (i_pThis->m_pConstAttr)->m_eAudioSID);//Set audio.
- }
- else {
- // Resume the Decoder
- DEC_PlaybackCommand(DEC_PLAYBACK_CMD_RESUME, NULL);
- }
- return;
- }
- #ifdef D_NO_CLIPS_AUTORUN
- extern BOOL g_in_full_stop;
- #endif
- #define SCR_RATE 90000L
- UINT16 MPEGClip_getTime(const Clip *i_pThis)
- {
- DWORD dwCurrPTS;
- UINT16 dwCurrentTime;
- static UINT16 dwBeUsedTime;
- #ifdef D_NO_CLIPS_AUTORUN
- if (g_in_full_stop)
- return 0;
- #endif
- if(PE_CD_GetDecoderCurrentLocationSCR(&dwCurrPTS))
- {
- dwCurrentTime = (UINT16)(dwCurrPTS/SCR_RATE);
- //angieh_0412_2004:In Fast Backword if the SCR is 0,don't update current time.
- if( (gns.clips.iScanSpeed < 0 || gns.clips.iSlowSpeed < 0) && (dwCurrentTime == 0) )
- dwCurrentTime = dwBeUsedTime;
- dwBeUsedTime = dwCurrentTime;
- }
- else
- dwCurrentTime = dwBeUsedTime;
-
- return dwCurrentTime;
- }
- void MPEGClip_recordMarker(const Clip *i_pThis, ClipMarker *o_pMarker)
- {
- dbg_printf(("MPEGClip_recordMarker()n"));
- o_pMarker->dwAddress= PE_Clips_GetCurrLocation();
- o_pMarker->uTime= GenericClip_getTime(i_pThis);
- o_pMarker->uClipNumer = gns.clips.uCurrentClipNumber;
- return;
- }