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

📄 dvbepg.c

📁 MiniWinOuterSM MiniWinOuterSM
💻 C
📖 第 1 页 / 共 2 页
字号:
// Epg.cpp: implementation of the Epg class.
//
//////////////////////////////////////////////////////////////////////

#include "dvbepg.h"
#include "string.h"
#include "PrVideo.h"
#include "PrAudio.h"
#include "PrTuner.h"
#include"prmem.h"
#ifdef WIN32
#define PLAY_PRIORITY 120
#define SEARCH_PRIORITY 120
#else
#define PLAY_PRIORITY 220
#define SEARCH_PRIORITY 220
#endif
#define MAX_TS_SERVICE 40
#define USE_PSI_MONITOR 1
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
static PRThread schThread=NULL;
static PRThread playThread=NULL;
static PRMsgQ msgQEPG=NULL;
static PRMsgQ msgQPlay=NULL;
static PRPartition memPool;
static PRMutex epgMutex=NULL;
static UINT epgInited=0;
static void SearchProc(void*params);//EPG接收任务
static void PlayProc(void*params);//A/V播出任务

typedef struct{
	PRSem sem;
	UCHAR buf[4096];
}FILTERCONTEXT;
typedef struct{
	USHORT netid;
	USHORT tsid;
	USHORT serviceId;
	int version;
	PRMutex lock;
	SECTIONDB*secDB;
}SCHEDULE;
typedef struct{
	UINT msgID;
	UINT wParam;
	UINT lParam;
}EPGREQUEST;
static SECTIONDB*SchedulePF;
static PRMpgFilt fltEit;
static PRMpgFilt fltTDT;
static PRMpgFilt fltSDT;
static PRMpgFilt fltNIT;
static PRMpgFilt fltPAT;
static PRMpgFilt fltPMT;
static SERVICELOCATOR CurrentService;
static SCHEDULE Schedules[MAX_TS_SERVICE];
static SCHEDULE*GetScheduleSlot(USHORT netid,USHORT tsid,USHORT sid,int alloc);

