# 第 9 部分回顾 · 控制面与媒体面如何合拢

> 第 9 部分把前八部分焊成一个整体——Call 是媒体中枢、RtpTransportControllerSend 是发送侧神经中枢、BitrateAllocator 分带宽、媒体引擎提供编解码、BaseChannel 缝合 SDP 与媒体。这一章串起这条主线，并给出「一个包的一生」全景。

- 作者：David（道雾轩）
- 专栏：音视频与 WebRTC 详解（https://daiw.org/manual/webrtc.md）
- 最后更新：2026-08-03
- 原文：https://daiw.org/manual/webrtc/call-recap
- 转载与引用：请注明出处并附原文链接（https://daiw.org/about/copyright）

# 第 9 部分回顾 · 控制面与媒体面如何合拢

[第 9 部分](https://daiw.org/manual/webrtc/call-object)是**收束章**——前八部分讲的是一个个子系统（[协商](https://daiw.org/manual/webrtc/offer-answer-handler)、[ICE](https://daiw.org/manual/webrtc/ice-overview)、[DTLS](https://daiw.org/manual/webrtc/dtls-handshake)、[RTP](https://daiw.org/manual/webrtc/rtp-packet)、[拥塞控制](https://daiw.org/manual/webrtc/congestion-control-overview)、[视频](https://daiw.org/manual/webrtc/video-pipeline-overview)、[音频](https://daiw.org/manual/webrtc/audio-pipeline-overview)、[数据通道](https://daiw.org/manual/webrtc/data-channel-overview)），这一部分讲**它们怎么被组织成一次完整通话**。

## 五个角色

第 9 部分的五章，是“一次通话”这台机器的骨架：

| 角色 | 是什么 | 位置 |
| --- | --- | --- |
| [`Call`](https://daiw.org/manual/webrtc/call-object) | 媒体面中枢：所有[收发流](https://daiw.org/manual/webrtc/video-pipeline-overview)的工厂 + 容器 + 协调者 | [worker 线程](https://daiw.org/manual/webrtc/threading-model) |
| [`RtpTransportControllerSend`](https://daiw.org/manual/webrtc/rtp-transport-controller-send) | 发送侧神经中枢：[GoogCC](https://daiw.org/manual/webrtc/congestion-control-overview) + [pacer](https://daiw.org/manual/webrtc/pacing) + [PacketRouter](https://daiw.org/manual/webrtc/rtp-transport-controller-send) + [反馈适配](https://daiw.org/manual/webrtc/transport-cc) | 通话级单例 |
| [`BitrateAllocator`](https://daiw.org/manual/webrtc/bitrate-allocator) | 把[总带宽](https://daiw.org/manual/webrtc/rate-control)分给各流（音频优先） | Call 持有 |
| [媒体引擎](https://daiw.org/manual/webrtc/media-engine) | 提供[编解码器](https://daiw.org/manual/webrtc/video-encoder-abstraction)、建[媒体通道](https://daiw.org/manual/webrtc/media-channels) | `media/engine/` |
| [`BaseChannel`](https://daiw.org/manual/webrtc/media-channels) | 缝合 [SDP 协商](https://daiw.org/manual/webrtc/offer-answer-handler)与[媒体](https://daiw.org/manual/webrtc/call-object) | 跨 worker/network 线程 |

<Callout type="info">
  **一句话串起来：[`PeerConnection`（控制面）](https://daiw.org/manual/webrtc/peer-connection-object)[协商](https://daiw.org/manual/webrtc/offer-answer-handler)出“发什么”，[`BaseChannel`](https://daiw.org/manual/webrtc/media-channels) 把它落到[媒体引擎](https://daiw.org/manual/webrtc/media-engine)建的通道，[`Call`](https://daiw.org/manual/webrtc/call-object) 据此建[收发流](https://daiw.org/manual/webrtc/video-pipeline-overview)，[`RtpTransportControllerSend`](https://daiw.org/manual/webrtc/rtp-transport-controller-send) 统一管这些流的[拥塞控制 + 发送节奏](https://daiw.org/manual/webrtc/congestion-control-overview)，[`BitrateAllocator`](https://daiw.org/manual/webrtc/bitrate-allocator) 把带宽分给它们。** 这就是一次通话媒体面的完整骨架——控制面（[第 1 部分](https://daiw.org/manual/webrtc/peer-connection-object)）谈定，媒体面（[第 6/7 部分](https://daiw.org/manual/webrtc/video-pipeline-overview)）执行，而第 9 部分这几个角色是**把两者接起来、并让多条流协调共享资源**的中间层。
</Callout>

## 一个视频包的一生（全景）

用第 9 部分的骨架，把[前八部分](https://daiw.org/manual/webrtc)串成“**一个视频包从摄像头到对端屏幕**”的全景——这是本教程走到这里，你应该能看懂的整条链：

```mermaid
flowchart TD
    CAM["摄像头采集(第 6 部分)"] --> ENC["编码器编码<br/>VP8/AV1(第 6 部分)"]
    ENC --> PKT["RTP 打包(第 4 部分)"]
    PKT --> PACE["pacer 平滑发送<br/>(RtpTransportControllerSend)"]
    PACE --> SRTP["SRTP 加密(第 3 部分)"]
    SRTP --> ICE["经 ICE 选定的路径(第 2 部分)"]
    ICE --> NET(("网络"))
    NET --> ICE2["对端 ICE 传输"]
    ICE2 --> UNSRTP["SRTP 解密(第 3 部分)"]
    UNSRTP --> DEMUX["RTP 解复用<br/>BaseChannel 收包(第 4/9 部分)"]
    DEMUX --> JB["视频 jitter buffer<br/>重组帧(第 6 部分)"]
    JB --> DEC["解码器解码(第 6 部分)"]
    DEC --> DISP["渲染到屏幕"]
    FB["接收侧反馈<br/>RTCP/Transport-CC(第 4 部分)"] -.->|"回传"| CC["GoogCC 调码率(第 5 部分)"]
    CC -.->|"控制"| ENC
```

这条链里，几乎[每一部分](https://daiw.org/manual/webrtc)都出场了：[采集编码（6）](https://daiw.org/manual/webrtc/video-source-encoder) → [打包（4）](https://daiw.org/manual/webrtc/rtp-packet) → [pacing(5/9)](https://daiw.org/manual/webrtc/pacing) → [加密（3）](https://daiw.org/manual/webrtc/srtp-encryption) → [ICE 路径（2）](https://daiw.org/manual/webrtc/p2p-transport-channel) → 网络 → [解密（3）](https://daiw.org/manual/webrtc/srtp-encryption) → [解复用（4/9）](https://daiw.org/manual/webrtc/rtp-demuxer) → [jitter buffer(6)](https://daiw.org/manual/webrtc/video-jitter-buffer) → [解码（6）](https://daiw.org/manual/webrtc/video-decode-recovery) → 渲染，外加[反馈闭环调码率（4/5）](https://daiw.org/manual/webrtc/rate-control)。**第 9 部分的 `Call` / `BaseChannel` / `RtpTransportControllerSend`，就是让这条链上的每个环节各就各位、协同运转的组织者。**

## 我们完成了什么

走到这里，本教程覆盖了 WebRTC 的**核心引擎**（[第 0~9 部分](https://daiw.org/manual/webrtc)）：

<Callout type="info">
  **从“[什么是 WebRTC](https://daiw.org/manual/webrtc/what-is-webrtc)”到“[一次通话怎么被组织起来](https://daiw.org/manual/webrtc/call-object)”，我们已经贯通了主干**——[会话怎么谈成（1）](https://daiw.org/manual/webrtc/offer-answer-handler)、[连接怎么建立（2）](https://daiw.org/manual/webrtc/ice-overview)、[怎么加密（3）](https://daiw.org/manual/webrtc/security-overview)、[媒体怎么打包传输（4）](https://daiw.org/manual/webrtc/rtp-packet)、[怎么应对带宽变化（5）](https://daiw.org/manual/webrtc/congestion-control-overview)、[视频（6）](https://daiw.org/manual/webrtc/video-pipeline-overview)和[音频（7）](https://daiw.org/manual/webrtc/audio-pipeline-overview)管线、[数据通道（8）](https://daiw.org/manual/webrtc/data-channel-overview)，以及[这一切怎么被 Call 组织成一次通话（9）](https://daiw.org/manual/webrtc/call-object)。这是 WebRTC 的**主体骨架**。
</Callout>

接下来的部分，转向**支撑这套引擎的基础设施与工程实践**：第 10 部分看引擎底下的 [`rtc_base`](https://daiw.org/manual/webrtc/threading-model)（线程、任务队列、时间、缓冲这些[到处被用到](https://daiw.org/manual/webrtc/threading-model)的地基），第 11 部分看[怎么观测和调试](https://daiw.org/manual/webrtc/stats-collector)一次通话，第 12 部分看[平台集成](https://daiw.org/manual/webrtc/what-is-webrtc)（Android/iOS/桌面采集）。骨架已经立起来了，后面是让它在真实世界里跑稳的血肉。

## 小结与下一部分

**第 9 部分**把前八部分焊成整体：[`Call`](https://daiw.org/manual/webrtc/call-object)（媒体中枢）、[`RtpTransportControllerSend`](https://daiw.org/manual/webrtc/rtp-transport-controller-send)（发送侧神经中枢）、[`BitrateAllocator`](https://daiw.org/manual/webrtc/bitrate-allocator)（分带宽）、[媒体引擎](https://daiw.org/manual/webrtc/media-engine)（供编解码）、[`BaseChannel`](https://daiw.org/manual/webrtc/media-channels)（缝合 [SDP](https://daiw.org/manual/webrtc/offer-answer-handler) 与[媒体](https://daiw.org/manual/webrtc/video-pipeline-overview)）——五个角色让[协商](https://daiw.org/manual/webrtc/peer-connection-object)、[传输](https://daiw.org/manual/webrtc/rtp-packet)、[编解码](https://daiw.org/manual/webrtc/video-pipeline-overview)协同成一次通话。我们也用“[一个视频包的一生](https://daiw.org/manual/webrtc/call-recap)”把[整条链](https://daiw.org/manual/webrtc)串了起来。

WebRTC 的**核心引擎**到此讲完。下一部分，深入引擎底下那层[到处都在用的地基](https://daiw.org/manual/webrtc/threading-model)。👉 [第 10 部分 · 基础设施 rtc_base](https://daiw.org/manual/webrtc/rtc-base-overview)。

## 参考资料

- [1] 本部分各章：[Call](https://daiw.org/manual/webrtc/call-object)、[RtpTransportControllerSend](https://daiw.org/manual/webrtc/rtp-transport-controller-send)、[BitrateAllocator](https://daiw.org/manual/webrtc/bitrate-allocator)、[媒体引擎](https://daiw.org/manual/webrtc/media-engine)、[媒体通道](https://daiw.org/manual/webrtc/media-channels)。
- [2] libwebrtc 源码.`call/`、`media/engine/`、`pc/channel.cc` 全景。
- [3] WebRTC 官方架构图 `g3doc/`（印证本章的分层视角）。
