fix(vdd): 避免旋转后恢复串流错误重建虚拟显示器 - #889
Conversation
Summary by CodeRabbit
Walkthrough新增显示方向辅助函数和广告模式匹配分类器。 Changes广告显示模式匹配
Estimated code review effort: 3 (Moderate) | ~20 minutes Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
48d221d to
1ee6f54
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/display_device/vdd_utils.cpp`:
- Around line 817-844: 在 wait_for_mode_publication 的超时返回 false
路径中补充一次诊断日志,记录当前显示方向以及 Windows 实际枚举到的每个模式的宽度、高度和刷新率;复用或扩展 is_mode_advertised
的枚举结果传递方式,确保完整列表只在最终超时时输出一次,而不是每次轮询重复记录。
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: aeb748ab-ba6b-4290-8f6b-5576e8dec6cc
📒 Files selected for processing (3)
src/display_device/vdd_utils.cppsrc/display_device/vdd_utils.htests/unit/test_vdd_safety.cpp
🚧 Files skipped from review as they are similar to previous changes (2)
- tests/unit/test_vdd_safety.cpp
- src/display_device/vdd_utils.h
📜 Review details
🧰 Additional context used
📓 Path-based instructions (1)
src/**/*.{cpp,c,h}
⚙️ CodeRabbit configuration file
src/**/*.{cpp,c,h}: Sunshine 核心 C++ 源码,自托管游戏串流服务器。审查要点:内存安全、 线程安全、RAII 资源管理、安全漏洞。注意预处理宏控制的平台相关代码。
Files:
src/display_device/vdd_utils.cpp
🔇 Additional comments (1)
src/display_device/vdd_utils.cpp (1)
58-77: LGTM!
| DEVMODEW current_mode {}; | ||
| current_mode.dmSize = sizeof(current_mode); | ||
| const bool orientation_known = | ||
| EnumDisplaySettingsW(wide_display_name.c_str(), ENUM_CURRENT_SETTINGS, ¤t_mode) && | ||
| (current_mode.dmFields & DM_DISPLAYORIENTATION) != 0; | ||
| const bool swaps_axes = orientation_known && orientation_swaps_axes(current_mode.dmDisplayOrientation); | ||
|
|
||
| for (DWORD index = 0; index < 4096; ++index) { | ||
| DEVMODEW mode {}; | ||
| mode.dmSize = sizeof(mode); | ||
| if (!EnumDisplaySettingsW(wide_display_name.c_str(), index, &mode)) { | ||
| break; | ||
| } | ||
|
|
||
| if (advertised_mode_matches( | ||
| mode.dmPelsWidth, | ||
| mode.dmPelsHeight, | ||
| mode.dmDisplayFrequency, | ||
| requested_mode)) { | ||
| const auto match = classify_advertised_mode( | ||
| mode.dmPelsWidth, | ||
| mode.dmPelsHeight, | ||
| mode.dmDisplayFrequency, | ||
| requested_mode, | ||
| swaps_axes); | ||
| if (match == advertised_mode_match_e::rotation_equivalent) { | ||
| BOOST_LOG(info) << "VDD mode " | ||
| << requested_mode.resolution.width << 'x' << requested_mode.resolution.height | ||
| << " is available through the current " | ||
| << orientation_degrees(current_mode.dmDisplayOrientation) | ||
| << "-degree display orientation; reusing the existing monitor"; | ||
| } | ||
| if (match != advertised_mode_match_e::none) { |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
补齐模式发布超时的诊断信息。
is_mode_advertised 只在发现 rotation_equivalent 时记录方向。若没有匹配,wait_for_mode_publication 会在 Line 863 直接返回 false,但当前代码没有记录当前方向或 Windows 实际枚举的 (width, height, refresh) 列表。请在超时路径记录一次这些信息,并避免在每次轮询时重复输出完整列表。
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/display_device/vdd_utils.cpp` around lines 817 - 844, 在
wait_for_mode_publication 的超时返回 false 路径中补充一次诊断日志,记录当前显示方向以及 Windows
实际枚举到的每个模式的宽度、高度和刷新率;复用或扩展 is_mode_advertised
的枚举结果传递方式,确保完整列表只在最终超时时输出一次,而不是每次轮询重复记录。
说明
客户端跟随屏幕旋转后,Windows 会根据当前显示方向交换 VDD 模式的逻辑宽高。恢复串流请求仍使用原始分辨率,原有的精确匹配会将旋转后的等价模式判定为缺失,触发无效重建,并可能导致恢复请求返回 503。
修改
该修改不改变客户端协议,也不放宽未旋转状态下的模式匹配。