解析TS流PAT和PMT 代码.docx
《解析TS流PAT和PMT 代码.docx》由会员分享,可在线阅读,更多相关《解析TS流PAT和PMT 代码.docx(11页珍藏版)》请在冰豆网上搜索。
解析TS流PAT和PMT代码
#include
#include
#include
#definets_path"/home/huohuo/huangwork/work/birds.ts"//TS文件的绝对路径
voidRead_Ts_Packet(FILE*file_handle,unsignedchar*packet_buf,intlen);//读一个TS流的packet
intparse_TS(unsignedchar*buffer,intFileSize);//分析TS流,并找出PAT的PID和PAT的table
voidparse_PAT(unsignedchar*buffer,intlen);//分析PAT,并找出所含频道的数目和PMT的PID
voidpronum_pmtid_printf();//打印PMT的PID
unsignedchar*Find_PMT(unsignedshortpmt_pid);//找出PMT的table
voidparse_PMT(unsignedchar*buffer,intlen,unsignedshortpmt_pid);//解析PMT,找出其中的Video和Audio的PID
voidprintf_program_list();//打印PMTtable中包含的stream的类型和PID
unsignedchar*Find_video_audio(unsignedshortprogram_pid,unsignedchartype);//找出Video或者Audio的table
typedefstruct
{
unsignedshortprogram_num;//program'snum
unsignedshortpmt_pid;//
}PROGRAM;
typedefstruct
{
unsignedcharstream_type;
unsignedshortelementary_pid;
}PRO_LIST;
PROGRAMprograms[10]={{0,0}};//用来存储PMT的PID和数量
unsignedintnum=0;//totalprogram
PRO_LISTprogram_list[10]={{0,0}};//用来存储PMT中stream的类型和PID
unsignedintprogram_list_num=0;
FILE*file_handle;//指向TS流的指针
unsignedintFileSize=0;
intmain()
{
unsignedcharbuffer[188]={0};
unsignedchar*pmt_buffer,*Video_or_Audio_buffer;
unsignedinti=0,j=0,ret=0;
pmt_buffer=(unsignedchar*)malloc(sizeof(char)*188);//给buffer分配空间
memset(pmt_buffer,0,sizeof(char)*188);//清空buffer
Video_or_Audio_buffer=(unsignedchar*)malloc(sizeof(char)*188);
memset(Video_or_Audio_buffer,0,sizeof(char)*188);
file_handle=fopen(ts_path,"rb+");//以二进制方式打开TS文件
if(NULL==file_handle)//判断是否打开文件
{
perror("fopen");
printf("openfileerror!
\n");
return0;
}
else
printf("openfilesuccess!
\n");
fseek(file_handle,0,SEEK_END);//指针file_handle将以SEEK_END位置偏移0个位置,即将指针移动到文件尾
FileSize=ftell(file_handle);//计算file_handle到文件头的偏移字节数,即计算文件的大小
printf("filesize=%d\n",FileSize);
rewind(file_handle);//equivalent(void)feek(file_handle,0L,SEEK_SET)将file_handle指针移动到文件头位置
printf("findPATbegin-------->\n");
for(i=0;i{
Read_Ts_Packet(file_handle,buffer,188);//读TS的packet函数,每次读188个字节到buffer
ret=parse_TS(buffer,188);//解析188个字节的TS'spacket,并打印找到的PAT’stable。
如果解析成功即找到PAT,则返回1,否则返回0
if(ret==1)
{
break;
}
else
{
printf("ThereisnoPATtable!
\n");
}
}
if(ret==1)
{
parse_PAT(buffer,188);//解析PAT,并找出所含频道的数目和PMT的PID
}
pronum_pmtid_printf();//打印PMT的PID
rewind(file_handle);
printf("findPMTbegin-------->\n");
for(i=0;i{
pmt_buffer=Find_PMT(programs[i].pmt_pid);//根据PMT的PID找到PMT'stable
printf("PMTtable-------->\n");
for(j=0;j<188;j++)
{
printf("0x%x",pmt_buffer[j]);//打印PMT
}
if(pmt_buffer)
{
parse_PMT(pmt_buffer,188,programs[i].pmt_pid);//解析找到的PMT,得到Video、Audio等的PID
}
memset(pmt_buffer,0,sizeof(char)*188);
printf("\n");
}
printf_program_list();//打印elementary流的PID和type。
rewind(file_handle);
printf("findAudioandVideobegin-------->\n");
for(i=0;i{
Video_or_Audio_buffer=Find_video_audio(program_list[i].elementary_pid,
program_list[i].stream_type);//根据PID找到elementary流
printf("theprogram'sPIDis0x%x\n",program_list[i].elementary_pid);
printf("theprogram'sTable--------->\n");
for(j=0;j<188;j++)
{
printf("0x%x",Video_or_Audio_buffer[j]);//打印elementary'stable
}
memset(Video_or_Audio_buffer,0,sizeof(char)*188);
printf("\n");
}
free(pmt_buffer);
free(Video_or_Audio_buffer);
pmt_buffer=NULL;
Video_or_Audio_buffer=NULL;
fclose(file_handle);
printf("\n");
return1;
}
/**************************************************
*readoneTSpacket'sdata
**************************************************/
voidRead_Ts_Packet(FILE*file_handle,unsignedchar*packet_buf,intlen)
{
fread(packet_buf,188,1,file_handle);
}
intparse_TS(unsignedchar*buffer,intFileSize)
{
unsignedchar*temp=buffer;
shortpat_pid;
inti=0;
if(buffer[0]!
=0x47)
{
printf("it'snotatspacket!
\n");
return0;
}
while(temp{
pat_pid=(temp[1]&0x1f)<<8|temp[2];
if(pat_pid!
=0)
printf("findingPATtable....\n");
else
{
printf("alreadyfindthePATtable\n");
printf("pat_pid=0x%x\n",pat_pid);
printf("pattable------->\n");
for(i=0;i<=187;i++)
{
printf("0x%x",buffer[i]);
}
printf("\n");
return1;
}
temp=temp+188;
}
return0;
}
/*******************************************************
*parsePATtable,getthePMT'sPID
*********************************************************/
voidparse_PAT(unsignedchar*buffer,intlen)
{
unsignedchar*temp,*p;
charadaptation_control;
intadaptation_length,i=0;
unsignedshortsection_length,prg_No,PMT_Pid;
temp=buffer;
adaptation_control=temp[3]&0x30;
if(adaptation_control==0x10)
temp=buffer+4+1;
elseif(adaptation_control==0x30)
{
adaptation_length=buffer[4];
temp=buffer+4+1+adaptation_length+1;
}
else
{
return;
}
section_length=(temp[1]&0x0f)<<8|temp[2];
p=temp+1+section_length;
temp=temp+8;
while(temp{
prg_No=(temp[0]<<8)|(temp[1]);
if(prg_No==0)
{
temp=temp+4;
continue;
}
else
{
PMT_Pid=(temp[2]&0x1f)<<8|temp[3];
programs[num].program_num=prg_No;
programs[num].pmt_pid=PMT_Pid;
//printf("pmt_pidisox%x\n",PMT_Pid);
num++;
temp=temp+4;
}
}
}
voidpronum_pmtid_printf()
{
unsignedinti;
printf("PATtable'sprogram_numandPMT'sPID:
\n");
for(i=0;i{
printf("program_num=0x%x(%d),PMT_Pid=0x%x(%d)\n",
programs[i].program_num,programs[i].program_num,
programs[i].pmt_pid,programs[i].pmt_pid);
}
}
voidprintf_program_list()
{
unsignedinti;
printf("AllPMTTable'sprogramlist:
\n");
for(i=0;i{
printf("stream_type=0x%x,elementary_pid=0x%x\n",program_list[i].stream_type,program_list[i].elementary_pid);
}
printf("\n");
}
unsignedchar*Find_PMT(unsignedshortpmt_pid)
{
unsignedinti=0,j=0;
intpid;
unsignedchar*buffer;
buffer=(unsignedchar*)malloc(sizeof(char)*188);
memset(buffer,0,sizeof(char)*188);
rewind(file_handle);
for(j=0;j{
Read_Ts_Packet(file_handle,buffer,188);
if(buffer[0]!
=0x47)
{
printf("It'snotTSpacket!
\n");
}
else
{
pid=(buffer[1]&0x1f)<<8|buffer[2];
if(pid==pmt_pid)
{
printf("PMTTablealreadyfind!
\n");
returnbuffer;
}
else
printf("findingPMTtable.......\n");
}
}
}
unsignedchar*Find_video_audio(unsignedshortprogram_pid,unsignedchartype)
{
unsignedinti=0,j=0;
intpid;
unsignedchar*buffer;
buffer=(unsignedchar*)malloc(sizeof(char)*188);
memset(buffer,0,sizeof(char)*188);
rewind(file_handle);
for(j=0;j{
Read_Ts_Packet(file_handle,buffer,188);
if(buffer[0]!
=0x47)
{
printf("It'snotTSpacket!
\n");
}
else
{
pid=(buffer[1]&0x1f)<<8|buffer[2];
if(program_pid==pid)
{
if(type==0x02)
printf("FindaprogramandthisprogramisVideotype!
\n");
elseif(type==0x03)
printf("FindaprogramandthisprogramisAudiotype!
\n");
else
printf("Findaprogrambutthisprogramisothertype!
\n");
returnbuffer;
}
else
printf("findingVideoorAudiotable.....\n");
}
}
}
voidparse_PMT(unsignedchar*buffer,intlen,unsignedshortpmt_pid)
{
unsignedchar*temp,*p;
charadaptation_control;
intadaptation_length,i=0;
intprogram_info_length;
intES_info_length;
unsignedshortsection_length,pid;
temp=buffer;
adaptation_control=temp[3]&0x30;
if(adaptation_control==0x10)
{
temp=buffer+4+1;
}
elseif(adaptation_control==0x30)
{
adaptation_length=buffer[4];
temp=buffer+5+adaptation_length+1;
}
else
return;
section_length=(temp[1]&0x0f)<<8|temp[2];
p=temp+1+section_length;
//temp=temp+10;
program_info_length=(temp[10]&0x0f)<<8|temp[11];
temp=temp+12+program_info_length;
for(;temp{
program_list[program_list_num].stream_type=temp[0],
program_list[program_list_num].elementary_pid=(temp[1]&0x1f)<<8|temp[2];
ES_info_length=(temp[3]&0x0f)<<8|temp[4];
temp=temp+4+ES_info_length+1;
program_list_num++;
}
}