nav_clips.c
上传用户:super_houu
上传日期:2008-09-21
资源大小:4099k
文件大小:200k
源码类别:

DVD

开发平台:

Others

  1. // Update the current Playback-Mode
  2. g_pClipsNav->m_uCurrPlaybackMode= PM_GetPlaybackMode();
  3. return;
  4. }
  5. /////////////////////////////////////////////////////////////////////////////
  6. // OnNextItem()
  7. //
  8. // Description: A handler for the IE_CORE_NEXT_CHAPTER Event.
  9. //
  10. // Input: None
  11. // Output: None
  12. // In/Out: None
  13. // Return: None
  14. //
  15. // Remarks:
  16. // The handler schedules the next Item on the Playlist for playback, unless
  17. // the current Item is already the last one on the Playlist.
  18. static void OnNextItem()
  19. {
  20. BOOL bToAbortPlayback = 1;
  21. dbg_printf(("OnNext()n"));
  22. #ifdef USE_AUX_SUBTITLES
  23. // undisplay auxiliary subtitles, if exist.
  24. if ((SI_IS_CURRENT_MPEG4_CLIP && (FALSE != areAuxSubtitlePresent())) ||
  25. SI_CLIPS_MP4_INTERNAL_SUBTITLE_ON)
  26. stopDisplayAuxSubtitles();
  27. #endif
  28. if (PST_STOP == gcs.pstate) {
  29. dbg_printf(("Next is invalid in Stop state.n"));
  30.   core_report_error( IE_UI_REPORT_ERROR, (void *) CLIPSNAV_ERR_PROHIBITED_UOP );
  31. return;
  32. }
  33. if((eWINDOWS_EXPLORER_STYLE == SHARED_INFO.eWindowsExplorerStyleBrowser)
  34. && eSingleItem == SHARED_INFO.uExplorerStyleBrowserPlayMode)
  35. {
  36. core_report_error( IE_UI_REPORT_ERROR, (void *) CLIPSNAV_ERR_PROHIBITED_UOP );
  37. return;
  38. }
  39. if(PM_IsPlaybackRandom(PM_GetPlaybackMode()))
  40. {
  41. PM_ShuffleProgramList(FALSE, 0);
  42. SHARED_INFO.uCurrPlaylistItem = 0;
  43. }
  44. if (0 == computePlaylistItem(SHARED_INFO.uCurrPlaylistItem, TRUE)) 
  45. {
  46.   if(FALSE == IsGotoNextChapterAllowed())
  47. return;
  48. else 
  49.       if(PM_IsRepeatFolder())
  50. SHARED_INFO.uCurrPlaylistItem= 0;
  51.     else
  52. {
  53. if( eWINDOWS_EXPLORER_STYLE == SHARED_INFO.eWindowsExplorerStyleBrowser) 
  54. {
  55. if (PST_STOP != gcs.pstate) 
  56. {
  57. // Stop the current playback, and re-invoke playback at the previous item
  58. UINT16 hClipInstance= ClipsRepository_getInstanceAt(SHARED_INFO.uCurrentClipNumber-1);
  59. Clip_abortPlayback(hClipInstance, TRUE);
  60. bToAbortPlayback = 0;
  61. }
  62. #ifdef MANUAL_DIRECTORY_EXPLORER
  63. if( 0 == getFirstItemInSubFoldersOrNextFolders())
  64. {
  65. if(!PM_IsRepeatAll())
  66. {
  67. // Cancel Intro Play Mode if Stop
  68. SHARED_INFO.bIsIntroPlayMode = FALSE;
  69. gcs.pstate= PST_STOP;
  70. return;
  71. }
  72. else
  73. if(0 == computePlaylistItem(0, TRUE))
  74. getFirstItemInSubFoldersOrNextFolders();
  75. }
  76. #endif
  77. }
  78. SHARED_INFO.uCurrPlaylistItem= 0;
  79. }
  80. }
  81. //if there is already a timer running, we disable it first
  82. timer_service_disable(g_pClipsNav->m_hPresentationTimer);
  83. // Advance to the next Item
  84. SHARED_INFO.uCurrPlaylistItem= computePlaylistItem(SHARED_INFO.uCurrPlaylistItem, TRUE);
  85. cancelRepeatModes(PM_REPEAT_AB_MASK);
  86. // Clear any Resume Marker
  87. (g_pClipsNav->m_cmResumeMarker).dwAddress= (ULONG)-1;
  88. if (PST_STOP != gcs.pstate) {
  89. if(bToAbortPlayback)
  90. {
  91. // Abort the current playback, if any
  92. UINT16 hClipInstance= ClipsRepository_getInstanceAt(SHARED_INFO.uCurrentClipNumber-1);
  93. Clip_abortPlayback(hClipInstance, TRUE);
  94. }
  95. // <<< Robin_0903_2004
  96. #ifdef DIVX_SUPPORT_MULTI_SUBTITLE_MODE0
  97. bNeedWaitForUI = TRUE;
  98. #endif
  99. // >>> Robin_0903_2004
  100. // Invoke playback of the next item
  101. if (! invokePlayback(FALSE)) {
  102. tr_printf(("FATAL: Failed to invoke playbackn"));
  103. gcs.pstate= PST_STOP;
  104. }
  105. }
  106. return;
  107. }
  108. /////////////////////////////////////////////////////////////////////////////
  109. // OnPreviousItem()
  110. //
  111. // Description: A handler for the IE_CORE_PREVIOUS_CHAPTER Event.
  112. //
  113. // Input: None
  114. // Output: None
  115. // In/Out: None
  116. // Return: None
  117. //
  118. // Remarks:
  119. // The handler schedules the previous Item on the Playlist for playback, unless
  120. // the current Item is already the first one on the Playlist.
  121. static void OnPreviousItem()
  122. {
  123. BOOL bToAbortPlayback = 1;
  124. dbg_printf(("OnPrevious()n"));
  125. #ifdef USE_AUX_SUBTITLES
  126. // undisplay auxiliary subtitles, if exist.
  127. if ((SI_IS_CURRENT_MPEG4_CLIP && (FALSE != areAuxSubtitlePresent())) ||
  128. SI_CLIPS_MP4_INTERNAL_SUBTITLE_ON)
  129. stopDisplayAuxSubtitles();
  130. #endif
  131. if (PST_STOP == gcs.pstate) {
  132. dbg_printf(("Previous invalid in Stop state.n"));
  133.   core_report_error( IE_UI_REPORT_ERROR, (void *) CLIPSNAV_ERR_PROHIBITED_UOP );
  134. return;
  135. }
  136. if((eWINDOWS_EXPLORER_STYLE == SHARED_INFO.eWindowsExplorerStyleBrowser)
  137. && eSingleItem == SHARED_INFO.uExplorerStyleBrowserPlayMode)
  138. {
  139. core_report_error( IE_UI_REPORT_ERROR, (void *) CLIPSNAV_ERR_PROHIBITED_UOP );
  140. return;
  141. }
  142. //if there is already a timer running, we disable it first
  143. timer_service_disable(g_pClipsNav->m_hPresentationTimer);
  144. // Cancel Intro Play Mode if Stop
  145. SHARED_INFO.bIsIntroPlayMode = FALSE;
  146. #ifdef D_USE_VARIABLE_FOR_LIB
  147. if (SHARED_INFO.iCurrentTime <= clips_skip_back_threshold)
  148. #else
  149. if (SHARED_INFO.iCurrentTime <= CLIPS_SKIP_BACK_THRESHOLD)
  150. #endif
  151. {
  152. if(PM_IsPlaybackRandom(PM_GetPlaybackMode()))
  153. {
  154. PM_ShuffleProgramList(FALSE, 0);
  155. SHARED_INFO.uCurrPlaylistItem = PM_GetProgramSize();
  156. }
  157. if (0 == computePlaylistItem(SHARED_INFO.uCurrPlaylistItem, FALSE)) 
  158. {
  159. if (FALSE == IsGotoPreviousChapterAllowed())
  160. return;
  161. if( eSingle_LIST_STYLE == SHARED_INFO.eWindowsExplorerStyleBrowser ||
  162. ((eWINDOWS_EXPLORER_STYLE == SHARED_INFO.eWindowsExplorerStyleBrowser) && 
  163.   (eWholeDisc != SHARED_INFO.uExplorerStyleBrowserPlayMode)) )
  164. {
  165. #ifdef CLIPS_WRAP_AROUND_ON_PROGRAM_EDGES
  166. // Set the Current Item to one past the Last item on the Play-List (i.e.
  167. // wrap-around is performed).
  168. SHARED_INFO.uCurrPlaylistItem= computePlaylistItem(PM_GetProgramSize(), FALSE);
  169. #else
  170. // Wrap-around if Repeat-All is on
  171. if(PM_IsRepeatFolder())
  172. {
  173. // Set the Current Item to one past the Last item on the Play-List (i.e.
  174. // wrap-around is performed).
  175. SHARED_INFO.uCurrPlaylistItem= computePlaylistItem(PM_GetProgramSize(), FALSE);
  176. }
  177. #endif  //CLIPS_WRAP_AROUND_ON_PROGRAM_EDGES
  178. }
  179. #ifdef MANUAL_DIRECTORY_EXPLORER
  180. else
  181. if( eWINDOWS_EXPLORER_STYLE == SHARED_INFO.eWindowsExplorerStyleBrowser)
  182. {
  183. if (PST_STOP != gcs.pstate)
  184. {
  185. // Stop the current playback, and re-invoke playback at the previous item
  186. UINT16 hClipInstance= ClipsRepository_getInstanceAt(SHARED_INFO.uCurrentClipNumber-1);
  187. Clip_abortPlayback(hClipInstance, TRUE);
  188.       bToAbortPlayback = 0;
  189. }
  190. SHARED_INFO.uCurrPlaylistItem = getLastItemInPrevFolders();
  191. if(0 == SHARED_INFO.uCurrPlaylistItem)
  192. {
  193. gcs.pstate= PST_STOP;
  194. return;
  195. }
  196. }
  197. #endif
  198. }
  199. else 
  200. {
  201. // Move back to the previous Item
  202. SHARED_INFO.uCurrPlaylistItem= computePlaylistItem(SHARED_INFO.uCurrPlaylistItem, FALSE);
  203. }
  204. }
  205. cancelRepeatModes(PM_REPEAT_AB_MASK);
  206. // Clear any Resume Marker
  207. (g_pClipsNav->m_cmResumeMarker).dwAddress= (ULONG)-1;
  208. if (PST_STOP != gcs.pstate) {
  209. if(bToAbortPlayback)
  210. {
  211. // Stop the current playback, and re-invoke playback at the previous item
  212. UINT16 hClipInstance= ClipsRepository_getInstanceAt(SHARED_INFO.uCurrentClipNumber-1);
  213. Clip_abortPlayback(hClipInstance, TRUE);
  214. }
  215. // <<< Robin_0903_2004
  216. #ifdef DIVX_SUPPORT_MULTI_SUBTITLE_MODE0
  217. bNeedWaitForUI = TRUE;
  218. #endif
  219. // >>> Robin_0903_2004
  220. // Invoke playback of the previous item
  221. if (! invokePlayback(FALSE)) {
  222. tr_printf(("FATAL: Failed to invoke playbackn"));
  223. gcs.pstate= PST_STOP;
  224. }
  225. }
  226. return;
  227. }
  228. /////////////////////////////////////////////////////////////////////////////
  229. // OnNumericSelection()
  230. //
  231. // Description: A handler for the IE_CORE_MENU_NUMERICAL_SELECTION or 
  232. // IE_CORE_GOTO_ENTRY Events.
  233. //
  234. // Input: iSelection - An index of the Playlist Item to select.
  235. // Output: None
  236. // In/Out: None
  237. // Return: None
  238. //
  239. // Remarks:
  240. // The handler sets the current Playlist Item to the one which resides
  241. // inside the Playlist at the specified index.
  242. static void OnNumericSelection(UINT16 iSelection)
  243. {
  244. UINT16 hClipInstance;
  245. UINT8 ucWhichWindow;
  246. BOOL bEntryIsDIR;
  247. // Robin_0715_2004, merge changelist #23919
  248. if ( PM_IsPlaybackShuffle(PM_GetPlaybackMode())
  249. #ifndef CLIPS_ONNUMERICSELECTION_DONT_CANCEL_PROGRAM
  250. ||PM_IsPlaybackProgram(PM_GetPlaybackMode())
  251. #endif
  252. ) {
  253. PM_SetPlaybackMode(PM_PLAYBACK_NORMAL);
  254. OnModeChange();
  255. Clips_SetExplorerStyleBrowserDiscScanMode(FALSE);
  256. Clips_SetExplorerStyleBrowserPlayMode(eSingleFolder);
  257. PM_ClearRepeat();
  258. }
  259. ucWhichWindow = iSelection >> 13;//to support to 5000 clips in one folder
  260. iSelection &= 0x1fff;
  261. // Verify that the selected number is legal
  262. if(eLEFT_WINDOW == ucWhichWindow)
  263. {
  264. UINT16 usMaxEntries;
  265. usMaxEntries = PEER_DIR_ARRAY_SIZE;
  266. if ((0 == iSelection) || (iSelection > usMaxEntries))
  267. {
  268. tr_printf(("Illegal Selection Number. Ignored.n"));
  269. return;
  270. }
  271. }
  272. else// Verify that the selected number is legal
  273. {
  274. UINT16 uProgramSize= PM_GetProgramSize();
  275. if(0 == uProgramSize)
  276. uProgramSize = SUB_DIR_ARRAY_SIZE;
  277. else
  278. uProgramSize = uProgramSize - 1 + SUB_DIR_ARRAY_SIZE;
  279. if ((0 == iSelection)
  280.     || (iSelection > uProgramSize)) {
  281. tr_printf(("Illegal Selection Number. Ignored.n"));
  282. return;
  283. }
  284. }
  285. //check if the entry is a dir.
  286. bEntryIsDIR = 0;
  287. if(eRIGHT_WINDOW == ucWhichWindow || eSingle_WINDOW == ucWhichWindow)
  288. {
  289. #ifdef CLIPS_JPEG_DIGEST_SUPPORT
  290. if (g_pClipsNav->m_bDigestMode) {
  291. UINT16 uClipIndex;
  292. // Extract the correct Play-List Item corresponding to the Digest-selection
  293. if (!Array_getAt(g_pClipsNav->m_hDigestUnits, (iSelection-1), (BYTE*)&uClipIndex)) {
  294. tr_printf(("Cannot retrieve the selected Clip-Index.n"));
  295. return;
  296. }
  297. iSelection= (1 + (int)uClipIndex);
  298. _terminateDigestMode();
  299. }
  300. else
  301. #endif //CLIPS_JPEG_DIGEST_SUPPORT
  302. #ifdef MANUAL_DIRECTORY_EXPLORER
  303. if(iSelection <= SUB_DIR_ARRAY_SIZE)
  304. {
  305. Browser_OpenFolder( ucWhichWindow, iSelection, TRUE);
  306. return;
  307. }
  308. else
  309. #endif
  310. {
  311. iSelection -= SUB_DIR_ARRAY_SIZE;
  312. // Establish the validity of the selected Clip given the Playback-Filter
  313. hClipInstance= ClipsRepository_getInstanceAt(PM_GetProgramListEntry((UINT16)iSelection)-1);
  314. if (NULL == hClipInstance)
  315. {
  316. tr_printf(("Numeric-Selection rejected, due to no valid instancen"));
  317. return;
  318. }
  319. else
  320. if ((0 == (Clip_getType(hClipInstance) & g_uPlaybackFilter)))
  321. {
  322. tr_printf(("Numeric-Selection rejected, due to Playback-Filter conflict.n"));
  323. return;
  324. }
  325. }
  326. }
  327. #ifdef MANUAL_DIRECTORY_EXPLORER
  328. else
  329. if(eLEFT_WINDOW == ucWhichWindow)
  330. {
  331. Browser_OpenFolder( ucWhichWindow, iSelection, TRUE);
  332. return;
  333. }
  334. #endif
  335.   if(eWINDOWS_EXPLORER_STYLE != SHARED_INFO.eWindowsExplorerStyleBrowser)
  336. {
  337. if (! PM_IsPlaybackNormal(PM_GetPlaybackMode())) {
  338. // Return to Normal Playback
  339. PM_SetPlaybackMode(PM_PLAYBACK_NORMAL);
  340. OnModeChange();
  341. }
  342. }
  343. // Disable the Presentation Timer
  344. timer_service_disable(g_pClipsNav->m_hPresentationTimer);
  345. // Cancel Intro Play Mode if Stop
  346. SHARED_INFO.bIsIntroPlayMode = FALSE;
  347. // Abort any ongoing playback
  348. if (!((0 == SHARED_INFO.uCurrentClipNumber) || (SHARED_INFO.uCurrentClipNumber > (PM_GetProgramSize() - 1))))
  349.    {
  350. if (PST_STOP != gcs.pstate)
  351.       {
  352. hClipInstance= ClipsRepository_getInstanceAt(SHARED_INFO.uCurrentClipNumber-1);
  353. Clip_abortPlayback(hClipInstance, TRUE);
  354. }
  355. }
  356. // Cancel any current Repeat-Modes, except Folder
  357.    if(eWINDOWS_EXPLORER_STYLE != SHARED_INFO.eWindowsExplorerStyleBrowser)
  358. cancelRepeatModes(PM_REPEAT_SINGLE | PM_REPEAT_ALL | PM_REPEAT_AB_MASK);
  359. // Clear any Resume Marker
  360. (g_pClipsNav->m_cmResumeMarker).dwAddress= (ULONG)-1;
  361. SHARED_INFO.uCurrPlaylistItem= (UINT16)iSelection;
  362. gcs.pstate= PST_PLAY;
  363. // <<< Robin_0903_2004
  364. #ifdef DIVX_SUPPORT_MULTI_SUBTITLE_MODE0
  365. bNeedWaitForUI = TRUE;
  366. #endif
  367. // >>> Robin_0903_2004
  368. if (! invokePlayback(TRUE)) {
  369. tr_printf(("FATAL: Failed to invoke playback of a Playlist Item.n"));
  370. gcs.pstate= PST_STOP;
  371. }
  372. return;
  373. }
  374. #ifdef CLIPS_JPEG_SUPPORT
  375. /////////////////////////////////////////////////////////////////////////////
  376. // OnAngleSelection()
  377. //
  378. // Description: Handles Angle selection
  379. //
  380. // Input: i_eAngle - The selected Angle to apply
  381. // Output: None
  382. // In/Out: None
  383. // Return: None
  384. //
  385. // Remarks: None
  386. static void OnAngleSelection(enClipImageOrientation i_eAngle)
  387. {
  388. UINT16 hClipInstance;
  389. dbg_printf(("OnAngleSelection(%d)n", i_eAngle));
  390. // Retrieve the Clip-Information for the current Clip
  391. hClipInstance= ClipsRepository_getInstanceAt(SHARED_INFO.uCurrentClipNumber-1);
  392. if (NULL == hClipInstance) {
  393. tr_printf(("FATAL: OnAngleSelection() Failed [1]: Cannot retrieve info for the Current-Clip.n"));
  394. return;
  395. }
  396. // Set the selected Orientation
  397. Clip_setOrientation(hClipInstance, i_eAngle);
  398. // Disable the Presentation-Timer
  399. if(timer_service_is_active(g_pClipsNav->m_hPresentationTimer))
  400. timer_service_disable(g_pClipsNav->m_hPresentationTimer);
  401. // Clear any Resume Marker
  402. (g_pClipsNav->m_cmResumeMarker).dwAddress= (ULONG)-1;
  403. // <<< Robin_0903_2004
  404. #ifdef DIVX_SUPPORT_MULTI_SUBTITLE_MODE0
  405. bNeedWaitForUI = FALSE;
  406. #endif
  407. // >>> Robin_0903_2004
  408. // Re-invoke playback of the current Clip, to apply the new Angle
  409. if (!invokePlayback(FALSE)) {
  410. tr_printf(("FATAL: OnAngleSelection() Failed [2]: Cannot re-invoke playback.n"));
  411. gcs.pstate= PST_STOP;
  412. }
  413. return;
  414. }
  415. /////////////////////////////////////////////////////////////////////////////
  416. // OnTransitionSelection()
  417. //
  418. // Description: Handles Transition-Effect selection
  419. //
  420. // Input: i_eTransition - The selected Transition-Effect to apply
  421. // Output: None
  422. // In/Out: None
  423. // Return: None
  424. //
  425. // Remarks:
  426. // Transition-Effect is only applied if the current Clip hasn't finished
  427. // presenting, and is using some kind of Transition-Effect.
  428. static void OnTransitionSelection(enClipTransitionEffect i_eTransition)
  429. {
  430. dbg_printf(("OnTransitionSelection(%d)n", i_eTransition));
  431. if (PST_STOP != gcs.pstate) {
  432. UINT16 hClipInstance= ClipsRepository_getInstanceAt(SHARED_INFO.uCurrentClipNumber-1);
  433. if ((eCS_Finished != Clip_getStatus(hClipInstance)) &&
  434. (eCTE_None != Clip_getTransitionEffect(hClipInstance)))
  435. {
  436. Clip_setTransitionEffect(hClipInstance, i_eTransition);
  437. }
  438. }
  439. SHARED_INFO.eCurrentTransition= (UINT8)i_eTransition;
  440. return;
  441. }
  442. #ifdef CLIPS_JPEG_DIGEST_SUPPORT
  443. /////////////////////////////////////////////////////////////////////////////
  444. // _handleDigestUnit()
  445. //
  446. // Description: A Callback function supplied to the Digest mechanism
  447. //
  448. // Input: uUnitIndex - The Index of the Play-Item to Digest
  449. // eQuery - The requested Query
  450. // Output: None
  451. // In/Out: None
  452. // Return: None
  453. //
  454. // Remarks: None
  455. static BOOL _handleDigestUnit(UINT16 uUnitIndex, enDigestQuery eQuery)
  456. {
  457. UINT16 uClipIndex;
  458. UINT16 hClipInstance;
  459. dbg_printf(("_handleDigestUnit(%d, %d)n", uUnitIndex, (UINT16)eQuery));
  460. if (!Array_getAt(g_pClipsNav->m_hDigestUnits, uUnitIndex, (BYTE*)&uClipIndex)) {
  461. dbg_printf(("Cannot retrieve Clip-Index to digest.n"));
  462. return FALSE;
  463. }
  464. hClipInstance= ClipsRepository_getInstanceAt(uClipIndex);
  465. if (NULL == hClipInstance) {
  466. tr_printf(("FATAL: _handleDigestUnit() Failed [1]n"));
  467. return FALSE;
  468. }
  469. switch (eQuery)
  470. {
  471. case eDigestQuery_Start:
  472. // Reset error recovery
  473. (g_pClipsNav->m_ErrorRecoveryInfo).uRetryCount= CLIPS_ERROR_RECOVERY_RETRY_COUNT;
  474. Clip_digest(hClipInstance);
  475. return TRUE;
  476. case eDigestQuery_Stop:
  477. Clip_abortPlayback(hClipInstance, TRUE);
  478. return TRUE;
  479. case eDigestQuery_IsFinished:
  480. if (eCS_Error_Decoding == Clip_getStatus(hClipInstance)) {
  481. if (0 < (g_pClipsNav->m_ErrorRecoveryInfo).uRetryCount) {
  482. (g_pClipsNav->m_ErrorRecoveryInfo).uRetryCount--;
  483. Clip_digest(hClipInstance);
  484. }
  485. }
  486. else
  487. return (eCS_Busy != Clip_getStatus(hClipInstance));
  488. }
  489. return FALSE;
  490. }
  491. /////////////////////////////////////////////////////////////////////////////
  492. // OnDigest()
  493. //
  494. // Description: Handle invocation of Digest Mode
  495. //
  496. // Input: Param - The selected Digest-Mode to engage
  497. // Output: None
  498. // In/Out: None
  499. // Return: None
  500. //
  501. // Remarks: None
  502. static void OnDigest(UINT16 Param)
  503. {
  504. UINT16 uDigestIndex, uInitialDigestItem, uIndex;
  505. dbg_printf(("OnDigest() %02xn", Param));
  506. // If already on digest mode, ignore the request
  507. if (g_pClipsNav->m_bDigestMode) {
  508. dbg_printf(("Already on digest mode. Ignored.n"));
  509. return;
  510. }
  511. // Make sure that there's anything to Digest
  512. if ((0 == g_pClipsNav->m_uDigestableItemsCnt) ||
  513. (0 == (g_pClipsNav->m_uDigestableTypes & g_uPlaybackFilter)))
  514. {
  515. dbg_printf(("WARNING: OnDigest() Failed [1]: No suitable items.n"));
  516. return;
  517. }
  518. // Allocate the Digest-Units Array
  519. g_pClipsNav->m_hDigestUnits= Array_construct(g_pClipsNav->m_uDigestableItemsCnt, 
  520.  sizeof(UINT16), NULL);
  521. if (NULL == g_pClipsNav->m_hDigestUnits) {
  522. tr_printf(("FATAL: OnDigest() Failed [2]: Cannot allocate digest items array!n"));
  523. return;
  524. }
  525. // Cancel Repeat Mode
  526. cancelRepeatModes(PM_REPEAT_AB_MASK);
  527. // Cancel Intro Play Mode if Stop
  528. SHARED_INFO.bIsIntroPlayMode = FALSE;
  529. // Fill the array only with appropriate Clips
  530. uInitialDigestItem= 0;
  531. uDigestIndex= 0;
  532. for (uIndex=0; 
  533.  (uIndex < SHARED_INFO.uClipsCnt) && (uDigestIndex < g_pClipsNav->m_uDigestableItemsCnt);
  534.  uIndex++)
  535. {
  536. UINT16 hClipInstance= ClipsRepository_getInstanceAt(uIndex);
  537. if (NULL == hClipInstance) {
  538. dbg_printf(("WARNING: OnDigest() Failed [3]n"));
  539. continue;
  540. }
  541. if (Clip_hasAttribute(hClipInstance, eCA_Digestable)) {
  542. if (SHARED_INFO.uCurrentClipNumber == (1 + uIndex))
  543. uInitialDigestItem= uDigestIndex;
  544. if (!Array_setAt(g_pClipsNav->m_hDigestUnits, uDigestIndex++, 
  545.  (const BYTE*)&uIndex))
  546. {
  547. dbg_printf(("WARNING: OnDigest() Failed [4]n"));
  548. }
  549. }
  550. }
  551. // Disable the Presentation-Timer
  552. timer_service_disable(g_pClipsNav->m_hPresentationTimer);
  553. // Abort any ongoing playback
  554. if (PST_STOP != gcs.pstate) {
  555. UINT16 hClipInstance= ClipsRepository_getInstanceAt(SHARED_INFO.uCurrentClipNumber-1);
  556. Clip_abortPlayback(hClipInstance, TRUE);
  557. }
  558. if (NULL != g_pClipsNav->m_hCachedClip)
  559. Clip_abortPlayback(g_pClipsNav->m_hCachedClip, TRUE);
  560. // Enable Digest-Mode
  561. PE_Clips_EnableDigestMode(TRUE, eClipType_JPEG);
  562. // Move to Still State, and Presentation mode
  563. gcs.pstate= PST_STILL;
  564. // Initialize the Digest mechanism
  565. if (! Digest_init(_handleDigestUnit, uDigestIndex, eDiscView, 1)) {
  566. tr_printf(("FATAL: OnDigest() Failed [4]: Cannot initialize Digestn"));
  567. return;
  568. }
  569. // Move to Digest-Mode
  570. g_pClipsNav->m_bDigestMode= TRUE;
  571. // Record the current Operation-Mask, to be restored once Digest-Mode is terminated
  572. g_pClipsNav->m_ulCOP_Mask= COP_MASK;
  573. // Launch Digest
  574. #ifdef EXINO2 //ZKR JK0414 : always display from first picture 
  575. Digest_start((uInitialDigestItem/6)*6);
  576. #else
  577. Digest_start(uInitialDigestItem);
  578. #endif
  579. // Set-up the relevant Operation-Mask
  580. CLEAR_COP_MASK(COP_PLAY | COP_PAUSE | COP_STEP | COP_SLOW | COP_SCAN | 
  581.    COP_SCAN_BACKWARD | COP_NEXT_CHAPTER | COP_PREVIOUS_CHAPTER);
  582. SET_COP_MASK(COP_STOP | COP_NEXT_CHAPTER | COP_PREVIOUS_CHAPTER);
  583. return;
  584. }
  585. /////////////////////////////////////////////////////////////////////////////
  586. // _terminateDigestMode()
  587. //
  588. // Description: Terminates the current Digest
  589. //
  590. // Input: None
  591. // Output: None
  592. // In/Out: None
  593. // Return: None
  594. //
  595. // Remarks: None
  596. static void _terminateDigestMode(void)
  597. {
  598. dbg_printf(("_terminateDigestModen"));
  599. #ifdef SUPPORT_FLASH_CARD
  600.   drv_abort_play();
  601. #endif
  602. // Disable Digest-Mode
  603. PE_Clips_EnableDigestMode(FALSE, eClipType_JPEG);
  604. // Terminate the Digest mechanism
  605. Digest_terminate();
  606. // Restore the Operation-Mask
  607. SET_COP_MASK(g_pClipsNav->m_ulCOP_Mask);
  608. // Free the Digest-Units Array
  609. if (NULL != g_pClipsNav->m_hDigestUnits) {
  610. Array_destruct(g_pClipsNav->m_hDigestUnits);
  611. g_pClipsNav->m_hDigestUnits= NULL;
  612. }
  613. // Terminate Digest-Mode
  614. g_pClipsNav->m_bDigestMode= FALSE;
  615. return;
  616. }
  617. #endif //CLIPS_JPEG_DIGEST_SUPPORT
  618. #endif //CLIPS_JPEG_SUPPORT
  619. /////////////////////////////////////////////////////////////////////////////
  620. // PerformErrorRecovery()
  621. //
  622. // Description: Handles Error-Recovery
  623. //
  624. // Input: hClipInstance - The instance of the Clip to be recovered
  625. // eStatus - The current Status of the Clip specified in hClipInstance
  626. // Output: None
  627. // In/Out: None
  628. // Return: None
  629. //
  630. // Remarks: None
  631. static void PerformErrorRecovery(UINT16 hClipInstance, enClipStatus eStatus)
  632. {
  633. // Handle an Unsupported-Format Error
  634. if (eCS_Error_UnsupportedFormat == eStatus) {
  635. dbg_printf(("INFO: Unsupported Format encountered!n"));
  636. // Reflect the Error, for user's intervention
  637. (SHARED_INFO.cieCurrClip).eClipStatus= (UINT8)eStatus;
  638. // Unless pausing, continue to the next Item
  639. if (PST_PAUSE != gcs.pstate)
  640. OnPlaybackFinished();
  641. return;
  642. }
  643. // Handle a Decoding Error
  644. if (eCS_Error_Decoding == eStatus) {
  645. dbg_printf(("INFO: Decoding-Error found. Recovering...n"));
  646. if ((g_pClipsNav->m_ErrorRecoveryInfo).uRetryCount > 0) {
  647. (g_pClipsNav->m_ErrorRecoveryInfo).uRetryCount--;
  648. Clip_abortPlayback(hClipInstance, TRUE);
  649. // Repeat the current Clip
  650. if (Clip_hasAttribute(hClipInstance, eCA_Markable)) {
  651. ClipMarker cmRecovery;
  652. Clip_recordMarker(hClipInstance, &cmRecovery);
  653. // Increment the Address
  654. cmRecovery.dwAddress += CLIPS_LOCATION_TOLERANCE;
  655. Clip_startPlayback(hClipInstance, &cmRecovery, FALSE);
  656. }
  657. else {
  658. Clip_startPlayback(hClipInstance, NULL, FALSE);
  659. }
  660. }
  661. else {
  662. // Unrecoverable-Error
  663. dbg_printf(("INFO: Retries expired; abandoning current Clip.n"));
  664. // Reflect the Error, for user's intervention
  665. (SHARED_INFO.cieCurrClip).eClipStatus= (UINT8)eStatus;
  666. // Unless pausing, continue to the next Item
  667. if (PST_PAUSE != gcs.pstate)
  668. OnPlaybackFinished();
  669. }
  670. return;
  671. }
  672. // Nothing to do: just reflect the current Status
  673. (SHARED_INFO.cieCurrClip).eClipStatus= (UINT8)eStatus;
  674. }
  675. /////////////////////////////////////////////////////////////////////////////
  676. // OnScan(int iScanSpeed)
  677. //
  678. // Description: Handles Scan Request from UI
  679. //
  680. // Input: iScanSpeed: Scan Speed Requested
  681. // Output: None
  682. // In/Out: None
  683. // Return: None
  684. //
  685. // Remarks: None
  686. static void OnScan(int iScanSpeed)
  687. {
  688. UINT16 hClipInstance;
  689. // Start Scan
  690. dbg_printf(("On Scan()n"));
  691. hClipInstance= ClipsRepository_getInstanceAt(SHARED_INFO.uCurrentClipNumber-1);
  692. if ( ( NULL != hClipInstance) && ( PST_STOP != gcs.pstate ) && Clip_hasAttribute(hClipInstance, eCA_Scanable) ){
  693. // Cancel Intro Play Mode if Stop
  694. cancelRepeatModes(PM_REPEAT_AB_MASK);
  695. SHARED_INFO.bIsIntroPlayMode = FALSE;
  696. Clip_Scan(hClipInstance, iScanSpeed);
  697. }
  698. return;
  699. }
  700. //////////////////////////////////////////////////////////////////////////////////
  701. // Function name : OnIntro
  702. //
  703. // Input Parameters : void
  704. //
  705. // Return Value : void 
  706. //
  707. // Description : Begin to start intro playback or stop it.
  708. //////////////////////////////////////////////////////////////////////////////////
  709. static void OnIntro(void)
  710. {
  711. if (TRUE != SHARED_INFO.bIsIntroPlayMode)
  712. {
  713. if ( PST_STOP == gcs.pstate ){
  714. dbg_printf(("Cancel Playmode/Repeat moden"));
  715. PM_SetPlaybackMode(0);
  716. PM_ClearRepeat();
  717. SHARED_INFO.bIsIntroPlayMode = TRUE;
  718. SHARED_INFO.uCurrPlaylistItem= computePlaylistItem(SHARED_INFO.uCurrPlaylistItem, FALSE);
  719. OnPlay();
  720. }else
  721. dbg_printf(("Can't Activate Intro Mode in non-stop moden"));
  722. }else
  723. dbg_printf((" Already in intro mode, ignoren"));
  724. return;
  725. }
  726. ///////////////////////////////////////////////////////////////////////////////
  727. // Function Name: OnGotoTime(WORD Time)
  728. //
  729. // Input: Seek Time inside current playback Clip
  730. // 
  731. // Return: None
  732. //
  733. // Description: We only support Track Time Search for MP3 Clips now
  734. ///////////////////////////////////////////////////////////////////////////////
  735. static void OnGotoTime(WORD wTime)
  736. {
  737. UINT16 hClipInstance;
  738. WORD  wTrackTime;
  739. DWORD dwStartAddress, dwJumpOffset;
  740. dbg_printf(("On GotoTime at: %04xn", wTime));
  741. #ifdef USE_AUX_SUBTITLES
  742. if ((SI_IS_CURRENT_MPEG4_CLIP && (FALSE != areAuxSubtitlePresent())) ||
  743. SI_CLIPS_MP4_INTERNAL_SUBTITLE_ON)// Robin_0528_2004_A
  744. {
  745. // stop subtitle seeking
  746. setSubtitlesPlayMode(FALSE);
  747. stopDisplayAuxSubtitles();
  748. }
  749. #endif
  750. if ( ( PST_PLAY != gcs.pstate ) && ( PST_PAUSE != gcs.pstate ) ){
  751. dbg_printf(("Can't activate Clip Goto Time in non-play-pause moden"));
  752. return;
  753. }
  754. hClipInstance= ClipsRepository_getInstanceAt(SHARED_INFO.uCurrentClipNumber-1);
  755. if ( ( NULL == hClipInstance ) && ( eClipType_MP3 != Clip_getType(hClipInstance)) && ( eClipType_MPEG != Clip_getType(hClipInstance)) ){
  756. dbg_printf(("Can't find clip or current clip is not MP3 Clipn"));
  757. return;
  758. }
  759. // Calcuate jump location for different clips(MP3/MPEG)
  760. switch ( Clip_getType(hClipInstance) ){
  761. case eClipType_MP3:
  762. if ( gns.clips.uTotalPlaybackTime <= wTime ){
  763. dbg_printf(("Goto Time %04x is more than Total Track Time %04xn", wTime, wTrackTime));
  764. return;
  765. }
  766. dwStartAddress = MP3_Time_To_Address(wTime);
  767. break;
  768. case eClipType_MPEG:
  769. wTrackTime = (DWORD)((gns.clips.cieCurrClip.ciInfo.cbFileSize) >> 11)/(DWORD)CLIPS_MPEG_NUM_OF_SECTORES_PER_SECOND;
  770. if ( wTrackTime <= wTime ){
  771. dbg_printf(("Goto Time %04x is more than Total Track Time %04xn", wTime, wTrackTime));
  772. return;
  773. }
  774. dwJumpOffset = (DWORD)CLIPS_MPEG_NUM_OF_SECTORES_PER_SECOND * (DWORD)wTime;
  775.                      dwStartAddress = (gns.clips.cieCurrClip.ciInfo.dwFileLocation) + dwJumpOffset;
  776. break;
  777. case eClipType_AVI:
  778. #ifdef IS_ASF_CAPABLE
  779. case eClipType_ASF:
  780. #endif
  781. #ifdef IS_MP4_CAPABLE
  782. case eClipType_MP4:
  783. #endif
  784. if ( gns.clips.uTotalPlaybackTime <= wTime )
  785. {
  786. dbg_printf(("Goto time %04d is more than total clip time %04dn", wTime, gns.clips.uTotalPlaybackTime));
  787. return;
  788. }
  789. dbg_printf(("MPEG4 Goto Time: Time %04x Track Time %04xn", wTime, wTrackTime));
  790. dwStartAddress = gns.clips.cieCurrClip.ciInfo.dwFileLocation;
  791. break;
  792. default:
  793. dbg_printf(("Non supported format for time search, returnn"));
  794. return;
  795. }
  796. dbg_printf(("File Start Address is %08x, jump to start at %08xn", gns.clips.cieCurrClip.ciInfo.dwFileLocation,
  797. dwJumpOffset));
  798. Clip_abortPlayback(hClipInstance, TRUE);
  799. // gcs.pstate = PST_STILL;
  800. cancelRepeatModes(PM_REPEAT_AB_MASK);
  801. (g_pClipsNav->m_cmResumeMarker).dwAddress = dwStartAddress;
  802. (g_pClipsNav->m_cmResumeMarker).uTime = wTime;
  803. #ifdef USE_AUX_SUBTITLES
  804. if (SI_IS_CURRENT_MPEG4_CLIP && (FALSE != areAuxSubtitlePresent()))// Robin_0528_2004_A
  805. {
  806. // replace 0 with the updated time once it can be determined before
  807.          // playback starts.
  808. subtitleGoToTime(0);
  809. setSubtitlesPlayMode(TRUE);
  810. }
  811. else if (SI_CLIPS_MP4_INTERNAL_SUBTITLE_ON)
  812. {
  813. setSubtitlesPlayMode(TRUE);
  814. }
  815. #endif
  816. // <<< Robin_0903_2004   
  817. #ifdef DIVX_SUPPORT_MULTI_SUBTITLE_MODE0
  818. bNeedWaitForUI = FALSE;
  819. #endif
  820. // >>> Robin_0903_2004    
  821. if (!invokePlayback(FALSE)) {
  822. tr_printf(("FATAL: Failed to invoke playbackn"));
  823. gcs.pstate= PST_STOP;
  824. }
  825. return;
  826. }
  827. /////////////////////////////////////////////////////////////////////////////////////////////////
  828. //  Function Name: OnA2BRepeat(int Param)
  829. //
  830. //  Input: A2B Action
  831. //
  832. //  Return: None
  833. //
  834. //  Description: Take the proper action for A2B according to "Param"
  835. /////////////////////////////////////////////////////////////////////////////////////////////////
  836. static void OnA2BRepeat(int Param)
  837. {
  838. UINT16 hClipInstance;
  839. dbg_printf(("On A2B Repeat Requrestn"));
  840. if ( PST_PLAY != gcs.pstate ){
  841. dbg_printf(("Can't activated A2B in non-play moden"));
  842. return;
  843. }
  844. hClipInstance= ClipsRepository_getInstanceAt(SHARED_INFO.uCurrentClipNumber-1);
  845. // if ( ( NULL == hClipInstance ) || ( eClipType_MP3 != Clip_getType(hClipInstance)) 
  846. // || ( eClipType_MPEG != Clip_getType(hClipInstance)) ){
  847. if ( !Clip_hasAttribute(hClipInstance, eCA_Markable)){
  848. dbg_printf(("Can't find clip or current clip is not MP3 Clipn"));
  849. return;
  850. }
  851. if (0 == (int)Param) {
  852. OnCancelABRepeat();
  853. return;
  854. }
  855. if (PM_GetRepeatAB() & PM_REPEAT_AB_B) {
  856. OnCancelABRepeat();
  857. PM_SetRepeatAB(0);
  858. }
  859. else {
  860. if ( 0 == PM_GetRepeatAB() ){ //) && ((g_pClipsNav->m_PositionA).iPlaylistItem < 0)) {
  861. OnSetMarkerA();
  862. PM_SetRepeatAB(PM_REPEAT_AB_A);
  863. if ( SI_IS_CURRENT_MPEG_CLIP ){
  864. if ( g_pClipsNav->m_PositionA.dwAddress > MPEG_SEARCH_ADDRESS_OFFSET )
  865. {
  866. #ifdef SUPPORT_FLASH_CARD
  867. if(!IS_PLAYING_CARD)
  868. #endif
  869. g_pClipsNav->m_PositionA.dwAddress -= MPEG_SEARCH_ADDRESS_OFFSET;
  870. }
  871. }
  872. }
  873. else {
  874. OnSetMarkerB();
  875. PM_SetRepeatAB(PM_REPEAT_AB_B);
  876. }
  877. }
  878.    return;
  879. }
  880. /////////////////////////////////////////////////////////////////////////////////////////////////
  881. // void SetMarker(ClipMarker eMarkerType, WORD uBookmarkNumber) -
  882. // Records the current playback position in the desired Marker.
  883. //
  884. // Input:
  885. // eMarkerType - Identifies which Marker is to be used for recording
  886. // uBookmarkNumber - If a Bookmark is being recorded, identifies the serial number
  887. // of the requested Bookmark within the list of available Bookmarks
  888. //
  889. // Output:
  890. // None. The requested Marker is recorded.
  891. //
  892. // Remarks:
  893. // If an attempt is made to record a non-existent Bookmark, the recording is aborted.
  894. static void SetMarker(enClip_MarkerType eMarkerType, WORD uBookmarkNumber)
  895. {
  896. UINT16 hClipInstance;
  897. ClipMarker *pMarker= NULL;
  898. hClipInstance= ClipsRepository_getInstanceAt(SHARED_INFO.uCurrentClipNumber-1);
  899. if ( NULL == hClipInstance )
  900. return;
  901. // Select the appropriate Marker to set
  902. switch (eMarkerType) 
  903. {
  904. case eMarkerA: pMarker= &(g_pClipsNav->m_PositionA);
  905. break;
  906. case eMarkerB: pMarker= &(g_pClipsNav->m_PositionB);
  907. break;
  908. case eResumePlayback:
  909. pMarker= &(g_pClipsNav->m_cmResumeMarker);
  910. break;
  911. case eBookmark:
  912. if (uBookmarkNumber >= CLIPS_MAX_BOOKMARKER_NUM){
  913. dbg_printf(("UnSupported Bookmarker Numbern"));
  914. pMarker= NULL;
  915. }
  916. // else
  917. // pMarker= &(g_pClipsNav->m_Bookmarks[uBookmarkNumber]);
  918. dbg_printf(("Not supported Bookmarker Typen"));
  919. break;
  920. }
  921. Clip_recordMarker(hClipInstance, pMarker);
  922. return;
  923. }
  924. /////////////////////////////////////////////////////////////////////////////////////////////////
  925. // void ClearMarker(enCDDA_MarkerType eMarkerType, WORD uBookmarkNumber) -
  926. // Clears the desired Marker.
  927. //
  928. // Input:
  929. // eMarkerType - Identifies which Marker is to be cleared
  930. // uBookmarkNumber - If a Bookmark is being cleared, identifies the serial number
  931. // of the requested Bookmark within the list of available Bookmarks
  932. //
  933. // Output:
  934. // None. The requested Marker is cleared.
  935. //
  936. // Remarks:
  937. // If an attempt is made to clear a non-existent Bookmark, the clearing is aborted.
  938. static void ClearMarker(enClip_MarkerType eMarkerType, WORD uBookmarkNumber)
  939. {
  940. ClipMarker *pMarker= NULL;
  941. // Select the appropriate Marker to set
  942. switch (eMarkerType) 
  943. {
  944. case eMarkerA: pMarker= &(g_pClipsNav->m_PositionA);
  945. break;
  946. case eMarkerB: pMarker= &(g_pClipsNav->m_PositionB);
  947. break;
  948. case eResumePlayback:
  949. pMarker= &(g_pClipsNav->m_cmResumeMarker);
  950. break;
  951. case eBookmark:
  952. if (uBookmarkNumber >= CLIPS_MAX_BOOKMARKER_NUM){
  953. dbg_printf(("UnSupported Bookmarker Numbern"));
  954. pMarker= NULL;
  955. }
  956. // else
  957. // pMarker= &(g_pCDDANav->m_Bookmarks[uBookmarkNumber]);
  958. dbg_printf(("Not supported Bookmarker Typen"));
  959. break;
  960. //#endif
  961. }
  962. if (NULL != pMarker) {
  963. pMarker->uTime = -1;
  964. pMarker->dwAddress= -1;
  965. pMarker->uClipNumer = -1;
  966. }
  967. return;
  968. }
  969. /////////////////////////////////////////////////////////////////////////////////////////////////
  970. // void OnSetMarkerA() -
  971. // Handles an event of setting the first Marker for an A->B Repeat sequence.
  972. //
  973. // Input:
  974. // None.
  975. // Output:
  976. // None.
  977. //
  978. // Remarks:
  979. // The method calls for the setting of the MarkerA Marker.
  980. static void OnSetMarkerA()
  981. {
  982. dbg_printf(("OnSetMarkAn"));
  983. SetMarker(eMarkerA, 0);
  984. return;
  985. }
  986. /////////////////////////////////////////////////////////////////////////////////////////////////
  987. // void OnSetMarkerB() -
  988. // Handles an event of setting the second Marker for an A->B Repeat sequence.
  989. //
  990. // Input:
  991. // None.
  992. //
  993. // Output:
  994. // None.
  995. //
  996. // Remarks:
  997. // The method calls for the setting of the MarkerB Marker, and then it initiates the
  998. // REPEAT_AB Play-Mode.
  999. static void OnSetMarkerB()
  1000. {
  1001. dbg_printf(("OnSetMarkB()n"));
  1002. // First, record the current position as MarkerB and stop playback
  1003. SetMarker(eMarkerB, 0);
  1004. // Prohibit an A-B Segment of less than 1 Second
  1005. if (((g_pClipsNav->m_PositionB).uTime - (g_pClipsNav->m_PositionA).uTime) < CLIPS_A2B_MIN_GAP)
  1006. {
  1007. // Force a 5 Second gap between Point-A and Point-B
  1008. (g_pClipsNav->m_PositionB).uTime= (g_pClipsNav->m_PositionA).uTime + CLIPS_A2B_MIN_GAP;
  1009. }
  1010. // Stop Playback
  1011. PE_CD_AbortPlayback(TRUE);
  1012. // Move the Current-Position to Point-A
  1013. memcpy(&(g_pClipsNav->m_cmResumeMarker), &(g_pClipsNav->m_PositionA), sizeof(ClipMarker));
  1014. // Invoke A-B Repeat, and start Playback
  1015. PM_SetRepeatAB(PM_REPEAT_AB_B);
  1016. // <<< Robin_0903_2004
  1017. #ifdef DIVX_SUPPORT_MULTI_SUBTITLE_MODE0
  1018. bNeedWaitForUI = FALSE;
  1019. #endif
  1020. // >>> Robin_0903_2004
  1021. // Schedule a playback using the Markers just set
  1022. if (! invokePlayback(FALSE)) {
  1023. dbg_printf(("Error: Failed to invoke playbackn"));
  1024. gcs.pstate= PST_STOP;
  1025. }
  1026. ie_send(IE_UI_STATE_CHANGE);
  1027. return;
  1028. }
  1029. /////////////////////////////////////////////////////////////////////////////////////////////////
  1030. // void OnCancelABRepeat() -
  1031. // Handles an event of cancelling the current REPEAT_AB Play-Mode.
  1032. //
  1033. // Input:
  1034. // None.
  1035. //
  1036. // Output:
  1037. // None.
  1038. //
  1039. // Remarks:
  1040. // The method aborts the current Play-Mode by clearing both MarkerA and MarkerB, and
  1041. // removing the REPEAT_AB Bit from the Play-Mode mask.
  1042. // In addition, the method will re-sechedule a Rendezvous-Point, if needed,
  1043. // in order to assure correct playback of the following items.
  1044. static void OnCancelABRepeat()
  1045. {
  1046. dbg_printf(("OnCancelABRepeat()n"));
  1047. // Clear the current setting of both markers
  1048. ClearMarker(eMarkerA, 0);
  1049. ClearMarker(eMarkerB, 0);
  1050. PM_SetRepeatAB(0);
  1051. ie_send(IE_UI_STATE_CHANGE);
  1052. return;
  1053. }
  1054. ////////////////////////////////////////////////////////////////////////////////////////////////
  1055. // void OnDrmInfoMsgArrived() -
  1056. // Handles an IE_CORE_DRM_INFO_ARRIVED Event.
  1057. //
  1058. // Input:
  1059. // None.
  1060. //
  1061. // Output:
  1062. // None. 
  1063. //
  1064. // Remarks:
  1065. // None.
  1066. //////////////////////////////////////////////////////////////////////////////////////////
  1067. //usually only 64 words are used.
  1068. #define MAX_ENCODED_BUFFER 100
  1069. static void OnDrmInfoMsgArrived(void)
  1070. {
  1071.     UINT16 uiStatus;
  1072.     UINT16 i;
  1073.     UINT16 uiWriteIteration;
  1074.     UINT16 uiNumOfWriteIterations;
  1075.     UINT32 uiFrameKeyIndex;
  1076.     UINT32 uiTemp1,uiTemp2;
  1077.     UINT16 wTimeOut;
  1078.     
  1079.     UINT16 a_chEncodedVideoChunckBuffer[MAX_ENCODED_BUFFER];
  1080.     UINT16 a_chDecodedVideoChunckBuffer[MAX_ENCODED_BUFFER];
  1081.     UINT32 uiInputBufferSize;
  1082.     UINT32 uiInputBufferSizeWords;
  1083.     UINT32 uiOutputBufferSize;
  1084. uiStatus = inport(DS2CFIFO_STATUS_ADDR); 
  1085.     // wait for at least first three words in the fifo 
  1086.     // (buffer size and frame key index)
  1087. if(!uiStatus)
  1088. {
  1089. tr_printf(("Nothing in FIFOn"));
  1090. return;
  1091. }
  1092.     uiTemp1 = inport(DS2CFIFO_DATA_ADDR);
  1093.     uiTemp2 = inport(DS2CFIFO_DATA_ADDR);
  1094.     uiInputBufferSize = (uiTemp1<<16)|(uiTemp2);
  1095.     
  1096.     if (uiInputBufferSize > (MAX_ENCODED_BUFFER*2) ) 
  1097.     {
  1098.        tr_printf(("Error - uiInputBufferSize larger then %d words!n",MAX_ENCODED_BUFFER*2));
  1099. return;
  1100.     }
  1101.     // get Frame key index
  1102.     uiFrameKeyIndex = inport(DS2CFIFO_DATA_ADDR);
  1103.     
  1104. // get encoded block offset
  1105.    uiInputBufferSizeWords = uiInputBufferSize/2;
  1106.     for (i=0;
  1107.          i<uiInputBufferSizeWords && i<MAX_ENCODED_BUFFER;
  1108.          i++)
  1109.     {
  1110.      int timeOut = 0;
  1111.         do { 
  1112.             uiStatus = inport(DS2CFIFO_STATUS_ADDR); 
  1113. if (timeOut > 10000) // Robin_0609_2004_A, avoid system stick when select Failed DivX file (can't playback) during playbacking DivX-DRM file
  1114. {
  1115. dbg_printf(("WARNING: OnDrmInfoMsgArrived() Failed!n"));
  1116. return;
  1117. }
  1118. timeOut++;
  1119.         } while ( uiStatus < 1 );
  1120.         a_chEncodedVideoChunckBuffer[i] = inport(DS2CFIFO_DATA_ADDR);
  1121. }
  1122. #ifdef AVI_DRM_SUPPORT
  1123.     HandleDrmMessage( uiFrameKeyIndex, 
  1124.                       (BYTE*)a_chEncodedVideoChunckBuffer, 
  1125.                       uiInputBufferSize,
  1126.                       (BYTE*)a_chDecodedVideoChunckBuffer, 
  1127.                       &uiOutputBufferSize);
  1128.    
  1129. #endif //AVI_DRM_SUPPORT
  1130.   
  1131.    // send the decrypted data through the shared memory
  1132.    uiNumOfWriteIterations = (UINT16)uiInputBufferSizeWords/DRM_DECRYPTED_SHARED_MEM_LENGTH;
  1133.    for (uiWriteIteration = 0; uiWriteIteration < uiNumOfWriteIterations; uiWriteIteration++)
  1134.    {
  1135.    wTimeOut = 1000;
  1136.    while (wTimeOut--)
  1137.       {
  1138.    if (FALSE == DEC_AVI_GetDemuxSharedBit(DRM_DECRYPTED_FLAG_OFFSET, DRM_DECRYPTED_FLAG_BIT))
  1139. break;
  1140.    delay_us(1000UL);
  1141.    }
  1142.    
  1143.    if (TRUE == DEC_AVI_GetDemuxSharedBit(DRM_DECRYPTED_FLAG_OFFSET, DRM_DECRYPTED_FLAG_BIT))
  1144. {
  1145.    tr_printf(("Time out in OnDrmInfoMsgArrived()!n"));
  1146.    return;
  1147. }
  1148.    
  1149.    for (i = 0; i < DRM_DECRYPTED_SHARED_MEM_LENGTH; i++)
  1150.    {
  1151.    DVP_API_DR_Write(DVP_DS2C_FIFO_START_OFFSET+i, a_chDecodedVideoChunckBuffer[(uiWriteIteration*DRM_DECRYPTED_SHARED_MEM_LENGTH) + i ]);
  1152.       }
  1153.    
  1154.    DEC_AVI_SetDemuxSharedBit(DRM_DECRYPTED_FLAG_OFFSET, DRM_DECRYPTED_FLAG_BIT);
  1155.    }
  1156.    if ( uiInputBufferSizeWords % DRM_DECRYPTED_SHARED_MEM_LENGTH)
  1157.    {
  1158.    wTimeOut = 1000;
  1159.    while (wTimeOut--)
  1160.       {
  1161.    if (FALSE == DEC_AVI_GetDemuxSharedBit(DRM_DECRYPTED_FLAG_OFFSET, DRM_DECRYPTED_FLAG_BIT))
  1162. break;
  1163.    delay_us(1000UL);
  1164. }
  1165.    
  1166.    if (TRUE == DEC_AVI_GetDemuxSharedBit(DRM_DECRYPTED_FLAG_OFFSET, DRM_DECRYPTED_FLAG_BIT))
  1167. {
  1168.    tr_printf(("Time out in OnDrmInfoMsgArrived()!n"));
  1169.    return;
  1170. }
  1171.    
  1172.    for (i = 0; i < (uiInputBufferSizeWords % DRM_DECRYPTED_SHARED_MEM_LENGTH); i++)
  1173.    {
  1174.    DVP_API_DR_Write(DVP_DS2C_FIFO_START_OFFSET+i, a_chDecodedVideoChunckBuffer[(uiWriteIteration*DRM_DECRYPTED_SHARED_MEM_LENGTH) + i ]);
  1175.       }
  1176.    DEC_AVI_SetDemuxSharedBit(DRM_DECRYPTED_FLAG_OFFSET, DRM_DECRYPTED_FLAG_BIT);
  1177.    }
  1178.  
  1179.  
  1180.    return;
  1181. }
  1182. #ifdef AVI_AUDIO_CHANGE_ONSCAN //ZKR JK0413 : add for Divx audio change on-the-fly
  1183. /////////////////////////////////////////////////////////////////////////////////////////////////
  1184. // void OnAuioChanged() -
  1185. // Handles an IE_CORE_AUDIO_CHANGE Event.
  1186. //
  1187. // Input:
  1188. // None
  1189. //
  1190. // Output:
  1191. // None. 
  1192. //
  1193. // Remarks:
  1194. static void OnAudioChanged(void)
  1195. {
  1196. UINT16 hClipInstance= ClipsRepository_getInstanceAt(SHARED_INFO.uCurrentClipNumber-1);
  1197. tr_printf(("nav_clips : IDX(%d)n",_mpeg4AudioCurrentDispIdx));
  1198. sc_GetBytes(SC_MPEG4_AUDIO_STREAM_INFO_ADDR,
  1199. (_mpeg4AudioCurrentDispIdx * SIZE_OF_AUDIO_STREAM_INFO),
  1200. SIZE_OF_AUDIO_STREAM_INFO,
  1201. (BYTE*)&_mpeg4AudioStreamInfo
  1202. );
  1203. #ifdef  EXINO2
  1204. if ( gcs.pstate == PST_PLAY ) {
  1205. gcs.pstate = PST_STOP;
  1206. OnPlay();
  1207. }
  1208. #else     //PATCH: For audio chagne on fly, use the index table of previous audio stream. Potential A/V sync problem exsits.
  1209. if ( gcs.pstate == PST_PLAY ) 
  1210. {
  1211. Clip_recordMarker(hClipInstance, &g_pClipsNav->m_cmResumeMarker);
  1212. PE_CD_AbortPlayback(TRUE); // Maintain Standby mode
  1213. // Clip_abortPlayback(hClipInstance, TRUE);
  1214. // <<< Robin_0903_2004
  1215. #ifdef DIVX_SUPPORT_MULTI_SUBTITLE_MODE0
  1216. bNeedWaitForUI = FALSE;
  1217. #endif
  1218. // >>> Robin_0903_2004
  1219. if (!invokePlayback(FALSE)) {
  1220. dbg_printf(("Failed to play-back the current List.n"));
  1221. gcs.pstate= PST_STOP;
  1222. }
  1223. }
  1224. #endif
  1225. }
  1226. #endif //AVI_AUDIO_CHANGE_ONSCAN
  1227. #ifdef IS_MP4_CAPABLE
  1228. static void OnChapterChanged(void)
  1229. {
  1230. MPEG4ChapterEntry mpeg4ChapterEntry;
  1231. DWORD dwDRAMAddr;
  1232. // <<< Robin_1119_2004, fix the wrong chapter number calculation 
  1233. WORD wTimeStart;
  1234. WORD wTimeEnd;
  1235. dwDRAMAddr = _dwMP4ChapterDRAMStartAddr - ((SI_CLIPS_CHAPTER_CURRENT_DISP_IDX+1) * sizeof(MPEG4ChapterEntry)/2);
  1236. if (_mpeg4ChapterCurrentDispIdx > 0)
  1237. {
  1238. wai_sem(SEM_DRAM_ID);
  1239. I49_ReadDRAMData(dwDRAMAddr,(UINT16*)&mpeg4ChapterEntry, (sizeof(MPEG4ChapterEntry)/2));
  1240. sig_sem(SEM_DRAM_ID);
  1241. wTimeStart = mpeg4ChapterEntry.uiChapterTime;
  1242. }
  1243. else
  1244. {
  1245. wTimeStart = 0;
  1246. }
  1247. if (_mpeg4ChapterCurrentDispIdx < (_mpeg4ChapterAvailableNum -1))
  1248. {
  1249. dwDRAMAddr -= sizeof(MPEG4ChapterEntry)/2;
  1250. wai_sem(SEM_DRAM_ID);
  1251. I49_ReadDRAMData(dwDRAMAddr,(UINT16*)&mpeg4ChapterEntry, (sizeof(MPEG4ChapterEntry)/2));
  1252. sig_sem(SEM_DRAM_ID);
  1253. wTimeEnd = mpeg4ChapterEntry.uiChapterTime;
  1254. }
  1255. else
  1256. {
  1257. wTimeEnd = 0xFFFFU;
  1258. }
  1259. _uiMP4ChapterStartTime = wTimeStart;
  1260. _uiMP4ChapterEndTime = wTimeEnd;
  1261. OnGotoTime(wTimeStart);
  1262. // >>> Robin_1119_2004
  1263. }
  1264. #endif
  1265. /////////////////////////////////////////////////////////////////////////////////////////////////
  1266. // void OnSubtitleChanged() -
  1267. // Handles an IE_CORE_SUBTITLE_ARRIVED Event.
  1268. //
  1269. // Input:
  1270. // None
  1271. //
  1272. // Output:
  1273. // None. 
  1274. //
  1275. // Remarks:
  1276. // The handler is used for DivX playback only.
  1277. // the routine is handling Subtitles arrived from the Demux task
  1278. static void OnSubtitleChanged(void)
  1279. {
  1280. UINT16 hClipInstance= ClipsRepository_getInstanceAt(SHARED_INFO.uCurrentClipNumber-1);
  1281. // <<< Robin_0903_2004
  1282. MPEG4SubtitleStreamInfo mpeg4LastSubtitleStreamInfo;
  1283. // printf("IDX:%dn",SI_CLIPS_SUB_CURRENT_DISP_IDX);
  1284. sc_GetBytes(SC_MPEG4_SUBTITLE_STREAM_INFO_ADDR,
  1285. (SI_CLIPS_SUB_CURRENT_DISP_IDX * SIZE_OF_SUBTITLE_STREAM_INFO),
  1286. SIZE_OF_SUBTITLE_STREAM_INFO,
  1287. (BYTE*)&_mpeg4SubtitleStreamInfo
  1288. );
  1289. if (SI_CLIPS_SUB_CURRENT_DISP_IDX == MAX_SUB_PER_CLIP)
  1290. {
  1291. sc_GetBytes(SC_MPEG4_SUBTITLE_STREAM_INFO_ADDR,
  1292. ((SI_CLIPS_SUB_AVAILABLE_NUM-1) * SIZE_OF_SUBTITLE_STREAM_INFO),
  1293. SIZE_OF_SUBTITLE_STREAM_INFO,
  1294. (BYTE*)&mpeg4LastSubtitleStreamInfo
  1295. );
  1296. }
  1297. else
  1298. {
  1299. sc_GetBytes(SC_MPEG4_SUBTITLE_STREAM_INFO_ADDR,
  1300. ((SI_CLIPS_SUB_CURRENT_DISP_IDX-1) * SIZE_OF_SUBTITLE_STREAM_INFO),
  1301. SIZE_OF_SUBTITLE_STREAM_INFO,
  1302. (BYTE*)&mpeg4LastSubtitleStreamInfo
  1303. );
  1304. }
  1305. if(SI_CLIPS_SUB_CURRENT_DISP_IDX == MAX_SUB_PER_CLIP)
  1306. {
  1307. DEC_AVI_ChangedSubtitle(0xFFFF);
  1308. _mpeg4SubtitleStreamID = NO_STREAM;
  1309. if(mpeg4LastSubtitleStreamInfo.type > INTERNAL_SUBT)
  1310. {
  1311. // Robin_0329_2005, stop to display the external subtitle
  1312. setSubtitlesPlayMode(FALSE);
  1313. stopDisplayAuxSubtitles();
  1314. return;
  1315. }
  1316. }
  1317. else
  1318. {
  1319. // Robin_0419_2005, fix the problem when change subtitle language in sami
  1320. if (_mpeg4SubtitleCurrentDispIdx >= _mpeg4SubtitleInternalAvailableNum)
  1321. {
  1322. DEC_AVI_ChangedSubtitle(0xFFFF);
  1323. // push the internal subtitle, TBD
  1324. if ((_mpeg4SubtitleInternalAvailableNum == 0) && (_mpeg4SubtitleAvailableNum == 1)) // only one external subtitle
  1325. {
  1326. subtitleGoToTime(0);
  1327. setSubtitlesPlayMode(TRUE);
  1328. return;
  1329. }
  1330. }
  1331. else
  1332. {
  1333. DEC_AVI_ChangedSubtitle(_mpeg4SubtitleStreamID);
  1334. }
  1335. }
  1336. #ifdef AVI_SUBTITLE_CHANGE_ONSCAN 
  1337. #ifdef EXINO2   //ZKR JK0419 : not change subtitle
  1338. if (PST_PLAY== gcs.pstate)
  1339.     {
  1340. OnScan(0);
  1341. gcs.pstate= PST_PLAY;
  1342.     }    
  1343. #else
  1344. if ( gcs.pstate == PST_PLAY ) 
  1345. {
  1346. Clip_recordMarker(hClipInstance, &g_pClipsNav->m_cmResumeMarker);
  1347. PE_CD_AbortPlayback(TRUE); // Maintain Standby mode
  1348. // Clip_abortPlayback(hClipInstance, TRUE);
  1349. #ifdef DIVX_SUPPORT_MULTI_SUBTITLE_MODE0
  1350. bNeedWaitForUI = FALSE;
  1351. #endif
  1352. // >>> Robin_0903_2004
  1353. if (!invokePlayback(FALSE)) {
  1354. dbg_printf(("Failed to play-back the current List.n"));
  1355. gcs.pstate= PST_STOP;
  1356. }
  1357. }
  1358. #endif
  1359. #endif
  1360. }
  1361. /////////////////////////////////////////////////////////////////////////////////////////////////
  1362. // void OnSubtitleArrived() -
  1363. // Handles an IE_CORE_SUBTITLE_ARRIVED Event.
  1364. //
  1365. // Input:
  1366. // None
  1367. //
  1368. // Output:
  1369. // None. 
  1370. //
  1371. // Remarks:
  1372. // The handler is used for DivX playback only.
  1373. // the routine is handling Subtitles arrived from the Demux task
  1374. static void OnSubtitleArrived(void)
  1375. {
  1376. char Duration[28];
  1377. UINT8 index_duration;
  1378. UINT16 Width,Height,Left,Top,Right,Bottom,FieldOffset,Temp,SP_DCSQT_SA,DCSQ0_SQ_NXT_DCSQ_SA,SPDSize;
  1379. DWORD Chunck_Size,SPB_Pointer,Temp1,Temp2;
  1380. RGB_S ClrBackGround,ClrPattern,ClrEmpasis1,ClrEmpasis2; 
  1381. YUV_S ClrBackGround_yuv,ClrPattern_yuv,ClrEmpasis1_yuv,ClrEmpasis2_yuv; 
  1382. UINT8 i;
  1383. UINT32 UlPts,UlEndPts,UlTempPts,StDataSize,BmpSize,BmpStuffing;
  1384. UINT16 buff_header[4], buff_command[15],t1,t2;
  1385. UINT8 index=0,SPUStuffing,command_size;
  1386.    UINT16 status;
  1387. //    static UINT8 Count = 0;
  1388. #if defined(SDRAM_2X16MBITS) && defined(NEW_2X16M_MAPPING)
  1389. UINT16 uiACBStartAddressAVI,uiSPBStartAddressAVI, uiAPPStartAddressAVI;
  1390. UINT32 SPBStartAddressAVI;
  1391. UINT32 SPBEndAddressAVI;
  1392. #endif
  1393. UINT16 wWindwosWidth, wDiff;
  1394. status = inport(DS2CFIFO_STATUS_ADDR);
  1395. if(status != 31)
  1396. {
  1397. tr_printf(("not all message recievedn"));
  1398. // asm int 3;
  1399. }
  1400. // get Chunck Size
  1401. Temp1 = inport(DS2CFIFO_DATA_ADDR);
  1402. Temp2 = inport(DS2CFIFO_DATA_ADDR);
  1403. Chunck_Size = (Temp1<<16)|(Temp2);
  1404. // get SPB Pointer
  1405. Temp1 = inport(DS2CFIFO_DATA_ADDR);
  1406. Temp2 = inport(DS2CFIFO_DATA_ADDR);
  1407. SPB_Pointer = (Temp1<<16)|(Temp2);
  1408. // printf("SPB_Pointer:%08lxn",SPB_Pointer);
  1409. for(index_duration=0;index_duration<28;index_duration+=2)
  1410. {
  1411. Temp = inport(DS2CFIFO_DATA_ADDR);
  1412. Duration[index_duration] =  (char) (Temp & 0xff);
  1413. Duration[index_duration+1] =  (char) ((Temp & 0xff00)>>8);
  1414. }
  1415. Width = inport(DS2CFIFO_DATA_ADDR);
  1416. Height = inport(DS2CFIFO_DATA_ADDR);
  1417. Left = inport(DS2CFIFO_DATA_ADDR);
  1418. Top = inport(DS2CFIFO_DATA_ADDR);
  1419. Right = inport(DS2CFIFO_DATA_ADDR);
  1420. Bottom = inport(DS2CFIFO_DATA_ADDR);
  1421. // move the subpicture to the center
  1422. wWindwosWidth = Right + Left;
  1423. if (wWindwosWidth < 720)
  1424. {
  1425. wDiff = (720-wWindwosWidth)/2;
  1426. Left += wDiff;
  1427. Right += wDiff;
  1428. }
  1429.     // a hardware bug in I76
  1430.     // When progressive and NTSC->PAL, if SPU start line is multiple of 10, 
  1431.     // the line of two fields are flip.
  1432. if (DEC_IsVideoPal())
  1433. {
  1434.      if (0 == Top%10)
  1435. {
  1436.          Top += 2;
  1437.             Bottom += 2;
  1438. }
  1439. }
  1440.     
  1441. FieldOffset = inport(DS2CFIFO_DATA_ADDR);
  1442. // if(Count==10)
  1443. // {
  1444. // printf("W:%x H:%x L:%x T:%x R:%x B:%x F:%xn",Width,Height,Left,Top,Right,Bottom,FieldOffset);
  1445. // }
  1446. Bottom -=2;
  1447. Temp = inport(DS2CFIFO_DATA_ADDR);
  1448. ClrBackGround.red   = (char) (Temp & 0xff);
  1449. ClrBackGround.green = (char) ((Temp & 0xff00)>>8);
  1450. Temp = inport(DS2CFIFO_DATA_ADDR);
  1451. ClrBackGround.blue  = (char) (Temp & 0xff);
  1452. ClrPattern.red = (char) ((Temp & 0xff00)>>8);
  1453. Temp = inport(DS2CFIFO_DATA_ADDR);
  1454. ClrPattern.green  = (char) (Temp & 0xff);
  1455. ClrPattern.blue   = (char) ((Temp & 0xff00)>>8);
  1456. Temp = inport(DS2CFIFO_DATA_ADDR);
  1457. ClrEmpasis1.red   = (char) (Temp & 0xff);
  1458. ClrEmpasis1.green = (char) ((Temp & 0xff00)>>8);
  1459. Temp = inport(DS2CFIFO_DATA_ADDR);
  1460. ClrEmpasis1.blue  = (char) (Temp & 0xff);
  1461. ClrEmpasis2.red   = (char) ((Temp & 0xff00)>>8);
  1462. Temp = inport(DS2CFIFO_DATA_ADDR);
  1463. ClrEmpasis2.green  = (char) (Temp & 0xff);
  1464. ClrEmpasis2.blue   = (char) ((Temp & 0xff00)>>8);
  1465. if(change_pallet)
  1466. {
  1467. /* SubPicture Reset */
  1468. /* set the SP switch */
  1469. outport(SPSWITCH_ADDR,0x5);
  1470. /* set the SP Scale */
  1471. // The feature subtitle window size is 640x480/720x480
  1472. if (DEC_IsVideoPal())
  1473. {
  1474. I49_ParameterWrite(SPSCALE_ADDR, 0x02); // NTSC->PAL
  1475. }
  1476. else
  1477. {
  1478. I49_ParameterWrite(SPSCALE_ADDR, 0x00);
  1479. }
  1480. change_pallet = FALSE;
  1481. t1 = RGB_2_Y(ClrBackGround.red,ClrBackGround.green,ClrBackGround.blue);//( (  66 * ClrBackGround.red + 129 * ClrBackGround.green +  25 * ClrBackGround.blue + 128) >> 8) +  16;
  1482. ClrBackGround_yuv.Y = t1;
  1483. if(t1 > 235)
  1484. ClrBackGround_yuv.Y = 235;
  1485. if(t1 < 16)
  1486. ClrBackGround_yuv.Y = 16;
  1487. t1 = RGB_2_U(ClrBackGround.red,ClrBackGround.green,ClrBackGround.blue);//( ( -38 * ClrBackGround.red -  74 * ClrBackGround.green + 112 * ClrBackGround.blue + 128) >> 8) + 128;
  1488. ClrBackGround_yuv.U = t1;
  1489. if(t1 > 240)
  1490. ClrBackGround_yuv.U = 240;
  1491. if(t1 < 16)
  1492. ClrBackGround_yuv.U = 16;
  1493. t1 = RGB_2_V(ClrBackGround.red,ClrBackGround.green,ClrBackGround.blue);//( ( 112 * ClrBackGround.red -  94 * ClrBackGround.green -  18 * ClrBackGround.blue + 128) >> 8) + 128;
  1494. ClrBackGround_yuv.V = t1;
  1495. if(t1 > 240)
  1496. ClrBackGround_yuv.V = 240;
  1497. if(t1 < 16)
  1498. ClrBackGround_yuv.V = 16;
  1499. t1 = RGB_2_Y(ClrPattern.red,ClrPattern.green,ClrPattern.blue);
  1500. ClrPattern_yuv.Y = t1;
  1501. if(t1 > 235)
  1502. ClrPattern_yuv.Y = 235;
  1503. if(t1 < 16)
  1504. ClrPattern_yuv.Y = 16;
  1505. t1 = RGB_2_U(ClrPattern.red,ClrPattern.green,ClrPattern.blue);
  1506. ClrPattern_yuv.U = t1;
  1507. if(t1 > 240)
  1508. ClrPattern_yuv.U = 240;
  1509. if(t1 < 16)
  1510. ClrPattern_yuv.U = 16;
  1511. t1 = RGB_2_V(ClrPattern.red,ClrPattern.green,ClrPattern.blue);
  1512. ClrPattern_yuv.V = t1;
  1513. if(t1 > 240)
  1514. ClrPattern_yuv.V = 240;
  1515. if(t1 < 16)
  1516. ClrPattern_yuv.V = 16;
  1517. t1 = RGB_2_Y(ClrEmpasis1.red,ClrEmpasis1.green,ClrEmpasis1.blue);
  1518. ClrEmpasis1_yuv.Y = t1;
  1519. if(t1 > 235)
  1520. ClrEmpasis1_yuv.Y = 235;
  1521. if(t1 < 16)
  1522. ClrEmpasis1_yuv.Y = 16;
  1523. t1 = RGB_2_U(ClrEmpasis1.red,ClrEmpasis1.green,ClrEmpasis1.blue);
  1524. ClrEmpasis1_yuv.U = t1;
  1525. if(t1 > 240)
  1526. ClrEmpasis1_yuv.U = 240;
  1527. if(t1 < 16)
  1528. ClrEmpasis1_yuv.U = 16;
  1529. t1 = RGB_2_V(ClrEmpasis1.red,ClrEmpasis1.green,ClrEmpasis1.blue);
  1530. ClrEmpasis1_yuv.V = t1;
  1531. if(t1 > 240)
  1532. ClrEmpasis1_yuv.V = 240;
  1533. if(t1 < 16)
  1534. ClrEmpasis1_yuv.V = 16;
  1535. t1 = RGB_2_Y(ClrEmpasis2.red,ClrEmpasis2.green,ClrEmpasis2.blue);
  1536. ClrEmpasis2_yuv.Y = t1;
  1537. if(t1 > 235)
  1538. ClrEmpasis2_yuv.Y = 235;
  1539. if(t1 < 16)
  1540. ClrEmpasis2_yuv.Y = 16;
  1541. t1 = RGB_2_U(ClrEmpasis2.red,ClrEmpasis2.green,ClrEmpasis2.blue);
  1542. ClrEmpasis2_yuv.U = t1;
  1543. if(t1 > 240)
  1544. ClrEmpasis2_yuv.U = 240;
  1545. if(t1 < 16)
  1546. ClrEmpasis2_yuv.U = 16;
  1547. t1 = RGB_2_V(ClrEmpasis2.red,ClrEmpasis2.green,ClrEmpasis2.blue);
  1548. ClrEmpasis2_yuv.V = t1;
  1549. if(t1 > 240)
  1550. ClrEmpasis2_yuv.V = 240;
  1551. if(t1 < 16)
  1552. ClrEmpasis2_yuv.V = 16;
  1553.     
  1554. // printf("RGB => BG:%02x%02x%02x PT:%02x%02x%02x E1:%02x%02x%02x E2:%02x%02x%02xn",
  1555. // ClrBackGround.red,ClrBackGround.green,ClrBackGround.blue,
  1556. // ClrPattern.red,ClrPattern.green,ClrPattern.blue,
  1557. // ClrEmpasis1.red,ClrEmpasis1.green,ClrEmpasis1.blue,
  1558. // ClrEmpasis2.red,ClrEmpasis2.green,ClrEmpasis2.blue );
  1559. //
  1560. //    printf("YUV => BG:%02x%02x%02x PT:%02x%02x%02x E1:%02x%02x%02x E2:%02x%02x%02xn",
  1561. // ClrBackGround_yuv.Y,ClrBackGround_yuv.U,ClrBackGround_yuv.V,
  1562. // ClrPattern_yuv.Y,ClrPattern_yuv.U,ClrPattern_yuv.V,
  1563. // ClrEmpasis1_yuv.Y,ClrEmpasis1_yuv.U,ClrEmpasis1_yuv.V,
  1564. // ClrEmpasis2_yuv.Y,ClrEmpasis2_yuv.U,ClrEmpasis2_yuv.V );
  1565. // program the pallet
  1566. outport(SPPALETTE_ADDR,(UINT16)ClrBackGround_yuv.Y);
  1567. outport(SPPALETTE_ADDR,(UINT16)((ClrBackGround_yuv.V<<8) | ClrBackGround_yuv.U));
  1568. outport(SPPALETTE_ADDR,(UINT16)ClrPattern_yuv.Y);
  1569. outport(SPPALETTE_ADDR,(UINT16)((ClrPattern_yuv.V<<8) | ClrPattern_yuv.U));
  1570. outport(SPPALETTE_ADDR,(UINT16)ClrEmpasis1_yuv.Y);
  1571. outport(SPPALETTE_ADDR,(UINT16)((ClrEmpasis1_yuv.V<<8) | ClrEmpasis1_yuv.U));
  1572. outport(SPPALETTE_ADDR,(UINT16)ClrEmpasis2_yuv.Y);
  1573. outport(SPPALETTE_ADDR,(UINT16)((ClrEmpasis2_yuv.V<<8) | ClrEmpasis2_yuv.U));
  1574. // printf("%x ",(UINT16)ClrBackGround_yuv.Y);
  1575. // printf("%x ",(UINT16)ClrBackGround_yuv.Y);
  1576. // empty the other 12
  1577. for(i=0;i<12;i++)
  1578. {
  1579. outport(SPPALETTE_ADDR,0);
  1580. outport(SPPALETTE_ADDR,0);
  1581. }
  1582. }
  1583. FieldOffset += 4;
  1584. // Calculate UlPts
  1585. UlPts  = ((((Duration[1] - '0')*10)+(Duration[2]-'0'))*3600);
  1586. UlPts += ((((Duration[4] - '0')*10)+(Duration[5] - '0'))*60);
  1587. UlPts += (((Duration[7] - '0')*10)+(Duration[8] - '0'));
  1588. UlPts *= 90000;
  1589. UlTempPts = (Duration[10] - '0')*100 + (Duration[11] - '0')*10 + (Duration[12] - '0');
  1590. UlTempPts *= 90;
  1591. UlPts += UlTempPts;
  1592. StDataSize = Chunck_Size -/* FourCCSize - CkSizeSize -*/ DurationSize;
  1593. BmpSize = StDataSize - STDHeaderSize;
  1594. SPUStuffing = BmpSize&1;
  1595. // BmpStuffing = DCSQTSize > (SPUHdrSize + BmpSize + DCSQTSize)/2 ? (DCSQTSize - SPUHdrSize - BmpSize + 1)/2:0;
  1596. // Calculate SPDSize
  1597. SPDSize = SPUHdrSize + BmpSize + /*(BmpStuffing*2) +*/ DCSQTSize + SPUStuffing;
  1598. // Calculate SP_DCSQT_SA
  1599. SP_DCSQT_SA = SPUHdrSize + BmpSize /* + (BmpStuffing*2)*/;
  1600. DCSQ0_SQ_NXT_DCSQ_SA = SP_DCSQT_SA + DCSQ0Size;
  1601. /*
  1602. buff_header[1] = ((UlPts&0xff000000)>>24);
  1603. buff_header[0] = ((UlPts&0x00ff0000)>>16);
  1604. buff_header[3] = ((UlPts&0x0000ff00)>>8);
  1605. buff_header[2] = ((UlPts&0x000000ff));
  1606. //memcpy((void*) buff_header , (void*)(&UlPts), sizeof(UlPts) );
  1607. buff_header[5] = (SPDSize>>8);
  1608. buff_header[4] = (SPDSize&0xFF);
  1609. buff_header[7] = (SP_DCSQT_SA>>8);
  1610. buff_header[6] = (SP_DCSQT_SA&0xFF);
  1611. */
  1612. buff_header[0] = ((UlPts&0xffff0000)>>16);
  1613. buff_header[1] = ((UlPts&0x0000ffff));
  1614. buff_header[2] = SPDSize;
  1615. buff_header[3] = SP_DCSQT_SA;
  1616. if(SPUStuffing)
  1617. {
  1618. // printf("STUFn");
  1619. buff_command[index++] = ((DCSQ0_SQ_NXT_DCSQ_SA&0xff00)>>8);
  1620. buff_command[index++] = (((DCSQ0_SQ_NXT_DCSQ_SA&0xff)<<8)|0x03);
  1621. buff_command[index++] = 0x3210;
  1622. buff_command[index++] = 0x04FF;
  1623. buff_command[index++] = 0xF005;
  1624. t1 = ((Left&0x03ff)<<4);
  1625. t2 = ((Right&0x300)>>8);
  1626. buff_command[index++]  = t1 | t2;//0x0a02;//(((Left&0x03ff)<<4)   | ((Right&0x300)>>8));
  1627. // printf("L:%04x R:%04x b:%04xn",t1,t2,buff_command[index-1]);
  1628. // printf("L:%x R:%xn",((Left&0x03ff)<<4),((Right&0x300)>>8));
  1629. buff_command[index++]  = (((Right&0xff)<<8) | ((Top&0x3f0)>>4));
  1630. buff_command[index++]  = (((Top&0xe)<<12)    | (Bottom&0x3ff));
  1631. // if(Count==10)
  1632. // {
  1633. // printf("b1:%04x %04x %04x ",buff_command[index-3],buff_command[index-2],buff_command[index-1]);
  1634. // }
  1635. // if(!(Top&0x1))
  1636. // {
  1637. buff_command[index++] = 0x0600;
  1638. buff_command[index++] = ((0x0400) | ((FieldOffset&0xff00)>>8));
  1639. buff_command[index++] = ((FieldOffset&0xff)<<8);
  1640. /* }
  1641. else
  1642. {
  1643. buff_command[index++] = ((0x0600) |((FieldOffset&0xff00)>>8));
  1644. buff_command[index++] = ((FieldOffset&0xff) | (0x00)); 
  1645. buff_command[index++] = 0x0400;
  1646. }
  1647. */
  1648. UlEndPts  = ((((Duration[14] - '0')*10)+(Duration[15] - '0'))*3600);
  1649. UlEndPts += ((((Duration[17] - '0')*10)+(Duration[18] - '0'))*60);
  1650. UlEndPts += (((Duration[20] - '0')*10)+(Duration[21] - '0'));
  1651. UlEndPts *= 90000;
  1652. UlTempPts = (Duration[23] - '0')*100 + (Duration[24] - '0')*10 + (Duration[25] - '0');
  1653. UlTempPts *= 90;
  1654. UlEndPts += UlTempPts;
  1655. UlTempPts = ((UlEndPts - UlPts)>>10);
  1656. buff_command[index++] = ((0xFF00) | ((UlTempPts&0xff00)>>8));
  1657. buff_command[index++] = (((UlTempPts&0x00ff)<<8)| ((DCSQ0_SQ_NXT_DCSQ_SA&0xFF00)>>8));
  1658. buff_command[index++] = (((DCSQ0_SQ_NXT_DCSQ_SA&0x00FF)<<8) | (0x0002));
  1659. buff_command[index++] = 0xFFFF;
  1660. }
  1661. else
  1662. {
  1663. // printf("STUF!!n");
  1664. buff_command[index++] = 0x0000;
  1665. buff_command[index++] = DCSQ0_SQ_NXT_DCSQ_SA;
  1666. buff_command[index++] = 0x0332;
  1667. buff_command[index++] = 0x1004;
  1668. // Contrast
  1669. buff_command[index++] = 0xFFF0;   
  1670. buff_command[index++] = ((0x0500) | ((Left&0x3f0)>>4));
  1671. buff_command[index++] = (((Left&0xf)<<12) | (Right&0x3ff));
  1672. buff_command[index++] = (((Top&0x3fe)<<4) | ((Bottom&0x300)>>8));
  1673. buff_command[index++] = (((Bottom&0xff)<<8) | 0x0006) ;
  1674. // if(Count==10)
  1675. // {
  1676. // printf("b1:%04x %04x %04x %04x",buff_command[index-4],buff_command[index-3],buff_command[index-2],buff_command[index-1]);
  1677. // }
  1678. // if(Top&0x1)
  1679. // {
  1680. buff_command[index++] = 0x0004;
  1681. buff_command[index++] = FieldOffset;
  1682. /* }
  1683. else
  1684. {
  1685. buff_command[index++] = FieldOffset;
  1686. buff_command[index++] = 0x0004;
  1687. }
  1688. */
  1689. buff_command[index++] = 0x00FF;
  1690. UlEndPts  = ((((Duration[14] - '0')*10)+(Duration[15] - '0'))*3600);
  1691. UlEndPts += ((((Duration[17] - '0')*10)+(Duration[18] - '0'))*60);
  1692. UlEndPts += (((Duration[20] - '0')*10)+(Duration[21] - '0'));
  1693. UlEndPts *= 90000;
  1694. UlTempPts = (Duration[23] - '0')*100 + (Duration[24] - '0')*10 + (Duration[25] - '0');
  1695. UlTempPts *= 90;
  1696. UlEndPts += UlTempPts;
  1697. UlTempPts = ((UlEndPts - UlPts)>>10);
  1698. buff_command[index++] = (UlTempPts&0xFFFF);
  1699. buff_command[index++] = DCSQ0_SQ_NXT_DCSQ_SA;
  1700. buff_command[index++] = 0x02FF;
  1701. }
  1702. #if defined(SDRAM_2X16MBITS) && defined(NEW_2X16M_MAPPING)
  1703. // MPEG4Clip_dynamic_malloc(&uiACBStartAddressAVI, &uiSPBStartAddressAVI, &uiAPPStartAddressAVI);
  1704. UlTempPts = _mpeg4InternalSubtitleBufferStartAddr;
  1705. SPBStartAddressAVI = _mpeg4InternalSubtitleBufferStartAddr * 512UL; 
  1706. SPBEndAddressAVI = (_mpeg4InternalSubtitleBufferStartAddr + SPB_SIZE_AVI) * 512UL;
  1707. #else
  1708. UlTempPts = (OSD_BUFFER_SIZE_AVI + VCB_SIZE_AVI + ACB_SIZE_AVI);
  1709. #endif
  1710. UlTempPts *= 512UL;
  1711. UlTempPts += (SPB_Pointer/2);
  1712. #if 0
  1713. {
  1714. int i;
  1715. for(i=0;i<SPU_HEADER_LENGTH;i++)
  1716. {
  1717. printf("%04x ",buff_header[i]);
  1718. }
  1719. printf("n");
  1720. for(i=0;i<SPU_COMMAND_LENGTH;i++)
  1721. {
  1722. printf("%04x ",buff_command[i]);
  1723. }
  1724. printf("n");
  1725. }
  1726. #endif
  1727. // SRkeep = InterruptDisable();
  1728. // semaphore_set(SEM_DRAM);
  1729. // printf("SPB_Pointer:%08lx ",UlTempPts);
  1730. #if defined(SDRAM_2X16MBITS) && defined(NEW_2X16M_MAPPING)
  1731. CyclicWriteDRAMData(SPBStartAddressAVI,SPBEndAddressAVI,
  1732. UlTempPts,(UINT16*)buff_header, SPU_HEADER_LENGTH);
  1733. #else
  1734. CyclicWriteDRAMData(SPB_START_AVI,SPB_END_AVI,
  1735.                         UlTempPts,(UINT16*)buff_header, SPU_HEADER_LENGTH);
  1736. #endif
  1737. // I49_WriteDRAMDataNSW(UlTempPts,(UINT16*)buff_header, SPU_HEADER_LENGTH);
  1738. if(SPUStuffing)
  1739. {
  1740. UlTempPts += (SPU_HEADER_LENGTH + ((BmpSize+1)/2));
  1741. }
  1742. else
  1743. {
  1744. UlTempPts += (SPU_HEADER_LENGTH + (BmpSize/2));
  1745. }
  1746. // printf("%08lx n",UlTempPts);
  1747. #if (defined(SDRAM_2X16MBITS) && defined(NEW_2X16M_MAPPING))
  1748. CyclicWriteDRAMData(SPBStartAddressAVI,SPBEndAddressAVI,
  1749. UlTempPts,(UINT16*)buff_command, SPU_COMMAND_LENGTH);
  1750. #else
  1751. CyclicWriteDRAMData(SPB_START_AVI,SPB_END_AVI,
  1752.                         UlTempPts,(UINT16*)buff_command, SPU_COMMAND_LENGTH);
  1753. #endif
  1754. // I49_WriteDRAMDataNSW(UlTempPts, (UINT16*)buff_command, SPU_COMMAND_LENGTH);
  1755. // semaphore_clear(SEM_DRAM);
  1756. // Count++;
  1757. // printf("C:%d",Count++);
  1758. outport(SPD_INCREMENT_ADDR,0x1);
  1759. }
  1760. /////////////////////////////////////////////////////////////////////////////////////////////////
  1761. // void OnDemuxFinished() -
  1762. // Handles an IE_CORE_DEMUX_FINISHED Event.
  1763. //
  1764. // Input:
  1765. // None
  1766. //
  1767. // Output:
  1768. // None. The playback is skipped to the nex/previous I frame.
  1769. //
  1770. // Remarks:
  1771. // The handler is used for DivX playback only.
  1772. // In case the demux reached the end sector, the DivX navigator is notified and request the
  1773. // next/previous I frame according to the index table.
  1774. static void OnDemuxFinished(void)
  1775. {
  1776. const ClipInfoEx *pCurrClip = &(SHARED_INFO).cieCurrClip;
  1777. /* Make sure we are in scanning mode */
  1778. if ( ((PST_SCAN != gcs.pstate) || (0 == gns.clips.iScanSpeed))
  1779.  && (PST_SLOW != gcs.pstate) )
  1780. {
  1781. dbg_printf(("Scanning cancelled. Ignored.n"));
  1782. return;
  1783. }
  1784. /* Make sure we are playing MPEG4 file */
  1785. if ( ((enClipType)pCurrClip->ciInfo.eType != eClipType_AVI) 
  1786. #ifdef IS_ASF_CAPABLE
  1787. && ((enClipType)pCurrClip->ciInfo.eType != eClipType_ASF)
  1788. #endif
  1789. #ifdef IS_MP4_CAPABLE
  1790. && ((enClipType)pCurrClip->ciInfo.eType != eClipType_MP4)
  1791. #endif
  1792. )
  1793. {
  1794. return;
  1795. }
  1796. Clip_continueScanning();
  1797. }
  1798. /////////////////////////////////////////////////////////////////////////////////////////////////
  1799. // void OnIFrameDisplayed() -
  1800. // Handles an IE_CORE_I_FRAME Event.
  1801. //
  1802. // Input:
  1803. // None
  1804. //
  1805. // Output:
  1806. // None. The playback is skipped forward/backwards in order to seek and present the next
  1807. // I-Frame.
  1808. //
  1809. // Remarks:
  1810. // The handler checks the direction of the current Scan.
  1811. // In case of a forward scan, the current playback is halted and restarted from a position
  1812. // further down the stream.
  1813. // In the case of a backwards scan, the current playback is halted and restarted from a 
  1814. // position preceding the current one.
  1815. // In both cases, if the next position is outside the boundaries of the current Playing-Segment,
  1816. // the appropriate action is performed; i.e.: the next item (in forward scan) or the previous
  1817. // item (in backwards scan) is invoked.
  1818. static void OnIFrameDisplayed(void)
  1819. {
  1820. DWORD dwCurrLocation= -1;
  1821. DWORD dwNextLocation;
  1822. BOOL bLocationFromDriveValid;
  1823. DWORD dwClipStartAddress, dwClipEndAddress;
  1824. dbg_printf(("OnIFrameDisplayed()n"));
  1825. SET_COP_MASK(COP_SCAN);
  1826. // Make sure that Scanning is still active
  1827. if ( ((PST_SCAN != gcs.pstate) || (0 == gns.clips.iScanSpeed))
  1828. &&(PST_SLOW != gcs.pstate) )
  1829. {
  1830. dbg_printf(("Scanning cancelled. Ignored.n"));
  1831. dwCurrLocation= -1; // Reset the Scan position
  1832. return;
  1833. }
  1834. dwClipStartAddress = (DWORD)gns.clips.cieCurrClip.ciInfo.dwFileLocation;
  1835. dwClipEndAddress = (DWORD)(gns.clips.cieCurrClip.ciInfo.cbFileSize >> 11) + 1 + dwClipStartAddress;
  1836. if(gns.clips.iScanSpeed < 0)
  1837. dwCurrLocation = CurrLocationBackup;
  1838. else
  1839. dwCurrLocation = PE_Clips_GetCurrLocation();
  1840. // Abort the current Playback, without changing Decoder mode
  1841. PE_CD_AbortPlayback(TRUE);
  1842. // Calculate the Next target location; avoid slipping over the edge
  1843. if (gns.clips.iScanSpeed != 0)
  1844. {
  1845. dwNextLocation= (dwCurrLocation + (gns.clips.iScanSpeed * CLIPS_MPEG_NUM_OF_SECTORES_PER_SECOND));
  1846. }
  1847. else if (gns.clips.iSlowSpeed != 0)
  1848. {
  1849. dwNextLocation= (dwCurrLocation + (gns.clips.iSlowSpeed * CLIPS_MPEG_NUM_OF_SECTORES_PER_SECOND));
  1850. }
  1851. if ((INT32)dwNextLocation < 0)
  1852. dwNextLocation= 0;
  1853. // Check the Scanning-direction, and act accordingly
  1854. if (gns.clips.iScanSpeed > 0) {
  1855. if (dwNextLocation < dwClipEndAddress ) {
  1856. // The next sub-segment to skip to is within the boundaries of the current segment
  1857. dwCurrLocation= dwNextLocation;
  1858. }
  1859. else {
  1860. //<<<angieh_0412_2004:Don't reset the state it will be used when compute the next track.
  1861. //gcs.pstate = PST_PLAY;
  1862. //gns.clips.iScanSpeed = 0;
  1863. //angieh_0412_2004>>>
  1864. PE_CD_CancelNotification(IFrame);
  1865. ie_send(IE_CORE_CDNAV_FINISHED);
  1866. return;
  1867. }
  1868. }
  1869. else if ( ( gns.clips.iScanSpeed < 0 ) || ( gns.clips.iSlowSpeed < 0 )){
  1870. // Continue Scanning
  1871. if (dwNextLocation > dwClipStartAddress ) {
  1872. // The previous sub-segment to skip to is within the boundaries of the current segment
  1873. dwCurrLocation= dwNextLocation;
  1874. }
  1875. else {
  1876. //<<<angieh_0412_2004:Don't reset the state it will be used when compute the next track.
  1877. //gcs.pstate = PST_PLAY;
  1878. //gns.clips.iScanSpeed = 0;
  1879. //gns.clips.iSlowSpeed = 0;
  1880. //angieh_0412_2004>>>
  1881. PE_CD_CancelNotification(IFrame);
  1882. ie_send(IE_CORE_CDNAV_FINISHED);
  1883. return;
  1884. }
  1885. }
  1886. if (gns.clips.iScanSpeed != 0)
  1887. gcs.pstate= PST_SCAN;
  1888. else{
  1889. if (gns.clips.iSlowSpeed != 0)
  1890. gcs.pstate= PST_SLOW;
  1891. }
  1892. // Arrange for an additional I-Frame notification
  1893. PE_CD_RequestNotification(IFrame);
  1894. // Engage the Error-Recovery mehcanism for I-Frame Display Miss
  1895. (g_pClipsNav->m_ErrorRecoveryInfo).uRetryCount= CLIPS_ERROR_RECOVERY_RETRY_COUNT;
  1896. // Invoke playback of the next sub-segment within the current segment
  1897. if ( (gns.clips.iScanSpeed != 0) || (gns.clips.iSlowSpeed != 0) ){
  1898. // UINT16 uTime = PE_Clips_GetClock(); //SUPPORT_FLASH_CARD
  1899. // DEC_SetDiskType(i_pThis->m_pConstAttr)->m_eBitstreamType);
  1900. // Prepare for decoding
  1901. DEC_prepare_to_decode();
  1902. DEC_SetSID(DEC_SID_TYPE_AUDIO, NoAudio);
  1903. DEC_SetSID(DEC_SID_TYPE_VIDEO, 0xE0);
  1904. // Inform the Decoder of the Playback-Range
  1905. PE_Clips_SetPlaybackRange(dwCurrLocation, dwClipEndAddress - dwCurrLocation, UNLIMITED_FILE_SIZE);
  1906. if(gns.clips.iScanSpeed < 0)
  1907. CurrLocationBackup = dwCurrLocation;
  1908. else
  1909. CurrLocationBackup = -1;
  1910. // Invoke playback of the Decoder & Drive
  1911. // NOTE: The order of invocation is important, and must not be changed!
  1912. DEC_PlaybackCommand(DEC_PLAYBACK_CMD_REF_FRAME_ONLY, NULL);//jeanz_0319_2005 Reset right command
  1913. //LX051703: Add AV Data mode for Play CD
  1914. if (!PE_Clips_Playback_Sectors(DRVCF_CDSPEED_1X | DRVF_PLAY_CD_AV_DATA, dwCurrLocation, dwClipEndAddress - dwCurrLocation )) {
  1915. dbg_printf(("WARNING: GenericClip_play() Failed [1]n"));
  1916. return FALSE;
  1917. }
  1918. }
  1919. return;
  1920. }
  1921. /////////////////////////////////////////////////////////////////////////////////////////////////
  1922. // void OnStep() -
  1923. // Handels an IE_CORE_STEP Event.
  1924. //
  1925. // Input:
  1926. // None
  1927. //
  1928. // Output:
  1929. // The appropriate PE method is called to step forward.
  1930. static void OnStep(void)
  1931. {
  1932. UINT16 hClipInstance;
  1933. hClipInstance= ClipsRepository_getInstanceAt(SHARED_INFO.uCurrentClipNumber-1);
  1934. if ( NULL == hClipInstance )
  1935. return;
  1936. dbg_printf(("OnStep()n"));
  1937. if ( !Clip_hasAttribute(hClipInstance, eCA_Slowable)){
  1938. dbg_printf(("Step Foward not supportedn"));
  1939. }
  1940. if (PST_PAUSE != gcs.pstate) {
  1941. dbg_printf(("Step is illegal when not Pausing. Ignored.n"));
  1942. return;
  1943. }
  1944. // Cancel Intro Playmode
  1945. gns.clips.bIsIntroPlayMode = FALSE;
  1946. PE_CD_Step();
  1947. return;
  1948. }
  1949. /////////////////////////////////////////////////////////////////////////////////////////////////
  1950. // void OnDriveError(void) -
  1951. // Handles an IE_CORE_DRIVE_READ_FAIL Event.
  1952. //
  1953. // Input:
  1954. // None.
  1955. //
  1956. // Output:
  1957. // None.
  1958. //
  1959. // Remarks:
  1960. // The function is activated to perform error handling for the clip resulting from 
  1961. // drive errors. Currently only for DivX.
  1962. static void OnDriveError(void)
  1963. {
  1964. UINT16 hClipInstance = ClipsRepository_getInstanceAt(SHARED_INFO.uCurrentClipNumber-1);
  1965. Clip_performErrorHandling(hClipInstance);
  1966. }
  1967. /////////////////////////////////////////////////////////////////////////////////////////////////
  1968. // void OnDemuxError(void) -
  1969. // Handles an IE_CORE_DEMUX_ERROR Event.
  1970. //
  1971. // Input:
  1972. // None.
  1973. //
  1974. // Output:
  1975. // None.
  1976. //
  1977. // Remarks:
  1978. // The function is activated to perform error handling for the clip resulting from 
  1979. // DEMUX-CPU communication errors. Currently only for DivX.
  1980. static void OnDemuxError(void)
  1981. {
  1982. UINT16 hClipInstance = ClipsRepository_getInstanceAt(SHARED_INFO.uCurrentClipNumber-1);
  1983. Clip_performErrorHandling(hClipInstance);
  1984. }
  1985. /////////////////////////////////////////////////////////////////////////////////////////////////
  1986. // void OnSlow(int iSpeed) -
  1987. // Handles an IE_CORE_SLOW Event.
  1988. //
  1989. // Input:
  1990. // iSpeed - Holds the requested Slow-Motion speed.
  1991. //
  1992. // Output:
  1993. // None. Slow forward is started, if possible.
  1994. //
  1995. // Remarks:
  1996. // Requests a Slow-Motion from the PE.
  1997. static void OnSlow(int iSpeed)
  1998. {
  1999. dbg_printf(("OnSlow(%d)n", iSpeed));
  2000. if (PST_STOP == gcs.pstate) {
  2001. dbg_printf(("Cannot slow forward during a stop. Ignored.n"));
  2002. return;
  2003. }
  2004. // Cancel Intro Playmode
  2005. gns.clips.bIsIntroPlayMode = FALSE;
  2006. if (IS_CLIPS_TYPE_MPEG4)
  2007. {
  2008. if (PST_PAUSE == gcs.pstate)
  2009. _bMPEG4PauseToSlow = TRUE;
  2010. else
  2011. _bMPEG4PauseToSlow = FALSE;
  2012. }
  2013. // Eliminate current Scanning
  2014. if ( (PST_SCAN == gcs.pstate) || ( ( PST_SLOW == gcs.pstate) && ( gns.clips.iSlowSpeed < 0 ) ) )
  2015. {
  2016. OnScan(0);
  2017. gcs.pstate= PST_PLAY;
  2018. }
  2019. // First of all, resume Normal-Playback, if in Stop or Pause (essential for Slow-Motion),
  2020. // or if Scanning is being eliminated.
  2021. if ((PST_STOP == gcs.pstate) || (PST_PAUSE == gcs.pstate) || (0 == iSpeed))
  2022. PE_CD_SetSlowMotion(FALSE, 0);
  2023. // Now actually invoke Slow-Motion, if necessary
  2024. if (0 != iSpeed) {
  2025. if (iSpeed > 0) {
  2026. PE_CD_SetSlowMotion(TRUE, (UINT8)iSpeed);
  2027. PE_CD_CancelNotification(IFrame);
  2028. gcs.pstate= PST_SLOW;
  2029. }
  2030. else {
  2031. iSpeed = ((int)(iSpeed) + 9)*(-1);
  2032. //This routine is like OnScan, we separate it with OnScan is becasue we don't want the gcs.pstate to be confused
  2033. PE_CD_RequestNotification(IFrame);
  2034. //cancel Trigger Bit notification
  2035. PE_CD_CancelNotification(TriggerBit);
  2036. #ifdef SUPPORT_FLASH_CARD
  2037. if(IS_PLAYING_CARD)
  2038. drv_suspend_playback(TRUE);
  2039. #endif
  2040. PE_CD_SetScan(TRUE, NoAudio, iSpeed);
  2041. #ifdef SUPPORT_FLASH_CARD
  2042. if(IS_PLAYING_CARD)
  2043. drv_suspend_playback(FALSE);
  2044. #endif
  2045. gcs.pstate = PST_SLOW;
  2046. }
  2047. }
  2048. gns.clips.iSlowSpeed= iSpeed;
  2049. if (IS_CLIPS_TYPE_MPEG4)
  2050. {
  2051. _bMPEG4PauseToSlow = FALSE;
  2052. }
  2053. return;
  2054. }
  2055. #ifdef _DEBUG
  2056. static void OnStatusReport()
  2057. {
  2058. const ClipInfoEx *pCurrClip= &(SHARED_INFO).cieCurrClip;
  2059. WCHAR szTempDirectoryName[SC_CLIPS_CURRENT_DIRECTORY_SZ*2];
  2060. WCHAR szTempFilename[SC_CLIPS_CURRENT_FILENAME_SZ*2];
  2061. tr_printf(("Status Report for Clips-Navigatorn"));
  2062. tr_printf(("tTotal number of items on Playlist: %dn", (int)(PM_GetProgramSize()-1)));
  2063. tr_printf(("tCurrent Playlist item: %dn", (int)SHARED_INFO.uCurrPlaylistItem));
  2064. tr_printf(("tClip No. %d.n", SHARED_INFO.uCurrentClipNumber));
  2065. // tr_printf(("tClip-Path: %sn", DBG_W2A(pCurrClip->ciInfo.szDirectoryName)));
  2066. // tr_printf(("tClip-name: %sn", DBG_W2A(pCurrClip->ciInfo.szFilename)));
  2067. sc_GetBytes(SC_CLIPS_CURRENT_DIRECTORY_ADDR, (WORD)0, (WORD)(SC_CLIPS_CURRENT_DIRECTORY_SZ*4), (BYTE*)szTempDirectoryName);
  2068. sc_GetBytes(SC_CLIPS_CURRENT_FILENAME_ADDR, (WORD)0, (WORD)(SC_CLIPS_CURRENT_FILENAME_SZ*4), (BYTE*)szTempFilename);
  2069. tr_printf(("tClip-Path: %sn", DBG_W2A(szTempDirectoryName)));
  2070. tr_printf(("tClip-name: %sn", DBG_W2A(szTempFilename)));
  2071. if (! (SHARED_INFO.cieCurrClip).bIsExtendedInfoAvailable) {
  2072. tr_printf(("No Extended Information available.n"));
  2073. return;
  2074. }
  2075. #ifdef CLIPS_ACQUIRE_EXTENDED_INFO
  2076. // tr_printf(("tPlayback-Time: %d Seconds.n", pCurrClip->uPlaybackTime));
  2077. switch ((enClipType)pCurrClip->ciInfo.eType)
  2078. {
  2079. case eClipType_MP3:
  2080. {
  2081. //Angie_0810_2004:Move the MP3 and WMA extend info from gns to SCPAD for I86 memory reducing.
  2082. MP3_ID3v1Tag id3Tag;
  2083. printf("tClip-Type: MP3n");
  2084. #ifdef CLIPS_MP3_EXTRACT_ID3V1_TAG
  2085. sc_GetBytes(gns.clips.cieCurrClip.ExtInfo_sc_handle, 0, sizeof(MP3_ID3v1Tag), (BYTE *)&id3Tag);
  2086. printf("tTitle: %sn", DBG_W2A(id3Tag.szSongName));
  2087. printf("tArtist: %sn", DBG_W2A(id3Tag.szArtist));
  2088. printf("tAlbum: %sn", DBG_W2A(id3Tag.szAlbum));
  2089. printf("tYear: %sn", DBG_W2A(id3Tag.szYear));
  2090. printf("tGenre: %sn", DBG_W2A(id3Tag.pszGenre));
  2091. printf("tTrack-Num: %dn", id3Tag.uTrackNum);
  2092. printf("tComment: %sn", DBG_W2A(id3Tag.szComment));
  2093. #endif //CLIPS_MP3_EXTRACT_ID3V1_TAG
  2094. }
  2095. break;
  2096. case eClipType_WMA:
  2097. {
  2098. //Angie_0810_2004:Move the MP3 and WMA extend info from gns to SCPAD for I86 memory reducing.
  2099. WMA_ExtendInfo wmaContentDesc;
  2100. printf("tClip-Type: MP3n");
  2101. #ifdef CLIPS_WMA_EXTRACT_CONTENT_DESC
  2102. sc_GetBytes(gns.clips.cieCurrClip.ExtInfo_sc_handle, 0, sizeof(WMA_ExtendInfo), (BYTE *)&wmaContentDesc);
  2103. printf("tTitle: %sn", DBG_W2A(wmaContentDesc.szTitle));
  2104. printf("tAuthor: %sn", DBG_W2A(wmaContentDesc.szAuthor));
  2105. printf("tCopyright: %sn", DBG_W2A(wmaContentDesc.szCopyright));
  2106. printf("tDescription: %sn", DBG_W2A(wmaContentDesc.szDescription));
  2107. #endif //CLIPS_WMA_EXTRACT_CONTENT_DESC
  2108. }
  2109. break;
  2110. case eClipType_JPEG:
  2111. {
  2112. printf("tClips-Type: JPEGn");
  2113. }
  2114. break;
  2115. default:
  2116. break;
  2117. }
  2118. #endif //CLIPS_ACQUIRE_EXTENDED_INFO
  2119. return;
  2120. }
  2121. #endif //_DEBUG
  2122. static BOOL Browser_Construct(void)
  2123. {
  2124. UINT32 dwRepositoryAddress= (UINT32)SC_CLIPSDIR1_LIST_ADDRESS;
  2125. // Dynamically allocate an Array for Peer Directories found
  2126. SHARED_INFO.hDirsArray[0] = Array_constructEx(MAX_SUBDIRS_CNT, 2 * (1+MAX_DIRNAME_LEN), &dwRepositoryAddress); //jerry cai todo: should be 2 * (1+MAX_DIRNAME_LEN)
  2127. if (NULL == SHARED_INFO.hDirsArray[0]) 
  2128. {
  2129. tr_printf(("FATAL: Clips_construct() Failed [3]: Low system resourcesn"));
  2130. return FALSE;
  2131. }
  2132. #ifdef MANUAL_DIRECTORY_EXPLORER
  2133. dwRepositoryAddress= (UINT32)SC_CLIPSDIR2_LIST_ADDRESS;
  2134. // Dynamically allocate an Array for Sub-Directories found
  2135. SHARED_INFO.hDirsArray[1] = Array_constructEx(MAX_SUBDIRS_CNT, 2 * (1+MAX_DIRNAME_LEN), &dwRepositoryAddress); //jerry cai todo: should be 2 * (1+MAX_DIRNAME_LEN)
  2136. if (NULL == SHARED_INFO.hDirsArray[1])
  2137. {
  2138. tr_printf(("FATAL: Clips_construct() Failed [4]: Low system resourcesn"));
  2139. return FALSE;
  2140. }
  2141. Browser_InitArrays();
  2142. #endif
  2143. return TRUE;
  2144. }
  2145. static void Browser_Destruct(void)
  2146. {
  2147. Array_clear(SHARED_INFO.hDirsArray[0]);
  2148. Array_destruct(SHARED_INFO.hDirsArray[0]);
  2149. #ifdef MANUAL_DIRECTORY_EXPLORER
  2150. Array_clear(SHARED_INFO.hDirsArray[1]);
  2151. Array_destruct(SHARED_INFO.hDirsArray[1]);
  2152. #endif
  2153. }
  2154. #ifdef MANUAL_DIRECTORY_EXPLORER
  2155. static void Browser_InitArrays(void)
  2156. {
  2157. CLIPS_PEER_ARRAY = 0;
  2158. SHARED_INFO.uPeerDirCount= 0;
  2159. SHARED_INFO.uSubDirCount= 0;
  2160. }
  2161. /*
  2162. when go ing to sub directory, the old subDir becomes peerDir,
  2163. The new subDir will be rebuilt.
  2164. Out: previous SubDirArray is now PeerDirArray.
  2165. SHARED_INFO.uPeerDirCount is updated also.
  2166. */
  2167. static void Browser_SwitchArrays(void)
  2168. {
  2169. CLIPS_PEER_ARRAY = 1 - CLIPS_PEER_ARRAY;
  2170. SHARED_INFO.uPeerDirCount= PEER_DIR_ARRAY_SIZE;
  2171. }
  2172. /*
  2173. remove the entries of the array
  2174. */
  2175. static void Browser_ResetPeerFoldersArray(void)
  2176. {
  2177. ArrayInitBound(SHARED_INFO.hDirsArray[CLIPS_PEER_ARRAY], 0);
  2178. SHARED_INFO.uPeerDirCount= 0;
  2179. }
  2180. /*
  2181. remove the entries of the array
  2182. */
  2183. static void Browser_ResetSubFoldersArray(void)
  2184. {
  2185. ArrayInitBound(SHARED_INFO.hDirsArray[CLIPS_SUB_ARRAY], 0);
  2186. SHARED_INFO.uSubDirCount= 0;
  2187. }
  2188. /*
  2189. Author: Jerry CAI
  2190. Feb 24, 2003
  2191. Desp: This function builds a list of the directories that are peers of the working folder.
  2192. Caller: It's called when the smart navigator enters parent directory. 
  2193. In: Suppose the working folder is in the right window(this is the default state).
  2194. Out:PeerDir list is updated.
  2195. SHARED_INFO.uCurrentDir is updated also.
  2196.  
  2197. */
  2198. static BOOL Browser_BuildPeerFoldersList(UINT16 uMaxDirsToFind)
  2199. {
  2200. BOOL bSearchAborted;
  2201. UINT16 hFindFile;
  2202. FindData *pFileInfo;
  2203. UINT16 hInstance;
  2204. LPWSTR pszWorkingFolderName = NULL;
  2205. SHARED_INFO.uCurrentDir = 1;
  2206. // Allocate a FindData structure
  2207. pFileInfo= (FindData*)malloc(sizeof(FindData));
  2208. if (NULL == pFileInfo)
  2209. {
  2210. tr_printf(("FATAL: Browser_BuildPeerFoldersList() Failed [2]: Low system resourcesn"));
  2211. return FALSE;
  2212. }
  2213. Browser_ResetPeerFoldersArray();
  2214. //working folder is root 
  2215. if(TRUE == FileSys_InRootDir())
  2216. {
  2217. hInstance = 1;
  2218. wcscpy(&pFileInfo->szFileID[0], L"ROOT");
  2219. // Enqueue the Directory found
  2220. if (! Array_setAt(SHARED_INFO.hDirsArray[CLIPS_PEER_ARRAY], hInstance - 1,
  2221.   (const BYTE*)pFileInfo->szFileID))
  2222. {
  2223. tr_printf(("WARNING: _findAndAddClips() Failed [3]n"));
  2224. }
  2225. SHARED_INFO.uPeerDirCount= 1;
  2226. if(pFileInfo)
  2227. free(pFileInfo);
  2228. return;
  2229. }
  2230. pszWorkingFolderName = (LPWSTR)malloc((1 + MAX_DIRNAME_LEN) * sizeof(WCHAR));
  2231. if (NULL == pszWorkingFolderName) 
  2232. {
  2233. tr_printf(("FATAL: Browser_BuildPeerFoldersList() Failed [2]: Low system resources.n"));
  2234. return FALSE;
  2235. }
  2236. //Get the working folder's name.
  2237. {
  2238. LPWSTR pszDelim;
  2239. WCHAR currPath[MAX_PATH];
  2240. // Copy the Directory-Name
  2241. FileSys_getCurrentPath(currPath);
  2242. pszDelim= wcsrchr(currPath, FileSys_getPathDelimiter());
  2243. if (NULL != pszDelim)
  2244. pszDelim++;
  2245. else
  2246. pszDelim= currPath;//(LPWSTR)FileSys_getCurrentPath();
  2247. wcsncpy(pszWorkingFolderName, pszDelim, MAX_DIRNAME_LEN);
  2248. }
  2249. //Set the working folder to be in the left window.
  2250. FileSys_goUp();
  2251. // Start scanning the Current Directory
  2252. hFindFile= FileSys_findFirstFile(FILESYS_WILDCARD_SEARCH, pFileInfo);
  2253. if (NULL == hFindFile)
  2254.  {
  2255. if(NULL != pszWorkingFolderName)
  2256. free(pszWorkingFolderName);
  2257. free(pFileInfo);
  2258. return FALSE;
  2259.  }
  2260. // Start scanning the Current-Directory
  2261. bSearchAborted= FALSE;
  2262. do {
  2263. // If an Exception was thrown, abort the search
  2264. if (Exception_catchAndRethrow(EXCEPTION_MEDIUM_EJECTED)) {
  2265. tr_printf(("EXCEPTION: Browser_BuildPeerFoldersList() Aborting [2]n"));
  2266. bSearchAborted= TRUE;
  2267. break;
  2268. }
  2269. // Verify that there is vacancy in the Clips-Repository
  2270. if (uMaxDirsToFind == PEER_DIR_ARRAY_SIZE)
  2271. break;
  2272. // Check the Type of File found
  2273. if (FILETYPE_VOLUME == pFileInfo->uFileType) 
  2274. {
  2275.   //do nothing.
  2276. }
  2277. else
  2278. if (FILETYPE_DIRECTORY == pFileInfo->uFileType)
  2279.  {
  2280. hInstance= 1 + PEER_DIR_ARRAY_SIZE;
  2281. // Skip the Current directories
  2282. if (0x00 == pFileInfo->szFileID[0] || 0 == wcscmp(pFileInfo->szFileID, L"."))
  2283. continue;
  2284. //parent directory
  2285. if( (0x01 == pFileInfo->szFileID[0]) || 0 == wcscmp(pFileInfo->szFileID, L".."))
  2286. {
  2287. WCHAR currPath[MAX_PATH];
  2288. FileSys_getCurrentPath(currPath);
  2289. if( currPath[0] == 0)
  2290. wcscpy(&pFileInfo->szFileID[0], L"ROOT");
  2291. else
  2292. wcscpy(&pFileInfo->szFileID[0], L"..");
  2293. }
  2294. //update current dir.
  2295. if (0 == wcsncmp(pFileInfo->szFileID, pszWorkingFolderName, MAX_DIRNAME_LEN))
  2296. SHARED_INFO.uCurrentDir = hInstance;
  2297. // Enqueue the Directory found, for later use
  2298. if (! Array_setAt(SHARED_INFO.hDirsArray[CLIPS_PEER_ARRAY], hInstance - 1,
  2299.   (const BYTE*)pFileInfo->szFileID))
  2300. {
  2301. tr_printf(("WARNING: _findAndAddClips() Failed [3]n"));
  2302. break;
  2303. }
  2304. }
  2305. } while (FileSys_findNextFile(hFindFile, pFileInfo));
  2306. // Terminate the search
  2307. FileSys_findClose(hFindFile);
  2308. //set the working folder to right window by default. 
  2309. if (! FileSys_changeDir(pszWorkingFolderName)) 
  2310. {
  2311. tr_printf(("WARNING: FileSys_changeDir() Failed [7]n"));
  2312. bSearchAborted= TRUE;
  2313. }
  2314. SHARED_INFO.uPeerDirCount= PEER_DIR_ARRAY_SIZE;
  2315. if(NULL != pszWorkingFolderName)
  2316. free(pszWorkingFolderName);
  2317. if(NULL != pFileInfo)
  2318. free(pFileInfo);
  2319. return (! bSearchAborted);
  2320. }
  2321. /*
  2322. Browser_BuildFolderContentList
  2323. Desc: Find all the items either file or subdir in the working directory. Create 
  2324. a clip object for each of the item and save the clip in ClipsRepository, which
  2325. is an array based on SDRAM scratch pad. For a subdir item, its fileId is saved
  2326. in another array SHARED_INFO.hDirsArray[CLIPS_SUB_ARRAY]. This is because a clip
  2327. object doesn't have a entry like fileId, though entry szFilename seems to have 
  2328. the same value.    
  2329. Out: SHARED_INFO.uCurrentClipNumber = 0, this means no item is on playing.
  2330.   
  2331. should be called after Browser_BuildPeerFoldersList.
  2332. */
  2333. static BOOL Browser_BuildFolderContentList(UINT16 uMaxClipsToFind)
  2334. {
  2335. BOOL bSearchAborted;
  2336. UINT16 hFindFile;
  2337. FindData *pFileInfo;
  2338. UINT16 hInstance;
  2339. SHARED_INFO.uCurrentClipNumber = 0; 
  2340. Browser_ResetSubFoldersArray();
  2341. ClipsRepository_clear();
  2342. // Allocate a FindData structure
  2343. pFileInfo= (FindData*)malloc(sizeof(FindData));
  2344. if (NULL == pFileInfo) 
  2345. {
  2346. tr_printf(("FATAL: Browser_BuildFolderContentList() Failed [2]: Low system resourcesn"));
  2347. return FALSE;
  2348. }
  2349. // Start scanning the Current Directory
  2350. hFindFile= FileSys_findFirstFile(FILESYS_WILDCARD_SEARCH, pFileInfo);
  2351. if (NULL == hFindFile) {
  2352. free(pFileInfo);
  2353. return FALSE;
  2354. }
  2355. // Start scanning the Current-Directory
  2356. bSearchAborted= FALSE;
  2357. do {
  2358. // If an Exception was thrown, abort the search
  2359. if (Exception_catchAndRethrow(EXCEPTION_MEDIUM_EJECTED)) {
  2360. tr_printf(("EXCEPTION: Browser_BuildFolderContentList() Aborting [2]n"));
  2361. bSearchAborted= TRUE;
  2362. break;
  2363. }
  2364. // Verify that there is vacancy in the Clips-Repository
  2365. if (uMaxClipsToFind == ClipsRepository_getSize())
  2366. break;
  2367. // Check the Type of File found
  2368. if (FILETYPE_VOLUME == pFileInfo->uFileType) 
  2369. {
  2370.   //do nothing.
  2371. }
  2372. else
  2373. if (FILETYPE_DIRECTORY == pFileInfo->uFileType) 
  2374. {
  2375. hInstance= 1 + SUB_DIR_ARRAY_SIZE;
  2376. // Skip the Current directories
  2377. if (0x00 == pFileInfo->szFileID[0] || 0 == wcscmp(pFileInfo->szFileID, L"."))
  2378. continue;
  2379. //parent directory
  2380. if( (0x01 == pFileInfo->szFileID[0]) || 0 == wcscmp(pFileInfo->szFileID, L".."))
  2381. {
  2382. WCHAR currPath[MAX_PATH];
  2383. FileSys_getCurrentPath(currPath);
  2384. if(currPath[0] == 0)
  2385. wcscpy(&pFileInfo->szFileID[0], L"ROOT");
  2386. else
  2387. wcscpy(&pFileInfo->szFileID[0], L"..");
  2388. }
  2389. // Enqueue the Directory found, for later use
  2390. if (! Array_setAt(SHARED_INFO.hDirsArray[CLIPS_SUB_ARRAY], hInstance - 1,
  2391.   (const BYTE*)pFileInfo->szFileID))
  2392. {
  2393. tr_printf(("WARNING: _findAndAddClips() Failed [3]n"));
  2394. break;
  2395. }
  2396. else // it's a file
  2397. {
  2398. UINT16 hClipInstance= ClipsRepository_addClip(pFileInfo);
  2399. if (NULL == hClipInstance) {
  2400. dbg_printf(("WARNING: Browser_BuildFolderContentList() Failed [4]: %s rejected.n", DBG_W2A(pFileInfo->szFileID)));
  2401. continue;
  2402. }
  2403. // Update the Available-Types
  2404. g_uAvailableClipTypes |= (UINT16)Clip_getType(hClipInstance);
  2405. #ifdef CLIPS_JPEG_DIGEST_SUPPORT
  2406. // Update the number of Digestable Items
  2407. if (Clip_hasAttribute(hClipInstance, eCA_Digestable)) {
  2408. g_pClipsNav->m_uDigestableTypes |= (UINT16)Clip_getType(hClipInstance);
  2409. g_pClipsNav->m_uDigestableItemsCnt++;
  2410. }
  2411. #endif //CLIPS_JPEG_DIGEST_SUPPORT
  2412. dbg_printf(("%d. %sn", ClipsRepository_getSize(), DBG_W2A(pFileInfo->szFileID)));
  2413. }
  2414. } while (FileSys_findNextFile(hFindFile, pFileInfo));
  2415. // Terminate the search
  2416. FileSys_findClose(hFindFile);
  2417. SHARED_INFO.uSubDirCount= SUB_DIR_ARRAY_SIZE;
  2418. free(pFileInfo);
  2419. return (! bSearchAborted);
  2420. }
  2421. /*
  2422. When the browser is already opened, USER click on a dir entry to open it.
  2423. */
  2424. static void Browser_OpenFolder(UINT8 ucWhichWindow, int iWhichEntry, BOOL bNotifyUI)
  2425. {
  2426. FindData *pFileInfo;
  2427. // Allocate a FindData structure
  2428. pFileInfo= (FindData*)malloc(sizeof(FindData));
  2429. if (NULL == pFileInfo)
  2430. {
  2431. tr_printf(("FATAL: Browser_OpenFolder() Failed [1]: Low system resourcesn"));
  2432. return FALSE;
  2433. }
  2434. if(eLEFT_WINDOW == ucWhichWindow) //It's a peer directory in the left window
  2435. Array_getAt(SHARED_INFO.hDirsArray[CLIPS_PEER_ARRAY],iWhichEntry - 1,(const BYTE*)pFileInfo->szFileID);
  2436. else
  2437. if(eRIGHT_WINDOW == ucWhichWindow) //It's a sub directory in the right window
  2438. Array_getAt(SHARED_INFO.hDirsArray[CLIPS_SUB_ARRAY],(iWhichEntry - 1),(const BYTE*)pFileInfo->szFileID);
  2439.   
  2440. //go up to parent directory.
  2441. if(0 == wcscmp(pFileInfo->szFileID, L"..") || 0 == wcscmp(pFileInfo->szFileID, L"ROOT"))
  2442. {
  2443. if(FALSE == FileSys_InRootDir())
  2444. {
  2445. FileSys_goUp(); 
  2446. Browser_Build(eBuildAll, bNotifyUI);
  2447. }
  2448. else
  2449. notifyUIOnBrowserContentChange(eCLIPS_UPDATE_NONE, eCLIPS_UPDATE_NONE);
  2450. }
  2451. else
  2452. if(eLEFT_WINDOW == ucWhichWindow && iWhichEntry != SHARED_INFO.uCurrentDir) //It's a peer directory in the left window
  2453. {
  2454. // go to the new working directory.
  2455. FileSys_goUp();
  2456. if (! FileSys_changeDir(pFileInfo->szFileID)) 
  2457. {
  2458. tr_printf(("WARNING: go to subDir() Failed [7]n"));
  2459. free(pFileInfo);
  2460. return;
  2461. }
  2462. SHARED_INFO.uCurrentDir = iWhichEntry;
  2463. Browser_Build(eBuildFileListOnly, bNotifyUI);
  2464. }
  2465. else
  2466. if(eRIGHT_WINDOW == ucWhichWindow) //It's a sub directory in the right window
  2467. {
  2468. SHARED_INFO.uCurrentDir = iWhichEntry;
  2469. if (! FileSys_changeDir(pFileInfo->szFileID))
  2470. {
  2471. tr_printf(("WARNING: go to subDir() Failed [7]n"));
  2472. free(pFileInfo);
  2473. return;
  2474. }
  2475. Browser_Build(eBuildPeerDirListBasedOnSubDirList, bNotifyUI);
  2476. }
  2477. else
  2478. notifyUIOnBrowserContentChange(eCLIPS_UPDATE_NONE, eCLIPS_UPDATE_NONE);
  2479. free(pFileInfo);
  2480. return;
  2481. }
  2482. /*
  2483. -Build the list of the content of the working directory and the list of 
  2484. the working directory's peers.
  2485. -Initialize the program list and start play the
  2486. content of the working directory.
  2487. In:  
  2488. eBuildAll, true when need to build everything from scratch.
  2489. eBuildFileListOnly, true when the peer dir doesn't need to change when going to a peer dir.
  2490. eBuildPeerDirListBasedOnSubDirList, true when SubDir exists and can be used as PeerDir
  2491. when going to a lower level directory.
  2492. Out:g_pClipsNav->m_eClipsListStatus is firstly set to be eCLS_Building and finally 
  2493. eCLS_Finalized. At this point UI is supposed to refresh it's browser.
  2494. notify UI to refresh it's browser.
  2495.  
  2496. */
  2497. static void Browser_Build(enBuildBrowser eBuildBrowserType, BOOL bNotifyUI)
  2498. {
  2499. UINT32 Param;
  2500. BYTE ucUpdatePeerDirListWindow = eCLIPS_UPDATE_ALL;
  2501. #ifdef CLIPS_JPEG_DIGEST_SUPPORT
  2502. g_pClipsNav->m_bDigestMode= FALSE;
  2503. g_pClipsNav->m_uDigestableTypes= (UINT16)eClipType_None;
  2504. g_pClipsNav->m_uDigestableItemsCnt= 0;
  2505. #endif //CLIPS_JPEG_DIGEST_SUPPORT
  2506. // Reset the Available Types
  2507. g_uAvailableClipTypes= (UINT16)eClipType_None;
  2508. // Invoke the search
  2509. g_pClipsNav->m_eClipsListStatus= (UINT8)eCLS_Building;
  2510. //build peer DIR.
  2511. if(eBuildPeerDirListBasedOnSubDirList == eBuildBrowserType)
  2512. Browser_SwitchArrays();
  2513. else
  2514. if(eBuildAll == eBuildBrowserType)
  2515. Browser_BuildPeerFoldersList(MAX_SUBDIRS_CNT);
  2516. else
  2517. if(eBuildFileListOnly == eBuildBrowserType)
  2518. {
  2519.   ucUpdatePeerDirListWindow = eCLIPS_UPDATE_INDEX;
  2520. }
  2521. //build file list.
  2522. Browser_BuildFolderContentList(CLIPS_MAX_PROGRAM_SIZE);
  2523. //build the program list and play the first item.
  2524. Clips_finalizeClipsList();
  2525. if(TRUE == bNotifyUI)
  2526. notifyUIOnBrowserContentChange(ucUpdatePeerDirListWindow, eCLIPS_UPDATE_ALL);
  2527. return;
  2528. }
  2529. void Browser_GetPeerFolderInfo(UINT16 uDirNum,ClipInfo *o_pInfo)
  2530. {
  2531.   Browser_GetFolderInfo(uDirNum, o_pInfo, eLEFT_WINDOW);
  2532. }
  2533. static void Browser_GetFolderInfo(UINT16 uDirNum,ClipInfo *o_pInfo, enWINDOWTYPE eWin)
  2534. {
  2535. FindData *pFileInfo;
  2536. BYTE ucDirArray;
  2537. if(eLEFT_WINDOW == eWin)
  2538. {
  2539. ucDirArray = CLIPS_PEER_ARRAY;
  2540. }
  2541. else
  2542. {
  2543. ucDirArray = CLIPS_SUB_ARRAY;
  2544. }
  2545. // Allocate a FindData structure
  2546. pFileInfo= (FindData*)malloc(sizeof(FindData));
  2547. if (NULL == pFileInfo) 
  2548. {
  2549. tr_printf(("FATAL: Browser_GetFolderInfo() Failed [1]: Low system resourcesn"));
  2550. return;
  2551. }
  2552. //uDirNum is 1 based.
  2553. if(0 == uDirNum || uDirNum > Array_getSize(SHARED_INFO.hDirsArray[ucDirArray]))
  2554. {
  2555. tr_printf(("WARNING: Browser_GetFolderInfo() try to get non exist item."));
  2556. free(pFileInfo);
  2557. return;
  2558. }
  2559. Array_getAt(SHARED_INFO.hDirsArray[ucDirArray],uDirNum - 1,(const BYTE*)pFileInfo->szFileID);
  2560. //Get the working folder's name.
  2561. {
  2562. LPWSTR pszDelim;
  2563. // Copy the Directory-Name
  2564. pszDelim= wcsrchr(pFileInfo->szFileID, FileSys_getPathDelimiter());
  2565. if (NULL != pszDelim)
  2566. pszDelim++;
  2567. else
  2568. pszDelim= (LPWSTR)pFileInfo->szFileID;
  2569. wcsncpy(&(o_pInfo->szFilename), pszDelim, CLIPS_MAX_DIRNAME_LEN);
  2570. }
  2571. o_pInfo->eType = eClipType_DIR;
  2572. free(pFileInfo);
  2573. return;
  2574. }
  2575. /*
  2576. Desc: get a playable item in the 1st sub folder of the current working folder.
  2577.       if such a item is not available. Go to next folder and repeat the process.
  2578. In: none.
  2579. Out: Current working folder is changed to the sub or next folder that contains a 
  2580.      playable item. 
  2581.      SHARED_INFO.uCurrPlaylistItem is updated to be the 1st playable item in the 
  2582.      working folder.
  2583.      An event is sent to UI to notify the change of working folder.
  2584. */
  2585. static UINT16 getFirstItemInSubFoldersOrNextFolders(void)
  2586. {
  2587. UINT16 uNextItem = 0;
  2588. BOOL bWholeDiscFinished = 0;
  2589. BOOL is_need_update_all = 0;
  2590. // <<< SEC CH.KO040204:Only normal play can access next folder
  2591. #ifdef EXINO2
  2592. if(PM_IsPlaybackShuffle(PM_GetPlaybackMode()))
  2593. return 0;
  2594. #endif
  2595. // SEC CH.KO040204 >>>
  2596. //<<<BillTang_0714_2004: moved here from below while(1){} to avoid 
  2597. //calling DEC_Stop_DVP_cmd() without dec_CacheInit() around causing
  2598. //discGetBytes() failed in case of some sectors already cached!
  2599. #ifdef CLIPS_DISPLAY_BACKGROUND
  2600. PE_Clips_DisplayBackground();
  2601. #else
  2602. PE_Clips_DisplayLogo();
  2603. #endif //CLIPS_DISPLAY_BACKGROUND
  2604. //BillTang_0714_2004>>>
  2605. while(1)
  2606. {
  2607. if(0 == uNextItem)
  2608. {
  2609. UINT16 dirNo = 0;
  2610. int i;
  2611. //play 1st sub dir is the working folder
  2612. if(1 < SUB_DIR_ARRAY_SIZE)//has sub dir, go check is there is anything to play.
  2613. {
  2614. Browser_OpenFolder( eRIGHT_WINDOW, 2, FALSE);
  2615. uNextItem = computePlaylistItem(0, TRUE);
  2616. continue;
  2617. }
  2618. else // no sub dir
  2619. {
  2620. while(1)
  2621. {
  2622. if(SHARED_INFO.uCurrentDir < Array_getSize(SHARED_INFO.hDirsArray[CLIPS_PEER_ARRAY] )) // has peer folder after him
  2623. {
  2624. //got peer dirs to play.
  2625. Browser_OpenFolder( eLEFT_WINDOW, SHARED_INFO.uCurrentDir+1, FALSE);
  2626. uNextItem = computePlaylistItem(0, TRUE);
  2627. break;
  2628. }
  2629. else //no peer folder following him.
  2630. {
  2631. is_need_update_all = TRUE;
  2632. if(TRUE == FileSys_InRootDir())//have reached to root, no more items to play.
  2633. {
  2634. bWholeDiscFinished++;
  2635. if (PM_IsRepeatAll())
  2636. {
  2637. while (1 < SUB_DIR_ARRAY_SIZE )
  2638. Browser_OpenFolder( eRIGHT_WINDOW, 2, FALSE);
  2639. uNextItem = computePlaylistItem(0, TRUE);
  2640. }
  2641. break;
  2642. }
  2643. else // go 1 level up and repeat the process.
  2644. {
  2645. Browser_OpenFolder( eLEFT_WINDOW, 1, FALSE);
  2646. continue; //go check if it has peer sub dir follows him.
  2647. }
  2648. }
  2649. }
  2650. if((1 == bWholeDiscFinished && (!PM_IsRepeatAll())) || 1 < bWholeDiscFinished)
  2651. break;
  2652. continue;//go check if there is anything to play.
  2653. }
  2654. }
  2655. else
  2656. break;
  2657. }
  2658. if(is_need_update_all)
  2659. notifyUIOnBrowserContentChange(eCLIPS_UPDATE_ALL, eCLIPS_UPDATE_ALL);
  2660. else
  2661. notifyUIOnBrowserContentChange(eCLIPS_UPDATE_INDEX, eCLIPS_UPDATE_ALL);
  2662. return uNextItem;
  2663. }
  2664. /*
  2665. Desc: get a playable item in the prev folder of the current working folder.
  2666.       if such a item is not available. Go to prev folder's  last sub folder 
  2667.       and repeat the process.
  2668. In: none.
  2669. Out: Current working folder is changed to the prev that contains a 
  2670.      playable item. 
  2671.      SHARED_INFO.uCurrPlaylistItem is updated to be the last playable item in the 
  2672.      working folder.
  2673.      An event is sent to UI to notify the change of working folder.
  2674. */
  2675. static UINT16 getLastItemInPrevFolders(void)
  2676. {
  2677. BOOL bWholeDiscFinished = 0;
  2678. UINT16 uPrevItem = 0;
  2679. BOOL is_need_update_all = 0;
  2680. while(1)
  2681. {
  2682. if(0 == uPrevItem)
  2683. {
  2684. int i;
  2685. while(1)
  2686. {
  2687. if(SHARED_INFO.uCurrentDir > 2) // has peer folder before him
  2688. {
  2689. //got peer dirs to play.
  2690. Browser_OpenFolder( eLEFT_WINDOW, SHARED_INFO.uCurrentDir - 1, FALSE);
  2691. while(1)
  2692. {
  2693. UINT16 dirNo = 0;
  2694. if(1 < SUB_DIR_ARRAY_SIZE) // a sub dir is found
  2695. {
  2696. Browser_OpenFolder( eRIGHT_WINDOW, SUB_DIR_ARRAY_SIZE, FALSE);
  2697. continue;
  2698. }
  2699. else
  2700. break; 
  2701. }
  2702. uPrevItem = computePlaylistItem(ClipsRepository_getSize() + 1, FALSE);
  2703. break;
  2704. }
  2705. else //no peer folder before him.
  2706. {
  2707. is_need_update_all = TRUE;
  2708. if(TRUE == FileSys_InRootDir())//have reached to root, no more items to play.
  2709. {
  2710. bWholeDiscFinished++;
  2711. if (PM_IsRepeatAll())
  2712. {
  2713. while (1 < SUB_DIR_ARRAY_SIZE )
  2714. Browser_OpenFolder( eRIGHT_WINDOW, SUB_DIR_ARRAY_SIZE, FALSE);
  2715. uPrevItem = computePlaylistItem(ClipsRepository_getSize() + 1, FALSE);
  2716. }
  2717. break;
  2718. }
  2719. else // go 1 level up and repeat the process.
  2720. {
  2721. Browser_OpenFolder( eLEFT_WINDOW, 1, FALSE);
  2722. continue; //go check if it has peer sub dir follows him.
  2723. }
  2724. }
  2725. }
  2726. if((1 == bWholeDiscFinished && (!PM_IsRepeatAll())) || 1 < bWholeDiscFinished)
  2727. break;
  2728. continue;//go check if there is anything to play.
  2729. }
  2730. else
  2731. break;
  2732. }
  2733. #ifdef CLIPS_DISPLAY_BACKGROUND
  2734. PE_Clips_DisplayBackground();
  2735. #else
  2736. PE_Clips_DisplayLogo();
  2737. #endif //CLIPS_DISPLAY_BACKGROUND
  2738. if(is_need_update_all)
  2739. notifyUIOnBrowserContentChange(eCLIPS_UPDATE_ALL, eCLIPS_UPDATE_ALL);
  2740. else
  2741. notifyUIOnBrowserContentChange(eCLIPS_UPDATE_INDEX, eCLIPS_UPDATE_ALL);
  2742. return uPrevItem;
  2743. }
  2744. /*
  2745. Desc: Notify UI when the content of the PeerDirList or the FileList changes, or when the current playing  
  2746. item no. changes, or when the current Dir No. changes.
  2747. In: ucUpdatePeerDirListWindow - what has changed in PeerDirList window.
  2748. ucUpdateFileListWindow - what has changed in FileList window.
  2749. Out:a IE_UI_CLIPS_UPDATE message is sent to UI. 
  2750. */
  2751. static void notifyUIOnBrowserContentChange(BYTE ucUpdatePeerDirListWindow, BYTE ucUpdateFileListWindow)
  2752. {
  2753. UINT32 Param=0;
  2754. //if(eWINDOWS_EXPLORER_STYLE == SHARED_INFO.eWindowsExplorerStyleBrowser)
  2755. {
  2756. Param = (((UINT32)ucUpdatePeerDirListWindow)<<16)|ucUpdateFileListWindow;
  2757. ie_send_ex(IE_UI_CLIPS_UPDATE, (void *)(Param));
  2758. }
  2759. #ifdef MANUAL_DIRECTORY_EXPLORER
  2760. SHARED_INFO.uSubDirArraySize = SUB_DIR_ARRAY_SIZE;//ERICM_4JUN25K
  2761. #endif
  2762. return;
  2763. }
  2764. #endif
  2765. /*
  2766. FileSys_InRootDir
  2767. Desc: check if the working folder is root directory.
  2768. In:   None
  2769. Out:  None
  2770. Return: TRUE - yes it's root directory.
  2771. FALSE - no it's not
  2772. */
  2773. static BOOL FileSys_InRootDir(void)
  2774. {
  2775. WCHAR currPath[MAX_PATH];
  2776. FileSys_getCurrentPath(currPath);
  2777. return (0 == currPath[0]);
  2778. }
  2779. static void SetBrowserStyle(enClipsBrowserStyle eBrowserStyle)
  2780. {
  2781. SHARED_INFO.eWindowsExplorerStyleBrowser = eBrowserStyle;
  2782. #ifdef MANUAL_DIRECTORY_EXPLORER
  2783. if(eSingle_LIST_STYLE == SHARED_INFO.eWindowsExplorerStyleBrowser)
  2784.   SHARED_INFO.bDisplayLogoWhenPlayAudioOnlySteam = 0;
  2785. else
  2786.   SHARED_INFO.bDisplayLogoWhenPlayAudioOnlySteam = 1;
  2787. #endif
  2788. }
  2789. BOOL Clips_getPlayListItemInfoAt(UINT16 uPlayListItem, ClipInfo *o_pClipFileInfo)
  2790. {
  2791. return Clips_getClipFileInfoAt(PM_GetProgramListEntry((UINT16)uPlayListItem), o_pClipFileInfo);
  2792. }
  2793. static BOOL IsGotoNextChapterAllowed()
  2794. {
  2795. #ifdef EXINO2
  2796. // <<< SEC CH.KO040204: Only normal play can access next folder
  2797. // <<< SEC CH.KO050804: if subfolder not existed, kodak picture cd mulfunc problem fixed
  2798.   if((PM_IsPlaybackNormal(PM_GetPlaybackMode()))&& (g_disc_type !=DEC_DISC_TYPE_PICTURE_CD))
  2799. #else
  2800. if(PM_IsPlaybackRandom(PM_GetPlaybackMode()))
  2801. #endif
  2802. {
  2803. return TRUE;
  2804. }
  2805. if (0 == computePlaylistItem(SHARED_INFO.uCurrPlaylistItem, TRUE)) 
  2806. {
  2807. if(eWholeDisc != SHARED_INFO.uExplorerStyleBrowserPlayMode)
  2808. {
  2809. #ifdef CLIPS_WRAP_AROUND_ON_PROGRAM_EDGES
  2810. #else
  2811. // Wrap-around if Repeat-All is on
  2812. if (PM_IsRepeatAll() || PM_IsRepeatFolder()) {
  2813. }
  2814. else {
  2815. return FALSE;
  2816. }
  2817. #endif //CLIPS_WRAP_AROUND_ON_PROGRAM_EDGES
  2818. }
  2819. #ifdef EXINO2
  2820. // <<< SEC CH.KO040204:Only normal play can access next folder
  2821. else if(PM_IsPlaybackRandom(PM_GetPlaybackMode())|| PM_IsPlaybackShuffle(PM_GetPlaybackMode()))
  2822. return FALSE;
  2823. // SEC CH.KO040204 >>>
  2824. #endif
  2825. }
  2826. return TRUE;
  2827. }
  2828. static BOOL IsGotoPreviousChapterAllowed()
  2829. {
  2830. if(PM_IsPlaybackRandom(PM_GetPlaybackMode()))
  2831. {
  2832. return TRUE;
  2833. }
  2834. if (0 == computePlaylistItem(SHARED_INFO.uCurrPlaylistItem, FALSE)) 
  2835. {
  2836. if(eWholeDisc != SHARED_INFO.uExplorerStyleBrowserPlayMode)
  2837. {
  2838. #ifdef CLIPS_WRAP_AROUND_ON_PROGRAM_EDGES
  2839. #else
  2840. // Wrap-around if Repeat-All is on
  2841. if (PM_IsRepeatAll() || PM_IsRepeatFolder()) {
  2842. }
  2843. else {
  2844. return FALSE;
  2845. }
  2846. #endif //CLIPS_WRAP_AROUND_ON_PROGRAM_EDGES
  2847. }
  2848. }
  2849. return TRUE;
  2850. }
  2851. #define min(a,b) (((a) < (b)) ? (a) : (b))
  2852. void
  2853. CyclicWriteDRAMData(const INT32 uiBufferStart,const INT32 uiBufferEnd,
  2854.                     UINT32 uiAddress, UINT16* puiTarget, UINT32 uiLength )
  2855. {
  2856.    /* we assume that uiAddress <= uiBufferEnd */
  2857.    /* first write is from uiAdress, length is min(uiLength, uiBufferEnd-uiAddress) */
  2858.    /* scond write is for the remaining - which is uiBufferEnd-uiAddress */
  2859.    UINT32 uiWriteLengthFirstCall;
  2860.    UINT32 uiWriteLengthSecondCall;
  2861.    //UINT32 kk;
  2862. //   printf("start:%lx end:%lx ",uiBufferStart,uiBufferEnd);
  2863.    while(uiAddress >= uiBufferEnd)
  2864.    {
  2865. //    uiAddress -= (SPB_SIZE_AVI*512UL);
  2866. uiAddress -= (uiBufferEnd - uiBufferStart);
  2867.    }
  2868.    uiWriteLengthFirstCall = min(uiLength, uiBufferEnd - uiAddress);
  2869.    uiWriteLengthSecondCall = uiLength - uiWriteLengthFirstCall ;
  2870.    wai_sem(SEM_DRAM_ID);
  2871.    I49_WriteDRAMDataNSW(uiAddress, (UINT16*)puiTarget, uiWriteLengthFirstCall);
  2872. // printf("addr:%lxn",uiAddress);
  2873.    if ( uiWriteLengthFirstCall != uiLength )
  2874.    {
  2875. //      printf("BUG!!!n");
  2876.       I49_WriteDRAMDataNSW(uiBufferStart, 
  2877.                        (UINT16*)(puiTarget + uiWriteLengthFirstCall ), 
  2878.                        uiWriteLengthSecondCall );
  2879.    }
  2880.    sig_sem(SEM_DRAM_ID);
  2881.    return;
  2882. }
  2883. #ifdef EXINO2 //ZKR JK0413 : change the macro 
  2884. UINT16 Clips_getTotalDigestNum(void)
  2885. {
  2886. return g_pClipsNav->m_uDigestableItemsCnt;
  2887. }
  2888. #endif
  2889. #ifdef SUPPORT_FLASH_CARD
  2890. UINT32 Clips_GetCurrClipSize(void)
  2891. {
  2892. return (gns.clips.cieCurrClip.ciInfo.cbFileSize);
  2893. }
  2894. UINT32 Clips_GetCurrClipSartAddr(void)
  2895. {
  2896. return (gns.clips.cieCurrClip.ciInfo.dwFileLocation);
  2897. }
  2898. //JERRYC_2004_Oct_21
  2899. BOOL Clips_IsAddrWithinCurrClip(UINT32 lsn)
  2900. {
  2901. if(lsn < (gns.clips.cieCurrClip.ciInfo.dwFileLocation))
  2902.     return FALSE;
  2903.    else
  2904.    lsn -= gns.clips.cieCurrClip.ciInfo.dwFileLocation;
  2905.    if((lsn*LOGICAL_BLOCK_SIZE) >= Clips_GetCurrClipSize())
  2906.     return FALSE;
  2907.    return TRUE;
  2908. }
  2909. //JERRYC_FEB19            
  2910. /*
  2911. Desc: translate a logical address of a clips into a physical address address on flash card.
  2912. */
  2913. UINT32 Clips_GetPSNOnFlashCardAndOffset(UINT32 lsn, UINT32* pOffset)
  2914. {
  2915. STRUCT_FILE file;
  2916.    UINT32 psn;
  2917. UINT32 offset = lsn - gns.clips.cieCurrClip.ciInfo.dwFileLocation;
  2918.     UINT16 blocksPerCluster;
  2919.     
  2920.    //in digest mode, gns.clips.cieCurrClip doesn't refer to the clip to play.
  2921. if (g_pClipsNav->m_bDigestMode || (FALSE == Clips_IsAddrWithinCurrClip(lsn))){
  2922.      *pOffset = 0;
  2923. return lsn;
  2924.    }
  2925. //open file
  2926. FileSys_FileOpen(&file, gns.clips.cieCurrClip.ciInfo.dwFileLocation, 0, gns.clips.cieCurrClip.ciInfo.cbFileSize);
  2927. FileSys_FileSeek(&file, 0, (LOGICAL_BLOCK_SIZE * offset));
  2928. psn = file.fx_file_current_physical_cluster;
  2929.    dbg_printf(("get psn on card, lsn:%lx, psn:%lx.n", lsn, psn));
  2930.     blocksPerCluster = (file.fx_file_media_ptr->fx_media_sectors_per_cluster)/4;
  2931.     if(blocksPerCluster > 0){
  2932.    *pOffset = (offset % blocksPerCluster)*LOGICAL_BLOCK_SIZE;
  2933.     }
  2934.     else
  2935.      *pOffset = 0;
  2936.         
  2937. FileSys_FileClose(&file);
  2938. return psn;
  2939. }
  2940.         //JERRYC_FEB19            
  2941. /*
  2942. Desc: translate a logical address of a clips into a physical address address on flash card.
  2943. */
  2944. UINT32 Clips_GetPSNOnFlashCard(UINT32 lsn)
  2945. {
  2946. STRUCT_FILE file;
  2947.    UINT32 psn;
  2948. UINT32 offset = lsn - gns.clips.cieCurrClip.ciInfo.dwFileLocation;
  2949.    //in digest mode, gns.clips.cieCurrClip doesn't refer to the clip to play.
  2950. if (g_pClipsNav->m_bDigestMode || (FALSE == Clips_IsAddrWithinCurrClip(lsn)))
  2951. return lsn;
  2952. //open file
  2953. FileSys_FileOpen(&file, gns.clips.cieCurrClip.ciInfo.dwFileLocation, 0, gns.clips.cieCurrClip.ciInfo.cbFileSize);
  2954. FileSys_FileSeek(&file, 0, (LOGICAL_BLOCK_SIZE * offset));
  2955. psn = file.fx_file_current_physical_cluster;
  2956. FileSys_FileClose(&file);
  2957.    dbg_printf(("get psn on card, lsn:%lx, psn:%lx.n", lsn, psn));
  2958. return psn;
  2959. }
  2960. #endif