WebRTC Video Flow
Abstract |
WebRTC Video Flow |
Authors |
Walter Fan |
Status |
v1.0 |
Updated |
2026-08-17 |
Overview
WebRTC 的视频处理流程分为发送端和接收端两条主线。发送端从摄像头采集视频帧, 经过预处理、编码、RTP 打包后发送到网络;接收端从网络接收 RTP 包, 经过解包、解码、渲染后显示到屏幕上。
VideoSendStream 发送流程
VideoSendStream (位于 video/video_send_stream.h) 管理完整的视频发送链路。
数据流如下:
flowchart TD
Src["VideoSource Camera/Screen"] --> VB[VideoBroadcaster]
VB --> VSE[VideoStreamEncoder]
VSE --> VA["VideoAdapter 分辨率/帧率适配"]
VSE --> VE["VideoEncoder VP8/VP9/H264/AV1"]
VSE --> ERS[EncoderRateSettings 码率控制]
VSE --> EIC[EncodedImageCallback]
EIC --> RVS[RtpVideoSender]
RVS --> RP["RtpPacketizer NAL to RTP"]
RVS --> FG["FecGenerator ULP-FEC / FlexFEC"]
RVS --> RTX[RtxSender 重传]
RVS --> PS[PacedSender 平滑发送]
PS --> Net[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) 管理视频接收链路。
数据流如下:
flowchart TD
Net[Network UDP Socket] --> Recv[RtpVideoStreamReceiver2]
Recv --> Dep["RtpDepacketizer RTP to NAL"]
Recv --> Nack[NackModule 丢包检测与重传请求]
Recv --> PB[PacketBuffer 帧组装]
Recv --> FB[FrameBuffer 帧排序与等待]
FB --> Wait[等待关键帧]
FB --> DepChk[帧间依赖检查]
FB --> JB[Jitter Buffer 延迟控制]
FB --> Dec["VideoDecoder VP8/VP9/H264/AV1"]
Dec --> ODF["VideoReceiveStream::OnDecodedFrame"]
ODF --> IVS[IncomingVideoStream]
IVS --> Sink[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 估计的可用带宽分配码率
flowchart TD
A[GCC 估计带宽下降] --> B[BitrateAllocator 降低目标码率]
B --> C[VideoStreamEncoder 调整编码参数]
C --> D[降低帧率 FrameDropper]
C --> E[降低分辨率 VideoAdapter]
C --> F[降低编码质量 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