左右TS分析流
字节。在TS流里能够填入非常多类型的数据。如视频、音频、自己定义信息等。他的包的结构为,包头为4个字节,负载为184个字节(这184个字节不一定都是有效数据。有一些可能为填充数据)。
由于在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 ; ?*.~..?
?
].紿

memcpy(buf, pheader, );
pheader->transport_error_indicator = buf[] >> ;
pheader->payload_unit_start_indicator = buf[] >> & ] >> & ] & | buf[];
pheader->transport_scrambling_control = buf[] >> ;
pheader->adaption_field_control = buf[] >> & ] & ;
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;

如今看看我们的TS流片断样例。看来正好是47 40 00开头的。一个TS流的头部占领了4个字节。剩下的负载部分的内容由PID来决定。样例看来就是一个PAT表。在这里有个地方须要注意一下。payload_unit_start_indicator为1时。在前4个字节之后会有一个调整字节,它的数值决定了负载内容的详细開始位置。如今看样例中的数据47 40 00 17 00第五个字节是00,说明紧跟着00之后就是详细的负载内容。

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;


;
packet->table_id = buffer[];
packet->section_syntax_indicator = buffer[] >> ;
packet->zero = buffer[] >> & ] >> & ] & | buffer[];
packet->transport_stream_id = buffer[] << | buffer[];
packet->reserved_2 = buffer[] >> ;
packet->version_number = buffer[] >> & ] << ) >> ;
packet->section_number = buffer[];
packet->last_section_number = buffer[];
+ packet->section_length;
packet->CRC_32 = (buffer[len-] &
| (buffer[len-] &
| (buffer[len-] &
| (buffer[len-] & ; n < packet->section_length - ; n ++ )
{
packet->program_number = buffer[] << | buffer[];
packet->reserved_3 = buffer[] >> ;
] << ) << | buffer[];
] << ) << | buffer[];
}
n += ;
}
}

循环的次数通过section_length元素的确定。在这个样例中program_map_PID为20,所以以下来PMT分析时。就是查找47 40 20的开头的TS包。

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;


;
packet->table_id = buffer[];
packet->section_syntax_indicator = buffer[] >> ;
packet->zero = buffer[] >> ;
packet->reserved_1 = buffer[] >> ;
packet->section_length = (buffer[] & | buffer[];
packet->program_number = buffer[] << | buffer[];
packet->reserved_2 = buffer[] >> ;
packet->version_number = buffer[] >> & ] << ) >> ;
packet->section_number = buffer[];
packet->last_section_number = buffer[];
packet->reserved_3 = buffer[] >> ;
packet->PCR_PID = ((buffer[] << ) | buffer[]) & ] >> ;
packet->program_info_length = (buffer[] & | buffer[];
;
packet->CRC_32 = (buffer[len-] &
| (buffer[len-] &
| (buffer[len-] &
| (buffer[len-] & )
pos += packet->program_info_length;
) - ; )
{
packet->stream_type = buffer[pos];
packet->reserved_5 = buffer[pos+] >> ;
packet->elementary_PID = ((buffer[pos+] << ) | buffer[pos+]) & ] >> ;
packet->ES_info_length = (buffer[pos+] & | buffer[pos+];
)
{
pos = pos+;
pos += packet->ES_info_length;
}
;
}
i++;
}
}

