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

📄 dvbdata.c

📁 MiniWinOuterSM MiniWinOuterSM
💻 C
字号:
// dvbdata.c: implementation of the dvbdata class.
//
//////////////////////////////////////////////////////////////////////

#include "dvbdata.h"
#include "stdio.h"
#include"secdb.h"
#include"PrMem.h"
#include"string.h"
#include"FavGroup.h"
#define VERIFIED_BYTES 0x82101215
static TSDATA*streams=NULL;
static SECTIONDB*bouquetDB=NULL;//业务群链表
static SECTIONDB*networkDB=NULL;//NIT链表
static SIInternalCMP(UCHAR*sec1,UCHAR*sec2)
{
	UINT id1,id2;
	USHORT eid1,eid2;
	UCHAR tid1,tid2,sno1,sno2;
	tid1=GetTableID(sec1);eid1=GetExtTableID(sec1);sno1=GetSectionNo(sec1);
	tid2=GetTableID(sec2);eid2=GetExtTableID(sec2);sno2=GetSectionNo(sec2);
	if((tid1==0x00)||(tid1==0x02)||(tid1>=0x3B&&tid1<=0x3E)||(tid1==0x4A)){
		//PAT,PMT,BAT,DSMCC
		id1=(tid1<<24)|(eid1<<8)|sno1;
		id2=(tid2<<24)|(eid2<<8)|sno2;
		return id1-id2;
	}else if((tid1==0x40)||(tid1==0x41)||(tid1==0x42)||
			(tid1==0x46)||(tid1>=0x4E&&tid1<=0x6F)){//NIT,SDT,EIT
		id1=(tid1<<24)|(eid1<<8)|sno1;//不比较TableID
		id2=(tid2<<24)|(eid2<<8)|sno2;
		return id1-id2;
	}else if(tid1==0x01||(tid1>=0x80&&tid1<=0x8F)){//CAT CMT
		return tid1-tid2;
	}else if((tid1>=0x70)&&(tid1<=0x73)){//TDT RST ST TOT
		return tid1-tid2;
	}else{
		printf("SectionCompare Wrong section tableID=0x%02X\n",tid2);
	}
	return 0;
}

int CreateSystemDB(void){
	networkDB=CreateSectionDB(SIInternalCMP,NULL);
	bouquetDB=CreateSectionDB(SIInternalCMP,NULL);
	return 2;
}
int ResetSystemDB(void)
{
	FreeDBSections(networkDB);
	FreeDBSections(bouquetDB);
}
int DestroySystemDB(void)
{
	TSDATA*ts=streams;
	DestroySectionDB(networkDB);
	DestroySectionDB(bouquetDB);
	FreeAllTS();
	networkDB=NULL;
	bouquetDB=NULL;
	streams=NULL;
}

