视频编码基础:I帧、P帧 和 B 帧

I 帧、P 帧和 B 帧的概念是视频压缩领域的基础。这三种帧类型在特定情况下用于提高编解码器的压缩效率、压缩流的视频质量以及流对传输和存储错误和故障的恢复能力。

在本文中,我们将了解 I 帧、P 帧和 B 帧的工作原理以及它们的用途。

目录

1. 帧内预测和帧间预测

2. 什么是I帧?

3. 什么是P帧?

4. 什么是B帧? 

5. 参考B帧和非参考B帧

6. 在视频压缩/流化中使用I、P和B帧

6.1 在哪里使用I帧?

6.2 刷新视频质量

6.3 恢复比特流错误

6.4 Trick Modes(快进快退)

6.5 在哪里使用P帧和B帧?

7. 结论


1. 帧内预测和帧间预测

在本篇文章中,我并不会深入讲解帧内预测和帧间预测(Intra and Inter-prediction)的技术细节,但是我会告诉你它们为何存在以及有什么用处。

以下方图片为例。图片显示了两个视频帧(彼此相邻),有一个黑色像素的矩形块在其中移动。在第一帧中,该块位于图像的左侧,而在第二帧中,它已经移到了右侧。 

如果我想用现代视频编码器(如H.264或HEVC)压缩帧2,我会这样做:

  1. 将视频分解为多个像素块(宏块),并逐一压缩。
  2. 为了压缩每个宏块,首先在当前帧和前后帧中搜索,找到与我们想要压缩的宏块相似的宏块。
  3. 记录最佳匹配的宏块的位置(位于哪一帧以及在该帧中的位置)。然后,两个宏块之间的差异被压缩,并和位置信息一起被发送给解码器。

请看下方图片。如果要压缩帧2中的宏块(已用红色方框标记),你认为最佳方法是什么?该怎么做?

图片

  1. 首先,我可以查看帧1,并找到相匹配的宏块。它似乎移动了一个帧宽(我知道要少一些)的距离,并与帧2中像素块的高度大约相同。好的,运动矢量出现了。
  2. 我在同一帧内搜索,并很快发现,位于红色方框标记的宏块与上方的宏块相同。所以,我可以让解码器复制这一宏块,而不必再去其他帧搜索。这样一来,运动矢量便是最小的(如果存在的话)。

现在我们来看下一个示例。如果想要压缩帧2中包含蓝色球体的宏块,我们该怎么做呢?

在同一帧内搜索,还是在前面的编码帧中搜索?

图 24

  1.  首先,我可以查看第 1 帧并找到匹配的球体。它似乎移动了大约框架宽度的距离(我知道少一点)并向上移动了一点。这给了我们运动矢量。包含球体的两个块之间的差异似乎非常小(猜测!)
  2. 其次,我可以在同一帧内搜索并意识到没有其他块包含球体。因此,在同一帧内搜索匹配项的运气不好!

从上面那些示例中,我们都学到了什么?

1.编码器搜索匹配宏块以减少需要传输的数据的大小,整个过程通过运动估计和补偿来完成,这使得编码器可以在另一帧内发现宏块的水平和垂直位移。

2.编码器可以在同一帧内(帧内预测)和相邻帧内(帧间预测)搜到匹配的宏块。

3.它比较每个宏块的帧间和帧内预测结果,并选出最佳结果。这个过程被称为“模式选择”,我认为这是视频编码器最核心的部分。

现在,看完对帧内预测和帧间预测的快速介绍,让我们来学习I帧、P帧和B帧吧!

2. 什么是I帧?

I帧或关键帧或帧内帧(I-frame or Key-Frame or Intra-frame)仅由帧内预测的宏块组成。

I帧中的每个宏块只能在同一帧内匹配其他宏块,这意味着,它只能利用帧内“空间冗余”来进行压缩。空间冗余是一个术语,用来指单个帧的像素之间的相似性。

