iOS中H264的编码原理 - 音视频总结
I帧: 关键帧, 采用帧内压缩技术
举个栗子, 如果摄像头对着一个蜗牛拍摄, 1秒钟之内, 这个蜗牛发生的变化是非常少的, 摄像机一般一秒钟会抓取几十帧的数据, 我们看这个蜗牛这一秒钟的几十帧数据, 会感觉每一帧都几乎是一样的, 蜗牛在一秒钟里的变化实在太小了, 以至于肉眼几乎感觉不到有变化.
像动画, 是25帧/s, 一般视频文件都是在30帧/s左右, 对于一些要求比较高的, 对动作的精细有要求, 想要捕捉到完整的动作的, 高级的摄像机一般是60帧/s, 比如100米短跑时拍摄运动员的动作. 而对于像蜗牛这样一组帧它的变化很小, 为了压缩数据变小, 可以将第一帧完整的保存下来, 作为后面的帧的依赖, 这样后面的第二帧存储第一帧的差异就可以了, 以此类推. 如果没有这个关键帧, 后面要解码数据是完成不了的, 所以I帧特别关键.
P帧: 向前参考帧, 压缩时只参考前一个帧, 采用帧间压缩技术
视频的第一帧会被作为关键帧保存下来. 而后面的帧会向前依赖, 也就是第二帧依赖于第一帧, 后面所有的帧只存储前一帧的差异. 这样就能将数据大大的减少, 从而达到一个高压缩率的效果.
B帧: 双向参考帧, 压缩时既参考前一帧也参考后一帧, 采用帧间压缩技术
-
B帧, 即参考前一帧, 也参考后一帧, 这样使得它的压缩率更高, 存储的数据量更小, 因为前一帧和后一帧有的数据, 都可以不用存储了, 所以为了数据更小, 可以使用B帧. 使用B帧的数量越多, 你的压缩率就越高, 这是B帧的优点.
-
B帧的缺点就是, 在实时互动直播中, B帧要参考后面的帧才能解码, 那在网络传输中就要等待后面的帧传输过来. 这样子的话, 解码的快慢就跟网络有关了, 如果网络好, 解码就快一些, 如果网络不好解码就慢一些, 丢包时还要等待重传, 等待时间的长短,就要看当时的网络情况了, 这对于实时互动直播是无法忍受的, 所以对于实时互动直播, 一般不会使用B帧.
-
有了B帧, 我们就可以根据情况选择使用了, 比如在泛娱乐直播中, 可以接受一定程度的延时, 又需要比较高的压缩比就可以使用B帧.
GOF(Group of Frame)或者说GOP(Group of Picture)一组帧
如果在一秒钟内, 有30帧, 这30帧可以画成一组, 如果摄像机或者镜头它一分钟内都没有发生变化, 那也可以把这一分钟内所有的帧画做一组.
什么叫一组帧?
就是一个I帧到下一个I帧, 这一组的数据, 包括B帧/P帧, 我们称为GOF.
SPS/PPS
SPS/PPS 实际上就是存储 GOP 的参数, 存储着GOP的相关信息, 没有这些信息, 我们的解码工作就无法顺利做好
SPS(Sequence Parameter Set, 序列参数集)存放帧数, 参考帧数目, 解码图像尺寸, 帧场编码模式选择标识等.
PPS(Picture Parameter Set, 图像参数集), 存放熵编码模式选择标识, 片组数目, 初始量化参数和去方块滤波系数调整标识等(与图像相关的信息)
在一组帧之前我们首先收到的是SPS/PPS数据, 如果没有这2组数据我们是无法解码的, 如果我们在解码时发生错误, 首先要检查是否有SPS/PPS, 如果没有, 可能是因为没有发送过来, 或者是发送过程中丢失了. SPS/PPS数据, 我们也将其归类到I帧, 这2组数据是绝对不能丢的.
视频花屏/卡顿的原因
我们在观看视频时, 如果遇到花屏/卡顿现象, 一般都是GOF的问题
- 如果GOF分组中的P帧丢失, 就会造成解码端的图像发生错误.
- 为了避免发生花屏, 一般发现P帧或I帧丢失, 就不显示本GOF内的所有帧, 等到下一个I帧过来后才重新刷新图像
- 这是因为没有刷新屏幕, 而且丢包的这一组帧全部扔掉了, 图像就会卡住那里不动, 这就是卡顿的原因.
所以总结起来就是, 花屏是因为丢失了数据. 而卡顿是因为怕花屏, 而主动把数据丢了, 从而产生了卡顿.
视频都有哪些视频编解码器
x264/x265
x264是目前使用最广泛的编解码器, 它的性能非常优秀, 如果使用软编的话, 基本上都是用的x264. x265也在走向成熟, 在直播系统里, 因为它的压缩比非常高, 所以占用的CPU也非常高, 就目前来说, 在直播系统里是不可用的. 在点播系统里可以尝试使用x265了.
openH264
相对于X264性能要低一些, 但是它有一个特点, 支持SVC视频技术, 就是将视频分层传输, 将视频数据分为小中大三个部分, 如果网络差, 就只传输最小的内核视频帧. 如果网络稍微好点就将中间的一层也传输过去, 如果网络很好, 就把全部的三层都传输过去, 然后可以将三层数据叠加在一起就形成了原来的视频. 如果只有最小的内核层, 只能看到图像的大概信息, 这是不清晰的, 每加一层就清晰一些.
缺点是SVC在移动端不是一个标准, 很多硬件都不支持, 如果使用SVC就不能使用硬编码, 只能使用软编码, 这对CPU的消耗相当大, 就会造成手机容易发烫、耗电等问题.
vp8/vp9
由谷歌退出, vp8对应的是x264, vp9对应的是x265.
H.265(H.264的升级版)
H.265是一种新的视频压缩标准, 核心价值是在原来带宽条件下传输更高质量的网络视频. 只需要原先一半左右的带宽即可播放相同质量的视频.
H.265编码后的结果是我们想要的, 但是在编码过程中, H.265比H.264的复杂度高很多, 所需要功耗更大, 耗时更长, 也就对设备要求更高, 而且还有目前的主流浏览器不支持H.265, 这就导致了即使H.265有着很大的优势, 也没有取代H.264成为主流.