#include #include #include #include #include #include #include #include #include #include #include #include "types.h" #include "nvm_ioctl.h" #include "umf_mod.h" #include "umf_debug.h" #include #include "subcustomer_setting.h" #include "al_setting.h" #include "app_data_setting.h" #if defined(CONFIG_UMF_ONLYONECOPY_DATASECTION) #include "sismmio.h" #endif #ifdef CONFIG_ENABLE_UMF_LANGUAGE_MODULES #include "umf_langmod.h" #include "subcustomer_setting.h" #include "al_setting.h" #include "app_data_setting.h" #endif #include "kmf_ioctl.h" #include "ap_extern.h" #if (defined CONFIG_MOD_PACK_TT) || (defined CONFIG_MOD_PACK_SUB) #include "mmap_malloc.h" #include "al_teletext.h" #ifdef CONFIG_MOD_PACK_SUB #include "mid_sub.h" #endif #endif #define MOD_DEBUG #ifdef MOD_DEBUG #undef DEBF #define DEBF(fmt, arg...) UMFDBG(0,fmt, ##arg) #else #define DEBF(fmt, arg...) #endif #ifdef CONFIG_ENABLE_UMF_MODULES #define MEASURE_LOADING_TIME #define MODULE_INFO_FILE "/tmp/mod.info" typedef struct { INT32 fd; UINT32 gotRtInfo; UINT32 vma; /* module runtime address(4k alignment) in umf VMA */ UINT32 size; /* module size */ UINT32 dataSegStart; /* start address of data section and bss section */ UINT32 dataSegSize; /* sizeof data section and bss section */ UINT32 bLoaded; } ModRtInfo_t; typedef struct { UMFMOD_ID eModID; /* module's ID */ UINT8 *pModFlashName; /* module's tag in flash image, refer to mergedir/flash_layout.gyp */ UINT8 *pModFSFile; /* file's name after load module data from flash */ UINT8 *pModSegName; /* module segment name, refer to aps/application/customer/appfolder/umflink.ld */ ModRtInfo_t stModRtInfo; /* it's a slot to store runtime information when this module is loaded */ } ModuleParam_t; #ifdef CONFIG_ENABLE_UMF_LANGUAGE_MODULES static UMFMOD_ID g_LangModeIndex = UMFMOD_MAX; static Boolean g_AllLangIsMemory = FALSE; #endif /* module informations & configuration area */ static ModuleParam_t stModParam[UMFMOD_MAX] = { #ifdef CONFIG_MOD_PACK_MEDIA {UMFMOD_MEDIA, (UINT8 *)"ModMedia", (UINT8 *)"/tmp/umf.media", (UINT8 *)".media", {-1, 0, 0, 0, 0, 0, 0}}, #else {-1, NULL, NULL, NULL, {-1, 0, 0, 0, 0, 0, 0}}, #endif #ifdef CONFIG_MOD_PACK_PICLIB {UMFMOD_PICTURE, (UINT8 *)"ModPicture", (UINT8 *)"/tmp/umf.picture", (UINT8 *)".picture", {-1, 0, 0, 0, 0, 0, 0}}, #else {-1, NULL, NULL, NULL, {-1, 0, 0, 0, 0, 0, 0}}, #endif #ifdef CONFIG_MOD_PACK_RUNAV {UMFMOD_FFMPEG, (UINT8 *)"ModFfmpeg", (UINT8 *)"/tmp/umf.ffmpeg", (UINT8 *)".ffmpeg", {-1, 0, 0, 0, 0, 0, 0}}, #else {-1, NULL, NULL, NULL, {-1, 0, 0, 0, 0, 0, 0}}, #endif #ifdef CONFIG_MOD_PACK_ATV {UMFMOD_ATV, (UINT8 *)"ModAtv", (UINT8 *)"/tmp/umf.atv", (UINT8 *)".atv", {-1, 0, 0, 0, 0, 0, 0}}, #else {-1, NULL, NULL, NULL, {-1, 0, 0, 0, 0, 0, 0}}, #endif #ifdef CONFIG_MOD_PACK_DTV {UMFMOD_DTV, (UINT8 *)"ModDtv", (UINT8 *)"/tmp/umf.dtv", (UINT8 *)".dtv", {-1, 0, 0, 0, 0, 0, 0}}, #else {-1, NULL, NULL, NULL, {-1, 0, 0, 0, 0, 0, 0}}, #endif #ifdef CONFIG_MOD_PACK_TT {UMFMOD_TT, (UINT8 *)"ModTT", (UINT8 *)"/tmp/umf.teletext", (UINT8 *)".teletext", {-1, 0, 0, 0, 0, 0, 0}}, #else {-1, NULL, NULL, NULL, {-1, 0, 0, 0, 0, 0, 0}}, #endif #ifdef CONFIG_MOD_PACK_SUB {UMFMOD_SUB, (UINT8 *)"ModSub", (UINT8 *)"/tmp/umf.subtitle", (UINT8 *)".subtitle", {-1, 0, 0, 0, 0, 0, 0}}, #else {-1, NULL, NULL, NULL, {-1, 0, 0, 0, 0, 0, 0}}, #endif #ifdef CONFIG_ENABLE_UMF_LANGUAGE_MODULES /*langMode begin(This context is auto generated by ./tools/gen_LangMode.py please don't modify.)*/ {UMFMOD_TV_IDL_Spanish, (UINT8 *)"Spanish", (UINT8 *)"/tmp/umf.TV_IDL_Spanish", (UINT8 *)".TV_IDL_Spanish", {-1, 0, 0, 0, 0, 0, 0}}, {UMFMOD_TV_IDL_French, (UINT8 *)"French", (UINT8 *)"/tmp/umf.TV_IDL_French", (UINT8 *)".TV_IDL_French", {-1, 0, 0, 0, 0, 0, 0}}, {UMFMOD_TV_IDL_German, (UINT8 *)"German", (UINT8 *)"/tmp/umf.TV_IDL_German", (UINT8 *)".TV_IDL_German", {-1, 0, 0, 0, 0, 0, 0}}, {UMFMOD_TV_IDL_Italian, (UINT8 *)"Italian", (UINT8 *)"/tmp/umf.TV_IDL_Italian", (UINT8 *)".TV_IDL_Italian", {-1, 0, 0, 0, 0, 0, 0}}, {UMFMOD_TV_IDL_Portuguese, (UINT8 *)"Portuguese", (UINT8 *)"/tmp/umf.TV_IDL_Portuguese", (UINT8 *)".TV_IDL_Portuguese", {-1, 0, 0, 0, 0, 0, 0}}, {UMFMOD_TV_IDL_Polish, (UINT8 *)"Polish", (UINT8 *)"/tmp/umf.TV_IDL_Polish", (UINT8 *)".TV_IDL_Polish", {-1, 0, 0, 0, 0, 0, 0}}, {UMFMOD_TV_IDL_Russian, (UINT8 *)"Russian", (UINT8 *)"/tmp/umf.TV_IDL_Russian", (UINT8 *)".TV_IDL_Russian", {-1, 0, 0, 0, 0, 0, 0}}, {UMFMOD_TV_IDL_Finnish, (UINT8 *)"Finnish", (UINT8 *)"/tmp/umf.TV_IDL_Finnish", (UINT8 *)".TV_IDL_Finnish", {-1, 0, 0, 0, 0, 0, 0}}, {UMFMOD_TV_IDL_Swedish, (UINT8 *)"Swedish", (UINT8 *)"/tmp/umf.TV_IDL_Swedish", (UINT8 *)".TV_IDL_Swedish", {-1, 0, 0, 0, 0, 0, 0}}, {UMFMOD_TV_IDL_Greek, (UINT8 *)"Greek", (UINT8 *)"/tmp/umf.TV_IDL_Greek", (UINT8 *)".TV_IDL_Greek", {-1, 0, 0, 0, 0, 0, 0}}, {UMFMOD_TV_IDL_Dutch, (UINT8 *)"Dutch", (UINT8 *)"/tmp/umf.TV_IDL_Dutch", (UINT8 *)".TV_IDL_Dutch", {-1, 0, 0, 0, 0, 0, 0}}, {UMFMOD_TV_IDL_English, (UINT8 *)"English", (UINT8 *)"/tmp/umf.TV_IDL_English", (UINT8 *)".TV_IDL_English", {-1, 0, 0, 0, 0, 0, 0}}, {UMFMOD_TV_IDL_Schinese, (UINT8 *)"Schinese", (UINT8 *)"/tmp/umf.TV_IDL_Schinese", (UINT8 *)".TV_IDL_Schinese", {-1, 0, 0, 0, 0, 0, 0}}, /*langMode end.(This context is auto generated by ./tools/gen_LangMode.py please don't modify.)*/ #endif }; extern int LzDecode(void *inFile, void *outFile, size_t inFileSize, unsigned char reserveMm); static ModuleParam_t* umf_findModule(UMFMOD_ID eID) { ModuleParam_t *pModParam = NULL; UINT32 iter = 0; FILE *fp = NULL; INT8 tmpModSegName[80]; UINT32 size = 0; UINT32 vma = 0; UINT32 dataSegStart = 0; UINT32 dataSegEnd = 0; INT32 found = 0; while (iter < UMFMOD_MAX) { if (stModParam[iter].eModID == eID) { pModParam = &stModParam[iter]; break; } iter++; } if (iter < UMFMOD_MAX && !pModParam->stModRtInfo.gotRtInfo) { if (pModParam->stModRtInfo.fd == -1) { fp = fopen(MODULE_INFO_FILE, "r"); if (fp == NULL) { printf("[%s,%d]open %s fail.\n", __FUNCTION__, __LINE__, MODULE_INFO_FILE); return NULL; } while (!feof(fp)) { memset(tmpModSegName, 0, 80); fscanf(fp, "%80s %x %x %x %x", tmpModSegName, &size, &vma, &dataSegStart, &dataSegEnd); if (strcmp(tmpModSegName, (INT8*)stModParam[iter].pModSegName) == 0) { found = 1; pModParam->stModRtInfo.vma = vma; pModParam->stModRtInfo.size = size; pModParam->stModRtInfo.dataSegStart = dataSegStart; pModParam->stModRtInfo.dataSegSize = dataSegEnd - dataSegStart; UMFDBG(0, "Module:%s\tVMA:0x%08x Size:0x%08x DataSegStart:0x%08x DataSegEnd:0x%08x\n", (char*)&tmpModSegName, vma, size, dataSegStart, dataSegEnd); pModParam->stModRtInfo.gotRtInfo = 1; break; } } fclose(fp); if (!found) { return NULL; } } } return pModParam; } INT32 umf_loadModule(UMFMOD_ID eID) { UMFDBG(0, "Enter %s\n", __FUNCTION__); ModuleParam_t *pMod = umf_findModule(eID); void *ptr = NULL; void *dataPtr = NULL; UINT32 modSizeC = 0; /* compressed size */ UINT32 modSizeNC = 0; /* uncompressed size */ void *pSrcBuf = NULL; UINT8 *destBuf = NULL; UINT32 u32FlashSize = 0; /*This is flash driver information*/ unsigned char reserveMm = FALSE; #if defined(CONFIG_CHIP_512L) || defined (CONFIG_SUPPORT_64M_DTV) || defined (CONFIG_RUNAV_USE_RESERVE_MEMORY) input_type_t eInputType = INPUT_TYPE_DISABLE; MID_DISP_DTVGetInputType(&eInputType); #endif #ifdef MEASURE_LOADING_TIME struct timespec pre_tp, post_tp; struct timespec result; clock_gettime(CLOCK_MONOTONIC, &pre_tp); #endif #if (defined CONFIG_MOD_PACK_TT) || (defined CONFIG_MOD_PACK_SUB) static UMFMOD_ID pre_id = UMFMOD_MAX; #endif if (!pMod) { printf("[%s,%d]find module fail,eID:%d\n", __FUNCTION__, __LINE__, eID); return -1; } if (pMod->stModRtInfo.bLoaded) /* this module has been loaded */ { printf("[%s,%d]this module has been loaded,eID:%d\n", __FUNCTION__, __LINE__, eID); return 0; } void* pMAP = NULL; int fd = 0; FlashTableSearch_t flashtable = {0}; flashtable.pTag = (void *)(pMod->pModFlashName); flashtable.Addr = 0; flashtable.Flashddr = 0; flashtable.size = 0; ioctl(kmfdev, KMF_IOC_LookupFlashTable, &flashtable); if ((fd=open("/dev/mem", O_RDWR | O_DSYNC)) < 0) { UMFDBG(0, "[%s,%d] open /dev/mem fail. error:%s\n", __FUNCTION__,__LINE__, strerror(errno)); return -1; } u32FlashSize = Cmd_GetFlashSize(); pMAP = mmap(0, u32FlashSize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0x1c000000); pSrcBuf = pMAP+(flashtable.Flashddr&0x00ffffff); modSizeC = flashtable.size; printf("[%s:%d] ++++++++++++++++++++modSizeNC: %d, modSizeC: %d\n",__FUNCTION__,__LINE__,*(UINT32*)pSrcBuf, modSizeC); modSizeNC = *(UINT32*)pSrcBuf; printf("pMod->pModFlashName is %s\n\n",pMod->pModFlashName); if (pMod->stModRtInfo.size != modSizeNC) { UMFDBG(0, "Size not equal, maybe this module don't we need?(%d,%d)\n", pMod->stModRtInfo.size, modSizeNC); goto FAIL2; } if((pMod->stModRtInfo.fd = open((INT8*)pMod->pModFSFile, O_RDWR|O_CREAT|O_SYNC)) < 0) { UMFDBG(0, "[%s,%d] open %s fail. error:%s\n", __FUNCTION__,__LINE__, pMod->pModFSFile,strerror(errno)); goto FAIL2; } /* create a empty file with length modSizeNC and a space tail */ if(-1 == lseek(pMod->stModRtInfo.fd, (off_t)(modSizeNC - 1), SEEK_SET)) { UMFDBG(0, "[%s,%d] lseek fail. error:%s\n", __FUNCTION__,__LINE__,strerror(errno)); goto FAIL1; } if(1 != write(pMod->stModRtInfo.fd, " ", 1)) { UMFDBG(0, "[%s,%d] write file fail. error:%s\n", __FUNCTION__,__LINE__,strerror(errno)); goto FAIL1; } if((destBuf = mmap(NULL, pMod->stModRtInfo.size, PROT_READ|PROT_WRITE, MAP_SHARED, pMod->stModRtInfo.fd, 0)) == MAP_FAILED) { printf("[%s,%d]mmap fail. error: %s\n", __FUNCTION__, __LINE__,strerror(errno)); goto FAIL1; } else { memset(destBuf, 0, modSizeNC); } #if defined(CONFIG_CHIP_512L) || defined (CONFIG_SUPPORT_64M_DTV) #ifdef CONFIG_DVB_SYSTEM_DVBT2_SUPPORT //TT2C if ((eInputType == INPUT_TYPE_MEDIA) || (eInputType == INPUT_TYPE_USB)) { reserveMm = TRUE; //compression use t2 demod reserved mem } #ifdef CONFIG_SUPPORT_PVR else { reserveMm = TRUE; } #endif #else //TCS #ifdef CONFIG_SUPPORT_PVR if (eInputType != INPUT_TYPE_USB) { reserveMm = TRUE; } #endif #endif /*when use subtitle reverse memory, need mmap uninit by TT and subtitle module.*/ #if (defined CONFIG_MOD_PACK_TT) || (defined CONFIG_MOD_PACK_SUB) if ((!(pre_id == UMFMOD_TT && eID == UMFMOD_SUB)) && (eID <= UMFMOD_SUB) ) { #ifdef CONFIG_MOD_PACK_TT AL_TTX_Stop(); #endif TTOrSubModUnload(); } #endif #endif #if ((defined CONFIG_MOD_PACK_TT) || (defined CONFIG_MOD_PACK_SUB)) && (defined CONFIG_ENABLE_UMF_LANGUAGE_MODULES) if (eID > UMFMOD_SUB && eID < UMFMOD_MAX) { reserveMm = 2; } #endif #ifdef CONFIG_RUNAV_USE_RESERVE_MEMORY if(((eInputType == INPUT_TYPE_MEDIA) || (eInputType == INPUT_TYPE_USB)) && eID == UMFMOD_FFMPEG) reserveMm = TRUE; #endif if (0 != LzDecode((UINT8 *)pSrcBuf + sizeof(INT32), (void *)destBuf, modSizeC - sizeof(INT32), reserveMm)) { printf("[%s,%d]decompress %s error!\n", __FUNCTION__, __LINE__, pMod->pModFlashName); munmap(destBuf, pMod->stModRtInfo.size); goto FAIL1; } munmap(destBuf, pMod->stModRtInfo.size); /* now mapping this module to umf's VMA */ if((ptr = mmap((void*)pMod->stModRtInfo.vma, pMod->stModRtInfo.size - pMod->stModRtInfo.dataSegSize, PROT_READ|PROT_EXEC, MAP_PRIVATE, pMod->stModRtInfo.fd, 0)) != (void*)pMod->stModRtInfo.vma) { printf("[%s,%d]the mapped address(%p) don't we needed(0x%08x), module loading fail!.\n", __FUNCTION__, __LINE__, ptr, pMod->stModRtInfo.vma); goto FAIL1; } if (pMod->stModRtInfo.dataSegSize) { if((dataPtr = mmap((void*)pMod->stModRtInfo.dataSegStart, pMod->stModRtInfo.dataSegSize, PROT_READ|PROT_WRITE, MAP_PRIVATE, pMod->stModRtInfo.fd, pMod->stModRtInfo.dataSegStart - pMod->stModRtInfo.vma)) != (void*)pMod->stModRtInfo.dataSegStart) { printf("[%s,%d]the mapped address(%p) don't we needed(0x%08x), module loading fail!.\n", __FUNCTION__, __LINE__, dataPtr, pMod->stModRtInfo.dataSegStart); goto FAIL1; } } pMod->stModRtInfo.bLoaded = 1; #ifdef MEASURE_LOADING_TIME clock_gettime(CLOCK_MONOTONIC, &post_tp); result.tv_sec = post_tp.tv_sec - pre_tp.tv_sec; result.tv_nsec = post_tp.tv_nsec - pre_tp.tv_nsec; printf("load module(%s) from flash(FlashSize:%d Kb, DRAMSize:%d Kb), spend time:%.3f s\n", pMod->pModFlashName, modSizeC / 1024, modSizeNC / 1024, ((unsigned long) (result.tv_sec * 1000000000L + result.tv_nsec)) / 1000000000.0); #endif close(fd); munmap(pMAP, u32FlashSize); pMAP = NULL; pSrcBuf = NULL; printf("\n\n[UMF Module]:load module %s successfull!\n\n", pMod->pModFSFile); #if defined CONFIG_UMF_ONLYONECOPY_DATASECTION && !defined CONFIG_CORE_DUMP { int fd; unsigned int i,j; unsigned char *ptr; sismmio_ioctl_section_remap remap; remap.vaddr_start = pMod->stModRtInfo.dataSegStart; remap.length = pMod->stModRtInfo.dataSegSize; ptr = (unsigned char *)remap.vaddr_start; for (i = 0; i < remap.length; i += getpagesize()){ j = *(volatile unsigned char *)(ptr + i); j = j; } fd = open("/dev/sismmio",O_RDWR); remap.opt = 1; ioctl(fd, SISMMIO_SECTIION_REMAP, &remap); close(fd); } #endif UMFDBG(0, "Exit %s\n", __FUNCTION__); #if (defined CONFIG_MOD_PACK_TT) || (defined CONFIG_MOD_PACK_SUB) pre_id = eID; #endif return 0; FAIL1: if (ptr) { munmap(ptr, pMod->stModRtInfo.size - pMod->stModRtInfo.dataSegSize); } if (dataPtr) { munmap(dataPtr, pMod->stModRtInfo.dataSegSize); } close(pMod->stModRtInfo.fd); pMod->stModRtInfo.fd = -1; FAIL2: close(fd); munmap(pMAP, u32FlashSize); pMAP = NULL; pSrcBuf = NULL; printf("\n\n[UMF Module]:load module %s Fail!\n\n", pMod->pModFSFile); UMFDBG(0, "Exit %s\n", __FUNCTION__); return -1; } INT32 umf_checkModuleLoaded(UMFMOD_ID eID) { UMFDBG(0, "Enter %s\n", __FUNCTION__); ModuleParam_t *pMod = umf_findModule(eID); if (!pMod) { printf("[%s,%d]find module fail,eID:%d\n", __FUNCTION__, __LINE__, eID); return -1; } if (pMod->stModRtInfo.bLoaded)/* this module has been loaded */ { return 1; } else { return 0; } } INT32 umf_unloadModule(UMFMOD_ID eID) { UMFDBG(0, "Enter %s\n", __FUNCTION__); ModuleParam_t *pMod = umf_findModule(eID); if (!pMod) { printf("[%s,%d]find module fail,eID:%d\n", __FUNCTION__, __LINE__, eID); UMFDBG(0, "Exit %s\n", __FUNCTION__); return -1; } if (pMod->stModRtInfo.bLoaded)/* this module has been loaded */ { UMFDBG(0, "Module: %d,Modulename:%s,\tVMA:0x%08x Size:0x%08x\n", eID,pMod->pModFlashName, pMod->stModRtInfo.vma, pMod->stModRtInfo.size); munmap((void*)pMod->stModRtInfo.vma, pMod->stModRtInfo.size - pMod->stModRtInfo.dataSegSize); if (pMod->stModRtInfo.dataSegSize) { munmap((void*)pMod->stModRtInfo.dataSegStart, pMod->stModRtInfo.dataSegSize); } close(pMod->stModRtInfo.fd); pMod->stModRtInfo.fd = -1; unlink((INT8*)pMod->pModFSFile); pMod->stModRtInfo.bLoaded = 0; /*After unload ffmpeg module, need call av_mmap_uninit().*/ #ifdef CONFIG_RUNAV_USE_RESERVE_MEMORY if (eID == UMFMOD_FFMPEG) { extern void av_mmap_uninit(void); av_mmap_uninit(); } #endif } UMFDBG(0, "Exit %s\n", __FUNCTION__); return 0; } /*load language by user interface*/ #ifdef CONFIG_ENABLE_UMF_LANGUAGE_MODULES #if 0 INT32 umf_loadAllLangModule(void) { UINT32 i = 0; UINT32 u32tablesize = 0; if (g_AllLangIsMemory == TRUE) { return 0; } u32tablesize = sizeof(u8LangModeMapping)/sizeof(u8LangModeMapping[0]); for (i = 0; i < u32tablesize; i++) { if (g_LangModeIndex == (UMFMOD_ID)u8LangModeMapping[i][1]) { continue; } umf_loadModule(u8LangModeMapping[i][1]); } g_AllLangIsMemory = TRUE; return 0; } INT32 umf_unloadAllLangModule(void) { UINT32 i = 0; UINT32 u32tablesize = 0; if (g_AllLangIsMemory == FALSE) { return 0; } u32tablesize = sizeof(u8LangModeMapping)/sizeof(u8LangModeMapping[0]); for (i = 0; i < u32tablesize; i++) { if (g_LangModeIndex == (UMFMOD_ID)u8LangModeMapping[i][1]) { continue; } umf_unloadModule(u8LangModeMapping[i][1]); } g_AllLangIsMemory = FALSE; return 0; } #endif INT32 umf_loadLangModuleByUILang(INT8 eLangName) { UMFMOD_ID eModeID = UMFMOD_MAX; UINT32 i = 0; UINT32 u32tablesize = 0; if (g_AllLangIsMemory) { return 0; } u32tablesize = sizeof(u8LangModeMapping)/sizeof(u8LangModeMapping[0]); for (i = 0; i < u32tablesize; i++) { if (u8LangModeMapping[i][0] == eLangName) { eModeID = u8LangModeMapping[i][1]; break; } } printf("\n\ni = %d, u32tablesize is %d\n\n",i, u32tablesize); if (i < u32tablesize) { if (g_LangModeIndex > UMFMOD_ATV && g_LangModeIndex < UMFMOD_MAX && g_LangModeIndex != eModeID) { umf_unloadModule(g_LangModeIndex); } g_LangModeIndex = eModeID; umf_loadModule(eModeID); } g_AllLangIsMemory = FALSE; return 0; } #endif #if (defined CONFIG_MOD_PACK_TT) || (defined CONFIG_MOD_PACK_SUB) Boolean TTOrSubModLoad(Boolean MMapInit) { Boolean LoadFlag = TRUE; if (MMap_CheckInit() == TRUE) { printf("\n====[%s, %d]===TT/SUB module has been loaded and mmap~~\n",__FUNCTION__,__LINE__); LoadFlag = FALSE; return LoadFlag; } #ifdef CONFIG_MOD_PACK_TT if (umf_checkModuleLoaded(UMFMOD_TT) == 0) { if (umf_loadModule(UMFMOD_TT) != 0) { printf("\n====[%s, %d]===load TT module fail~~\n",__FUNCTION__,__LINE__); LoadFlag = FALSE; } } #endif #ifdef CONFIG_MOD_PACK_SUB if (umf_checkModuleLoaded(UMFMOD_SUB) == 0) { if (umf_loadModule(UMFMOD_SUB) != 0) { printf("\n====[%s, %d]===load SUB module fail~~\n",__FUNCTION__,__LINE__); LoadFlag = FALSE; } } #endif if (LoadFlag == TRUE) { #ifdef CONFIG_MOD_PACK_SUB MID_Subtitle_constructor(); #endif if (MMapInit == TRUE) { if (MMap_Init() != 0) { LoadFlag = FALSE; printf("\n====[%s, %d]===mmap fail~~\n",__FUNCTION__,__LINE__); } } } return LoadFlag; } Boolean TTOrSubModUnload(void) { Boolean UnloadFlag = TRUE; #ifdef CONFIG_MOD_PACK_TT if (umf_checkModuleLoaded(UMFMOD_TT) == 1) { if (umf_unloadModule(UMFMOD_TT) != 0) { printf("\n====[%s, %d]===unload TT module fail~~\n",__FUNCTION__,__LINE__); UnloadFlag = FALSE; } } #endif #ifdef CONFIG_MOD_PACK_SUB if (umf_checkModuleLoaded(UMFMOD_SUB) == 1) { MID_Subtitle_destructor(); if (umf_unloadModule(UMFMOD_SUB) != 0) { printf("\n====[%s, %d]===unload SUB module fail~~\n",__FUNCTION__,__LINE__); UnloadFlag = FALSE; } } #endif if (UnloadFlag == TRUE) { MMap_Uninit(); } return UnloadFlag; } #endif #endif