牛刀 —— 汨罗网络屏幕投影软件的技术实现

将电脑显示通过网络,特别是WIFI连接到另外一个显示器显示出来,又叫网络投屏,无线投屏,WIFI Display,Miracast,镜屏、转屏、切屏、同屏等等,一个典型的应用,就是无线投影,笔记本电脑通过WIFI无线,直接投影,不需要接线。
  图1
  
  主流的技术实现方式就是:在电脑发送端,通过软件将屏幕捕捉下来(就是截屏),压缩后,通过网络传输到另外一个电脑接收后显示。另外这个设备可以是Windows、Linux或者Android等系统的电脑,或者定制的嵌入式接收解码设备,其实也是个电脑。原理说起来非常简单,但是实现起来却不简单,看看是哪些些企业在做这个,就应当明白这不是牛刀杀鸡。
  原来有一些专业厂商,比如Display  Link 的USB显示器,还有比如华为等一些硬件厂商生产销售的无线同屏器等,还有一些纯粹做软件的比如台湾的 MirrorOp等等,后来intel专门开发了WIDI无线投屏技术(Windows8.1以后,已经合并到微软的Miracast中),苹果有所谓airplay,谷歌有Miracast,微软也在Win8.1开始专门开发了所谓的WIFI Miracast,至此,这群顶尖的科技大腕基本到齐,来折腾这个网络投屏的东西。
  实现技术就是两个3步曲,发送端:截屏→压缩→传输,接收端:接收→解压→显示。
  在Windows系统里面,最简单的截屏函数,由微软提供GDI API,使用超级简单也可靠,但是速度比较慢,消耗系统资源较多;原来微软也提供了Mirror Driver就是,就是所谓镜像驱动方式,在XP下,可以明显提高截屏速度,减少CPU占用,虽然Win7也支持,但是在Win7下,速度和CPU占用没有什么优势。Win8以后,微软抛弃了镜像驱动方式,新支持GXDI方式,截屏速度和CPU占用比GDI有压倒性优势,但是也有些问题,比如有些窗口系统栏不能捕捉,有时引起鼠标闪烁,双显示卡使用NV显示不支持等等。
  按常理来想象,毕竟最终是显示卡显示,因此在显示卡直接拦截捕捉显示数据应当是个好办法。果然,intel和NVIDIA确有这种想法。intel在Media SDK中提供了屏幕捕捉插件,按照其说明,可以直接快速将显示卡的数据捕捉出来,但是文档说的清楚,在Windows 8.1以上,也是由系统的SDK实现的,我只能理解为由GXDI接口实现的。NVIDIA提供了Screen Capture SDK,看样子明显不是采用windows系统截屏SDK实现,应当是直接捕捉显示卡里面的数据,并且就一个函数,就可以直接压缩为H264数据,可惜,Screen Capture SDK只能在专业显示卡支持,普通市面销售的显示卡却不支持。AMD显示卡没有发现有类似SDK放出来。因此,在本软件中采用的是GXDI和GDI二种捕屏技术,在Win8.1以上的时候,优先采用GXDI,不支持时自动采用GDI方式,但是用户也可以强制指定GDI方式。
  图2
  
  捕捉屏幕后,如果不压缩,直接传输,当然效果最好,并且延迟也最小,但是数据量太大。按照1920*1080的屏幕,捕捉屏幕的数据是RGBA,这样,一个屏幕的数据量就是:1920*1080*4=8309760bytes,根据经验,每秒25帧是流畅的基本要求,如果要实时显示效果好,应当要到30帧以上,如果按照30帧,则30*8309760 = 249292800bytes,网络速度是安装bps计算的,也就是每个bytes要8个bps,这样就要求网络带宽249292800*8=1994342400,大约是1900G/s,这个要万兆以太网才可能,普通的WIFI网络实际网络速度一般都在5MBbytes/s以下,因此压缩是必须的。H265是最热门的压缩技术,目前大家都看好,但是,经过实践检验,需要占用CPU资源太大,虽然可以节省网络带宽,但是容易导致发送端CPU过高占用,引起卡顿。H264是目前最成熟的压缩方式,特别是在GPU支持时,还可以明显降低CPU这要求。本软件会自动检测,在支持Intel Media SDK的GPU时,就默认采用GPU压缩,当前主流的Intel CPU包含主流低档的凌动CPU都已经支持,因此压缩屏幕占用的CPU非常低,一般是在15%以下。不过随着软、硬件发展,相信将来是H265的天下,本软件默认采用H264,但用户可以手动选择H265压缩方式。
  图3
  
  传统以太网是一个没有优先级别的网络,但是目前的以太网,也支持优先级别。人耳朵对于声音最敏感,本软件采用了声音传输最高,其次是视频的网络QOS API。目前常规的标准方式投屏是,捕捉屏幕后,按照一定的标准压制成为H264或者H265的标准流格式,这样符合某种标准的接收终端就可以接收、解压并且播放了。但是,实践中发现,以太网,特别是WIFI网络是个非常不稳定的网络,电脑的CPU等,也是非常不同的,如果采用这种流的方式,往往难以保证好效果。本软件采用一对一的方式,每一帧图片压缩和解压播放都是全部自动适应的结果,这样保证了发送端,接收端系统、CPU、网络全部安装尽量优化自动适应,实际证明,这种做法效果良好,可以在300K左右,普通i3电脑流畅投屏高清电影,用户无明显感觉延迟,发送端CPU占用20%左右,效果非常理想。
  XP下捕捉声音比较复杂,该系统已经退出主流,因此本软件只支持Win7以上声音发送,当然XP作为接受端可以播放声音。WASAPI捕捉声音占用CPU少,速度快,通用性强,效果良好。采用aac压缩,开初打算采用100%质量,但是个人仔细听多个场景,感觉85%质量和100%听不出什么区别,因此采用85%aac压缩音频质量。人耳对延迟的敏感程度比眼睛要高多了,因此声音和屏幕是分别2个SOCKET端口发送,分别是4568和4567,发送声音的优先级别高于发送屏幕。
  作为声音捕捉发送,声音延迟是不可能彻底避免的,如果延迟不多,感觉不大,比如我个人感觉,声音延迟300ms(毫秒)以内,没有明显感觉,如果大于300毫秒,逐渐感觉明显起来;本软件在640ms左右的时候,就会强制同步。如果开始就缓存一定声音再播放,效果会更加顺滑些,但是就会引起延迟,本软件采取的策略是实时性优先,不缓存,立即播放,允许一定延迟积累。软件会实时显示投屏和投音的的网络和延迟情况:
  图4
  
  网络投屏,如果效果不好,2个方面的原因多见,一个是电脑配置或者系统运行太多任务问题,导致CPU占用太高,如果发现CPU老是占在100%,这样效果就差了。AMD的CPU容易出现这些情况,好在目前AMD CPU的笔记本少见了。Intel CPU目前大都支持GPU的H264硬件压缩,CPU占用就低了。另外一个主要问题是网络问题了。
  本软件一般速度有300K/S就可以流畅投屏,这样相当于网络速度2.4Mbps,是一个非常容易满足的要求,我采用一个10年前购买恐龙级别的磊科AP,穿过一堵墙,网络速度测试只有300K/S,也可以流畅投屏。但是在WIFI环境下,有些一些效果很差的AP,还有些网络复杂网络环境,导致超烂的WIFI网络状况,为了帮助用户诊断投屏问题,本软件专门实现了网络速度测试,只需要一个按钮,就一目了然,如果发现网络不能满足时,方便查找解决。一般正常WIFI连接时,在一个AP下的2台电脑,速度超过1MB/S,这样可以保证1920(1080流畅投屏,但是,有时在网络通过多个AP路由,或者信号条件不好时,WIFI网络速度下降到100~200K/S或者更低,投屏将明显卡顿。
  因为有些网络设备会对重复的数据进行压缩或者优化,因此本网速度测试是通过每个数据都是产生随机数字发送,避免这种压缩优化的影响。当网络速度很快时,比如高速有线网络,因为CPU产生随机数字速度制约,可能会不能发挥出高速网络速度,因而测得网速可能偏低,但是对于比较低速的WIFI网络,这个影响应当不大。
  图5
  
  本软件分为发送端和接收端,分部在不同电脑执行。执行发送端后,会自动通过UDP广播查找同一局域网的接收端,并填充到“投屏到”按钮右边的多选输入框中。由于UDP广播不能过路由,因此不能自动查找跨局域网电脑。但投屏可以跨局域网,用户可以直接填入接收端的IP地址或者主机名称,再按“投屏到”按钮即可。本软件只会在软件启动和IP地址变化时才发送UDP查询广播,避免轮询发送UDP广播导致网络负担。
  上次投屏成功的IP地址或者主机名称,会保存到注册表中,最多缓存3个,下次发送端软件会读取这个值。如果是上次缓存中的地址,同时UDP广播查找发现了,就会直接出现在输入框中,否则,下次软件启动时,输入框最上面一行是空,下面依次填入UDP广播发现的接收端IP地址,最底部是上次投屏成功缓存的IP或者主机名称。
  要发送成功,一个必要条件是发送端可以通过TCP/IP连接到接收端,如果垮网段,必须保证接收端可以访问。比如要通过互联网将屏幕投影到接收端,则接收端应当有公网IP地址或者设置端口映射的方式,这个可以发通过送端ping接收端来进行测试验证。
  如果没有AP,需要直连,可以直接将发送端或者接收端作为AP(微软叫做承载网络),这样也可以无需AP,直接点对点连接。
  图6
  
  WIFI Miracast,,仅限于WIFI直连使用,不能通过联网;毕竟电脑通常是联入网络使用的,这是常态,几乎相当要接电一样,因此,采用本软件这种自动发发现接收端,并且一键转屏的方式最直接和方便。
  采用本软件发送屏幕到投影仪,屏幕的自动适应比直接连接显示线材要强多了,不需要改变发送电脑本身屏幕分辨率,接收端完全自动适应。默认是保持发送端屏幕显示长宽比例,用户也可以指定全屏显示,有如下3个选项:
  图7
  
  在发送端和接收端显示比例是一样的时候,则接收端总是满屏显示。
  在发送端投屏到接收端如果屏幕比例不相同情况下,接收端有2种显示方式:
  一是接收端保持发送端的显示比例,不拉伸或者缩小,这样,图像就不失真,但是也就不满屏;该情况下,又分2种技术实现方式,一种是采用CPU计算,软件拉伸,这样兼容性最好,适合各种情况,因此是默认选项。另外一种,是由显示卡和显示器固件实现拉伸,等于就是调整屏幕分辨率实现,这样效果很好,速度最快,不占用CPU,目前测试电脑显示器基本没有问题,但是,某些硬件,比如某些品种康佳电视机做显示设备,可能会不满屏,硬件拉伸兼容性比软件拉伸稍差。
  在发送端和接收端协商发送屏幕尺寸时,本软件确定尺寸是最小的一端,理由很简单,发送更大尺寸屏幕图像不会提高最终显示效果,但是却会消耗更多的网络和计算资源。如果发送端和接收端屏幕尺寸一样,当然就不会发生缩放。
  每秒帧数,这是投屏最终显示流畅效果最终的指标,每个环节都有影响,包括屏幕捕捉,压缩,传输,解压缩,缩放拉伸,显示。其中,显示分辨率是直接影响到每个环节的指标,如果需要提高每秒帧数,改进流畅程度,缩小显示分辨率效果直接而明显。
  接收端在运行是,会阻止电脑进入休眠和屏幕保护,未接收时,显示接收端主机名称和IP地址:
  图8
  
  如果1分钟没有接收发送者,也没有鼠标键盘动作,会进入一个特定的屏幕保护程序,也就是10秒钟随机切换位置显示接收端主机和IP地址,如下:
  图9
  
  接收端默认是先来占住的策略,就是接收者正在接收时,另外一个发送者发送将会失败,并且会提示是具体哪个发送者正在发送。用户也可以设置接收者为抢来抢去的策略。由于局域网是内网,WIFI链接本身就可以设置密码,因此没有必要再在这个上面增加密码设置。
  汨罗是单词Mirror(镜像)的近音,也是一个地名,听说地名不能注册商标。原来去申请过2个商标,耗费若干钱财,但是也不成功。取地名不保护,也就免得别人反而申请商标来指责我侵权了,这种教训也是有的。
  2012年的时候,本人从事嵌入式系统开发的时候,曾经在飞思卡尔IMX53和RTL8511上面开发,初步实现了电脑传屏接收端的原型,嵌入式系统是linux,在ubuntu 12.04上面开发和编译,后来为了开发调试方便,将客户端改到Windows下,之后,也曾经编译开发过Andriod的版本,Andriod下有可以使用的版本,但是目前没有公开发布,现在总算搞出一个Windows发送端和接收端的成品出来,投屏效果已经感觉很理想了。
  本软件完全免费下载安装使用,如果不注册,会在投屏显示为注册版字样,除此之外没有其他限制。
    软件下载地址(新手只需要下载一个网络屏幕投影安装程序的文件即可):
    http://pan.baidu.com/s/1dFh2EFf
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值