多媒体开发之--- 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之殇

时间: 2024-10-13 12:16:07

多媒体开发之--- rtsp 中的H264 编码+打包+解码相关知识es、pes、ts...的相关文章

iOS URL中汉字的编码和解码

发现NSString类中有内置的方法可以实现.他们分别是: - (NSString *)stringByAddingPercentEscapesUsingEncoding:(NSStringEncoding)encoding- (NSString *)stringByReplacingPercentEscapesUsingEncoding:(NSStringEncoding)encoding 只要传入相应的编码即可以进行编码和解码了,不过此方法是对整个Url进行编码的所以如果有Query Str

java中URL 的编码和解码函数

java中URL 的编码和解码函数java.net.URLEncoder.encode(String s)和java.net.URLDecoder.decode(String s);在javascript 中URL 的编码和解码函数escape(String s)和unescape(String s) ; 在前台:var url="test.jsp?param="+escape('this%is#te=st&o k?+/');在后台: String param=request.

Python中进行Base64编码和解码

Base64编码是一种“防君子不防小人”的编码方式.广泛应用于MIME协议,作为电子邮件的传输编码,生成的编码可逆,后一两位可能有“=”,生成的编码都是ascii字符.优点:速度快,ascii字符,肉眼不可理解缺点:编码比较长,非常容易被破解,仅适用于加密非关键信息的场合Python中进行Base64编码和解码>>> import base64>>> s = '我是字符串'>>> a = base64.b64encode(s)>>>

Android中常用的编码和解码(加密和解密)的问题

1. URL Encoding     编码目的是为了在?址上可以包含中文等特殊字符解码是为了把编码后的内容还原成原始的内容格式如下%9C%3C%F3%98 规则: %hex_byte 就是将实际的字节转换为十六进制进行显示编码URLEncoder.encode(String str, String charset) 解码 URLDecoder.encode(String str, String charset) eg.    %E6%88%91%E6%98%AFvhly%EF%BC%8C%E4

C#关于编码、解码相关问题

编码.解码技术是我们在程序中开发中经常使用到的,对一些敏感信息的存储,比如密码之类的,我们一般是不会直接以明文直接存储到数据库的,而是会通过各种算法,可以是现成的MD5(一种散列算法).或者是Hash算法+Salt(混淆因子),甚至是自己定义的一套算法进行加解密.这里不想阐述加解密技术,在之前的一篇博客当中,简单列举了两种基本方法,见.NET加解密技术.这里重点讲解一下编码.解码以及乱码的相关问题. 我们先看一个简单的例子: string str = "abcd";//测试字符串 by

Python中字符的编码与解码

1 文本和字节序列 我们都知道字符串,就是由一些字符组成的序列构成串,那么字符又是什么呢?计算机只能识别二进制的东西,那么计算机又为什么会显示我们的汉字,或者是某个字母呢? 由于最早发明使用计算机是美国人,他们为了解决了英语如何在电脑上显示,就制定了一套标准:ASCII ((American Standard Code for Information Interchange): 美国信息交换标准代码),主要用于显示现代英语和其他西欧语言.到目前为止共定义了128个字符,从0-127的二进制数分别

ASP.NET中字符串的编码与解码

开始编/解码前,需要引入命名空间 using System.Text; 编码按钮代码: protected void BtnPWD_Click(object sender, EventArgs e) { if (this.TxtStr.Text == "") { Response.Write("<script language=javascript>alert('对不起,文本框为空');location='javascript:history.go(-1)'<

centos 安装ffmpeg 及h264编码打包

切记删除原有ffmpeg 1.编译yasm. ./configure --prefix=/usr/local/yasm make make install 2.解压x264,进入目录,输入: ./configure --prefix=/usr/local/x264 --enable-shared --enable-static --enable-yasm make make install 3.解压ffmpeg,进入目录,输入: ./configure --prefix=/usr/local/f

Kafka中使用Avro编码、解码消息

1.消费者代码 import com.twitter.bijection.Injection; import com.twitter.bijection.avro.GenericAvroCodecs; import org.apache.avro.Schema; import org.apache.avro.generic.GenericData; import org.apache.avro.generic.GenericRecord; import org.apache.kafka.clie