# RtpRtcp 模块 · 每条流的收发中枢

> modules/rtp_rtcp 的核心是 ModuleRtpRtcpImpl2——每条媒体流一个，统管这条流的 RTP 发送与 RTCP 收发。这一章讲清它在收发管线里的位置、它把 RtpSender 与 RtcpSender/RtcpReceiver 捆在一起的角色，以及一条流为什么需要这么一个中枢。

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

# RtpRtcp 模块 · 每条流的收发中枢

[包结构](https://daiw.org/manual/webrtc/rtp-packet)有了，谁来实际收发、并处理[反馈](https://daiw.org/manual/webrtc/rtcp-reports)？是 `modules/rtp_rtcp/` 的核心类——**`ModuleRtpRtcpImpl2`**。它是**每条媒体流的收发中枢**，把这条流的 RTP 发送和 RTCP 收发统管起来。这一章认识它。

## 一条流，一个模块

`ModuleRtpRtcpImpl2`（`modules/rtp_rtcp/source/rtp_rtcp_impl2.h`）实现 `RtpRtcpInterface`：

```cpp
// modules/rtp_rtcp/source/rtp_rtcp_impl2.h(节选)
class ModuleRtpRtcpImpl2 final : public RtpRtcpInterface, ... {
  void IncomingRtcpPacket(std::span<const uint8_t> incoming_packet) override;
  void RegisterSendRtpHeaderExtension(absl::string_view uri, int id) override;
  // 统管:发 RTP、发 RTCP、收 RTCP
};
```

<Callout type="info">
  **每条媒体流（一个 [SSRC](https://daiw.org/manual/webrtc/rtp-packet)）对应一个 `ModuleRtpRtcpImpl2`。** 你发一路视频、收一路音频，就各有一个这样的模块实例。它像这条流的「本地邮局」，统管三件事：

  1. **发 RTP** —— 把[编码器](https://daiw.org/manual/webrtc/source-map)出的媒体，交给 [`RtpSender`](https://daiw.org/manual/webrtc/rtp-sender) 打包发出。
  2. **发 RTCP** —— 定期发送 [RTCP 报告](https://daiw.org/manual/webrtc/rtcp-reports)（发送方报告 SR、[反馈](https://daiw.org/manual/webrtc/rtcp-feedback)等）。
  3. **收 RTCP** —— `IncomingRtcpPacket` 接收对端的 [RTCP 反馈](https://daiw.org/manual/webrtc/rtcp-feedback)（丢包报告、[NACK](https://daiw.org/manual/webrtc/nack-rtx)、[带宽反馈](https://daiw.org/manual/webrtc/transport-cc)），解析后驱动[重传](https://daiw.org/manual/webrtc/nack-rtx)、[码率调整](https://daiw.org/manual/webrtc/source-map)。

  它是 RTP 世界和上层（[编解码](https://daiw.org/manual/webrtc/source-map)、[拥塞控制](https://daiw.org/manual/webrtc/source-map)）之间的枢纽——上层通过它发媒体，对端的反馈也通过它回到上层。
</Callout>

## 它捆着哪些零件

`ModuleRtpRtcpImpl2` 本身是个「协调者」，真正干活的是它持有的几个子组件：

| 子组件 | 干什么 | 本教程 |
| --- | --- | --- |
| `RTPSender` / `RtpSenderEgress` | 打包并[发送 RTP](https://daiw.org/manual/webrtc/rtp-sender) | [下一章](https://daiw.org/manual/webrtc/rtp-sender) |
| `RTCPSender` | 生成并发送 [RTCP 报告 / 反馈](https://daiw.org/manual/webrtc/rtcp-reports) | 第 4 部分 |
| `RTCPReceiver` | 解析收到的 [RTCP](https://daiw.org/manual/webrtc/rtcp-feedback) | 第 4 部分 |

把「发媒体」「发反馈」「收反馈」三条线捆在一个模块里，是有道理的：它们围绕**同一条流**（同一个 SSRC），要共享这条流的状态（发了哪些包、[序号到哪了](https://daiw.org/manual/webrtc/rtp-packet)、收到的[丢包报告](https://daiw.org/manual/webrtc/rtcp-feedback)对应哪些包）。放一起，状态才好协同。

## 「2」是什么意思

你可能注意到类名带个 `2`——`ModuleRtpRtcpImpl2`。这是 WebRTC 演进的痕迹：它是旧 `ModuleRtpRtcpImpl` 的**重写版**，主要为了适配[新的线程 / 任务队列模型](https://daiw.org/manual/webrtc/threading-model)（更贴合 [TaskQueue](https://daiw.org/manual/webrtc/threading-model)，减少锁）。读 WebRTC 常见这种带版本号的类（`VideoReceiveStream2` 等）——**看到 `2` 就知道它是某个组件的现代重写**，老版本可能还在但正被淘汰。这也提醒我们[「api/ 稳定、实现常重构」](https://daiw.org/manual/webrtc/reading-the-source)的约定。

## 在管线里的位置

把它放进[发送管线](https://daiw.org/manual/webrtc/source-map)看：

```mermaid
flowchart TD
    ENC["编码器出媒体(第 6/7 部分)"] --> MOD["ModuleRtpRtcpImpl2(本流中枢)"]
    MOD -->|"打包"| SND["RtpSender / RtpSenderEgress"]
    SND -->|"经 Pacing 平滑(第 5 部分)"| SRTP["SRTP 加密 → ICE 发出"]
    PEER["对端 RTCP 反馈"] -->|"IncomingRtcpPacket"| MOD
    MOD -->|"驱动重传 / 调码率"| CC["NACK / 拥塞控制"]
```

上层编码器把媒体喂给模块，模块打包、发送、并接收对端反馈，反馈又驱动重传与码率调整——**一条流的收发闭环，就以 `ModuleRtpRtcpImpl2` 为中心转起来**。

## 小结与下一章

**`ModuleRtpRtcpImpl2`**（`modules/rtp_rtcp/source/rtp_rtcp_impl2.h`，实现 `RtpRtcpInterface`）是**每条流（一个 SSRC）的收发中枢**，统管三件事：发 [RTP](https://daiw.org/manual/webrtc/rtp-sender)、发 [RTCP](https://daiw.org/manual/webrtc/rtcp-reports)、收 RTCP（`IncomingRtcpPacket`）。它捆着 `RTPSender`/`RtpSenderEgress`、`RTCPSender`、`RTCPReceiver`，让围绕同一条流的状态好协同。类名的 `2` 表示它是[适配新线程模型](https://daiw.org/manual/webrtc/threading-model)的现代重写。

发送这条线最值得细看——[打包、发送、以及为重传保留历史](https://daiw.org/manual/webrtc/nack-rtx)。下一章深入发送侧。👉 [RtpSender 与发送路径](https://daiw.org/manual/webrtc/rtp-sender)。

## 参考资料

- [1] libwebrtc 源码.`modules/rtp_rtcp/source/rtp_rtcp_impl2.h` / `.cc`（`ModuleRtpRtcpImpl2`、`IncomingRtcpPacket`）。
- [2] libwebrtc 源码.`modules/rtp_rtcp/source/rtp_rtcp_interface.h`（接口）。
- [3] IETF RFC 3550「RTP/RTCP」。
