EP05:Simulcast 的原理和用途¶
| 上集回顾 | EP04《传输技术三国杀:RTMP / SRT / WHIP》讲完了三种推流协议怎么处理丢包 |
|---|---|
| 下集预告 | EP06《推拉流安全:签名、Token 与防盗链实战》 |
0. 本集目标¶
看完这一集,观众应该能做到两件事:
- 说清楚 Simulcast 的底层机制:为什么"一路推流出多档画质"不需要服务端转码,多档画质到底是谁、在哪、怎么编出来的。
- 说清楚为什么是 Simulcast,不是 SVC——这不是随便选的,是编解码器生态现状决定的取舍。
1. 开场钩子(逐字稿要点)¶
EP02 提过一句话:"网络侧不用转码"。EP04 讲了 ABR 降级时"先降码率、再降分辨率"的判定逻辑。这一集把这两句话之间缺的那一环补上:多档画质怎么在发送端产生,服务端如何不做像素域转码而安全切换画质档位。
2. Simulcast 是什么:一路推流,同时产出多档独立画质¶
Simulcast 不是"一份编码,服务端裁剪出多档",而是发送端同时产生多份可独立解码的编码(encoding)。 比如一路 1080P 输入开 3 层 Simulcast,可以产生 1080P、720P、360P 三份独立编码并分别以 RTP 发送。产品可以用多个编码器实例实现,也可以由支持多路输出的硬件/软件编码管线实现;"必须同时跑多个独立编码器实例"不是协议标准要求。
对比一下如果没有 Simulcast,想要多档画质的传统做法是什么样:服务端转码——服务端先把收到的流完整解码成原始画面,再按每个目标档位重新编码一遍。解码 + 多次重新编码是相当重的计算负担,而且天然带来额外的处理延迟。
Simulcast 把这份工作从"服务端解码再编码"变成"推流端编码器一次性多编几份",服务端收到的每一层都已经是可以直接转发给观众的完整画面,不需要解码、不需要重新编码,只做字节转发。这就是 EP02 提到"网络侧不用转码"的技术根因:转码的工作量没有消失,只是被挪到了推流端的编码器上,用推流端的编码算力换服务端的转码算力。
3. 为什么是 Simulcast,不是 SVC¶
懂一点编解码的人可能会问:可分层编码(SVC, Scalable Video Coding)不是更省编码带宽吗?为什么不用 SVC?
- SVC 的思路:编码输出包含基础层和一个或多个时域/空域/质量增强层,层之间存在依赖关系。转发端可按依赖结构选择转发子集。它通常比多份完全独立编码更节省总码率,但编码复杂度、具体收益和发送端算力不能一概而论。
- 代价是复杂度和兼容性:SFU/Edge 必须理解并正确处理层标识、依赖关系和切换点,接收端也必须支持对应 codec/profile/scalability mode。VP9、AV1 在 WebRTC 中常见 SVC 模式较多;H264/HEVC 是否可用取决于浏览器、系统解码器、协商和产品实现,不能把某一产品现状写成标准禁止。
- Simulcast 的各编码可独立解码:WebRTC 中常用 RID、SSRC 和 SDP/RTP 映射区分 encoding;RID 并非所有协议和封装下都必然存在。转发端仍需维护 RTP 序列、时间戳、RTCP 反馈和层切换状态,并非无条件的"只做字节转发"。
本项目当前以 H264/HEVC 为主,并基于目标浏览器和现有收发端能力选择 Simulcast。这是 PPCDN 当前产品兼容性取舍,不是 H264/HEVC 标准本身排除 SVC,也不是所有 WebRTC 产品的唯一选择。 选型时应以目标终端矩阵和互操作测试为准。
4. 怎么用:分层、ABR 安全切换,与多轨是两个独立维度¶
- 层数上限:PPCDN 当前产品限制为 H264 最多 4 层、HEVC 最多 3 层(设计见
docs/design/whip-hevc-h264-multitrack-simulcast-design.zh-CN.md:"HEVC simulcast 总层数最大为 3 层,即必须小于 4;H264 沿用现有层数配置上限");这不是 Simulcast、RTP 或相应编码标准规定的通用上限,是本项目当前编码器管线和终端矩阵下的产品取舍。每个 encoding 需要可区分的 RTP 标识和独立状态,具体使用 RID、SSRC 还是其他映射取决于协商与实现。 - ABR 怎么切换层:服务端可根据接收端反馈和可用带宽估计升降档。切到另一个独立 encoding 时,通常应等待目标层的随机接入点;对本项目 H264/HEVC 流,常见做法是请求并等待 IDR/关键帧,再完成 RTP 时间戳和序列号连续性处理。关键帧可能需要通过 PLI/FIR 请求,生成会消耗码率且存在等待时间,所以正确切换能避免引用链损坏和花屏,但不保证零等待、零卡顿或必然无感。
- 和多轨(H264/HEVC 双码流)是两个独立维度:多轨解决的是"给不同解码能力的浏览器分别提供 H264 或 HEVC",Simulcast 解决的是"给不同网络/画质需求提供不同档位"。两者可以同时开:H264 和 HEVC 各自独立维护自己的 Simulcast 层数、RID 序列和编码器,互不影响(比如 H264 开 4 层的同时,HEVC 可以独立开 3 层)。
5. 框图¶
5.1 服务端转码 vs Simulcast:转码工作挪到了哪里¶
【传统方案:服务端转码】
推流端 ──单一编码流──▶ 服务端
│ 解码成原始画面
▼
按每个目标档位重新编码(1080P / 720P / 360P)
│ CPU 密集,带来额外处理延迟
▼
分发给不同观众
【Simulcast】
┌─ 编码器 A:1080P ──┐
推流端 ──────┼─ 编码器 B:720P ──┼──▶ 服务端(只转发字节,不解码不编码)──▶ 分发给不同观众
└─ 编码器 C:360P ──┘
(三份编码同时跑在推流端,各自独立、可直接解码)
5.2 Simulcast 分层结构¶
推流端编码器
│
├── 主编码器(如 1080P)──▶ RTP 流,RID = "high"
├── 缩放层编码器(720P)──▶ RTP 流,RID = "mid"
└── 缩放层编码器(360P)──▶ RTP 流,RID = "low"
三条流各自独立、完整可解码,服务端按 RID 识别并转发对应层
5.3 ABR 在关键帧边界安全切换¶
观众当前正在播放 "mid" 档(720P)
│
▼
服务端检测到丢包率上升,决定降档到 "low"(360P)
│
▼
请求或等待 "low" 层的可用关键帧(本例为 IDR)
│
▼
从这个 IDR 开始,改为转发 "low" 层的数据
│
▼
目标:避免花屏;是否无感取决于关键帧等待、缓冲和 RTP 连续性处理
6. 结尾与下集预告(逐字稿要点)¶
这一集把"一路推流出多档、服务端不用转码"拆到了机制层面:Simulcast 由发送端产生多份独立 encoding,服务端无需做像素域转码,但仍要处理 RTP/RTCP 和切换状态;PPCDN 选择它而不是 SVC,是当前终端矩阵下的产品取舍。切换到独立层时应从可用随机接入点开始,并正确处理反馈与 RTP 连续性,关键帧边界本身不等于无条件无缝。
下一集,我们从"怎么编"转到"怎么防"——推拉流的签名、Token 机制,以及怎么做防盗链。