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

DVD

开发平台:

Others

  1. //Sean_1213_2004
  2. /****************************************************************************************
  3.  *  Copyright (c) 2000 ZORAN Corporation, All Rights Reserved
  4.  *  THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF ZORAN CORPORATION
  5.  *
  6.  *  File: $Workfile: OGG.c $             
  7.  *
  8.  * Description:
  9.  * ============
  10.  * OGG Clip implementation
  11.  *
  12.  * Log:
  13.  * ====
  14.  ****************************************************************************************
  15.  * Updates:
  16.  ****************************************************************************************
  17.  * 2004/09/05 : created by SeanLiu to support Vorbis OGG bitstream.
  18.  * 
  19.  ****************************************************************************************/
  20. #include "Config.h" // Global Configuration - do not remove!
  21. #ifdef IS_OGG_VORBIS_CAPABLE
  22. #ifdef _DEBUG
  23. #undef IFTRACE
  24. #define IFTRACE if (gTraceNavigator)
  25. #include "DebugDbgMain.h"
  26. #endif
  27. #include "Includemath-macro.h"
  28. //#include "KernelEventDef.H"
  29. #include "DecoderDecoder.h"
  30. #include "DecoderDec_defs.h"
  31. #include "Decoderlow_levelDEC_LL_Def.h"
  32. #include "Drivedrv_api.h"
  33. #include "Drivedrv_defs.h"
  34. #include "LogoLogo.h"
  35. #include "PlaycoreCoremainCoreGDef.h"
  36. #include "PlaycoreAuxCacheAuxCache.h"
  37. #include "PlaycoreFileSysFileSystem.h"
  38. #include "PlaycoreNav_ClipsOGG.h"
  39. #include "PlaycoreNav_ClipsClip_Impl.h"
  40. #include "PlaycoreNav_ClipsGenericClip.h"
  41. #include "PlaycoreNav_ClipsNav_Clips.h"
  42. #include "PlaycoreNav_ClipsPE_Clips.h"
  43. #define bOGGUnsupported gns.clips.globals.oggGlobals.bOGGUnsupported
  44. static BOOL OGG_SearchVorbisPacket(DWORD start_address, DWORD *offset, DWORD lengh,BYTE packet_type);
  45. /////////////////////////////////////////////////////////////////////////////
  46. // General OGG
  47. /////////////////////////////////////////////////////////////////////////////
  48. static BOOL OGG_SearchVorbisPacket(DWORD start_address, DWORD *offset, DWORD lengh,BYTE packet_type)
  49. {
  50. BYTE ObjectBuff[OGG_HEADER_TAG_SIZE+1];
  51. BYTE NextByte;
  52. UINT16 i;
  53. if ( !AuxCache_GetBytes(start_address, *offset, OGG_HEADER_TAG_SIZE, ObjectBuff) )
  54. {
  55. dbg_printf(("WARNING: OGG_GetOGGInfo() Failed [1]n"));
  56. return FALSE;
  57. }
  58. *offset += OGG_HEADER_TAG_SIZE;
  59. while(*offset < lengh)
  60. {
  61. (*offset)++;
  62. if((!memcmp((ObjectBuff+1), OGG_HEADER_TAG,OGG_HEADER_TAG_SIZE)) && (ObjectBuff[0] == packet_type))
  63. {
  64. return TRUE;
  65. }
  66. if ( !AuxCache_GetBytes(start_address, *offset, 1, &NextByte))
  67. {
  68. dbg_printf(("WARNING: OGG_GetOGGInfo() Failed [3]n"));
  69. return FALSE;
  70. }
  71. for(i=0; i<OGG_HEADER_TAG_SIZE; i++)
  72. {
  73. ObjectBuff[i] = ObjectBuff[i+1];
  74. }
  75. ObjectBuff[i] = NextByte;
  76. return FALSE;
  77. }
  78. /////////////////////////////////////////////////////////////////////////////
  79. // Public Services
  80. #pragma argsused
  81. void OGG_setPresentationTime(UINT8 uPresentationTime)
  82. {
  83. dbg_printf(("WARNING: OGG_setPresentationTime() Failed: OGG Clips cannot have a presentation time.n"));
  84. }
  85. BOOL OGG_GetOGGInfo(DWORD dwClipStartAddr,WORD i_pExtInfo_sc_handle)
  86. {
  87. DWORD cbOffset=0;
  88. VORBIS_OGG_IDENTIFICATION_HEADER OGG_identification_header;
  89. UINT16 i;
  90. bOGGUnsupported = TRUE;
  91. if(!OGG_SearchVorbisPacket(dwClipStartAddr, &cbOffset, 58,OGG_PACKET_TYPE_IDENTIFICATION))
  92. {
  93. return FALSE;
  94. }
  95. if ( !AuxCache_GetBytes(dwClipStartAddr, cbOffset, sizeof(VORBIS_OGG_IDENTIFICATION_HEADER), &OGG_identification_header))
  96. {
  97. dbg_printf(("WARNING: OGG_GetOGGInfo() Failed [2]n"));
  98. return FALSE;
  99. }
  100. gns.clips.iClipSamplingRate = OGG_identification_header.audio_sample_rate;
  101. if(((OGG_identification_header.audio_sample_rate != 48000) && (OGG_identification_header.audio_sample_rate != 32000)
  102. && (OGG_identification_header.audio_sample_rate != 44100) && (OGG_identification_header.audio_sample_rate != 24000)
  103. && (OGG_identification_header.audio_sample_rate != 16000) && (OGG_identification_header.audio_sample_rate != 22050))
  104. || ((OGG_identification_header.audio_channels != 1) && (OGG_identification_header.audio_channels != 2))
  105. )
  106. {
  107. return FALSE;
  108. }
  109. bOGGUnsupported = FALSE;
  110. #if (defined(CLIPS_ACQUIRE_EXTENDED_INFO) && defined(CLIPS_OGG_EXTRACT_INFO))
  111. ASSERT(NULL != i_pExtInfo_sc_handle);
  112. cbOffset = 58;
  113. if(OGG_SearchVorbisPacket(dwClipStartAddr, &cbOffset, 128,OGG_PACKET_TYPE_COMMENT))
  114. {
  115. UINT32 vendor_length;
  116. UINT32 user_comment_list_length;
  117. UINT32 length;
  118. UINT8 comment[OGG_TEXT_LENGTH+VORBIS_COMMENT_MAX_LEN];
  119. OGG_ExtendInfo ogg_extend_info;
  120. UINT32 i;
  121. memset(&ogg_extend_info,0,sizeof(OGG_ExtendInfo));
  122. if ( !AuxCache_GetBytes(dwClipStartAddr, cbOffset, sizeof(UINT32), &vendor_length))
  123. {
  124. dbg_printf(("WARNING: OGG_GetOGGInfo() Failed [2]n"));
  125. return TRUE;
  126. }
  127. cbOffset = cbOffset + 4 + vendor_length;
  128. if ( !AuxCache_GetBytes(dwClipStartAddr, cbOffset, sizeof(UINT32), &user_comment_list_length))
  129. {
  130. dbg_printf(("WARNING: OGG_GetOGGInfo() Failed [2]n"));
  131. return TRUE;
  132. }
  133. cbOffset +=4;
  134. for(i=0;i<user_comment_list_length;i++)
  135. {
  136. if ( !AuxCache_GetBytes(dwClipStartAddr, cbOffset, sizeof(UINT32), &length))
  137. {
  138. dbg_printf(("WARNING: OGG_GetOGGInfo() Failed [2]n"));
  139. return TRUE;
  140. }
  141. cbOffset +=4;
  142. if ( !AuxCache_GetBytes(dwClipStartAddr, cbOffset, GET_MINIMUM(length,(OGG_TEXT_LENGTH+VORBIS_COMMENT_MAX_LEN)), comment))
  143. {
  144. dbg_printf(("WARNING: OGG_GetOGGInfo() Failed [2]n"));
  145. return TRUE;
  146. }
  147. cbOffset +=length;
  148. //TODO: deal with multiple case later.
  149. if(!memcmp(comment, VORBIS_COMMENT_TITLE_TAG,VORBIS_COMMENT_TITLE_LEN))
  150. {
  151. memcpy(ogg_extend_info.szTitle,(comment+VORBIS_COMMENT_TITLE_LEN),GET_MINIMUM(length,OGG_TEXT_LENGTH));
  152. }
  153. else
  154. if(!memcmp(comment, VORBIS_COMMENT_ALBUM_TAG,VORBIS_COMMENT_ALBUM_LEN))
  155. {
  156. memcpy(ogg_extend_info.szAlbum,(comment+VORBIS_COMMENT_ALBUM_LEN),GET_MINIMUM(length,OGG_TEXT_LENGTH));
  157. }
  158. else
  159. if(!memcmp(comment, VORBIS_COMMENT_ARTIST_TAG,VORBIS_COMMENT_ARTIST_LEN))
  160. {
  161. memcpy(ogg_extend_info.szArtist,(comment+VORBIS_COMMENT_ARTIST_LEN),GET_MINIMUM(length,OGG_TEXT_LENGTH));
  162. }
  163. else
  164. if(!memcmp(comment, VORBIS_COMMENT_COPYRIGHT_TAG,VORBIS_COMMENT_COPYRIGHT_LEN))
  165. {
  166. memcpy(ogg_extend_info.szCopyright,(comment+VORBIS_COMMENT_COPYRIGHT_LEN),GET_MINIMUM(length,OGG_TEXT_LENGTH));
  167. }
  168. else
  169. if(!memcmp(comment, VORBIS_COMMENT_DESCRIPTION_TAG,VORBIS_COMMENT_DESCRIPTION_LEN))
  170. {
  171. memcpy(ogg_extend_info.szDescription,(comment+VORBIS_COMMENT_DESCRIPTION_LEN),GET_MINIMUM(length,OGG_TEXT_LENGTH));
  172. }
  173. else
  174. if(!memcmp(comment, VORBIS_COMMENT_GENRE_TAG,VORBIS_COMMENT_GENRE_LEN))
  175. {
  176. memcpy(ogg_extend_info.szGenre,(comment+VORBIS_COMMENT_GENRE_LEN),GET_MINIMUM(length,OGG_TEXT_LENGTH));
  177. }
  178. }
  179. sc_SetBytes(i_pExtInfo_sc_handle,0,sizeof(OGG_ExtendInfo),(BYTE *)&ogg_extend_info);
  180. }
  181. #endif //CLIPS_OGG_EXTRACT_INFO
  182. return TRUE;
  183. }
  184. /////////////////////////////////////////////////////////////////////////////
  185. // OGG Clip
  186. /////////////////////////////////////////////////////////////////////////////
  187. /////////////////////////////////////////////////////////////////////////////
  188. // Forward Declarations of Virtual Methods
  189. BOOL OGGClip_getExtendedInfo(const struct Clip_TAG *i_pThis, WORD i_pExtInfo_sc_handle);
  190. BOOL OGGClip_play(Clip *i_pThis, const ClipMarker *i_pResumeMarker,BOOL bCacheOnly);
  191. enClipStatus OGGClip_getStatus(const Clip *i_pThis);
  192. void OGGClip_refresh(Clip *i_pThis);
  193. UINT16 OGGClip_getTime(const Clip *i_pThis);
  194. void OGGClip_recordMarker(const Clip *i_pThis, ClipMarker *o_pMarker);
  195. /////////////////////////////////////////////////////////////////////////////
  196. // Const Factory
  197. // Valid Extenions List
  198. BEGIN_CLIP_VALID_EXTENSIONS_MAP(OGG)
  199. CLIP_VALID_EXTENSIONS_ENTRY(L"OGG")
  200. END_CLIP_VALID_EXTENSIONS_MAP()
  201. // Constant Attributes
  202. DECLARE_CLIP_CONST_ATTR(OGG, 
  203. DECLARE_CLIP_VTABLE(OGGClip_getExtendedInfo,
  204. OGGClip_play,
  205. GenericClip_pause,
  206. OGGClip_getStatus,
  207. GenericClip_abort,
  208. OGGClip_recordMarker,
  209. OGGClip_refresh,
  210. OGGClip_getTime,
  211. GenericClip_digest,
  212. GenericClip_scan
  213. ),
  214. eClipType_OGG,
  215. DEC_ASID_OGG, 0xFF, DEC_DISC_TYPE_OGG,
  216. eCA_Markable,
  217. NULL
  218. )
  219. /////////////////////////////////////////////////////////////////////////////
  220. // Public Services
  221. BOOL OGGClip_isKindOf(LPCWSTR i_pszFilename)
  222. {
  223. return GenericClip_isKindOf(i_pszFilename, CLIP_VALID_EXTENSIONS(OGG));
  224. }
  225. void OGGClip_construct(Clip *o_pThis, const FindData *i_pFileInfo)
  226. {
  227. GenericClip_construct(o_pThis, i_pFileInfo);
  228. o_pThis->m_pConstAttr= &CLIP_CONST_ATTR(OGG);
  229. }
  230. /////////////////////////////////////////////////////////////////////////////
  231. // Virtual Methods
  232. BOOL OGGClip_getExtendedInfo(const struct Clip_TAG *i_pThis, WORD i_pExtInfo_sc_handle)
  233. {
  234. dbg_printf(("OGGClip_getExtendedInfo()n"));
  235. return OGG_GetOGGInfo(i_pThis->m_cfiInfo.dwFileLocation, i_pExtInfo_sc_handle);
  236. }
  237. BOOL OGGClip_play(Clip *i_pThis, const ClipMarker *i_pResumeMarker, BOOL bCacheOnly)
  238. {
  239. //don't use GenericClip_play now for AC3 clips debug
  240. //return GenericClip_play(i_pThis, i_pResumeMarker, bCacheOnly);
  241. DWORD dwStartLBA;
  242. ULONG ulBlocksCnt;
  243. ULONG cbPlaybackLength;
  244. dbg_printf(("OGG_play()n"));
  245. // Cached-playback is unsupported by default
  246. if (bCacheOnly)
  247. return FALSE;
  248. drv_abort_play();
  249. // Kill any existing Zoom
  250. DEC_SetZoomScale(NO_ZOOM);
  251. // Configure the Decoder to the appropriate Bitstream Type
  252. DEC_SetDiskType((i_pThis->m_pConstAttr)->m_eBitstreamType);
  253. // Prepare for decoding
  254. DEC_prepare_to_decode();
  255. DEC_SetSID(DEC_SID_TYPE_AUDIO, OGG_SID);
  256. DEC_SetSID(DEC_SID_TYPE_VIDEO, (i_pThis->m_pConstAttr)->m_eVideoSID);
  257. // Select the appropriate Clock
  258. PE_Clips_SelectClock(eCT_Internal);
  259. // Calculate the Playback Start-Address
  260. if (NULL == i_pResumeMarker) 
  261. {
  262. // Start at the beginning
  263. dwStartLBA= (i_pThis->m_cfiInfo).dwFileLocation;
  264. }
  265. else 
  266. {
  267. // Playback is being resumed
  268. dwStartLBA= i_pResumeMarker->dwAddress;
  269. }
  270. // Calculate the Playback Length (in Bytes)
  271. cbPlaybackLength= ( (i_pThis->m_cfiInfo).cbFileSize - (LOGICAL_BLOCK_SIZE * (dwStartLBA - (i_pThis->m_cfiInfo).dwFileLocation)) );
  272. ulBlocksCnt= ((cbPlaybackLength + LOGICAL_BLOCK_SIZE - 1) / LOGICAL_BLOCK_SIZE);
  273. // Inform the Decoder of the Playback-Range
  274. PE_Clips_SetPlaybackRange(dwStartLBA, ulBlocksCnt, cbPlaybackLength/2);
  275. // Invoke playback of the Decoder & Drive
  276. // NOTE: The order of invocation is important, and must not be changed!
  277. DEC_PlaybackCommand(DEC_PLAYBACK_CMD_PLAY, NULL);
  278. if (!PE_Clips_Playback_Sectors(DRVCF_CDSPEED_1X | DRVF_PLAY_CD_AV_DATA, dwStartLBA, ulBlocksCnt))
  279. {
  280. tr_printf(("WARNING: OGG_play() Failed [1]n"));
  281. return FALSE;
  282. }
  283. // Restart the Clock
  284. PE_Clips_EnableClock(TRUE, TRUE,(NULL != i_pResumeMarker) ? i_pResumeMarker->uTime : 0);
  285. return TRUE;
  286. }
  287. #pragma argsused
  288. enClipStatus OGGClip_getStatus(const Clip *i_pThis)
  289. {
  290. #if 0
  291. if( bOGGUnsupported )
  292. {
  293. bOGGUnsupported = FALSE;
  294. return eCS_Error_UnsupportedFormat;
  295. }
  296. if (drv_is_play_done() && DEC_IsPlaybackFinished(FALSE))
  297. {
  298. return eCS_Finished;
  299. }
  300. switch(DEC_OGG_getStatus())
  301. {
  302. case OGG_STAT_DECODING_ERROR :
  303. tr_printf(("OGGClip_getStatus: eCS_Error_Decodingn"));
  304. return eCS_Error_Decoding;
  305. case OGG_STAT_FINISHED :
  306. return eCS_Finished;
  307. }
  308. return eCS_Busy;
  309. #else
  310. static UINT16 CurrentClipNumber = 0;
  311. static BOOL msg_is_sent = FALSE;
  312. if( bOGGUnsupported )
  313. {
  314. bOGGUnsupported = FALSE;
  315. return eCS_Error_UnsupportedFormat;
  316. }
  317. if(gns.clips.uCurrentClipNumber != CurrentClipNumber)
  318. {
  319. msg_is_sent = FALSE;
  320. CurrentClipNumber = gns.clips.uCurrentClipNumber;
  321. }
  322. if(drv_is_play_done() && DEC_IsPlaybackFinished(FALSE))
  323. {
  324. if(!msg_is_sent)
  325. {
  326. msg_is_sent = TRUE;
  327. return eCS_Finished;
  328. }
  329. else
  330. {
  331. return eCS_Busy;
  332. }
  333. }
  334. switch(DEC_OGG_getStatus())
  335. {
  336. case OGG_STAT_DECODING_ERROR :
  337. tr_printf(("OGGClip_getStatus: eCS_Error_Decodingn"));
  338. return eCS_Error_Decoding;
  339. case OGG_STAT_FINISHED :
  340. return eCS_Finished;
  341. }
  342. return eCS_Busy;
  343. #endif
  344. }
  345. #pragma argsused
  346. void OGGClip_refresh(Clip *i_pThis)
  347. {
  348. if (PST_PLAY == gcs.pstate) 
  349. {
  350. BOOL bEnableClock= (0 != DEC_ReadCodeBufferFullness(DEC_AUDIO_CODE_BUFFER, DEC_FULLNESS_IN_BYTES));
  351. PE_Clips_EnableClock(bEnableClock, FALSE, 0);
  352. }
  353. }
  354. UINT16 OGGClip_getTime(const Clip *i_pThis)
  355. {
  356. return PE_Clips_GetClock();
  357. }
  358. void OGGClip_recordMarker(const Clip *i_pThis, ClipMarker *o_pMarker)
  359. {
  360. o_pMarker->dwAddress= PE_Clips_GetCurrLocation();
  361. o_pMarker->uTime= GenericClip_getTime(i_pThis);
  362. o_pMarker->uClipNumer = gns.clips.uCurrentClipNumber;
  363. return;
  364. }
  365. #endif //IS_OGG_VORBIS_CAPABLE
  366. //<<<Sean_1213_2004