[startup] WebRTC 客户端连接前编码器空转 6 秒(encode 180+ 帧到 void) #19

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

现象

时间线:

时刻 事件
14:47:55.119 编码器初始化完成(libx264 2560×1440 @ 11Mbps)
14:47:55.119 First frame processed, encoder initialized, transitioning to Streaming
14:47:56.178 stats: encoded_fps=29.7 sent_fps=0.0空转开始可见
...(持续 6 秒)... encoded_fps ≈ 23–32,sent_fps = 0
14:48:01.892 WebRTC connected
14:48:01.917 first IDR produced

6 秒内编码器产出 ~180 帧但无处可去(彼时还没有 WebRTC client,也没开 --output)。

根因(怀疑)

src/state_portal.rs:706-713 维护 paused 标志:

let now_paused = !connected;
if was_paused && !now_paused {
    tracing::info!("WebRTC client connected, resuming encoding");
}
paused.store(now_paused, Ordering::Relaxed);

paused 初始值默认是 true(语义上"未连接即暂停"),但:

  1. 该循环只在 WebRTC 主循环 tick 时执行;编码线程可能在 paused 置位前已消费若干帧
  2. encode_cpu_frame 的 paused 检查(src/avhw.rs:1116-1120)依赖 self.webrtc_paused: Option<Arc<AtomicBool>>——若该字段为 None永不暂停
  3. 需要确认 webrtc_paused 是否在 SwEncImport::new_webrtc() 路径正确传递

影响

  • 启动后到客户端连接前,CPU 持续 ~30fps 软编 1440p H.264(保守估计 15–25% 单核)
  • 笔记本/移动场景浪费电量
  • 编码器产出的所有帧丢弃——纯损耗

期望行为

  • --output 未指定 + 无 WebRTC client:编码器完全不应启动,或启动后立即进入 paused
  • --output 模式:编码器应运行(写文件)
  • --port 模式:编码器在 WebRTC client connect 之前不应运行

修复方向

  1. StatePortal::new() 阶段,WebRTC 模式下显式初始化 paused = true
  2. 验证 SwEncEncode::webrtc_paused 字段在 encode 线程 spawn 前已 Some(...)
  3. (可选)启动时不立即 spawn 编码线程,等首个 WebRTC client connect 再 spawn

复现

wl-webrtc --port 56666 -v
# 注意日志 14:47:55 到客户端连接之间的 stats 行
# 关注 encoded_fps > 0 且 sent_fps = 0 的窗口
## 现象 时间线: | 时刻 | 事件 | |---|---| | `14:47:55.119` | 编码器初始化完成(libx264 2560×1440 @ 11Mbps) | | `14:47:55.119` | `First frame processed, encoder initialized, transitioning to Streaming` | | `14:47:56.178` | stats: `encoded_fps=29.7 sent_fps=0.0` ← **空转开始可见** | | ...(持续 6 秒)... | encoded_fps ≈ 23–32,sent_fps = 0 | | `14:48:01.892` | WebRTC connected | | `14:48:01.917` | first IDR produced | **6 秒内编码器产出 ~180 帧但无处可去**(彼时还没有 WebRTC client,也没开 --output)。 ## 根因(怀疑) `src/state_portal.rs:706-713` 维护 `paused` 标志: ```rust let now_paused = !connected; if was_paused && !now_paused { tracing::info!("WebRTC client connected, resuming encoding"); } paused.store(now_paused, Ordering::Relaxed); ``` `paused` 初始值默认是 `true`(语义上"未连接即暂停"),但: 1. 该循环只在 WebRTC 主循环 tick 时执行;编码线程可能在 paused 置位前已消费若干帧 2. `encode_cpu_frame` 的 paused 检查(`src/avhw.rs:1116-1120`)依赖 `self.webrtc_paused: Option<Arc<AtomicBool>>`——若该字段为 `None` 则**永不暂停** 3. 需要确认 `webrtc_paused` 是否在 `SwEncImport::new_webrtc()` 路径正确传递 ## 影响 - 启动后到客户端连接前,CPU 持续 ~30fps 软编 1440p H.264(保守估计 15–25% 单核) - 笔记本/移动场景浪费电量 - 编码器产出的所有帧丢弃——纯损耗 ## 期望行为 - `--output` 未指定 + 无 WebRTC client:编码器**完全不应启动**,或启动后立即进入 paused - 仅 `--output` 模式:编码器应运行(写文件) - 仅 `--port` 模式:编码器在 WebRTC client connect 之前不应运行 ## 修复方向 1. 在 `StatePortal::new()` 阶段,WebRTC 模式下显式初始化 `paused = true` 2. 验证 `SwEncEncode::webrtc_paused` 字段在 encode 线程 spawn 前已 `Some(...)` 3. (可选)启动时不立即 spawn 编码线程,等首个 WebRTC client connect 再 spawn ## 复现 ```bash wl-webrtc --port 56666 -v # 注意日志 14:47:55 到客户端连接之间的 stats 行 # 关注 encoded_fps > 0 且 sent_fps = 0 的窗口 ```
dailz added the area/encoderpriority/higharea/pipelinetype/bug labels 2026-06-13 23:04:21 +08:00
dailz closed this issue 2026-06-20 19:57:25 +08:00
Sign in to join this conversation.