1、引言
调用系统 VideoToolbox 的 API 实现一个硬编很容易,仔细看看文档、了解 API 的使用实现一个基本功能相信难不倒大家。但实际工作中有许多细节,一不注意就会掉坑里,甚至有些系统性问题难以解决。本文一方面会介绍必备的基础知识,带大家对编码有一个基本的认识,另一方面也会分享直播 SDK 在 VT 硬编实现上遇到的问题和解决方案,希望能帮助到大家。
2、必备基础知识
2.1 帧概念
-
I 帧(帧内编码图像帧)即帧内(Intra)图像,采用帧内编码,不参考其它图像,但可作为其它类型图像的参考帧。
-
P 帧(预测编码图像帧)即预测(Predicted)图像,采用帧间编码,参考前一幅 I 或 P 图像,用作运动补偿。
-
B 帧(双向预测编码图像帧)即双向预测(Bi-predicted)图像,提供最高的压缩比,它既需要之前的图像帧( I 帧或 P 帧),也需要后来的图像帧( P 帧),采用运动预测的方式进行帧间双向预测编码。
2.2 时间戳
-
PTS:显示时间戳,主要用于视频的同步和输出,在渲染的时候使用,在没有 B frame 的情况下 DTS 和 PTS 的输出顺序是一样的。
-
DTS:解码时间戳,主要用于视频的解码,在解码阶段使用。
-
CTS = PTS - DTS。
示例:
| gop | I | B | B | P | B | B | P |
|---|---|---|---|---|---|---|---|
| 显示顺序 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
| 解码顺序 | 1 | 3 | 4 | 2 | 6 | 7 | 5 |
| PTS | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
| DTS | 1 | 3 | 4 | 2 | 6 | 7 | 5 |
2.3 GOP & Reference
GOP:一段时间内图像变化不大的图像集我们就可以称之为一个序列,gop 就是一组视频帧,其中第一个 I 帧我们称为是 IDR 帧。
Reference:参考周期,指两个 P 帧之间的距离,iOS 硬件编码器中无法指定。
2.4 IDR
一个 GOP 的第一个帧称 IDR 帧(立即刷新帧),IDR 帧的作用是立刻刷新,使错误不致传播。从 IDR 帧开始, 重新算一个新的序列开始编码。而 I 帧不具有随机访问的能力,这个功能是由 IDR 承担。IDR 帧会导致 DPB (DecodedPictureBuffer 参考帧列表——这是关键所在)清空,而 I 不会。
IDR 帧一定是 I 图像,但 I 帧不一定是 IDR 图像。一个序列中可以有很多的 I 帧图像,I 帧图像之后的图像可以引用 I 帧图像之间的图像做运动参考。
2.5 码率控制
-
ABR:平均目标码率,简单场景分配较低 bit,复杂场景分配足够 bit,使得有限的 bit 数能够在不同场景下合理分配,这类似 VBR。同时一定时间内,平均码率又接近设置的目标码率,这样可以控制输出文件的大小,这又类似 CBR。可以认为是 CBR 和 VBR 的折中方案,这是大多数人的选择。特别在对质量和视频带宽都有要求的情况下,可以优先选择该模式,一般速度是 VBR 的两倍到三倍,相同体积的视频文件质量却比 CBR 好很多。
-
适用场景:ABR 在直播和低延时系统用的比较多,因为只编码了一次,所以速度快,同时兼顾了视频质量和带宽,对于转码速度有要求的情况下也可以选择该模式。
-
特点:视频质量整体可控,同时兼顾了视频码率和速度,是一个折中方案,实际用的比较多;使用过程一般要让调用方设置,最低码率、最高码率和平均码率,这些值要尽可能设置合理点。
-
-
VBR:(Variable Bit Rate)可变码率,简单场景分配比较大的 QP,压缩率小,质量高。复杂场景分配较小 QP。得到基本稳定的视觉质量,因为人眼本来就对复杂场景不敏感,缺点在于输出码率大小不可控。
-
适用场景:VBR 适用于那些对带宽和编码速度不太限制,但是对质量有很高要求的场景。特别是在运动的复杂场景下也可以保持比较高的清晰度且输出质量比较稳定,适合对延时不敏感的点播,录播或者存储系统。
-
特点:码率不稳定,质量基本稳定且非常高;编码速度一般比较慢,点播、下载和存储系统可以优先使用,不适合低延时、直播系统;这种模型完全不考虑输出的视频带宽,为了质量,需要多少码率就占用多少,也不太考虑编码速度。
-
-
CBR:(Constant Bit Rate)恒定码率,一定时间范围内比特率基本保持的恒定,属于码率优先模型。
-
适用场景:一般也不建议使用这种方式,虽然输出的码率总是处于一个稳定值,但是质量不稳定,不能充分有效利用网络带宽,因为这种模型不考虑视频内容的复杂性,把所有视频帧的内容统一对待。但是有些编码软件只支持固定质量或者固定码率方式,有时不得不用。用的时候在允许的带宽范围内尽可能把带宽设置大点,以防止复杂运动场景下视频质量很低,如果设置的不合理,在运动场景下直接就糊了。
-
特点:码率稳定,但是质量不稳定,带宽有效利用率不高,特别当该值设置不合理,在复杂运动场景下,画面非常模糊,非常影响观看体验。
-
2.6 编码数据裸流
H264 的码流结构它主要有两种格式:Annex B 和 AVCC。Annex B 格式以 0x000001 或 0x00000001 开头,AVCC 格式以所在的 NALU 的长度开头,以 Annex B 为例。

但对于一个 H.264 裸流来说,就是一系列 NALU 的集合 ,每个 NALU 既可以表示图像数据,也可以表示处理图像所需要的参数数据。

NALU结构分为视频编码层(VCL)和网络适配层(NAL):
视频编码层( VCL 即 Video Coding Layer) :负责高效的视频内容表示,这是核心算法引擎,其中对宏块、片的处理都包含在这个层级上,它输出的数据是 SODB 。
网络适配层( NAL 即 Network Abstraction Layer) :以网络所要求的恰当方式对数据进行打包和发送,比较简单,先报 VCL 吐出来的数据 SODB 进行字节对齐,形成 RBSP ,最后把 RBSP 数据前面加上 NAL 头则组成一个 NALU 单元。
NALU = NALU Header + RBSP

但严格来讲 NALU = NALU Header + EBSP,而 EBSP = 防竞争的 RBSP,H.264 规范规定,编码器吐出来的数据需要在每个 NALU 添加起始码:0x00 00 01或者0x00 00 00 01, 用来指示一个 NALU 的起始 ,0x000000 时,也可以表示当前 NALU 的结束,如果 NALU 内部存在 0x00 00 01 or 0x00

本文介绍了iOS VideoToolbox的硬编基础知识,包括帧概念、时间戳、GOP、IDR、码率控制和编码数据裸流。详细讲解了VideoToolbox的使用方法,分享了在实际开发中遇到的坑,如属性设置失败、Gop不符合预期、编码卡死、码率编不上去等问题,并给出了相应的解决方案。最后总结了编码知识和VideoToolbox的实践经验,为开发者提供参考。
最低0.47元/天 解锁文章
283

被折叠的 条评论
为什么被折叠?



