WWDC Quick Look 💓 By SwiftGGTeam
Explore low-latency video encoding with VideoToolbox

Explore low-latency video encoding with VideoToolbox

观看原视频

Highlight

VideoToolbox 新增低延迟 H.264 硬件编码模式,消除帧重排、码率控制器快速适应网络变化,720p@30fps 可减少约 100ms 延迟,支持时域可伸缩性和长期参考帧。

核心内容

你开发了一个视频会议应用。用户反馈说对话有延迟,经常互相打断。延迟来自哪里?

视频编码器内部通常有帧重排缓冲(为了用 B-frame 提高压缩效率),这引入了 3-5 帧的延迟。码率控制器对网络变化的响应也比较慢。这些加在一起,端到端延迟可能超过 200ms。

VideoToolbox 的新低延迟模式专门解决这个问题。

详细内容

低延迟模式的工作原理

02:05

低延迟模式做两个核心优化:

  1. 消除帧重排。采用一进一出的编码模式,每帧输入后立即编码输出,不等待后续帧。
  2. 快速码率适应。码率控制器对网络变化响应更快,减少拥塞导致的延迟。

对于 720p@30fps 视频,低延迟模式可以减少约 100ms 的延迟。这在视频会议中非常关键。

03:14

关键点:

  • 低延迟模式始终使用硬件加速编码
  • 只支持 H.264 编码
  • iOS 和 macOS 都支持
  • 压缩效率比默认模式略低,但延迟显著降低

启用低延迟模式

05:03

启用方式很简单,只需要在创建 compression session 时设置一个 flag:

var encoderSpecification: CFMutableDictionary = CFDictionaryCreateMutable(
    kCFAllocatorDefault,
    0,
    &kCFTypeDictionaryKeyCallBacks,
    &kCFTypeDictionaryValueCallBacks
)

// 启用低延迟码率控制
CFDictionarySetValue(
    encoderSpecification,
    kVTVideoEncoderSpecification_EnableLowLatencyRateControl,
    kCFBooleanTrue
)

// 创建 compression session
let session = VTCompressionSessionCreate(
    allocator: kCFAllocatorDefault,
    width: 1280,
    height: 720,
    codecType: kCMVideoCodecType_H264,
    encoderSpecification: encoderSpecification,
    imageBufferAttributes: nil,
    compressedDataAllocator: nil,
    outputCallback: outputHandler,
    refcon: &context,
    compressionSessionOut: &session
)

// 配置码率(和平时一样)
VTSessionSetProperty(
    session,
    key: kVTCompressionPropertyKey_AverageBitRate,
    value: 2000000 as CFNumber  // 2 Mbps
)

05:03

关键点:

  • kVTVideoEncoderSpecification_EnableLowLatencyRateControl 启用低延迟模式
  • 其他配置(码率、分辨率)和平时一样
  • 编码器自动使用硬件加速
  • 输出回调中接收编码后的帧

新 Profile 支持

06:10

低延迟模式新增两个 profile:

  • Constrained Baseline Profile (CBP):用于低成本应用,兼容性最好
  • Constrained High Profile (CHP):压缩比更高,适合带宽受限场景
// 使用 Constrained Baseline Profile
VTSessionSetProperty(
    session,
    key: kVTCompressionPropertyKey_ProfileLevel,
    value: kVTProfileLevel_H264_ConstrainedBaseline_AutoLevel
)

// 使用 Constrained High Profile
VTSessionSetProperty(
    session,
    key: kVTCompressionPropertyKey_ProfileLevel,
    value: kVTProfileLevel_H264_ConstrainedHigh_AutoLevel
)

07:35

关键点:

  • CBP 兼容性最好,几乎所有解码器都支持
  • CHP 压缩效率更高
  • 根据对方解码能力选择 profile
  • AutoLevel 让编码器自动选择 level

时域可伸缩性

07:54

多方视频会议中,每个接收方的带宽不同。传统做法是为每个接收方编码不同的码流,效率低。

时域可伸缩性只编码一个码流,但把帧分成两层:

  • Base layer:包含一半帧率,可以独立解码
  • Enhancement layer:补充帧,和 base layer 一起提供完整帧率
// 设置 base layer 帧率比例
VTSessionSetProperty(
    session,
    key: kVTCompressionPropertyKey_BaseLayerFrameRateFraction,
    value: 0.5 as CFNumber  // 一半帧给 base layer
)

// 设置 base layer 码率比例
VTSessionSetProperty(
    session,
    key: kVTCompressionPropertyKey_BaseLayerBitRateFraction,
    value: 0.6 as CFNumber  // 60% 码率给 base layer
)

11:15

关键点:

  • base layer 帧率是输入的一半
  • base layer 码率建议占总码率的 60%-80%
  • 低带宽接收方只收 base layer
  • 高带宽接收方收 base + enhancement layer
  • enhancement layer 的帧丢失不影响其他帧

最大帧量化参数

12:26

帧 QP(Quantization Parameter)控制图像质量和码率。QP 越低,质量越高,码率越大。

低延迟模式下,你可以设置最大允许 QP,防止编码器在复杂场景下过度降低质量。

VTSessionSetProperty(
    session,
    key: kVTCompressionPropertyKey_MaxAllowedFrameQP,
    value: 30 as CFNumber  // QP 上限为 30
)

14:22

关键点:

  • QP 范围是 1-51
  • 设置上限后,编码器不会使用更高的 QP
  • 如果码率预算不足,编码器会丢帧而不是降低质量
  • 适合屏幕共享等需要清晰文字的场景

长期参考帧(LTR)

14:45

网络丢包后,解码器需要请求刷新帧。传统做法是发送 I-frame(关键帧),但 I-frame 很大,在网络差时可能加重拥塞。

LTR 用更小的预测帧(LTR-P)替代 I-frame 做刷新。

// 启用 LTR
VTSessionSetProperty(
    session,
    key: kVTCompressionPropertyKey_EnableLTR,
    value: kCFBooleanTrue
)

// 编码器在输出中标记需要确认的 LTR 帧
// 应用层收到确认后,通过 AcknowledgedLTRTokens 告知编码器

// 请求刷新帧
VTSessionSetProperty(
    session,
    key: kVTCompressionPropertyKey_ForceLTRRefresh,
    value: kCFBooleanTrue
)

17:07

关键点:

  • LTR 帧比普通 P-frame 稍大,但比 I-frame 小得多
  • 应用层负责帧确认和重试逻辑
  • 没有已确认的 LTR 时,编码器回退到 I-frame
  • 适合网络不稳定的场景

核心启发

  1. 为视频会议应用启用低延迟编码。一行配置减少约 100ms 延迟。入口 API:kVTVideoEncoderSpecification_EnableLowLatencyRateControl

  2. 用时域可伸缩性优化多方会议。一个码流服务不同带宽的接收方,比编码多个码流省电。入口 API:kVTCompressionPropertyKey_BaseLayerFrameRateFraction

  3. 为屏幕共享设置最大 QP。防止文字和 UI 在复杂场景下变模糊。入口 API:kVTCompressionPropertyKey_MaxAllowedFrameQP

  4. 用 LTR 提升弱网恢复能力。丢包后用 LTR-P 帧刷新,比 I-frame 更快到达。入口 API:kVTCompressionPropertyKey_EnableLTR

  5. 根据对方解码能力选择 profile。和低端设备通信用 CBP,和高端设备通信用 CHP。入口 API:kVTCompressionPropertyKey_ProfileLevel

关联 Session

评论

GitHub Issues · utterances