首页 » 网站建设 » phparray_spice技巧_基于 SPICE 协议的硬编推流整合筹划在云游戏中的应用

phparray_spice技巧_基于 SPICE 协议的硬编推流整合筹划在云游戏中的应用

访客 2024-11-18 0

扫一扫用手机浏览

文章目录 [+]

X 协议:比较早的协议,X server 直接管理 GPU 内的 framebuffer 和 X Client 提交命令,通过 XClient(Xlib 或 XCB)向 Xserver(Xorg)提交干系命令实现,且有很多扩展协议,但是弊端须要一个额外的 Windows Manager 来处理多个运用。
目前已经被 Wayland 这种扩展协议取代,composer 处理输入,窗口,合成显示等功能。
GLX:由于是用来做间接渲染,做了两个事情:1)将 OpenGL 和 X window API 绑定 2)通过 X server 转发 GL 的调用。
实质还是 X 协议那一套。
FB driver:历史遗留显示子系统,供应了 Framebuffer 获取,图像操作原语,电源管理等功能。
OpenGL:统一的 3D 图形渲染 API 接口,各主流厂商(Intel、 Nvidia、AMD、Qualcomm 等)都支持的接口,主流实现的是开源的 mesa。
Mesa 3D 是其最主流的开源实现,值得把稳的是 Mesa 不仅支持 OpenGL,还支持 Vulkan, Direct 3D 等渲染 API。
DRM:Direct Rendering Manager, 目前主流的 GPU 显示子系统,用户态利用 libDRM 的 DRM API 来操作 DRM 设备,对 GPU 通过 ioctl 等标准文件操作来通信,实现:framebuffer 管理。
用户态抽象渲染能力:如 Buffer Object 管理,GPU 作业命令提交等,一样平常和详细 driver 干系。
Virtual Driver 支持:包含 vmwgfx(VMware 桥接设备)和 virgl(Virto 桥接设备)Prime Zero-copy memory,buffer 通过用户态的 fd 文件描述符代表了实际显存中的 DMA buffer,通过 Prime API 导出 FD,可以在 IPC 之间通报。

包含 Wayland 比较主流的所有图像栈变得非常繁芜:

phparray_spice技巧_基于 SPICE 协议的硬编推流整合筹划在云游戏中的应用

每种运用的图像数据流都比较繁芜,但大致流线是:运用(显示 Client)->(显示 Server)->OpenGL/EGL->Mesa 3D->libDRM->(内核)DRM->GPU 驱动。

phparray_spice技巧_基于 SPICE 协议的硬编推流整合筹划在云游戏中的应用
(图片来自网络侵删)
Android 图形栈

以 SurfaceFlinger 为核心,掩护了所有 app 窗口的交叠覆盖关系:

OpenGL ES:2D/3D 渲染走的路径,利用 drm 所有功能进行绘制渲染。
Gralloc FB: 利用 drm 为 app 供应显存管理等功能。
HWComposer: 调用 openGL 窗口合成 RGB 或者 YUV,实现屏幕绘制。

综合 Linux 图形栈和 Android 图形栈可以创造在底层都是基于 drm 实现,实现硬编方案的核心思想便是渲染和编码都利用宿主侧的 GPU,并且渲染和编码 Zero-copy,以是有两类技能:

virto-gpu 技能将 OpenGLES 命令导出(virgl)之后再反过来调用宿主侧的 virglrenderer,又将其翻译回 OpenGL 和 GLSL,然后再调用宿主的 OpenGL,这部分技能代表是 Qemu 方案。
利用假的抽象 GPU。
在抽象层 GPU 层进行拦截,并调用宿主侧的 GPU。

直接导出 DRM 句柄,利用 DRM 的 Zero-copy 的特性进行渲染和编码,渲染和编码通过 IPC 技能通报 fd,这部分代表是 AiC(Android in Container)容器化技能。
以上两类技能由于终极都是 drm 图像 buffer,故都可以通过 IPC 技能在渲染进程和编码进程之间通过 IPC 通报。
渲染进程一样平常在容器/仿照器内,编码进程一样平常在容器外。
多媒体编解码干系

以上图形栈涉及显示和渲染,在云游戏的场景中,还需考虑编码设计的技能栈。
就编码而言:

