TS流解析源码.docx
《TS流解析源码.docx》由会员分享,可在线阅读,更多相关《TS流解析源码.docx(39页珍藏版)》请在冰豆网上搜索。
TS流解析源码
非常实用的解析TS流源码
废话不说,直接上传源码。
TsParser.cpp:
#include"stdafx.h"
#include"crc.h"
#include"log.h"
#include"xstring.h"
#include"Xml.h"
#include"osfile.h"
#include"TsParser.h"
#include"OcgMem.h"
#include"MptsTransfer.h"
#include"main.h"
#include"osfile.h"
#include"osdir.h"
/*TS流分析器*/
CTsParser:
:
CTsParser()
{
m_pat_filter=NULL;
m_pat_buf=NULL;
m_pat_size=0;
m_sdt_filter=NULL;
m_bufsize=12*188*1024;
m_head=0;
m_tail=0;
m_buf=(unsignedchar*)OCG_MALLOC(m_bufsize);
}
CTsParser:
:
~CTsParser()
{
uint16_tpmt_pid,serv_id;
SProgInfospi;
TSSDTInfosdt;
void*position;
if(m_pat_filter)
{
m_demux.DestroyFilter(m_pat_filter);
m_pat_filter=NULL;
}
if(m_pat_buf)
{
OCG_FREE(m_pat_buf);
m_pat_buf=NULL;
}
if(m_sdt_filter)
{
m_demux.DestroyFilter(m_sdt_filter);
m_sdt_filter=NULL;
}
if(m_buf)
{
OCG_FREE(m_buf);
m_buf=NULL;
}
position=m_pmtmap.GetFirst(&pmt_pid,&spi);
while(position)
{
if(spi.filter)
m_demux.DestroyFilter(spi.filter);
if(spi.pmt_buf)
OCG_FREE(spi.pmt_buf);
position=m_pmtmap.GetNext(&pmt_pid,&spi,position);
}
m_pmtmap.RemoveAll();
/*清除SDT信息*/
position=m_sdtmap.GetFirst(&serv_id,&sdt);
while(position){
if(sdt.sdt_service_node){
TSSDTServiceInfo*serv_del,*serv_tmp=sdt.sdt_service_node;
while(serv_tmp){
serv_del=serv_tmp;
serv_tmp=serv_tmp->next;
serv_del->next=NULL;
OCG_FREE(serv_del);
}
}
if(sdt.sdt_multilingual_node){
TSSDTMultilingualInfo*multi_del,*multi_tmp=sdt.sdt_multilingual_node;
while(multi_tmp){
multi_del=multi_tmp;
multi_tmp=multi_tmp->next;
multi_del->next=NULL;
OCG_FREE(multi_del);
}
}
position=m_sdtmap.GetNext(&serv_id,&sdt,position);
}
m_sdtmap.RemoveAll();
}
/*PAT/PMT-SECTION输出回调函数*/
voidCTsParser:
:
FilterProc(void*filter,unsignedchar*buf,int32_tsize,uint32_tlParam)
{
if(filter==((CTsParser*)lParam)->m_pat_filter)
((CTsParser*)lParam)->OnPatSection(filter,buf,size);
elseif(filter==((CTsParser*)lParam)->m_sdt_filter)
((CTsParser*)lParam)->OnSdtSection(filter,buf,size);
else
((CTsParser*)lParam)->OnPmtSection(filter,buf,size);
}
/*SDT-SECTION处理函数*/
boolCTsParser:
:
OnSdtSection(void*filter,unsignedchar*buf,int32_tsize)
{
unsignedchar*p,*q,*q1;
int32_tlen,mutili_len;
uint16_tservice_id,sdt_service_id;
uint32_tcrc32,ival;
unsignedcharversion_number,section_number,last_section_number;
void*position;
TSSDTInfo*sdt_info=NULL;
TSSDTServiceInfo*sdt_service_des=NULL,*serv_tmp=NULL;
TSSDTMultilingualInfo*sdt_multilingual_des=NULL,*multi_tmp=NULL;
/*pat/pmt的尺寸不可能超过1024字节*/
if(1024=m_sdt_filter)
returnfalse;
/*CRC校验*/
crc32=GetCrc32(buf,size-4);
memcpy(&ival,buf+size-4,4);
if(ival!
=htonl(crc32))
returnfalse;
version_number=(buf[5]>>1)&0x1f;
section_number=buf[6];
last_section_number=buf[7];
if(last_section_numberreturnfalse;
p=buf;
p+=11;
while(p{
/*service_id*/
service_id=(p[0]<<8)|p[1];
p+=2;
/*EIT...*/
p+=1;
/*descriptor_loop_length*/
len=((p[0]&0xf)<<8)+p[1];
p+=2;
position=m_sdtmap.GetFirst(&sdt_service_id,NULL);
while(position)
{
sdt_info=m_sdtmap.GetValue(position);
if(sdt_info->sdt_service_id==service_id){
sdt_info->bIsSucceed=true;
break;
}
else{
sdt_info=NULL;
}
position=m_sdtmap.GetNext(&sdt_service_id,NULL,position);
}
/*或许当前pat信息还没解析出来,存储结构还未建立好*/
if(!
sdt_info)
returnfalse;
/*descriptors:
descriptor_tag
(1)+descriptor_length
(1)+...*/
q=p;
while(p{
/*descriptor_tag*/
switch(p[0])
{
case0x48:
/*service_descriptor*/
sdt_service_des=(TSSDTServiceInfo*)OCG_MALLOC(sizeof(TSSDTServiceInfo));
if(!
sdt_service_des)
returnfalse;
memset(sdt_service_des,0,sizeof(TSSDTServiceInfo));
p+=2;
/*获取service_descriptor信息*/
sdt_service_des->sdt_service_type=*p;
p+=1;
memcpy(&sdt_service_des->sdt_service_provider_name,p+1,*p);
sdt_service_des->sdt_service_provider_name[*p]=0;
p+=*p;
p+=1;
memcpy(&sdt_service_des->sdt_service_name,p+1,*p);
sdt_service_des->sdt_service_name[*p]=0;
p+=*p;
p+=1;
/*建立链表关系*/
if(!
sdt_info->sdt_service_node){
sdt_info->sdt_service_node=sdt_service_des;
}
else{
serv_tmp=sdt_info->sdt_service_node;
while(serv_tmp){
if(!
serv_tmp->next)
break;
serv_tmp=serv_tmp->next;
}
serv_tmp->next=sdt_service_des;
serv_tmp->next->next=NULL;
}
break;
case0x5d:
/*multilingul_service_name_descriptor*/
mutili_len=p[1];
p+=2;
q1=p;
while(psdt_multilingual_des=(TSSDTMultilingualInfo*)OCG_MALLOC(sizeof(TSSDTMultilingualInfo));
if(!
sdt_multilingual_des)
returnfalse;
memset(sdt_multilingual_des,0,sizeof(TSSDTMultilingualInfo));
/*获取multilingual_name_descriptor*/
memcpy(&sdt_multilingual_des->sdt_ISO_639_language_code,p,4);
sdt_multilingual_des->sdt_ISO_639_language_code<<=8;
sdt_multilingual_des->sdt_ISO_639_language_code=htonl(sdt_multilingual_des->sdt_ISO_639_language_code);
p+=3;
memcpy(&sdt_multilingual_des->sdt_service_provider_name,p+1,*p);
sdt_multilingual_des->sdt_service_provider_name[*p]=0;
p+=*p;
p+=1;
memcpy(&sdt_multilingual_des->sdt_service_name,p+1,*p);
sdt_multilingual_des->sdt_service_name[*p]=0;
p+=*p;
p+=1;
/*建立链表关系*/
if(!
sdt_info->sdt_multilingual_node){
sdt_info->sdt_multilingual_node=sdt_multilingual_des;
}
else{
multi_tmp=sdt_info->sdt_multilingual_node;
while(multi_tmp){
if(!
multi_tmp->next)
break;
multi_tmp=multi_tmp->next;
}
multi_tmp->next=sdt_multilingual_des;
multi_tmp->next->next=NULL;
}
}
break;
default:
/*othersdescriptor_tag*/
p+=2+p[1];
break;
}
}
}
returntrue;
}
/*PAT-SECTION处理函数*/
boolCTsParser:
:
OnPatSection(void*filter,unsignedchar*buf,int32_tsize)
{
unsignedchar*p,*q;
uint16_tservice_id;
uint16_tpmt_pid;
SProgInfospi;
void*position;
uint32_tcrc32,ival;
unsignedcharversion_number,section_number,last_section_number;
TSSDTInfosdt;
/*pat/pmt的尺寸不可能超过1024字节*/
if(1024=m_pat_filter)
returnfalse;
/*CRC校验*/
crc32=GetCrc32(buf,size-4);
memcpy(&ival,buf+size-4,4);
if(ival!
=htonl(crc32))
returnfalse;
version_number=(buf[5]>>1)&0x1f;
section_number=buf[6];
last_section_number=buf[7];
if(last_section_numberreturnfalse;
/*如果PAT版本号改变,则删除所有PAT/PMT记录,重新生成所有信息*/
if(m_pat_buf&&(version_number!
=((m_pat_buf[5]>>1)&0x1f)||
last_section_number!
=m_pat_buf[7]))
{
OCG_FREE(m_pat_buf);
m_pat_buf=NULL;
m_pat_size=0;
position=m_pmtmap.GetFirst(&pmt_pid,&spi);
while(position)
{
if(spi.filter)
m_demux.DestroyFilter(spi.filter);
if(spi.pmt_buf)
OCG_FREE(spi.pmt_buf);
position=m_pmtmap.GetNext(&pmt_pid,&spi,position);
}
m_pmtmap.RemoveAll();
}
if(m_pat_buf==NULL)
{
m_pat_size=(last_section_number+1)*1024;
m_pat_buf=(unsignedchar*)OCG_MALLOC(m_pat_size);
if(m_pat_buf==NULL)
returnfalse;
memset(m_pat_buf,0xff,m_pat_size);
}
/*如果SECTION已经存在,则不必再次处理*/
p=m_pat_buf;
while(*p!
=0xff&&p{
if(p[6]==section_number)
returnfalse;
p+=3+((p[1]&0xf)<<8)+p[2];
}
/*BUFFER不够大:
不可能出现*/
if(m_pat_buf+m_pat_size
{
OCG_ASSERT(false);
returnfalse;
}
/*保存PAT-SECTION*/
memcpy(p,buf,size);
/*提取PMT信息*/
q=p;
p+=8;
while(p+4<=q+size-4)
{
service_id=(p[0]<<8)|p[1];
p+=2;
if(service_id!
=0)
{
pmt_pid=((p[0]&0x1f)<<8)|p[1];
/*如果是第一次找到该PMT,则添加*/
if(m_pmtmap.Search(pmt_pid,&spi)==NULL)
{
memset(&spi,0,sizeof(spi));
/*开始过滤PMT*/
spi.filter=m_demux.CreateFilterExt(pmt_pid,0x02,0xff,
service_id,0xffff,1024,CTsParser:
:
FilterProc,(uint32_t)this);
/*添加*/
m_pmtmap.Insert(pmt_pid,spi);
}
/*如果是第一次找到该SDT,则添加*/
if(NULL==m_sdtmap.Search(service_id,&sdt))
{
memset(&sdt,0,sizeof(sdt));
sdt.sdt_service_id=service_id;
sdt.bIsSucceed=false;
/*添加*/
m_sdtmap.Insert(service_id,sdt);
}
}
p+=2;
}
returntrue;
}
/*PMT-SECTION处理函数*/
boolCTsParser:
:
OnPmtSection(void*filter,unsignedchar*buf,int32_tsize)
{
uint16_tpmt_pid;
SProgInfo*pspi;
void*position;
uint32_tcrc32,ival;
int32_tlen;
unsignedchar*p;
/*pat/pmt的尺寸不可能超过1024字节*/
if(1024=0x02)
returnfalse;
/*CRC校验*/
crc32=GetCrc32(buf,size-4);
memcpy(&ival,buf+size-4,4);
if(ival!
=htonl(crc32))
{
log_error("mptspmtcrcerror!
");
returnfalse;
}
position=m_pmtmap.GetFirst(&pmt_pid,NULL);
while(position)
{
pspi=m_pmtmap.GetValue(position);
if(pspi->filter==filter)
{
/*保存*/
if(pspi->pmt_buf&&pspi->pmt_size