I帧在不同的视频编解码器中以不同的形式出现,如IDR、CRA或者BLA。这些不同类型的I帧本质相同:都不存在时域预测。

I帧有很多用处,在我们学习P帧和B帧之后,我们再来研究。

3. 什么是P帧?

P帧代表预测帧,除了空域预测以外,它还可以通过时域预测来进行压缩。P帧参考前面的帧进行运动估计。P帧中的每个宏块都可以被:

  • 时域预测
  • 空域预测
  • 跳过(skipped)(是指让解码器复制前一帧内的位于相同位置的宏块——0运动向量)

图片

我做了一个插图来说明重点。您可以在上图中看到 I 帧和 P 帧。P-帧是指前面讨论过的先前编码的 I/P-帧。您还可以看到帧编码/解码的顺序与它们呈现给用户的方式相同。这是因为 P 帧仅参考先前编码的图片。

4. 什么是B帧? 

B帧可以参考在其前后出现的帧。B帧中的B就代表双向(Bi-Directional)。如果你的视频编解码器使用基于宏块的压缩(如H.264/AVC所做的一样),那么B帧中的每个宏块都可以:

  • 后向预测(使用未来的帧)
  • 前向预测(使用过去的帧)
  • 无帧间预测,仅帧内预测
  • 完全跳过(帧内或帧间预测)

由于B帧可以参考和插入在它之前和之后发生的两个(或更多)帧(在时间维度上),所以它可以显著降低帧的大小,同时保持视频质量。B帧能够利用空间冗余和时间冗余(未来的帧和过去的帧),这使得它在视频压缩中非常有用。

但是,B帧是资源密集型——无论是从编码侧还是解码侧看,让我们来看看原因。

想要理解B帧的作用,我们需要先理解呈现/显示顺序和解码顺序的概念。

以I帧和P帧为例。如果你只使用这两种类型的帧,那么每一帧要么参考自身(I 帧),要么参考前一帧(P 帧)。因此,帧可以以相同的顺序进出编码器。这里,呈现顺序(或显示顺序)与编码、解码顺序相同。

图片

但如果某一帧要参考未来显示的一帧,你要怎么做呢?这是我们在使用B帧压缩时经常遇到的情况。下图中显示了一个GOP(group of pictures)结构,GOP是一组连续的画面,在每一个mini-GOP中,都使用了两个B帧和一个P帧,也就是IBBPBBP。

图片

解码器端也是如此操作。

按照解码顺序,解码器先解码帧1(I帧),然后是帧2(P帧)。但它却无法显示帧2,因为在解码顺序中的实际上是帧4!所以,解码器需要将帧2(按解码顺序)放入缓冲区,然后等待显示它的时机。

所以,编码器和解码器需要在内存中维护两个“顺序”或“序列”:一个将帧放置在正确的显示顺序中,另一个用于将帧按照编码和解码所需顺序放置。

由于重新排序的要求,B帧会影响解码器缓冲区的大小,并增加延迟。

这就是为什么许多系统在压缩一个B帧时,对可用作参考的帧数做出严格的限制的原因。按照同样的思路,H.264/AVC的Baseline profile因为瞄准低端设备的,所以不允许使用B帧或Slice。

5. 参考B帧和非参考B帧

 我们在上文中学过,B帧可以参考两帧或者多帧,通常,(根据其位置)一帧在前,一帧在后。我们也已知道,I帧不参考任何帧,P帧只参考前面的帧。那么问题来了——任何帧都能使用B帧作为它的参考帧吗?

答案是肯定的。

  • 如果B帧可以作为参考帧,它就被称为参考B帧。

  • 如果B帧不用作参考帧,它便被称为非参考B帧。

在比特流中标明参考B帧和非参考B帧非常重要,因为解码器需要在DBP(Decoded Picture Buffer,解码图像缓存)中存储参考帧。

