704 字
4 分钟
[hisi] H.264 WebRTC 指南
引言
海思(HiSilicon)系列芯片的硬件编码器(VENC)输出标准 Annex-B 格式 H.264 码流。在 WebRTC 传输场景中,需针对 NALU 封装格式、首帧解码及弱网环境进行适配优化。本文示例基于 libdatachannel 库实现。
Waiting for api.github.com...
1. NALU 封装格式:Annex-B 与 AVCC
1.1 硬件特性 (Annex-B)
- 输出模式:流式流水线输出。
- 结构:使用
00 00 00 01或00 00 01作为 NALU 起始码。 - 动机:硬件编码器无需获知 NALU 总长度即可开始输出数据,最大限度降低编码延迟。
1.2 软件处理 (AVCC)
- 结构:使用 4 字节大端序长度字段作为 NALU 前缀。
- 优势:
- 解析效率:支持 复杂度的 NALU 边界定位。
- 降低负载:避免软件层逐字节扫描起始码( 复杂度)带来的 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 帧的发送频率,避免因大体积数据包加剧网络堵塞。
- 降低码率:根据带宽估值下调 VENC 的目标码率(
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/