Skip to content

Latest commit

 

History

History
85 lines (44 loc) · 11.6 KB

关键帧.md

File metadata and controls

85 lines (44 loc) · 11.6 KB

关键帧

I、P、B帧

在H.264协议中定义了3种帧,完整编码的帧叫I帧、参考之前的I帧生成的只对差异部分进行编码的帧叫P帧、还有一种参考前后的帧进行编码的帧叫B帧。

  • I帧(Intra coded picture):帧内编码图像帧简称关键帧,这一帧画面的完整保留,解码时只需要本帧数据就可以完成.I帧通常是每个GOP(MPEG所使用的一种视频压缩技术)的第一个,GOP就是指两个I帧之间的距离。

    我们在做直播的时候,想要能达到秒开的效果,因为I帧是能不依赖其他帧独立完成解码的,这就意味着当播放器接收到I帧就能立马渲染出来,而接收到P、B帧则需要等待依赖的帧而不能立马完成解码和渲染,这个期间就会黑屏,所以可以在服务端通过缓存GOP,保证播放端在接入直播时能先获取到I帧马上渲染出画面,从而提高起播速度。在直播服务器中,支持设置一个cache,用于存放GOP,直播服务器缓存了当前的GOP序列,当播放端请求数据的时候,CDN会从I帧返回给客户端,从而保证客户端可以快速进行播放。当然由于缓存的是之前的视频信息,当音频数据到达播放端后,为了音视频同步播放器会进行视频的快进处理。

  • P帧(Predictive coded picture):预测编码图像帧简称差别帧,这一帧跟之前的一个关键帧或P帧的差别,解码时需要用之前缓存的画面叠加上本帧定义的差别,生成最终的画面。也就是说P帧没有完整的画面数据,只有与前一帧的画面差别的数据。

  • B帧(Bidirectionally predicted picture):双向预测编码图像帧简称双向差别帧,也就是B帧记录的是本帧与前后帧的差别。也就是要解码B帧,不仅要取得之前的缓存画面,还要解码之后的画面,通过前后画面与本帧数据的叠加来获取最终的画面。B帧压缩率高,但是解码时会更耗CPU。

GOP

这3种帧用于表示传输的视频画面。在H.264中图像以序列为单位进行组织,一个序列是一段图像编码后的数据流,以I帧开始,到下一个I帧结束,中间部分也被称为一个GOP。

GOP(Group of Pictures)是一组连续的画面,由一张I帧和数张B/P帧组成,是视频图像编码器和解码器存取的基本单位,它的排列顺序将会一直重复到影像结束。 编码器将多张图像进行编码后生产成一段一段的 GOP ,解码器在播放时则是读取一段一段的GOP进行解码后读取画面再渲染显示。

**编码器将多张图像进行编码后生产成一段一段的 GOP ( Group of Pictures ) , 解码器在播放时则是读取一段一段的 GOP 进行解码后读取画面再渲染显示。**GOP ( Group of Pictures) 是一组连续的画面,由一张 I 帧和数张 B / P 帧组成,是视频图像编码器和解码器存取的基本单位,它的排列顺序将会一直重复到影像结束。I 帧是内部编码帧(也称为关键帧),P帧是前向预测帧(前向参考帧),B 帧是双向内插帧(双向参考帧)。简单地讲,I 帧是一个完整的画面,而 P 帧和 B 帧记录的是相对于 I 帧的变化。如果没有 I 帧,P 帧和 B 帧就无法解码。

GOP是指一组连续的图像,由一个I帧和多个B/P帧组成,是编解码器存取的基本单位。GOP结构常用的两个参数为M和N,M用于指定GOP中首个P帧和I帧之间的距离,N用于指定一个GOP的大小。例如M=1,N=15,GOP结构为IPBBPBBPBBPBBPB IPBBPBB。GOP指两个I帧之间的距离,Reference指两个P帧之间的距离。一个I帧所占用的字节数大于一个P帧,一个P帧所占用的字节数大于一个B帧,所以在码率不变的前提下,GOP值越大,P、B帧的数量就会越多,平均每个I、P、B帧所占用的字节数就越多,也就更容易获取较好的图像质量;Reference越大,B帧的数量就越多,同理也更容易获得较好的图像质量。需要说明的是,通过提高GOP值来提高图像质量是有限度的,在遇到场景切换的情况时,H.264编码器会自动强制插入一个I帧,此时实际的GOP值被缩短了。

