TS流的解析
因为在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 ; ?*.~..??].紿
// Adjust TS packet header
void adjust_TS_packet_header(TS_packet_header* pheader)
{
unsigned char buf[];
memcpy(buf, pheader, );
pheader->transport_error_indicator = buf[] >> ;
pheader->payload_unit_start_indicator = buf[] >> & 0x01;
pheader->transport_priority = buf[] >> & 0x01;
pheader->PID = (buf[] & 0x1F) << | buf[];
pheader->transport_scrambling_control = buf[] >> ;
pheader->adaption_field_control = buf[] >> & 0x03;
pheader->continuity_counter = buf[] & 0x03;
}
// Transport packet header
typedef struct TS_packet_header
{
unsigned sync_byte : ;
unsigned transport_error_indicator : ;
unsigned payload_unit_start_indicator : ;
unsigned transport_priority : ;
unsigned PID : ;
unsigned transport_scrambling_control : ;
unsigned adaption_field_control : ;
unsigned continuity_counter : ;
} TS_packet_header;
// PAT table
// Programm Association Table
typedef struct TS_PAT
{
unsigned table_id : ;
unsigned section_syntax_indicator : ;
unsigned zero : ;
unsigned reserved_1 : ;
unsigned section_length : ;
unsigned transport_stream_id : ;
unsigned reserved_2 : ;
unsigned version_number : ;
unsigned current_next_indicator : ;
unsigned section_number : ;
unsigned last_section_number : ;
unsigned program_number : ;
unsigned reserved_3 : ;
unsigned network_PID : ;
unsigned program_map_PID : ;
unsigned CRC_32 : ;
} TS_PAT;
// Adjust PAT table
void adjust_PAT_table ( TS_PAT * packet, char * buffer )
{
int n = , i = ;
int len = ;
packet->table_id = buffer[];
packet->section_syntax_indicator = buffer[] >> ;
packet->zero = buffer[] >> & 0x1;
packet->reserved_1 = buffer[] >> & 0x3;
packet->section_length = (buffer[] & 0x0F) << | buffer[];
packet->transport_stream_id = buffer[] << | buffer[];
packet->reserved_2 = buffer[] >> ;
packet->version_number = buffer[] >> & 0x1F;
packet->current_next_indicator = (buffer[] << ) >> ;
packet->section_number = buffer[];
packet->last_section_number = buffer[];
// Get CRC_32
len = + packet->section_length;
packet->CRC_32 = (buffer[len-] & 0x000000FF) <<
| (buffer[len-] & 0x000000FF) <<
| (buffer[len-] & 0x000000FF) <<
| (buffer[len-] & 0x000000FF);
// Parse network_PID or program_map_PID
for ( n = ; n < packet->section_length - ; n ++ )
{
packet->program_number = buffer[] << | buffer[];
packet->reserved_3 = buffer[] >> ;
if ( packet->program_number == 0x0 )
packet->network_PID = (buffer[] << ) << | buffer[];
else
{
packet->program_map_PID = (buffer[] << ) << | buffer[];
}
n += ;
}
}
// PMT table
// Program Map Table
typedef struct TS_PMT
{
unsigned table_id : ;
unsigned section_syntax_indicator : ;
unsigned zero : ;
unsigned reserved_1 : ;
unsigned section_length : ;
unsigned program_number : ;
unsigned reserved_2 : ;
unsigned version_number : ;
unsigned current_next_indicator : ;
unsigned section_number : ;
unsigned last_section_number : ;
unsigned reserved_3 : ;
unsigned PCR_PID : ;
unsigned reserved_4 : ;
unsigned program_info_length : ;
unsigned stream_type : ;
unsigned reserved_5 : ;
unsigned elementary_PID : ;
unsigned reserved_6 : ;
unsigned ES_info_length : ;
unsigned CRC_32 : ;
} TS_PMT;
// Adjust PMT table
void adjust_PMT_table ( TS_PMT * packet, char * buffer )
{
int pos = , len = ;
int i = ;
packet->table_id = buffer[];
packet->section_syntax_indicator = buffer[] >> ;
packet->zero = buffer[] >> ;
packet->reserved_1 = buffer[] >> ;
packet->section_length = (buffer[] & 0x0F) << | buffer[];
packet->program_number = buffer[] << | buffer[];
packet->reserved_2 = buffer[] >> ;
packet->version_number = buffer[] >> & 0x1F;
packet->current_next_indicator = (buffer[] << ) >> ;
packet->section_number = buffer[];
packet->last_section_number = buffer[];
packet->reserved_3 = buffer[] >> ;
packet->PCR_PID = ((buffer[] << ) | buffer[]) & 0x1FFF;
packet->reserved_4 = buffer[] >> ;
packet->program_info_length = (buffer[] & 0x0F) << | buffer[];
// Get CRC_32
len = packet->section_length + ;
packet->CRC_32 = (buffer[len-] & 0x000000FF) <<
| (buffer[len-] & 0x000000FF) <<
| (buffer[len-] & 0x000000FF) <<
| (buffer[len-] & 0x000000FF);
// program info descriptor
if ( packet->program_info_length != )
pos += packet->program_info_length;
// Get stream type and PID
for ( ; pos <= (packet->section_length + ) - ; )
{
packet->stream_type = buffer[pos];
packet->reserved_5 = buffer[pos+] >> ;
packet->elementary_PID = ((buffer[pos+] << ) | buffer[pos+]) & 0x1FFF;
packet->reserved_6 = buffer[pos+] >> ;
packet->ES_info_length = (buffer[pos+] & 0x0F) << | buffer[pos+];
// Store in es
es[i].type = packet->stream_type;
es[i].pid = packet->elementary_PID;
if ( packet->ES_info_length != )
{
pos = pos+;
pos += packet->ES_info_length;
}
else
{
pos += ;
}
i++;
}
}
TS流的解析的更多相关文章
- 关于TS流的解析
字节.在TS流里可以填入很多类型的数据,如视频.音频.自定义信息等.他的包的结构为,包头为4个字节,负载为184个字节(这184个字节不一定都是有效数据,有一些可能为填充数据). 工作形式: 因为在T ...
- TS流解析 一
一 从TS流开始 数字电视机顶盒接收到的是一段段的码流,我们称之为TS(Transport Stream,传输流),每个TS流都携带一些信息,如Video.Audio以及我们需要学习的PAT.PMT等 ...
- TS流解析 四
一 从TS流开始 数字电视机顶盒接收到的是一段段的码流,我们称之为TS(Transport Stream,传输流),每个TS流都携带一些信息,如Video.Audio以及我们需要学习的PAT.PMT等 ...
- TS流PAT/PMT详解
一 从TS流开始 从MPEG-2到DVB,看着看着突然就出现了一大堆表格,什么PAT.PMT.CAT……如此多的表该怎样深入了解呢? 我们知道,数字电视机顶盒接收到的是一段段的码流,我们称之为TS(T ...
- TS流分析
http://blog.csdn.net/zxh821112/article/details/17587215 一 从TS流开始 数字电视机顶盒接收到的是一段段的码流,我们称之为TS(Transpor ...
- 从TS流到PAT和PMT
转自:https://blog.csdn.net/rongdeguoqian/article/details/18214627 一 从TS流开始 最近开始学习数字电视机顶盒的开发,从MPEG-2到DV ...
- 分析ffmpeg解析ts流信息的源码
花费一些时间,然后全部扔了.为了不忘记和抛砖引玉,特发此贴. ffmpeg解析ts流 1.目的 打算软件方式解析出pat,pmt等码流信息 2.源代码所在位置 下载ffmpeg ...
- TS流解析 二 *****
1.TS格式介绍 TS:全称为MPEG2-TS.TS即"Transport Stream"的缩写.它是分包发送的,每一个包长为188字节(还有192和204个字节的包).包的结构为 ...
- ffmpeg解析TS流
介绍: MPEG的系统层编码为不同的应用场景设计了两种格式: TS(Transport Stream) 和PS(Program Stream), 它们两者之间不具有层级关系, 在逻辑上,它们两者都 ...
随机推荐
- L1-030 一帮一
“一帮一学习小组”是中小学中常见的学习组织方式,老师把学习成绩靠前的学生跟学习成绩靠后的学生排在一组.本题就请你编写程序帮助老师自动完成这个分配工作,即在得到全班学生的排名后,在当前尚未分组的学生中, ...
- 增量打包DOC版
压缩zip的命令有的系统没有的自己去下载一个,否则关闭压缩zip的命令. 有需要的自行更改,这是满足我需求的. 执行 publish.bat 即可,当然需要将文件清单写好放在 resources.tx ...
- docker中进行IDA远程调试提示“TRACEME: Operation not permitted[1] Closing connection from 192.168.109.1...”的解决方法
加入 --security-opt seccomp:unconfined选项,关闭docker远程命令执行保护 如: docker run --security-opt seccomp:unconfi ...
- 安装 Java 6
从服务器下载 Linux 64位 jdk 到本地.下载地址:\\192.167.100.225\share\Tool\JAVA\jdk-6u34-linux-x64.bin 给安装文件添加执行权限 $ ...
- net start mysql启动mysql,提示发生系统错误 5 拒绝访问 解决方法
解决问题方法如下: 在dos下运行net start mysql 不能启动mysql!提示发生系统错误 5:拒绝访问!切换到管理员模式就可以启动了.所以我们要以管理员身份来运行cmd程序来启动mys ...
- chapter02 三种决策树模型:单一决策树、随机森林、GBDT(梯度提升决策树) 预测泰坦尼克号乘客生还情况
单一标准的决策树:会根每维特征对预测结果的影响程度进行排序,进而决定不同特征从上至下构建分类节点的顺序.Random Forest Classifier:使用相同的训练样本同时搭建多个独立的分类模型, ...
- Laravel学习之旅(三)
视图 一.怎么新建视图: 1.视图默认存放路径:resources/views: 2.laravel模板支持原生的PHP,直接可以在resources/views新建一个PHP文件,例如: index ...
- Fire! 又是图 bfs
Joe works in a maze. Unfortunately, portions of the maze havecaught on re, and the owner of the ma ...
- Git Authoritative Guide 学习
一.git命令1.git add -u : 将工作区中所有改动的文件添加到暂存区(修改.删除),但是不提交未被git跟踪的文件 -i : 可以进入交互界面选择性提交 -A : 相对于-u,它还提交新建 ...
- 构建一个dbt 数据库适配器
脚手架新的适配器 首先,将odbc适配器模板复制到同一目录中的新文件. 更新dbt / adapters / factory.py以将新适配器包含为类型.还要将类型添加到dbt / contracts ...