在 Linux 中 ffmepg 或者 gstreamer 等标准多媒体框架对上封装了运用接口,对下对接了硬件供应编解码如 CUDA NVEnc 接口或 VAAPI 接口。
在 Android 中利用 OMX 作为其多媒体框架,MediaCodec 驱动对接 vendor 驱动来实现硬编解码能力。

如果想要在 Android 内利用硬件编解码,要么实现一套 OMX 到 ffmpeg 的转换翻译,要么厂商对接实现 OMX 的 vendor 驱动,否则很难在 Android(容器或仿照器中)内硬件编码。
比较合理的办法是导出 libdrm 的 FD,渲染和编码在不同的进程中,编码选择在 host 中调用 ffmepg 或者 vender 的编码 API 进行编码,进而完玉成部推流。

方案

硬编目前精力放在处理进程间通报图像 prime FD,还有相应的音频,双向 input 通信等。
采取统一的 Spice 协议或者改造的 Spice 协议统一 Android 虚拟化和容器化整合方案。

spice 协议

SPICE,Simple Protocol for Independent Computing Environment,是 Redhat 公司开源的一套远程桌面虚拟化协议,旨在供应商业级别的远程桌面体验。
Spice 协议具有如下优点:

开源:易于扩展和功能定制;跨平台:Windows/Linux/Mac OS 平台全兼容;支持外接设备:除常用 USB 设备外,打印机和扫描仪等设备也能在远程利用;丰富的媒体支持:包括视频、音频、图像;更小的带宽占用:Spice 里内置图像压缩算法,有效减少数据传输时的带宽占用;更安全的数据传输:Spice 可以利用 OpenSSL 加密传输数据。
概述

包含四个部分:协议、客户端侧、做事端侧和虚拟机侧。
个中:

协议:是客户端侧、做事端侧和虚拟机侧三个部分交互时所遵照的准则;客户端:卖力吸收并转换虚拟机数据,以及发送用户输入数据到虚拟机,从而使得用户能够与虚拟机进行交互;做事端:集成在 Hypervisor 内部的一个用户层组件,使得 Hypervisor(如 QEMU)支持 Spice 协议;虚拟机侧:指所有支配在虚拟机内部的必需组件,如 QXL 驱动、Spice Agent 等。

图像流

上图示意了全体图像从 Guest OS 到客户端图像传输通路,个中:

QEMU:虚拟机环境,目前利用Guest OS:运行在虚机中的操作系统Client OS:运行在 host 侧的运用程序GDI/X:Graphics Device Interface,图像引擎,图像栈供应的显示接口(如 mesa)QXL:设备驱动,供应了套动态 设备须要客户机的 QXL 驱动来发挥全部浸染。
但是,当没有驱动的时候,标准的 VGA 也能支持该设备。
这个模式还能显示虚拟机启动的勾引阶段。
QXL 设备通过命令和指针环,显示中断,指针事宜,I/O 端口来与驱动交互。

QXL 设备的其他功能包括:

初始化和映射设备 ROM,RAM 和 VRAM 到物理内存映射 I/O 端口,处理读写来管理:区域更新,命令,指针关照,IRQ 更新,模式设置,设备重置,记录日志等。
环-初始化和掩护命令和指针环,从环获取命令和指针命令,等待关照。
掩护资源环。
利用 QXLWorker 接口与相应的 red worker 通信,这是在 red dispatcher 中实现的,它把设备调用翻译为写到 red worker 通道,或者从 red worker 通道中读取消息。
注册 QXL 接口来使 worker 能与设备通信。
这个接口包括 PCI 信息和功能(如寄托一个 worker,从环中获取显示和指针命令,显示和指针关照,模式改变关照等)。
定义支持 QXL 模式和改变当前模式(如 VGA:所有监听器反响一个单一设备)处理在 VGA 模式中显示的初始化,更新,改变尺寸和刷新。
VDagent 命令流

Spice Server

Spice 协议改造

Spice Client 收到 Spice Server 端发过来的 main,display,playback 等通道后:

显示通道在默认的 display 上调用 GTK widget 干系组件将图像画在屏幕上。
获取 playback 音频数据,通过 gstreamer 的 pipeline,调用 alsa 播放音频。
其他鼠标键盘等处理,不作任何处理。

为适宜我们的推流改造如下:

对原协议改动比较大的:

Display Channel 通道,这部分在获取到 FD 之后,原来画在 GTK 的流程通过 HwFrame 适配模块,转换成 RTC 编码所需的数据源(YUV 或者 RGBA)。
Main Channel 通道增加 VDAgent 类型增加自定义类型传输 RTC 远程调用指令,反向通过封装将 RTC 的事宜和 DataChannel 通报给 GameService(游戏管理做事进程)。
Spice 协议抓包