另一方面,在一个GOP中,P、B帧是由I帧预测得到的,当I帧的图像质量比较差时,会影响到一个GOP中后续P、B帧的图像质量,直到下一个GOP开始才有可能得以恢复,所以GOP值也不宜设置得过大。同时,由于P、B帧的复杂度大于I帧,所以过多的P、B帧会影响编码效率,使编码效率降低。另外,过长的GOP还会影响Seek操作的响应速度,由于P、B帧是由前面的I或P帧预测得到的,所以Seek操作需要直接定位,在解码某个P或B帧时,需要先解码得到本GOP内的I帧及之前的N个预测帧才可以,GOP值越长,需要解码的预测帧就越多,Seek响应的时间也越长。

GOP的形式通常有两种,包括闭合式GOP和开放式GOP。闭合式GOP只需参考本GOP内的图像,而不需参考前后GOP的数据。这种模式决定了闭合式GOP的显示顺序总是以I帧开始而以P帧结束。开放式GOP中的B帧解码时可能要用到其前一个GOP或后一个GOP的某些帧。码流中包含B帧的时候才会出现开放式GOP。

IDR

IDR(Instantaneous Decoding Refresh)是H.264视频编码中的一种特殊的I帧。它包含了所有的视频序列信息,并且通过强制性地要求解码器重新初始化来保证解码正确性。IDR通常用于视频流中断或丢失时,重新恢复视频流的一种方式。

总之,I帧是视频序列中的一种关键帧,它能够独立解码,而IDR是一种特殊的I帧,具有重新初始化解码器的特殊作用。

一个序列(GOP)的第一个图像叫做IDR图像(立即刷新图像),IDR图像都是I帧图像。H.264引入IDR图像是为了解码的重新同步,当解码器解码到IDR图像时,立即将参考帧队列清空,将已解码的数据全部输出或抛弃,重新查找下一个参考集,开始解码一个新的序列。这样,如果前一个序列出现重大错误,在这里可以获得重新同步的机会。IDR图像之后的图像永远不会使用IDR之前的图像数据来解码。一个序列就是一段内容差异不太大的图像编码后生成的一串数据流。当运动变化比较少时,一个序列可以很长,因为运动变化少就代表图像画面的内容变动很小,所以就可以是一个I帧,然后一直是P帧、B帧。当运动变化多时,一个序列可能会比较短,比如只包含一个I帧和几个P帧、B帧。

 那么IDR帧与I帧的区别是什么呢?因为H264采用了多帧预测,所以I帧之后的P帧有可能会参考I 帧之前的帧,这就使得在随机访问的时候不能以找到I帧作为参考条件,因为即使找到I帧,I帧之后的帧还是有可能解析不出来,而IDR帧 就是一种特殊的I帧,即这一帧之后的所有参考帧只会参考到这个IDR 帧,而不会再参考前面的帧。在解码器中,一旦收到一个IDR帧,就会 立即清理参考帧缓冲区,并将IDR帧作为被参考的帧。
 I和IDR帧都是使用帧内预测的。它们都是同一个东西而已,在编码和解码中为了方便,要首个I帧和其他I帧区别开,所以才把第一个首个I帧叫IDR,这样就方便控制编码和解码流程。 IDR帧的作用是立刻刷新,使错误不致传播,从IDR帧开始,重新算一个新的序列开始编码。而I帧不具有随机访问的能力,这个功能是由IDR承担。  IDR会导致DPB(DecodedPictureBuffer  参考帧列表——这是关键所在)清空,而I不会。IDR图像一定是I图像,但I图像不一定是IDR图像。一个序列中可以有很多的I图像,I图像之后的图像可以引用I图像之间的图像做运动参考。一个序列中可以有很多的I图像,I图像之后的图象可以引用I图像之间的图像做运动参考。
 对于IDR帧来说,在IDR帧之后的所有帧都不能引用任何IDR帧之前的帧的内容,与此相反,对于普通的I-帧来说,位于其之后的B-和P-帧可以引用位于普通I-帧之前的I-帧。从随机存取的视频流中,播放器永远可以从一个IDR帧播放,因为在它之后没有任何帧引用之前的帧。但是,不能在一个没有IDR帧的视频中从任意点开始播放,因为后面的帧总是会引用前面的帧 。
 收到 IDR 帧时,解码器另外需要做的工作就是:把所有的 PPS 和 SPS 参数进行更新。
 对IDR帧的处理(与I帧的处理相同):(1) 进行帧内预测,决定所采用的帧内预测模式。(2) 像素值减去预测值,得到残差。(3) 对残差进行变换和量化。(4) 变长编码和算术编码。(5) 重构图像并滤波,得到的图像作为其它帧的参考帧。
 多参考帧情况下, 举个例子 :有如下帧序列: IPPPP I P PPP ……。按照 3 个参考帧编码。
 因为“按照 3 个参考帧编码”,所以参考帧队列长度为 3 。
 遇到第二个 I 时,并不清空参考帧队列,把这个 I 帧加入参考帧队列(当然 I 编码时不用参考帧。)。再检测到其后面的 P 帧时,用到之前的 PPI 三帧做参考了。