extern BroadcastMessage(UINT,UINT,UINT);
extern SECTIONDATA*GetFirstNIT();
static int EITCMPPF(unsigned char*sec1,unsigned char*sec2)
{
	unsigned int id1,id2;
	unsigned short tsid1,tsid2,eid1,eid2;
	unsigned char sno1,sno2;
	tsid1=GetEitStreamID(sec1);tsid2=GetEitStreamID(sec2);
	eid1=GetEitServiceID(sec1);sno1=GetSectionNo(sec1);
	eid2=GetEitServiceID(sec2);sno2=GetSectionNo(sec2);
	//EIT不比较TableID
	if(tsid1!=tsid2)
		return tsid1-tsid2;
	id1=(eid1<<8)|sno1;
	id2=(eid2<<8)|sno2;
	return id1-id2;
}
static int EITCMPSCH(unsigned char*sec1,unsigned char*sec2)
{
	unsigned int id1,id2;
	id1=((UINT)GetTableID(sec1)<<24)|((UINT)GetEitServiceID(sec1)<<8)|GetSectionNo(sec1);
	id2=((UINT)GetTableID(sec2)<<24)|((UINT)GetEitServiceID(sec2)<<8)|GetSectionNo(sec2);
	//只比较sectionNo 和TableID就可以了.
	return id1-id2; 
}
static void EitCBK(PRMpgFilt filt, void *userData, UCHAR*section,UINT length)
{
	SERVICELOCATOR s;
	SCHEDULE*ch;
	UCHAR tableID=GetTableID(section);
	if((tableID<0x4E)||(tableID>0x6F)){
		TRACE("EIT TableID [%02X] Error\r\n",tableID);
		return ;
	}
	if(tableID<0x50){
	    s.netId=GetEitNetID(section);
	    s.tsId=GetEitStreamID(section);
	    s.serviceId=GetEitServiceID(section);
	    AddSection(SchedulePF,section);
	    if(SchedulePF->Count>512)
			TRACE("SchedulePF::Count=%d %d.%d.%d TBID=%X\r\n",SchedulePF->Count,
			s.netId,s.tsId,s.serviceId,tableID);
	    return ;
	}else{
	    static int cnt=0;
	    UCHAR sno=GetSectionNo(section);
	    s.netId=GetEitNetID(section);
	    s.tsId=GetEitStreamID(section);
	    s.serviceId=GetEitServiceID(section);
	    ch=GetScheduleSlot(s.netId,s.tsId,s.serviceId,((tableID&0x50)==0x50));
		if(ch){ 
			AddSection(ch->secDB,section);
			if((cnt++%200==0))
				TRACE("RECV EIT %d.%d.%d CNT=%d\r\n",s.netId,s.tsId,s.serviceId,ch->secDB->Count);
		}else if( (tableID&0x50)==0x50){
			int i;
			TRACE("Actural Service %d.%d.%d no Cahed!!!\r\n",s.netId,s.tsId,s.serviceId);
	    }
	}
}
static int GetTSFrequency(USHORT netId,USHORT tsId,PRTunerParams*tun)
{
	SECTIONDB*db=GetNetworkDB();
	SECTIONDATA*sec;
	int rc=0;
	//PrMutexLock(db->lock,-1);
	sec=db->sections;
	while(sec&&(rc==0)){
		int i,cnt=GetNitTSCount(sec->Data);
		for(i=0;i<cnt;i++){
			DVBStream stm;
			GetNitTSStream(sec->Data,&stm,i);
			if(stm.original_network_id==netId&&stm.transport_stream_id==tsId){
				GetDeliveryTuneInfo(&stm,tun);
				//TRACE("TS %d.%d Freq=%d\r\n",stm.original_network_id,stm.transport_stream_id,tun->frequency);
				rc=1;
				break;
			}
		}
		sec=sec->next;
	}
	if(db->Count>40)
		TRACE("!!!!!NIT has %d sections\r\n",db->Count);
	//PrMutexUnlock(db->lock);
	return rc;
}
static void SDTCBK(PRMpgFilt filt, void *userData, UCHAR*section,UINT length)
{
	USHORT netid=GetSdtNetID(section);
	USHORT tsid=GetSdtStreamID(section);
	TSDATA*ts;
	static int cc=0;
	UCHAR tableId=GetTableID(section);
	if(tableId==0x4A){
		SECTIONDB*db=GetBouquetDB();
		AddSection(db,section);
		return;
	}else if(tableId==0x42){
	    //ts=FindTSByFrequency(PrGetLastFrequency());
		ts=FindTS(netid,tsid);
		if(ts==NULL)ts=CreateTS(netid,tsid);
	    ts->netId=netid;ts->tsId=tsid;
	}else if(tableId==0x46){
	    ts=FindTS(netid,tsid);
	    if(ts==NULL)ts=CreateTS(netid,tsid);
	}else{
		TRACE("SDT/BAT TableID[%02X]ERROR\r\n",tableId);
		return ;
	}
	if(ts->tunerParams.frequency==0){
		GetTSFrequency(netid,tsid,&ts->tunerParams);
		//ts->tunerParams.frequency=PrGetLastFrequency();
	}
	AddSection(ts->sdt,section);
	if(ts->sdt->Count>10||(cc++%20==0)){
		TSDATA*t=GetFirstTS();
		int tc=0;
		while(t){
			t=t->next;
			tc++;
		}
		TRACE("!!!ts %d.%d has %d sdt sections TSCount=%d\r\n",ts->netId,ts->tsId,
			ts->sdt->Count,tc);
	}
}
static void NITCBK(PRMpgFilt filt, void *userData, UCHAR*section,UINT length)
{
	SECTIONDB*db;
	static unsigned int version=0xFFFFFFFF;
	db=GetNetworkDB();
	if((section[0]&0xFE)!=0x40){
		TRACE("NIT TableID[%02X]Error\r\n",section[0]);
		return ;
	}
	AddSection(db,section);
	if(version!=db->version){
		USHORT nid=GetNitNetID(section);
		int i,cnt=GetNitTSCount(section);
		TRACE("**RECV NIT NETID=%d SEC %d COUNT=%d\r\n",nid,GetSectionNo(section),db->Count);
		for(i=0;i<cnt;i++){
			DVBStream stm;
			TSDATA*ts=GetFirstTS();
			GetNitTSStream(section,&stm,i);
			while(ts){
				if(ts->netId==stm.original_network_id
					&&ts->tsId==stm.transport_stream_id){
					GetDeliveryTuneInfo(&stm,&ts->tunerParams);
					TRACE("TS %d.%d Freq=%d\r\n",ts->netId,ts->tsId,ts->tunerParams.frequency);
					break;
				}
				ts=ts->next;
			}
		}
		version=db->version;
	}
}
extern UINT UTCTime2SecondsFrom1970(INT mjd,UINT utc);
static void TDTCBK(PRMpgFilt filt, void *userData, UCHAR*section,UINT length)
{
	USHORT mjd;
	UINT utc,secondsFrom1970;
	if(section[0]==0x70){//TDT
		USHORT y,m,d,h,min,sec;
		GetUTCTime(section,&mjd,&utc);
		GetYMDFromMJD(mjd,&y,&m,&d);
		GetHMSFromUTC(utc,&h,&min,&sec);
		secondsFrom1970=UTCTime2SecondsFrom1970(mjd,utc);
		PrTimeSetTime(secondsFrom1970);
		TRACE("RECV TDT %d/%02d/%02d %02d:%02d:%02d\r\n",y+1900,m,d,h,min,sec);
	}else{//0x73 TOT
		USHORT y,m,d,h,min,sec;
		TIMEOFFSETINFO tos[16];
		INT cnt,i;
		GetTOTTime(section,&mjd,&utc);
		GetYMDFromMJD(mjd,&y,&m,&d);
		GetHMSFromUTC(utc,&h,&min,&sec);
		cnt=GetTOTOffsetInfo(section,tos); 
		for(i=0;i<cnt;i++){
			TIMEOFFSETINFO*t=tos+i;
			TRACE("%s, Region=%d Offset=%04X Change=%04X %06X Next=%04X\r\n",
				t->CountryCode,t->CountryRegionId,t->LocalTimeOffset,
				t->TimeOfChangeMJD,t->TimeOfChangeUTC,t->NextTimeOffset);
		}
	}
}
static void PATCBK(PRMpgFilt filt, void *userData, UCHAR*section,UINT length)
{
	SERVICELOCATOR svc;
	USHORT tsid=GetPatStreamID(section);
	GetCurrentService(&svc);
	if(section[0]!=0){
		TRACE("PAT TabelID[%02X] Error\r\n",section[0]);
		return ;
	}
	if(svc.tsId==tsid){
		TSDATA*ts=FindTS(svc.netId,tsid);
		if(ts){
			static int cc=0;
			AddSection(ts->pat,section);
			if(cc++%50==0)TRACE("recv PAT %d.%d\r\n",svc.netId,tsid);
		}
	}
}
static void PMTCBK(PRMpgFilt filt, void *userData, UCHAR*section,UINT length)
{
	SERVICELOCATOR svc;
	USHORT sid=GetPmtServiceID(section);
	GetCurrentService(&svc);
	if(section[0]!=2){
		TRACE("PMT TabelID[%02X] Error\r\n",section[0]);
		return ;
	}
	if((svc.serviceId==sid)){
		TSDATA*ts=FindTS(svc.netId,svc.tsId);
		if(ts){
			static int cc=0;
			AddSection(ts->pmt,section);
			if(cc++%50==0)TRACE("recv PMT %d.%d.%d\r\n",svc.netId,svc.tsId,sid);
		}
	}
}
int EpgInit(int memsize)
{
	int i;
	UCHAR mask,data;
	if(playThread!=NULL)
		return 0;
	SchedulePF=CreateSectionDB(EITCMPPF,NULL);
	CreateSystemDB();
	epgMutex=PrMutexCreate();
	epgInited=1;
	if((msgQEPG=PrMsgQCreate(64,sizeof(EPGREQUEST)))==NULL)
		return 1;
	if((msgQPlay=PrMsgQCreate(16,sizeof(SERVICELOCATOR)))==NULL)
		return 1;
	playThread=PrThreadCreate(8192,PLAY_PRIORITY,PlayProc,NULL);
	if(playThread==NULL)
		return 1;
	schThread=PrThreadCreate(8192,SEARCH_PRIORITY,SearchProc,NULL);
	if(schThread==NULL)
		return 1;
	memPool=PrPartitionCreate(memsize);
	if(memPool==NULL)
		return 1;
	for(i=0;i<MAX_TS_SERVICE;i++){
		PRMutex schLock;
		memset(&Schedules[i],0,sizeof(SCHEDULE));
		Schedules[i].lock=schLock=PrMutexCreate();
		Schedules[i].lock=schLock;
		Schedules[i].secDB=CreateSectionDB(EITCMPSCH,schLock);
	}
	fltEit=FilterCreate(0,MPGFILT_SECTION);	//// EIT 
	FilterSetPID(fltEit,0x12);
	mask=0xC0;data=0x4E;
	FilterSetMask(fltEit,&mask,&data,1);
	FilterSetCrcMode(fltEit,1);
	FilterSetNotify(fltEit,EitCBK,0);
	FilterStart(fltEit);
	
	fltTDT=FilterCreate(0,MPGFILT_SECTION); //// TDT TOT 
	FilterSetPID(fltTDT,0x14);
	mask=0xF0;data=0x70;
	FilterSetMask(fltTDT,&mask,&data,1);
	FilterSetNotify(fltTDT,TDTCBK,0);
	FilterStart(fltTDT);
	
	fltSDT=FilterCreate(0,MPGFILT_SECTION);	//// SDT Actual/Other and BAT
	FilterSetPID(fltSDT,0x11);
	mask=0xF3;data=0x42;
	FilterSetMask(fltSDT,&mask,&data,1);
	FilterSetNotify(fltSDT,SDTCBK,0);
	FilterStart(fltSDT);

	fltNIT=FilterCreate(0,MPGFILT_SECTION);	//// NIT
	FilterSetPID(fltNIT,0x10);
	mask=0xFE;data=0x40;
	FilterSetMask(fltNIT,&mask,&data,1);
	FilterSetNotify(fltNIT,NITCBK,0);
	FilterStart(fltNIT);	
#ifdef USE_PSI_MONITOR
	fltPAT=FilterCreate(0,MPGFILT_SECTION);
	FilterSetPID(fltPAT,0x0);
	mask=0xFD;data=0x00;
	FilterSetMask(fltPAT,&mask,&data,1);
	FilterSetNotify(fltPAT,PATCBK,0);
	FilterStart(fltPAT);	

	fltPMT=FilterCreate(0,MPGFILT_SECTION);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -