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

DVD

开发平台:

Others

  1. /****************************************************************************************
  2.  *  Copyright (c) 2000 ZORAN Corporation, All Rights Reserved
  3.  *  THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF ZORAN CORPORATION
  4.  *
  5.  *  File: $Workfile: WMA.c $             
  6.  *
  7.  * Description:
  8.  * ============
  9.  * WMA Clip implementation
  10.  *
  11.  * Log:
  12.  * ====
  13.  ****************************************************************************************
  14.  * Updates:
  15.  ****************************************************************************************
  16.  * $Log: /I76/I76_Common/I76_Reference/Playcore/Nav_Clips/WMA.c $
  17.  * 
  18.  * 12    3/05/04 3:00p Terencet
  19.  * correct can't get WMA stream information because wrong address
  20.  * 
  21.  * 11    2/13/04 7:05p Terencet
  22.  * handle WMA unsupported sample/bit rate on CPU side
  23.  * 
  24.  * 10    1/20/04 12:30p Chaol
  25.  * handle WMA unsupportted sample rate and bit rate on CPU side
  26.  * 
  27.  * 9     12/18/03 11:43a Leslie
  28.  * Abort drive each time after retriveing  ASF info from WMA file
  29.  * 
  30.  * 8     11/27/03 13:27 Nmaurer
  31.  * Use DEC_ReadCodeBufferFullness to get the BE buffers fullness
  32.  * 
  33.  * 7     11/15/03 7:11p Leslie
  34.  * Replace old  Video API Low Level Files with new ones
  35.  * 
  36.  * 6     11/10/03 11:33a Leonh
  37.  * Get Sampling rate for WMA
  38.  * 
  39.  * 5     03-03-04 11:34 Jerryc
  40.  * jerry cai, merge new nav clips lib 
  41.  * 
  42.  * 3     03-01-10 12:21 Leslie
  43.  * Add wide-character strings support
  44.  * 
  45.  * 2     03-01-09 12:30 Leslie
  46.  * 
  47.  * 1     10/30/02 18:06 Rond
  48.  * 
  49.  * 1     11/09/02 15:49 Atai
  50.  * 
  51.  * 2     22/08/02 18:18 Nirm
  52.  * - First revision.
  53.  * 
  54.  * 1     16/08/02 14:52 Nirm
  55.  ****************************************************************************************/
  56. #include "Config.h" // Global Configuration - do not remove!
  57. #ifdef _DEBUG
  58. #undef IFTRACE
  59. #define IFTRACE if (gTraceNavigator)
  60. #include "DebugDbgMain.h"
  61. #endif
  62. #include "Includemath-macro.h"
  63. //#include "KernelEventDef.H"
  64. #include "DecoderDecoder.h"
  65. #include "DecoderDec_defs.h"
  66. #include "Decoderlow_levelDEC_LL_Def.h"
  67. #include "Drivedrv_api.h"
  68. #include "Drivedrv_defs.h"
  69. #include "LogoLogo.h"
  70. #include "PlaycoreCoremainCoreGDef.h"
  71. #include "PlaycoreAuxCacheAuxCache.h"
  72. #include "PlaycoreFileSysFileSystem.h"
  73. #include "PlaycoreNav_ClipsWMA_ASF.h"
  74. #include "PlaycoreNav_ClipsWMA.h"
  75. #include "PlaycoreNav_ClipsClip_Impl.h"
  76. #include "PlaycoreNav_ClipsGenericClip.h"
  77. #include "PlaycoreNav_ClipsNav_Clips.h"
  78. #include "PlaycoreNav_ClipsPE_Clips.h"
  79. //JerryCAI_0923_2003_A
  80. extern DEC_DISC_TYPE gDiskType;
  81. /////////////////////////////////////////////////////////////////////////////
  82. // General WMA
  83. /////////////////////////////////////////////////////////////////////////////
  84. /////////////////////////////////////////////////////////////////////////////
  85. // Common Structures & Types
  86. /////////////////////////////////////////////////////////////////////////////
  87. // Globals and Singletons
  88. #define g_ASFInfoCache gns.clips.globals.wmaGlobals.g_ASFInfoCache
  89. /*
  90. ADP didn't handle the unsupported sample rate and bit rate, in I54, it's handle by CPU
  91. Currently, the WMA decoder supports the following sampling and bit rates:
  92. 1. Sampling rates: 32kHz, 44.1 kHz, and 48 kHz
  93. 2. Bit rates: 32 kbps or higher
  94. */
  95. #ifdef CLIPS_WMA_UNSUPPORTRATE_HANDLE_BY_CPU
  96. #define WMA_SUPPORTED_SAMPLINGRATE_MIN 32000UL
  97. #define WMA_SUPPORTED_SAMPLINGRATE_MAX 48000UL
  98. #define WMA_BITRATE_MARGIN 1000UL
  99. #define WMA_SUPPORTED_BITRATE_MIN (32000UL-WMA_BITRATE_MARGIN)
  100. #define WMA_SUPPORTED_BITRATE_MAX 384000UL
  101. #define bWMAUnsupportedRate gns.clips.globals.wmaGlobals.bWMAUnsupportedRate
  102. #endif
  103. #if (defined(CLIPS_ACQUIRE_EXTENDED_INFO) && defined(CLIPS_WMA_EXTRACT_CONTENT_DESC))
  104. CONST GUID g_guidHeaderObj= HEADER_OBJECT_GUID;
  105. CONST GUID g_guidPropertiesObj= PROPERTIES_OBJECT_GUID;
  106. CONST GUID g_guidStreamPropertiesObj= STREAM_PROPERTIES_OBJECT_GUID;
  107. CONST GUID g_guidAudioStreamPropertiesObj= AUDIO_STREAM_PROPERTIES_GUID;
  108. CONST GUID g_guidContentDescriptionObj= CONTENT_DESCRIPTION_OBJECT_GUID;
  109. #endif //(defined(CLIPS_ACQUIRE_EXTENDED_INFO) && defined(CLIPS_WMA_EXTRACT_CONTENT_DESC))
  110. /////////////////////////////////////////////////////////////////////////////
  111. // Private Services
  112. /////////////////////////////////////////////////////////////////////////////
  113. // _convertUnicodeToASCII()
  114. //
  115. // Description: Converts a Unicode string into native ASCII.
  116. //
  117. // Input: i_pszUnicode - A Unicode string to convert.
  118. // uSourceLength - The length, in Bytes, of the source Unicode string.
  119. // Output: o_pszTargetAscii - A target string, to hold the resulting ASCII
  120. //    representation.
  121. // In/Out: None
  122. // Return: None
  123. //
  124. // Remarks:
  125. // 1. A source Unicode string holds wide-characters, each 2-Bytes long.
  126. //    These are converted to the equivalent single-Byte ANSI characters, if
  127. //    such a conversion is possible.
  128. // 2. The size of the target ASCII string must be at least half that of the
  129. //    source Unicode string in order to accomodate the full conversion.
  130. static void _convertUnicodeToASCII(const WCHAR *i_pszUnicode, LPSTR o_pszTargetAscii,
  131.    UINT8 uSourceLength)
  132. {
  133. UINT8 uPos;
  134. UINT8 uEffectiveLength= (MIN(uSourceLength, (2*WMA_TEXT_LENGTH)) / 2);
  135. dbg_printf(("_convertUnicodeToASCII() calling.n"));
  136. for (uPos=0; uPos < uEffectiveLength; uPos++) {
  137. char wcCharHigh= ((i_pszUnicode[uPos] >> 8) & 0xFF);
  138. char wcCharLow= (i_pszUnicode[uPos] & 0xFF);
  139. char cAsciiEquivalent;
  140. if (wcCharHigh >= 0x03)
  141. cAsciiEquivalent= '?'; // No ASCII equivalent
  142. else
  143. cAsciiEquivalent= wcCharLow;
  144. o_pszTargetAscii[uPos]= cAsciiEquivalent;
  145. }
  146. // NULL-terminate the constructed string
  147. o_pszTargetAscii[uPos]= 0;
  148. return;
  149. }
  150. /////////////////////////////////////////////////////////////////////////////
  151. // _acquireASFInfo()
  152. //
  153. // Description: Acquires the ASF-Information for a Clip
  154. //
  155. // Input: dwClipStartAddr - The start-address of the Clip
  156. // Output: o_pInfo - Points to an ASFInfo structure, to receive the result
  157. // In/Out: None
  158. // Return: TRUE if the ASF-Information was extracted successfully;
  159. // FALSE otherwise.
  160. //
  161. // Remarks:
  162. // ASF Information is extracted from the Header and Properties Objects of
  163. // the stream.
  164. static BOOL _acquireASFInfo(DWORD dwClipStartAddr, ASFInfo *o_pInfo)
  165. {
  166. DWORD cbOffset;
  167. DWORD dwHeadersCnt;
  168. DWORD cbObjectSize;
  169. BYTE  aObjectBuff[sizeof(HeaderObject)];
  170. // Read the Header-Object's base, and verify that this is indeed a Header Object
  171. if ( !AuxCache_GetBytes(dwClipStartAddr, 0, sizeof(aObjectBuff), aObjectBuff)
  172. #if (defined(CLIPS_ACQUIRE_EXTENDED_INFO) && defined(CLIPS_WMA_EXTRACT_CONTENT_DESC))
  173. ||
  174.  (0 != memcmp(aObjectBuff, &g_guidHeaderObj, sizeof(GUID))) 
  175. #endif
  176.  )
  177. {
  178. dbg_printf(("WARNING: _acquireASFInfo() Failed [1]n"));
  179. return FALSE;
  180. }
  181. // Extract the Headers-Count
  182. dwHeadersCnt= ((HeaderObject*)aObjectBuff)->dwHeadersCnt;
  183. // Extract the Total Size of the Header-Object
  184. // NOTE: The following line assumes that the Object's size is a 32-bit
  185. //       number (the high 32-bits are ignored).
  186. o_pInfo->cbHeaderSize= LE_QWORD_LOW(((struct ObjectBase*)aObjectBuff)->cbSize);
  187. // Scan the ASF Headers, looking for a Properties Object
  188. cbOffset= sizeof(HeaderObject);
  189. while (dwHeadersCnt > 0) {
  190. // Read the next Object
  191. if (!AuxCache_GetBytes(dwClipStartAddr, cbOffset, sizeof(ContentDescriptionObject), 
  192.   aObjectBuff)) 
  193. {
  194. dbg_printf(("WARNING: _acquireASFInfo() Failed [2]n"));
  195. break;
  196. }
  197. // Extract the Object's Size
  198. // NOTE: The following line assumes that the Object's size is a 32-bit
  199. //       number (the high 32-bits are ignored).
  200. cbObjectSize= LE_QWORD_LOW(((struct ObjectBase*)aObjectBuff)->cbSize);
  201. #if (defined(CLIPS_ACQUIRE_EXTENDED_INFO) && defined(CLIPS_WMA_EXTRACT_CONTENT_DESC))
  202. // Check if this is a Properties Object
  203. if (0 == memcmp(aObjectBuff, &g_guidPropertiesObj, sizeof(GUID))) {
  204. break;
  205. }
  206. #endif
  207. // This isn't the required Object - continue to the next one
  208. dwHeadersCnt--;
  209. // NOTE: The following line assumes that the Object's length is a 32-bit
  210. //       number (the high 32-bits are ignored).
  211. cbOffset += cbObjectSize;
  212. }
  213. // Check if the required Object was found
  214. if (0 == dwHeadersCnt)
  215. return FALSE;
  216. // Now extract the Maximum size of Interleaved Packets
  217. cbOffset += PROPERTIES_OBJECT_MAX_PKT_SIZE_OFFSET;
  218. if (!AuxCache_GetBytes(dwClipStartAddr, cbOffset, sizeof(DWORD), 
  219.   (BYTE*)&o_pInfo->cbPacketSize)) 
  220. {
  221. dbg_printf(("WARNING: _acquireASFInfo() Failed [3]n"));
  222. return FALSE;
  223. }
  224. return TRUE;
  225. }
  226. /////////////////////////////////////////////////////////////////////////////
  227. // Public Services
  228. #pragma argsused
  229. void WMA_setPresentationTime(UINT8 uPresentationTime)
  230. {
  231. dbg_printf(("WARNING: WMA_setPresentationTime() Failed: WMA Clips cannot have a presentation time.n"));
  232. }
  233. #if (defined(CLIPS_ACQUIRE_EXTENDED_INFO) && defined(CLIPS_WMA_EXTRACT_CONTENT_DESC))
  234. BOOL WMA_GetWMAInfo(DWORD dwClipStartAddr,
  235.    WORD i_pExtInfo_sc_handle)
  236. {
  237. WORD *pCurrTextLen;
  238. DWORD cbOffset;
  239. DWORD dwHeadersCnt;
  240. DWORD cbObjectSize;
  241. BYTE  aObjectBuff[sizeof(ContentDescriptionObject)];
  242. BYTE  ucContentCnt;
  243. WCHAR szUnicodeText[WMA_TEXT_LENGTH];
  244. LPWSTR pszDestTextField;
  245. //Angie_0810_2004:Move the MP3 and WMA extend info from gns to SCPAD for I86 memory reducing.
  246. WMA_ExtendInfo o_pInfoDesc;
  247. //Stivenz_1131_2004: fix WMA extendinfo display error.
  248. memset(&o_pInfoDesc,0,sizeof(WMA_ExtendInfo));
  249. // Read the Header-Object's base, and verify that this is indeed a Header Object
  250. if ( !AuxCache_GetBytes(dwClipStartAddr, 0, sizeof(aObjectBuff), aObjectBuff) 
  251. #if (defined(CLIPS_ACQUIRE_EXTENDED_INFO) && defined(CLIPS_WMA_EXTRACT_CONTENT_DESC))
  252. ||
  253.  (0 != memcmp(aObjectBuff, &g_guidHeaderObj, sizeof(GUID))) 
  254. #endif
  255.  )
  256. {
  257. dbg_printf(("WARNING: WMA_GetWMAInfo() Failed [1]n"));
  258. return FALSE;
  259. }
  260. // Extract the Headers-Count
  261. dwHeadersCnt= ((HeaderObject*)aObjectBuff)->dwHeadersCnt;
  262. // Scan the ASF Headers, looking for a Content-Description Object
  263. cbOffset= sizeof(HeaderObject);
  264. while (dwHeadersCnt > 0) {
  265. // Read the next Object
  266. if (!AuxCache_GetBytes(dwClipStartAddr, cbOffset, sizeof(ContentDescriptionObject), 
  267.   aObjectBuff)) 
  268. {
  269. dbg_printf(("WARNING: WMA_GetWMAInfo() Failed [2]n"));
  270. break;
  271. }
  272. // Extract the Object's Size
  273. // NOTE: The following line assumes that the Object's size is a 32-bit number (the high 32-bits are ignored).
  274. cbObjectSize= LE_QWORD_LOW(((struct ObjectBase*)aObjectBuff)->cbSize);
  275. // Check if this is a audio stream properties Object
  276. if (0 == memcmp(aObjectBuff, &g_guidStreamPropertiesObj, GUID_SIZE))
  277. {
  278. DWORD streamTypeIDOffset;
  279. streamTypeIDOffset = cbOffset+OBJECT_HEADER_SIZE;
  280. // get the stream type from steam properties object
  281. if (AuxCache_GetBytes(dwClipStartAddr, streamTypeIDOffset, GUID_SIZE, aObjectBuff)) 
  282. {
  283. // Check if this is a ASF_Audio_Media
  284. if (0 == memcmp(aObjectBuff, &g_guidAudioStreamPropertiesObj, GUID_SIZE) )
  285. {
  286. DWORD TypeSpecificOffset;
  287. TypeSpecificOffset = cbOffset+TYPE_SPECIFIC_DATA_ADD;
  288. if (AuxCache_GetBytes(dwClipStartAddr, TypeSpecificOffset, sizeof(WAVEFORMATEX), aObjectBuff)) 
  289. {
  290. memcpy(&(gns.clips.iClipSamplingRate), (unsigned char *) (&aObjectBuff [4]), sizeof(gns.clips.iClipSamplingRate));
  291. #ifdef CLIPS_WMA_UNSUPPORTRATE_HANDLE_BY_CPU
  292. {
  293. UINT32 ulAverageBitRate;
  294. memcpy(&ulAverageBitRate, (unsigned char *) (&aObjectBuff [8]), sizeof(ulAverageBitRate));
  295. ulAverageBitRate = 8*ulAverageBitRate;
  296. if( (gns.clips.iClipSamplingRate < WMA_SUPPORTED_SAMPLINGRATE_MIN)||
  297. (ulAverageBitRate < WMA_SUPPORTED_BITRATE_MIN) )
  298. {
  299. bWMAUnsupportedRate = TRUE;
  300. if(gns.clips.iClipSamplingRate < WMA_SUPPORTED_SAMPLINGRATE_MIN)
  301. tr_printf(("nWMA unsupported sampling rate= %8ldn", gns.clips.iClipSamplingRate));
  302. if(ulAverageBitRate < WMA_SUPPORTED_BITRATE_MIN)
  303. tr_printf(("nWMA unsupported bit rate= %8ldn", ulAverageBitRate));
  304. }
  305. else
  306. bWMAUnsupportedRate = FALSE;
  307. }
  308. #endif
  309. }
  310. else
  311. {
  312. dbg_printf(("WARNING: WMA get Audio Stream Type Specific Data Failedn"));
  313. }
  314. }
  315. else
  316. {
  317. dbg_printf(("WARNING: WMA is not a standard ASF audion"));
  318. }
  319. }
  320. else
  321. {
  322. dbg_printf(("WARNING: WMA get Audio Stream Type ID Failedn"));
  323. }
  324. }
  325. // Check if this is a Contents-Description Object
  326. else if (0 == memcmp(aObjectBuff, &g_guidContentDescriptionObj, sizeof(GUID)))
  327. {
  328. DWORD ContentDescriptionOffset;
  329. ContentDescriptionOffset = cbOffset+sizeof(ContentDescriptionObject);
  330. // Extract the relevant fields of the Content-Description Object
  331. pCurrTextLen= (WORD*)&aObjectBuff[sizeof(struct ObjectBase)];
  332. pszDestTextField= o_pInfoDesc.szTitle;
  333. // Collect the text: Title/Author/Copyright/Description
  334. for (ucContentCnt=0; ucContentCnt < 4; ucContentCnt++) {
  335. // Copy the current field to the Unicode-buffer
  336. if (!AuxCache_GetBytes(dwClipStartAddr, ContentDescriptionOffset, sizeof(szUnicodeText), (BYTE*)szUnicodeText)) {
  337. dbg_printf(("WARNING: WMA_GetWMAInfo() Failed [3]n"));
  338. continue;
  339. }
  340. // NOTE: The text is given in Little-Endian order, since it originates from a PC
  341. if (*pCurrTextLen) {
  342. #ifdef MOTOROLA
  343. swab((LPSTR)szUnicodeText, (LPSTR)pszDestTextField, sizeof(szUnicodeText));
  344. #else
  345. memcpy(pszDestTextField, szUnicodeText, sizeof(szUnicodeText));
  346. #endif //MOTOROLA
  347. pszDestTextField[WMA_TEXT_LENGTH-1]= 0;
  348. }
  349. // Continue to the next field
  350. ContentDescriptionOffset += *pCurrTextLen;
  351. pCurrTextLen++;
  352. pszDestTextField += (WMA_TEXT_LENGTH+1);
  353. }
  354. }
  355. // continue to the next object
  356. dwHeadersCnt--;
  357. // NOTE: The following line assumes that the Object's length is a 32-bit number (the high 32-bits are ignored).
  358. cbOffset += cbObjectSize;
  359. }
  360. sc_SetBytes(i_pExtInfo_sc_handle,0,sizeof(WMA_ExtendInfo),(BYTE *)&o_pInfoDesc);
  361. return TRUE;
  362. }
  363. #endif //(defined(CLIPS_ACQUIRE_EXTENDED_INFO) && defined(CLIPS_WMA_EXTRACT_CONTENT_DESC))
  364. /////////////////////////////////////////////////////////////////////////////
  365. // WMA Clip
  366. /////////////////////////////////////////////////////////////////////////////
  367. /////////////////////////////////////////////////////////////////////////////
  368. // Forward Declarations of Virtual Methods
  369. BOOL WMAClip_getExtendedInfo(const struct Clip_TAG *i_pThis, 
  370.  WORD i_pExtInfo_sc_handle);
  371. BOOL WMAClip_play(Clip *i_pThis, const ClipMarker *i_pResumeMarker,
  372.   BOOL bCacheOnly);
  373. enClipStatus WMAClip_getStatus(const Clip *i_pThis);
  374. void WMAClip_refresh(Clip *i_pThis);
  375. /////////////////////////////////////////////////////////////////////////////
  376. // Const Factory
  377. // Valid Extenions List
  378. BEGIN_CLIP_VALID_EXTENSIONS_MAP(WMA)
  379. CLIP_VALID_EXTENSIONS_ENTRY(L"WMA")
  380. END_CLIP_VALID_EXTENSIONS_MAP()
  381. // Constant Attributes
  382. DECLARE_CLIP_CONST_ATTR(WMA, 
  383. DECLARE_CLIP_VTABLE(WMAClip_getExtendedInfo,
  384. WMAClip_play,
  385. GenericClip_pause,
  386. WMAClip_getStatus,
  387. GenericClip_abort,
  388. GenericClip_recordMarker,
  389. WMAClip_refresh,
  390. GenericClip_getTime,
  391. GenericClip_digest,
  392. GenericClip_scan
  393. ),
  394. eClipType_WMA,
  395. DEC_ASID_WMA, 0xFF, DEC_DISC_TYPE_WMA,
  396. eCA_Markable,
  397. NULL
  398. )
  399. /////////////////////////////////////////////////////////////////////////////
  400. // Public Services
  401. BOOL WMAClip_isKindOf(LPCWSTR i_pszFilename)
  402. {
  403. return GenericClip_isKindOf(i_pszFilename, CLIP_VALID_EXTENSIONS(WMA));
  404. }
  405. void WMAClip_construct(Clip *o_pThis, const FindData *i_pFileInfo)
  406. {
  407. GenericClip_construct(o_pThis, i_pFileInfo);
  408. o_pThis->m_pConstAttr= &CLIP_CONST_ATTR(WMA);
  409. }
  410. /////////////////////////////////////////////////////////////////////////////
  411. // Virtual Methods
  412. BOOL WMAClip_getExtendedInfo(const struct Clip_TAG *i_pThis, 
  413.  WORD i_pExtInfo_sc_handle)
  414. {
  415. BOOL bSuccess= FALSE;
  416. dbg_printf(("WMAClip_getExtendedInfo()n"));
  417. #ifdef CLIPS_WMA_EXTRACT_CONTENT_DESC
  418. ASSERT(NULL != i_pExtInfo_sc_handle)
  419. bSuccess= WMA_GetWMAInfo(i_pThis->m_cfiInfo.dwFileLocation, 
  420. i_pExtInfo_sc_handle);
  421. #endif //CLIPS_WMA_EXTRACT_CONTENT_DESC
  422. return bSuccess;
  423. }
  424. BOOL WMAClip_play(Clip *i_pThis, const ClipMarker *i_pResumeMarker,
  425.   BOOL bCacheOnly)
  426. {
  427. BOOL bAudioPacketPosAvailable= FALSE;
  428. ASFInfo *pASFInfo;
  429. dbg_printf(("WMAClip_play()n"));
  430.    gDiskType = (i_pThis->m_pConstAttr)->m_eBitstreamType; //gDiskType must be set before calling DEC_prepare_to_decode().
  431. // Acquire this Clip's ASF-Info from the Cache
  432. pASFInfo= &g_ASFInfoCache.asfInfo;
  433. // Check if the ASF-Info should be acquired
  434. if ((NULL == i_pResumeMarker) && 
  435. (g_ASFInfoCache.dwID != (i_pThis->m_cfiInfo).dwFileLocation))
  436. {
  437. if (_acquireASFInfo((i_pThis->m_cfiInfo).dwFileLocation, pASFInfo)) 
  438. {
  439. g_ASFInfoCache.dwID= (i_pThis->m_cfiInfo).dwFileLocation;
  440. }
  441. else
  442. {
  443. tr_printf(("nWarning: Corrupted file!n"));
  444. // Stop the Clock
  445. PE_Clips_EnableClock(FALSE, TRUE, 0);
  446. DEC_CacheInit();
  447. //abort playback if ASF info unavailable
  448. GenericClip_abort(i_pThis,TRUE);
  449. // bWMAUnsupportedRate = TRUE;
  450. return TRUE;
  451. }
  452. }
  453. drv_abort_play();// abort drive after reading ASF-Info from Drive
  454. // Set the Audio-Packet Offset to Zero by default
  455. #ifndef D_ENABLE_DIVX_WMA_SUPPORT
  456. DEC_WMA_SetAudioPacketHeaderOffset(0);
  457. #endif
  458. // In case of playback-resumption, calculate the position of the next 
  459. // Audio-Packet Header.
  460. if ((NULL != i_pResumeMarker) && 
  461. (g_ASFInfoCache.dwID == (i_pThis->m_cfiInfo).dwFileLocation)) 
  462. {
  463. UINT32 cbFileOffset;
  464. DWORD  cbAudioPacketOffset;
  465. cbFileOffset= (LOGICAL_BLOCK_SIZE * 
  466.    (i_pResumeMarker->dwAddress - (i_pThis->m_cfiInfo).dwFileLocation));
  467. cbAudioPacketOffset= 
  468. ( pASFInfo->cbPacketSize - 
  469.   ((cbFileOffset - pASFInfo->cbHeaderSize - 
  470. sizeof(DataSectionIntroductionObject)) % pASFInfo->cbPacketSize) );
  471. // Inform the Decoder about the offset
  472. #ifndef D_ENABLE_DIVX_WMA_SUPPORT
  473. DEC_WMA_SetAudioPacketHeaderOffset(cbAudioPacketOffset);
  474. #endif
  475. bAudioPacketPosAvailable= TRUE;
  476. }
  477. // Override the Resume-Marker if the Audio-Packet position isn't available
  478. return GenericClip_play(i_pThis, 
  479. (bAudioPacketPosAvailable ? i_pResumeMarker : NULL), 
  480. bCacheOnly);
  481. }
  482. #pragma argsused
  483. enClipStatus WMAClip_getStatus(const Clip *i_pThis)
  484. {
  485. #ifdef CLIPS_WMA_UNSUPPORTRATE_HANDLE_BY_CPU
  486. if( bWMAUnsupportedRate )
  487. {
  488. bWMAUnsupportedRate = FALSE;
  489. return eCS_Error_UnsupportedFormat;
  490. }
  491. #endif
  492. if (drv_is_play_done() && DEC_IsPlaybackFinished(FALSE))
  493. return eCS_Finished;
  494. #ifdef CLIPS_WMA_READ_ADP_STATUS
  495. {
  496. UINT8 uStatus;
  497. uStatus= DEC_WMA_getStatus();
  498. switch (uStatus)
  499. {
  500. case WMA_STAT_ERR_UNSUPPORTED:
  501. tr_printf(("WMAClip_getStatus : WMA_STAT_ERR_UNSUPPORTEDn"));
  502. return eCS_Error_UnsupportedFormat;
  503. case WMA_STAT_ERR_FATAL:
  504. tr_printf(("WMAClip_getStatus : WMA_STAT_ERR_FATALn"));
  505. return eCS_Error_Decoding;
  506. }
  507. }
  508. #endif //CLIPS_WMA_READ_ADP_STATUS
  509. return eCS_Busy;
  510. }
  511. #pragma argsused
  512. void WMAClip_refresh(Clip *i_pThis)
  513. {
  514. if (PST_PLAY == gcs.pstate) {
  515. BOOL bEnableClock= (0 != DEC_ReadCodeBufferFullness(DEC_AUDIO_CODE_BUFFER, DEC_FULLNESS_IN_BYTES));
  516. PE_Clips_EnableClock(bEnableClock, FALSE, 0);
  517. }
  518. }