AVI.c
上传用户:super_houu
上传日期:2008-09-21
资源大小:4099k
文件大小:131k
- /****************************************************************************************
- * Copyright (c) 2003 ZORAN Corporation, All Rights Reserved
- * THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF ZORAN CORPORATION
- *
- * File: $Workfile: AVI.c $
- *
- * Description:
- * ============
- *
- *
- * Log:
- * ====
- * $Revision: #12 $
- * $Change: 57739 $
- * Last Modified by $Author: callie.cai $ at $DateTime: 2005/09/29 15:10:23 $
- ****************************************************************************************
- * Updates:
- ****************************************************************************************
- * $Log: /I76/I76_Common/I76_Reference/Playcore/Nav_Clips/AVI.c $
- *
- * 79 4/03/04 1:58p Robinj
- * avoid calculation overflow
- *
- * 78 04-04-02 15:01 Fwang
- * Fix green screen by MPP.
- *
- * 77 04-04-01 19:19 Fwang
- * Fix AVI AB repeat goes to start of clip.
- *
- * 76 3/30/04 10:04p Robinj
- * support special 3ivx clip, "fccHandler" is "mp4v"/"rmp4" and
- * "biCompression" is "rmp4", it's same as "XVID"
- *
- * 75 04-03-30 15:51 Fwang
- * Fix pause after scan.
- *
- * 74 04-03-29 11:09 Leonh
- * keep the zoom when scan
- *
- * 73 3/25/04 7:52p Robinj
- * fix wrong number display when change subtitle/audio stream
- *
- * 72 3/25/04 7:28p Rond
- * added watchdog for divx 3.11
- *
- * 71 3/24/04 5:35p Robinj
- * support special divx clip, "fccHandler" is "DX50" and "biCompression"
- * is "DX50", it's same as "Divx 5"
- * playback without audio output when DIVX audio is PCM/ADPCM/WMA
- *
- * 70 3/22/04 10:20a Robinj
- * special divx clip, "fccHandler" is "MSVC" and "biCompression" is
- * "DIVX", it's same as "Divx 4.12"
- *
- * 69 3/21/04 8:49p Lotan
- * merge 4 with certification DB
- *
- * 68 3/21/04 8:00p Hamadk
- * Removed DRV_SET_BIT_RATE macro
- *
- * 67 3/10/04 4:21p Lotan
- * Merge with Divx Certification DB 3
- *
- * 66 04-03-09 21:50 Leslie
- * Mem reduction for DRM
- *
- * 65 3/08/04 4:14p Hamadk
- * Merging with DivX certification DB - Optimized AVI file info memory
- *
- * 64 3/04/04 10:22p Lotan
- * Second merge with Divx Certification DB,
- * including 2x16 SDram
- *
- * 63 3/01/04 6:29p Lotan
- * merge with Divx certification DB
- *
-
- * From Divx Certification DB
- * DRM - add casting - just to make sure it is done correctly
- * chage DRM indication, according to Divx's request
- * Corrected calculation of time in idx proccessing for VBR
- * Removed looking for Nandub - treat all clips with audio scale of 1152
- * as VBR
- * update Divx DRM rental screen parameters
- * - Added support for different I spaces in the IDX for different clips
- * - Code cleanup.
- * Added error handling for DivX (Drive & Demux)
- * Corrected getStatus() when IP FF is not supported
- * Corrected saving/reading idx entries
- * Replaced the autoplay patch
- * patch to prevent index proccessing on auto play
- * remove UI temp screen
- * add DRM rental check and screen
- * - Corrected Idx calculation for CBR to be more accurate.
- * - Replaced printfs with dbg_printfs.
- * No IP support
- * Removed FIFO_destruct()
- * add Reading Index message
- * - Corrected bug in FB.
- * - Code cleanup.
- * fixed bug of more than one audio stream
- * add DRM trick mode support
- * divX Version for Certification
- * drive speed up is ON
-
- ====================
- * 62 2/27/04 7:06p Robinj
- * Prohibit "FF/FB" when "idx1" not found
- *
- * 61 2/19/04 10:47p Robinj
- * fix the problem of chunk size is zero
- *
- * 60 2/17/04 3:09p Lotan
- *
- * 58 2/15/04 7:40p Lotan
- * update DRM process. Add registration check, etc.
- *
- * 57 2/13/04 12:09a Rond
- * moved speed for High bit rate clips
- *
- * 56 04-02-11 17:33 Fwang
- * Enable CPU scaling for DVD/VCD/SVCD.
- *
- * 55 2/11/04 12:41a Lotan
- * new Divx DRM handling method.
- *
- * 54 2/10/04 8:44p Rond
- * mpeg layer 2
- *
- * 53 3/02/04 10:36 Lotan
- * rollback, due to bug in VBR processing
- *
- * 51 20/01/04 12:12 Lotan
- * change DRM flag for DVP from false to true - for DRM support
- *
- * 50 1/13/04 12:11 Hamadk
- * Merged with CES DB
- *
- * 49 12/26/03 14:08 Hamadk
- *
- * 48 12/26/03 13:45 Hamadk
- * - Added support for changing the start of the idx processing.
- * - Fixed bug in idx processing not to regard audio for non-audio clips.
- * - Fixed bug in resuming from FF I only to FF IP.
- *
- * 47 12/25/03 15:50 Hamadk
- * - Fixed bug in processing time to address.
- * - Changed idx processing not to hangup in case of there's many audio
- * chunks before key frames.
- *
- * 46 12/25/03 11:15 Hamadk
- * - Corrected updating of the time.
- * - Corrected resuming from FF I only.
- * - Corrected clearing DVPGen2 in resuming from FF IP.
- *
- * 45 12/24/03 19:27 Hamadk
- *
- * 44 12/24/03 17:41 Hamadk
- * FF & GoTo time basically work
- *
- * 43 12/24/03 9:38 Eyalr
- * removed 512 width of Aharon temp slot machine
- *
- * 42 12/23/03 12:31p Chaol
- * for compilation pass
- *
- * 41 12/23/03 12:12p Chaol
- * modify MPP implement
- *
- * 40 03-12-23 11:07 Fwang
- * Workaround for video garbage when skip between clips.
- *
- * 39 12/22/03 5:35p Chaol
- * add MPP support for Divx
- *
- * 38 22/12/03 14:53 Lotan
- * solve special clip14 problem --> supports "mp43" (divx3.11) encoder
- *
- * 37 12/18/03 19:14 Hamadk
- * - Corrected FF operation.
- * - Corrected GoTo time operation.
- * - Removed code orginization
- *
- * 36 03-12-18 13:22 Fwang
- * Implement CC-RAM scaling.
- *
- * 35 12/18/03 12:41 Hamadk
- * Changed getTime function not to check the SCLK in case the DVP is still
- * not in NSPB
- *
- * 34 12/18/03 11:15 Hamadk
- * - Replaced sending the demux fixed video/audio stream numbers to the
- * actual played ones.
- * - Code cleanup.
- *
- * 33 12/18/03 9:46 Nmaurer
- * Adjust the Drive speed according to the clip bitrate
- *
- * 32 12/17/03 18:08 Eyalr
- * fixed 512 width Divx problem
- *
- * 31 16/12/03 14:37 Lotan
- * fix subtitle bug (picture of clips with subtitle was wrong)
- *
- * 30 12/14/03 19:27 Eyalr
- * added two parameters to set files
- *
- * 29 12/14/03 18:31 Eyalr
- *
- * 28 12/12/03 16:33 Eyalr
- *
- * 27 12/12/03 14:02 Eyalr
- *
- * 26 12/11/03 10:06 Eyalr
- *
- * 25 12/09/03 17:20 Eyalr
- * changed SEt file param
- *
- * 24 12/08/03 3:49p Fwang
- * To avoid uninitialized scaling parameter.
- *
- * 23 12/07/03 8:51p Fwang
- * Scaling by CPU
- *
- * 22 12/04/03 1:11p Leslie
- * Abort drive each time after we finish parse AVI File Header information
- *
- * 21 11/30/03 10:05 Eyalr
- *
- * 20 11/27/03 18:40 Eyalr
- *
- * 19 11/27/03 18:19 Eyalr
- *
- * 18 11/26/03 17:24 Eyalr
- * Zooming & Scalling on CPU
- *
- * 17 11/26/03 15:55 Eyalr
- *
- * 16 11/26/03 11:59 Eyalr
- * playing XVID
- *
- * 15 25/11/03 18:07 Lotan
- * fix playback range calculation bug
- *
- * 14 11/24/03 18:59 Eyalr
- * display logo on stop
- *
- * 13 11/18/03 9:29 Eyalr
- * added SID for Decoder & UI
- *
- * 12 11/17/03 14:10 Eyalr
- *
- * 11 11/06/03 15:16 Eyalr
- * added new features for Divx
- *
- * 10 10/29/03 17:46 Eyalr
- *
- * 9 10/22/03 19:04 Hamadk
- * - Moved AVI Clip navigator info in the global navigation union.
- * - Changed the clip's get status function to be like generic clip.
- * - Updated function names.
- * - Added support for XVID.
- * - Code cleanup.
- *
- * 8 10/20/03 14:34 Eyalr
- *
- * 7 10/12/03 15:12 Hamadk
- * - Fixed idx processing.
- * - Added documentation.
- * - Code cleanup.
- *
- * 6 10/12/03 9:06 Hamadk
- * Corrected processing of the Idx
- *
- * 5 10/02/03 18:47 Hamadk
- * Corrected calculating the requested entry from the IDX
- *
- * 4 10/02/03 17:46 Hamadk
- * Corrected reaching the end of the idx table while scanning
- *
- * 3 10/02/03 10:35 Hamadk
- * - Corrected calculation of end address and end offset
- * - Added support for FF/FB
- *
- * 2 9/29/03 8:18 Hamadk
- *
- ****************************************************************************************/
- #include "Config.h" // Global Configuration - do not remove!
- #ifdef _DEBUG
- #undef IFTRACE
- #define IFTRACE if (gTraceNavigator)
- #include "Debugdbgmain.h"
- #endif
- #include "Decoderadp_api.h"
- #include "Decoderlow_levelDEC_LL_API.h"
- #include "Decoderlow_levelDEC_LL_Def.h"
- #include "Drivedrv_api.h"
- #include "Includestring_ex.h"
- #include "KernelEventDef.H"
- #include "KernelKer_API.h"
- #include "LogoLogo.h"
- #include "PlaycoreCoremainCoreDefs.h"
- #include "PlaycoreCoremainCoreGDef.h"
- #include "PlaycoreAuxCacheAuxCache.h"
- #include "PlaycoreNav_CDDAPE_CD.h"
- #include "PlaycoreNav_ClipsAVI.h"
- #include "PlaycoreNav_ClipsAVI_private.h"
- #include "PlaycoreNav_ClipsClip_Impl.h"
- #include "PlaycoreNav_ClipsGenericClip.h"
- #include "PlaycoreNav_ClipsPE_Clips.h"
- #include "PlaycorePlayModePlayMode.h"
- #include "PlaycorePSPS.h"
- #include "DecoderDec_Avi_Drm.h"
- #include "Decoderlow_levelDEC_LL_Reg.h"
- #include "PlaycoreNav_ClipsAviDrmLibDrmCommonDrmErrors.h"
- #include "PlaycoreNav_ClipsMpeg4ClipsCommon.h"
- #ifdef USE_AUX_SUBTITLES
- #include "PlaycoreNav_ClipsAuxSubtitles.h"
- #endif
- #ifdef AVI_DRM_SUPPORT
- #include "Playcore/Nav_Clips/AviDrm/libDrmDecrypt/DrmAdpApi.h"
- #endif
- #ifdef _DEBUG
- #include "CPUTimefunc.h"
- #endif
- #ifdef SUPPORT_FLASH_CARD
- #include "drivefe_manager.h"
- #include "mediacardsincluderegister.h"
- #endif
- /////////////////////////////////////////////////////////////////////////////
- // Globals and Singletions
- #define CALC_IDX_ENTRY_ADDRESS(address, offset) (address - (offset >> 1) - sizeof(IndexEntry)/2)
- static AVIIndexEntry* _idxEntries = NULL;
- static UINT16 _aviIdxIDiff;
- /* DRM info */
- #ifdef AVI_DRM_SUPPORT
- extern UINT16 uiAviDrmFrameKeyIndex;
- extern keyInstance* pMasterKeyInstance;
- WORD g_ScAviDrm_KeysOffset = SC_AVI_DRM_KEYS_ADDR;
- BOOL g_bDivxRentanSelection;
- BOOL g_bUserAck;
- UINT16 g_DivxRentalsLeft=0;
- UINT16 g_DivxRentalsTotal=0;
- #endif //AVI_DRM_SUPPORT
- // RB_TBD
- // Robin_1003_2004_D
- //static BOOL bVideoBeforeAudio = FALSE;
- // Robin_1003_2004_C
- static BOOL bVideoAudioInterleave = TRUE;
- #ifdef NO_AUTO_PLAY_FOR_CLIPS
- BOOL g_patch_4_auto_play;
- #endif
- extern CURRENT_STATES gcst; /* Global current status */
- extern BOOL change_pallet;
- // Robin_1119_2004, display AVI audio/subtitle language
- static CONST LanguageCode DIVX_LANGUAGE_CODE_LUT[] =
- {
- {""}, // 0 None
- {"Ara"}, // 1 Arabic
- {"Bul"}, // 2 Bulgarian
- {"Cat"}, // 3 Catalan
- {"Chi"}, // 4 Chinese
- {"Cze"}, // 5 Czech
- {"Dan"}, // 6 Danish
- {"Ger"}, // 7 German
- {"Gre"}, // 8 Greek
- {"Eng"}, // 9 English
- {"Spa"}, // 10 Spanish
- {"Fin"}, // 11 Finnish
- {"Fre"}, // 12 French
- {"Heb"}, // 13 Hebrew
- {"Hun"}, // 14 Hungarian
- {"Ice"}, // 15 Icelandic
- {"Ita"}, // 16 Italian
- {"Jap"}, // 17 Japanese
- {"Kor"}, // 18 Korean
- {"Dut"}, // 19 Dutch
- {"Nor"}, // 20 Norwegian
- {"Pol"}, // 21 Polish
- {"Por"}, // 22 Portuguese
- {"Rha"}, // 23 Rhaeto-Romanic
- {"Rom"}, // 24 Romanian
- {"Rus"}, // 25 Russian
- {"Cro"}, // 26 Croatian
- {"Slo"}, // 27 Slovak
- {"Alb"}, // 28 Albanian
- {"Swe"}, // 29 Swedish
- {"Tha"}, // 30 Thai
- {"Tur"}, // 31 Turkish
- {"Urd"}, // 32 Urdu
- {"Bah"}, // 33 Bahasa
- };
- /////////////////////////////////////////////////////////////////////////////
- #ifdef DIVX_SUPPORT_MULTI_SUBTITLE_MODE0
- extern WORD Get_SubFile_Select(void);
- #endif
- #ifdef MPP_SUPPORT
- extern void DEC_SetMPP(BOOL enable);
- #endif
- static BOOL _aviDetectBVOP(void);
- /////////////////////////////////////////////////////////////////////////////
- // Forward Declarations of Virtual Methods
- BOOL AVIClip_getExtendedInfo(const struct Clip_TAG *i_pThis, WORD i_pExtInfo_sc_handle);
- BOOL AVIClip_play(Clip *i_pThis, const ClipMarker *i_pResumeMarker, BOOL bCacheOnly);
- void AVIClip_pause(Clip *i_pThis, BOOL bEnable);
- void AVIClip_refresh(Clip *i_pThis);
- UINT16 AVIClip_getTime(const Clip *i_pThis);
- enClipStatus AVIClip_getStatus(const Clip *i_pThis);
- void AVIClip_scan(Clip *i_pThis, int iScanSpeed);
- void AVIClip_recordMarker(const Clip *i_pThis, ClipMarker *o_pMarker);
- void AVIClip_abort(Clip *i_pThis, BOOL bMaintainStandby);
- /////////////////////////////////////////////////////////////////////////////
- // Const Factory
- /* Valid Extenions List */
- BEGIN_CLIP_VALID_EXTENSIONS_MAP(AVI)
- CLIP_VALID_EXTENSIONS_ENTRY(L"AVI")
- CLIP_VALID_EXTENSIONS_ENTRY(L"DIVX")
- CLIP_VALID_EXTENSIONS_ENTRY(L"DIV")
- CLIP_VALID_EXTENSIONS_ENTRY(L"XVID")
- END_CLIP_VALID_EXTENSIONS_MAP()
- /* Constant Attributes */
- DECLARE_CLIP_CONST_ATTR(AVI,
- DECLARE_CLIP_VTABLE(AVIClip_getExtendedInfo,
- AVIClip_play,
- AVIClip_pause,
- AVIClip_getStatus,
- AVIClip_abort,
- AVIClip_recordMarker,
- AVIClip_refresh,
- AVIClip_getTime,
- GenericClip_digest,
- AVIClip_scan
- ),
- eClipType_AVI,
- 0xFF, 0xE0, DEC_DISC_TYPE_AVI, //FW0408_2005C Set 0xE0 as video SID
- (eCA_Scanable | eCA_Zoomable | eCA_Slowable | eCA_Markable/* | eCA_Digestable*/),
- NULL
- )
- /////////////////////////////////////////////////////////////////////////////
- // Private Services
- // <<< Robin_1003_2004_A, check the chunk offset in the Index is from the "movi"
- ///////////////////////////////////////////////////////////////////////////
- // Function name : _checkAVIClipOffset
- // Purpose : Check the offset in Index is from MOVI
- // Input Parameters : dwClipStartAddr - the clip start add
- // : dwMovieListOffset - the offset of Movi
- // Output Parameters :
- // Return type : BOOL
- ///////////////////////////////////////////////////////////////////////////
- static BOOL _checkAVIClipOffset(DWORD dwClipStartAddr, DWORD dwMovieListOffset)
- {
- IndexEntry indexEntry;
- DWORD dwOffset;
- DWORD dwFourCC;
- DWORD dwVideoStreamID1, dwVideoStreamID2;
- UINT16 uiCount;
- if (FALSE == _bMPEG4TrickModeOn)
- return FALSE;
- dwVideoStreamID1 = ((DWORD)('c') << 24) + ((DWORD)('d')<<16) + ((DWORD)(_mpeg4VideoStreamID+ '0') << 8) + '0';
- dwVideoStreamID2 = ((DWORD)('b') << 24) + ((DWORD)('d')<<16) + ((DWORD)(_mpeg4VideoStreamID + '0') << 8) + '0';
- for(uiCount=0;uiCount<2;uiCount++)
- {
- wai_sem(SEM_DRAM_ID);
- I49_ReadDRAMData(CALC_IDX_ENTRY_ADDRESS(MPEG4_PROCESSING_BUFF_ADDR,(uiCount*sizeof(IndexEntry))),
- (UINT16*)&indexEntry, sizeof(IndexEntry)/2);
- sig_sem( SEM_DRAM_ID );
- dwOffset = indexEntry.ulVideoChunkOffset + dwMovieListOffset - FOURCC_FIELD_LENGTH;
- AuxCache_GetBytes(dwClipStartAddr, dwOffset, FOURCC_FIELD_LENGTH, &dwFourCC);
- if ((dwFourCC != dwVideoStreamID1) && (dwFourCC != dwVideoStreamID2) )
- return FALSE;
-
- }
- return TRUE;
- }
- // >>> Robin_1003_2004_A
- ///////////////////////////////////////////////////////////////////////////
- // Function name : StringToFourCC
- // Purpose : Returns the FOURCC string type.
- // Input Parameters : fourCCstring - The FourCC string.
- // Output Parameters: none
- // Return type : The FourCC type.
- ///////////////////////////////////////////////////////////////////////////
- static EFourCCType StringToFourCC(char* fourCCstring)
- {
- if (0 == strnicmp(fourCCstring, VIDEO_STREAM_TYPE_ID, FOURCC_FIELD_LENGTH))
- {
- return EVids;
- }
- else if (0 == strnicmp(fourCCstring, AUDIO_STREAM_TYPE_ID, FOURCC_FIELD_LENGTH))
- {
- return EAuds;
- }
- else if (0 == strnicmp(fourCCstring, TEXT_STREAM_TYPE_ID, FOURCC_FIELD_LENGTH))
- {
- return ETxts;
- }
- else if (0 == strnicmp(fourCCstring, AVI_STREAM_HEADER_START_ID, FOURCC_FIELD_LENGTH))
- {
- return EStrl;
- }
- else if (0 == strnicmp(fourCCstring, AVI_STREAM_HEADER_ID, FOURCC_FIELD_LENGTH))
- {
- return EStrh;
- }
- else if (0 == strnicmp(fourCCstring, AVI_STREAM_FORMAT_ID, FOURCC_FIELD_LENGTH))
- {
- return EStrf;
- }
- else if (0 == strnicmp(fourCCstring, AVI_STREAM_HEADER_DATA_ID, FOURCC_FIELD_LENGTH))
- {
- return EStrd;
- }
- /* else */
- return EInvalid;
- }
- ///////////////////////////////////////////////////////////////////////////
- // Function name : _getAdjacentIFrames
- // Purpose : Returns the nearby I frames of the given time, with
- // their times.
- // Input Parameters : dwClipStartAddr - The start address of the clip.
- // wCurrTime - The current time.
- // Return type : TRUE - if succeeded, FALSE otherwise.
- // Output Parameters: The tow I frames numbers with their times.
- // Description :
- ///////////////////////////////////////////////////////////////////////////
- static BOOL _getAdjacentIFrames(DWORD dwClipStartAddr, WORD wCurrTime,
- UINT32* ulFirstIFrame, UINT32* ulSecondIFrame,
- WORD* wFirstITime, WORD* wSecondITime,
- UINT32* ulFirstIIdx, UINT32* ulSecondIIdx)
- {
- UINT32 ulIndex;
- UINT32 ulRequestedFrameNumber;
- IndexEntry currIndexEntry;
- IndexEntry previousIndexEntry;
- DWORD dwFirstChunkOffset;
- /* Read the index if it is not read yet */
- if (FALSE == _aquireAndProcessIdx(dwClipStartAddr, _mpeg4VideoStreamID, _mpeg4AudioStreamID,&dwFirstChunkOffset))
- {
- dbg_printf(("WARNING: _getAdjacentIFrames() FAILEDn"));
- return FALSE;
- }
- /* Calculate the frame number corresponding to the given time */
- // Robin_1003_2004_B
- ulRequestedFrameNumber = caclFrameOfTime(wCurrTime,
- _mpeg4VideoRate,
- _mpeg4VideoScale);
- /* Seek the index table to find the nearby I frames */
- for (ulIndex=0; ulIndex<_uiMPEG4NextIndexEntry; ulIndex++)
- {
- wai_sem(SEM_DRAM_ID);
- I49_ReadDRAMData(CALC_IDX_ENTRY_ADDRESS(MPEG4_PROCESSING_BUFF_ADDR, (ulIndex*sizeof(currIndexEntry))),
- (UINT16*)&currIndexEntry, sizeof(currIndexEntry)/2);
- sig_sem(SEM_DRAM_ID);
- if (currIndexEntry.ulVideoFrameNumber < ulRequestedFrameNumber)
- {
- /* Checking if this is the last entry */
- if ( (_uiMPEG4NextIndexEntry-1) == ulIndex )
- {
- /* Get the previous entry in the index table */
- wai_sem(SEM_DRAM_ID);
- I49_ReadDRAMData(CALC_IDX_ENTRY_ADDRESS(MPEG4_PROCESSING_BUFF_ADDR,((ulIndex-1)*sizeof(IndexEntry))),
- (UINT16*)&previousIndexEntry, sizeof(IndexEntry)/2);
- sig_sem(SEM_DRAM_ID);
- *ulFirstIIdx = ulIndex - 1;
- *ulSecondIIdx = ulIndex;
- break;
- }
- }
- else
- {
- /* Check if this is the first entry */
- if (0UL == ulIndex)
- {
- previousIndexEntry = currIndexEntry;
- /* Get the previous entry in the index table */
- wai_sem(SEM_DRAM_ID);
- I49_ReadDRAMData(CALC_IDX_ENTRY_ADDRESS(MPEG4_PROCESSING_BUFF_ADDR,((ulIndex+1)*sizeof(IndexEntry))),
- (UINT16*)&currIndexEntry, sizeof(IndexEntry)/2);
- sig_sem(SEM_DRAM_ID);
- *ulFirstIIdx = ulIndex;
- *ulSecondIIdx = ulIndex + 1;
- }
- else
- {
- /* Get the previous entry in the index table */
- wai_sem(SEM_DRAM_ID);
- I49_ReadDRAMData(CALC_IDX_ENTRY_ADDRESS(MPEG4_PROCESSING_BUFF_ADDR, ((ulIndex-1)*sizeof(IndexEntry))),
- (UINT16*)&previousIndexEntry, sizeof(IndexEntry)/2);
- sig_sem(SEM_DRAM_ID);
- *ulFirstIIdx = ulIndex - 1;
- *ulSecondIIdx = ulIndex;
- }
- break;
- }
- }
- // Robin_1003_2004_B
- *wFirstITime = caclTimeOfFrame(previousIndexEntry.ulVideoFrameNumber,
- _mpeg4VideoRate,
- _mpeg4VideoScale);
- // Robin_1003_2004_B
- *wSecondITime = caclTimeOfFrame(currIndexEntry.ulVideoFrameNumber,
- _mpeg4VideoRate,
- _mpeg4VideoScale);
- *ulFirstIFrame = previousIndexEntry.ulVideoFrameNumber;
- *ulSecondIFrame = currIndexEntry.ulVideoFrameNumber;
- return TRUE;
- }
- ///////////////////////////////////////////////////////////////////////////
- // Function name : _getNextIFrames
- // Purpose : Returns the next I frames of the given frame number, with
- // their indexs.
- // Input Parameters : dwClipStartAddr - The start address of the clip.
- // ulRequestedFrameNumber - The current frame number.
- // Return type : TRUE - if succeeded, FALSE otherwise.
- // Output Parameters: The next Iframe index.
- // Description :
- ///////////////////////////////////////////////////////////////////////////
- static BOOL _getNextIFrames(DWORD dwClipStartAddr, UINT32 ulRequestedFrameNumber,
- UINT32* ulNextIIdx, UINT16* wNextITime)
- {
- UINT32 ulIndex;
- IndexEntry currIndexEntry;
- DWORD dwFirstChunkOffset;
- // Read the index if it is not read yet
- if (FALSE == _aquireAndProcessIdx(dwClipStartAddr, _mpeg4VideoStreamID, _mpeg4AudioStreamID,&dwFirstChunkOffset))
- {
- dbg_printf(("WARNING: _getNextIFrames() FAILEDn"));
- return FALSE;
- }
- // Seek the index table to find the nearby I frames
- for (ulIndex=0; ulIndex<=_uiMPEG4NextIndexEntry; ulIndex++)
- {
- if(ulIndex == _uiMPEG4NextIndexEntry)
- {
- dbg_printf(("ulIndex == _uiMPEG4NextIndexEntryn"));
- break;
- }
-
- wai_sem(SEM_DRAM_ID);
- I49_ReadDRAMData(CALC_IDX_ENTRY_ADDRESS(MPEG4_PROCESSING_BUFF_ADDR, (ulIndex*sizeof(currIndexEntry))),
- (UINT16*)&currIndexEntry, sizeof(currIndexEntry)/2);
- sig_sem( SEM_DRAM_ID );
- if (currIndexEntry.ulVideoFrameNumber > ulRequestedFrameNumber)
- {
- break;
- }
- }
- *ulNextIIdx = ulIndex;
- // Robin_1003_2004_B
- *wNextITime = caclTimeOfFrame(currIndexEntry.ulVideoFrameNumber,
- _mpeg4VideoRate,
- _mpeg4VideoScale);
- return TRUE;
- }
- ///////////////////////////////////////////////////////////////////////////
- // Function name : _getNextFOURCC
- // Purpose : Returns the next FOURCC in the file.
- // Input Parameters : dwClipStartAddr - The start address to get the FOURCC.
- // dwOffset - The offset to read the FOURCC.
- // Return type : TRUE - if succeeded, FALSE otherwise.
- // Output Parameters: pForccInfo - The FOURCC info which was read.
- // Description : The function reads the first 32 bits from the
- // specified location, if it a 'LIST' FOURCC it returns
- // the list's type FOURCC (among the other things),
- // otherwise, it is assumed this is a chunk FOURCC.
- ///////////////////////////////////////////////////////////////////////////
- static BOOL _getNextFOURCC(DWORD dwClipStartAddr, DWORD dwOffset, FOURCCInfo* pForccInfo)
- {
- BYTE aCurrSize[4];
-
- if (!AuxCache_GetBytes(dwClipStartAddr, dwOffset, (WORD)FOURCC_FIELD_LENGTH, pForccInfo->aFOURCCBuff))
- {
- dbg_printf(("FATAL: _getNextList() Failed [1]n"));
- return FALSE;
- }
- pForccInfo->bIsList = FALSE;
- dwOffset += FOURCC_FIELD_LENGTH; /* Skipping the FOURCC field */
- /* Check whether the FOURCC is 'LIST' */
- if (0 == strnicmp((LPSTR)(pForccInfo->aFOURCCBuff), AVI_LIST_FOURCC_ID, FOURCC_FIELD_LENGTH))
- {
- /* List is detected */
- pForccInfo->bIsList = TRUE;
- dwOffset += SIZE_FIELD_LENGTH; /* Skipping the size field */
- /* Reading the list type FOURCC */
- if (!AuxCache_GetBytes(dwClipStartAddr, dwOffset, (WORD)FOURCC_FIELD_LENGTH, pForccInfo->aFOURCCBuff))
- {
- dbg_printf(("FATAL: _getNextList() Failed [2]n"));
- return FALSE;
- }
- dwOffset -= SIZE_FIELD_LENGTH; /* Updating the offset for the list size field */
- }
- /* Getting the list/chunk size */
- if (!AuxCache_GetBytes(dwClipStartAddr, dwOffset, (WORD)sizeof(aCurrSize), aCurrSize))
- {
- dbg_printf(("FATAL: _getNextList() Failed [3]n"));
- return FALSE;
- }
- pForccInfo->ulSize = ((*((UINT32*)aCurrSize) + 1) /2) * 2;// padding to word boundary
- return TRUE;
- }
- ///////////////////////////////////////////////////////////////////////////
- // Function name : _searchForFOURCC
- // Purpose : Searches for a specific FOURCC according to the
- // requested one.
- // Input Parameters : dwClipStartAddr - The start address to get the FOURCC.
- // pdwOffset - Pointer to the offset to read the FOURCC.
- // fourccName - The FOURCC to search for.
- // bReadFOURCCData - Indicates whether the FOURCC data
- // should be read.
- // Output Parameters: pForccInfo - The requested FOURCC info.
- // pdwOffset - Update the offset to the next chunk/list.
- // Return type : TRUE - if succeeded, FALSE otherwise.
- // Description :
- ///////////////////////////////////////////////////////////////////////////
- static BOOL _searchForFOURCC(DWORD dwClipStartAddr, DWORD* pdwOffset,
- LPSTR fourccName, FOURCCInfo* pFourccInfo, BOOL bReadFOURCCData, WORD wDataSize)
- {
- /* Keep checking the next available FOURCC till reaching the required one */
- while (TRUE)
- {
- /* Get the next FOURCC */
- if (FALSE == _getNextFOURCC(dwClipStartAddr, *pdwOffset, pFourccInfo))
- {
- dbg_printf(("FATAL: _searchForFOURCC() Failed [1]n"));
- return FALSE;
- }
- /* Check whether this is the FOURCC we are looking for */
- if (0 == strnicmp((LPSTR)pFourccInfo->aFOURCCBuff, fourccName, FOURCC_FIELD_LENGTH))
- {
- /* Reach the chunk/list data area */
- (*pdwOffset) += FOURCC_FIELD_LENGTH;
- (*pdwOffset) += SIZE_FIELD_LENGTH;
- if (TRUE == pFourccInfo->bIsList)
- {
- (*pdwOffset) += LIST_TYPE_FIELD_LENGTH;
- }
- /* Read the chunk/list data if required */
- if (TRUE == bReadFOURCCData)
- {
-
- if (!AuxCache_GetBytes(dwClipStartAddr, *pdwOffset, wDataSize, pFourccInfo->pData))
- {
- dbg_printf(("FATAL: _searchForFOURCC() Failed [2]n"));
- return FALSE;
- }
- }
- /* Update the offset to reach the next list/chunk */
- if (TRUE == pFourccInfo->bIsList)
- {
- (*pdwOffset) -= LIST_TYPE_FIELD_LENGTH;
- }
- (*pdwOffset) += (DWORD)pFourccInfo->ulSize;
- return TRUE;
- }
- /* Skip to the next list/chunk */
- (*pdwOffset) += FOURCC_FIELD_LENGTH;
- (*pdwOffset) += SIZE_FIELD_LENGTH;
- (*pdwOffset) += (DWORD)pFourccInfo->ulSize;
- // get the wrong data because bad disc
- if (4 > strlen((LPSTR)pFourccInfo->aFOURCCBuff))
- {
- tr_printf(("Failed: Wrong Fourcc, %s", (LPSTR)pFourccInfo->aFOURCCBuff));
- return FALSE;
- }
-
- }
- }
- ///////////////////////////////////////////////////////////////////////////
- // Function name : _searchForDrmFOURCC
- // Purpose : Searches for a DRM FOURCC, if found, all of the necessary
- // DRM data will be saved in the scratch pad.
- //
- // Input Parameters : DWORD dwClipStartAddr, - The start address to get the FOURCC
- // DWORD* pdwOffset, - Pointer to the offset to read the FOURCC.
- // FOURCCInfo* pFourccInfo - The FOURCC to search for (DRM)
- //
- // Output Parameters: None.
- // Return type : TRUE - if the stream should be played (DRM not found, or DRM found,
- // and its legal to play.
- // FALSE - if the steram should not be played (registration expired, etc.)
- ///////////////////////////////////////////////////////////////////////////
- static BOOL _searchForDrmFOURCC(DWORD dwClipStartAddr, DWORD* pdwOffset, FOURCCInfo* pFourccInfo)
- {
- #ifdef AVI_DRM_SUPPORT
-
- BYTE* drmInfoHeader;
- BYTE* drmPlayContext;
- uint8_t useLimit;
- uint8_t useCount;
- uint8_t result = DRM_ERROR_NONE;
- WORD wDataSize;
- UINT32 drm_length;
-
- dbg_printf(("Reset DRM globals.n"));
- uiAviDrmFrameKeyIndex = -1;
- if (NULL != pMasterKeyInstance)
- {
- free (pMasterKeyInstance);
- dbg_printf(("key instance was set in the beggining!n"));
- pMasterKeyInstance = NULL;
- }
-
- /* Get the next FOURCC */
- if (FALSE == _getNextFOURCC(dwClipStartAddr, *pdwOffset, pFourccInfo))
- {
- dbg_printf(("no DRMn"));
- _bAVIDrmOn = FALSE;
- return TRUE;
- }
-
- /* Check if this fourCC is DRM (assuming the strl was video */
- if (0 == strnicmp((LPSTR)pFourccInfo->aFOURCCBuff, AVI_STREAM_HEADER_DATA_ID, FOURCC_FIELD_LENGTH))
- {
- /* Reach the chunk/list data area */
- (*pdwOffset) += FOURCC_FIELD_LENGTH;
- (*pdwOffset) += SIZE_FIELD_LENGTH;
-
- // Robin_2004_0525_A, patch for the "strd" chunk, no DRM information
- (*pdwOffset) += 4;
- if (!AuxCache_GetBytes(dwClipStartAddr, *pdwOffset, 4, &drm_length))
- {
- dbg_printf(("FATAL: _searchForFOURCC() Failed [3]n"));
- return TRUE;
- }
- (*pdwOffset) += 4;
- // The condition is not accurate, Robin_2004_0525_A
- if ((drm_length >= 2224) && (pFourccInfo->ulSize >= 2232))
- {
- dbg_printf(("DRM onn"));
- _bAVIDrmOn = TRUE;
- #ifdef SUPPORT_FLASH_CARD //DIVX with DRM is not supported on card.
- if(IS_PLAYING_CARD)
- return FALSE;
- #endif
- }
- else
- {
- dbg_printf(("no DRMn"));
- _bAVIDrmOn = FALSE;
- return TRUE;
- }
- // <<< Robin_2004_0525_A
- /* prase DRM data */
-
- /* Read the chunk/list data if required */
- wDataSize = (FALSE == pFourccInfo->bIsList) ?
- ((WORD)pFourccInfo->ulSize ) :
- ((WORD)pFourccInfo->ulSize - LIST_TYPE_FIELD_LENGTH);
-
- #ifdef AVI_MALLOC_SIZE_DOWN
- // wDataSize -= DRM_FRAME_KEY_COUNT * KEY_SIZE_BYTES;
- wDataSize = sizeof (DrmHeader);
- #endif
- drmPlayContext = (BYTE*)malloc (wDataSize+1);
- drmInfoHeader = drmPlayContext ; // pointer assignment!
- //drmInfoHeader = (BYTE*)malloc (wDataSize);
-
- if ( NULL == drmInfoHeader)
- {
- dbg_printf(("malloc drm info header size: %d failed!!n",wDataSize));
- return FALSE;
-
- }
- else
- {
- dbg_printf(("malloc drm info header size: %d successfulln",wDataSize));
- }
-
- if (!AuxCache_GetBytes(dwClipStartAddr, *pdwOffset, wDataSize, drmInfoHeader))
- {
- dbg_printf(("FATAL: _searchForFOURCC() Failed [2]n"));
- free (drmInfoHeader);
- return TRUE;
- }
-
- result = drmInitPlaybackContext( drmPlayContext );
- if (DRM_ERROR_NONE != result)
- {
- ie_send(IE_UI_DIVX_MSG_AUTHORIZATION_ERROR);
- dbg_printf(("1 DRM Message 1 (generic), code %d - Screen 2n", result));
- free (drmInfoHeader);
- gcs.pstate= PST_STOP;
- return FALSE;
- }
-
- result = drmQueryRentalStatus(drmPlayContext, &useLimit, &useCount);
- if (DRM_ERROR_RENTAL_EXPIRED == result)
- {
- ie_send(IE_UI_DIVX_MSG_RENTAL_EXPIRED);
- dbg_printf(("2 DRM Message 2 (expired), code %d - Screen 3n", result));
- free (drmInfoHeader);
- gcs.pstate= PST_STOP;
- return FALSE;
- }
- if (DRM_ERROR_NOT_AUTH_USER == result)
- {
- ie_send(IE_UI_DIVX_MSG_AUTHORIZATION_ERROR);
- dbg_printf(("3 DRM Message 3 (not auth user), code %d - Screen 2n", result));
- free (drmInfoHeader);
- gcs.pstate= PST_STOP;
- return FALSE;
- }
- if (DRM_ERROR_NOT_LIMITED_RENTAL_TYPE != result &&
- DRM_ERROR_NONE != result)
- {
- ie_send(IE_UI_DIVX_MSG_AUTHORIZATION_ERROR);
- dbg_printf(("4 DRM Message 1 (generic), code %d - Screen 2n", result));
- free (drmInfoHeader);
- gcs.pstate= PST_STOP;
- return FALSE;
- }
- if (useLimit > 0)
- {
- // char buffer[10];
- UINT16 watchdog=0;
- dbg_printf(("You have %d out of %d views. Ok to continue (y or n)? - Screen 4n", useCount, useLimit));
- g_DivxRentalsLeft = (UINT16)(useLimit - useCount);
- g_DivxRentalsTotal = useLimit;
- g_bUserAck = FALSE;
- g_bDivxRentanSelection = FALSE;
- dbg_printf(("g_bUserAck: %sn", (g_bUserAck)? "TRUE":"FALSE"));
- ie_send(IE_UI_DIVX_RENTAL_CONFIRM);
- // here we should wait for UI response
- // Robin_0715_2004, merge changelist #24356
- while( !g_bUserAck && watchdog++ < 1000 )
- {
- usleep(100000UL); // wait
- }
- if(!g_bUserAck)
- ie_send(IE_UI_CLOSE_MENU); //inform UI close DRM menu
-
- if ( g_bDivxRentanSelection == FALSE)
- {
- dbg_printf(("g_bDivxRentanSelection DONT PLAYn"));
- dbg_printf(("Playback canceled.n"));
- free (drmInfoHeader);
- return FALSE;
- }
- /* LOTAN */
- dbg_printf(("g_bDivxRentanSelection PLAYn"));
- }
- #ifdef AVI_MALLOC_SIZE_DOWN
- result = drmCommitPlayback( drmInfoHeader, dwClipStartAddr, *pdwOffset );
- #else
- result = drmCommitPlayback( drmInfoHeader );
- #endif
- if (result != DRM_ERROR_NONE)
- {
- if (DRM_ERROR_NOT_AUTH_USER == result)
- {
- ie_send(IE_UI_DIVX_MSG_AUTHORIZATION_ERROR);
- dbg_printf(("5 DRM Message 3 (not auth user), code %d - Screen 2n", result));
- free(drmInfoHeader);
- gcs.pstate= PST_STOP;
- return FALSE;
- }
-
- if (DRM_ERROR_RENTAL_EXPIRED == result)
- {
- ie_send(IE_UI_DIVX_MSG_RENTAL_EXPIRED);
- dbg_printf(("6 DRM Message 2 (expired), code %d - Screen 3n", result));
- free (drmInfoHeader);
- gcs.pstate= PST_STOP;
- return FALSE;
- }
-
- ie_send(IE_UI_DIVX_MSG_AUTHORIZATION_ERROR);
- dbg_printf(("7 DRM Message 1 (generic), code %d - Screen 2n", result));
- free (drmInfoHeader);
- gcs.pstate= PST_STOP;
- return FALSE;
- }
-
- sc_SetBytes(g_ScAviDrm_KeysOffset, 0, wDataSize, (BYTE *)drmInfoHeader);
-
- free (drmInfoHeader);
-
- /* Update the offset to reach the next list/chunk */
- if (TRUE == pFourccInfo->bIsList)
- {
- (*pdwOffset) -= LIST_TYPE_FIELD_LENGTH;
- }
- (*pdwOffset) += (DWORD)pFourccInfo->ulSize;
- return TRUE;
- }
- else
- #endif // AVI_DRM_SUPPORT
- {
- dbg_printf(("no DRMn"));
- _bAVIDrmOn = FALSE;
- }
-
- return TRUE;
-
-
- }
- ///////////////////////////////////////////////////////////////////////////
- // Function name : _aquireAVIStreamsInfo
- // Purpose : Reads the 'strl' lists from the AVI file header.
- // Input Parameters : dwClipStartAddr - The start address to get the lists.
- // dwOffset - The offset to read the lists.
- // Return type : TRUE - if succeeded, FALSE otherwise.
- // Description : The function aquires the streams info by reading the
- // 'strl' lists from the AVI file header up to the
- // maximum number of streams.
- // Currently, the function reads the first Video and Audio
- // streams only.
- ///////////////////////////////////////////////////////////////////////////
- static BOOL _aquireAVIStreamsInfo(DWORD dwClipStartAddr, DWORD dwOffset, DWORD *dwStrdOffset)
- {
- FOURCCInfo currFourcc;
- DWORD dwOrginalOffset = dwOffset;
- DWORD dwNextStrlOffset = 0UL;
- BOOL bVideoStreamFound = FALSE;
- BOOL bLookForDRM = FALSE;
- UINT8 uiCounter = 0, uiAudioCnt = 0, uiSubtitleCnt = 0;
- EFourCCType eFourCcType;
- AVIStreamHeader aviStreamheader;
- BitMapInfoHeader* pBitmapInfoHeader;
- WaveFormat* pWaveFormatInfo;
- LanguageCode *languageCode;
-
- _mpeg4VideoStreamID = NO_STREAM;
- _mpeg4AudioStreamID = NO_STREAM;
- _mpeg4SubtitleStreamID = NO_STREAM;
-
- // clear the audio stream info
- memset((BYTE*)&_mpeg4AudioStreamInfo, 0, SIZE_OF_AUDIO_STREAM_INFO);
- sc_SetBytes(SC_MPEG4_AUDIO_STREAM_INFO_ADDR,
- 0,
- SIZE_OF_AUDIO_STREAM_INFO,
- (BYTE*)&_mpeg4AudioStreamInfo
- );
-
- uiCounter = 0;
- _mpeg4SubtitleAvailableNum =0;
- _mpeg4SubtitleInternalAvailableNum = 0;
- _mpeg4AudioAvailableNum =0;
- _mpeg4ChapterAvailableNum =0;
- _mpeg4VideoScale = 1;
- _mpeg4VideoRate = 30;// supposed
- /* Reach the first video and audio streams */
- while (TRUE)
- {
- /* Get the next FOURCC */
- if (FALSE == _getNextFOURCC(dwClipStartAddr, dwOffset, &currFourcc))
- {
- dbg_printf(("FATAL: _aquireAVIStreamsInfo() Failed [1]n"));
- return FALSE;
- }
- /* Reach the data zone of the list/chunk */
- dwNextStrlOffset += (DWORD)currFourcc.ulSize;
- dwNextStrlOffset += FOURCC_FIELD_LENGTH;
- dwNextStrlOffset += SIZE_FIELD_LENGTH;
-
- /* Checking for 'strl' chunk */
- if (0 == strnicmp((LPSTR)currFourcc.aFOURCCBuff, AVI_STREAM_HEADER_START_ID, FOURCC_FIELD_LENGTH))
- {
- CHAR streamType[FOURCC_FIELD_LENGTH] = {0};
-
- /* Reach the internal chunks */
- dwOffset += FOURCC_FIELD_LENGTH;
- dwOffset += SIZE_FIELD_LENGTH;
- dwOffset += LIST_TYPE_FIELD_LENGTH;
-
- /* Read 'strh' and 'strf' couple */
- currFourcc.pData = (BYTE*)(&aviStreamheader);
- if ( FALSE == _searchForFOURCC(dwClipStartAddr, &dwOffset, AVI_STREAM_HEADER_ID, &currFourcc, TRUE, sizeof(AVIStreamHeader)) )
- {
- dbg_printf(("FATAL: _aquireAVIStreamsInfo() Failed [2]n"));
- return FALSE;
- }
- // Robin_1119_2004, display AVI audio/subtitle language
- languageCode = &DIVX_LANGUAGE_CODE_LUT[aviStreamheader.wLanguage];
-
- /* Determie what data 'strf' chunk contains */
- convertFOURCCToString(aviStreamheader.fccType, streamType);
-
- eFourCcType = StringToFourCC(streamType);
-
- switch (eFourCcType)
- {
- case (EVids):
- if (FALSE == bVideoStreamFound)
- {
- /* Video Stream */
- while (aviStreamheader.dwRate>1000000UL)
- {
- aviStreamheader.dwRate = aviStreamheader.dwRate / 10;
- aviStreamheader.dwScale = (aviStreamheader.dwScale+5) / 10;
- }
-
- _mpeg4VideoScale = aviStreamheader.dwScale;
- _mpeg4VideoRate = aviStreamheader.dwRate;
- _mpeg4VideoLength = aviStreamheader.dwLength;
- // _aviVideoStreamInfo._aviStreamType = AVI_VIDEO_STREAM;
- bVideoStreamFound = TRUE;
- bLookForDRM = TRUE;
- // _mpeg4VideoStreamID = uiCounter; // Robin_0527_2004_B, fix the first stream not video stream
- pBitmapInfoHeader = malloc(sizeof(BitMapInfoHeader));
- if( NULL == pBitmapInfoHeader)
- {
- tr_printf(("FATAL: _aquireAVIStreamsInfo() Failed [3]: Malloc failed. Low system resource.n"));
- return FALSE;
- }
- currFourcc.pData = (BYTE*)(pBitmapInfoHeader);
- /* Read the 'strf' chunk according to the stream type */
- if ( FALSE == _searchForFOURCC(dwClipStartAddr, &dwOffset, AVI_STREAM_FORMAT_ID, &currFourcc, TRUE, sizeof(BitMapInfoHeader)) )
- {
- dbg_printf(("FATAL: _aquireAVIStreamsInfo() Failed [4]n"));
- free(pBitmapInfoHeader);
- return FALSE;
- }
- // Robin_0809_2004, store the video header data
- _mpeg4VideoHeight = (WORD)(pBitmapInfoHeader->lHeight & 0xFFFF);
- _mpeg4VideoWidth = (WORD)(pBitmapInfoHeader->lWidth & 0xFFFF);
- _mpeg4VideoCodec = determineDivXVersion(aviStreamheader.fccHandler,pBitmapInfoHeader->dwCompression);
- free(pBitmapInfoHeader);
-
- if (DIVX_UNKNOWN == _mpeg4VideoCodec)
- {
- continue;
- }
- if (currFourcc.ulSize > 0x28)
- {
- WORD wVideoHeaderSize;
- WORD wOffset;
- BOOL bFirst = TRUE;
- BOOL bFoundStartCode = FALSE;
- WORD wVideoHeaderCacheSize;
-
- BYTE videoHeaderBuff[MPEG4_VIDEO_HEADER_CACHE_SIZE];
- dbg_printf(("The video strf size more than 0x28 n"));
- wVideoHeaderSize = (WORD)(currFourcc.ulSize - 0x28);
- wOffset = 0;
- _mpeg4VideoHeaderDataLength = 0;
- while(wVideoHeaderSize > 0)
- {
- wVideoHeaderCacheSize = min(wVideoHeaderSize,MPEG4_VIDEO_HEADER_CACHE_SIZE);
- if (!AuxCache_GetBytes(dwClipStartAddr, (dwOffset - wVideoHeaderSize), (WORD)wVideoHeaderCacheSize, videoHeaderBuff))
- {
- dbg_printf(("FATAL: _aquireAVIStreamsInfo() Failed [5]n"));
- return FALSE;
- }
- if(TRUE == (wVideoHeaderCacheSize & 0x1))
- videoHeaderBuff[wVideoHeaderCacheSize] = 0;
- wVideoHeaderCacheSize += (wVideoHeaderCacheSize & 0x1);
- if (TRUE == bFirst)
- {
- int i;
- for (i=0; i<(MPEG4_VIDEO_HEADER_CACHE_SIZE -4);i++)
- {
- if(videoHeaderBuff[i] != 0)
- break;
- if(videoHeaderBuff[i+1] != 0)
- break;
- if((videoHeaderBuff[i+2] != 0) && (videoHeaderBuff[i+2] != 1) )
- break;
- if(videoHeaderBuff[i+2] == 1)
- {
- bFoundStartCode = TRUE;
- break;
- }
- }
- bFirst = FALSE;
- }
- if(FALSE ==bFoundStartCode)
- {
- dbg_printf(("Not found video start code n"));
- break;
- }
- sc_SetBytes(SC_MPEG4_VIDEO_HEADER_DATA_ADDR,
- wOffset,
- wVideoHeaderCacheSize,
- (BYTE*)&videoHeaderBuff
- );
-
- wVideoHeaderSize -= wVideoHeaderCacheSize;
- wOffset += wVideoHeaderCacheSize;
- if ((videoHeaderBuff[wVideoHeaderCacheSize-1] == 0) &&
- (videoHeaderBuff[wVideoHeaderCacheSize-2] == 0) &&
- (videoHeaderBuff[wVideoHeaderCacheSize-3] == 0) &&
- (videoHeaderBuff[wVideoHeaderCacheSize-4] == 0))
- break;
- }
-
- if (wOffset > MPEG4_VIDEO_HEADER_BUFFER_SIZE)
- dbg_printf(("Video header data length more than 1024bytes! n"));
- _mpeg4VideoHeaderDataLength = wOffset;
- }
-
- _mpeg4VideoStreamID = uiCounter; // Robin_0527_2004_B, fix the first stream not video stream
- // Robin_0705_2004, restrict DivX image size not exceed 720x576
- {
- WORD wNumOfMB = ((_mpeg4VideoWidth + 15) / 16) * ((_mpeg4VideoHeight + 15) / 16);
- if(wNumOfMB > 1620) // 720x576/256
- {
- dbg_printf(("Too large image size! Width: %d, Height: %dn",_mpeg4VideoWidth,_mpeg4VideoHeight));
- return FALSE;
- }
- if(_mpeg4VideoWidth > 720)
- {
- dbg_printf(("Too large image width! Playback with artifacts! Width: %d, Height: %dn",_mpeg4VideoWidth,_mpeg4VideoHeight));
- }
- }
- }
- else
- {
- /* Subtitle Stream */
- if (uiSubtitleCnt >= MAX_SUB_PER_CLIP)
- {
- tr_printf(("TOO MUCH SUBTITLE STREAMSn"));
- }
- else
- {
- _mpeg4SubtitleStreamID = uiCounter;
- _mpeg4SubtitleType = INTERNAL_SUBP; // RB_TBD
- memcpy(_mpeg4SubtitleLanguageCode,languageCode,3);
- sc_SetBytes(SC_MPEG4_SUBTITLE_STREAM_INFO_ADDR,
- (uiSubtitleCnt * SIZE_OF_SUBTITLE_STREAM_INFO),
- SIZE_OF_SUBTITLE_STREAM_INFO,
- (BYTE*)&_mpeg4SubtitleStreamInfo
- );
-
- uiSubtitleCnt++;
- _mpeg4SubtitleAvailableNum = uiSubtitleCnt;
- _mpeg4SubtitleInternalAvailableNum = uiSubtitleCnt;
- }
- }
- break;
- case (EAuds):
- if (uiAudioCnt >= MAX_AUDS_PER_CLIP)
- {
- tr_printf(("TOO MUCH AUDIO STREAMSn"));
- }
- else
- {
- _mpeg4AudioScale = aviStreamheader.dwScale;
- _mpeg4AudioRate = aviStreamheader.dwRate;
- _mpeg4AudioLength = aviStreamheader.dwLength;
- // _aviAudioStreamInfo._aviStreamType = AVI_AUDIO_STREAM;
-
- pWaveFormatInfo = (WaveFormat*)malloc(sizeof(WaveFormat));
- if( NULL == pWaveFormatInfo)
- {
- tr_printf(("FATAL: _aquireAVIStreamsInfo() Failed [6]: Malloc failed. Low system resource.n"));
- return FALSE;
- }
- currFourcc.pData = (BYTE*)pWaveFormatInfo;
- /* Read the 'strf' chunk according to the stream type */
- if ( FALSE == _searchForFOURCC(dwClipStartAddr, &dwOffset, AVI_STREAM_FORMAT_ID, &currFourcc, TRUE, sizeof(WaveFormat)) )
- {
- dbg_printf(("FATAL: _aquireAVIStreamsInfo() Failed [7]n"));
- free(pWaveFormatInfo);
- return FALSE;
- }
-
- _mpeg4AudioSamplesPerSec = pWaveFormatInfo->wave.dwSamplesPerSec;
- _mpeg4AudioCodec = determineAudioCodec(0UL, pWaveFormatInfo->wave.wFormatTag, FALSE);
- if (AUDIO_UNKNOWN == _mpeg4AudioCodec)
- {
- free(pWaveFormatInfo);
- break;
- }
- #ifdef D_ENABLE_ADPCM_SUPPORT
- if ((ADPCM == _mpeg4AudioCodec) ||(PCM == _mpeg4AudioCodec))
- {
- // _mpeg4AudioChannels_ADPCM = pWaveFormatInfo->wave.wChannels;
- _mpeg4AudioSamplesPerBlock_ADPCM = pWaveFormatInfo->adpcm.wSamplesPerBlock;
- _mpeg4AudioBlockAlign_ADPCM = pWaveFormatInfo->wave.wBlockAlign;
- }
- if (PCM == _mpeg4AudioCodec)
- _mpeg4AudioBitsPerSample_ADPCM = (8 * pWaveFormatInfo->wave.wBlockAlign) / pWaveFormatInfo->wave.wChannels;
- else if (ADPCM == _mpeg4AudioCodec)
- _mpeg4AudioBitsPerSample_ADPCM = pWaveFormatInfo->wave.wBitsPerSample;
- #endif
- #ifdef D_ENABLE_DIVX_WMA_SUPPORT
- if (WMA == _mpeg4AudioCodec)
- {
- // _mpeg4AudioChannels_WMA = pWaveFormatInfo->wave.wChannels;
- _mpeg4AudioBlockAlign_WMA = pWaveFormatInfo->wave.wBlockAlign;
- _mpeg4AudioEncoderOptions_WMA = pWaveFormatInfo->wma.wEncoderOptions;
- }
- #endif
- _mpeg4AudioChannels = pWaveFormatInfo->wave.wChannels;
- _mpeg4AudioAvgBytesPerSec = pWaveFormatInfo->wave.dwAvgBytesPerSec;
- _mpeg4AudioStreamID = uiCounter;
- memcpy(_mpeg4AudioLanguageCode,languageCode,3);
- sc_SetBytes(SC_MPEG4_AUDIO_STREAM_INFO_ADDR,
- (uiAudioCnt * SIZE_OF_AUDIO_STREAM_INFO),
- SIZE_OF_AUDIO_STREAM_INFO,
- (BYTE*)&_mpeg4AudioStreamInfo
- );
-
- uiAudioCnt++;
- _mpeg4AudioAvailableNum = uiAudioCnt;
- free(pWaveFormatInfo);
- }
- break;
- // Robin_0117_2005, support AVI internal text subtitle
- #if 0
- case(ETxts):
- /* Subtitle Stream (Text) */
- if (uiSubtitleCnt >= MAX_SUB_PER_CLIP)
- {
- tr_printf(("TOO MUCH SUBTITLE STREAMSn"));
- }
- else
- {
- _mpeg4SubtitleStreamID = uiCounter;
- _mpeg4SubtitleType = AVI_INTERNAL_TEXT; // RB_TBD
- memcpy(_mpeg4SubtitleLanguageCode,languageCode,3);
- sc_SetBytes(SC_MPEG4_SUBTITLE_STREAM_INFO_ADDR,
- (uiSubtitleCnt * SIZE_OF_SUBTITLE_STREAM_INFO),
- SIZE_OF_SUBTITLE_STREAM_INFO,
- (BYTE*)&_mpeg4SubtitleStreamInfo
- );
-
- uiSubtitleCnt++;
- _mpeg4SubtitleAvailableNum = uiSubtitleCnt;
- }
- break;
- #endif
-
- }
- while (dwOffset < (dwNextStrlOffset + dwOrginalOffset))
- {
- // Get the next FOURCC
- if (FALSE == _getNextFOURCC(dwClipStartAddr, dwOffset, &currFourcc))
- {
- dbg_printf(("FATAL: _aquireAVIStreamsInfo() Failed [6]n"));
- return FALSE;
- }
-
- if (0 == strnicmp((LPSTR)currFourcc.aFOURCCBuff, AVI_STREAM_HEADER_DATA_ID, FOURCC_FIELD_LENGTH)) // "strd"
- {
- // DRM data
- if ( bLookForDRM )
- {
- *dwStrdOffset = dwOffset;
- bLookForDRM = FALSE;
- }
- }
-
- dwOffset += FOURCC_FIELD_LENGTH;
- dwOffset += SIZE_FIELD_LENGTH;
- dwOffset += currFourcc.ulSize;
- }
-
- uiCounter++;
-
- }
- else
- {
- /* No more 'strl' chunks exist, finish */
- break;
- }
-
- /* Skip to the next 'strl' chunk */
- dwOffset = dwNextStrlOffset + dwOrginalOffset;
- }
- return TRUE;
- }
- ///////////////////////////////////////////////////////////////////////////
- // Function name : _aquireAVIInfo
- // Purpose : Reads all the needed data from the AVI file header.
- // Input Parameters : dwClipStartAddr - The start address of the AVI file.
- // Return type : TRUE - if succeeded, FALSE otherwise.
- // Description : The function reads all the data needed for managing
- // of the playback including parameters needed by the
- // DVP.
- ///////////////////////////////////////////////////////////////////////////
- static BOOL _acquireAVIInfo(DWORD dwClipStartAddr)
- {
- FOURCCInfo currFourcc;
- DWORD dwOffset = AVI_HEADER_OFFSET;
- AVIMainHeader* pAviMainHeader;
- DWORD dwStrdOffset = 0;
- dbg_printf(("Aquiring AVI file info...n"));
- /* Verifying that the RIFF file is an AVI one */
- if (!AuxCache_GetBytes(dwClipStartAddr, AVI_ID_OFFSET, (WORD)FOURCC_FIELD_LENGTH, currFourcc.aFOURCCBuff))
- {
- dbg_printf(("FATAL: _acquireAVIInfo() Failed [1]n"));
- return FALSE;
- }
- if (0 == strnicmp((LPSTR)(currFourcc.aFOURCCBuff), AVI_FILE_ID, FOURCC_FIELD_LENGTH))
- {
- dbg_printf(("AVI FOURCC detected...n"));
- }
- else
- {
- tr_printf(("FATAL: AVI FOURCC was not detectedn"));
- return FALSE;
- }
- /* Reading the AVI file header */
- while (TRUE)
- {
- if (FALSE == _getNextFOURCC(dwClipStartAddr, dwOffset, &currFourcc))
- {
- dbg_printf(("FATAL: _acquireAVIInfo() Failed [2]n"));
- return FALSE;
- }
- /* Checking if we reached the start of the header */
- else if (0 == strnicmp((LPSTR)currFourcc.aFOURCCBuff, AVI_HEADER_START_ID, FOURCC_FIELD_LENGTH))
- {
- /* Updating offset to reach the next chunks */
- dwOffset += FOURCC_FIELD_LENGTH;
- dwOffset += SIZE_FIELD_LENGTH;
- dwOffset += LIST_TYPE_FIELD_LENGTH;
- break;
- }
- /* Skipping the list/chunk */
- dwOffset += FOURCC_FIELD_LENGTH;
- dwOffset += SIZE_FIELD_LENGTH;
- dwOffset += (DWORD)currFourcc.ulSize;
- }
- /* Read the 'avih' chunk */
- pAviMainHeader = malloc(sizeof(AVIMainHeader));
- if( NULL == pAviMainHeader)
- {
- tr_printf(("FATAL: _acquireAVIInfo() Failed [3]: Malloc failed. Low system resource.n"));
- return FALSE;
- }
-
- currFourcc.pData = (BYTE*)(pAviMainHeader);
- if ( FALSE == _searchForFOURCC(dwClipStartAddr, &dwOffset, AVI_MAIN_HEADER_ID, &currFourcc, TRUE, sizeof(AVIMainHeader)) )
- {
- dbg_printf(("FATAL: _acquireAVIInfo() Failed [4]n"));
- free(pAviMainHeader);
- return FALSE;
- }
- _bAVIHasIndex = (pAviMainHeader->dwFlags & AVI_HAS_INDEX) ? TRUE : FALSE;
- free(pAviMainHeader);
- /* Read the streams info */
- if (FALSE == _aquireAVIStreamsInfo(dwClipStartAddr, dwOffset, &dwStrdOffset))
- {
- dbg_printf(("FATAL: _acquireAVIInfo() Failed [5]n"));
- return FALSE;
- }
- if (dwStrdOffset != 0)
- {
- if ( FALSE == _searchForDrmFOURCC(dwClipStartAddr, &dwStrdOffset, &currFourcc ))
- {
- dbg_printf(("clip fail becuase of DRMn"));
- return FALSE;
- }
- }
- /* Check if the 'INFO' list is avaiable */
- /* dwOffset = AVI_HEADER_OFFSET;
-
- if ( TRUE == _searchForFOURCC(dwClipStartAddr, &dwOffset, AVI_INFO_LIST_ID, &currFourcc, FALSE, 0) )
- {
- /* Read ISFT chunk from INFO list */
- /* Update the offset to reach the info list data */
- /* dwOffset -= (DWORD)currFourcc.ulSize;
- dwOffset += FOURCC_FIELD_LENGTH;
- if ( TRUE == _searchForFOURCC(dwClipStartAddr, &dwOffset, AVI_ISET_CHUNK_ID, &currFourcc, FALSE, 0) )
- {
- BYTE aISFTBuff[VIRTUALDUB_ID_LENGTH];
- /* update the offset to reach "ISFT" chunk data*/
- /* dwOffset -= (DWORD)currFourcc.ulSize;
- if (discGetBytes(dwClipStartAddr, dwOffset, (WORD)VIRTUALDUB_ID_LENGTH, aISFTBuff))
- {
- if ( (0 == strnicmp((LPSTR)aISFTBuff, AVI_NANDUB_ID, NANDUB_ID_LENGTH)) ||
- (0 == strnicmp((LPSTR)aISFTBuff, AVI_VIRTUALDUB_ID, VIRTUALDUB_ID_LENGTH)) )
- {
- dbg_printf(("Nandub is detected....n"));
- _aviFileInfo.bIsNandub = TRUE;
- }
- }
- }
- }*/
- return TRUE;
- }
- ///////////////////////////////////////////////////////////////////////////
- // Function name : _getIdxEntry
- // Purpose : Retuns the next entry in the index table.
- // Input Parameters : dwClipStartAddr - The start address to get the entries.
- // dwOffset - The offset to read the entries.
- // Return type : TRUE if the operation succeeded, FALSE otherwise.
- // Description : The function reads several idx entries and returns the
- // first one. Upon calling of the function, if the
- // entry already exists from previous reading then it is
- // returned, otherwise, another segment of entries is read.
- // The caching of the entries is used for speeding up
- // idx processing.
- ///////////////////////////////////////////////////////////////////////////
- static BOOL _getIdxEntry(DWORD dwClipStartAddr, DWORD dwOffset, DWORD ulIdxSize,
- AVIIndexEntry* pCurrEntry, BOOL bFirstTime, UINT32 ulLeftIdxSize)
- {
- if (NULL == _idxEntries)
- return FALSE;
-
- /* Check whether the entry already exist in the cache */
- if (NUM_OF_IDX_ENTRIES_CACHE == _uiAVICurrCachedIdxEntry)
- {
- /* Read the next segment of idx entries */
- /* Check if the left size is lower than the entries cache size */
- if (ulLeftIdxSize < (WORD)(NUM_OF_IDX_ENTRIES_CACHE*sizeof(AVIIndexEntry)))
- {
- if (!AuxCache_GetFile(dwClipStartAddr, dwOffset, (WORD)ulLeftIdxSize,
- ulIdxSize, bFirstTime, (BYTE*)_idxEntries))
- {
- dbg_printf(("FATAL: _cacheIdxEntries() Failed[1]n"));
- return FALSE;
- }
- }
- else
- {
- if (!AuxCache_GetFile(dwClipStartAddr, dwOffset, (WORD)(NUM_OF_IDX_ENTRIES_CACHE*sizeof(AVIIndexEntry)),
- ulIdxSize, bFirstTime, (BYTE*)_idxEntries))
- {
- dbg_printf(("FATAL: _cacheIdxEntries() Failed[2]n"));
- return FALSE;
- }
- }
- _uiAVICurrCachedIdxEntry = 0;
- }
- *pCurrEntry = _idxEntries[_uiAVICurrCachedIdxEntry++];
- return TRUE;
- }
- ///////////////////////////////////////////////////////////////////////////
- // Function name : _saveIdxEntry
- // Purpose : Saving an idx entry in the memory.
- // Input Parameters : ulVidFrameNumber - Video frame number to save.
- // dwVidChunkOffset - Video chunk offset.
- // dwVidChunkSize - Video chunk size.
- // dwAudioChunkOffset - Corresponding audio chunk offset.
- // dwAudioChunkDelta - Offset within the audio chunk.
- // uiSkipVideoChunks - Video frames between the audio
- // chunk and the appropiate video one.
- // uiSkipAudioChunks - Audio chunks to skip
- // Return type : TRUE if the operation succeeded, FALSE otherwise.
- ///////////////////////////////////////////////////////////////////////////
- // <<< Robin_1003_2004_D
- static BOOL _saveIdxEntry(UINT32 ulVidFrameNumber, DWORD dwVidChunkOffset, DWORD dwVidChunkSize,
- DWORD dwAudioChunkOffset, DWORD dwAudioChunkDelta, UINT16 uiSkipVideoChunks, UINT16 uiSkipAudioChunks)
- {
- IndexEntry indexEntry;
- /* Check whether we are out of memory */
- if (_uiMPEG4NextIndexEntry >= MAX_NUMBER_OF_IDX_ENTRIES)
- {
- dbg_printf(("FATAL: _saveIdxEntry() Failedn"));
- return FALSE;
- }
-
- if ( (_lAVIPreviousFrameNumber == -1) ||
- (1000*(ulVidFrameNumber - _lAVIPreviousFrameNumber) >= _aviIdxIDiff) )
- {
- indexEntry.ulVideoFrameNumber = ulVidFrameNumber;
- indexEntry.ulVideoChunkOffset = dwVidChunkOffset;
- indexEntry.ulVideoChunkSize = dwVidChunkSize;
- indexEntry.ulAudioChunkOffset = dwAudioChunkOffset;
- indexEntry.ulAudioChunkDelta = dwAudioChunkDelta;
- indexEntry.uiSkipVideoChunks = uiSkipVideoChunks;
- indexEntry.uiSkipAudioChunks = uiSkipAudioChunks;
- wai_sem(SEM_DRAM_ID);
- I49_WriteDRAMData(CALC_IDX_ENTRY_ADDRESS(MPEG4_PROCESSING_BUFF_ADDR, (((DWORD)(_uiMPEG4NextIndexEntry))*sizeof(IndexEntry))), // Robin_1119_2004_B, avoid the overflow
- (UINT16*)&indexEntry, sizeof(IndexEntry)/2);
- sig_sem(SEM_DRAM_ID);
- _lAVIPreviousFrameNumber = ulVidFrameNumber;
- _uiMPEG4NextIndexEntry++;
- }
- return TRUE;
- }
- ///////////////////////////////////////////////////////////////////////////
- // Function name : _aquireAndProcessIdx
- // Purpose : Reading and processing the index table.
- // Input Parameters : dwClipStartAddr - The start address to get the entries.
- // uiVideoStreamNum - The video stream number to process.
- // uiAudioStreamNum - The audio stream number to process.
- // Return type : TRUE if the operation succeeded, FALSE otherwise.
- // Description : The function reads the idx entries, process them and
- // saves them in the memory to be used for trick modes.
- // The function aquires the idx only once.
- ///////////////////////////////////////////////////////////////////////////
- #ifdef V882_FLASH_CARD
- #define USE_HEAP //todo: change to USE_SC
- #endif//V882_FLASH_CARD
- static BOOL _aquireAndProcessIdx(DWORD dwClipStartAddr,
- UINT8 uiVideoStreamNum, UINT8 uiAudioStreamNum, DWORD* dwFirstChunkOffset)
- {
- int iAudioReminderCounter100 = 100;
- int iAudioReminderCounter10000 = 100;
- int iVideoReminderCounter100 = 100;
- int iVideoReminderCounter10000 = 100;
- DWORD dwIdxOffset = AVI_HEADER_OFFSET;
- FOURCCInfo idxList;
- UINT32 ulLeftSize;
- AVIIndexEntry currEntry;
- UINT32 ulCurrFrameNumber = 0;
- UINT32 ulFramesBeforeAudioCh = 0;
- BOOL bIsFirstAudioChunk = TRUE;
- DWORD dwCurrAudioChunkDelta = 0;
- DWORD dwCurrAudioChunkOffset = 0;
- DWORD dwCurrAudioChunkSize = 0;
- DWORD dwAudioSkip;
- DWORD dwAudioSkipRemider100;
- DWORD dwAudioSkipRemider10000;
- DWORD dwVideoSkip;
- DWORD dwVideoSkipRemider100;
- DWORD dwVideoSkipRemider10000;
- UINT32 ulCurrVideoTime = 0;
- UINT32 ulCurrAudioTime =0;
- BOOL bFirstEntry;
- DWORD dwIdxClipStartAddr;
- DWORD ulLeftSizeSave;
- BOOL bDrmFound = FALSE;
- #ifndef USE_HEAP
- IdxFIFOElement idxFIFO[FIFO_LEN];
- #else
- // WORD idxFIFO;
- IdxFIFOElement* idxFIFO;
- #endif
- UINT16 fifoHead, fifoTail;
- // <<< Robin_0907_2004_B
- BOOL bIdxFifoOverFlow = FALSE;
- DWORD dwIdxOffsetStore;
- UINT32 ulLeftSizeStore;
- // >>> Robin_0907_2004_B
- DWORD dwTotalAudioLength;
- DWORD dwTotalAudioCount = 0UL;
- #if defined(_DEBUG) || defined(D_RELEASE_TRACE_ENABLED) // ZKR GL051004
- UINT32 ulStartTime = gen_timer()/1000UL;
- #endif
- #ifdef USE_HEAP
- _freeStorageInterfaceAndIndex();
- #endif
- /* Check if the idx processing already has failed */
- if ((FALSE == _bMPEG4TrickModeOn) && (_uiMPEG4NextIndexEntry == 0))
- {
- return FALSE;
- }
- /* Check if the index exists */
- if (FALSE == _bAVIHasIndex)
- {
- tr_printf(("WARNING: _aquireAndProcessIdx() Failed - Index does not existn"));
- _bMPEG4TrickModeOn = FALSE;
- _dwMPEG4ProcessingEndAddr = MPEG4_PROCESSING_BUFF_ADDR;
- return FALSE;
- }
- /* Check if the index was already processed */
- if (TRUE == _bMPEG4IsIndexProcessed)
- {
- return TRUE;
- }
- _uiMPEG4ProcessedFileAddr = dwClipStartAddr;
-
- dbg_printf(("AVI Clip: Aquiring Index Table Infon"));
- _dwMPEG4ProcessingEndAddr = MPEG4_PROCESSING_BUFF_ADDR;
-
- _uiMPEG4NextIndexEntry = 0;
- _uiAVICurrCachedIdxEntry = NUM_OF_IDX_ENTRIES_CACHE;
-
- /* Reaching the 'idx1' FOURCC */
- if (FALSE == _searchForFOURCC(dwClipStartAddr, &dwIdxOffset, AVI_IDX_CHUNK_ID, &idxList, FALSE, 0))
- {
- dbg_printf(("FATAL: _aquireAndProcessIdx() Failed [1]n"));
- _bMPEG4TrickModeOn = FALSE;
-
- return FALSE;
- }
- dwIdxOffset -= (DWORD)idxList.ulSize;
- ulLeftSize = idxList.ulSize;
- dwIdxClipStartAddr = dwClipStartAddr + (dwIdxOffset/2048UL);
- dwIdxOffset = dwIdxOffset % 2048UL;
-
- /* Check if the file doesn't contain audio stream */
- if (NO_STREAM == _mpeg4AudioStreamID)
- {
- /* Signal to the idx processing not to wait for audio chunk at the beginning */
- bIsFirstAudioChunk = FALSE;
- }
- if (NO_STREAM != _mpeg4AudioStreamID)
- {
- if ( (_mpeg4AudioScale == AVI_VBR_AUD_STREAM_SCALE) /*&&
- (TRUE == _aviFileInfo.bIsNandub)*/ )
- {
- /* VBR audio stream */
- UINT32 ulDelta;
- tr_printf(("Detected VBR audio stream...n"));
- // <<< Robin_2004_0519_A, change the index processing when VBR audio
- // dwVideoSkip mean the time of one video frame, in unit of 0.1ms
- dwVideoSkip = (10000UL * _mpeg4VideoScale) /
- _mpeg4VideoRate;
- ulDelta = (10000UL * _mpeg4VideoScale) -
- (dwVideoSkip * _mpeg4VideoRate);
- // Robin_0201_2005, avoid the calculate overflow
- if (((10000UL*ulDelta)/10000UL) == ulDelta)
- {
- ulDelta = (10000UL*ulDelta) / _mpeg4VideoRate;
- }
- else if (((5000UL*ulDelta)/5000UL) == ulDelta)
- {
- ulDelta = ((5000UL*ulDelta) / _mpeg4VideoRate) * 2;
- }
- else if (((1000UL*ulDelta)/1000UL) == ulDelta)
- {
- ulDelta = ((1000UL*ulDelta) / _mpeg4VideoRate) * 10;
- }
- else if (((100UL*ulDelta)/100UL) == ulDelta)
- {
- ulDelta = ((100UL*ulDelta) / _mpeg4VideoRate) * 100;
- }
- dwVideoSkipRemider100 = ulDelta / 100;
- dwVideoSkipRemider10000 = ulDelta % 100;
- dwAudioSkip = (10000UL * AVI_VBR_AUD_STREAM_SCALE) / _mpeg4AudioRate;
- ulDelta = (10000UL * AVI_VBR_AUD_STREAM_SCALE) -
- (dwAudioSkip * _mpeg4AudioRate);
- // Robin_0201_2005, avoid the calculate overflow
- if (((10000UL*ulDelta)/10000UL) == ulDelta)
- {
- ulDelta = (10000UL*ulDelta) / _mpeg4AudioRate;
- }
- else if (((5000UL*ulDelta)/5000UL) == ulDelta)
- {
- ulDelta = ((5000UL*ulDelta) / _mpeg4AudioRate) * 2;
- }
- else if (((1000UL*ulDelta)/1000UL) == ulDelta)
- {
- ulDelta = ((1000UL*ulDelta) / _mpeg4AudioRate) * 10;
- }
- else if (((100UL*ulDelta)/100UL) == ulDelta)
- {
- ulDelta = ((100UL*ulDelta) / _mpeg4AudioRate) * 100;
- }
- dwAudioSkipRemider100 = ulDelta / 100;
- dwAudioSkipRemider10000 = ulDelta % 100;
- dbg_printf(("IDX: audio skip: %ld, reminder100: %ld, reminder10000: %ldn",
- dwAudioSkip, dwAudioSkipRemider100, dwAudioSkipRemider10000));
- dbg_printf(("IDX: video skip: %ld, reminder100: %ld, reminder10000: %ldn",
- dwVideoSkip, dwVideoSkipRemider100, dwVideoSkipRemider10000));
- // >>> Robin_2004_0519_A
- }
- else
- {
- UINT32 ulDelta;
- UINT16 uVideoTotalPlaybackTime;
- UINT16 uAudioTotalPlaybackTime;
- /* CBR audio stream
- * Warning: The ahead order of computation is very important to prevent overflow and
- * for the computation's accurecy.
- */
- if (0 == _mpeg4AudioLength)
- {
- DWORD dwAudRate = _mpeg4AudioRate;
- DWORD dwFileLength = (10*_mpeg4VideoLength *
- _mpeg4VideoScale) /
- _mpeg4VideoRate;
- _mpeg4AudioLength = dwAudRate * dwFileLength/10;
- }
- // Robin_0607_2004_A, handle some special divx with video/audio total playback time not equal (absdiff > 1)
- uVideoTotalPlaybackTime = caclTimeOfFrame(_mpeg4VideoLength, _mpeg4VideoRate, _mpeg4VideoScale);
- if (0 != _mpeg4AudioAvgBytesPerSec)
- uAudioTotalPlaybackTime = (UINT16)((_mpeg4AudioLength * _mpeg4AudioScale) / _mpeg4AudioAvgBytesPerSec);
- // <<< Robin_0930_2004, avoid the calculation overflow
- if(((ABS_DIFF(uVideoTotalPlaybackTime, uAudioTotalPlaybackTime) > 1) && 0 != _mpeg4AudioAvgBytesPerSec)
- || (0UL == (_mpeg4AudioAvgBytesPerSec * _mpeg4VideoScale) % _mpeg4VideoRate)) // for some special divx clips
- {
-
- dwAudioSkip = (_mpeg4AudioAvgBytesPerSec * _mpeg4VideoScale) / _mpeg4VideoRate;
-
- ulDelta = (_mpeg4AudioAvgBytesPerSec * _mpeg4VideoScale) - (_mpeg4VideoRate * dwAudioSkip);
- if (((10000UL*ulDelta)/10000UL) == ulDelta)
- ulDelta = (10000UL*ulDelta) / _mpeg4VideoRate;
- else if (((5000UL*ulDelta)/5000UL) == ulDelta)
- ulDelta = ((5000UL*ulDelta) / _mpeg4VideoRate) * 2;
- else if (((1000UL*ulDelta)/1000UL) == ulDelta)
- ulDelta = ((1000UL*ulDelta) / _mpeg4VideoRate) * 10;
- else
- ulDelta = ((100UL*ulDelta) / _mpeg4VideoRate) * 100;
- }
- else
- {
- dwAudioSkip = (_mpeg4AudioLength * _mpeg4AudioScale) / _mpeg4VideoLength;
- ulDelta = (_mpeg4AudioLength * _mpeg4AudioScale) - (_mpeg4VideoLength * dwAudioSkip);
- if (((10000UL*ulDelta)/10000UL) == ulDelta)
- ulDelta = (10000UL*ulDelta) / _mpeg4VideoLength;
- else if (((5000UL*ulDelta)/5000UL) == ulDelta)
- ulDelta = ((5000UL*ulDelta) / _mpeg4VideoLength) * 2;
- else if (((1000UL*ulDelta)/1000UL) == ulDelta)
- ulDelta = ((1000UL*ulDelta) / _mpeg4VideoLength) * 10;
- else
- ulDelta = ((100UL*ulDelta) /_mpeg4VideoLength) * 100;
- }
- dwAudioSkipRemider100 = ulDelta / 100;
- dwAudioSkipRemider10000 = ulDelta % 100;
-
- dbg_printf(("IDX: audio skip: %ld, reminder100: %ld, reminder10000: %ldn",
- dwAudioSkip, dwAudioSkipRemider100, dwAudioSkipRemider10000));
- }
- }
- bFirstEntry = TRUE;
- ulLeftSizeSave = ulLeftSize;
- fifoHead = fifoTail = 0;
- /* Determine the difference between the saved I-frames according to the AVI file */
- #ifdef SDRAM_2X16MBITS
- if (_mpeg4VideoLength >= IDX_LONG_I_DIFF_THRESHOLD)
- {
- _aviIdxIDiff = IDX_TABLE_LONG_TIME_DIFFERANCE *
- (_mpeg4VideoRate /
- _mpeg4VideoScale);
- dbg_printf(("IDX: Diff between I frames is: %d msecn", IDX_TABLE_LONG_TIME_DIFFERANCE));
- }
- else
- {
- _aviIdxIDiff = IDX_TABLE_SHORT_TIME_DIFFERANCE *
- (_mpeg4VideoRate /
- _mpeg4VideoScale);
- dbg_printf(("IDX: Diff between I frames is: %d msecn", IDX_TABLE_SHORT_TIME_DIFFERANCE));
- }
- #else
- _aviIdxIDiff = IDX_TABLE_SHORT_TIME_DIFFERANCE * (UINT16)(_mpeg4VideoRate / _mpeg4VideoScale);
- dbg_printf(("IDX: Diff between I frames is: %d msecn", IDX_TABLE_SHORT_TIME_DIFFERANCE));
- #endif // SDRAM_2X16MBITS
- #if (defined(SUPPORT_FLASH_CARD) && (!defined(I86_HW_FCU)))
- if(IS_PLAYING_CARD)
- _idxEntries = FCU_IDX_ENTRIES_START;
- else
- #endif
- _idxEntries = (BYTE*) malloc(NUM_OF_IDX_ENTRIES_CACHE*sizeof(AVIIndexEntry));
- if (NULL == _idxEntries)
- {
- tr_printf(("FATAL: couldn't allocate memory for idx caching...n"));
- _bMPEG4TrickModeOn = FALSE;
- return FALSE;
- }
- // Robin_1003_2004_D
- _bAVIVideoBeforeAudio = FALSE;
- // Robin_1003_2004_C
- bVideoAudioInterleave = TRUE;
- if (_mpeg4AudioScale == AVI_VBR_AUD_STREAM_SCALE)
- dwTotalAudioLength = _mpeg4AudioLength;
- else
- dwTotalAudioLength = _mpeg4AudioLength * _mpeg4AudioScale;
-
- /* Reading the index entries and saving the I frames only */
- ulLeftSize = ((ulLeftSize+15) >> 4) << 4; // ensure "ulLeftSize" in unit of 16 bytes // Robin_0809_2004
- // <<< Robin_0907_2004_B
- dwIdxOffsetStore = dwIdxOffset;
- ulLeftSizeStore = ulLeftSize;
- #ifdef USE_HEAP
- // idxFIFO = sc_Malloc((FIFO_LEN*sizeof(IdxFIFOElement) + 4 -1)/4);
- idxFIFO = malloc(FIFO_LEN*sizeof(IdxFIFOElement));
- if(NULL_HANDLE == idxFIFO){
- printf("AVI.c, Fatal: low system resource, idxFIFO.n");
- return FALSE;
- }
- #endif
- // >>> Robin_0907_2004_B
- while (ulLeftSize > 0UL)
- {
- DWORD dwSizeOfCurrEntry;
- UINT8 uiStreamNumber;
- if (FALSE == _getIdxEntry(dwIdxClipStartAddr, dwIdxOffset, ulLeftSizeSave,
- &currEntry, bFirstEntry, ulLeftSize))
- {
- dbg_printf(("FATAL: _aquireAndProcessIdx() Failed [2]n"));
- if (ulLeftSize < 4096UL) // can't get last two sectors
- break;
- AuxCache_GetFileTerminate();
- #if (defined(SUPPORT_FLASH_CARD) && (!defined(I86_HW_FCU)))
- if (!IS_PLAYING_CARD)
- #endif
- free(_idxEntries);
- _idxEntries = NULL;
- _bMPEG4TrickModeOn = FALSE;
- #ifdef USE_HEAP
- // sc_Free(idxFIFO, ((FIFO_LEN*sizeof(IdxFIFOElement) + 4 -1)/4));
- free(idxFIFO);
- #endif
- return FALSE;
- }
- if (TRUE == bFirstEntry)
- {
- *dwFirstChunkOffset = currEntry.dwChunkOffset;
- bFirstEntry = FALSE;
- }
- dwSizeOfCurrEntry = (DWORD)sizeof(currEntry);
- ulLeftSize -= (UINT32)dwSizeOfCurrEntry;
- dwIdxOffset += dwSizeOfCurrEntry;
- if (0 == currEntry.dwChunkOffset) // index corrupted
- continue;
-
- /* Calculating the stream number of the entry */
- uiStreamNumber = (currEntry.ucChunkID[0] - '0')*10 + currEntry.ucChunkID[1] - '0';
- /* Check whether the current entry does not belong to the current played AV streams */
- if ( (('d' == currEntry.ucChunkID[2]) && (uiStreamNumber != uiVideoStreamNum)) ||
- (('w' == currEntry.ucChunkID[2]) && (uiStreamNumber != uiAudioStreamNum)) )
- {
- /* Not the current played stream - ignore it */
- continue;
- }
- if ( 'w' == currEntry.ucChunkID[2] )
- {
- if (_mpeg4AudioScale == AVI_VBR_AUD_STREAM_SCALE)
- dwTotalAudioCount ++;
- else
- dwTotalAudioCount += currEntry.dwChunkLength;
- }
-
- /* Check the entry type (video/audio/DRM) */
- if ( 'd' == currEntry.ucChunkID[2] )
- {
- if ( 'd' == currEntry.ucChunkID[3] )
- {
- /* DRM entry */
- /* mark DRM chunk found, so it's value can be added to the following video */
- bDrmFound = TRUE;
- }
- else if ( ('c' == currEntry.ucChunkID[3]) || ('b' == currEntry.ucChunkID[3]) )
- {
- /* Video Entry */
- if (TRUE == bDrmFound)
- {
- currEntry.dwChunkOffset -= 0x12;
- currEntry.dwChunkLength += 0x12;
- bDrmFound = FALSE;
- }
- /* Check if this is a video chunk in which no audio is preceding it */
- if (TRUE == bIsFirstAudioChunk)
- {
- /* If this is the first video frame - drop it */
- if (FALSE == _bAVIVideoBeforeAudio)
- {
- _bAVIVideoBeforeAudio = TRUE;
- // Robin_1003_2004_D
- tr_printf(("WARNING: The video chunk is before the audio chunk!n"));
- }
- }