spice图像压缩简介

本文详细介绍了SPICE图像压缩的主要方法,包括无损压缩算法QUIC和GLZ,以及有损压缩算法JPEG。同时阐述了SPICE图像压缩的流程,从GDI接口获取图像开始,通过判断图像是否采用JPEG压缩,并在特定函数中选择合适的压缩算法。最终,SPICE图像通过TCP传输至客户端进行解码。

目前的spice图像压缩主要采用了quic,glz和jpeg。quic和glz是无损压缩算法,quic主要用于照片,glz用于人工图像,jpeg也主要用于照片压缩但是是有损的。jpeg能节省50%的带宽,glz只能节省20%,但是jpeg会带来更大的开销,所以不能都使用jpeg进行压缩。

spice官网对于广域网支持的介绍:点击打开链接

spice图像压缩的流程:

qxl首先通过gdi接口获取到刷新的区域图像,然后传送给spice-server,spice-server获取到图像后通过

    static inline void marshall_qxl_drawable(RedChannelClient *rcc,SpiceMarshaller *m, DrawablePipeItem *dpi)
函数先判断图像是应该当做视频处理还是图像处理,如果是视频就调用
    red_marshall_stream_data(rcc, m, item)
如果是图像先判断是否采用jpeg压缩,是否采用jpeg压缩是在
    static void red_init(RedWorker *worker, WorkerInitData *init_data)
里设置,worker->jpeg_state = init_data->jpeg_state;

如果想采用jpeg压缩可以直接更改为worker->jpeg_state =SPICE_WAN_COMPRESSION_ALWAYS;或者在Reds.c里把

spice_wan_compression_t jpeg_state = SPICE_WAN_COMPRESSION_AUTO;更改为

        spice_wan_compression_t jpeg_state = SPICE_WAN_COMPRESSION_ALWAYS;

spice-server中图像的最终压缩都是在

    static inline int red_compress_image(DisplayChannelClient *dcc,SpiceImage *dest, SpiceBitmap *src, Drawable *drawable,int can_lossy,compress_send_data_t* o_comp_data)
在这个函数里会根据image_compression,图像的大小,图像的格式来选择相应的压缩算法。

spice-server通过tcp传输给spice-gtk客户端,客户端会通过数据流来判断出是采用何种压缩算法并采用相应的算法进行decode。

### 3.1 理解 SPICE 的图形输出机制 SPICE 协议通过 `reds` 模块与 QEMU 的图形输出接口进行交互,通常使用 `qxl` 模拟显卡的帧缓冲数据进行图像传输。为了支持 vGPU,需要修改 SPICE 的源码,使其能够识别和处理来自 vGPU 的帧缓冲数据流。这一过程涉及对 `spice-server` 的图形采集模块进行重构,确保其能够解析 vGPU 提供的硬件帧缓存格式[^1]。 ### 3.2 修改 SPICE 源码的关键模块 SPICE 的核心图形处理逻辑位于 `server/reds.c` 和 `server/stream.c` 文件中。为了支持 vGPU,需要在 `reds.c` 中添加对 vGPU 设备的帧缓冲读取接口,通常通过 `virglrenderer` 或 `VFIO` 提供的 DRM/KMS 接口获取 GPU 输出数据。以下是一个简化的帧缓冲读取接口示例: ```c // 在 reds.c 中添加 vGPU 帧缓冲读取函数 static void vgpu_framebuffer_update(SpiceServer *s) { // 通过 DRM/KMS 接口获取当前帧缓冲数据 uint32_t *fb_data = vgpu_get_framebuffer_data(); int width = vgpu_get_width(); int height = vgpu_get_height(); // 调用 SPICE 内部的图像更新函数 reds_update_area(s, 0, 0, width, height, fb_data); } ``` 此外,还需在 `stream.c` 中优化图像流的编码方式,使其支持 vGPU 提供的高分辨率和高色深格式,例如 32 位 ARGB 格式。这通常涉及修改 `spice_stream_set_format` 函数,确保其兼容 vGPU 的像素格式。 ### 3.3 集成硬件编码器以提升性能 SPICE 默认使用软件编码器(如 `jpeg` 或 `zlib`)进行图像压缩,这在高分辨率和高帧率场景下性能较低。为了提升图像传输效率,可以在 SPICE 中集成硬件编码器(如 NVIDIA 的 NVENC 或 Intel 的 VAAPI)。这通常涉及在 `server/encoder.c` 中添加硬件编码器插件,并在 `reds.c` 中调用其接口进行图像压缩。以下是一个硬件编码器调用的简化示例: ```c // 在 encoder.c 中添加硬件编码器初始化函数 void encoder_hw_init(SpiceServer *s) { s->hw_encoder = hw_encoder_create(); if (!s->hw_encoder) { // 回退到软件编码器 s->use_hw_encoder = false; } else { s->use_hw_encoder = true; } } // 在 reds.c 中调用硬件编码器进行图像压缩 static void vgpu_framebuffer_update(SpiceServer *s) { uint32_t *fb_data = vgpu_get_framebuffer_data(); int width = vgpu_get_width(); int height = vgpu_get_height(); if (s->use_hw_encoder) { hw_encoder_encode(s->hw_encoder, fb_data, width, height); } else { software_encoder_encode(fb_data, width, height); } } ``` ### 3.4 配置虚拟化环境以支持 vGPU 在修改 SPICE 源码后,还需要在 QEMU/KVM 环境中启用 IOMMU 和 VFIO 设备直通,以确保虚拟机能够正确访问 vGPU 资源。以下是一个典型的 QEMU 启动命令示例,启用了 IOMMU 并将 vGPU 设备直通给虚拟机: ```bash qemu-system-x86_64 \ -machine q35 \ -cpu EPYC \ -enable-kvm \ -device vfio-pci,host=01:00.0 \ -device vfio-pci,host=01:00.1 \ -kernel-irqchip \ -device intel-iommu,intremap=on,caching-mode=on \ -spice port=5900,addr=0.0.0.0,disable-ticketing \ -device qxl-vga \ -monitor stdio ``` 该配置启用了 Intel IOMMU,并将两个 vGPU 设备(`01:00.0` 和 `01:00.1`)直通给虚拟机。同时,SPICE 服务监听在 `5900` 端口,并禁用认证机制以方便测试。 ###
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值