11 KiB
RemoteDesk 差网络自适应设计
1. 目标
RemoteDesk 在延迟、抖动、随机丢包和突发丢包变化时保持会话可控制。优先级固定为:
键盘/鼠标按键 > 控制与心跳 > 音频 > 视频实时性 > 视频清晰度 > 剪贴板 > 文件传输
目标不是在任意丢包率下维持最高画质,而是在恶化时快速退化、避免断开,在恢复时平稳升档。
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. 视频自适应
质量控制器管理三个独立维度:
- 码率:优先调整,支持编码器运行时更新。
- 帧率:动态画面从 60 降至 30/20/15 fps。
- 分辨率:码率不足时按档位降采样,不频繁重建会话。
建议的初始阶梯:
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. 重连
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 的真实机器测试后锁定,不能只凭模拟器数据决定。