漫谈 5G 时代的云游戏

何为云游戏

每个人都打过游戏,以表现形式划分,有PC端游、主机游戏、页游、手游、游戏机等。这些游戏都有一个共同特点,就是游戏画面都是在 本地设备上实时渲染 的,要注意渲染指的是一帧帧的游戏画面,不是游戏资源文件,资源文件可以是一次性下载好或者在线下载的,比如《魔兽世界》的资源包在30G左右,光是安装游戏就要一天。

由于游戏渲染需要大量计算,操作流畅的游戏1秒钟需要绘制25帧以上的画面。为了玩的爽,玩家必须要买高端显卡、专业主机,或者最新款的旗舰手机。看新闻上说,NVIDIA又出了一款光线追踪显卡,具有超强的光线表现力(人物模型额头闪闪发光),价格感人,最高售价1W刀。

这样就引入一个思考,每个玩家都要花大把银子升级游戏设备,有没有更便捷的方式玩游戏呢? 比如我有一台轻薄的上网本、一个低配的手机,可以玩游戏大作吗?

云游戏的出现就是为了实现这个目的,将游戏放到 服务端 运行,玩家只需要一个 普通的连网设备 ,通过网络获取游戏实时画面,可以理解为玩家在看一个游戏视频,只不过这个视频是可以互动的。

相信很多人的第一反应是这个靠谱吗,我怎么没听说哪个游戏是这么玩的。要相信技术发展是日新月异的,无人驾驶就是个很好的范例,大家都觉得很遥远,但是特斯拉已经支持无人驾驶了,特斯拉车主已经每天在用这项功能了。

google在2019年3月发布了 Stadia云游戏 平台,相信在5G时代,云游戏一定是靠谱的。

实现方案

云游戏的发展趋势让时间去证明,我们更关心的是技术实现方案,其实云游戏和直播有些类似的地方,都是 连网获取实时画面、可以互动、要求低延迟 ,不同之处在于数据来源不同,云游戏的数据来自于游戏画面,直播来源于主播的直播设备,那么可以参考直播技术。

直播的流程为:

  1. 主播端 画面采集

  2. 主播端 推流至服务端

  3. 服务端 将视频流分发到各个负载节点

  4. 观众端 获取视频流并播放

展开来说:

主播端为数据生产者,需要通过摄像头采集 实时画面 ,ios、android都提供了sdk来获取摄像头画面,假定1秒采集25帧画面,这25帧画面是原始RGB图像数据,不能直接传输到服务端,因为数据量太大了。 

数据量可以计算下,假定分辨率为1920*1080,每个像素点有3个字节存储RGB颜色,则每一帧的数据量= 1920*1080*3.0/1024/1024 = 5.9M, 那么 25帧的数据量 = 148M,意味着1秒钟需要传输148兆的数据,这个5G也够呛。

原始画面需要压缩传输,这个就属于视频编码的技术领域,可能听说过 H.264编码 吧,至少知道JPEG编码,jpg格式图片压缩效果就很好,据说能实现95%的压缩率,也就是100M压缩成5M,挺厉害的。

H.264编码简单来说包括 帧内压缩帧间压缩 ,帧内压缩就是JPEG这种压缩单张图片的编码技术,帧间压缩就是多个帧之间的有关联的压缩方法,将每个帧编码为 I帧、P帧、B帧 中的一类,每一类的特点是:

  • I帧是 关键帧 ,独立存在,可以理解为全量数据

  • P帧是 过渡帧 ,依赖于前面的I帧或P帧,可以理解为增量更新

  • B帧也是 过渡 ,依赖于前面和后面的数据帧

从一个I帧开始到下一个I帧出现为一个 编码group ,每个group可以独立解码,因此丢失一个group不会影响下一个group的数据。理解了I、P、B这3类帧,就能理解很多视频现象,比如有时候视频进度条不能随意拖动,因为视频必须从一个I帧开始,不能从P、B帧开始。 如果出现花屏,很有可能就是I帧丢失。

将原始RGB图像压缩成H.264帧,可以用 ffmpeg库 实现,就可以推送到服务器。推流一般使用 rtmp协议 ,这个是adobe指定的一种非公开格式的协议,但很多人通过抓包已经了解该协议的格式。

服务端收到rtmp流后,需要将数据分发到各个 CDN 负载结点。由于直播用户量大,动辄几百万人观看同一个明星直播,服务端必须做负载均衡,通俗点就是堆机器,用户从离自己最近的CDN结点获取数据。nginx可以安装rtmp模块,实现负载。

观众端通过rtmp协议拿到视频流后,做H.264格式解码,也就是I、P帧(一般 不生成B帧 ),得到原始画面,播放视频流观看主播。

以上是直播技术的简要介绍,云游戏与之基本接近,差异地方有:

  • 云游戏的数据来自于 服务端的游戏进程 ;直播来自于另一个客户端

  • 云游戏对延迟要求更高, 延迟<50ms ;直播延迟较高,在1~5s之间

  • 云游戏的服务端软硬件要求高,高配显卡、大流量带宽、容器技术、游戏并发量

低延迟实现

低延迟是云游戏的关键技术,必须实现 比直播延迟更低 的技术方案。这里分享一个开源项目 gaminganywhere ,已经能实现低延迟的云游戏,这里简要介绍下gaminganywhere简称GA,的实现原理。

1. 通过 hook方式 注入游戏进程,实现画面抓取和流服务器功能

游戏底层渲染引擎就是DirectX和OpenGL,不管用虚幻还是unity之类的引擎,最终还是通过这两个库驱动显卡,GA通过hook钩子,拦截 Direct3DCreate9glFlush 这2个函数,实现游戏画面抓取功能。

2. 获取游戏画面后,编码成 H264帧 ,并通过 RTSP协议 发送至客户端

GA借助 live555 这个开源 RTSP流媒体服务器 ,通过hook方式给游戏进程添加了流服务器的功能,启动游戏的同时,启动RTSP服务器。 当有客户端通过RTSP协议连接该游戏时,即可实现画面传输。RTSP协议是一种在视频 监控行业 广泛使用的协议,很多摄像头内置RTSP协议。

3. 低延迟除了要求协议,更多体现在 代码优化 上,细节决定成败,GA在细节上做了很多功夫,目测延迟低于0.5s,表现优秀。

云游戏代表一个技术新方向,其低延迟技术也可用于其他应用,相信在5G时代,必定能有代表性的产品出现,打破当前的行业局势。