TSDATA*CreateTS(USHORT netId,USHORT tsId)
{
	TSDATA*newts,*ts=streams;
	newts=(TSDATA*)PrMalloc(sizeof(TSDATA));
	memset(newts,0,sizeof(TSDATA));
	newts->netId=netId;
	newts->tsId=tsId;
	newts->lock=PrMutexCreate();
	newts->pat=CreateSectionDB(SIInternalCMP,newts->lock);
	newts->pmt=CreateSectionDB(SIInternalCMP,newts->lock);
	newts->sdt=CreateSectionDB(SIInternalCMP,newts->lock);
	memset(newts->States,16,MAX_TSPROGRAM*2);
	if(streams==NULL)
		streams=newts;
	else{
		ts=streams;
		while(ts){
			if(ts->next==NULL){
				ts->next=newts;
				break;
			}
			ts=ts->next;
		}
	}
	return newts;
}
TSDATA*FindTS(USHORT netId,USHORT tsId)//查找一个TS
{
	TSDATA*ts=streams;
	while(ts){
		if(ts->tsId==tsId)
			return ts;
		ts=ts->next;
	}
	return NULL;
}
TSDATA*FindTSByFrequency(UINT32 freq)
{
	TSDATA*ts=streams;
	while(ts){
		if(ts->tunerParams.frequency ==freq)
			return ts;
		ts=ts->next;
	}
	return NULL;
}
TSDATA*GetFirstTS(void)
{
	return streams;
}
void FreeTSData(TSDATA*ts)//释放TS结构的所有内存但不包括TS结构本身
{
	SECTIONDATA*sd;
	sd=ts->pat->sections;
	while(sd){
		SERVICELOCATOR s;
		INT16 i,pc=GetPatProgramCount(sd->Data);
		s.netId=ts->netId;
		s.tsId=GetPatStreamID(sd->Data);
		for(i=0;i<pc;i++){
			DVBProgram prg;
			GetPatProgram(sd->Data,&prg,i);
			s.serviceId=prg.program_number;
			if(s.serviceId)
				DeleteServiceFromFavGroup(NULL,&s);
		}
		sd=sd->next;
	}
	sd=ts->sdt->sections;
	while(sd){
		SERVICELOCATOR s;
		INT16 i,sc=GetSdtServiceCount(sd->Data);
		s.netId=GetSdtNetID(sd->Data);
		s.tsId=GetSdtStreamID(sd->Data);
		for(i=0;i<sc;i++){
			DVBService svr;
			GetSdtService(sd->Data,&svr,i);
			s.serviceId=svr.service_id;
			DeleteServiceFromFavGroup(NULL,&s);
		}
		sd=sd->next;
	}
	FreeDBSections(ts->pat);
	FreeDBSections(ts->pmt);
	FreeDBSections(ts->sdt);
}
void FreeAllTS(void)//释放所有TS的数据包括TS本身 
{
	TSDATA*ts=GetFirstTS();
	while(ts){
		TSDATA*t=ts->next;
		FreeTSData(ts);
		PrFree(ts);
		ts=t;
	}
	streams=NULL;
}

