这是我参与12月更文挑战的第14天,活动详情查看:2021最后一次更文挑战
在之前文章介绍流类型的时候,我有顺带提到过 H.264 相关知识,最近因为视频播流花屏问题,我又再次踏上了研究 H.264 解码的路程。
大家平时可能对视频播流这一块了解比较少,我也是一样的,那么后面的几天,让我们一起来尝试解决花屏问题,今天先从streamer端给出的解决方案,以及解决方案里的名词来学习起来。
streamer端给出的解决方案
对于花屏问题,streamer端的说法有以下两点:
- streamer端改成只 cache SPS、PPS ,不 cache 最近 I帧 ,建议SDK端在收到第一帧之前将 P帧 都丢掉,不要往解码器里送,这样可以避免掉花屏。
- SDK端有没有 flush render 的操作,将显示的额 buffer 清空。
对H.264有了解的同学,对I帧、P帧、B帧一定也不陌生,我来给大家讲一下我理解的I帧、P帧、B帧:
I帧、P帧、B帧
- 在 H.264 协议里定义了三种帧,完整编码的帧叫 I帧 ,参考之前的 I帧 生成的只包含差异部分编码的帧叫 P帧 ,还有一种参考前后的帧编码的帧叫 B帧 。
- 在 H.264 中图像以序列为单位进行组织,一个序列是一段图像编码后的数据流,以 I帧 开始,到下一个 I帧 结束。
I帧(关键帧、基础帧)
- I帧 是帧内编码帧 ,表示关键帧;
- 是 P帧 和 B帧 的参考帧;
- I帧 所占数据的信息量比较大(可以通过这个特点,在ws连接传输的视频流中,肉眼找到I帧位置)。
- 当解码器解码到 I帧 时,将已解码的数据全部输出或抛弃,重新查找参数集,开始一个新的序列。这样如果前一个序列出现重大错误,在这里可以获得重新同步的机会。
P帧(差别帧)
- P帧 表示的是这一个 P帧 跟之前的一个 P帧 的差别(也就是差别帧),解码时需要用之前缓存的画面叠加上本帧定义的差别,生成最终画面。( P帧 没有完整画面数据,只有与前一帧的画面差别的数据);
- P帧 是 I帧 后面相隔1~2帧的编码帧,以 I帧 为参考帧;
- 由于是参考帧,可能造成解码错误的扩散;
- 压缩比较高。
B帧(双向差别帧)
- B帧 记录的是本帧与前后帧的差别;
- 是由前面的 I或P帧 和后面的 P帧 来进行预测的;
- 不是参考帧,不会造成解码错误的扩散;
- 压缩比最高。
其实 I帧、P帧、B帧 并不仅限于以上几条,以上只是其一些比较简单的特性,便于大家快速理解什么是 I帧、P帧、B帧 ,以方便我们后续对问题进行分析和解决。
一般大家解 H.264 类型的视频流,都会以 I帧 做为基础帧,以 I帧 预测 P帧 ,再由 I帧 和 P帧 预测 B帧, 但是此次streamer要求改成只 cache SPS、PPS ,不 cache 最近 I帧,让我有些不理解,下期文章我们可能会对 SPS、PPS 进行进一步了解,后续进行分析解码时,为什么要cache SPS、PPS 而不是 cache 最近 I帧。