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.h

  • video/video_stream_encoder.h

  • modules/rtp_rtcp/source/rtp_video_sender.h

  • video/rtp_video_stream_receiver2.h