ci / rust (push) Canceled after 0s
ci / web (push) Canceled after 0s
ci / package-preview (push) Canceled after 0s
ci / package-installer (push) Canceled after 0s
ci / linux-agent (push) Canceled after 0s
ci / edge-service (push) Canceled after 0s
ci / coturn-pop (push) Canceled after 0s
ci / package-windows-host (push) Canceled after 0s
219 lines
11 KiB
Markdown
219 lines
11 KiB
Markdown
# RemoteDesk 差网络自适应设计
|
||
|
||
## 1. 目标
|
||
|
||
RemoteDesk 在延迟、抖动、随机丢包和突发丢包变化时保持会话可控制。优先级固定为:
|
||
|
||
```text
|
||
键盘/鼠标按键 > 控制与心跳 > 音频 > 视频实时性 > 视频清晰度 > 剪贴板 > 文件传输
|
||
```
|
||
|
||
目标不是在任意丢包率下维持最高画质,而是在恶化时快速退化、避免断开,在恢复时平稳升档。
|
||
|
||
## 2. 两类连接
|
||
|
||
### 2.1 Linux Native Channel
|
||
|
||
Linux 桌面使用 WebRTC,可以利用 RTP/RTCP、TWCC、GCC、NACK、RTX、PLI 和 Opus FEC。RemoteDesk 不重新实现底层拥塞控制,只在 GStreamer/WebRTC 的带宽估算上增加产品级质量策略。
|
||
|
||
同一策略适用于 Direct、Single Edge 和 Dual Edge。质量报告增加 path mode、两端 POP、TURN transport、骨干指标和 ICE restart 次数,用于区分最后一公里问题、POP 间路径问题和端点过载。
|
||
|
||
### 2.2 Windows RDP
|
||
|
||
RDP 的网络恢复能力由 IronRDP 协议实现决定。M0 必须验证:
|
||
|
||
- RDP UDP multitransport。
|
||
- 图形管线在丢包和重连后的恢复行为。
|
||
|
||
### 2.3 Windows Headless Hysteria2
|
||
|
||
Windows Headless 使用 Hysteria2 作为网络承载,但应用层必须保持输入、音频和视频分流:
|
||
|
||
control stream:输入、心跳、配置和 KeyframeRequest,可靠且最高优先级。
|
||
|
||
audio path:Opus,独立 jitter buffer,允许 PLC/FEC。
|
||
|
||
video datagram:H.264/HEVC/AV1,允许丢包和丢帧。
|
||
|
||
file stream:文件和剪贴板,可靠、最低优先级、限速。
|
||
|
||
视频不能放入会因丢包而阻塞后续数据的可靠流。Hysteria2 的 datagram 能力必须由具体 adapter 验证;不能仅因为底层使用 UDP 就假设应用已经具备不可靠语义。若某部署只能提供可靠 QUIC stream,Windows Headless 视频通道不得宣称实时丢包模式。
|
||
|
||
视频分片带有 stream_id、generation、frame_id、fragment_id、fragment_count、PTS 和关键帧标记。缺少任意分片时丢弃整个视频帧;重组超时或帧已过期时立即丢弃;不重传过期视频包。关键帧或参考链损坏后通过控制流请求 IDR。
|
||
|
||
无硬件 GPU 时 compatibility 模式会进一步受 CPU 编码预算限制。编码器报告 software/degraded 后,质量控制器必须优先降低视频帧率和分辨率,再降低码率;视频队列不得因 CPU 编码变慢而无限增长。输入控制和 Opus 音频保持独立调度,软件编码过载时可以丢弃过期视频帧,但不能阻塞输入或音频。
|
||
|
||
Hysteria2 的带宽和队列不能让视频占满控制面。输入预留最高优先级,音频次之,视频使用有界队列,文件只使用剩余带宽。必须监控路径 RTT、抖动、队列延迟、包丢失、输入延迟和音画偏差,而不是只观察总吞吐。
|
||
- 动态调整视觉效果、色深或编码模式的能力。
|
||
- UDP 不可用时 TCP 模式的延迟和队头阻塞表现。
|
||
|
||
若 IronRDP 尚不支持关键网络能力,差网络场景使用系统 mstsc 回退,并在客户端明确显示当前 Adapter。
|
||
|
||
## 3. 质量指标
|
||
|
||
每秒收集原始指标,并计算短期、中期 EWMA:
|
||
|
||
| 指标 | 来源 | 用途 |
|
||
|---|---|---|
|
||
| RTT | RTCP/DataChannel heartbeat | 交互延迟和重传收益 |
|
||
| Packet loss | RTCP report | 退档和恢复判断 |
|
||
| Jitter | RTCP report | jitter buffer 和帧率判断 |
|
||
| Available bitrate | TWCC/GCC | 编码码率上限 |
|
||
| NACK/RTX rate | RTP feedback | 判断持续丢包与重传成本 |
|
||
| PLI/FIR | decoder feedback | 请求关键帧和诊断解码失败 |
|
||
| Decode/render time | Windows Client | 判断客户端过载而非网络问题 |
|
||
| Send/encode queue | Linux Agent | 判断编码或上行拥塞 |
|
||
| DataChannel buffered amount | SCTP | 限制文件与剪贴板流量 |
|
||
|
||
网络问题、编码器过载和解码器过载必须分别诊断,不能全部显示成“网络差”。
|
||
|
||
## 4. 链路状态机
|
||
|
||
默认状态分级仅作为初始调参基线:
|
||
|
||
| 状态 | 参考信号 | 行为 |
|
||
|---|---|---|
|
||
| Good | 丢包 <1%,RTT/抖动稳定 | 缓慢提高码率或分辨率 |
|
||
| Fair | 丢包 1%~5% 或抖动上升 | 降低码率,保持分辨率和输入响应 |
|
||
| Poor | 丢包 5%~12% 或连续 PLI | 降帧率/分辨率,启用适合的恢复机制 |
|
||
| Critical | 丢包 >12%、RTT 激增或反馈中断 | 最低视频档,暂停文件传输,准备重连 |
|
||
|
||
真实决策组合使用可用码率、RTT、抖动和队列,不只看一个丢包数字。
|
||
|
||
状态转换规则:
|
||
|
||
- 恶化使用短窗口,连续多个样本后快速降档。
|
||
- 恢复使用更长窗口,稳定后一次只升一档。
|
||
- 刚升档后设置冷却时间,防止立刻回落。
|
||
- 用户设置的最大分辨率、帧率和码率始终是硬上限。
|
||
- 窗口不在前台时主动降低帧率,不归类为网络退化。
|
||
|
||
## 5. 视频自适应
|
||
|
||
质量控制器管理三个独立维度:
|
||
|
||
1. 码率:优先调整,支持编码器运行时更新。
|
||
2. 帧率:动态画面从 60 降至 30/20/15 fps。
|
||
3. 分辨率:码率不足时按档位降采样,不频繁重建会话。
|
||
|
||
建议的初始阶梯:
|
||
|
||
```text
|
||
2160p60 -> 2160p30 -> 1440p30 -> 1080p30 -> 720p30 -> 720p15
|
||
```
|
||
|
||
实际起始档由显示器、编码器和用户上限决定。办公静态桌面可以降低刷新频率但保持较高分辨率;动态画面可以优先保持帧率并降低清晰度。
|
||
|
||
用户分辨率策略与自适应的关系:
|
||
|
||
- 自动跟随:稳定窗口尺寸作为当前目标和上限,窗口拖动期间不连续重配编码器。
|
||
- 原始分辨率:源桌面尺寸作为上限;本地窗口缩放不触发源尺寸变化。
|
||
- 固定/自定义:所选宽高是编码目标和硬上限,网络恢复也不能自动升得更高。
|
||
- 允许自适应降档(默认):Poor/Critical 状态可临时低于用户目标,恢复后逐级回到目标。
|
||
- 锁定分辨率:不自动降尺寸,优先降低码率和帧率;若仍超出带宽则明确提示卡顿/画质风险。
|
||
|
||
Linux 的自适应只重配 GPU video processor/scaler、DMA-BUF caps 和硬件编码器,不调用 Wayland 合成器设置或 XRandR 改变实体显示模式。分辨率切换保留控制通道,完成后发送新 generation、实际编码尺寸并请求关键帧。Agent 和客户端在新 generation 上重新验证 `EndpointMemoryPath`;若任一端变成 CPU/cross-GPU copy,严格会话暂停媒体并失败,不能为了降分辨率静默破坏零拷贝。接收端在首个新尺寸关键帧到达前保持最后一帧,避免短暂黑屏。
|
||
|
||
编码器策略:
|
||
|
||
- 编码码率跟随 GCC target,但保留音频和控制余量。
|
||
- GOP 不宜过长,避免丢失参考帧后长期花屏。
|
||
- 收到 PLI/FIR 时请求 IDR,但限制关键帧频率,防止反馈风暴。
|
||
- 丢弃已过期的待编码帧,实时性优先于完整性。
|
||
- 只在短 RTT 下积极使用 RTX;高 RTT 下过时重传价值较低。
|
||
- FEC 通过能力协商启用,并计入总带宽,不默认无条件开启。
|
||
|
||
## 6. 音频
|
||
|
||
- Opus 使用独立 RTP 流和较高优先级。
|
||
- 差网络时优先降低视频,不先中断音频。
|
||
- 按协商结果启用 Opus in-band FEC。
|
||
- 静音或无音频时使用 DTX 降低占用。
|
||
- jitter buffer 自适应但设置交互场景最大延迟上限。
|
||
|
||
## 7. 输入和控制
|
||
|
||
输入消息按语义选择可靠性:
|
||
|
||
| 消息 | 可靠性 |
|
||
|---|---|
|
||
| 键盘按下/释放 | 可靠、有序 |
|
||
| 鼠标按键 | 可靠、有序 |
|
||
| 鼠标绝对位置 | 可丢弃旧值,最新值优先 |
|
||
| 鼠标相对移动 | 短时有序,过期不重传 |
|
||
| 滚轮 | 有序,限制短时合并 |
|
||
| 分辨率/显示器 | 可靠、有序 |
|
||
| 心跳/会话控制 | 可靠、独立 channel |
|
||
|
||
断线或重连时,客户端与 Agent 交换完整按键/鼠标状态,主动释放可能卡住的按键。
|
||
|
||
## 8. 剪贴板和文件
|
||
|
||
- 与输入使用不同 DataChannel,避免队头阻塞。
|
||
- 设置 `bufferedAmount` 高水位,超过后暂停生产数据。
|
||
- Poor 状态限制剪贴板图片和文件带宽。
|
||
- Critical 状态暂停文件传输,但保留取消和状态消息。
|
||
- 恢复后继续按已确认分块序号传输,不重发整个文件。
|
||
- 大量粘贴不能挤占终端交互消息。
|
||
|
||
## 9. 重连
|
||
|
||
```text
|
||
Connected
|
||
-> Degraded
|
||
-> Reconnecting
|
||
-> Connected | Failed
|
||
```
|
||
|
||
- 短时反馈丢失先进入 Degraded,不立即关闭会话。
|
||
- WebRTC 尝试 ICE restart;直接连接环境仍可能因接口变化需要重建 PeerConnection。
|
||
- Direct candidate 失败时可以切换 TURN POP;POP 故障时请求备用 POP credential 后再次 ICE restart。
|
||
- 重连期间 Linux session 进程保留有限时间,编码暂停或降到最低。
|
||
- 成功后先恢复输入/控制,再恢复音频和视频。
|
||
- 重连后请求关键帧,并同步显示器与输入状态。
|
||
- 超过最大宽限期明确结束,不无限占用远端资源。
|
||
|
||
## 10. 用户设置
|
||
|
||
提供简单预设,不要求用户理解协议参数:
|
||
|
||
- 自动:默认,自适应所有档位。
|
||
- 清晰:提高最低分辨率,允许更低帧率。
|
||
- 流畅:保持目标帧率,允许更快降分辨率。
|
||
- 低带宽:限制最大码率、分辨率和文件速度。
|
||
|
||
分辨率设置独立于画质预设,可选自动跟随、原始、720p、1080p、1440p、4K 或自定义。画质预设只能在分辨率上限以内选择档位,不能覆盖用户设定的上限。
|
||
|
||
路径策略独立于画质预设:
|
||
|
||
- 智能优选:默认,并行评分 Direct/Single/Dual。
|
||
- 直连优先:直连达到最低质量门槛时不使用 CDN。
|
||
- CDN 优先:优先双边缘优质骨干,失败后回退其他路径。
|
||
|
||
高级诊断页可查看 RTT、丢包、抖动、码率、帧率、编码/解码耗时、重传和当前档位,但不允许任意修改危险的底层 RTP 参数。
|
||
|
||
## 11. 测试
|
||
|
||
在虚拟化测试网络中通过 Linux bridge/network namespace 和 `tc netem` 注入:
|
||
|
||
- 随机丢包:1%、3%、5%、10%、15%。
|
||
- 突发丢包:短突发与 Gilbert-Elliott 模型。
|
||
- RTT:30、100、250、500 ms。
|
||
- 抖动:10、30、80 ms。
|
||
- 带宽阶跃:20 Mbps 降到 2 Mbps,再恢复。
|
||
- 重排、重复包和短时完全中断。
|
||
- Direct、TURN UDP、TURN TCP/TLS 和 POP 故障切换。
|
||
- Direct 可用但跨网质量差时选择 Dual Edge,并验证 POP 间骨干路径。
|
||
|
||
验收目标:
|
||
|
||
- 5% 随机丢包下会话不主动断开,输入保持可用。
|
||
- 10% 突发丢包后在数秒内降档,不持续花屏。
|
||
- 网络恢复后平稳升档,不发生持续码率振荡。
|
||
- 文件传输不会阻塞键盘、鼠标和心跳。
|
||
- 丢失关键视频参考帧后能通过 PLI/IDR 恢复。
|
||
- 日志可以区分网络、编码和解码瓶颈。
|
||
- 诊断可以区分 Direct/Relay、POP 和 TURN transport。
|
||
|
||
具体时延和画质阈值在 M0/M3 的真实机器测试后锁定,不能只凭模拟器数据决定。
|