704 字
4 分钟
[hisi] H.264 WebRTC 指南

引言#

海思(HiSilicon)系列芯片的硬件编码器(VENC)输出标准 Annex-B 格式 H.264 码流。在 WebRTC 传输场景中,需针对 NALU 封装格式、首帧解码及弱网环境进行适配优化。本文示例基于 libdatachannel 库实现。

paullouisageneau
/
libdatachannel
Waiting for api.github.com...
00K
0K
0K
Waiting...

1. NALU 封装格式:Annex-B 与 AVCC#

1.1 硬件特性 (Annex-B)#

  • 输出模式:流式流水线输出。
  • 结构:使用 00 00 00 0100 00 01 作为 NALU 起始码。
  • 动机:硬件编码器无需获知 NALU 总长度即可开始输出数据,最大限度降低编码延迟。

1.2 软件处理 (AVCC)#

  • 结构:使用 4 字节大端序长度字段作为 NALU 前缀。
  • 优势
    • 解析效率:支持 O(1)O(1) 复杂度的 NALU 边界定位。
    • 降低负载:避免软件层逐字节扫描起始码(O(N)O(N) 复杂度)带来的 CPU 开销。

2. 关键业务逻辑实现#

2.1 SEI 过滤 (Type 6)#

海思编码器常在码流中插入补充增强信息(SEI)。由于部分 WebRTC 客户端(如 Chrome)对非标准 SEI 兼容性较差,建议在应用层将其过滤。

2.2 首帧解码保证#

WebRTC 会话建立后的首包数据必须包含关键帧及解码参数:

  • SPS/PPS 注入:应用层需缓存最新的 SPS (Type 7) 与 PPS (Type 8)。
  • 聚合发送:在检测到 IDR 帧 (Type 5) 时,将 SPS、PPS 与 IDR 帧顺序拼接后统一发送,确保解码器可完成初始化。

2.3 格式转换最佳实践#

建议在应用层解析 Annex-B 码流,提取 NALU 长度信息,并配置传输库(如 libdatachannel)使用 AVCC (Length-prefixed) 模式发送,以优化传输路径性能。

3. 弱网环境处理#

3.1 丢包补救 (PLI)#

  • 现象:参考帧损坏导致画面花屏。
  • 机制:接收端触发 RTCP PLI 请求。
  • 实现:调用 HI_MPI_VENC_RequestIDR 接口产生新 IDR 帧,并同步发送缓存的 SPS/PPS。

3.2 拥塞控制 (BWE)#

  • 现象:网络带宽不足导致延迟升高或丢包。
  • 实现
    • 降低码率:根据带宽估值下调 VENC 的目标码率(u32MaxBitRate)。
    • 调整帧率:必要时降低编码帧率以维持单帧质量。
    • 注意:拥塞状态下应限制 IDR 帧的发送频率,避免因大体积数据包加剧网络堵塞。

4. 发送逻辑示例 (C++)#

// 配置 AVCC 模式
auto packetizer = make_shared<H264RtpPacketizer>(
NalUnit::Separator::Length{4},
rtpConfig,
1200
);
void handleHisiFrame(const vector<uint8_t>& nalu, uint32_t ts) {
uint8_t type = nalu[0] & 0x1F;
if (type == 6) return; // 过滤 SEI
if (type == 7) { cached_sps = nalu; return; }
if (type == 8) { cached_pps = nalu; return; }
if (type == 5) {
// 构造 AVCC 聚合包: [Len][SPS] + [Len][PPS] + [Len][IDR]
sendAggregatedIDR(cached_sps, cached_pps, nalu, ts);
} else {
sendSinglePFrame(nalu, ts);
}
}

5. 调试建议#

  • 状态检查:通过 chrome://webrtc-internals 确认 framesDecoded 状态。
  • MTU 优化:针对高清分辨率,建议将 RTP MTU 限制在 1200 字节以内,避免 IP 层分片。
[hisi] H.264 WebRTC 指南
https://www.eustia-astraea.top/posts/hisi/h264-webrtc-debug-guide/
作者
mcsl
发布于
2025-01-25
许可协议
CC BY-NC-SA 4.0