WebRTC Video Flow
Abstract |
WebRTC Video Flow |
Authors |
Walter Fan |
Status |
v1.0 |
Updated |
2026-03-20 |
Overview
WebRTC 的视频处理流程分为发送端和接收端两条主线。发送端从摄像头采集视频帧, 经过预处理、编码、RTP 打包后发送到网络;接收端从网络接收 RTP 包, 经过解包、解码、渲染后显示到屏幕上。
VideoSendStream 发送流程
VideoSendStream (位于 video/video_send_stream.h) 管理完整的视频发送链路。
数据流如下:
VideoSource (Camera/Screen)
|
VideoBroadcaster
|
VideoStreamEncoder
| ├── VideoAdapter (分辨率/帧率适配)
| ├── VideoEncoder (VP8/VP9/H264/AV1)
| └── EncoderRateSettings (码率控制)
|
EncodedImageCallback
|
RtpVideoSender
| ├── RtpPacketizer (NAL → RTP)
| ├── FecGenerator (ULP-FEC / FlexFEC)
| └── RtxSender (重传)
|
PacedSender (平滑发送)
|
Network (UDP Socket)
关键类说明
VideoStreamEncoder: 发送端最核心的类,负责:
接收原始视频帧 (
VideoFrame)根据带宽和 CPU 负载动态调整编码参数 (
QualityScaler)调用编解码器进行编码
支持 Simulcast 多流编码
// VideoStreamEncoder 的核心回调
class VideoStreamEncoder : public VideoStreamEncoderInterface,
public EncodedImageCallback {
// 接收原始视频帧
void OnFrame(const VideoFrame& frame) override;
// 编码完成回调
EncodedImageCallback::Result OnEncodedImage(
const EncodedImage& encoded_image,
const CodecSpecificInfo* codec_specific) override;
};
RtpVideoSender: 负责将编码后的视频帧打包为 RTP 包:
根据编解码器类型选择打包方式 (VP8/VP9/H264 各有不同的 RTP payload format)
添加 RTP header extensions (如 transport-cc, abs-send-time)
生成 FEC 冗余包用于前向纠错
管理 RTX 重传流
VideoReceiveStream 接收流程
VideoReceiveStream (位于 video/video_receive_stream2.h) 管理视频接收链路。
数据流如下:
Network (UDP Socket)
|
RtpVideoStreamReceiver2
| ├── RtpDepacketizer (RTP → NAL)
| ├── NackModule (丢包检测与重传请求)
| └── PacketBuffer (帧组装)
|
FrameBuffer (帧排序与等待)
| ├── 等待关键帧
| ├── 帧间依赖检查
| └── Jitter Buffer 延迟控制
|
VideoDecoder (VP8/VP9/H264/AV1)
|
VideoReceiveStream::OnDecodedFrame
|
IncomingVideoStream
|
VideoSink (Renderer / Display)
关键类说明
RtpVideoStreamReceiver2: 接收端的入口,负责:
解析 RTP 包,提取视频 payload
处理 NACK:检测丢包并发送重传请求
处理 FEC:利用冗余包恢复丢失的数据包
组装完整的视频帧
FrameBuffer: 帧级别的缓冲管理:
维护帧的依赖关系 (参考帧是否已到达)
控制解码时机,平衡延迟和流畅性
请求关键帧 (PLI/FIR) 当无法解码时
// 接收端的关键流程
void RtpVideoStreamReceiver2::OnRtpPacket(const RtpPacketReceived& packet) {
// 1. 解析 RTP header 和 payload
// 2. 检查是否需要 NACK
// 3. 将 packet 放入 PacketBuffer
// 4. 尝试组装完整帧
// 5. 完整帧送入 FrameBuffer
}
void VideoReceiveStream2::OnCompleteFrame(
std::unique_ptr<EncodedFrame> frame) {
// 将完整帧插入 FrameBuffer
// FrameBuffer 在合适的时机取出帧进行解码
}
码率自适应
发送端根据网络状况动态调整视频质量:
QualityScaler: 监控编码器输出的 QP 值,QP 过高时降低分辨率
OveruseFrameDetector: 监控 CPU 使用率,过载时降低帧率或分辨率
BitrateAllocator: 根据 GCC 估计的可用带宽分配码率
GCC 估计带宽下降
|
BitrateAllocator 降低目标码率
|
VideoStreamEncoder 调整编码参数
| ├── 降低帧率 (FrameDropper)
| ├── 降低分辨率 (VideoAdapter)
| └── 降低编码质量 (QP 上升)
Simulcast 与 SVC
WebRTC 支持两种多层编码方式:
Simulcast: 同时编码多个独立的分辨率层 (如 720p + 360p + 180p),每层独立编码
SVC (Scalable Video Coding): 编码为可分层的单一码流,VP9 和 AV1 原生支持
Simulcast 在 SFU 架构中广泛使用,SFU 根据每个接收端的带宽选择转发合适的层。
参考资料
源码路径:
video/video_send_stream.h,video/video_receive_stream2.hvideo/video_stream_encoder.hmodules/rtp_rtcp/source/rtp_video_sender.hvideo/rtp_video_stream_receiver2.h