[bitrate] 启动码率 11 Mbps 忽略后续 BWE 反馈,首个 IDR 偏大 #21

Closed
opened 2026-06-13 23:05:33 +08:00 by dailz · 0 comments
Owner

现象

启动序列:

时刻 事件 码率
14:47:55.119 编码器初始化 11 059 200 bps(auto)
14:48:01.886 WebRTC 连上,首条 BWE 5 000 000 bps
14:48:01.889 应用 BWE 反馈 target_bps=5000000
14:48:01.917 首 IDR 47 039 字节(≈ 750ms @ 500kbps 等价)

会话初期 ~6 秒编码器在 11Mbps 跑,但彼时无客户端(见 #19);客户端连上后立刻发现 BWE 只有 5Mbps,编码器在 1ms 内降到 5Mbps——但首 IDR 已在更早 14:47:55–14:48:01 窗口若开启 --output 模式会被以 11Mbps 写出。

根因

src/state_portal.rs:200-202

let actual_bitrate = self.args.bitrate.unwrap_or_else(|| {
    5 * (enc_width as u64) * (enc_height as u64) * (self.args.fps as u64) / 100
});

固定公式 5 × W × H × fps / 100,不考虑:

  • 网络 BWE(WebRTC 模式下尚无连接,可理解)
  • 显示器实际刷新率(不一定 = fps 设定)
  • 编码内容复杂度

WebRTC 模式下 BWE 要等客户端连接后才到,所以冷启动 IDR 一定会跑偏

影响

  • 模式相关:
    • WebRTC:首 IDR 后立即被 BWE 修正,影响较小(只是 IDR 偏大,1 帧瞬时 burst 可能造成短暂拥塞)
    • --output 文件模式:直接以 11Mbps 写 mp4,文件偏大且无任何反馈机制纠正
  • libx264 启动时打印多条 VBV bitrate (2000000) > level limit (62500) 警告,噪音

修复方向

WebRTC 模式

  1. 推迟编码器初始化到首个 BWE 到达后(或首个 keyframe request)
  2. 若坚持预初始化,用保守默认(如 2 Mbps)而非 11 Mbps
  3. 首 IDR 后立即检查是否已有 BWE,若有则立即 avcodec_send_frame 重设 rc_bitrate

--output 模式

  1. 当前公式作为默认可保留,但日志应明确输出"无反馈通道,码率固定"
  2. 文档/CLI help 标注建议值范围(1080p30 ≈ 5–8 Mbps,1440p60 ≈ 12–16 Mbps)

关联

  • #19 启动空转期间 11Mbps 让 CPU 占用更高
  • 首帧 47KB burst 在低带宽客户端上可能触发早期丢包 → 视频端 PLI → 触发 #16 的 2 秒等待
## 现象 启动序列: | 时刻 | 事件 | 码率 | |---|---|---| | `14:47:55.119` | 编码器初始化 | **11 059 200 bps**(auto) | | `14:48:01.886` | WebRTC 连上,首条 BWE | 5 000 000 bps | | `14:48:01.889` | 应用 BWE 反馈 | target_bps=5000000 | | `14:48:01.917` | 首 IDR | **47 039 字节**(≈ 750ms @ 500kbps 等价) | 会话初期 ~6 秒编码器在 11Mbps 跑,但彼时无客户端(见 #19);客户端连上后立刻发现 BWE 只有 5Mbps,编码器在 1ms 内降到 5Mbps——但首 IDR 已在更早 14:47:55–14:48:01 窗口若开启 `--output` 模式会被以 11Mbps 写出。 ## 根因 `src/state_portal.rs:200-202`: ```rust let actual_bitrate = self.args.bitrate.unwrap_or_else(|| { 5 * (enc_width as u64) * (enc_height as u64) * (self.args.fps as u64) / 100 }); ``` 固定公式 `5 × W × H × fps / 100`,不考虑: - 网络 BWE(WebRTC 模式下尚无连接,可理解) - 显示器实际刷新率(不一定 = fps 设定) - 编码内容复杂度 WebRTC 模式下 BWE 要等客户端连接后才到,所以**冷启动 IDR 一定会跑偏**。 ## 影响 - 模式相关: - **WebRTC**:首 IDR 后立即被 BWE 修正,影响较小(只是 IDR 偏大,1 帧瞬时 burst 可能造成短暂拥塞) - **`--output` 文件模式**:直接以 11Mbps 写 mp4,文件偏大且无任何反馈机制纠正 - `libx264` 启动时打印多条 `VBV bitrate (2000000) > level limit (62500)` 警告,噪音 ## 修复方向 **WebRTC 模式**: 1. 推迟编码器初始化到首个 BWE 到达后(或首个 keyframe request) 2. 若坚持预初始化,用保守默认(如 2 Mbps)而非 11 Mbps 3. 首 IDR 后立即检查是否已有 BWE,若有则立即 `avcodec_send_frame` 重设 rc_bitrate **`--output` 模式**: 1. 当前公式作为默认可保留,但日志应明确输出"无反馈通道,码率固定" 2. 文档/CLI help 标注建议值范围(1080p30 ≈ 5–8 Mbps,1440p60 ≈ 12–16 Mbps) ## 关联 - #19 启动空转期间 11Mbps 让 CPU 占用更高 - 首帧 47KB burst 在低带宽客户端上可能触发早期丢包 → 视频端 PLI → 触发 #16 的 2 秒等待
dailz added the area/webrtctype/enhancementarea/encoderpriority/medium labels 2026-06-13 23:05:33 +08:00
dailz closed this issue 2026-06-21 10:10:20 +08:00
Sign in to join this conversation.