视频自适应 · 降分辨率还是降帧率
网络或 CPU 不够时,视频要主动降质保流畅——降分辨率还是降帧率?这一章读 g3doc/adaptation.md:Resource 如何发出 overuse/underuse 信号、QualityScaler 盯 QP、编码耗时当 CPU 代理、以及 DegradationPreference 如何决定牺牲哪个维度。
视频自适应 · 降分辨率还是降帧率
网络带宽和 CPU 都是有限且多变的。当它们不够用时,视频主动降质总比卡死强。但降质有讲究:降分辨率(画面变糊)还是降帧率(动作变卡)? 这套「视频自适应(Video Adaptation)」逻辑,g3doc/adaptation.md 讲得很清楚。
机制:Resource 发信号
g3doc/adaptation.md 开门见山:
Video adaptation ... reduces the bandwidth or CPU consumption by reducing encoded video quality.
自适应的触发机制,是一套 Resource(资源) 抽象:
每个 Resource 监控一个指标,过载时喊 SetUsageState(kOveruse)、宽裕时喊 kUnderuse——VideoStreamEncoder 据此在两个维度(分辨率 / 帧率)上降质或恢复。 默认有两个 Resource(g3doc/adaptation.md):
- QP Scaler(质量伸缩) —— 盯编码后帧的 QP(量化参数)。QP 反映「为了塞进码率预算,画质被压得多狠」:QP 高于高阈值 = 当前分辨率下画质已经差得不可接受(压太狠了)→
kOveruse(该降分辨率了,让每个像素分到更多码率);QP 低于低阈值 = 画质有富余 →kUnderuse(可以升回去)。由QualityScaler实现。 - Encode Usage(编码耗时) —— 盯编码一帧要多久,作为 CPU 使用率的代理(
g3doc/adaptation.md的巧思:CPU 越忙,编码越慢)。编码耗时超阈值 → CPU 扛不住 →kOveruse。
两个 Resource,一个管「码率 / 画质」(QP),一个管「CPU」(编码耗时)——分别对应视频自适应要平衡的两大约束。还能注入自定义 Resource(如监控设备温度),Call::AddAdaptationResource。
降哪个维度:DegradationPreference
过载了,该牺牲分辨率还是帧率?这取决于 DegradationPreference(绑定源时传入):
| DegradationPreference | 过载时牺牲 | 适合 |
|---|---|---|
MAINTAIN_FRAMERATE | 降分辨率(保帧率) | 视频通话(动作流畅重要) |
MAINTAIN_RESOLUTION | 降帧率(保分辨率) | 屏幕共享 / 演示(文字清晰重要) |
BALANCED | 两者平衡取舍 | 通用 |
DISABLED | 不自适应 | 特殊场景 |
降分辨率 vs 降帧率,取决于内容「更怕糊还是更怕卡」。 视频通话里,人脸和动作是主体——宁可画面小一点(降分辨率),也要动作流畅(保帧率),所以用 MAINTAIN_FRAMERATE。而共享一份文档 / 代码 / 幻灯片时,内容基本静止但文字必须看清——宁可翻页卡顿一下(降帧率),也要每个字清晰(保分辨率),所以用 MAINTAIN_RESOLUTION。同一个“降质”动作,对不同内容有截然不同的最优方向——这个洞察,让 WebRTC 的自适应不是一刀切,而是贴合场景。g3doc/adaptation.md 还指出:QP scaler 只在 MAINTAIN_FRAMERATE 或 BALANCED 下启用(因为它管的就是“降分辨率”这个维度)。
两个源头:带宽不够 vs 算力不够
自适应其实应对两种不同的短缺,别混淆:
- 带宽不够 —— 拥塞控制把目标码率压低了,编码器为塞进预算把 QP 提高、画质变差,QP scaler 于是触发降分辨率。根源在网络。
- 算力不够 —— 设备 CPU 忙不过来,编码耗时变长,encode usage resource 触发降质。根源在本机。
两者都通过同一套 Resource 机制表达为 overuse/underuse,VideoStreamEncoder 统一响应——不管是“网慢”还是“机器慢”,都是降质保流畅。这个统一抽象很漂亮:自适应不关心短缺的来源,只关心“过载了就降、宽裕了就升”。
自适应闭环
这个闭环和拥塞控制闭环并行运转:拥塞控制管“码率预算”,自适应管“在预算和算力下怎么分辨率 / 帧率取舍”——两者配合,让视频在烂网 + 弱机下也能维持可用体验。
小结与下一章
视频自适应在网络 / CPU 不够时降质保流畅。机制是 Resource 发 kOveruse/kUnderuse 信号:默认两个——QualityScaler 盯 QP(画质被压多狠 → 管降分辨率)、Encode Usage 盯编码耗时(CPU 代理)。降分辨率还是帧率由 DegradationPreference 定:通话 MAINTAIN_FRAMERATE(降分辨率保流畅)、共享屏幕 MAINTAIN_RESOLUTION(降帧率保清晰)。它统一应对“带宽不够”和“算力不够”两种短缺。
一路发一档视频是自适应,但要同时服务多个不同网络的接收者(会议里有人网好有人网差),得同时发多档——这就是联播与 SVC。下一章。👉 联播与 SVC。
参考资料
- [1] libwebrtc 源码.
g3doc/adaptation.md(Resource、QP scaler、encode usage、degradation preference)。 - [2] libwebrtc 源码.
video/adaptation/、modules/video_coding/utility/quality_scaler.h、api/adaptation/resource.h。 - [3]
api/video_codecs/video_encoder.h(QpThresholds、scaling_settings)。