AVI.c
上传用户:super_houu
上传日期:2008-09-21
资源大小:4099k
文件大小:131k
- if (currEntry.dwFlags & AVI_IS_KEY_FRAME)
- {
- /* A key frame was found - saving it */
- if ((NO_STREAM == _mpeg4AudioStreamID) || (TRUE == _bAVIVideoBeforeAudio))
- {
- /* Save the key frame without audio info */
- if ( FALSE == _saveIdxEntry(ulCurrFrameNumber, currEntry.dwChunkOffset,
- currEntry.dwChunkLength, 0, 0, 0, 0) )
- {
- dbg_printf(("FATAL: _aquireAndProcessIdx() Failed [3]n"));
- 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;
- }
- }
- else
- {
- /* Save the key frame with the corresponding audio info */
- if ( FALSE == _saveIdxEntry(ulCurrFrameNumber, currEntry.dwChunkOffset,
- currEntry.dwChunkLength, dwCurrAudioChunkOffset,
- dwCurrAudioChunkDelta,
- (UINT16)(ulCurrFrameNumber-ulFramesBeforeAudioCh),
- 0) )
- {
- dbg_printf(("FATAL: _aquireAndProcessIdx() Failed [3]n"));
- 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;
- }
- }
- }
- /* Updating the audio info */
- if ((NO_STREAM != _mpeg4AudioStreamID) && (FALSE == bIsFirstAudioChunk) && (FALSE == _bAVIVideoBeforeAudio))
- {
- if ( (_mpeg4AudioScale == AVI_VBR_AUD_STREAM_SCALE) /*&&
- (TRUE == _aviFileInfo.bIsNandub)*/ )
- {
- /* VBR audio stream */
- /* Calculate the audio verses the video time and check
- * whether we should skip to the next audio chunks.
- */
- // <<< Robin_2004_0519_A, change the index processing when VBR audio
- while (ulCurrVideoTime > ulCurrAudioTime)
- {
- ulCurrAudioTime += dwAudioSkip;
- if (!iAudioReminderCounter100)
- {
- ulCurrAudioTime += dwAudioSkipRemider100;
- iAudioReminderCounter100 =100;
- iAudioReminderCounter10000--;
- if (!iAudioReminderCounter10000)
- {
- ulCurrAudioTime += dwAudioSkipRemider10000;
- iAudioReminderCounter10000 =100;
- }
- }
- iAudioReminderCounter100--;
-
- // >>> Robin_2004_0519_A
-
- if (fifoHead != fifoTail)
- {
- /* Remove from the head of FIFO */
- #if 0//def USE_HEAP
- {
- IdxFIFOElement fifoEntry;
- sc_GetBytes(idxFIFO, fifoHead*(sizeof(IdxFIFOElement)), sizeof(IdxFIFOElement), (BYTE*)(&fifoEntry));
- dwCurrAudioChunkOffset = fifoEntry.dwAudioChunksOffsets;
- dwCurrAudioChunkSize = fifoEntry.dwAudioChunksLengths;
- ulFramesBeforeAudioCh = fifoEntry.dwAudioChunksFrames;
- fifoHead++;
- }
- #else
- dwCurrAudioChunkOffset = idxFIFO[fifoHead].dwAudioChunksOffsets;
- dwCurrAudioChunkSize = idxFIFO[fifoHead].dwAudioChunksLengths;
- ulFramesBeforeAudioCh = idxFIFO[fifoHead++].dwAudioChunksFrames;
- #endif
- fifoHead &= FIFO_WRAPAOURND;
- dwTotalAudioLength --;
- }
- else
- {
- /* FIFO underflow */
- // Robin_1119_2004_B, there is not left audio data
- if (dwTotalAudioLength != 0)
- {
- _bAVIVideoBeforeAudio = TRUE;
- tr_printf(("WARNING: The VBR audio chunk fifo underlow!n"));
- }
- break;
- }
- }
- // <<< Robin_2004_0519_A, change the index processing when VBR audio
- ulCurrVideoTime += dwVideoSkip;
- if (!iVideoReminderCounter100)
- {
- ulCurrVideoTime += dwVideoSkipRemider100;
- iVideoReminderCounter100 =100;
- iVideoReminderCounter10000--;
- if (!iVideoReminderCounter10000)
- {
- ulCurrVideoTime += dwVideoSkipRemider10000;
- iVideoReminderCounter10000 =100;
- }
- }
-
- iVideoReminderCounter100--;
-
- // >>> Robin_2004_0519_A
- }
- else
- {
- /* CBR audio stream */
- dwCurrAudioChunkDelta += dwAudioSkip;
-
- if (!iAudioReminderCounter100)
- {
- dwCurrAudioChunkDelta += dwAudioSkipRemider100;
- iAudioReminderCounter100 = 100;
- iAudioReminderCounter10000--;
- if (!iAudioReminderCounter10000)
- {
- dwCurrAudioChunkDelta += dwAudioSkipRemider10000;
- iAudioReminderCounter10000 = 100;
- }
- }
-
- iAudioReminderCounter100--;
- /* Update the audio corresponding to the next video frame */
- /* Check whether we are still in the same audio chunk */
- while (dwCurrAudioChunkDelta > dwCurrAudioChunkSize)
- {
- /* Crossed to a different Audio chunk */
- // DWORD ulAudioChunkOffset, ulAudioChunkLength;
- if (fifoHead != fifoTail)
- {
- /* Remove from the head of FIFO */
- dwCurrAudioChunkDelta = dwCurrAudioChunkDelta - dwCurrAudioChunkSize;
- #if 0//def USE_HEAP
- {
- IdxFIFOElement fifoEntry;
- sc_GetBytes(idxFIFO, fifoHead*(sizeof(IdxFIFOElement)), sizeof(IdxFIFOElement), (BYTE *)(&fifoEntry));
- dwCurrAudioChunkOffset = fifoEntry.dwAudioChunksOffsets;
- dwCurrAudioChunkSize = fifoEntry.dwAudioChunksLengths;
- ulFramesBeforeAudioCh = fifoEntry.dwAudioChunksFrames;
- fifoHead++;
- }
- #else
- dwCurrAudioChunkOffset = idxFIFO[fifoHead].dwAudioChunksOffsets;
- dwCurrAudioChunkSize = idxFIFO[fifoHead].dwAudioChunksLengths;
- ulFramesBeforeAudioCh = idxFIFO[fifoHead++].dwAudioChunksFrames;
- #endif
- fifoHead &= FIFO_WRAPAOURND;
- dwTotalAudioLength -= dwCurrAudioChunkSize;
- }
- else
- {
- /* FIFO underflow */
- // Robin_1003_2004_D
- // Robin_1119_2004_B, there is not left audio data
- if (dwTotalAudioLength != 0)
- {
- _bAVIVideoBeforeAudio = TRUE;
- tr_printf(("WARNING: The CBR audio chunk fifo underlow!n"));
- }
- break;
- }
- }
- }
- }
- ulCurrFrameNumber++;
- }
- }
- else if (( 'w' == currEntry.ucChunkID[2] ) && (FALSE == _bAVIVideoBeforeAudio))
- {
- /* Audio Entry */
- if (TRUE == bIsFirstAudioChunk)
- {
- dwCurrAudioChunkDelta = 0;
- dwCurrAudioChunkSize = currEntry.dwChunkLength;
- dwCurrAudioChunkOffset = currEntry.dwChunkOffset;
- ulFramesBeforeAudioCh = 0UL;
- bIsFirstAudioChunk = FALSE;
- if (_mpeg4AudioScale == AVI_VBR_AUD_STREAM_SCALE)
- dwTotalAudioLength --;
- else
- dwTotalAudioLength -= dwCurrAudioChunkSize;
- }
- else
- {
- if (((fifoTail+1)&FIFO_WRAPAOURND) != fifoHead)
- {
- //Insert to the tail of FIFO
- #if 0//def USE_HEAP
- {
- IdxFIFOElement fifoEntry;
- fifoEntry.dwAudioChunksOffsets = currEntry.dwChunkOffset;
- fifoEntry.dwAudioChunksLengths= currEntry.dwChunkLength;
- fifoEntry.dwAudioChunksFrames= ulCurrFrameNumber;
- sc_SetBytes(idxFIFO, fifoTail*(sizeof(IdxFIFOElement)), sizeof(IdxFIFOElement), (BYTE*)(&fifoEntry));
- fifoTail++;
- }
- #else
- idxFIFO[fifoTail].dwAudioChunksOffsets = currEntry.dwChunkOffset;
- idxFIFO[fifoTail].dwAudioChunksLengths= currEntry.dwChunkLength;
- idxFIFO[fifoTail++].dwAudioChunksFrames= ulCurrFrameNumber;
- #endif
- fifoTail &= FIFO_WRAPAOURND;
- }
- else
- {
- //FIFO overflow.
- tr_printf(("WARNING: IDX processing is cut during to low resourcesn"));
- // <<< Robin_0907_2004_B
- bIdxFifoOverFlow = TRUE;
- _bAVIVideoBeforeAudio = TRUE;
- // break;
- }
- }
- }
- // Robin_0117_2005, support AVI internal text subtitle
- #if 0
- else if ( 't' == currEntry.ucChunkID[2] )
- {
- // "Text "
- UINT16 uiSubtitleNum;
- for (uiSubtitleNum=0;uiSubtitleNum<_mpeg4SubtitleAvailableNum;uiSubtitleNum++)
- {
- sc_GetBytes(SC_MPEG4_SUBTITLE_STREAM_INFO_ADDR,
- (uiSubtitleNum * SIZE_OF_SUBTITLE_STREAM_INFO),
- SIZE_OF_SUBTITLE_STREAM_INFO,
- (BYTE*)&_mpeg4SubtitleStreamInfo
- );
- if (uiStreamNumber == _mpeg4SubtitleStreamID && AVI_INTERNAL_TEXT == _mpeg4SubtitleType)
- {
- _mpeg4SubtitleOffsetInAvi = currEntry.dwChunkOffset;
- sc_SetBytes(SC_MPEG4_SUBTITLE_STREAM_INFO_ADDR,
- (uiSubtitleNum * SIZE_OF_SUBTITLE_STREAM_INFO),
- SIZE_OF_SUBTITLE_STREAM_INFO,
- (BYTE*)&_mpeg4SubtitleStreamInfo
- );
- }
-
- }
- }
- #endif
- }
-
- AuxCache_GetFileTerminate();
- // <<< Robin_1003_2004_D
- // Robin_1222_2004, count the actual audio length
- if ((ulLeftSize == 0) && (ulCurrFrameNumber == _mpeg4VideoLength)) // index is completely scan
- {
- if (_mpeg4AudioScale == AVI_VBR_AUD_STREAM_SCALE)
- dwTotalAudioLength = _mpeg4AudioLength;
- else
- dwTotalAudioLength = _mpeg4AudioLength * _mpeg4AudioScale;
-
- if (dwTotalAudioCount != dwTotalAudioLength)
- {
- dbg_printf(("The original audio length is %ldn", _mpeg4AudioLength));
-
- if (_mpeg4AudioScale == AVI_VBR_AUD_STREAM_SCALE)
- _mpeg4AudioLength = dwTotalAudioCount;
- else
- _mpeg4AudioLength = dwTotalAudioCount/_mpeg4AudioScale;
- dbg_printf(("The actual audio length is %ldn", _mpeg4AudioLength));
-
- sc_SetBytes(SC_MPEG4_AUDIO_STREAM_INFO_ADDR,
- (_mpeg4AudioCurrentDispIdx * SIZE_OF_AUDIO_STREAM_INFO),
- SIZE_OF_AUDIO_STREAM_INFO,
- (BYTE*)&_mpeg4AudioStreamInfo
- );
- }
- }
- if ((TRUE == bIdxFifoOverFlow) || (TRUE == _bAVIVideoBeforeAudio))
- {
- UINT32 ulIndex = 0UL;
- IndexEntry indexEntry;
- DWORD dwAudioCount = 0UL;
- DWORD dwAudioLastCount = 0UL;
- DWORD dwAudioBoundary;
- UINT32 ulAudioChunkNumber = 0;
- UINT32 ulAudioChunkNumberBefore = 0;
-
- // DWORD dwAudioChunkSize = 0UL;
- // DWORD dwPrevAudiochunkSize = 0UL;
- bFirstEntry = TRUE;
- ulCurrFrameNumber = 0UL;
-
- _uiAVICurrCachedIdxEntry = NUM_OF_IDX_ENTRIES_CACHE;
- wai_sem(SEM_DRAM_ID);
- I49_ReadDRAMData(CALC_IDX_ENTRY_ADDRESS(MPEG4_PROCESSING_BUFF_ADDR, (ulIndex*sizeof(IndexEntry))),
- (UINT16*)&indexEntry, sizeof(IndexEntry)/2);
- sig_sem(SEM_DRAM_ID);
- dwAudioBoundary = indexEntry.ulVideoFrameNumber * dwAudioSkip;
- dwAudioBoundary += ((indexEntry.ulVideoFrameNumber * dwAudioSkipRemider100)/100UL);
- dwAudioBoundary += ((indexEntry.ulVideoFrameNumber * dwAudioSkipRemider10000)/10000UL);
- while (ulLeftSizeStore > 0UL)
- {
- DWORD dwSizeOfCurrEntry;
- UINT8 uiStreamNumber;
-
- if (FALSE == _getIdxEntry(dwIdxClipStartAddr, dwIdxOffsetStore, ulLeftSizeSave,
- &currEntry, bFirstEntry, ulLeftSizeStore))
- {
- dbg_printf(("FATAL: _aquireAndProcessIdx() Failed [2]n"));
- if (ulLeftSizeStore < 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;
- }
-
- bFirstEntry = FALSE;
-
- dwSizeOfCurrEntry = (DWORD)sizeof(currEntry);
- ulLeftSizeStore -= (UINT32)dwSizeOfCurrEntry;
- dwIdxOffsetStore += 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 ( ('d' == currEntry.ucChunkID[2]) && (('c' == currEntry.ucChunkID[3]) || ('b' == currEntry.ucChunkID[3])) )
- {
- if (ulCurrFrameNumber <= indexEntry.ulVideoFrameNumber)
- {
- ulAudioChunkNumberBefore = ulAudioChunkNumber;
- }
- // RB_2005_0511, framenumber start from 0
- ulCurrFrameNumber++;
- }
- else if ( 'w' == currEntry.ucChunkID[2] )
- {
- if ( (_mpeg4AudioScale == AVI_VBR_AUD_STREAM_SCALE))
- {
- dwAudioCount += dwAudioSkip;
- if (!iAudioReminderCounter100)
- {
- dwAudioCount += dwAudioSkipRemider100;
- iAudioReminderCounter100 =100;
- iAudioReminderCounter10000--;
- if (!iAudioReminderCounter10000)
- {
- dwAudioCount += dwAudioSkipRemider10000;
- iAudioReminderCounter10000 =100;
- }
- }
- iAudioReminderCounter100--;
- }
- else
- {
- dwAudioLastCount = dwAudioCount;
- dwAudioCount += currEntry.dwChunkLength;
- }
- while (dwAudioCount > dwAudioBoundary)
- {
- indexEntry.ulAudioChunkOffset = currEntry.dwChunkOffset;
- if ( (_mpeg4AudioScale == AVI_VBR_AUD_STREAM_SCALE))
- {
- indexEntry.ulAudioChunkDelta = 0UL;
- }
- else
- {
- indexEntry.ulAudioChunkDelta = (dwAudioBoundary - dwAudioLastCount);
- }
-
- if (indexEntry.ulVideoFrameNumber >= ulCurrFrameNumber)
- {
- indexEntry.uiSkipVideoChunks = (UINT16)(indexEntry.ulVideoFrameNumber-ulCurrFrameNumber);
- indexEntry.uiSkipAudioChunks = 0;
- }
- else
- {
- indexEntry.uiSkipVideoChunks = 0;
- indexEntry.uiSkipAudioChunks = (UINT16)(ulAudioChunkNumber - ulAudioChunkNumberBefore);
- }
- // <<< Robin_1003_2004_C
- // check the audio/video is interleave
- if (ABS_DIFF(indexEntry.ulAudioChunkOffset, indexEntry.ulVideoChunkOffset) > 0x1000000UL) // more than 16MB, not accuracy
- {
- bVideoAudioInterleave = FALSE;
- tr_printf(("WARNING: Video/Audio is not interleaved, playback without audio!n"));
- }
- // >>> Robin_1003_2004_C
- wai_sem(SEM_DRAM_ID);
- I49_WriteDRAMData(CALC_IDX_ENTRY_ADDRESS(MPEG4_PROCESSING_BUFF_ADDR, (ulIndex*sizeof(IndexEntry))),
- (UINT16*)&indexEntry, sizeof(IndexEntry)/2);
- sig_sem(SEM_DRAM_ID);
-
- ulIndex ++;
- if (ulIndex >= _uiMPEG4NextIndexEntry )
- break;
- wai_sem(SEM_DRAM_ID);
- I49_ReadDRAMData(CALC_IDX_ENTRY_ADDRESS(MPEG4_PROCESSING_BUFF_ADDR, (ulIndex*sizeof(IndexEntry))),
- (UINT16*)&indexEntry, sizeof(IndexEntry)/2);
- sig_sem(SEM_DRAM_ID);
-
- if ( (_mpeg4AudioScale == AVI_VBR_AUD_STREAM_SCALE))
- {
- /* VBR audio stream */
- dwAudioBoundary = indexEntry.ulVideoFrameNumber * dwVideoSkip;
- dwAudioBoundary += ((indexEntry.ulVideoFrameNumber * dwVideoSkipRemider100 + (
- (indexEntry.ulVideoFrameNumber * dwVideoSkipRemider10000)/100UL) )/100UL);
- }
- else
- {
- /* CBR audio stream */
- dwAudioBoundary = indexEntry.ulVideoFrameNumber * dwAudioSkip;
- dwAudioBoundary += ((indexEntry.ulVideoFrameNumber * dwAudioSkipRemider100 +
- ((indexEntry.ulVideoFrameNumber * dwAudioSkipRemider10000)/100UL))/100UL);
- }
- }
- ulAudioChunkNumber ++;
- }
-
- if (ulIndex >= _uiMPEG4NextIndexEntry )
- break;
- // Robin_1003_2004_C
- if (FALSE == bVideoAudioInterleave)
- break;
- }
- // >>> Robin_0907_2004_B
- }
- // >>> Robin_1003_2004_D
- AuxCache_GetFileTerminate();
- #if (defined(SUPPORT_FLASH_CARD) && (!defined(I86_HW_FCU)))
- if(!IS_PLAYING_CARD)
- #endif
- free(_idxEntries);
- _idxEntries = NULL;
- _dwMPEG4ProcessingEndAddr = (CALC_IDX_ENTRY_ADDRESS(MPEG4_PROCESSING_BUFF_ADDR, (((DWORD)(_uiMPEG4NextIndexEntry-1))*sizeof(IndexEntry))) >>9) <<9; // Robin_1119_2004_B, avoid the overflow
- _dwMPEG4ProcessingEndAddr = (_dwMPEG4ProcessingEndAddr>>9)<<9;
- #ifdef USE_AUX_SUBTITLES
- _mpeg4ExternalSubtitleAddr = _dwMPEG4ProcessingEndAddr;
- #endif
- _bMPEG4IsIndexProcessed = TRUE;
- // <<< Robin_0907_2004_B
- if (_uiMPEG4NextIndexEntry > 1)
- _bMPEG4TrickModeOn = TRUE;
- else
- _bMPEG4TrickModeOn = FALSE;
- // >>> Robin_0907_2004_B
- dbg_printf(("_aquireAndProcessIdx FINISHED, total time: %ld msecn", gen_timer()/1000UL-ulStartTime));
- dbg_printf(("Total saved I frames: %dn", _uiMPEG4NextIndexEntry));
-
- dbg_printf(("Start address of index table: 0x%lxn",_dwMPEG4ProcessingEndAddr));
- #ifdef USE_HEAP
- // sc_Free(idxFIFO, ((FIFO_LEN*sizeof(IdxFIFOElement) + 4 -1)/4));
- free(idxFIFO);
- #endif
- return TRUE;
- }
- ///////////////////////////////////////////////////////////////////////////
- // Function name : _aviProcessTimeToAddressInfo
- // Purpose : Calculate the frame number corresponding to the given
- // time and the index entry used for it.
- // Input Parameters : dwClipStartAddr - The start address of the AVI file.
- // WORD - The requested time (msec)
- // Return type : TRUE if the operation succeeded, FALSE otherwise.
- // Description : The function seeks for the closest frame number in
- // the idx table.
- ///////////////////////////////////////////////////////////////////////////
- static BOOL _aviProcessTimeToAddressInfo(DWORD dwClipStartAddr, WORD wTime)
- {
- UINT32 ulFirstIFrame;
- UINT32 ulSecondIFrame;
- WORD wFirstITime;
- WORD wSecondITime;
- UINT32 ulFirstIIdx;
- UINT32 ulSecondIIdx;
- UINT16 uiFirstDelta;
- UINT16 uiSecondDelta;
- UINT32 ulRequestedFrameNum;
- dbg_printf(("_aviProcessTimeToAddressInfo()n"));
- if (FALSE == _getAdjacentIFrames(dwClipStartAddr, wTime,
- &ulFirstIFrame, &ulSecondIFrame,
- &wFirstITime, &wSecondITime,
- &ulFirstIIdx, &ulSecondIIdx) )
- {
- dbg_printf(("WARNING: _aviProcessTimeToAddressInfo() FAILEDn"));
- return FALSE;
- }
- /* Calculate the frame number corresponding to the given time */
- ulRequestedFrameNum = caclFrameOfTime(wTime,
- _mpeg4VideoRate,
- _mpeg4VideoScale);
- /* Check the closest I frame */
- uiFirstDelta = (ulFirstIFrame >= ulRequestedFrameNum) ?
- (UINT16)(ulFirstIFrame - ulRequestedFrameNum) :
- (UINT16)(ulRequestedFrameNum - ulFirstIFrame);
- uiSecondDelta = (ulSecondIFrame >= ulRequestedFrameNum) ?
- (UINT16)(ulSecondIFrame - ulRequestedFrameNum) :
- (UINT16)(ulRequestedFrameNum - ulSecondIFrame);
- if (PM_GetRepeatAB())
- _ulMPEG4RequestedFrameIndex = ulFirstIIdx;
- else
- _ulMPEG4RequestedFrameIndex = (uiFirstDelta <= uiSecondDelta) ? ulFirstIIdx : ulSecondIIdx;
- dbg_printf(("Actual frame number %ld, calculated frame number %ldn", ulRequestedFrameNum,
- (_ulMPEG4RequestedFrameIndex == ulFirstIIdx) ? ulFirstIFrame : ulSecondIFrame));
- return TRUE;
- }
- ////////////////////////////////////////////////////////////////////////////
- // Function name : _aviScan
- // Purpose : Handle scanning of the avi file.
- // Input Parameters : iIndexIncrement - The increment to reach the next
- // index entry that needs to be played.
- // bContinue - indicates whether the scanning has just
- // started or not.
- // Return type : TRUE if the operation succeeded, FALSE otherwise.
- // Description : The function accesses the next entry in the idx table
- // and asks the decoder and the drive to play that entry.
- ////////////////////////////////////////////////////////////////////////////
- static BOOL _aviScan(INT8 iIndexIncrement, BOOL bContinue)
- {
- DWORD dwStartLBA;
- WORD wClipStartOffset;
- WORD wClipEndOffset;
- ULONG ulBlocksCnt;
- IndexEntry indexEntry;
- dbg_printf(("_aviScan()n"));
- #ifdef AVI_FF_NO_INDEX
- if (FALSE == _bMPEG4TrickModeOn)
- {
- if (TRUE == bContinue)
- {
- DEC_AVI_SetIOnly(FALSE);
- DEC_AVI_SetIPOnly(FALSE);
- DEC_AVI_EnableFinishCB(FALSE);
- ie_send(IE_CORE_CDNAV_FINISHED);
- return TRUE;
- }
-
-
- DEC_AVI_GetVideoStatus((UINT32*)&_uiMPEG4StartTime, (UINT32*)&ulBlocksCnt);
- dwStartLBA = _dwMPEG4ClipStartLBA + (_ulMPEG4TotalBlocksCnt - ulBlocksCnt);
- wClipStartOffset = 0;
- wClipEndOffset = _wMPEG4ClipEndOffset;
- }
- else
- #endif
- {
- /* If we are not yet in scan mode, calculate the entry in the index corresponding to the current time */
- if (FALSE == bContinue)
- {
- if (FALSE == _aviProcessTimeToAddressInfo(_dwMPEG4FileLocation, _uiMPEG4StartTime))
- {
- dbg_printf(("WARNNING: _aviScan() Failed [1]n"));
- return FALSE;
- }
- }
- /* Check whether we scanned the whole idx table */
- if ( (((INT32)_ulMPEG4RequestedFrameIndex + (INT32)iIndexIncrement) >= _uiMPEG4NextIndexEntry) ||
- (((INT32)_ulMPEG4RequestedFrameIndex + (INT32)iIndexIncrement) < 0) )
- {
- DEC_AVI_EnableFinishCB(FALSE);
- ie_send(IE_CORE_CDNAV_FINISHED);
- return TRUE;
- }
- /* Calculate the next entry to be played */
- _ulMPEG4RequestedFrameIndex = (UINT32)((INT32)_ulMPEG4RequestedFrameIndex + (INT32)iIndexIncrement);
- wai_sem(SEM_DRAM_ID);
- I49_ReadDRAMData(CALC_IDX_ENTRY_ADDRESS(MPEG4_PROCESSING_BUFF_ADDR,(_ulMPEG4RequestedFrameIndex*sizeof(IndexEntry))),
- (UINT16*)&indexEntry, sizeof(IndexEntry)/2);
- sig_sem(SEM_DRAM_ID);
- /* Calculate the playback addresses */
- dwStartLBA = _dwMPEG4ClipStartLBA +
- ( (_wMPEG4ClipStartOffset + indexEntry.ulVideoChunkOffset - FOURCC_FIELD_LENGTH) >> 11);
- wClipStartOffset = (WORD)((_wMPEG4ClipStartOffset + indexEntry.ulVideoChunkOffset
- - FOURCC_FIELD_LENGTH) % LOGICAL_BLOCK_SIZE);
- ulBlocksCnt = (wClipStartOffset + indexEntry.ulVideoChunkSize +
- FOURCC_FIELD_LENGTH + SIZE_FIELD_LENGTH + LOGICAL_BLOCK_SIZE - 1) / LOGICAL_BLOCK_SIZE;
- #ifdef SUPPORT_FLASH_CARD
- if(IS_PLAYING_CARD)
- ulBlocksCnt += 16;
- #endif
- wClipEndOffset = (WORD)((wClipStartOffset + indexEntry.ulVideoChunkSize +
- FOURCC_FIELD_LENGTH + SIZE_FIELD_LENGTH) % LOGICAL_BLOCK_SIZE);
- wClipEndOffset += (wClipEndOffset % 2); /* Word alignment */
- if (0 == wClipEndOffset)
- {
- wClipEndOffset = 2048;
- }
- /* Calculate the start time */
- _uiMPEG4StartTime = caclTimeOfFrame(indexEntry.ulVideoFrameNumber,
- _mpeg4VideoRate,
- _mpeg4VideoScale);
- }
- if (FALSE == bContinue)
- {
- /* Scanning just started, re initialize the decoder */
- DWORD dwSampleRate;
- UINT8 uiAudioSID;
- UINT8 uiAudioSIDDecoder;
- determineAudioInfo(&uiAudioSID, &uiAudioSIDDecoder, &dwSampleRate);
- prePlayProcessing(dwSampleRate, NO_STREAM, NO_STREAM, 0xFF, FALSE);
- API_ADPSetMp3_Throw_Out_Cntr(0);
- /* Signal to the DVP the decision */
- DEC_AVI_SetIOnly(TRUE);
- DEC_AVI_SetIPOnly(FALSE);
- DEC_AVI_ResetDemuxStatus();
- DEC_AVI_SetStartVideoChunks(indexEntry.ulVideoFrameNumber);
- /* The order of the calls to the functions should not be changed! */
- DEC_AVI_SetPlaybackParams(wClipStartOffset, wClipEndOffset, _uiMPEG4StartTime, 0, 0);
- PE_Clips_SetPlaybackRange(dwStartLBA, ulBlocksCnt, UNLIMITED_FILE_SIZE);
- if (!PE_Clips_Playback_Sectors(DRVCF_CDSPEED_1X | DRVF_PLAY_CD_AV_DATA, dwStartLBA, ulBlocksCnt))
- {
- dbg_printf(("FATAL: _aviScan() Failed [3]n"));
- return FALSE;
- }
- }
- else
- {
- /* Stopping the current drive playback */
- drv_abort_play();
- /* Signal to the DVP the decision */
- DEC_AVI_SetIOnly(TRUE);
- DEC_AVI_SetIPOnly(FALSE);
- DEC_AVI_ResetDemuxStatus();
- DEC_AVI_SetStartVideoChunks(indexEntry.ulVideoFrameNumber);
- /* Set the next playback request to the decoder and to the drive */
- DEC_AVI_SetPlaybackParams(wClipStartOffset, wClipEndOffset, _uiMPEG4StartTime, 0, 0);
- PE_Clips_SetPlaybackRange(dwStartLBA, ulBlocksCnt, UNLIMITED_FILE_SIZE);
- if (!PE_Clips_Playback_Sectors(DRVCF_CDSPEED_1X | DRVF_PLAY_CD_AV_DATA, dwStartLBA, ulBlocksCnt))
- {
- dbg_printf(("WARNNING: _aviScan() Failed [4]n"));
- return FALSE;
- }
- }
- /* Install call back from the decoder */
- DEC_AVI_EnableFinishCB(TRUE);
- return TRUE;
- }
- // Robin_1011_2004_D
- #ifdef PATCH_VIDEO_NOT_B
- ///////////////////////////////////////////////////////////////////////////
- // Function name : _detectBVOP
- // Purpose : Detect if B-VOP exist
- // Input Parameters :
- // Return type : if B-VOP exist, return TRUE. if not exist, return FALSE
- // Description :
- ///////////////////////////////////////////////////////////////////////////
- static BOOL _aviDetectBVOP()
- {
- DWORD dwStartLBA,dwClipStartOffset;
- DWORD pdwOffset;
- BYTE videoStreamID1[FOURCC_FIELD_LENGTH], videoStreamID2[FOURCC_FIELD_LENGTH];
- IndexEntry* pIndexEntry;
- BYTE videoHeaderBuff[64]; // 64 is enough
- WORD wVideoHeaderSize;
- FOURCCInfo pFourccInfo;
- BYTE videoObjectType;
- int i,j;
-
- if (_mpeg4VideoCodec== DIVX_3_11 ||
- _mpeg4VideoCodec == DIVX_4_12 ||
- _mpeg4VideoCodec == MP43 ||
- _mpeg4VideoCodec == DIVX_UNKNOWN)
- {
- dbg_printf(("Video isn't B encoded.n"));
- return FALSE;
- }
- wVideoHeaderSize = 64;
-
- if (_mpeg4VideoHeaderDataLength > 0)
- {
- wVideoHeaderSize = min(wVideoHeaderSize,MPEG4_VIDEO_HEADER_CACHE_SIZE);
- wai_sem(SEM_DRAM_ID);
- I49_ReadDRAMData(SC_MPEG4_VIDEO_HEADER_DATA_ADDR, &videoHeaderBuff, wVideoHeaderSize);
- sig_sem(SEM_DRAM_ID);
- }
- else
- {
-
- dwStartLBA = _dwMPEG4ClipStartLBA;;
- dwClipStartOffset = (DWORD)_wMPEG4ClipStartOffset;;
- if (TRUE == _bMPEG4TrickModeOn)
- {
- pIndexEntry = malloc(sizeof(IndexEntry));
- if( NULL == pIndexEntry)
- {
- dbg_printf(("FATAL: _aviDetectBVOP() Failed [4]: Malloc failed. Low system resource.n"));
- return FALSE;
- }
- wai_sem(SEM_DRAM_ID);
- I49_ReadDRAMData(CALC_IDX_ENTRY_ADDRESS(MPEG4_PROCESSING_BUFF_ADDR,0),
- (UINT16*)pIndexEntry, sizeof(IndexEntry)/2);
- sig_sem( SEM_DRAM_ID );
- pdwOffset = dwClipStartOffset + pIndexEntry->ulVideoChunkOffset + FOURCC_FIELD_LENGTH;
- free(pIndexEntry);
- }
- else
- {
- videoStreamID1[0] = '0';
- videoStreamID1[1] = _mpeg4VideoStreamID + '0';
- videoStreamID1[2] = 'd';
- videoStreamID1[3] = 'c';
- videoStreamID2[0] = '0';
- videoStreamID2[1] = _mpeg4VideoStreamID + '0';
- videoStreamID2[2] = 'd';
- videoStreamID2[3] = 'b';
- pdwOffset = dwClipStartOffset;
- while(TRUE)
- {
- /* Get the next FOURCC */
- if (FALSE == _getNextFOURCC(dwStartLBA, pdwOffset, &pFourccInfo))
- {
- dbg_printf(("_detectBVOP(): _searchForFOURCC() Failedn"));
- return FALSE;
- }
-
- //there is "LISTxxxxrec " before the chunk header
- if (TRUE == pFourccInfo.bIsList &&
- 0 == strnicmp((LPSTR)pFourccInfo.aFOURCCBuff, "rec ", FOURCC_FIELD_LENGTH))
- {
- pdwOffset += FOURCC_FIELD_LENGTH;
- pdwOffset += SIZE_FIELD_LENGTH;
- pdwOffset += FOURCC_FIELD_LENGTH;
- if (FALSE == _getNextFOURCC(dwStartLBA, pdwOffset, &pFourccInfo))
- {
- dbg_printf(("_detectBVOP(): _searchForFOURCC() Failedn"));
- return FALSE;
- }
- }
- /* Check whether this is the FOURCC we are looking for */
- if (0 == strnicmp((LPSTR)pFourccInfo.aFOURCCBuff, (LPSTR)videoStreamID1, FOURCC_FIELD_LENGTH) ||
- 0 == strnicmp((LPSTR)pFourccInfo.aFOURCCBuff, (LPSTR)videoStreamID2, FOURCC_FIELD_LENGTH))
- {
- /* Reach the chunk/list data area */
- pdwOffset += FOURCC_FIELD_LENGTH;
- pdwOffset += SIZE_FIELD_LENGTH;
- break;
- }
- /* Skip to the next list/chunk */
- pdwOffset += FOURCC_FIELD_LENGTH;
- pdwOffset += SIZE_FIELD_LENGTH;
- pdwOffset += (DWORD)pFourccInfo.ulSize;
- }
- }
-
- if (!AuxCache_GetBytes(dwStartLBA, pdwOffset, wVideoHeaderSize, videoHeaderBuff))
- {
- dbg_printf(("_detectBVOP(): AuxCache_GetBytes Failedn"));
- return FALSE;
- }
- }
- for (i=0; i<(wVideoHeaderSize -4);i++)
- {
- if(videoHeaderBuff[i] != 0)
- continue;
- if(videoHeaderBuff[i+1] != 0)
- continue;
- if(videoHeaderBuff[i+2] == 1)
- {
- if ((videoHeaderBuff[i+3] >= 20) && (videoHeaderBuff[i+3] <= 0x2F)) // video obejct layer start code
- {
- break;
- }
- }
- }
- if (i >= (wVideoHeaderSize -4))
- return FALSE;
-
- i += 4;
- j=0;
- j+=1;// random_accessible_vol
- videoObjectType = (videoHeaderBuff[i+(j+1)/8]<<1) + (videoHeaderBuff[i+1+(j+1)/8]>>7);
- dbg_printf(("Video object 0x%xn",videoObjectType));
- j+=8;//video_object_type_indication
- if (((videoHeaderBuff[i+(j+1)/8] >> (7-(j%8))) & 0x1) == 0x1)
- j+=7;
- j+=1;
- if (((videoHeaderBuff[i+(j+1)/8] >> (7-4 -(j%8))) & 0xF) == 0xF) //
- j+=16;
- j+=4;
- if (((videoHeaderBuff[i+(j+1)/8] >> (7-(j%8))) & 0x1) == 0x1)
- {
- j+=1;
- j+=2;
- if (((videoHeaderBuff[i+(j+1)/8] >> (7-(j%8))) & 0x1) == 0x1) // low delay
- {
- dbg_printf(("Video isn't B encoded.n"));
- return FALSE;
- }
- else
- return TRUE;
- }
- else
- {
- if(videoObjectType == 0x01) // simple
- return FALSE;
- else if (videoObjectType == 0x11) // advanced simple
- return TRUE;
- else
- return FALSE;
- }
- }
- #endif
- /////////////////////////////////////////////////////////////////////////////
- // Public Services
- BOOL AVIClip_isKindOf(LPCWSTR i_pszFilename)
- {
- return GenericClip_isKindOf(i_pszFilename, CLIP_VALID_EXTENSIONS(AVI));
- }
- void AVIClip_construct(struct Clip_TAG *o_pThis, const FindData *i_pFileInfo)
- {
- GenericClip_construct(o_pThis, i_pFileInfo);
- o_pThis->m_pConstAttr = &CLIP_CONST_ATTR(AVI);
- }
- ///////////////////////////////////////////////////////////////////////////
- // Function name : AVIClip_continueScanning
- // Purpose : Trigger the navigator to give the next playback
- // request during scanning.
- // Input Parameters : none
- // Return type : none
- // Description : The function acts as a callback from the DEMUX to
- // signal reaching the end of the previous playback
- // request.
- ///////////////////////////////////////////////////////////////////////////
- void AVIClip_continueScanning(void)
- {
- /* Verify that we are in FF I only mode */
- #ifdef IP_SUPPORT
- if ( (gns.clips.iScanSpeed != 0) && (gns.clips.iScanSpeed != SCAN_SPEED_2X) )
- #else
- if (gns.clips.iScanSpeed != 0)
- #endif
- {
- _aviScan(_iMPEG4CurrentScanningMode, TRUE);
- }
- }
- /////////////////////////////////////////////////////////////////////////////
- // Virtual Methods
- #pragma argsused
- BOOL AVIClip_getExtendedInfo(const struct Clip_TAG *i_pThis,
- WORD i_pExtInfo_sc_handle)
- {
- // TBD - 'strn' chunk
- return FALSE;
- }
- #pragma argsused
- BOOL AVIClip_play(Clip *i_pThis, const ClipMarker *i_pResumeMarker, BOOL bCacheOnly)
- {
- DWORD dwClipStartAddr = (i_pThis->m_cfiInfo).dwFileLocation, dwStartLBA;
- WORD wClipStartOffset;
- WORD wClipEndOffset;
- FOURCCInfo movieList;
- DWORD dwMovieListOffset = AVI_HEADER_OFFSET;
- ULONG ulBlocksCnt;
- UINT8 uiAudioSID, uiAudioSIDDecoder;
- DWORD dwSamplingRate;
- UINT16 uiNumOfFramesToSkip = 0;
- // Robin_1003_2004_D
- UINT16 uiNumOfAudioChunksToSkip = 0;
- // Robin_1009_2004, large size of audio chunk, more than 2^16
- UINT32 uiNumOfAudBytesToSkip = 0;
- UINT32 uiNumOfFramesStart = 0;
- static DWORD dwFirstChunkOffset; // Robin_0809_2004, hold the value of fisrtchunkoffset when index not processing
- IndexEntry* pIndexEntry;
- // <<< Robin_0903_2004
- #ifdef DIVX_SUPPORT_MULTI_SUBTITLE_MODE0
- static BYTE subFileSelect = 0;
- static UINT8 subtitleSelect = 0;
- #endif
- // >>> Robin_0903_2004
- static BYTE lastSubtitleStreamID;
- dbg_printf(("Playing AVI filen"));
-
- Logo_selectSource(eFrame);
-
- #if defined(NO_AUTO_PLAY_FOR_CLIPS) || defined(NO_AUTO_PLAY_ONLY_FOR_DVIX)
- if (g_patch_4_auto_play)
- {
- g_patch_4_auto_play = FALSE;
- return TRUE;
- }
- #endif
-
- _uiMPEG4TotalDVPIdleTime = 0;
- /* Check if the AVI info should be acquired */
- if (NULL == i_pResumeMarker)
- {
- _bMPEG4PauseToSlow = FALSE;
- _mpeg4SubtitleCurrentDispIdx = 0;
- _mpeg4AudioCurrentDispIdx = 0;
- _mpeg4ChapterCurrentDispIdx = 0;
- change_pallet = TRUE;
- _bMPEG4WasClockEnabled = FALSE;
- if (_uiMPEG4ProcessedFileAddr != dwClipStartAddr) //Don't process index if already processed.
- _bMPEG4IsIndexProcessed = FALSE;
-
- _iMPEG4CurrentScanningMode = 0;
- _lAVIPreviousFrameNumber = -1;
- _uiMPEG4NumOfDecodedChunksMemory = 0;
- _bMPEG4TrickModeOn = TRUE;
- _uiMPEG4StartTime = 0;
- // _dwMPEG4ProcessingEndAddr = MPEG4_PROCESSING_BUFF_ADDR;
- // Clear shared RAM offsets that will be used
- DEC_AVI_ClearSharedOffset(0);
- DEC_AVI_ClearSharedOffset(1);
- // RB_1124_2004, add "mpeg4 loading..." display
- ie_send(IE_UI_MPEG4_LOADING_START);
-
- if (FALSE == _acquireAVIInfo(dwClipStartAddr))
- {
- Logo_selectSource(eStartup);
- Logo_display();
-
- //inform UI to display "Wrong File Content"
- ie_send(IE_UI_CLIPS_CLEAR_UI);
- core_report_error( IE_UI_REPORT_ERROR, (void *) CLIPSNAV_ERR_WRONGFILE_UOP );
- tr_printf(("FATAL: AVIClip_play() Failed [1]n"));
- usleep(300000UL); // ensure UI accept the event
- return FALSE;
- }
- #ifdef AVI_DRM_SUPPORT
- Logo_selectSource(eFrame);
- #endif
- if (_mpeg4AudioCurrentDispIdx >= _mpeg4AudioAvailableNum)
- {
- _mpeg4AudioCurrentDispIdx = 0;
- }
- if (_bAVIDrmOn)
- PS_Save();
-
- DEC_AVI_SetDrm( _bAVIDrmOn );
- if (DIVX_UNKNOWN == _mpeg4VideoCodec)
- {
- dbg_printf(("FATAL: AVIClip_play() Failed [2]n"));
- ie_send(IE_UI_CLIPS_CLEAR_UI);
- return FALSE;
- }
- // always first audio stream
- sc_GetBytes(SC_MPEG4_AUDIO_STREAM_INFO_ADDR,
- 0,
- SIZE_OF_AUDIO_STREAM_INFO,
- (BYTE*)&_mpeg4AudioStreamInfo
- );
- if (_mpeg4AudioAvailableNum == 0)
- _mpeg4AudioStreamID = NO_STREAM;
-
- ie_send(IE_UI_MPEG4_LOADING_START);
- #ifdef AVI_PROCCESS_IDX_ON_CLIP_START
- if (FALSE == _aquireAndProcessIdx(dwClipStartAddr, _mpeg4VideoStreamID, _mpeg4AudioStreamID, &dwFirstChunkOffset))
- {
- dbg_printf(("WARNING: Aquiring the INDEX FAILEDn"));
- }
- #endif // AVI_PROCCESS_IDX_ON_CLIP_START
- // <<< Robin_1003_2004_C
- if (FALSE == bVideoAudioInterleave)
- {
- _mpeg4AudioStreamID = NO_STREAM;
- }
- determineAudioInfo(&uiAudioSID, &uiAudioSIDDecoder, &dwSamplingRate);
- // >>> Robin_1003_2004_C
- #ifdef AVI_FF_NO_INDEX
- DEC_AVI_SetIndex(_bMPEG4TrickModeOn);
- #endif
- // Robin_0527_2004_A
- #ifdef USE_AUX_SUBTITLES
- #ifdef USE_AUX_SUBTITLES
- if (_bMPEG4IsIndexProcessed == FALSE) // mean no index
- _mpeg4ExternalSubtitleAddr = MPEG4_PROCESSING_BUFF_ADDR;
- #endif
- // <<< Robin_0903_2004
- // <<< Robin_0907_2004
- SI_CLIPS_SUB_CURRENT_DISP_IDX = SI_CLIPS_SUB_AVAILABLE_NUM;
- if (FALSE == initAuxSubtitles(&(i_pThis->m_cfiInfo), _mpeg4VideoScale, _mpeg4VideoRate))
- // >>> Robin_0907_2004
- {
- SI_CLIPS_SUB_CURRENT_DISP_IDX = 0;
- }
- // >>> Robin_0903_2004
- AuxCache_GetFileTerminate();
- #endif //USE_AUX_SUBTITLES
- // <<< Robin_0903_2004
- #ifdef DIVX_SUPPORT_MULTI_SUBTITLE_MODE0
- subFileSelect = Get_SubFile_Select();
- subtitleSelect = SI_CLIPS_SUB_CURRENT_DISP_IDX;
- #endif
-
- #ifdef DIVX_SUPPORT_MULTI_SUBTITLE
- if (SI_CLIPS_SUB_AVAILABLE_NUM > 1)
- {
- sc_GetBytes(SC_MPEG4_SUBTITLE_STREAM_INFO_ADDR,
- (SI_CLIPS_SUB_CURRENT_DISP_IDX * SIZE_OF_SUBTITLE_STREAM_INFO),
- SIZE_OF_SUBTITLE_STREAM_INFO,
- (BYTE*)&_mpeg4SubtitleStreamInfo
- );
- }
- #endif
- // >>> Robin_0903_2004
- /* Reaching the movie list FOURCC */
- if (FALSE == _searchForFOURCC(dwClipStartAddr, &dwMovieListOffset, AVI_MOVIE_LIST_ID, &movieList, FALSE, 0))
- {
- dbg_printf(("FATAL: AVIClip_play() Failed [3]n"));
- ie_send(IE_UI_CLIPS_CLEAR_UI);
- return FALSE;
- }
- #if 0
- {
- // search "AVIX"
- DWORD dwAvi2OffsetSec;
- FOURCCInfo Avi2FourccInfo;
- dwAvi2OffsetSec = dwMovieListOffset;
- if (TRUE == _searchForFOURCC(dwClipStartAddr, &dwAvi2OffsetSec, RIFF_ID, &Avi2FourccInfo, FALSE, 0))
- {
- if (dwAvi2OffsetSec <= (i_pThis->m_cfiInfo).cbFileSize)
- {
- dwAvi2OffsetSec -= (DWORD)Avi2FourccInfo.ulSize;
- if (TRUE == AuxCache_GetBytes(dwClipStartAddr, dwAvi2OffsetSec, (WORD)FOURCC_FIELD_LENGTH, Avi2FourccInfo.aFOURCCBuff))
- {
- /* Verifying that the RIFF file is an AVIX one */
- if (0 == strnicmp((LPSTR)(Avi2FourccInfo.aFOURCCBuff), AVI2_ID, FOURCC_FIELD_LENGTH))
- {
- dbg_printf(("AVI2 FOURCC detected...n"));
- dwAvi2OffsetSec += FOURCC_FIELD_LENGTH;
- if (TRUE == _searchForFOURCC(dwClipStartAddr, &dwAvi2OffsetSec, AVI_MOVIE_LIST_ID, &Avi2FourccInfo, FALSE, 0))
- {
- movieList.ulSize += (dwAvi2OffsetSec - dwMovieListOffset) ;
- dwMovieListOffset = dwAvi2OffsetSec;
- }
- }
- }
-
- }
- }
- }
- #endif
- /* Updating the offset to the start of the movie list data */
- dwMovieListOffset -= (DWORD)movieList.ulSize;
- dwMovieListOffset += LIST_TYPE_FIELD_LENGTH;
-
- /* Calculate and save playback addresses */
- dwStartLBA = dwClipStartAddr + (dwMovieListOffset >> 11);
- wClipStartOffset = (WORD)(dwMovieListOffset % LOGICAL_BLOCK_SIZE);
- // <<< Robin_1014_2004, merge the Orion change, the playbackrange size should be smaller than the actual file size,
- if ((i_pThis->m_cfiInfo).cbFileSize < (wClipStartOffset + movieList.ulSize - LIST_TYPE_FIELD_LENGTH))
- {
- ulBlocksCnt = ((wClipStartOffset + ((i_pThis->m_cfiInfo).cbFileSize - dwMovieListOffset + LIST_TYPE_FIELD_LENGTH) +
- LOGICAL_BLOCK_SIZE - 1) / LOGICAL_BLOCK_SIZE);
- wClipEndOffset = (WORD)((wClipStartOffset + ((i_pThis->m_cfiInfo).cbFileSize - dwMovieListOffset + LIST_TYPE_FIELD_LENGTH) - LIST_TYPE_FIELD_LENGTH) % LOGICAL_BLOCK_SIZE);
-
- }
- else
- {
- ulBlocksCnt = ((wClipStartOffset + movieList.ulSize - LIST_TYPE_FIELD_LENGTH +
- LOGICAL_BLOCK_SIZE - 1) / LOGICAL_BLOCK_SIZE);
- wClipEndOffset = (WORD)((wClipStartOffset + movieList.ulSize - LIST_TYPE_FIELD_LENGTH) % LOGICAL_BLOCK_SIZE);
- }
- // >>> Robin_1004_2004,
- wClipEndOffset += (wClipEndOffset % 2); /* Word alignment */
-
- if (0 == wClipEndOffset)
- {
- wClipEndOffset = 2048;
- }
-
- /*
- in some AVI files, the chunk offset of index is given as an offset from the start of the file.
- */
- if (dwFirstChunkOffset == dwMovieListOffset)
- {
-
- // <<< Robin_1003_2004_A
- if (TRUE == _checkAVIClipOffset(dwClipStartAddr,dwMovieListOffset))
- {
- _dwMPEG4ClipStartLBA = dwStartLBA;
- _wMPEG4ClipStartOffset = wClipStartOffset;
- }
- // >>> Robin_1003_2004_A
- else
- {
- _dwMPEG4ClipStartLBA = dwClipStartAddr;
- _wMPEG4ClipStartOffset = 4;
- }
- }
- else
- {
- _dwMPEG4ClipStartLBA = dwStartLBA;
- _wMPEG4ClipStartOffset = wClipStartOffset;
- }
- _wMPEG4ClipEndOffset = wClipEndOffset;
- _ulMPEG4TotalBlocksCnt = ulBlocksCnt;
- _dwMPEG4FileLocation = dwClipStartAddr;
- // <<< Robin_1003_2004_C
- if (FALSE == bVideoAudioInterleave)
- {
- pIndexEntry = malloc(sizeof(IndexEntry));
- if( NULL == pIndexEntry)
- {
- dbg_printf(("FATAL: AVIClip_play() Failed [4]: Malloc failed. Low system resource.n"));
- return FALSE;
- }
- wai_sem(SEM_DRAM_ID);
- I49_ReadDRAMData(CALC_IDX_ENTRY_ADDRESS(MPEG4_PROCESSING_BUFF_ADDR,0),
- (UINT16*)pIndexEntry, sizeof(IndexEntry)/2);
- sig_sem( SEM_DRAM_ID );
- dwStartLBA = _dwMPEG4ClipStartLBA +
- ( (_wMPEG4ClipStartOffset + pIndexEntry->ulVideoChunkOffset - FOURCC_FIELD_LENGTH) >> 11);
- wClipStartOffset = (_wMPEG4ClipStartOffset + pIndexEntry->ulVideoChunkOffset -
- FOURCC_FIELD_LENGTH) % LOGICAL_BLOCK_SIZE;
- ulBlocksCnt = _ulMPEG4TotalBlocksCnt - (dwStartLBA - _dwMPEG4ClipStartLBA);
- wClipEndOffset = _wMPEG4ClipEndOffset;
-
- free(pIndexEntry);
- }
- // >>> Robin_1003_2004_C
- /* Set total clip time */
- // Robin_1003_2004_B
- // Robin_1009_2004, total time is max value of video/audio playback time
- {
- UINT16 uVideoTotalPlaybackTime, uAudioTotalPlaybackTime;
- uVideoTotalPlaybackTime = caclTimeOfFrame( _mpeg4VideoLength,
- _mpeg4VideoRate,
- _mpeg4VideoScale);
- if (_mpeg4AudioStreamID== NO_STREAM)
- uAudioTotalPlaybackTime = 0;
- else
- // <<< Robin_1012_2004, calculate the total time of CBR/VBR audio
- {
- if (_mpeg4AudioScale == AVI_VBR_AUD_STREAM_SCALE)
- {
- // VBR audio
- uAudioTotalPlaybackTime = caclTimeOfFrame(_mpeg4AudioLength,
- _mpeg4AudioRate,
- _mpeg4AudioScale);
- }
- else
- {
- // CBR audio
- uAudioTotalPlaybackTime = (_mpeg4AudioLength *
- _mpeg4AudioScale) /
- _mpeg4AudioAvgBytesPerSec;
- }
- }
- // >>> Robin_1012_2004,
- gns.clips.uTotalPlaybackTime = MAX(uVideoTotalPlaybackTime,uAudioTotalPlaybackTime);
-
- }
-
- dbg_printf(("Total Clip Time: %d secn", gns.clips.uTotalPlaybackTime));
- #ifdef PATCH_VIDEO_NOT_B
- _bMPEG4IsBVopExist = _aviDetectBVOP();
- #endif
- // Robin_0117_2005, support AVI internal text subtitle
- #if 0
- if (_mpeg4SubtitleType == AVI_INTERNAL_TEXT && _mpeg4SubtitleStreamID != NO_STREAM)
- {
- aviParseInternalSubtileText();
- lastSubtitleStreamID = _mpeg4SubtitleStreamID;
- }
- #endif
- ie_send(IE_UI_CLIPS_CLEAR_UI);
- }
- else
- {
- #ifdef AVI_FF_NO_INDEX
- if ((FALSE == _bMPEG4TrickModeOn) && (_uiMPEG4NextIndexEntry == 0))
- {
- /* Resuming, handled as goto time */
- DEC_AVI_ChangedSubtitle(_mpeg4SubtitleStreamID);
- determineAudioInfo(&uiAudioSID, &uiAudioSIDDecoder, &dwSamplingRate);
- DEC_AVI_GetVideoStatus((UINT32*)&_uiMPEG4StartTime, (UINT32*)&ulBlocksCnt);
- dwStartLBA = _dwMPEG4ClipStartLBA + (_ulMPEG4TotalBlocksCnt - ulBlocksCnt);
- wClipStartOffset = 0;
- wClipEndOffset = _wMPEG4ClipEndOffset;
- uiNumOfFramesToSkip = 0;
- uiNumOfAudBytesToSkip = 0;
- uiNumOfFramesStart = 0;
- }
- else
- #endif
- {
- UINT16 uAudioTotalPlaybackTime;
-
- /* Resuming, handled as goto time */
- DEC_AVI_ChangedSubtitle(_mpeg4SubtitleStreamID);
-
- /* Calculate the video frame to skip to */
- _aviProcessTimeToAddressInfo(i_pResumeMarker->dwAddress, i_pResumeMarker->uTime);
- // <<< Robin_1003_2004_C
- if (FALSE == bVideoAudioInterleave)
- {
- _mpeg4AudioStreamID = NO_STREAM;
- }
- // >>> // Robin_1003_2004_C
- determineAudioInfo(&uiAudioSID, &uiAudioSIDDecoder, &dwSamplingRate);
-
- // <<< Robin_1210_2004, if the resume time exceed the total audio time, set audio is no stream
- {
-
- if (_mpeg4AudioStreamID== NO_STREAM)
- uAudioTotalPlaybackTime = 0;
- else if (_mpeg4AudioLength == 0)
- uAudioTotalPlaybackTime = gns.clips.uTotalPlaybackTime;
- else
- {
- if (_mpeg4AudioScale == AVI_VBR_AUD_STREAM_SCALE)
- {
- // VBR audio
- uAudioTotalPlaybackTime = caclTimeOfFrame(_mpeg4AudioLength,
- _mpeg4AudioRate,
- _mpeg4AudioScale);
- }
- else
- {
- // CBR audio
- uAudioTotalPlaybackTime = (_mpeg4AudioLength *
- _mpeg4AudioScale) /
- _mpeg4AudioAvgBytesPerSec;
- }
- }
- }
- // >>> Robin_1210_2004
- pIndexEntry = malloc(sizeof(IndexEntry));
- if( NULL == pIndexEntry)
- {
- dbg_printf(("FATAL: AVIClip_play() Failed [5]: Malloc failed. Low system resource.n"));
- return FALSE;
- }
-
- wai_sem(SEM_DRAM_ID);
- I49_ReadDRAMData(CALC_IDX_ENTRY_ADDRESS(MPEG4_PROCESSING_BUFF_ADDR,(_ulMPEG4RequestedFrameIndex*sizeof(IndexEntry))),
- (UINT16*)pIndexEntry, sizeof(IndexEntry)/2);
- sig_sem( SEM_DRAM_ID );
- dbg_printf(("Resuming: Frame number %ld, Video chunk offset 0x%lx, Audio chunk offset 0x%lxn",
- pIndexEntry->ulVideoFrameNumber, pIndexEntry->ulVideoChunkOffset,
- pIndexEntry->ulAudioChunkOffset));
- /* Calculate the actual start time */
- _uiMPEG4StartTime = caclTimeOfFrame(pIndexEntry->ulVideoFrameNumber,
- _mpeg4VideoRate,
- _mpeg4VideoScale);
-
- dbg_printf(("time %d secn", _uiMPEG4StartTime));
-
- if (_uiMPEG4StartTime >= uAudioTotalPlaybackTime)
- {
- uiAudioSID = NO_STREAM;
- uiAudioSIDDecoder = NoAudio;
- }
-
- if ((NO_STREAM == _mpeg4AudioStreamID) || /*(TRUE == _bAVIVideoBeforeAudio) ||*/
- (_uiMPEG4StartTime >= uAudioTotalPlaybackTime)) //Robin_1210_2004
- {
- /* Start playback from the exact video chunk */
- dwStartLBA = _dwMPEG4ClipStartLBA +
- ( (_wMPEG4ClipStartOffset + pIndexEntry->ulVideoChunkOffset - FOURCC_FIELD_LENGTH) >> 11);
- wClipStartOffset = (WORD)((_wMPEG4ClipStartOffset + pIndexEntry->ulVideoChunkOffset -
- FOURCC_FIELD_LENGTH) % LOGICAL_BLOCK_SIZE);
- uiNumOfFramesToSkip = 0;
- uiNumOfAudBytesToSkip = 0;
- uiNumOfFramesStart = pIndexEntry->ulVideoFrameNumber;
- }
- else
- {
- /* Start playback from the audio chunk preceeding the correcsponding video */
- // <<< Robin_1003_2004_D
- if (pIndexEntry->ulAudioChunkOffset < pIndexEntry->ulVideoChunkOffset)
- {
- dwStartLBA = _dwMPEG4ClipStartLBA +
- ( (_wMPEG4ClipStartOffset + pIndexEntry->ulAudioChunkOffset - FOURCC_FIELD_LENGTH) >> 11);
- wClipStartOffset = (_wMPEG4ClipStartOffset + pIndexEntry->ulAudioChunkOffset -
- FOURCC_FIELD_LENGTH) % LOGICAL_BLOCK_SIZE;
- }
- else
- {
- dwStartLBA = _dwMPEG4ClipStartLBA +
- ( (_wMPEG4ClipStartOffset + pIndexEntry->ulVideoChunkOffset - FOURCC_FIELD_LENGTH) >> 11);
- wClipStartOffset = (_wMPEG4ClipStartOffset + pIndexEntry->ulVideoChunkOffset -
- FOURCC_FIELD_LENGTH) % LOGICAL_BLOCK_SIZE;
- }
- uiNumOfFramesToSkip = pIndexEntry->uiSkipVideoChunks;
- uiNumOfAudioChunksToSkip = pIndexEntry->uiSkipAudioChunks;
- // Robin_1009_2004
- uiNumOfAudBytesToSkip = pIndexEntry->ulAudioChunkDelta;
- uiNumOfFramesStart = pIndexEntry->ulVideoFrameNumber;
- }
- free(pIndexEntry);
- #ifdef AVI_AUDIO_CHANGE_ONSCAN //PATCH: To keep audio frame alignment for audio change on fly, because index table is not accurate
- if (_mpeg4AudioCurrentDispIdx != 0) // Robin_0125_2005_B, only first audio stream be processed druing the index processing
- uiNumOfAudBytesToSkip = 0;
- #endif
- dbg_printf(("ADP skip %ld bytes, DVP skip %d frames, DVP start %ld framen",
- uiNumOfAudBytesToSkip, uiNumOfFramesToSkip,uiNumOfFramesStart));
- ulBlocksCnt = _ulMPEG4TotalBlocksCnt - (dwStartLBA - _dwMPEG4ClipStartLBA);
- wClipEndOffset = _wMPEG4ClipEndOffset;
-
- }
- // <<< Robin_0903_2004
- #ifdef DIVX_SUPPORT_MULTI_SUBTITLE_MODE0
- if (subFileSelect != Get_SubFile_Select())
- {
- MPEG4SubtitleStreamInfo mpeg4LastSubtitleStreamInfo;
- while(SI_CLIPS_SUB_AVAILABLE_NUM > 0)
- {
- sc_GetBytes(SC_MPEG4_SUBTITLE_STREAM_INFO_ADDR,
- ((SI_CLIPS_SUB_AVAILABLE_NUM-1) * SIZE_OF_SUBTITLE_STREAM_INFO),
- SIZE_OF_SUBTITLE_STREAM_INFO,
- (BYTE*)&mpeg4LastSubtitleStreamInfo
- );
- if(mpeg4LastSubtitleStreamInfo.type > INTERNAL_SUBT)
- SI_CLIPS_SUB_AVAILABLE_NUM--;
- else
- break;
- }
- // <<< Robin_0907_2004
- SI_CLIPS_SUB_CURRENT_DISP_IDX = SI_CLIPS_SUB_AVAILABLE_NUM;
- if (FALSE == initAuxSubtitles(&(i_pThis->m_cfiInfo), _mpeg4VideoScale, _mpeg4VideoRate))
- {
- SI_CLIPS_SUB_CURRENT_DISP_IDX = 0;
- }
- AuxCache_GetFileTerminate();
- }
- else if ((SI_CLIPS_SUB_CURRENT_DISP_IDX < SI_CLIPS_SUB_AVAILABLE_NUM) && (_mpeg4SubtitleType == SAMI)
- && (subtitleSelect != SI_CLIPS_SUB_CURRENT_DISP_IDX))
- {
- UINT16 uiSubNum = SI_CLIPS_SUB_AVAILABLE_NUM;
- MPEG4SubtitleStreamInfo mpeg4LastSubtitleStreamInfo;
- while(uiSubNum > 0)
- {
- sc_GetBytes(SC_MPEG4_SUBTITLE_STREAM_INFO_ADDR,
- ((uiSubNum-1) * SIZE_OF_SUBTITLE_STREAM_INFO),
- SIZE_OF_SUBTITLE_STREAM_INFO,
- (BYTE*)&mpeg4LastSubtitleStreamInfo
- );
- if(mpeg4LastSubtitleStreamInfo.type > INTERNAL_SUBT)
- uiSubNum--;
- else
- break;
- }
-
- if ((SI_CLIPS_SUB_AVAILABLE_NUM - uiSubNum) > 1 ) // sami with multi-language
- {
- SI_CLIPS_SUB_AVAILABLE_NUM = uiSubNum;
- if (FALSE == initAuxSubtitles(&(i_pThis->m_cfiInfo), _mpeg4VideoScale, _mpeg4VideoRate))
- {
- SI_CLIPS_SUB_CURRENT_DISP_IDX = 0;
- }
- AuxCache_GetFileTerminate();
- }
- }
- // >>> Robin_0907_2004
- subFileSelect = Get_SubFile_Select();
- subtitleSelect = SI_CLIPS_SUB_CURRENT_DISP_IDX;
-
- if (SI_CLIPS_SUB_AVAILABLE_NUM > 1)
- {
- sc_GetBytes(SC_MPEG4_SUBTITLE_STREAM_INFO_ADDR,
- (SI_CLIPS_SUB_CURRENT_DISP_IDX * SIZE_OF_SUBTITLE_STREAM_INFO),
- SIZE_OF_SUBTITLE_STREAM_INFO,
- (BYTE*)&_mpeg4SubtitleStreamInfo
- );
-
- }
- if (SI_CLIPS_SUB_CURRENT_DISP_IDX == MAX_SUB_PER_CLIP)
- _mpeg4SubtitleStreamID = NO_STREAM;
- #endif
- // >>> Robin_0903_2004
- // Robin_0117_2005, support AVI internal text subtitle
- #if 0
- if (_mpeg4SubtitleType == AVI_INTERNAL_TEXT && _mpeg4SubtitleStreamID != NO_STREAM
- && lastSubtitleStreamID != _mpeg4SubtitleStreamID)
- {
- aviParseInternalSubtileText();
- lastSubtitleStreamID = _mpeg4SubtitleStreamID;
- }
- #endif
- }
-
- prePlayProcessing(dwSamplingRate, uiAudioSID, uiAudioSIDDecoder, (i_pThis->m_pConstAttr)->m_eVideoSID,
- (NULL != i_pResumeMarker) ? FALSE : TRUE);
- #if 0 //FW0408_2005D Move to prePlayProcessing()
- // Set AVI video scaling
- DEC_EnableManualScaling(PROG_SCALER_MODE_CCRAM);
- DEC_SetViewMode(gps->view_mode);
- #endif
- // JG_0819_2004: FF/FB->PLAY/PAUSE need not to do scaling again
- //FW_0526_2005B Comment out, move to prePlayProcessing()
- //if (NULL == i_pResumeMarker)
- //gcst.mNeedScaling = TRUE;
- // <<< Robin_1011_2004, skip bytes by DVP
- // API_ADPSetMp3_Throw_Out_Cntr(uiNumOfAudBytesToSkip);
- API_ADPSetMp3_Throw_Out_Cntr(0);
- uiNumOfAudBytesToSkip = (uiNumOfAudBytesToSkip>>1)<<1; // word align
- #ifdef D_ENABLE_ADPCM_SUPPORT
- if (_mpeg4AudioCodec == ADPCM || _mpeg4AudioCodec == PCM)
- uiNumOfAudBytesToSkip = (uiNumOfAudBytesToSkip/_mpeg4AudioBlockAlign_ADPCM) * _mpeg4AudioBlockAlign_ADPCM;
- #endif
- #ifdef D_ENABLE_DIVX_WMA_SUPPORT
- if (_mpeg4AudioCodec == WMA)
- uiNumOfAudBytesToSkip = (uiNumOfAudBytesToSkip/_mpeg4AudioBlockAlign_WMA) * _mpeg4AudioBlockAlign_WMA;
- #endif
-
- DEC_MP4_SetFirstSkipBytes(0UL,uiNumOfAudBytesToSkip,0UL);
- // Robin_0715_2004, merge changelist #24806
- // API_ADP_UpdateTaskParam( UPDATE_TASK_PARAM_MP3_THROW_OUT_CNTR,0 , NOT_SEND_TO_ADP);
- // >>> Robin_1011_2004
- DEC_AVI_SetStartVideoChunks(uiNumOfFramesStart);
- // Robin_1003_2004_D
- DEC_AVI_SetPlaybackParams(wClipStartOffset, wClipEndOffset, _uiMPEG4StartTime, uiNumOfFramesToSkip,uiNumOfAudioChunksToSkip );
- PE_Clips_SetPlaybackRange(dwStartLBA, ulBlocksCnt, UNLIMITED_FILE_SIZE);
-
- if (IS_CD_MEDIA)
- {
- drv_set_bit_rate(DRV_HIGH_BITRATE_E);
- }
-
- if (!PE_Clips_Playback_Sectors(DRVCF_CDSPEED_1X | DRVF_PLAY_CD_AV_DATA, dwStartLBA, ulBlocksCnt))
- {
- dbg_printf(("FATAL: AVIClip_play() Failed [6]n"));
- return FALSE;
- }
-
- return TRUE;
- }
- #pragma argsused
- void AVIClip_pause(Clip *i_pThis, BOOL bEnable)
- {
- dbg_printf(("AVIClip_pause(%d)n", bEnable));
- if (bEnable)
- {
- /* in case we were in FF, */
- if (gns.clips.iScanSpeed != 0)
- {
- int watchdog = 100;
- AVIClip_scan(i_pThis, 0); /* Resume playback */
- //Wait until enter NSPB
- while (DEC_getState() != DEC_LL_STATUS0_C_STATE_NSPB && --watchdog)
- {
- usleep(5000UL);
- }
- }
- /* Clear DVP indication that this is a pause-stop (and not pause) */
- DEC_AVI_ClearDemuxSharedBit(AVI_FILE_PAUSE_OFFSET, AVI_FILE_PAUSE_BIT);
- API_ADPSetMp3_Throw_Out_Cntr(0);
- /* Pause the Decoder */
- DEC_PlaybackCommand(DEC_PLAYBACK_CMD_PAUSE, NULL);
- }
- else
- {
- #ifdef USE_AUX_SUBTITLES
- if (FALSE != areAuxSubtitlePresent()) // Robin_0528_2004_A, disable AuxSubtitle function if it not availabe
- {
- // perform seek in subtitles storage
- // replace 0 with the correct time, once it can be determined before playback
- // actually resumes
- subtitleGoToTime(0);
- setSubtitlesPlayMode(TRUE);
- }
- #endif //USE_AUX_SUBTITLES
- /* Resume the Decoder */
- /* in case we were in FF, terminate it and resume playback */
- DEC_PlaybackCommand(DEC_PLAYBACK_CMD_RESUME, NULL);
- }
- }
- #pragma argsused
- void AVIClip_refresh(Clip *i_pThis)
- {
- #ifdef MPP_SUPPORT
- /* just enable MPP after playback, otherwise screen green or flash */
- if( (PST_STOP != gcs.pstate) && (gns.clips.iCurrentTime >= 1) )
- {
- DEC_SetMPP( gcst.mMPP_Enable );
- }
- #endif
- }
- #pragma argsused
- enClipStatus AVIClip_getStatus(const Clip *i_pThis)
- {
- UINT32 uiNumOfDecodedChunksCurrent;
- UINT16 uiVideoDecodingError;
- /* If we are in FF/FB I only, don't regard this status */
- #ifdef IP_SUPPORT
- if ( (PST_SCAN == gcs.pstate) && (SCAN_SPEED_2X != gns.clips.iScanSpeed) )
- #else
- if (PST_SCAN == gcs.pstate)
- #endif
- {
- return eCS_Busy;
- }
- /* In NSPB check the DVP video status and perform error handling if it gets stuck */
- DEC_AVI_GetVideoDecodingStatus(&uiNumOfDecodedChunksCurrent,&uiVideoDecodingError);
- #ifdef SUPPORT_FLASH_CARD
- if(IS_PLAYING_CARD)
- _uiMPEG4TotalDVPIdleTime += 50; /* Core tick - 200 msec , slow down the counter for card*/
- else
- #endif
- _uiMPEG4TotalDVPIdleTime += 200; /* Core tick - 200 msec */
- if (PST_PLAY == gcs.pstate &&
- 0 != _uiMPEG4NumOfDecodedChunksMemory &&
- _uiMPEG4NumOfDecodedChunksMemory == uiNumOfDecodedChunksCurrent &&
- (_uiMPEG4TotalDVPIdleTime >= DVP_VIDEO_TASK_WATCHDOG_TIME || uiVideoDecodingError == 0xF) &&
- _uiMPEG4NumOfDecodedChunksMemory != _mpeg4VideoLength )
- {
- ClipMarker mClipMarker;
- UINT32 ulNextIIdx;
- WORD wNextITime;
- tr_printf(("DVP video error...n"));
- /* Resume playback from the next I frame */
- _uiMPEG4NumOfDecodedChunksMemory = 0; /* Prevent re-initiating */
- _uiMPEG4TotalDVPIdleTime = 0;
- if (TRUE == _getNextIFrames((i_pThis->m_cfiInfo).dwFileLocation, uiNumOfDecodedChunksCurrent,
- &ulNextIIdx, &wNextITime) )
- {
- if(ulNextIIdx == _uiMPEG4NextIndexEntry)
- {
- DEC_AVI_EnableFinishCB(FALSE);
- ie_send(IE_CORE_CDNAV_FINISHED);
- }
-
- mClipMarker.dwAddress = (i_pThis->m_cfiInfo).dwFileLocation;
- if(wNextITime <= mClipMarker.uTime)
- mClipMarker.uTime = wNextITime+1;
- else
- mClipMarker.uTime = wNextITime;
- (i_pThis->m_pConstAttr->m_vtable.m_pfPlay)(i_pThis, &mClipMarker, FALSE);
- }
- else
- {
- ie_send(IE_CORE_CDNAV_FINISHED);
- return eCS_Busy;
- }
- }
- else if ( (_uiMPEG4NumOfDecodedChunksMemory != uiNumOfDecodedChunksCurrent) || (0 == _uiMPEG4NumOfDecodedChunksMemory) )
- {
- _uiMPEG4TotalDVPIdleTime = 0;
- }
-
- _uiMPEG4NumOfDecodedChunksMemory = uiNumOfDecodedChunksCurrent;
- /* Normal speed playback */
- if (drv_is_play_done() && DEC_IsPlaybackFinished(FALSE))
- {
- return eCS_Finished;
- }
- return eCS_Busy;
- }
- #pragma argsused
- UINT16 AVIClip_getTime(const Clip *i_pThis)
- {
- UINT16 uiStatus2 = inport(I64_STATUS_2);
-
- /* Check if the DVP is not running yet */
- if ( (uiStatus2 & DVP_UPDATED_SCLK_MASK) == 0 )
- {
- /* SCLK start time is still not updated by the DVP */
- _bMPEG4WasClockEnabled = FALSE;
-
- return _uiMPEG4StartTime;
- }
- else if (FALSE == _bMPEG4WasClockEnabled)
- {
- PE_Clips_EnableClock(TRUE, TRUE, _uiMPEG4StartTime);
- _bMPEG4WasClockEnabled = TRUE;
- }
- #ifdef USE_AUX_SUBTITLES
- if (FALSE != areAuxSubtitlePresent())// Robin_0528_2004_A
- {
- // read the SCLK to get better update resolution than 1 sec.
- checkAndHandleAuxSubtitles(PE_Clips_GetClock_Raw()); // Robin_2004_0517_B, resolution in ms
- }
- #endif // USE_AUX_SUBTITLES
- _uiMPEG4StartTime = PE_Clips_GetClock();
- return _uiMPEG4StartTime;
- }
- #pragma argsused
- void AVIClip_abort(Clip *i_pThis, BOOL bMaintainStandby)
- {
- #ifdef MPP_SUPPORT
- DEC_SetMPP(FALSE);
- #endif
- #ifdef AVI_DRM_SUPPORT
- if (NULL != pMasterKeyInstance)
- {
- free (pMasterKeyInstance);
- dbg_printf(("key instance memory free.n"));
- pMasterKeyInstance = NULL;
- }
- #endif //AVI_DRM_SUPPORT
-
- DEC_AVI_EnableFinishCB(FALSE);
- if (IS_CD_MEDIA)
- {
- drv_set_bit_rate(DRV_NORMAL_BITRATE_E);
- }
-
- GenericClip_abort(i_pThis, bMaintainStandby);
- }
- #pragma argsused
- void AVIClip_scan(Clip *i_pThis, int iScanSpeed)
- {
- INT8 iIndexIncrement;
- // Robin_0903_2004_B, merge changlist #26190 from the Main DB
- UINT8 eNoBScanSpeedMap = 0;
- #ifdef A_SD340E
- ///////wesleyj for divx scan speed
- if(iScanSpeed > 0)
- {
- if(iScanSpeed >=30)
- iScanSpeed = 8;
- else if(iScanSpeed >=8)
- iScanSpeed = 4;
- else
- iScanSpeed = 2;
- }
- else if(iScanSpeed < 0)
- {
- if(iScanSpeed < -30)
- iScanSpeed = -20;
- else if(iScanSpeed < -8)
- iScanSpeed = -8;
- else if(iScanSpeed < -4)
- iScanSpeed = -4;
- else
- iScanSpeed = -2;
- }
- ///////////////////////////////////
- #endif
- #ifdef AVI_FF_NO_INDEX
- if (_bMPEG4TrickModeOn)
- #endif
- {
- // <<< Robin_0903_2004_B, merge changlist #26190 from the Main DB
- if (iScanSpeed > 0)
- {
- if (iScanSpeed <=2)
- eNoBScanSpeedMap = 4;
- else if (iScanSpeed <=4)
- eNoBScanSpeedMap = 8;
- else
- eNoBScanSpeedMap = 20;
- }
- else if(iScanSpeed < -8)
- {
- iScanSpeed = -20;
- }
- // >>> Robin_0903_2004_B
- }
- /* Check if we are in scanning */
- if (iScanSpeed != 0)
- {
- if ( (PST_SLOW == gcs.pstate) || (PST_PLAY == gcs.pstate) || (PST_SCAN == gcs.pstate) || (PST_PAUSE == gcs.pstate) )
- {
- #ifdef USE_AUX_SUBTITLES
- if (FALSE != areAuxSubtitlePresent())// Robin_0528_2004_A
- {
- // stop subtitle seeking
- setSubtitlesPlayMode(FALSE);
- stopDisplayAuxSubtitles();
- }
- #endif //USE_AUX_SUBTITLES
- #ifdef IP_SUPPORT
- if ( ! FOUND_B_PICS_IN_CLIP && iScanSpeed > 0 )
- {
- // Robin_0903_2004_B
- iScanSpeed = eNoBScanSpeedMap;
- dbg_printf(("No B pictures detectedn"));
- }
- if( _aviFileInfo.bDrmOn && iScanSpeed > 0 )
- {
- // Robin_0903_2004_B
- iScanSpeed = eNoBScanSpeedMap;
- dbg_printf(("DRM on, no FF-IPn"));
- }
- #else
- if ( iScanSpeed > 0 )
- {
- #ifdef AVI_FF_NO_INDEX
- if (_bMPEG4TrickModeOn)
- #endif
- // Robin_0903_2004_B
- iScanSpeed = eNoBScanSpeedMap;
- }
- #endif
- dbg_printf(("AVIClip_scan(x%d)n", iScanSpeed));
- /* Calculate the increment in the idx table */
- switch (iScanSpeed)
- {
- case SCAN_SPEED_2X:
- DEC_AVI_EnableFinishCB(FALSE);
- DEC_AVI_SetIOnly(FALSE);
- /* If we are moving from I to IP only, need to resume playback */
- if (gns.clips.iScanSpeed != 0)
- {
- AVIClip_scan(i_pThis, 0); /* Resume playback */
- AVIClip_scan(i_pThis, SCAN_SPEED_2X); /* Resume IP scanning mode */
- return;
- }
- #ifdef AVI_FF_NO_INDEX
- if (FALSE == _bMPEG4TrickModeOn)
- DEC_AVI_EnableFinishCB(TRUE);
- #endif
- DEC_AVI_SetIPOnly(TRUE);
- iIndexIncrement = I_P_INCREMENT;
- _iMPEG4CurrentScanningMode = iIndexIncrement;
- gns.clips.iScanSpeed = iScanSpeed;
- gcs.pstate= PST_SCAN;
- return;
- case SCAN_SPEED_4X:
- #ifdef AVI_FF_NO_INDEX
- if (FALSE == _bMPEG4TrickModeOn)
- {
- DEC_AVI_SetIPOnly(FALSE);
- DEC_AVI_SetIOnly(TRUE);
- iIndexIncrement = ONE_I_INCREMENT;
- _iMPEG4CurrentScanningMode = iIndexIncrement;
- gns.clips.iScanSpeed = iScanSpeed;
- gcs.pstate= PST_SCAN;
- DEC_AVI_EnableFinishCB(TRUE);
- return;
- }
- else
- #endif
- iIndexIncrement = ONE_I_INCREMENT;
- break;
- case SCAN_SPEED_8X:
- iIndexIncrement = TOW_I_INCREMENT;
- break;
- case SCAN_SPEED_20X:
- iIndexIncrement = FOUR_I_INCREMENT;
- break;
- case (-SCAN_SPEED_2X):
- iIndexIncrement = -ONE_I_INCREMENT;
- break;
- case (-SCAN_SPEED_4X):
- iIndexIncrement = -TOW_I_INCREMENT;
- break;
- case (-SCAN_SPEED_8X):
- iIndexIncrement = -FOUR_I_INCREMENT;
- break;
- case (-SCAN_SPEED_20X):
- iIndexIncrement = -EIGHT_I_INCREMENT;
- break;
- }
- /* Check if we changed from IP to I only mode */
- if ( (gns.clips.iScanSpeed == SCAN_SPEED_2X) || (gns.clips.iScanSpeed == 0) )
- {
- gcs.pstate = PST_SCAN;
- /* Start I only scan mode */
- if (FALSE == _aviScan(iIndexIncrement, FALSE))
- {
- dbg_printf(("WARNNING: AVIClip_scan() FAILEDn"));
- }
- }
- /*
- * Else - the DEMUX status polling time was enabled before,
- * and so, when the time is triggered the scanning will continue
- * according to the updated scanning mode
- */
- gns.clips.iScanSpeed = iScanSpeed;
- _iMPEG4CurrentScanningMode = iIndexIncrement;
- }
- }
- else
- {
- /* Playing after scanning - resume playback */
- ClipMarker mClipMarker;
- #ifdef USE_AUX_SUBTITLES
- if (FALSE != areAuxSubtitlePresent())// Robin_0528_2004_A
- {
- // replace 0 with the correct time, once it can be determined before playback
- // actually resumes
- subtitleGoToTime(0);
- setSubtitlesPlayMode(TRUE);
-
- }
- #endif //USE_AUX_SUBTITLES
- #ifdef AVI_FF_NO_INDEX
- if (FALSE == _bMPEG4TrickModeOn)
- {
- DEC_AVI_SetIPOnly(FALSE);
- DEC_AVI_SetIOnly(FALSE);
- DEC_AVI_EnableFinishCB(FALSE);
- }
- else
- #endif
- {
- if (_iMPEG4CurrentScanningMode == I_P_INCREMENT)
- {
- DEC_AVI_SetIPOnly(FALSE);
- }
- else /* I only mode */
- {
- DEC_AVI_SetIOnly(FALSE);
- /* Remove DEMUX callback */
- DEC_AVI_EnableFinishCB(FALSE);
- }
- }
- /* Save the info used for resuming */
- mClipMarker.dwAddress = (i_pThis->m_cfiInfo).dwFileLocation;
- mClipMarker.uTime = _uiMPEG4StartTime;
- gns.clips.iScanSpeed = 0;
- // gcs.pstate = PST_PLAY;
- /* Resume playback */
- (i_pThis->m_pConstAttr->m_vtable.m_pfPlay)(i_pThis, &mClipMarker, FALSE);
- }
- }
- #pragma argsused
- void AVIClip_recordMarker(const Clip *i_pThis, ClipMarker *o_pMarker)
- {
- dbg_printf(("AVIClip_recordMarker()n"));
- #ifdef AVI_FF_NO_INDEX
- if ((FALSE == _bMPEG4TrickModeOn) && (_uiMPEG4NextIndexEntry == 0))
- {
- UINT32 ulTime, ulBlocksCnt ;
- DEC_AVI_GetVideoStatus(&ulTime, &ulBlocksCnt);
- o_pMarker->dwAddress = _dwMPEG4ClipStartLBA + (_ulMPEG4TotalBlocksCnt - ulBlocksCnt);
- o_pMarker->uTime = (UINT16)ulTime;
- o_pMarker->uClipNumer = gns.clips.uCurrentClipNumber;
- }
- else
- #endif
- {
- /* Saving the info needed for playback resuming */
- o_pMarker->dwAddress = (i_pThis->m_cfiInfo).dwFileLocation;
- o_pMarker->uTime = (i_pThis->m_pConstAttr->m_vtable.m_pfGetTime)(i_pThis);
- o_pMarker->uClipNumer = gns.clips.uCurrentClipNumber;
- }
- }
- void AVIClip_performErrorHandling(const Clip *i_pThis)
- {
- dbg_printf(("AVIClip_performErrorHandling()n"));
- /* The current error handling is only in scanning mode */
- /* Check whether we are in FF I only or not */
- #ifdef IP_SUPPORT
- if ( (gcs.pstate == PST_SCAN) && (gns.clips.iScanSpeed != SCAN_SPEED_2X) )
- #else
- if (gcs.pstate == PST_SCAN)
- #endif
- {
- /* Remove the callback from the demux */
- DEC_AVI_EnableFinishCB(FALSE);
- /* Start I only FF from the beginning */
- _aviScan(_iMPEG4CurrentScanningMode, FALSE);
- #ifdef SUPPORT_FLASH_CARD
- if(IS_PLAYING_CARD)
- _uiMPEG4StartTime += gns.clips.iScanSpeed;
- #endif
- }
- else
- {
- /* NSPB recovery, resume playback from the next I frame */
- ClipMarker mClipMarker;
- UINT32 ulNextIIdx;
- WORD wNextITime;
- if(_uiMPEG4NumOfDecodedChunksMemory > 0)
- {
- if (TRUE == _getNextIFrames((i_pThis->m_cfiInfo).dwFileLocation, _uiMPEG4NumOfDecodedChunksMemory,
- &ulNextIIdx, &wNextITime) )
- {
- if(ulNextIIdx == _uiMPEG4NextIndexEntry)
- {
- DEC_AVI_EnableFinishCB(FALSE);
- ie_send(IE_CORE_CDNAV_FINISHED);
- }
-
- mClipMarker.dwAddress = (i_pThis->m_cfiInfo).dwFileLocation;
-
- if(wNextITime <= mClipMarker.uTime)
- mClipMarker.uTime = wNextITime+1;
- else
- mClipMarker.uTime = wNextITime;
-
- (i_pThis->m_pConstAttr->m_vtable.m_pfPlay)(i_pThis, &mClipMarker, FALSE);
- }
- }
- /* Else - we can't do anything */
- }
- }