多媒体开发之--- rtsp 中的H264 编码+打包+解码相关知识es、pes、ts...
1)ES流(Elementary Stream): 也叫基本码流,包含视频、音频或数据的连续码流.
2)PES流(Packet Elementary Stream): 也叫打包的基本码流, 是将基本的码流ES流根据需要分成长度不等的数据包, 并加上包头就形成了打包的基本码流PES流.
3)TS流(Transport Stream): 也叫传输流, 是由固定长度为188字节的包组成, 含有独立时基的一个或多个program, 一个program又可以包含多个视频、音频、和文字信息的ES流; 每个ES流会有不同的PID标示. 而又为了可以分析这些ES流, TS有一些固定的PID用来间隔发送program和ES流信息的表格: PAT和PMT表,(在MPEG-2系统中,由视频, 音频的ES流和辅助数据复接生成的用于实际传输的标准信息流称为MPEG-2传送流)
封装 : 就是捆绑打包, 将画面视频文件和音轨文件打包在一起, 并按照一定规则建立排序和索引, 便于播放器或播放软件来索引播放. 包括AVI / PS(Program Stream)/ TS(Transport Stream)/ MKV(Matroska)等。
4)I frame :帧内编码帧又称intra picture,I帧通常是每个
GOP(MPEG所使用的一种视频压缩技术)的第一个帧,经过适度地压缩,做为随机访问的参考点,可以当成图象。I帧可以看成是一个图像经过压缩后的产物。
5)P frame:前向预测编码帧又称predictive-frame,通过充分将低于图像序列中前面已编码帧的时间冗余信息来压缩传输数据量的编码图像,也叫预测帧;
6)B frame:双向预测内插编码帧又称bi-directional interpolated predictionframe,既考虑与源图像序列前面已编码帧,也顾及源图像序列后面已编码帧之间的时间冗余信息来压缩传输数据量的编码图像,也叫双向预测帧;
7)PTS:PresentationTime Stamp。PTS主要用于度量解码后的视频帧什么时候被显示出来;
8)DTS:Decode TimeStamp。DTS主要是标识读入内存中的bit流在什么时候开始送入解码器中进行解码。
在没有B帧存在的情况下DTS的顺序和PTS的顺序应该是一样的。
9)
I frame:自身可以通过视频解压算法解压成一张单独的完整的图片。
P frame:需要参考其前面的一个I frame或者B frame来生成一张完整的图片。
B frame:则要参考其前一个I或者P帧及其后面的一个P帧来生成一张完整的图片。
两个I frame之间形成一个GOP,在x264中同时可以通过参数来设定bf的大小,即:I和p或者两个P之间B的数量。
通过上述基本可以说明如果有B frame存在的情况下,一个GOP的最后一个frame一定是P.
(10)DTS和PTS的不同:
DTS主要用于视频的解码,在解码阶段使用.PTS主要用于视频的同步和输出.在display的时候使用.在没有B
frame的情况下.DTS和PTS的输出顺序是一样的.
下面给出一个GOP为15的例子,其解码的参照frame及其解码的顺序都在里面:
如上图:I frame
的解码不依赖于任何的其它的帧.而p frame的解码则依赖于其前面的I frame或者P
frame.B frame的解码则依赖于其前的最近的一个I frame或者P frame及其后的最近的一个P
frame.
(11)视频解码大致流程如下:
(12)PTS的计算
方法一、根据前后帧的IPB类型,可以得知帧的实际显示顺序,使用前面获取的sps信息中的帧率,以及帧计数frame_count即可计算出PTS。此方法需要做几帧缓存(一般缓存一个group的长度)。
I P B B I P B B I P B ...帧类型
1 2 3 4 5 6 7 8 9 10 11 ...第几帧
1 4 2 3 5 8 6 7 9 12 10...帧显示顺序
一个I帧与下一个I帧之间,是一个group。
从上图可见,P类型的帧的显示顺序,是排在后面最后一个B帧之后。
所以要获取第7帧的pts,起码要知道他下一帧的类型,才能得知他的显示顺序。
第8帧的pts=1000(毫秒)*7(帧显示顺序)*帧率
方法二、每一个slice的信息里面,都记录有pic_order_cnt_lsb,当前帧在这个group中的显示顺序。通过这个pic_order_cnt_lsb,可以直接计算出当前帧的PTS。此方法不需要做帧缓存。
计算公式:
pts=1000*(i_frame_counter+ pic_order_cnt_lsb)*(time_scale/num_units_in_tick)
i_frame_counter是最近一次I帧位置的帧序,通过I帧计数+当前group中的帧序,得到帧实际显示序列位置,乘上帧率,再乘上1000(毫秒)的base_clock(基本时钟频率),得到PTS。
I P B B I P B B I P B
...帧类型
1 2 3 4 5 6 7 8 9 10 11 ...第几帧
1 4 2 3 5 8 6 7 9 12 10 ...帧显示顺序
0 6 2 4 0 6 2 4 0 6 2
... pic_order_cnt_lsb
细心一点可以注意到,在上图,slice里面的pic_order_cnt_lsb是以2进行递增。
通常H264里面的sps中记录的帧率,也是实际帧率的2倍time_scale/num_units_in_tick=fps*2
因此,实际的计算公式应该是这样
pts=1000*(i_frame_counter*2+pic_order_cnt_lsb)*(time_scale/num_units_in_tick)
或者是
pts=1000*(i_frame_counter+pic_order_cnt_lsb/2)*(time_scale/num_units_in_tick/2)
所以,第11帧的pts应该是这么计算
1000*(9*2+2)*(time_scale/num_units_in_tick)
RTP打包H264的时间戳,由于H264标准说明是90000/帧率,这里pts的base_clock都是按照1000(毫秒)计算,如果复用到ts里,base_clock是90k,所以还应该再乘以90。
pic_order_cnt_lsb:
lsb:least significant bits POC低位
poc:picture oder counter
pic_order_cnt_type:指明了POC(Picture Order Count)的编码方法、POC标识图像的播放顺序。
http://www.cppblog.com/dvb-dvb/archive/2009/08/12/99268.html
http://blog.csdn.net/ljh081231/article/details/5828997
http://www.chinavideo.org/archiver/?tid-5256.html 264码流的帧率求解
http://bbs.csdn.net/topics/390368092 rtp 帧率、时间戳
http://70565912.blog.51cto.com/1358202/533736/ pts 获取代码实现
http://zhongcong386.blog.163.com/blog/static/1347278042012113033745404/
http://www.xuebuyuan.com/660091.html
http://video.vomont.com/client.html
http://www.phpv.net/html/122.html 破解电视下载
http://wxinpeng.iteye.com/blog/2106068 rtsp 公网地址
http://www.foko.cn/admin/upload/201323123111.pdf 美赞ipc
http://www.fanli7.net/a/bianchengyuyan/_NET/20130415/297725.html
http://blog.csdn.net/ljh081231/article/details/8124535 ccd之殇
多媒体开发之--- rtsp 中的H264 编码+打包+解码相关知识es、pes、ts...的更多相关文章
- Python中进行Base64编码和解码
Base64编码 广泛应用于MIME协议,作为电子邮件的传输编码,生成的编码可逆,后一两位可能有“=”,生成的编码都是ascii字符.优点:速度快,ascii字符,肉眼不可理解缺点:编码比较长,非常容 ...
- java中URL 的编码和解码函数
java中URL 的编码和解码函数java.net.URLEncoder.encode(String s)和java.net.URLDecoder.decode(String s);在javascri ...
- python中的URL编码和解码
python中的URL编码和解码:test.py # 引入urllib的request模块 import urllib.request url = 'https://www.douban.com/j/ ...
- java中的url 编码与解码
什么是application/x-www-form-urlencoded字符串? 答:它是一种编码类型.当URL地址里包含非西欧字符的字符串时,系统会将这些字符转换成application/x-www ...
- php和js中json的编码和解码
php中 1)编码 $jsonStr = json_encode($array) 2)解码 $arr = json_decode($jsonStr) <?php echo json_encode ...
- iOS URL中汉字的编码和解码
发现NSString类中有内置的方法可以实现.他们分别是: - (NSString *)stringByAddingPercentEscapesUsingEncoding:(NSStringEncod ...
- Javascript中的url编码与解码(详解)
摘要 本文主要针对URI编解码的相关问题做了介绍,对url编码中哪些字符需要编码.为什么需要编码做了详细的说明,并对比分析了Javascript中和编解码相关的几对函数escape / unescap ...
- Python3中字符串的编码与解码以及编码之间转换(decode、encode)
一.编码 二.编码与解码 Python3中对py文件的默认编码是urf-8.但是字符串的编码是Unicode. 由于Unicode采用32位4个字节来表示一个字符,存储和传输太浪费资源,所以传输和存储 ...
- Java 8中的Base64编码和解码
转自:https://juejin.im/post/5c99b2976fb9a070e76376cc Java 8会因为将lambdas,流,新的日期/时间模型和Nashorn JavaScript引 ...
随机推荐
- 解决方案:An error was encountered while running(Domain=FBSOpenApplicationErrorDomain, Code=4)
iOS simulator出现问题,提示: An error was encountered while running (Domain = FBSOpenApplicationErrorDomain ...
- 第一个Mac程序——倒计时v1&v2
先放效果图: 这是我第一次尝试在Mac平台下编程,之前学过几天IOS开发,一直在等MJ老师更新.闲下来不编程不舒服,给自己,也给老婆编了这个以提醒自己好好学习.v2版加入了各种倒计时.改进了界面.把倒 ...
- 来自Jakob Jenkov的Jackson教程
Jakob Jenkov是Java界的牛人. 下面是收集的与Jackson有关的教程: JSON: http://tutorials.jenkov.com/java-json/index.html J ...
- Python-爬虫-针对有frame框架的页面
有的页面会使用frame 框架,使用Selenium + PhantomJS 后并不会加载iframe 框架中的网页内容.iframe 框架相当于在页面中又加载了一个页面,需要使用Selenium 的 ...
- xpath节点匹配简易教程
2017-03-23 非本人原创,只是写爬虫时很有用,就留下了 <A id="a1"> <B id="b1"> <C id=&qu ...
- 改进xutils下载管理器,使其,在随意地方进行进度更新,以及其它状态监听操作
1.前面在做下载进度监听.尝试过,通过加入 弱引用的View进度条,到相应的集合. 等到要进行更新进度的时候.通过Key 获取相应的VIew来进行更新 进度条.效果是达到了,可是我们怎样来监听其它的状 ...
- ios多线程操作(四)—— GCD核心概念
GCD全称Grand Central Dispatch.可译为"大派发中枢调度器",以纯C语言写成,提供了很多很强大的函数.GCD是苹果公司为多核的并行运算提出的解决方式,它能够自 ...
- Unity3D的脚本-script入门
来自:http://blog.163.com/shininglore@126/blog/static/961841802013412101454833/ Unity3D的基本操作很容易就能掌握了,接下 ...
- Oracle基础 程序包
一.程序包 程序包是一种数据库对象,它是对相关PLSQL类型.子程序.游标.异常.变量和常量的封装.程序包包含两部分内容: 1.程序包规范:可以声明类型.变量.常量.异常.游标和子程序. 2.程序包主 ...
- python ——单下划线(约定)
命名规则: 通常使用小写单词,必要时用下划线分隔增加可读性. 使用一个前导下划线仅用于不打算作为类的公共接口的内部方法和实例变量. Python不强制要求这样; 它取决于程序员是否遵守这个约定. 使用 ...