static int FindServiceInTS(TSDATA*ts,USHORT serviceID,DVBService*service)
{//
	if(ts==NULL)
		return -1;
	if(ts->sdt){
		SECTIONDATA*sd=ts->sdt->sections;
		while(sd){
			int i,sCount=GetSdtServiceCount(sd->Data);
			for(i=0;i<sCount;i++){
				DVBService svr;
				GetSdtService(sd->Data,&svr,i);
				if(svr.service_id==serviceID){
					if(service!=NULL)
						*service=svr;
					return 0x2000|i;
				}
			}
			sd=sd->next;
		}
	}else if(ts->pat&&ts->pmt){
		int i=0;
		SECTIONDATA*sd=ts->pmt->sections;
		while(sd){
			if(GetPmtServiceID(sd->Data)==serviceID)
				return 0x1000|i;
			sd=sd->next;
		}
	}
	return -1;
}
int GetServiceInfo(const SERVICELOCATOR*sloc,DVBService*service)//
{
	int rc;
	if(sloc){
		TSDATA*ts=FindTS(sloc->netId,sloc->tsId);
		rc=FindServiceInTS(ts,sloc->serviceId,service);
		if(rc==-1)return 0;
		else if(rc&0x2000)return 2;
		else return 1;
	}
	return 0;
}
int GetServiceType(SERVICELOCATOR*service)
{
	DVBService svr;
	int rc=GetServiceInfo(service,&svr);
	if(rc==2){
		UCHAR*p=FindDescriptor(svr.descriptors,svr.descriptor_loop_length,SERVICE_DESCRIPTOR_TAG);
		if(p)
			return p[2];
	}
	return 0;
}
int GetNvodTimeShiftService(SERVICELOCATOR*refService,SERVICELOCATOR*timeShifts)
{
	DVBService svr;
	int rc=GetServiceInfo(refService,&svr);
	if(rc==2){
		int  i,count;
		UCHAR*p=FindDescriptor(svr.descriptors,svr.descriptor_loop_length,NVOD_REFERENCE_DESCRIPTOR_TAG);
		if(p==NULL)
			return 0;
		count=p[1]/6;
		if(timeShifts){
			p+=2;
			for(i=0;i<count;i++,p+=6){
				timeShifts[i].tsId=(p[0]<<8)|p[1];
				timeShifts[i].netId=(p[2]<<8)|p[3];
				timeShifts[i].serviceId=(p[4]<<8)|p[5];
			}
		}
		return count;
	}
	return 0;
}
int GetServiceName(SERVICELOCATOR*sloc,char*provider,char*sname,UCHAR*lan)
{
	DVBService svr;
	int rc=GetServiceInfo(sloc,&svr);
	switch(rc){
	case 0:
		if(sname)sname[0]=0;
		if(provider)provider[0]=0;
		break;
	case 1:
		if(sname)
			   sprintf(sname,"DTV%d",sloc->serviceId);
		break;
	case 2:GetSdtServiceName(&svr,(UCHAR*)provider,(UCHAR*)sname,lan);
	}
	return rc;
}
int GetServiceParams(const SERVICELOCATOR*sloc,UINT*pids)
{
	TSDATA*ts=FindTS(sloc->netId,sloc->tsId);
	if(ts){
		SECTIONDATA*sd=ts->pmt->sections;
		while(sd){
			unsigned sid=GetPmtServiceID(sd->Data);
			if(sid==sloc->serviceId){
				int i,ec=GetPmtElementCount(sd->Data);
				for(i=0;i<ec;i++){
					ProgElement p;
					GetPmtElement(sd->Data,&p,i);
					if(pids)
						pids[i]=(p.stream_type<<16)|p.elementary_PID;
				}
				if(pids)pids[ec]=GetPmtPCRPID(sd->Data);
				return ec+1;
			}
			sd=sd->next;
		}
	}
	return 0;
}
int GetServicePIDS(const SERVICELOCATOR*sloc,USHORT*pcrPID,
				   USHORT*vID,USHORT*aIDs)
{
	UINT pids[64],count,i,ac,rc;
	count=GetServiceParams(sloc,pids);
	if(count==0)
		return 0;
	*pcrPID=pids[count-1];
	ac=0;rc=0;
	for(i=0;i<count-1;i++){
		switch(pids[i]>>16){
		case 1:
		case 2:*vID=pids[i]&0x1FFF;rc++;break;
		case 3:
		case 4:aIDs[ac++]=pids[i]&0x1FFF;rc++;break;
		}
	}
	return rc+1;
}
USHORT GetServiceState(SERVICELOCATOR*sloc,USHORT mask)
{
	TSDATA*ts=FindTS(sloc->netId,sloc->tsId);
	int i=FindServiceInTS(ts,sloc->serviceId,NULL);
	if(i==-1)
		return 0;
	i&=0xFF;
	return ts->States[i]&mask;
}
USHORT SetServiceState(SERVICELOCATOR*sloc,USHORT mask)
{
	TSDATA*ts=FindTS(sloc->netId,sloc->tsId);
	int i=FindServiceInTS(ts,sloc->serviceId,NULL);
	if(i==-1)
		return 0;
	i&=0xFF;
	ts->States[i]|=mask;
	return 1;
}
USHORT GetServicePmtPID(SERVICELOCATOR*sloc)
{
	TSDATA*ts=FindTS(sloc->netId,sloc->tsId);
	if(ts&&ts->pat&&ts->pat->sections){
		return GetPmtPID(ts->pat->sections->Data,sloc->serviceId);
	}
	return 0;
}