如果某一帧被标记为非参考B帧,但却将其用作参考帧,那么解码器很可能崩溃。因为解码器大概率在解码和显示之后就已经删除此帧。

与非参考B帧相比,大部分解码器在量化参考B帧时会获得更好的质量,从而减少传播损失。

6. 在视频压缩/流化中使用I、P和B帧

在理解了I帧、P帧和B帧的工作原理之后,我们来解决一个重要问题:为什么要使用它们?

在下面内容中,我们会学习I帧、P帧和B帧在视频压缩中最重要的用例。

6.1 在哪里使用I帧?

我们在前面的部分了解到,I帧可以被独立地编码、解码,这使得它在视频压缩中得到广泛应用。

6.2 刷新视频质量

I帧的插入通常表示GOP(或视频片段)的结束。I帧压缩不依靠前一帧编码,从而可以刷新视频质量。正因为I帧在保持视频质量方面有如此重要的作用,所以通常情况下,编码器会在大小和质量方面偏向I帧。在编码高质量的I帧后,编码器便可以使用该I帧作为参考图像来压缩P帧和B帧。

那I帧只能用于刷新视频质量吗?不仅如此。

6.3 恢复比特流错误

我们之前说过,I帧可以被独立地编码和解码。这意味着I帧可用于恢复视频文件或视频流中的灾难性故障。

我们来看看是它是如何做到的。

如果P帧和参考B帧遭到破坏,其他所有依赖于它们的帧就不能完整解码,这会直接导致视频故障。视频通常无法从此类问题中恢复。然而,当被破坏的视频流到达I帧,因为I帧被独立地编码解码,所以视频问题可以从I帧恢复。

这种I帧通常被称为IDR帧(Instantaneous Decoder Refresh,即时解码刷新),并且这种不参考I帧之前图像的行为被称为闭合GOP(Closed GOP)。

IDR帧通常在ABR流中表示视频的某个新片段。由IDR帧开始,平台可以确保新片段能够独立于其他片段被解码。即使由于传输问题导致一些片段损坏或丢失,这一特性也能保证视频可以继续播放。

6.4 Trick Modes(快进快退)

最后,关键帧对于Trick Modes来说至关重要!

如果想在一个视频中快进快退,则在视频开始时需要一个I帧,对吧?

假设你搜索到的是P帧或者B帧,但解码器已经从内存中删除了参考帧,你该怎么重建它们呢?视频播放器很自然地会找到一个起始点(I帧)并成功解码,然后从这一点开始播放。

这又引出另一个有趣的事情。

如果你的关键帧在视频中相隔时间很长,假设它们之间间隔20秒,那么你的用户只能以20秒为增量进行快进快退,这样的体验非常糟糕!

如果关键帧放置太多,那么虽然快进快退体验会很棒,但这时候视频就太大了,可能导致网路缓冲等问题。

所以设计出最佳的GOP和mini-GOP结构真的是一项平衡的艺术。

6.5 在哪里使用P帧和B帧?

人们经常会问:在哪里、什么时候以及如何使用P帧和B帧?

如果你已经理解上文中所描述的P帧和B帧的工作原理,那么你就知道P帧和B帧可以在减少视频大小的同时,保证视频质量。这就是它们的主要用途!在合适的位置插入P帧和B帧可以减小视频文件尺寸或者比特率,并且仍能保持一定的视频质量水平。

基于你所使用的GOP和mini-GOP结构,使用相关QP值压缩P帧和B帧(被参考或者不被参考),你就可以达到目标比特率或视频质量。

7. 结论

我希望这篇关于I帧、P帧和B帧的文章能够帮助你增加关于视频压缩的知识。想要更深入地理解它们,你可以下载静态编译好的 FFmpeg 版本,并在 FFmpeg 中使用 GOP、no-b-frame 相关设置来查看视频的大小及其质量如何变化。

  • 15
    点赞
  • 56
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值