数据压缩比

数据压缩比大约为:

I帧 : P帧 : B帧 = 7 :20 : 50

P帧和B帧极大的节省了数据量,节省出来的空间可以用来多保存一些I帧,以实现在相同码率下,提供更好的画质。

PTS和DTS

【为什么会有PTS和DTS的概念】

通过上面的描述可以看出:P帧需要参考前面的I帧或P帧才可以生成一张完整的图片,而B帧则需要参考前面I帧或P帧及其后面的一个P帧才可以生成一张完整的图片。这样就带来了一个问题:在视频流中,先到来的 B 帧无法立即解码,需要等待它依赖的后面的 I、P 帧先解码完成,这样一来播放时间与解码时间不一致了,顺序打乱了,那这些帧该如何播放呢?这时就引入了另外两个概念:DTS 和 PTS。在没有B帧的情况下,DTS和PTS的输出顺序是一样的。因为B 帧打乱了解码和显示的顺序,所以一旦存在B帧,PTS与DTS势必就会 不同。

【PTS和DTS】

先来了解一下PTS和DTS的基本概念:

DTS(Decoding Time Stamp):即解码时间戳,这个时间戳的意义在于告诉播放器该在什么时候解码这一帧的数据。 PTS(Presentation Time Stamp):即显示时间戳,这个时间戳用来告诉播放器该在什么时候显示这一帧的数据。

虽然 DTS、PTS 是用于指导播放端的行为,但它们是在编码的时候由编码器生成的。

在视频采集的时候是录制一帧就编码一帧发送一帧的,在编码的时候会生成 PTS,这里需要特别注意的是 frame(帧)的编码方式,在通常的场景中,编解码器编码一个 I 帧,然后向后跳过几个帧,用编码 I 帧作为基准帧对一个未来 P 帧进行编码,然后跳回到 I 帧之后的下一个帧。编码的 I 帧和 P 帧之间的帧被编码为 B 帧。之后,编码器会再次跳过几个帧,使用第一个 P 帧作为基准帧编码另外一个 P 帧,然后再次跳回,用 B 帧填充显示序列中的空隙。这个过程不断继续,每 12 到 15 个 P 帧和 B 帧内插入一个新的 I 帧。P 帧由前一个 I 帧或 P 帧图像来预测,而 B 帧由前后的两个 P 帧或一个 I 帧和一个 P 帧来预测,因而编解码和帧的显示顺序有所不同