然后就能够把数据是用调整函数填入结构中。然后得到详细节目的PID为视频0x21, 音频0x22。
版权声明:本文博主原创文章。博客,未经同意不得转载。
左右TS分析流的更多相关文章
- 关于ES、PES、PS/TS 码流
一.基本概念 )ES ES--Elementary Streams (原始流)是直接从编码器出来的数据流,可以是编码过的视频数据流(H.264,MJPEG等),音频数据流(AAC),或其他编码 ...
- ffmpeg利用libav库把yuv视频流转换为TS串流
今天到月末了,才发我这个月的第一篇文章,因为这个月前三周一直在看ffmpeg的libavcodec和libavformat两个库源码.实验室要做一个“小传大”的软件,就是android手机或平板电脑的 ...
- 流媒体ts/ps流封装/分析
1.TS 1) 感谢星辰同学,还热乎着,
- go http 下载视频(TS码流文件)(推荐一个网站学习 go example)
视频 http下载代码 dn.go(注意:代码很ugly,没怎么花时间) 总体感觉特别简单,网上看了下 net/http ,io这2个库的使用, 几分钟就写完了,感觉cpp 在做工具这块 开发效率的 ...
- TS流分析
http://blog.csdn.net/zxh821112/article/details/17587215 一 从TS流开始 数字电视机顶盒接收到的是一段段的码流,我们称之为TS(Transpor ...
- TS流格式(转)
一 从TS流开始 数字电视机顶盒接收到的是一段段的码流,我们称之为TS(Transport Stream,传输流),每个TS流都携带一些信息,如Video.Audio以及我们需要学习的PAT.PMT等 ...
- ts文件分析(纯c解析代码)
参考链接: 1. MPEG-2 TS码流分析 https://blog.csdn.net/zhubin215130/article/details/8958567 TS Header PAT PMT ...
- TS流解析 一
一 从TS流开始 数字电视机顶盒接收到的是一段段的码流,我们称之为TS(Transport Stream,传输流),每个TS流都携带一些信息,如Video.Audio以及我们需要学习的PAT.PMT等 ...
- ffmpeg解析TS流
介绍: MPEG的系统层编码为不同的应用场景设计了两种格式: TS(Transport Stream) 和PS(Program Stream), 它们两者之间不具有层级关系, 在逻辑上,它们两者都 ...
随机推荐
- 用C++语言开发Android程序 配置开发环境
转自:http://www.cnblogs.com/yaotong/p/3622430.html 用C++语言开发Android程序 配置开发环境 如果你是一个C++语言的死忠,你喜欢C++语言到 ...
- Windows phone 8 学习笔记(4) 应用的启动
原文:Windows phone 8 学习笔记(4) 应用的启动 Windows phone 8 的应用除了可以直接从开始菜单以及应用列表中打开外,还可以通过其他的方式打开.照片中心.音乐+视频中心提 ...
- 【前段开发】行内元素和块级元素总结(HTML CSS)
块级元素 <address> information on author <blockquote> long quotation <button> push but ...
- 认为C/C++很难理解、找工作面试笔试,快看看这本书!
假设你是C/C++谁刚开始学习,看这本书.因为也许你读其他的书还不如不看.一定要选择一本好书. 假设你正在准备工作,请认真看这本书,由于这本书会教会你工作中必备的知识,相信你即将面临的语法类题目不会超 ...
- mysql 触发器和存储过程组合使用,实现定时触发操作
mysql可以实现定时触发功能,比如说定于某某时间mysql数据库做什么工作,或每隔多长时间做什么工作. 第二种情况应用还是比较广的,比如说我希望每天检查一下我的数据信息,超过一个月的无用信息清除以腾 ...
- 教你如何使用U盘装系统
首先,你必须有一个4G以上U菜,然后,U光盘制作软件(这里我们使用url=KRVS0FUdaNAMKPUXUxjEijxBMalUjaJHph-tL-x4gXGSwVNUW3fj6RfuZtrMg1Y ...
- 瑞丽的SQL-SQL Server的表旋转(行列转换)
所谓表旋转,就是将表的行转换为列,或是将表的列转换为行,这是从SQL Server 2005開始提供的新技术.因此,如果希望使用此功能,须要将数据库的兼容级别设置为90.表旋转在某些方面也是攻克了表的 ...
- [原创] 使用rpi + crontab + git 定时向bitbucket 推送 照片
#前提条件,你得有一个bitbucket的帐户 1.定时启动脚本代码 使用的是crontab Cronfile 内容如下: 此文件的意思是,每隔10分钟,就运行一次 /home/pi/Rpi_uplo ...
- C++面试宝典2011版
1.new.delete.malloc.free关系 delete会调用对象的析构函数,和new相应free仅仅会释放内存,new调用构造函数.malloc与free是C++/C语言的标准库函数,ne ...
- python udp编程实例
与python tcp编程控制见 http://blog.csdn.net/aspnet_lyc/article/details/39854569 c++ udp/tcp 编程见 http://blo ...