可以通过 socat 等工具代理 domain socket 来剖析 spice 协议,对一个完全的 Spice 协议交互流程,通过 TCP dump 抓取 wireshark 日志如下:

先通过 main channel 建立连接,认证,然后依次建立 Spice Display, Spice PLAYBACK, SPICE RECORD, SPICE INPUT 等通道,末了通过各通道发送特定的。

这里重点关注以下:

Main Channel 的 VDAgent 通道,在 CLIPBOARD 和 FILE_XFER 之外添加 VD_AGENT_VENDOR_DATA,为远程 gRPC 调用,吸收 android 侧的封装数据。

Display Channel,GL_SCANOUT_UNIX, 屏幕初始化/改分辨率后的,一样平常用在初始化的时候。

GL_DRAW_DONE,当屏幕内容有变革的时候通报此,可以认为是每一幅安卓画面。

Playback Channel,android 系统的声音,如音量变革,声音开始与停滞等。

QEMU 方案

QEMU 方案可以直接复用社区的 qemu+kvm 方案,除了针对不同硬件导出不同的 fd 之外。

AiC 容器

比较于虚拟化,容器化的分外之处在于 qemu 已经集成 Spice Server 组件,虚拟化的容器须要容器外编码的话须要导出音频,视频和掌握通道,然后实现一套类似 Spice 协议的架构,为统一兼容性通过增加下图的转发模块 Adapter/SpiceServer,将 IPC 通道再次转发至 Spice 通道,实现 QEMU/AiC 方案的统一。

方案参数

在全体整合方案中,有如下成分和参数需考虑:

仿照器或者容器环境区分。
如果导出的 fd 在仿照器和容器方案同等,不须要区分,否则须要通过环境变量或者传入启动参数来区分。
DRM device 指定。
在携带 GTK 的版本中须要指定 Display 的 device,移除 Xorg 依赖后需指定 Render node。
编码显卡硬件指定,由于不同硬件编码不同,在编码模块须要通过当前硬件信息来确定编码办法。
图形导出

从虚机或者容器导出,有两种类型的图形显存的 fd:

KHR_STREAM

渲染到宿主侧的 surface,suface 导出 EGLSTREAM,通过eglCreateStreamKHR和eglGetStreamFileDescriptorKHR导出对应的 EGLStreamKHR 文件描述符,适用于 NVIDIA 显卡。
消费侧通过eglStreamConsumerAcquireKHR导出对应的 stream,但编码不能直策应用 stream 类型, CUDA 供应了 OpenGL 与 CUDA 互操作 API,将 texture 或者 render buffer 绑定 CUDA 资源之后,CuGraphicsSubResourceGetMappedArray映射出 CUarray 指针供编码器利用。

MESA_IMAGE

渲染到宿主侧的 texture,texture 导出为 DMA buffer,通过eglExportDMABUFImageQueryMESA,eglExportDMABUFImageMESA导出,适用于 AMD/Intel 显卡。
消费侧通过此创建 EGLImage, 并绑定 2D 纹理,将此纹理的 textureID 通报给编码器 VAAPI 通过此编码器进行编码。

优化与演进代码重构

随着支撑的方案类型增加,全体工程在知足功能情形下逐渐难以掩护,通过 C++重写各个模块,将 HwFrame 模块抽象,对日志/SRE 各模块划分重构,将工程模块化。

移除 Xorg

Xorg 作为 X(11)协议中的 Server 的实现,Spice Client 的通过调用 GTK API 端做 client,存在弊端:

默认会将导出的 fd,通过 GTK widget 画在默认的 Display 上,但是实际推流过程并不须要这个步骤。
支配 Xorg 也增加了繁芜度。

须要将依赖和 GTK 的组件移除,降落组件依赖繁芜性和性能花费。

详细而言:

