⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dvb_eit.c

📁 DVB软件,基于CT216软件的开发源程序.
💻 C
📖 第 1 页 / 共 5 页
字号:
#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 + -