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

DVD

开发平台:

Others

  1. dwPrevSampleTime1000 = dwCurrentSampleTime1000;
  2. if ((dwCurrentSampleNumber % MP4_SUBTITLE_SAMPLE_ENTRY_BUFF_SIZE) == (MP4_SUBTITLE_SAMPLE_ENTRY_BUFF_SIZE -1))
  3. {
  4. *dwSyncSampleAddr -= MP4_SUBTITLE_SMAPLE_ENTRY_BUFF_SIZE; 
  5. wai_sem(SEM_DRAM_ID);
  6. I49_WriteDRAMData(*dwSyncSampleAddr,(UINT16*)&mp4SubtitleSampleEntry, MP4_SUBTITLE_SMAPLE_ENTRY_BUFF_SIZE);
  7. sig_sem(SEM_DRAM_ID);
  8. }
  9. }
  10. bFirstTime = FALSE;
  11. }
  12. if (codecType == CODEC_TYPE_VIDEO)
  13. if (dwSyncNumber < _uiMPEG4NextIndexEntry)
  14. _uiMPEG4NextIndexEntry = (UINT16)(dwSyncNumber&0xFFFF);
  15. if ((_mpeg4VideoStreamID == NO_STREAM) && (codecType == CODEC_TYPE_AUDIO))
  16. {
  17. _uiMPEG4NextIndexEntry = dwSyncNumber;
  18. }
  19. #ifdef D_ENABLE_AAC_SUPPORT
  20. if ((codecType == CODEC_TYPE_AUDIO) && (_mpeg4AudioCodec == AAC))
  21. {
  22. if(_mpeg4AudioInfo_AAC.maxBlockSize > 0x1000)
  23. tr_printf(("The max AAC block size is greater than 0x1000!n"));
  24. else
  25. tr_printf(("Max AAC block size is %dn", _mpeg4AudioInfo_AAC.maxBlockSize));
  26. }
  27. #endif
  28. if (dwChunkNumber != mp4STCOEntryCount)
  29. {
  30. dbg_printf(("MP4 Chunk Number is not equal!n"));
  31. dbg_printf(("Chunk Number Save: 0x%lx, Totla: 0x%lxn", dwChunkNumber, mp4STCOEntryCount));
  32. sc_GetBytes(wSampleTableAddrEXAddr,0,SIZE_OF_MP4StreamSampleTableAddrEX,(BYTE*)&mp4StreamSampleTableAddrEX);
  33. mp4STCOEntryCount = dwChunkNumber;
  34. mp4STSCEntryCount = dwChunkNumber;
  35. sc_SetBytes(wSampleTableAddrEXAddr,0,SIZE_OF_MP4StreamSampleTableAddrEX,(BYTE*)&mp4StreamSampleTableAddrEX);
  36. }
  37. *dwChunkSizeAddr = (((*dwChunkSizeAddr) + 0x1FFUL)>>9)<<9;
  38. *dwSyncSampleAddr = (*dwSyncSampleAddr>>9)<<9; // descend
  39. return TRUE;
  40. }
  41. #ifndef MP4_STORE_SAMPLETABLE_AFTER
  42. ///////////////////////////////////////////////////////////////////////////
  43. // Function name : _mp4SampleTableProcssing
  44. // Purpose : MP4 Sample Table Processing to get the Index Table and Chunk Size Table.
  45. // Input Parameters : dwStartAddr - The start address to get the BOX.
  46. // Return type : TRUE - if succeeded, FALSE otherwise.
  47. ///////////////////////////////////////////////////////////////////////////
  48. static BOOL _mp4SampleTableProcessing(DWORD dwStartAddr)
  49. {
  50. WORD wSampleTableAddrEXAddr = SC_MPEG4_VIDEO_SAMPLE_TABLE_ADDREX_BUFF_ADDR;
  51. MP4_CODEC_TYPE codecType = CODEC_TYPE_VIDEO;
  52. // DWORD dwAudioScale = 0, dwAudioRate = 0;
  53. DWORD dwSyncSampleAddr; // descend
  54. DWORD dwChunkSizeAddr;
  55. MP4StreamSampleTableAddrEX mp4StreamSampleTableAddrEX;
  56. // DWORD dwMP4VideoSTSSEntryCount;
  57. BYTE currAudioStreamNum;
  58. DWORD dwmp4VideoSTSSStartAdd;
  59. BYTE currSubStreamNum;
  60. if (_bMPEG4IsIndexProcessed == TRUE)
  61. return TRUE;
  62. _dwMPEG4ProcessingEndAddr = MPEG4_PROCESSING_BUFF_ADDR;
  63. if (_mpeg4VideoStreamID != NO_STREAM)
  64. {
  65. // video sample table address
  66. sc_GetBytes(wSampleTableAddrEXAddr,
  67. 0,SIZE_OF_MP4StreamSampleTableAddrEX,(BYTE*)&mp4StreamSampleTableAddrEX);
  68. if (mp4STSSEntryCount >= 0x10000UL)
  69. {
  70. _uiMPEG4NextIndexEntry = 0xFFFF;
  71. dbg_printf(("WARNING: MP4 Sync Sample is more than 65535 n"));
  72. }
  73. else
  74. _uiMPEG4NextIndexEntry = (UINT16)(mp4STSSEntryCount & 0xFFFF);
  75. mp4ChunkSizeStartAddr = _dwMP4SampleTableAddr;
  76. mp4SyncEntryStartAddr = _dwMPEG4ProcessingEndAddr;
  77. sc_SetBytes(wSampleTableAddrEXAddr,
  78. 0,SIZE_OF_MP4StreamSampleTableAddrEX,(BYTE*)&mp4StreamSampleTableAddrEX);
  79. dwSyncSampleAddr = mp4SyncEntryStartAddr; //video
  80. dwChunkSizeAddr = mp4ChunkSizeStartAddr; //video
  81. dwmp4VideoSTSSStartAdd = mp4STSSStartAdd;
  82. // video sample table processing
  83. if (FALSE == _mp4StreamSampleTableProcessing(dwStartAddr, wSampleTableAddrEXAddr, &dwChunkSizeAddr, &dwSyncSampleAddr, 
  84. codecType, dwmp4VideoSTSSStartAdd))
  85. {
  86. dbg_printf(("_mp4SampleTableProcessing(): _mp4StreamSampleTableProcessing() Fail[] n"));
  87. AuxCache_GetFileTerminate();
  88. return FALSE;
  89. }
  90. AuxCache_GetFileTerminate();
  91. tr_printf(("Video dwSyncSampleAddr: %ld KB, Size: %ld KBn",mp4SyncEntryStartAddr>>9, (mp4SyncEntryStartAddr - dwSyncSampleAddr)>>9));
  92. }
  93. else
  94. {
  95. dwChunkSizeAddr = _dwMP4SampleTableAddr;
  96. dwSyncSampleAddr = MPEG4_PROCESSING_BUFF_ADDR;
  97. }
  98. codecType = CODEC_TYPE_AUDIO;
  99. for (currAudioStreamNum = 0; currAudioStreamNum < _mpeg4AudioAvailableNum; currAudioStreamNum++)
  100. {
  101. wSampleTableAddrEXAddr = SC_MPEG4_AUDIO_SAMPLE_TABLE_ADDREX_BUFF_ADDR + (currAudioStreamNum * SIZE_OF_MP4StreamSampleTableAddrEX_IN_DWORD);
  102. sc_GetBytes(wSampleTableAddrEXAddr,0,SIZE_OF_MP4StreamSampleTableAddrEX,(BYTE*)&mp4StreamSampleTableAddrEX);
  103. mp4SyncEntryStartAddr = dwSyncSampleAddr;
  104. mp4ChunkSizeStartAddr = dwChunkSizeAddr;
  105. sc_SetBytes(wSampleTableAddrEXAddr,0,SIZE_OF_MP4StreamSampleTableAddrEX,(BYTE*)&mp4StreamSampleTableAddrEX);
  106. // read aduio stream info from DRAM
  107. sc_GetBytes(SC_MPEG4_AUDIO_STREAM_INFO_ADDR,
  108.    (currAudioStreamNum * SIZE_OF_AUDIO_STREAM_INFO),
  109. SIZE_OF_AUDIO_STREAM_INFO,
  110. (BYTE*)&_mpeg4AudioStreamInfo
  111. );
  112. // audio sample table processing
  113. if (FALSE == _mp4StreamSampleTableProcessing(dwStartAddr, wSampleTableAddrEXAddr, &dwChunkSizeAddr, &dwSyncSampleAddr, 
  114. codecType, dwmp4VideoSTSSStartAdd))
  115. {
  116. dbg_printf(("_mp4SampleTableProcessing(): _mp4StreamSampleTableProcessing() Fail[] n"));
  117. AuxCache_GetFileTerminate();
  118. return FALSE;
  119. }
  120. AuxCache_GetFileTerminate();
  121. tr_printf(("Audio dwSyncSampleAddr: %ld KB, Size: %ld KBn",mp4SyncEntryStartAddr>>9, (mp4SyncEntryStartAddr - dwSyncSampleAddr)>>9));
  122. #ifdef D_ENABLE_AAC_SUPPORT
  123. if (_mpeg4AudioCodec == AAC)
  124. {
  125. sc_SetBytes(SC_MPEG4_AUDIO_STREAM_INFO_ADDR,
  126.    (currAudioStreamNum * SIZE_OF_AUDIO_STREAM_INFO),
  127. SIZE_OF_AUDIO_STREAM_INFO,
  128. (BYTE*)&_mpeg4AudioStreamInfo
  129. );
  130. }
  131. #endif
  132. }
  133. codecType = CODEC_TYPE_SUBPICTURE;
  134. for (currSubStreamNum = 0; currSubStreamNum < _mpeg4SubtitleAvailableNum; currSubStreamNum++)
  135. {
  136. wSampleTableAddrEXAddr = SC_MPEG4_SUBTITLE_SAMPLE_TABLE_ADDREX_BUFF_ADDR + (currSubStreamNum * SIZE_OF_MP4StreamSampleTableAddrEX_IN_DWORD);
  137. sc_GetBytes(wSampleTableAddrEXAddr,0,SIZE_OF_MP4StreamSampleTableAddrEX,(BYTE*)&mp4StreamSampleTableAddrEX);
  138. mp4SyncEntryStartAddr = dwSyncSampleAddr;
  139. mp4ChunkSizeStartAddr = dwChunkSizeAddr;
  140. sc_SetBytes(wSampleTableAddrEXAddr,0,SIZE_OF_MP4StreamSampleTableAddrEX,(BYTE*)&mp4StreamSampleTableAddrEX);
  141. // read subtitle stream info from DRAM
  142. sc_GetBytes(SC_MPEG4_SUBTITLE_STREAM_INFO_ADDR,
  143.    (currSubStreamNum * SIZE_OF_SUBTITLE_STREAM_INFO),
  144. SIZE_OF_SUBTITLE_STREAM_INFO,
  145. (BYTE*)&_mpeg4SubtitleStreamInfo
  146. );
  147. if (_mpeg4SubtitleType == INTERNAL_SUBP)
  148. codecType = CODEC_TYPE_SUBPICTURE;
  149. else if (_mpeg4SubtitleType == INTERNAL_SUBT)
  150. codecType = CODEC_TYPE_SUBTITLE;
  151. // subpicture sample table processing
  152. if (FALSE == _mp4StreamSampleTableProcessing(dwStartAddr, wSampleTableAddrEXAddr, &dwChunkSizeAddr, &dwSyncSampleAddr, 
  153. codecType, dwmp4VideoSTSSStartAdd))
  154. {
  155. dbg_printf(("_mp4SampleTableProcessing(): _mp4StreamSampleTableProcessing() Fail[] n"));
  156. AuxCache_GetFileTerminate();
  157. return FALSE;
  158. }
  159. AuxCache_GetFileTerminate();
  160. tr_printf(("Subtitle dwSyncSampleAddr: %ld KB, Size: %ld KBn",mp4SyncEntryStartAddr>>9, (mp4SyncEntryStartAddr - dwSyncSampleAddr)>>9));
  161. }
  162. _dwMP4ChunkSizeStartAddr = dwSyncSampleAddr;
  163. return TRUE;
  164. }
  165. #endif
  166. #ifdef MP4_PACK_TRANSFER_CHUNK_SIZE
  167. static void _mp4StorePackTransferChunkSize(DWORD dwChunkSizeAddr, DWORD* pChunkSizeBuff)
  168. {
  169. if (TRUE == bMP4NeedPack)
  170. {
  171. WORD  wCount;
  172. DWORD  dwChunkSize;
  173. DWORD  dwStreamID;
  174. DWORD pPackBuff[MP4_PACK_CHUNK_SIZE_TABLE_BUFF_SIZE];
  175. WORD  wPackBuffOffset = 0;  // in byte
  176. WORD   wPackBuffBitOffset = 0;
  177. memset((BYTE*)&pPackBuff[0],0,sizeof(pPackBuff));
  178. for(wCount=0;wCount<MP4_CHUNK_SIZE_TABLE_BUFF_SIZE;wCount++)
  179. {
  180. dwChunkSize = (*pChunkSizeBuff) >> 8;
  181. dwStreamID = (*pChunkSizeBuff) & 0xFFUL;
  182. pPackBuff[wPackBuffOffset] += (dwStreamID<<wPackBuffBitOffset);
  183. wPackBuffBitOffset += 4; // RB_TBD
  184. if (wPackBuffBitOffset>16)
  185. {
  186. pPackBuff[wPackBuffOffset] += (dwChunkSize << wPackBuffBitOffset); 
  187. wPackBuffOffset++;
  188. pPackBuff[wPackBuffOffset] += (dwChunkSize >> (32-wPackBuffBitOffset));
  189. wPackBuffBitOffset = wPackBuffBitOffset - 16;
  190. }
  191. else
  192. {
  193. pPackBuff[wPackBuffOffset] += (dwChunkSize << wPackBuffBitOffset); 
  194. if (wPackBuffBitOffset == 16)
  195. {
  196. wPackBuffBitOffset = 0;
  197. wPackBuffOffset ++;
  198. }
  199. else
  200. wPackBuffBitOffset += 16;
  201. }
  202. pChunkSizeBuff++;
  203. }
  204. wai_sem(SEM_DRAM_ID);
  205. I49_WriteDRAMData(dwChunkSizeAddr,(UINT16*)&pPackBuff, MP4_PACK_CHUNK_SIZE_ENTRY_BUFF_SIZE);
  206. sig_sem(SEM_DRAM_ID);
  207. }
  208. else
  209. {
  210. wai_sem(SEM_DRAM_ID);
  211. I49_WriteDRAMData(dwChunkSizeAddr,(UINT16*)pChunkSizeBuff, MP4_CHUNK_SIZE_ENTRY_BUFF_SIZE);
  212. sig_sem(SEM_DRAM_ID);
  213. }
  214. }
  215. static void _mp4LoadPackTransferChunkSize(DWORD dwChunkSizeAddr, DWORD* pChunkSizeBuff)
  216. {
  217. if (TRUE == bMP4NeedPack)
  218. {
  219. WORD  wCount;
  220. DWORD  dwChunkSize;
  221. DWORD  dwStreamID;
  222. DWORD pPackBuff[MP4_PACK_CHUNK_SIZE_TABLE_BUFF_SIZE];
  223. WORD  wPackBuffOffset = 0;  // in byte
  224. WORD   wPackBuffBitOffset = 0;
  225. wai_sem(SEM_DRAM_ID);
  226. I49_ReadDRAMData(dwChunkSizeAddr,(UINT16*)&pPackBuff, MP4_PACK_CHUNK_SIZE_ENTRY_BUFF_SIZE);
  227. sig_sem(SEM_DRAM_ID);
  228. for(wCount=0;wCount<MP4_CHUNK_SIZE_TABLE_BUFF_SIZE;wCount++)
  229. {
  230. dwStreamID = (pPackBuff[wPackBuffOffset] >> wPackBuffBitOffset) & 0xFUL;
  231. wPackBuffBitOffset += 4; // RB_TBD
  232. if (wPackBuffBitOffset>16)
  233. {
  234. dwChunkSize = (pPackBuff[wPackBuffOffset] >> wPackBuffBitOffset);
  235. wPackBuffOffset++;
  236. dwChunkSize += (pPackBuff[wPackBuffOffset] << (32-wPackBuffBitOffset));
  237. dwChunkSize = dwChunkSize & 0xFFFFUL;
  238. wPackBuffBitOffset = wPackBuffBitOffset - 16;
  239. }
  240. else
  241. {
  242. dwChunkSize = (pPackBuff[wPackBuffOffset] >> wPackBuffBitOffset) & 0xFFFFUL;
  243. if (wPackBuffBitOffset == 16)
  244. {
  245. wPackBuffBitOffset = 0;
  246. wPackBuffOffset ++;
  247. }
  248. else
  249. wPackBuffBitOffset += 16;
  250. }
  251. (*pChunkSizeBuff++) = (dwChunkSize << 8) + dwStreamID;
  252. }
  253. }
  254. else
  255. {
  256. wai_sem(SEM_DRAM_ID);
  257. I49_ReadDRAMData(dwChunkSizeAddr,(UINT16*)pChunkSizeBuff, MP4_CHUNK_SIZE_ENTRY_BUFF_SIZE);
  258. sig_sem(SEM_DRAM_ID);
  259. }
  260. }
  261. static DWORD _mp4CalculatePackTransferChunkSize(DWORD dwChunkSizeAddr, DWORD* pChunkSizeBuff)
  262. {
  263. DWORD dwCaculateChunkSize = 0;
  264. WORD  wCount;
  265. DWORD  dwChunkSize;
  266. WORD  wPackBuffOffset = 0;  // in byte
  267. WORD   wPackBuffBitOffset = 0;
  268. if (TRUE == bMP4NeedPack)
  269. {
  270. wai_sem(SEM_DRAM_ID);
  271. I49_ReadDRAMData(dwChunkSizeAddr,(UINT16*)pChunkSizeBuff, MP4_PACK_CHUNK_SIZE_ENTRY_BUFF_SIZE2);
  272. sig_sem(SEM_DRAM_ID);
  273. for(wCount=0;wCount<MP4_CHUNK_SIZE_TABLE_BUFF_SIZE2;wCount++)
  274. {
  275. wPackBuffBitOffset += 4; // RB_TBD
  276. if (wPackBuffBitOffset>16)
  277. {
  278. dwChunkSize = (pChunkSizeBuff[wPackBuffOffset] >> wPackBuffBitOffset);
  279. wPackBuffOffset++;
  280. dwChunkSize += (pChunkSizeBuff[wPackBuffOffset] << (32-wPackBuffBitOffset));
  281. dwChunkSize = dwChunkSize & 0xFFFFUL;
  282. wPackBuffBitOffset = wPackBuffBitOffset - 16;
  283. }
  284. else
  285. {
  286. dwChunkSize = (pChunkSizeBuff[wPackBuffOffset] >> wPackBuffBitOffset) & 0xFFFFUL;
  287. if (wPackBuffBitOffset == 16)
  288. {
  289. wPackBuffBitOffset = 0;
  290. wPackBuffOffset ++;
  291. }
  292. else
  293. wPackBuffBitOffset += 16;
  294. }
  295. dwCaculateChunkSize += dwChunkSize;
  296. }
  297. }
  298. else
  299. {
  300. wai_sem(SEM_DRAM_ID);
  301. I49_ReadDRAMData(dwChunkSizeAddr,(UINT16*)pChunkSizeBuff, MP4_CHUNK_SIZE_ENTRY_BUFF_SIZE2);
  302. sig_sem(SEM_DRAM_ID);
  303. for(wCount=0;wCount<MP4_CHUNK_SIZE_TABLE_BUFF_SIZE2;wCount++)
  304. {
  305. dwCaculateChunkSize += (pChunkSizeBuff[wCount] >> 8); 
  306. }
  307. }
  308. return dwCaculateChunkSize;
  309. }
  310. #endif
  311. ///////////////////////////////////////////////////////////////////////////
  312. // Function name : _mp4ChunkSizeProcessing
  313. // Purpose : MP4 Chunk Size Processing to Chunk Size Table.
  314. // Input Parameters : dwStartAddr - The start address to get the BOX.
  315. // Return type : TRUE - if succeeded, FALSE otherwise.
  316. ///////////////////////////////////////////////////////////////////////////
  317. static BOOL _mp4ChunkSizeProcessing(void)
  318. {
  319. MP4StreamChunkSizeBuff  *pStreamChunkSizeBuff;
  320. DWORD dwStreamChunkFlag = 0UL, dwCurrStreamChunkFlag = 0UL; // 
  321. MP4StreamSampleTableAddrEX mp4StreamSampleTableAddrEX;
  322. int iStreamNumber;
  323. WORD wSampleTableAddrEXAddr;
  324. DWORD dwChunkOffset = 0xFFFFFFFFUL;
  325. DWORD dwChunkSize;
  326. DWORD dwPreChunkOffset = 0;
  327. int iCurrStreamNumber;
  328. int iPrevStreamNumber;
  329. BOOL bFirstTime = TRUE;
  330. DWORD dwChunkCount = 0;
  331. DWORD dwChunkSizeAddr = _dwMP4ChunkSizeStartAddr;
  332. DWORD dwChunkNumber = 0;
  333. if (_bMPEG4IsIndexProcessed == TRUE)
  334. return TRUE;
  335. pStreamChunkSizeBuff = (BYTE*)malloc((1+_mpeg4AudioAvailableNum+_mpeg4SubtitleAvailableNum + uiMP4ReservedNum) * sizeof(MP4StreamChunkSizeBuff));
  336. if (NULL == pStreamChunkSizeBuff)
  337. {
  338. tr_printf(("FATAL: couldn't allocate memory for chunk size buffer ...n"));
  339. return FALSE;
  340. }
  341. for (iStreamNumber=0;iStreamNumber<=(_mpeg4AudioAvailableNum+_mpeg4SubtitleAvailableNum + uiMP4ReservedNum);iStreamNumber++)
  342. {
  343. if (iStreamNumber <= _mpeg4AudioAvailableNum)
  344. wSampleTableAddrEXAddr = SC_MPEG4_VIDEO_SAMPLE_TABLE_ADDREX_BUFF_ADDR + (iStreamNumber * SIZE_OF_MP4StreamSampleTableAddrEX_IN_DWORD);
  345. else if (iStreamNumber <= (_mpeg4AudioAvailableNum+_mpeg4SubtitleAvailableNum))
  346. wSampleTableAddrEXAddr = SC_MPEG4_VIDEO_SAMPLE_TABLE_ADDREX_BUFF_ADDR + ((iStreamNumber - _mpeg4AudioAvailableNum + MAX_AUDS_PER_CLIP)* SIZE_OF_MP4StreamSampleTableAddrEX_IN_DWORD);
  347. else
  348. wSampleTableAddrEXAddr = SC_MPEG4_VIDEO_SAMPLE_TABLE_ADDREX_BUFF_ADDR + ((iStreamNumber - _mpeg4AudioAvailableNum - _mpeg4SubtitleAvailableNum + MAX_AUDS_PER_CLIP + MAX_SUB_PER_CLIP)* SIZE_OF_MP4StreamSampleTableAddrEX_IN_DWORD);
  349. sc_GetBytes(wSampleTableAddrEXAddr,
  350. 0,SIZE_OF_MP4StreamSampleTableAddrEX,(BYTE*)&mp4StreamSampleTableAddrEX);
  351. pStreamChunkSizeBuff[iStreamNumber].dwStreamChunkOffsetAddr = mp4STCOStartAddr;
  352. #ifndef MP4_NO_DUMMY_CHUNK
  353. pStreamChunkSizeBuff[iStreamNumber].dwStreamChunkSizeAddr = mp4ChunkSizeStartAddr;
  354. #endif
  355. pStreamChunkSizeBuff[iStreamNumber].dwStreamChunkTotal = mp4STCOEntryCount;
  356. dwChunkNumber += mp4STCOEntryCount;
  357. pStreamChunkSizeBuff[iStreamNumber].dwStreamChunkNumber = 0;
  358. dwStreamChunkFlag = dwStreamChunkFlag | (1UL<<iStreamNumber);
  359. #ifdef MP4_PACK_STCO
  360. pStreamChunkSizeBuff[iStreamNumber].bPackSTCO = mp4PackSTCO;
  361. if (TRUE == pStreamChunkSizeBuff[iStreamNumber].bPackSTCO)
  362. {
  363. wai_sem(SEM_DRAM_ID);
  364. I49_ReadDRAMData(pStreamChunkSizeBuff[iStreamNumber].dwStreamChunkOffsetAddr,(UINT16*)&(pStreamChunkSizeBuff[iStreamNumber].dwPrevChunkOffset), (sizeof(DWORD)/2));
  365. sig_sem(SEM_DRAM_ID);
  366. pStreamChunkSizeBuff[iStreamNumber].dwStreamChunkOffsetAddr += (sizeof(DWORD)/2);
  367. }
  368. #endif
  369. }
  370. if(dwChunkNumber >= MP4_PACK_CHUNK_NUMBER_THRESHOLD)
  371. {
  372. bMP4NeedPack = TRUE;
  373. tr_printf(("nWARNING: Total Chunk Number is large than %ld: %ldn", MP4_PACK_CHUNK_NUMBER_THRESHOLD, dwChunkNumber));
  374. }
  375. else
  376. bMP4NeedPack = FALSE;
  377. if (TRUE == bMP4NeedPack)
  378. dwMP4MaxStoreChunkSize = 0xFFFFUL;
  379. else
  380. dwMP4MaxStoreChunkSize = 0xFFFF00UL;
  381. if (_mpeg4VideoStreamID == NO_STREAM)
  382. pStreamChunkSizeBuff[0].dwStreamChunkTotal = 0;
  383. for (iStreamNumber=0;iStreamNumber<=(_mpeg4AudioAvailableNum+_mpeg4SubtitleAvailableNum + uiMP4ReservedNum);iStreamNumber++)
  384. {
  385. #ifdef MP4_PACK_STCO
  386. if (TRUE == pStreamChunkSizeBuff[iStreamNumber].bPackSTCO)
  387. {
  388. _mp4LoadSTCOTable(pStreamChunkSizeBuff[iStreamNumber].dwStreamChunkOffsetAddr,&(pStreamChunkSizeBuff[iStreamNumber].OffsetBuff[0]),&(pStreamChunkSizeBuff[iStreamNumber].dwPrevChunkOffset));
  389. pStreamChunkSizeBuff[iStreamNumber].dwStreamChunkOffsetAddr += MP4_PACK_STCO_BUFF_SIZE_IN_WORD;
  390. }
  391. else
  392. #endif
  393. {
  394. wai_sem(SEM_DRAM_ID);
  395. I49_ReadDRAMData(pStreamChunkSizeBuff[iStreamNumber].dwStreamChunkOffsetAddr ,(UINT16*)&(pStreamChunkSizeBuff[iStreamNumber].OffsetBuff[0]), (MP4_CHUNK_SIZE_BUFF_SIZE*sizeof(DWORD)/2));
  396. #ifndef MP4_NO_DUMMY_CHUNK
  397. I49_ReadDRAMData(pStreamChunkSizeBuff[iStreamNumber].dwStreamChunkSizeAddr ,(UINT16*)&(pStreamChunkSizeBuff[iStreamNumber].SizeBuff[0]), (MP4_CHUNK_SIZE_BUFF_SIZE*sizeof(DWORD)/2));
  398. #endif
  399. sig_sem(SEM_DRAM_ID);
  400. #ifndef MP4_NO_DUMMY_CHUNK
  401. pStreamChunkSizeBuff[iStreamNumber].dwStreamChunkSizeAddr += (MP4_CHUNK_SIZE_BUFF_SIZE*sizeof(DWORD)/2);
  402. #endif
  403. pStreamChunkSizeBuff[iStreamNumber].dwStreamChunkOffsetAddr += (MP4_CHUNK_SIZE_BUFF_SIZE*sizeof(DWORD)/2);
  404. }
  405. pStreamChunkSizeBuff[iStreamNumber].dwStreamChunkOffset = pStreamChunkSizeBuff[iStreamNumber].OffsetBuff[(INT16)(pStreamChunkSizeBuff[iStreamNumber].dwStreamChunkNumber % MP4_CHUNK_SIZE_BUFF_SIZE)];
  406. }
  407. while (TRUE)
  408. {
  409. // search the samllest chunk offset
  410. for (iStreamNumber=0;iStreamNumber<=(_mpeg4AudioAvailableNum+_mpeg4SubtitleAvailableNum + uiMP4ReservedNum);iStreamNumber++)
  411. {
  412. if (pStreamChunkSizeBuff[iStreamNumber].dwStreamChunkNumber == pStreamChunkSizeBuff[iStreamNumber].dwStreamChunkTotal)
  413. {
  414. if (iStreamNumber == (_mpeg4AudioAvailableNum+_mpeg4SubtitleAvailableNum + uiMP4ReservedNum))
  415. {
  416. if (iStreamNumber > _mpeg4AudioAvailableNum+_mpeg4SubtitleAvailableNum )
  417. uiMP4ReservedNum --;
  418. }
  419. dwCurrStreamChunkFlag = dwCurrStreamChunkFlag | (1UL<<iStreamNumber);
  420. if (dwCurrStreamChunkFlag == dwStreamChunkFlag)
  421. dwChunkOffset = _dwMP4LastChunkEndOffset;
  422. continue;
  423. }
  424. if (pStreamChunkSizeBuff[iStreamNumber].dwStreamChunkOffset < dwChunkOffset)
  425. {
  426. dwChunkOffset = pStreamChunkSizeBuff[iStreamNumber].dwStreamChunkOffset;
  427. #ifndef MP4_NO_DUMMY_CHUNK
  428. dwChunkSize = pStreamChunkSizeBuff[iStreamNumber].SizeBuff[MP4_CHUNK_SIZE_BUFF_SIZE - 1 - (INT16)(pStreamChunkSizeBuff[iStreamNumber].dwStreamChunkNumber % MP4_CHUNK_SIZE_BUFF_SIZE)];
  429. #endif
  430. iCurrStreamNumber = iStreamNumber;
  431. }
  432. }
  433. pStreamChunkSizeBuff[iCurrStreamNumber].dwStreamChunkNumber++;
  434. if (pStreamChunkSizeBuff[iCurrStreamNumber].dwStreamChunkNumber % MP4_CHUNK_SIZE_BUFF_SIZE == 0)
  435. {
  436. #ifdef MP4_PACK_STCO
  437. if (TRUE == pStreamChunkSizeBuff[iCurrStreamNumber].bPackSTCO)
  438. {
  439. _mp4LoadSTCOTable(pStreamChunkSizeBuff[iCurrStreamNumber].dwStreamChunkOffsetAddr,&(pStreamChunkSizeBuff[iCurrStreamNumber].OffsetBuff[0]),&(pStreamChunkSizeBuff[iCurrStreamNumber].dwPrevChunkOffset));
  440. pStreamChunkSizeBuff[iCurrStreamNumber].dwStreamChunkOffsetAddr += MP4_PACK_STCO_BUFF_SIZE_IN_WORD;
  441. }
  442. else
  443. #endif
  444. {
  445. wai_sem(SEM_DRAM_ID);
  446. I49_ReadDRAMData(pStreamChunkSizeBuff[iCurrStreamNumber].dwStreamChunkOffsetAddr ,(UINT16*)&(pStreamChunkSizeBuff[iCurrStreamNumber].OffsetBuff[0]), (MP4_CHUNK_SIZE_BUFF_SIZE*sizeof(DWORD)/2));
  447. #ifndef MP4_NO_DUMMY_CHUNK
  448. I49_ReadDRAMData(pStreamChunkSizeBuff[iStreamNumber].dwStreamChunkSizeAddr ,(UINT16*)&(pStreamChunkSizeBuff[iStreamNumber].SizeBuff[0]), (MP4_CHUNK_SIZE_BUFF_SIZE*sizeof(DWORD)/2));
  449. #endif
  450. sig_sem(SEM_DRAM_ID);
  451. #ifndef MP4_NO_DUMMY_CHUNK
  452. pStreamChunkSizeBuff[iStreamNumber].dwStreamChunkSizeAddr += (MP4_CHUNK_SIZE_BUFF_SIZE*sizeof(DWORD)/2);
  453. #endif
  454. pStreamChunkSizeBuff[iCurrStreamNumber].dwStreamChunkOffsetAddr += (MP4_CHUNK_SIZE_BUFF_SIZE*sizeof(DWORD)/2);
  455. }
  456. }
  457. pStreamChunkSizeBuff[iCurrStreamNumber].dwStreamChunkOffset = pStreamChunkSizeBuff[iCurrStreamNumber].OffsetBuff[(INT16)(pStreamChunkSizeBuff[iCurrStreamNumber].dwStreamChunkNumber % MP4_CHUNK_SIZE_BUFF_SIZE)];
  458. #ifndef MP4_NO_DUMMY_CHUNK
  459. if (dwCurrStreamChunkFlag == dwStreamChunkFlag)
  460. break;
  461. #endif
  462. if (TRUE == bFirstTime)
  463. {
  464. #ifdef MP4_NO_DUMMY_CHUNK
  465. _dwMP4FirstChunkOffset = dwChunkOffset;
  466. dwPreChunkOffset = dwChunkOffset;
  467. iPrevStreamNumber = iCurrStreamNumber;
  468. // _dwMP4LastChunkEndOffset = dwChunkOffset;
  469. if (iCurrStreamNumber <= (_mpeg4AudioAvailableNum+_mpeg4SubtitleAvailableNum))
  470. bFirstTime = FALSE;
  471. #else
  472. _dwMP4FirstChunkOffset = dwChunkOffset;
  473. _dwMP4LastChunkEndOffset = dwChunkOffset + dwChunkSize;
  474. #ifdef PRINTF_MP4_CHUNK_SIZE
  475. if (dwChunkCount < MAX_PRINTF_CHUNK_NUM)
  476. {
  477. dbg_printf(("ChunkCount: 0x%8lx, ChunkOffset: 0x%8lx, ChunkSize: %8ld, ChunkType: %2xn", 
  478. dwChunkCount,dwChunkOffset,dwChunkSize, iCurrStreamNumber));
  479. }
  480. #endif
  481. _dwMP4ChunkSizeBuff[MP4_CHUNK_SIZE_TABLE_BUFF_SIZE - 1 - (INT16)(dwChunkCount%MP4_CHUNK_SIZE_TABLE_BUFF_SIZE)] = ((dwChunkSize<<8) + iCurrStreamNumber);
  482. dwChunkCount++;
  483. bFirstTime = FALSE;
  484. #endif
  485. }
  486. else
  487. {
  488. #ifdef MP4_NO_DUMMY_CHUNK
  489. while (dwChunkOffset > dwPreChunkOffset)
  490. {
  491. DWORD dwChunkSizeTemp;
  492. dwChunkSizeTemp = min((dwChunkOffset - dwPreChunkOffset), dwMP4MaxStoreChunkSize);
  493. #ifdef PRINTF_MP4_CHUNK_SIZE
  494. if (dwChunkCount < MAX_PRINTF_CHUNK_NUM)
  495. {
  496. dbg_printf(("ChunkCount: %8lx, ChunkOffset: %8lx, ChunkSize: %8lx, ChunkType: %2xn", 
  497. dwChunkCount,dwPreChunkOffset, dwChunkSizeTemp, iPrevStreamNumber));
  498. }
  499. #endif
  500. _dwMP4ChunkSizeBuff[MP4_CHUNK_SIZE_TABLE_BUFF_SIZE - 1 - (INT16)(dwChunkCount%MP4_CHUNK_SIZE_TABLE_BUFF_SIZE)] = ((dwChunkSizeTemp<<8) + iPrevStreamNumber);
  501. if ((dwChunkCount % MP4_CHUNK_SIZE_TABLE_BUFF_SIZE) == (MP4_CHUNK_SIZE_TABLE_BUFF_SIZE-1))
  502. {
  503. #ifdef MP4_PACK_TRANSFER_CHUNK_SIZE
  504. if (TRUE == bMP4NeedPack)
  505. dwChunkSizeAddr -= MP4_PACK_CHUNK_SIZE_ENTRY_BUFF_SIZE;
  506. else
  507. dwChunkSizeAddr -= MP4_CHUNK_SIZE_ENTRY_BUFF_SIZE;
  508. _mp4StorePackTransferChunkSize(dwChunkSizeAddr, (DWORD*)&_dwMP4ChunkSizeBuff);
  509. #else
  510. dwChunkSizeAddr -= MP4_CHUNK_SIZE_ENTRY_BUFF_SIZE;
  511. wai_sem(SEM_DRAM_ID);
  512. I49_WriteDRAMData(dwChunkSizeAddr,(UINT16*)&_dwMP4ChunkSizeBuff, MP4_CHUNK_SIZE_ENTRY_BUFF_SIZE);
  513. sig_sem(SEM_DRAM_ID);
  514. #endif
  515. }
  516. dwChunkCount++;
  517. dwPreChunkOffset += dwChunkSizeTemp;
  518. }
  519. iPrevStreamNumber = iCurrStreamNumber;
  520. #else
  521. while (dwChunkOffset > _dwMP4LastChunkEndOffset)
  522. {
  523. DWORD dwChunkSizeTemp;
  524. dwChunkSizeTemp = min((dwChunkOffset - _dwMP4LastChunkEndOffset), dwMP4MaxStoreChunkSize);
  525. #ifdef PRINTF_MP4_CHUNK_SIZE
  526. if (dwChunkCount < MAX_PRINTF_CHUNK_NUM)
  527. {
  528. dbg_printf(("ChunkCount: %8lx, ChunkOffset: %8lx, ChunkSize: %8lx, ChunkType: %2xn", 
  529. dwChunkCount,_dwMP4LastChunkEndOffset, dwChunkSizeTemp, MP4_NOT_USED_STREAM_ID));
  530. }
  531. #endif
  532. _dwMP4ChunkSizeBuff[MP4_CHUNK_SIZE_TABLE_BUFF_SIZE - 1 - (INT16)(dwChunkCount%MP4_CHUNK_SIZE_TABLE_BUFF_SIZE)] = ((dwChunkSizeTemp <<8) + MP4_NOT_USED_STREAM_ID);
  533. if ((dwChunkCount % MP4_CHUNK_SIZE_TABLE_BUFF_SIZE) == (MP4_CHUNK_SIZE_TABLE_BUFF_SIZE-1))
  534. {
  535. #ifdef MP4_PACK_TRANSFER_CHUNK_SIZE
  536. if (TRUE == bMP4NeedPack)
  537. dwChunkSizeAddr -= MP4_PACK_CHUNK_SIZE_ENTRY_BUFF_SIZE;
  538. else
  539. dwChunkSizeAddr -= MP4_CHUNK_SIZE_ENTRY_BUFF_SIZE;
  540. _mp4StorePackTransferChunkSize(dwChunkSizeAddr, (DWORD*)&_dwMP4ChunkSizeBuff);
  541. #else
  542. dwChunkSizeAddr -= MP4_CHUNK_SIZE_ENTRY_BUFF_SIZE;
  543. wai_sem(SEM_DRAM_ID);
  544. I49_WriteDRAMData(dwChunkSizeAddr,(UINT16*)&_dwMP4ChunkSizeBuff, MP4_CHUNK_SIZE_ENTRY_BUFF_SIZE);
  545. sig_sem(SEM_DRAM_ID);
  546. #endif
  547. }
  548. dwChunkCount++;
  549. _dwMP4LastChunkEndOffset += dwChunkSizeTemp;
  550. }
  551. do
  552. {
  553. DWORD dwChunkSizeTemp;
  554. dwChunkSizeTemp = min(dwChunkSize, dwMP4MaxStoreChunkSize);
  555. #ifdef PRINTF_MP4_CHUNK_SIZE
  556. if (dwChunkCount < MAX_PRINTF_CHUNK_NUM)
  557. {
  558. dbg_printf(("ChunkCount: %8lx, ChunkOffset: %8lx, ChunkSize: %8lx, ChunkType: %2xn", 
  559. dwChunkCount,_dwMP4LastChunkEndOffset, dwChunkSizeTemp, iCurrStreamNumber));
  560. }
  561. #endif
  562. _dwMP4ChunkSizeBuff[MP4_CHUNK_SIZE_TABLE_BUFF_SIZE - 1 - (INT16)(dwChunkCount%MP4_CHUNK_SIZE_TABLE_BUFF_SIZE)] = ((dwChunkSizeTemp<<8) + iCurrStreamNumber);
  563. if ((dwChunkCount % MP4_CHUNK_SIZE_TABLE_BUFF_SIZE) == (MP4_CHUNK_SIZE_TABLE_BUFF_SIZE-1))
  564. {
  565. #ifdef MP4_PACK_TRANSFER_CHUNK_SIZE
  566. if (TRUE == bMP4NeedPack)
  567. dwChunkSizeAddr -= MP4_PACK_CHUNK_SIZE_ENTRY_BUFF_SIZE;
  568. else
  569. dwChunkSizeAddr -= MP4_CHUNK_SIZE_ENTRY_BUFF_SIZE;
  570. _mp4StorePackTransferChunkSize(dwChunkSizeAddr, (DWORD*)&_dwMP4ChunkSizeBuff);
  571. #else
  572. dwChunkSizeAddr -= MP4_CHUNK_SIZE_ENTRY_BUFF_SIZE;
  573. wai_sem(SEM_DRAM_ID);
  574. I49_WriteDRAMData(dwChunkSizeAddr,(UINT16*)&_dwMP4ChunkSizeBuff, MP4_CHUNK_SIZE_ENTRY_BUFF_SIZE);
  575. sig_sem(SEM_DRAM_ID);
  576. #endif
  577. }
  578. dwChunkCount++;
  579. _dwMP4LastChunkEndOffset += dwChunkSizeTemp;
  580. dwChunkSize -= dwChunkSizeTemp;
  581. }while(dwChunkSize > 0UL);
  582. #endif
  583. }
  584. #ifdef MP4_NO_DUMMY_CHUNK
  585. if (dwCurrStreamChunkFlag == dwStreamChunkFlag)
  586. break;
  587. #endif
  588. // _dwMP4LastChunkEndOffset = dwChunkOffset + dwChunkSize;
  589. dwChunkOffset = 0xFFFFFFFFUL;
  590. }
  591. if ((dwChunkCount % MP4_CHUNK_SIZE_TABLE_BUFF_SIZE) != 0)
  592. {
  593. #ifdef MP4_PACK_TRANSFER_CHUNK_SIZE
  594. if (TRUE == bMP4NeedPack)
  595. dwChunkSizeAddr -= MP4_PACK_CHUNK_SIZE_ENTRY_BUFF_SIZE;
  596. else
  597. dwChunkSizeAddr -= MP4_CHUNK_SIZE_ENTRY_BUFF_SIZE;
  598. _mp4StorePackTransferChunkSize(dwChunkSizeAddr, (DWORD*)&_dwMP4ChunkSizeBuff);
  599. #else
  600. dwChunkSizeAddr -= MP4_CHUNK_SIZE_ENTRY_BUFF_SIZE;
  601. wai_sem(SEM_DRAM_ID);
  602. I49_WriteDRAMData(dwChunkSizeAddr,(UINT16*)&_dwMP4ChunkSizeBuff, MP4_CHUNK_SIZE_ENTRY_BUFF_SIZE);
  603. sig_sem(SEM_DRAM_ID);
  604. #endif
  605. }
  606. _dwMP4ChunkSizeEntryTotal = dwChunkCount;
  607. _dwMPEG4ProcessingEndAddr = dwChunkSizeAddr;
  608. _dwMPEG4ProcessingEndAddr = (_dwMPEG4ProcessingEndAddr>>9)<<9;
  609. tr_printf(("n_dwMP4ChunkSizeStartAddr: %ld KB, Size: %ld KBn", _dwMP4ChunkSizeStartAddr>>9, (_dwMP4ChunkSizeStartAddr - _dwMPEG4ProcessingEndAddr)>>9));
  610. // _dwMP4ChunkSizeEndAddr = dwChunkSizeAddr;
  611. free(pStreamChunkSizeBuff);
  612. return TRUE;
  613. }
  614. static BOOL _mp4GetAdjacentIFrames(WORD wTime, DWORD *dwVideoSyncSampleNum, DWORD *dwSyncSampleOffset)
  615. {
  616. MP4VideoSyncEntry mp4VideoSyncEntry;
  617. MP4AudioSyncEntry mp4AudioSyncEntry;
  618. DWORD  dwRequestedFrameNumber;
  619. // DWORD  dwIndex,dwSyncEntryAddr;
  620. DWORD  dwUpIndex,dwUpSyncEntryAddr;
  621. DWORD  dwDownIndex,dwDownSyncEntryAddr;
  622. DWORD dwUpDiff, dwDownDiff, dwDiff;
  623. DWORD dwAudioSyncSampleOffset;
  624. WORD wSampleTableAddrEXAddr;
  625. MP4StreamSampleTableAddrEX mp4StreamSampleTableAddrEX;
  626. if (_mpeg4VideoStreamID == NO_STREAM)
  627. {
  628. _ulMPEG4RequestedFrameIndex = wTime;
  629. // get the correspond audio sync 
  630. wSampleTableAddrEXAddr = SC_MPEG4_AUDIO_SAMPLE_TABLE_ADDREX_BUFF_ADDR + (_mpeg4AudioCurrentDispIdx * SIZE_OF_MP4StreamSampleTableAddrEX_IN_DWORD);
  631. sc_GetBytes(wSampleTableAddrEXAddr,
  632. 0,SIZE_OF_MP4StreamSampleTableAddrEX,(BYTE*)&mp4StreamSampleTableAddrEX);
  633. wSampleTableAddrEXAddr = SC_MPEG4_AUDIO_SAMPLE_TABLE_ADDREX_BUFF_ADDR + (_mpeg4AudioCurrentDispIdx * SIZE_OF_MP4StreamSampleTableAddrEX_IN_DWORD);
  634. sc_GetBytes(wSampleTableAddrEXAddr,
  635. 0,SIZE_OF_MP4StreamSampleTableAddrEX,(BYTE*)&mp4StreamSampleTableAddrEX);
  636. dwUpSyncEntryAddr = MP4_CALC_ENTRY_ADDRESS(mp4SyncEntryStartAddr, MP4_AUDIO_SYNC_ENTRY_SIZE, _ulMPEG4RequestedFrameIndex);
  637. wai_sem(SEM_DRAM_ID);
  638. I49_ReadDRAMData(dwUpSyncEntryAddr,(UINT16*)&mp4AudioSyncEntry, MP4_AUDIO_SYNC_ENTRY_SIZE);
  639. sig_sem(SEM_DRAM_ID);
  640. dwAudioSyncSampleOffset = mp4AudioSyncEntry.dwSyncChunkOffset/* + mp4AudioSyncEntry.dwOffsetofChunk*/;
  641. *dwVideoSyncSampleNum = wTime * 30UL;
  642. *dwSyncSampleOffset = dwAudioSyncSampleOffset;
  643. return TRUE;
  644. }
  645. dwRequestedFrameNumber = caclFrameOfTime(wTime, _mpeg4VideoRate, _mpeg4VideoScale);
  646. dwUpIndex = (dwRequestedFrameNumber * 1000UL) /_mpeg4VideoLength;
  647. dwUpIndex = (dwUpIndex * _uiMPEG4NextIndexEntry) / 1000UL;
  648. dwUpIndex = min(dwUpIndex, (_uiMPEG4NextIndexEntry-1));
  649. dwUpSyncEntryAddr = MP4_CALC_ENTRY_ADDRESS(MPEG4_PROCESSING_BUFF_ADDR, MP4_VIDEO_SYNC_ENTRY_SIZE, dwUpIndex);
  650. dwDownIndex = dwUpIndex;
  651. dwDownSyncEntryAddr = dwUpSyncEntryAddr;
  652. dwUpDiff = 0xFFFFFFFFUL;
  653. dwDownDiff = 0xFFFFFFFFUL;
  654. while (TRUE)
  655. {
  656. wai_sem(SEM_DRAM_ID);
  657. I49_ReadDRAMData(dwUpSyncEntryAddr,(UINT16*)&mp4VideoSyncEntry, MP4_VIDEO_SYNC_ENTRY_SIZE);
  658. sig_sem(SEM_DRAM_ID);
  659. dwDiff = ABS_DIFF(mp4VideoSyncEntry.dwSyncSampleNumber,dwRequestedFrameNumber);
  660. if (dwDiff > dwUpDiff)
  661. break;
  662. dwUpDiff = dwDiff;
  663. dwUpIndex++;
  664. if (dwUpIndex >= _uiMPEG4NextIndexEntry)
  665. break;
  666. dwUpSyncEntryAddr -= MP4_VIDEO_SYNC_ENTRY_SIZE;
  667. }
  668. while (TRUE)
  669. {
  670. wai_sem(SEM_DRAM_ID);
  671. I49_ReadDRAMData(dwDownSyncEntryAddr,(UINT16*)&mp4VideoSyncEntry, MP4_VIDEO_SYNC_ENTRY_SIZE);
  672. sig_sem(SEM_DRAM_ID);
  673. dwDiff = ABS_DIFF(mp4VideoSyncEntry.dwSyncSampleNumber,dwRequestedFrameNumber);
  674. if (dwDiff > dwDownDiff)
  675. break;
  676. dwDownDiff = dwDiff;
  677. dwDownIndex --;
  678. if ((INT32)dwDownIndex < 0)
  679. break;
  680. dwDownSyncEntryAddr += MP4_VIDEO_SYNC_ENTRY_SIZE;
  681. }
  682. if (dwDownDiff <= dwUpDiff)
  683. _ulMPEG4RequestedFrameIndex = dwDownIndex+1;
  684. else
  685. _ulMPEG4RequestedFrameIndex = dwUpIndex-1;
  686.    if (PM_GetRepeatAB())
  687.         _ulMPEG4RequestedFrameIndex = dwUpIndex-1;
  688. dwUpSyncEntryAddr = MP4_CALC_ENTRY_ADDRESS(MPEG4_PROCESSING_BUFF_ADDR, MP4_VIDEO_SYNC_ENTRY_SIZE, _ulMPEG4RequestedFrameIndex);
  689. wai_sem(SEM_DRAM_ID);
  690. I49_ReadDRAMData(dwUpSyncEntryAddr,(UINT16*)&mp4VideoSyncEntry, MP4_VIDEO_SYNC_ENTRY_SIZE);
  691. sig_sem(SEM_DRAM_ID);
  692. *dwVideoSyncSampleNum = mp4VideoSyncEntry.dwSyncSampleNumber;
  693. *dwSyncSampleOffset = mp4VideoSyncEntry.dwSyncChunkOffset/* + mp4VideoSyncEntry.dwOffsetofChunk*/;
  694. // get the correspond audio sync 
  695. wSampleTableAddrEXAddr = SC_MPEG4_AUDIO_SAMPLE_TABLE_ADDREX_BUFF_ADDR + (_mpeg4AudioCurrentDispIdx * SIZE_OF_MP4StreamSampleTableAddrEX_IN_DWORD);
  696. sc_GetBytes(wSampleTableAddrEXAddr,
  697. 0,SIZE_OF_MP4StreamSampleTableAddrEX,(BYTE*)&mp4StreamSampleTableAddrEX);
  698. dwUpSyncEntryAddr = MP4_CALC_ENTRY_ADDRESS(mp4SyncEntryStartAddr, MP4_AUDIO_SYNC_ENTRY_SIZE, _ulMPEG4RequestedFrameIndex);
  699. wai_sem(SEM_DRAM_ID);
  700. I49_ReadDRAMData(dwUpSyncEntryAddr,(UINT16*)&mp4AudioSyncEntry, MP4_AUDIO_SYNC_ENTRY_SIZE);
  701. sig_sem(SEM_DRAM_ID);
  702. dwAudioSyncSampleOffset = mp4AudioSyncEntry.dwSyncChunkOffset/* + mp4AudioSyncEntry.dwOffsetofChunk*/;
  703. if (*dwSyncSampleOffset > dwAudioSyncSampleOffset)
  704. *dwSyncSampleOffset = dwAudioSyncSampleOffset;
  705. return TRUE;
  706. }
  707. static BOOL _mp4GetNextIFrames(UINT32 ulRequestedSampleNumber,  UINT16* uiNextIIdx, MP4VideoSyncEntry* mp4VideoSyncEntry)
  708. {
  709. for((*uiNextIIdx)=0; (*uiNextIIdx) < _uiMPEG4NextIndexEntry; (*uiNextIIdx)++)
  710. {
  711. wai_sem(SEM_DRAM_ID);
  712. I49_ReadDRAMData(MP4_CALC_ENTRY_ADDRESS(MPEG4_PROCESSING_BUFF_ADDR, (sizeof(MP4VideoSyncEntry)/2),*uiNextIIdx),
  713.  (UINT16*)mp4VideoSyncEntry, sizeof(MP4VideoSyncEntry)/2);
  714. sig_sem(SEM_DRAM_ID);
  715. if((mp4VideoSyncEntry->dwSyncSampleNumber) > ulRequestedSampleNumber)
  716. {
  717. break;
  718. }
  719. }
  720. return TRUE;
  721. }
  722. static void _mp4SetFirstSkipBytes(BOOL bScan)
  723. {
  724. MP4VideoSyncEntry mp4VideoSyncEntry;
  725. MP4AudioSyncEntry mp4AudioSyncEntry;
  726. DWORD  dwMP4VideosyncEntryAddr;
  727. DWORD dwAudioSyncEntryAddr;
  728. MP4StreamSampleTableAddrEX mp4StreamSampleTableAddrEX;
  729. if ((FALSE == bScan) && (_mpeg4VideoStreamID != NO_STREAM))
  730. {
  731. dwMP4VideosyncEntryAddr = MP4_CALC_ENTRY_ADDRESS(MPEG4_PROCESSING_BUFF_ADDR, MP4_VIDEO_SYNC_ENTRY_SIZE, _ulMPEG4RequestedFrameIndex);
  732. wai_sem(SEM_DRAM_ID);
  733. I49_ReadDRAMData(dwMP4VideosyncEntryAddr,(UINT16*)&mp4VideoSyncEntry, MP4_VIDEO_SYNC_ENTRY_SIZE);
  734. sig_sem(SEM_DRAM_ID);
  735. sc_GetBytes(SC_MPEG4_AUDIO_SAMPLE_TABLE_ADDREX_BUFF_ADDR + (_mpeg4AudioCurrentDispIdx * SIZE_OF_MP4StreamSampleTableAddrEX_IN_DWORD),
  736. 0,SIZE_OF_MP4StreamSampleTableAddrEX,(BYTE*)&mp4StreamSampleTableAddrEX);
  737. dwAudioSyncEntryAddr = MP4_CALC_ENTRY_ADDRESS(mp4SyncEntryStartAddr, MP4_AUDIO_SYNC_ENTRY_SIZE, _ulMPEG4RequestedFrameIndex);
  738. wai_sem(SEM_DRAM_ID);
  739. I49_ReadDRAMData(dwAudioSyncEntryAddr,(UINT16*)&mp4AudioSyncEntry, MP4_AUDIO_SYNC_ENTRY_SIZE);
  740. sig_sem(SEM_DRAM_ID);
  741. DEC_MP4_SetFirstSkipBytes(mp4VideoSyncEntry.dwOffsetofChunk, mp4AudioSyncEntry.dwOffsetofChunk, 0);
  742. tr_printf(("First Skip Bytes of Video: %8lx, Audio: %8lxn", mp4VideoSyncEntry.dwOffsetofChunk, mp4AudioSyncEntry.dwOffsetofChunk));
  743. }
  744. else
  745. {
  746. DEC_MP4_SetFirstSkipBytes(0, 0, 0);
  747. }
  748. return;
  749. }
  750. #ifdef MP4_TANSFER_CHUNKSIZE_BY_FIFO
  751. static void _mp4TransferChunkSizeByFifo(void)
  752. {
  753. BYTE chunkID;
  754. BYTE preChunkID;
  755. BOOL bFirstGetChunk;
  756. WORD wTransferLength;
  757. // DWORD  mp4TransferChunkSizeBuff[MP4_TRANSFER_CHUNKSIZE_FIFO_LENGTH];
  758. DWORD* mp4TransferChunkSizeBuff;
  759. // BOOL  bLastChunkIsNotUsed;
  760. DWORD  dwChunkSizeAddr;
  761. DWORD  dwChunkSize;
  762. DWORD  dwChunkSizeAndId;
  763. mp4TransferChunkSizeBuff = (DWORD*)(&_MP4SharedBuff[0]);
  764. if (FALSE == DEC_MP4_ChunkSizeFifoEmpty())
  765. return;
  766. preChunkID = MP4_NOT_USED_STREAM_ID;
  767. chunkID = MP4_NOT_USED_STREAM_ID;
  768. dwChunkSize = 0;
  769. wTransferLength = 0;
  770. // bLastChunkIsNotUsed = FALSE;
  771. bFirstGetChunk = TRUE;
  772. #ifdef PRINTF_MP4_TRANSFER_CHUNK_SIZE
  773. {
  774. dbg_printf(("ChunkSize Index : %lxn", _dwMP4ChunkSizeEntryIndex));
  775. }
  776. #endif
  777. while (TRUE)
  778. {
  779. if (_dwMP4ChunkSizeEntryIndex > _dwMP4ChunkSizeEntryTotal)
  780. break;
  781. if (_dwMP4ChunkSizeEntryIndex == _dwMP4ChunkSizeEntryTotal)
  782. {
  783. mp4TransferChunkSizeBuff[wTransferLength++] = (((DWORD)preChunkID)<<24) + dwChunkSize;
  784. _dwMP4ChunkSizeEntryIndex ++;
  785. break;
  786. }
  787. dwChunkSizeAndId = _dwMP4ChunkSizeBuff[MP4_CHUNK_SIZE_TABLE_BUFF_SIZE - (INT16)(_dwMP4ChunkSizeEntryIndex%MP4_CHUNK_SIZE_TABLE_BUFF_SIZE) - 1];
  788. preChunkID = chunkID;
  789. chunkID = (BYTE)(dwChunkSizeAndId & 0xFF);
  790. dwChunkSize += (dwChunkSizeAndId >> 8);
  791. _dwMP4ChunkSizeEntryIndex++;
  792. _dwMP4ChunkOffset += (dwChunkSizeAndId >> 8);
  793. if (((chunkID == _mpeg4VideoStreamID) && (_dwMP4ChunkOffset <= _dwMP4VideoSyncOffset)) ||
  794. ((chunkID == _mpeg4AudioStreamID) && (_dwMP4ChunkOffset <= _dwMP4AudioSyncOffset)) /*||
  795. ((chunkID == _mpeg4SubtitleStreamID) && (_dwMP4ChunkOffset <= _dwMP4VideoSyncOffset))*/)
  796. {
  797. chunkID = MP4_NOT_USED_STREAM_ID;
  798. }
  799. if ((chunkID != _mpeg4VideoStreamID) && (chunkID != _mpeg4AudioStreamID) && (chunkID != _mpeg4SubtitleStreamID))
  800. chunkID = MP4_NOT_USED_STREAM_ID;
  801. if (FALSE == bFirstGetChunk)
  802. {
  803. if ((preChunkID != chunkID) || (dwChunkSize >= MP4_MAX_CHUNK_SIZE))
  804. {
  805. dwChunkSize -= (dwChunkSizeAndId >> 8);
  806. mp4TransferChunkSizeBuff[wTransferLength++] = (((DWORD)preChunkID)<<24) + dwChunkSize;
  807. //preChunkID = chunkID;
  808. //dwChunkSize = (dwChunkSizeAndId >> 8);
  809. _dwMP4ChunkSizeEntryIndex--;
  810. _dwMP4ChunkOffset -= (dwChunkSizeAndId >> 8);
  811. dwChunkSize = 0;
  812. bFirstGetChunk = TRUE;
  813. }
  814. }
  815. else
  816. {
  817. bFirstGetChunk = FALSE; 
  818. }
  819. // mp4TransferChunkSizeBuff[wTransferLength++] = (((DWORD)chunkID)<<24) + dwChunkSize;
  820. // dwChunkSize = 0;
  821. if (_dwMP4ChunkSizeEntryIndex % MP4_CHUNK_SIZE_TABLE_BUFF_SIZE == 0)
  822. {
  823. #ifdef MP4_PACK_TRANSFER_CHUNK_SIZE
  824. if (TRUE == bMP4NeedPack)
  825. dwChunkSizeAddr = MP4_CALC_ENTRY_ADDRESS(_dwMP4ChunkSizeStartAddr, MP4_PACK_CHUNK_SIZE_ENTRY_BUFF_SIZE, 
  826. (_dwMP4ChunkSizeEntryIndex/MP4_CHUNK_SIZE_TABLE_BUFF_SIZE));
  827. else
  828. dwChunkSizeAddr = MP4_CALC_ENTRY_ADDRESS(_dwMP4ChunkSizeStartAddr, MP4_CHUNK_SIZE_ENTRY_BUFF_SIZE, 
  829. (_dwMP4ChunkSizeEntryIndex/MP4_CHUNK_SIZE_TABLE_BUFF_SIZE));
  830. _mp4LoadPackTransferChunkSize(dwChunkSizeAddr, (DWORD*)&_dwMP4ChunkSizeBuff);
  831. #else
  832. dwChunkSizeAddr = MP4_CALC_ENTRY_ADDRESS(_dwMP4ChunkSizeStartAddr, MP4_CHUNK_SIZE_ENTRY_BUFF_SIZE, 
  833. (_dwMP4ChunkSizeEntryIndex/MP4_CHUNK_SIZE_TABLE_BUFF_SIZE));
  834. wai_sem(SEM_DRAM_ID);
  835. I49_ReadDRAMData(dwChunkSizeAddr,(UINT16*)&_dwMP4ChunkSizeBuff, MP4_CHUNK_SIZE_ENTRY_BUFF_SIZE);
  836. sig_sem(SEM_DRAM_ID);
  837. #endif
  838. }
  839. bFirstGetChunk = FALSE; 
  840. if (wTransferLength >= MP4_TRANSFER_CHUNKSIZE_FIFO_LENGTH)
  841. break;
  842. }
  843. while (wTransferLength < MP4_TRANSFER_CHUNKSIZE_FIFO_LENGTH)
  844. mp4TransferChunkSizeBuff[wTransferLength++] = 0xFFFFFFFFUL;
  845. #ifdef PRINTF_MP4_TRANSFER_CHUNK_SIZE
  846. {
  847. int i;
  848. for (i=0;i<MP4_TRANSFER_CHUNKSIZE_FIFO_LENGTH; i++)
  849. {
  850. dbg_printf(("Tansfer Chunk Offset: %8lx, Size: %8lx, Type: %2xn", dwTransferChunkOffset, mp4TransferChunkSizeBuff[i]&0xFFFFFFUL, mp4TransferChunkSizeBuff[i]>>24));
  851. dwTransferChunkOffset += (mp4TransferChunkSizeBuff[i]&0xFFFFFFUL);
  852. }
  853. }
  854. #endif
  855. DEC_MP4_ChunkSizeFifoWrite(mp4TransferChunkSizeBuff);
  856. return;
  857. }
  858. #endif
  859. static void _mp4GetChunkSizeEntryIndex(BOOL bVideoOnly)
  860. {
  861. MP4VideoSyncEntry mp4VideoSyncEntry;
  862. MP4AudioSyncEntry mp4AudioSyncEntry;
  863. DWORD  dwMP4VideosyncEntryAddr;
  864. DWORD  dwChunkSyncOffset;
  865. DWORD  dwChunkSizeAddr;
  866. DWORD  dwChunkSize;
  867. DWORD dwAudioSyncEntryAddr;
  868. MP4StreamSampleTableAddrEX mp4StreamSampleTableAddrEX;
  869. if (TRUE == bVideoOnly)
  870. {
  871. dwMP4VideosyncEntryAddr = MP4_CALC_ENTRY_ADDRESS(MPEG4_PROCESSING_BUFF_ADDR, MP4_VIDEO_SYNC_ENTRY_SIZE, _ulMPEG4RequestedFrameIndex);
  872. wai_sem(SEM_DRAM_ID);
  873. I49_ReadDRAMData(dwMP4VideosyncEntryAddr,(UINT16*)&mp4VideoSyncEntry, MP4_VIDEO_SYNC_ENTRY_SIZE);
  874. sig_sem(SEM_DRAM_ID);
  875. dwChunkSyncOffset = mp4VideoSyncEntry.dwSyncChunkOffset;
  876. _dwMP4VideoSyncOffset = dwChunkSyncOffset;
  877. _dwMP4AudioSyncOffset = dwChunkSyncOffset; 
  878. }
  879. else if (_ulMPEG4RequestedFrameIndex == 0)
  880. {
  881. dwChunkSyncOffset = _dwMP4FirstChunkOffset;
  882. _dwMP4ChunkOffset = _dwMP4FirstChunkOffset; 
  883. _dwMP4VideoSyncOffset = dwChunkSyncOffset;
  884. _dwMP4AudioSyncOffset = dwChunkSyncOffset; 
  885. _dwMP4ChunkSizeEntryIndex = 0UL;
  886. }
  887. else
  888. {
  889. dwMP4VideosyncEntryAddr = MP4_CALC_ENTRY_ADDRESS(MPEG4_PROCESSING_BUFF_ADDR, MP4_VIDEO_SYNC_ENTRY_SIZE, _ulMPEG4RequestedFrameIndex);
  890. wai_sem(SEM_DRAM_ID);
  891. I49_ReadDRAMData(dwMP4VideosyncEntryAddr,(UINT16*)&mp4VideoSyncEntry, MP4_VIDEO_SYNC_ENTRY_SIZE);
  892. sig_sem(SEM_DRAM_ID);
  893. sc_GetBytes(SC_MPEG4_AUDIO_SAMPLE_TABLE_ADDREX_BUFF_ADDR + (_mpeg4AudioCurrentDispIdx * SIZE_OF_MP4StreamSampleTableAddrEX_IN_DWORD),
  894. 0,SIZE_OF_MP4StreamSampleTableAddrEX,(BYTE*)&mp4StreamSampleTableAddrEX);
  895. dwAudioSyncEntryAddr = MP4_CALC_ENTRY_ADDRESS(mp4SyncEntryStartAddr, MP4_AUDIO_SYNC_ENTRY_SIZE, _ulMPEG4RequestedFrameIndex);
  896. wai_sem(SEM_DRAM_ID);
  897. I49_ReadDRAMData(dwAudioSyncEntryAddr,(UINT16*)&mp4AudioSyncEntry, MP4_AUDIO_SYNC_ENTRY_SIZE);
  898. sig_sem(SEM_DRAM_ID);
  899.   
  900. // DEC_MP4_SetFirstSkipBytes(mp4VideoSyncEntry.dwOffsetofChunk, mp4AudioSyncEntry.dwOffsetofChunk, 0);
  901. if ((_mpeg4VideoStreamID != NO_STREAM) && (_mpeg4AudioStreamID != NO_STREAM))
  902. {
  903. dwChunkSyncOffset = min(mp4VideoSyncEntry.dwSyncChunkOffset, mp4AudioSyncEntry.dwSyncChunkOffset);
  904. _dwMP4VideoSyncOffset = mp4VideoSyncEntry.dwSyncChunkOffset;
  905. _dwMP4AudioSyncOffset = mp4AudioSyncEntry.dwSyncChunkOffset; 
  906. }
  907. else if (_mpeg4VideoStreamID != NO_STREAM)
  908. {
  909. dwChunkSyncOffset = mp4VideoSyncEntry.dwSyncChunkOffset;
  910. _dwMP4VideoSyncOffset = dwChunkSyncOffset;
  911. _dwMP4AudioSyncOffset = dwChunkSyncOffset; 
  912. }
  913. else if (_mpeg4AudioStreamID != NO_STREAM)
  914. {
  915. dwChunkSyncOffset = mp4AudioSyncEntry.dwSyncChunkOffset;
  916. _dwMP4VideoSyncOffset = dwChunkSyncOffset;
  917. _dwMP4AudioSyncOffset = dwChunkSyncOffset; 
  918. }
  919. }
  920. tr_printf(("First chunk Offset of Video: %8lx, Audio: %8lxn",_dwMP4VideoSyncOffset, _dwMP4AudioSyncOffset));
  921. if ((dwChunkSyncOffset - _dwMP4FirstChunkOffset) <= (_dwMP4LastChunkEndOffset - dwChunkSyncOffset))
  922. {
  923. _dwMP4ChunkOffset = _dwMP4FirstChunkOffset; 
  924. _dwMP4ChunkSizeEntryIndex = 0UL;
  925. #ifdef MP4_PACK_TRANSFER_CHUNK_SIZE
  926. #if 0
  927. if (TRUE == bMP4NeedPack)
  928. dwChunkSizeAddr = MP4_CALC_ENTRY_ADDRESS(_dwMP4ChunkSizeStartAddr, MP4_PACK_CHUNK_SIZE_ENTRY_BUFF_SIZE, 0);
  929. else
  930. dwChunkSizeAddr = MP4_CALC_ENTRY_ADDRESS(_dwMP4ChunkSizeStartAddr, MP4_CHUNK_SIZE_ENTRY_BUFF_SIZE, 0);
  931. #else
  932. // Robin_0110_2005, reduce the seek time
  933. if (TRUE == bMP4NeedPack)
  934. dwChunkSizeAddr = MP4_CALC_ENTRY_ADDRESS(_dwMP4ChunkSizeStartAddr, MP4_PACK_CHUNK_SIZE_ENTRY_BUFF_SIZE, 3);
  935. else
  936. dwChunkSizeAddr = MP4_CALC_ENTRY_ADDRESS(_dwMP4ChunkSizeStartAddr, MP4_CHUNK_SIZE_ENTRY_BUFF_SIZE, 3);
  937. while (TRUE)
  938. {
  939. dwChunkSize = _mp4CalculatePackTransferChunkSize(dwChunkSizeAddr, (DWORD*)&_MP4SharedBuff);
  940. _dwMP4ChunkOffset += dwChunkSize;
  941. if (_dwMP4ChunkOffset > dwChunkSyncOffset)
  942. {
  943. if (TRUE == bMP4NeedPack)
  944. dwChunkSizeAddr += (MP4_PACK_CHUNK_SIZE_ENTRY_BUFF_SIZE2 - MP4_PACK_CHUNK_SIZE_ENTRY_BUFF_SIZE);
  945. else
  946. dwChunkSizeAddr += (MP4_CHUNK_SIZE_ENTRY_BUFF_SIZE2 - MP4_CHUNK_SIZE_ENTRY_BUFF_SIZE);
  947. _dwMP4ChunkOffset -= dwChunkSize;
  948. break;
  949. }
  950. _dwMP4ChunkSizeEntryIndex += MP4_CHUNK_SIZE_TABLE_BUFF_SIZE2;
  951. if (TRUE == bMP4NeedPack)
  952. dwChunkSizeAddr -= MP4_PACK_CHUNK_SIZE_ENTRY_BUFF_SIZE2;
  953. else
  954. dwChunkSizeAddr -= MP4_CHUNK_SIZE_ENTRY_BUFF_SIZE2;
  955. }
  956. #endif
  957. _mp4LoadPackTransferChunkSize(dwChunkSizeAddr, (DWORD*)&_dwMP4ChunkSizeBuff);
  958. #else
  959. dwChunkSizeAddr = MP4_CALC_ENTRY_ADDRESS(_dwMP4ChunkSizeStartAddr, MP4_CHUNK_SIZE_ENTRY_BUFF_SIZE, 0);
  960. wai_sem(SEM_DRAM_ID);
  961. I49_ReadDRAMData(dwChunkSizeAddr,(UINT16*)&_dwMP4ChunkSizeBuff, MP4_CHUNK_SIZE_ENTRY_BUFF_SIZE);
  962. sig_sem(SEM_DRAM_ID);
  963. #endif
  964. while (TRUE)
  965. {
  966. dwChunkSize = _dwMP4ChunkSizeBuff[MP4_CHUNK_SIZE_TABLE_BUFF_SIZE - (INT16)(_dwMP4ChunkSizeEntryIndex%MP4_CHUNK_SIZE_TABLE_BUFF_SIZE) - 1] >> 8;
  967. _dwMP4ChunkOffset += dwChunkSize;
  968. if (_dwMP4ChunkOffset > dwChunkSyncOffset)
  969. break;
  970. _dwMP4ChunkSizeEntryIndex++;
  971. if (_dwMP4ChunkSizeEntryIndex % MP4_CHUNK_SIZE_TABLE_BUFF_SIZE == 0)
  972. {
  973. #ifdef MP4_PACK_TRANSFER_CHUNK_SIZE
  974. if (TRUE == bMP4NeedPack)
  975. dwChunkSizeAddr -= MP4_PACK_CHUNK_SIZE_ENTRY_BUFF_SIZE;
  976. else
  977. dwChunkSizeAddr -= MP4_CHUNK_SIZE_ENTRY_BUFF_SIZE;
  978. _mp4LoadPackTransferChunkSize(dwChunkSizeAddr, (DWORD*)&_dwMP4ChunkSizeBuff);
  979. #else
  980. dwChunkSizeAddr -= MP4_CHUNK_SIZE_ENTRY_BUFF_SIZE;
  981. wai_sem(SEM_DRAM_ID);
  982. I49_ReadDRAMData(dwChunkSizeAddr,(UINT16*)&_dwMP4ChunkSizeBuff, MP4_CHUNK_SIZE_ENTRY_BUFF_SIZE);
  983. sig_sem(SEM_DRAM_ID);
  984. #endif
  985. }
  986. }
  987. _dwMP4ChunkOffset -= dwChunkSize;
  988. }
  989. else
  990. {
  991. _dwMP4ChunkOffset = _dwMP4LastChunkEndOffset; 
  992. _dwMP4ChunkSizeEntryIndex = _dwMP4ChunkSizeEntryTotal -1;
  993. #ifdef MP4_PACK_TRANSFER_CHUNK_SIZE
  994. if (TRUE == bMP4NeedPack)
  995. dwChunkSizeAddr = MP4_CALC_ENTRY_ADDRESS(_dwMP4ChunkSizeStartAddr, MP4_PACK_CHUNK_SIZE_ENTRY_BUFF_SIZE, 
  996. (_dwMP4ChunkSizeEntryIndex/MP4_CHUNK_SIZE_TABLE_BUFF_SIZE) );
  997. else
  998. dwChunkSizeAddr = MP4_CALC_ENTRY_ADDRESS(_dwMP4ChunkSizeStartAddr, MP4_CHUNK_SIZE_ENTRY_BUFF_SIZE, 
  999. (_dwMP4ChunkSizeEntryIndex/MP4_CHUNK_SIZE_TABLE_BUFF_SIZE) );
  1000. _mp4LoadPackTransferChunkSize(dwChunkSizeAddr, (DWORD*)&_dwMP4ChunkSizeBuff);
  1001. #else
  1002. dwChunkSizeAddr = MP4_CALC_ENTRY_ADDRESS(_dwMP4ChunkSizeStartAddr, MP4_CHUNK_SIZE_ENTRY_BUFF_SIZE, 
  1003. (_dwMP4ChunkSizeEntryIndex/MP4_CHUNK_SIZE_TABLE_BUFF_SIZE) );
  1004. wai_sem(SEM_DRAM_ID);
  1005. I49_ReadDRAMData(dwChunkSizeAddr,(UINT16*)&_dwMP4ChunkSizeBuff, MP4_CHUNK_SIZE_ENTRY_BUFF_SIZE);
  1006. sig_sem(SEM_DRAM_ID);
  1007. #endif
  1008. while (TRUE)
  1009. {
  1010. dwChunkSize = _dwMP4ChunkSizeBuff[MP4_CHUNK_SIZE_TABLE_BUFF_SIZE - (INT16)(_dwMP4ChunkSizeEntryIndex%MP4_CHUNK_SIZE_TABLE_BUFF_SIZE) - 1] >> 8;
  1011. _dwMP4ChunkOffset -= dwChunkSize;
  1012. if (_dwMP4ChunkOffset <= dwChunkSyncOffset)
  1013. break;
  1014. if (_dwMP4ChunkSizeEntryIndex % MP4_CHUNK_SIZE_TABLE_BUFF_SIZE == 0)
  1015. {
  1016. #ifdef MP4_PACK_TRANSFER_CHUNK_SIZE
  1017. if (TRUE == bMP4NeedPack)
  1018. dwChunkSizeAddr += MP4_PACK_CHUNK_SIZE_ENTRY_BUFF_SIZE;
  1019. else
  1020. dwChunkSizeAddr += MP4_CHUNK_SIZE_ENTRY_BUFF_SIZE;
  1021. #if 1
  1022. // Robin_0110_2005, reduce the seek time
  1023. while (TRUE)
  1024. {
  1025. dwChunkSize = _mp4CalculatePackTransferChunkSize(dwChunkSizeAddr, (DWORD*)&_MP4SharedBuff);
  1026. _dwMP4ChunkOffset -= dwChunkSize;
  1027. if (_dwMP4ChunkOffset <= dwChunkSyncOffset)
  1028. {
  1029. _dwMP4ChunkOffset += dwChunkSize;
  1030. break;
  1031. }
  1032. _dwMP4ChunkSizeEntryIndex -= MP4_CHUNK_SIZE_TABLE_BUFF_SIZE2;
  1033. if (TRUE == bMP4NeedPack)
  1034. dwChunkSizeAddr += MP4_PACK_CHUNK_SIZE_ENTRY_BUFF_SIZE2;
  1035. else
  1036. dwChunkSizeAddr += MP4_CHUNK_SIZE_ENTRY_BUFF_SIZE2;
  1037. }
  1038. #endif
  1039. _mp4LoadPackTransferChunkSize(dwChunkSizeAddr, (DWORD*)&_dwMP4ChunkSizeBuff);
  1040. #else
  1041. dwChunkSizeAddr += MP4_CHUNK_SIZE_ENTRY_BUFF_SIZE;
  1042. wai_sem(SEM_DRAM_ID);
  1043. I49_ReadDRAMData(dwChunkSizeAddr,(UINT16*)&_dwMP4ChunkSizeBuff, MP4_CHUNK_SIZE_ENTRY_BUFF_SIZE);
  1044. sig_sem(SEM_DRAM_ID);
  1045. #endif
  1046. }
  1047. _dwMP4ChunkSizeEntryIndex--;
  1048. }
  1049. }
  1050. #ifdef PRINTF_MP4_TRANSFER_CHUNK_SIZE
  1051. dwTransferChunkOffset = _dwMP4ChunkOffset;
  1052. #endif
  1053. // search the correspond subtitle sample count
  1054. if (_mpeg4SubtitleType == INTERNAL_SUBT || _mpeg4SubtitleType == INTERNAL_SUBP)
  1055. {
  1056. DWORD dwSubtitleSampleEntryAddr;
  1057. MP4SubtitleSampleEntry mp4SubtitleSampleEntry[MP4_SUBTITLE_SAMPLE_ENTRY_BUFF_SIZE];
  1058. _dwMP4SubtitleSampleCount = 0UL;
  1059. _dwMP4SubtitleSampleStartTime = 0UL;
  1060. sc_GetBytes(SC_MPEG4_SUBTITLE_SAMPLE_TABLE_ADDREX_BUFF_ADDR + (_mpeg4SubtitleCurrentDispIdx * SIZE_OF_MP4StreamSampleTableAddrEX_IN_DWORD),
  1061. 0,SIZE_OF_MP4StreamSampleTableAddrEX,(BYTE*)&mp4StreamSampleTableAddrEX);
  1062. _dwMP4SubtitleSampleAddr = mp4SyncEntryStartAddr;
  1063. for (_dwMP4SubtitleSampleCount=0;_dwMP4SubtitleSampleCount<mp4STSZEntryCount;_dwMP4SubtitleSampleCount++)
  1064. {
  1065. if (_dwMP4SubtitleSampleCount % MP4_SUBTITLE_SAMPLE_ENTRY_BUFF_SIZE == 0)
  1066. {
  1067. _dwMP4SubtitleSampleAddr -= MP4_SUBTITLE_SMAPLE_ENTRY_BUFF_SIZE;
  1068. wai_sem(SEM_DRAM_ID);
  1069. I49_ReadDRAMData(_dwMP4SubtitleSampleAddr,(UINT16*)&mp4SubtitleSampleEntry, MP4_SUBTITLE_SMAPLE_ENTRY_BUFF_SIZE);
  1070. sig_sem(SEM_DRAM_ID);
  1071. }
  1072. if (mp4SubtitleSampleEntry[MP4_SUBTITLE_SAMPLE_ENTRY_BUFF_SIZE - 1 - (_dwMP4SubtitleSampleCount % MP4_SUBTITLE_SAMPLE_ENTRY_BUFF_SIZE)].dwChunkOffset >= _dwMP4ChunkOffset)
  1073. break;
  1074. _dwMP4SubtitleSampleStartTime = mp4SubtitleSampleEntry[MP4_SUBTITLE_SAMPLE_ENTRY_BUFF_SIZE - 1 - (_dwMP4SubtitleSampleCount % MP4_SUBTITLE_SAMPLE_ENTRY_BUFF_SIZE)].dwSampleEndTime; // last sample
  1075. }
  1076. _dwMP4SubtitleSampleAddr += ((MP4_SUBTITLE_SAMPLE_ENTRY_BUFF_SIZE - 1 - (_dwMP4SubtitleSampleCount % MP4_SUBTITLE_SAMPLE_ENTRY_BUFF_SIZE)) * MP4_SUBTITLE_SMAPLE_ENTRY_SIZE);
  1077. _dwMP4SubtitleReadDRAMAddr = _dwMP4SubtitleWriteDRAMAddr = _mpeg4InternalSubtitleBufferStartAddr * 512UL;
  1078. if (_mpeg4SubtitleType == INTERNAL_SUBT)
  1079. mp4InitSubtitles();
  1080. }
  1081. }
  1082. static void _mp4TransferChunkSize(/*BOOL bFirst,*/ BOOL bWait)
  1083. {
  1084. DWORD  dwChunkSizeAddr;
  1085. DWORD  dwChunkSize;
  1086. DWORD  dwChunkSizeAndId;
  1087. BYTE chunkID;
  1088. BYTE preChunkID;
  1089. BOOL bFirstGetChunk;
  1090. WORD wTransferLength;
  1091. DWORD  mp4TransferChunkSizeBuff[MP4_TRANSFER_CHUNKSIZE_LENGTH];
  1092. // BOOL  bLastChunkIsNotUsed;
  1093. BOOL bTransferChunkSizeFlag;
  1094. bTransferChunkSizeFlag = DEC_AVI_GetDemuxSharedBit( MP4_TRANSFER_STATUS_OFFSET, MP4_TRANSFER_CHUNK_SIZE_BIT);
  1095. if(TRUE == bWait)
  1096. {
  1097. while (TRUE == bTransferChunkSizeFlag)
  1098. bTransferChunkSizeFlag = DEC_AVI_GetDemuxSharedBit( MP4_TRANSFER_STATUS_OFFSET, MP4_TRANSFER_CHUNK_SIZE_BIT);
  1099. }
  1100. else
  1101. {
  1102. if (TRUE == bTransferChunkSizeFlag)
  1103. return;
  1104. }
  1105.     preChunkID = MP4_NOT_USED_STREAM_ID;
  1106. chunkID = MP4_NOT_USED_STREAM_ID;
  1107. dwChunkSize = 0;
  1108. wTransferLength = 0;
  1109. // bLastChunkIsNotUsed = FALSE;
  1110. bFirstGetChunk = TRUE;
  1111. #ifdef PRINTF_MP4_TRANSFER_CHUNK_SIZE
  1112. {
  1113. dbg_printf(("ChunkSize Index : %lxn", _dwMP4ChunkSizeEntryIndex));
  1114. }
  1115. #endif
  1116. while (TRUE)
  1117. {
  1118. if (_dwMP4ChunkSizeEntryIndex > _dwMP4ChunkSizeEntryTotal)
  1119. break;
  1120. if (_dwMP4ChunkSizeEntryIndex == _dwMP4ChunkSizeEntryTotal)
  1121. {
  1122. mp4TransferChunkSizeBuff[wTransferLength++] = (((DWORD)preChunkID)<<24) + dwChunkSize;
  1123. _dwMP4ChunkSizeEntryIndex ++;
  1124. break;
  1125. }
  1126. dwChunkSizeAndId = _dwMP4ChunkSizeBuff[MP4_CHUNK_SIZE_TABLE_BUFF_SIZE - (INT16)(_dwMP4ChunkSizeEntryIndex%MP4_CHUNK_SIZE_TABLE_BUFF_SIZE) - 1];
  1127. preChunkID = chunkID;
  1128. chunkID = (BYTE)(dwChunkSizeAndId & 0xFF);
  1129. dwChunkSize += (dwChunkSizeAndId >> 8);
  1130. _dwMP4ChunkSizeEntryIndex++;
  1131. _dwMP4ChunkOffset += (dwChunkSizeAndId >> 8);
  1132. if (((chunkID == _mpeg4VideoStreamID) && (_dwMP4ChunkOffset <= _dwMP4VideoSyncOffset)) ||
  1133. ((chunkID == _mpeg4AudioStreamID) && (_dwMP4ChunkOffset <= _dwMP4AudioSyncOffset)) /*||
  1134. ((chunkID == _mpeg4SubtitleStreamID) && (_dwMP4ChunkOffset <= _dwMP4VideoSyncOffset))*/)
  1135. {
  1136. chunkID = MP4_NOT_USED_STREAM_ID;
  1137. }
  1138. if ((chunkID != _mpeg4VideoStreamID) && (chunkID != _mpeg4AudioStreamID) && (chunkID != _mpeg4SubtitleStreamID))
  1139. chunkID = MP4_NOT_USED_STREAM_ID;
  1140. if (FALSE == bFirstGetChunk)
  1141. {
  1142. if ((preChunkID != chunkID) || (dwChunkSize >= MP4_MAX_CHUNK_SIZE) || (_mpeg4VideoStreamID == NO_STREAM))
  1143. {
  1144. dwChunkSize -= (dwChunkSizeAndId >> 8);
  1145. mp4TransferChunkSizeBuff[wTransferLength++] = (((DWORD)preChunkID)<<24) + dwChunkSize;
  1146. //preChunkID = chunkID;
  1147. //dwChunkSize = (dwChunkSizeAndId >> 8);
  1148. _dwMP4ChunkSizeEntryIndex--;
  1149. _dwMP4ChunkOffset -= (dwChunkSizeAndId >> 8);
  1150. dwChunkSize = 0;
  1151. bFirstGetChunk = TRUE;
  1152. }
  1153. }
  1154. else
  1155. {
  1156. bFirstGetChunk = FALSE; 
  1157. }
  1158. if (_dwMP4ChunkSizeEntryIndex % MP4_CHUNK_SIZE_TABLE_BUFF_SIZE == 0)
  1159. {
  1160. #ifdef MP4_PACK_TRANSFER_CHUNK_SIZE
  1161. if (TRUE == bMP4NeedPack)
  1162. dwChunkSizeAddr = MP4_CALC_ENTRY_ADDRESS(_dwMP4ChunkSizeStartAddr, MP4_PACK_CHUNK_SIZE_ENTRY_BUFF_SIZE, 
  1163. (_dwMP4ChunkSizeEntryIndex/MP4_CHUNK_SIZE_TABLE_BUFF_SIZE));
  1164. else
  1165. dwChunkSizeAddr = MP4_CALC_ENTRY_ADDRESS(_dwMP4ChunkSizeStartAddr, MP4_CHUNK_SIZE_ENTRY_BUFF_SIZE, 
  1166. (_dwMP4ChunkSizeEntryIndex/MP4_CHUNK_SIZE_TABLE_BUFF_SIZE));
  1167. _mp4LoadPackTransferChunkSize(dwChunkSizeAddr, (DWORD*)&_dwMP4ChunkSizeBuff);
  1168. #else
  1169. dwChunkSizeAddr = MP4_CALC_ENTRY_ADDRESS(_dwMP4ChunkSizeStartAddr, MP4_CHUNK_SIZE_ENTRY_BUFF_SIZE, 
  1170. (_dwMP4ChunkSizeEntryIndex/MP4_CHUNK_SIZE_TABLE_BUFF_SIZE));
  1171. wai_sem(SEM_DRAM_ID);
  1172. I49_ReadDRAMData(dwChunkSizeAddr,(UINT16*)&_dwMP4ChunkSizeBuff, MP4_CHUNK_SIZE_ENTRY_BUFF_SIZE);
  1173. sig_sem(SEM_DRAM_ID);
  1174. #endif
  1175. }
  1176. if (wTransferLength >= MP4_TRANSFER_CHUNKSIZE_LENGTH)
  1177. break;
  1178. }
  1179. while (wTransferLength < MP4_TRANSFER_CHUNKSIZE_LENGTH)
  1180. mp4TransferChunkSizeBuff[wTransferLength++] = 0xFFFFFFFFUL;
  1181. #ifdef PRINTF_MP4_TRANSFER_CHUNK_SIZE
  1182. {
  1183. int i;
  1184. for (i=0;i<MP4_TRANSFER_CHUNKSIZE_LENGTH; i++)
  1185. {
  1186. dbg_printf(("Tansfer Chunk Offset: %8lx, Size: %8lx, Type: %2xn", dwTransferChunkOffset, mp4TransferChunkSizeBuff[i]&0xFFFFFFUL, mp4TransferChunkSizeBuff[i]>>24));
  1187. dwTransferChunkOffset += (mp4TransferChunkSizeBuff[i]&0xFFFFFFUL);
  1188. }
  1189. }
  1190. #endif
  1191. DEC_MP4_TransferChunkSize(wTransferLength,(DWORD*)&mp4TransferChunkSizeBuff);
  1192. return;
  1193. }
  1194. static void _mp4PrePlayProcessing(DWORD dwSamplingRate, UINT8 uiAudioSid,
  1195.    UINT8 uiAudioSIDDecoder, UINT8 uiVideoSid, BOOL bClipStart, BOOL bScan)
  1196. {
  1197. BYTE Temp[4];
  1198. // for clear ADP internal Buffer
  1199. AuxCache_GetBytes(_dwMPEG4ClipStartLBA, 0, 4, &Temp[0]);
  1200. // for clear ADP APP buffer
  1201. _mp4ClearAPPBuffer();
  1202. #ifdef MP4_TANSFER_CHUNKSIZE_BY_FIFO
  1203. DEC_MP4_ChunkSizeFifoInit();
  1204. #endif
  1205. prePlayProcessing(dwSamplingRate,  uiAudioSid, uiAudioSIDDecoder, uiVideoSid, bClipStart);
  1206. _mp4SetFirstSkipBytes(bScan);
  1207. return;
  1208. }
  1209. static void _mp4InitTransferChunkSize(BOOL bScan, DWORD dwVideoSampleSize )
  1210. {
  1211. if (FALSE == bScan)
  1212. {
  1213. _mp4GetChunkSizeEntryIndex(FALSE);
  1214. _mp4TransferChunkSize(/*TRUE,*/ TRUE);
  1215. _mp4TransferChunkSize(/*FALSE,*/ TRUE);
  1216. _mp4TransferChunkSize(/*FALSE,*/TRUE);
  1217. _mp4TransferChunkSize(/*FALSE,*/ TRUE);
  1218. _mp4TransferChunkSize(/*FALSE,*/TRUE);
  1219. _mp4TransferChunkSize(/*FALSE,*/TRUE);
  1220. _mp4TransferChunkSize(/*FALSE,*/TRUE);
  1221. _mp4TransferChunkSize(/*FALSE,*/TRUE);
  1222. DEC_MP4_UnsetFlashCardNotNeedCheck();
  1223. #ifdef MP4_TANSFER_CHUNKSIZE_BY_FIFO
  1224. _mp4TransferChunkSizeByFifo();
  1225. #endif
  1226. }
  1227. else
  1228. {
  1229. WORD wTransferLength = 0;
  1230. DWORD  mp4TransferChunkSizeBuff[MP4_TRANSFER_CHUNKSIZE_LENGTH];
  1231. mp4TransferChunkSizeBuff[wTransferLength++] = (((DWORD)_mpeg4VideoStreamID) << 24) + dwVideoSampleSize;
  1232. #ifdef SUPPORT_FLASH_CARD
  1233. if(IS_PLAYING_CARD)
  1234. {
  1235. DWORD  dwChunkSizeAndId;
  1236. BYTE chunkID;
  1237. DWORD dwChunkSize;
  1238. BOOL bFirstGetChunk = TRUE;
  1239. MP4VideoSyncEntry mp4VideoSyncEntry;
  1240. DWORD  dwMP4VideosyncEntryAddr;
  1241. DWORD  dwChunkSizeAddr;
  1242. UINT8 chunkCount = 0;
  1243. _mp4GetChunkSizeEntryIndex(TRUE);
  1244. while (TRUE)
  1245. {
  1246. if (_dwMP4ChunkSizeEntryIndex >= _dwMP4ChunkSizeEntryTotal)
  1247. break;
  1248. dwChunkSizeAndId = _dwMP4ChunkSizeBuff[MP4_CHUNK_SIZE_TABLE_BUFF_SIZE - (INT16)(_dwMP4ChunkSizeEntryIndex%MP4_CHUNK_SIZE_TABLE_BUFF_SIZE) - 1];
  1249. chunkID = (BYTE)(dwChunkSizeAndId & 0xFF);
  1250. dwChunkSize = (dwChunkSizeAndId >> 8);
  1251. _dwMP4ChunkSizeEntryIndex++;
  1252. if (chunkID != _mpeg4VideoStreamID)
  1253. chunkID = MP4_NOT_USED_STREAM_ID;
  1254. if (bFirstGetChunk)
  1255. {
  1256. dwMP4VideosyncEntryAddr = MP4_CALC_ENTRY_ADDRESS(MPEG4_PROCESSING_BUFF_ADDR, MP4_VIDEO_SYNC_ENTRY_SIZE, _ulMPEG4RequestedFrameIndex);
  1257. wai_sem(SEM_DRAM_ID);
  1258. I49_ReadDRAMData(dwMP4VideosyncEntryAddr,(UINT16*)&mp4VideoSyncEntry, MP4_VIDEO_SYNC_ENTRY_SIZE);
  1259. sig_sem(SEM_DRAM_ID);
  1260. dwChunkSize -= (mp4VideoSyncEntry.dwOffsetofChunk + mp4VideoSyncEntry.dwSyncSampleSize);
  1261. bFirstGetChunk = FALSE; 
  1262. }
  1263. if (dwChunkSize ==0)
  1264. continue;
  1265. mp4TransferChunkSizeBuff[wTransferLength++] = (((DWORD)chunkID)<<24) + dwChunkSize; // chunk id in MSB[31-24]
  1266. if (chunkID == _mpeg4VideoStreamID && chunkCount >2)
  1267. break;
  1268. chunkCount++;
  1269. if (_dwMP4ChunkSizeEntryIndex % MP4_CHUNK_SIZE_TABLE_BUFF_SIZE == 0)
  1270. {
  1271. #ifdef MP4_PACK_TRANSFER_CHUNK_SIZE
  1272. if (TRUE == bMP4NeedPack)
  1273. dwChunkSizeAddr = MP4_CALC_ENTRY_ADDRESS(_dwMP4ChunkSizeStartAddr, MP4_PACK_CHUNK_SIZE_ENTRY_BUFF_SIZE, 
  1274. (_dwMP4ChunkSizeEntryIndex/MP4_CHUNK_SIZE_TABLE_BUFF_SIZE));
  1275. else
  1276. dwChunkSizeAddr = MP4_CALC_ENTRY_ADDRESS(_dwMP4ChunkSizeStartAddr, MP4_CHUNK_SIZE_ENTRY_BUFF_SIZE, 
  1277. (_dwMP4ChunkSizeEntryIndex/MP4_CHUNK_SIZE_TABLE_BUFF_SIZE));
  1278. _mp4LoadPackTransferChunkSize(dwChunkSizeAddr, (DWORD*)&_dwMP4ChunkSizeBuff);
  1279. #else
  1280. dwChunkSizeAddr = MP4_CALC_ENTRY_ADDRESS(_dwMP4ChunkSizeStartAddr, MP4_CHUNK_SIZE_ENTRY_BUFF_SIZE, 
  1281. (_dwMP4ChunkSizeEntryIndex/MP4_CHUNK_SIZE_TABLE_BUFF_SIZE));
  1282. wai_sem(SEM_DRAM_ID);
  1283. I49_ReadDRAMData(dwChunkSizeAddr,(UINT16*)&_dwMP4ChunkSizeBuff, MP4_CHUNK_SIZE_ENTRY_BUFF_SIZE);
  1284. sig_sem(SEM_DRAM_ID);
  1285. #endif
  1286. }
  1287. if (wTransferLength >= MP4_TRANSFER_CHUNKSIZE_LENGTH)
  1288. break;
  1289. }
  1290. }
  1291. else
  1292. #endif
  1293. mp4TransferChunkSizeBuff[wTransferLength++] = 0xFF000000UL + 16*2048UL;
  1294. while (wTransferLength < MP4_TRANSFER_CHUNKSIZE_LENGTH)
  1295. mp4TransferChunkSizeBuff[wTransferLength++] = 0xFFFFFFFFUL; 
  1296. DEC_MP4_TransferChunkSize(wTransferLength,(DWORD*)&mp4TransferChunkSizeBuff);
  1297. DEC_MP4_SetFlashCardNotNeedCheck();
  1298. }
  1299. }
  1300. /*
  1301. static void _mp4GetTransferTimes()
  1302. {
  1303. MP4StreamSampleTableAddrEX mp4StreamSampleTableAddrEX;
  1304. DWORD dwSamplesPre200ms;
  1305. _wMP4TransferChunkSizeTimes = 0;
  1306. sc_GetBytes(SC_MPEG4_VIDEO_SAMPLE_TABLE_ADDREX_BUFF_ADDR,
  1307. 0,SIZE_OF_MP4StreamSampleTableAddrEX,(BYTE*)&mp4StreamSampleTableAddrEX);
  1308. dwSamplesPre200ms = _mpeg4VideoRate / (_mpeg4VideoScale * MP4_TRANSFER_CHUNKSIZE_TIMES_IN_SEC);  
  1309. dwSamplesPre200ms++;
  1310. _wMP4TransferChunkSizeTimes += (WORD)((dwSamplesPre200ms * mp4STCOEntryCount) / mp4STSZEntryCount);
  1311. _wMP4TransferChunkSizeTimes ++;
  1312. sc_GetBytes(SC_MPEG4_AUDIO_SAMPLE_TABLE_ADDREX_BUFF_ADDR + (_mpeg4AudioCurrentDispIdx * SIZE_OF_MP4StreamSampleTableAddrEX_IN_DWORD),
  1313. 0,SIZE_OF_MP4StreamSampleTableAddrEX,(BYTE*)&mp4StreamSampleTableAddrEX);
  1314. dwSamplesPre200ms = _mpeg4AudioRate / (_mpeg4AudioScale * MP4_TRANSFER_CHUNKSIZE_TIMES_IN_SEC);  
  1315. dwSamplesPre200ms++;
  1316. _wMP4TransferChunkSizeTimes += (WORD)((dwSamplesPre200ms * mp4STCOEntryCount) / mp4STSZEntryCount);
  1317. _wMP4TransferChunkSizeTimes ++;
  1318. }
  1319. */
  1320. static BOOL _mp4Scan(INT8 iIndexIncrement, BOOL bContinue)
  1321. {
  1322. DWORD dwStartLBA;
  1323. WORD wClipStartOffset;
  1324. WORD wClipEndOffset;
  1325. ULONG ulBlocksCnt;
  1326. MP4VideoSyncEntry mp4VideoSyncEntry;
  1327. DWORD dwVideoSyncSampleNum, dwSyncSampleOffset;
  1328. dbg_printf(("_mp4Scan()n"));
  1329. /* If we are not yet in scan mode, calculate the entry in the index corresponding to the current time */
  1330. if (FALSE == bContinue)
  1331. {
  1332.   if(FALSE == _mp4GetAdjacentIFrames(_uiMPEG4StartTime,&dwVideoSyncSampleNum, &dwSyncSampleOffset))
  1333. {
  1334. dbg_printf(("WARNNING: _mp4Scan() Failed [1]n"));
  1335. return FALSE;
  1336. }
  1337. }
  1338. /* Check whether we scanned the whole idx table */
  1339. if ( (((INT32)_ulMPEG4RequestedFrameIndex + (INT32)iIndexIncrement) >= _uiMPEG4NextIndexEntry) ||
  1340.  (((INT32)_ulMPEG4RequestedFrameIndex + (INT32)iIndexIncrement) < 0) )
  1341. {
  1342. DEC_AVI_EnableFinishCB(FALSE);
  1343. ie_send(IE_CORE_CDNAV_FINISHED);
  1344. return TRUE;
  1345. }
  1346. /* Calculate the next entry to be played */
  1347. _ulMPEG4RequestedFrameIndex = (UINT32)((INT32)_ulMPEG4RequestedFrameIndex + (INT32)iIndexIncrement);
  1348. wai_sem(SEM_DRAM_ID);
  1349. I49_ReadDRAMData(MP4_CALC_ENTRY_ADDRESS(MPEG4_PROCESSING_BUFF_ADDR, (sizeof(MP4VideoSyncEntry)/2), _ulMPEG4RequestedFrameIndex),
  1350.  (UINT16*)&mp4VideoSyncEntry, sizeof(MP4VideoSyncEntry)/2);
  1351. sig_sem(SEM_DRAM_ID);
  1352. tr_printf(("nVideo Sync SampleNumber: %lx, ChunkOffset: %lx, OffsetOfChunk: %lx, SampleSize %lxnn",
  1353. mp4VideoSyncEntry.dwSyncSampleNumber, mp4VideoSyncEntry.dwSyncChunkOffset, mp4VideoSyncEntry.dwOffsetofChunk, mp4VideoSyncEntry.dwSyncSampleSize));
  1354. /* Calculate the playback addresses */
  1355. dwStartLBA = _dwMPEG4ClipStartLBA + ((mp4VideoSyncEntry.dwSyncChunkOffset + mp4VideoSyncEntry.dwOffsetofChunk)>> 11);
  1356. wClipStartOffset = (WORD)( (mp4VideoSyncEntry.dwSyncChunkOffset + mp4VideoSyncEntry.dwOffsetofChunk) % LOGICAL_BLOCK_SIZE);
  1357. ulBlocksCnt = (wClipStartOffset + mp4VideoSyncEntry.dwSyncSampleSize + LOGICAL_BLOCK_SIZE - 1) / LOGICAL_BLOCK_SIZE;
  1358. ulBlocksCnt += 16;
  1359. wClipEndOffset = (WORD)((wClipStartOffset + mp4VideoSyncEntry.dwSyncSampleSize) % LOGICAL_BLOCK_SIZE);
  1360.     if (0 == wClipEndOffset)
  1361.     {
  1362.        wClipEndOffset = 2048;
  1363.     }
  1364. /* Calculate the start time */
  1365. _uiMPEG4StartTime = caclTimeOfFrame(mp4VideoSyncEntry.dwSyncSampleNumber ,_mpeg4VideoRate, _mpeg4VideoScale);
  1366. if (FALSE == bContinue)
  1367. {
  1368. /* Scanning just started, re initialize the decoder */
  1369. DWORD dwSampleRate;
  1370. UINT8 uiAudioSID;
  1371. UINT8 uiAudioSIDDecoder;
  1372. determineAudioInfo(&uiAudioSID, &uiAudioSIDDecoder, &dwSampleRate);
  1373. _mp4PrePlayProcessing(dwSampleRate, NO_STREAM, NO_STREAM, 0xFF, FALSE, TRUE);
  1374. API_ADPSetMp3_Throw_Out_Cntr(0);
  1375. /* Signal to the DVP the decision */
  1376. DEC_AVI_SetIOnly(TRUE);
  1377. DEC_AVI_SetIPOnly(FALSE);
  1378. DEC_AVI_ResetDemuxStatus();
  1379. DEC_AVI_SetStartVideoChunks(mp4VideoSyncEntry.dwSyncSampleNumber);
  1380. /* The order of the calls to the functions should not be changed! */
  1381. DEC_AVI_SetPlaybackParams(wClipStartOffset, wClipEndOffset, _uiMPEG4StartTime, 0, 0);
  1382. PE_Clips_SetPlaybackRange(dwStartLBA, ulBlocksCnt, UNLIMITED_FILE_SIZE);
  1383. _mp4InitTransferChunkSize(TRUE, mp4VideoSyncEntry.dwSyncSampleSize);
  1384. if (!PE_Clips_Playback_Sectors(DRVCF_CDSPEED_1X | DRVF_PLAY_CD_AV_DATA, dwStartLBA, ulBlocksCnt))
  1385. {
  1386. dbg_printf(("FATAL: _asfScan() Failed [2]n"));
  1387. return FALSE;
  1388. }
  1389. }
  1390. else
  1391. {
  1392. #ifdef SUPPORT_FLASH_CARD
  1393. if(IS_PLAYING_CARD)
  1394. {
  1395. DWORD dwSampleRate;
  1396. UINT8 uiAudioSID;
  1397. UINT8 uiAudioSIDDecoder;
  1398. determineAudioInfo(&uiAudioSID, &uiAudioSIDDecoder, &dwSampleRate);
  1399. prePlayProcessing(dwSampleRate,  NO_STREAM, NO_STREAM, 0xFF, FALSE);
  1400. _mp4SetFirstSkipBytes(TRUE);
  1401. }
  1402. else
  1403. #endif
  1404. /* Stopping the current drive playback */
  1405. drv_abort_play();
  1406. /* Signal to the DVP the decision */
  1407. DEC_AVI_SetIOnly(TRUE);
  1408. DEC_AVI_SetIPOnly(FALSE);
  1409. DEC_AVI_ResetDemuxStatus();
  1410. DEC_AVI_SetStartVideoChunks(mp4VideoSyncEntry.dwSyncSampleNumber);
  1411. /* Set the next playback request to the decoder and to the drive */
  1412. DEC_AVI_SetPlaybackParams(wClipStartOffset, wClipEndOffset, _uiMPEG4StartTime, 0, 0);
  1413. PE_Clips_SetPlaybackRange(dwStartLBA, ulBlocksCnt, UNLIMITED_FILE_SIZE);
  1414. _mp4InitTransferChunkSize(TRUE, mp4VideoSyncEntry.dwSyncSampleSize);
  1415. if (!PE_Clips_Playback_Sectors(DRVCF_CDSPEED_1X | DRVF_PLAY_CD_AV_DATA, dwStartLBA, ulBlocksCnt))
  1416. {
  1417. dbg_printf(("WARNNING: _asfScan() Failed [3]n"));
  1418. return FALSE;
  1419. }
  1420. }
  1421. /* Install call back from the decoder */
  1422. DEC_AVI_EnableFinishCB(TRUE);
  1423. return TRUE;
  1424. }
  1425. static void _mp4ClearAPPBuffer(void)
  1426. {
  1427. #define APP_ACC_OFFSET 0x1800 // in word
  1428. #define APP_ACC_SIZE 0xC800 // in word
  1429. DWORD dwAppStartAddr = REAL_APP_START_ADDR + APP_ACC_OFFSET;
  1430. DWORD dwAppEndAddr;
  1431. WORD ClearBuf[32] = {0};
  1432. dwAppEndAddr = dwAppStartAddr + APP_ACC_SIZE;
  1433. while(dwAppStartAddr < dwAppEndAddr)
  1434. {
  1435. wai_sem(SEM_DRAM_ID);
  1436. I49_WriteDRAMData(dwAppStartAddr,(UINT16*)(&ClearBuf[0]), 32);
  1437. sig_sem(SEM_DRAM_ID);
  1438. dwAppStartAddr += 32;
  1439. }
  1440. }
  1441. static void _mp4ChapterProcess(DWORD dwStartAddr)
  1442. {
  1443. MPEG4ChapterEntry mpeg4ChapterEntry;
  1444. DWORD dwEntryCount;
  1445. UINT16 uiChapterNameOffset;
  1446. UINT16 uiChapterNameLen;
  1447. UINT16 uiUnicodeNameLen;
  1448. QWORD qwTime;
  1449. UINT32 ulTime;
  1450. BYTE  TempBuff[10];
  1451. WORD unicodeBuff[10];
  1452. WORD wLastUnicode;
  1453. DWORD dwOffset;
  1454. WORD wVersion;
  1455. DWORD dwChapterDRAMAddr;
  1456. if (_bMPEG4IsIndexProcessed == TRUE)
  1457. return;
  1458. _mpeg4ChapterAvailableNum = 0;
  1459. if (0UL == _dwMP4ChapterOffset)
  1460. return;
  1461. else
  1462. dwOffset = _dwMP4ChapterOffset;
  1463. if (FALSE == AuxCache_GetBytes(dwStartAddr, dwOffset, (WORD)9, &TempBuff[0]))
  1464. {
  1465. dbg_printf(("_mp4StreamsInfoProcessing(): AuxCache_GetBytes() Fail[3] n"));
  1466. return;
  1467. }
  1468. dwOffset += 9;
  1469. wVersion = (WORD)TempBuff[0];
  1470. dwEntryCount = _toBe32(&TempBuff[5]);
  1471. // _mpeg4ChapterAvailableNum = dwEntryCount;
  1472. _dwMP4ChapterDRAMStartAddr = _dwMPEG4ProcessingEndAddr;
  1473. dwChapterDRAMAddr = _dwMP4ChapterDRAMStartAddr;
  1474. if (wVersion == 1)
  1475. uiChapterNameOffset = 9;
  1476. else
  1477. uiChapterNameOffset = 5;
  1478. while(dwEntryCount--)
  1479. {
  1480. if (FALSE == AuxCache_GetBytes(dwStartAddr, dwOffset, uiChapterNameOffset, &TempBuff[0]))
  1481. {
  1482. dbg_printf(("_mp4StreamsInfoProcessing(): AuxCache_GetBytes() Fail[3] n"));
  1483. return;
  1484. }
  1485. dwOffset += uiChapterNameOffset;
  1486. if (wVersion == 1)
  1487. {
  1488. qwTime[1] = _toBe32(&TempBuff[0]);
  1489. qwTime[0] = _toBe32(&TempBuff[4]);
  1490. ulTime = qwTimeDiv10000(qwTime); // in ms
  1491. ulTime /= 1000UL;
  1492. }
  1493. else
  1494. {
  1495. ulTime = _toBe32(&TempBuff[0]);
  1496. ulTime /= 10000000UL;
  1497. }
  1498. mpeg4ChapterEntry.uiChapterTime = (WORD)ulTime;
  1499. uiChapterNameLen = TempBuff[uiChapterNameOffset-1];
  1500. uiUnicodeNameLen = 0;
  1501. wLastUnicode = 0;
  1502. while (uiChapterNameLen > 0)
  1503. {
  1504. UINT16 uiBufferSize;
  1505. UINT16 uiUnicodeBufferSize;
  1506. UINT16 uiUnicodeBufferOffset;
  1507. uiBufferSize = min(uiChapterNameLen, 10);
  1508. if (FALSE == AuxCache_GetBytes(dwStartAddr, dwOffset, uiChapterNameOffset, &TempBuff[0]))
  1509. {
  1510. dbg_printf(("_mp4StreamsInfoProcessing(): AuxCache_GetBytes() Fail[3] n"));
  1511. return;
  1512. }
  1513. uiUnicodeBufferSize =0;
  1514. UTF8ToUnicode(TempBuff, unicodeBuff, uiBufferSize, &wLastUnicode, &uiUnicodeBufferSize);
  1515.             dwOffset += uiBufferSize;
  1516.             uiChapterNameLen -= uiBufferSize;
  1517.             
  1518. uiUnicodeBufferOffset = 0;
  1519. while(uiUnicodeBufferSize--)
  1520. {
  1521. mpeg4ChapterEntry.wChapterName[uiUnicodeNameLen++] = unicodeBuff[uiUnicodeBufferOffset++];
  1522. if (uiUnicodeNameLen>=(MPEG4_CHAPTER_NAME_LENGTH-2))
  1523. break;
  1524. }
  1525. }
  1526. mpeg4ChapterEntry.wChapterName[uiUnicodeNameLen] = 0; // end flag
  1527. // store chapter entry
  1528. dwChapterDRAMAddr -= (sizeof(MPEG4ChapterEntry)/2);
  1529. wai_sem(SEM_DRAM_ID);
  1530. I49_WriteDRAMData(dwChapterDRAMAddr,(UINT16*)&mpeg4ChapterEntry, (sizeof(MPEG4ChapterEntry)/2));
  1531. sig_sem(SEM_DRAM_ID);
  1532. _mpeg4ChapterAvailableNum ++;
  1533. }
  1534. _dwMPEG4ProcessingEndAddr = dwChapterDRAMAddr;
  1535. _dwMPEG4ProcessingEndAddr = (_dwMPEG4ProcessingEndAddr>>9)<<9;
  1536. dbg_printf(("MP4 Chapter Number: %dn", _mpeg4ChapterAvailableNum));
  1537. }
  1538. static void _mp4ChapterInit(void)
  1539. {
  1540. DWORD dwDRAMAddr;
  1541. MPEG4ChapterEntry mpeg4ChapterEntry;
  1542. _uiMP4ChapterStartTime =0;
  1543. _uiMP4ChapterEndTime = 0;
  1544. _mpeg4ChapterCurrentDispIdx = 0;
  1545. if (_mpeg4ChapterAvailableNum <= 1)
  1546. {
  1547. _uiMP4ChapterEndTime = 0xFFFFU;
  1548. return;
  1549. }
  1550. dwDRAMAddr = _dwMP4ChapterDRAMStartAddr - ((_mpeg4ChapterCurrentDispIdx+1) * sizeof(MPEG4ChapterEntry)/2);
  1551. wai_sem(SEM_DRAM_ID);
  1552. I49_ReadDRAMData(dwDRAMAddr,(UINT16*)&mpeg4ChapterEntry, (sizeof(MPEG4ChapterEntry)/2));
  1553. sig_sem(SEM_DRAM_ID);
  1554. _uiMP4ChapterStartTime = mpeg4ChapterEntry.uiChapterTime;
  1555. if (_mpeg4ChapterCurrentDispIdx < (_mpeg4ChapterAvailableNum -1))
  1556. {
  1557. dwDRAMAddr -= (sizeof(MPEG4ChapterEntry)/2);
  1558. wai_sem(SEM_DRAM_ID);
  1559. I49_ReadDRAMData(dwDRAMAddr,(UINT16*)&mpeg4ChapterEntry, (sizeof(MPEG4ChapterEntry)/2));
  1560. sig_sem(SEM_DRAM_ID);
  1561. _uiMP4ChapterEndTime = mpeg4ChapterEntry.uiChapterTime;
  1562. }
  1563. else
  1564. {
  1565. _uiMP4ChapterEndTime = 0xFFFFU;
  1566. }
  1567. }
  1568. static void _mp4ChapterRefresh(void)
  1569. {
  1570. DWORD dwDRAMAddr;
  1571. MPEG4ChapterEntry mpeg4ChapterEntry;
  1572. if (_uiMPEG4StartTime > _uiMP4ChapterEndTime)
  1573. {
  1574. _mpeg4ChapterCurrentDispIdx ++;
  1575. if (_mpeg4ChapterCurrentDispIdx < (_mpeg4ChapterAvailableNum -1))
  1576. {
  1577. dwDRAMAddr = _dwMP4ChapterDRAMStartAddr - ((_mpeg4ChapterCurrentDispIdx+2) * sizeof(MPEG4ChapterEntry)/2);
  1578. wai_sem(SEM_DRAM_ID);
  1579. I49_ReadDRAMData(dwDRAMAddr,(UINT16*)&mpeg4ChapterEntry, (sizeof(MPEG4ChapterEntry)/2));
  1580. sig_sem(SEM_DRAM_ID);
  1581. _uiMP4ChapterStartTime = _uiMP4ChapterEndTime;
  1582. _uiMP4ChapterEndTime = mpeg4ChapterEntry.uiChapterTime;
  1583. }
  1584. else
  1585. {
  1586. _uiMP4ChapterStartTime = _uiMP4ChapterEndTime;
  1587. _uiMP4ChapterEndTime = 0xFFFFU;
  1588. }
  1589. }
  1590. if ((_uiMPEG4StartTime+1) < _uiMP4ChapterStartTime)
  1591. {
  1592. if (_mpeg4ChapterCurrentDispIdx > 0)
  1593. {
  1594. _mpeg4ChapterCurrentDispIdx --;
  1595. dwDRAMAddr = _dwMP4ChapterDRAMStartAddr - ((_mpeg4ChapterCurrentDispIdx+1) * sizeof(MPEG4ChapterEntry)/2);
  1596. wai_sem(SEM_DRAM_ID);
  1597. I49_ReadDRAMData(dwDRAMAddr,(UINT16*)&mpeg4ChapterEntry, (sizeof(MPEG4ChapterEntry)/2));
  1598. sig_sem(SEM_DRAM_ID);
  1599. _uiMP4ChapterEndTime = _uiMP4ChapterStartTime;
  1600. _uiMP4ChapterStartTime = mpeg4ChapterEntry.uiChapterTime;
  1601. }
  1602. else
  1603. {
  1604. // _uiMP4ChapterEndTime = _uiMP4ChapterStartTime;
  1605. _uiMP4ChapterStartTime = 0;
  1606. }
  1607. }
  1608. }
  1609. #ifdef PATCH_VIDEO_NOT_B
  1610. ///////////////////////////////////////////////////////////////////////////
  1611. // Function name : _detectBVOP
  1612. // Purpose : Detect if B-VOP exist
  1613. // Input Parameters : 
  1614. // Return type : if B-VOP exist, return TRUE. if not exist, return FALSE
  1615. // Description :
  1616. ///////////////////////////////////////////////////////////////////////////
  1617. static BOOL _mp4DetectBVOP(void)
  1618. {
  1619. //DWORD dwStartLBA,dwClipStartOffset;
  1620. //DWORD pdwOffset;
  1621. //BYTE videoStreamID1[FOURCC_FIELD_LENGTH], videoStreamID2[FOURCC_FIELD_LENGTH];
  1622. BYTE videoHeaderBuff[64]; // 64 is enough
  1623. WORD wVideoHeaderSize;
  1624. BYTE videoObjectType;
  1625. int i,j;
  1626. if (_mpeg4VideoCodec== DIVX_3_11 ||
  1627. _mpeg4VideoCodec == DIVX_4_12 ||
  1628. _mpeg4VideoCodec == MP43 ||
  1629. _mpeg4VideoCodec == DIVX_UNKNOWN)
  1630. {
  1631. dbg_printf(("Video isn't B encoded.n"));
  1632. return FALSE;
  1633. }
  1634. wVideoHeaderSize = 64;
  1635. if (_mpeg4VideoHeaderDataLength > 0) // always in MP4
  1636. {
  1637. wVideoHeaderSize = min(wVideoHeaderSize,MPEG4_VIDEO_HEADER_CACHE_SIZE);
  1638. wai_sem(SEM_DRAM_ID);
  1639. I49_ReadDRAMData(SC_MPEG4_VIDEO_HEADER_DATA_ADDR, &videoHeaderBuff, wVideoHeaderSize);
  1640. sig_sem(SEM_DRAM_ID);
  1641. }
  1642. else
  1643. {
  1644. dbg_printf(("Video header data is in the moive data.n"));
  1645. return FALSE;
  1646. }
  1647. for (i=0; i<(wVideoHeaderSize -4);i++)
  1648. {
  1649. if(videoHeaderBuff[i] != 0)
  1650. continue;
  1651. if(videoHeaderBuff[i+1] != 0)
  1652. continue;
  1653. if(videoHeaderBuff[i+2] == 1)
  1654. {
  1655. if ((videoHeaderBuff[i+3] >= 20) && (videoHeaderBuff[i+3] <= 0x2F)) // video obejct layer start code
  1656. {
  1657. break;
  1658. }
  1659. }
  1660. }
  1661. if (i >= (wVideoHeaderSize -4))
  1662. return FALSE;
  1663. i += 4;
  1664. j=0;
  1665. j+=1;// random_accessible_vol
  1666. videoObjectType = (videoHeaderBuff[i+(j+1)/8]<<1) + (videoHeaderBuff[i+1+(j+1)/8]>>7);
  1667. dbg_printf(("Video object 0x%xn",videoObjectType));
  1668. j+=8;//video_object_type_indication
  1669. if ((videoHeaderBuff[i+(j+1)/8] >> (7-(j%8)) & 0x1) == 0x1)
  1670. j+=7;
  1671. j+=1;
  1672. if ((videoHeaderBuff[i+(j+1)/8] >> (7-4 -(j%8)) & 0xF) == 0xF) // 
  1673. j+=16;
  1674. j+=4;
  1675. if ((videoHeaderBuff[i+(j+1)/8] >> (7-(j%8)) & 0x1) == 0x1)
  1676. {
  1677. j+=1;
  1678. j+=2;
  1679. if ((videoHeaderBuff[i+(j+1)/8] >> (7-(j%8)) & 0x1) == 0x1) // low delay
  1680. {
  1681. dbg_printf(("Video isn't B encoded.n"));
  1682. return FALSE;
  1683. }
  1684. else
  1685. return TRUE;
  1686. }
  1687. else
  1688. {
  1689. if(videoObjectType == 0x01) // simple 
  1690. return FALSE;
  1691. else if (videoObjectType == 0x11) // advanced simple
  1692. return TRUE;
  1693. else
  1694. return FALSE;
  1695. }
  1696. }
  1697. #endif
  1698. /////////////////////////////////////////////////////////////////////////////
  1699. // Public Services
  1700. BOOL MP4Clip_isKindOf(LPCWSTR i_pszFilename)
  1701. {
  1702. return GenericClip_isKindOf(i_pszFilename, CLIP_VALID_EXTENSIONS(MP4));
  1703. }
  1704. void MP4Clip_construct(struct Clip_TAG *o_pThis, const FindData *i_pFileInfo)
  1705. {
  1706. GenericClip_construct(o_pThis, i_pFileInfo);
  1707.    o_pThis->m_pConstAttr = &CLIP_CONST_ATTR(MP4);
  1708. }
  1709. #pragma argsused
  1710. BOOL MP4Clip_getExtendedInfo(const struct Clip_TAG *i_pThis, 
  1711.  void *o_pExtInfoContainer)
  1712. {
  1713. return FALSE;
  1714. }
  1715. #pragma argsused
  1716. BOOL MP4Clip_play(Clip *i_pThis, const ClipMarker *i_pResumeMarker, BOOL bCacheOnly) 
  1717. DWORD  dwClipStartAddr = (i_pThis->m_cfiInfo).dwFileLocation, dwStartLBA;
  1718. WORD  wClipStartOffset;
  1719. WORD  wClipEndOffset;
  1720. ULONG  ulBlocksCnt;
  1721. UINT8  uiAudioSID, uiAudioSIDDecoder;
  1722. DWORD  dwSamplingRate;
  1723. DWORD dwMdatSize;
  1724. DWORD dwVideoSyncSampleNum, dwSyncSampleOffset;
  1725. UINT32  ulStartTime1, ulStartTime2;
  1726. UINT32 ulEndTime1, ulEndTime2;
  1727. dbg_printf(("Playing MP4 filen"));
  1728. Logo_selectSource(eFrame);
  1729. #if defined(NO_AUTO_PLAY_FOR_CLIPS) || defined(NO_AUTO_PLAY_ONLY_FOR_DVIX)
  1730. if (g_patch_4_auto_play)
  1731. {
  1732. g_patch_4_auto_play = FALSE;
  1733. return TRUE;
  1734. }
  1735. #endif
  1736. _uiMPEG4TotalDVPIdleTime = 0;
  1737. /* Check if the ASF info should be acquired */
  1738. if (NULL == i_pResumeMarker)
  1739. {
  1740. _bMPEG4PauseToSlow = FALSE;
  1741. _mpeg4SubtitleCurrentDispIdx = 0;
  1742. _mpeg4AudioCurrentDispIdx = 0;
  1743. _mpeg4ChapterCurrentDispIdx = 0;
  1744. change_pallet = TRUE;
  1745. _bMPEG4WasClockEnabled = FALSE;
  1746. if (_uiMPEG4ProcessedFileAddr != dwClipStartAddr)        //Don't process index if already processed.
  1747. _bMPEG4IsIndexProcessed = FALSE;
  1748. _iMPEG4CurrentScanningMode = 0;
  1749. _uiMPEG4NumOfDecodedChunksMemory = 0;
  1750. _bMPEG4TrickModeOn = TRUE;
  1751. _uiMPEG4StartTime = 0;
  1752. // _dwMPEG4ProcessingEndAddr = MPEG4_PROCESSING_BUFF_ADDR;
  1753. _ulMPEG4RequestedFrameIndex = 0UL;
  1754. // Clear shared RAM offsets that will be used 
  1755. DEC_AVI_ClearSharedOffset(0); 
  1756. DEC_AVI_ClearSharedOffset(1); 
  1757. // RB_1124_2004, add "mpeg4 loading..." display 
  1758. ie_send(IE_UI_MPEG4_LOADING_START);
  1759. ulStartTime2 = ulStartTime1 = (gen_timer()/1000UL);
  1760. if (FALSE == _mp4InfoProcessing(dwClipStartAddr,(i_pThis->m_cfiInfo).cbFileSize)) 
  1761. {
  1762. Logo_selectSource(eStartup);
  1763. Logo_display();
  1764. ie_send(IE_UI_CLIPS_CLEAR_UI);
  1765. // Robin_0125_2005, display more info
  1766. if (bMP4DRMDisable)
  1767. core_report_error( IE_UI_REPORT_ERROR, (void *) CLIPSNAV_ERR_MP4_DRMDISABLE_UOP );
  1768. else if (bMP4UnSupportProfile)
  1769. core_report_error( IE_UI_REPORT_ERROR, (void *) CLIPSNAV_ERR_MP4_UNSUPPORTPROFILE_UOP );
  1770. else
  1771. core_report_error( IE_UI_REPORT_ERROR, (void *) CLIPSNAV_ERR_WRONGFILE_UOP );
  1772. tr_printf(("FATAL: MP4Clip_play() Failed [1]n"));
  1773. usleep(300000UL);  // ensure UI accept the event
  1774. // <<< Stivenz_0223_2005: If current chapter is unsupported then goto next.
  1775. #ifdef D_MP4_SKIP_UNSUPPORTED_CHAPTER
  1776. DEC_CacheInit();  /* should clear the data which was cached by last unsupport chapter*/
  1777. #endif
  1778. return FALSE;
  1779. }
  1780. ulEndTime1 = (gen_timer()/1000UL);
  1781. tr_printf(("_mp4InfoProcessing() total time : %ld msecn", ulEndTime1-ulStartTime1));
  1782. // if (NO_STREAM == _mpeg4VideoStreamID)
  1783. // {
  1784. // tr_printf(("FATAL: MP4Clip_play() Failed [2]n"));
  1785. // return FALSE;
  1786. // }
  1787. ie_send(IE_UI_MPEG4_LOADING_START);
  1788. ulStartTime1 = (gen_timer()/1000UL);
  1789. if (FALSE == _mp4SampleTableProcessing(dwClipStartAddr))
  1790. {
  1791. tr_printf(("MP4Clip_play(): _mp4SampleTableProcessing() Fail[] n"));
  1792. ie_send(IE_UI_CLIPS_CLEAR_UI);
  1793. return FALSE;
  1794. }
  1795. ulEndTime1 = (gen_timer()/1000UL);
  1796. tr_printf(("_mp4SampleTableProcessing() total time : %ld msecn",ulEndTime1-ulStartTime1));
  1797. // _bMPEG4TrickModeOn = TRUE;
  1798. ie_send(IE_UI_MPEG4_LOADING_START);
  1799. ulStartTime1 = (gen_timer()/1000UL);
  1800. if (FALSE == _mp4ChunkSizeProcessing())
  1801. {
  1802. tr_printf(("MP4Clip_play(): _mp4ChunkSizeProcessing() Fail[] n"));
  1803. ie_send(IE_UI_CLIPS_CLEAR_UI);
  1804. return FALSE;
  1805. }
  1806. ulEndTime1 = (gen_timer()/1000UL);
  1807. tr_printf(("_mp4ChunkSizeProcessing() total time : %ld msecn",ulEndTime1-ulStartTime1));
  1808. _mp4ChapterProcess(dwClipStartAddr);
  1809. #ifdef USE_AUX_SUBTITLES 
  1810. if (_bMPEG4IsIndexProcessed == FALSE)
  1811. _mpeg4ExternalSubtitleAddr = _dwMPEG4ProcessingEndAddr;
  1812. #endif
  1813. _uiMPEG4ProcessedFileAddr = dwClipStartAddr;
  1814. _bMPEG4IsIndexProcessed = TRUE;
  1815. #ifdef AVI_FF_NO_INDEX
  1816. DEC_AVI_SetIndex(_bMPEG4TrickModeOn);
  1817. #endif
  1818. #ifdef USE_AUX_SUBTITLES 
  1819. initAuxSubtitles(&(i_pThis->m_cfiInfo), _mpeg4VideoScale,_mpeg4VideoRate);
  1820. AuxCache_GetFileTerminate();
  1821. #endif //USE_AUX_SUBTITLES 
  1822. // always first subtitle stream 
  1823. sc_GetBytes(SC_MPEG4_SUBTITLE_STREAM_INFO_ADDR,
  1824. 0,
  1825. SIZE_OF_SUBTITLE_STREAM_INFO,
  1826. (BYTE*)&_mpeg4SubtitleStreamInfo
  1827. );
  1828. if (_mpeg4SubtitleAvailableNum == 0)
  1829. _mpeg4SubtitleStreamID = NO_STREAM;
  1830. {
  1831. UINT16 uiAudioIdx;
  1832. UINT16 uiAudioNum = 0;
  1833. for (uiAudioIdx=0;uiAudioIdx<_mpeg4AudioAvailableNum;uiAudioIdx++)
  1834. {
  1835. sc_GetBytes(SC_MPEG4_AUDIO_STREAM_INFO_ADDR,
  1836. (uiAudioIdx * SIZE_OF_AUDIO_STREAM_INFO),
  1837. SIZE_OF_AUDIO_STREAM_INFO,
  1838. (BYTE*)&_mpeg4AudioStreamInfo
  1839. );
  1840. if (_mpeg4AudioCodec != AUDIO_UNKNOWN)
  1841. {
  1842. if (uiAudioIdx > uiAudioNum)
  1843. {
  1844. sc_SetBytes(SC_MPEG4_AUDIO_STREAM_INFO_ADDR,
  1845. (uiAudioNum * SIZE_OF_AUDIO_STREAM_INFO),
  1846. SIZE_OF_AUDIO_STREAM_INFO,
  1847. (BYTE*)&_mpeg4AudioStreamInfo
  1848. );
  1849. }
  1850. uiAudioNum++;
  1851. }
  1852. }
  1853. _mpeg4AudioAvailableNum = uiAudioNum;
  1854. }
  1855. // First Audio Stream Info
  1856. sc_GetBytes(SC_MPEG4_AUDIO_STREAM_INFO_ADDR,
  1857. 0,
  1858. SIZE_OF_AUDIO_STREAM_INFO,
  1859. (BYTE*)&_mpeg4AudioStreamInfo
  1860. );
  1861. if (_mpeg4AudioAvailableNum == 0)
  1862. _mpeg4AudioStreamID = NO_STREAM;
  1863. determineAudioInfo(&uiAudioSID, &uiAudioSIDDecoder, &dwSamplingRate);
  1864. /* Calculate and save playback addresses */
  1865. dwStartLBA = dwClipStartAddr + (_dwMP4FirstChunkOffset >> 11);
  1866. wClipStartOffset = (WORD)(_dwMP4FirstChunkOffset % LOGICAL_BLOCK_SIZE);
  1867. /* Set total clip time */
  1868. {
  1869. UINT16 uVideoTotalPlaybackTime, uAudioTotalPlaybackTime;
  1870. if (_mpeg4VideoStreamID == NO_STREAM)
  1871. uVideoTotalPlaybackTime = 0;
  1872. else
  1873. uVideoTotalPlaybackTime = caclTimeOfFrame( _mpeg4VideoLength, _mpeg4VideoRate, _mpeg4VideoScale);
  1874. if (_mpeg4AudioStreamID== NO_STREAM)
  1875. uAudioTotalPlaybackTime = 0;
  1876. else
  1877. // <<< Robin_1012_2004, calculate the total time of CBR/VBR audio 
  1878. {
  1879. if ((_mpeg4AudioScale == AVI_VBR_AUD_STREAM_SCALE) ||(_mpeg4AudioCodec == AAC))
  1880. {
  1881. // VBR audio
  1882. uAudioTotalPlaybackTime = caclTimeOfFrame(_mpeg4AudioLength, _mpeg4AudioRate, _mpeg4AudioScale);
  1883. }
  1884. else
  1885. {
  1886. // CBR audio
  1887. uAudioTotalPlaybackTime = (_mpeg4AudioLength * _mpeg4AudioScale) / _mpeg4AudioAvgBytesPerSec;
  1888. }    
  1889. }
  1890. // >>> Robin_1012_2004,
  1891. gns.clips.uTotalPlaybackTime = MAX(uVideoTotalPlaybackTime,uAudioTotalPlaybackTime);    
  1892. }
  1893. dbg_printf(("Total Clip Time: %d secn", gns.clips.uTotalPlaybackTime));
  1894. dwMdatSize = _dwMP4LastChunkEndOffset - _dwMP4FirstChunkOffset;
  1895. ulBlocksCnt = (wClipStartOffset + dwMdatSize + LOGICAL_BLOCK_SIZE - 1) / LOGICAL_BLOCK_SIZE;
  1896. wClipEndOffset = (WORD)((wClipStartOffset + dwMdatSize) % LOGICAL_BLOCK_SIZE);
  1897. if (0 == wClipEndOffset)
  1898. {
  1899. wClipEndOffset = 2048;
  1900. }
  1901. // _dwMPEG4ClipStartLBA = dwStartLBA;
  1902. _dwMPEG4ClipStartLBA = dwClipStartAddr;
  1903. _wMPEG4ClipStartOffset = wClipStartOffset;
  1904. _wMPEG4ClipEndOffset = wClipEndOffset;
  1905. _ulMPEG4TotalBlocksCnt = ulBlocksCnt;
  1906. _dwMPEG4FileLocation = dwClipStartAddr;
  1907. dwVideoSyncSampleNum = 0UL;
  1908. #ifdef PATCH_VIDEO_NOT_B
  1909. _bMPEG4IsBVopExist = _mp4DetectBVOP();
  1910. #endif
  1911. _mp4ChapterInit();
  1912. // Robin_1119_2004, restrict the flashcard transfer bytes at one times
  1913. {
  1914. UINT32 ulAverageChunkSize;
  1915. UINT32 ulFlashCardTransferBytes;
  1916. ulAverageChunkSize = (_dwMP4LastChunkEndOffset - _dwMP4FirstChunkOffset) / _dwMP4ChunkSizeEntryTotal;
  1917. ulFlashCardTransferBytes = ulAverageChunkSize * 32; // DVP store 64 chunk info
  1918. ulFlashCardTransferBytes = ((ulFlashCardTransferBytes + 1023) / 1024) * 1024;
  1919. tr_printf(("Average Chunk Size : %ld, FlashCard Transfer Bytes: %ld n", ulAverageChunkSize, ulFlashCardTransferBytes));
  1920. DEC_MP4_SetFlashCardTransferByte(ulFlashCardTransferBytes);
  1921. }
  1922. ulEndTime2 = (gen_timer()/1000UL);
  1923. tr_printf(("MP4Clip_Play() total time : %ld msecn",ulEndTime2-ulStartTime2));
  1924. ie_send(IE_UI_CLIPS_CLEAR_UI);
  1925. }
  1926. else
  1927. {
  1928. {
  1929. BYTE Temp[4];
  1930. AuxCache_GetBytes(dwClipStartAddr, 0, 4, &Temp[0]);
  1931. }
  1932. /* Resuming, handled as goto time */
  1933. DEC_AVI_ChangedSubtitle(_mpeg4SubtitleStreamID);
  1934. /* Calculate the video frame to skip to */
  1935. _mp4GetAdjacentIFrames(i_pResumeMarker->uTime,&dwVideoSyncSampleNum, &dwSyncSampleOffset);
  1936. determineAudioInfo(&uiAudioSID, &uiAudioSIDDecoder, &dwSamplingRate);
  1937. if (_ulMPEG4RequestedFrameIndex == 0)
  1938. dwSyncSampleOffset = _dwMP4FirstChunkOffset;
  1939. dwStartLBA = _dwMPEG4ClipStartLBA + ( dwSyncSampleOffset >> 11);
  1940. wClipStartOffset = (WORD)( dwSyncSampleOffset % LOGICAL_BLOCK_SIZE);
  1941. ulBlocksCnt = _ulMPEG4TotalBlocksCnt - (dwStartLBA - _dwMPEG4ClipStartLBA);
  1942. wClipEndOffset = _wMPEG4ClipEndOffset;
  1943. _uiMPEG4StartTime = caclTimeOfFrame(dwVideoSyncSampleNum,_mpeg4VideoRate, _mpeg4VideoScale);
  1944. }
  1945. // _mp4GetTransferTimes();
  1946. // _mp4ClearAPPBuffer();
  1947. if (_mpeg4VideoStreamID == NO_STREAM)
  1948. Logo_selectSource(eStartup);
  1949. _mp4PrePlayProcessing(dwSamplingRate, uiAudioSID, uiAudioSIDDecoder, (i_pThis->m_pConstAttr)->m_eVideoSID,
  1950.    ((NULL != i_pResumeMarker) ? FALSE : TRUE), FALSE);
  1951. #if 0  //FW0408_2005D Move to prePlayProcessing()
  1952. // Set AVI video scaling
  1953. DEC_EnableManualScaling(PROG_SCALER_MODE_CCRAM);
  1954. DEC_SetViewMode(gps->view_mode);
  1955. #endif
  1956. // JG_0819_2004: FF/FB->PLAY/PAUSE need not to do scaling again
  1957. //FW_0526_2005B Comment out, move to prePlayProcessing()
  1958. //if (NULL == i_pResumeMarker)
  1959. //gcst.mNeedScaling = TRUE;
  1960. // _mp4ClearAPPBuffer();
  1961. API_ADPSetMp3_Throw_Out_Cntr(0);
  1962. API_ADP_UpdateTaskParam( UPDATE_TASK_PARAM_MP3_THROW_OUT_CNTR,0 , NOT_SEND_TO_ADP);
  1963. DEC_AVI_SetStartVideoChunks(dwVideoSyncSampleNum); // TBD..
  1964. DEC_AVI_SetPlaybackParams(wClipStartOffset, wClipEndOffset, _uiMPEG4StartTime, 0, 0);
  1965. PE_Clips_SetPlaybackRange(dwStartLBA, ulBlocksCnt, UNLIMITED_FILE_SIZE);
  1966. _mp4InitTransferChunkSize(FALSE,0UL);
  1967. if (IS_CD_MEDIA)
  1968. {
  1969. drv_set_bit_rate(DRV_HIGH_BITRATE_E);
  1970. }
  1971. if (!PE_Clips_Playback_Sectors(DRVCF_CDSPEED_1X | DRVF_PLAY_CD_AV_DATA, dwStartLBA, ulBlocksCnt))
  1972. {
  1973. dbg_printf(("FATAL: AVIClip_play() Failed [6]n"));
  1974. return FALSE;
  1975. }
  1976. return TRUE;
  1977. }
  1978. #pragma argsused
  1979. void MP4Clip_pause(Clip *i_pThis, BOOL bEnable) 
  1980. dbg_printf(("MP4Clip_pause(%d)n", bEnable));
  1981. if (bEnable) 
  1982. {
  1983. /* in case we were in FF, */
  1984. if (gns.clips.iScanSpeed != 0)
  1985. {
  1986. int watchdog = 100;
  1987. MP4Clip_scan(i_pThis, 0); /* Resume playback */
  1988. //Wait until enter NSPB
  1989. while (DEC_getState() != DEC_LL_STATUS0_C_STATE_NSPB && --watchdog)
  1990. {
  1991. usleep(5000UL);
  1992. }
  1993. }
  1994. /* Clear DVP indication that this is a pause-stop (and not pause) */
  1995. DEC_AVI_ClearDemuxSharedBit(AVI_FILE_PAUSE_OFFSET, AVI_FILE_PAUSE_BIT);
  1996. API_ADPSetMp3_Throw_Out_Cntr(0);
  1997. /* Pause the Decoder */
  1998. DEC_PlaybackCommand(DEC_PLAYBACK_CMD_PAUSE, NULL);
  1999. }
  2000. else 
  2001. {
  2002. #ifdef USE_AUX_SUBTITLES
  2003. // RB_TBD
  2004. if (FALSE != areAuxSubtitlePresent()) // Robin_0528_2004_A, disable AuxSubtitle function if it not availabe
  2005. {
  2006. // perform seek in subtitles storage
  2007. // replace 0 with the correct time, once it can be determined before playback
  2008. // actually resumes
  2009. subtitleGoToTime(0);
  2010. setSubtitlesPlayMode(TRUE);
  2011. }
  2012. #endif //USE_AUX_SUBTITLES 
  2013. /* Resume the Decoder */
  2014. /* in case we were in FF, terminate it and resume playback */
  2015. DEC_PlaybackCommand(DEC_PLAYBACK_CMD_RESUME, NULL);
  2016. }
  2017. }
  2018. #pragma argsused
  2019. void MP4Clip_refresh(Clip *i_pThis) 
  2020. {
  2021. #ifdef MPP_SUPPORT
  2022. /* just enable MPP after playback, otherwise screen green or flash */
  2023. if( (PST_STOP != gcs.pstate) && (gns.clips.iCurrentTime >= 1) )
  2024. {
  2025. DEC_SetMPP( gcst.mMPP_Enable );
  2026. }
  2027. #endif
  2028. }
  2029. #pragma argsused
  2030. enClipStatus MP4Clip_getStatus(const Clip *i_pThis)
  2031. {
  2032. UINT32 uiNumOfDecodedSampleCurrent;
  2033. UINT16 uiVideoDecodingError;
  2034. UINT16 uVideoCodeBufferFullness;
  2035. MP4VideoSyncEntry mp4VideoSyncEntry;
  2036. /* If we are in FF/FB I only, don't regard this status */
  2037. #ifdef IP_SUPPORT
  2038. if ( (PST_SCAN == gcs.pstate) && (SCAN_SPEED_2X != gns.clips.iScanSpeed) )
  2039. #else
  2040. if (PST_SCAN == gcs.pstate)
  2041. #endif
  2042. {
  2043. return eCS_Busy;
  2044. }
  2045. /* In NSPB check the DVP video status and perform error handling if it gets stuck */
  2046. DEC_AVI_GetVideoDecodingStatus(&uiNumOfDecodedSampleCurrent,&uiVideoDecodingError);
  2047. uVideoCodeBufferFullness = (UINT16)DEC_ReadCodeBufferFullness(DEC_VIDEO_CODE_BUFFER, DEC_FULLNESS_IN_BYTES);
  2048. #ifdef SUPPORT_FLASH_CARD
  2049. if(IS_PLAYING_CARD)
  2050. _uiMPEG4TotalDVPIdleTime += 50; /* Core tick - 200 msec , slow down the counter for card*/
  2051. else
  2052. #endif
  2053. _uiMPEG4TotalDVPIdleTime += 200; /* Core tick - 200 msec */
  2054. if ( PST_PLAY == gcs.pstate &&
  2055.  _uiMPEG4NumOfDecodedChunksMemory == uiNumOfDecodedSampleCurrent &&
  2056.  (_uiMPEG4TotalDVPIdleTime >= DVP_VIDEO_TASK_WATCHDOG_TIME || uiVideoDecodingError == 0xF) &&
  2057.  (uVideoCodeBufferFullness != 0))
  2058. {
  2059. ClipMarker mClipMarker;
  2060. UINT16 uiNextIIdx;
  2061. WORD wNextITime;
  2062. tr_printf(("DVP video error...  time: %dn", _uiMPEG4StartTime));
  2063. /* Resume playback from the next I frame */
  2064. _uiMPEG4NumOfDecodedChunksMemory = 0; /* Prevent re-initiating */
  2065. _uiMPEG4TotalDVPIdleTime = 0;
  2066. if(TRUE == _mp4GetNextIFrames(uiNumOfDecodedSampleCurrent, &uiNextIIdx, &mp4VideoSyncEntry))
  2067. {
  2068. if(uiNextIIdx == _uiMPEG4NextIndexEntry)
  2069. {
  2070. return eCS_Finished;
  2071. }
  2072. mClipMarker.dwAddress = (i_pThis->m_cfiInfo).dwFileLocation;
  2073. wNextITime = (WORD)(caclTimeOfFrame(uiNumOfDecodedSampleCurrent,_mpeg4VideoRate, _mpeg4VideoScale ));
  2074. if(wNextITime <= mClipMarker.uTime)
  2075. mClipMarker.uTime = wNextITime+1;
  2076. else
  2077. mClipMarker.uTime = wNextITime;
  2078. }
  2079. (i_pThis->m_pConstAttr->m_vtable.m_pfPlay)(i_pThis, &mClipMarker, FALSE);
  2080. }
  2081. else if ( (_uiMPEG4NumOfDecodedChunksMemory != uiNumOfDecodedSampleCurrent) || (0 == _uiMPEG4NumOfDecodedChunksMemory) )
  2082. {
  2083. _uiMPEG4TotalDVPIdleTime = 0;
  2084. }
  2085. _uiMPEG4NumOfDecodedChunksMemory = uiNumOfDecodedSampleCurrent;
  2086. // transfer chunk size
  2087. #ifdef MP4_TANSFER_CHUNKSIZE_BY_FIFO
  2088. if ((PST_PLAY == gcs.pstate) || (PST_PAUSE == gcs.pstate) ||(PST_SLOW == gcs.pstate ))
  2089. _mp4TransferChunkSizeByFifo();
  2090. #else
  2091. if ((PST_PLAY == gcs.pstate) || (PST_PAUSE == gcs.pstate) ||(PST_SLOW == gcs.pstate ))
  2092. _mp4TransferChunkSize(/*FALSE,*/ FALSE);
  2093. #endif
  2094. /* Normal speed playback */
  2095. if (drv_is_play_done() && DEC_IsPlaybackFinished(FALSE))
  2096. {
  2097. if (_mpeg4VideoStreamID != NO_STREAM)
  2098. return eCS_Finished;
  2099. else if ((_uiMPEG4StartTime+1) >= gns.clips.uTotalPlaybackTime)
  2100. return eCS_Finished;
  2101. }
  2102. return eCS_Busy;
  2103. }
  2104. #pragma argsused
  2105. UINT16 MP4Clip_getTime(const Clip *i_pThis) 
  2106. {
  2107. UINT16 uiStatus2 = inport(I64_STATUS_2);
  2108. /* Check if the DVP is not running yet */
  2109. if ( (uiStatus2 & DVP_UPDATED_SCLK_MASK) == 0 )
  2110. {
  2111. /* SCLK start time is still not updated by the DVP */
  2112. _bMPEG4WasClockEnabled = FALSE;
  2113. return _uiMPEG4StartTime;
  2114. }
  2115. else if (FALSE == _bMPEG4WasClockEnabled)
  2116. {
  2117. PE_Clips_EnableClock(TRUE, TRUE, _uiMPEG4StartTime);
  2118. _bMPEG4WasClockEnabled = TRUE;
  2119. }
  2120. #ifdef USE_AUX_SUBTITLES
  2121. if (FALSE != areAuxSubtitlePresent())// Robin_0528_2004_A
  2122.    {
  2123. // read the SCLK to get better update resolution than 1 sec.
  2124. checkAndHandleAuxSubtitles(PE_Clips_GetClock_Raw()); // Robin_2004_0517_B, resolution in ms
  2125. }
  2126. #endif // USE_AUX_SUBTITLES
  2127. if ((PST_PLAY == gcs.pstate) || (PST_PAUSE == gcs.pstate) ||(PST_SLOW == gcs.pstate ))
  2128. {
  2129. if (_bMP4InternalSubtitle)// Robin_0528_2004_A
  2130. {
  2131. mp4CheckAndHandleSubtitle(PE_Clips_GetClock_Raw()); // resolution in ms
  2132. }
  2133. }
  2134. _uiMPEG4StartTime = PE_Clips_GetClock();
  2135. _mp4ChapterRefresh();
  2136. return _uiMPEG4StartTime;
  2137. }
  2138. #pragma argsused
  2139. void MP4Clip_abort(Clip *i_pThis, BOOL bMaintainStandby)
  2140. {
  2141. #ifdef MPP_SUPPORT
  2142. DEC_SetMPP(FALSE);
  2143. #endif
  2144.    
  2145. DEC_AVI_EnableFinishCB(FALSE);
  2146. #ifdef MP4_TANSFER_CHUNKSIZE_BY_FIFO
  2147. DEC_MP4_ChunkSizeFifoInit();
  2148. #endif
  2149. DEC_MP4_SetFlashCardNotNeedCheck();
  2150. if (IS_CD_MEDIA)
  2151. {
  2152. drv_set_bit_rate(DRV_NORMAL_BITRATE_E);
  2153. }
  2154. GenericClip_abort(i_pThis, bMaintainStandby);
  2155. _mp4ClearAPPBuffer();
  2156. }
  2157. #pragma argsused
  2158. void MP4Clip_scan(Clip *i_pThis, int iScanSpeed)
  2159. INT8 iIndexIncrement;
  2160. UINT8 eNoBScanSpeedMap = 0;
  2161. if (iScanSpeed > 0)
  2162. {
  2163. if (iScanSpeed < ((SCAN_SPEED_2X+SCAN_SPEED_4X)/2))
  2164. iScanSpeed = SCAN_SPEED_2X;
  2165. else if (iScanSpeed <((SCAN_SPEED_4X+SCAN_SPEED_8X)/2))
  2166. iScanSpeed = SCAN_SPEED_4X;
  2167. else if (iScanSpeed <((SCAN_SPEED_8X+SCAN_SPEED_20X)/2))
  2168. iScanSpeed = SCAN_SPEED_8X;
  2169. else
  2170. iScanSpeed = SCAN_SPEED_20X;
  2171. }
  2172. else if(iScanSpeed < 0)
  2173. {
  2174. if (iScanSpeed > -((SCAN_SPEED_2X+SCAN_SPEED_4X)/2))
  2175. iScanSpeed = -SCAN_SPEED_2X;
  2176. else if (iScanSpeed > -((SCAN_SPEED_4X+SCAN_SPEED_8X)/2))
  2177. iScanSpeed = -SCAN_SPEED_4X;
  2178. else if (iScanSpeed > -((SCAN_SPEED_8X+SCAN_SPEED_20X)/2))
  2179. iScanSpeed = -SCAN_SPEED_8X;
  2180. else
  2181. iScanSpeed = -SCAN_SPEED_20X;
  2182. }
  2183. if (iScanSpeed == SCAN_SPEED_2X)
  2184. eNoBScanSpeedMap = SCAN_SPEED_4X;
  2185. else if (iScanSpeed == SCAN_SPEED_4X)
  2186. eNoBScanSpeedMap = SCAN_SPEED_8X;
  2187. else if (iScanSpeed == SCAN_SPEED_8X)
  2188. eNoBScanSpeedMap = SCAN_SPEED_20X;
  2189. else if (iScanSpeed == SCAN_SPEED_20X)
  2190. eNoBScanSpeedMap = SCAN_SPEED_40X;
  2191. /* Check if we are in scanning */
  2192. if (iScanSpeed != 0)
  2193. {
  2194. if ( (PST_SLOW == gcs.pstate) || (PST_PLAY == gcs.pstate) || (PST_SCAN == gcs.pstate)  || (PST_PAUSE == gcs.pstate) )
  2195. {
  2196. #ifdef USE_AUX_SUBTITLES
  2197. if (FALSE != areAuxSubtitlePresent() || _bMP4InternalSubtitle)// Robin_0528_2004_A
  2198. {
  2199. // stop subtitle seeking
  2200. setSubtitlesPlayMode(FALSE);
  2201. stopDisplayAuxSubtitles();
  2202. }
  2203. #endif //USE_AUX_SUBTITLES
  2204. #ifdef IP_SUPPORT
  2205. if ( ! FOUND_B_PICS_IN_CLIP && iScanSpeed > 0 )
  2206. {
  2207. iScanSpeed = eNoBScanSpeedMap;
  2208. dbg_printf(("No B pictures detectedn"));
  2209. }
  2210. #else
  2211. if ( iScanSpeed > 0 )
  2212. {
  2213. #ifdef AVI_FF_NO_INDEX
  2214. if (TRUE == _bMPEG4TrickModeOn)
  2215. #endif
  2216.          iScanSpeed = eNoBScanSpeedMap; 
  2217. }
  2218. #endif
  2219. dbg_printf(("MP4Clip_scan(x%d)n", iScanSpeed));
  2220. /* Calculate the increment in the idx table */
  2221. switch (iScanSpeed)
  2222. {
  2223. case SCAN_SPEED_2X:
  2224. DEC_AVI_EnableFinishCB(FALSE);
  2225. DEC_AVI_SetIOnly(FALSE);
  2226. /* If we are moving from I to IP only, need to resume playback */
  2227. if (gns.clips.iScanSpeed != 0)
  2228. {
  2229. MP4Clip_scan(i_pThis, 0); /* Resume playback */
  2230. MP4Clip_scan(i_pThis, SCAN_SPEED_2X); /* Resume IP scanning mode */
  2231. return;
  2232. }
  2233. #ifdef AVI_FF_NO_INDEX
  2234. if (FALSE == _bMPEG4TrickModeOn)
  2235. DEC_AVI_EnableFinishCB(TRUE);
  2236. #endif
  2237. DEC_AVI_SetIPOnly(TRUE);
  2238. iIndexIncrement = I_P_INCREMENT;
  2239. _iMPEG4CurrentScanningMode = iIndexIncrement;
  2240. gns.clips.iScanSpeed = iScanSpeed;
  2241. gcs.pstate= PST_SCAN;
  2242. return;
  2243. case SCAN_SPEED_4X:
  2244. #ifdef AVI_FF_NO_INDEX
  2245. if (FALSE == _bMPEG4TrickModeOn)
  2246. {
  2247. DEC_AVI_SetIPOnly(FALSE);
  2248. DEC_AVI_SetIOnly(TRUE);
  2249. iIndexIncrement = ONE_I_INCREMENT;
  2250. _iMPEG4CurrentScanningMode = iIndexIncrement;
  2251. gns.clips.iScanSpeed = iScanSpeed;
  2252. gcs.pstate= PST_SCAN;
  2253. DEC_AVI_EnableFinishCB(TRUE);
  2254. return;
  2255. }
  2256. else
  2257. #endif
  2258. iIndexIncrement = ONE_I_INCREMENT;
  2259. break;
  2260. case SCAN_SPEED_8X:
  2261. iIndexIncrement = TOW_I_INCREMENT;
  2262. break;
  2263. case SCAN_SPEED_20X:
  2264. iIndexIncrement = FOUR_I_INCREMENT;
  2265. break;
  2266. case SCAN_SPEED_40X:
  2267. iIndexIncrement = EIGHT_I_INCREMENT;
  2268. break;
  2269. case (-SCAN_SPEED_2X):
  2270. iIndexIncrement = -ONE_I_INCREMENT;
  2271. break;
  2272. case (-SCAN_SPEED_4X):
  2273. iIndexIncrement = -TOW_I_INCREMENT;
  2274. break;
  2275. case (-SCAN_SPEED_8X):
  2276. iIndexIncrement = -FOUR_I_INCREMENT;
  2277. break;
  2278. case (-SCAN_SPEED_20X):
  2279. iIndexIncrement = -EIGHT_I_INCREMENT;
  2280. break;
  2281. }
  2282. /* Check if we changed from IP to I only mode */
  2283. if ( (gns.clips.iScanSpeed == SCAN_SPEED_2X) || (gns.clips.iScanSpeed == 0) )
  2284. {
  2285. gcs.pstate = PST_SCAN;
  2286. // first time, 
  2287. DEC_PlaybackCommand(DEC_PLAYBACK_CMD_STOP, 0);
  2288. /* Start I only scan mode */
  2289. if (FALSE == _mp4Scan(iIndexIncrement, FALSE))
  2290. {
  2291. dbg_printf(("WARNNING: AVIClip_scan() FAILEDn"));
  2292. }
  2293. }
  2294. /*
  2295.  * Else - the DEMUX status polling time was enabled before,
  2296.  *  and so, when the time is triggered the scanning will continue 
  2297.  *  according to the updated scanning mode 
  2298.  */
  2299. gns.clips.iScanSpeed = iScanSpeed;
  2300. _iMPEG4CurrentScanningMode = iIndexIncrement;
  2301. }
  2302. }
  2303. else
  2304. {
  2305. /* Playing after scanning - resume playback */
  2306. ClipMarker mClipMarker;
  2307. #ifdef USE_AUX_SUBTITLES
  2308. if (FALSE != areAuxSubtitlePresent())// Robin_0528_2004_A
  2309. {
  2310. // replace 0 with the correct time, once it can be determined before playback
  2311. // actually resumes
  2312. subtitleGoToTime(0);
  2313. setSubtitlesPlayMode(TRUE);
  2314. }
  2315. else if (_bMP4InternalSubtitle)
  2316. {
  2317. setSubtitlesPlayMode(TRUE);
  2318. }
  2319. #endif //USE_AUX_SUBTITLES 
  2320. #ifdef AVI_FF_NO_INDEX
  2321. if (FALSE == _bMPEG4TrickModeOn)
  2322. {
  2323. DEC_AVI_SetIPOnly(FALSE);
  2324. DEC_AVI_SetIOnly(FALSE);
  2325. DEC_AVI_EnableFinishCB(FALSE);
  2326. return;
  2327. }
  2328. else
  2329. #endif
  2330. {
  2331. if (_iMPEG4CurrentScanningMode == I_P_INCREMENT)
  2332. {
  2333. DEC_AVI_SetIPOnly(FALSE);
  2334. }
  2335. else /* I only mode */
  2336. {
  2337. DEC_AVI_SetIOnly(FALSE);
  2338. /* Remove DEMUX callback */
  2339. DEC_AVI_EnableFinishCB(FALSE);
  2340. }
  2341. }
  2342. /* Save the info used for resuming */
  2343. mClipMarker.dwAddress = (i_pThis->m_cfiInfo).dwFileLocation;
  2344. mClipMarker.uTime = _uiMPEG4StartTime;
  2345. gns.clips.iScanSpeed = 0;
  2346. gcs.pstate = PST_PLAY;
  2347. /* Resume playback */
  2348. (i_pThis->m_pConstAttr->m_vtable.m_pfPlay)(i_pThis, &mClipMarker, FALSE);
  2349. }
  2350. }
  2351. #pragma argsused
  2352. void MP4Clip_recordMarker(const Clip *i_pThis, ClipMarker *o_pMarker)
  2353. {
  2354. dbg_printf(("MP4Clip_recordMarker()n"));
  2355. /* Saving the info needed for playback resuming */
  2356. o_pMarker->dwAddress = (i_pThis->m_cfiInfo).dwFileLocation;
  2357. o_pMarker->uTime = (i_pThis->m_pConstAttr->m_vtable.m_pfGetTime)(i_pThis);
  2358. o_pMarker->uClipNumer = gns.clips.uCurrentClipNumber;
  2359. }
  2360. void MP4Clip_continueScanning(void)
  2361. {
  2362. /* Verify that we are in FF I only mode */
  2363. #ifdef IP_SUPPORT
  2364. if ( (gns.clips.iScanSpeed != 0) && (gns.clips.iScanSpeed != SCAN_SPEED_2X) )
  2365. #else
  2366. if (gns.clips.iScanSpeed != 0)
  2367. #endif
  2368. {
  2369. _mp4Scan(_iMPEG4CurrentScanningMode, TRUE);
  2370. }
  2371. }
  2372. void MP4Clip_performErrorHandling(const Clip *i_pThis)
  2373. {
  2374. dbg_printf(("MP4Clip_performErrorHandling()n"));
  2375. /* The current error handling is only in scanning mode */
  2376. /* Check whether we are in FF I only or not */
  2377. #ifdef IP_SUPPORT
  2378. if ( (gcs.pstate == PST_SCAN) && (gns.clips.iScanSpeed != SCAN_SPEED_2X) )
  2379. #else
  2380. if (gcs.pstate == PST_SCAN)
  2381. #endif
  2382. {
  2383. /* Remove the callback from the demux */
  2384. DEC_AVI_EnableFinishCB(FALSE);
  2385. /* Start I only FF from the beginning */
  2386. _mp4Scan(_iMPEG4CurrentScanningMode, TRUE);
  2387. #ifdef SUPPORT_FLASH_CARD
  2388. if(IS_PLAYING_CARD)
  2389. _uiMPEG4StartTime += gns.clips.iScanSpeed;
  2390. #endif
  2391. }
  2392. else
  2393. {
  2394. /* NSPB recovery, resume playback from the next I frame */
  2395. ClipMarker mClipMarker;
  2396. MP4VideoSyncEntry mp4VideoSyncEntry;
  2397.         UINT16 uiNextIIdx;
  2398. UINT32 uiNumOfDecodedSampleCurrent;
  2399. WORD wNextITime;
  2400. UINT16 uiVideoDecodingError;
  2401. DEC_AVI_GetVideoDecodingStatus(&uiNumOfDecodedSampleCurrent,&uiVideoDecodingError);
  2402. if(TRUE == _mp4GetNextIFrames(uiNumOfDecodedSampleCurrent, &uiNextIIdx, &mp4VideoSyncEntry))
  2403. {
  2404. if(uiNextIIdx == _uiMPEG4NextIndexEntry)
  2405. {
  2406. return;
  2407. }
  2408. mClipMarker.dwAddress = (i_pThis->m_cfiInfo).dwFileLocation;
  2409. wNextITime = (WORD)(caclTimeOfFrame(uiNumOfDecodedSampleCurrent,_mpeg4VideoRate, _mpeg4VideoScale ));
  2410. if(wNextITime <= mClipMarker.uTime)
  2411. mClipMarker.uTime = wNextITime+1;
  2412. else
  2413. mClipMarker.uTime = wNextITime;
  2414. }
  2415. (i_pThis->m_pConstAttr->m_vtable.m_pfPlay)(i_pThis, &mClipMarker, FALSE);
  2416. }
  2417. }
  2418. static void _mp4SubtitleWriteDRAM(UINT32 ulAddress, UINT16* pBuffer, UINT32 ulLength )
  2419. {
  2420. UINT32 ulWriteLengthFirst;
  2421. UINT32 ulWriteLngthSecond;
  2422. UINT32 ulBufferStartAddr, ulBufferEndAddr;
  2423. ulBufferStartAddr = _mpeg4InternalSubtitleBufferStartAddr * 512UL;
  2424. ulBufferEndAddr = (_mpeg4InternalSubtitleBufferStartAddr + SPB_SIZE_AVI) * 512UL;
  2425.     while(ulAddress >= ulBufferEndAddr)
  2426.    {
  2427. ulAddress -= (ulBufferEndAddr - ulBufferStartAddr);
  2428.    }
  2429.    ulWriteLengthFirst = min(ulLength, ulBufferEndAddr -ulAddress);
  2430.    ulWriteLngthSecond = ulLength - ulWriteLengthFirst;
  2431.    wai_sem(SEM_DRAM_ID);
  2432.    I49_WriteDRAMDataNSW(ulAddress, (UINT16*)pBuffer, ulWriteLengthFirst);
  2433.    
  2434.    if ( ulWriteLngthSecond != 0UL )
  2435.    {
  2436.       I49_WriteDRAMDataNSW(ulBufferStartAddr, (UINT16*)(pBuffer + ulWriteLengthFirst ), ulWriteLngthSecond );
  2437.    }
  2438.    sig_sem(SEM_DRAM_ID);
  2439.    return;
  2440. }
  2441. static void _mp4SubtitleStoreTimeAndSample(UINT32 ulStartTime,UINT32 ulEndTime,UINT32 ulSampleSize, WORD* pBuffer)
  2442. {
  2443. UINT32 ulSampleSizeInWord;
  2444. ulSampleSizeInWord = (ulSampleSize+1)/2;
  2445. _mp4SubtitleWriteDRAM( _dwMP4SubtitleWriteDRAMAddr, (UINT16*)(&ulStartTime), 2);
  2446. _mp4SubtitleWriteDRAM( (_dwMP4SubtitleWriteDRAMAddr+2), (UINT16*)(&ulSampleSize), 2);
  2447. _mp4SubtitleWriteDRAM( (_dwMP4SubtitleWriteDRAMAddr+4), pBuffer, ulSampleSizeInWord );
  2448. _mp4SubtitleWriteDRAM((_dwMP4SubtitleWriteDRAMAddr+4+ulSampleSizeInWord), (UINT16*)(&ulEndTime), 2);
  2449. _dwMP4SubtitleWriteDRAMAddr += (6+ulSampleSizeInWord);
  2450. }
  2451. // Robin_1230_2004, send subpicture pts to DVP
  2452. void _mp4SubPictureArrived(void)
  2453. {
  2454. UINT16 uiStatus;
  2455. UINT16 uiTemp1,uiTemp2;
  2456. UINT32 uiSPDSize;
  2457. UINT16 uiPTS[2];
  2458. MP4SubtitleSampleEntry mp4SubtitleSampleEntry;
  2459. uiStatus = inport(DS2CFIFO_STATUS_ADDR); 
  2460. if(!uiStatus)
  2461. {
  2462. tr_printf(("Nothing in FIFOn"));
  2463. return;
  2464. }
  2465.     uiTemp1 = inport(DS2CFIFO_DATA_ADDR);
  2466.     uiTemp2 = inport(DS2CFIFO_DATA_ADDR);
  2467.     uiSPDSize = ((DWORD)uiTemp1<<16)|(uiTemp2);
  2468. wai_sem(SEM_DRAM_ID);
  2469. I49_ReadDRAMData(_dwMP4SubtitleSampleAddr,(UINT16*)&mp4SubtitleSampleEntry, MP4_SUBTITLE_SMAPLE_ENTRY_SIZE);
  2470. sig_sem(SEM_DRAM_ID);
  2471. _dwMP4SubtitleSampleAddr -= MP4_SUBTITLE_SMAPLE_ENTRY_SIZE;
  2472. if (uiSPDSize != mp4SubtitleSampleEntry.dwSampleSize)
  2473. tr_printf(("Error: SubPicture size from DVP : %ld, from CPU : %ldn", uiSPDSize, mp4SubtitleSampleEntry.dwSampleSize));
  2474. uiPTS[0] = (UINT16)((90UL * mp4SubtitleSampleEntry.dwSampleEndTime) >> 16);
  2475. uiPTS[1] = (UINT16)((90UL * mp4SubtitleSampleEntry.dwSampleEndTime) & 0xFFFFUL);
  2476. I49_DVPFIFOWrite(&uiPTS, 2);
  2477. }
  2478. void MP4Clip_subtitleArrived(void)
  2479. {
  2480. UINT16 uiStatus;
  2481. UINT16 uiTemp1,uiTemp2;
  2482. UINT32 uiInputBufferSize;
  2483. UINT32 uiInputBufferSizeWords;
  2484. UINT32 uiInputCount;
  2485. BYTE *pSubtitleBuffer;
  2486. MP4SubtitleSampleEntry mp4SubtitleSampleEntry;
  2487. // static UINT32 ulSubtitleSkipBytes = 0UL;
  2488. if (INTERNAL_SUBP == _mpeg4SubtitleType)
  2489. {
  2490. _mp4SubPictureArrived();
  2491. return;
  2492. }
  2493. uiStatus = inport(DS2CFIFO_STATUS_ADDR); 
  2494. if(!uiStatus)
  2495. {
  2496. tr_printf(("Nothing in FIFOn"));
  2497. return;
  2498. }
  2499.     uiTemp1 = inport(DS2CFIFO_DATA_ADDR);
  2500.     uiTemp2 = inport(DS2CFIFO_DATA_ADDR);
  2501.     uiInputBufferSize = ((DWORD)uiTemp1<<16)|(uiTemp2);
  2502. uiInputBufferSizeWords = (uiInputBufferSize+1)/2;
  2503. pSubtitleBuffer = (BYTE*)malloc(uiInputBufferSizeWords * sizeof(WORD) );
  2504. if (NULL == pSubtitleBuffer)
  2505. {
  2506. tr_printf(("FATAL: couldn't allocate memory for subtitle buffer, size: %ldn", (uiInputBufferSizeWords*2)));
  2507. // RB_TBD
  2508. return;
  2509. }
  2510. for(uiInputCount=0; uiInputCount<uiInputBufferSizeWords; uiInputCount++)
  2511. {
  2512. int timeOut = 0;
  2513.         do { 
  2514.             uiStatus = inport(DS2CFIFO_STATUS_ADDR); 
  2515. if (timeOut > 10000)
  2516. {
  2517. dbg_printf(("WARNING: MP4Clip_subtitleArrived() Failed!n"));
  2518. // RB_TBD
  2519. free(pSubtitleBuffer);
  2520. return;
  2521. }
  2522. timeOut++;
  2523.         } while ( uiStatus < 1 );
  2524.         uiTemp1 = inport(DS2CFIFO_DATA_ADDR);
  2525.         pSubtitleBuffer[2*uiInputCount] = (BYTE)(uiTemp1 >> 8);
  2526.         pSubtitleBuffer[(2*uiInputCount)+1] = (BYTE)(uiTemp1 & 0xFF);
  2527. }
  2528. uiInputCount = 0;
  2529. while(uiInputCount < uiInputBufferSize)
  2530. {
  2531. UINT32 ulStartTime;
  2532. UINT32 ulEndTime;
  2533. UINT32 ulSampleSize;
  2534. wai_sem(SEM_DRAM_ID);
  2535. I49_ReadDRAMData(_dwMP4SubtitleSampleAddr,(UINT16*)&mp4SubtitleSampleEntry, MP4_SUBTITLE_SMAPLE_ENTRY_SIZE);
  2536. sig_sem(SEM_DRAM_ID);
  2537. _dwMP4SubtitleSampleAddr -= MP4_SUBTITLE_SMAPLE_ENTRY_SIZE;
  2538. ulStartTime = _dwMP4SubtitleSampleStartTime;
  2539. _dwMP4SubtitleSampleStartTime = mp4SubtitleSampleEntry.dwSampleEndTime;
  2540. ulEndTime = _dwMP4SubtitleSampleStartTime;
  2541. ulSampleSize = mp4SubtitleSampleEntry.dwSampleSize;
  2542. // uiInputCount += mp4SubtitleSampleEntry.dwSampleSize;
  2543. if ((mp4SubtitleSampleEntry.dwSampleSize == 1) && (pSubtitleBuffer[uiInputCount] == 0))
  2544. {
  2545. uiInputCount += mp4SubtitleSampleEntry.dwSampleSize;
  2546. continue;
  2547. }
  2548. _mp4SubtitleStoreTimeAndSample(ulStartTime,ulEndTime,ulSampleSize,(WORD*)(pSubtitleBuffer+uiInputCount));
  2549. uiInputCount += mp4SubtitleSampleEntry.dwSampleSize;
  2550. }
  2551. free(pSubtitleBuffer);
  2552. }
  2553. #endif