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

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: MP3.c $             
  6.  *
  7.  * Description:
  8.  * ============
  9.  * MP3 Clip implementation
  10.  *
  11.  * Log:
  12.  * ====
  13.  ****************************************************************************************
  14.  * Updates:
  15.  ****************************************************************************************
  16.  * $Log: /I76/I76_Common/I76_Reference/Playcore/Nav_Clips/MP3.c $
  17.  * 
  18.  ****************************************************************************************/
  19. #include "Config.h" // Global Configuration - do not remove!
  20. #ifdef _DEBUG
  21. #undef IFTRACE
  22. #define IFTRACE if (gTraceNavigator)
  23. #include "DebugDbgMain.h"
  24. #endif
  25. #include "DecoderDecoder.h"
  26. #include "DecoderDec_defs.h"
  27. #include "Decoderlow_levelDEC_LL_Def.h"
  28. #include "Drivedrv_api.h"
  29. #include "Drivedrv_defs.h"
  30. #include "LogoLogo.h"
  31. #include "PlaycoreCoremainCoreGDef.h"
  32. #include "PlaycoreAuxCacheAuxCache.h"
  33. #include "PlaycoreFileSysFileSystem.h"
  34. #include "PlaycoreNav_ClipsMP3.h"
  35. #include "PlaycoreNav_ClipsClip_Impl.h"
  36. #include "PlaycoreNav_ClipsGenericClip.h"
  37. #include "PlaycoreNav_ClipsNav_Clips.h"
  38. #include "PlaycoreNav_ClipsPE_Clips.h"
  39. #include "PlaycoreNav_CDDAPE_CD.h"
  40. /////////////////////////////////////////////////////////////////////////////
  41. // General MP3
  42. /////////////////////////////////////////////////////////////////////////////
  43. #define m_frameBytes  gns.clips.globals.mp3Globals.m_frameBytes
  44. #define dwUsPerFrame  gns.clips.globals.mp3Globals.dwUsPerFrame
  45. #define aHeaderBuffer  gns.clips.globals.mp3Globals.aHeaderBuffer
  46. #define uiBuffNo  gns.clips.globals.mp3Globals.uiBuffNo
  47. #define dwClipStartAddrForHeadBuffer gns.clips.globals.mp3Globals.dwClipStartAddrForHeadBuffer
  48. #define m_pXingHeader  gns.clips.globals.mp3Globals.m_pXingHeader
  49. #define ucMP3PlayabckFinishedCounter gns.clips.globals.mp3Globals.ucMP3PlayabckFinishedCounter
  50. typedef struct
  51. {
  52.    int sync; /* 1 if valid sync */
  53.    int id;
  54.    int option;
  55.    int prot;
  56.    int br_index;
  57.    int sr_index;
  58.    int pad;
  59.    int private_bit;
  60.    int mode;
  61.    int mode_ext;
  62.    int cr;
  63.    int original;
  64.    int emphasis;
  65. } MPEG_HEAD;
  66. static CONST int mp_br_table[2][16] = 
  67. {
  68. {0, 8 , 16, 24, 32, 40, 48, 56 , 64 , 80 , 96 , 112, 128, 144, 160, 0},
  69. {0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 0}
  70. };
  71. static CONST int mp_sr20_table[2][4] = 
  72. {
  73. {441, 480, 320, -999}, 
  74. {882, 960, 640, -999}
  75. };
  76. static CONST int mp_br_tableL1[2][16] = 
  77. {
  78. {0, 32, 48, 56, 64 , 80 , 96 , 112, 128, 144, 160, 176, 192, 224, 256, 0}, /* mpeg2 */
  79. {0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 0}
  80. };
  81. static CONST int mp_br_tableL3[2][16] = 
  82. {
  83. {0, 8 , 16, 24, 32, 40, 48, 56, 64 , 80 , 96 , 112, 128, 144, 160, 0}, /* mpeg 2 */
  84. {0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 0}
  85. };
  86. static CONST DWORD sample_rate_table[8] =
  87. {
  88.     22050L, 24000L, 16000L, 1L, 44100L, 48000L, 32000L, 1L
  89. };
  90. static CONST int l[4] = {25, 3, 2, 1};
  91. static int head_info(DWORD offset, unsigned int n, MPEG_HEAD * h);
  92. static int head_info3(DWORD offset, unsigned int n, MPEG_HEAD *h, unsigned int *searchForward); 
  93. static int head_info2(DWORD offset, unsigned int n, MPEG_HEAD * h);
  94. static void GetBitstreamStats(DWORD dwClipStartAddr, int *piTotalSeconds);
  95. static BOOL GetHeadInfo(DWORD dwClipStartAddr, MPEG_HEAD * pm_sMpegHead, int *pm_frameBytes);
  96. static void InitHeaderBuff(BYTE * buff, DWORD dwClipStartAddr);
  97. static BYTE GetCharFromDisc(DWORD n);
  98. static BOOL GetXingHeader(XHEADDATA *X,  DWORD offset);
  99. ////////////////////////////////////////////////////////////////////////////
  100. // Forward Declarations of Virtual Methods
  101. BOOL MP3Clip_getExtendedInfo(const struct Clip_TAG *i_pThis, 
  102.  WORD i_pExtInfo_sc_handle);
  103. void MP3Clip_refresh(Clip *i_pThis);
  104. enClipStatus MP3_getStatus(const Clip *i_pThis);
  105. void MP3_scan(Clip *i_pThis, int iScanSpeed);
  106. void MP3_recordMarker(Clip *i_pThis, ClipMarker *o_pMarker);
  107. void MP3_pause(Clip *i_pThis, BOOL bEnable);
  108. BOOL MP3_play(Clip *i_pThis, const ClipMarker *i_pResumeMarker,
  109.   BOOL bCacheOnly);
  110. UINT16 MP3Clip_GetTime(Clip *i_pThis);
  111. /////////////////////////////////////////////////////////////////////////////
  112. // Constants and Enumerations
  113. #define MAX_FRAME_SIZE 1441L
  114. #define NUM_OF_SANITY_CHECK 3L
  115. #define INITIAL_FRAME_SIZE (MAX_FRAME_SIZE * NUM_OF_SANITY_CHECK)
  116. #define MAX_DECODING_RETRY 32
  117. #define TEMP_BUFF_SIZE 128
  118. #define FRAMES_FLAG 0x0001
  119. #define BYTES_FLAG 0x0002
  120. #define MPEG_FRAMES_TO_SAMPLE 80
  121. #define ID3_GENRE_COUNT 116
  122. #define ID3_GENRE_DEFAULT 255
  123. #ifdef EXINO2 // ZKR GL041804 : No need to delay fo finishing the playback.
  124. #define DEFAULT_MP3_PLAYBACK_FINISHED_COUNTER 0
  125. #else 
  126. #define DEFAULT_MP3_PLAYBACK_FINISHED_COUNTER 10
  127. #endif
  128. LPWSTR _str2wcs(LPCSTR pszSource, LPWSTR pszDest, unsigned int cbDestSize);
  129. /////////////////////////////////////////////////////////////////////////////
  130. // Globals and Singletons
  131. // Valid Extenions List
  132. BEGIN_CLIP_VALID_EXTENSIONS_MAP(MP3)
  133. CLIP_VALID_EXTENSIONS_ENTRY(L"MP3")
  134. CLIP_VALID_EXTENSIONS_ENTRY(L"MP2")
  135. END_CLIP_VALID_EXTENSIONS_MAP()
  136. // Constant Attributes
  137. DECLARE_CLIP_CONST_ATTR(MP3, 
  138. DECLARE_CLIP_VTABLE(MP3Clip_getExtendedInfo,
  139. MP3_play,
  140. MP3_pause,
  141. MP3_getStatus,
  142. GenericClip_abort,
  143. MP3_recordMarker,
  144. MP3Clip_refresh,
  145. MP3Clip_GetTime,
  146. GenericClip_digest,
  147. MP3_scan
  148. ),
  149. eClipType_MP3,
  150. DEC_ASID_MP3, 0xFF, DEC_DISC_TYPE_MP3,
  151. ( eCA_Markable | eCA_Scanable ),
  152. NULL
  153. )
  154. #ifdef MOTOROLA
  155. #define BE_DWORD(a) a
  156. #define BE_WORD(a) a
  157. #else
  158. #define BE_DWORD(a) (DWORD)((a << 24) | ((a & 0xFF00) << 8) | ((a & 0xFF0000L) >> 8) | ((a & 0xFF000000L) >> 24))
  159. #define BE_WORD(a) (WORD)((a << 8) | (a >> 8))
  160. #endif // MOTOROLA
  161. #if (defined(CLIPS_ACQUIRE_EXTENDED_INFO) && defined(CLIPS_MP3_EXTRACT_ID3V1_TAG))
  162. BOOL isFailedToReadMP3Head = FALSE;
  163. static CONST LPSTR g_pszEmptyField= "                              ";
  164. static CONST LPWSTR g_aMP3_ID3Genres[ID3_GENRE_COUNT+1] =
  165. { L"", L"Blues", L"Classic Rock", L"Country", L"Dance", L"Disco", L"Funk", L"Grunge", 
  166.   L"Hip-Hop", L"Jazz", L"Metal", L"New Age", L"Oldies", L"Other", L"Pop", L"R&B", 
  167.   L"Rap", L"Reggae", L"Rock", L"Techno", L"Industrial", L"Alternative", L"Ska", 
  168.   L"Death Metal", L"Pranks", L"Soundtrack", L"Euro-Techno", L"Ambient", 
  169.   L"Trip-Hop", L"Vocal", L"Jazz+Funk", L"Fusion", L"Trance", L"Classical", 
  170.   L"Instrumental", L"Acid", L"House", L"Game", L"Sound Clip", L"Gospel", L"Noise", 
  171.   L"Alt. Rock", L"Bass", L"Soul", L"Punk", L"Space", L"Meditative", L"Instrumental Pop",
  172.   L"Instrumental Rock", L"Ethnic", L"Gothic", L"Darkwave", L"Techno-Industrial", 
  173.   L"Electronic", L"Pop-Folk", L"Eurodance", L"Dream", L"Southern Rock", L"Comedy", 
  174.   L"Cult", L"Gangsta", L"Top 40", L"Christian Rap", L"Pop/Funk", L"Jungle", 
  175.   L"Native American", L"Cabaret", L"New Wave", L"Psychadelic", L"Rave", 
  176.   L"Showtunes", L"Trailer", L"Lo-Fi", L"Tribal", L"Acid Punk", L"Acid Jazz", 
  177.   L"Polka", L"Retro", L"Musical", L"Rock & Roll", L"Hard Rock", L"Folk", 
  178.   L"Folk/Rock", L"National Folk", L"Swing", L"Fast-Fusion", L"Bebob", L"Latin", L"Revival", 
  179.   L"Celtic", L"Bluegrass", L"Avantgarde", L"Gothic Rock", L"Progressive Rock", 
  180.   L"Psychadelic Rock", L"Symphonic Rock", L"Slow Rock", L"Big Band", L"Chorus", 
  181.   L"Easy Listening", L"Acoustic", L"Humour", L"Speech", L"Chanson", L"Opera", 
  182.   L"Chamber Music", L"Sonata", L"Symphony", L"Booty Bass", L"Primus", 
  183.   L"Porn Groove", L"Satire", L"Slow Jam", L"Club", L"Tango", L"Samba", L"Folklore"
  184. };
  185. // The Frame Bitrate according to the MPEG-Layer (MPEG Audio 1.0, Section 2.4.2.3)
  186. static CONST UINT16 g_aBitrateByMpeg1Layer[15][3] = 
  187. {
  188. { 0  , 0  , 0   },
  189. { 32 , 32 , 32  },
  190. { 64 , 48 , 40  },
  191. { 96 , 56 , 48  },
  192. { 128, 64 , 56  },
  193. { 160, 80 , 64  },
  194. { 192, 96 , 80  },
  195. { 224, 112, 96  },
  196. { 256, 128, 112 },
  197. { 288, 160, 128 },
  198. { 320, 192, 160 },
  199. { 352, 224, 192 },
  200. { 384, 256, 224 },
  201. { 416, 320, 256 },
  202. { 448, 384, 320 }
  203. };
  204. static CONST UINT16 g_aBitrateByMpeg2Layer[15][3] = 
  205. {
  206. { 0  , 0  , 0   },
  207. { 32 , 32 , 8   },
  208. { 64 , 48 , 16  },
  209. { 96 , 56 , 24  },
  210. { 128, 64 , 32  },
  211. { 160, 80 , 64  },
  212. { 192, 96 , 80  },
  213. { 224, 112, 56  },
  214. { 256, 128, 64  },
  215. { 288, 160, 128 },
  216. { 320, 192, 160 },
  217. { 352, 224, 112 },
  218. { 384, 256, 128 },
  219. { 416, 320, 256 },
  220. { 448, 384, 320 }
  221. };
  222. #endif //(CLIPS_ACQUIRE_EXTENDED_INFO) && (CLIPS_MP3_EXTRACT_ID3V1_TAG)
  223. /////////////////////////////////////////////////////////////////////////////
  224. // Private Services
  225. #pragma argsused
  226. void MP3_setPresentationTime(UINT8 uPresentationTime)
  227. {
  228. dbg_printf(("WARNING: MP3_setPresentationTime() Failed: MP3 Clips cannot have a presentation time.n"));
  229. }
  230. #if (defined(CLIPS_ACQUIRE_EXTENDED_INFO) && defined(CLIPS_MP3_EXTRACT_ID3V1_TAG))
  231. BOOL MP3_getID3v1Tag(DWORD dwClipStartAddr, DWORD cbClipSize, 
  232.  WORD i_pExtInfo_sc_handle)
  233. {
  234. INT32 iOffset;
  235. BYTE aTagBuffer[ID3V1_SIZE];
  236. UINT16 uBlocksCnt;
  237. DWORD dwStartLBA;
  238. //Angie_0810_2004:Move the MP3 and WMA extend info from gns to SCPAD for I86 memory reducing.
  239. MP3_ID3v1Tag o_pID3v1Tag;
  240. // Reset the result
  241. memset(&o_pID3v1Tag, 0, sizeof(MP3_ID3v1Tag));
  242. o_pID3v1Tag.pszGenre= g_aMP3_ID3Genres[0];
  243. // First of all, calculate the LBA to fetch, and the offset within that LBA
  244. // in which the ID3v1-Tag should reside (the last 128 Bytes of the Clip).
  245. uBlocksCnt= (UINT16)(cbClipSize / LOGICAL_BLOCK_SIZE);
  246. dwStartLBA= (dwClipStartAddr + uBlocksCnt);
  247. iOffset= (cbClipSize - (LOGICAL_BLOCK_SIZE * (ULONG)uBlocksCnt) - ID3V1_SIZE);
  248. if (iOffset < 0) 
  249. {
  250. UINT32 uPortionOfLastSector= (cbClipSize - (LOGICAL_BLOCK_SIZE * (ULONG)uBlocksCnt));
  251. iOffset= (LOGICAL_BLOCK_SIZE - (ID3V1_SIZE - uPortionOfLastSector));
  252. dwStartLBA--;
  253. }
  254. // Now fetch the last 128 Bytes of the Clip
  255. if (! AuxCache_GetBytes(dwStartLBA, (DWORD)iOffset, ID3V1_SIZE, aTagBuffer)) 
  256. {
  257. dbg_printf(("Failed to extract an MP3-ID3v1 Tag.n"));
  258. isFailedToReadMP3Head = TRUE;
  259. drv_abort_play();
  260. return FALSE;
  261. }
  262. // Examine the Buffer, and search for the "TAG" identifier
  263. if (0 != strncmp((LPCSTR)aTagBuffer, "TAG", 3)) 
  264. {
  265. // The Clip doesn't have an ID3v1 Tag
  266. return FALSE;
  267. }
  268. // Copy the various fields into the destination Tag, converted into UNICODE-CS0
  269. if (0 != memcmp((LPCSTR)&aTagBuffer[3], g_pszEmptyField, ID3V1_TEXT_LENGTH));
  270. _str2wcs((LPCSTR)&aTagBuffer[3], o_pID3v1Tag.szSongName, sizeof(o_pID3v1Tag.szSongName));
  271. if (0 != memcmp((LPCSTR)&aTagBuffer[33], g_pszEmptyField, ID3V1_TEXT_LENGTH))
  272. _str2wcs((LPCSTR)&aTagBuffer[33], o_pID3v1Tag.szArtist, sizeof(o_pID3v1Tag.szArtist));
  273. if (0 != memcmp((LPCSTR)&aTagBuffer[63], g_pszEmptyField, ID3V1_TEXT_LENGTH))
  274. _str2wcs((LPCSTR)&aTagBuffer[63], o_pID3v1Tag.szAlbum, sizeof(o_pID3v1Tag.szAlbum));
  275. if (0 != memcmp((LPCSTR)&aTagBuffer[93], g_pszEmptyField, 4))
  276. _str2wcs((LPCSTR)&aTagBuffer[93], o_pID3v1Tag.szYear, sizeof(o_pID3v1Tag.szYear));
  277. if (0 != memcmp((LPCSTR)&aTagBuffer[97], g_pszEmptyField, ID3V1_TEXT_LENGTH))
  278. _str2wcs((LPCSTR)&aTagBuffer[97], o_pID3v1Tag.szComment, sizeof(o_pID3v1Tag.szComment));
  279. // Extrapulate the Track-Number field: if the Comment field's next-to-last char
  280. // is NULL, then the last char is the Track-Number.
  281. if (0 == o_pID3v1Tag.szComment[ID3V1_TEXT_LENGTH-2])
  282. o_pID3v1Tag.uTrackNum= o_pID3v1Tag.szComment[ID3V1_TEXT_LENGTH-1];
  283. else
  284. o_pID3v1Tag.uTrackNum= 0;
  285. // Assign the Genre-name
  286. if ((ID3_GENRE_DEFAULT == aTagBuffer[127]) || (ID3_GENRE_COUNT <= aTagBuffer[127]))
  287. o_pID3v1Tag.pszGenre= g_aMP3_ID3Genres[0]; // The Default Genre, or an Undefined one
  288. else
  289. o_pID3v1Tag.pszGenre= g_aMP3_ID3Genres[aTagBuffer[127] + 1];
  290. sc_SetBytes(i_pExtInfo_sc_handle,0,sizeof(MP3_ID3v1Tag),(BYTE *)&o_pID3v1Tag);
  291. drv_abort_play();
  292. return TRUE;
  293. }
  294. #endif //(CLIPS_ACQUIRE_EXTENDED_INFO) && (CLIPS_MP3_EXTRACT_ID3V1_TAG)
  295. /////////////////////////////////////////////////////////////////////////////
  296. // Public Services
  297. BOOL MP3Clip_isKindOf(LPCWSTR i_pszFilename)
  298. {
  299. return GenericClip_isKindOf(i_pszFilename, CLIP_VALID_EXTENSIONS(MP3));
  300. }
  301. void MP3Clip_construct(Clip *o_pThis, const FindData *i_pFileInfo)
  302. {
  303. GenericClip_construct(o_pThis, i_pFileInfo);
  304. o_pThis->m_pConstAttr= &CLIP_CONST_ATTR(MP3);
  305. }
  306. /////////////////////////////////////////////////////////////////////////////
  307. // Virtual Methods
  308. BOOL MP3Clip_getExtendedInfo(const struct Clip_TAG *i_pThis, 
  309.  WORD i_pExtInfo_sc_handle)
  310. {
  311. BOOL bSuccess= FALSE;
  312. int iTotalSeconds;
  313. dbg_printf(("MP3Clip_getExtendedInfo()n"));
  314. #ifdef CLIPS_MP3_EXTRACT_ID3V1_TAG
  315. ASSERT(NULL != i_pExtInfo_sc_handle)
  316. bSuccess= MP3_getID3v1Tag(i_pThis->m_cfiInfo.dwFileLocation, 
  317.   i_pThis->m_cfiInfo.cbFileSize,
  318.   i_pExtInfo_sc_handle);
  319. #endif //CLIPS_MP3_EXTRACT_ID3V1_TAG
  320. GetBitstreamStats(i_pThis->m_cfiInfo.dwFileLocation, &iTotalSeconds);
  321. gns.clips.uTotalPlaybackTime = iTotalSeconds;
  322. return bSuccess;
  323. }
  324. #pragma argsused
  325. void MP3Clip_refresh(Clip *i_pThis)
  326. {
  327. UINT32 dwBufferLevel;
  328. if (PST_PLAY == gcs.pstate) 
  329. {
  330. BOOL bEnableClock;
  331. dwBufferLevel = DEC_ReadCodeBufferFullness(DEC_AUDIO_CODE_BUFFER, DEC_FULLNESS_IN_BYTES);
  332. if (dwBufferLevel == 0)
  333. {
  334. bEnableClock = FALSE;
  335. }
  336. else
  337. {
  338. bEnableClock = TRUE;
  339. }
  340. if ( (0 == dwBufferLevel) && drv_is_play_done())
  341. {
  342. PE_Clips_EnableClock(bEnableClock, TRUE, 0);
  343. }
  344. else
  345. {
  346. PE_Clips_EnableClock(bEnableClock, FALSE, 0);
  347. }
  348. }
  349. else
  350. {
  351. if ( (PST_SCAN == gcs.pstate)  && (eCS_Finished == MP3_getStatus(i_pThis)) )
  352. {
  353. PE_Clips_EnableClock(FALSE, TRUE, 0);
  354. }
  355. }
  356. }
  357. enClipStatus MP3_getStatus(const Clip *i_pThis)
  358. {
  359. static UINT16 uiWatchDog = 100; // 10s, called on 100ms tick.
  360. static UINT16 uLastReadTime;
  361. if (PST_PLAY == gcs.pstate)
  362. {
  363. if (PE_Clips_GetClock() == uLastReadTime)
  364. {
  365. // either decoder got stuck or drive is trying to bring data.
  366. uiWatchDog--;
  367. }
  368. else
  369. {
  370. uiWatchDog = 100;
  371. uLastReadTime = PE_Clips_GetClock();
  372. }
  373. if (0 == uiWatchDog)
  374. {
  375. uiWatchDog = 100;
  376. return eCS_Finished;
  377. }
  378. }
  379. else
  380. {
  381. uiWatchDog = 100;
  382. }
  383. if (PST_SCAN != gcs.pstate)
  384. {
  385. if (drv_is_play_done() && DEC_IsPlaybackFinished(FALSE)) 
  386. {
  387. if (0 == ucMP3PlayabckFinishedCounter)
  388. {
  389. return eCS_Finished;
  390. }
  391. else
  392. {
  393. ucMP3PlayabckFinishedCounter--;
  394. return eCS_Busy;
  395. }
  396. }
  397.   
  398. ucMP3PlayabckFinishedCounter = DEFAULT_MP3_PLAYBACK_FINISHED_COUNTER;
  399. return eCS_Busy;
  400. }
  401. else
  402. {
  403. UINT16 uCurrTime = PE_Clips_GetClock();
  404. // Check if Scan in current Clip is finished
  405. if ( (uCurrTime >= gns.clips.uTotalPlaybackTime) ||
  406.         (0 == uCurrTime) )
  407. {
  408. return eCS_Finished;
  409. }
  410. else
  411. {
  412. return eCS_Busy;
  413. }
  414. }
  415. }
  416. void MP3_pause(Clip *i_pThis, BOOL bEnable)
  417. {
  418. if ( (PST_SCAN == gcs.pstate) || (0 != gns.clips.iScanSpeed) )
  419. {
  420. if (bEnable)
  421. {
  422. PE_Clips_EnableClock(FALSE, FALSE, 0);
  423. }
  424. else
  425. {
  426. if (PST_PLAY == gcs.pstate)
  427. {
  428. gns.clips.iScanSpeed = 0;
  429. }
  430. MP3_scan(i_pThis, gns.clips.iScanSpeed);
  431. }
  432. }
  433. else
  434. {
  435. GenericClip_pause(i_pThis, bEnable);
  436. }
  437. }
  438. BOOL MP3_play(Clip *i_pThis, const ClipMarker *i_pResumeMarker,
  439.   BOOL bCacheOnly)
  440. {
  441. DWORD dwStartLBA;
  442. ULONG ulBlocksCnt, cbPlaybackLength;
  443. dbg_printf(("MP3_play()n"));
  444. ucMP3PlayabckFinishedCounter = DEFAULT_MP3_PLAYBACK_FINISHED_COUNTER;
  445. // Cached-playback is unsupported by default
  446. if (bCacheOnly)
  447. return FALSE;
  448. drv_abort_play();
  449. // Kill any existing Zoom
  450. DEC_SetZoomScale(NO_ZOOM);
  451. // Configure the Decoder to the appropriate Bitstream Type
  452. DEC_SetDiskType((i_pThis->m_pConstAttr)->m_eBitstreamType);
  453. // Prepare for decoding
  454. DEC_prepare_to_decode();
  455. #ifdef CLIPS_MP3_EXTRACT_ID3V1_TAG
  456. if (gns.clips.cieCurrClip.mpeginfo.uLayer == IS_LAYER_II)
  457. {
  458. DEC_SetSID(DEC_SID_TYPE_AUDIO, MPEG_SID0);
  459. }
  460. else
  461. #endif
  462. {
  463. DEC_SetSID(DEC_SID_TYPE_AUDIO, MP3_SID);
  464. }
  465. DEC_SetSID(DEC_SID_TYPE_VIDEO, (i_pThis->m_pConstAttr)->m_eVideoSID);
  466.     // Set audio ID for MP2 again.
  467. #ifdef CLIPS_MP3_EXTRACT_ID3V1_TAG
  468. if (gns.clips.cieCurrClip.mpeginfo.uLayer == IS_LAYER_II)
  469. {
  470. DEC_SetSID(DEC_SID_TYPE_AUDIO, MPEG_SID0);
  471. }
  472. #endif
  473. // Select the appropriate Clock
  474. PE_Clips_SelectClock(eCT_Internal);
  475. // Calculate the Playback Start-Address
  476. if (NULL == i_pResumeMarker) 
  477. {
  478. // Start at the beginning
  479. dwStartLBA= (i_pThis->m_cfiInfo).dwFileLocation;
  480. }
  481. else 
  482. {
  483. // Playback is being resumed
  484. dwStartLBA= i_pResumeMarker->dwAddress;
  485. }
  486. // Calculate the Playback Length (in Bytes)
  487. cbPlaybackLength= ( (i_pThis->m_cfiInfo).cbFileSize - 
  488. (LOGICAL_BLOCK_SIZE * (dwStartLBA - (i_pThis->m_cfiInfo).dwFileLocation)) );
  489. ulBlocksCnt= ((cbPlaybackLength + LOGICAL_BLOCK_SIZE - 1) / LOGICAL_BLOCK_SIZE);
  490. // Inform the Decoder of the Playback-Range
  491. PE_Clips_SetPlaybackRange(dwStartLBA, ulBlocksCnt, cbPlaybackLength/2);
  492. // Invoke playback of the Decoder & Drive
  493. // NOTE: The order of invocation is important, and must not be changed!
  494. DEC_PlaybackCommand(DEC_PLAYBACK_CMD_PLAY, NULL);
  495. if (!PE_Clips_Playback_Sectors(DRVCF_CDSPEED_1X | DRVF_PLAY_CD_AV_DATA, dwStartLBA, ulBlocksCnt))
  496. {
  497. tr_printf(("WARNING: MP3_play() Failed [1]n"));
  498. return FALSE;
  499. }
  500. // Restart the Clock
  501. PE_Clips_EnableClock(TRUE, TRUE,
  502.  (NULL != i_pResumeMarker) ? i_pResumeMarker->uTime : 0);
  503. return TRUE;
  504. }
  505. void MP3_scan(Clip *i_pThis, int iScanSpeed)
  506. {
  507. UINT16 ulCurrTime = PE_Clips_GetClock();
  508. dbg_printf(("MP3 Scan(%d)n", iScanSpeed));
  509. if (iScanSpeed != 0)
  510. {
  511. if (0 < iScanSpeed && 0 == ulCurrTime)
  512. {
  513. ulCurrTime = 1;
  514. }
  515. PE_Clips_SelectClock(eCT_Internal);
  516. PE_Clips_EnableClock(TRUE, TRUE, ulCurrTime); // Reset curent clock
  517. if (PST_PLAY == gcs.pstate)
  518. {
  519. PE_CD_AbortPlayback(TRUE);
  520. gcs.pstate = PST_SCAN;
  521. gns.clips.iScanSpeed = iScanSpeed;
  522. }
  523. else
  524. {
  525. ClipMarker mClipMarker;
  526. PE_Clips_SelectClock(eCT_Decoder);
  527. // Cancel Scan during Scan mode
  528. mClipMarker.dwAddress = MP3_Time_To_Address(ulCurrTime);
  529. mClipMarker.uTime = ulCurrTime;
  530. gns.clips.iScanSpeed = 0;
  531. gcs.pstate = PST_PLAY;
  532. dbg_printf(("Resume from %lx, file start address is %lxn", mClipMarker.dwAddress, i_pThis->m_cfiInfo.dwFileLocation));
  533. (i_pThis->m_pConstAttr->m_vtable.m_pfPlay)(i_pThis, &mClipMarker, FALSE);
  534. }
  535. return;
  536. }
  537. void MP3_recordMarker(Clip *i_pThis, ClipMarker *o_pMarker)
  538. {
  539. if (NULL != o_pMarker) 
  540. {
  541. DWORD dwStartAddress, dwJumpOffset;
  542. UINT16 uiTime;
  543. // Record the current position
  544. uiTime = PE_Clips_GetClock();
  545. o_pMarker->uTime = uiTime;
  546. dwStartAddress = MP3_Time_To_Address(uiTime); 
  547. o_pMarker->dwAddress = dwStartAddress;
  548. o_pMarker->uClipNumer = gns.clips.uCurrentClipNumber;
  549. }
  550. return;
  551. }
  552. UINT16 MP3Clip_GetTime(Clip *i_pThis)
  553. {
  554. UINT16 iCurrentTime;
  555. // Update Current Elapsed Time
  556. iCurrentTime = PE_Clips_GetClock();
  557. return iCurrentTime;
  558. }
  559. DWORD MP3_Time_To_Address(WORD uTime)
  560. {
  561. DWORD dwJumpOffset;
  562. if (dwUsPerFrame)
  563. {
  564. dwJumpOffset = ((DWORD)(uTime)*1000000/dwUsPerFrame *m_frameBytes)>>11;
  565. }
  566. else
  567. {
  568. dwJumpOffset = 0;
  569. }
  570. return (gns.clips.cieCurrClip.ciInfo.dwFileLocation) + dwJumpOffset;
  571. }
  572. /*--------------------------------------------------------------*/
  573. static int head_info(DWORD offset, unsigned int n, MPEG_HEAD * h)
  574. {
  575. int framebytes;
  576. int mpeg25_flag;
  577. if (n > 10000)
  578. n = 10000; /* limit scan for free format */
  579. h->sync = 0;
  580. //if ((GetCharFromDisc(0] == 0xFF) && ((GetCharFromDisc(1] & 0xF0) == 0xF0))
  581. if ((GetCharFromDisc(offset + 0) == 0xFF) && ((GetCharFromDisc(offset +0+1) & 0xF0) == 0xF0))
  582. {
  583. mpeg25_flag = 0; // mpeg 1 & 2
  584. }
  585. else if ((GetCharFromDisc(offset +0) == 0xFF) && ((GetCharFromDisc(offset +0+1) & 0xF0) == 0xE0))
  586. {
  587. mpeg25_flag = 1; // mpeg 2.5
  588. }
  589. else
  590. return 0; // sync fail
  591. h->sync = 1;
  592. if (mpeg25_flag)
  593. h->sync = 2; //low bit clear signals mpeg25 (as in 0xFFE)
  594. h->id = (GetCharFromDisc(offset +0+1) & 0x08) >> 3;
  595. h->option = (GetCharFromDisc(offset +0+1) & 0x06) >> 1;
  596. h->prot = (GetCharFromDisc(offset +0+1) & 0x01);
  597. h->br_index = (GetCharFromDisc(offset +0+2) & 0xf0) >> 4;
  598. h->sr_index = (GetCharFromDisc(offset +0+2) & 0x0c) >> 2;
  599. h->pad = (GetCharFromDisc(offset +0+2) & 0x02) >> 1;
  600. h->private_bit = (GetCharFromDisc(offset +0+2) & 0x01);
  601. h->mode = (GetCharFromDisc(offset +0+3) & 0xc0) >> 6;
  602. h->mode_ext = (GetCharFromDisc(offset +0+3) & 0x30) >> 4;
  603. h->cr = (GetCharFromDisc(offset +0+3) & 0x08) >> 3;
  604. h->original = (GetCharFromDisc(offset +0+3) & 0x04) >> 2;
  605. h->emphasis = (GetCharFromDisc(offset +0+3) & 0x03);
  606. // if( mpeg25_flag ) {
  607.  //    if( h->sr_index == 2 ) return 0;   // fail 8khz
  608.  //}
  609. /* compute framebytes for Layer I, II, III */
  610. if (h->option < 1)
  611. return 0;
  612. if (h->option > 3)
  613. return 0;
  614. framebytes = 0;
  615. #ifdef CLIPS_MP3_EXTRACT_ID3V1_TAG
  616. if (h->br_index > 0)
  617. {
  618. if (h->option == 3)
  619. { /* layer I */
  620. gns.clips.cieCurrClip.mpeginfo.uLayer = 1;
  621. framebytes =
  622. (ULONG)240 * mp_br_tableL1[h->id][h->br_index]
  623. / mp_sr20_table[h->id][h->sr_index];
  624. framebytes = 4 * framebytes;
  625. }
  626. else if (h->option == 2)
  627. { /* layer II */
  628. gns.clips.cieCurrClip.mpeginfo.uLayer = 2;
  629. framebytes =
  630. (ULONG)2880 * mp_br_table[h->id][h->br_index]
  631. / mp_sr20_table[h->id][h->sr_index];
  632. }
  633. else if (h->option == 1)
  634. { /* layer III */
  635. gns.clips.cieCurrClip.mpeginfo.uLayer = 3;
  636. if (h->id)
  637. { // mpeg1
  638. framebytes =
  639. (ULONG)2880 * mp_br_tableL3[h->id][h->br_index]
  640. / mp_sr20_table[h->id][h->sr_index];
  641. }
  642. else
  643. { // mpeg2
  644. if (mpeg25_flag)
  645. { // mpeg2.2
  646. framebytes =
  647. (ULONG)2880 * mp_br_tableL3[h->id][h->br_index]
  648. / mp_sr20_table[h->id][h->sr_index];
  649. }
  650. else
  651. {
  652. framebytes =
  653. (ULONG)1440 * mp_br_tableL3[h->id][h->br_index]
  654. / mp_sr20_table[h->id][h->sr_index];
  655. }
  656. }
  657. }
  658. }
  659. else
  660.       framebytes = -1; /* free format */
  661. #endif
  662. return framebytes;
  663. }
  664. static int head_info3(DWORD offset, unsigned int n, MPEG_HEAD *h, unsigned int *searchForward) {
  665. unsigned int pBuf = 0;
  666.    BYTE c0,c1;
  667.    c0 = GetCharFromDisc(offset + pBuf);
  668.    c1 = GetCharFromDisc(offset + pBuf+1);
  669. // jdw insertion...
  670.    while ((pBuf < n) && !((c0 == 0xFF) &&
  671.           ((c1 & 0xF0) == 0xF0 ||
  672.           (c1 & 0xF0) == 0xE0)))
  673.    {
  674. pBuf++;
  675. c0 = GetCharFromDisc(offset + pBuf);
  676. c1 = GetCharFromDisc(offset + pBuf+1);
  677.    }
  678.    if (pBuf == n) return 0;
  679.    *searchForward = pBuf;
  680.    return head_info2(offset + pBuf, n - pBuf,h);
  681. }
  682. /*--------------------------------------------------------------*/
  683. static int head_info2(DWORD offset, unsigned int n, MPEG_HEAD * h)
  684. {
  685. int framebytes;
  686. framebytes = head_info(offset, n, h);
  687. if (framebytes == 0)
  688. return 0;
  689. return framebytes;
  690. }
  691. static void GetBitstreamStats(DWORD dwClipStartAddr, int *piTotalSeconds)
  692. {
  693. int sampRateIndex;
  694. MPEG_HEAD m_sMpegHead;
  695. DWORD dwTotalFrames, dwSampleRate;
  696. int iLayer;
  697. //<<Leon.He_1001_05: Prevent the total time caculating overflow
  698. DWORD dwTempTotalFrames;
  699. WORD wShift = 0;
  700. //>>Leon.He_1001_05
  701. *piTotalSeconds = 0;
  702. dwUsPerFrame = 0;
  703. dwTotalFrames = dwSampleRate = 0;
  704. if (FALSE == GetHeadInfo(dwClipStartAddr, &m_sMpegHead, &m_frameBytes))
  705. {
  706. dwTotalFrames = -1;
  707. *piTotalSeconds = -1;
  708. return;
  709. }
  710. sampRateIndex = 4 * m_sMpegHead.id + m_sMpegHead.sr_index;
  711. dwSampleRate = sample_rate_table[sampRateIndex];
  712. if ((m_sMpegHead.sync & 1) == 0)
  713. dwSampleRate = dwSampleRate / 2;    // mpeg25
  714. gns.clips.iClipSamplingRate = dwSampleRate;
  715. iLayer = l[m_sMpegHead.option];
  716. if (m_sMpegHead.id == 1)
  717. dwUsPerFrame = (ULONG)(1152 * 1000000) / (ULONG)dwSampleRate;
  718. else
  719. dwUsPerFrame = (ULONG)(576 * 1000000) / (ULONG)dwSampleRate;
  720. #ifdef CLIPS_MP3_EXTRACT_ID3V1_TAG
  721. if (gns.clips.cieCurrClip.ciInfo.cbFileSize > 0 && 0 != m_frameBytes)
  722. {
  723. //<<Leon.He_1001_05: Prevent the total time caculating overflow
  724. // MP3 VBR total time
  725. if (gns.clips.cieCurrClip.mpeginfo.isXingHeaderOn)
  726. dwTotalFrames = m_pXingHeader.frames;
  727. else
  728. dwTotalFrames = gns.clips.cieCurrClip.ciInfo.cbFileSize / m_frameBytes;
  729. dwTempTotalFrames = dwTotalFrames;
  730. wShift = 0;
  731. while ((DWORD_MAX/dwUsPerFrame)< dwTempTotalFrames)
  732. {
  733. wShift++;
  734. dwTempTotalFrames = dwTotalFrames>>wShift;
  735. }
  736. *piTotalSeconds = ((ULONG) dwTempTotalFrames *
  737. (ULONG) dwUsPerFrame)/ (1000000>>wShift);
  738. //>>Leon.He_1001_05
  739. }
  740. else
  741. {
  742. dwTotalFrames = -1;
  743. *piTotalSeconds = -1;
  744. }
  745. #endif
  746. return ;
  747. }
  748. static void InitHeaderBuff(BYTE * buff, DWORD dwClipStartAddr)
  749. {
  750. aHeaderBuffer = buff;
  751. uiBuffNo = -1;
  752. dwClipStartAddrForHeadBuffer = dwClipStartAddr;
  753. }
  754. static BYTE GetCharFromDisc(DWORD n)
  755. {
  756. //LeonHe_2005_0519: Jump out directly when Failed to read the MP3 Head.
  757. if(isFailedToReadMP3Head)
  758. return NULL;
  759. if((n/TEMP_BUFF_SIZE) != uiBuffNo)
  760. {
  761. uiBuffNo = n/TEMP_BUFF_SIZE;
  762. //AngieHe_1111_2004: Add (DOWRD) to avoid the offset overflow.
  763. if (!AuxCache_GetBytes(dwClipStartAddrForHeadBuffer, (DWORD)uiBuffNo*TEMP_BUFF_SIZE, TEMP_BUFF_SIZE, aHeaderBuffer))
  764. {
  765. memset(aHeaderBuffer, 0, TEMP_BUFF_SIZE);
  766. //>>LeonHe_2005_0519: Set a Flag when Failed to read the MP3 Head.
  767. isFailedToReadMP3Head = TRUE;
  768. drv_abort_play();
  769. //<<LeonHe_2005_0519
  770. }
  771. }
  772. return (aHeaderBuffer[n%TEMP_BUFF_SIZE]);
  773. }
  774. static BOOL GetHeadInfo(DWORD dwClipStartAddr, MPEG_HEAD * pm_sMpegHead, int *pm_frameBytes)
  775. {
  776. int          iLoop, iFrame, iOffset;
  777. int          iLastSRIndex = -1, iLastOption = -1;
  778. int          iLastId = -1, iLastMode = -1;
  779. unsigned int iForward;
  780. BYTE  abTempBuffer[TEMP_BUFF_SIZE];
  781. MPEG_HEAD m_sMpegHead;
  782. #ifdef CLIPS_MP3_EXTRACT_ID3V1_TAG
  783. InitHeaderBuff(abTempBuffer, dwClipStartAddr);
  784. for (iLoop = 0; iLoop < MAX_DECODING_RETRY; iLoop++)
  785. {
  786. for(iFrame = 0, iOffset = 0; iFrame < NUM_OF_SANITY_CHECK; iFrame++)
  787. {
  788. m_frameBytes = head_info3((DWORD)iLoop*INITIAL_FRAME_SIZE + iOffset,INITIAL_FRAME_SIZE - iOffset, &m_sMpegHead,&iForward);
  789. if (m_frameBytes > 0 && iFrame == 0)
  790. {
  791. iOffset += m_frameBytes + iForward + m_sMpegHead.pad;
  792. iLastSRIndex = m_sMpegHead.sr_index;
  793. iLastOption = m_sMpegHead.option;
  794. iLastId = m_sMpegHead.id;
  795. iLastMode = m_sMpegHead.mode;
  796. continue;
  797. }
  798. if (m_frameBytes > 0 && m_frameBytes < MAX_FRAME_SIZE &&
  799. (m_sMpegHead.option == 1 || m_sMpegHead.option == 2) &&
  800. iLastSRIndex == m_sMpegHead.sr_index &&
  801. iLastOption == m_sMpegHead.option && 
  802. iLastId == m_sMpegHead.id && 
  803. iLastMode == m_sMpegHead.mode)
  804. {
  805. iOffset += m_frameBytes + iForward + m_sMpegHead.pad;
  806. iLastSRIndex = m_sMpegHead.sr_index;
  807. iLastOption = m_sMpegHead.option;
  808. iLastId = m_sMpegHead.id;
  809. iLastMode = m_sMpegHead.mode;
  810. //<<<LeonH_0818_2003_A :For Get mp3 VBR total time
  811. if (iFrame < NUM_OF_SANITY_CHECK - 1)
  812. continue; 
  813. if (gns.clips.cieCurrClip.mpeginfo.isXingHeaderOn)
  814. gns.clips.cieCurrClip.mpeginfo.isXingHeaderOn = FALSE;
  815. if (!GetXingHeader(&m_pXingHeader, 0))
  816. gns.clips.cieCurrClip.mpeginfo.isXingHeaderOn = FALSE;
  817. else
  818. gns.clips.cieCurrClip.mpeginfo.isXingHeaderOn = TRUE;
  819. //<<<Leonh_0818_2003_A
  820. continue;
  821. }
  822. break;
  823. }
  824. if (iFrame == NUM_OF_SANITY_CHECK)
  825. {
  826. memcpy(pm_sMpegHead, &m_sMpegHead, sizeof(m_sMpegHead));
  827. *pm_frameBytes = m_frameBytes;
  828. return TRUE;
  829. }
  830. }
  831. #endif
  832. return FALSE;
  833. }
  834. //<<<LeonH_0818_2003_A :For Get mp3 VBR total time
  835. int ExtractI4(DWORD offset)
  836. {
  837.     int x;
  838.     // big endian extract
  839.     
  840.     x = GetCharFromDisc(offset++);
  841.     x <<= 8;
  842.     x |= GetCharFromDisc(offset++);
  843.     x <<= 8;
  844.     x |= GetCharFromDisc(offset++);
  845.     x <<= 8;
  846.     x |= GetCharFromDisc(offset);
  847.     
  848.     return x;
  849. }
  850. static BOOL GetXingHeader(XHEADDATA *X,  DWORD offset)
  851. {
  852. int i, head_flags;
  853. int h_id, h_mode, h_sr_index;
  854. // get Xing header data
  855. X->flags = 0;     // clear to null incase fail
  856. // get selected MPEG header data
  857. h_id= (GetCharFromDisc(offset +0+1) & 0x08) >> 3;
  858. h_mode = (GetCharFromDisc(offset +0+3) & 0xc0) >> 6;
  859. // determine offset of header
  860. if( h_id ) 
  861. {        // mpeg1
  862. if( h_mode != 3 ) 
  863. offset+=(32+4);
  864. else              
  865. offset+=(17+4);
  866. }
  867. else 
  868. {      // mpeg2
  869. if( h_mode != 3 ) 
  870. offset+=(17+4);
  871. else            
  872. offset+=(9+4);
  873. }
  874.      if(GetCharFromDisc(offset++) !='X') return FALSE;
  875.      if(GetCharFromDisc(offset++) !='i') return FALSE;
  876.      if(GetCharFromDisc(offset++) !='n') return FALSE;
  877.      if(GetCharFromDisc(offset++) !='g') return FALSE;
  878.     
  879. X->h_id = h_id;
  880. head_flags = X->flags = ExtractI4(offset); offset+=4;      // get flags
  881. if( head_flags & FRAMES_FLAG ) {X->frames   = ExtractI4(offset); offset+=4;}
  882. if( head_flags & BYTES_FLAG )  {X->bytes = ExtractI4(offset); offset+=4;}
  883. return TRUE;       // success
  884. }
  885. //<<<Leonh_0818_2003_A