虚拟显示器终极解决方案 IndirectDisplay
自从上了大学,因为学校到家的距离不算远,所以我经常两头跑。别人两头跑带个笔记本也就好了;我虽然也背着个重的一笔还有1060独显的SB2回家,但是还是经常有访问放在学校的PC的需求。
有需求就要解决,一开始我用的就是普通的RDP;RDP好是好,但是他没法调用显卡也没法打游戏,图像压缩算法也不适合串流。所以自然要掏出云游戏神器 Parsec
什么,你问我为啥要串流回学校打游戏?主要有三点,一是家里的电脑E3+Vega64虽然还能打不少游戏,但是肯定比不上3700X+2080;二是学校有千兆对等,这么高的上传不用一用就感觉很亏;三是因为我就是想折腾一下。
原因介绍完了,该掏出 Parsec 了。Parsec 以及 Moonlight、Steam 等等一系列游戏串流软件都有一个问题就是你必须有一个能输出的显示器他才能抓取到视频流,不然就是黑屏。我总不能一直把宿舍的显示器打开,方便全体舍友随时视奸我在干嘛吧。那么就得虚拟一个显示器(Dummy Display / Fake Display),无非五种方案:
- 专业级显卡直接支持添加 EDID Profile 来虚拟显示器(NVIDIA GRID)
- 用 HDMI 诱骗器(假负载),淘宝十五一个
- SplashTop、VNC 的虚拟显示器(不清楚具体实现)
- Windows 10 1607 之前的系统可以通过强制 VGA 输出(如图)
- Windows 10 的 Indirect Display
有钱人选第一种,穷一点的选第二种;第三种我从来没成功过但是 AJ 大哥说可以;第四种没试过;而今天要说的就是第五种。
事情的一开始就是 AJ 跟我说他找到了一个很不错的虚拟屏幕驱动,我尝试了一下,确实很好用,但是只有一个问题:固定了1920x1080分辨率
接下来我就掏出 IDA 对着这个驱动 usbmmIdd.dll 一顿艹,强行把里面的1920x1080改成3840x2160,结果我获得了一个没有分辨率模式选择的显示器
既然直接修改没法用,那就尝试探究一下原理吧,我在它的 inf 里看到了这么一段注释
; usbmmm.inf
;
; Installation inf for the USB Mobile Monitor Indirect Display Adapater
; http://www.usbmobilemonitor.com
; Copyright Amyuni Technologies: http://www.amyuni.com
;
其中这个 Indirect Display 吸引了我,经过鸟姐姐的提醒我找到了微软官方的 Indirect Display Sample
还有一篇 CSDN 上的付费文章以及一个不开源的 GitHub 项目...
自然我们肯定会选择自己编译一份用,毕竟那个项目其实是个远控项目而虚拟显示器只是其中的一部分,咱们用不着。
代码写下来,找到驱动的代码,往里面注入自己需要的 EDID 和显示模式(分辨率),然后编译安装即可。(编译需要 Windows Driver Kit)
经过测试,Windows 桌面以及 CSGO 等游戏都可以正常识别并输出到这个显示器,Parsec 也可以抓到视频流,效果不错
下面附上我编译好的驱动(2024年2月14日在 Win 11 下编译更新),供没有环境的读者直接使用,里面已经包括了1080P、2K、4K以及iPad Pro(2388x1668)这四个常用分辨率的模式;如果有读者对可执行文件的安全性有疑虑,或者缺少了你需要的分辨率,可以自己编译一份。
https://archeb-my.sharepoint.com/:u:/g/personal/i_gfw_moe/Ecf6B-anUPRJtf3U9jhw_bMB0CCH3QIKuWaaqrnIOMID9w?e=TzixoM
最后分享一个小技巧,Parsec 手动加上 encoder_min_bitrate = 50
这个参数到 config 里可以强行设置最低码率,只要带宽足够一点都不会糊。我串流打 CSGO 的时候一般都在 45Mbps 左右,没有出现掉帧卡顿花屏的情况。Parsec
默认的码率选择十分弱智,你选 50Mbps 它实际只用 15Mbps,建议大家都手动调一下这个参数。
You may read the English version of this post here:
https://archeb.medium.com/how-to-run-parsec-without-monitor-heres-a-virtual-monitor-solution-for-you-indirect-display-ecba5173b86a