Display channel 干系的 GTK widget 依赖移除,。
更换原有 Display,对 Nvidia,getPlatformDisplayEXT(EGL_PLATFORM_DEVICE_EXT, (EGLNativeDisplayType)dev[num], NULL)导出。
更换原有 Display,对 VAAPI 的 AMD 或者 Intel 显卡,由于利用的 mesa 图形栈,getPlatformDisplayEXT(EGL_PLATFORM_GBM_MESA导出,须要把稳的一点是在 VAAPI 接口中,将初始化用的 Display 换成 DRM 导出。

#if ENABLE_GTKint vaapi_init() { x11_display = XOpenDisplay(g_getenv("DISPLAY")); va_display = vaGetDisplay(x11_display);#elseint vaapi_init(int drm_fd) { va_display = (uint64_t)vaGetDisplayDRM(drm_fd); g_message("drm_fd:%d va_dpy:%p", drm_fd, va_display);#endif int major_ver, minor_ver; va_status = vaInitialize(va_display, &major_ver, &minor_ver); return 0;}移除 gstreamer

音频的 pipeline 利用了 gstreamer,这部分依赖可以去掉。

图形转换优化

总体想法便是图像的 Zero-copy,减少在 CPU 与 GPU 之间的拷贝与图形格式之间转换。

编码卡支持

支持主机通过 PCIE 外插硬件编码卡进行硬件编码。

稠浊硬件编码支持

总体想法便是利用 host 渲染能力,将渲染后的 RGBA 或者 YUV 导出给编码卡,达到最大限度利用渲染资源,提高并发路数的事情。

自升级

通过 Host Gameservice 进程自我升级固件,不依赖整体支配 pod 节点镜像更新,可以灵巧实现升级。

监控与 SRE

对系统指标的打点和性能的监控,完善 SRE 等监控体系,管理进程崩溃,卡去世,内测泄露等检测。

其他

全体云游戏的视频流硬编码方案的实现和上线支配离不开跨部门的互助,再次感谢一起将全体方案从开始设计到到上线的内部兄弟团队如根本系统部门 STE,多媒体 RTC 等部门,通过团队协作推动全体方案上线以及后续线上持续优化和管理。

关于我们

作为字节跳动的视频中台部门,视频架构支持了字节全系产品的点播、直播、实时通信、图片、云游戏、多媒体业务发展,目标成为业界多媒体办理方案领导者,构建极致的视频技能/产品做事体验!

视频架构-设备与做事团队聚焦多媒体+IoT/5G 干系领域,孵化能够赋能业务的新场景和核心技能,打造极致的、软硬件结合的技能办理方案,上线了云游戏、云手机、视联网、多屏互动等多款做事,支持了抖音、西瓜等浩瀚内部产品,同时也通过火山引擎供应 toB 做事。
欢迎更多同学加入我们,构建行业顶尖的视频创新技能,联系luxuguang@bytedance.com 注明“设备与做事方向”。

参考https://en.wikipedia.org/wiki/Direct_Rendering_Managerhttps://en.wikipedia.org/wiki/Direct_Rendering_Infrastructurehttps://en.wikipedia.org/wiki/Mesa_(computer_graphics)https://source.android.com/devices/graphicshttps://www.opengl.org/https://www.mesa3d.org/https://www.spice-space.org/https://www.qemu.org/https://docs.nvidia.com/cuda/cuda-driver-api/index.html
标签:

相关文章

U盘记账,高效便捷的财务管理新方式

随着科技的不断发展,我们的生活越来越离不开电子设备。U盘作为一种便携式存储设备,不仅方便我们存储和传输文件,还可以成为我们日常财务...

网站建设 2025-01-01 阅读0 评论0

U盘销毁,数据安全与隐私保护的必经之路

随着信息技术的飞速发展,U盘作为一种便携式存储设备,已成为人们日常生活中不可或缺的工具。U盘在带来便利的也带来了数据泄露的风险。因...

网站建设 2025-01-01 阅读0 评论0

主机升级指南,提升性能,介绍全新体验

随着科技的飞速发展,计算机硬件也在不断更新迭代。作为计算机的核心部件,主机性能的高低直接影响着我们的使用体验。如何对主机进行升级呢...

网站建设 2025-01-01 阅读0 评论0

主机箱换新攻略,焕新电脑,焕新生活

随着科技的不断发展,电脑已经成为我们生活中不可或缺的一部分。随着时间的推移,电脑的性能和外观可能会逐渐变得过时。为了保持电脑的最佳...

网站建设 2025-01-01 阅读0 评论0

中考语言编程,开启智能时代的关键钥匙

随着科技的飞速发展,人工智能已成为我国经济社会发展的重要驱动力。在中考改革的大背景下,编程教育逐渐成为热点,而语言编程作为编程教育...

网站建设 2025-01-01 阅读0 评论0