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

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: MP4.c $             
  6.  *
  7.  * Description: 
  8.  * ============
  9.  *  MP4 Implement
  10.  * 
  11.  * Log:
  12.  * ====
  13.  * $Revision: #36 $
  14.  * $Change: 29878 $ 
  15.  * Last Modified by $Author: robin.jiang $ at $DateTime: 2004/10/29 18:04:12 $ 
  16.  ****************************************************************************************
  17.  * Updates:
  18.  ****************************************************************************************
  19.  * $Log: /I76/I76_Common/I76_Reference/Playcore/Nav_Clips/MP4.c $
  20.  *
  21.  * 1 8/2/2004 RobinJ
  22.  * Created
  23.  *
  24.  ****************************************************************************************/
  25. #include "Config.h" // Global Configuration - do not remove!
  26. #ifdef IS_MP4_CAPABLE
  27. #ifdef _DEBUG
  28. #undef IFTRACE
  29. #define IFTRACE if (gTraceNavigator)
  30. #include "Debugdbgmain.h"
  31. #endif
  32. #include "Includesysdefs.h"
  33. #include "KernelEventDef.H"
  34. #include "PlaycoreNav_ClipsMP4.h"
  35. #include "PlaycoreNav_ClipsMpeg4ClipsCommon.h"
  36. #include "PlaycoreNav_ClipsClip_Impl.h"
  37. #include "PlaycoreNav_ClipsGenericClip.h"
  38. #include "PlaycoreNav_ClipsPE_Clips.h"
  39. #include "PlaycoreCoremainCoreDefs.h"
  40. #include "PlaycoreCoremainCoreGDef.h"
  41. #include "LogoLogo.h"
  42. #include "PlaycoreAuxCacheAuxCache.h"
  43. #include "Decoderlow_levelDEC_LL_Reg.h"
  44. #include "PlaycorePlayModePlayMode.h"
  45. #include "Drivedrv_api.h"
  46. #include "DecoderDecoder.h"
  47. #ifdef USE_AUX_SUBTITLES
  48. #include "PlaycoreNav_ClipsAuxSubtitles.h"
  49. #endif
  50. #ifdef SUPPORT_FLASH_CARD
  51. #include "drivefe_manager.h"
  52. #include "mediacardsincluderegister.h"
  53. #endif
  54. #ifdef _DEBUG
  55. #include "CPUTimefunc.h"
  56. #endif
  57. /////////////////////////////////////////////////////////////////////////////
  58. // Globals and Singletions
  59. /////////////////////////////////////////////////////////////////////////////
  60. // just for debug
  61. //#define PRINTF_MP4_SMAPLE_TABLE
  62. //#define MAX_PRINTF_TABLE_SIZE (MAX_SAMPLE_TABLE_BUFFER_SIZE*1)
  63. //#define PRINTF_MP4_CHUNK_SIZE
  64. //#define MAX_PRINTF_CHUNK_NUM 100
  65. //#ifdef PRINTF_MP4_CHUNK_SIZE
  66. //static UINT32 MAX_PRINTF_CHUNK_NUM = 3000;
  67. //#endif
  68. //#define PRINTF_MP4_TRANSFER_CHUNK_SIZE
  69. //#ifdef PRINTF_MP4_TRANSFER_CHUNK_SIZE
  70. //static DWORD dwTransferChunkOffset = 0;
  71. //#endif
  72. #define MP4_PACK_TRANSFER_CHUNK_SIZE 1
  73. #ifdef SDRAM_2X16MBITS
  74. #define MP4_PACK_CHUNK_NUMBER_THRESHOLD 120000UL
  75. #else
  76. #define MP4_PACK_CHUNK_NUMBER_THRESHOLD 350000UL
  77. #endif
  78. #ifdef SDRAM_2X16MBITS
  79. #define FRAME_BUFFER_R1_ADDR 0x0B3800UL
  80. #else
  81. #define FRAME_BUFFER_R1_ADDR 0x200000UL
  82. #endif
  83. #define MP4_PACK_STSC 1
  84. #define MP4_PACK_STCO_BUFF_SIZE 10
  85. #define MP4_PACK_STCO_BUFF_SIZE_IN_WORD 5
  86. #define MP4_STORE_SAMPLETABLE_AFTER 1
  87. static BOOL bMP4NeedPack = TRUE; // if true, max chunk size is 0xFFFF
  88. static DWORD dwMP4MaxStoreChunkSize = 0xFFFF00UL;
  89. static UINT8 uiMP4ReservedNum = 0;
  90. static BOOL bMP4UnSupportProfile;
  91. // <<< Stivenz_0223_2005: If current chapter is unsupported then goto next.
  92. #ifdef D_MP4_SKIP_UNSUPPORTED_CHAPTER
  93. BOOL bMP4DRMDisable = FALSE;
  94. #else
  95. static BOOL bMP4DRMDisable;
  96. #endif
  97. #ifdef NO_AUTO_PLAY_FOR_CLIPS
  98. extern BOOL g_patch_4_auto_play;
  99. #endif
  100. static CONST UINT32 SAMPLE_RATE_TABLE[16] = {96000UL,88200UL,64000UL,48000UL,44100UL,32000UL,
  101. 24000UL,22050UL,16000UL,12000UL,11025UL,8000UL,
  102. 7350UL,0UL,0UL,0UL};
  103. #define mp4STSCOffsetInFile mp4StreamSampleTableAddrEX.mp4StreamSampleTableAddr.dwSTSCOffsetInFile
  104. #define mp4STSCStartAddr mp4StreamSampleTableAddrEX.mp4StreamSampleTableAddr.dwSTSCStartAddr
  105. #define mp4STSCEntryCount mp4StreamSampleTableAddrEX.mp4StreamSampleTableAddr.dwSTSCEntryCount
  106. #define mp4STCOOffsetInFile mp4StreamSampleTableAddrEX.mp4StreamSampleTableAddr.dwSTCOOffsetInFile
  107. #define mp4STCOStartAddr mp4StreamSampleTableAddrEX.mp4StreamSampleTableAddr.dwSTCOStartAddr
  108. #define mp4STCOEntryCount mp4StreamSampleTableAddrEX.mp4StreamSampleTableAddr.dwSTCOEntryCount
  109. #define mp4STSSOffsetInFile mp4StreamSampleTableAddrEX.mp4StreamSampleTableAddr.dwSTSSOffsetInFile
  110. #define mp4STSSStartAdd mp4StreamSampleTableAddrEX.mp4StreamSampleTableAddr.dwSTSSStartAddr
  111. #define mp4STSSEntryCount mp4StreamSampleTableAddrEX.mp4StreamSampleTableAddr.dwSTSSEntryCount
  112. #define mp4STTSOffsetInFile mp4StreamSampleTableAddrEX.mp4StreamSampleTableAddr.dwSTTSOffsetInFile
  113. #define mp4STTSStartAddr mp4StreamSampleTableAddrEX.mp4StreamSampleTableAddr.dwSTTSStartAddr
  114. #define mp4STTSEntryCount mp4StreamSampleTableAddrEX.mp4StreamSampleTableAddr.dwSTTSEntryCount
  115. #define mp4CompactSampeSize mp4StreamSampleTableAddrEX.mp4StreamSampleTableAddr.bCompactSampeSize
  116. #define mp4STSZOffsetInFile mp4StreamSampleTableAddrEX.mp4StreamSampleTableAddr.dwSTSZOffsetInFile
  117. #define mp4STSZSampleSize mp4StreamSampleTableAddrEX.mp4StreamSampleTableAddr.dwSTSZSampleSize
  118. #define mp4STSZEntryCount mp4StreamSampleTableAddrEX.mp4StreamSampleTableAddr.dwSTSZEntryCount
  119. #define mp4ChunkSizeStartAddr  mp4StreamSampleTableAddrEX.mp4StreamSampleTableAddr.dwChunkSizeStartAddr // not used
  120. #define mp4SyncEntryStartAddr mp4StreamSampleTableAddrEX.mp4StreamSampleTableAddr.dwSyncEntryStartAddr
  121. #define mp4PackSTSC mp4StreamSampleTableAddrEX.mp4StreamSampleTableAddr.bPackSTSC
  122. #define mp4PackSTCO mp4StreamSampleTableAddrEX.mp4StreamSampleTableAddr.bPackSTCO
  123. #define mp4PackSTSZ mp4StreamSampleTableAddrEX.mp4StreamSampleTableAddr.bPackSTSZ
  124. #define mp4CO64 mp4StreamSampleTableAddrEX.mp4StreamSampleTableAddr.bCO64
  125. #define SIZE_OF_MP4StreamSampleTableAddrEX (sizeof(MP4StreamSampleTableAddrEX))
  126. #define SIZE_OF_MP4StreamSampleTableAddrEX_IN_DWORD ((sizeof(MP4StreamSampleTableAddrEX) + 3) >>2)
  127. #define MP4_AUDIO_SYNC_ENTRY_SIZE (sizeof(MP4AudioSyncEntry)/2)
  128. #define MP4_VIDEO_SYNC_ENTRY_SIZE (sizeof(MP4VideoSyncEntry)/2)
  129. #define MP4_AUDIO_SYNC_ENTRY_BUFF_SIZE (MP4_SYNC_ENTRY_BUFF_SIZE*MP4_AUDIO_SYNC_ENTRY_SIZE)
  130. #define MP4_VIDEO_SYNC_ENTRY_BUFF_SIZE (MP4_SYNC_ENTRY_BUFF_SIZE*MP4_VIDEO_SYNC_ENTRY_SIZE)
  131. #define MP4_SUBTITLE_SMAPLE_ENTRY_SIZE (sizeof(MP4SubtitleSampleEntry)/2)
  132. #define MP4_SUBTITLE_SMAPLE_ENTRY_BUFF_SIZE (MP4_SUBTITLE_SAMPLE_ENTRY_BUFF_SIZE * MP4_SUBTITLE_SMAPLE_ENTRY_SIZE)
  133. #define MP4_CALC_ENTRY_ADDRESS(address,size,index) (address - (index * size) - size)
  134. #define MP4_CHUNK_SIZE_ENTRY_SIZE (sizeof(DWORD) / 2)
  135. #define MP4_CHUNK_SIZE_ENTRY_BUFF_SIZE (MP4_CHUNK_SIZE_TABLE_BUFF_SIZE * MP4_CHUNK_SIZE_ENTRY_SIZE)
  136. #define MP4_PACK_CHUNK_SIZE_ENTRY_BUFF_SIZE (MP4_PACK_CHUNK_SIZE_TABLE_BUFF_SIZE * MP4_CHUNK_SIZE_ENTRY_SIZE)
  137. #define MP4_CHUNK_SIZE_TABLE_BUFF_SIZE2 64
  138. #define MP4_PACK_CHUNK_SIZE_TABLE_BUFF_SIZE2 40
  139. #define MP4_CHUNK_SIZE_ENTRY_BUFF_SIZE2 (MP4_CHUNK_SIZE_TABLE_BUFF_SIZE2 * MP4_CHUNK_SIZE_ENTRY_SIZE)
  140. #define MP4_PACK_CHUNK_SIZE_ENTRY_BUFF_SIZE2 (MP4_PACK_CHUNK_SIZE_TABLE_BUFF_SIZE2 * MP4_CHUNK_SIZE_ENTRY_SIZE)
  141. extern CURRENT_STATES gcst; /* Global current status */
  142. extern BOOL change_pallet;
  143. extern void DEC_SetMPP(BOOL enable);
  144. extern void DEC_MP4_ChunkSizeFifoInit();
  145. /////////////////////////////////////////////////////////////////////////////
  146. static UINT32 _toBe32(BYTE *pBuff);
  147. static UINT16 _toBe16(BYTE *pBuff);
  148. #ifdef D_ENABLE_AAC_SUPPORT
  149. static UINT32 getbits(UINT8 *buffer,UINT8 *CurrentPtr,UINT32 *cword,UINT8 *nbits,UINT8 n, UINT16 length);
  150. static BOOL _mp4ReadAudioSpecificConfig(BYTE *AudioSpecificConfig, UINT16 length);
  151. #endif
  152. static BOOL _mp4ReadSubPictureConfig(BYTE *SubPictureConfig, UINT16 length);
  153. static BOOL _mp4GetNextBox(DWORD dwClipStartAddr, DWORD* dwOffset, MP4Box* pMP4Box);
  154. static int  _mp4ReadDescr(DWORD dwStartAddr, DWORD *dwOffset, int *tag);
  155. static BOOL _mp4StoreSampleTable(DWORD dwStartAddr, DWORD dwOffset, DWORD dwSampleTableSize, DWORD dwSampleTableAddr, BOOL b64Bits);
  156. static BOOL _mp4ReadBox_ESDS(DWORD dwStartAddr, DWORD dwOffset, MP4_CODEC_TYPE trackCodecType, int *len);
  157. static BOOL _mp4StreamsInfoProcessing(DWORD dwStartAddr, DWORD dwStartOffset, DWORD dwSize);
  158. static BOOL _mp4InfoProcessing(DWORD dwClipStartAddr, ULONG cbFileSize);
  159. static BOOL _mp4StreamSampleTableProcessing(DWORD dwStartAddr, WORD wSampleTableAddrEXAddr, DWORD *dwChunkSizeAddr, DWORD *dwSyncSampleAddr, 
  160. MP4_CODEC_TYPE codecType, DWORD dwMP4VideoSTSSStartAdd);
  161. static BOOL _mp4SampleTableProcessing(DWORD dwStartAddr);
  162. static void _mp4SetFirstSkipBytes(BOOL bScan);
  163. static void _mp4TransferChunkSize(/*BOOL bFirst,*/ BOOL bWait);
  164. static BOOL _mp4ChunkSizeProcessing(void);
  165. static BOOL _mp4GetAdjacentIFrames(WORD wTime, DWORD *dwVideoSyncSampleNum, DWORD *dwSyncSampleOffset);
  166. static void _mp4PrePlayProcessing(DWORD dwSamplingRate, UINT8 uiAudioSid,
  167.    UINT8 uiAudioSIDDecoder, UINT8 uiVideoSid, BOOL bClipStart, BOOL bScan);
  168. static void _mp4InitTransferChunkSize(BOOL bScan, DWORD dwVideoSampleSize );
  169. #ifdef MP4_TANSFER_CHUNKSIZE_BY_FIFO
  170. static void _mp4TransferChunkSizeByFifo(void);
  171. #endif
  172. static BOOL _mp4Scan(INT8 iIndexIncrement, BOOL bContinue);
  173. static void _mp4ClearAPPBuffer(void);
  174. static void _mp4ChapterRefresh(void);
  175. static BOOL _mp4DetectBVOP(void);
  176. // Forward Declarations of Virtual Methods
  177. BOOL  MP4Clip_getExtendedInfo(const struct Clip_TAG *i_pThis, void *o_pExtInfoContainer);
  178. BOOL  MP4Clip_play(Clip *i_pThis, const ClipMarker *i_pResumeMarker, BOOL bCacheOnly);
  179. void  MP4Clip_pause(Clip *i_pThis, BOOL bEnable);
  180. void  MP4Clip_refresh(Clip *i_pThis);
  181. UINT16  MP4Clip_getTime(const Clip *i_pThis);
  182. enClipStatus MP4Clip_getStatus(const Clip *i_pThis);
  183. void  MP4Clip_scan(Clip *i_pThis, int iScanSpeed);
  184. void  MP4Clip_recordMarker(const Clip *i_pThis, ClipMarker *o_pMarker);
  185. void  MP4Clip_abort(Clip *i_pThis, BOOL bMaintainStandby);
  186. void _mp4SubPictureArrived();
  187. #ifdef MP4_TANSFER_CHUNKSIZE_BY_FIFO
  188. extern void DEC_MP4_ChunkSizeFifoInit(void);
  189. extern void DEC_MP4_SetFlashCardNotNeedCheck(void);
  190. #endif
  191. extern void mp4InitSubtitles(void);
  192. /////////////////////////////////////////////////////////////////////////////
  193. // Const Factory
  194. /* Valid Extenions List */
  195. BEGIN_CLIP_VALID_EXTENSIONS_MAP(MP4)
  196. CLIP_VALID_EXTENSIONS_ENTRY(L"MP4")
  197. CLIP_VALID_EXTENSIONS_ENTRY(L"M4A")
  198. // CLIP_VALID_EXTENSIONS_ENTRY(L"MP4V") // Robin_TBD
  199. // CLIP_VALID_EXTENSIONS_ENTRY(L"MP4A") // Robin_TBD
  200. // CLIP_VALID_EXTENSIONS_ENTRY(L"3GP") // Robin_TBD
  201. // CLIP_VALID_EXTENSIONS_ENTRY(L"MOV") // Robin_TBD
  202. END_CLIP_VALID_EXTENSIONS_MAP()
  203. /* Constant Attributes */
  204. DECLARE_CLIP_CONST_ATTR(MP4, 
  205. DECLARE_CLIP_VTABLE(MP4Clip_getExtendedInfo,
  206. MP4Clip_play,
  207. MP4Clip_pause,
  208. MP4Clip_getStatus,
  209. MP4Clip_abort,
  210. MP4Clip_recordMarker,
  211. MP4Clip_refresh,
  212. MP4Clip_getTime,
  213. GenericClip_digest,
  214. MP4Clip_scan
  215. ),
  216. eClipType_MP4,
  217. 0xFF, 0xE0, DEC_DISC_TYPE_MP4, //FW0408_2005C Set 0xE0 as video SID
  218. (eCA_Scanable | eCA_Zoomable | eCA_Slowable | eCA_Markable/* | eCA_Digestable*/),
  219. NULL
  220. )
  221. /////////////////////////////////////////////////////////////////////////////
  222. // Private Services
  223. ///////////////////////////////////////////////////////////////////////////
  224. static UINT32 _toBe32(BYTE *pBuff)
  225. {
  226. #if 1
  227. UINT32 ulResult;
  228. BYTE *pResult = (BYTE*)&ulResult;
  229. UINT16 uiInputIndex;
  230. UINT16 uiOutputIndex = 3;
  231. for (uiInputIndex=0; uiInputIndex<4; uiInputIndex++)
  232. {
  233. pResult[uiOutputIndex] = pBuff[uiInputIndex];
  234. uiOutputIndex--;
  235. }
  236. return ulResult;
  237. #else
  238. return (((UINT32)pBuff[0] << 24) | ((UINT32)pBuff[1] << 16)  | ((UINT32)pBuff[2] << 8) | ((UINT32)pBuff[3]));
  239. #endif
  240. }
  241. static UINT16 _toBe16(BYTE *pBuff)
  242. {
  243. return (((UINT16)pBuff[0] << 8) | ((UINT16)pBuff[1]));
  244. }
  245. #ifdef D_ENABLE_AAC_SUPPORT
  246. static UINT32 getbits(UINT8 *buffer,UINT8 *CurrentPtr,UINT32 *cword,UINT8 *nbits,UINT8 n,  UINT16 length)
  247. {
  248. if(n <= 16)
  249. {
  250.     if(*nbits <= 16)
  251.     {
  252. if((*CurrentPtr > (length-1)) && (*nbits < n))
  253. {
  254. dbg_printf(("getbits: not enough data to parse!n"));
  255. return 0;
  256. }
  257.     
  258. *cword = (*cword << 16 ) | ((UINT32)(*((UINT8 *)(buffer + (*CurrentPtr)))) << 8) | (UINT32)(*((UINT8 *)(buffer + (*CurrentPtr) + 1)));
  259. *nbits += 16;
  260. (*CurrentPtr) += 2;
  261.     }
  262.     *nbits -= n;
  263.     
  264.     return ((*cword >> *nbits) & ((1<<n)-1));
  265. }
  266. else
  267. {
  268. return ((getbits(buffer,CurrentPtr,cword,nbits,(n-16),length) << 16) | getbits(buffer,CurrentPtr,cword,nbits,16,length));
  269. }
  270. }
  271. ///////////////////////////////////////////////////////////////////////////
  272. // Function name : _mp4ReadAudioSpecificConfig
  273. // Purpose : parse AudioSpecificConfig info 
  274. // Input Parameters : AudioSpecificConfig - The start address to AudioSpecificConfig.
  275. //
  276. // Return type : TRUE - if succeeded, FALSE otherwise.
  277. ///////////////////////////////////////////////////////////////////////////
  278. static BOOL _mp4ReadAudioSpecificConfig(BYTE *AudioSpecificConfig, UINT16 length)
  279. {
  280. UINT8 audioObjectType;
  281. UINT8 CurrentPtr = 0;
  282. UINT32 cword=0;
  283. UINT8 nbits=0;
  284. UINT8 i;
  285. audioObjectType = (UINT8)getbits(AudioSpecificConfig,&CurrentPtr,&cword,&nbits,5, length);
  286. _mpeg4AudioInfo_AAC.samplingFrequencyIndex = getbits(AudioSpecificConfig,&CurrentPtr,&cword,&nbits,4, length);
  287. if(_mpeg4AudioInfo_AAC.samplingFrequencyIndex == 0xF)
  288. {
  289. _mpeg4AudioSamplesPerSec = getbits(AudioSpecificConfig,&CurrentPtr,&cword,&nbits,24, length);
  290. }
  291. else
  292. {
  293. _mpeg4AudioSamplesPerSec = SAMPLE_RATE_TABLE[_mpeg4AudioInfo_AAC.samplingFrequencyIndex % 16];
  294. }
  295. _mpeg4AudioInfo_AAC.channelConfiguration = getbits(AudioSpecificConfig,&CurrentPtr,&cword,&nbits,4, length);
  296. if((audioObjectType != 1) && (audioObjectType != 2) && (audioObjectType != 3)
  297. && (audioObjectType != 4) && (audioObjectType != 6) && (audioObjectType != 7)
  298. && (audioObjectType != 17) && (audioObjectType != 19) && (audioObjectType != 20)
  299. && (audioObjectType != 21) && (audioObjectType != 22) && (audioObjectType != 23)
  300. )
  301. {
  302. return FALSE;
  303. }
  304. getbits(AudioSpecificConfig,&CurrentPtr,&cword,&nbits,1, length);
  305. if(getbits(AudioSpecificConfig,&CurrentPtr,&cword,&nbits,1, length))
  306. {
  307. getbits(AudioSpecificConfig,&CurrentPtr,&cword,&nbits,14, length);
  308. }
  309. getbits(AudioSpecificConfig,&CurrentPtr,&cword,&nbits,1, length);
  310. if(!_mpeg4AudioInfo_AAC.channelConfiguration)
  311. {
  312. getbits(AudioSpecificConfig,&CurrentPtr,&cword,&nbits,10, length);
  313. _mpeg4AudioInfo_AAC.num_front_channel_elements = getbits(AudioSpecificConfig,&CurrentPtr,&cword,&nbits,4, length);
  314. _mpeg4AudioInfo_AAC.num_side_channel_elements = getbits(AudioSpecificConfig,&CurrentPtr,&cword,&nbits,4, length);
  315. _mpeg4AudioInfo_AAC.num_back_channel_elements = getbits(AudioSpecificConfig,&CurrentPtr,&cword,&nbits,4, length);
  316. _mpeg4AudioInfo_AAC.num_lfe_channel_elements = getbits(AudioSpecificConfig,&CurrentPtr,&cword,&nbits,2, length);
  317. getbits(AudioSpecificConfig,&CurrentPtr,&cword,&nbits,7, length);
  318. if(getbits(AudioSpecificConfig,&CurrentPtr,&cword,&nbits,1, length))
  319. {
  320. getbits(AudioSpecificConfig,&CurrentPtr,&cword,&nbits,4, length);
  321. }
  322. if(getbits(AudioSpecificConfig,&CurrentPtr,&cword,&nbits,1, length))
  323. {
  324. getbits(AudioSpecificConfig,&CurrentPtr,&cword,&nbits,4, length);
  325. }
  326. if(getbits(AudioSpecificConfig,&CurrentPtr,&cword,&nbits,1, length))
  327. {
  328. getbits(AudioSpecificConfig,&CurrentPtr,&cword,&nbits,3, length);
  329. }
  330. for(i=0; i < _mpeg4AudioInfo_AAC.num_front_channel_elements; i++)
  331. {
  332. _mpeg4AudioInfo_AAC.main_channel_elements[i].front_element_is_cpe = getbits(AudioSpecificConfig,&CurrentPtr,&cword,&nbits,1, length);
  333. _mpeg4AudioInfo_AAC.main_channel_elements[i].front_element_tag_select = getbits(AudioSpecificConfig,&CurrentPtr,&cword,&nbits,4, length);
  334. }
  335. for(i=0; i < _mpeg4AudioInfo_AAC.num_side_channel_elements; i++)
  336. {
  337. _mpeg4AudioInfo_AAC.main_channel_elements[i].side_element_is_cpe = getbits(AudioSpecificConfig,&CurrentPtr,&cword,&nbits,1, length);
  338. _mpeg4AudioInfo_AAC.main_channel_elements[i].side_element_tag_select = getbits(AudioSpecificConfig,&CurrentPtr,&cword,&nbits,4, length);
  339. }
  340. for(i=0; i < _mpeg4AudioInfo_AAC.num_back_channel_elements; i++)
  341. {
  342. _mpeg4AudioInfo_AAC.main_channel_elements[i].back_element_is_cpe = getbits(AudioSpecificConfig,&CurrentPtr,&cword,&nbits,1, length);
  343. _mpeg4AudioInfo_AAC.main_channel_elements[i].back_element_tag_select = getbits(AudioSpecificConfig,&CurrentPtr,&cword,&nbits,4, length);
  344. }
  345. for(i=0; i < _mpeg4AudioInfo_AAC.num_lfe_channel_elements; i++)
  346. {
  347. _mpeg4AudioInfo_AAC.lfe_channel_elements[i].lfe_element_tag_select = getbits(AudioSpecificConfig,&CurrentPtr,&cword,&nbits,4, length);
  348. }
  349. }
  350. return TRUE;
  351. }
  352. #endif //D_ENABLE_AAC_SUPPORT
  353. ///////////////////////////////////////////////////////////////////////////
  354. // Function name : _mp4ReadSubPictureSpecificConfig
  355. // Purpose : parse SubPictureSpecificConfig info 
  356. // Input Parameters : SubPictureConfig - The start address to SubPictureConfig.
  357. //
  358. // Return type : TRUE - if succeeded, FALSE otherwise.
  359. ///////////////////////////////////////////////////////////////////////////
  360. static BOOL _mp4ReadSubPictureConfig(BYTE *SubPictureConfig, UINT16 length)
  361. {
  362. UINT16 uiCount = 0;
  363. while(uiCount < (length-3))
  364. {
  365.         I49_ParameterWrite(SPPALETTE_ADDR, ((WORD)(SubPictureConfig[uiCount+1])&0xFF));   /* m.s. 16 bits */
  366.         I49_ParameterWrite(SPPALETTE_ADDR, (((WORD) (SubPictureConfig[uiCount+2])<<8) |
  367.    ((WORD)(SubPictureConfig[uiCount+3])))); /* l.s. 16 bits */
  368. uiCount += 4;
  369. }
  370. while (uiCount < (64 -3))
  371. {
  372.         I49_ParameterWrite(SPPALETTE_ADDR, 0);   /* m.s. 16 bits */
  373.         I49_ParameterWrite(SPPALETTE_ADDR, 0); /* l.s. 16 bits */
  374. uiCount += 4;
  375. }
  376. return TRUE;
  377. }
  378. ///////////////////////////////////////////////////////////////////////////
  379. // Function name : _mp4GetNextBox
  380. // Purpose : Returns the next BOX in the file.
  381. // Input Parameters : dwClipStartAddr - The start address to get the BOX.
  382. //   dwOffset        - The offset to read the BOX.
  383. // Return type : TRUE - if succeeded, FALSE otherwise.
  384. // Output Parameters   : pMP4Box - The BOX info which was read.
  385. ///////////////////////////////////////////////////////////////////////////
  386. static BOOL _mp4GetNextBox(DWORD dwClipStartAddr, DWORD* dwOffset, MP4Box* pMP4Box)
  387. {
  388. BYTE Temp[8];
  389. if (FALSE == AuxCache_GetBytes(dwClipStartAddr, *dwOffset, (WORD)8, &Temp[0]))
  390. {
  391. dbg_printf(("FATAL: _mp4GetNextBox() Failed [1]n"));
  392. return FALSE;
  393. }
  394. *dwOffset += 8UL;
  395. pMP4Box->ulSize = _toBe32(&Temp[0]);
  396. memcpy((BYTE*)&pMP4Box->ulType,&Temp[4],4);
  397. if (pMP4Box->ulSize == 1UL) // large size
  398. {
  399. if (FALSE == AuxCache_GetBytes(dwClipStartAddr, *dwOffset, 8, &Temp[0]))
  400. {
  401. dbg_printf(("FATAL: _mp4GetNextBox() Failed [2]n"));
  402. return FALSE;
  403. }
  404. *dwOffset += 8UL;
  405. pMP4Box->ulSize = _toBe32(&Temp[4]);
  406. pMP4Box->ulSize -= 8UL;
  407. }
  408. if (0 == strnicmp((LPSTR)(pMP4Box->ulSize), MP4_USER_TYPE_ID, FOURCC_FIELD_LENGTH))
  409. {
  410. *dwOffset += 16UL;
  411. pMP4Box->ulSize -= 16UL;
  412. }
  413. pMP4Box->ulSize -= 8UL;
  414. return TRUE;
  415. }
  416. ///////////////////////////////////////////////////////////////////////////
  417. // Function name : _mp4ReadDescr
  418. // Purpose : Returns the Descriptor Tag.
  419. // Input Parameters : dwClipAddr - The start address to get the Descriptor.
  420. //   dwOffset        - The offset to read the Descriptor.
  421. // Return type : TRUE - if succeeded, FALSE otherwise.
  422. // Output Parameters   : Tag - The descriptor tag.
  423. ///////////////////////////////////////////////////////////////////////////
  424. static int _mp4ReadDescr(DWORD dwStartAddr, DWORD *dwOffset, int *tag)
  425. {
  426. int len = 0;
  427. int count = 4;
  428. int i = 1;
  429. BYTE TempBuff[5];
  430. if (FALSE == AuxCache_GetBytes(dwStartAddr, *dwOffset, (WORD)5, &TempBuff[0]))
  431. return len;
  432. (*dwOffset)++;
  433. *tag = (int)TempBuff[0];
  434. while (count--)
  435. {
  436. int c;
  437. c = (int)TempBuff[i++];
  438. (*dwOffset)++;
  439. len = (len << 7) | (c & 0x7f);
  440. if (!(c & 0x80))
  441. break;
  442. }
  443. return len;
  444. }
  445. ///////////////////////////////////////////////////////////////////////////
  446. // Function name : _mp4StoreSampleTable
  447. // Purpose : store the sample table to DRAM
  448. // Input Parameters : dwStartAddr - The start address to get the Sample Table.
  449. //   dwOffset   - The offset to read the Sample Table.
  450. //   dwSampleTableSize - the size of the Sampe Table
  451. //   dwSampleTableAddr - The store DRAM start address of the Sample Table.
  452. //    b64Bits - "co64", discard the high 32bits
  453. // Return type : TRUE - if succeeded, FALSE otherwise.
  454. // Output Parameters   : 
  455. ///////////////////////////////////////////////////////////////////////////
  456. static BOOL _mp4StoreSampleTable(DWORD dwStartAddr, DWORD dwOffset, DWORD dwSampleTableSize, DWORD dwSampleTableAddr, BOOL b64Bits)
  457. {
  458. DWORD dwSize = dwSampleTableSize;
  459. DWORD dwDRAMAddr = dwSampleTableAddr;
  460. WORD wCacheSize;
  461. WORD wStoreSize;
  462. BOOL bError = TRUE;
  463. BOOL bFirstTime = TRUE;
  464. DWORD dwSampleTableStartAddr;
  465. DWORD dwSampleTableOffset;
  466. DWORD dwSampleTableSizeSave;
  467. #ifdef PRINTF_MP4_SMAPLE_TABLE
  468. DWORD dwPrintfOffset = dwOffset;
  469. DWORD dwPrintfCount = 0;
  470. int i;
  471. #endif
  472. dwSampleTableStartAddr = dwStartAddr + (dwOffset/2048UL);
  473. dwSampleTableOffset = dwOffset%2048UL;
  474. dwSampleTableSizeSave = dwSampleTableSize + dwSampleTableOffset;
  475. while (dwSize > 0)
  476. {
  477. wCacheSize = (dwSize < MAX_SAMPLE_TABLE_BUFFER_SIZE) ? (WORD)dwSize : MAX_SAMPLE_TABLE_BUFFER_SIZE;
  478. #ifdef SUPPORT_FLASH_CARD
  479. if(IS_PLAYING_CARD)
  480. {
  481. if (!AuxCache_GetBytes(dwSampleTableStartAddr, dwSampleTableOffset, wCacheSize, (BYTE*)&_MP4SharedBuff[0]))
  482. {
  483. bError = FALSE;
  484. dbg_printf(("_mp4StoreSampleTable(): AuxCache_GetBytes() Fail[] n"));
  485. break;
  486. }
  487. }
  488. else
  489. #endif
  490. if (!AuxCache_GetFile(dwSampleTableStartAddr, dwSampleTableOffset, wCacheSize, dwSampleTableSizeSave, bFirstTime, (BYTE*)&_MP4SharedBuff[0]))
  491. {
  492. bError = FALSE;
  493. dbg_printf(("_mp4StoreSampleTable(): AuxCache_GetFile() Fail[] n"));
  494. break;
  495. }
  496. if(bError == FALSE)
  497. break;
  498. #ifdef PRINTF_MP4_SMAPLE_TABLE
  499. if (dwPrintfCount < MAX_PRINTF_TABLE_SIZE)
  500. {
  501. for (wStoreSize = 0; wStoreSize < wCacheSize; wStoreSize+= 16)
  502. {
  503. dbg_printf(("%lx  ",dwPrintfOffset));
  504. for(i=0;i<16;i++)
  505. dbg_printf(("%2x ",_MP4SharedBuff[wStoreSize+i]));
  506. dbg_printf(("n"));
  507. dwPrintfOffset += 16;
  508. }
  509. }
  510. dwPrintfCount += wCacheSize;
  511. #endif
  512. if(TRUE == b64Bits)
  513. {
  514. WORD wOffset=0;
  515. WORD wCacheSizeTemp = wCacheSize;
  516. while(wCacheSizeTemp)
  517. {
  518. memcpy((BYTE*)&_MP4SharedBuff[4*wOffset],(BYTE*)&_MP4SharedBuff[(8*wOffset)+4],4);
  519. wCacheSizeTemp -= 8;
  520. wOffset += 1;
  521. }
  522. wStoreSize = wCacheSize/2; 
  523. }
  524. else
  525. {
  526. wStoreSize = wCacheSize; 
  527. }
  528. {
  529. WORD wInOffset;
  530. BYTE temp;
  531. for (wInOffset = 0; wInOffset < wStoreSize; wInOffset+=4)
  532. {
  533. temp = _MP4SharedBuff[wInOffset+3];
  534. _MP4SharedBuff[wInOffset+3] = _MP4SharedBuff[wInOffset];
  535. _MP4SharedBuff[wInOffset] = temp;
  536. temp = _MP4SharedBuff[wInOffset +2];
  537. _MP4SharedBuff[wInOffset+2] = _MP4SharedBuff[wInOffset+1];
  538. _MP4SharedBuff[wInOffset+1] = temp;
  539. }
  540. }
  541. wai_sem(SEM_DRAM_ID);
  542. I49_WriteDRAMData(dwDRAMAddr,(UINT16*)&_MP4SharedBuff[0], (wStoreSize/2));
  543. sig_sem(SEM_DRAM_ID);
  544. dwSize -= wCacheSize;
  545. dwDRAMAddr += (wStoreSize/2); // in words
  546. dwSampleTableOffset += wCacheSize;
  547. bFirstTime = FALSE;
  548. }
  549. AuxCache_GetFileTerminate();
  550. return bError;
  551. }
  552. #ifdef MP4_PACK_STSC
  553. static BOOL _mp4StorePackSTSC(DWORD dwStartAddr, DWORD dwOffset, /*DWORD dwSampeTableEntryCount,*/ DWORD dwSampleTableSize, DWORD dwSampleTableAddr)
  554. {
  555. DWORD dwSize = dwSampleTableSize;
  556. DWORD dwDRAMAddr = dwSampleTableAddr;
  557. WORD wCacheSize;
  558. WORD wStoreSize;
  559. BOOL bError = TRUE;
  560. BOOL bFirstTime = TRUE;
  561. DWORD dwSampleTableStartAddr;
  562. DWORD dwSampleTableOffset;
  563. DWORD dwSampleTableSizeSave;
  564. DWORD dwFirstChunk;
  565. DWORD dwSamplePreChunk;
  566. DWORD dwPackSTSC;
  567. #ifdef PRINTF_MP4_SMAPLE_TABLE
  568. DWORD dwPrintfOffset = dwOffset;
  569. DWORD dwPrintfCount = 0;
  570. int i;
  571. #endif
  572. dwSampleTableStartAddr = dwStartAddr + (dwOffset/2048UL);
  573. dwSampleTableOffset = dwOffset%2048UL;
  574. dwSampleTableSizeSave = dwSampleTableSize + dwSampleTableOffset;
  575. #define MAX_STSC_BUFFER_SIZE ((MAX_SAMPLE_TABLE_BUFFER_SIZE/sizeof(MP4SampleToChunkEntry))*sizeof(MP4SampleToChunkEntry))
  576. while (dwSize > 0)
  577. {
  578. wCacheSize = (dwSize < MAX_STSC_BUFFER_SIZE) ? (WORD)dwSize : MAX_STSC_BUFFER_SIZE;
  579. #ifdef SUPPORT_FLASH_CARD
  580. if(IS_PLAYING_CARD)
  581. {
  582. if (!AuxCache_GetBytes(dwSampleTableStartAddr, dwSampleTableOffset, wCacheSize, (BYTE*)&_MP4SharedBuff[0]))
  583. {
  584. bError = FALSE;
  585. dbg_printf(("_mp4StorePackSTSC(): AuxCache_GetBytes() Fail[] n"));
  586. break;
  587. }
  588. }
  589. else
  590. #endif
  591. if (!AuxCache_GetFile(dwSampleTableStartAddr, dwSampleTableOffset, wCacheSize, dwSampleTableSizeSave, bFirstTime, (BYTE*)&_MP4SharedBuff[0]))
  592. {
  593. bError = FALSE;
  594. dbg_printf(("_mp4StorePackSTSC(): AuxCache_GetFile() Fail[] n"));
  595. break;
  596. }
  597. #ifdef PRINTF_MP4_SMAPLE_TABLE
  598. if (dwPrintfCount < MAX_PRINTF_TABLE_SIZE)
  599. {
  600. for (wStoreSize = 0; wStoreSize < wCacheSize; wStoreSize+= 16)
  601. {
  602. dbg_printf(("%lx  ",dwPrintfOffset));
  603. for(i=0;i<16;i++)
  604. dbg_printf(("%2x ",_MP4SharedBuff[wStoreSize+i]));
  605. dbg_printf(("n"));
  606. dwPrintfOffset += 16;
  607. }
  608. }
  609. dwPrintfCount += wCacheSize;
  610. #endif
  611. for (wStoreSize = 0; wStoreSize < wCacheSize; wStoreSize+= 12)
  612. {
  613. dwFirstChunk = _toBe32((BYTE*)&_MP4SharedBuff[wStoreSize]);
  614. dwSamplePreChunk = _toBe32((BYTE*)&_MP4SharedBuff[wStoreSize+4]);
  615. if (dwFirstChunk >= 0x100000UL)
  616. {
  617. bError = FALSE;
  618. tr_printf(("nERROR: too many chunks! dwFirstChunk: %ldn", dwFirstChunk));
  619. }
  620. if (dwSamplePreChunk >= 0x1000UL)
  621. {
  622. bError = FALSE;
  623. tr_printf(("nERROR: too many sample per chunk! dwSamplePreChunk: %ldn",dwSamplePreChunk));
  624. }
  625. dwPackSTSC = (dwFirstChunk<<12) + dwSamplePreChunk;
  626. memcpy((BYTE*)&_MP4SharedBuff[wStoreSize/3],(BYTE*)&dwPackSTSC,4);
  627. }
  628. if(bError == FALSE)
  629. break;
  630. wai_sem(SEM_DRAM_ID);
  631. I49_WriteDRAMData(dwDRAMAddr,(UINT16*)&_MP4SharedBuff[0], (wStoreSize/6));
  632. sig_sem(SEM_DRAM_ID);
  633. dwSize -= wCacheSize;
  634. dwDRAMAddr += (wStoreSize/6); // in words
  635. dwSampleTableOffset += wCacheSize;
  636. bFirstTime = FALSE;
  637. }
  638. AuxCache_GetFileTerminate();
  639. return bError;
  640. }
  641. static BOOL _mp4CheckIfPackSTSC(DWORD dwSTSCEntryCount, DWORD dwSyncSampleAddr)
  642. {
  643. DWORD dwSTSCEndAddr;
  644. DWORD dwSyncStartAddr;
  645. DWORD dwEntrySize;
  646. dwEntrySize = _uiMPEG4NextIndexEntry * sizeof(MP4VideoSyncEntry);
  647. dwSyncStartAddr = dwSyncSampleAddr - (dwEntrySize>>1);
  648. dwSyncStartAddr = (dwSyncStartAddr>>9)<<9;
  649. dwEntrySize = dwSTSCEntryCount * sizeof(MP4SampleToChunkEntry);
  650. dwSTSCEndAddr = _dwMP4SampleTableAddr + (dwEntrySize>>1);
  651. dwSTSCEndAddr = ((dwSTSCEndAddr + 0x1FFUL)>>9)<<9; 
  652. if (dwSTSCEndAddr >= dwSyncStartAddr)
  653. {
  654. dwSTSCEndAddr = _dwMP4SampleTableAddr + ((dwEntrySize>>1)/3);
  655. dwSTSCEndAddr = ((dwSTSCEndAddr + 0x1FFUL)>>9)<<9; 
  656. if (dwSTSCEndAddr >= dwSyncStartAddr)
  657. {
  658. tr_printf(("nnNo enough memory space to store STSC!nn"));
  659. }
  660. return TRUE;
  661. }
  662. else
  663. return FALSE;
  664. }
  665. #endif
  666. #ifdef MP4_PACK_STCO
  667. static BOOL _mp4StoreSTCOTable(DWORD dwStartAddr, DWORD dwOffset, DWORD dwEntryCount, DWORD dwSampleTableAddr, BOOL b64Bits)
  668. {
  669. DWORD dwSize;
  670. DWORD dwDRAMAddr = dwSampleTableAddr;
  671. WORD wCacheSize;
  672. WORD wStoreSize;
  673. BOOL bError = TRUE;
  674. BOOL bFirstTime = TRUE;
  675. DWORD dwSampleTableStartAddr;
  676. DWORD dwSampleTableOffset;
  677. DWORD dwSampleTableSizeSave;
  678. DWORD dwChunkOffset;
  679. DWORD dwPreChunkOffset;
  680. DWORD   dwSampleTableSize;
  681. WORD wOffset;
  682. WORD wPackOffset;
  683. #ifdef PRINTF_MP4_SMAPLE_TABLE
  684. DWORD dwPrintfOffset = dwOffset;
  685. DWORD dwPrintfCount = 0;
  686. int i;
  687. #endif
  688. dwSampleTableSize = dwEntryCount * sizeof(DWORD) * (b64Bits ? 2 : 1);
  689. dwSize = dwSampleTableSize;
  690. dwSampleTableStartAddr = dwStartAddr + (dwOffset/2048UL);
  691. dwSampleTableOffset = dwOffset%2048UL;
  692. dwSampleTableSizeSave = dwSampleTableSize + dwSampleTableOffset;
  693. while (dwSize > 0)
  694. {
  695. wCacheSize = (dwSize < MAX_SAMPLE_TABLE_BUFFER_SIZE) ? (WORD)dwSize : MAX_SAMPLE_TABLE_BUFFER_SIZE;
  696. #ifdef SUPPORT_FLASH_CARD
  697. if(IS_PLAYING_CARD)
  698. {
  699. if (!AuxCache_GetBytes(dwSampleTableStartAddr, dwSampleTableOffset, wCacheSize, (BYTE*)&_MP4SharedBuff[0]))
  700. {
  701. bError = FALSE;
  702. dbg_printf(("_mp4StoreSampleTable(): AuxCache_GetBytes() Fail[] n"));
  703. break;
  704. }
  705. }
  706. else
  707. #endif
  708. if (!AuxCache_GetFile(dwSampleTableStartAddr, dwSampleTableOffset, wCacheSize, dwSampleTableSizeSave, bFirstTime, (BYTE*)&_MP4SharedBuff[0]))
  709. {
  710. bError = FALSE;
  711. dbg_printf(("_mp4StoreSampleTable(): AuxCache_GetFile() Fail[] n"));
  712. break;
  713. }
  714. if(bError == FALSE)
  715. break;
  716. #ifdef PRINTF_MP4_SMAPLE_TABLE
  717. if (dwPrintfCount < MAX_PRINTF_TABLE_SIZE)
  718. {
  719. for (wStoreSize = 0; wStoreSize < wCacheSize; wStoreSize+= 16)
  720. {
  721. dbg_printf(("%lx  ",dwPrintfOffset));
  722. for(i=0;i<16;i++)
  723. dbg_printf(("%2x ",_MP4SharedBuff[wStoreSize+i]));
  724. dbg_printf(("n"));
  725. dwPrintfOffset += 16;
  726. }
  727. }
  728. dwPrintfCount += wCacheSize;
  729. #endif
  730. if(TRUE == b64Bits)
  731. {
  732. WORD wCacheSizeTemp = wCacheSize;
  733. wOffset = 0;
  734. while(wCacheSizeTemp)
  735. {
  736. memcpy((BYTE*)&_MP4SharedBuff[4*wOffset],(BYTE*)&_MP4SharedBuff[(8*wOffset)+4],4);
  737. wCacheSizeTemp -= 8;
  738. wOffset += 1;
  739. }
  740. wStoreSize = wCacheSize/2; 
  741. }
  742. else
  743. {
  744. wStoreSize = wCacheSize; 
  745. }
  746. // if (TRUE == bNeedPack)
  747. DWORD dwChunkSize;
  748. wOffset = 0;
  749. wPackOffset = 0;
  750. if (TRUE == bFirstTime)
  751. {
  752. dwPreChunkOffset = _toBe32(&_MP4SharedBuff[0]);
  753. wai_sem(SEM_DRAM_ID);
  754. I49_WriteDRAMData(dwDRAMAddr,(UINT16*)&dwPreChunkOffset, 2); // first chunk offset
  755. sig_sem(SEM_DRAM_ID);
  756. dwDRAMAddr += 2; // in words
  757. }
  758. while (wOffset<wStoreSize/4)
  759. {
  760. dwChunkOffset = _toBe32(&_MP4SharedBuff[4*wOffset]);
  761. dwChunkSize = dwChunkOffset - dwPreChunkOffset;
  762. dwPreChunkOffset = dwChunkOffset;
  763. if (wOffset%2 == 0)
  764. {
  765. _MP4SharedBuff[wPackOffset++] = (BYTE)dwChunkSize;
  766. _MP4SharedBuff[wPackOffset++] = (BYTE)(dwChunkSize>>8);
  767. _MP4SharedBuff[wPackOffset] = (BYTE)(dwChunkSize>>16);
  768. }
  769. else
  770. {
  771. _MP4SharedBuff[wPackOffset++] += (BYTE)(dwChunkSize <<4);
  772. _MP4SharedBuff[wPackOffset++] = (BYTE)(dwChunkSize>>4);
  773. _MP4SharedBuff[wPackOffset++] = (BYTE)(dwChunkSize>>12);
  774. }
  775. wOffset++;
  776. }
  777. wai_sem(SEM_DRAM_ID);
  778. I49_WriteDRAMData(dwDRAMAddr,(UINT16*)&_MP4SharedBuff[0], ((wPackOffset+1)/2));
  779. sig_sem(SEM_DRAM_ID);
  780. dwDRAMAddr += (wPackOffset/2); // in words
  781. }
  782. // else
  783. // {
  784. // wai_sem(SEM_DRAM_ID);
  785. // I49_WriteDRAMData(dwDRAMAddr,(UINT16*)&_MP4SharedBuff[0], (wStoreSize/2));
  786. // sig_sem(SEM_DRAM_ID);
  787. // dwDRAMAddr += (wStoreSize/2); // in words
  788. // }
  789. dwSize -= wCacheSize;
  790. dwSampleTableOffset += wCacheSize;
  791. bFirstTime = FALSE;
  792. }
  793. AuxCache_GetFileTerminate();
  794. return bError;
  795. }
  796. static void _mp4LoadSTCOTable(DWORD dwSTCODRAMAddr, DWORD* mp4ChunkOffsetBuff,DWORD* dwPreChunkOffset)
  797. {
  798. BYTE packBuff[MP4_PACK_STCO_BUFF_SIZE];
  799. WORD wOffset;
  800. WORD wPackOffset = 0; 
  801. DWORD dwChunkSize;
  802. wai_sem(SEM_DRAM_ID);
  803. I49_ReadDRAMData(dwSTCODRAMAddr,(UINT16*)&packBuff, MP4_PACK_STCO_BUFF_SIZE_IN_WORD);
  804. sig_sem(SEM_DRAM_ID);
  805. for (wOffset=0;wOffset<MP4_CHUNK_OFFSET_BUFF_SIZE;wOffset++)
  806. {
  807. if (wOffset%2 == 0)
  808. {
  809. dwChunkSize = packBuff[wPackOffset++];
  810. dwChunkSize += (((DWORD)(packBuff[wPackOffset++])) << 8);
  811. dwChunkSize += (((DWORD)(packBuff[wPackOffset] & 0xF)) << 16);
  812. }
  813. else
  814. {
  815. dwChunkSize = packBuff[wPackOffset++] >> 4;
  816. dwChunkSize += (((DWORD)(packBuff[wPackOffset++])) << 4);
  817. dwChunkSize += (((DWORD)(packBuff[wPackOffset++])) << 12);
  818. }
  819. *dwPreChunkOffset += dwChunkSize;
  820. mp4ChunkOffsetBuff[wOffset] = *dwPreChunkOffset;
  821. }
  822. }
  823. static BOOL _mp4CheckSampleTable(BOOL* bPackTansferSize, BOOL* bPackSTCO )
  824. {
  825. DWORD dwTansferChunkTableSize;
  826. DWORD dwVideoSyncTableSize;
  827. DWORD dwAudioSyncTableSize;
  828. DWORD dwSTCOSize;
  829. DWORD dwVideoSTSSSize;
  830. DWORD dwSizeFromACBtoAPP;
  831. DWORD dwSize;
  832. dwSizeFromACBtoAPP = 2*(COLOCATED_INFO_AVI - SAMPLE_TABLE_START_ADDR) - 0x20000; // -128KB
  833. dwSTCOSize = _dwMP4ChunkSizeEntryTotal * 4UL;
  834. dwVideoSTSSSize = _uiMPEG4NextIndexEntry * 4UL;
  835. dwTansferChunkTableSize = _dwMP4ChunkSizeEntryTotal * 4UL; // 20bit every chunk
  836. dwVideoSyncTableSize = _uiMPEG4NextIndexEntry * sizeof(MP4VideoSyncEntry);
  837. dwAudioSyncTableSize = _mpeg4AudioAvailableNum * _uiMPEG4NextIndexEntry * sizeof(MP4VideoSyncEntry);
  838. dwSize = dwSTCOSize + dwVideoSTSSSize + dwTansferChunkTableSize + dwVideoSyncTableSize + dwAudioSyncTableSize;
  839. *bPackTansferSize = FALSE;
  840. *bPackSTCO = FALSE;
  841. if (dwSize > dwSizeFromACBtoAPP) 
  842. {
  843. *bPackTansferSize = TRUE;
  844. dwTansferChunkTableSize = (_dwMP4ChunkSizeEntryTotal * 20UL) / 8UL;
  845. dwSize = dwSTCOSize + dwVideoSTSSSize + dwTansferChunkTableSize + dwVideoSyncTableSize + dwAudioSyncTableSize;
  846. if (dwSize > dwSizeFromACBtoAPP) 
  847. {
  848. *bPackSTCO = TRUE;
  849. dwSTCOSize = (_dwMP4ChunkSizeEntryTotal * 20UL) / 8UL;
  850. dwSize = dwSTCOSize + dwVideoSTSSSize + dwTansferChunkTableSize + dwVideoSyncTableSize + dwAudioSyncTableSize;
  851. if (dwSize > dwSizeFromACBtoAPP) 
  852. {
  853. tr_printf(("nnNo enough SDRAM to Process MP4 !nn")); // RB_TBD
  854. tr_printf(("The total chunk number is %ldn", _dwMP4ChunkSizeEntryTotal));
  855. return FALSE;
  856. }
  857. }
  858. }
  859. return TRUE;
  860. }
  861. #endif
  862. #ifdef MP4_STORE_SAMPLETABLE_AFTER
  863. static BOOL _mp4SampleTableProcessing(DWORD dwStartAddr)
  864. {
  865. WORD wSampleTableAddrEXAddr = SC_MPEG4_VIDEO_SAMPLE_TABLE_ADDREX_BUFF_ADDR;
  866. MP4_CODEC_TYPE codecType = CODEC_TYPE_VIDEO;
  867. MP4StreamSampleTableAddrEX mp4StreamSampleTableAddrEX;
  868. DWORD dwmp4VideoSTSSStartAdd;
  869. DWORD dwSyncSampleAddr; // descend
  870. DWORD dwChunkSizeAddr;
  871. // DWORD dwPreSampleTableAddr;
  872. BYTE currAudioStreamNum;
  873. BYTE currSubStreamNum;
  874. DWORD dwEntrySize;
  875. //BOOL bPackSTSC = FALSE;
  876. BOOL bPackSTCO = FALSE;
  877. //BOOL bPackSTSZ  = FALSE;
  878. BOOL bPackTansferSize;
  879. if (_bMPEG4IsIndexProcessed == TRUE)
  880. return TRUE;
  881. #if MP4_PACK_STCO
  882. if (FALSE == _mp4CheckSampleTable(&bPackTansferSize, &bPackSTCO ))
  883. {
  884. return FALSE;
  885. }
  886. #endif
  887. _dwMP4SampleTableAddr = SAMPLE_TABLE_START_ADDR; // ACB start address
  888. _dwMPEG4ProcessingEndAddr = MPEG4_PROCESSING_BUFF_ADDR; // Colocated AVI info
  889. dwSyncSampleAddr =  _dwMPEG4ProcessingEndAddr;
  890. if (_mpeg4VideoStreamID != NO_STREAM)
  891. {
  892. // video sample table address
  893. sc_GetBytes(wSampleTableAddrEXAddr,
  894. 0,SIZE_OF_MP4StreamSampleTableAddrEX,(BYTE*)&mp4StreamSampleTableAddrEX);
  895. #if MP4_PACK_STCO
  896. mp4PackSTCO = bPackSTCO;
  897. #else
  898. mp4PackSTCO = FALSE;
  899. #endif
  900. // STCO
  901. if (FALSE == mp4PackSTCO)
  902. {
  903. dwEntrySize = mp4STCOEntryCount * sizeof(DWORD) * (mp4CO64 ? 2 : 1);
  904.  _mp4StoreSampleTable(dwStartAddr, mp4STCOOffsetInFile, dwEntrySize, _dwMP4SampleTableAddr, mp4CO64);
  905. mp4STCOStartAddr = _dwMP4SampleTableAddr;
  906. _dwMP4SampleTableAddr += ((mp4STCOEntryCount * sizeof(DWORD))>>1);
  907. _dwMP4SampleTableAddr = ((_dwMP4SampleTableAddr + 0x1FFUL)>>9)<<9; 
  908. }
  909. #ifdef MP4_PACK_STCO
  910. else
  911. {
  912. tr_printf(("Video Pack STCOn"));
  913. dwEntrySize = mp4STCOEntryCount * sizeof(DWORD) * (mp4CO64 ? 2 : 1);
  914. _mp4StoreSTCOTable(dwStartAddr, mp4STCOOffsetInFile, mp4STCOEntryCount, _dwMP4SampleTableAddr, mp4CO64);
  915. mp4STCOStartAddr = _dwMP4SampleTableAddr;
  916. _dwMP4SampleTableAddr += (((mp4STCOEntryCount+3)/4) * MP4_PACK_STCO_BUFF_SIZE_IN_WORD);
  917. _dwMP4SampleTableAddr += (16*sizeof(DWORD));
  918. _dwMP4SampleTableAddr = ((_dwMP4SampleTableAddr + 0x1FFUL)>>9)<<9;
  919. }
  920. #endif
  921. tr_printf(("Video dwSampleTableAddr - stco : %ld KB, Size: %ld KBn", mp4STCOStartAddr>>9,(_dwMP4SampleTableAddr-mp4STCOStartAddr)>>9));
  922. // STSS
  923. {
  924. dwEntrySize = mp4STSSEntryCount * sizeof(DWORD);
  925. _mp4StoreSampleTable(dwStartAddr, mp4STSSOffsetInFile, dwEntrySize, _dwMP4SampleTableAddr, FALSE);
  926. mp4STSSStartAdd = _dwMP4SampleTableAddr;
  927. _dwMP4SampleTableAddr += (dwEntrySize>>1);
  928. _dwMP4SampleTableAddr = ((_dwMP4SampleTableAddr + 0x1FFUL)>>9)<<9; 
  929. tr_printf(("Video dwSampleTableAddr - stss : %ld KB, Size: %ld KBn", mp4STSSStartAdd>>9,(_dwMP4SampleTableAddr-mp4STSSStartAdd)>>9));
  930. }
  931. // stsc, 
  932. #ifdef MP4_PACK_STSC
  933. mp4PackSTSC = _mp4CheckIfPackSTSC(mp4STSCEntryCount, dwSyncSampleAddr);
  934. #else
  935. mp4PackSTSC = FALSE;
  936. #endif
  937. // STSC
  938. if (FALSE == mp4PackSTSC)
  939. {
  940. dwEntrySize = mp4STSCEntryCount * sizeof(MP4SampleToChunkEntry);
  941. _mp4StoreSampleTable(dwStartAddr, mp4STSCOffsetInFile, dwEntrySize, _dwMP4SampleTableAddr, FALSE);
  942. mp4STSCStartAddr = _dwMP4SampleTableAddr;
  943. _dwMP4SampleTableAddr += (dwEntrySize>>1);
  944. _dwMP4SampleTableAddr = ((_dwMP4SampleTableAddr + 0x1FFUL)>>9)<<9; 
  945. }
  946. #ifdef  MP4_PACK_STSC
  947. else
  948. {
  949. dwEntrySize = mp4STSCEntryCount * sizeof(MP4SampleToChunkEntry);
  950. _mp4StorePackSTSC(dwStartAddr, mp4STSCOffsetInFile, /*mp4STSCEntryCount,*/ dwEntrySize, _dwMP4SampleTableAddr);
  951. mp4STSCStartAddr = _dwMP4SampleTableAddr;
  952. _dwMP4SampleTableAddr += ((dwEntrySize/3)>>1);
  953. _dwMP4SampleTableAddr = ((_dwMP4SampleTableAddr + 0x1FFUL)>>9)<<9; 
  954. tr_printf(("Video Pack STSCn"));
  955. }
  956. #endif
  957. tr_printf(("Video dwSampleTableAddr - stsc : %ld KB, Size: %ld KBn", mp4STSCStartAddr>>9,(_dwMP4SampleTableAddr-mp4STSCStartAddr)>>9));
  958. #if 0
  959. if (mp4STCOEntryCount > 50000)
  960. mp4PackSTSZ = TRUE; // max chunk offset delta is 0x1000000
  961. else
  962. #endif
  963. mp4PackSTSZ = FALSE;
  964. mp4ChunkSizeStartAddr = _dwMP4SampleTableAddr; // not used
  965. mp4SyncEntryStartAddr = _dwMPEG4ProcessingEndAddr;
  966. sc_SetBytes(wSampleTableAddrEXAddr,
  967. 0,SIZE_OF_MP4StreamSampleTableAddrEX,(BYTE*)&mp4StreamSampleTableAddrEX);
  968. dwSyncSampleAddr = mp4SyncEntryStartAddr; //video
  969. dwChunkSizeAddr = mp4ChunkSizeStartAddr; //video
  970. dwmp4VideoSTSSStartAdd = mp4STSSStartAdd;
  971. // video sample table processing
  972. if (FALSE == _mp4StreamSampleTableProcessing(dwStartAddr, wSampleTableAddrEXAddr, &dwChunkSizeAddr, &dwSyncSampleAddr, 
  973. codecType, dwmp4VideoSTSSStartAdd))
  974. {
  975. dbg_printf(("_mp4SampleTableProcessing(): _mp4StreamSampleTableProcessing() Fail[] n"));
  976. AuxCache_GetFileTerminate();
  977. return FALSE;
  978. }
  979. AuxCache_GetFileTerminate();
  980. tr_printf(("Video dwSyncSampleAddr: %ld KB, Size: %ld KBn",mp4SyncEntryStartAddr>>9, (mp4SyncEntryStartAddr - dwSyncSampleAddr)>>9));
  981. _dwMP4SampleTableAddr = mp4STSCStartAddr; //"stsc" is not used again
  982. }
  983. else // if no video, every audio frame is key-frame, RB_TBD 
  984. {
  985. dwChunkSizeAddr = _dwMP4SampleTableAddr;
  986. dwSyncSampleAddr = MPEG4_PROCESSING_BUFF_ADDR;
  987. }
  988. codecType = CODEC_TYPE_AUDIO;
  989. for (currAudioStreamNum = 0; currAudioStreamNum < _mpeg4AudioAvailableNum; currAudioStreamNum++)
  990. {
  991. wSampleTableAddrEXAddr = SC_MPEG4_AUDIO_SAMPLE_TABLE_ADDREX_BUFF_ADDR + (currAudioStreamNum * SIZE_OF_MP4StreamSampleTableAddrEX_IN_DWORD);
  992. sc_GetBytes(wSampleTableAddrEXAddr,0,SIZE_OF_MP4StreamSampleTableAddrEX,(BYTE*)&mp4StreamSampleTableAddrEX);
  993. #if 0
  994. if (mp4STCOEntryCount > 50000)
  995. mp4PackSTSZ = TRUE;  // max chunk offset delta is 0x1000000
  996. else
  997. #endif
  998. mp4PackSTSZ = FALSE;
  999. #if MP4_PACK_STCO
  1000. mp4PackSTCO = bPackSTCO;
  1001. #else
  1002. mp4PackSTCO = FALSE;
  1003. #endif
  1004. // STCO
  1005. if (FALSE == mp4PackSTCO)
  1006. {
  1007. dwEntrySize = mp4STCOEntryCount * sizeof(DWORD) * (mp4CO64 ? 2 : 1);
  1008.  _mp4StoreSampleTable(dwStartAddr, mp4STCOOffsetInFile, dwEntrySize, _dwMP4SampleTableAddr, mp4CO64);
  1009. mp4STCOStartAddr = _dwMP4SampleTableAddr;
  1010. _dwMP4SampleTableAddr += ((mp4STCOEntryCount * sizeof(DWORD))>>1);
  1011. _dwMP4SampleTableAddr = ((_dwMP4SampleTableAddr + 0x1FFUL)>>9)<<9; 
  1012. }
  1013. #ifdef MP4_PACK_STCO
  1014. else
  1015. {
  1016. tr_printf(("Audio Pack STCOn"));
  1017. dwEntrySize = mp4STCOEntryCount * sizeof(DWORD) * (mp4CO64 ? 2 : 1);
  1018. _mp4StoreSTCOTable(dwStartAddr, mp4STCOOffsetInFile, mp4STCOEntryCount, _dwMP4SampleTableAddr, mp4CO64);
  1019. mp4STCOStartAddr = _dwMP4SampleTableAddr;
  1020. _dwMP4SampleTableAddr += (((mp4STCOEntryCount+3)/4) * MP4_PACK_STCO_BUFF_SIZE_IN_WORD);
  1021. _dwMP4SampleTableAddr += (16*sizeof(DWORD));
  1022. _dwMP4SampleTableAddr = ((_dwMP4SampleTableAddr + 0x1FFUL)>>9)<<9;
  1023. }
  1024. #endif
  1025. tr_printf(("Audio dwSampleTableAddr - stco : %ld KB, Size: %ld KBn", mp4STCOStartAddr>>9,(_dwMP4SampleTableAddr-mp4STCOStartAddr)>>9));
  1026. // stsc, 
  1027. #ifdef MP4_PACK_STSC
  1028. mp4PackSTSC = _mp4CheckIfPackSTSC(mp4STSCEntryCount, dwSyncSampleAddr);
  1029. #else
  1030. mp4PackSTSC = FALSE;
  1031. #endif
  1032. // STSC
  1033. if (FALSE == mp4PackSTSC)
  1034. {
  1035. dwEntrySize = mp4STSCEntryCount * sizeof(MP4SampleToChunkEntry);
  1036. _mp4StoreSampleTable(dwStartAddr, mp4STSCOffsetInFile, dwEntrySize, _dwMP4SampleTableAddr, FALSE);
  1037. mp4STSCStartAddr = _dwMP4SampleTableAddr;
  1038. _dwMP4SampleTableAddr += (dwEntrySize>>1);
  1039. _dwMP4SampleTableAddr = ((_dwMP4SampleTableAddr + 0x1FFUL)>>9)<<9; 
  1040. }
  1041. #ifdef  MP4_PACK_STSC
  1042. else
  1043. {
  1044. dwEntrySize = mp4STSCEntryCount * sizeof(MP4SampleToChunkEntry);
  1045. _mp4StorePackSTSC(dwStartAddr, mp4STSCOffsetInFile, /*mp4STSCEntryCount,*/ dwEntrySize, _dwMP4SampleTableAddr);
  1046. mp4STSCStartAddr = _dwMP4SampleTableAddr;
  1047. _dwMP4SampleTableAddr += ((dwEntrySize/3)>>1);
  1048. _dwMP4SampleTableAddr = ((_dwMP4SampleTableAddr + 0x1FFUL)>>9)<<9; 
  1049. tr_printf(("Audio Pack STSCn"));
  1050. }
  1051. #endif
  1052. tr_printf(("Audio dwSampleTableAddr - stsc : %ld KB, Size: %ld KBn", mp4STSCStartAddr>>9,(_dwMP4SampleTableAddr-mp4STSCStartAddr)>>9));
  1053. mp4SyncEntryStartAddr = dwSyncSampleAddr;
  1054. mp4ChunkSizeStartAddr = dwChunkSizeAddr;
  1055. sc_SetBytes(wSampleTableAddrEXAddr,0,SIZE_OF_MP4StreamSampleTableAddrEX,(BYTE*)&mp4StreamSampleTableAddrEX);
  1056. // read aduio stream info from DRAM
  1057. sc_GetBytes(SC_MPEG4_AUDIO_STREAM_INFO_ADDR,
  1058.    (currAudioStreamNum * SIZE_OF_AUDIO_STREAM_INFO),
  1059. SIZE_OF_AUDIO_STREAM_INFO,
  1060. (BYTE*)&_mpeg4AudioStreamInfo
  1061. );
  1062. // audio sample table processing
  1063. if (FALSE == _mp4StreamSampleTableProcessing(dwStartAddr, wSampleTableAddrEXAddr, &dwChunkSizeAddr, &dwSyncSampleAddr, 
  1064. codecType, dwmp4VideoSTSSStartAdd))
  1065. {
  1066. dbg_printf(("_mp4SampleTableProcessing(): _mp4StreamSampleTableProcessing() Fail[] n"));
  1067. AuxCache_GetFileTerminate();
  1068. return FALSE;
  1069. }
  1070. AuxCache_GetFileTerminate();
  1071. tr_printf(("Audio dwSyncSampleAddr: %ld KB, Size: %ld KBn",mp4SyncEntryStartAddr>>9, (mp4SyncEntryStartAddr - dwSyncSampleAddr)>>9));
  1072. _dwMP4SampleTableAddr = mp4STSCStartAddr; //"stsc" is not used again
  1073. #ifdef D_ENABLE_AAC_SUPPORT
  1074. if (_mpeg4AudioCodec == AAC)
  1075. {
  1076. sc_SetBytes(SC_MPEG4_AUDIO_STREAM_INFO_ADDR,
  1077.    (currAudioStreamNum * SIZE_OF_AUDIO_STREAM_INFO),
  1078. SIZE_OF_AUDIO_STREAM_INFO,
  1079. (BYTE*)&_mpeg4AudioStreamInfo
  1080. );
  1081. }
  1082. #endif
  1083. }
  1084. codecType = CODEC_TYPE_SUBPICTURE;
  1085. for (currSubStreamNum = 0; currSubStreamNum < _mpeg4SubtitleAvailableNum; currSubStreamNum++)
  1086. {
  1087. wSampleTableAddrEXAddr = SC_MPEG4_SUBTITLE_SAMPLE_TABLE_ADDREX_BUFF_ADDR + (currSubStreamNum * SIZE_OF_MP4StreamSampleTableAddrEX_IN_DWORD);
  1088. sc_GetBytes(wSampleTableAddrEXAddr,0,SIZE_OF_MP4StreamSampleTableAddrEX,(BYTE*)&mp4StreamSampleTableAddrEX);
  1089. #if 0
  1090. if (mp4STCOEntryCount > 50000)
  1091. mp4PackSTSZ = TRUE; // max chunk offset delta is 0x1000000
  1092. else
  1093. #endif
  1094. mp4PackSTSZ = FALSE;
  1095. mp4PackSTCO = FALSE;
  1096. // STCO
  1097. if (FALSE == mp4PackSTCO)
  1098. {
  1099. dwEntrySize = mp4STCOEntryCount * sizeof(DWORD) * (mp4CO64 ? 2 : 1);
  1100.  _mp4StoreSampleTable(dwStartAddr, mp4STCOOffsetInFile, dwEntrySize, _dwMP4SampleTableAddr, mp4CO64);
  1101. mp4STCOStartAddr = _dwMP4SampleTableAddr;
  1102. _dwMP4SampleTableAddr += ((mp4STCOEntryCount * sizeof(DWORD))>>1);
  1103. _dwMP4SampleTableAddr = ((_dwMP4SampleTableAddr + 0x1FFUL)>>9)<<9; 
  1104. }
  1105. tr_printf(("Subtitle dwSampleTableAddr - stco : %ld KB, Size: %ld KBn", mp4STCOStartAddr>>9,(_dwMP4SampleTableAddr-mp4STCOStartAddr)>>9));
  1106. // read subtitle stream info from DRAM
  1107. sc_GetBytes(SC_MPEG4_SUBTITLE_STREAM_INFO_ADDR,
  1108.    (currSubStreamNum * SIZE_OF_SUBTITLE_STREAM_INFO),
  1109. SIZE_OF_SUBTITLE_STREAM_INFO,
  1110. (BYTE*)&_mpeg4SubtitleStreamInfo
  1111. );
  1112. if (_mpeg4SubtitleType == INTERNAL_SUBP)
  1113. codecType = CODEC_TYPE_SUBPICTURE;
  1114. else if (_mpeg4SubtitleType == INTERNAL_SUBT)
  1115. codecType = CODEC_TYPE_SUBTITLE;
  1116. // "stts"
  1117. if (CODEC_TYPE_SUBTITLE == codecType || CODEC_TYPE_SUBPICTURE == codecType)
  1118. {
  1119. dwEntrySize = mp4STTSEntryCount * sizeof(MP4TimeToSampleEntry);
  1120. _mp4StoreSampleTable(dwStartAddr, mp4STTSOffsetInFile, dwEntrySize, _dwMP4SampleTableAddr, FALSE);
  1121. tr_printf(("dwSampleTableAddr - stts : 0x%lx, Size: 0x%lxn",_dwMP4SampleTableAddr,(dwEntrySize>>1)));
  1122. mp4STTSStartAddr = _dwMP4SampleTableAddr;
  1123. _dwMP4SampleTableAddr += (dwEntrySize>>1);
  1124. _dwMP4SampleTableAddr = ((_dwMP4SampleTableAddr + 0x1FFUL)>>9)<<9; 
  1125. tr_printf(("Subtitle dwSampleTableAddr - stts : %ld KB, Size: %ld KBn", mp4STTSStartAddr>>9,(_dwMP4SampleTableAddr-mp4STTSStartAddr)>>9));
  1126. }
  1127. // stsc, 
  1128. mp4PackSTSC = FALSE;
  1129. // STSC
  1130. if (FALSE == mp4PackSTSC)
  1131. {
  1132. dwEntrySize = mp4STSCEntryCount * sizeof(MP4SampleToChunkEntry);
  1133. _mp4StoreSampleTable(dwStartAddr, mp4STSCOffsetInFile, dwEntrySize, _dwMP4SampleTableAddr, FALSE);
  1134. mp4STSCStartAddr = _dwMP4SampleTableAddr;
  1135. _dwMP4SampleTableAddr += (dwEntrySize>>1);
  1136. _dwMP4SampleTableAddr = ((_dwMP4SampleTableAddr + 0x1FFUL)>>9)<<9; 
  1137. }
  1138. #ifdef  MP4_PACK_STSC
  1139. else
  1140. {
  1141. dwEntrySize = mp4STSCEntryCount * sizeof(MP4SampleToChunkEntry);
  1142. _mp4StorePackSTSC(dwStartAddr, mp4STSCOffsetInFile, /*mp4STSCEntryCount,*/ dwEntrySize, _dwMP4SampleTableAddr);
  1143. mp4STSCStartAddr = _dwMP4SampleTableAddr;
  1144. _dwMP4SampleTableAddr += ((dwEntrySize/3)>>1);
  1145. _dwMP4SampleTableAddr = ((_dwMP4SampleTableAddr + 0x1FFUL)>>9)<<9; 
  1146. tr_printf(("Subtitle Pack STSCn"));
  1147. }
  1148. #endif
  1149. tr_printf(("Subtitle dwSampleTableAddr - stsc : %ld KB, Size: %ld KBn", mp4STSCStartAddr>>9,(_dwMP4SampleTableAddr-mp4STSCStartAddr)>>9));
  1150. mp4SyncEntryStartAddr = dwSyncSampleAddr;
  1151. mp4ChunkSizeStartAddr = dwChunkSizeAddr;
  1152. sc_SetBytes(wSampleTableAddrEXAddr,0,SIZE_OF_MP4StreamSampleTableAddrEX,(BYTE*)&mp4StreamSampleTableAddrEX);
  1153. // read subtitle stream info from DRAM
  1154. sc_GetBytes(SC_MPEG4_SUBTITLE_STREAM_INFO_ADDR,
  1155.    (currSubStreamNum * SIZE_OF_SUBTITLE_STREAM_INFO),
  1156. SIZE_OF_SUBTITLE_STREAM_INFO,
  1157. (BYTE*)&_mpeg4SubtitleStreamInfo
  1158. );
  1159. if (_mpeg4SubtitleType == INTERNAL_SUBP)
  1160. codecType = CODEC_TYPE_SUBPICTURE;
  1161. else if (_mpeg4SubtitleType == INTERNAL_SUBT)
  1162. codecType = CODEC_TYPE_SUBTITLE;
  1163. // subpicture sample table processing
  1164. if (FALSE == _mp4StreamSampleTableProcessing(dwStartAddr, wSampleTableAddrEXAddr, &dwChunkSizeAddr, &dwSyncSampleAddr, 
  1165. codecType, dwmp4VideoSTSSStartAdd))
  1166. {
  1167. dbg_printf(("_mp4SampleTableProcessing(): _mp4StreamSampleTableProcessing() Fail[] n"));
  1168. AuxCache_GetFileTerminate();
  1169. return FALSE;
  1170. }
  1171. AuxCache_GetFileTerminate();
  1172. tr_printf(("Subtitle dwSyncSampleAddr: %ld KB, Size: %ld KBn",mp4SyncEntryStartAddr>>9, (mp4SyncEntryStartAddr - dwSyncSampleAddr)>>9));
  1173. _dwMP4SampleTableAddr = mp4STSCStartAddr; //"stsc" is not used again
  1174. }
  1175. // Robin_0106_2005, some unused chunks in the media data
  1176. codecType = CODEC_TYPE_RESERVED;
  1177. for (currSubStreamNum = 0; currSubStreamNum < uiMP4ReservedNum; currSubStreamNum++)
  1178. {
  1179. wSampleTableAddrEXAddr = SC_MPEG4_RESERVED_SAMPLE_TABLE_ADDREX_BUFF_ADDR + (currSubStreamNum * SIZE_OF_MP4StreamSampleTableAddrEX_IN_DWORD);
  1180. sc_GetBytes(wSampleTableAddrEXAddr,0,SIZE_OF_MP4StreamSampleTableAddrEX,(BYTE*)&mp4StreamSampleTableAddrEX);
  1181. mp4PackSTCO = FALSE;
  1182. // STCO
  1183. if (FALSE == mp4PackSTCO)
  1184. {
  1185. dwEntrySize = mp4STCOEntryCount * sizeof(DWORD) * (mp4CO64 ? 2 : 1);
  1186.  _mp4StoreSampleTable(dwStartAddr, mp4STCOOffsetInFile, dwEntrySize, _dwMP4SampleTableAddr, mp4CO64);
  1187. mp4STCOStartAddr = _dwMP4SampleTableAddr;
  1188. _dwMP4SampleTableAddr += ((mp4STCOEntryCount * sizeof(DWORD))>>1);
  1189. _dwMP4SampleTableAddr = ((_dwMP4SampleTableAddr + 0x1FFUL)>>9)<<9; 
  1190. }
  1191. sc_SetBytes(wSampleTableAddrEXAddr,0,SIZE_OF_MP4StreamSampleTableAddrEX,(BYTE*)&mp4StreamSampleTableAddrEX);
  1192. }
  1193. _dwMP4ChunkSizeStartAddr = dwSyncSampleAddr;
  1194. return TRUE;
  1195. }
  1196. #endif
  1197. ///////////////////////////////////////////////////////////////////////////
  1198. // Function name : _mp4ReadBox_ESDS
  1199. // Purpose : store the video/audio header data to DRAM
  1200. // Input Parameters : dwClipAddr - The start address to get the Descriptor.
  1201. //   dwOffset        - The offset to read the Descriptor.
  1202. // Return type : TRUE - if succeeded, FALSE otherwise.
  1203. // Output Parameters   : len - the header data length
  1204. ///////////////////////////////////////////////////////////////////////////
  1205. static BOOL _mp4ReadBox_ESDS(DWORD dwStartAddr, DWORD dwOffset, MP4_CODEC_TYPE trackCodecType, int *len)
  1206. {
  1207. int tag,length;
  1208. DWORD dwOffset_Temp;
  1209. BYTE *pHeaderDataBuff;
  1210. dwOffset_Temp = dwOffset + 4UL;
  1211. length = _mp4ReadDescr(dwStartAddr, &dwOffset_Temp, &tag);
  1212. if(tag == MP4_ES_DESCR_Tag)
  1213. {
  1214. dwOffset_Temp += 3UL;
  1215. length = _mp4ReadDescr(dwStartAddr, &dwOffset_Temp, &tag);
  1216. if(tag == MP4_DEC_CONFIG_DESCR_Tag)
  1217. {
  1218. dwOffset_Temp += 13UL;
  1219. length = _mp4ReadDescr(dwStartAddr, &dwOffset_Temp, &tag);
  1220. if(tag == MP4_DEC_SPECIFIC_DESCR_Tag)
  1221. {
  1222. if(length > 128)
  1223. {
  1224. dbg_printf(("_mp4ReadBox_ESDS(): Too big size of the header data n"));
  1225. return FALSE;
  1226. }
  1227. pHeaderDataBuff = (BYTE*)malloc(length);
  1228. if(NULL == pHeaderDataBuff)
  1229. {
  1230. dbg_printf(("_mp4ReadBox_ESDS(): couldn't allocate memory for header data ...n"));
  1231. return FALSE;
  1232. }
  1233. if (FALSE == AuxCache_GetBytes(dwStartAddr, dwOffset_Temp, length, pHeaderDataBuff))
  1234. {
  1235. free(pHeaderDataBuff);
  1236. dbg_printf(("_mp4ReadBox_ESDS(): AuxCache_GetBytes() Fail[] n"));
  1237. return FALSE;
  1238. }
  1239. if(trackCodecType == CODEC_TYPE_VIDEO)
  1240. {
  1241. sc_SetBytes(SC_MPEG4_VIDEO_HEADER_DATA_ADDR,0,length,pHeaderDataBuff);
  1242.       
  1243. free(pHeaderDataBuff);
  1244. *len = length;
  1245. }
  1246. else if (trackCodecType == CODEC_TYPE_AUDIO)
  1247. {
  1248. #ifdef D_ENABLE_AAC_SUPPORT
  1249. if(FALSE == _mp4ReadAudioSpecificConfig(pHeaderDataBuff,length))
  1250. {
  1251. free(pHeaderDataBuff);
  1252. *len = 0;
  1253. dbg_printf(("_mp4ReadBox_ESDS(): couldn't parse AudioSpecificConfig headern"));
  1254. return FALSE;
  1255. }
  1256. else
  1257. #endif //D_ENABLE_AAC_SUPPORT
  1258. {
  1259. free(pHeaderDataBuff);
  1260. *len = length;
  1261. }
  1262. }
  1263. else if(trackCodecType == CODEC_TYPE_SUBPICTURE)
  1264. {
  1265. if(FALSE == _mp4ReadSubPictureConfig(pHeaderDataBuff,length))
  1266. {
  1267. free(pHeaderDataBuff);
  1268. *len = 0;
  1269. dbg_printf(("_mp4ReadBox_ESDS(): couldn't parse SubPictureSpecificConfig headern"));
  1270. return FALSE;
  1271. }
  1272. else
  1273. {
  1274. free(pHeaderDataBuff);
  1275. *len = length;
  1276. }
  1277. }
  1278. else
  1279. {
  1280. free(pHeaderDataBuff);
  1281. *len = 0;
  1282. }
  1283. }
  1284. }
  1285. }
  1286. return TRUE;
  1287. }
  1288. ///////////////////////////////////////////////////////////////////////////
  1289. // Function name : _mp4StreamsInfoProcessing
  1290. // Purpose : Reads the 'moov' BOX.
  1291. // Input Parameters : dwStartAddr - The start address to get the BOX.
  1292. //   dwStartOffset - The start offset to get the BOX.
  1293. //   dwSize     - The BOX' size.
  1294. // Return type : TRUE - if succeeded, FALSE otherwise.
  1295. ///////////////////////////////////////////////////////////////////////////
  1296. static BOOL _mp4StreamsInfoProcessing(DWORD dwStartAddr, DWORD dwStartOffset, DWORD dwSize)
  1297. {
  1298. // UINT8   uiAudioStreamID[MAX_AUDS_PER_CLIP];
  1299. // UINT8   uiVideoStreamID;
  1300. // UINT8   uiSubtitleStreamID[MAX_SUB_PER_CLIP];
  1301. // UINT8 uiAudioCnt = 0,uiSubtitleCnt = 0;
  1302. DWORD dwOffset = dwStartOffset, dwOffsetTemp;
  1303. // MPEG4StreamHeadInfo videoStreamHeaderInfo, firstAudioStreamHeaderInfo;
  1304. // MPEG4VideoStreamInfoTemp *pVideoStreamInfoTemp;
  1305. // MPEG4AudioStreamInfoTemp *pAudioStreamInfoTemp;
  1306. MP4Box MP4BoxBuff;
  1307. BYTE TempBuff[10]; // version+flags
  1308. WORD wVersion;
  1309. // BOOL bGetNextBoxFalse = FALSE;
  1310. // BOOL bGetBytes = FALSE;
  1311. BOOL bError = FALSE;
  1312. // DWORD dwTrackID;
  1313. DWORD dwTrackTimeScale = 1;
  1314. BOOL bVideoTrackExist = FALSE;
  1315. BOOL bAudioTrackExist = FALSE;
  1316. BOOL bTrackValid = FALSE;
  1317. MP4_CODEC_TYPE trackCodecType;
  1318. WORD wNumOfMB;
  1319. DWORD dwEntryCount;
  1320. MP4StreamSampleTableAddrEX mp4StreamSampleTableAddrEX;
  1321. BYTE mp4StreamSampleTableFlag =0;
  1322. // DWORD dwSampleTableAddr = SAMPLE_TABLE_START_ADDR;
  1323. DWORD dwEndOffset = dwStartOffset + dwSize-8UL;
  1324. CHAR languageCode[3];
  1325. _dwMP4SampleTableAddr = SAMPLE_TABLE_START_ADDR;
  1326. _mpeg4SubtitleAvailableNum =0;
  1327. _mpeg4SubtitleInternalAvailableNum = 0;
  1328. _mpeg4AudioAvailableNum =0;
  1329. _mpeg4ChapterAvailableNum =0;
  1330. _mpeg4VideoStreamID = NO_STREAM;
  1331. _mpeg4AudioStreamID = NO_STREAM;
  1332. _mpeg4SubtitleStreamID = NO_STREAM;
  1333. trackCodecType = CODEC_TYPE_UNKNOWN;
  1334. _mpeg4VideoHeaderDataLength = 0;
  1335. _mpeg4VideoScale = 1;
  1336. _mpeg4VideoRate = 30;// supposed
  1337. _mpeg4VideoCodec = MP4V;
  1338. _dwMP4ChapterOffset = 0;
  1339. _dwMP4ChunkSizeEntryTotal = 0;
  1340. uiMP4ReservedNum = 0;
  1341. while (dwOffset < dwEndOffset)
  1342. {
  1343. if (FALSE == _mp4GetNextBox(dwStartAddr, &dwOffset, &MP4BoxBuff))
  1344. {
  1345. bError = TRUE;
  1346. dbg_printf(("_mp4StreamsInfoProcessing(): AuxCache_GetBytes() Fail[1] n"));
  1347. break;
  1348. }
  1349. if ((0 == strnicmp((LPSTR)(&MP4BoxBuff.ulType), MP4_TRACK_ID, FOURCC_FIELD_LENGTH)) ||
  1350. (0 == strnicmp((LPSTR)(&MP4BoxBuff.ulType), MP4_MEDIA_ID, FOURCC_FIELD_LENGTH)) ||
  1351. (0 == strnicmp((LPSTR)(&MP4BoxBuff.ulType), MP4_MEDIA_INFOMATION_ID, FOURCC_FIELD_LENGTH)) ||
  1352. (0 == strnicmp((LPSTR)(&MP4BoxBuff.ulType), MP4_SAMPLE_TABLE_ID, FOURCC_FIELD_LENGTH)) ||
  1353. (0 == strnicmp((LPSTR)(&MP4BoxBuff.ulType), MP4_USER_DATA_ID, FOURCC_FIELD_LENGTH)))
  1354. {
  1355. // container BOX
  1356. // dwOffset += 8UL;
  1357. }
  1358. else
  1359. {
  1360. dwOffsetTemp = dwOffset;
  1361. dwOffset += MP4BoxBuff.ulSize;
  1362. }
  1363. if (0 == strnicmp((LPSTR)(&MP4BoxBuff.ulType), MP4_TRACK_HEADER_ID, FOURCC_FIELD_LENGTH))
  1364. {
  1365. if(trackCodecType == CODEC_TYPE_VIDEO)
  1366.             {
  1367. _mpeg4VideoRate = dwTrackTimeScale;
  1368. if ((mp4StreamSampleTableFlag & VIDEO_SAMPLETABLE_VALID) == VIDEO_SAMPLETABLE_VALID)
  1369. {
  1370. // mp4ChunkSizeStartAddr = dwSampleTableAddr;
  1371. // mp4SyncEntryStartAddr = MPEG4_PROCESSING_BUFF_ADDR;
  1372. sc_SetBytes(SC_MPEG4_VIDEO_SAMPLE_TABLE_ADDREX_BUFF_ADDR,0,SIZE_OF_MP4StreamSampleTableAddrEX,(BYTE*)&mp4StreamSampleTableAddrEX);
  1373. }
  1374. else
  1375. {
  1376. tr_printf(("Short of the video sample table!n"));
  1377. _mpeg4VideoStreamID = NO_STREAM;
  1378. _mpeg4VideoCodec = DIVX_UNKNOWN;
  1379. }
  1380.             }
  1381. else if (trackCodecType == CODEC_TYPE_AUDIO)
  1382. {
  1383. _mpeg4AudioRate = dwTrackTimeScale;
  1384. memcpy(_mpeg4AudioLanguageCode,languageCode,3);
  1385. // store aduio stream info to DRAM
  1386. sc_SetBytes(SC_MPEG4_AUDIO_STREAM_INFO_ADDR,
  1387.        ((_mpeg4AudioAvailableNum-1) * SIZE_OF_AUDIO_STREAM_INFO),
  1388.        SIZE_OF_AUDIO_STREAM_INFO,
  1389.        (BYTE*)&_mpeg4AudioStreamInfo
  1390.        );
  1391. if ((mp4StreamSampleTableFlag & AUDIO_SAMPLETABLE_VALID) == AUDIO_SAMPLETABLE_VALID)
  1392. {
  1393. sc_SetBytes(SC_MPEG4_AUDIO_SAMPLE_TABLE_ADDREX_BUFF_ADDR + ((_mpeg4AudioAvailableNum - 1) *SIZE_OF_MP4StreamSampleTableAddrEX_IN_DWORD),
  1394. 0,SIZE_OF_MP4StreamSampleTableAddrEX,(BYTE*)&mp4StreamSampleTableAddrEX);
  1395. }
  1396. else
  1397. {
  1398. tr_printf(("Short of the audio sample table!n"));
  1399. _mpeg4AudioStreamID = NO_STREAM;
  1400. _mpeg4AudioCodec = AUDIO_UNKNOWN;
  1401. _mpeg4AudioAvailableNum --;
  1402. }
  1403. }
  1404. else if (trackCodecType == CODEC_TYPE_SUBPICTURE || trackCodecType == CODEC_TYPE_SUBTITLE)
  1405. {
  1406. _mpeg4SubtitleTimeScale = dwTrackTimeScale;
  1407. memcpy(_mpeg4SubtitleLanguageCode,languageCode,3);
  1408. sc_SetBytes(SC_MPEG4_SUBTITLE_STREAM_INFO_ADDR,
  1409.        ((_mpeg4SubtitleAvailableNum-1) * SIZE_OF_SUBTITLE_STREAM_INFO),
  1410.        SIZE_OF_SUBTITLE_STREAM_INFO,
  1411.        (BYTE*)&_mpeg4SubtitleStreamInfo
  1412.        );
  1413. if ((mp4StreamSampleTableFlag & SUB_SAMPLETABLE_VALID) == SUB_SAMPLETABLE_VALID)
  1414. {
  1415.              sc_SetBytes(SC_MPEG4_SUBTITLE_SAMPLE_TABLE_ADDREX_BUFF_ADDR + ((_mpeg4SubtitleAvailableNum - 1) * SIZE_OF_MP4StreamSampleTableAddrEX_IN_DWORD),
  1416.              0,SIZE_OF_MP4StreamSampleTableAddrEX,(BYTE*)&mp4StreamSampleTableAddrEX);
  1417. }
  1418. else
  1419. {
  1420. tr_printf(("Short of the subtitle sample table!n"));
  1421. _mpeg4SubtitleStreamID = NO_STREAM;
  1422. // _mpeg4SubtitleType = INTERNAL_SUBP;
  1423. _mpeg4SubtitleAvailableNum --;
  1424. _mpeg4SubtitleInternalAvailableNum --;
  1425. }
  1426. }
  1427. else if (trackCodecType == CODEC_TYPE_RESERVED)
  1428. {
  1429. if (mp4STCOEntryCount != 0)
  1430. {
  1431. sc_SetBytes(SC_MPEG4_RESERVED_SAMPLE_TABLE_ADDREX_BUFF_ADDR + (uiMP4ReservedNum * SIZE_OF_MP4StreamSampleTableAddrEX_IN_DWORD),
  1432.              0,SIZE_OF_MP4StreamSampleTableAddrEX,(BYTE*)&mp4StreamSampleTableAddrEX);
  1433. uiMP4ReservedNum ++;
  1434. }
  1435. }
  1436. trackCodecType = CODEC_TYPE_UNKNOWN;
  1437. // trak header, "tkhd"
  1438. if (FALSE == AuxCache_GetBytes(dwStartAddr, dwOffsetTemp, (WORD)4, &TempBuff[0]))
  1439. {
  1440. bError = TRUE;
  1441. dbg_printf(("_mp4StreamsInfoProcessing(): AuxCache_GetBytes() Fail[2] n"));
  1442. break;
  1443. }
  1444. dwOffsetTemp += 4UL;
  1445. wVersion = (WORD)TempBuff[0];
  1446. dwOffsetTemp += ((wVersion == 1) ? 16UL : 8UL);
  1447. // if (FALSE == AuxCache_GetBytes(dwStartAddr, dwOffsetTemp, (WORD)4, &TempBuff[0]))
  1448. // {
  1449. // bError = TRUE;
  1450. // dbg_printf(("_mp4StreamsInfoProcessing(): AuxCache_GetBytes() Fail[] n"));
  1451. // break;
  1452. // }
  1453. // dwTrackID = _toBe32(&TempBuff[0]);
  1454. dwOffsetTemp += ((wVersion == 1) ? 12UL : 8UL);
  1455. dwOffsetTemp += 52UL;
  1456. // if (FALSE == AuxCache_GetBytes(dwStartAddr, dwOffsetTemp, (WORD)8, &TempBuff[0]))
  1457. // {
  1458. // bError = TRUE;
  1459. // dbg_printf(("_mp4StreamsInfoProcessing(): AuxCache_GetBytes() Fail[] n"));
  1460. // break;
  1461. // }
  1462. bTrackValid = FALSE;
  1463. mp4StreamSampleTableFlag = 0;
  1464. }
  1465. else if (0 == strnicmp((LPSTR)(&MP4BoxBuff.ulType), MP4_MEDIA_HEADER_ID, FOURCC_FIELD_LENGTH))
  1466. {
  1467. // media header, overall information, "mdhd"
  1468. if (FALSE == AuxCache_GetBytes(dwStartAddr, dwOffsetTemp, (WORD)4, &TempBuff[0]))
  1469. {
  1470. bError = TRUE;
  1471. dbg_printf(("_mp4StreamsInfoProcessing(): AuxCache_GetBytes() Fail[3] n"));
  1472. break;
  1473. }
  1474. dwOffsetTemp += 4UL;
  1475. wVersion = (WORD)TempBuff[0];
  1476. dwOffsetTemp += ((wVersion == 1) ? 16UL : 8UL);
  1477. if (FALSE == AuxCache_GetBytes(dwStartAddr, dwOffsetTemp, (WORD)4, &TempBuff[0]))
  1478. {
  1479. bError = TRUE;
  1480. dbg_printf(("_mp4StreamsInfoProcessing(): AuxCache_GetBytes() Fail[4] n"));
  1481. break;
  1482. }
  1483.             dwOffsetTemp += 4UL;
  1484. dwTrackTimeScale = _toBe32(&TempBuff[0]);
  1485. dwOffsetTemp += ((wVersion == 1) ? 8UL : 4UL);
  1486. if (FALSE == AuxCache_GetBytes(dwStartAddr, dwOffsetTemp, (WORD)2, &TempBuff[0]))
  1487. {
  1488. bError = TRUE;
  1489. dbg_printf(("_mp4StreamsInfoProcessing(): AuxCache_GetBytes() Fail[4] n"));
  1490. break;
  1491. }
  1492. languageCode[0] = (TempBuff[0] >> 2) + 0x40; // Upper case
  1493. languageCode[1] = (((TempBuff[0] & 0x3)<<3) + (TempBuff[1] >> 5)) + 0x60;
  1494. languageCode[2] = (TempBuff[1] & 0x1F) + 0x60;
  1495. if (!((languageCode[0] >= 0x41) && (languageCode[0] <= 0x5A) &&
  1496. (languageCode[1] >= 0x61) && (languageCode[1] <= 0x7A) &&
  1497. (languageCode[2] >= 0x61) && (languageCode[2] <= 0x7A))) // invalid
  1498. {
  1499. languageCode[0] = 0;
  1500. languageCode[1] = 0;
  1501. languageCode[2] = 0;
  1502. }
  1503. }
  1504. else if (0 == strnicmp((LPSTR)(&MP4BoxBuff.ulType), MP4_HANDLER_REFERENCE_ID, FOURCC_FIELD_LENGTH))
  1505. {
  1506. // handler reference, "hdlr"
  1507. dwOffsetTemp += 8UL;
  1508. if (FALSE == AuxCache_GetBytes(dwStartAddr, dwOffsetTemp, (WORD)4, &TempBuff[0]))
  1509. {
  1510. bError = TRUE;
  1511. dbg_printf(("_mp4StreamsInfoProcessing(): AuxCache_GetBytes() Fail[5] n"));
  1512. break;
  1513. }
  1514. if (0 == strnicmp((LPSTR)(&TempBuff[0]), MP4_VIDEO_TRACK_HANDLER_TYPE, FOURCC_FIELD_LENGTH))
  1515. {
  1516. // video stream
  1517. trackCodecType = CODEC_TYPE_VIDEO;
  1518. bTrackValid = TRUE;
  1519. }
  1520. else if (0 == strnicmp((LPSTR)(&TempBuff[0]), MP4_AUDIO_TRACK_HANDLER_TYPE, FOURCC_FIELD_LENGTH))
  1521. {
  1522. // audio stream
  1523. trackCodecType = CODEC_TYPE_AUDIO;
  1524. // _mpeg4AudioHeaderDataLength = 0;
  1525. bTrackValid = TRUE;
  1526. }
  1527. #if 1
  1528. else if (0 == strnicmp((LPSTR)(&TempBuff[0]), MP4_SUBPICTURE_TRACK_HANDLER_TYPE, FOURCC_FIELD_LENGTH))
  1529. {
  1530. // subpicture stream
  1531. trackCodecType = CODEC_TYPE_SUBPICTURE;
  1532. bTrackValid = TRUE;
  1533. _mpeg4SubtitleAvailableNum++;
  1534. _mpeg4SubtitleInternalAvailableNum ++;
  1535. _mpeg4SubtitleStreamID = _mpeg4AudioAvailableNum+_mpeg4SubtitleAvailableNum;
  1536. _mpeg4SubtitleType = INTERNAL_SUBP;
  1537. }
  1538. else if (0 == strnicmp((LPSTR)(&TempBuff[0]), MP4_SUBTITLE_TRACK_HANDLER_TYPE, FOURCC_FIELD_LENGTH))
  1539. {
  1540. // subtitle stream
  1541. #if 1
  1542. trackCodecType = CODEC_TYPE_SUBTITLE;
  1543. bTrackValid = TRUE;
  1544. _mpeg4SubtitleAvailableNum++;
  1545. _mpeg4SubtitleInternalAvailableNum ++;
  1546. _mpeg4SubtitleStreamID = _mpeg4AudioAvailableNum+_mpeg4SubtitleAvailableNum;
  1547. _mpeg4SubtitleType = INTERNAL_SUBT;
  1548. #endif
  1549. }
  1550. #endif
  1551. else if (0 == strnicmp((LPSTR)(&TempBuff[0]), MP4_ODSM_TRACK_HANDLE_TYPE, FOURCC_FIELD_LENGTH))
  1552. {
  1553. trackCodecType = CODEC_TYPE_RESERVED;
  1554. bTrackValid = TRUE;
  1555. }
  1556. else if (0 == strnicmp((LPSTR)(&TempBuff[0]), MP4_BIFS_TRACK_HANDLE_TYPE, FOURCC_FIELD_LENGTH))
  1557. {
  1558. trackCodecType = CODEC_TYPE_RESERVED;
  1559. bTrackValid = TRUE;
  1560. }
  1561. }
  1562. #ifdef MP4_DRM_SUPPORT
  1563. else if (0 == strnicmp((LPSTR)(&MP4BoxBuff.ulType), MP4_NERO_DRM_ID, FOURCC_FIELD_LENGTH))
  1564. {
  1565. UINT32  uiDRMVersion;
  1566. BOOL bDRMEnable;
  1567. // BOOL bDRMPlaybackOnPc;
  1568. BOOL bDRMPlaybackOnCe;
  1569. BOOL bDRAMEnableStreaming;
  1570. BOOL bPlayback;
  1571. if (FALSE == AuxCache_GetBytes(dwStartAddr, dwOffsetTemp, (WORD)7, &TempBuff[0]))
  1572. {
  1573. bError = TRUE;
  1574. dbg_printf(("_mp4StreamsInfoProcessing(): AuxCache_GetBytes() Fail[13] n"));
  1575. break;
  1576. }
  1577. uiDRMVersion = _toBe32(&TempBuff[0]);
  1578. bDRMEnable = ((TempBuff[4] & 0x80) != 0);
  1579. // bDRMPlaybackOnPc = ((TempBuff[5] & 0x80) != 0);
  1580. bDRMPlaybackOnCe = ((TempBuff[5] & 0x40) != 0);
  1581. bDRAMEnableStreaming = ((TempBuff[6] & 0x80) != 0);
  1582. if (FALSE == bDRMEnable)
  1583. bPlayback = TRUE;
  1584. else
  1585. {
  1586. if (1 != uiDRMVersion)
  1587. bPlayback = FALSE;
  1588. else
  1589. {
  1590. if ((TRUE == bDRMPlaybackOnCe) && (TRUE == bDRAMEnableStreaming))
  1591. bPlayback = TRUE;
  1592. else
  1593. bPlayback = FALSE;
  1594. }
  1595. }
  1596. if (FALSE == bPlayback)
  1597. {
  1598. bMP4DRMDisable = TRUE;
  1599. tr_printf(("Can't Playback this file becuase DRM disable. n"));
  1600. return FALSE;
  1601. }
  1602. }
  1603. else
  1604. #endif
  1605. if (0 == strnicmp((LPSTR)(&MP4BoxBuff.ulType), MP4_CHAPTER_LIST_ID, FOURCC_FIELD_LENGTH))
  1606. {
  1607. _dwMP4ChapterOffset = dwOffsetTemp;
  1608. }
  1609. else if (0 == strnicmp((LPSTR)(&MP4BoxBuff.ulType), MP4_SAMPLE_DESCRIPTION_ID, FOURCC_FIELD_LENGTH))
  1610. {
  1611. // sample description, "stsd"
  1612. // DWORD dwEntryCount;
  1613. DWORD dwSize;
  1614. int len;
  1615. dwOffsetTemp += 8UL;
  1616. // if (FALSE == AuxCache_GetBytes(dwStartAddr, dwOffsetTemp, (WORD)4, &TempBuff[0]))
  1617. // {
  1618. // bError = TRUE;
  1619. // dbg_printf(("_mp4StreamsInfoProcessing(): AuxCache_GetBytes() Fail[] n"));
  1620. // break;
  1621. // }
  1622. // dwEntryCount = _toBe32(&TempBuff[0]);
  1623. // while(dwEntryCount--)
  1624. // {
  1625. if (FALSE == _mp4GetNextBox(dwStartAddr, &dwOffsetTemp, &MP4BoxBuff))
  1626. {
  1627. bError = TRUE;
  1628. break;
  1629. }
  1630. dwSize = MP4BoxBuff.ulSize;
  1631. if(trackCodecType == CODEC_TYPE_VIDEO)
  1632. {
  1633. dwOffsetTemp += 24UL;
  1634. dwSize -= 24UL;
  1635. // _mpeg4VideoStreamID = (BYTE)(dwTrackID & 0xff);
  1636. _mpeg4VideoCodec = determineDivXVersion(0UL,MP4BoxBuff.ulType);
  1637. if (_mpeg4VideoCodec == DIVX_UNKNOWN)
  1638. {
  1639. trackCodecType = CODEC_TYPE_UNKNOWN;
  1640. return FALSE;
  1641. // continue;
  1642. }
  1643. _mpeg4VideoStreamID = 0;
  1644. bVideoTrackExist = TRUE;
  1645. // bTrackValid = TRUE;
  1646. if (FALSE == AuxCache_GetBytes(dwStartAddr, dwOffsetTemp, (WORD)4, &TempBuff[0]))
  1647. {
  1648. bError = TRUE;
  1649. dbg_printf(("_mp4StreamsInfoProcessing(): AuxCache_GetBytes() Fail[6] n"));
  1650. break;
  1651. }
  1652. _mpeg4VideoWidth = _toBe16(&TempBuff[0]);
  1653. _mpeg4VideoHeight = _toBe16(&TempBuff[2]);
  1654. wNumOfMB = ((_mpeg4VideoWidth + 15) / 16) * ((_mpeg4VideoHeight + 15) / 16);
  1655. if(wNumOfMB > 1620) // 720x576/256
  1656. {
  1657. bError = TRUE;
  1658. dbg_printf(("Too large image size! Width: %d, Height: %dn",_mpeg4VideoWidth,_mpeg4VideoHeight));
  1659. break;
  1660. }
  1661. if(_mpeg4VideoWidth > 720)
  1662. {
  1663. dbg_printf(("Too large image width! Playback with artifacts! Width: %d, Height: %ln",_mpeg4VideoWidth,_mpeg4VideoHeight));
  1664. }
  1665. dwOffsetTemp += 54UL;
  1666. dwSize -= 54UL;
  1667. while(dwSize >= 8)
  1668. {
  1669. if (FALSE == _mp4GetNextBox(dwStartAddr, &dwOffsetTemp, &MP4BoxBuff))
  1670. {
  1671. bError = TRUE;
  1672. break;
  1673. }
  1674. if (0 == strnicmp((LPSTR)(&MP4BoxBuff.ulType), MP4_ESDS_ID, FOURCC_FIELD_LENGTH))
  1675. {
  1676. len = 0;
  1677. if (FALSE == _mp4ReadBox_ESDS(dwStartAddr, dwOffsetTemp, trackCodecType,&len))
  1678. {
  1679. bError = TRUE;
  1680. break;
  1681. }
  1682. if(len != 0)
  1683. _mpeg4VideoHeaderDataLength = len+(len%2);
  1684. }
  1685. dwSize -= (MP4BoxBuff.ulSize + 8UL); // supposed 32-bits size and not "uuid" type
  1686. dwOffsetTemp += MP4BoxBuff.ulSize;
  1687. }
  1688. if(bError == TRUE )
  1689. break;
  1690. }
  1691. else if (trackCodecType == CODEC_TYPE_AUDIO)
  1692. {
  1693. WORD wBitsPerSample;
  1694. dwOffsetTemp += 16UL;
  1695. dwSize -= 16UL;
  1696. // _mpeg4AudioStreamID = (BYTE)(dwTrackID & 0xff);
  1697. _mpeg4AudioCodec = determineAudioCodec(MP4BoxBuff.ulType, 0 , TRUE);
  1698. if (AUDIO_UNKNOWN == _mpeg4AudioCodec)
  1699. {
  1700. trackCodecType = CODEC_TYPE_UNKNOWN;
  1701. continue;
  1702. }
  1703. // bTrackValid = TRUE;
  1704. bAudioTrackExist = TRUE;
  1705. _mpeg4AudioAvailableNum++;
  1706. _mpeg4AudioStreamID = _mpeg4AudioAvailableNum;
  1707. if (FALSE == AuxCache_GetBytes(dwStartAddr, dwOffsetTemp, (WORD)10, &TempBuff[0]))
  1708. {
  1709. bError = TRUE;
  1710. dbg_printf(("_mp4StreamsInfoProcessing(): AuxCache_GetBytes() Fail[7] n"));
  1711. break;
  1712. }
  1713. _mpeg4AudioChannels = _toBe16(&TempBuff[0]);
  1714. wBitsPerSample = _toBe16(&TempBuff[2]);
  1715. _mpeg4AudioSamplesPerSec = (DWORD)_toBe16(&TempBuff[8]); // max: 65535 ? RB_TBD
  1716. #ifdef D_ENABLE_ADPCM_SUPPORT
  1717. if(_mpeg4AudioCodec == PCM)
  1718. {
  1719. _mpeg4AudioBitsPerSample_ADPCM = (BYTE)(wBitsPerSample & 0xff);
  1720. // _mpeg4AudioChannels_ADPCM = (BYTE)(wChanels & 0xff);
  1721. }
  1722. else 
  1723. #endif
  1724. if (_mpeg4AudioCodec == AAC)
  1725. {
  1726. dwOffsetTemp += 12UL;
  1727. dwSize -= 12UL;
  1728. while(dwSize >= 8)
  1729. {
  1730. if (FALSE == _mp4GetNextBox(dwStartAddr, &dwOffsetTemp, &MP4BoxBuff))
  1731. {
  1732. bError = TRUE;
  1733. break;
  1734. }
  1735. if (0 == strnicmp((LPSTR)(&MP4BoxBuff.ulType), MP4_ESDS_ID, FOURCC_FIELD_LENGTH))
  1736. {
  1737. len = 0;
  1738. if (FALSE == _mp4ReadBox_ESDS(dwStartAddr, dwOffsetTemp, trackCodecType,&len))
  1739. {
  1740. _mpeg4AudioCodec = AUDIO_UNKNOWN;
  1741. //bError = TRUE;
  1742. break;
  1743. }
  1744. // if(len != 0)
  1745. // _mpeg4AudioHeaderDataLength = len;
  1746. }
  1747. dwSize -= (MP4BoxBuff.ulSize + 8UL); // supposed 32-bits size and not "uuid" type
  1748. dwOffsetTemp += MP4BoxBuff.ulSize;
  1749. }
  1750. if(bError == TRUE )
  1751. break;
  1752. }
  1753. }
  1754. else if (trackCodecType == CODEC_TYPE_SUBPICTURE)
  1755. {
  1756. if (MP4BoxBuff.ulType != MKTAG('m', 'p', '4', 's'))
  1757. {
  1758. trackCodecType = CODEC_TYPE_UNKNOWN;
  1759. continue;
  1760. }
  1761. dwOffsetTemp += 8UL;
  1762. dwSize -= 8UL;
  1763. while(dwSize >= 8)
  1764. {
  1765. if (FALSE == _mp4GetNextBox(dwStartAddr, &dwOffsetTemp, &MP4BoxBuff))
  1766. {
  1767. bError = TRUE;
  1768. break;
  1769. }
  1770. if (0 == strnicmp((LPSTR)(&MP4BoxBuff.ulType), MP4_ESDS_ID, FOURCC_FIELD_LENGTH))
  1771. {
  1772. len = 0;
  1773. if (FALSE == _mp4ReadBox_ESDS(dwStartAddr, dwOffsetTemp, trackCodecType,&len))
  1774. {
  1775. bError = TRUE;
  1776. break;
  1777. }
  1778. }
  1779. dwSize -= (MP4BoxBuff.ulSize + 8UL); // supposed 32-bits size and not "uuid" type
  1780. dwOffsetTemp += MP4BoxBuff.ulSize;
  1781. }
  1782. }
  1783. if(bError == TRUE)
  1784. break;
  1785. }
  1786. else if (bTrackValid == FALSE)
  1787. {
  1788. // bypass
  1789. }
  1790. else if (0 == strnicmp((LPSTR)(&MP4BoxBuff.ulType), MP4_DECODING_TIME_TO_SAMPLE_ID, FOURCC_FIELD_LENGTH))
  1791. {
  1792. // Decoding Time to Sample, "stts"
  1793. DWORD dwSampleCount;
  1794. DWORD dwSampleDelta;
  1795. mp4StreamSampleTableFlag = mp4StreamSampleTableFlag | STTS;
  1796. dwOffsetTemp += 4UL;
  1797. if (FALSE == AuxCache_GetBytes(dwStartAddr, dwOffsetTemp, (WORD)4, &TempBuff[0]))
  1798. {
  1799. bError = TRUE;
  1800. dbg_printf(("_mp4StreamsInfoProcessing(): AuxCache_GetBytes() Fail[8] n"));
  1801. break;
  1802. }
  1803. dwEntryCount = _toBe32(&TempBuff[0]);
  1804. dwOffsetTemp += 4UL;
  1805. if((trackCodecType == CODEC_TYPE_VIDEO) || (trackCodecType == CODEC_TYPE_AUDIO))
  1806. {
  1807. if(dwEntryCount > 1 ) // supposed dwEntryCount =1 for video/audio, TBD for subtitle
  1808. {
  1809. DWORD dwEntrySize;
  1810. WORD wCacheSize;
  1811. DWORD dwDRAMAddr = _dwMP4SampleTableAddr;
  1812. WORD wCurrEntryCount;
  1813. WORD wOffset;
  1814. DWORD dwSampleCountSum = 0UL;
  1815. DWORD dwSampleDeltaSum = 0UL;
  1816. dbg_printf(("_mp4StreamsInfoProcessing(): dwEntryCount is greater than 1 n"));
  1817. // get the average value
  1818. #define MP4_STTS_ENTRY_STORE_MAX 100
  1819. dwEntryCount = MIN(dwEntryCount,MP4_STTS_ENTRY_STORE_MAX);
  1820. dwEntrySize = dwEntryCount * 2 * sizeof(DWORD);
  1821. // No used again, temporary store 
  1822. if(FALSE == _mp4StoreSampleTable(dwStartAddr, dwOffsetTemp, dwEntrySize, _dwMP4SampleTableAddr, FALSE))
  1823. {
  1824. bError = TRUE;
  1825. dbg_printf(("_mp4StreamsInfoProcessing(): _mp4StoreSampleTable() Fail[11] n"));
  1826. break;
  1827. }
  1828. while(dwEntrySize > 0)
  1829. {
  1830. wCacheSize = (dwEntrySize < MAX_SAMPLE_TABLE_BUFFER_SIZE) ? (WORD)dwEntrySize : MAX_SAMPLE_TABLE_BUFFER_SIZE;
  1831. wai_sem(SEM_DRAM_ID);
  1832. I49_ReadDRAMData(dwDRAMAddr,(UINT16*)&_MP4SharedBuff[0], (wCacheSize/2));
  1833. sig_sem(SEM_DRAM_ID);
  1834. wCurrEntryCount = wCacheSize/8;
  1835. wOffset = 0;
  1836. while(wCurrEntryCount--)
  1837. {
  1838. // <<< Stivenz_0224_2005: Fix MP4 remain time error
  1839. memcpy(&dwSampleCount, &_MP4SharedBuff[8*wOffset], 4);
  1840. memcpy(&dwSampleDelta, &_MP4SharedBuff[(8*wOffset)+4], 4);
  1841. //dwSampleCount = _toBe32((DWORD*)&_MP4SharedBuff[8*wOffset]); // RB_TBD
  1842. //dwSampleDelta = _toBe32((BYTE*)&_MP4SharedBuff[(8*wOffset)+4]);
  1843. // >>> Stivenz_0224_2005: Fix MP4 remain time error
  1844. dwSampleCountSum += dwSampleCount;
  1845. dwSampleDeltaSum += (dwSampleCount*dwSampleDelta);
  1846. wOffset ++;
  1847. if (dwSampleCountSum > MP4_STTS_ENTRY_STORE_MAX)
  1848. break;
  1849. }
  1850. if (dwSampleCountSum > MP4_STTS_ENTRY_STORE_MAX)
  1851. break;
  1852. dwEntrySize -= wCacheSize;
  1853. }
  1854. dwSampleDelta = dwSampleDeltaSum/dwSampleCountSum;
  1855. }
  1856. else
  1857. {
  1858. if (FALSE == AuxCache_GetBytes(dwStartAddr, dwOffsetTemp, (WORD)8, &TempBuff[0]))
  1859. {
  1860. bError = TRUE;
  1861. dbg_printf(("_mp4StreamsInfoProcessing(): AuxCache_GetBytes() Fail[9] n"));
  1862. break;
  1863. }
  1864. dwSampleCount = _toBe32(&TempBuff[0]); // RB_TBD
  1865. dwSampleDelta = _toBe32(&TempBuff[4]);
  1866. }
  1867. }
  1868. else if (trackCodecType == CODEC_TYPE_SUBTITLE || trackCodecType == CODEC_TYPE_SUBPICTURE)
  1869. {
  1870. DWORD dwEntrySize;
  1871. mp4STTSOffsetInFile = dwOffsetTemp;
  1872. mp4STTSStartAddr = _dwMP4SampleTableAddr;
  1873. mp4STTSEntryCount = dwEntryCount;
  1874. dwEntrySize = dwEntryCount * sizeof(MP4TimeToSampleEntry);
  1875. #ifdef MP4_STORE_SAMPLETABLE_AFTER
  1876. dbg_printf((" STTS' offset: 0x%lx, Count: 0x%lx, Size: 0x%lxn", dwOffsetTemp, dwEntryCount, dwEntrySize));
  1877. #else
  1878. if(FALSE == _mp4StoreSampleTable(dwStartAddr, dwOffsetTemp, dwEntrySize, _dwMP4SampleTableAddr, FALSE))
  1879. {
  1880. bError = TRUE;
  1881. dbg_printf(("_mp4StreamsInfoProcessing(): _mp4StoreSampleTable() Fail[11] n"));
  1882. break;
  1883. }
  1884. dbg_printf(("=========================================================n"));
  1885. dbg_printf(("dwSampleTableAddr - stts : 0x%lx, Size: 0x%lxn",_dwMP4SampleTableAddr,(dwEntrySize>>1)));
  1886. dbg_printf(("=========================================================n"));
  1887. _dwMP4SampleTableAddr += (dwEntrySize>>1);
  1888. _dwMP4SampleTableAddr = ((_dwMP4SampleTableAddr>>9)+1)<<9; 
  1889. #endif
  1890. }
  1891. if(trackCodecType == CODEC_TYPE_VIDEO)
  1892. {
  1893. // _mpeg4VideoLength = dwSampleCount;
  1894. _mpeg4VideoScale = dwSampleDelta;
  1895. }
  1896. else if (trackCodecType == CODEC_TYPE_AUDIO)
  1897. {
  1898. // _mpeg4AudioLength = dwSampleCount;
  1899. _mpeg4AudioScale = dwSampleDelta;
  1900. }
  1901. }
  1902. else if (0 == strnicmp((LPSTR)(&MP4BoxBuff.ulType), MP4_SAMPLE_TO_CHUNK_ID, FOURCC_FIELD_LENGTH))
  1903. {
  1904. // sampe to chunk, "stsc"
  1905. DWORD dwEntrySize;
  1906. dwOffsetTemp += 4UL;
  1907. if (FALSE == AuxCache_GetBytes(dwStartAddr, dwOffsetTemp, (WORD)4, &TempBuff[0]))
  1908. {
  1909. bError = TRUE;
  1910. dbg_printf(("_mp4StreamsInfoProcessing(): AuxCache_GetBytes() Fail[10] n"));
  1911. break;
  1912. }
  1913. dwEntryCount = _toBe32(&TempBuff[0]);
  1914. dwOffsetTemp += 4UL;
  1915. mp4StreamSampleTableFlag = mp4StreamSampleTableFlag | STSC; 
  1916. mp4STSCOffsetInFile = dwOffsetTemp;
  1917. mp4STSCStartAddr = _dwMP4SampleTableAddr;
  1918. mp4STSCEntryCount = dwEntryCount;
  1919. dwEntrySize = dwEntryCount * sizeof(MP4SampleToChunkEntry);
  1920. #ifdef MP4_STORE_SAMPLETABLE_AFTER
  1921. dbg_printf((" STSC' offset: 0x%lx, Count: 0x%lx, Size: 0x%lxn", dwOffsetTemp, dwEntryCount, dwEntrySize));
  1922. #else
  1923. if(FALSE == _mp4StoreSampleTable(dwStartAddr, dwOffsetTemp, dwEntrySize, _dwMP4SampleTableAddr, FALSE))
  1924. {
  1925. bError = TRUE;
  1926. dbg_printf(("_mp4StreamsInfoProcessing(): _mp4StoreSampleTable() Fail[11] n"));
  1927. break;
  1928. }
  1929. dbg_printf(("=========================================================n"));
  1930. dbg_printf(("dwSampleTableAddr - stsc : 0x%lx, Size: 0x%lxn",_dwMP4SampleTableAddr,(dwEntrySize>>1)));
  1931. dbg_printf(("=========================================================n"));
  1932. _dwMP4SampleTableAddr += (dwEntrySize>>1);
  1933. _dwMP4SampleTableAddr = ((_dwMP4SampleTableAddr>>9)+1)<<9; 
  1934. #endif
  1935. }
  1936. else if ((0 == strnicmp((LPSTR)(&MP4BoxBuff.ulType), MP4_SAMPLE_SIZE_ID, FOURCC_FIELD_LENGTH)) ||
  1937. (0 == strnicmp((LPSTR)(&MP4BoxBuff.ulType), MP4_COMPACT_SAMPLE_SIZE_ID, FOURCC_FIELD_LENGTH)))
  1938. {
  1939. // Sample Size "stsz" or Compact Sample Size "stz2"
  1940. mp4CompactSampeSize = FALSE;
  1941. if (0 == strnicmp((LPSTR)(&MP4BoxBuff.ulType), MP4_COMPACT_SAMPLE_SIZE_ID, FOURCC_FIELD_LENGTH))
  1942. mp4CompactSampeSize = TRUE;
  1943. dwOffsetTemp += 4UL;
  1944. if (FALSE == AuxCache_GetBytes(dwStartAddr, dwOffsetTemp, (WORD)8, &TempBuff[0]))
  1945. {
  1946. bError = TRUE;
  1947. dbg_printf(("_mp4StreamsInfoProcessing(): AuxCache_GetBytes() Fail[12 n"));
  1948. break;
  1949. }
  1950. mp4STSZSampleSize = _toBe32(&TempBuff[0]);
  1951. mp4STSZEntryCount = _toBe32(&TempBuff[4]);
  1952. if(trackCodecType == CODEC_TYPE_VIDEO)
  1953. {
  1954. _mpeg4VideoLength = mp4STSZEntryCount;
  1955. }
  1956. else if (trackCodecType == CODEC_TYPE_AUDIO)
  1957. {
  1958. _mpeg4AudioLength = mp4STSZEntryCount;
  1959. }
  1960. mp4STSZOffsetInFile = (dwOffsetTemp+8UL);
  1961. mp4StreamSampleTableFlag = mp4StreamSampleTableFlag | STSZ; 
  1962. }
  1963. else if ((0 == strnicmp((LPSTR)(&MP4BoxBuff.ulType), MP4_CHUNK_OFFSET_ID, FOURCC_FIELD_LENGTH)) ||
  1964. (0 == strnicmp((LPSTR)(&MP4BoxBuff.ulType), MP4_64BIT_CHUNK_OFFSET_ID, FOURCC_FIELD_LENGTH)))
  1965. {
  1966. // Chunk Offset "stco" or 64bits Chunk Offset "co64"
  1967. DWORD dwEntrySize;
  1968. mp4CO64 = FALSE;
  1969. if (0 == strnicmp((LPSTR)(&MP4BoxBuff.ulType), MP4_64BIT_CHUNK_OFFSET_ID, FOURCC_FIELD_LENGTH))
  1970. mp4CO64 = TRUE;
  1971. dwOffsetTemp += 4UL;
  1972. if (FALSE == AuxCache_GetBytes(dwStartAddr, dwOffsetTemp, (WORD)4, &TempBuff[0]))
  1973. {
  1974. bError = TRUE;
  1975. dbg_printf(("_mp4StreamsInfoProcessing(): AuxCache_GetBytes() Fail[13] n"));
  1976. break;
  1977. }
  1978. dwEntryCount = _toBe32(&TempBuff[0]);
  1979. dwOffsetTemp += 4UL;
  1980. mp4STCOOffsetInFile = dwOffsetTemp;
  1981. mp4STCOStartAddr = _dwMP4SampleTableAddr;
  1982. mp4STCOEntryCount = dwEntryCount;
  1983. if (dwEntryCount != 0UL) // patch from illegal stream
  1984. mp4StreamSampleTableFlag = mp4StreamSampleTableFlag | STCO; 
  1985. else
  1986. tr_printf(("This track's stco entry count is 0, invalid!n"));
  1987. _dwMP4ChunkSizeEntryTotal += dwEntryCount;
  1988. dwEntrySize = dwEntryCount * sizeof(DWORD) * (mp4CO64 ? 2 : 1);
  1989. #ifdef MP4_STORE_SAMPLETABLE_AFTER
  1990. dbg_printf((" STCO' offset: 0x%lx, Count: 0x%lx, Size: 0x%lxn", dwOffsetTemp, dwEntryCount, dwEntrySize));
  1991. #else
  1992. if(FALSE == _mp4StoreSampleTable(dwStartAddr, dwOffsetTemp, dwEntrySize, _dwMP4SampleTableAddr, mp4CO64))
  1993. {
  1994. bError = TRUE;
  1995. dbg_printf(("_mp4StreamsInfoProcessing(): _mp4StoreSampleTable() Fail[14] n"));
  1996. break;
  1997. }
  1998. dbg_printf(("=========================================================n"));
  1999. dbg_printf(("dwSampleTableAddr - stco : 0x%lx, Size: 0x%lxn",_dwMP4SampleTableAddr,((dwEntryCount * sizeof(DWORD))>>1)));
  2000. dbg_printf(("=========================================================n"));
  2001. _dwMP4SampleTableAddr += ((dwEntryCount * sizeof(DWORD))>>1);
  2002. _dwMP4SampleTableAddr = ((_dwMP4SampleTableAddr>>9)+1)<<9;
  2003. #endif
  2004. }
  2005. else if ((0 == strnicmp((LPSTR)(&MP4BoxBuff.ulType), MP4_SYNC_SAMPLE_ID, FOURCC_FIELD_LENGTH)) && 
  2006. (trackCodecType == CODEC_TYPE_VIDEO)) // only store video track "stss"
  2007. {
  2008. // Sync Sample, "stss"
  2009. DWORD dwEntrySize;
  2010. dwOffsetTemp += 4UL;
  2011. if (FALSE == AuxCache_GetBytes(dwStartAddr, dwOffsetTemp, (WORD)4, &TempBuff[0]))
  2012. {
  2013. bError = TRUE;
  2014. dbg_printf(("_mp4StreamsInfoProcessing(): AuxCache_GetBytes() Fail[15] n"));
  2015. break;
  2016. }
  2017. dwEntryCount = _toBe32(&TempBuff[0]);
  2018. dwOffsetTemp += 4UL;
  2019. mp4STSSOffsetInFile = dwOffsetTemp;
  2020. mp4STSSStartAdd = _dwMP4SampleTableAddr;
  2021. mp4STSSEntryCount = dwEntryCount;
  2022. if (mp4STSSEntryCount >= 0x10000UL) // RB_TBD
  2023. {
  2024. _uiMPEG4NextIndexEntry = 0xFFFF;
  2025. tr_printf(("WARNING: MP4 Sync Sample is more than 65535 n"));
  2026. }
  2027. else
  2028. {
  2029. _uiMPEG4NextIndexEntry = (UINT16)(mp4STSSEntryCount & 0xFFFFUL);
  2030. }
  2031. mp4StreamSampleTableFlag = mp4StreamSampleTableFlag | STSS; 
  2032. dwEntrySize = dwEntryCount * sizeof(DWORD);
  2033. #ifdef MP4_STORE_SAMPLETABLE_AFTER
  2034. dbg_printf((" STTS' offset: 0x%lx, Count: 0x%lx, Size: 0x%lxn", dwOffsetTemp, dwEntryCount, dwEntrySize));
  2035. #else
  2036. if(FALSE == _mp4StoreSampleTable(dwStartAddr, dwOffsetTemp, dwEntrySize, _dwMP4SampleTableAddr, FALSE))
  2037. {
  2038. bError = TRUE;
  2039. dbg_printf(("_mp4StreamsInfoProcessing(): _mp4StoreSampleTable() Fail[16] n"));
  2040. break;
  2041. }
  2042. dbg_printf(("=========================================================n"));
  2043. dbg_printf(("dwSampleTableAddr - stss : 0x%lx, Size: 0x%lxn",_dwMP4SampleTableAddr,(dwEntrySize>>1)));
  2044. dbg_printf(("=========================================================n"));
  2045. _dwMP4SampleTableAddr += (dwEntrySize>>1);
  2046. _dwMP4SampleTableAddr = ((_dwMP4SampleTableAddr>>9)+1)<<9;
  2047. #endif
  2048. }
  2049. if(bError == TRUE)
  2050. break;
  2051. }
  2052. if(trackCodecType == CODEC_TYPE_VIDEO)
  2053. {
  2054. _mpeg4VideoRate = dwTrackTimeScale;
  2055. if ((mp4StreamSampleTableFlag & VIDEO_SAMPLETABLE_VALID) == VIDEO_SAMPLETABLE_VALID)
  2056. {
  2057. sc_SetBytes(SC_MPEG4_VIDEO_SAMPLE_TABLE_ADDREX_BUFF_ADDR,0,SIZE_OF_MP4StreamSampleTableAddrEX,(BYTE*)&mp4StreamSampleTableAddrEX);
  2058. }
  2059. else
  2060. {
  2061. tr_printf(("Short of the video sample table!n"));
  2062. _mpeg4VideoStreamID = NO_STREAM;
  2063. _mpeg4VideoCodec = DIVX_UNKNOWN;
  2064. }
  2065. }
  2066. else if (trackCodecType == CODEC_TYPE_AUDIO)
  2067. {
  2068. _mpeg4AudioRate = dwTrackTimeScale;
  2069. memcpy(_mpeg4AudioLanguageCode,languageCode,3);
  2070. // store aduio stream info to DRAM
  2071. sc_SetBytes(SC_MPEG4_AUDIO_STREAM_INFO_ADDR,
  2072. ((_mpeg4AudioAvailableNum-1) * SIZE_OF_AUDIO_STREAM_INFO),
  2073. SIZE_OF_AUDIO_STREAM_INFO,
  2074. (BYTE*)&_mpeg4AudioStreamInfo
  2075. );
  2076. if ((mp4StreamSampleTableFlag & AUDIO_SAMPLETABLE_VALID) == AUDIO_SAMPLETABLE_VALID)
  2077. {
  2078. sc_SetBytes(SC_MPEG4_AUDIO_SAMPLE_TABLE_ADDREX_BUFF_ADDR + ((_mpeg4AudioAvailableNum - 1) *SIZE_OF_MP4StreamSampleTableAddrEX_IN_DWORD),
  2079. 0,SIZE_OF_MP4StreamSampleTableAddrEX,(BYTE*)&mp4StreamSampleTableAddrEX);
  2080. }
  2081. else
  2082. {
  2083. tr_printf(("Short of the audio sample table!n"));
  2084. _mpeg4AudioStreamID = NO_STREAM;
  2085. _mpeg4AudioCodec = AUDIO_UNKNOWN;
  2086. _mpeg4AudioAvailableNum --;
  2087. }
  2088. }
  2089. else if (trackCodecType == CODEC_TYPE_SUBPICTURE || trackCodecType == CODEC_TYPE_SUBTITLE)
  2090. {
  2091. _mpeg4SubtitleTimeScale = dwTrackTimeScale;
  2092. memcpy(_mpeg4SubtitleLanguageCode,languageCode,3);
  2093. sc_SetBytes(SC_MPEG4_SUBTITLE_STREAM_INFO_ADDR,
  2094.        ((_mpeg4SubtitleAvailableNum-1) * SIZE_OF_SUBTITLE_STREAM_INFO),
  2095.        SIZE_OF_SUBTITLE_STREAM_INFO,
  2096. (BYTE*)&_mpeg4SubtitleStreamInfo
  2097.       );
  2098. if ((mp4StreamSampleTableFlag & SUB_SAMPLETABLE_VALID) == SUB_SAMPLETABLE_VALID)
  2099. {
  2100. sc_SetBytes(SC_MPEG4_SUBTITLE_SAMPLE_TABLE_ADDREX_BUFF_ADDR + ((_mpeg4SubtitleAvailableNum - 1) * SIZE_OF_MP4StreamSampleTableAddrEX_IN_DWORD),
  2101. 0,SIZE_OF_MP4StreamSampleTableAddrEX,(BYTE*)&mp4StreamSampleTableAddrEX);
  2102. }
  2103. else
  2104. {
  2105. tr_printf(("Short of the subtitle sample table!n"));
  2106. _mpeg4SubtitleStreamID = NO_STREAM;
  2107. // _mpeg4SubtitleType = INTERNAL_SUBP;
  2108. _mpeg4SubtitleAvailableNum --;
  2109. _mpeg4SubtitleInternalAvailableNum --;
  2110. }
  2111. }
  2112. else if (trackCodecType == CODEC_TYPE_RESERVED)
  2113. {
  2114. if (mp4STCOEntryCount != 0)
  2115. {
  2116. sc_SetBytes(SC_MPEG4_RESERVED_SAMPLE_TABLE_ADDREX_BUFF_ADDR + (uiMP4ReservedNum * SIZE_OF_MP4StreamSampleTableAddrEX_IN_DWORD),
  2117.             0,SIZE_OF_MP4StreamSampleTableAddrEX,(BYTE*)&mp4StreamSampleTableAddrEX);
  2118. uiMP4ReservedNum ++;
  2119. }
  2120. }
  2121. if(TRUE == bError)
  2122. {
  2123. tr_printf(("FATAL: _mp4StreamsInfoProcessing() Failed n"));
  2124. return FALSE;
  2125. }
  2126. else
  2127. {
  2128. if (FALSE == bAudioTrackExist)
  2129. tr_printf(("No found the audio stream n"));
  2130. else if (FALSE == bVideoTrackExist)
  2131. tr_printf(("No found the video stream n"));
  2132. return TRUE;
  2133. }
  2134. }
  2135. ///////////////////////////////////////////////////////////////////////////
  2136. // Function name : _mp4InfoProcessing
  2137. // Purpose : Reads all the needed data from the MP4 file header.
  2138. // Input Parameters : dwClipStartAddr - The start address of the ASF file.
  2139. // Return type : TRUE - if succeeded, FALSE otherwise.
  2140. // Description : The function reads all the data needed for managing
  2141. //   of the playback including parameters needed by the
  2142. //   DVP.
  2143. ///////////////////////////////////////////////////////////////////////////
  2144. static BOOL _mp4InfoProcessing(DWORD dwClipStartAddr, ULONG cbFileSize)
  2145. {
  2146. DWORD dwOffset = 0UL;
  2147. BOOL bMP4File = FALSE;
  2148. MP4Box MP4BoxBuff;
  2149. BOOL bMediaFound = FALSE;
  2150. if (_bMPEG4IsIndexProcessed == TRUE)
  2151. return TRUE;
  2152. dbg_printf(("Aquiring MP4 file info...n"));
  2153. _bMP4IsNeroDigital = FALSE;
  2154. bMP4UnSupportProfile = FALSE;
  2155. bMP4DRMDisable = FALSE;
  2156. /* Verifying that the .MP4 file is an MP4 one */
  2157. while (dwOffset <= (cbFileSize-8UL))
  2158. {
  2159. if (FALSE == _mp4GetNextBox(dwClipStartAddr, &dwOffset, &MP4BoxBuff))
  2160. {
  2161. dbg_printf(("FATAL: _mp4InfoProcessing() Failed [1]n"));
  2162. return FALSE;
  2163. }
  2164. if (0 == strnicmp((LPSTR)(&MP4BoxBuff.ulType), MP4_FILE_TYPE_ID, FOURCC_FIELD_LENGTH))
  2165. {
  2166. bMP4File = TRUE;
  2167. break;
  2168. }
  2169. dwOffset += MP4BoxBuff.ulSize;
  2170. }
  2171. // found Nero Digital FourCC code
  2172. {
  2173. DWORD dwOffsetTemp = dwOffset + 8UL; // major_band and minor_version
  2174. UINT32 ulCompatibleBrandsSize;
  2175. BYTE TempBuff[4];
  2176. ulCompatibleBrandsSize = (MP4BoxBuff.ulSize - 8UL)/4;
  2177. while (ulCompatibleBrandsSize--)
  2178. {
  2179. if (FALSE == AuxCache_GetBytes(dwClipStartAddr, dwOffsetTemp, (WORD)4, &TempBuff[0]))
  2180. {
  2181. dbg_printf(("_mp4InfoProcessing(): AuxCache_GetBytes() Fail[1] n"));
  2182. break;
  2183. }
  2184. dwOffsetTemp += 4UL;
  2185. if ((0 == strnicmp((LPSTR)(&TempBuff[0]), NERO_DIGITAL_MOBIE, FOURCC_FIELD_LENGTH)) ||
  2186. (0 == strnicmp((LPSTR)(&TempBuff[0]), NERO_DIGITAL_PORTABLE, FOURCC_FIELD_LENGTH)) ||
  2187. (0 == strnicmp((LPSTR)(&TempBuff[0]), NERO_DIGITAL_STANDARD, FOURCC_FIELD_LENGTH)) ||
  2188. (0 == strnicmp((LPSTR)(&TempBuff[0]), NERO_DIGITAL_CINEMA, FOURCC_FIELD_LENGTH)) ||
  2189. (0 == strnicmp((LPSTR)(&TempBuff[0]), NERO_DIGITAL_HDTV, FOURCC_FIELD_LENGTH)))
  2190. {
  2191. _bMP4IsNeroDigital = TRUE;
  2192. break;
  2193. }
  2194. else if ((0 == strnicmp((LPSTR)(&TempBuff[0]), NERO_DIGITAL_MOBIE_AVC, FOURCC_FIELD_LENGTH)) ||
  2195. (0 == strnicmp((LPSTR)(&TempBuff[0]), NERO_DIGITAL_PORTABLE_AVC, FOURCC_FIELD_LENGTH)) ||
  2196. (0 == strnicmp((LPSTR)(&TempBuff[0]), NERO_DIGITAL_STANDARD_AVC, FOURCC_FIELD_LENGTH)) ||
  2197. (0 == strnicmp((LPSTR)(&TempBuff[0]), NERO_DIGITAL_CINEMA_AVC, FOURCC_FIELD_LENGTH)) ||
  2198. (0 == strnicmp((LPSTR)(&TempBuff[0]), NERO_DIGITAL_HDTV_AVC, FOURCC_FIELD_LENGTH)))
  2199. {
  2200. bMP4UnSupportProfile = TRUE;
  2201. return FALSE;
  2202. }
  2203. }
  2204. }
  2205. if (FALSE == bMP4File)
  2206. {
  2207. tr_printf(("FATAL: MP4 Header was not detectedn"));
  2208. return FALSE;
  2209. }
  2210. /* Reading the MP4 file header */
  2211. dwOffset = 0UL;
  2212. while (dwOffset < (cbFileSize-8UL))
  2213. {
  2214. if (FALSE == _mp4GetNextBox(dwClipStartAddr, &dwOffset, &MP4BoxBuff))
  2215. {
  2216. dbg_printf(("FATAL: _mp4InfoProcessing() Failed [2]n"));
  2217. return FALSE;
  2218. }
  2219. if (0 == strnicmp((LPSTR)(&MP4BoxBuff.ulType), MP4_MOVIE_ID, FOURCC_FIELD_LENGTH))
  2220. {
  2221. // meda-data
  2222. if(FALSE == _mp4StreamsInfoProcessing(dwClipStartAddr,dwOffset, MP4BoxBuff.ulSize))
  2223. {
  2224. dbg_printf(("FATAL: _mp4InfoProcessing() Failed [3]n"));
  2225. return FALSE;
  2226. }
  2227. bMediaFound = TRUE;
  2228. }
  2229. else if (0 == strnicmp((LPSTR)(&MP4BoxBuff.ulType), MP4_MEDIA_DATA_ID, FOURCC_FIELD_LENGTH))
  2230. {
  2231. // media data
  2232. #ifdef MP4_NO_DUMMY_CHUNK
  2233. _dwMP4LastChunkEndOffset = dwOffset + MP4BoxBuff.ulSize;
  2234. #endif
  2235. }
  2236. dwOffset += MP4BoxBuff.ulSize;
  2237. }
  2238. return bMediaFound;
  2239. }
  2240. ///////////////////////////////////////////////////////////////////////////
  2241. // Function name : _mp4VideoSampleTableProcessing
  2242. // Purpose : MP4 Video Sample Table Processing to get the Index Table and Chunk Size Table.
  2243. // Input Parameters : dwStartAddr - The start address to get the BOX.
  2244. // Return type : TRUE - if succeeded, FALSE otherwise.
  2245. ///////////////////////////////////////////////////////////////////////////
  2246. static BOOL _mp4StreamSampleTableProcessing(DWORD dwStartAddr, WORD wSampleTableAddrEXAddr, DWORD *dwChunkSizeAddr, DWORD *dwSyncSampleAddr, 
  2247. MP4_CODEC_TYPE codecType, DWORD dwMP4VideoSTSSStartAdd)
  2248. {
  2249. DWORD dwCurrentSampleSize;
  2250. DWORD dwCurrentSampleNumber;
  2251. DWORD dwCacheSampleNumberBound = 0UL, dwLastCacheSampleNumberBound = 0UL;
  2252. WORD wCacheSize;
  2253. BYTE fieldSizeInBytes;
  2254. DWORD dwSampleNumberPerChunk, dwChunkNumber = 0UL, dwChunkNumberBound = 0UL;
  2255. DWORD dwFirstSampleNumberOfChunk = 0UL;
  2256. DWORD dwChunkSize = 0UL, dwChunkOffset;
  2257. DWORD dwSyncSampleNumber = 0UL;
  2258. DWORD dwSyncNumber = 0UL;
  2259. // DWORD dwSTSCOffset, dwSTSCEntryCount;
  2260. BOOL bFirstTime = TRUE;
  2261. MP4StreamSampleTableAddrEX mp4StreamSampleTableAddrEX;
  2262. #ifdef MP4_PACK_STSC
  2263. DWORD dwPackSTSC;
  2264. #endif
  2265. MP4SampleToChunkEntry mp4SampleToChunkEntry;
  2266. DWORD mp4ChunkOffsetBuff[MP4_CHUNK_OFFSET_BUFF_SIZE];
  2267. #ifndef MP4_NO_DUMMY_CHUNK
  2268. #if 0
  2269. DWORD mp4ChunkSizeBuff[MP4_CHUNK_SIZE_BUFF_SIZE][2];
  2270. #else
  2271. DWORD mp4ChunkSizeBuff[MP4_CHUNK_SIZE_BUFF_SIZE];
  2272. #endif
  2273. #endif
  2274. DWORD mp4SyncSampleBuff[MP4_SYNC_SAMPLE_BUFF_SIZE];
  2275. MP4VideoSyncEntry mp4VideoSyncEntry[MP4_SYNC_ENTRY_BUFF_SIZE];
  2276. MP4AudioSyncEntry mp4AudioSyncEntry[MP4_SYNC_ENTRY_BUFF_SIZE];
  2277. DWORD dwAudioSkip;
  2278. DWORD dwAudioSkipRemider100;
  2279. DWORD dwAudioSkipRemider10000;
  2280. DWORD dwVideoSkip;
  2281. DWORD dwVideoSkipRemider100;
  2282. DWORD dwVideoSkipRemider10000;
  2283. DWORD dwSyncTime = 0UL;
  2284. DWORD dwAudioTime = 0UL;
  2285. WORD   wAudioOnlySyncTime = 0; // in second
  2286. DWORD dwSampleTableStartAddr;
  2287. DWORD dwSampleTableOffset;
  2288. DWORD  dwSampleTableSize;
  2289. DWORD dwVideoSTSSStartAdd = dwMP4VideoSTSSStartAdd;
  2290. MP4TimeToSampleEntry mp4TimeToSampleEntry;
  2291. MP4SubtitleSampleEntry mp4SubtitleSampleEntry[MP4_SUBTITLE_SAMPLE_ENTRY_BUFF_SIZE];
  2292. DWORD dwSampleCount = 0;
  2293. DWORD dwSampleTimeDelta;
  2294. DWORD dwCurrentSampleTime = 0;
  2295. DWORD dwCurrentSampleReminder = 0;
  2296. DWORD dwCurrentSampleTimeDelta;
  2297. DWORD dwCurrentSampleTime10, dwCurrentSampleTime1000;
  2298. DWORD dwPrevSampleTime1000 = 0;
  2299. DWORD dwSTCOAddr, dwSTSCCount, dwSTSCAddr;
  2300. #ifdef MP4_PACK_STCO
  2301. DWORD dwPreChunkOffset;
  2302. BOOL bPackSTCO;
  2303. #endif
  2304. sc_GetBytes(wSampleTableAddrEXAddr,0,SIZE_OF_MP4StreamSampleTableAddrEX,(BYTE*)&mp4StreamSampleTableAddrEX);
  2305. dwSTCOAddr = mp4STCOStartAddr;
  2306. dwSTSCCount = mp4STSCEntryCount;
  2307. dwSTSCAddr = mp4STSCStartAddr;
  2308. #ifdef MP4_PACK_STCO
  2309. bPackSTCO = mp4PackSTCO;
  2310. #endif
  2311. if(mp4CompactSampeSize)
  2312. fieldSizeInBytes = (BYTE)((mp4STSZSampleSize>>3) & 0xff);
  2313. else
  2314. fieldSizeInBytes = (BYTE)4;
  2315. if (fieldSizeInBytes == 0)
  2316. {
  2317. tr_printf(("Not support the stz2 field size is 4 n"));
  2318. return FALSE;
  2319. }
  2320. if (codecType == CODEC_TYPE_AUDIO)
  2321. {
  2322. UINT32 ulDelta;
  2323. dbg_printf(("The difference of A/V sync is %d msn", ((1000UL * _mpeg4AudioScale) / _mpeg4AudioRate)));
  2324. dwAudioSkip = (10000UL * _mpeg4AudioScale) / _mpeg4AudioRate; 
  2325. ulDelta = (10000UL * _mpeg4AudioScale) - (dwAudioSkip * _mpeg4AudioRate);
  2326. ulDelta = (10000UL *ulDelta) / _mpeg4AudioRate;
  2327. dwAudioSkipRemider100 = ulDelta / 100;
  2328. dwAudioSkipRemider10000 = ulDelta % 100;
  2329. if (_mpeg4VideoStreamID != NO_STREAM)
  2330. {
  2331. dwVideoSkip = (10000UL * _mpeg4VideoScale) / _mpeg4VideoRate; 
  2332. ulDelta = (10000UL * _mpeg4VideoScale) - (dwVideoSkip * _mpeg4VideoRate);
  2333. ulDelta = (10000UL *ulDelta) / _mpeg4VideoRate;
  2334. dwVideoSkipRemider100 = ulDelta / 100;
  2335. dwVideoSkipRemider10000 = ulDelta % 100;
  2336. }
  2337. #ifdef D_ENABLE_AAC_SUPPORT
  2338. if (_mpeg4AudioCodec == AAC)
  2339. _mpeg4AudioInfo_AAC.maxBlockSize = 0;
  2340. #endif
  2341. }
  2342. dwSampleTableStartAddr = dwStartAddr + (mp4STSZOffsetInFile/2048UL);
  2343. dwSampleTableOffset = mp4STSZOffsetInFile%2048UL;
  2344. dwSampleTableSize = mp4STSZEntryCount * fieldSizeInBytes;
  2345. dwSampleTableSize += dwSampleTableOffset;
  2346. for(dwCurrentSampleNumber=0UL; dwCurrentSampleNumber<=mp4STSZEntryCount; dwCurrentSampleNumber++)
  2347. {
  2348. // get the smple number per chunk, from "stsc"
  2349. #ifdef MP4_PACK_STSC
  2350. if (TRUE == mp4PackSTSC)
  2351. {
  2352. if (TRUE == bFirstTime)
  2353. {
  2354. wai_sem(SEM_DRAM_ID);
  2355. I49_ReadDRAMData(dwSTSCAddr,(UINT16*)&dwPackSTSC, (sizeof(DWORD)/2));
  2356. sig_sem(SEM_DRAM_ID);
  2357. dwSampleNumberPerChunk = dwPackSTSC & 0xFFFUL;
  2358. dwSTSCCount--;
  2359. if (dwSTSCCount > 0UL)
  2360. {
  2361. dwSTSCAddr += (sizeof(DWORD)/2);
  2362. wai_sem(SEM_DRAM_ID);
  2363. I49_ReadDRAMData(dwSTSCAddr,(UINT16*)&dwPackSTSC, (sizeof(DWORD)/2));
  2364. sig_sem(SEM_DRAM_ID);
  2365. dwChunkNumberBound =  (dwPackSTSC>>12)  -1;
  2366. dwSTSCCount--;
  2367. }
  2368. else
  2369. {
  2370. dwChunkNumberBound = 0xFFFFFFFFUL;
  2371. }
  2372. }
  2373. else if (dwChunkNumber >= dwChunkNumberBound)
  2374. {
  2375. dwSampleNumberPerChunk = dwPackSTSC & 0xFFFUL;
  2376. if (dwSTSCCount > 0UL)
  2377. {
  2378. dwSTSCAddr += (sizeof(DWORD)/2);
  2379. wai_sem(SEM_DRAM_ID);
  2380. I49_ReadDRAMData(dwSTSCAddr,(UINT16*)&dwPackSTSC, (sizeof(DWORD)/2));
  2381. sig_sem(SEM_DRAM_ID);
  2382. dwChunkNumberBound = (dwPackSTSC>>12)-1;
  2383. dwSTSCCount --;
  2384. }
  2385. else
  2386. {
  2387. dwChunkNumberBound = 0xFFFFFFFFUL;
  2388. }
  2389. }
  2390. }
  2391. else
  2392. #endif
  2393. {
  2394. if (TRUE == bFirstTime)
  2395. {
  2396. wai_sem(SEM_DRAM_ID);
  2397. I49_ReadDRAMData(dwSTSCAddr,(UINT16*)&mp4SampleToChunkEntry, (sizeof(MP4SampleToChunkEntry)/2));
  2398. sig_sem(SEM_DRAM_ID);
  2399. dwSampleNumberPerChunk = mp4SampleToChunkEntry.dwSamplePerChunk;//_toBe32((BYTE*)&mp4SampleToChunkEntry.dwSamplePerChunk);
  2400. dwSTSCCount--;
  2401. if (dwSTSCCount > 0UL)
  2402. {
  2403. dwSTSCAddr += (sizeof(MP4SampleToChunkEntry)/2);
  2404. wai_sem(SEM_DRAM_ID);
  2405. I49_ReadDRAMData(dwSTSCAddr,(UINT16*)&mp4SampleToChunkEntry, (sizeof(MP4SampleToChunkEntry)/2));
  2406. sig_sem(SEM_DRAM_ID);
  2407. dwChunkNumberBound = mp4SampleToChunkEntry.dwFirstChunk - 1; //_toBe32((BYTE*)&mp4SampleToChunkEntry.dwFirstChunk)-1;
  2408. dwSTSCCount--;
  2409. }
  2410. else
  2411. {
  2412. dwChunkNumberBound = 0xFFFFFFFFUL;
  2413. }
  2414. }
  2415. else if (dwChunkNumber >= dwChunkNumberBound)
  2416. {
  2417. dwSampleNumberPerChunk = mp4SampleToChunkEntry.dwSamplePerChunk; //_toBe32((BYTE*)&mp4SampleToChunkEntry.dwSamplePerChunk);
  2418. if (dwSTSCCount > 0UL)
  2419. {
  2420. dwSTSCAddr += (sizeof(MP4SampleToChunkEntry)/2);
  2421. wai_sem(SEM_DRAM_ID);
  2422. I49_ReadDRAMData(dwSTSCAddr,(UINT16*)&mp4SampleToChunkEntry, (sizeof(MP4SampleToChunkEntry)/2));
  2423. sig_sem(SEM_DRAM_ID);
  2424. dwChunkNumberBound = mp4SampleToChunkEntry.dwFirstChunk- 1;//_toBe32((BYTE*)&mp4SampleToChunkEntry.dwFirstChunk)-1;
  2425. dwSTSCCount --;
  2426. }
  2427. else
  2428. {
  2429. dwChunkNumberBound = 0xFFFFFFFFUL;
  2430. }
  2431. }
  2432. }
  2433. // get the current sample size, from "stsz"
  2434. if ((FALSE == mp4CompactSampeSize) &&(mp4STSZSampleSize != 0))
  2435. dwCurrentSampleSize = mp4STSZSampleSize;
  2436. else if (dwCurrentSampleNumber >= mp4STSZEntryCount)
  2437. dwCurrentSampleSize = 0UL;
  2438. else
  2439. {
  2440. if ((TRUE == bFirstTime) || (dwCurrentSampleNumber >= dwCacheSampleNumberBound))
  2441. {
  2442. DWORD dwLeftSampleSize = (mp4STSZEntryCount-dwCurrentSampleNumber)*fieldSizeInBytes; 
  2443. DWORD dwOffset = dwSampleTableOffset + (dwCurrentSampleNumber * fieldSizeInBytes);
  2444. wCacheSize = (WORD)min(dwLeftSampleSize, MAX_SAMPLE_TABLE_BUFFER_SIZE);
  2445. #ifdef SUPPORT_FLASH_CARD
  2446. if(IS_PLAYING_CARD)
  2447. {
  2448. if (!AuxCache_GetBytes(dwSampleTableStartAddr, dwOffset, wCacheSize, (BYTE*)&_MP4SharedBuff[0]))
  2449. {
  2450. dbg_printf(("_mp4VideoSampleTableProcessing(): AuxCache_GetBytes() Fail[] n"));
  2451. break;
  2452. }
  2453. }
  2454. else
  2455. #endif
  2456. if (!AuxCache_GetFile(dwSampleTableStartAddr, dwOffset, wCacheSize, dwSampleTableSize, bFirstTime, (BYTE*)&_MP4SharedBuff[0]))
  2457. {
  2458. dbg_printf(("_mp4VideoSampleTableProcessing(): AuxCache_GetFile() Fail[] n"));
  2459. return FALSE;
  2460. }
  2461. dwLastCacheSampleNumberBound = dwCacheSampleNumberBound;
  2462. dwCacheSampleNumberBound += (wCacheSize/fieldSizeInBytes);
  2463. }
  2464. if (fieldSizeInBytes == 4)
  2465. dwCurrentSampleSize = _toBe32((BYTE*)&_MP4SharedBuff[4*(INT16)(dwCurrentSampleNumber - dwLastCacheSampleNumberBound)]);
  2466. else if (fieldSizeInBytes == 2)
  2467. dwCurrentSampleSize = _toBe16((BYTE*)&_MP4SharedBuff[2*(INT16)(dwCurrentSampleNumber - dwLastCacheSampleNumberBound)]);
  2468. else if (fieldSizeInBytes == 1)
  2469. dwCurrentSampleSize = _MP4SharedBuff[(INT16)(dwCurrentSampleNumber - dwLastCacheSampleNumberBound)];
  2470. }
  2471. #ifdef D_ENABLE_AAC_SUPPORT
  2472. if ((codecType == CODEC_TYPE_AUDIO) && (_mpeg4AudioCodec == AAC))
  2473. if(dwCurrentSampleSize > (DWORD)(_mpeg4AudioInfo_AAC.maxBlockSize)) 
  2474. _mpeg4AudioInfo_AAC.maxBlockSize =(UINT16) (dwCurrentSampleSize & 0xFFFF);
  2475. #endif
  2476. dwChunkSize += dwCurrentSampleSize;
  2477. // get the chunk offset, from "stco"
  2478. if (TRUE == bFirstTime)
  2479. {
  2480. #ifdef MP4_PACK_STCO
  2481. if (TRUE == bPackSTCO)
  2482. {
  2483. wai_sem(SEM_DRAM_ID);
  2484. I49_ReadDRAMData(dwSTCOAddr,(UINT16*)&dwPreChunkOffset, (sizeof(DWORD)/2));
  2485. sig_sem(SEM_DRAM_ID);
  2486. dwSTCOAddr += (sizeof(DWORD)/2);
  2487. }
  2488. #endif
  2489. if ((dwChunkNumber % MP4_CHUNK_OFFSET_BUFF_SIZE) == 0)
  2490. {
  2491. #ifdef MP4_PACK_STCO
  2492. if (TRUE == bPackSTCO)
  2493. {
  2494. _mp4LoadSTCOTable(dwSTCOAddr,mp4ChunkOffsetBuff,&dwPreChunkOffset);
  2495. dwSTCOAddr += MP4_PACK_STCO_BUFF_SIZE_IN_WORD;
  2496. }
  2497. else
  2498. #endif
  2499. {
  2500. wai_sem(SEM_DRAM_ID);
  2501. I49_ReadDRAMData(dwSTCOAddr,(UINT16*)&mp4ChunkOffsetBuff, ((MP4_CHUNK_OFFSET_BUFF_SIZE*sizeof(DWORD))/2));
  2502. sig_sem(SEM_DRAM_ID);
  2503. dwSTCOAddr += ((MP4_CHUNK_OFFSET_BUFF_SIZE*sizeof(DWORD))/2);
  2504. }
  2505. }
  2506. dwChunkOffset = mp4ChunkOffsetBuff[(INT16)(dwChunkNumber % MP4_CHUNK_OFFSET_BUFF_SIZE)];
  2507. }
  2508. if (((dwCurrentSampleNumber - dwFirstSampleNumberOfChunk) == dwSampleNumberPerChunk))
  2509. {
  2510. #ifndef MP4_NO_DUMMY_CHUNK
  2511. #if 0
  2512. mp4ChunkSizeBuff[MP4_CHUNK_SIZE_BUFF_SIZE - 1 - (INT16)(dwChunkNumber % MP4_CHUNK_SIZE_BUFF_SIZE)][0] = dwChunkOffset;
  2513. mp4ChunkSizeBuff[MP4_CHUNK_SIZE_BUFF_SIZE - 1 - (INT16)(dwChunkNumber % MP4_CHUNK_SIZE_BUFF_SIZE)][1] = dwChunkSize-dwCurrentSampleSize;
  2514. #else
  2515. mp4ChunkSizeBuff[MP4_CHUNK_SIZE_BUFF_SIZE - 1 - (INT16)(dwChunkNumber % MP4_CHUNK_SIZE_BUFF_SIZE)] = dwChunkSize-dwCurrentSampleSize;
  2516. #endif
  2517. if ((dwChunkNumber % MP4_CHUNK_SIZE_BUFF_SIZE) == (MP4_CHUNK_SIZE_BUFF_SIZE-1) ||
  2518. (dwChunkNumber == (mp4STCOEntryCount -1) ))
  2519. {
  2520. #if 0
  2521. wai_sem(SEM_DRAM_ID);
  2522. I49_WriteDRAMData(*dwChunkSizeAddr,(UINT16*)&mp4ChunkSizeBuff, ((MP4_CHUNK_SIZE_BUFF_SIZE*sizeof(DWORD))));
  2523. sig_sem(SEM_DRAM_ID);
  2524. *dwChunkSizeAddr += ((MP4_CHUNK_SIZE_BUFF_SIZE*sizeof(DWORD)));
  2525. #else
  2526. wai_sem(SEM_DRAM_ID);
  2527. I49_WriteDRAMData(*dwChunkSizeAddr,(UINT16*)&mp4ChunkSizeBuff, ((MP4_CHUNK_SIZE_BUFF_SIZE*sizeof(DWORD)) /2));
  2528. sig_sem(SEM_DRAM_ID);
  2529. *dwChunkSizeAddr += ((MP4_CHUNK_SIZE_BUFF_SIZE*sizeof(DWORD))/2);
  2530. #endif
  2531. }
  2532. #endif
  2533. dwFirstSampleNumberOfChunk = dwCurrentSampleNumber;
  2534. dwChunkSize = dwCurrentSampleSize;
  2535. dwChunkNumber ++;
  2536. if (((dwChunkNumber % MP4_CHUNK_OFFSET_BUFF_SIZE) == 0))
  2537. {
  2538. #ifdef MP4_PACK_STCO
  2539. if (TRUE == bPackSTCO)
  2540. {
  2541. _mp4LoadSTCOTable(dwSTCOAddr,mp4ChunkOffsetBuff,&dwPreChunkOffset);
  2542. dwSTCOAddr += MP4_PACK_STCO_BUFF_SIZE_IN_WORD;
  2543. }
  2544. else
  2545. #endif
  2546. {
  2547. wai_sem(SEM_DRAM_ID);
  2548. I49_ReadDRAMData(dwSTCOAddr,(UINT16*)&mp4ChunkOffsetBuff, ((MP4_CHUNK_OFFSET_BUFF_SIZE*sizeof(DWORD))/2));
  2549. sig_sem(SEM_DRAM_ID);
  2550. dwSTCOAddr += ((MP4_CHUNK_OFFSET_BUFF_SIZE*sizeof(DWORD))/2);
  2551. }
  2552. }
  2553. dwChunkOffset = mp4ChunkOffsetBuff[(INT16)(dwChunkNumber % MP4_CHUNK_OFFSET_BUFF_SIZE)];
  2554. }
  2555. if ((_mpeg4VideoStreamID != NO_STREAM) && (codecType != CODEC_TYPE_SUBPICTURE) && (codecType != CODEC_TYPE_SUBTITLE))
  2556. {
  2557. // get sync sample, from "stss", TBD_Robin
  2558. if (codecType == CODEC_TYPE_VIDEO)
  2559. {
  2560. if (TRUE == bFirstTime)
  2561. {
  2562. wai_sem(SEM_DRAM_ID);
  2563. I49_ReadDRAMData(dwVideoSTSSStartAdd,(UINT16*)&mp4SyncSampleBuff, ((MP4_SYNC_SAMPLE_BUFF_SIZE*sizeof(DWORD))/2));
  2564. sig_sem(SEM_DRAM_ID);
  2565. dwVideoSTSSStartAdd += ((MP4_SYNC_SAMPLE_BUFF_SIZE*sizeof(DWORD))/2);
  2566. dwSyncSampleNumber = mp4SyncSampleBuff[(INT16)(dwSyncNumber % MP4_SYNC_SAMPLE_BUFF_SIZE)] - 1;//_toBe32((BYTE*)&mp4SyncSampleBuff[(INT16)(dwSyncNumber % MP4_SYNC_SAMPLE_BUFF_SIZE)]) -1;
  2567. }
  2568. if (dwCurrentSampleNumber == dwSyncSampleNumber)
  2569. {
  2570. mp4VideoSyncEntry[MP4_SYNC_ENTRY_BUFF_SIZE - 1 - (INT16)(dwSyncNumber%MP4_SYNC_ENTRY_BUFF_SIZE)].dwSyncSampleNumber = dwSyncSampleNumber;
  2571. mp4VideoSyncEntry[MP4_SYNC_ENTRY_BUFF_SIZE - 1 - (INT16)(dwSyncNumber%MP4_SYNC_ENTRY_BUFF_SIZE)].dwSyncChunkOffset = dwChunkOffset;
  2572. mp4VideoSyncEntry[MP4_SYNC_ENTRY_BUFF_SIZE - 1 - (INT16)(dwSyncNumber%MP4_SYNC_ENTRY_BUFF_SIZE)].dwOffsetofChunk = dwChunkSize - dwCurrentSampleSize;
  2573. mp4VideoSyncEntry[MP4_SYNC_ENTRY_BUFF_SIZE - 1 - (INT16)(dwSyncNumber%MP4_SYNC_ENTRY_BUFF_SIZE)].dwSyncSampleSize = dwCurrentSampleSize;
  2574. if (((dwSyncNumber % MP4_SYNC_ENTRY_BUFF_SIZE) == (MP4_SYNC_ENTRY_BUFF_SIZE-1)) ||
  2575. (dwSyncNumber >= (mp4STSSEntryCount-1)))
  2576. {
  2577. *dwSyncSampleAddr -= MP4_VIDEO_SYNC_ENTRY_BUFF_SIZE;
  2578. wai_sem(SEM_DRAM_ID);
  2579. I49_WriteDRAMData(*dwSyncSampleAddr,(UINT16*)&mp4VideoSyncEntry, MP4_VIDEO_SYNC_ENTRY_BUFF_SIZE);
  2580. sig_sem(SEM_DRAM_ID);
  2581. }
  2582. dwSyncNumber ++;
  2583. if ((dwSyncNumber % MP4_SYNC_SAMPLE_BUFF_SIZE) == 0)
  2584. {
  2585. wai_sem(SEM_DRAM_ID);
  2586. I49_ReadDRAMData(dwVideoSTSSStartAdd,(UINT16*)&mp4SyncSampleBuff, ((MP4_SYNC_SAMPLE_BUFF_SIZE*sizeof(DWORD))/2));
  2587. sig_sem(SEM_DRAM_ID);
  2588. dwVideoSTSSStartAdd += ((MP4_SYNC_SAMPLE_BUFF_SIZE*sizeof(DWORD))/2);
  2589. }
  2590. if (dwSyncNumber >= _uiMPEG4NextIndexEntry)
  2591. dwSyncSampleNumber = 0xFFFFFFFFUL;
  2592. else
  2593. dwSyncSampleNumber = mp4SyncSampleBuff[(INT16)(dwSyncNumber % MP4_SYNC_SAMPLE_BUFF_SIZE)] - 1;//_toBe32((BYTE*)&mp4SyncSampleBuff[(INT16)(dwSyncNumber % MP4_SYNC_SAMPLE_BUFF_SIZE)]) -1;
  2594. }
  2595. // if (dwSyncNumber > mp4STSSEntryCount)
  2596. // {
  2597. // dbg_printf(("_mp4VideoSampleTableProcessing(): Too many sync sample n"));
  2598. // return FALSE;
  2599. // }
  2600. }
  2601. else if (codecType == CODEC_TYPE_AUDIO)
  2602. {
  2603. if (TRUE == bFirstTime)
  2604. {
  2605. wai_sem(SEM_DRAM_ID);
  2606. I49_ReadDRAMData(dwVideoSTSSStartAdd,(UINT16*)&mp4SyncSampleBuff, ((MP4_SYNC_SAMPLE_BUFF_SIZE*sizeof(DWORD))/2));
  2607. sig_sem(SEM_DRAM_ID);
  2608. dwVideoSTSSStartAdd += ((MP4_SYNC_SAMPLE_BUFF_SIZE*sizeof(DWORD))/2);
  2609. dwSyncSampleNumber = mp4SyncSampleBuff[(INT16)(dwSyncNumber % MP4_SYNC_SAMPLE_BUFF_SIZE)] - 1;//_toBe32((BYTE*)&mp4SyncSampleBuff[(INT16)(dwSyncNumber % MP4_SYNC_SAMPLE_BUFF_SIZE)]) -1;
  2610. dwSyncTime = dwSyncSampleNumber * dwVideoSkip;
  2611. dwSyncTime += ((dwSyncSampleNumber * dwVideoSkipRemider100)/ 100UL);
  2612. dwSyncTime += ((dwSyncSampleNumber * dwVideoSkipRemider10000) / 10000UL);
  2613. }
  2614. dwAudioTime += dwAudioSkip;
  2615. if ((dwCurrentSampleNumber % 100UL) == 0UL)
  2616. dwAudioTime += dwAudioSkipRemider100;
  2617. if ((dwCurrentSampleNumber % 10000UL) == 0UL)
  2618. dwAudioTime += dwAudioSkipRemider10000;
  2619. if (dwAudioTime >= dwSyncTime)
  2620. {
  2621. mp4AudioSyncEntry[MP4_SYNC_ENTRY_BUFF_SIZE - 1 - (INT16)(dwSyncNumber%MP4_SYNC_ENTRY_BUFF_SIZE)].dwSyncChunkOffset = dwChunkOffset;
  2622. mp4AudioSyncEntry[MP4_SYNC_ENTRY_BUFF_SIZE - 1 - (INT16)(dwSyncNumber%MP4_SYNC_ENTRY_BUFF_SIZE)].dwOffsetofChunk = dwChunkSize - dwCurrentSampleSize;
  2623. if ((dwSyncNumber % MP4_SYNC_ENTRY_BUFF_SIZE) == (MP4_SYNC_ENTRY_BUFF_SIZE-1) ||
  2624. (dwSyncNumber >= (mp4STSSEntryCount-1)))
  2625. {
  2626. *dwSyncSampleAddr -= MP4_AUDIO_SYNC_ENTRY_BUFF_SIZE;
  2627. wai_sem(SEM_DRAM_ID);
  2628. I49_WriteDRAMData(*dwSyncSampleAddr,(UINT16*)&mp4AudioSyncEntry, MP4_AUDIO_SYNC_ENTRY_BUFF_SIZE);
  2629. sig_sem(SEM_DRAM_ID);
  2630. }
  2631. dwSyncNumber ++;
  2632. if ((dwSyncNumber % MP4_SYNC_SAMPLE_BUFF_SIZE) == 0)
  2633. {
  2634. wai_sem(SEM_DRAM_ID);
  2635. I49_ReadDRAMData(dwVideoSTSSStartAdd,(UINT16*)&mp4SyncSampleBuff, ((MP4_SYNC_SAMPLE_BUFF_SIZE*sizeof(DWORD))/2));
  2636. sig_sem(SEM_DRAM_ID);
  2637. dwVideoSTSSStartAdd += ((MP4_SYNC_SAMPLE_BUFF_SIZE*sizeof(DWORD))/2);
  2638. }
  2639. if (dwSyncNumber >= _uiMPEG4NextIndexEntry)
  2640. dwSyncTime = 0xFFFFFFFFUL;
  2641. else
  2642. {
  2643. dwSyncSampleNumber = mp4SyncSampleBuff[(INT16)(dwSyncNumber % MP4_SYNC_SAMPLE_BUFF_SIZE)] - 1;//_toBe32((BYTE*)&mp4SyncSampleBuff[(INT16)(dwSyncNumber % MP4_SYNC_SAMPLE_BUFF_SIZE)]) -1;
  2644. dwSyncTime = dwSyncSampleNumber * dwVideoSkip;
  2645. dwSyncTime += ((dwSyncSampleNumber * dwVideoSkipRemider100)/ 100UL);
  2646. dwSyncTime += ((dwSyncSampleNumber * dwVideoSkipRemider10000) / 10000UL);
  2647. }
  2648. }
  2649. }
  2650. }
  2651. else if ((_mpeg4VideoStreamID == NO_STREAM) && (codecType == CODEC_TYPE_AUDIO))
  2652. {
  2653. dwAudioTime += dwAudioSkip;
  2654. if ((dwCurrentSampleNumber % 100UL) == 0UL)
  2655. dwAudioTime += dwAudioSkipRemider100;
  2656. if ((dwCurrentSampleNumber % 10000UL) == 0UL)
  2657. dwAudioTime += dwAudioSkipRemider10000;
  2658. while ((dwAudioTime/10000UL) - wAudioOnlySyncTime >= 1)
  2659. {
  2660. wAudioOnlySyncTime ++;
  2661. mp4AudioSyncEntry[0].dwSyncChunkOffset = dwChunkOffset;
  2662. mp4AudioSyncEntry[0].dwOffsetofChunk = dwChunkSize - dwCurrentSampleSize;
  2663. *dwSyncSampleAddr -= MP4_AUDIO_SYNC_ENTRY_SIZE;
  2664. wai_sem(SEM_DRAM_ID);
  2665. I49_WriteDRAMData(*dwSyncSampleAddr,(UINT16*)&mp4AudioSyncEntry, MP4_AUDIO_SYNC_ENTRY_SIZE);
  2666. sig_sem(SEM_DRAM_ID);
  2667. dwSyncNumber ++;
  2668. }
  2669. }
  2670. else if (codecType == CODEC_TYPE_SUBTITLE || codecType == CODEC_TYPE_SUBPICTURE)
  2671. {
  2672. // get decoding time to sample box, "stts"
  2673. if ((TRUE == bFirstTime) || (dwCurrentSampleNumber == dwSampleCount))
  2674. {
  2675. wai_sem(SEM_DRAM_ID);
  2676. I49_ReadDRAMData(mp4STTSStartAddr,(UINT16*)&mp4TimeToSampleEntry, (sizeof(MP4TimeToSampleEntry)/2));
  2677. sig_sem(SEM_DRAM_ID);
  2678. mp4STTSStartAddr += (sizeof(MP4TimeToSampleEntry)/2);
  2679. dwSampleCount += mp4TimeToSampleEntry.dwSampleCount;//_toBe32((BYTE*)&mp4TimeToSampleEntry.dwSampleCount);
  2680. dwSampleTimeDelta = mp4TimeToSampleEntry.dwSampleDelta;//_toBe32((BYTE*)&mp4TimeToSampleEntry.dwSampleDelta);
  2681. }
  2682. dwCurrentSampleReminder += dwSampleTimeDelta;
  2683. dwCurrentSampleTimeDelta = dwCurrentSampleReminder / _mpeg4SubtitleTimeScale;
  2684. dwCurrentSampleTime += dwCurrentSampleTimeDelta;
  2685. dwCurrentSampleReminder -= (dwCurrentSampleTimeDelta * _mpeg4SubtitleTimeScale);
  2686. dwCurrentSampleTime10 = (10 * dwCurrentSampleReminder) / _mpeg4SubtitleTimeScale;
  2687. dwCurrentSampleTime1000 = dwCurrentSampleTime*1000 + dwCurrentSampleTime10*100;
  2688. mp4SubtitleSampleEntry[MP4_SUBTITLE_SAMPLE_ENTRY_BUFF_SIZE - 1 -(dwCurrentSampleNumber % MP4_SUBTITLE_SAMPLE_ENTRY_BUFF_SIZE)].dwChunkOffset = dwChunkOffset;
  2689. mp4SubtitleSampleEntry[MP4_SUBTITLE_SAMPLE_ENTRY_BUFF_SIZE - 1 -(dwCurrentSampleNumber % MP4_SUBTITLE_SAMPLE_ENTRY_BUFF_SIZE)].dwSampleSize = dwCurrentSampleSize;
  2690. if (codecType == CODEC_TYPE_SUBTITLE)
  2691. mp4SubtitleSampleEntry[MP4_SUBTITLE_SAMPLE_ENTRY_BUFF_SIZE - 1 - (dwCurrentSampleNumber % MP4_SUBTITLE_SAMPLE_ENTRY_BUFF_SIZE)].dwSampleEndTime = dwCurrentSampleTime1000;
  2692. else
  2693. mp4SubtitleSampleEntry[MP4_SUBTITLE_SAMPLE_ENTRY_BUFF_SIZE - 1 - (dwCurrentSampleNumber % MP4_SUBTITLE_SAMPLE_ENTRY_BUFF_SIZE)].dwSampleEndTime = dwPrevSampleTime1000;