nav_svcd.c
上传用户:super_houu
上传日期:2008-09-21
资源大小:4099k
文件大小:253k
- /* **************************************************************************************
- * Copyright (c) 2002 ZORAN Corporation, All Rights Reserved
- * THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF ZORAN CORPORATION
- *
- * File: $Workfile: nav_svcd.c $
- *
- * Description:
- * ============
- * SVCD Navigator implementation
- *
- * Log:
- * ====
- * $Revision: 131 $
- * Last Modified by $Author: Leslie $ at $Modtime: 04-04-03 13:35 $
- ****************************************************************************************
- * Updates:
- ****************************************************************************************
- * $Log: /I76/I76_Common/I76_Reference/Playcore/Nav_SVCD/nav_svcd.c $
- *
- * 131 04-04-03 14:06 Leslie
- * Set initial Drive MSF when start a new playback
- *
- * 130 04-04-01 23:38 Leslie
- * Change type definition
- *
- * 129 4/01/04 10:50p Johnk
- * support HW POWER_ON_RESUME
- *
- * 128 04-04-01 17:14 Williaml
- * it can't play from a accurate REPA point time when RepAB function in
- * use
- *
- * 127 04-04-01 15:41 Hansenw
- * fix OSD flashes 00:00 at repeat AB
- *
- * 126 04-03-30 16:13 Williaml
- * set the play mode to normal from program, intro or shuffle after full
- * stop
- *
- * 125 04-03-30 11:08 Williaml
- * Merge the latest code for K1
- *
- * 124 3/28/04 9:08p Nmaurer
- * Rename to drv_bin2bcd
- *
- * 123 3/25/04 11:36p Johnk
- * merged the latest code for S1
- *
- * 122 04-03-24 15:09 Angieh
- * For Alco,support previous func when play the first track.
- *
- * 121 3/11/04 3:31p Terencet
- * add check for VCD version2.0
- *
- * 120 04-03-09 18:52 Angieh
- * Add SVCD_DIGEST_SUPPORT macro.
- *
- * 119 2/27/04 5:20p Johnk
- * Merged the latest S1 changes
- *
- * 118 2/24/04 3:05p Robinj
- * Patch SVCD with MPEG1 format
- * when "STOP", change g_disc_type to DEC_DISC_TYPE_VCD
- *
- * 117 2/20/04 6:19p Glenl
- * Merged S1 code
- *
- * 116 2/20/04 4:34p Leonh
- * not start stucktrigger for cdda on vcd
- *
- * 115 2/16/04 5:13p Lyncolnc
- * Merged S1 Changes.
- *
- * 114 1/25/04 8:22 Nmaurer
- * Add drv_ prefix to Drive routines
- *
- * 113 11/28/03 5:49p Fwang
- * Detect squence header on menu also.
- *
- * 112 11/26/03 11:05p Leslie
- * Re-Schedule StuckTrigger bit when peform error recovery
- *
- * 111 11/26/03 11:10a Leslie
- * Don't do byte swap for getting Segment Start Address
- *
- * 110 11/19/03 11:40a Leslie
- * Add sampling rate detection for SVCD discs
- *
- * 109 11/03/03 4:09p Leslie
- * Fix playback out of range proble when do sequence header detection for
- * Entry Items
- *
- * 108 10/15/03 8:46a Leslie
- * Remove Karaoke Recording
- *
- * 107 9/29/03 11:59a Chaol
- *
- * 106 9/05/03 11:58a Mikex
- * make the repeat mark B point not at the last 2 second of current track
- * signature: MikeX_0905_2003_A
- *
- * 105 03-08-29 0:02 Leslie
- * Code cleanup
- *
- * 104 8/27/03 7:04p Mikex
- * Add the recovery error mechanism in digest mode.
- * Signature: mikex_0827_2003_a
- *
- * 103 8/27/03 3:51p Leonh
- * avoid black back ground when digest with PBC ON
- *
- * 102 8/21/03 7:43p Mikex
- * roll back mikex_0821_2003_b change, because this bug was fixed by
- * deleting the repeat single choice on mode menu and run time mode menu.
- *
- * 101 8/21/03 1:29p Mikex
- * Add a judgement for the single repeat on OnNextItem function
- *
- * 100 8/21/03 10:55a Mikex
- * add a delay on digest mode after canceling the AB repeat
- *
- * 99 03-08-17 18:51 Leslie
- * Add comments
- *
- * 98 03-07-28 17:03 Leslie
- * Check in changes for Task Force
- *
- * 97 03-07-17 14:37 Mikelv
- * Using a more accurate condition "iCurrentTime == 10" to judge the
- * finish of playing a item in intro mode,instead of the previous
- * condition "iCurrentTime > 10"
- *
- * 96 03-07-16 17:59 Mikelv
- * If current played item is the first one in the program list,then
- * prohibit skipb operation,as customer required.
- *
- * 95 03-07-11 18:13 Mikelv
- * pause not cancel intro mode(request by vestel)
- *
- * 94 03-07-11 16:57 Mikelv
- * donnot clear intro mode at some state(skip,skipb,scan,ect.)
- *
- * 93 03-07-08 20:48 Tonnyg
- * no skipfb if repeat single and PBC on
- *
- * 92 03-07-04 15:11 Mikelv
- * For svcd using pts to measure time,we also need to update current entry
- * number.
- *
- * 91 03-06-25 11:40 Hannahh
- *
- * 90 03-06-19 17:40 Hannahh
- *
- * 89 03-06-19 10:43 Mikelv
- * For a playlist,if itemcnt is 0,should jump to next list
- *
- * 88 03-06-18 22:15 Mikelv
- *
- * 87 03-06-17 19:58 Fwang
- *
- * 86 03-06-17 16:43 Mikelv
- * remove patch for setting TV_SYS_AUTO problem
- *
- * 85 03-06-17 15:00 Fwang
- * Optimize NVM_BMK parameter.
- *
- * 84 03-06-16 21:55 Mikelv
- *
- * 83 03-06-12 11:12 Fwang
- * Elapsed time by PTS
- *
- * 82 03-06-10 21:54 Leslie
- * Fix the type conversion problem when calculating playsectors for
- * laylist Playtime.
- *
- * 81 03-06-09 15:13 Mikelv
- * When bookmark encountered,PE_CD_AbortPlayback() was called and the
- * current time went to zero,at this time,continuely pressed repAB,it will
- * set bookmarkA at 00:00:00,and it is not right.So,prohibit setting
- * bookmarkA at time 00:00:00.
- *
- * 80 03-06-05 14:51 Mikelv
- * Enlarge the least time for repeatAB
- *
- * 79 03-06-04 21:05 Mikelv
- *
- * 78 6/04/03 3:32p Clifflv
- * add mute for amplifier
- *
- * 77 03-06-03 17:51 Fwang
- * Cancel scan mode when enter digest.
- *
- * 76 03-06-02 18:24 Fwang
- * Set NVM bookmark by parameter
- *
- * 75 03-05-29 11:34 Leslie
- * Handle DVP Decoding stucking
- *
- * 74 03-05-28 11:19 Fwang
- * Specified auto postion in NVM_BMK_SET()
- *
- * 73 03-05-28 9:40 Fwang
- * Set bookmark type in NVM_BMK_SET()
- *
- * 72 03-05-27 22:44 Fwang
- * Add NVM bookmark
- *
- * 71 03-05-23 22:49 Leslie
- * Enable Watchdog for still picture presentation
- *
- * 70 03-05-22 11:48 Leslie
- * Add jmp table for error recovery
- * Code cleanup
- *
- * 69 03-05-21 21:41 Leslie
- * Notify UI operation error for time search if time is invalid
- *
- * 68 03-05-16 22:20 Leslie
- * New error recovery implementation
- *
- * 67 5/15/03 9:13a Tonnyg
- * enable disc search when PBC on for s/vcd.
- *
- * 66 03-04-29 22:32 Leslie
- * Add Entry Information parse
- *
- * 65 03-04-23 11:41 Mikelv
- * if play mode changed,clear the bookmarks.
- *
- * 64 03-04-17 17:51 Tonnyg
- * fix the bug that can't set A-B after set A/A-B then repeat single
- *
- * 63 03-04-17 15:45 Tonnyg
- * add prohibit information display to illegal selection
- *
- * 62 03-04-17 14:51 Tonnyg
- * Prohibit pre/next when repeat single, just jump to the beginning, same
- * as DVD.
- *
- * 61 03-04-09 20:04 Leslie
- *
- * 60 03-04-07 14:48 Billt
- * don't cancel repeat when play from stopresume
- *
- * 59 03-03-26 16:45 Hannahh
- *
- * 58 03-03-26 11:21 Leslie
- * Fix the Slow Backward Track boundary problem
- *
- * 58 03-03-22 17:40 Leslie
- * Fix Slow Backward Track boundary problem
- *
- * 57 03-03-15 20:33 Leslie
- *
- * 56 03-03-13 15:15 Leslie
- * Fix SVCD Slow/Fast back problem on boundary of tracks
- *
- * 56 3/03/03 7:02p Rinata
- * Update g_pSVCDNav->m_dwSecondTrackAddress before return when VCD is
- * detected on scratch disc
- *
- * 55 03-03-03 10:35 Leslie
- *
- * 54 03-02-28 14:55 Leslie
- * Set correct list item number when switch from PBC on to off
- *
- * 53 03-02-27 15:13 Leslie
- * Update with ZCH change
- *
- * 54 2/26/03 9:50p Rinata
- * fixed calculation of wTotalElpasedTime
- *
- * 53 03-02-24 14:19 Hannahh
- * Replace printf to debug
- *
- * 52 03-02-24 14:09 Hannahh
- * Replace printf to debug
- *
- * 51 2/21/03 7:19a Stephaneh
- * Added functions to access SVCD navigator variables from UI, in order to
- * check zoom availability (especially during SVCD menu)
- *
- * 50 03-02-18 10:34 Leslie
- * Support SVCD Total elapsed time
- *
- * 49 2/07/03 10:48p Tomasp
- * - changed SW feature selection to compilation switch
- * - code clean up
- *
- * 48 03-01-28 2:26 Leslie
- * Support DISC_TRACK_DIGEST_VIEW_ENABLE mode
- * Using Sc-Pad instead of Heap to save memory for Digest Mode
- *
- * 47 03-01-24 20:33 Leslie
- * Support Intro Play Mode for VCD/SVCD/CVD
- *
- * 46 1/23/03 4:28a Rinata
- * Change Dacs API name and add more Dacs support
- *
- * 45 03-01-14 1:41 Leslie
- * Fix Slow Reverse problem
- *
- * 44 03-01-10 12:23 Leslie
- * Update with File-System Change
- *
- * 43 12/09/02 6:12p Leslie
- * Code cleanup
- *
- * 42 11/29/02 7:44a Leslie
- * Infor Error to UI if Return operation is not valid
- *
- * 41 11/13/02 10:48a Leslie
- * Set the right Audio SID for VCD Entry items playback
- *
- * 40 11/10/02 10:10a Leslie
- * Fix Slow-Rev->Pause->Play freezing problem
- *
- * 39 10/30/02 19:14 Yarone
- * change error recovery print to tr
- *
- * 38 10/30/02 17:49 Rond
- *
- * 68 4/06/02 10:14 Nirm
- * - Corrected COP_MASK handling for NEXT: should only be during PBC-Off.
- *
- * 67 2/06/02 15:46 Nirm
- * - Allowed time-display during MPEG-2 segments.
- *
- * 66 27/05/02 18:21 Nirm
- * - Cleaned-up compilation-warnings.
- *
- * 65 27/05/02 10:46 Ettim
- * Changed the number of available bookmarks to 5.
- *
- * 64 5/16/02 11:43a Dingming
- * fix the svcd total time problem
- *
- * 63 15/05/02 9:23 Ettim
- * Removed some compilation warning messages.
- *
- * 62 13/05/02 20:18 Nirm
- * - Expilict casting of some fields, to prevent unwanted trancation.
- *
- * 61 12/05/02 17:53 Ettim
- * Disabling zoom when playing CDDA tracks (Bug #198).
- * Cancle any ongoing zoom when returning to still menu (Bug #197).
- *
- * 60 5/10/02 12:15p Dingming
- * fix shuffle stuck problem
- *
- * 59 9/05/02 18:22 Ettim
- * Enabled Next on Repeat All from the last track back to the first track.
- * (Bug #240)
- *
- * 58 9/05/02 15:48 Ettim
- * Emulating an EndList to overcome authoring errors.
- *
- * 57 5/08/02 10:12a Dingming
- * support disc time search(required by china customer)
- *
- * 56 7/05/02 17:55 Nirm
- * - Automatic cancellation of A-B Repeat upon invocation of Digest.
- *
- * 55 7/05/02 16:41 Ettim
- * Added PowerOnResume playback support.
- *
- * 54 6/05/02 14:30 Ettim
- * Added Remaining time value.
- *
- * 53 29/04/02 18:53 Nirm
- * - Code cleanup.
- *
- * 52 23/04/02 14:42 Ettim
- * Performing Prev in a play list when the current item is not the first
- * one, even if Prev Offset is 0xFFFF (Added switch
- * SVCD_FORCE_PERVIOUS_ITEM)
- *
- * 51 23/04/02 9:35 Nirm
- * - Added dependency in "Config.h".
- *
- * 50 22/04/02 18:43 Ettim
- * Fixing some bugs reported by FFM:
- * =============================
- * Clearing Scan & Slow COP_MASK when displaying still images, i.e. slides
- * (FFM VCD bug #5).
- * When performing fast backwards on PROHIBIT_SCAN_ACROSS... from a CDDA
- * track to a VCD track switching to Normal playback of the current track
- * (FFM VCD bug #4).
- * Disabling trigger bit notification when PBC is set to off (worked fine
- * inspite FFM bug #18 was reported).
- *
- * 49 4/16/02 1:15p Dingming
- * If current track is the last track(PBC off mode),disable next
- * operation
- *
- * 48 14/04/02 18:31 Ettim
- * Avoid updating the time when during STOP state.
- *
- * 47 4/11/02 1:08p Dingming
- * fix bookmark can not use item 3.
- * remove Sequence header check for non-vcd
- *
- * 46 11/04/02 9:46 Ettim
- * Getting the parameters for the digest (digest mode & intro frames
- * count) from the UI.
- *
- * 45 10/04/02 12:25 Ettim
- * Moved here the structure Digest_Unit_TAG from digest
- *
- * 44 3/31/02 14:43 Ettim
- * Performing resume play when getting play command while in digest mode.
- * Removing the digest prev/next handling from the navigator.
- *
- * 43 25/03/02 21:00 Nirm
- * Added #include.
- *
- * 42 20/03/02 1:32 Nirm
- * - Fixed a bug in _getPSDRecord(): When the PSD file size is reported to
- * be less than SVCD_PSD_CACHE_SIZE, the cache-hit logic malfunctions for
- * data-requests that exceed the expected range (i.e. authoring-error).
- *
- * 41 3/11/02 17:42 Ettim
- * Initializing the rand seed
- *
- * 40 3/10/02 17:30 Ettim
- * Added Motion Digest support.
- *
- * 39 4/03/02 20:49 Nirm
- * Integrated support for Full-Stop.
- *
- * 38 4/03/02 16:18 Nirm
- * - Fixed wrong time-search in case of SVCD: Time need not be multiplied
- * by two.
- *
- * 37 2/28/02 14:55 Ettim
- * + Updating Next / Prev operation mask while on Digest mode
- * + Performing stop/resume only on track-digest and not disc-digest
- *
- * 36 2/27/02 17:31 Ettim
- * Added Digest support.
- *
- * 35 19/02/02 19:26 Nirm
- * Cancelled Trigger-Bit notification request on transition PBC-On -> PBC
- * Off.
- *
- * 34 2/18/02 17:57 Ettim
- * Implementing the audio sid selection both in the ui and in the
- * navigator.
- *
- * 33 18/02/02 11:26 Nirm
- * Fixed typo in uCurrAudioSID.
- *
- * 32 2/18/02 11:23 Ettim
- * Updated Audio SID setting for the channels C0 & C1
- *
- * 31 2/18/02 11:10 Ettim
- * Updated Audio SID setting for the channels C0 & C1
- *
- * 30 2/18/02 11:01 Ettim
- * Updated Audio SID setting for the channels C0 & C1
- *
- * 29 2/17/02 16:40 Ettim
- * Clearing and setting trigger bit notification on scanning and stop
- * scanning.
- *
- * 28 2/14/02 13:08 Ettim
- * Fixed some warning messages.
- *
- * 27 2/13/02 19:36 Ettim
- * Disabling SLOW & STEP while playing a CDDA track.
- * Implementing AB-Repeat inside a CDDA track.
- * Setting prev on the first play item to jump to the beginning of that
- * item.
- *
- * 26 2/11/02 17:30 Ettim
- * Updating the TimeOffset after scan stopped. (Fixed the FB->Item
- * boundary reached->Play->Absolute time error problem)
- *
- * 25 2/10/02 15:04 Ettim
- * Using the Array for SDRAM allocations.
- * Enabling play, next and prev on Auto Pause.
- *
- * 24 2/06/02 17:17 Ettim
- * Enabling play after slow mode.
- * Fixing the problem of Fast reverse & play - retrying before abandoning
- * the PTS-based measurement
- * Canceling scanning when moving to the previous or the next item.
- *
- * 23 31/01/02 13:49 Nirm
- * Changed CVD support implementation.
- *
- * 22 30/01/02 20:48 Nirm
- * Compilation-Warnings removal.
- *
- * 21 30/01/02 19:34 Nirm
- * Removed unneeded debugging-messages.
- *
- * 20 27/01/02 20:05 Nirm
- * Corrected renewal of Pause across Track boundaries.
- *
- * 16 1/21/02 17:45 Ettim
- * Fixing the feature SVCD_PROHIBIT_PAUSE_ACROSS_ITEM_BOUNDARIES - while
- * perfoming Pause->Next waiting for the first frame of the next track to
- * be displayed.
- * Handling the sequence FF->Pause->Play so that the play continues from
- * the point of the pause.
- *
- * 15 19/01/02 13:05 Atai
- * Change error debug printing
- *
- * 14 1/17/02 19:14 Ettim
- * Handling the CVD encryption
- *
- * 13 16/01/02 18:24 Nirm
- * Replaced dbprintf's with dbg_printf.
- *
- * 12 1/16/02 16:18 Ettim
- * Updating the latest changes performed in the I54 svcd navigator (VBR &
- * Tracks.svd file parsing).
- * Setting the operation mask to enable play while scanning.
- * Updating the macro PE_CD_SetDiscType to get only 1 argument.
- *
- * 9 1/14/02 18:53 Ettim
- * Implementing the AB Repeat option for SVCD_USE_ABSOLUTE_TIME feature.
- *
- * 8 1/13/02 18:18 Ettim
- *
- * 7 1/10/02 18:01 Ettim
- * Implementing the feature SVCD_USE_ABSOLUTE_TIME
- * Fixing the scan - corrected playback resumption from scanning
- *
- * 6 1/07/02 12:04 Ettim
- *
- * 5 1/02/02 14:49 Ettim
- *
- * 4 1/01/02 15:32 Ettim
- *
- * 3 1/01/02 14:03 Atai
- * Code cleaning
- *
- *
- **************************************************************************************** */
- #include "Config.h" // Global Configuration - do not remove!
- #ifdef _DEBUG
- #define IFTRACE if (gTraceNavigator)
- #include "DebugDbgMain.h"
- #endif
- #include "includesysdefs.h"
- #include "includestring_ex.h"
- #include "Kernelker_api.h"
- #include "Kerneleventdef.h"
- #include "playcorecoremaincoregdef.h"
- #include "Drivedrv_api.h"
- #include "PlaycoreAuxCacheAuxCache.h"
- #include "playcoreFileSysFileSystem.h"
- #include "Decoderdecoder.h"
- #include "Decoderdec_io.h"
- #include "playcorePlayModeplaymode.h"
- #include "playcorenav_cddape_cd.h"
- #include "playcorenav_svcdnav_svcd.h"
- #include "playcoreScpadscmgr.h" //SDRAM operations
- #include "playcoreDataStructuresArray.h"
- #include "PlaycoreTimingTiming.h"
- #include "Playcorenav_cddaCdnav_err.h"
- #include "Customerdevicedacaudio_dac.h"
- #include "stringsstrings.h"
- #ifndef EXINO2 //ZKR JK0331 : for power_on_resume in EEPROM
- #ifdef HW_POWER_ON_RESUME
- #include "PlaycoreCoremainnvm_bmk.h"
- #endif
- #endif //EXINO2
- #ifdef WATCHDOG_TRIGGERED_BY_FE
- #include "Playcorenav_svcdsvcd_error_jmp_tbl.c"
- #endif
- #if defined(SVCD_DIGEST_SUPPORT)
- #include "PlaycoreDigestdigest.h"
- #ifndef SVCD_DIGEST_INTRO_FRAMES_CNT
- #define SVCD_DIGEST_INTRO_FRAMES_CNT 5
- #endif
- #endif
- /////////////////////////////////////////////////////////////////////////////////////////////////
- // Globals & Singletons
- extern BOOL g_in_full_stop;
- static WORD g_uNextStaticAllocationOffset = SC_SVCD_NAV_ADDR;
- BYTE g_DigestReadDiscError = 0;
- #if defined(ENHANCED_SEQ_HDR_READING) || defined(EXINO2)
- BOOL g_ucReadSeqHdr = FALSE;
- #endif
- //////////////////////////////////////////////////////////////////////////////////////////////////
- //Function prototypes
- #ifndef EXINO2 //ZKR JK0331 : for power_on_resume in EEPROM
- #ifdef HW_POWER_ON_RESUME
- BOOL SVCDNAV_NvmBmk_Match(NVM_GENERIC_BMK* pGenric_bmk);
- void SVCDNAV_NvmBmk_Set( WORD sc_handle);
- void SVCDNAV_NvmBmk_Play(NVM_GENERIC_BMK *pGenric_bmk);
- #endif
- #endif //EXINO2
- /////////////////////////////////////////////////////////////////////////////
- // Constants and Enumerations
- #define SVCD_ENTRY_SIZE 4 //size in bytes of each entry in the VCD
- #define SCR_RATE 90000L
- #define SVCD_TRACKS_TABLE_ENTRY_SIZE sizeof(SVCD_TracksInfo)
- #define TIME_TILL_VIDEO_ACTIVE 100000L
- #define SVCD_PTS_MONOTONITY_GRACE_RETRIES 10
- #define SLOW_SCAN_SPEED (SHARED_INFO.m_iSlowSpeed)//-1
- #define MAX_WATCHDOG_RETRY_TIMES 50//LX051302: Maximum retry times for error recovery, otherwise, skip to next play item
- #define NUM_OF_SECTORS_PER_SECOND ( ( DEC_DISC_TYPE_VCD == g_pSVCDNav->m_uDiscStandard ) ? 75L : 150L )//LX051302
-
- /////////////////////////////////////////////////////////////////////////////
- // Macros
- #define SHARED_INFO (gns.svcd)
- #define SVCDMessageGap SHARED_INFO.SVCDMessageGap
- #define g_hEntriesTable SHARED_INFO.g_hEntriesTable
- #define g_hSegmentsContentTable SHARED_INFO.g_hSegmentsContentTable
- #define g_hTracksTable SHARED_INFO.g_hTracksTable
- #define g_pSVCDNav SHARED_INFO.g_pSVCDNav
- #define SCAN_FINISH_GAP 30
- //Macros for working seamlessly with "Big Endian" and "Little Endian" platforms
- #ifdef MOTOROLA
- #define BE_DWORD(a) a
- #define BE_WORD(a) a
- #else
- #define BE_DWORD(a) (DWORD)((a << 24) | ((a & 0xFF00) << 8) | ((a & 0xFF0000L) >> 8) | ((a & 0xFF000000L) >> 24))
- #define BE_WORD(a) (WORD)((a << 8) | (a >> 8))
- #endif //MOTOROLA
- /////////////////////////////////////////////////////////////////////////////
- // Common Data-Structures
- typedef struct SVCD_Tracks_Info_TAG
- {
- UINT16 uTrackTime; //Track's time
- BYTE uAudioInfo; //Track's audio info
- } SVCD_TracksInfo;
- typedef struct Digest_Unit_TAG
- {
- DWORD dwAddress;
- UINT16 uSize;
- } Digest_Unit;
- #ifdef D_USE_VARIABLE_FOR_LIB
- extern WORD svcd_skip_back_threshold;
- #endif
- /////////////////////////////////////////////////////////////////////////////////////////////////
- // Private Services - Prototype declaration
- // Internal Services
- static void Constructor(void);
- static void Destructor(void);
- static BOOL _getPSDRecord(DWORD i_dwPSD_Offset, WORD i_uBytesCnt, BYTE *o_pBuffer);
- static ULONG _getBlocksPerSecond(UINT uTrackNumber, ULONG ulTrackSize);
- #ifdef SVCD_DIGEST_SUPPORT
- static void _terminateDigestMode(void);
- #endif
- static void UpdateAudioInfo(UINT uTrackNumber);
- static void SetMarker(enSVCD_MarkerType eMarkerType, WORD uBookmarkNumber);
- static void ClearMarker(enSVCD_MarkerType eMarkerType, WORD uBookmarkNumber);
- static WORD FindDefaultSelectionOffset(DWORD dwCurrentLocation);
- static BOOL PlayItem(WORD uPlayItemNumber, DWORD dwStartPosition);
- static BOOL InvokePlayback(void);
- static DWORD CalculateRecoveryAddress(DWORD dwErrorAddress);
- static void PerformErrorRecovery(void);
- static void CancelRepeatModes(BYTE uModesMask);
- // Internal Events Handlers
- static void OnTimeout(void);
- static void OnWaitTimeExpired(void);
- static void OnPausePeriodExpired(void);
- // Event Handlers
- static void OnTick(void);
- #ifdef D_ENABLE_ELAPSEDTIME_FOR_SLIDESHOW
- static void OnTickOneSec(void);
- #endif
- static void OnPlay(void);
- static void OnRendezvousPoint(enSVCD_RendezvousType eType);
- static void OnPlaybackFinished(void);
- static void OnAutoPauseEngaged(void);
- static void OnStop(enSVCD_StopType eStopType);
- static void OnStep(void);
- static void OnModeChange(void);
- static void OnSetMarkerA(void);
- static void OnSetMarkerB(void);
- static void OnCancelABRepeat(void);
- static void OnGoToBookmark(WORD uBookmarkNumber);
- #ifdef D_ENABLE_DISC_TIMESEARCH
- static void OnGotoDiscTime(ULONG ulTime);
- #endif
- static void OnGotoTime(ULONG ulTime);
- #ifdef SVCD_DIGEST_SUPPORT
- static void OnDigest(UINT16 Param);
- #endif
- static void OnScan(int iSpeed);
- static void OnSlow(int Speed);
- static void OnIFrameDisplayed(void);
- static void OnNextItem(void);
- static void OnPreviousItem(void);
- static void OnNumericSelection(WORD uSelection);
- static void OnGotoEntry(WORD uSelection);
- static void OnReturn(void);
- static void OnAudioSelection(WORD uSelection);
- static void OnStatusReport(void);
- static void OnIntro(void);
- #ifdef EXINO2 //ZKR JK0331 : for power_on_resume in EEPROM
- #ifdef HW_POWER_ON_RESUME
- static WORD GetResumeLeadOutInfo(void);
- static void GetCurretnLocationStructure(void);
- static void GetPSDAvaiableInfo(void);
- static void GetCurrentListInfo(void);
- static void GetVideoTypeInfo(void);
- static void SetResumeLeadOutInfo(void);
- static void SetCurretnLocationStructure(void);
- static void SetPSDAvaiableInfo(void);
- static void SetCurrentListInfo(void);
- static void SetVideoTypeInfo(void);
- static void ClearResumeLeadOutInfo(void);
- #endif
- #endif //EXINO2
- /////////////////////////////////////////////////////////////////////////////////////////////////
- // Public Services
- /////////////////////////////////////////////////////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////////////////////////////
- // int SVCD_Navigator(HDLR_OP Op, EVENT Event, void *Param) -
- // The main router for SVCD-Navigation Events.
- //
- // Input:
- // Op - The type of operation being invoked
- // Event - The event to route
- // Param - An optional parameter for the event being routed
- //
- // Output:
- // Zero if the routing is successful.
- int SVCD_Navigator(HDLR_OP Op, EVENT Event, void *Param)
- {
- UINT16 status2 = inport(I64_STATUS_2);
-
- switch (Op)
- {
- case HDLR_ENTER: Constructor();
- break;
- case HDLR_EXIT: Destructor();
- break;
- case HDLR_EVENT:
- //In case the allocation failed there is no point in handling the event
- if (NULL == g_pSVCDNav)
- return -1;
- switch (Event)
- {
- case IE_CORE_PAUSE:
- OnStop(ePause);
- break;
- case IE_CORE_STEP:
- OnStep();
- break;
- case IE_CORE_STOP:
- {
- enSVCD_StopType eStopType;
- if ((g_disc_type == DEC_DISC_TYPE_SVCD) && (status2 & DEC_LL_STATUS2_SVCD_MPEG1))
- g_disc_type = DEC_DISC_TYPE_VCD;
-
- #ifndef SVCD_ALLOW_NONPBC_RESUME
- eStopType= eFullStop;
- #else
- #ifdef SVCD_DIGEST_SUPPORT
- if (g_pSVCDNav->m_bDigestMode)
- if (eTrackView == Digest_getDigestMode())
- eStopType= eStopResume;
- else
- eStopType= eFullStop;
- else
- eStopType= eStopResume;
- #else
- eStopType= eStopResume;
- #endif //SVCD_DIGEST_SUPPORT
-
- #endif //SVCD_ALLOW_NONPBC_RESUME
- #ifndef SVCD_ALLOW_PBC_RESUME
- // Prohibit "Resume" for PBC on
- if (PM_IsPBC(PM_GetPlaybackMode()))
- eStopType= eFullStop;
- #endif //SVCD_ALLOW_PBC_RESUME
- if (TRUE == (BOOL)Param)
- eStopType= eFullStop;
- OnStop(eStopType);
- }
- break;
- case IE_CORE_RESTART:
- #ifdef EXINO2 //ZKR JK0331 : for power_on_resume in EEPORM
- #ifdef HW_POWER_ON_RESUME
- ClearMarker(eResumePlayback, 0);
-
- if ( GetResumeLeadOutInfo() == gns.svcd.wTotalPlaybackTime)
- {
- ClearResumeLeadOutInfo();
- GetCurretnLocationStructure();
- GetPSDAvaiableInfo();
- GetCurrentListInfo();
- GetVideoTypeInfo();
- if ( g_pSVCDNav->m_bIsUsingPSD )
- {
- PM_SetPBC(TRUE);
- g_pSVCDNav->m_uCurrPlaybackMode= PM_GetPlaybackMode();
- if ( ( g_pSVCDNav->m_iCurrVideoType == STILL_LOWRES ) || ( g_pSVCDNav->m_iCurrVideoType == STILL_HIRES ) )
- gns.svcd.m_CurrPosition.dwStartAddress = -1;
- // <<< SEC shKang122203 : takes too many times for resume playback when menu on status
- #ifdef DISABLE
- g_pSVCDNav->m_dwPSD_CacheBase= 0xFFFF;
- #endif // DISABLE
- // SEC shKang122203 >>>
- }
- else
- {
- PM_SetPBC(FALSE);
- PM_SetPlaybackMode((BYTE) PM_PLAYBACK_NORMAL);
- g_pSVCDNav->m_uCurrPlaybackMode= PM_GetPlaybackMode();
- }
- // <<< ZKR GL50104 : Eliminate unnecessary sequence header reads.
- #if defined(ENHANCED_SEQ_HDR_READING) || defined(EXINO2)
- g_ucReadSeqHdr = TRUE;
- #endif
- // >>>
- }
- else
- #endif
- #else //EXINO2
- #ifdef HW_POWER_ON_RESUME
- ClearMarker(eResumePlayback, 0);
- if ((TRUE == (BOOL)Param)&&(NVM_BMK_Play()))
- {
- dbg_printf(("nNVM Bookmark restart. "));
- }
- else
- #endif//HW_POWER_ON_RESUME
- #endif //EXINO2
-
- {
- #ifdef K1_WL
- if (resume_play_request)
- {
- memcpy(&(gns.svcd.m_CurrPosition), &(g_pSVCDNav->m_ResumePlayback), sizeof(SVCD_Marker));
- resume_play_request = 0;
- }
- else
- #endif
- {
- #ifdef K1_WL
- ClearMarker(eResumePlayback,0);
- #endif
- (gns.svcd.m_CurrPosition).ListType= Undetermined;
- (gns.svcd.m_CurrPosition).dwPSD_Offset= 0;
- (gns.svcd.m_CurrPosition).uListItem= 1; // Start playback from the first Item
- }
- }
- // Fall-Through!
- case IE_CORE_PLAY:
- OnPlay();
- // <<< ZKR GL050104 : Eliminate unnecessary sequence header reads.
- #if defined(ENHANCED_SEQ_HDR_READING) || defined(EXINO2)
- g_ucReadSeqHdr = FALSE;
- #endif
- // >>>
- break;
- case IE_CORE_TITLE_MENU:
- case IE_CORE_DIGEST:
- #ifdef SVCD_DIGEST_SUPPORT
- OnCancelABRepeat();
- usleep(400000L); //mikex_0821_2003_a: add a delay after canceling the AB repeat
- OnDigest((UINT16)Param & 0xFFFF);
- #endif //SVCD_DIGEST_SUPPORT
- break;
- case IE_CORE_NEXT_CHAPTER:
- OnNextItem();
- break;
- case IE_CORE_PREVIOUS_CHAPTER:
- OnPreviousItem();
- break;
- case IE_CORE_GOTO_ENTRY:
- OnGotoEntry((UINT16)Param);
- break;
- case IE_CORE_MENU_NUMERICAL_SELECTION:
- case IE_CORE_NUM_SELECTION:
- OnNumericSelection((UINT16)Param);
- break;
- case IE_CORE_RETURN:
- OnReturn();
- break;
- case IE_CORE_CDNAV_RENDEZVOUS:
- OnRendezvousPoint((enSVCD_RendezvousType)Param);
- break;
- case IE_CORE_CDNAV_FINISHED:
- OnPlaybackFinished();
- break;
- case IE_CORE_CDNAV_TRIGGER:
- OnAutoPauseEngaged();
- break;
- case IE_CORE_AB_REPEAT:
- if (FALSE == (BOOL)Param) {
- OnCancelABRepeat();
- break;
- }
- if (PM_GetRepeatAB() & PM_REPEAT_AB_B)
- OnCancelABRepeat();
- else { //after set A or A-B, set repeat single, then A will never be setted for the dwStartAddress is still there.
- if ((0 == PM_GetRepeatAB())) //&& (-1 == (g_pSVCDNav->m_PositionA).dwStartAddress)) // so I remove this condition, if this is necessary, let me know please, tonnyg
- OnSetMarkerA();
- else if (PM_REPEAT_AB_A == PM_GetRepeatAB())
- OnSetMarkerB();
- }
- break;
- case IE_CORE_SET_BOOKMARK:
- #ifndef EXINO2 //ZKR JK0331 : for power_on_resume in EEPROM
- #ifdef HW_POWER_ON_RESUME
- NVM_BMK_SET((int)Param);
- #endif
- #endif
- SetMarker(eBookmark, (UINT16)Param -1);
- break;
- case IE_CORE_GOTO_BOOKMARK:
- OnGoToBookmark((UINT16)Param - 1);
- break;
- case IE_CORE_SLOW:
- OnSlow((int)Param);
- break;
- case IE_CORE_SCAN:
- OnScan((int)Param);
- break;
- case IE_CORE_TICK_200:
- OnTick();
- break;
- case IE_CORE_TICK_ONE_SEC:
- #ifdef D_ENABLE_ELAPSEDTIME_FOR_SLIDESHOW
- OnTickOneSec();
- #endif
- break;
- case IE_CORE_I_FRAME:
- OnIFrameDisplayed();
- break;
- case IE_CORE_SEAMLESS_MODE_CHANGE:
- OnModeChange();
- break;
- case IE_CORE_AUDIO_STREAM_SELECTION:
- OnAudioSelection((UINT16)Param);
- break;
- case IE_CORE_PM_RESET:
- // Reset the PM mode : program,repeat, random , reset play -A-B
- PM_SetPlaybackMode(PM_PLAYBACK_NORMAL);
- PM_ClearRepeat();
- break;
- //<<<Leslie_0828_2003_B: Comment out
- #if 0
- case IE_CORE_PAUSE_DRIVE: // Fall-Through!
- case IE_CORE_RESUME_DRIVE:
- break;
- #endif
- //Leslie_0828_2003_B>>>
- case IE_CORE_GOTO_TIME:
- OnGotoTime((ULONG)Param);
- // <<< SEC BK.LIM092203 // ZKR GLV778
- #ifdef EXINO2
- ie_send(IE_UI_REFRESH_TIME);
- #endif
- //SEC BK.LIM092203>>>
- break;
- case IE_CORE_GOTO_DISC_TIME:
- #ifdef D_ENABLE_DISC_TIMESEARCH
- OnGotoDiscTime((ULONG)Param);
- #endif
- break;
- #ifdef WATCHDOG_TRIGGERED_BY_FE
- case IE_CORE_DRIVE_READ_FAIL:
- if ( DRV_READ_ERROR_ECC == (DRV_READ_ERROR_TYPE)Param){
- (g_pSVCDNav->m_ErrorRecoveryInfo).ucRetryCounter = 0;
- break;
- }
- dbg_printf(("SVCD_Nav: DriveDriver_ReadFail encountered.n"));
-
- // Force Error-Recovery
- (g_pSVCDNav->m_ErrorRecoveryInfo).uTimeout= 1;
- (g_pSVCDNav->m_ErrorRecoveryInfo).dwParam = PE_CD_GetCurrentLocation();
- tr_printf(("Current location is %lxn", (g_pSVCDNav->m_ErrorRecoveryInfo).dwParam));
- PerformErrorRecovery();
- break;
- case IE_CORE_PICTURE_DECODING_STUCK:
- tr_printf((" Picture Decoding Stuckingn"));
- ie_send_ex(IE_CORE_DRIVE_READ_FAIL, (void *)DRV_READ_ERROR_FROM_BE );
-
- break;
- #endif //WATCHDOG_TRIGGERED_BY_FE
- case EVENT_CLASS_CORE:
- #ifdef _DEBUG
- OnStatusReport();
- #endif //_DEBUG
- break;
- case IE_CORE_CDNAV_INTRO:
- OnIntro();
- break;
- default:
- dbg_printf(("SVCD_Nav: Unexpected Event (%04x)n", (Event & 0xFFFF)));
- break;
- }
- break;
- default:
- dbg_printf(("SVCD_Nav: Unknown Operation requested (%d)n", Op));
- break;
- }
- return 0;
- }
- /////////////////////////////////////////////////////////////////////////////////////////////////
- // Private Services
- /////////////////////////////////////////////////////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////////////////////////////
- // Internal Services
- /////////////////////////////////////////////////////////////////////////////////////////////////
- // void Constructor() -
- // A Constructor for a SVCD-Navigator instance.
- //
- // Input:
- // None
- //
- // Output:
- // None. The Navigator is constructed.
- //
- // Remarks:
- // This method constructs a new SVCD-Navigator, whose internal data and status
- // are kept in the global SVCD_Nav structure.
- static void Constructor(void)
- {
- WORD uEntriesUsedCnt;
- WORD uCurrTrack= 0;
- ULONG ulTemp;
- BYTE aBuffer[SVCD_INFO_HDR_SIZE+1];
- //WORD uSegmentTableEntryOffset;
- //WORD uCurrEntryOffset;
-
- DWORD dwDiscOffset;
- DWORD dwEncryptionInfoAddr;
- DWORD dwEncryptionInfoSize;
- TrackInfo TrackTwo, LastTrack;
- DWORD dwTemp;
- WORD wTemp;
- dbg_printf(("SVCD_Constructor()n"));
- dbg_printf(("--> SVCD-Navigator size is: %d Bytes.n", sizeof(SVCD_Nav_Info)));
- #ifndef EXINO2 //ZKR JK0331 : for power_on_resume in EEPROM
- #ifdef HW_POWER_ON_RESUME
- NVM_BMK_Hook(BMK_SVCD, SVCDNAV_NvmBmk_Match, SVCDNAV_NvmBmk_Set, SVCDNAV_NvmBmk_Play);
- NVM_BMK_Verify();
- #endif
- #endif
- // Initialize the Default Program-List (in case of a VCD1.1 disc, or
- // when PSD-Usage is explicitly disabled).
-
- SVCDMessageGap.ScanFinishGap = 0;
- PM_InitializeProgramList();
- for (ulTemp=1; ulTemp < (((ULONG)PE_CD_GetTracksCnt()==1)?2:(ULONG)PE_CD_GetTracksCnt()); ulTemp++)
- PM_SetProgramListEntry((WORD)ulTemp, (WORD)(ulTemp+1));
- //Allocating the SVCD Navigator struct
- g_pSVCDNav = (SVCD_Nav_Info *)malloc(sizeof(SVCD_Nav_Info));
- if (NULL == g_pSVCDNav) {
- dbg_printf(("Failed to allocate resources for the SVCD Navigator struct.n"));
- return;
- }
- //initializing the rand seed
- srand((UINT16)timing_get_clock());
- // Assume playback NOT using the Playback-Sequence-Descriptor (PSD)
- g_pSVCDNav->m_bIsUsingPSD= FALSE;
- // General initializations
- memset(&(g_pSVCDNav->m_NavigationInfo), 0, sizeof(g_pSVCDNav->m_NavigationInfo));
- #ifdef SVCD_DIGEST_SUPPORT
- g_pSVCDNav->m_bDigestMode = FALSE;
- g_pSVCDNav->m_uiDigestUnits = NULL;
- #endif //SVCD_DIGEST_SUPPORT
- g_pSVCDNav->m_bPendingEvent= FALSE;
- g_pSVCDNav->m_dwWaitTime= SVCD_INFINITE;
- g_pSVCDNav->m_dwTimeout= SVCD_INFINITE;
- g_pSVCDNav->m_dwPausePeriod= SVCD_INFINITE;
- g_pSVCDNav->m_uFirstCDDA_Track= 100;
- SHARED_INFO.m_iScanSpeed= 0;
- SHARED_INFO.bIsIntroPlayMode = FALSE;
- // Clear all Markers and Bookmarks
- ClearMarker(eResumePlayback, 0);
- ClearMarker(eMarkerA, 0);
- ClearMarker(eMarkerB, 0);
-
- for (ulTemp=0; ulTemp < SVCD_MAX_BOOKMARKS; ulTemp++)
- ClearMarker(eBookmark, (WORD)ulTemp);
- // Initialize the Playback-Mode to "Normal"
- PM_SetPlaybackMode(PM_PLAYBACK_NORMAL);
- g_pSVCDNav->m_uCurrPlaybackMode= PM_GetPlaybackMode();
- // Reset Time-Measurement Info
- #ifdef USE_PTS_TO_MEASURE_TIME
- (g_pSVCDNav->m_TimeMeasurementInfo).bUsePTS= TRUE; // By default, measuer using PTS's
- #else
- (g_pSVCDNav->m_TimeMeasurementInfo).bUsePTS= FALSE; // Measuer not using PTS's
- #endif
- (g_pSVCDNav->m_TimeMeasurementInfo).bAcquireStartPTS= TRUE;
- (g_pSVCDNav->m_TimeMeasurementInfo).dwStartPTS= 0;
- // Set the deafult values for the Current-Position marker
- (SHARED_INFO.m_CurrPosition).ListType= Undetermined; // The type of the first List is yet undetermined
- (SHARED_INFO.m_CurrPosition).dwPSD_Offset= 0; // The first List is at the beginning of the PSD
- (SHARED_INFO.m_CurrPosition).uListItem= 1; // By default, begin with the first item in the List
- (SHARED_INFO.m_CurrPosition).dwStartAddress= -1; // The address is yet undefined
- // Reset the Current-Location Change indicator
- g_pSVCDNav->m_bLocationChanging= FALSE;
- g_pSVCDNav->m_dwTargetLocation= 0;
- // Initialize the settings of the Global variables
- SHARED_INFO.iCurrentTime= 0;
- SHARED_INFO.uCurrentTrackNumber= 2;
- gns.svcd.bEntryInfoAvaiable = FALSE;
- gns.svcd.wCurrentEntryNumber = 0xFFFF;
-
- //configure the disc type to VCD by default
- // PE_CD_SetDiscType(DEC_DISC_TYPE_VCD);//LX0713: Comment out, in case teh Dec Cache is flushed
- if (! PE_CD_GetTrackInfo( (PE_CD_GetTracksCnt()==1)?1:2, &TrackTwo) ||
- ! PE_CD_GetTrackInfo(PE_CD_GetTracksCnt(), &LastTrack))
- {
- SHARED_INFO.wTotalPlaybackTime= 0;
- SHARED_INFO.wRemainingPlaybackTime = 0;
- }
- else
- {
- if(PE_CD_GetTracksCnt()==1)
- {
- BYTE aBuffer[SVCD_INFO_HDR_SIZE];
- if (AuxCache_GetBytes(SVCD_ENTRIES_FILE_ADDRESS, 0, SVCD_ENTRIES_HDR_SIZE, aBuffer))
- {
- if ((0 == strncmp((LPSTR)aBuffer, "ENTRYVCD", 8)) ||
- (0 == strncmp((LPSTR)aBuffer, "ENTRYSVD", 8)))
-
- if ( AuxCache_GetBytes(SVCD_ENTRIES_FILE_ADDRESS, 12, 4, aBuffer))
- {
- TrackTwo.dwStartAddress = drv_msf2lbn(drv_bcd2bin(aBuffer[1]), drv_bcd2bin(aBuffer[2]), drv_bcd2bin(aBuffer[3]));
- }
- }
- }
- SHARED_INFO.wTotalPlaybackTime=
- (WORD)(((LastTrack.dwStartAddress + LastTrack.ulBlocksCnt) -
- TrackTwo.dwStartAddress) / SVCD_BLOCKS_PER_SECOND);
- SHARED_INFO.wRemainingPlaybackTime = SHARED_INFO.wTotalPlaybackTime;
- }
- gcs.pstate= PST_STOP;
- //setting the operation mask
- SET_COP_MASK(0xFFFFFFFFL);
- #ifdef SVCD_DIGEST_SUPPORT
- CLEAR_COP_MASK(COP_ROOT_MENU | COP_ANGLE_CHANGE | COP_SUBPIC_CHANGE);
- SET_COP_MASK(COP_TITLE_MENU);
- #else
- CLEAR_COP_MASK(COP_TITLE_MENU | COP_ROOT_MENU | COP_ANGLE_CHANGE | COP_SUBPIC_CHANGE);
- #endif //SVCD_DIGEST_SUPPORT
- //Set default value
- {
- SHARED_INFO.uCurrentAudioSIDChannel = 1;
- SHARED_INFO.bPBC_Available = FALSE;
- SHARED_INFO.bIsVCD20 = FALSE;
- }
- // Parse the "INFO.VCD" file, and extract the necessary information:
- // First of all, get the System-Identification information
- //if( PE_CD_GetTracksCnt() ==1 )
- // return;
- //ML0618 remove for not being used
- if (! AuxCache_GetBytes(SVCD_INFO_FILE_ADDRESS, 0, SVCD_INFO_HDR_SIZE, aBuffer)) {
- dbg_printf(("Failed to parse INFO.VCD!n"));
- return;
- }
- aBuffer[SVCD_INFO_HDR_SIZE]= 0;
- //Setting the default value to a non encrypted disk
- g_pSVCDNav->m_bIsEncrypted= FALSE;
- // Find-out the type of Standard used in this disc (VCD or SVCD)
- // if (_isSimilarStrings((LPCSTR)aBuffer, "VIDEO_CD")) {
- if ( DEC_DISC_TYPE_VCD == g_disc_type ){//LX0713: Direct check disc type
- dbg_printf(("<<< VCD Disc Detected >>>n"));
- g_pSVCDNav->m_uDiscStandard= DEC_DISC_TYPE_VCD;
- CLEAR_COP_MASK(COP_AUDIO_CHANGE);
- }
- // else if (_isSimilarStrings((LPCSTR)aBuffer, "SUPERVCD") ||
- // _isSimilarStrings((LPCSTR)aBuffer, "HQ-VCD "))
- else if ( DEC_DISC_TYPE_SVCD == g_disc_type ){//LX0713: Direct check disc type
- dbg_printf(("<<< SVCD Disc Detected >>>n"));
- g_pSVCDNav->m_uDiscStandard= DEC_DISC_TYPE_SVCD;
- // Check whether or not the streams are encrypted (CVD)
- if ((eISO9660 == FileSys_determineType()) && FileSys_selectType(eISO9660) &&
- FileSys_initialize(FALSE))
- {
- if (FileSys_changeDir(L"EXT") && FileSys_fileExists(L"DISK.ID")) {
- FindData fdInfo;
- UINT16 hFileFind= FileSys_findFirstFile(L"DISK.ID", &fdInfo);
- if (NULL != hFileFind) {
- g_pSVCDNav->m_bIsEncrypted= TRUE;
- dwEncryptionInfoAddr= fdInfo.dwStartAddr;
- dwEncryptionInfoSize= (DWORD)fdInfo.cbFileSizeLow;
- dbg_printf(("<<< CVD (Encrypted SVCD) Detected >>>n"));
- FileSys_findClose(hFileFind);
- }
- }
- } // endof ISO-9660
- }
- //<<<LX071703: Comment out, meaningless to do this here, alreay know either it is VCD or SVCD
- #if 0
- else {
- BOOL bSuccess;
- g_pSVCDNav->m_dwSecondTrackAddress = TrackTwo.dwStartAddress; // update m_dwSecondTrackAddress
- bSuccess = AuxCache_GetBytes(SVCD_KARINFO_FILE_ADDRESS, 0, 11, aBuffer);
- if (!bSuccess) {
- dbg_printf(("Failed to read the KARINFO.BIH file!n"));
- return;
- }
- if (_isSimilarStrings((LPCSTR)aBuffer, "KARINFO.BIH")) {
- dbg_printf(("<<< VCD 1.1 Disc Detected >>>n"));
- }
- else {
- dbg_printf(("ERROR! The file INFO.VCD is corrupted. Assuming VCD 1.1.n"));
- }
- return;
- }
- #endif
- //LX071703>>>
- dbg_printf(("Version number: %02x.%02xn", aBuffer[8], aBuffer[9]));
- dbg_printf(("Album-ID: %sn", (LPSTR)&aBuffer[10]));
- //check if it is version 2.0 for VCD discs
- if( (aBuffer[8]==0x02)&&(aBuffer[9]==0x00))
- SHARED_INFO.bIsVCD20 = TRUE;
-
- // Now, get selected Navigation-Information
- // We assume that the following information is already resident in the cache
- // Therefore there is no need to encapsulate the calls with exception ingoring
- if ( ! AuxCache_GetBytes( SVCD_INFO_FILE_ADDRESS, SVCD_INFO_HDR_SIZE + 18, 4, (BYTE *)(&(dwTemp)) ) ) {
- dbg_printf((" Failed to parse PSD Size!n"));
- g_pSVCDNav->m_NavigationInfo.ulPSD_Size= 0;
- return;
- }
- else
- g_pSVCDNav->m_NavigationInfo.ulPSD_Size = BE_DWORD(dwTemp);
- if (0 == g_pSVCDNav->m_NavigationInfo.ulPSD_Size)
- SHARED_INFO.bPBC_Available = FALSE;
- if ( ! AuxCache_GetBytes( SVCD_INFO_FILE_ADDRESS, SVCD_INFO_HDR_SIZE + 22, 3, (BYTE *)(g_pSVCDNav->m_NavigationInfo.aFirstSegmentAddress) ) ) {
- dbg_printf((" Failed to parse First Segment Address!n"));
- return;
- }
- //Leslie_1125_2003: Temporarily comment out, need to check why we need to do byte swap here
- #if 0
- else
- {
- BYTE bTemp = g_pSVCDNav->m_NavigationInfo.aFirstSegmentAddress[1];
- g_pSVCDNav->m_NavigationInfo.aFirstSegmentAddress[1] = g_pSVCDNav->m_NavigationInfo.aFirstSegmentAddress[0];
- g_pSVCDNav->m_NavigationInfo.aFirstSegmentAddress[0] = bTemp;
- }
- #endif
- if ( ! AuxCache_GetBytes( SVCD_INFO_FILE_ADDRESS, SVCD_INFO_HDR_SIZE + 25, 1, (BYTE *)(&(g_pSVCDNav->m_NavigationInfo.uOffsetMultiplier)) ) ) {
- dbg_printf((" Failed to parse Offset Multiplier!n"));
- return;
- }
- if ( ! AuxCache_GetBytes( SVCD_INFO_FILE_ADDRESS, SVCD_INFO_HDR_SIZE + 28, 2, (BYTE *)(&wTemp) ) ) {
- dbg_printf((" Failed to parse Maximum segment Number!n"));
- return;
- }
- else
- g_pSVCDNav->m_NavigationInfo.uMaxSegmentNumber = BE_WORD(wTemp);
- // If a PSD exists, then parse the Segment Play-Item Contents Table, and convert it into
- // a collection of SVCD_SegmentPlayItem structures
- if (0 != (g_pSVCDNav->m_NavigationInfo).ulPSD_Size) {
- WORD uCurrSegmentNumber= 1, uSegmentIndex = 0;
- BYTE uSegmentContents;
- SVCD_SegmentPlayItem CurrPlayItem;
- dwDiscOffset= SVCD_SEGMENT_OFFSET_IN_INFO;
- // Get the first Segment's Contents
- //EttiM 27/11/2001 - Nutralizing all calls for exception_xxx
- if (! AuxCache_GetBytes(SVCD_INFO_FILE_ADDRESS, dwDiscOffset++, 1, &uSegmentContents)) {
- dbg_printf(("Failed to parse the Segments Play-Items Table!n"));
- return;
- }
- CurrPlayItem.uSegmentNumber= uCurrSegmentNumber;
- CurrPlayItem.uContents= uSegmentContents;
- CurrPlayItem.uSubSegmentCnt = 1;
-
- // Make sure that the Maximal-Segment Number is valid. If not, assume the maximal possible
- // number of Segments.
- //EttiM TODO: needs to be reconsidered in the future
- //if (0 == (g_pSVCDNav->m_NavigationInfo).uMaxSegmentNumber)
- // (g_pSVCDNav->m_NavigationInfo).uMaxSegmentNumber= SVCD_SEGMENTS_TABLE_SIZE;
- // Allocate enough memory for the Segments table
- //g_uSegmentsContentTable= sc_Malloc(((g_pSVCDNav->m_NavigationInfo).uMaxSegmentNumber * sizeof(SVCD_SegmentPlayItem))/ BYTE_PER_CONTAINER);
- g_hSegmentsContentTable = Array_construct((g_pSVCDNav->m_NavigationInfo).uMaxSegmentNumber,
- sizeof(SVCD_SegmentPlayItem), NULL);
- if (NULL == g_hSegmentsContentTable) {
- dbg_printf(("Failed to allocate resources for the Segments Table.n"));
- return;
- }
- //uSegmentTableEntryOffset = g_uSegmentsContentTable;
- while (uCurrSegmentNumber <= (g_pSVCDNav->m_NavigationInfo).uMaxSegmentNumber) {
- if (! AuxCache_GetBytes(SVCD_INFO_FILE_ADDRESS, dwDiscOffset++, 1, &uSegmentContents)) {
- dbg_printf(("Failed to parse the Segments Play-Items Table!n"));
- return;
- }
- uCurrSegmentNumber++;
- // Check if the current Contents byte starts a new Play-Item
- if (0 == (uSegmentContents & 0x20)) {
- // First, store the previous Play-Item in the Table
- //sc_Write(uSegmentTableEntryOffset, (sizeof(SVCD_SegmentPlayItem) / BYTE_PER_CONTAINER), (Sc_cont*)&CurrPlayItem);
- Array_setAt(g_hSegmentsContentTable, uSegmentIndex, (BYTE *)&CurrPlayItem);
- uSegmentIndex++;
-
- //uSegmentTableEntryOffset += (sizeof(SVCD_SegmentPlayItem) / BYTE_PER_CONTAINER);
- // Now fill-in a new Play-Item
- CurrPlayItem.uSegmentNumber= uCurrSegmentNumber;
- CurrPlayItem.uContents= uSegmentContents;
- //holding the number of sub segments per play item instead of the actual number of blocks
- CurrPlayItem.uSubSegmentCnt = 1;
-
- }
- else
- CurrPlayItem.uSubSegmentCnt++;
- } // endof while
- // Request for notifications of Trigger-Bit occurrence
- PE_CD_RequestNotification(TriggerBit);
- // Engage PSD-usage
- g_pSVCDNav->m_bIsUsingPSD= TRUE;
- #ifdef STORE_PBC_VALUE_IN_PS
- if(PS_GetPBC())
- PM_SetPBC(TRUE);
- else
- PM_SetPBC(FALSE);
- #else
- //mikel_0912_2003_b add compile switch for pbc default setting off
- #ifdef CONFIG_4MB_FLASH
- #ifndef D_DEFAULT_PBCOFF
- // Update the final decision regarding PBC
- PM_SetPBC(TRUE);
- #endif
- #else
- #ifdef D_DEFAULT_PBCOFF//tecobest gxd 20051010
- PM_SetPBC(FALSE);
- #endif
- //IFNDEF(CdMedia_Macro.bD_DEFAULT_PBCOFF)
- // Update the final decision regarding PBC
- // PM_SetPBC(TRUE);
- //ENDIF
- #endif
- #endif //STORE_PBC_VALUE_IN_PS
- }
- else { // A PSD file doesn't exist
- // Do nothing
- PM_SetPBC(FALSE);//LX0713: Set PBC Mode FALSE
- }
- // Now parse the ENTRIES file, which must exist
- memset((void *)aBuffer, 0, SVCD_ENTRIES_HDR_SIZE+1);
- //EttiM 27/11/2001 - Nutralizing all calls for exception_xxx
- if (! AuxCache_GetBytes(SVCD_ENTRIES_FILE_ADDRESS, 0, SVCD_ENTRIES_HDR_SIZE, aBuffer)) {
- dbg_printf(("Failed to parse ENTRIES.VCD!n"));
- g_pSVCDNav->m_NavigationInfo.ulPSD_Size= 0;
- g_pSVCDNav->m_bIsUsingPSD= FALSE;
- return;
- }
- if (_isSimilarStrings((LPCSTR)aBuffer, "ENTRYVCD")) {
- g_pSVCDNav->m_wEntriesUsedCnt = ((aBuffer[10] << 8) | aBuffer[11]);
- dbg_printf(("Entries-File Version: %02x.%02xn", aBuffer[8], aBuffer[9]));
- dbg_printf(("Number of used Entries: %un", g_pSVCDNav->m_wEntriesUsedCnt));
- }
- else {
- // The Entries-File is possibly corrupted: don't use the PSD information
- g_pSVCDNav->m_wEntriesUsedCnt = 0;
- g_pSVCDNav->m_NavigationInfo.ulPSD_Size= 0;
- g_pSVCDNav->m_bIsUsingPSD= FALSE;
- dbg_printf(("Entries-File Header is currupted.n"));
- }
- // For each of the reported entries in the file do the following:
- // - If it is the first entry within a given Track, verify that the start-address is accurate,
- // by cross-checking against the TOC entry for that Track; in case of a mismatch, override
- // the Entries information with the TOC information.
- // - Copy the Entry information to the designated place in Entries-Table.
- dwDiscOffset = SVCD_ENTRIES_HDR_SIZE;
- uEntriesUsedCnt = g_pSVCDNav->m_wEntriesUsedCnt;
- g_hEntriesTable = Array_construct((1 + g_pSVCDNav->m_wEntriesUsedCnt),
- SVCD_ENTRY_SIZE,
- &g_uNextStaticAllocationOffset);
- if ( ( g_pSVCDNav->m_wEntriesUsedCnt > 0 ) && ( NULL != g_hEntriesTable ) )
- gns.svcd.bEntryInfoAvaiable = TRUE;
- while (uEntriesUsedCnt > 0)
- {
- if (! AuxCache_GetBytes(SVCD_ENTRIES_FILE_ADDRESS, dwDiscOffset, 4, aBuffer)) {
- dbg_printf(("Failed to parse the Entries file!n"));
- g_pSVCDNav->m_bIsUsingPSD = FALSE;
- return;
- }
- dwDiscOffset += 4;
- if (drv_bcd2bin(aBuffer[0]) != uCurrTrack) {
- TrackInfo CurrTrack;
- // This is the first occurrence of the Track - cross-check it against the TOC
- uCurrTrack= (WORD)drv_bcd2bin(aBuffer[0]);
- if (! PE_CD_GetTrackInfo(uCurrTrack, &CurrTrack)) {
- dbg_printf(("Failed to access the TOC for Track %d.n", (int)uCurrTrack));
- continue;
- }
- if (drv_msf2lbn(drv_bcd2bin(aBuffer[1]), drv_bcd2bin(aBuffer[2]), drv_bcd2bin(aBuffer[3])) != CurrTrack.dwStartAddress) {
- WORD wMin, wSec, wFrm;
- dbg_printf(("Mismatch between Entries info and TOC info for Track %d.n", (int)uCurrTrack));
- // Override the erroneous location with the TOC information
- PE_CD_GetTrackInfoEx(uCurrTrack, &wMin, &wSec, &wFrm);
- aBuffer[1]= drv_bin2bcd(wMin);
- aBuffer[2]= drv_bin2bcd(wSec);
- aBuffer[3]= drv_bin2bcd(wFrm);
- }
- }
- // Copy the (possibly corrected) information to the Entries-Table
- Array_setAt(g_hEntriesTable,
- (g_pSVCDNav->m_wEntriesUsedCnt - uEntriesUsedCnt),
- (BYTE *)aBuffer);
-
- uEntriesUsedCnt--;
- }
- //We add another dummy item at the end of the entries table to mark the last entry
- aBuffer[0] = 0xFF;
- aBuffer[1] = 0xFF;
- aBuffer[2] = 0xFF;
- aBuffer[3] = 0xFF;
- Array_setAt(g_hEntriesTable, g_pSVCDNav->m_wEntriesUsedCnt, (BYTE *)aBuffer);
- //PSD caching handling - the PSD caching area starts at the end of the entries table.
- if (g_pSVCDNav->m_bIsUsingPSD)
- {
- BYTE ucDummy;
- BOOL bPSDRecordAvaliable;
- //setting the PSD caching address to start at the end of the entries table
- g_pSVCDNav->m_wPSD_CacheOffset = g_uNextStaticAllocationOffset;
- g_uNextStaticAllocationOffset += CONTAINER_COUNT(SVCD_PSD_CACHE_SIZE);//Angie_1117_2004: Add the current malloc size for the next static SCPad malloc.
- SHARED_INFO.bPBC_Available = TRUE;
-
- // Force caching of the PSD
- g_pSVCDNav->m_dwPSD_CacheBase = NULL_HANDLE;
- bPSDRecordAvaliable = _getPSDRecord(0, 1, &ucDummy);
- if (FALSE == bPSDRecordAvaliable){
- tr_printf(("Can't get PSD Recodern"));
- }
- // bPSDRecordAvaliable = _getPSDRecord(0, 1, &ucDummy);//LX0713: Comment out, no need to do twice
- if (!bPSDRecordAvaliable)
- {
- dbg_printf(("Failed to cache PSD information.n"));
- g_pSVCDNav->m_bIsUsingPSD = FALSE;
- SHARED_INFO.bPBC_Available = FALSE;
- if (PM_IsPBC(PM_GetPlaybackMode()))
- PM_SetPBC(FALSE);
- return;
- }
- }
- // Mark the base for all CDDA Tracks (if any) in this disc. The first CDDA Track in
- // a SVCD disc is located past the last non-CDDA Track.
- g_pSVCDNav->m_uFirstCDDA_Track= (1 + uCurrTrack);
- // Verify that this track indeed exists and that it actually holds CDDA data.
- // This is done by cross-checking against the TOC info for that track.
- while (g_pSVCDNav->m_uFirstCDDA_Track <= (WORD)PE_CD_GetTracksCnt()) {
- BYTE ucCtrlField;
- DWORD dwDummy;
- if (! PE_CD_GetTrackTOC(g_pSVCDNav->m_uFirstCDDA_Track, &ucCtrlField, &dwDummy, &dwDummy)) {
- dbg_printf(("Failed to acquire TOC information for Track %d.n", g_pSVCDNav->m_uFirstCDDA_Track));
- break;
- }
- // Check if this Track is marked as a CDDA track
- if (0x0 == (ucCtrlField & 0x4))
- break;
- // This track is a Data track - continue to the next one
- g_pSVCDNav->m_uFirstCDDA_Track++;
- }
- //by default there is no MPEG2 directory on the VCD
- g_pSVCDNav->m_bIsMPEG2 = FALSE;
- g_pSVCDNav->m_uCurrAudioSID = MPEG_SID0;
- SHARED_INFO.uCurrentAudioSIDChannel = 1;
- // For SVCD discs, collect the AV-Tracks information
- if (DEC_DISC_TYPE_SVCD == g_pSVCDNav->m_uDiscStandard)
- {
- UINT uTracksCnt= (UINT)PE_CD_GetTracksCnt();
- //UINT cbTracksFileSize= SVCD_TRACKS_HDR_SIZE + (SVCD_TRACKS_RECORD_SIZE * uTracksCnt);
- //we keep only the playback time for each track
- //UINT uTracksTableSize = (SVCD_TRACKS_TABLE_ENTRY_SIZE * uTracksCnt);
- DWORD dwTracksFileAddr;
- //g_uTracksTableOffset = sc_Malloc(uTracksTableSize / BYTE_PER_CONTAINER);
- g_hTracksTable = Array_construct(uTracksCnt, SVCD_TRACKS_TABLE_ENTRY_SIZE, NULL);
- if (NULL == g_hTracksTable) {
- dbg_printf(("Failed to allocate memory for the AV-Tracks Table.n"));
- return;
- }
- // Load the TRACKS file
- if ((eISO9660 == FileSys_determineType()) && FileSys_selectType(eISO9660) &&
- FileSys_initialize(FALSE) && FileSys_changeDir(L"SVCD") &&
- FileSys_getFileLocation(L"TRACKS.SVD", &dwTracksFileAddr))
- {
- UINT uInd;
- SVCD_TracksInfo TracksInfo;
- //checking if there is a directory named MPEG2
- FileSys_goToRootDir();
- g_pSVCDNav->m_bIsMPEG2 = FileSys_changeDir(L"MPEG2");
- //reading the tracks file into the tracks table
- for (uInd = 0; uInd < uTracksCnt; uInd++)
- {
- if (! AuxCache_GetBytes(dwTracksFileAddr, (SVCD_TRACKS_HDR_SIZE + (SVCD_TRACKS_RECORD_SIZE * uInd)),
- SVCD_TRACKS_RECORD_SIZE, aBuffer))
- {
- dbg_printf(("Failed to load TRACKS.SVD!n"));
- Array_destruct(g_hTracksTable);
- g_hTracksTable = NULL;
- //SHARED_INFO.wTotalPlaybackTime *= 2;
-
- return;
- }
-
- //writing the calculated time to the table
- TracksInfo.uTrackTime = ( (drv_bcd2bin(aBuffer[0]) * 60) + //minute
- (drv_bcd2bin(aBuffer[1]))); //second
- TracksInfo.uAudioInfo = aBuffer[4];
- Array_setAt(g_hTracksTable, uInd, (BYTE *)&TracksInfo);
- //DM051602 no need for this,we already get the total time at the beginning
- //adding it to the total playback time
- //SHARED_INFO.wTotalPlaybackTime += (WORD)TracksInfo.uTrackTime;
- }
- }
- else
- {
- dbg_printf(("Failed to acquire TRACKS.SVDn"));
- Array_destruct(g_hTracksTable);
- g_hTracksTable = NULL;
- //SHARED_INFO.wTotalPlaybackTime *= 2;
- }
- SHARED_INFO.wRemainingPlaybackTime = SHARED_INFO.wTotalPlaybackTime;
- } // endof if (DEC_DISC_TYPE_SVCD)
- //getting the second track's address for absolute time calculations purposes
- g_pSVCDNav->m_dwSecondTrackAddress = TrackTwo.dwStartAddress;
-
- // Update the final state of PBC and the Playback-Mode
- if (PM_IsPBC(PM_GetPlaybackMode()) && ! g_pSVCDNav->m_bIsUsingPSD)
- PM_SetPBC(FALSE);
- g_pSVCDNav->m_bIsUsingPSD = PM_IsPBC(PM_GetPlaybackMode());
- g_pSVCDNav->m_ulSecondTrackBlocksPerSecond = _getBlocksPerSecond(2, TrackTwo.ulBlocksCnt);
- PM_SetPBC(g_pSVCDNav->m_bIsUsingPSD);
- // If no PBC is being used, then disable the Return Key
- if (! g_pSVCDNav->m_bIsUsingPSD)
- CLEAR_COP_MASK(COP_RETURN);
- // Update the current Playback-Mode
- g_pSVCDNav->m_uCurrPlaybackMode= PM_GetPlaybackMode();
- // Reset the Error-Recovery mechanism
- (g_pSVCDNav->m_ErrorRecoveryInfo).eRecoveryType= eNoError;
- (g_pSVCDNav->m_ErrorRecoveryInfo).uTimeout= 0;
- (g_pSVCDNav->m_ErrorRecoveryInfo).ucRetryCounter = 0;//LX051302
- #ifdef CVD_ENABLED
- if (g_pSVCDNav->m_bIsEncrypted) {
- // Writing the encoding information to the SDRAM
- if (!PE_CD_EnableCVDDecryption(TRUE, dwEncryptionInfoAddr, dwEncryptionInfoSize))
- {
- dbg_printf(("Failed to extract the Disk-ID.n"));
- g_pSVCDNav->m_bIsEncrypted = FALSE;
- }
- }
- #endif //CVD_ENABLE
- //default setting of the current track information
- g_pSVCDNav->m_aCurrTrack[0]= 0;
- g_pSVCDNav->m_aCurrTrack[1]= -1;
- g_pSVCDNav->m_aCurrTrack[2] = 1;
- //setting the actual value of the disc type
- PE_CD_SetDiscType(g_pSVCDNav->m_uDiscStandard);
- return;
- }
- /////////////////////////////////////////////////////////////////////////////////////////////////
- // void Destructor() -
- // A Destructor for a SVCD-Navigator instance.
- //
- // Input:
- // None.
- //
- // Output:
- // None.
- //
- // Remarks:
- // This method destructs an existing instance of the SVCD-Navigator.
- static void Destructor(void)
- {
- dbg_printf(("SVCD_Destructor()n"));
- #ifdef EXINO2 //ZKR JK0331 : for power_on_resume in EEPROM
- #ifdef HW_POWER_ON_RESUME
- if (g_power_state == POWER_SEQUENCE_OFF_REQUESTED)
- {
- if( (g_in_full_stop != TRUE ) && (PlayList == (gns.svcd.m_CurrPosition).ListType) )
- {
- SetPSDAvaiableInfo();
- SetResumeLeadOutInfo();
- SetCurretnLocationStructure();
- SetCurrentListInfo();
- SetVideoTypeInfo();
- }
- }
- #endif//HW_POWER_ON_RESUME
- #else //EXINO2
- #ifdef HW_POWER_ON_RESUME
- NVM_BMK_UnHook();
- #endif
- #endif //EXINO2
- // Abort any playback
- gcs.pstate = PST_STOP;
- PE_CD_CancelNotification(TriggerBit); // Cancel the Trigger Bit for Auto Pause
-
- PE_CD_AbortPlayback(FALSE); // Force a complete stop
- PE_CD_DisplayLogo();
- if (PST_SCAN == gcs.pstate)
- OnScan(0);
- #ifdef CVD_ENABLED
- if (g_pSVCDNav->m_bIsEncrypted)
- PE_CD_EnableCVDDecryption(FALSE, 0, 0);
- #endif
- #ifdef SVCD_DIGEST_SUPPORT
- if (g_pSVCDNav->m_bDigestMode)
- _terminateDigestMode();
- #endif
- // Free resources
- if (NULL != g_hSegmentsContentTable)
- Array_destruct(g_hSegmentsContentTable);
- if (NULL != g_hEntriesTable)
- {
- Array_destruct(g_hEntriesTable);
- //AngieHe_0114_2005: Should intialize it when destruct,Or it will add again and again when doing open/close many times.
- g_uNextStaticAllocationOffset = SC_SVCD_NAV_ADDR;
- }
- if (NULL != g_hTracksTable)
- Array_destruct(g_hTracksTable);
- g_hSegmentsContentTable = NULL;
- g_hEntriesTable = NULL;
- g_hTracksTable = NULL;
- if (NULL != g_pSVCDNav)
- free(g_pSVCDNav);
- // Cancel any PBC
- PM_SetPBC(FALSE);
- g_in_full_stop = TRUE; /* forces next PLAY to be mapped to RESTART */
- return;
- }
- /////////////////////////////////////////////////////////////////////////////////////////////////
- // BOOL _getPSDRecord( DWORD dwPSD_Offset, WORD uBytesCnt, BYTE *pBuffer) -
- // Retreives a PSD record from the PSD-Cache.
- //
- // Input:
- // This - Points to the current instance of the SVCD-Navigator
- // dwPSW_Offset - The offset within the PSD file of the desired record
- // uBytesCnt - The size of the record to retrieve, in Bytes
- // pBuffer - A pointer to a buffer whose size is at least uBytesCnt Bytes, which
- // will holds the retrieved record.
- //
- // Output:
- // TRUE on success; FALSE otherwise.
- //
- // Remarks:
- // This function is used to both retrieve a PSD record from the PSD-Cache, and to manage the
- // PSD Cache, which is held in the Scratch-Pad.
- // If the requested PSD-Offset is not found in the Cache, the function flushes the entire
- // Cache, and fills it with PSD information starting from the requested Offset, and until
- // the Cache is full.
- static BOOL _getPSDRecord(DWORD i_dwPSD_Offset, WORD i_uBytesCnt, BYTE *o_pBuffer)
- {
- // First of all, check if the required Record is inside the PSD-Cache
- if ( (NULL_HANDLE == g_pSVCDNav->m_dwPSD_CacheBase) ||
- (i_dwPSD_Offset < (DWORD)g_pSVCDNav->m_dwPSD_CacheBase) ||
- ((i_dwPSD_Offset + i_uBytesCnt) > (g_pSVCDNav->m_dwPSD_CacheBase + SVCD_PSD_CACHE_SIZE)) )
- {
- dbg_printf(("PSD-Cache Miss: Caching %d Bytes.n", SVCD_PSD_CACHE_SIZE));
- if (! sc_CopyFromDisc(SVCD_PSD_FILE_ADDRESS, i_dwPSD_Offset, SVCD_PSD_CACHE_SIZE,
- g_pSVCDNav->m_wPSD_CacheOffset))
- {
- dbg_printf(("Failed to Cache PSD information.n"));
- return FALSE;
- }
- g_pSVCDNav->m_dwPSD_CacheBase = i_dwPSD_Offset;
- }
- // Retrieve the required record from the PSD-Cache in the Scratch-Pad
- sc_GetBytes(g_pSVCDNav->m_wPSD_CacheOffset, (WORD)(i_dwPSD_Offset - g_pSVCDNav->m_dwPSD_CacheBase), (WORD)i_uBytesCnt, o_pBuffer);
- return TRUE;
- }
- //////////////////////////////////////////////////////////////////////////////////
- // Function name : _getBlocksPerSecond
- //
- // Purpose : Calculating the VBR for SVCD according to the TRACKS.SVD
- // file content.
- //
- // Input Parameters :
- // UINT uTrackNumber
- // ULONG ulTrackSize
- //
- // Return Value : ULONG
- //
- // Description : Reading the value from the appropriate table in the SDRAM,
- // while taking under consideration cases in which the values
- // are unavailble because of file corruption or wrong data.
- //////////////////////////////////////////////////////////////////////////////////
- static ULONG _getBlocksPerSecond(UINT uTrackNumber, ULONG ulTrackSize)
- {
- ULONG ulBlocksPerSec= SVCD_BLOCKS_PER_SECOND;
- SVCD_TracksInfo TracksInfo;
- if (DEC_DISC_TYPE_SVCD == g_pSVCDNav->m_uDiscStandard)
- {
- #if 0
- //if (NULL_HANDLE != g_uTracksTableOffset)
- if (NULL != g_hTracksTable)
- {
- Array_getAt(g_hTracksTable, (uTrackNumber - 2), (BYTE *)&TracksInfo);
-
- if (TracksInfo.uTrackTime > 0) {
- ulBlocksPerSec= (ulTrackSize / TracksInfo.uTrackTime);
- // Sanity check: make sure that the amount is reasonable for an SVCD
- if (ulBlocksPerSec <= SVCD_BLOCKS_PER_SECOND)
- ulBlocksPerSec= (2 * SVCD_BLOCKS_PER_SECOND);
- }
- else
- // Either the table is illegal or track is less than a second
- ulBlocksPerSec= (2 * SVCD_BLOCKS_PER_SECOND);
- }
- else {
- ulBlocksPerSec= (2 * SVCD_BLOCKS_PER_SECOND);
- }
- #else
- ulBlocksPerSec= (2 * SVCD_BLOCKS_PER_SECOND);
- #endif
- }
- dbg_printf(("BlocksPerSecond= %ld.n", ulBlocksPerSec));
- return ulBlocksPerSec;
- }
- #ifdef SVCD_DIGEST_SUPPORT
- //////////////////////////////////////////////////////////////////////////////////
- // Function name : _terminateDigestMode
- //
- // Purpose : Terminating the on going digest mode.
- //
- // Input Parameters : none
- //
- // Return Value : static void
- //
- // Description : stopping the digest mode, restoring the operation mask, and
- // freeing the digest items array.
- //////////////////////////////////////////////////////////////////////////////////
- static void _terminateDigestMode(void)
- {
- //terminating the current digest session
- Digest_terminate();
- //restoring the operation mask
- SET_COP_MASK(g_pSVCDNav->m_ulCOP_Mask);
- //freeing the digest items array
- // free(g_pSVCDNav->m_uiDigestUnits);
- Array_destruct(g_pSVCDNav->m_uiDigestUnits);
- g_pSVCDNav->m_uiDigestUnits = NULL;
- g_pSVCDNav->m_bDigestMode = FALSE;
-
- }
- #endif //SVCD_DIGEST_SUPPORT
- //////////////////////////////////////////////////////////////////////////////////
- // Function name : UpdateAudioInfo
- //
- // Purpose : Updating the shared audio information.
- //
- // Input Parameters :
- // UINT uTrackNumber - the current played track
- // Return Value : none
- //
- // Description : Reading the current track's audio information from the
- // tracks table and updating the shared information of the
- // current audio sid - currently available audio channels, and
- // the current selected channel.
- //////////////////////////////////////////////////////////////////////////////////
- static void UpdateAudioInfo(UINT uTrackNumber)
- {
- BYTE uAudioInfo;
- SVCD_TracksInfo TracksInfo;
- #ifndef ASSUME_SVCD_4_AUDIO_CHANNELS
- BOOL bC0_Channel, bC1_Channel;
- #endif
- #ifdef ASSUME_SVCD_4_AUDIO_CHANNELS
- SHARED_INFO.uTotalNumberOfAudioChannels = 4;
- #else
- bC0_Channel = FALSE;
- bC1_Channel = FALSE;
- if (NULL == g_hTracksTable) {
- SHARED_INFO.uCurrentAudioSIDChannel = 1;
- g_pSVCDNav->m_uCurrAudioSID = MPEG_SID0;
- SHARED_INFO.uTotalNumberOfAudioChannels = 1;
- return;
- }
- //reading the tracks audio information from the tracks table
- Array_getAt(g_hTracksTable, (uTrackNumber - 2), (BYTE *)&TracksInfo);
- //updating the shared information
- //default values
- SHARED_INFO.uTotalNumberOfAudioChannels = 0;
- uAudioInfo = TracksInfo.uAudioInfo;
- //Setting the total number of available channels
- if (uAudioInfo & 0x0F) {
- bC0_Channel = TRUE;
- if ((g_pSVCDNav->m_bIsMPEG2) && (uAudioInfo & 0x03))
- SHARED_INFO.uTotalNumberOfAudioChannels = 2;
- else
- SHARED_INFO.uTotalNumberOfAudioChannels++;
- }
- if ((uAudioInfo & 0xF0) && (!g_pSVCDNav->m_bIsMPEG2)) {
- bC1_Channel = TRUE;
- SHARED_INFO.uTotalNumberOfAudioChannels++;
- }
- if ((bC0_Channel) && (!bC1_Channel)) {
- g_pSVCDNav->m_uCurrAudioSID = MPEG_SID0;
- SHARED_INFO.uCurrentAudioSIDChannel = 1;
- }
- else if ((bC1_Channel) && (!bC0_Channel)) {
- g_pSVCDNav->m_uCurrAudioSID = MPEG_SID1;
- SHARED_INFO.uCurrentAudioSIDChannel = 2;
- }
- else if ((bC1_Channel) && (bC0_Channel)) {
- g_pSVCDNav->m_uCurrAudioSID = ((1 == SHARED_INFO.uCurrentAudioSIDChannel) ? MPEG_SID0: MPEG_SID1);
- }
- #endif
- }
- /////////////////////////////////////////////////////////////////////////////////////////////////
- // void SetMarker(enSVCD_MarkerType eMarkerType, WORD uBookmarkNumber) -
- // Sets a certain Marker.
- //
- // Input:
- // eMarkerType - Identifies the type of Marker to set
- // uBookmarkNumber - If the Marker Type is "Bookmark", this parameter supplies the
- // serial-number of the Bookmark to set
- //
- // Output:
- // None. The appropriate marker is set.
- //
- static void SetMarker(enSVCD_MarkerType eMarkerType, WORD uBookmarkNumber)
- {
- SVCD_Marker *pMarker= NULL;
- switch (eMarkerType)
- {
- case eMarkerA: pMarker= &(g_pSVCDNav->m_PositionA);
- break;
- case eMarkerB: pMarker= &(g_pSVCDNav->m_PositionB);
- break;
- case eResumePlayback:
- pMarker= &(g_pSVCDNav->m_ResumePlayback);
- break;
- case eBookmark:
- if (uBookmarkNumber >= SVCD_MAX_BOOKMARKS)
- pMarker= NULL;
- else
- pMarker= &(g_pSVCDNav->m_Bookmarks[uBookmarkNumber]);
- break;
- }
- if (NULL == pMarker) {
- dbg_printf(("Failed to set the required Marker.n"));
- return;
- }
- // Set the Marker according to the Current-Position. If the current Playback-Status
- // is "Playing", then also record the current location of the Drive.
- memcpy(pMarker, &(SHARED_INFO.m_CurrPosition), sizeof(SVCD_Marker));
- if ((PST_STOP != gcs.pstate)
- #ifdef K1_WL
- && (PST_STILL != gcs.pstate) //add by wl032404
- #endif
- )
- {
- // Record the current position
- if (SHARED_INFO.bIsElapsedTimeValid)
- {
- #ifdef SVCD_USE_ABSOLUTE_TIME
- //if (SHARED_INFO.uCurrentTrackNumber < g_pSVCDNav->m_uFirstCDDA_Track)
- pMarker->dwStartAddress = (g_pSVCDNav->m_dwSecondTrackAddress +
- (SHARED_INFO.iCurrentTime * g_pSVCDNav->m_aCurrTrack[2]));
- //else
- // pMarker->dwStartAddress = SHARED_INFO.iCurrentTime * g_pSVCDNav->m_aCurrTrack[2];
- #else //SVCD_USE_ABSOLUTE_TIME
- pMarker->dwStartAddress = (g_pSVCDNav->m_aCurrTrack[0] +
- (SHARED_INFO.iCurrentTime * g_pSVCDNav->m_aCurrTrack[2]));
- #endif //SVCD_USE_ABSOLUTE_TIME
-
- }
- else if ((SHARED_INFO.m_CurrPosition).dwStartAddress != -1) //jeanz_0316_2005 Don't set start address of PBC menu, because it won't find the right address when bookmark play.
- pMarker->dwStartAddress = (PE_CD_GetCurrentLocation() - SVCD_LOCATION_TOLERANCE);
- }
- //add by wl032404
- #ifdef K1_WL
- if (( g_pSVCDNav->m_iCurrVideoType == STILL_LOWRES ) || ( g_pSVCDNav->m_iCurrVideoType == STILL_HIRES )
- && (SelectionList == ((gns.svcd).m_CurrPosition).ListType))
- pMarker->dwStartAddress = -1;
- #endif
- // <<< SEC CH.KO050404:porting from trino code
- #ifdef EXINO2
- if (PST_STOP != gcs.pstate)
- {
- if ( eMarkerType == eMarkerA )
- {
- core_set_bookmark_info( 4, pMarker->dwStartAddress/75L ); //FW120501 Record time of marker A
- }
- else
- if ( eMarkerType == eBookmark ){//ZORAN LX0319: set bookmark info
- core_set_bookmark_info( uBookmarkNumber + 1, pMarker->dwStartAddress/75L );
- }
- }
- #endif
- // SEC CH.KO050404>>>
- return;
- }
- /////////////////////////////////////////////////////////////////////////////////////////////////
- // void ClearMarker(enSVCD_MarkerType eMarkerType, WORD uBookmarkNumber) -
- // Sets a certain Marker.
- //
- // Input:
- // eMarkerType - Identifies the type of Marker to clear
- // uBookmarkNumber - If the Marker Type is "Bookmark", this parameter supplies the
- // serial-number of the Bookmark to clear
- //
- // Output:
- // None. The appropriate marker is cleared.
- //
- static void ClearMarker(enSVCD_MarkerType eMarkerType, WORD uBookmarkNumber)
- {
- SVCD_Marker *pMarker= NULL;
- switch (eMarkerType)
- {
- case eMarkerA: pMarker= &(g_pSVCDNav->m_PositionA);
- break;
- case eMarkerB: pMarker= &(g_pSVCDNav->m_PositionB);
- break;
- case eResumePlayback:
- pMarker= &(g_pSVCDNav->m_ResumePlayback);
- break;
- case eBookmark:
- if (uBookmarkNumber >= SVCD_MAX_BOOKMARKS)
- pMarker= NULL;
- else
- pMarker= &(g_pSVCDNav->m_Bookmarks[uBookmarkNumber]);
- break;
- }
- if (NULL == pMarker) {
- dbg_printf(("Failed to clear the required Marker.n"));
- return;
- }
- // Mark the required Marker as invalid
- pMarker->ListType= Undetermined;
- pMarker->dwPSD_Offset= -1;
- pMarker->dwStartAddress= -1;
- pMarker->uListItem= 1;
- return;
- }
- /////////////////////////////////////////////////////////////////////////////////////////////////
- //WORD FindDefaultSelectionOffset(DWORD dwCurrentLocation) -
- // Searches for a Default-Selection List-Offset.
- //
- // Input:
- // dwCurrentLocation - The absolute address of the current location, or -1 if the
- // decision should be done not based on the current location.
- //
- // Output:
- // The List-Offset of the correct Default-List, or 0xFFFF if such a List cannot
- // be determined.
- //
- // Remarks:
- // This function can select a default List Offset in two differnet manners:
- // 1. In Random;
- // 2. Using the Current-Location - the function goes over the different Entries
- // in the ENTRIES database, until the first Entry which has the same Track-Number
- // as the current Track is found.
- // It then goes over each of the entries associated with the current List, and
- // searches for the two entries that contain the Current Location.
- //
- // Method 1 is suitable of any Selection-List; Method 2 is only applicable for
- // Multi-Default Selection-Lists.
- static WORD FindDefaultSelectionOffset(DWORD dwCurrentLocation)
- {
- BYTE aBuffer[2];
- WORD uOffset= 0xFFFF; //, uSC_Offset;
- WORD uCurrItem;
- WORD uRemainingItemsCnt= ((SHARED_INFO.m_CurrList).SelectionList).uSelectionsCnt;
- WORD uTrackNumber, uCurrSection;
- BYTE aCurrEntry[4], aNextEntry[4];
- DWORD dwPSD_Base= ((SHARED_INFO.m_CurrPosition).dwPSD_Offset + SVCD_SELECTIONLIST_HDR_SIZE);
- DWORD dwTrackStartAddress;
- UINT16 uIndex=0;
-
- // First of all, check how to make the selection: in Random, or based on the Current-Location
- if (-1 == dwCurrentLocation) {
- // Make a Random selection
- dbg_printf(("Selecting the first suitable item on the list.n"));
- // Randomly draw some Item in the Selection-List
- if (((SHARED_INFO.m_CurrList).SelectionList).uSelectionsCnt != 0 )//LX0902: Check if zero
- uCurrItem= (rand() % ((SHARED_INFO.m_CurrList).SelectionList).uSelectionsCnt);
- else
- return (WORD)-1;
- // Seek the Items in the List, until an item with a valid offset is found.
- // The list is searched in a cyclic manner.
- while (0 < uRemainingItemsCnt--) {
- // Try to retrieve the appropriate record from the PSD
- if (! _getPSDRecord((dwPSD_Base + (2 * uCurrItem)), 2, aBuffer)) {
- dbg_printf(("Failed to retrieve PSD information.n"));
- return (WORD)-1;
- }
- // Extract and check the value of the Item's offset in the PSD
- uOffset= ((aBuffer[0] << 8) | aBuffer[1]);
- // Check if the current Item has a valid Offset
- if (0xFFFF != uOffset)
- break;
- // The current Item has no valid Offset: continue to check the next item,
- // cyclically.
- uCurrItem= ((uCurrItem+1) % ((SHARED_INFO.m_CurrList).SelectionList).uSelectionsCnt);
- }
- if (0xFFFF == uOffset) {
- dbg_printf(("Cannot find any item on the List suitable for default playback.n"));
- return (WORD)-1;
- }
- return uOffset;
- }
- // Make a selection based on the current Play-Item and the Current-Location (Multi-Default Selection)
- // If the current Play-Item is a Track, find the first Entry containing this Track in the Database.
- if (((SHARED_INFO.m_CurrList).SelectionList).uPlayItemNumber < 100) {
- uTrackNumber= ((SHARED_INFO.m_CurrList).SelectionList).uPlayItemNumber;
- }
- else {
- Array_getAt(g_hEntriesTable,
- (((SHARED_INFO.m_CurrList).SelectionList).uPlayItemNumber - 100),
- (BYTE *)aCurrEntry);
- uTrackNumber= (WORD)drv_bcd2bin(aCurrEntry[0]);
- }
-
- // Go over each of the Entries, until an Entry with the requested
- // Track-Number is found.
- //uSC_Offset = g_uEntriesTableOffset;
- //sc_Read(uSC_Offset, SVCD_ENTRY_SIZE / BYTE_PER_CONTAINER, (Sc_cont*)aCurrEntry);
- uIndex = 0;
- Array_getAt(g_hEntriesTable, uIndex, (BYTE *)aCurrEntry);
-
- while (uTrackNumber != (WORD)drv_bcd2bin(aCurrEntry[0])) {
- Array_getAt(g_hEntriesTable, ++uIndex, (BYTE *)aCurrEntry);
- }
- // Extract the Start-Address of the Current Track
- dwTrackStartAddress= drv_msf2lbn(drv_bcd2bin(aCurrEntry[1]), drv_bcd2bin(aCurrEntry[2]), drv_bcd2bin(aCurrEntry[3]));
- // In a Multi-Default Selection-List, it is guaranteed that the Track is divided to at least uSelectionsCnt
- // sections, therefore start checking the Current-Location against each of these sections, until the
- // section containing the Current-Location is found.
- Array_getAt(g_hEntriesTable, ++uIndex, (BYTE *)aNextEntry);
- //checking if the next entry is the last entry in the table
- if ( (0xFF == aNextEntry[0]) && (0xFF == aNextEntry[1]) &&
- (0xFF == aNextEntry[2]) && (0xFF == aNextEntry[3]) )
- {
- uCurrSection = (uRemainingItemsCnt - 1); //the last section
- }
- else
- {
- for (uCurrSection= 0; uRemainingItemsCnt; uCurrSection++, uRemainingItemsCnt--) {
- DWORD dwStartAddress= drv_msf2lbn(drv_bcd2bin(aCurrEntry[1]), drv_bcd2bin(aCurrEntry[2]), drv_bcd2bin(aCurrEntry[3]));
- DWORD dwEndAddress= drv_msf2lbn(drv_bcd2bin(aNextEntry[1]), drv_bcd2bin(aNextEntry[2]), drv_bcd2bin(aNextEntry[3]));
- UINT32 uStartTime= ((dwStartAddress - dwTrackStartAddress) / SVCD_BLOCKS_PER_SECOND);
- UINT32 uEndTime= ((dwEndAddress - dwTrackStartAddress) / SVCD_BLOCKS_PER_SECOND);
- // First, check for an actual match
- if ((dwStartAddress <= dwCurrentLocation) && (dwCurrentLocation < dwEndAddress))
- break;
- // Second, try to match based on the Elapsed-Time, assuming a Fixed-Bitrate and a relation
- // of 75-Sectors per Second.
- if ((uStartTime <= SHARED_INFO.iCurrentTime) && (SHARED_INFO.iCurrentTime < uEndTime))
- break;
- // Third, try to match taking into consideration a fixed Tolerance, which arises from
- // buffering delays.
- if (((dwCurrentLocation - SVCD_LOCATION_TOLERANCE) >= dwStartAddress) &&
- ((dwCurrentLocation - SVCD_LOCATION_TOLERANCE) < dwEndAddress))
- break;
- // There isn't a match under any criterion -- continue to the next Entry
- *(DWORD*)aCurrEntry = *(DWORD*)aNextEntry;
-
- //uSC_Offset += SVCD_ENTRY_SIZE / BYTE_PER_CONTAINER;
- //sc_Read(uSC_Offset, SVCD_ENTRY_SIZE / BYTE_PER_CONTAINER, (Sc_cont*)aNextEntry);
- uIndex++;
- Array_getAt(g_hEntriesTable, uIndex, (BYTE *)aNextEntry);
- }
- }
- // Now, uCurrSection holds the Zero-based offset inside the current Selection-List, which
- // holds the offset of the appropriate Default Item.
- if (! _getPSDRecord((dwPSD_Base + (2*uCurrSection)), 2, aBuffer)) {
- dbg_printf(("Failed to retrieve PSD information.n"));
- return (WORD)-1;
- }
- uOffset= ((aBuffer[0] << 8) | aBuffer[1]);
- return uOffset;
- }
- /////////////////////////////////////////////////////////////////////////////////////////////////
- // BOOL PlayItem(WORD uPlayItemNumber, DWORD dwStartPosition) -
- // Executes a playback of a certain Play-Item.
- //
- // Input:
- // uPlayItemNumber - The absolute Number of the Play-Item (PIN)
- // dwStartPosition - The absolute address from which to actually start the playback,
- // or -1 if the item should be played from its beginning.
- //
- // Output:
- // TRUE if the playback has been started successfully; FALSE otherwise.
- //
- // Remarks:
- // The function determines which kind of Item is being played: a Track, an Entry
- // or a Segment.
- // Accordingly, the correct starting-address, length and Stream-specific paramters
- // are computed.
- // Prior to actually invoking playback, the function calls for Automatic Video-Setting detection,
- // to allow the decoder to perform Scaling when needed.
- static BOOL PlayItem(WORD uPlayItemNumber, DWORD dwStartPosition)
- {
- WORD uCurrTrack= 0;
- DWORD dwSegmentStartAddress= 0;
- DWORD dwPlaybackStartAddress= 0;
- ULONG ulMaxBlocksCnt= 0;
- ULONG ulBlocksCnt= 0;
- DWORD dwActualItemStart;
- UINT16 uIndex;
- enPlaybackType ePBType= eNormalSpeed;
- ULONG ulPlaybackParam= 0;
- dbg_printf(("Playing PIN 0x%04x --> ", uPlayItemNumber));
- g_pSVCDNav->m_bIsSegment = FALSE;
- g_pSVCDNav->m_iCurrVideoType= NoVideo;
- #ifndef ASSUME_SVCD_4_AUDIO_CHANNELS
- g_pSVCDNav->m_uCurrAudioSID= NoAudio;
- #endif
- // Configure the Playback-Type and Parameter according to the current Play-State
- if (PST_SCAN == gcs.pstate) {
- ePBType= eScan;
- ulPlaybackParam= (ULONG)SHARED_INFO.m_iScanSpeed;
- }
- else if (PST_SLOW == gcs.pstate) {
- ePBType= eSlowMotion;
- ulPlaybackParam= (ULONG)SHARED_INFO.m_iSlowSpeed;
- }
- // Envalidate the Elapsed-Time gauge
- SHARED_INFO.bIsElapsedTimeValid= TRUE;
- SET_COP_MASK(COP_ABREPEAT);
- // Clear the Elapsed-Time, if the Item is going to be played from its beginning
- #ifndef SVCD_USE_ABSOLUTE_TIME
- if (-1 == dwStartPosition)
- SHARED_INFO.iCurrentTime= 0;
- #endif //SVCD_USE_ABSOLUTE_TIME
- // Configure the Time-Measurement information:
- // By default, use PTS's for measurement. Invalidate the Start-PTS, and
- // reset the Time-Offset.
- #ifdef USE_PTS_TO_MEASURE_TIME
- if( (ePBType != eScan) && (ePBType != eSlowMotion) )//jeanz_0511_2005 Fix stuck problem during boundary scan.
- (g_pSVCDNav->m_TimeMeasurementInfo).bUsePTS= TRUE; // By default, measuer using PTS's
- #else
- (g_pSVCDNav->m_TimeMeasurementInfo).bUsePTS= FALSE; // Measuer not using PTS's
- #endif
- (g_pSVCDNav->m_TimeMeasurementInfo).bAcquireStartPTS= TRUE;
- #ifndef SVCD_USE_ABSOLUTE_TIME
- (g_pSVCDNav->m_TimeMeasurementInfo).iTimeOffset= 0;
- #endif //SVCD_USE_ABSOLUTE_TIME
- if (uPlayItemNumber < 2) {
- if (! g_pSVCDNav->m_bIsUsingPSD) {
- // If PBC is not used, then this is an invalid PIN.
- dbg_printf(("Invalid PIN: %u.n", uPlayItemNumber));
- return FALSE;
- }
- // <<< SEC shKang032304 : Emergency for Invalid PlayItem
- #ifdef TRINO_MODEL
- else{
- if(PlayList == (SHARED_INFO.m_CurrPosition).ListType && !uPlayItemNumber){
- uPlayItemNumber = 2;
- g_ui_misc_flags.m_bIllegalVCD = TRUE;// <<< SEC CH.KO041404
- PM_SetPBC(FALSE);
- OnModeChange();
- }
- }
- #endif // TRINO_MODEL
- // SEC shKang032304 >>>
- // PBC is being used: this is a special case, of a Play-Item that
- // actually displays nothing. Just pretend to be playing something.
- // For a Selection-List, emulate a single iteration (regardless of the value
- // of the Repeat-Count field).
- if (SelectionList == (SHARED_INFO.m_CurrPosition).ListType)
- ((SHARED_INFO.m_CurrList).SelectionList).uRepeatCnt= 1;
- dbg_printf(("Connectivity Node.n"));
- dbg_printf(("Invalid PIN: %u! skip to next play item.n",uPlayItemNumber));
- ie_send(IE_CORE_CDNAV_FINISHED);
-
- return TRUE;
- }
- SET_COP_MASK(COP_STOP | COP_PAUSE | COP_SLOW | COP_SCAN | COP_SCAN_BACKWARD | COP_STEP);
- if ((uPlayItemNumber >= 2) && (uPlayItemNumber <= 99)) {
- // The Play-Item is a Track within the Disc: Check if it contains CDDA Audio or not,
- // and arrange for its playback, taking into considertation the value of the Playing-Time
- // in the case of a PlayList.
- TrackInfo CurrTrack;
- dbg_printf(("Track #%u.n", uPlayItemNumber));
- g_pSVCDNav->m_iCurrVideoType= MPEG_2;
- if (uPlayItemNumber < g_pSVCDNav->m_uFirstCDDA_Track) {
- // This is an AV Track
- g_pSVCDNav->m_uCurrAudioSID = (MPEG_SID0|SI_SVCD_AUDIO_NUM-1);
- UpdateAudioInfo(uPlayItemNumber);
- SET_COP_MASK(COP_ZOOM);
- }
- else {
- // This is a CDDA Track
- g_pSVCDNav->m_uCurrAudioSID = CDDA_SID;
- (g_pSVCDNav->m_TimeMeasurementInfo).bUsePTS= FALSE; // For CDDA, use MSF instead of PTS
-
- if (PST_SCAN == gcs.pstate)
- ePBType = eSearch;
- //When playnig a CDDA slow & step & zoom are prohibited
- CLEAR_COP_MASK(COP_SLOW | COP_STEP | COP_ZOOM);
- }
- // Acquire information of the associated Track
- if ( PE_CD_GetTrackInfo(((ULONG)PE_CD_GetTracksCnt()==1?1:uPlayItemNumber), &CurrTrack))
- {
- if(PE_CD_GetTracksCnt()==1)
- {
- BYTE aBuffer[SVCD_INFO_HDR_SIZE];
- DWORD dwStartAddress;
- if (AuxCache_GetBytes(SVCD_ENTRIES_FILE_ADDRESS, 0, SVCD_ENTRIES_HDR_SIZE, aBuffer))
- {
- if ((0 == strncmp((LPSTR)aBuffer, "ENTRYVCD", 8)) ||
- (0 == strncmp((LPSTR)aBuffer, "ENTRYSVD", 8)))
- if ( AuxCache_GetBytes(SVCD_ENTRIES_FILE_ADDRESS, 12, 4, aBuffer))
- {
- dwStartAddress = drv_msf2lbn(drv_bcd2bin(aBuffer[1]), drv_bcd2bin(aBuffer[2]), drv_bcd2bin(aBuffer[3]));
- CurrTrack.ulBlocksCnt = CurrTrack.ulBlocksCnt + CurrTrack.dwStartAddress - dwStartAddress;
- CurrTrack.dwStartAddress=dwStartAddress;
- }
- }
- }
- }
- else
- {
- dbg_printf(("Failed to enumerate Track Information.n"));
- return FALSE;
- }
- uCurrTrack= uPlayItemNumber;
- dwSegmentStartAddress= CurrTrack.dwStartAddress;
- ulMaxBlocksCnt= CurrTrack.ulBlocksCnt;
- // Record the boundaries of the Track
- g_pSVCDNav->m_aCurrTrack[0]= CurrTrack.dwStartAddress;
- g_pSVCDNav->m_aCurrTrack[1]= CurrTrack.dwStartAddress + CurrTrack.ulBlocksCnt;
- g_pSVCDNav->m_aCurrTrack[2] = _getBlocksPerSecond(uCurrTrack, CurrTrack.ulBlocksCnt);
- dwActualItemStart= CurrTrack.dwStartAddress;
- if (! g_pSVCDNav->m_bIsUsingPSD) {
- // When the PSD is NOT being used, then the Play-Items are always Track numbers
- if (-1 == dwStartPosition) {
- dwPlaybackStartAddress= CurrTrack.dwStartAddress;
- ulBlocksCnt= CurrTrack.ulBlocksCnt;
- }
- else {
- dwPlaybackStartAddress= dwStartPosition;
- ulBlocksCnt= (CurrTrack.ulBlocksCnt - (dwPlaybackStartAddress - CurrTrack.dwStartAddress));
- }
- }
- else {
- // When the PSD is being used, distinguish between a Play-List and a Selection-List
- if (PlayList == (SHARED_INFO.m_CurrPosition).ListType) {
- ULONG ulListPlaySectors;
- ulListPlaySectors = (ULONG)( 5*(ULONG)gns.svcd.m_CurrList.PlayList.uPlayingTime);
-
- // For a Play-List, play from the Start-Address, if one is supplied. The amount
- // of Blocks to play is then determined by the Playing-Time for this Item.
- if (-1 == dwStartPosition) {
- dwPlaybackStartAddress= CurrTrack.dwStartAddress;
- ulBlocksCnt= (0 == ((SHARED_INFO.m_CurrList).PlayList).uPlayingTime) ?
- CurrTrack.ulBlocksCnt : ulListPlaySectors;
- }
- else {
- dwPlaybackStartAddress= dwStartPosition;
- if (0 == ((SHARED_INFO.m_CurrList).PlayList).uPlayingTime) {
- ulBlocksCnt= (CurrTrack.ulBlocksCnt - (dwPlaybackStartAddress - CurrTrack.dwStartAddress));
- }
- else {
- DWORD dwDestinationAddress= (CurrTrack.dwStartAddress + ulListPlaySectors);
- ulBlocksCnt= (dwDestinationAddress - dwPlaybackStartAddress);
- }
- }
- }
- else {
- // For a Selection-List, play from the Start-Address, if one is supplied. Play
- // until the End of the Item.
- if (-1 == dwStartPosition) {
- dwPlaybackStartAddress= CurrTrack.dwStartAddress;
- ulBlocksCnt= CurrTrack.ulBlocksCnt;
- }
- else {
- dwPlaybackStartAddress= dwStartPosition;
- ulBlocksCnt= (CurrTrack.ulBlocksCnt - (dwPlaybackStartAddress - CurrTrack.dwStartAddress));
- }
- }
- }
- // Set the Time-Offset for Time Measurement
- #ifdef SVCD_USE_ABSOLUTE_TIME
- if (!g_pSVCDNav->m_bIsUsingPSD)
- {
- if (uPlayItemNumber < g_pSVCDNav->m_uFirstCDDA_Track)
- //calculating the absolute time offset from the beginning of track #2
- (g_pSVCDNav->m_TimeMeasurementInfo).iTimeOffset = (int)((dwPlaybackStartAddress - g_pSVCDNav->m_dwSecondTrackAddress) / g_pSVCDNav->m_aCurrTrack[2]);
- else
- (g_pSVCDNav->m_TimeMeasurementInfo).iTimeOffset = (int)(dwPlaybackStartAddress / g_pSVCDNav->m_aCurrTrack[2]);
- }
- else
- //in case PBC on, we use relative time only
- (g_pSVCDNav->m_TimeMeasurementInfo).iTimeOffset = (int)((dwPlaybackStartAddress - CurrTrack.dwStartAddress) / g_pSVCDNav->m_aCurrTrack[2]);
- #else //SVCD_USE_ABSOLUTE_TIME
- (g_pSVCDNav->m_TimeMeasurementInfo).iTimeOffset = (int)((dwPlaybackStartAddress - CurrTrack.dwStartAddress) / g_pSVCDNav->m_aCurrTrack[2]);
- #endif //SVCD_USE_ABSOLUTE_TIME
-
- }
- else if ((uPlayItemNumber >= 100) && (uPlayItemNumber <= 599)) {
- // The Play-Item is an Entry from the Entries-Database: Extract the appropriate record
- // and arrange for playback of the item, taking into consideration the value of the Playing-Time
- // in the case of a PlayList.
- BYTE aBuffer[4];
- TrackInfo CurrTrack;
- dbg_printf(("Entry #%u.n", (uPlayItemNumber - 99)));
- // Extract the Entry from the Entries-Table
- //sc_Read(g_uEntriesTableOffset + (SVCD_ENTRY_SIZE * (uPlayItemNumber - 100) / BYTE_PER_CONTAINER),
- // (SVCD_ENTRY_SIZE / BYTE_PER_CONTAINER), (Sc_cont*)aBuffer);
- Array_getAt(g_hEntriesTable, (uPlayItemNumber - 100), (BYTE *)aBuffer);
-
- dbg_printf(("Track %02x, %02x:%02x:%02xn", aBuffer[0], aBuffer[1], aBuffer[2], aBuffer[3]));
- uCurrTrack= (WORD)drv_bcd2bin(aBuffer[0]);
- // Check if the Entry is inside a CDDA Track
- g_pSVCDNav->m_iCurrVideoType= MPEG_2;
- if ( DEC_DISC_TYPE_SVCD != g_pSVCDNav->m_uDiscStandard )
- g_pSVCDNav->m_uCurrAudioSID= MPEG_SID0;
- else
- g_pSVCDNav->m_uCurrAudioSID = (MPEG_SID0|SI_SVCD_AUDIO_NUM-1); //DM080205
-
- //g_pSVCDNav->m_iCurrAudioType= (uCurrTrack >= g_pSVCDNav->m_uFirstCDDA_Track) ? CDDA_SID : MPEG_SID;
- UpdateAudioInfo(uCurrTrack);
- // Retrieve Track-Information, for future use
- if (! PE_CD_GetTrackInfo((int)uCurrTrack, &CurrTrack)) {
- dbg_printf(("Failed to extract Track information.n"));
- return FALSE;
- }
- // Record the boundaries of the containing Track
- g_pSVCDNav->m_aCurrTrack[0]= CurrTrack.dwStartAddress;
- g_pSVCDNav->m_aCurrTrack[1]= (CurrTrack.dwStartAddress + CurrTrack.ulBlocksCnt);
- g_pSVCDNav->m_aCurrTrack[2] = _getBlocksPerSecond(uCurrTrack, CurrTrack.ulBlocksCnt);
- // Calculate the start address
- dwSegmentStartAddress= drv_msf2lbn(drv_bcd2bin(aBuffer[1]), drv_bcd2bin(aBuffer[2]), drv_bcd2bin(aBuffer[3]));
- dwActualItemStart= dwSegmentStartAddress;
- // ulMaxBlocksCnt= CurrTrack.ulBlocksCnt;
- ulMaxBlocksCnt = (CurrTrack.dwStartAddress + CurrTrack.ulBlocksCnt) - dwActualItemStart;
- // Calculate the number of Blocks to play, according to the List Type and the
- // Start-Address.
- if (PlayList == (SHARED_INFO.m_CurrPosition).ListType) {
- ULONG ulListPlaySectors;
- ulListPlaySectors = (ULONG)( 5*(ULONG)gns.svcd.m_CurrList.PlayList.uPlayingTime);
-
- // For a Play-List, play from the Start-Address, if one is supplied. The amount
- // of Blocks to play is then determined by the Playing-Time for this Item.
- if (-1 == dwStartPosition) {
- dwPlaybackStartAddress= dwSegmentStartAddress;
- if (0 == ((SHARED_INFO.m_CurrList).PlayList).uPlayingTime)
- ulBlocksCnt= (CurrTrack.ulBlocksCnt - (dwPlaybackStartAddress - CurrTrack.dwStartAddress));
- else
- ulBlocksCnt= ulListPlaySectors;
- }
- else {
- dwPlaybackStartAddress= dwStartPosition;
- if (0 == ((SHARED_INFO.m_CurrList).PlayList).uPlayingTime) {
- ulBlocksCnt= (CurrTrack.ulBlocksCnt - (dwPlaybackStartAddress - CurrTrack.dwStartAddress));
- }
- else {
- DWORD dwDestinationAddress= (dwSegmentStartAddress + ulListPlaySectors);
- ulBlocksCnt= (dwDestinationAddress - dwPlaybackStartAddress);
- }
- }
- }
- else {
- // For a Selection-List, play from the Start-Address, if one is supplied. Play
- // until the End of the Item.
- if (-1 == dwStartPosition)
- dwPlaybackStartAddress= dwSegmentStartAddress;
- else
- dwPlaybackStartAddress= dwStartPosition;
- ulBlocksCnt= (CurrTrack.ulBlocksCnt - (dwPlaybackStartAddress - CurrTrack.dwStartAddress));
- }
- #ifdef SVCD_USE_ABSOLUTE_TIME
- if (!g_pSVCDNav->m_bIsUsingPSD)
- //calculating the absolute time offset from the beginning of track #2
- (g_pSVCDNav->m_TimeMeasurementInfo).iTimeOffset = (int)((dwPlaybackStartAddress - g_pSVCDNav->m_dwSecondTrackAddress) / g_pSVCDNav->m_aCurrTrack[2]);
- else
- (g_pSVCDNav->m_TimeMeasurementInfo).iTimeOffset= (int)((dwPlaybackStartAddress - CurrTrack.dwStartAddress) / g_pSVCDNav->m_aCurrTrack[2]);
- #else
- // Set the Time-Offset for Time Measurement
- (g_pSVCDNav->m_TimeMeasurementInfo).iTimeOffset= (int)((dwPlaybackStartAddress - CurrTrack.dwStartAddress) / g_pSVCDNav->m_aCurrTrack[2]);
- #endif //SVCD_USE_ABSOLUTE_TIME
- }
- else if ((uPlayItemNumber >= 1000) && (uPlayItemNumber <= 2979)) {
- // The Play-Item is a Segment Play-Item: Search for the corresponding structure within
- // the Items-List.
- SVCD_SegmentPlayItem CurrItem;
- BYTE uSegmentContents;
- dbg_printf(("Segment #%u.n", (uPlayItemNumber - 999)));
- #if 0
- //DM080602 fix sometime menu got scrached
- if (gps->tv_standard == TV_SYS_AUTO)
- {
- BOOL bVideoTypeIsPal = FALSE;
- if (! AuxCache_GetBytes(SVCD_INFO_FILE_ADDRESS, SVCD_SEGMENT_OFFSET_IN_INFO+uPlayItemNumber-1000, 1, &uSegmentContents)) {
- dbg_printf(("Failed to parse the Segments Play-Items Table!n"));
- }
-
- if ((uSegmentContents & 0x1C) > 0x10)
- {
- //PAL segment
- bVideoTypeIsPal = TRUE;
- }
- else if ((uSegmentContents & 0x1C) > 0)
- {
- //NTSC segment
- bVideoTypeIsPal = FALSE;
- }
- PE_CD_Set_OutputVideo_Fromat(bVideoTypeIsPal);
- }
- #endif
- g_pSVCDNav->m_bIsSegment = TRUE;
- // Invalidate the Elapsed-Time indication for Segments, and prohibit A-B Repeat inside
- // a Segment.
- SHARED_INFO.bIsElapsedTimeValid= FALSE;
- SHARED_INFO.iCurrentTime= 0;
- CLEAR_COP_MASK(COP_ABREPEAT);
- SHARED_INFO.uCurrentTrackNumber = uCurrTrack= 1; // Segment Play-Items are always located in Track #1
- g_pSVCDNav->m_aCurrTrack[0] = 0;
- g_pSVCDNav->m_aCurrTrack[1] = -1;
- g_pSVCDNav->m_aCurrTrack[2] = (DEC_DISC_TYPE_SVCD == g_pSVCDNav->m_uDiscStandard) ? 2*SVCD_BLOCKS_PER_SECOND : SVCD_BLOCKS_PER_SECOND;
- CurrItem.uSegmentNumber = 0;
- //Reading the segments and getting the PSD Table offset on the SDRAM
- uIndex= 0;
- while (CurrItem.uSegmentNumber != (uPlayItemNumber - 999)) {
- Array_getAt(g_hSegmentsContentTable, uIndex++, (BYTE *)&CurrItem);
- }
- // Calculate the Start-Address of the Play-Item, assuming that each Segment has a constant
- // size of 2 Seconds.
- dwSegmentStartAddress= (((DWORD)uPlayItemNumber - 1000) * SVCD_BLOCKS_PER_SEGMENT) +
- (DWORD)drv_msf2lbn(drv_bcd2bin((g_pSVCDNav->m_NavigationInfo).aFirstSegmentAddress[0]),
- drv_bcd2bin((g_pSVCDNav->m_NavigationInfo).aFirstSegmentAddress[1]),
- drv_bcd2bin((g_pSVCDNav->m_NavigationInfo).aFirstSegmentAddress[2]));
- dwActualItemStart = dwSegmentStartAddress;
- if (-1 == dwStartPosition) {
- dwPlaybackStartAddress= dwSegmentStartAddress;
- ulBlocksCnt = CurrItem.uSubSegmentCnt * SVCD_BLOCKS_PER_SEGMENT;
- }
- else {
- dwPlaybackStartAddress= dwStartPosition;
- ulBlocksCnt= ((CurrItem.uSubSegmentCnt * SVCD_BLOCKS_PER_SEGMENT) - (dwStartPosition - dwSegmentStartAddress));
- }
- ulMaxBlocksCnt = CurrItem.uSubSegmentCnt * SVCD_BLOCKS_PER_SEGMENT;
- // Check if the Play-Item contains Audio
- if (CurrItem.uContents & 0x3)
- g_pSVCDNav->m_uCurrAudioSID= MPEG_SID0;
- else //DM091702 means no audio
- g_pSVCDNav->m_uCurrAudioSID= NoAudio;
-
- // Check if the Play-Item has a Still Image or Motion video, and check the Resolution
- // settings
- switch ((CurrItem.uContents & 0xC) >> 2)
- {
- case 0x1:
- g_pSVCDNav->m_iCurrVideoType= STILL_LOWRES;
- //slow motion and scan is prohibited during still images playback
- CLEAR_COP_MASK(COP_SLOW | COP_SCAN | COP_SCAN_BACKWARD);
- //clearing previous zoom operation
- ie_send_ex(IE_CORE_ZOOM, (void*)NO_ZOOM);
- #ifdef D_ENABLE_ELAPSEDTIME_FOR_SLIDESHOW
- // In still picture, allow display of the Elapsed-Time
- if ( PlayList == (SHARED_INFO.m_CurrPosition).ListType)
- SHARED_INFO.bIsElapsedTimeValid= TRUE;
- #endif
- break;
- case 0x2:
- g_pSVCDNav->m_iCurrVideoType= STILL_HIRES;
-
- //slow motion and scan is prohibited during still images playback
- CLEAR_COP_MASK(COP_SLOW | COP_SCAN | COP_SCAN_BACKWARD);
- //clearing previous zoom operation
- ie_send_ex(IE_CORE_ZOOM, (void*)NO_ZOOM);
- #ifdef D_ENABLE_ELAPSEDTIME_FOR_SLIDESHOW
- // In still picture, allow display of the Elapsed-Time
- if ( PlayList == (SHARED_INFO.m_CurrPosition).ListType)
- SHARED_INFO.bIsElapsedTimeValid= TRUE;
- #endif
- break;
- case 0x3:
- g_pSVCDNav->m_iCurrVideoType= MPEG_2;
- // In MPEG-2 streams, allow display of the Elapsed-Time
- SHARED_INFO.bIsElapsedTimeValid= TRUE;
- break;
- }
- //<<<LX091202
- if ( ( g_pSVCDNav->m_iCurrVideoType == STILL_HIRES ) || ( g_pSVCDNav->m_iCurrVideoType == STILL_LOWRES ) )
- g_pSVCDNav->ucStillPicturePlaybackFinishedGapCounter = SVCD_STILL_PICTURE_MISS_TIMEOUT;
- else
- g_pSVCDNav->ucStillPicturePlaybackFinishedGapCounter = 0x00;
- //LX091202>>>
- #ifdef _DEBUG
- // Check the Encoding-System of the Play-Item
- if (CurrItem.uContents & 0x10)
- dbg_printf(("Encoding-System is NTSC.n"));
- else
- dbg_printf(("Encoding-System is PAL.n"));
- #endif //_DEBUG
- }
- else
- {
- dbg_printf(("Invalid PIN: %u! skip to next play item.n",uPlayItemNumber));
- ie_send(IE_CORE_CDNAV_FINISHED);
- return TRUE;
- }
- // In case of Random-Access, call for Video-Settings detection, unless the item is a CDDA Track
- if ((CDDA_SID != g_pSVCDNav->m_uCurrAudioSID)
- #if defined(ENHANCED_SEQ_HDR_READING) || defined(EXINO2) // ZKR GL050104 : Eliminate unnecessary sequence header reads.
- && (g_ucReadSeqHdr || g_pSVCDNav->m_bIsUsingPSD)
- #endif
- && (PST_SCAN != gcs.pstate)
- &&((g_disc_type == DEC_DISC_TYPE_VCD) || (g_disc_type == DEC_DISC_TYPE_SVCD)) )
- {
- if(!(PM_GetRepeatAB()&PM_REPEAT_AB_B))
- { if (! PE_CD_AutoDetectVideoSetting(g_pSVCDNav->m_iCurrVideoType, dwSegmentStartAddress, ulMaxBlocksCnt)) {
- dbg_printf(("Failed to detect Video settings.n"));
- }
- }
- }
- #ifdef D_ENABLE_SVCD_SAMPLE_RATE_DETECTION
- if ( ( g_disc_type == DEC_DISC_TYPE_SVCD ) && ( PST_SCAN != gcs.pstate ) && ( PST_SLOW != gcs.pstate ) )
- gns.svcd.ulSVDSamplingRate = PE_CD_AutoDetectAudioSetting(g_pSVCDNav->m_uCurrAudioSID, dwSegmentStartAddress, ulMaxBlocksCnt);
- #endif //D_ENABLE_SVCD_SAMPLE_RATE_DETECTION
- // Update information for Scanning
- g_pSVCDNav->m_aCurrSegment[0]= dwActualItemStart;
- g_pSVCDNav->m_aCurrSegment[1]= (dwPlaybackStartAddress + ulBlocksCnt);
- // When in Reverse-Scan, play from the End
- if ((0 != SHARED_INFO.m_iScanSpeed) && (SHARED_INFO.m_iScanSpeed < 0)) {
- dwPlaybackStartAddress= (dwPlaybackStartAddress + ulBlocksCnt) -
- (2 * abs(SHARED_INFO.m_iScanSpeed) * SVCD_BLOCKS_PER_SECOND);
- if (uPlayItemNumber < g_pSVCDNav->m_uFirstCDDA_Track)
- ulBlocksCnt= (2 * abs(SHARED_INFO.m_iScanSpeed) * SVCD_BLOCKS_PER_SECOND);
- }
- // Update the Global position variable
- SHARED_INFO.uCurrentTrackNumber= uCurrTrack;
- // Request for notifications of Trigger-Bit occurrence
- if (g_pSVCDNav->m_bIsUsingPSD)
- PE_CD_RequestNotification(TriggerBit);
- //jeanz_0511_2005 Fix stuck problem during boundary scan.
- // Request for notifications of IFrame occurrence
- if ( (eScan == ePBType) ||(eSlowMotion == ePBType) )
- PE_CD_RequestNotification(IFrame);
- // Initiate the Error-Recovery Mechanism for Playback-Hangup, unless the item is a Segment
- // that contains a Still image; in which case there is no criterion for detecting a
- // playback-hangup (even if the Still image is accompanied by Audio).
- #if defined (WATCHDOG_TRIGGERED_BY_FE) && !defined (EXINO2)
- if ( g_pSVCDNav->m_bIsSegment && (NoVideo == g_pSVCDNav->m_iCurrVideoType) ) {
- #else
- if (g_pSVCDNav->m_bIsSegment && (MPEG_2 != g_pSVCDNav->m_iCurrVideoType)) {
- #endif
- (g_pSVCDNav->m_ErrorRecoveryInfo).eRecoveryType= eNoError;
- }
- else {
- (g_pSVCDNav->m_ErrorRecoveryInfo).uTimeout= (SVCD_PB_HANGUP_TIMEOUT * (1 + abs(SHARED_INFO.m_iSlowSpeed)));
- (g_pSVCDNav->m_ErrorRecoveryInfo).eRecoveryType= ePlaybackHangup;
- (g_pSVCDNav->m_ErrorRecoveryInfo).dwParam= dwPlaybackStartAddress;
- (g_pSVCDNav->m_ErrorRecoveryInfo).ucRetryCounter = 0;//LX051302
- }
-
- // Indicate that a Current-Location Change is about to take place
- g_pSVCDNav->m_bLocationChanging= TRUE;
- g_pSVCDNav->m_dwTargetLocation= dwPlaybackStartAddress;
- // Display/Remove the Background, depending on whether or not the Item is a CDDA Track,
- // and whether or not PBC is On.
- if ((! g_pSVCDNav->m_bIsUsingPSD) && (CDDA_SID == g_pSVCDNav->m_uCurrAudioSID))
- PE_CD_DisplayBackground(TRUE);
- else
- PE_CD_DisplayBackground(FALSE);
- PE_CD_SetCurrentLocationLBN_Bakcup(dwPlaybackStartAddress);
-
- // Invoke playback
- return PE_CD_PlaySegment(g_pSVCDNav->m_iCurrVideoType, g_pSVCDNav->m_uCurrAudioSID,
- dwPlaybackStartAddress, ulBlocksCnt,
- ePBType, ulPlaybackParam);
- }
- /////////////////////////////////////////////////////////////////////////////////////////////////
- // BOOL InvokePlayback() -
- // Invokes playback of the current List.
- //
- // Input:
- // None
- //
- // Output:
- // TRUE if the playback has been started successfully; FALSE otherwise.
- //
- // Remarks:
- // The function uses the Current-Position in order to retrieve information regarding the
- // next List to play. Once the current List is established, the function calls for
- // playback of the appropriate Play-Item.
- static BOOL InvokePlayback(void)
- {
- int iCurrSlowSpeed = 0;
- // Terminate any pending Rendezvous events
- g_pSVCDNav->m_dwWaitTime= SVCD_INFINITE;
- g_pSVCDNav->m_dwTimeout= SVCD_INFINITE;
- g_pSVCDNav->m_dwPausePeriod= SVCD_INFINITE;
- // Cancel any ongoing playback, while maintaining the current Play-State
- if (PST_STOP != gcs.pstate) {
- PE_CD_AbortPlayback(TRUE); // Maintain Standby mode
- }
- // In the case of not using the PSD, just arrange for playback of the Track whose number is
- // stored in the Program-List Entry pointed by CurrPosition.uListItem.
- if (! g_pSVCDNav->m_bIsUsingPSD) {
- dbg_printf(("Invoking Playback without PSD.n"));
- if ((PST_SCAN == gcs.pstate) && (0 != SHARED_INFO.m_iScanSpeed)) {
- #ifdef SVCD_PROHIBIT_SCAN_ACROSS_ITEM_BOUNDARIES
- // Cancel the on-going Scanning
- OnScan(0);
- gcs.pstate= PST_PLAY;
- #endif //SVCD_PROHIBIT_SCAN_ACROSS_ITEM_BOUNDARIES
- }
- else if ((PST_SLOW == gcs.pstate) && (0 != SHARED_INFO.m_iSlowSpeed)) {
- // First of all, cancel the current Slow-Motion
- iCurrSlowSpeed= SHARED_INFO.m_iSlowSpeed;
- OnSlow(0); // Cancel the ongoing Slow-Motion
- gcs.pstate= PST_PLAY;
- }
- else if (PST_PAUSE == gcs.pstate) {
- #ifdef SVCD_PROHIBIT_PAUSE_ACROSS_ITEM_BOUNDARIES
- // Move to Play state
- gcs.pstate= PST_PLAY;
- #endif //SVCD_PROHIBIT_PAUSE_ACROSS_ITEM_BOUNDARIES
- }
- else {
- // Move to Play state
- gcs.pstate= PST_PLAY;
- }
-
- if (! PlayItem(PM_GetProgramListEntry((SHARED_INFO.m_CurrPosition).uListItem),
- (SHARED_INFO.m_CurrPosition).dwStartAddress))
- {
- dbg_printf(("Failed to play the required Track.n"));
- gcs.pstate= PST_STOP;
- return FALSE;
- }
- #ifndef SVCD_PROHIBIT_SLOW_ACROSS_ITEM_BOUNDARIES
- // Renew Slow-Motion
- if (0 != iCurrSlowSpeed)
- OnSlow(iCurrSlowSpeed);
- #endif //SVCD_PROHIBIT_SLOW_ACROSS_ITEM_BOUNDARIES
- #ifndef SVCD_PROHIBIT_PAUSE_ACROSS_ITEM_BOUNDARIES
- //waiting till the first frame of the next track is displayed
- if (CDDA_SID != g_pSVCDNav->m_uCurrAudioSID)
- {
- int iRetryCount= 20;
- while (!PE_CD_VideoIsActive() && iRetryCount)
- {
- usleep((DWORD)TIME_TILL_VIDEO_ACTIVE);
- iRetryCount--;
- }
- }
- // Renew Pause
- if (PST_PAUSE == gcs.pstate)
- OnStop(ePause);
- #endif //SVCD_PROHIBIT_PAUSE_ACROSS_ITEM_BOUNDARIES
- (SHARED_INFO.m_CurrPosition).dwStartAddress= -1;
- //in case we are playing audio the step and slow options are prohibited
- if (CDDA_SID == g_pSVCDNav->m_uCurrAudioSID)
- {
- SET_COP_MASK(COP_STOP | COP_PAUSE | COP_SCAN | COP_SCAN_BACKWARD |
- COP_NEXT_CHAPTER | COP_PREVIOUS_CHAPTER);
- CLEAR_COP_MASK(COP_SLOW | COP_STEP);
- }
- else
- {
-
- SET_COP_MASK(COP_STOP | COP_PAUSE | COP_SLOW | COP_SCAN | COP_SCAN_BACKWARD |
- COP_STEP | COP_NEXT_CHAPTER | COP_PREVIOUS_CHAPTER);
- //If current track is the last one,clear next cop mask
- if ((SHARED_INFO.m_CurrPosition).uListItem == (PM_GetProgramSize() - 1))
- CLEAR_COP_MASK(COP_NEXT_CHAPTER);
- }
- return TRUE;
- }
- // The PSD information is being used:
- // Check if there's need to determine the type of the List
- if (Undetermined == (SHARED_INFO.m_CurrPosition).ListType) {
- BYTE aBuffer[SVCD_SELECTIONLIST_HDR_SIZE];
- if (! _getPSDRecord((SHARED_INFO.m_CurrPosition).dwPSD_Offset, SVCD_SELECTIONLIST_HDR_SIZE, aBuffer)) {
- dbg_printf(("Failed to parse a PSD List.n"));
- return FALSE;
- }
- switch (aBuffer[0])
- {
- case 0x10: // This is a PlayList
- dbg_printf(("Parsing a PlayListn"));
- (SHARED_INFO.m_CurrPosition).ListType= PlayList;
- ((SHARED_INFO.m_CurrList).PlayList).uItemsCnt= (WORD)aBuffer[1];
- ((SHARED_INFO.m_CurrList).PlayList).uPrevOffset= ((aBuffer[4] << 8) | aBuffer[5]);
- ((SHARED_INFO.m_CurrList).PlayList).uNextOffset= ((aBuffer[6] << 8) | aBuffer[7]);
- ((SHARED_INFO.m_CurrList).PlayList).uReturnOffset= ((aBuffer[8] << 8) | aBuffer[9]);
- ((SHARED_INFO.m_CurrList).PlayList).uPlayingTime= ((aBuffer[10] << 8) | aBuffer[11]);
- ((SHARED_INFO.m_CurrList).PlayList).wWaitTime= aBuffer[12];
- ((SHARED_INFO.m_CurrList).PlayList).wAutoPausePeriod= aBuffer[13];
- break;
- case 0x18: // This is a SelectionList
- dbg_printf(("Parsing a SelectionListn"));
- (SHARED_INFO.m_CurrPosition).ListType= SelectionList;
- ((SHARED_INFO.m_CurrList).SelectionList).uSelectionsCnt= (WORD)aBuffer[2];
- ((SHARED_INFO.m_CurrList).SelectionList).uSelectionBase= (WORD)aBuffer[3];
- ((SHARED_INFO.m_CurrList).SelectionList).uPrevOffset= ((aBuffer[6] << 8) | aBuffer[7]);
- ((SHARED_INFO.m_CurrList).SelectionList).uNextOffset= ((aBuffer[8] << 8) | aBuffer[9]);
- ((SHARED_INFO.m_CurrList).SelectionList).uReturnOffset= ((aBuffer[10] << 8) | aBuffer[11]);
- ((SHARED_INFO.m_CurrList).SelectionList).uDefaultOffset= ((aBuffer[12] << 8) | aBuffer[13]);
- ((SHARED_INFO.m_CurrList).SelectionList).uTimeoutOffset= ((aBuffer[14] << 8) | aBuffer[15]);
- ((SHARED_INFO.m_CurrList).SelectionList).wTimeoutWaitTime= aBuffer[16];
- ((SHARED_INFO.m_CurrList).SelectionList).uRepeatCnt= (WORD)(aBuffer[17] & 0x7F);
- ((SHARED_INFO.m_CurrList).SelectionList).bPostponeEventsDuringPlay= (aBuffer[17] & 0x80) ? TRUE : FALSE;
- ((SHARED_INFO.m_CurrList).SelectionList).uPlayItemNumber= ((aBuffer[18] << 8) | aBuffer[19]);
- break;
- case 0x1F: // This is an EndList
- dbg_printf(("Parsing an EndListn"));
- (SHARED_INFO.m_CurrPosition).ListType= EndList;
- break;
- // <<< SEC CH.KO041204: for illegal VCD
- #ifdef EXINO2
- default:
- (SHARED_INFO.m_CurrPosition).ListType= Undetermined;
- PM_SetPBC(FALSE);
- OnModeChange();
- g_ui_misc_flags.m_bIllegalVCD = TRUE;
- break;
- #endif
- // SEC CH.KO041204 >>>
- }
- } // endof if
- // Invoke the Playback using the information in the current PSD List:
- switch ((SHARED_INFO.m_CurrPosition).ListType)
- {
- case PlayList:
- {
- BYTE aBuffer[2];
- DWORD dwPSD_Offset= ((SHARED_INFO.m_CurrPosition).dwPSD_Offset + SVCD_PLAYLIST_HDR_SIZE
- + (2 * ((SHARED_INFO.m_CurrPosition).uListItem - 1)));
- if (! _getPSDRecord(dwPSD_Offset, 2, aBuffer)) {
- dbg_printf(("Failed to retrieve PSD information.n"));
- return FALSE;
- }
- if ((PST_SCAN == gcs.pstate) && (0 != SHARED_INFO.m_iScanSpeed)) {
- #ifdef SVCD_PROHIBIT_SCAN_ACROSS_ITEM_BOUNDARIES
- // Cancel the on-going Scanning
- OnScan(0);
- gcs.pstate= PST_PLAY;
- #endif //SVCD_PROHIBIT_SCAN_ACROSS_ITEM_BOUNDARIES
- }
- else if ((PST_SLOW == gcs.pstate) && (0 != SHARED_INFO.m_iSlowSpeed)) {
- #ifdef SVCD_PROHIBIT_SLOW_ACROSS_ITEM_BOUNDARIES
- // Cancel the on-going Slow-Motion
- OnSlow(0);
- gcs.pstate= PST_PLAY;
- #endif //SVCD_PROHIBIT_SLOW_ACROSS_ITEM_BOUNDARIES
- }
- else {
- // Move to Play state
- gcs.pstate= PST_PLAY;
- }
- // Update the Previous, Next, and Return Core-Operations according to the appropriate Offsets
- #ifdef SVCD_FORCE_PERVIOUS_ITEM
- #ifndef SKIP_TO_THE_BEGINING//angieh_0324_2004:For Alco,support previous func when play the first track.
- if ((0xFFFF == ((SHARED_INFO.m_CurrList).PlayList).uPrevOffset) &&
- (1 == (SHARED_INFO.m_CurrPosition).uListItem))
- CLEAR_COP_MASK(COP_PREVIOUS_CHAPTER);
- else
- #endif
- #else
- if (0xFFFF == ((SHARED_INFO.m_CurrList).PlayList).uPrevOffset)
- CLEAR_COP_MASK(COP_PREVIOUS_CHAPTER);
- else
- #endif
- SET_COP_MASK(COP_PREVIOUS_CHAPTER);
- if (0xFFFF == ((SHARED_INFO.m_CurrList).PlayList).uNextOffset)
- CLEAR_COP_MASK(COP_NEXT_CHAPTER);
- else
- SET_COP_MASK(COP_NEXT_CHAPTER);
- if (0xFFFF == ((SHARED_INFO.m_CurrList).PlayList).uReturnOffset)
- CLEAR_COP_MASK(COP_RETURN);
- else
- SET_COP_MASK(COP_RETURN);
- if (! PlayItem(((aBuffer[0] << 8) | aBuffer[1]), (SHARED_INFO.m_CurrPosition).dwStartAddress)) {
- dbg_printf(("Failed to invoke playback of Play-Item Number %02x.n", ((aBuffer[0] << 8) | aBuffer[1])));
- gcs.pstate= PST_STOP;
- }
- (SHARED_INFO.m_CurrPosition).dwStartAddress= -1;
-
- if ( (SHARED_INFO.m_CurrPosition).dwStartAddress <= 0 )
- ((SHARED_INFO.m_CurrList).SelectionList).bPostponeEventsDuringPlay = FALSE;
- if (((SHARED_INFO.m_CurrList).PlayList).uItemsCnt == 0x0) //ML 061903 nothing being palyed so jump to next list
- ie_send_ex(IE_CORE_CDNAV_RENDEZVOUS, (void *)eWaitTimeExpired);
- }
- break;
- case SelectionList:
- // If Scanning is in progress, eliminate it
- if (PST_SCAN == gcs.pstate)
- OnScan(0);
- else if (PST_SLOW == gcs.pstate)
- OnSlow(0);
- gcs.pstate= PST_PLAY;
- // Update the Previous, Next, Return, and Play Core-Operations according to the appropriate Offsets
- #ifndef SKIP_TO_THE_BEGINING//angieh_0324_2004:For Alco,support previous func when play the first track.
- if (0xFFFF == ((SHARED_INFO.m_CurrList).SelectionList).uPrevOffset)
- CLEAR_COP_MASK(COP_PREVIOUS_CHAPTER);
- else
- #endif
- SET_COP_MASK(COP_PREVIOUS_CHAPTER);
- if (0xFFFF == ((SHARED_INFO.m_CurrList).SelectionList).uNextOffset)
- CLEAR_COP_MASK(COP_NEXT_CHAPTER);
- else
- SET_COP_MASK(COP_NEXT_CHAPTER);
- if (0xFFFF == ((SHARED_INFO.m_CurrList).SelectionList).uReturnOffset)
- CLEAR_COP_MASK(COP_RETURN);
- else
- SET_COP_MASK(COP_RETURN);
- if (0xFFFF == ((SHARED_INFO.m_CurrList).SelectionList).uDefaultOffset)
- CLEAR_COP_MASK(COP_PLAY);
- else
- SET_COP_MASK(COP_PLAY);
- if (! PlayItem(((SHARED_INFO.m_CurrList).SelectionList).uPlayItemNumber, (SHARED_INFO.m_CurrPosition).dwStartAddress)) {
- dbg_printf(("Failed to invoke playback of Play-Item Number %02x.n", ((SHARED_INFO.m_CurrList).SelectionList).uPlayItemNumber));
- return FALSE;
- }
- (SHARED_INFO.m_CurrPosition).dwStartAddress= -1;
- // Mark that a single iteration has been executed
- ((SHARED_INFO.m_CurrList).SelectionList).uRepeatCnt--;
- break;
- case EndList:
- // Perform Full-Stop (End of Playback)
- OnStop(eFullStop);
- return TRUE;
- // <<< SEC shKang041804 : some specific disc has a illegal List type. must work like VCD 1.0
- #ifdef EXINO2
- case Undetermined:
- {
- dbg_printf(("Invoking Playback without PSD.n"));
- if ((PST_SCAN == gcs.pstate) && (0 != SHARED_INFO.m_iScanSpeed)) {
- #ifdef SVCD_PROHIBIT_SCAN_ACROSS_ITEM_BOUNDARIES
- // Cancel the on-going Scanning
- OnScan(0);
- gcs.pstate= PST_PLAY;
- #endif //SVCD_PROHIBIT_SCAN_ACROSS_ITEM_BOUNDARIES
- }
- else if ((PST_SLOW == gcs.pstate) && (0 != SHARED_INFO.m_iSlowSpeed)) {
- // First of all, cancel the current Slow-Motion
- iCurrSlowSpeed= SHARED_INFO.m_iSlowSpeed;
- OnSlow(0); // Cancel the ongoing Slow-Motion
- gcs.pstate= PST_PLAY;
- }
- else if (PST_PAUSE == gcs.pstate) {
- #ifdef SVCD_PROHIBIT_PAUSE_ACROSS_ITEM_BOUNDARIES
- // Move to Play state
- gcs.pstate= PST_PLAY;
- #endif //SVCD_PROHIBIT_PAUSE_ACROSS_ITEM_BOUNDARIES
- }
- else {
- // Move to Play state
- gcs.pstate= PST_PLAY;
- }
-
- if (! PlayItem(PM_GetProgramListEntry((SHARED_INFO.m_CurrPosition).uListItem),
- (SHARED_INFO.m_CurrPosition).dwStartAddress))
- {
- dbg_printf(("Failed to play the required Track.n"));
- gcs.pstate= PST_STOP;
- return FALSE;
- }
- #ifndef SVCD_PROHIBIT_SLOW_ACROSS_ITEM_BOUNDARIES
- // Renew Slow-Motion
- if (0 != iCurrSlowSpeed)
- OnSlow(iCurrSlowSpeed);
- #endif //SVCD_PROHIBIT_SLOW_ACROSS_ITEM_BOUNDARIES
- #ifndef SVCD_PROHIBIT_PAUSE_ACROSS_ITEM_BOUNDARIES
- //waiting till the first frame of the next track is displayed
- if (CDDA_SID != g_pSVCDNav->m_uCurrAudioSID)
- {
- int iRetryCount= 20;
- while (!PE_CD_VideoIsActive() && iRetryCount)
- {
- usleep((DWORD)TIME_TILL_VIDEO_ACTIVE);
- iRetryCount--;
- }
- }
- // Renew Pause
- if (PST_PAUSE == gcs.pstate)
- OnStop(ePause);
- #endif //SVCD_PROHIBIT_PAUSE_ACROSS_ITEM_BOUNDARIES
- (SHARED_INFO.m_CurrPosition).dwStartAddress= -1;
- //in case we are playing audio the step and slow options are prohibited
- if (CDDA_SID == g_pSVCDNav->m_uCurrAudioSID)
- {
- SET_COP_MASK(COP_STOP | COP_PAUSE | COP_SCAN | COP_SCAN_BACKWARD |
- COP_NEXT_CHAPTER | COP_PREVIOUS_CHAPTER);
- CLEAR_COP_MASK(COP_SLOW | COP_STEP);
- }
- else
- {
-
- SET_COP_MASK(COP_STOP | COP_PAUSE | COP_SLOW | COP_SCAN | COP_SCAN_BACKWARD |
- COP_STEP | COP_NEXT_CHAPTER | COP_PREVIOUS_CHAPTER);
- //If current track is the last one,clear next cop mask
- if ((SHARED_INFO.m_CurrPosition).uListItem == (PM_GetProgramSize() - 1))
- CLEAR_COP_MASK(COP_NEXT_CHAPTER);
- }
- return TRUE;
- }
- #endif // EXINO2
- // SEC shKang041804 >>>
- }
- return TRUE;
- }
- /////////////////////////////////////////////////////////////////////////////////////////////////
- // void CalculateRecoveryAddress() -
- // Calculates a destination address for attempting Error-Recovery.
- //
- // Input:
- // dwErrorAddress - Holds the LBN where the Error occurred.
- //
- // Output:
- // None.
- //
- // Remarks:
- // If the Error Address is met for the first time, Recovery will be attempted from the
- // exact same place.
- // For successive occurrences of the Error, a Linear offset is used to advance through
- // the Segment.
- // Note: This function is only meant to be used in conjunction with a forward playback.
- // Since Reverse-Playback is unsupported, and Reverse-Scan is handled by a different
- // Error-Recovery mechanism, this poses no limitation over Error-Recovery.
- #define LINEAR_ERROR_RECOVERY_OFFSET 10
- static DWORD CalculateRecoveryAddress(DWORD dwErrorAddress)
- {
- #ifndef WATCHDOG_TRIGGERED_BY_FE
- static DWORD dwLastError= 0;
- static UINT8 uOccurrences= 0;
- // Check if this is the first time that we've seen this Address
- if (dwErrorAddress != dwLastError) {
- uOccurrences= 0; // Restart the mechanism for this Address
- dwLastError= dwErrorAddress;
- }
- // Begin Calculation of the Recovery Address
- if (1 == ++uOccurrences) {
- // At the first attempt, always try to replay the original segment
- return dwErrorAddress;
- }
- // Use a fixed linear offset for Recovery
- return (dwErrorAddress + LINEAR_ERROR_RECOVERY_OFFSET + (75 * uOccurrences));
- #else
- //<<<LX051302: New error recovery
- if ( (g_pSVCDNav->m_ErrorRecoveryInfo).ucRetryCounter < SVCD_ERROR_RETRY_NUM )
- return( dwErrorAddress +
- g_miSVCDNSPBErrorJumpTbl[(g_pSVCDNav->m_ErrorRecoveryInfo).ucRetryCounter]*NUM_OF_SECTORS_PER_SECOND);
- else
- return ( dwErrorAddress + (DWORD)( 4*NUM_OF_SECTORS_PER_SECOND*((g_pSVCDNav->m_ErrorRecoveryInfo).ucRetryCounter+1) ) );
- #endif//WATCHDOG_TRIGGERED_BY_FE
- //LX051302>>>
- }
- /////////////////////////////////////////////////////////////////////////////////////////////////
- // void PerformErrorRecovery() -
- // Performs Error-Recovery, if needed.
- //
- // Input:
- // None.
- //
- // Output:
- // None.
- //
- // Remarks:
- // The function uses the Error-Recovery Information in order to determine which kind of
- // Error-Recovery mechanism to engage, if any.
- // This function is expected to be called periodically in order to detecet an Error situation.
- // The Error-Recovery Mechanism is selected by the Navigator according to the appropriate
- // situation.
- // In response, this function will attempt to return the system to natural flow, if possible.
- static void PerformErrorRecovery(void)
- {
- DWORD dwCurrentLocation;
- dwCurrentLocation= PE_CD_GetCurrentLocation();
- // Check if there's need to activate Error-Recovery, by checking if the Timeout has expired.
- if (((g_pSVCDNav->m_ErrorRecoveryInfo).uTimeout <= 0) ||
- (0 != --(g_pSVCDNav->m_ErrorRecoveryInfo).uTimeout))
- return;
- switch ((g_pSVCDNav->m_ErrorRecoveryInfo).eRecoveryType)
- {
- case eNoError:
- //<<<mikex_0827_2003_a: add the recovery error mechanism in digest mode
- #ifdef SVCD_DIGEST_SUPPORT
- if(gcs.pstate == PST_STILL && g_pSVCDNav->m_bDigestMode != FALSE)
- g_DigestReadDiscError++;
- #endif
- //mikex_0827_2003_a>>>
- break;
- case eIFrameDisplayMiss:
- // Take care of I-Frame Display Miss
- dbg_printf(("I-Frame Display Missed -- Recovering...n"));
- ie_send(IE_CORE_I_FRAME); // Emulate the display of an I-Frame
- break;
- case ePlaybackHangup:
- #ifndef WATCHDOG_TRIGGERED_BY_FE
- // Take care of Playback-Hangup
- if ((PST_PLAY == gcs.pstate) || (PST_SLOW == gcs.pstate)) {
- if (dwCurrentLocation <= (g_pSVCDNav->m_ErrorRecoveryInfo).dwParam) {
- DWORD dwRecoveryAddress= CalculateRecoveryAddress((g_pSVCDNav->m_ErrorRecoveryInfo).dwParam);
- tr_printf(("Possible Playback-Hangup -- Recovering...n"));
- // Abort the current Playback, without changing the Decoder's mode
- PE_CD_AbortPlayback(TRUE);
- // Attempt recovery
- if (dwRecoveryAddress < g_pSVCDNav->m_aCurrSegment[1]) {
- // The Recovery Address is within the legal range: try to recover
- (g_pSVCDNav->m_ErrorRecoveryInfo).dwParam= dwRecoveryAddress;
- PE_CD_SetCurrentLocationLBN_Bakcup(dwRecoveryAddress);
- PE_CD_PlaySegment(g_pSVCDNav->m_iCurrVideoType, g_pSVCDNav->m_uCurrAudioSID,
- dwRecoveryAddress, (g_pSVCDNav->m_aCurrSegment[1] - dwRecoveryAddress),
- eNormalSpeed, 0);
- // Renew Slow-Motion, if necessary
- if (PST_SLOW == gcs.pstate)
- OnSlow(SHARED_INFO.m_iSlowSpeed);
- }
- else {
- // The Recovery-Address breaches the legal range: emulate a Playback-Finished
- // Event, so that navigation can carry on as if no error occurred.
- //CL, clear it, for we also send this message in tick
- //ie_send(IE_CORE_CDNAV_FINISHED);
- }
- }
- else {
- // So far so good - there's progress. Register the Current Loaction.
- (g_pSVCDNav->m_ErrorRecoveryInfo).dwParam= dwCurrentLocation;
- }
- // Setup the Timeout parameter for the next time, according to the Playback mode
- (g_pSVCDNav->m_ErrorRecoveryInfo).uTimeout= (SVCD_PB_HANGUP_TIMEOUT * (1 + abs(SHARED_INFO.m_iSlowSpeed)));
- }
- #else
- //<<<LX051302: New Error Recovery process
- // Take care of Playback-Hangup
- if ((PST_PLAY == gcs.pstate) || (PST_SLOW == gcs.pstate)) {
- DWORD dwRecoveryAddress= CalculateRecoveryAddress((g_pSVCDNav->m_ErrorRecoveryInfo).dwParam);
-
- dbg_printf(("Watchdog startedn"));
- //LX051302: Current segment playback finished if retry times is more than MAX_WATCHDOG_RETRY_TIMES
- if ( (g_pSVCDNav->m_ErrorRecoveryInfo).ucRetryCounter++ > MAX_WATCHDOG_RETRY_TIMES ){
- dbg_printf(("Too many retrys, skip to next playitemn"));
- ie_send(IE_CORE_CDNAV_FINISHED);
- }
-
- // Abort the current Playback, without changing the Decoder's mode
- PE_CD_AbortPlayback(TRUE);
- // Attempt recovery
- if (dwRecoveryAddress < g_pSVCDNav->m_aCurrSegment[1]) {
- // The Recovery Address is within the legal range: try to recover
- (g_pSVCDNav->m_ErrorRecoveryInfo).dwParam= dwRecoveryAddress;
- PE_CD_SetCurrentLocationLBN_Bakcup(dwRecoveryAddress);
- PE_CD_PlaySegment(g_pSVCDNav->m_iCurrVideoType, g_pSVCDNav->m_uCurrAudioSID,
- dwRecoveryAddress, (g_pSVCDNav->m_aCurrSegment[1] - dwRecoveryAddress),
- eNormalSpeed, 0);
- // Renew Slow-Motion, if necessary
- if (PST_SLOW == gcs.pstate)
- OnSlow(SHARED_INFO.m_iSlowSpeed);
- if (g_pSVCDNav->m_bIsSegment && (MPEG_2 != g_pSVCDNav->m_iCurrVideoType))
- {
- PE_CD_RequestNotification(IFrame);
- PE_CD_RequestNotification(StuckTrigger);
- }
- }
- else {
- // The Recovery-Address breaches the legal range: emulate a Playback-Finished
- // Event, so that navigation can carry on as if no error occurred.
- //CL, clear it, for we also send this message in tick
- tr_printf(("Watch dog started, end of current segment, skip to next playitemn"));
- ie_send(IE_CORE_CDNAV_FINISHED);
- }
- }
- #endif//WATCHDOG_TRIGGERED_BY_FE
- //LX051302>>>
- break;
- default:
- dbg_printf(("Unknown Error-Recovery Mechanism Type: %xn", (g_pSVCDNav->m_ErrorRecoveryInfo).eRecoveryType));
- break;
- }
- return;
- }
- /////////////////////////////////////////////////////////////////////////////////////////////////
- // void CancelRepeatModes(BYTE ucModesMask) -
- // Cancels one or more Repeat-Modes.
- //
- // Input:
- // ucModesMask - A bit-mask indicating which Repeat Mode(s) needs to be cancelled
- //
- // Output:
- // None. The requested Repeat-Modes are eliminated, if they were active.
- static void CancelRepeatModes(BYTE ucModesMask)
- {
- BOOL bRepeatModeChanged= FALSE;
- // Cancel "Repeat Single" if it is in effect
- if ((ucModesMask & PM_REPEAT_SINGLE) && PM_IsRepeatSingle()) {
- PM_SetRepeatSingle(FALSE);
- bRepeatModeChanged= TRUE;
- }
- // Cancel "Repeat All" if it is in effect
- if ((ucModesMask & PM_REPEAT_ALL) && PM_IsRepeatAll()) {
- PM_SetRepeatAll(FALSE);
- bRepeatModeChanged= TRUE;
- }
- // Cancel "Repeat A-B" if it is in effect
- if ((ucModesMask & PM_REPEAT_AB_MASK) && (0 != PM_GetRepeatAB())) {
- PM_SetRepeatAB(0);
- OnCancelABRepeat();
- bRepeatModeChanged= TRUE;
- }
- if (bRepeatModeChanged)
- ie_send(IE_UI_STATE_CHANGE);
- return;
- }
- /////////////////////////////////////////////////////////////////////////////////////////////////
- // void OnTimeout() -
- // Handels a Timeout Event, identified by the OnTick() service.
- //
- // Input:
- // None
- //
- // Output:
- // The next suitable List is selected for playback and invoked.
- //
- // Remarks:
- // A Timeout Event occurrs when a Play-Item finishes playback, and a Timeout period
- // has been defined for it. As long as there is no user-intervention, the Timeout counter
- // starts measuring the Timeout-period. When this period expires, this handler is called.
- //
- // The handler will examine the current List to establish the Timeout-List Offset.
- // This offset is used as the next List to play. If no such offset has been defined,
- // the current List is repeated.
- static void OnTimeout(void)
- {
- dbg_printf(("OnTimeout()n"));
- g_pSVCDNav->m_dwTimeout= SVCD_INFINITE;
- // Reset the current Position
- (SHARED_INFO.m_CurrPosition).ListType= Undetermined;
- (SHARED_INFO.m_CurrPosition).uListItem= 1; // Start playback from the first Item
- // The Timeout Event is relevant only for Selection-Lists, therefore the current List
- // must be of type SelectionList. Examine the TimeoutOffset Field to find out which
- // List needs to be played next. If there is no valid Timeout-Offset, select the first
- // suitable SelectionList Item.
- if (0xFFFF != ((SHARED_INFO.m_CurrList).SelectionList).uTimeoutOffset) {
- dbg_printf(("The Timeout-List is at offset: %04xn", ((SHARED_INFO.m_CurrList).SelectionList).uTimeoutOffset));
- (SHARED_INFO.m_CurrPosition).dwPSD_Offset= (g_pSVCDNav->m_NavigationInfo).uOffsetMultiplier *
- (UINT32)((SHARED_INFO.m_CurrList).SelectionList).uTimeoutOffset;
- }
- else {
- WORD uDefaultOffset= FindDefaultSelectionOffset(-1);
- dbg_printf(("No Timeout-List was defined.n"));
- if ((WORD)-1 == uDefaultOffset) {
- gcs.pstate= PST_STILL;
- return;
- }
- (SHARED_INFO.m_CurrPosition).dwPSD_Offset= (g_pSVCDNav->m_NavigationInfo).uOffsetMultiplier *
- (UINT32)uDefaultOffset;
- }
- // Cancel any current Repeat-Modes
- CancelRepeatModes(PM_REPEAT_SINGLE | PM_REPEAT_ALL | PM_REPEAT_AB_MASK);
- // Now actually invoke playback of the List
- gcs.pstate= PST_PLAY;
- if (! InvokePlayback()) {
- dbg_printf(("Failed to play-back the current List.n"));
- gcs.pstate= PST_STOP;
- }
- return;
- }
- /////////////////////////////////////////////////////////////////////////////////////////////////
- // void OnWaitTimeExpired() -
- // Handels a Wait-Expired Event, identified by the OnTick() service.
- //
- // Input:
- // None
- //
- // Output:
- // The next suitable List is selected for playback and invoked.
- //
- // Remarks:
- // A Wait-Expired Event occurs when a Play-Item within a Play-List finishes playback, and
- // a Waiting-Time is defined for that Play-List.
- // If the entire Play-List has been exhausted, then the next List is selected for playback.
- // Otherwise, the next Item on the Play-List is selected for playback.
- static void OnWaitTimeExpired(void)
- {
- dbg_printf(("OnWaitTimeExpired()n"));
- g_pSVCDNav->m_dwWaitTime= SVCD_INFINITE;
- // The WaitTimeExpired Event is relevant only for Play-Lists, therefore the current List
- // must be of type PlayList. Continue to play the next Play-Item on the List, or continue
- // to the next List if the last Item has been played.
- if (((SHARED_INFO.m_CurrList).PlayList).uItemsCnt <= (SHARED_INFO.m_CurrPosition).uListItem++)
- {
- dbg_printf(("PlayList playback is done. Switching to the next list.n"));
- if (0xFFFF == ((SHARED_INFO.m_CurrList).PlayList).uNextOffset) {
- dbg_printf(("Invalid Next List Offset for a Play-List. Ignored.n"));
- //Emulating an EndList to overcome authoring errors.
- (SHARED_INFO.m_CurrPosition).ListType= EndList;
- //return;
- }
- else
- {
- (SHARED_INFO.m_CurrPosition).ListType= Undetermined;
- (SHARED_INFO.m_CurrPosition).dwPSD_Offset= (g_pSVCDNav->m_NavigationInfo).uOffsetMultiplier *
- (UINT32)((SHARED_INFO.m_CurrList).PlayList).uNextOffset;
- (SHARED_INFO.m_CurrPosition).uListItem= 1; // Start playback from the first Item
- }
- // Cancel any current Repeat-Modes
- CancelRepeatModes(PM_REPEAT_SINGLE | PM_REPEAT_ALL | PM_REPEAT_AB_MASK);
- }
- // Continue playback of the current PlayList or the next SelectionList
- gcs.pstate= PST_PLAY;
- if (! InvokePlayback()) {
- dbg_printf(("Failed to invoke the next Play-Item.n"));
- gcs.pstate= PST_STOP;
- }
- return;
- }
- /////////////////////////////////////////////////////////////////////////////////////////////////
- // void OnPausePeriodExpired() -
- // Handels a Pause-Expired Event, identified by the OnTick() service;
- // or a Resume-Playback Event.
- //
- // Input:
- // None
- //
- // Output:
- // Normal playback is resumed.
- //
- // Remarks:
- // A Pause-Expired event occurrs when a stream uses the Trigger-Bit to trigger an
- // automatic-pause. When this happens, the playback pauses for the amount of time
- // defined and measured by the Auto-Pause-Period. When that period expires, this handler is
- // called.
- // This handler also gets called in response to a Resume-Playback event (to resume playback
- // that was previously paused by the user).
- static void OnPausePeriodExpired(void)
- {
- dbg_printf(("OnPausePeriodExpired()n"));
- g_pSVCDNav->m_dwPausePeriod= SVCD_INFINITE;
- PE_CD_PausePlayback(FALSE, g_pSVCDNav->m_uCurrAudioSID);
- gcs.pstate= PST_PLAY;
- // Re-install the notification request for Trigger-Bit occurrence, only
- // if the PSD information is being used (otherwise, nothing to do with
- // the Trigger-Bit).
- if (g_pSVCDNav->m_bIsUsingPSD)
- PE_CD_RequestNotification(TriggerBit);
- return;
- }
- /////////////////////////////////////////////////////////////////////////////////////////////////
- // void OnTick() -
- // Handles an IE_CORE_TICK200 Event.
- //
- // Input:
- // None
- //
- // Output:
- // Various internal timers are managed.
- //
- // Remarks:
- // The handler manages the different internal-timers, associated with temporal events
- // (Auto-Pause-Period, Waiting-Period, Timeout-Period).
- // In addition, the handler checks the Current-Location against the PositionB marker,
- // provided that REPEAT_AB is active. If a match is found, an appropriate Rendezvous
- // event is issued.
- //
- // In addition, when any of the different internal-timers expires, the handler will issue
- // an appropriate Rendezvous event.
- //
- // Apart from the Navigational-events related to timing, this handler also manages the
- // Error-Recovery mechanisms.
- static void OnTick(void)
- {
- int j;
- int iElapsedTime= SHARED_INFO.iCurrentTime;
- DWORD dwCurrentLocation;
- static int iRetryCount = SVCD_PTS_MONOTONITY_GRACE_RETRIES;
- // Gard for Zero Divided
- if (PST_STOP == gcs.pstate) {
- return;
- }
-
- dwCurrentLocation = PE_CD_GetCurrentLocation();
- //Leon.He_1003_05: Fix the bug can't play in VCD 2.0 selection list. It is not correct to just prevent PLAY EVENT when the state is PST_PLAY.
- /* if (PST_PLAY == gcs.pstate)
- if ((SHARED_INFO.uCurrentTrackNumber >1) && (SHARED_INFO.uCurrentTrackNumber <100))
- CLEAR_COP_MASK(COP_PLAY);
- else
- SET_COP_MASK(COP_PLAY);*/
- // Calculate the Elapsed Time
- if ((g_pSVCDNav->m_TimeMeasurementInfo).bUsePTS
- #ifdef D_ENABLE_ELAPSEDTIME_FOR_SLIDESHOW
- && !((g_pSVCDNav->m_iCurrVideoType == STILL_HIRES)||(g_pSVCDNav->m_iCurrVideoType == STILL_LOWRES))
- #endif
- ) {
- DWORD dwCurrPTS;
- // Attempt to calculate the Elapsed-Time based on the current PTS:
- // Acquire the Current-PTS
- if (PE_CD_GetDecoderCurrentLocationSCR(&dwCurrPTS))
- {
- //<<<ML0704 added
- //for using pts to measure,also need to update current entry number
- #ifdef PARSE_ENTRY_INFO
- if ( ( NULL != g_hEntriesTable ) && ( 0 != g_pSVCDNav->m_wEntriesUsedCnt )
- && ( PST_STOP != gcs.pstate ) && ( SHARED_INFO.uCurrentTrackNumber > 1 ) )
- {
-
- WORD i;
- BYTE aucBuffer[4];
- DWORD dwEntriesStartAddress;
- if ( 1 == g_pSVCDNav->m_wEntriesUsedCnt )
- {
- gns.svcd.wCurrentEntryNumber = 1;
- // tr_printf(("Current Entry Number is %04xn", gns.svcd.wCurrentEntryNumber));
- }
- else
- {
- for ( i = 0; i < g_pSVCDNav->m_wEntriesUsedCnt; i++)
- {
- Array_getAt(g_hEntriesTable, (UINT16)i, aucBuffer);
- dwEntriesStartAddress= drv_msf2lbn(drv_bcd2bin(aucBuffer[1]), drv_bcd2bin(aucBuffer[2]), drv_bcd2bin(aucBuffer[3]));
-
- if ( dwCurrentLocation < dwEntriesStartAddress )
- {
-
- for(j=0;j<=g_pSVCDNav->m_wEntriesUsedCnt;j++)
- {
- Array_getAt(g_hEntriesTable, (UINT16)j, aucBuffer);
- dwEntriesStartAddress = drv_msf2lbn(drv_bcd2bin(aucBuffer[1]), drv_bcd2bin(aucBuffer[2]), drv_bcd2bin(aucBuffer[3]));
- if(dwEntriesStartAddress>=g_pSVCDNav->m_aCurrTrack[0])
- break;
- }
- i=i-j;
- gns.svcd.wCurrentEntryNumber = i;
- // tr_printf(("Current Entry Number is %04xn", gns.svcd.wCurrentEntryNumber));
- break;
- }
- }
- }
- }
- else
- gns.svcd.wCurrentEntryNumber = 0xFFFF;
- #endif
- //>>>ML0704
- // Check if the Start-PTS must be acquired
- if ((g_pSVCDNav->m_TimeMeasurementInfo).bAcquireStartPTS)
- {
- (g_pSVCDNav->m_TimeMeasurementInfo).dwStartPTS= dwCurrPTS;
- (g_pSVCDNav->m_TimeMeasurementInfo).dwLastPTS= dwCurrPTS;
- (g_pSVCDNav->m_TimeMeasurementInfo).bAcquireStartPTS= FALSE;
- }
- // Check that the PTS has monotonically increased since last time
- if (dwCurrPTS >= (g_pSVCDNav->m_TimeMeasurementInfo).dwLastPTS) {
- // The Elapsed-Time is the difference between the Current-PTS and the Start-PTS,
- // divided by the PTS-Clock Frequency (90 KHz).
- if (dwCurrPTS>=(g_pSVCDNav->m_TimeMeasurementInfo).dwStartPTS)
- iElapsedTime= (g_pSVCDNav->m_TimeMeasurementInfo).iTimeOffset +
- (int)((dwCurrPTS - (g_pSVCDNav->m_TimeMeasurementInfo).dwStartPTS) / SCR_RATE);
- else {
- iElapsedTime= (g_pSVCDNav->m_TimeMeasurementInfo).iTimeOffset -
- (int)(((g_pSVCDNav->m_TimeMeasurementInfo).dwStartPTS - dwCurrPTS ) / SCR_RATE);
- if (iElapsedTime<0)
- tr_printf(("nCurrent PTS error ! n"));
- }
- gns.svcd.wTotalElpasedTime = iElapsedTime + ((g_pSVCDNav->m_aCurrTrack[0] - g_pSVCDNav->m_dwSecondTrackAddress) / g_pSVCDNav->m_aCurrTrack[2]);
- (g_pSVCDNav->m_TimeMeasurementInfo).dwLastPTS= dwCurrPTS;
- iRetryCount = SVCD_PTS_MONOTONITY_GRACE_RETRIES;
- }
- else {
- // The PTS hasn't increased monotonically - try again before abandoning
- // the PTS-based measurement
- if (iRetryCount > 0) {
- iRetryCount--;
- (g_pSVCDNav->m_TimeMeasurementInfo).dwLastPTS= dwCurrPTS;
- }
- else {
- (g_pSVCDNav->m_TimeMeasurementInfo).bUsePTS= FALSE;
- iRetryCount = SVCD_PTS_MONOTONITY_GRACE_RETRIES;
- }
- }
- }
- else {
- // Failed to acquire the current PTS: don't update the Elapsed-Time
- }
- }