SECTIONDB*GetBouquetDB(void)
{
	return bouquetDB;
}
int GetBouquetName(USHORT bouquetId,char*name,char*lan)
{
	SECTIONDATA*sd;
	if(bouquetDB){
		PrMutexLock(bouquetDB->lock,-1);
		sd=bouquetDB->sections;
		while(sd){
			if(GetBatBouquetID(sd->Data)==bouquetId)
				return GetBatBouquetName(sd->Data,(UCHAR*)name,(UCHAR*)lan);
			sd=sd->next;
		}
		PrMutexUnlock(bouquetDB->lock);
	}
	return 0;
}
SECTIONDB*GetNetworkDB(void)
{
	return networkDB;
}
int LoadDVBData(UCHAR*data)
{
	UCHAR*p=data;
	short i,Count;
	UINT verifyBytes,seclen;
#ifdef _WIN32
	FILE*f=fopen("fav.dat","rb");
	data=(UCHAR*)PrMalloc(1024*64);
	fread(data,1024*64,1,f);
	p=data;
#endif
	memcpy(&verifyBytes,p,4);p+=4;
	if(verifyBytes!=VERIFIED_BYTES)
		return 0;
	memcpy(&Count,p,2);	p+=2;//获取TS流数据总数
	for(i=0;i<Count;i++){
		TSDATA t,*ts;
		memcpy(&t,p,sizeof(TSDATA)); p+=sizeof(TSDATA);
		ts=CreateTS(t.netId,t.tsId);
		ts->tunerParams=t.tunerParams;
		//ts->pat=ts->pmt=ts->sdt=NULL;
		memcpy(&seclen,p,4);p+=4;
		while(seclen>0){
			int slen=GetSectionLength(p)+3;
			switch(p[0]){
			case 0x00:AddSection(ts->pat,p);break;				
			case 0x02:AddSection(ts->pmt,p);break;
			case 0x42:
			case 0x46:AddSection(ts->sdt,p);break;
			}
			seclen-=slen;		p+=slen;
		}
	}
	memcpy(&Count,p,2);p+=2;//获取GROUP总数
	for(i=0;i<Count;i++){
		FAVGROUP grp,*fav;
		int j;
		memcpy(&grp,p,sizeof(FAVGROUP));p+=sizeof(FAVGROUP);
		fav=CreateFavGroup(grp.name,grp.FavId);
		AddFavGroup(fav);
		for(j=0;j<grp.serviceCount;j++){
			SERVICELOCATOR s;
			memcpy(&s,p,sizeof(SERVICELOCATOR));p+=sizeof(SERVICELOCATOR);
			if(GetServiceInfo(&s,NULL))
				AddServiceToFavGroup(fav,&s);
		}
	}
	memcpy(&seclen,p,4);p+=4;//读取NIT BAT section数据的长度
	while(seclen){
		int slen=GetSectionLength(p)+3;
		if(p[0]==0x40||p[0]==0x41){
			AddSection(networkDB,p);
		}else if(p[0]==0x4A){
			AddSection(networkDB,p);
		}else
			break;
		seclen-=slen;	p+=slen;
	}
#ifdef _WIN32
	PrFree(data);
	fclose(f);
#endif
	return p-data;
}
static int WriteSection(UCHAR*data,SECTIONDB*secdb)
{
	UCHAR*p=data;
	SECTIONDATA*sd;
	if(secdb){
		sd=secdb->sections;
		while(sd){
			int slen=GetSectionLength(sd->Data)+3;
			memcpy(p,sd->Data,slen);
			p+=slen;
			sd=sd->next;
		}
	}
	return p-data;
}
int SaveDVBData(UCHAR*data)
{
	short Count=0;
	FAVGROUP*grp=GetFirstFavGroup();//favGroups;
	TSDATA*ts=streams;
	UINT verifyBytes=VERIFIED_BYTES;
	UCHAR*p=data;
	while(ts){
		Count++;
		ts=ts->next;
	}
	memcpy(p,&verifyBytes,4);p+=4;
	memcpy(p,&Count,2);p+=2;//写入TS总数 2 字节
	ts=streams;
	while(ts){
		UCHAR*pseclen;
		UINT secslen;
		memcpy(p,ts,sizeof(TSDATA));	p+=sizeof(TSDATA);
		pseclen=p;p+=4;
		p+=WriteSection(p,ts->pat);
		p+=WriteSection(p,ts->pmt);
		p+=WriteSection(p,ts->sdt);
		secslen=p-pseclen-4;
		memcpy(pseclen,&secslen,4);
		ts=ts->next;
	}
	Count=0;
	while(grp){
		Count++;
		grp=grp->next;
	}
	memcpy(p,&Count,2);	p+=2;//写入Group总数
	grp=GetFirstFavGroup();//favGroups;
	while(grp){
		int slen;
		memcpy(p,grp,sizeof(FAVGROUP));p+=sizeof(FAVGROUP);
		slen=grp->serviceCount*sizeof(SERVICELOCATOR);
		memcpy(p,grp->Services,slen);	p+=slen;
		grp=grp->next;		
	}
	{
		UCHAR*pseclen;
		UINT secslen;
		pseclen=p;p+=4;
		if(networkDB)
			p+=WriteSection(p,networkDB);
		if(bouquetDB)
			p+=WriteSection(p,bouquetDB);
		secslen=p-pseclen-4;
		memcpy(pseclen,&secslen,4);
	}
	return p-data;
}

⌨️ 快捷键说明

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