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

DVD

开发平台:

Others

  1. /* **************************************************************************************
  2.  *  Copyright (c) 2004 ZORAN Corporation, All Rights Reserved
  3.  *  THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF ZORAN CORPORATION
  4.  *
  5.  *  File: $Workfile: AuxCache.c $
  6.  *
  7.  * Description:
  8.  * ============
  9.  * Auxilary Data Caching Interface.
  10.  * 
  11.  * Log:
  12.  * ====
  13.  * $Revision:  $
  14.  * Last Modified by $Author:  $ at $Modtime:  $ 
  15.  ****************************************************************************************
  16.  * Updates:
  17.  ****************************************************************************************
  18.  * $Log: /I76/I76_Common/I76_Reference/Playcore/AuxCache/AuxCache.c $
  19.  * 
  20.  **************************************************************************************** */
  21. #include "Config.h" // Global Configuration - do not remove!
  22. #ifdef _DEBUG
  23. #define IFTRACE if (gTraceAuxCache)
  24. #include "DebugDbgMain.h"
  25. #endif
  26. /////////////////////////////////////////////////////////////////////////////////////////////////
  27. // Include files
  28. #include "Includesysdefs.h"
  29. #include "Includemath-macro.h"
  30. #include "DecoderDecoder.h"
  31. #include "Decoderlow_levelDEC_LL_API.h"
  32. #include "Decoderlow_levelDVP_API.h"
  33. #include "DriveDrv_API.h"
  34. #include "PlaycoreCoremainCoreGDef.h"
  35. #include "PlaycoreExceptionException.h"
  36. #if defined(SUPPORT_FLASH_CARD)||defined(MACESTROLINK_SUPPORT)
  37. #include "DriveFE_Manager.h"
  38. #include "mediacardsincluderegister.h"
  39. extern UINT32 Clips_GetCurrClipSize(void);
  40. extern UINT32 Clips_GetCurrClipSartAddr(void);
  41. //extern BOOL Clips_IsAddrWithinCurrClip(UINT32 lsn);//JERRYC_2004_Oct_21
  42. #endif
  43. #ifdef MACESTROLINK_SUPPORT
  44. #include "drivemacestrolink.h"
  45. #endif
  46. #ifdef SUPPORT_FLASH_CARD
  47. extern BOOL bReadAuxSubtitle;
  48. #endif
  49. /////////////////////////////////////////////////////////////////////////////////////////////////
  50. // Constants and Defines
  51. #define VCD_INFO_SECTOR_ADDR 0x96
  52. #define DVDSECT_READ_LENGTH 4
  53. #define CDSECT_READ_LENGTH 4
  54. #define LOGICAL_BLOCK_SIZE 2048
  55. #define DVDSECT_MAX_RETRIES 2
  56. #define CDSECT_MAX_RETRIES 2
  57. /////////////////////////////////////////////////////////////////////////////////////////////////
  58. // Private Services
  59. /////////////////////////////////////////////////////////////////////////////////////////////////
  60. // API
  61. /////////////////////////////////////////////////////////////////////////////
  62. // Function name : AuxCache_DiscReadBlock
  63. // Purpose : Request a playback from the drive driver.
  64. // Input Parameters : dwLBN - logical start address.
  65. //   wCount - number of sectors to read.
  66. // Return type : Always TRUE.
  67. // Output Parameters: none.
  68. // Remarks : Used for both CD and DVD.
  69. /////////////////////////////////////////////////////////////////////////////
  70. BOOL AuxCache_DiscReadBlock(DWORD dwLBN, WORD wCount)
  71. {
  72. if (IS_DVD_PHYSICAL_MEDIA) 
  73. {
  74. #ifdef MACESTROLINK_SUPPORT
  75. if(IS_PLAYING_MLNK)
  76. return MLNK_play_dvd((UINT32)dwLBN, (UINT32)wCount, DRVF_PLAY_DVD_DUMP_DATA);
  77. else
  78. #endif
  79. drv_play_dvd((UINT32)dwLBN, (UINT32)wCount, DRVF_PLAY_DVD_DUMP_DATA);
  80. }
  81. else
  82. {
  83. drv_play_cd_logical(DRVCF_CDSPEED_MAX|DRVF_PLAY_CD_DUMP_DATA, (UINT32)dwLBN, (UINT32)wCount);
  84. }
  85. return TRUE;
  86. }
  87. /////////////////////////////////////////////////////////////////////////////
  88. // Function name : AuxCache_GetBytes
  89. // Purpose : Retrieves auxiliary data bytes from media,
  90. //   takes care about sector boundary crossing
  91. //   and manages decoder cache.
  92. // Input Parameters : dwLBN - logical start address. 
  93. //   wCount - number of sectors to read.
  94. //   dwOffset - offset from start of the sector. Could be
  95. //  several sectors long.
  96. // Return type : BOOL - TRUE if successfull, FALSE otherwise.
  97. // Output Parameters: buff - the data buffer.
  98. // Remarks : Used for both CD and DVD.
  99. //   Max caching in a single read using this function is as 
  100. //   the size of the NAV buffer.
  101. /////////////////////////////////////////////////////////////////////////////
  102. BOOL AuxCache_GetBytes(DWORD dwLBN, DWORD dwOffset, WORD wNumOfBytes, BYTE *buff)
  103. {
  104. CACHE_SECTOR_HANDLE hSector;
  105. DWORD dwNormLBN;
  106. WORD wNormOffset;
  107. WORD wRemainCount;
  108. BOOL bResult = TRUE;
  109. WORD wReadLength;
  110. #ifdef _DEBUG
  111. static DWORD dwLastCachedLBN = 0;
  112. #endif
  113. //<<<<Hansen_04_09_22
  114. #ifdef MACESTROLINK_SUPPORT
  115. if(IS_PLAYING_MLNK&&MLNK_STATUS_ERROR())
  116. return FALSE;
  117. #endif
  118. //>>>>Hansen_04_09_22
  119. #ifdef SUPPORT_FLASH_CARD
  120. if (IS_PLAYING_CARD)
  121. {
  122. STRUCT_FILE *pfile = FCU_TEMP_FILE_STRCUT_ADDR;
  123. UINT32 actual_size;
  124.       UINT32 startAddr;
  125.    dbg_printf(("get bytes on card, lsn:%lx, offset:%lx.n", dwLBN, dwOffset));
  126. //      if(Clips_IsAddrWithinCurrClip(dwLBN) == FALSE)
  127. // Robin_0128_2005, during the auxsubtitle processing
  128. if (bReadAuxSubtitle)
  129.        pfile = FCU_TEMP_SUBTITLE_FILE_STRCUT_ADDR;
  130.       startAddr = pfile->fx_file_first_physical_cluster;
  131. FileSys_FileSeek(pfile, 0, (dwLBN - startAddr)*LOGICAL_BLOCK_SIZE + dwOffset);
  132. if(FX_SUCCESS != FileSys_FileRead(pfile, buff, wNumOfBytes, &actual_size) || 0 == actual_size)
  133. {
  134. dbg_printf(("discGetBytes on card failed.n"));
  135. return FALSE;
  136. }
  137. // FileSys_FileClose(pfile);
  138. return TRUE;
  139. }
  140. #endif
  141. #ifdef _DEBUG
  142. if (dwLastCachedLBN != dwLBN)
  143. {
  144. dbg_printf(("AuxCache_GetBytes(LBN: %08lx, offset: %04lx, bytes: %d)n", dwLBN, dwOffset, wNumOfBytes));
  145. dwLastCachedLBN = dwLBN;
  146. }
  147. #endif
  148. /* Check if an exception was thrown, if so, stop immediatly */
  149. if (Exception_catchAndRethrow(EXCEPTION_MEDIUM_EJECTED | EXCEPTION_POWER_DOWN_REQUEST)) 
  150. {
  151. tr_printf(("AuxCache_GetBytes() - Exception_catchAndRethrow[1]n"));
  152. return FALSE;
  153. }
  154. /* dwOffset is converted to number of sectors + the remaining part */
  155. dwNormLBN = dwLBN + (dwOffset >> 11);
  156. wNormOffset = (WORD)(dwOffset & 0x7FFL);
  157. wRemainCount = wNumOfBytes;
  158. /* Cache the data */
  159. while (wRemainCount && bResult)
  160. {
  161. /* If an Exception was thrown, abort */
  162. if (Exception_catchAndRethrow(EXCEPTION_MEDIUM_EJECTED | EXCEPTION_POWER_DOWN_REQUEST)) 
  163. {
  164. tr_printf(("AuxCache_GetBytes() - Exception_catchAndRethrow[2]n"));
  165. bResult = FALSE;
  166. break;
  167. }
  168. /* Check if data is already cached (Cache-hit) */
  169. if (DEC_CacheHit(dwNormLBN, &hSector))
  170. {
  171. WORD wRequestCount;
  172. #ifdef _DEBUG
  173. if (dwLastCachedLBN != dwNormLBN)
  174. {
  175. dbg_printf(("AuxCache_GetBytes() - Cache Hit %08lx, handle: %02x n", dwNormLBN, hSector));
  176. dwLastCachedLBN = dwNormLBN;
  177. }
  178. #endif
  179. /* Calculate the remaining bytes to cache */
  180. wRequestCount = (WORD)MIN(wRemainCount, (2048 - wNormOffset));
  181. /* Get the cached data */
  182. DEC_CacheGetBytes(hSector, wNormOffset, wRequestCount, buff);
  183. wRemainCount -= wRequestCount;
  184. /* Check if we still have data to get from subsequent sectors */
  185. if (wRemainCount)
  186. dwNormLBN++;
  187. /* Set lbn and offset to beginning of next sector */
  188. wNormOffset = 0;
  189. /* Increment buffer ptr accordingly */
  190. buff += wRequestCount;
  191. }
  192. }
  193. else /* Cache-miss */
  194. {
  195. UINT8 uiRetryCount; 
  196. if (IS_DVD_PHYSICAL_MEDIA) 
  197. {
  198. /* Check for invalid requests */
  199. UINT32 sa = dwNormLBN;
  200. #ifdef MACESTROLINK_SUPPORT
  201. if(!IS_PLAYING_MLNK)
  202. #endif
  203. {
  204. drv_lsn2psn(&sa);
  205. if (!drv_is_valid_psn(sa))
  206. {
  207. tr_printf(("AuxCache_GetBytes() - FAIL[1], invalid start addressn"));
  208. return FALSE;
  209. }
  210. }
  211. uiRetryCount = DVDSECT_MAX_RETRIES;
  212. }
  213. else 
  214. {
  215. /* Check for invalid requests */
  216. if (!drv_check_valid_lbn(dwNormLBN))
  217. {
  218. tr_printf(("AuxCache_GetBytes() - FAIL[2], invalid start addressn"));
  219. return FALSE;
  220. }
  221. uiRetryCount = CDSECT_MAX_RETRIES;
  222. }
  223. dbg_printf(("AuxCache_GetBytes() - Cache Miss %08lxn", dwNormLBN));
  224. /* Cache the needed data */
  225. do 
  226. {
  227. bResult = TRUE;
  228. /* If an Exception was thrown, abort */
  229. if (Exception_catchAndRethrow(EXCEPTION_MEDIUM_EJECTED | EXCEPTION_POWER_DOWN_REQUEST) ) 
  230. {
  231. tr_printf(("AuxCache_GetBytes() - Exception_catchAndRethrow[3]n"));
  232. bResult = FALSE;
  233. break;
  234. }
  235. if (IS_DVD_PHYSICAL_MEDIA)
  236. {
  237. wReadLength = DVDSECT_READ_LENGTH; /* Cache segment */
  238. /* Test whether the end LBN is valid */
  239. while (wReadLength > 1)
  240. {
  241. UINT32 sa = dwNormLBN + wReadLength - 1;
  242. drv_lsn2psn(&sa);
  243. if (!drv_is_valid_psn(sa))
  244. {
  245. wReadLength--;
  246. }
  247. else
  248. {
  249. break;
  250. }
  251. }
  252. }
  253. else
  254. {
  255. if (VCD_INFO_SECTOR_ADDR == dwNormLBN)
  256. {
  257. wReadLength = 2;
  258. }
  259. else
  260. {
  261. wReadLength = CDSECT_READ_LENGTH;
  262. }
  263. /* Test whether the end LBN is valid */
  264. while (wReadLength > 1)
  265. {
  266. if (!drv_check_valid_lbn(dwNormLBN + wReadLength - 1))
  267. {
  268. wReadLength--;
  269. }
  270. else
  271. {
  272. break;
  273. }
  274. }
  275. }
  276. /* Caching request from the decoder and the drive */
  277. dbg_printf(("AuxCache_GetBytes() - cache_sector...n"));
  278. DEC_CacheSector(dwNormLBN, wReadLength);
  279. dbg_printf(("AuxCache_GetBytes() - disc_read...n"));
  280. AuxCache_DiscReadBlock(dwNormLBN, wReadLength);
  281. /* Wait for the data to be cached */
  282. dbg_printf(("AuxCache_GetBytes() - wait_complete...n"));
  283. bResult = DEC_WaitCacheComplete();
  284. if (Exception_catchAndRethrow(EXCEPTION_MEDIUM_EJECTED | EXCEPTION_POWER_DOWN_REQUEST)) 
  285. {
  286. tr_printf(("AuxCache_GetBytes() - Exception_catchAndRethrow[4]n"));
  287. uiRetryCount = 0;
  288. break;
  289. }
  290. else if (!bResult)
  291. {
  292. //Hansen<<<04_09_22
  293. #ifdef MACESTROLINK_SUPPORT
  294. if(IS_PLAYING_MLNK)
  295. {
  296. MLNK_SET_ERROR();
  297. return FALSE;
  298. }
  299. #endif
  300. //Hansen>>>04_09_22
  301. uiRetryCount--;
  302. }
  303. while (!bResult && uiRetryCount);
  304. }
  305. }
  306. return bResult;
  307. }
  308. /////////////////////////////////////////////////////////////////////////////
  309. // Function name : AuxCache_GetFile
  310. // Purpose : Used to cache a large amount of consecutive data.
  311. // Input Parameters : dwLBN - logical start address.
  312. //   wNumOfBytes - number of sectors to be stored 
  313. // in the output buffer.
  314. //   dwOffset - offset within the start sector.
  315. //   dwTotalRequestedSize - the total requested size of the
  316. //  file that needs to be read.
  317. //   bRestart - Signals whether this is the first time the
  318. //  large caching request is posted.
  319. // Return type : BOOL - TRUE if successfull, FALSE otherwise.
  320. // Output Parameters: buff - the data buffer (whose size is wNumOfBytes).
  321. // Remarks : 1. Used for both CD and DVD.
  322. //   2. It is assumed that the cached data is consecutive.
  323. //   3. AuxCache_GetFileTerminate function should be called
  324. //  after finishing the use of this function.
  325. //   4. In contrary to AuxCache_GetBytes in which caches a
  326. //  fixed small number of bytes from the disc in cache
  327. //  miss this function request the total amount of data
  328. //  needed to be read from the drive.
  329. /////////////////////////////////////////////////////////////////////////////
  330. BOOL AuxCache_GetFile(DWORD dwLBN, DWORD dwOffset, WORD wNumOfBytes, 
  331.   DWORD dwTotalRequestedSize, BOOL bRestart, BYTE *buff)
  332. {
  333. static DWORD dwInitialOffset = 0UL; /* The start offset for the data */
  334. #ifdef SUPPORT_FLASH_CARD
  335. if (IS_PLAYING_CARD)
  336. {
  337. STRUCT_FILE *pfile = FCU_TEMP_FILE_STRCUT_ADDR;
  338. UINT32 actual_size;
  339. dbg_printf(("discGetFile, get bytes on card, lsn:%lx, offset:%lx, num: %x.n", dwLBN, dwOffset, wNumOfBytes));
  340. FileSys_FileSeek(pfile, 0, (dwLBN - Clips_GetCurrClipSartAddr())*LOGICAL_BLOCK_SIZE + dwOffset);
  341. if (FX_SUCCESS != FileSys_FileRead(pfile, buff, wNumOfBytes, &actual_size) || 0 == actual_size)
  342. {
  343. dbg_printf(("discGetBytes on card failed.n"));
  344. return FALSE;
  345. }
  346. // FileSys_FileClose(&file);
  347. return TRUE;
  348. }
  349. #endif
  350. if (Exception_catchAndRethrow(EXCEPTION_MEDIUM_EJECTED | EXCEPTION_POWER_DOWN_REQUEST)) 
  351. {
  352. dbg_printf(("AuxCache_GetFile() - Exception_catchAndRethrow[1]n"));
  353. return FALSE;
  354. }
  355. if (TRUE == bRestart)
  356. {
  357. DWORD dwBlockCount = (dwTotalRequestedSize + dwOffset + LOGICAL_BLOCK_SIZE - 1)/LOGICAL_BLOCK_SIZE;
  358. // <<< Robin_2004_0518_B, check the start/end address is valid
  359. if (IS_DVD_PHYSICAL_MEDIA)
  360. {
  361. /* the start address is already valid */
  362. while (dwBlockCount > 1)
  363. {
  364. UINT32 sa = dwLBN + dwBlockCount - 1;
  365. drv_lsn2psn(&sa);
  366. if (!drv_is_valid_psn(sa))
  367. {
  368. dwBlockCount--;
  369. dwBlockCount--;
  370. }
  371. else
  372. {
  373. break;
  374. }
  375. }
  376. }
  377. else
  378. {
  379. /* the start address is already valid */
  380. while (dwBlockCount > 1)
  381. {
  382. if (!drv_check_valid_lbn(dwLBN + dwBlockCount - 1))
  383. {
  384. dwBlockCount--;
  385. dwBlockCount--;
  386. }
  387. else
  388. {
  389. break;
  390. }
  391. }
  392. }
  393. // <<< Robin_2004_0518_B, check the start/end address is valid
  394. tr_printf(("AuxCache_GetFile - Start LBN: 0x%08lx, Offset: 0x%08lx, Total size: %ld bytesn",
  395. dwLBN, dwOffset, dwTotalRequestedSize));
  396. dwInitialOffset = dwOffset;
  397. drv_abort_play();
  398. DEC_Stop_DVP_cmd(0);
  399. /* Initialize the caching info */
  400. DEC_CacheInit();
  401. /* Check for invalid start LBN */
  402. if (IS_DVD_PHYSICAL_MEDIA) 
  403. {
  404. UINT32 sa = dwLBN;
  405. drv_lsn2psn(&sa); /* Covert LSN to PSN */
  406. if (!drv_is_valid_psn(sa))
  407. {
  408. tr_printf(("AuxCache_GetFile() - FAIL[1], invalid start addressn"));
  409. return FALSE;
  410. }
  411. }
  412. else 
  413. {
  414. if (!drv_check_valid_lbn(dwLBN))
  415. {
  416. tr_printf(("AuxCache_GetFile() - FAIL[2], invalid start addressn"));
  417. return FALSE;
  418. }
  419. }
  420. /* Request to read all of the given range from the DVP/Drive Driver */
  421. if (IS_DVD_PHYSICAL_MEDIA)
  422. {
  423. // DVD medium
  424. DWORD dwStartPSN = dwLBN;
  425. /* Signal to the DVP the new aux mode */
  426. DEC_SetCbSelect(DEC_LL_CBSELECT_DVD_AUX);
  427. drv_lsn2psn(&dwStartPSN);
  428. DEC_LL_SetDVDStartEndSector(dwStartPSN, dwBlockCount);
  429. DEC_DecryptionEnable(DEC_DECRYPT_BYPASS_DVD_E);
  430. DEC_Start_DVP_cmd();
  431. /* Give the drive the command to playback ALL of the request */
  432. drv_play_dvd(dwLBN, dwBlockCount, DRVF_PLAY_DVD_DUMP_DATA);
  433. }
  434. else
  435. {
  436. // CD medium
  437. DEC_SetCbSelect(DEC_LL_CBSELECT_CD_AUX);
  438. DEC_CD_SetPlaybackRange(dwLBN, dwBlockCount, UNLIMITED_FILE_SIZE);
  439. DEC_DecryptionEnable(DEC_DECRYPT_BYPASS_CD_E);
  440. DEC_Start_DVP_cmd();
  441. drv_play_cd_logical(DRVCF_CDSPEED_MAX|DRVF_PLAY_CD_DUMP_DATA, dwLBN, dwBlockCount);
  442. }
  443. /*
  444.  * Wait for the DVP to get the set playback range command and flush
  445.  * the In-FIFO.
  446.  */
  447. while (FALSE == DVP_API_GetSharedBit(DR_GENERAL_ADDR, IN_FIFO_FLUSH_SHARED_BIT))
  448. {
  449. /* If an Exception was thrown, abort */
  450. if (Exception_catchAndRethrow(EXCEPTION_MEDIUM_EJECTED)) 
  451. {
  452. dbg_printf(("AuxCache_GetFile() - Exception_catchAndRethrow[1]n"));
  453. return FALSE;
  454. }
  455. }
  456. /* Signal to the DVP that the CPU received the InFIFO flush indication */
  457. DVP_API_SetSharedBit(DR_GENERAL_ADDR, IN_FIFO_FLUSH_SHARED_BIT, FALSE);
  458. }
  459. /* Fill the output buffer with wNumOfBytes bytes */
  460. return DEC_CacheFile(dwInitialOffset, wNumOfBytes, buff, bRestart);
  461. }
  462. /////////////////////////////////////////////////////////////////////////////
  463. // Function name : AuxCache_GetFileTerminate
  464. // Purpose : Terminate AuxCache_GetFile caching operation.
  465. // Input Parameters : none.
  466. // Return type : none.
  467. // Output Parameters: none.
  468. //////////////////////////////////////////////////////////////////////////////
  469. void AuxCache_GetFileTerminate(void)
  470. {
  471. DEC_Stop_DVP_cmd((UINT8)0);
  472. /* Initialize the caching info */
  473. DEC_CacheInit();
  474. }