📄 sitable.c
字号:
// SITable.cpp: implementation of the CSITable class.
//
//////////////////////////////////////////////////////////////////////
#include "SITable.h"
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
#include "locale.h"
//==========================DESCRIPTOR_PARSE_FUNCTIONS========================================
UCHAR*FindDescriptor(UCHAR*des,short dslen,UCHAR tag)
{
USHORT i;
UCHAR*p=des;
for(i=0;dslen>0;i++){
if(p[0]==tag)
return p;
dslen-=(p[1]+2);
p+=(p[1]+2);
}
return NULL;
}
int GetNVODRefService(DVBService*service,NVODRefService*nvodrefService)
{
short sdlen,idx;
UCHAR*p=FindDescriptor(service->descriptors,service->descriptor_loop_length,NVOD_REFERENCE_DESCRIPTOR_TAG);
if(p==NULL)
return 0;
sdlen=*p++;
p++;
for(idx=0;sdlen>0;idx++){
nvodrefService[idx].transport_stream_ID=(p[0]<<8)|p[1];
nvodrefService[idx].original_network_ID=(p[2]<<8)|p[3];
nvodrefService[idx].service_ID=(p[4]<<8)|p[5];
sdlen-=6;
p+=6;
}
return idx;
}
#include"UNI2GB.c"
int unicode2gb(const char*UnicodeStr,char*GbStr)
{
char*pgb=GbStr;
UCHAR*puni;
USHORT uni;
puni=(UCHAR*)UnicodeStr;
do{
int lo,hi;
uni=(puni[0]<<8)|puni[1];
hi=sizeof(UNI2GB)/4;
lo=0;
while(lo<=hi){
int idx=(lo+hi)>>1;
if(uni>UNI2GB[idx][0])
lo=idx+1;
else if(uni<UNI2GB[idx][0])
hi=idx-1;
else{
if(uni>0xFF)*pgb++=UNI2GB[idx][1]>>8;
*pgb++=UNI2GB[idx][1]&0xFF;
break;
}
}
puni+=2;
}while(uni!=0);
return 0;
}
int ConvertString(char*str,int len)
{
int j;
unsigned char bstr[256];
if( (str==NULL)||(len<=0))
return 0;
memcpy(bstr,str+1,len-1);
switch(str[0]){
case 0x11:
{
bstr[len-1]=0;
bstr[len]=0;
unicode2gb((char*)bstr,str);
str[len]='\0';
}
return len-1;
case 0x13:
memcpy(str,str+1,len-1);
str[len-1]=0;
return len;
}
return len;
}
static UCHAR GetMultiServiceName(UCHAR*des,UCHAR*provider,UCHAR*sname,UCHAR*lan)
{
short sdlen;
UCHAR*pd=des;
sdlen=*pd++;
pd++;
for(;sdlen>0;){
UCHAR providerLen=pd[4];
UCHAR nameLen=pd[providerLen+4];
sdlen-=(nameLen+providerLen+5);
if((pd[0]!=lan[0])||(pd[1]!=lan[1])||(pd[2]!=lan[2])){
pd+=nameLen+providerLen+5;
continue;
}
memcpy(provider,pd+4,pd[3]);
provider[pd[3]]=0;
pd+=pd[3]+4;
memcpy(sname,pd+1,pd[0]);
ConvertString((char*)sname,pd[0]);
sname[pd[0]]=0;
return 1;
}
return 0;
}
UCHAR GetSdtServiceName(DVBService*service,UCHAR*provider,UCHAR*sname,UCHAR*lan)
//if success return service type else return 0xFF
{
UCHAR*pd;
UCHAR st;//service type
pd=FindDescriptor(service->descriptors,service->descriptor_loop_length,SERVICE_DESCRIPTOR_TAG);
if(pd==NULL)
return 0;
st=pd[2];
if(provider){
memcpy(provider,pd+4,pd[3]);
provider[pd[3]]=0;
ConvertString((char*)provider,pd[3]);
}
pd+=4+pd[3];
if(sname){
memcpy(sname,pd+1,pd[0]);
sname[pd[0]]=0;
ConvertString((char*)sname,pd[0]);
}
pd=FindDescriptor(service->descriptors,service->descriptor_loop_length,MULTILINGUAL_SERVICE_NAME_DESCRIPTOR_TAG);
if(pd&&lan)
GetMultiServiceName(pd,provider,sname,lan);
return st;
}
static int GetMosaicInfo(UCHAR*des,MOSAICINFO*mosaic)
{
USHORT i;
UCHAR*p;
int rc=0;
if(des==NULL)
return 0;
p=des+2;
mosaic->mosaic_entry_point=p[0]>>7;
mosaic->horiz_cell_count=(p[0]&0x7f)>>4;
mosaic->vert_cell_count=p[0]&0x07;
p++;
for(i=0;p-des<des[1]-1;i++,rc++)
{
UCHAR cellcount;
USHORT j;
MOSAICLOGICALCELL*lgcell=mosaic->logicalcells+i;
USHORT id=(p[0]<<8)|p[1];
lgcell->logical_cell_ID=id>>10;//logical_cell_id
lgcell->cell_presentation_info=id&0x07;
cellcount=p[2];//ementary_cell_field_length
p+=3;
for(j=0;j<cellcount;j++)
lgcell->cells[j]=*p++;
lgcell->link_type=*p++;
switch(lgcell->link_type){
case 1: lgcell->link_ID1=(p[0]<<8)|p[1];
p+=2;
break;
case 2:
case 3:
case 4:
lgcell->link_ID1=(p[0]<<8)|p[1];//original_network_ID
lgcell->link_ID2=(p[2]<<8)|p[3];//transport_stream_ID
lgcell->link_ID3=(p[4]<<8)|p[5];//service_ID
p+=6;
if(lgcell->link_type==4){
lgcell->link_ID4=(p[0]<<8)|p[1];
p+=2;
}
break;
}//end of switch
}
return rc;
}
int GetSdtMosaicInfo(DVBService*service,MOSAICINFO*mosaic)
{
UCHAR*des=FindDescriptor(service->descriptors,service->descriptor_loop_length,MOSAIC_DESCRIPTOR_TAG);
if(des==NULL)
return 0;
return GetMosaicInfo(des,mosaic);
}
UINT BCD2Int(UINT bcd)
{
UINT ret=0;
int r=1;
while(bcd){
ret+=(bcd&0x0F)*r;
bcd>>=4;
r*=10;
}
return ret;
}
UINT Int2BCD(UINT v)
{
UINT rc=0;
int shift=0;
while(v){
int s=v%10;
rc=(s<<shift)+rc;
v/=10;shift+=4;
}
return rc;
}
static UCHAR GetCableDelivery(DVBStream *ts,PRTunerParams*tune)
{
UCHAR*des=FindDescriptor(ts->descriptors,ts->transport_descriptor_length,CABLE_DESCRIPTOR_TAG);
if(des==NULL)
return 0;
#ifdef CABLE_DELIVERY_SYSTEM
tune->frequency=des[2]<<24;
tune->frequency|=des[3]<<16;
tune->frequency|=des[4]<<8;
tune->frequency|=des[5];
tune->frequency=BCD2Int(tune->frequency)/10;
//tune->u.qam.FEC_outer=des[7]&0x0F;
tune->u.qam.modulation=des[8];
tune->u.qam.symbol_rate=des[9]<<24;
tune->u.qam.symbol_rate|=des[10]<<16;
tune->u.qam.symbol_rate|=des[11]<<8;
tune->u.qam.symbol_rate|=des[12];
tune->u.qam.symbol_rate>>=4;
tune->u.qam.symbol_rate=BCD2Int(tune->u.qam.symbol_rate)/10;
tune->u.qam.fec_inner=des[12]&0x0f;
#else
#error "CABLE_DELIVERY_SYSTEM not defined!!!"
#endif
return 1;
}
static UCHAR GetSatelliteDelivery(DVBStream*ts,PRTunerParams*tune)
{
UCHAR*des=FindDescriptor(ts->descriptors,ts->transport_descriptor_length,SATELLITE_DESCRIPTOR_TAG);
if(des==NULL)
return 0;
#ifdef SATELLITE_DELIVERY_SYSTEM
tune->frequency=des[2]<<24;
tune->frequency|=des[3]<<16;
tune->frequency|=des[4]<<8;
tune->frequency|=des[5];
tune->frequency=BCD2Int(tune->frequency)/10;
//tune->orbital_position=(des[6]<<8)|des[7];
//tune->west_east_flag=des[8]>>7;
//tune->polarization=(des[8]>>5)&0x3;
//tune->modulation=des[8]&0x1f;
tune->u.qpsk.symbol_rate=des[9]<<24;
tune->u.qpsk.symbol_rate|=des[10]<<16;
tune->u.qpsk.symbol_rate|=des[11]<<8;
tune->u.qpsk.symbol_rate|=des[12];
tune->u.qpsk.symbol_rate>>=4;
tune->u.qpsk.symbol_rate=BCD2Int(tune->u.qpsk.symbol_rate)/10;
tune->u.qpsk.fec_inner=des[12]&0x0f;
#else
//#error "SATELLITE_DELIVERY_SYSTEM not defined!!"
#endif
return 1;
}
static UCHAR GetTerristrialDelivery(DVBStream*ts,PRTunerParams*tune)
{
UCHAR*des=FindDescriptor(ts->descriptors,ts->transport_descriptor_length,TERRESTRIAL_DESCRIPTOR_TAG);
if(des==NULL)
return 0;
#ifdef TERRISTRIAL_DELIVERY_SYSATEM
tune->frequency=des[2]<<24;
tune->frequency|=des[3]<<16;
tune->frequency|=des[4]<<8;
tune->frequency|=des[5];
tune->frequency=BCD2Int(tune->frequency)/10;
tune->u.ofdm.bandwidth=des[6]>>5;
//tune->reserved_future_use=des[6]&0x1f;
//tune->u.ofdm.constellation=p[5]>>6;
tune->u.ofdm.hierarchy_information=(des[7]>>3)&7;
tune->u.ofdm.code_rate_HP=des[7]&7;
tune->u.ofdm.code_rate_LP=des[8]>>5;
tune->u.ofdm.guard_interval=(des[8]>>3)&3;
tune->u.ofdm.transmission_mode=(des[8]>>1)&3;
#else
//#error "TERRISTRIAL_DELIVERY_SYSATEM not defined!!!"
#endif
return 1;
}
UCHAR GetDeliveryTuneInfo(DVBStream*ts,PRTunerParams*tune)
{
#ifdef CABLE_DELIVERY_SYSTEM
return GetCableDelivery(ts,tune);
#endif
#ifdef SATELLITE_DELIVERY_SYSTEM
return GetSatelliteDelivery(ts,tune);
#endif
#ifdef TERRISTRIAL_DELOVERY_SYSATEM
return GetTerristrialDelivery(ts,tune);
#endif
}
UCHAR GetShortEventName(DVBEvent*event,char*eventName,char*txt,char*lan)
{
UCHAR namelen,txtlen;
UCHAR*p;
UCHAR*des=FindDescriptor(event->descriptors,event->descriptor_loop_length,SHORT_EVENT_DESCRIPTOR_TAG);
if(des==NULL)
return 0;
p=des+2;
namelen=des[5];
if(eventName){
memcpy(eventName,des+6,namelen);
eventName[namelen]=0;
ConvertString(eventName,namelen);
}
txtlen=des[namelen+6];
if(txt){
memcpy(txt,des+namelen+6+1,txtlen);
txt[txtlen]=0;
ConvertString(txt,txtlen);
}
return 1;
}
UCHAR GetEventContentType(DVBEvent*event,UCHAR*tp1,UCHAR*tp2)
{
UCHAR*des=FindDescriptor(event->descriptors,event->descriptor_loop_length,CONTENT_DESCRIPTOR_TAG);
if((des==NULL)&&(des[1]<2))
return 0;
*tp1=des[2];
*tp2=des[3];
return 1;
}
static UCHAR GetMultiName(UCHAR*des,UCHAR*name,UCHAR*lan)
//multilingual_network_name_descriptor 0x5B
//multilingual_bouquet_name_descriptor 0x5C
{
UCHAR*p;
short len;
p=des+2;
len=des[1];
for(;len>0;){
if(lan==NULL){
memcpy(name,p+4,p[3]);
name[p[3]]=0; len-=p[3];
return 1;
}
if(p[0]==lan[0]&&p[1]==lan[1]&&p[2]==lan[2]){
memcpy(name,p+4,p[3]);
name[p[3]]=0;
len-=p[3];
return 1;
}
}
return 0;
}
static UCHAR GetName(UCHAR*des,UCHAR*name)
//tag=0x40 network_name_descriptor
//tag=0x47 bouquet_name_descriptor
{
memcpy(name,des+2,des[1]);
name[des[1]]=0;
return 1;
}
//============================================================================================
UCHAR GetTableID(UCHAR*section)
{
return section[0];
}
UCHAR GetSectionVersion(UCHAR*section)
{
return (section[5]>>1)&0x1f;
}
UINT GetSectionCRC(UCHAR*section)
{
UCHAR*p=section;
USHORT len=(USHORT)(p[1]&0x0F)<<8;
p+=(len+3-4);
return (p[0]<<24)|(p[1]<<16)|(p[2]<<8)|p[3];
}
USHORT GetExtTableID(UCHAR*section)
{
return (section[3]<<8)|section[4];
}
USHORT GetSectionLength(UCHAR*section)
{
UCHAR*p=section;
USHORT len=(USHORT)(p[1]&0x0F)<<8;
len|=p[2];
return len;
}
UCHAR GetSectionNo(UCHAR*section)
{
return section[6];
}
UCHAR GetLastSectionNo(UCHAR*section)
{
return section[7];
}
USHORT GetDesciptorCount(UCHAR*des,short deslooplen)
{
USHORT desCount=0;
for(;deslooplen>0;){
deslooplen-=des[1]+2;
des+=des[1]+2;
desCount++;
}
return desCount;
}
//////////////////////////////////////////////////////////////////////////
//========for NIT BAT================
USHORT GetNitFirstLoopLen(UCHAR*section)
{
return ((section[8]&0x0F)<<8)|section[9];
}
USHORT GetNitTSLoopLen(UCHAR*section)
{
UCHAR*p=section+10+GetNitFirstLoopLen(section);
return ((p[0]&0x0F)<<8)|p[1];
}
USHORT GetNitTSCount(UCHAR*section)
{
short tslen=GetNitTSLoopLen(section);
UCHAR*p=section+12+GetNitFirstLoopLen(section);
USHORT tsCount=0;
for(;tslen>0;){
USHORT len=((p[4]&0x0F)<<8)|p[5];
tslen-=6+len;
tsCount++;
p+=6+len;
}
return tsCount;
}
void GetNitTSStream(UCHAR*section,DVBStream*stream,int index)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -