📄 dvb_eit.c
字号:
{
return FALSE;
}
gen_point = 127;
pi8EitEventBufferStartPtr = (u8*)DVB_MemoryAllocate((EIT_MAX_EVENT_NUM*EIT_DB_LENGTH));
if (pi8EitEventBufferStartPtr == NULL)
{
DVB_MemoryFree((u8*)pu8EitHedaderBufferStartPtr);
pu8EitHedaderBufferStartPtr = NULL;
return FALSE;
}
//EIT_DBG(("\n>> pu8EitHedaderBufferStartPtr = %p\n",pu8EitHedaderBufferStartPtr));
//EIT_DBG(("\n>> pi8EitEventBufferStartPtr = %p\n",pi8EitEventBufferStartPtr));
b8EitBuffInit = TRUE;
return TRUE;
}
/******************************************************************************************/
void DVB_EitDbInit(void)
{
u16 u16SrvIdx;
u16 u16TmpSrvNum;
u8 u8Idx;
EN_SERVICE_TYPE enSrvType;
ST_SECTION_INFO_T* pstSecInfo;
if (b8EITInitialied == TRUE)
return;
EIT_DBG(("%s,%d> EIT init start\n", __FFLL__));
if (DVB_EitDbInitMemory() != TRUE)
{
EIT_DBG(("\n>> EIT : DVB_EitDbInitMemory() Fail\n"));
return ;
}
for(u8Idx=0;u8Idx<2;u8Idx++)
{
if(u8Idx==0)
enSrvType = EN_SERVICE_TYPE_TV;
else
enSrvType = EN_SERVICE_TYPE_RADIO;
u16TmpSrvNum = DVB_ServiceGetTotal(enSrvType);
//init u16EitHeaderIdx in service database
for(u16SrvIdx=0;u16SrvIdx<u16TmpSrvNum;u16SrvIdx++)
{
/*DVB_ServiceRead(enSrvType, u16SrvIdx, &stTmpSrvInfo);
stTmpSrvInfo.u16EitHeaderIdx = INVALID_LINK_IDX;
SetItemOfPgmListInDram(enSrvType, u16SrvIdx, &stTmpSrvInfo);*/
_u16DbEitHeaderIdx = INVALID_LINK_IDX;
DVB_DBSetEitHeader(enSrvType, u16SrvIdx, _u16DbEitHeaderIdx);
}
}
//init flag
memset(au8EventFlag, 0, sizeof(au8EventFlag));
memset(au8HeaderFlag, 0, sizeof(au8HeaderFlag));
//init section info
memset(&(astSecInfo[0]), 0, sizeof(astSecInfo));
for (u8Idx=0; u8Idx<EIT_SECTION_INFO_NUM; u8Idx++)
{
pstSecInfo = &(astSecInfo[u8Idx]);
EIT_DBG (("eitdbinit set to invalid_filter_id\n"));
pstSecInfo->u8FilterId = INVALID_FILTER_ID;
pstSecInfo->pu8SecBuffer = NULL;
pstSecInfo->pu8EventBuffer = NULL;
pstSecInfo->u8PF_Ver = INVALID_VERSION;
pstSecInfo->u8S1_Ver = INVALID_VERSION;
pstSecInfo->u8S2_Ver = INVALID_VERSION;
pstSecInfo->u16SrvIdx = 0xFFFF; // this should be a invalid value
pstSecInfo->u16OrgNID = 0xFFFF; /* original network ID */
pstSecInfo->u16TPID = 0xFFFF; /* transport stream ID */
}
/* reset TP service stTPService */
memset (&stTPService, 0x00, sizeof (stTPService));
stTPService.enEventType = EN_RETRIEVE_EVENT_STOP;
#ifdef BK_ENABLE
if (CT_OS_ResumeTask (&stDVBEITSetTask) != EN_CTOS_SUCCESS)
{
return;
}
#endif
b8InitEitDb = TRUE;
EIT_DBG(("%s,%d> EIT init finish\n", __FFLL__));
#if defined(SDRAM_32M)
EIT_DBG(("%s,%d> EIT using SDRAM_32M\n", __FFLL__));
#else
EIT_DBG(("%s,%d> EIT using SDRAM_64M\n", __FFLL__));
#endif
}
/******************************************************************************************/
EN_EITDB_STATUS DVB_EitGetPF_Event(EN_SERVICE_TYPE enSrvType, u16 u16SrvIdx, u8 u8PF_Flag, u16 *pu16RetIdx, ST_EIT_EVENT *pstEventInfo)
{
u8 u8Idx, u8OffsetIdx = 0;
u16 u16EventIdx, u16EitHeaderIdx;
EN_EITDB_STATUS enRetError;
ST_EIT_HEADER_T stTmpEitHeader;
ST_EIT_DB stTmpEitDb;
//u8PF_Flag just can has PRESENT_MASK or FOLLOWING_MASK at the same time.
if((u8PF_Flag != PRESENT_MASK) && (u8PF_Flag != FOLLOWING_MASK))
return EN_EITDB_WRONG_PARAMETER;
if (!pstEventInfo)
return EN_EITDB_WRONG_PARAMETER;
*pu16RetIdx = INVALID_LINK_IDX;
CT_OS_WaitOnSemaphore (&EITAccess_Sem, CTOS_WAIT);
enRetError = dvb_EitGetHeaderInfo(enSrvType, u16SrvIdx, &stTmpEitHeader, &u16EitHeaderIdx);
if(enRetError != EN_EITDB_NO_ERROR)
{
CT_OS_FreeSemaphore (&EITAccess_Sem);
return enRetError;
}
/*
//this service dosen't have the event that caller want
if(((stTmpEitHeader.u8PF_S_Flag & PRESENT_MASK) != u8PF_Flag) &&
((stTmpEitHeader.u8PF_S_Flag & FOLLOWING_MASK) != u8PF_Flag))
return EN_EITDB_HEADER_OR_EVENT_NOT_EXIST;
if((stTmpEitHeader.u8PF_S_Flag & PRESENT_MASK) != 0)
u8OffsetIdx++;
if((stTmpEitHeader.u8PF_S_Flag & FOLLOWING_MASK) != 0)
u8OffsetIdx++;
//mean this service just has schedule events
if(u8OffsetIdx == 0)
return EN_EITDB_HEADER_OR_EVENT_NOT_EXIST;
*/
if((stTmpEitHeader.u8PF_S_Flag & PRESENT_MASK) == u8PF_Flag)
u8OffsetIdx = 0;
else if((stTmpEitHeader.u8PF_S_Flag & FOLLOWING_MASK) == u8PF_Flag)
{
if((stTmpEitHeader.u8PF_S_Flag & PRESENT_MASK) != 0)
u8OffsetIdx = 1;
else
u8OffsetIdx = 0;
}
else
{
// Todo: DVB_EitDbRetrievePF_Event
CT_OS_FreeSemaphore (&EITAccess_Sem);
return EN_EITDB_EVENT_NOT_EXIST;
}
u8Idx = 0;
u16EventIdx = stTmpEitHeader.u16HeadEventIdx;
while(1)
{
enRetError = dvb_EitGetDbByIdx(u16EventIdx, &stTmpEitDb);
if(enRetError != EN_EITDB_NO_ERROR)
{
CT_OS_FreeSemaphore (&EITAccess_Sem);
return enRetError;
}
u8Idx++;
if(u8Idx > u8OffsetIdx)
break;
u16EventIdx = stTmpEitDb.u16NextEventIdx;
if(u16EventIdx == INVALID_LINK_IDX)
{
// Todo: DVB_EitDbRetrievePF_Event
CT_OS_FreeSemaphore (&EITAccess_Sem);
return EN_EITDB_EVENT_NOT_EXIST;
}
}
// Todo: This needs to compare the event time for updating event
*pu16RetIdx = u16EventIdx;
memcpy(pstEventInfo, &(stTmpEitDb.stEitEvent), sizeof(ST_EIT_EVENT));
CT_OS_FreeSemaphore (&EITAccess_Sem);
return EN_EITDB_NO_ERROR;
}
/******************************************************************************************/
EN_EITDB_STATUS DVB_EitGetPF_Event_Pseudo(EN_SERVICE_TYPE enSrvType, u16 u16SrvIdx, u8 u8PF_Flag, u16 *pu16RetIdx, ST_EIT_EVENT *pstEventInfo)
{
u16 u16EvenNum;
ST_DVB_TIME stEitTime;
u32 u32EitStartTime;
u32 u32EitEndTime;
u16 u16TempRetIdx;
if((u8PF_Flag != PRESENT_MASK) && (u8PF_Flag != FOLLOWING_MASK))
return EN_EITDB_WRONG_PARAMETER;
if (!pstEventInfo)
return EN_EITDB_WRONG_PARAMETER;
*pu16RetIdx = INVALID_LINK_IDX;
if(EN_EITDB_NO_ERROR==DVB_EitGetPF_Event(enSrvType,u16SrvIdx,u8PF_Flag,pu16RetIdx,pstEventInfo))
{
//EIT_DBG(("\n>>>get real PF info!\n"));
return EN_EITDB_NO_ERROR;
}
else
{
//get first schedules as pf info
if(DVB_LocalTimeGet(&stEitTime)==FALSE)
{
/// EIT_DBG(("\n>>>Eit get local time fail!\n"));
return EN_EITDB_ERROR;
}
else
{
u32EitStartTime = DVB_Mktime(stEitTime);
u32EitEndTime = ((u32EitStartTime/DAY_SECOND_OFFSET)+1)*DAY_SECOND_OFFSET - 1;
u32EitStartTime -= DVB_LocalTimeOffsetGet();
u32EitEndTime -= DVB_LocalTimeOffsetGet();
}
if(u8PF_Flag==PRESENT_MASK)
{
if(EN_EITDB_NO_ERROR==DVB_EitGetS_FirstEvent(enSrvType,u16SrvIdx,u32EitStartTime,u32EitEndTime,pu16RetIdx,&u16EvenNum,pstEventInfo))
{
//EIT_DBG(("\n>>>get first scheduel succeed! u32StartTime %d u32Duration %d u32EitStartTime %d\n",pstEventInfo->u32StartTime,pstEventInfo->u32Duration,u32EitStartTime));
if((pstEventInfo->u32StartTime +pstEventInfo->u32Duration-u32EitStartTime)>pstEventInfo->u32Duration)
return EN_EITDB_ERROR;
else
return EN_EITDB_NO_ERROR;
}
else
{
//EIT_DBG(("\n>>>get first schdeule fail!\n"));
return EN_EITDB_EVENT_NOT_EXIST;
}
}
if(u8PF_Flag==FOLLOWING_MASK)
{
if(EN_EITDB_NO_ERROR==DVB_EitGetS_FirstEvent(enSrvType,u16SrvIdx,u32EitStartTime,u32EitEndTime,&u16TempRetIdx,&u16EvenNum,pstEventInfo))
{
if((pstEventInfo->u32StartTime +pstEventInfo->u32Duration-u32EitStartTime)>pstEventInfo->u32Duration)
return EN_EITDB_ERROR;
else
{
if(EN_EITDB_NO_ERROR==DVB_EitGetS_NextEvent(u16TempRetIdx,pu16RetIdx,pstEventInfo))
{
// EIT_DBG(("\n>>>get second scheduel succeed!\n"));
return EN_EITDB_NO_ERROR;
}
else
{
// EIT_DBG(("\n>>>get second schdeule fail!\n"));
return EN_EITDB_EVENT_NOT_EXIST;
}
}
}
else
{
// EIT_DBG(("\n>>>get first schdeule fail,can not get second schedule!\n"));
return EN_EITDB_EVENT_NOT_EXIST;
}
}
}
return EN_EITDB_NO_ERROR;
}
/******************************************************************************************/
EN_EITDB_STATUS DVB_EitGetHeaderInfoBySrvIdx(EN_SERVICE_TYPE enSrvType, u16 u16SrvIdx, ST_EIT_HEADER_T *pstEitHeader)
{
u16 u16EitHeaderIdx;
return dvb_EitGetHeaderInfo(enSrvType, u16SrvIdx, pstEitHeader, &u16EitHeaderIdx);
}
/******************************************************************************************/
// delete this event of u16EventIdx
static EN_EITDB_STATUS dvb_EitDelOneEvent(ST_EIT_HEADER_T *pstEitHeader, u16 u16EventIdx)
{
u16 u16KeepPreIdx, u16KeepNextIdx;
ST_EIT_DB stDelEitDb;
EN_EITDB_STATUS enRetError;
if (!pstEitHeader)
{
return EN_EITDB_ERROR;
}
// check this event existing or not
if(EditDbFlag(u16EventIdx, EN_EIT_EVENT_FLAG, EN_CHECK_FLAG)==FALSE)
{
return EN_EITDB_EVENT_NOT_EXIST;
}
//EIT_DBG( (">>>>>> dvb_EitDelOneEvent\n"));
//dvb_EitGetDbByIdx(u16EventIdx, &stDelEitDb);
enRetError = dvb_EitGetDbByIdx(u16EventIdx, &stDelEitDb);
if (GetEitDbFirst16Bytes(u16EventIdx, &stDelEitDb) != EN_EITDB_NO_ERROR)
{
return EN_EITDB_ERROR;
}
u16KeepPreIdx = stDelEitDb.u16PreEventIdx;
u16KeepNextIdx = stDelEitDb.u16NextEventIdx;
//clear event flag, means the space is free now.
EditDbFlag(u16EventIdx, EN_EIT_EVENT_FLAG, EN_CLEAR_FLAG);
//NextEvent->previous = CurrentEvent->previous.
if(u16KeepNextIdx != INVALID_LINK_IDX)
{
if (dvb_EitGetDbByIdx(u16KeepNextIdx, &stDelEitDb) != EN_EITDB_NO_ERROR)
{
return EN_EITDB_ERROR;
}
stDelEitDb.u16PreEventIdx = u16KeepPreIdx;
dvb_EitSaveDbByIdx(u16KeepNextIdx, &stDelEitDb);
}
if(u16KeepPreIdx == INVALID_LINK_IDX) //This is the first event in the pstEitHeader.
{
// Header->HeadEventIdx = CurrentEvent->next.
pstEitHeader->u16HeadEventIdx = u16KeepNextIdx;
//don't need to save header here, it will be saved by caller.
}
else
{
// PreviousEvent->next = CurrentEvent->next.
if (dvb_EitGetDbByIdx(u16KeepPreIdx, &stDelEitDb) != EN_EITDB_NO_ERROR)
{
return EN_EITDB_ERROR;
}
stDelEitDb.u16NextEventIdx = u16KeepNextIdx;
dvb_EitSaveDbByIdx(u16KeepPreIdx, &stDelEitDb);
}
return EN_EITDB_NO_ERROR;
}
/******************************************************************************************/
// event will be save to dram here
static EN_EITDB_STATUS dvb_CreateP_Event(ST_EIT_HEADER_T *pstEitHeader, ST_EIT_EVENT *pstEventInfo)
{
u16 u16RetEventIdx;
u16 u16CurIdx;
ST_EIT_DB stTmpEitDb;
if (!pstEitHeader || !pstEventInfo)
return EN_EITDB_ERROR;
if(SearchEmptySpace(EN_EIT_EVENT_FLAG, &u16RetEventIdx) == FALSE)
{
// Todo: del expired or some events to acquire empty event
EIT_DBG(("%s,%d> Memory full when create p event.\n", __FFLL__));
//event full, try to del event
if(dvb_EitDelEvent4DbFull(pstEitHeader->u16HeadEventIdx, EN_EIT_EVENT_FLAG) == FALSE) //clean database to acquire space
return EN_EITDB_MEMORY_FULL;
//search empty space again
if(SearchEmptySpace(EN_EIT_EVENT_FLAG, &u16RetEventIdx) == FALSE)
return EN_EITDB_MEMORY_FULL;
}
// H->?, stTmpEitDb = P
memcpy(&(stTmpEitDb.stEitEvent), pstEventInfo, sizeof(ST_EIT_EVENT));
//update header and db info, H->P->?
stTmpEitDb.u16NextEventIdx = pstEitHeader->u16HeadEventIdx;
pstEitHeader->u16HeadEventIdx = u16RetEventIdx;
stTmpEitDb.u16PreEventIdx = INVALID_LINK_IDX;
// save the p event to dram
dvb_EitSaveDbByIdx(u16RetEventIdx, &stTmpEitDb);
// if H->P->Next != NULL, update H->P->NEXT info
if(stTmpEitDb.u16NextEventIdx != INVALID_LINK_IDX)
{
// u16CurIdx is P->next
u16CurIdx = stTmpEitDb.u16NextEventIdx;
if (dvb_EitGetDbByIdx(u16CurIdx, &stTmpEitDb) != EN_EITDB_NO_ERROR)
{
return EN_EITDB_ERROR;
}
// set u16CurIdx->previous = p
stTmpEitDb.u16PreEventIdx = u16RetEventIdx;
// save u16CurIdx
dvb_EitSaveDbByIdx(u16CurIdx, &stTmpEitDb);
}
return EN_EITDB_NO_ERROR;
}
/******************************************************************************************/
// header will not be save to dram here
static EN_EITDB_STATUS dvb_EitSetP_Event(ST_EIT_HEADER_T *pstEitHeader, u8 u8SecVer, ST_EIT_EVENT *pstEventInfo, bool8 b8ExistExtended)
{
u8 u8ClearMask;
EN_EITDB_STATUS enRetError;
ST_EIT_DB stTmpEitDb;
if ((!pstEitHeader) || (!pstEventInfo))
{
EIT_DBG (("fail {dvb_EitSetP_Event}pstEitHeader[0x%x] pstEventInfo[0x%x]\n",
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -