TS结构解析(详细的PAT和PMT解析代码)
http://blog.csdn.net/tuan891205/article/details/8557661
因为在TS流里可以填入很多种东西,所以有必要有一种机制来确定怎么来标识这些数据。制定TS流标准的机构就规定了一些数据结构来定义。比如: PSI(Program Specific Information)表,所以解析起来就像这样: 先接收一个负载里为PAT的数据包,在整个数据包里找到一个PMT包的ID。然后再接收一个含有PMT的数据包,在这个数据包里找到有关填入数据类型的ID。之后就在接收到的TS包里找含有这个ID的负载内容,这个内容就是填入的信息。根据填入的数据类型的ID的不同,在TS流复合多种信息是可行的。关键就是找到标识的ID号。
0000f32ch: 47 40 00 17 00 00 B0 0D 00 01 C1 00 00 00 01 E0 ; G@....?..?...?
0000f33ch: 20 A2 C3 29 41 FF FF FF FF FF FF FF FF FF FF FF ; ⒚)A
0000f34ch: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ;
0000f35ch: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ;
0000f36ch: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ;
0000f37ch: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ;
0000f38ch: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ;
0000f39ch: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ;
0000f3ach: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ;
0000f3bch: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ;
0000f3cch: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ;
0000f3dch: FF FF FF FF FF FF FF FF FF FF FF FF 47 40 20 17 ; G@ .
0000f3ech: 00 02 B0 1B 00 01 C1 00 00 E0 21 F0 00 1B E0 21 ; ..?..?.??.?
0000f3fch: F0 04 2A 02 7E 1F 03 E0 22 F0 00 5D 16 BD 48 ; ?*.~..??].紿
void adjust_TS_packet_header(TS_packet_header* pheader)
{
unsigned char buf[4];
memcpy(buf, pheader, 4);
pheader->transport_error_indicator = buf[1] >> 7;
pheader->payload_unit_start_indicator = buf[1] >> 6 & 0x01;
pheader->transport_priority = buf[1] >> 5 & 0x01;
pheader->PID = (buf[1] & 0x1F) << 8 | buf[2];
pheader->transport_scrambling_control = buf[3] >> 6;
pheader->adaption_field_control = buf[3] >> 4 & 0x03;
pheader->continuity_counter = buf[3] & 0x03;
}
typedef struct TS_packet_header
{
unsigned sync_byte : 8;
unsigned transport_error_indicator : 1;
unsigned payload_unit_start_indicator : 1;
unsigned transport_priority : 1;
unsigned PID : 13;
unsigned transport_scrambling_control : 2;
unsigned adaption_field_control : 2;
unsigned continuity_counter : 4;
} TS_packet_header;
// Programm Association Table
typedef struct TS_PAT
{
unsigned table_id : 8;
unsigned section_syntax_indicator : 1;
unsigned zero : 1;
unsigned reserved_1 : 2;
unsigned section_length : 12;
unsigned transport_stream_id : 16;
unsigned reserved_2 : 2;
unsigned version_number : 5;
unsigned current_next_indicator : 1;
unsigned section_number : 8;
unsigned last_section_number : 8;
unsigned program_number : 16;
unsigned reserved_3 : 3;
unsigned network_PID : 13;
unsigned program_map_PID : 13;
unsigned CRC_32 : 32;
} TS_PAT;
void adjust_PAT_table ( TS_PAT * packet, char * buffer )
{
int n = 0, i = 0;
int len = 0;
packet->table_id = buffer[0];
packet->section_syntax_indicator = buffer[1] >> 7;
packet->zero = buffer[1] >> 6 & 0x1;
packet->reserved_1 = buffer[1] >> 4 & 0x3;
packet->section_length = (buffer[1] & 0x0F) << 8 | buffer[2];
packet->transport_stream_id = buffer[3] << 8 | buffer[4];
packet->reserved_2 = buffer[5] >> 6;
packet->version_number = buffer[5] >> 1 & 0x1F;
packet->current_next_indicator = (buffer[5] << 7) >> 7;
packet->section_number = buffer[6];
packet->last_section_number = buffer[7];
// Get CRC_32
len = 3 + packet->section_length;
packet->CRC_32 = (buffer[len-4] & 0x000000FF) << 24
| (buffer[len-3] & 0x000000FF) << 16
| (buffer[len-2] & 0x000000FF) << 8
| (buffer[len-1] & 0x000000FF);
// Parse network_PID or program_map_PID
for ( n = 0; n < packet->section_length - 4; n ++ )
{
packet->program_number = buffer[8] << 8 | buffer[9];
packet->reserved_3 = buffer[10] >> 5;
if ( packet->program_number == 0x0 )
packet->network_PID = (buffer[10] << 3) << 5 | buffer[11];
else
{
packet->program_map_PID = (buffer[10] << 3) << 5 | buffer[11];
}
n += 5;
}
}
// Program Map Table
typedef struct TS_PMT
{
unsigned table_id : 8;
unsigned section_syntax_indicator : 1;
unsigned zero : 1;
unsigned reserved_1 : 2;
unsigned section_length : 12;
unsigned program_number : 16;
unsigned reserved_2 : 2;
unsigned version_number : 5;
unsigned current_next_indicator : 1;
unsigned section_number : 8;
unsigned last_section_number : 8;
unsigned reserved_3 : 3;
unsigned PCR_PID : 13;
unsigned reserved_4 : 4;
unsigned program_info_length : 12;
unsigned stream_type : 8;
unsigned reserved_5 : 3;
unsigned elementary_PID : 13;
unsigned reserved_6 : 4;
unsigned ES_info_length : 12;
unsigned CRC_32 : 32;
} TS_PMT;
void adjust_PMT_table ( TS_PMT * packet, char * buffer )
{
int pos = 12, len = 0;
int i = 0;
packet->table_id = buffer[0];
packet->section_syntax_indicator = buffer[1] >> 7;
packet->zero = buffer[1] >> 6;
packet->reserved_1 = buffer[1] >> 4;
packet->section_length = (buffer[1] & 0x0F) << 8 | buffer[2];
packet->program_number = buffer[3] << 8 | buffer[4];
packet->reserved_2 = buffer[5] >> 6;
packet->version_number = buffer[5] >> 1 & 0x1F;
packet->current_next_indicator = (buffer[5] << 7) >> 7;
packet->section_number = buffer[6];
packet->last_section_number = buffer[7];
packet->reserved_3 = buffer[8] >> 5;
packet->PCR_PID = ((buffer[8] << 8) | buffer[9]) & 0x1FFF;
packet->reserved_4 = buffer[10] >> 4;
packet->program_info_length = (buffer[10] & 0x0F) << 8 | buffer[11];
// Get CRC_32
len = packet->section_length + 3;
packet->CRC_32 = (buffer[len-4] & 0x000000FF) << 24
| (buffer[len-3] & 0x000000FF) << 16
| (buffer[len-2] & 0x000000FF) << 8
| (buffer[len-1] & 0x000000FF);
// program info descriptor
if ( packet->program_info_length != 0 )
pos += packet->program_info_length;
// Get stream type and PID
for ( ; pos <= (packet->section_length + 2 ) - 4; )
{
packet->stream_type = buffer[pos];
packet->reserved_5 = buffer[pos+1] >> 5;
packet->elementary_PID = ((buffer[pos+1] << 8) | buffer[pos+2]) & 0x1FFF;
packet->reserved_6 = buffer[pos+3] >> 4;
packet->ES_info_length = (buffer[pos+3] & 0x0F) << 8 | buffer[pos+4];
// Store in es
es[i].type = packet->stream_type;
es[i].pid = packet->elementary_PID;
if ( packet->ES_info_length != 0 )
{
pos = pos+5;
pos += packet->ES_info_length;
}
else
{
pos += 5;
}
i++;
}
}
TS结构解析(详细的PAT和PMT解析代码)相关推荐
- TS流PAT、PMT、ES、PES分析及解析代码
TS流即是我们所熟知的传输流,其是由定长的TS包组成(188字节),包括包头和负载数据.其中包头固定为4字节,用来指明包的起始位置.负载的PID以及各种标志位:负载则由各种表及基础流组成: PAT表给 ...
- 从mpeg ts文件中提取I帧(2):pat pmt解析
一.PAT用途 1.描述当前传输流中 PMT 的 PID 信息. 2.描述PMT,与SDT的对应关系. 3.program_number=0时为network pid即nit的pid,接收pmt时注意 ...
- 【PSI/SI学习系列】1.从TS流到PAT和PMT
[PSI/SI学习系列]1.从TS流到PAT和PMT 前言 欢迎到我的网站阅读:http://www.onelib.biz/blog/stb 一 从TS流开始 最近开始学习数字电视机顶盒的开发,从 ...
- TS流结构分析(PAT和PMT)
TS流也是由一个或多个PES组合而来的,他们可以具有相同的时间基准,也可以不同.其基本的复用思想是,对具有相同时间基准[color="#000000"]的多个PES现进行节目复用, ...
- TS流PAT、PMT、SDT内容
TS流: TS流.PS流.PES流和ES流都是什么? ES流(ElementaryStream):基本码流,不分段的音频.视频或其他信息的连续码流. PES流:把基本流ES分割成段,并加上相应头文件打 ...
- PAT、PMT、SDT详解
http://blog.chinaunix.NET/uid-24322243-id-2620180.html 下面针对解复用程序详细分析一下PAT,PMT和SDT三类表格的格式. PAT---Prog ...
- PAT、PMT、SDT详解 MPEG2-TS流的分析
下面针对解复用程序详细分析一下PAT,PMT和SDT三类表格的格式. PAT---Program Association Table,节目关联表.PAT表携带以下信息: (1) TS流ID--- tr ...
- 结构感知图像修复:ICCV2019论文解析
结构感知图像修复:ICCV2019论文解析 StructureFlow: Image Inpainting via Structure-aware Appearance Flow 论文链接: http ...
- 【算法】超详细的遗传算法(Genetic Algorithm)解析
转自:https://www.jianshu.com/p/ae5157c26af9 [算法]超详细的遗传算法(Genetic Algorithm)解析 00 目录 遗传算法定义 生物学术语 问题导入 ...
最新文章
- java动态url_使用url Param的动态主题
- python 异常处理模块_扩展Python模块系列(五)----异常和错误处理
- AAC ADTS格式分析
- Map.Entry如何使用?
- Teradata 金融数据模型FS-LDM
- 高质量C /C编程指南---序言
- htaccess 伪静态的规则
- Java实现简单图书管理系统
- LDAP DirectoryEntry access AD User
- 有源医疗器械电磁兼容入门知识汇总
- Week 8 CSP M2 HRZ学英语
- 更换鼠标垫(鼠标)的心路历程
- 无盘服务器文件管理,云图管家文档图纸管理软件
- 华三模拟器命令(陆续更新)
- 嵌入式系统之实时系统调度算法
- android 点击震动,Android 实现为点击事件添加震动效果
- IOS m3u8格式视频流截图
- Eclipse折叠代码插件folding 推荐
- Teamviewer退出锁定远程计算机
- PMP笔记-项目干系人管理要点总结