编码器抽象与编解码器 · VP8/VP9/AV1/H264/H265
WebRTC 用统一的 VideoEncoder 接口抽象各种编解码器,底下接 VP8、VP9、AV1、H264、H265。这一章读 video_codecs/video_encoder.h 的 InitEncode/Encode/SetRates,讲清这层抽象、编码器工厂、以及各编解码器的取舍。
编码器抽象与编解码器 · 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 | 硬件支持最广(手机几乎都有硬编) | 移动端、省电 |
| H265 | H264 的继任,压缩更好,但授权 / 支持受限 | 特定场景 |
编解码器的选择,是「压缩率 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 与能力)。