编码器抽象与编解码器 · VP8/VP9/AV1/H264/H265

WebRTC 用统一的 VideoEncoder 接口抽象各种编解码器,底下接 VP8、VP9、AV1、H264、H265。这一章读 video_codecs/video_encoder.h 的 InitEncode/Encode/SetRates,讲清这层抽象、编码器工厂、以及各编解码器的取舍。

作者 David更新于 第 54 篇(共 112 篇)

编码器抽象与编解码器 · VP8/VP9/AV1/H264/H265

准备好的帧交给编码器压缩。WebRTC 支持一大堆编解码器,但上层不想为每种写一套代码——于是有了统一的 VideoEncoder 抽象(api/video_codecs/video_encoder.h)。这一章看这层抽象和它下面的编解码器们。

VideoEncoder:统一接口

VideoEncoder 是所有视频编码器的公共接口,核心就三个方法:

// api/video_codecs/video_encoder.h(节选)
class RTC_EXPORT VideoEncoder {
  virtual int InitEncode(const VideoCodec* codec_settings, ...);  // 初始化
  virtual int32_t Encode(const VideoFrame& frame, ...);           // 编码一帧
  virtual void SetRates(const RateControlParameters& parameters); // 设目标码率/帧率
  // 编码结果通过 EncodedImageCallback 异步回调
};

VideoEncoder 把「五花八门的编解码器」收敛成一个统一契约:InitEncode 配置、Encode 喂一帧、SetRates 调码率,编好的压缩帧经 EncodedImageCallback 回调出来。 上层的 VideoStreamEncoder 只面对这个接口,完全不关心底下是 VP8 还是 AV1——换编解码器,对上层透明。这是依赖倒置的经典应用:上层依赖抽象 VideoEncoder,具体编解码器实现它。

尤其 SetRates 是拥塞控制闭环的落点:拥塞控制算出的目标码率,经分配后就是通过 SetRates 告诉编码器「你现在有这么多码率预算,编到这个大小之内」。编码器据此调整量化等参数,产出符合预算的压缩帧。「网络能承受多少」到「画质多高」的传导,最终就发生在这个方法调用里。

编码器由工厂创建——VideoEncoderFactory(可在 PeerConnectionFactory 依赖里替换),这让平台能提供硬件编码器(手机的专用编码芯片,省电省 CPU)或软件编码器。

五种编解码器

WebRTC 支持的主要视频编解码器,各有取舍:

编解码器特点典型场景
VP8老牌、兼容性最好、纯软件保底、老设备
VP9比 VP8 省 ~50% 码率,支持 SVC带宽敏感
AV1最新、压缩率最高,但编码最耗 CPU低带宽、有算力
H264硬件支持最广(手机几乎都有硬编)移动端、省电
H265H264 的继任,压缩更好,但授权 / 支持受限特定场景

编解码器的选择,是「压缩率 vs CPU vs 兼容性 vs 授权」的多方权衡。 压缩率越高(AV1 > VP9 > VP8),同样画质越省带宽,但编码越吃 CPU;硬件支持越广(H264),越省电、越流畅,但可能压缩率不如新编解码器;还有专利授权的现实考量(VP8/VP9/AV1 免版税,H264/H265 有授权问题)。所以 WebRTC 不押注单一编解码器,而是全都支持、协商时取双方交集——还记得 SDP 编解码器协商吗,两端各列支持的,取交集用。这套「抽象接口 + 多实现 + 协商选择」的架构,让 WebRTC 能随编解码器技术演进而演进,不被任何一种绑死。具体实现在 modules/video_coding/codecs/(vp8/vp9/av1/h264 等子目录)。

编码器输出:EncodedImage

编码器吐出的是 EncodedImage——一段压缩后的字节 + 元数据(是不是关键帧、时间戳、SVC 层信息等)。它经 EncodedImageCallback 回到 VideoStreamEncoder,再交给打包成 RTP。关键帧标记尤其重要:接收端丢包恢复、新加入者起播,都要从关键帧开始。

小结与下一章

VideoEncoder 是统一的编码器抽象(InitEncode 配置、Encode 喂帧、SetRates 设码率——拥塞控制闭环的落点),让上层不关心具体编解码器。由 VideoEncoderFactory 创建(可换硬件编码器)。五种编解码器 VP8 / VP9 / AV1 / H264 / H265 各有「压缩率 vs CPU vs 兼容 vs 授权」的取舍,WebRTC 全支持、协商取交集。输出 EncodedImage(压缩字节 + 关键帧等元数据)。

编码器能按 SetRates 调码率,但具体降到多低、是降分辨率还是降帧率,是一套精细的自适应逻辑。下一章专讲。👉 视频自适应。

参考资料

  • [1] libwebrtc 源码.api/video_codecs/video_encoder.h(InitEncode / Encode / SetRates)、video_encoder_factory.h。
  • [2] libwebrtc 源码.modules/video_coding/codecs/(vp8/vp9/av1/h264 实现)。
  • [3] api/video_codecs/(各编解码器的 profile 与能力)。

本页目录