AuxSubtitles.c
上传用户:super_houu
上传日期:2008-09-21
资源大小:4099k
文件大小:56k
- /**************************************************************
- * AuxSubtitles.c
- **************************************************************
- * Description:
- * ============
- * Handling of auxiliary subtitles files
- **************************************************************
- *
- * Hagay Barel 10.11.03
- **************************************************************/
- #include "Config.h" // Global Configuration - do not remove!
- #ifdef USE_AUX_SUBTITLES
- #ifdef _DEBUG
- #undef IFTRACE
- #ifdef DEBUG_AUX_SUBTITLES
- #define IFTRACE if (gTraceNavigator)
- #else
- #define IFTRACE
- #endif // DEBUG_AUX_SUBTITLES
- #include "Debugdbgmain.h"
- #endif // _DEBUG
- #include "PlaycoreNav_ClipsClip_Impl.h"
- #include "PlaycoreNav_ClipsGenericClip.h"
- #include "PlaycoreFileSysFileSystem.h"
- #include "PlaycoreExceptionException.h"
- #include "Decoderlow_levelDEC_LL_Reg.h"
- #include "KernelKer_API.H"
- #include "KernelEventDef.h"
- #include "PlaycoreScPadScPadAlloc.h"
- #include "PlaycoreScPadSCMGR.h"
- // <<< Robin_0903_2004
- //#include "PlaycoreNav_ClipsAVI_private.h"
- //#include "PlaycoreNav_ClipsAVI.h"
- #include "PlaycoreCoremainCoreGDef.h"
- // >>> Robin_0903_2004
- #ifdef DEBUG_AUX_SUBTITLES
- #include "CpuTimefunc.h"
- #endif
- #include "PlaycoreNav_ClipsAuxSubtitles.h"
- #include "PlaycoreNav_ClipsAuxSubtitlesCommonPrivate.h"
- #include "PlaycoreNav_ClipsMpeg4ClipsCommon.h"
- #ifdef SUPPORT_FLASH_CARD
- #include "drivefe_manager.h"
- #include "mediacardsincluderegister.h"
- #endif
- SubtitleStorageInterface* g_pSubtitleStorage = NULL;
- static BOOL _allocateStorageInterface(void);
- #ifdef AUX_SUBTITLES_INDEX
- SubtitleStorageIndex* g_pSubtitleIndex = NULL;
- static BOOL _allocateStorageIndex(void);
- #endif // AUX_SUBTITLES_INDEX
- #ifdef V882_FLASH_CARD
- BOOL _freeStorageInterfaceAndIndex(void);
- #else
- static BOOL _freeStorageInterfaceAndIndex(void);
- #endif//V882_FLASH_CARD
- static DWORD g_dwNextSubtitleUpdateSCLK = 0xffffffffL;
- static BYTE g_wSubtitleStatus = 0;
- DWORD g_dwSubtitleExtraOffset;
- #ifdef SUPPORT_FLASH_CARD
- BOOL bReadAuxSubtitle;
- #endif
- UINT16 getCurrentInstanceIndex(void);
- // Set when the reading pointer for subtitle storage points at the beginning of
- // a subtitle, cleared when it points to the end.
- #define AUX_SUBTITLE_START_DISPLAY_FLAG 1
- // Set when the string buffer was filled by the core task, but not yet handled
- // by the UI task
- #define AUX_SUBTITLE_BUFFER_LOCKED_FLAG 2
- // Set on normal playback - sequential subtitle seeking is performed.
- // Cleared on beginning of FF/FB/Goto
- #define AUX_SUBTITLE_PLAY_MODE_FLAG 4
- // Set when subtitles exist. When set, the UI will respond to the "Subtitle" key.
- #define AUX_SUBTITLE_AVAILABE_FLAG 8
- #define IS_AUX_SUBTITLE_START_DISPLAY (g_wSubtitleStatus & AUX_SUBTITLE_START_DISPLAY_FLAG)
- #define IS_AUX_SUBTITLE_BUFFER_LOCKED (g_wSubtitleStatus & AUX_SUBTITLE_BUFFER_LOCKED_FLAG)
- #define IS_AUX_SUBTITLE_PLAY_MODE (g_wSubtitleStatus & AUX_SUBTITLE_PLAY_MODE_FLAG)
- // <<< Robin_0903_2004
- #ifdef DIVX_SUPPORT_MULTI_SUBTITLE
- #define IS_AUX_SUBTITLE_EXIST (g_wSubtitleStatus & AUX_SUBTITLE_AVAILABE_FLAG)
- #define IS_AUX_SUBTITLE_AVAILABE ((g_wSubtitleStatus & AUX_SUBTITLE_AVAILABE_FLAG) && (_mpeg4SubtitleType> INTERNAL_SUBT))
- #else
- // <<< Robin_0907_2004
- #define IS_AUX_SUBTITLE_EXIST (g_wSubtitleStatus & AUX_SUBTITLE_AVAILABE_FLAG)
- // >>> Robin_0907_2004
- #define IS_AUX_SUBTITLE_AVAILABE (g_wSubtitleStatus & AUX_SUBTITLE_AVAILABE_FLAG)
- #endif
- // >>> Robin_0903_2004
- #define SET_AUX_SUBTITLE_START_DISPLAY(b) (g_wSubtitleStatus = (b) ? g_wSubtitleStatus | AUX_SUBTITLE_START_DISPLAY_FLAG : g_wSubtitleStatus & ~AUX_SUBTITLE_START_DISPLAY_FLAG )
- #define SET_AUX_SUBTITLE_BUFFER_LOCKED(b) (g_wSubtitleStatus = (b) ? g_wSubtitleStatus | AUX_SUBTITLE_BUFFER_LOCKED_FLAG : g_wSubtitleStatus & ~AUX_SUBTITLE_BUFFER_LOCKED_FLAG )
- #define SET_AUX_SUBTITLE_PLAY_MODE(b) (g_wSubtitleStatus = (b) ? g_wSubtitleStatus | AUX_SUBTITLE_PLAY_MODE_FLAG : g_wSubtitleStatus & ~AUX_SUBTITLE_PLAY_MODE_FLAG )
- #define SET_AUX_SUBTITLE_AVAILABE(b) (g_wSubtitleStatus = (b) ? g_wSubtitleStatus | AUX_SUBTITLE_AVAILABE_FLAG : g_wSubtitleStatus & ~AUX_SUBTITLE_AVAILABE_FLAG )
- // Robin_0527_2004_A
- #define CALC_SUBTITLE_ADDRESS(address, offset) (address - (offset >> 1) - STORAGE_INTERFACE_BUFFER_SIZE/2)
- // Robin_1003_2004_E
- /* Valid Extenions List */
- BEGIN_CLIP_VALID_EXTENSIONS_MAP(SUB)
- CLIP_VALID_EXTENSIONS_ENTRY(L"SUB")
- CLIP_VALID_EXTENSIONS_ENTRY(L"SRT")
- CLIP_VALID_EXTENSIONS_ENTRY(L"TXT")
- #ifdef SUPPORT_SAMI_SUBTITLE
- CLIP_VALID_EXTENSIONS_ENTRY(L"SMI")
- #endif
- CLIP_VALID_EXTENSIONS_ENTRY(L"SSA")
- CLIP_VALID_EXTENSIONS_ENTRY(L"ASS")
- CLIP_VALID_EXTENSIONS_ENTRY(L"PSB")
- #ifdef SUPPORT_SAMI_SUBTITLE
- CLIP_VALID_EXTENSIONS_ENTRY(L"SAMI")
- #endif
- END_CLIP_VALID_EXTENSIONS_MAP()
- /////////////////////////////////////////////////////////////////////////////////////////////
- // Function name : initAuxSubtitles
- // Purpose : Initializes auxiliary subtitles for a clip
- // Input Parameters : clipInfo - Information about the clip for which
- // to initialize subtitles
- // dwScale, dwRate - dwScale/dwRate is the number of seconds
- // per video frame
- // Return type : TRUE if subtitles were loaded, FALSE otherwise.
- // Description : The function looks for a subtitle files belonging to the given clip,
- // performs parsing and initializes interrupt and event handlers.
- /////////////////////////////////////////////////////////////////////////////////////////////
- BOOL initAuxSubtitles(ClipFileInfo *clipInfo, DWORD dwScale, DWORD dwRate)
- {
- DWORD dwSubtitlesFileAddress;
- DWORD dwSubtitlesFileSize;
- SubtitleParsingFuncPtr pfParseSubtitles;
- WORD wSubtitleID; // Robin_0903_2004
- /* SubtitlesFormatID sfFormatID; */
- #ifdef DEBUG_AUX_SUBTITLES
- UINT32 dwStart, dwEnd;
- #endif
- g_dwSubtitleExtraOffset = 0;
-
- // <<< Stivenz_1115_04: Memory optimization: Move g_SubtitleStorage and g_SubtitleIndex to heap.
- if(!_allocateStorageInterface())
- return FALSE;
- #ifdef AUX_SUBTITLES_INDEX
- if(!_allocateStorageIndex())
- {
- _freeStorageInterfaceAndIndex();
- return FALSE;
- }
- #endif
- // Stivenz_1115_04 >>>
- // this flag determines whether the UI will respond to the "subtitle" key
- // if subtitles exist, it would be set to true.
- SET_AUX_SUBTITLE_AVAILABE(FALSE);
- g_dwNextSubtitleUpdateSCLK = LAST_SUBTITLE_MARKER;
- #ifdef SUPPORT_FLASH_CARD
- if (IS_PLAYING_CARD)
- bReadAuxSubtitle = TRUE;
- #endif
- #ifdef DEBUG_AUX_SUBTITLES
- dwStart=gen_timer();
- #endif
- // is there an associated subtitle file of a recognized format?
- // <<< Robin_0903_2004
- #ifdef DIVX_SUPPORT_MULTI_SUBTITLE
- if (clipInfo->wSubFileCnt == 1)
- {
- wSubtitleID = 0;
- }
- else
- {
- wSubtitleID = Get_SubFile_Select();
- }
- if ( FALSE == findAndCheckAuxSubtitlesFile(clipInfo,&dwSubtitlesFileAddress,&dwSubtitlesFileSize,&pfParseSubtitles, wSubtitleID))
- #else
- if ( FALSE == findAndCheckAuxSubtitlesFile(clipInfo,&dwSubtitlesFileAddress,&dwSubtitlesFileSize,&pfParseSubtitles/*, &sfFormatID */))
- #endif
- {
- // >>> Robin_0903_2004
- dbg_printf(("initAuxSubtitles - Auxiliary subtitles file wasn't foundn"));
- #ifdef SUPPORT_FLASH_CARD
- if (IS_PLAYING_CARD)
- bReadAuxSubtitle = FALSE;
- #endif
- return FALSE;
- }
- // _mpeg4ExternalSubtitleAddr = _dwMPEG4ProcessingEndAddr;
-
- #ifdef DEBUG_AUX_SUBTITLES
- dwEnd=gen_timer();
- dbg_printf(("Subtitles finding & probing time: %lun",dwEnd-dwStart));
- #endif
- // if so, parse it and store its content.
- if ( FALSE == pfParseSubtitles(dwSubtitlesFileAddress,dwSubtitlesFileSize,dwScale,dwRate)) {
- tr_printf(("initAuxSubtitles - Couldn't parse subtitles filen"));
- #ifdef DEBUG_AUX_SUBTITLES
- dwEnd=gen_timer();
- dbg_printf(("Total subtitles handling time: %lun",dwEnd-dwStart));
- #endif
- #ifdef SUPPORT_FLASH_CARD
- if (IS_PLAYING_CARD)
- bReadAuxSubtitle = FALSE;
- #endif
- return FALSE;
- }
- // Robin_0527_2004_A
- _dwMPEG4ProcessingEndAddr = (CALC_SUBTITLE_ADDRESS( _mpeg4ExternalSubtitleAddr, g_pSubtitleStorage->dwCurrentStorageOffset) >>9) <<9;
- _dwMPEG4ProcessingEndAddr = (_dwMPEG4ProcessingEndAddr>>9)<<9;
-
- dbg_printf(("Start Address of Current External Subtitle : 0x%lxn",_dwMPEG4ProcessingEndAddr));
-
- subtitleStorageInitReading();
- subtitleStorageGetStartTime(&g_dwNextSubtitleUpdateSCLK);
- SET_AUX_SUBTITLE_START_DISPLAY(TRUE);
- SET_AUX_SUBTITLE_BUFFER_LOCKED(FALSE);
- SET_AUX_SUBTITLE_AVAILABE(TRUE);
- setSubtitlesPlayMode(TRUE);
- // g_dwSubtitleTimingOffset = 0;
- #ifdef DEBUG_AUX_SUBTITLES
- dwEnd=gen_timer();
- dbg_printf(("Total subtitles handling time: %lun",dwEnd-dwStart));
- #endif
- // initialize interrupt handlers?
- #ifdef SUPPORT_FLASH_CARD
- if (IS_PLAYING_CARD)
- bReadAuxSubtitle = FALSE;
- #endif
- return TRUE;
- }
- /////////////////////////////////////////////////////////////////////////////////////////////
- // Function name : findAndCheckAuxSubtitlesFile
- // Purpose : looks for a subtitle file for the given clip
- // Input Parameters : clipInfo - Information about the clip for which
- // to look for subtitles
- // Output Parameters: dwSubtitlesFileAddress - Start address of the 1st subtitles file that was found
- // dwSubtitlesFileSize - Size of the subtitles 1st file that was found
- // pfParse - The parsing function used by the detected format
- // of the 1st recognized subtitle file.
- // prParse=NULL if none was found.
- // Return type : TRUE if recognized subtitles were found, FALSE otherwise.
- // Description : The function looks for files which have the same name (only name, not extension)
- // as the given clip, and tests if they are recognized subtitle files.
- // It then determines the format of the 1st such file.
- /////////////////////////////////////////////////////////////////////////////////////////////
- // <<< Robin_0903_2004
- #ifdef DIVX_SUPPORT_MULTI_SUBTITLE
- BOOL findAndCheckAuxSubtitlesFile(ClipFileInfo *clipInfo,DWORD *dwSubtitlesFileAddress,
- DWORD *dwSubtitlesFileSize,SubtitleParsingFuncPtr *pfParse, WORD wSubtitleID)
- #else
- BOOL findAndCheckAuxSubtitlesFile(ClipFileInfo *clipInfo,DWORD *dwSubtitlesFileAddress,
- DWORD *dwSubtitlesFileSize,SubtitleParsingFuncPtr *pfParse)
- #endif
- // >>> Robin_0903_2004
- {
- // Robin_0527_2004_A, change the process of checking a subtitle file, change the memory allocate of subtitle
- // subtitle file name: avi_file_name + .SRT/.SUB/.SMI/..
- // limition:
- // 1) only support .SRT(SubRip)/.SUB(MicroDVD)/.TXT(MicroDVD)/.SMI(SAMI)/.SUB(SubViewer2.0)
- // .SSA(SubStation Alpha)/.ASS(Advanced SubStation Alpha)/.PSB(PowerDivX)/.TXT(TMPlayer)
- // 2) only support one external subtitle and no exist of internal subtitle
- // 3) only support western/central european language
- // 4) if USE_AUX_SUBTITLES, the cpu code size will exceed 1M(need SUPPORT_2M_FLASH)
- // 5) the max size of subtitle in memory is 200KB (SUBTITLES_MEMORY_SIZE)
- // 6) the max size of avi file name is 65
- // Robin_0715_2004, merge changelist #24166
- #if 1
- // <<< Robin_0903_2004
- #ifdef DIVX_SUPPORT_MULTI_SUBTITLE
- if(clipInfo->wSubFileCnt == 0 ||clipInfo->wSubFileCnt <= wSubtitleID )
- return FALSE;
- else
- {
- int i,j;
- Extend_Subtitle_Info_St SubtitleInfo;
- BOOL bAuxSubtitle = FALSE;
- SubtitleType auxSubtitleType;
- sc_GetBytes( SC_AVI_EXTEND_SUBTITLE_ADDR,
- ( ((clipInfo->wSubFileIndex)+wSubtitleID) * sizeof(Extend_Subtitle_Info_St) ),
- sizeof(Extend_Subtitle_Info_St),
- (BYTE*)&SubtitleInfo );
-
- *dwSubtitlesFileAddress = SubtitleInfo.dwSubtitlesFileAddress;
- // <<< Robin_1003_2004_E
- *dwSubtitlesFileSize = SubtitleInfo.dwSubtitlesFileSize;
- #ifdef SUPPORT_FLASH_CARD //JERRYC_2004_Oct_21
- if(IS_PLAYING_CARD)
- {
- STRUCT_FILE *pfile = FCU_TEMP_SUBTITLE_FILE_STRCUT_ADDR;
- //Is *dwSubtitlesFileAddress the real subtitle file start address?
- FileSys_FileOpen(pfile, *dwSubtitlesFileAddress, 0, *dwSubtitlesFileSize);
- }
- #endif
- for (j=0;j<SF_NUMBER_OF_FORMATS;j++)
- {
- if ( NULL != availableSubtitleFormats[j].pfProbe)
- {
- if (TRUE == availableSubtitleFormats[j].pfProbe(*dwSubtitlesFileAddress, *dwSubtitlesFileSize))
- {
- *pfParse=availableSubtitleFormats[j].pfParse;
- bAuxSubtitle = TRUE;
- auxSubtitleType = j+EXTERNAL_SUBP;
- break;
- }
- }
- }
- // >>> Robin_1003_2004_E
- if (bAuxSubtitle == TRUE)
- {
- // <<< Robin_0907_2004
- if (auxSubtitleType != SAMI && auxSubtitleType != EXTERNAL_SUBP)
- {
- // Robin_1119_2004, unknown auxsubtitle language
- memset(&_mpeg4SubtitleStreamInfo, 0, sizeof(MPEG4SubtitleStreamInfo));
- _mpeg4SubtitleStreamID = NO_STREAM;
- _mpeg4SubtitleType = auxSubtitleType;
- sc_SetBytes(SC_MPEG4_SUBTITLE_STREAM_INFO_ADDR,
- (SI_CLIPS_SUB_AVAILABLE_NUM * SIZE_OF_SUBTITLE_STREAM_INFO),
- SIZE_OF_SUBTITLE_STREAM_INFO,
- (BYTE*)&_mpeg4SubtitleStreamInfo
- );
-
- SI_CLIPS_SUB_AVAILABLE_NUM ++;
- }
- }
- // >>> Robin_0907_2004
- return bAuxSubtitle;
- }
- #else
- int i,j;
- // <<< Robin_1003_2004_E
- if ((NULL != clipInfo->dwSubtitlesFileAddress) && (NULL != clipInfo->dwSubtitlesFileSize))
- {
- *dwSubtitlesFileAddress = clipInfo->dwSubtitlesFileAddress;
- *dwSubtitlesFileSize = clipInfo->dwSubtitlesFileSize;
- for (j=0;j<SF_NUMBER_OF_FORMATS;j++)
- {
- if ( NULL != availableSubtitleFormats[j].pfProbe)
- {
- if (TRUE == availableSubtitleFormats[j].pfProbe(*dwSubtitlesFileAddress, *dwSubtitlesFileSize))
- {
- *pfParse=availableSubtitleFormats[j].pfParse;
- return TRUE;
- }
- }
- }
- }
- // >>> Robin_1003_2004_E
- return FALSE;
- #endif
- // >>> Robin_0903_2004
- #else
- #define AUXSUBTITLE_MAX_FILENAME_LEN 65 // same as szFileID[65]
- WCHAR szFilename [AUXSUBTITLE_MAX_FILENAME_LEN];
- LPCWSTR *i_aValidExtensions;
- unsigned int FsType;
- int i,j;
- BOOL bFindAuxSubtitlesFile = FALSE;
- int FileNameLength;
- FsType = FileSys_determineType();
- if (FileSys_selectType(FsType) && FileSys_initialize(TRUE))
- {
- if (FALSE == FileSys_changeDir(clipInfo->szDirectoryName))
- {
- return FALSE;
- }
- memset(&szFilename, 0, AUXSUBTITLE_MAX_FILENAME_LEN<<1);
- wcsncpy(szFilename,clipInfo->szFilename,wcslen(clipInfo->szFilename));
- if (CLIPS_MAX_FILENAME_LEN <= wcslen(clipInfo->szFilename))
- {
- if (FileSys_fileExists(szFilename))
- {
- FindData fdInfo;
- UINT16 hFileFind= FileSys_findFirstFile(szFilename, &fdInfo);
- if (NULL == hFileFind)
- return FALSE;
-
- do {
- if (fdInfo.dwStartAddr == clipInfo->dwFileLocation)
- {
- LPWSTR pszDelim;
- memset(&szFilename, 0, AUXSUBTITLE_MAX_FILENAME_LEN<<1);
-
- pszDelim= wcsrchr(fdInfo.szFileID, '.');
- wcsncpy(szFilename, fdInfo.szFileID, (int)(pszDelim - fdInfo.szFileID));
- break;
- }
- } while (FileSys_findNextFile(hFileFind, &fdInfo));
- FileSys_findClose(hFileFind);
- }
-
- }
- FileNameLength = wcslen(szFilename);
- for (i=0; i< SF_NUMBER_OF_FORMATS; i++)
- {
-
- i_aValidExtensions = availableSubtitleFormats[i].aFormatValidExtensions;
- for (j=0;NULL != i_aValidExtensions[j];j++)
- {
- wcsncat(szFilename, i_aValidExtensions[j],wcslen(i_aValidExtensions[j]));
- if (FileSys_fileExists(szFilename))
- {
- FindData fdInfo;
- UINT16 hFileFind= FileSys_findFirstFile(szFilename, &fdInfo);
-
- if (NULL != hFileFind)
- {
- dbg_printf(("The subtitle file is found.n"));
- *dwSubtitlesFileAddress= fdInfo.dwStartAddr;
- *dwSubtitlesFileSize= (DWORD)fdInfo.cbFileSizeLow;
- if ( NULL != availableSubtitleFormats[i].pfProbe)
- {
- if (TRUE == availableSubtitleFormats[i].pfProbe(*dwSubtitlesFileAddress, *dwSubtitlesFileSize))
- *pfParse=availableSubtitleFormats[i].pfParse;
- else
- continue;
- }
- *pfParse=availableSubtitleFormats[i].pfParse;
- FileSys_findClose(hFileFind);
- return TRUE;
- }
- }
- memset(&szFilename[FileNameLength], 0, wcslen(i_aValidExtensions[j])<<1);
-
- }
- }
- }
- return FALSE;
- #endif
- }
- void findAuxSubtitlesFile(Clip *pClip, const FindData *i_pFileInfo)
- {
- if ((eClipType_AVI == (pClip->m_pConstAttr)->m_eType)
- #ifdef IS_ASF_CAPABLE
- || (eClipType_ASF == (pClip->m_pConstAttr)->m_eType)
- #endif
- #ifdef IS_MP4_CAPABLE
- || (eClipType_MP4 == (pClip->m_pConstAttr)->m_eType)
- #endif
- )
- {
- int i,j;
- LPCWSTR *i_aValidExtensions;
- LPWSTR pszDelim;
- WCHAR szFilename [65];
- int FileNameLength;
- pszDelim= wcsrchr(i_pFileInfo->szFileID, '.');
- memset(&szFilename, 0, 65<<1);
- wcsncpy(szFilename, i_pFileInfo->szFileID, (int)(pszDelim - i_pFileInfo->szFileID+1));
- FileNameLength = wcslen(szFilename);
- // Robin_1112_2004, "*" mean any char/string
- #if 1 //MikeX_1213_2004_A
- wcsncat(szFilename, FILESYS_WILDCARD_SEARCH, sizeof(WCHAR));
- #endif
-
- // <<< Robin_0903_2004
- #ifdef DIVX_SUPPORT_MULTI_SUBTITLE
- (pClip->m_cfiInfo).wSubFileIndex = _mpeg4TotalSubtitleNum;
- (pClip->m_cfiInfo).wSubFileCnt = 0;
- #else
- (pClip->m_cfiInfo).dwSubtitlesFileAddress = NULL;
- // Robin_1003_2004_E
- (pClip->m_cfiInfo).dwSubtitlesFileSize = NULL;
- #endif
- // Robin_0730_2004, improve the speed of findAuxSubtitlesFile()
- {
- FindData fdInfo;
- UINT16 hFileFind= FileSys_findFirstFile(szFilename, &fdInfo);
- if (NULL == hFileFind)
- {
- #ifdef DIVX_SUPPORT_MULTI_SUBTITLE
- (pClip->m_cfiInfo).wSubFileIndex = 0;
- #endif
- return;
- }
-
- do {
- // Robin_1125_2004, if subtitle filesize larger than 1MB, not supported
- if (fdInfo.cbFileSizeLow > 1000000UL) // if filesize is larger than 1MB, not text subtitle
- continue;
- #ifdef SUPPORT_FLASH_CARD
- if(IS_PLAYING_CARD){
- if(0 != wcsncmp(fdInfo.szFileID, i_pFileInfo->szFileID, FileNameLength))
- continue;
- }
- #endif
-
- // <<< Robin_1003_2004_E
- if (GenericClip_isKindOf(fdInfo.szFileID, CLIP_VALID_EXTENSIONS(SUB)))
- {
- #ifdef DIVX_SUPPORT_MULTI_SUBTITLE
- Extend_Subtitle_Info_St foundSubtitle;
-
- foundSubtitle.dwSubtitlesFileAddress = fdInfo.dwStartAddr;
- foundSubtitle.dwSubtitlesFileSize = fdInfo.cbFileSizeLow;
- sc_SetBytes( SC_AVI_EXTEND_SUBTITLE_ADDR,
- (_mpeg4TotalSubtitleNum * sizeof(Extend_Subtitle_Info_St) ),
- sizeof(Extend_Subtitle_Info_St),
- (BYTE*)&foundSubtitle );
- (pClip->m_cfiInfo).wSubFileCnt ++;
- _mpeg4TotalSubtitleNum++;
- #else
- FileSys_findClose(hFileFind);
- (pClip->m_cfiInfo).dwSubtitlesFileAddress = fdInfo.dwStartAddr;
- (pClip->m_cfiInfo).dwSubtitlesFileSize = fdInfo.cbFileSizeLow;
- break;
- #endif
- // <<< Robin_0903_2004
- }
- // >>> Robin_1003_2004_E
- } while (FileSys_findNextFile(hFileFind, &fdInfo));
- FileSys_findClose(hFileFind);
-
- #ifdef SUPPORT_FLASH_CARD
- if(IS_PLAYING_CARD){
- FileSys_findFirstFile(i_pFileInfo->szFileID, &fdInfo);
- }
- #endif
- }
- }
- return;
- }
- /////////////////////////////////////////////////////////////////////////////////////////////
- // Function Name : subtitleStorageInitWriting
- // Purpose : Initializes the interface to the subtitles storage
- // Return type : void
- // Description :
- /////////////////////////////////////////////////////////////////////////////////////////////
- void subtitleStorageInitWriting(void)
- {
- // <<< Stivenz_1115_04: Memory optimization: Move g_SubtitleStorage and g_SubtitleIndex to heap.
- if(!_allocateStorageInterface())
- return;
- // Stivenz_1115_04 >>>
- memset(g_pSubtitleStorage,0,sizeof(SubtitleStorageInterface));
- #ifdef AUX_SUBTITLES_INDEX
- // <<< Stivenz_1115_04: Memory optimization: Move g_SubtitleStorage and g_SubtitleIndex to heap.
- if(!_allocateStorageIndex())
- return;
- // Stivenz_1115_04 >>>
- memset(g_pSubtitleIndex,0,sizeof(SubtitleStorageIndex));
- g_pSubtitleIndex->wInterval = 1;
- #endif // AUX_SUBTITLES_INDEX
- }
- /////////////////////////////////////////////////////////////////////////////////////////////
- // Function Name : subtitleStorageInitReading
- // Purpose : Initializes the interface to the subtitles storage
- // Return type : void
- // Description :
- /////////////////////////////////////////////////////////////////////////////////////////////
- void subtitleStorageInitReading(void)
- {
- // <<< Stivenz_1115_04: Memory optimization: Move g_SubtitleStorage and g_SubtitleIndex to heap.
- if(!_allocateStorageInterface())
- return;
- // Stivenz_1115_04 >>>
- memset(g_pSubtitleStorage,0,sizeof(SubtitleStorageInterface));
- subtitleStorageFillBuffer();
- }
- /////////////////////////////////////////////////////////////////////////////////////////////
- // Function Name : subtitleStorageMarkLastEntry
- // Purpose : to be used after the last subtitle was parsed.
- // Return type : TRUE - on success. FALSE when out of subtitle storage memory
- // Description : writes LAST_SUBTITLE_MARKER to the next position in the subtitle
- // storage.
- /////////////////////////////////////////////////////////////////////////////////////////////
- BOOL subtitleStorageMarkLastEntry(void)
- {
- if (!subtitleStorageWriteDWORD(LAST_SUBTITLE_MARKER))
- return FALSE;
- subtitleStorageCommitBuffer();
- #ifdef _DEBUG
- dbg_printf(("Byte count: %lun",g_pSubtitleStorage->dwByteCount));
- dbg_printf(("Entry count: %lun",g_pSubtitleStorage->dwEntryCount));
- dbg_printf(("Max entry length: %un",g_pSubtitleStorage->wMaxEntryLength));
- dbg_printf(("Max line length: %un",g_pSubtitleStorage->wMaxLineLength));
- #endif //_DEBUG
- return TRUE;
- }
- /////////////////////////////////////////////////////////////////////////////////////////////
- // Function Name : subtitleStorageStartEntry
- // Purpose : Opens a new subtitle entry
- // Input Parameters : dwStartSCLK - Display starting time (SCLK)
- // Return type : TRUE - on success. FALSE when out of subtitle storage memory
- // Description : writes the SCLK DWORD, followed by a null byte
- /////////////////////////////////////////////////////////////////////////////////////////////
- BOOL subtitleStorageStartEntry(DWORD dwStartSCLK)
- {
- dwStartSCLK = (dwStartSCLK > AUX_SUBTITLE_EARLY_DISPLAY_OFFSET) ? (dwStartSCLK - AUX_SUBTITLE_EARLY_DISPLAY_OFFSET) : 0;
- #ifdef AUX_SUBTITLES_INDEX
- updateSubtitlesIndex(g_pSubtitleStorage->dwCurrentStorageOffset +
- g_pSubtitleStorage->wBufferPos, dwStartSCLK);
- #endif // AUX_SUBTITLES_INDEX
- if (!subtitleStorageWriteDWORD(dwStartSCLK))
- return FALSE;
- if (!subtitleStorageWriteByte(0))
- return FALSE;
- #ifdef _DEBUG
- g_pSubtitleStorage->wCurrentEntryLength = 0;
- g_pSubtitleStorage->wCurrentLineLength = 0;
- #endif //_DEBUG
- return TRUE;
- }
- /////////////////////////////////////////////////////////////////////////////////////////////
- // Function Name : subtitleStorageEndEntry
- // Purpose : Closes a subtitle entry
- // Input Parameters : dwEndSCLK - Display starting time (SCLK)
- // Return type : TRUE - on success. FALSE when out of subtitle storage memory
- // Description : writes a null byte, followed by the SCLK DWORD.
- /////////////////////////////////////////////////////////////////////////////////////////////
- BOOL subtitleStorageEndEntry(DWORD dwEndSCLK)
- {
- dwEndSCLK = (dwEndSCLK > AUX_SUBTITLE_EARLY_DISPLAY_OFFSET) ? (dwEndSCLK - AUX_SUBTITLE_EARLY_DISPLAY_OFFSET) : 0;
- #ifdef _DEBUG
- g_pSubtitleStorage->dwEntryCount++;
- if ( g_pSubtitleStorage->wCurrentEntryLength > g_pSubtitleStorage->wMaxEntryLength )
- g_pSubtitleStorage->wMaxEntryLength = g_pSubtitleStorage->wCurrentEntryLength;
- if ( g_pSubtitleStorage->wCurrentLineLength > g_pSubtitleStorage->wMaxLineLength )
- g_pSubtitleStorage->wMaxLineLength = g_pSubtitleStorage->wCurrentLineLength;
- #endif //_DEBUG
- if (!subtitleStorageWriteByte(0))
- return FALSE;
- if (!subtitleStorageWriteDWORD(dwEndSCLK))
- return FALSE;
- return TRUE;
- }
- /////////////////////////////////////////////////////////////////////////////////////////////
- // Function Name : subtitleStorageWriteByte
- // Purpose : Writes a byte to the subtitle storage memory
- // Input Parameters : b - the byte to be stored
- // Return type : TRUE - on success. FALSE when out of subtitle storage memory
- // Description : writes the byte to the internal buffer. when full - writes the buffer
- // to the subtitle storage memory
- /////////////////////////////////////////////////////////////////////////////////////////////
- BOOL subtitleStorageWriteByte(BYTE b)
- {
- if (g_pSubtitleStorage->dwCurrentStorageOffset + g_pSubtitleStorage->wBufferPos >= SUBTITLES_MEMORY_SIZE)
- return FALSE;
- g_pSubtitleStorage->baBuffer[g_pSubtitleStorage->wBufferPos++] = b;
- if ( g_pSubtitleStorage->wBufferPos >= STORAGE_INTERFACE_BUFFER_SIZE )
- subtitleStorageCommitBuffer();
- #ifdef _DEBUG
- g_pSubtitleStorage->dwByteCount++;
- g_pSubtitleStorage->wCurrentEntryLength++;
- g_pSubtitleStorage->wCurrentLineLength++;
- #endif
- return TRUE;
- }
- /////////////////////////////////////////////////////////////////////////////////////////////
- // Function Name : subtitleStorageWriteDWORD
- // Purpose : Writes a double word to the subtitle storage memory
- // Input Parameters : dw - the dword to be stored
- // Return type : TRUE - on success. FALSE when out of subtitle storage memory
- // Description : writes the word to the internal buffer, byte by byte. when
- // the internal buffer is full - writes the buffer
- // to the subtitle storage memory
- /////////////////////////////////////////////////////////////////////////////////////////////
- BOOL subtitleStorageWriteDWORD(DWORD dw)
- {
- int i;
- for (i=0;i<4;i++) {
- // write the high byte
- if (!subtitleStorageWriteByte(dw >> 24 ))
- return FALSE;
- dw = dw << 8 ;
- }
- return TRUE;
- }
- /////////////////////////////////////////////////////////////////////////////////////////////
- // Function Name : subtitleStorageCommitBuffer
- // Purpose : Internal Write the internal buffer to memory
- // Return type : void
- // Description : uses sc_SetBytes to write the buffer to subtitle memory. resets wBufferPos
- /////////////////////////////////////////////////////////////////////////////////////////////
- void subtitleStorageCommitBuffer(void)
- {
- wai_sem(SEM_DRAM_ID);
- // Robin_0527_2004_A
- I49_WriteDRAMData (CALC_SUBTITLE_ADDRESS(_mpeg4ExternalSubtitleAddr , g_pSubtitleStorage->dwCurrentStorageOffset),
- (UINT16*)g_pSubtitleStorage->baBuffer, STORAGE_INTERFACE_BUFFER_SIZE/2);
- sig_sem(SEM_DRAM_ID);
- g_pSubtitleStorage->dwCurrentStorageOffset += g_pSubtitleStorage->wBufferPos;
- g_pSubtitleStorage->wBufferPos = 0;
- }
- /////////////////////////////////////////////////////////////////////////////////////////////
- // Function Name : subtitleStorageGetSubtitle
- // Purpose : Get a subtitle string and the end sclk count
- // Output Parameters: dwEndSCLK - The time for stopping the display of this subtitle in SCLK count
- // Return type : TRUE on success, FALSE if string is too long to fit in buffer
- // Description : Copies the subtitle string from subtitles storage memory to
- // the scratch pad. The string is copied as it was in the subtitles file,
- // except for conversion of formatting symbols. Conversion to Unicode or any
- // other format the OSD module requires, is likely to be language-dependant,
- // and should be performed by the calling function if necessary.
- // The time for displaying the returned subtitle should be determined beforehand,
- // and this function should be called when this time is reached. The end time is
- // returned by this function.
- /////////////////////////////////////////////////////////////////////////////////////////////
- BOOL subtitleStorageGetSubtitle(DWORD *dwEndSCLK)
- {
- int sc_pos = 0;
- int copyStart;
- BYTE c;
- int i=0;
- // skip the null byte
- subtitleStorageReadByte(&c);
- // save start address of the segment to be written to the scratch pad
- copyStart = g_pSubtitleStorage->wBufferPos;
- do
- {
- c = g_pSubtitleStorage->baBuffer[g_pSubtitleStorage->wBufferPos++];
- if ( g_pSubtitleStorage->wBufferPos >= STORAGE_INTERFACE_BUFFER_SIZE )
- {
- sc_SetBytes(SC_AUX_SUBTITLES_STRINGS_ADDR,
- sc_pos,
- g_pSubtitleStorage->wBufferPos - copyStart,
- &(g_pSubtitleStorage->baBuffer[copyStart]) );
- sc_pos += g_pSubtitleStorage->wBufferPos - copyStart;
- subtitleStorageFillBuffer();
- copyStart = g_pSubtitleStorage->wBufferPos;
- }
- i++;
- }
- while ( ' ' != c && i < SUBTITLE_STRING_SC_SZ_B );
- // if subtitle text is longer than the subtitle string buffer
- if ( i == SUBTITLE_STRING_SC_SZ_B ) {
- // read until the terminating null
- while ( ' ' != c )
- subtitleStorageReadByte(&c);
- // terminate the string
- if (copyStart != g_pSubtitleStorage->wBufferPos)
- {
- // the end of the string wasn't written to the scratch pad yet
- c = g_pSubtitleStorage->baBuffer[g_pSubtitleStorage->wBufferPos-1];
- g_pSubtitleStorage->baBuffer[g_pSubtitleStorage->wBufferPos-1] = ' ';
- }
- else
- {
- BYTE tmp[2];
- // the last char was alraedy written, so write directly to the scratch pad
- sc_GetBytes(SC_AUX_SUBTITLES_STRINGS_ADDR,
- (sc_pos)-1,
- 2,
- tmp );
- tmp[1]=' ';
- sc_SetBytes(SC_AUX_SUBTITLES_STRINGS_ADDR,
- (sc_pos)-1,
- 2,
- tmp );
- }
- dbg_printf(("End SCLK %lun",*dwEndSCLK));
- }
- // if some characters weren't yet copied to the scratch pad
- if (copyStart != g_pSubtitleStorage->wBufferPos)
- {
- sc_SetBytes(SC_AUX_SUBTITLES_STRINGS_ADDR,
- sc_pos,
- g_pSubtitleStorage->wBufferPos - copyStart,
- &(g_pSubtitleStorage->baBuffer[copyStart]) );
- if ( i == SUBTITLE_STRING_SC_SZ_B )
- {
- // resotre the character that was replaced by ' '
- g_pSubtitleStorage->baBuffer[g_pSubtitleStorage->wBufferPos-1] = c;
- }
- }
-
- // read end SCLK value
- subtitleStorageReadDWORD(dwEndSCLK);
- return ( i != SUBTITLE_STRING_SC_SZ_B );
- }
- /////////////////////////////////////////////////////////////////////////////////////////////
- // Function Name : subtitleStorageSkipSubtitle
- // Purpose : Go to the next subtitle, and get the start SCLK count
- // Output Parameters: dwStartSCLK - Start display time, as SCLK count
- // Description :
- /////////////////////////////////////////////////////////////////////////////////////////////
- BOOL subtitleStorageSkipSubtitle(DWORD *dwStartSCLK)
- {
- BYTE c;
- // skip the null byte
- subtitleStorageReadByte(&c);
- // skip the string
- do
- {
- subtitleStorageReadByte(&c);
- } while ( c != ' ' );
- // skip end SCLK value
- subtitleStorageReadDWORD(dwStartSCLK);
- return subtitleStorageGetStartTime(dwStartSCLK);
- }
- /////////////////////////////////////////////////////////////////////////////////////////////
- // Function Name : subtitleStorageGetStartTime
- // Purpose : Get the start SCLK count of the current subtitle
- // Output Parameters: dwStartSCLK - Start display time, as SCLK count
- // Return type : FALSE if there are no more subtitles. TRUE otherwise
- // Description : Reads the start SCLK count for this subtitle. If there are no more subtitle,
- // FALSE is returned, and also the value of dwStartSCLK is LAST_SUBTITLE_MARKER
- // which is set to be the max possible value of the SCLK
- /////////////////////////////////////////////////////////////////////////////////////////////
- BOOL subtitleStorageGetStartTime(DWORD *dwStartSCLK)
- {
- subtitleStorageReadDWORD(dwStartSCLK);
- if (LAST_SUBTITLE_MARKER == *dwStartSCLK) {
- subtitleStorageRewindBytes(4);
- return FALSE;
- }
- return TRUE;
- }
- /////////////////////////////////////////////////////////////////////////////////////////////
- // Function Name : subtitleStorageFillBuffer
- // Purpose : Internal function for reading from the subtitles memory in to the internal buffer
- // Input Parameters : storage - handle to a storage struct
- // Return type : void
- // Description : uses sc_GetBytes to write the buffer to subtitle memory. resets wBufferPos
- /////////////////////////////////////////////////////////////////////////////////////////////
- void subtitleStorageFillBuffer(void)
- {
- wai_sem(SEM_DRAM_ID);
- I49_ReadDRAMData(CALC_SUBTITLE_ADDRESS(_mpeg4ExternalSubtitleAddr , g_pSubtitleStorage->dwCurrentStorageOffset),
- (UINT16 *)g_pSubtitleStorage->baBuffer , STORAGE_INTERFACE_BUFFER_SIZE/2);
- sig_sem(SEM_DRAM_ID);
- g_pSubtitleStorage->dwCurrentStorageOffset += STORAGE_INTERFACE_BUFFER_SIZE;
- g_pSubtitleStorage->wBufferPos = 0;
- }
- /////////////////////////////////////////////////////////////////////////////////////////////
- // Function Name : subtitleStorageReadByte
- // Purpose : Reads a byte to the subtitle storage memory
- // Input Parameters : b - place to store the byte
- // Return type : void
- // Description : Reads the byte from the internal buffer. when empty - fills the buffer
- /////////////////////////////////////////////////////////////////////////////////////////////
- void subtitleStorageReadByte(BYTE *b)
- {
- *b = g_pSubtitleStorage->baBuffer[g_pSubtitleStorage->wBufferPos++];
- if ( g_pSubtitleStorage->wBufferPos >= STORAGE_INTERFACE_BUFFER_SIZE )
- subtitleStorageFillBuffer();
- }
- /////////////////////////////////////////////////////////////////////////////////////////////
- // Function Name : subtitleStorageReadDWORD
- // Purpose : Reads a byte to the subtitle storage memory
- // Input Parameters : b - place to store the DWOR
- // Return type : void
- // Description : Reads the DWORD byte by byte using subtitleStorageReadByte
- /////////////////////////////////////////////////////////////////////////////////////////////
- void subtitleStorageReadDWORD(DWORD *dw)
- {
- int i;
- BYTE b;
- *dw = 0;
- for (i=0;i<4;i++) {
- subtitleStorageReadByte(&b);
- (*dw) = (*dw) << 8 ;
- (*dw) += (DWORD)b;
- }
- }
- /////////////////////////////////////////////////////////////////////////////////////////////
- // Function Name : subtitleStorageRewindBytes
- // Purpose : Rewinds the subtitles storage pointer
- // Input Parameters: count - number of bytes to rewind
- // Return type : FALSE when attempting to rewind beyond the start of the subtitles storage
- // TRUE otherwise.
- // Description : Checks if the requested position is currently in the buffer, and updates
- // internal pointers if so. Otherwise, reads required data from the SDRAM
- /////////////////////////////////////////////////////////////////////////////////////////////
- BOOL subtitleStorageRewindBytes(WORD count)
- {
- BYTE bAlign=0;
- if ( g_pSubtitleStorage->dwCurrentStorageOffset - STORAGE_INTERFACE_BUFFER_SIZE
- + g_pSubtitleStorage->wBufferPos < count )
- return FALSE;
- else if ( g_pSubtitleStorage->wBufferPos >= count )
- g_pSubtitleStorage->wBufferPos -= count;
- else {
- g_pSubtitleStorage->dwCurrentStorageOffset -= (STORAGE_INTERFACE_BUFFER_SIZE + count - g_pSubtitleStorage->wBufferPos);
- g_pSubtitleStorage->wBufferPos=0;
- bAlign = g_pSubtitleStorage->dwCurrentStorageOffset & 0x3 ;
- g_pSubtitleStorage->dwCurrentStorageOffset -= bAlign;
- subtitleStorageFillBuffer();
- g_pSubtitleStorage->wBufferPos = bAlign;
- }
- return TRUE;
- }
- /////////////////////////////////////////////////////////////////////////////////////////////
- // Function Name : checkAndHandleAuxSubtitles
- // Purpose : Reads subtitles from memory, and sends them to the UI
- // when it's time to display them.
- // Input Parameters: dwCurrentTime - current SCLK count.
- // Return type : void
- // Description : Checks if the current time is later than the previously
- // noted "next update time". If it's time to start displaying
- // a new subtitle, and the UI task has finished dealing with
- // the previous subtitle, write the new subtitle text to a buffer
- // and send an event to the UI - to start displaying it.
- // if it's time to stop displaying a subtitle - send a proper
- // event to the UI.
- /////////////////////////////////////////////////////////////////////////////////////////////
- void checkAndHandleAuxSubtitles(DWORD dwCurrentTime)
- {
- if ( !IS_AUX_SUBTITLE_PLAY_MODE )
- return;
- while ( dwCurrentTime >= g_dwNextSubtitleUpdateSCLK )
- {
- if ( IS_AUX_SUBTITLE_START_DISPLAY ) {
- // the start SCLK was read, and now this time was reached.
- // display the subtitle
- // if the UI task finished with the previous subtitles, read a new one and tell the UI
- if ( FALSE == IS_AUX_SUBTITLE_BUFFER_LOCKED ) {
- if ( FALSE == subtitleStorageGetSubtitle(&g_dwNextSubtitleUpdateSCLK)) {
- dbg_printf(("Error - subtitle too longn"));
- }
- // check if the end time of new subtitle has passed too
- if (g_dwNextSubtitleUpdateSCLK < dwCurrentTime) {
- subtitleStorageGetStartTime(&g_dwNextSubtitleUpdateSCLK);
- }
- // tell the UI to display the string
- else {
- SET_AUX_SUBTITLE_BUFFER_LOCKED(TRUE);
- ie_send(IE_UI_START_DISPLAY_AUX_SUBTITLE);
- SET_AUX_SUBTITLE_START_DISPLAY(FALSE);
- }
- }
- else {
- subtitleStorageSkipSubtitle(&g_dwNextSubtitleUpdateSCLK);
- }
- }
- else {
- // the subtitle was displayed, and now it's the time to stop displaying
- subtitleStorageGetStartTime(&g_dwNextSubtitleUpdateSCLK);
- // avoid sending the stop event when the next subtitle should be
- // displayed immidiately
- if ( dwCurrentTime < g_dwNextSubtitleUpdateSCLK )
- ie_send(IE_UI_STOP_DISPLAY_AUX_SUBTITLE);
- SET_AUX_SUBTITLE_START_DISPLAY(TRUE);
- }
- }
- }
- /////////////////////////////////////////////////////////////////////////////////////////////
- // Function Name : unlockAuxSubtitlesStringBuffer
- // Purpose : unlock the string buffer
- // Return type : void
- // Description : After the UI receives an event from the core task to display subtitles
- // and processes the text in the subtitle string buffer, it calls this function
- // to designate that it no longer needs the data in the subtitles string buffer.
- // The core task can fill the buffer only when it's unlocked, and it locks
- // it before sending display subtitles event to the UI task.
- /////////////////////////////////////////////////////////////////////////////////////////////
- void unlockAuxSubtitlesStringBuffer(void)
- {
- SET_AUX_SUBTITLE_BUFFER_LOCKED(FALSE);
- }
- /////////////////////////////////////////////////////////////////////////////////////////////
- // Function Name : updateSubtitlesIndex
- // Purpose : add a new entry to the subtitles index
- // Input parameters: dwAddress - offest in bytes of the new entry, from the start of
- // the subtitles storage memory.
- // dwStartSCLK - start SCLK count for the new subtitle.
- // Return type : void
- // Description : This function is called for each new subtitles entry. It checks if
- // the entry should be indexed, and stores its time and address if it
- // should. In any given time, there's a uniform interval (in subtitle
- // entries) between each index entry. When the index is full, half of
- // the entries are discarded and the interval is multiplied by 2.
- /////////////////////////////////////////////////////////////////////////////////////////////
- #ifdef AUX_SUBTITLES_INDEX
- void updateSubtitlesIndex(DWORD dwAddress, DWORD dwStartSCLK)
- {
- int i;
- g_pSubtitleIndex->wSubtitlesModulu ++;
- if ( g_pSubtitleIndex->wSubtitlesModulu == g_pSubtitleIndex->wInterval ) {
- if ( g_pSubtitleIndex->bIndexPosition == SUBTITLE_INDEX_ENTRIES ) {
- for ( i=1 ; i< SUBTITLE_INDEX_ENTRIES ; i +=2 ) {
- g_pSubtitleIndex->entry[i>>1].dwAddress = g_pSubtitleIndex->entry[i].dwAddress;
- g_pSubtitleIndex->entry[i>>1].dwStartTime = g_pSubtitleIndex->entry[i].dwStartTime;
- }
- g_pSubtitleIndex->wInterval = g_pSubtitleIndex->wInterval << 1;
- g_pSubtitleIndex->bIndexPosition = SUBTITLE_INDEX_ENTRIES / 2;
- }
- g_pSubtitleIndex->entry[g_pSubtitleIndex->bIndexPosition].dwAddress = dwAddress;
- g_pSubtitleIndex->entry[g_pSubtitleIndex->bIndexPosition++].dwStartTime = dwStartSCLK;
- g_pSubtitleIndex->wSubtitlesModulu = 0;
- }
- }
- #endif // AUX_SUBTITLES_INDEX
- /////////////////////////////////////////////////////////////////////////////////////////////
- // Function Name : subtitleGoToTime
- // Purpose : Jump to a new time in the subtitle storage
- // Input parameters: dwCurrentTime - the new time
- // Return type : void
- // Description : After FF/FB/Goto, this function is used to set the next subtitle to be
- // the 1 right before the new time.
- /////////////////////////////////////////////////////////////////////////////////////////////
- void subtitleGoToTime(DWORD dwCurrentTime)
- {
- #ifdef DEBUG_AUX_SUBTITLES
- DWORD dwStart;
- DWORD dwEnd;
- dwStart=gen_timer();
- #endif
- // <<< Robin_0318_2005, need re-allocate the memory
- _allocateStorageInterface();
- // >>> Robin_0318_2005
- // WARNING: disable next 4 lines before uncommenting the next section
- g_pSubtitleStorage->dwCurrentStorageOffset = 0;
- g_pSubtitleStorage->wBufferPos=0;
- subtitleStorageFillBuffer();
- subtitleStorageGetStartTime(&g_dwNextSubtitleUpdateSCLK);
- /* Disabled until time can be determined before playback starts.
- // look for the first indexed entry with later time
- for (i=0 ; g_pSubtitleIndex->entry[i].dwStartTime<dwCurrentTime && i < g_pSubtitleIndex->bIndexPosition ; i++)
- {
- }
- // start search from the previous indexed entry, or from the beginning of
- // subtitle memory if the 1st indexed entry is too late
- dwPreviousAddress = i > 1 ? g_pSubtitleIndex->entry[i-1].dwAddress : 0 ;
- g_pSubtitleStorage->dwCurrentStorageOffset = dwPreviousAddress ;
- g_pSubtitleStorage->wBufferPos=0;
- subtitleStorageFillBuffer();
- // The time was indexed, so this function call only comes to advances
- // the reading pointer.
- subtitleStorageGetStartTime(&g_dwNextSubtitleUpdateSCLK);
- // search subtitle memory sequentially for the last subtitle before
- // the current time
- while (1)
- {
- if ( g_dwNextSubtitleUpdateSCLK >= dwCurrentTime )
- break;
- dwPreviousAddress = g_pSubtitleStorage->dwCurrentStorageOffset +
- g_pSubtitleStorage->wBufferPos - STORAGE_INTERFACE_BUFFER_SIZE - 4;
- subtitleStorageSkipSubtitle(&g_dwNextSubtitleUpdateSCLK);
- }
- g_pSubtitleStorage->dwCurrentStorageOffset = dwPreviousAddress ;
- g_pSubtitleStorage->wBufferPos=0;
- subtitleStorageFillBuffer();
- subtitleStorageGetStartTime(&g_dwNextSubtitleUpdateSCLK); */
- SET_AUX_SUBTITLE_START_DISPLAY(TRUE);
- #ifdef DEBUG_AUX_SUBTITLES
- dwEnd=gen_timer();
- dbg_printf(("Subtitles seek time: %lun",dwEnd-dwStart));
- #endif
- }
- /////////////////////////////////////////////////////////////////////////////////////////////
- // Function Name : setSubtitlesPlayMode
- // Purpose : Sets the play mode for subtitles - whether the core task should
- // check for new subtitles or not.
- // Input parameters: mode - whether play mode is on
- // Return type : void
- // Description : Before using FF/FB/Goto, play mode should be set to FALSE so that the
- // core task won't try to search for subtitles. After FF/FB/Goto is done
- // and subtitleGoToTime is called, play more should be set to TRUE.
- /////////////////////////////////////////////////////////////////////////////////////////////
- void setSubtitlesPlayMode(BOOL mode)
- {
- // transition from scanning to normal playback
- /*
- if (!IS_AUX_SUBTITLE_PLAY_MODE && mode == TRUE) {
- //SET_AUX_SUBTITLE_PERFORM_SEEK(TRUE);
- } */
- SET_AUX_SUBTITLE_PLAY_MODE(mode);
- dbg_printf(("Subtitles mode - %dn",mode));
- }
- /////////////////////////////////////////////////////////////////////////////////////////////
- // Function Name : stopDisplayAuxSubtitles
- // Purpose : notify the UI to stop displaying the current subtitle
- // Return type : void
- // Description :
- /////////////////////////////////////////////////////////////////////////////////////////////
- void stopDisplayAuxSubtitles(void)
- {
- ie_send(IE_UI_STOP_DISPLAY_AUX_SUBTITLE);
-
- //Stivenz_1115_04: Memory optimization: Move g_SubtitleStorage and g_SubtitleIndex to heap.
- _freeStorageInterfaceAndIndex();
- }
- BOOL areAuxSubtitlePresent(void)
- {
- return IS_AUX_SUBTITLE_AVAILABE;
- }
- // <<< Robin_0907_2004
- BOOL areAuxSubtitleExist(void)
- {
- return IS_AUX_SUBTITLE_EXIST;
- }
- // >>> Robin_0907_2004
- /*
- void switchBytesInWString(LPSTR str)
- {
- WCHAR tmp;
- WCHAR *p = (WCHAR *)str;
- while (*p != NULL )
- {
- tmp = *p;
- *p= (((tmp&0xff)<<8) | ((tmp&0xff00)>>8));
- p++;
- }
- }
- */
- // <<< Stivenz_1115_2004: Move g_SubtitleStorage to heap to save memory.
- ////////////////////////////////////////////////////////////////////////////////////////////
- // Function Name : _allocateStorageInterface
- // Purpose : malloc memory for auxiliary subtitle storage interface.
- // Return type : TRUE if success, otherwise FASLE
- // Description :this function is only for memory optimization.
- /////////////////////////////////////////////////////////////////////////////////////////////
- static BOOL _allocateStorageInterface(void)
- {
- if( NULL == g_pSubtitleStorage)
- {
- //dbg_printf(("initAuxSubtitles() malloc for g_pSubtitleStorage.n"));
- g_pSubtitleStorage = malloc(sizeof(SubtitleStorageInterface));
- if( NULL == g_pSubtitleStorage)
- {
- tr_printf(("FATAL: initAuxSubtitles() Failed [1]: Malloc failed. Low system resource.n"));
- return FALSE;
- }
- }
- return TRUE;
- }
- #ifdef AUX_SUBTITLES_INDEX
- ////////////////////////////////////////////////////////////////////////////////////////////
- // Function Name : _allocateStorageIndex
- // Purpose : malloc memory for auxiliary subtitle storage index.
- // Return type : TRUE if success, otherwise FASLE
- // Description :this function is only for memory optimization.
- /////////////////////////////////////////////////////////////////////////////////////////////
- static BOOL _allocateStorageIndex(void)
- {
- if(NULL == g_pSubtitleIndex)
- {
- //dbg_printf(("initAuxSubtitles() malloc for g_pSubtitleIndex.n"));
- g_pSubtitleIndex = malloc(sizeof(SubtitleStorageIndex));
- if( NULL == g_pSubtitleIndex)
- {
- tr_printf(("FATAL: initAuxSubtitles() Failed [2]: Malloc failed. Low system resource.n"));
- return FALSE;
- }
- }
- return TRUE;
- }
- #endif
- ////////////////////////////////////////////////////////////////////////////////////////////
- // Function Name : _FreeStorageInterfaceAndIndex
- // Purpose : free memory of auxiliary subtitle storage interface or index .
- // Return type : TRUE if success, otherwise FASLE
- // Description :this function is only for memory optimization.
- /////////////////////////////////////////////////////////////////////////////////////////////
- #ifdef V882_FLASH_CARD
- BOOL _freeStorageInterfaceAndIndex(void)
- #else
- static BOOL _freeStorageInterfaceAndIndex(void)
- #endif
- {
- SAFELY_FREE_PTR(g_pSubtitleStorage);
- #ifdef AUX_SUBTITLES_INDEX
- SAFELY_FREE_PTR(g_pSubtitleIndex);
- #endif // AUX_SUBTITLES_INDEX
- return TRUE;
- }
- // Stivenz_1115_2004 >>>
- #ifdef IS_MP4_CAPABLE
- static void _mp4SubtitleReadDRAM(UINT32 ulAddress, UINT16* pBuffer, UINT32 ulLength )
- {
- UINT32 ulWriteLengthFirst;
- UINT32 ulWriteLngthSecond;
- UINT32 ulBufferStartAddr, ulBufferEndAddr;
-
- ulBufferStartAddr = _mpeg4InternalSubtitleBufferStartAddr * 512UL;
- ulBufferEndAddr = (_mpeg4InternalSubtitleBufferStartAddr + SPB_SIZE_AVI) * 512UL;
-
-
- while(ulAddress >= ulBufferEndAddr)
- {
- ulAddress -= (ulBufferEndAddr - ulBufferStartAddr);
- }
- ulWriteLengthFirst = min(ulLength, ulBufferEndAddr -ulAddress);
- ulWriteLngthSecond = ulLength - ulWriteLengthFirst;
- wai_sem(SEM_DRAM_ID);
- I49_ReadDRAMDataNSW(ulAddress, (UINT16*)pBuffer, ulWriteLengthFirst);
-
- if ( ulWriteLngthSecond != 0UL)
- {
- I49_ReadDRAMDataNSW(ulBufferStartAddr, (UINT16*)(pBuffer + ulWriteLengthFirst ), ulWriteLngthSecond );
- }
- sig_sem(SEM_DRAM_ID);
- return;
- }
- static void _mp4SubtitleLoadTime(UINT32 *ulTime)
- {
- _mp4SubtitleReadDRAM( _dwMP4SubtitleReadDRAMAddr, (UINT16*)(ulTime), 2 );
- _dwMP4SubtitleReadDRAMAddr += 2;
- }
- static BOOL _mp4SubtitleLoadSample(void)
- {
- UINT32 ulSampleSize;
- UINT32 ulSampleSizeInWord;
- BYTE pBuffer[32];
- UINT16 uiSampleCount;
- UINT16 uiSampleOffset;
- WORD pUnicodeBuffer[32];
- WORD wLastUnicode = 0;
- UINT16 uiUnicodeOffset = 0;
-
- _mp4SubtitleReadDRAM( _dwMP4SubtitleReadDRAMAddr, (UINT16*)(&ulSampleSize), 2 );
- _dwMP4SubtitleReadDRAMAddr += 2;
-
- ulSampleSizeInWord = (ulSampleSize+1)/2;
- uiSampleCount = min(ulSampleSize,SUBTITLE_STRING_SC_SZ_B);
- uiSampleOffset = 0;
-
- while(uiSampleCount > 0)
- {
- UINT16 uiBufferSize;
- UINT16 uiUnicodeBufferSize;
- uiBufferSize = min(uiSampleCount, 32);
-
- _mp4SubtitleReadDRAM( (_dwMP4SubtitleReadDRAMAddr + (uiSampleOffset/2)), (UINT16*)pBuffer, ((uiBufferSize+1)/2) );
- uiUnicodeBufferSize = 0;
- UTF8ToUnicode(pBuffer, pUnicodeBuffer, uiBufferSize, &wLastUnicode, &uiUnicodeBufferSize);
- sc_SetBytes(SC_AUX_SUBTITLES_STRINGS_ADDR, 2*uiUnicodeOffset, 2*uiUnicodeBufferSize, (BYTE*)(&pUnicodeBuffer[0]) );
- uiSampleOffset += uiBufferSize;
- uiSampleCount -= uiBufferSize;
- uiUnicodeOffset += uiUnicodeBufferSize;
- }
- _dwMP4SubtitleReadDRAMAddr += ulSampleSizeInWord;
- return (ulSampleSize < SUBTITLE_STRING_SC_SZ_B);
- }
- static void _mp4SubtitleSkipSubtitle(UINT32 *ulTime)
- {
- UINT32 ulSampleSize;
- UINT32 ulSampleSizeInWord;
- _mp4SubtitleReadDRAM( _dwMP4SubtitleReadDRAMAddr, (UINT16*)(&ulSampleSize), 2 );
- _dwMP4SubtitleReadDRAMAddr += 2;
- ulSampleSizeInWord = (ulSampleSize+1)/2;
- _dwMP4SubtitleReadDRAMAddr += ulSampleSizeInWord;
- _dwMP4SubtitleReadDRAMAddr += 2; // skip end time
- _mp4SubtitleReadDRAM( _dwMP4SubtitleReadDRAMAddr, (UINT16*)(ulTime), 2 );
- _dwMP4SubtitleReadDRAMAddr += 2;
-
- }
- void mp4InitSubtitles(void)
- {
- g_dwNextSubtitleUpdateSCLK = LAST_SUBTITLE_MARKER;
- SET_AUX_SUBTITLE_START_DISPLAY(TRUE);
- SET_AUX_SUBTITLE_BUFFER_LOCKED(FALSE);
- // SET_AUX_SUBTITLE_AVAILABE(TRUE);
- // setSubtitlesPlayMode(TRUE);
- }
- void mp4CheckAndHandleSubtitle(DWORD dwCurrentTime)
- {
- if (_dwMP4SubtitleReadDRAMAddr == _dwMP4SubtitleWriteDRAMAddr) // no data
- {
- if (IS_AUX_SUBTITLE_START_DISPLAY)
- return;
-
- if ( dwCurrentTime >= g_dwNextSubtitleUpdateSCLK )
- {
- ie_send(IE_UI_STOP_DISPLAY_AUX_SUBTITLE);
- g_dwNextSubtitleUpdateSCLK = LAST_SUBTITLE_MARKER;
- SET_AUX_SUBTITLE_START_DISPLAY(TRUE);
- }
- return;
- }
-
- if (g_dwNextSubtitleUpdateSCLK == LAST_SUBTITLE_MARKER) // first time
- _mp4SubtitleLoadTime(&g_dwNextSubtitleUpdateSCLK);
- while (dwCurrentTime >= g_dwNextSubtitleUpdateSCLK)
- {
- if (IS_AUX_SUBTITLE_START_DISPLAY)
- {
- if (FALSE == IS_AUX_SUBTITLE_BUFFER_LOCKED)
- {
- if ( FALSE == _mp4SubtitleLoadSample())
- {
- dbg_printf(("Error - subtitle too longn"));
- }
- _mp4SubtitleLoadTime(&g_dwNextSubtitleUpdateSCLK);
- if (g_dwNextSubtitleUpdateSCLK < dwCurrentTime) {
- _mp4SubtitleLoadTime(&g_dwNextSubtitleUpdateSCLK);
- }
- else
- {
- SET_AUX_SUBTITLE_BUFFER_LOCKED(TRUE);
- ie_send(IE_UI_START_DISPLAY_AUX_SUBTITLE);
- SET_AUX_SUBTITLE_START_DISPLAY(FALSE);
- }
- }
- else
- {
- _mp4SubtitleSkipSubtitle(&g_dwNextSubtitleUpdateSCLK);
- }
- }
- else
- {
- _mp4SubtitleLoadTime(&g_dwNextSubtitleUpdateSCLK);
- if ( dwCurrentTime < g_dwNextSubtitleUpdateSCLK )
- {
- ie_send(IE_UI_STOP_DISPLAY_AUX_SUBTITLE);
- }
- SET_AUX_SUBTITLE_START_DISPLAY(TRUE);
- }
- }
-
- }
- #endif
- // Robin_0117_2005, support AVI internal text subtitle
- #ifdef IS_AVI_CAPABLE
- static BOOL _aviProcessInternalSubtitleText(DWORD dwStartLBA, DWORD dwFileSize)
- {
- BOOL bAuxSubtitle = FALSE;
- SubtitleParsingFuncPtr pfParseSubtitles;
- UINT16 uiCount;
-
-
- SET_AUX_SUBTITLE_AVAILABE(FALSE);
- g_dwNextSubtitleUpdateSCLK = LAST_SUBTITLE_MARKER;
- for (uiCount=0;uiCount<SF_NUMBER_OF_FORMATS;uiCount++)
- {
- if ( NULL != availableSubtitleFormats[uiCount].pfProbe)
- {
- if (TRUE == availableSubtitleFormats[uiCount].pfProbe(dwStartLBA, dwFileSize))
- {
- pfParseSubtitles=availableSubtitleFormats[uiCount].pfParse;
- bAuxSubtitle = TRUE;
- break;
- }
- }
- }
- if (bAuxSubtitle == FALSE)
- {
- tr_printf(("_aviProcessInternalSubtitleText - Couldn't probe subtitles filen"));
- return FALSE;
- }
- // _mpeg4ExternalSubtitleAddr = _dwMPEG4ProcessingEndAddr;
-
- // if so, parse it and store its content.
- if ( FALSE == pfParseSubtitles(dwStartLBA,dwFileSize,_mpeg4VideoScale,_mpeg4VideoRate)) {
- tr_printf(("_aviProcessInternalSubtitleText - Couldn't parse subtitles filen"));
- return FALSE;
- }
- _dwMPEG4ProcessingEndAddr = (CALC_SUBTITLE_ADDRESS( _mpeg4ExternalSubtitleAddr, g_pSubtitleStorage->dwCurrentStorageOffset) >>9) <<9;
- _dwMPEG4ProcessingEndAddr = (_dwMPEG4ProcessingEndAddr>>9)<<9;
-
- dbg_printf(("Start Address of Current External Subtitle : 0x%lxn",_dwMPEG4ProcessingEndAddr));
-
- subtitleStorageInitReading();
- subtitleStorageGetStartTime(&g_dwNextSubtitleUpdateSCLK);
- SET_AUX_SUBTITLE_START_DISPLAY(TRUE);
- SET_AUX_SUBTITLE_BUFFER_LOCKED(FALSE);
- SET_AUX_SUBTITLE_AVAILABE(TRUE);
- setSubtitlesPlayMode(TRUE);
- return TRUE;
- }
- ////////////////////////////////////////////////////////////////////////////
- // Function name : _aviParseInternalSubtileText
- // Purpose : Parse the internal subtitle (Text)
- // Input Parameters :
- // Return type :
- // Description :
- ////////////////////////////////////////////////////////////////////////////
- BOOL aviParseInternalSubtileText()
- {
- DWORD dwTextStartLBA;
- DWORD dwTextStartOffset;
- CHAR ucChunkID[4];
- UINT16 uiStreamNumber;
- DWORD dwNameSize;
- DWORD dwSize;
- g_dwSubtitleExtraOffset = 0;
-
- dwTextStartLBA = _dwMPEG4ClipStartLBA + ( (_wMPEG4ClipStartOffset + _mpeg4SubtitleOffsetInAvi - FOURCC_FIELD_LENGTH) >> 11);
- dwTextStartOffset = (WORD)((_wMPEG4ClipStartOffset + _mpeg4SubtitleOffsetInAvi -FOURCC_FIELD_LENGTH) % LOGICAL_BLOCK_SIZE);
- if (!AuxCache_GetBytes(dwTextStartLBA, dwTextStartOffset, 4, ucChunkID))
- {
- dbg_printf(("_aviParseInternalSubtileText(): AuxCache_GetBytes Failedn"));
- return FALSE;
- }
- uiStreamNumber = (ucChunkID[0] - '0')*10 + ucChunkID[1] - '0';
- if (uiStreamNumber == _mpeg4SubtitleStreamID && 't' == ucChunkID[2])
- {
- dwTextStartOffset += 4; // **tx
- dwTextStartOffset += 4; // chunk size
- dwTextStartOffset += 4; // char[4]; // ’GAB2’
- dwTextStartOffset += 1; // BYTE 0x00;
- dwTextStartOffset += 2; // WORD 0x02; // unicode
- if (!AuxCache_GetBytes(dwTextStartLBA, dwTextStartOffset, 4, &dwNameSize))
- {
- dbg_printf(("_aviParseInternalSubtileText(): AuxCache_GetBytes Failedn"));
- return FALSE;
- }
- dwTextStartOffset += 4; // DWORD dwSize_name; // length of stream name in bytes
- dwTextStartOffset += dwNameSize; // char name[dwSize_name]; // zero-terminated subtitle stream name encoded in UTF-16
- dwTextStartOffset +=2; // WORD 0x04;
- if (!AuxCache_GetBytes(dwTextStartLBA, dwTextStartOffset, 4, &dwSize))
- {
- dbg_printf(("_aviParseInternalSubtileText(): AuxCache_GetBytes Failedn"));
- return FALSE;
- }
- dwTextStartOffset += 4; // DWORD dwSize; // size of SRT/SSA text file
- // char data[dwSize]; // entire SRT/SSA file
- dwTextStartLBA += (dwTextStartOffset
- >>11);
- dwTextStartOffset = dwTextStartOffset % LOGICAL_BLOCK_SIZE;
- g_dwSubtitleExtraOffset = dwTextStartOffset;
- return(_aviProcessInternalSubtitleText(dwTextStartLBA, dwSize));
-
- }
- else
- {
- return FALSE;
- }
- }
- #endif
- #endif // USE_AUX_SUBTITLES