📄 dvb_eit.c
字号:
#include <stdio.h>
#include <string.h>
#include "ct_os.h"
#include "ct_demux.h"
#include "ct_filter.h"
#include "task_cfg.h"
#include "dvb_type.h"
#include "dvb_msg.h"
#include "dvb_filt.h"
#include "dvb_sys.h"
#include "dvb_fp.h"
#include "db_defs.h"
#include "db_eit.h"
#include "ap_si.h"
#define EIT_MSG(p) printf p
//#define EIT_DBG(p) printf p
#define EIT_DBG(p)
#define DEBUG_SEHEDULE 0
#define EIT_MONITOR_TASK_ENABLE
#define EIT_HEADER_BUFFER_START_ADDR ((u32)(pu8EitHedaderBufferStartPtr))
#define EIT_EVENT_BUFFER_START_ADDR ((u32)(pi8EitEventBufferStartPtr))
#define EIT_MAX_HEADER_NUM (MAX_NUM_OF_SRV)
//#define EIT_MAX_EVENT_NUM (2400)
#if (defined(CT216S) || defined (CT216H))
//fixed "EIT_MAX_EVENT_NUM", Event number = 3000 --> 800,
//aviod the EPG/TTX module memory allocate fail at ct216s v3.0(SDRAM = 64Mb)
#define EIT_MAX_EVENT_NUM (800)
#else //#if (defined(CT216S) | defined(CT216T))
#define EIT_MAX_EVENT_NUM (3000)
#endif //#if (defined(CT216S) | defined(CT216T))
#define BK_ENABLE
#define EIT_SECTION_INFO_NUM (5) // hard code 5
#define DAY_SECOND_OFFSET 86400
#define EIT_SEGMENT_SECONDE_OFFSET (3 * 60 * 60)
extern u32 freep; /* debug used */
#define NOT_FREE_EVENT_EXIT_EPG
/*
#if defined(SDRAM_32M)
#define EIT_MAX_EVENT_NUM 304
#define EIT_MAX_HEADER_NUM 128
#elif defined(SDRAM_64M)
#define EIT_MAX_EVENT_NUM 6144
#define EIT_MAX_HEADER_NUM 1024 // this value should be equal to MAX_NUM_OF_PGMLIST
#else
#define EIT_MAX_EVENT_NUM 6144
#define EIT_MAX_HEADER_NUM 1024 // this value should be equal to MAX_NUM_OF_PGMLIST
#endif
*/
/*#define EIT_HEADER_LENGTH (sizeof(ST_EIT_HEADER_T)/4) //DWORD
#define EIT_DB_LENGTH (sizeof(ST_EIT_DB)/4) //DWORD
#define EIT_EVENT_LENGTH (sizeof(ST_EIT_EVENT)/4) //DWORD*/
#define EIT_HEADER_LENGTH (sizeof(ST_EIT_HEADER_T)) //Byte
#define EIT_DB_LENGTH (sizeof(ST_EIT_DB)) //Byte
#define EIT_EVENT_LENGTH (sizeof(ST_EIT_EVENT)) //Byte
#define MAX_NUM_IN_A_GROUP 8
#define MAX_EVENT_FLAG (EIT_MAX_EVENT_NUM/MAX_NUM_IN_A_GROUP)
#define MAX_HEADER_FLAG (EIT_MAX_HEADER_NUM/MAX_NUM_IN_A_GROUP)
#ifndef INVALID_VERSION
#define INVALID_VERSION 0xFF
#endif
#define EITPF_TABLE_TIMEOUT 10000
#define EITS_TABLE_TIMEOUT 30000
#define EIT_TABLE_TIMEOUT 30000
#define EIT_BK_TABLE_TIMEOUT 5000
#define EIT_PF_SECTION_SIZE SECTION_1K //1K
#define EIT_S_SECTION_SIZE SECTION_4K //4K
#define EIT_SECTION_SIZE SECTION_4K //4K
#define EIT_PF_TABLEID 0x4E
#define EIT_S1_TABLEID 0x50
#define EIT_S2_TABLEID 0x51
#define DVB_EIT_WAIT_10_MS (10/CTOS_MS_PER_TICKS) // 1 tick = 10 ms
#define DVB_EIT_WAIT_100_MS (100/CTOS_MS_PER_TICKS) // 1 tick = 10 ms
#define DVB_EIT_WAIT_1000_MS (1000/CTOS_MS_PER_TICKS) // 1 tick = 10 ms
#define EIT_DB_TESTING
#define EITBK_WAIT_TIME (60* 1000) /* 1 seconds, in terms of millseconds ,
the waiting time to get the p/f or s1 or s2 */
#define MAX_NUM_SECTION_GROUP (256 / 8)
typedef struct
{
u8 u8FilterId;
EN_SERVICE_TYPE enSrvType;
u16 u16OrgNID; /* original network ID */
u16 u16TPID; /* transport stream ID */
u16 u16SrvID; /* service ID, program No */
u16 u16SrvIdx;
u8 u8PF_Ver;
u8 u8S1_Ver;
u8 u8S2_Ver;
u8 u8CurSection; /* only for schedule EIT */
u8 u8StartSection; /* only for schedule EIT */
u8 u8FinialSection; /* only for schedule EIT */
u32 u32EndTimeSec;
u8 *pu8SecBuffer;
u8 *pu8EventBuffer;
u8 au8NonGetSection_S1[MAX_NUM_SECTION_GROUP]; //The unit is bit. 0:We havn't gotten this section. 1:We already have or don't need this section.
u8 au8NonGetSection_S2[MAX_NUM_SECTION_GROUP]; //The unit is bit. 0:We havn't gotten this section. 1:We already have or don't need this section.
u8 u8PF_Flag; //bit1: present, bit2:following
}ST_SECTION_INFO_T;
#define S2_FLAG_FOR_ALL_SEV
u16 au16S2EventDbIdx [MAX_NUM_OF_SRV];
u32 au32S2StartTime [MAX_NUM_OF_SRV];
#define EIT_MAX_SAME_TP_SERVICE_NUM 64
typedef struct
{
u16 au16SrvIdx[EIT_MAX_SAME_TP_SERVICE_NUM];
#ifndef S2_FLAG_FOR_ALL_SEV
u16 au16S2EventDbIdx [EIT_MAX_SAME_TP_SERVICE_NUM];
u32 au32S2StartTime [EIT_MAX_SAME_TP_SERVICE_NUM];
#endif /* end #ifndef S2_FLAG_FOR_ALL_SEV */
EN_RETRIEVE_EVENT_TYPE enEventType;
u8 u8Num;
u8 u8CurIdx; /* range 0 ~ u8NUm-1 */
}ST_TP_SERVICE_T;
typedef enum
{
EN_CHECK_FLAG,
EN_SET_FLAG,
EN_CLEAR_FLAG
}EN_FLAG_ACTION;
typedef enum
{
EN_EIT_HEADER_FLAG,
EN_EIT_EVENT_FLAG
}EN_FLAG_EDITOR;
/******************************************************************************************/
u8* pu8EitHedaderBufferStartPtr = NULL;
u8* pi8EitEventBufferStartPtr = NULL;
bool8 b8EitBuffInit = FALSE;
CTOS_TASK stDVBEITGetTask, stDVBEITSetTask;
#ifdef EIT_MONITOR_TASK_ENABLE
u8 u8DVBEITGetTaskStack [DVB_EIT_GET_TASK_STACK_SIZE];
#endif
u8 u8DVBEITSetTaskStack [DVB_EIT_SET_TASK_STACK_SIZE];
//static ST_SECTION_INFO_T stSecInfo;
static ST_SECTION_INFO_T astSecInfo[EIT_SECTION_INFO_NUM];
static ST_TP_SERVICE_T stTPService;
static bool8 b8InitEitDb = FALSE;
//static DVB_ServiceInfo stTmpSrvInfo;
static u8 au8EventFlag[MAX_EVENT_FLAG];
static u8 au8HeaderFlag[MAX_HEADER_FLAG];
const u8 au8FlagMask[MAX_NUM_IN_A_GROUP] = {1, 1<<1, 1<<2, 1<<3, 1<<4, 1<<5, 1<<6, 1<<7};
static u16 _u16DbEitHeaderIdx;
static CTOS_SEMAPHORE EITCB_Sem;
static CTOS_SEMAPHORE EITAccess_Sem;
static CTOS_SEMAPHORE EITSetSection_Sem;
static bool8 b8EITInitialied = FALSE;
static u8 au8AvailableSection[MAX_FILTER_NUMBER];
static u8 u8InEPGMode = 0; /* to check is normal mode or epg mode */
/******************************************************************************************/
void dump_eit_event_header(u16 u16SrvIdx);
void dump_eit_event_db(u16 u16SrvIdx);
#ifdef EIT_DB_TESTING
void TestFillEventName(u8 *pu8String);
void TestFillEvent(/*u16 u16SrvIdx,*/ u8 u8SecVer, u8 u8PF_S_Flag, u16 u16StartTime);
void TestFillEvent2Db(void);
#endif
static EN_EITDB_STATUS DVB_EitSetEvent(ST_SECTION_INFO_T *pstSecInfo, EN_SERVICE_TYPE enSrvType, u16 u16SrvIdx, u8 u8SecVer, u8 u8PF_S_Flag, ST_EIT_EVENT *pstEventInfo);
static void ParseEitSectionPF(ST_SECTION_INFO_T *pstSecInfo);
static void ParseEitSectionS(ST_SECTION_INFO_T *pstSecInfo);
static void EitSectionCallback(u8 u8FID, EN_FILTER_STATUS enStatus);
static EN_EITDB_STATUS EitSectionProcess (u8 u8FID, EN_FILTER_STATUS enStatus);
static EN_EITDB_STATUS GetEitDbFirst16Bytes(u16 u16DbIdx, ST_EIT_DB *pstDb);
static bool8 dvb_EitDelEvent4DbFull(u16 u16CurHeadEventIdx, EN_FLAG_EDITOR enEditor);
static EN_EITDB_STATUS dvb_EitSetS_Event(ST_SECTION_INFO_T *pstSecInfo, ST_EIT_HEADER_T *pstEitHeader, u8 u8SecVer, ST_EIT_EVENT *pstEventInfo, bool8 b8ExistExtended);
static bool8 FindInsertLocation(u16 u16StartIdx, u16 *pu16TargetPreIdx, u16 *pu16TargetNextIdx, ST_EIT_EVENT *pstEventInfo);
static bool8 CheckValidEventTime(ST_EIT_EVENT *pstEventInfo);
static EN_EITDB_STATUS dvb_EitDelAll_S_Event(ST_EIT_HEADER_T *pstEitHeader);
static EN_EITDB_STATUS dvb_CreateF_Event(ST_EIT_HEADER_T *pstEitHeader, ST_EIT_EVENT *pstEventInfo);
static EN_EITDB_STATUS dvb_EitSetF_Event(ST_EIT_HEADER_T *pstEitHeader, u8 u8SecVer, ST_EIT_EVENT *pstEventInfo, bool8 b8ExistExtended);
static EN_EITDB_STATUS dvb_EitSetP_Event(ST_EIT_HEADER_T *pstEitHeader, u8 u8SecVer, ST_EIT_EVENT *pstEventInfo, bool8 b8ExistExtended);
static EN_EITDB_STATUS dvb_EitDelOneEvent(ST_EIT_HEADER_T *pstEitHeader, u16 u16EventIdx);
static EN_EITDB_STATUS dvb_CreateP_Event(ST_EIT_HEADER_T *pstEitHeader, ST_EIT_EVENT *pstEventInfo);
static bool8 SaveHeader2Dram(u16 u16HeadIdx, ST_EIT_HEADER_T *pstHeader);
static bool8 SearchEmptySpace(EN_FLAG_EDITOR enEditor, u16 *pu16RetIdx);
static EN_EITDB_STATUS dvb_EitCreateHeader(EN_SERVICE_TYPE enSrvType, u16 u16SrvIdx, ST_EIT_HEADER_T *pstHeader, u16 *pu16RetHeadIdx);
static EN_EITDB_STATUS dvb_EitGetHeaderInfo(EN_SERVICE_TYPE enSrvType, u16 u16SrvIdx, ST_EIT_HEADER_T *pstHeader, u16 *pu16RetHeadIdx);
static EN_EITDB_STATUS dvb_EitGetDbByIdx(u16 u16DbIdx, ST_EIT_DB *pstDb);
static bool8 EditDbFlag(u16 u16HeaderNo, EN_FLAG_EDITOR enEditor, EN_FLAG_ACTION enAction);
static bool8 dvb_EitDelLastEventByHead(ST_EIT_HEADER_T *pstEitHeader, u16 *pu16BeDelEventIdx);
static EN_EITDB_STATUS dvb_EitSaveDbByIdx(u16 u16DbIdx, ST_EIT_DB *pstDb);
bool8 EITBKAPStop (void);
/******************************************************************************************/
void PntSectionInfo (u8 flag, u8 u8idx)
{
ST_SECTION_INFO_T stSecInfo;
if (u8idx >= EIT_SECTION_INFO_NUM)
return;
stSecInfo = astSecInfo[u8idx];
EIT_DBG(("**[%d] {PntSectionInfo} type[%d] idx[%d] ID[0x%x] FID[0x%x] secbuf[0x%x] eventb[0x%x]\n",
flag,
stSecInfo.enSrvType,
stSecInfo.u16SrvIdx,
stSecInfo.u16SrvID,
stSecInfo.u8FilterId,
(int) stSecInfo.pu8SecBuffer,
(int) stSecInfo.pu8EventBuffer));
}
/* get section info structre by filter id */
u8 eitbksectionInfogetbyfltid (u8 u8FID)
{
u8 u8Idx;
ST_SECTION_INFO_T stSecInfo;
for (u8Idx = 0; u8Idx < EIT_SECTION_INFO_NUM; u8Idx++)
{
stSecInfo = astSecInfo[u8Idx];
//EIT_DBG( ("{eitbksectionInfogetbyfltid}[%d] [0x%x]-[0x%x]\n", u8Idx, stSecInfo.u8FilterId, u8FID));
if ((stSecInfo.u8FilterId == u8FID) && (stSecInfo.u8FilterId != INVALID_FILTER_ID))
{
return u8Idx;
}
}
EIT_DBG (("{EITBKSecInfGetByFltID} u8FID[%d] u8Idx[%d]\n", u8FID, u8Idx));
return u8Idx; /* EIT_SECTION_INFO_NUM */
}
u8 eitbksectionInfgetbysrvidx (EN_SERVICE_TYPE enSrvType, u16 u16SrvIdx)
{
u8 u8Idx;
ST_SECTION_INFO_T stSecInfo;
for (u8Idx = 0; u8Idx < EIT_SECTION_INFO_NUM; u8Idx++)
{
stSecInfo = astSecInfo[u8Idx];
if ((stSecInfo.enSrvType == enSrvType) && (stSecInfo.u16SrvIdx == u16SrvIdx))
{
EIT_DBG (("{eitbksectionInfgetbysrvidx}00 u8Idx[%d]\n", u8Idx));
return u8Idx;
}
}
EIT_DBG (("{eitbksectionInfgetbysrvidx}11 u8Idx[%d]\n", u8Idx));
return u8Idx; /* EIT_SECTION_INFO_NUM */
}
static u8 grouptpservice (EN_SERVICE_TYPE enSrvType, u16 u16SrvIdx, u16 *array, u8 u8MaxNum)
{
u16 i = 0;
u8 u8Idx = 0;
u16 u16SrvNumber = 0;
DVB_ServiceInfo stTempServiceInfo;
u16 u8TransponderIndex = 0;
u16SrvNumber = DVB_ServiceGetTotal(enSrvType);
if (DVB_ServiceRead (enSrvType, u16SrvIdx, &stTempServiceInfo) == FALSE)
{
return u8Idx;
}
u8TransponderIndex = stTempServiceInfo.u8TransponderIndex;
u8Idx = 0;
for (i = 0; i < u16SrvNumber; i++)
{
if (DVB_ServiceRead (enSrvType, i, &stTempServiceInfo) == FALSE)
{
continue;
}
if (stTempServiceInfo.u8TransponderIndex == u8TransponderIndex)
{
#if 0
if (u8InEPGMode == 1)
{
if (i == u16SrvIdx)
{
EIT_DBG (("BKEIT same[%d] [0x%x] [0x%x]\n", u8Idx - 1, i, DVB_GetSrvIDByDbIdx (enSrvType, i)));
continue;
}
}
#endif
u8Idx ++;
if (u8Idx <= u8MaxNum)
{
array[u8Idx - 1] = i;
EIT_DBG (("BKEIT [%d] [0x%x] [0x%x]\n", u8Idx - 1, i, DVB_GetSrvIDByDbIdx (enSrvType, i)));
}
else
{
return (u8Idx--);
}
}
}
//EIT_DBG (("{grouptpservice} %d [0x%x][0x%x][0x%x][0x%x][0x%x][0x%x][0x%x][0x%x][0x%x][0x%x]\n",
//u8Idx, array[0], array[1], array[2], array[3], array[4], array[5], array[6], array[7], array[8], array[9]));
return u8Idx;
}
static EN_SERVICE_TYPE enSrvTypePrev = 0;
static u16 u8TransponderIndexPrev = 0xFFFF;
/* TRUE : switch TP */
bool8 checktpswitch (EN_SERVICE_TYPE enSrvType, u16 u16SrvIdx)
{
DVB_ServiceInfo stTempServiceInfo;
if (DVB_ServiceRead (enSrvType, u16SrvIdx, &stTempServiceInfo) == FALSE)
{
return FALSE;
}
if ((enSrvTypePrev != enSrvType) || (u8TransponderIndexPrev == 0xFFFF))
{
EIT_DBG (("enSrvTypePrev[%d][%d] u8TransponderIndexPrev[%d]\n",
enSrvTypePrev, enSrvType, u8TransponderIndexPrev));
/* record the cur to pre flag */
enSrvTypePrev = enSrvType;
u8TransponderIndexPrev = stTempServiceInfo.u8TransponderIndex;
EIT_DBG (("set 11 u8TransponderIndexPrev[%d]\n", u8TransponderIndexPrev));
return TRUE;
}
if (u8TransponderIndexPrev != stTempServiceInfo.u8TransponderIndex)
{
u8TransponderIndexPrev = stTempServiceInfo.u8TransponderIndex;
EIT_DBG (("set 22 u8TransponderIndexPrev[%d]\n", u8TransponderIndexPrev));
return TRUE;
}
return FALSE;
}
bool8 eitbkfreesectioninfo (ST_SECTION_INFO_T *pstSecInfo)
{
if (!pstSecInfo)
return FALSE;
EIT_DBG ((" ##### eitbkfreesectioninfo\n"));
DVB_FilterClose (pstSecInfo->u8FilterId);
au8AvailableSection[pstSecInfo->u8FilterId] = 0;
if (pstSecInfo->pu8SecBuffer)
{
freep = 50;
DVB_MemoryFree((u8*)pstSecInfo->pu8SecBuffer);
}
if (pstSecInfo->pu8EventBuffer)
{
freep = 51;
DVB_MemoryFree((u8*)pstSecInfo->pu8EventBuffer);
}
pstSecInfo->pu8SecBuffer = NULL;
pstSecInfo->pu8EventBuffer = NULL;
EIT_DBG (("free secion set to INVALID_FILTER_ID org[0x%x]\n",pstSecInfo->u8FilterId));
pstSecInfo->u8FilterId = INVALID_FILTER_ID;
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 */
return TRUE;
}
bool8 eitbkresetsectionInfo (ST_SECTION_INFO_T *pstSecInfo)
{
if (!pstSecInfo)
return FALSE;
EIT_DBG ((" ######### eitbkresetsectionInfo start \n"));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -