spice 图像压缩算法相关代码逻辑流程

下面是转载http://blog.csdn.net/zhoujiaxq/article/details/11201893 内容,是对图像算法的简单介绍接流程

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

spice官网对于广域网支持的介绍:http://spice-space.org/page/Features/WanSupport

spice图像压缩的流程:

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

    static inline void marshall_qxl_drawable(RedChannelClient *rcc,SpiceMarshaller *m, DrawablePipeItem *dpi)

[cpp] view plaincopy

  1. static inline void marshall_qxl_drawable(RedChannelClient *rcc,SpiceMarshaller *m, DrawablePipeItem *dpi)

函数先判断图像是应该当做视频处理还是图像处理,如果是视频就调用

    red_marshall_stream_data(rcc, m, item)

[cpp] view plaincopy

  1. red_marshall_stream_data(rcc, m, item)

如果是图像先判断是否采用jpeg压缩,是否采用jpeg压缩是在

    static void red_init(RedWorker *worker, WorkerInitData *init_data)

[cpp] view plaincopy

  1. 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)

[cpp] view plaincopy

  1. 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。

*************************************************************华丽分割线****************************************************************

一种触发quic解码的路径,服务器发SPICE_MSG_DISPLAY_DRAW_COPY消息
display_handle_draw_copy进行处理
->surface->canvas->ops->draw_copy
->canvas_draw_copy
->canvas_get_image
->canvas_get_image_internal
->canvas_get_quic

1、quic算法的函数入口
  canvas_get_quic这个函数最终返回的是一个surface,原始位图写到
             dest = (uint8_t *)pixman_image_get_data(surface);

typedef struct display_surface {
    guint32                     surface_id;
    bool                        primary;
    enum SpiceSurfaceFmt        format;
    int                         width, height, stride, size;
    int                         shmid;
    uint8_t                     *data;
    SpiceCanvas                 *canvas;
    SpiceGlzDecoder             *glz_decoder;
    SpiceZlibDecoder            *zlib_decoder;
    SpiceJpegDecoder            *jpeg_decoder;
} display_surface;

struct _SpiceCanvas {
  SpiceCanvasOps *ops; //所有操作函数的函数指针的封装
};

客户端增加打印语句
在 canvas_base.c 文件函数中canvas_draw_copy增加下面的输出:
 pixman_image_t *canvas_image = spice_canvas->ops->get_image(spice_canvas, FALSE); 
int width = pixman_image_get_width (canvas_image); 
int height = pixman_image_get_height (canvas_image);

SPICE_DEBUG("canvas_draw_copy: %x:%d:%d, [bbox]:%d,%d,%d,%d, [type]%d, [src_area]:%d,%d,%d,%d", 
canvas_image, width, height, bbox->left, bbox->top, 
bbox->right - bbox->left, bbox->bottom - bbox->top, 
copy->src_bitmap->descriptor.type, 
copy->src_area.left, copy->src_area.top, 
copy->src_area.right - copy->src_area.left, copy->src_area.bottom - 
copy->src_area.top 
);

服务器端图像采集及压缩:
以下函数在red_worker.c 文件中。
display_channel_send_item 函数从QXL驱动中读取到当前图像的更新,然后发到客户端
->marshall_qxl_drawable 判断当前图像时视频还是图片的刷新,如果是视频的刷新回退出,再判断是无损还是有损压缩,调用相关的
函数接口。jpeg是有损压缩,根据设置这里使用无损压缩。
->red_marshall_qxl_drawable
->red_marshall_qxl_draw_copy
->fill_bits,fill_mask
->red_compress_image 进入图像压缩算法的选择,目前在quic 和glz lz算法之间进行,默认是glz,根据图像源的x,y,和stripe等等决定,是否
使用quic算法
->red_quic_compress_image quic算法 。。

时间: 2024-10-14 01:39:47

spice 图像压缩算法相关代码逻辑流程的相关文章

图像压缩算法简要说明

图像压缩的目的是减少图像的不相关性和冗余性使得其能够以有效的形式存储或者传输.图像压缩分为有损压缩和无损压缩,无损图像压缩常用于档案资料.医学.工程制图.剪贴画和漫画.有损图像压缩,对于低比特流的传输条件下常使用.有损图像压缩对于那些可以牺牲少许的图像质量而希望获得低比特传输的图像具有很广泛的应用. 图像的压缩方法就是研究如何减少或去掉数据中冗余部分以减小数据的存储空间,图像压缩中数据冗余主要包含以下几种: 1.编码冗余: 以灰度图像为例,像素点的取值范围是[0,255],而对于一幅图像来说,其

Kafka Producer相关代码分析

Kafka Producer相关代码分析 标签(空格分隔): kafka Kafka Producer将用户的消息发送到Kafka集群(准确讲是发送到Broker).本文将分析Producer相关的代码实现. 类kafka.producer.Producer 如果你自己实现Kafka客户端来发送消息的话,你就是用到这个类提供的接口来发送消息.(如果你对如何利用Producer API来发送消息还不是很熟悉的话,可以参看官方的例子).这个类提供了同步和异步两种方式来发送消息. 异步发送消息是基于同

微信支付之扫码支付相关代码(Java)

最近开发网站过程,需要引入支付过程,第三方支付中最火的莫过于支付宝支付和微信支付,下边借助微信支付官网上的文档,写一下接入微信支付之扫码支付的流程 相对支付宝支付而言,微信支付的开发文档写的相当的low,demo写的一点都不简洁,下边写一下微信扫码支付的过程,这一过程中,需要注意的所涉及的实际业务是怎样的,根据实际情况结合业务进行引入,在进入正式开发之前,要申请微信支付的相关内容按照官网的操作进行即可,审核成功后,会得到appId,商户号,商户平台登录账号和密码 登录微信支付官网 https:/

简单地迁移你的android jni代码逻辑到iOS - 编写iOS下jni.h的替代 - ocni.h

1. jni的代码逻辑中与上层平台语言交互了. 2. 使用非Xcode的ide开发工具,希望使用纯净的c/c++代码,不掺杂其它平台相关的语言语法. 3. 只想简单地替换jni代码对上层平台语言的功能调用. 对了,本文就是这样一个出发点. 先说一下jni.h头文件是为jni代码(c/c++)去使用java平台层的对象(功能)提供的c或c++接口集.如果在iOS平台OC层的生态环境下比较容易就可以实现同样功能的java对象,你的jni代码就不用去改变逻辑,只要将向java平台层访问的地方改成对同等

《开源框架那点事儿16》:缓存相关代码的演变

目录(?)[+] 需求整理 解决思路 具体实现 问题引入 上次我参与某个大型项目的优化工作,由于系统要求有比较高的TPS,因此就免不了要使用缓冲. 该项目中用的缓冲比较多,有MemCache,有Redis,有的还需要提供二级缓冲,也就是说应用服务器这层也可以设置一些缓冲. 当然去看相关实现代代码的时候,大致是下面的样子. [java] view plaincopyprint? public void saveSomeObject(SomeObject someObject){ MemCacheU

DataNode与NameNode交互机制相关代码分析

HDFS Federation是为解决HDFS单点故障而提出的NameNode水平扩展方案,该方案允许HDFS创建多个Namespace以提高集群的扩展性和隔离性.在Federation中新增了block-pool的概念,block-pool就是属于单个Namespace的一组block,每个DataNode为所有的block-pool存储block,可以理解block-pool是一个重新将block划分的逻辑概念,同一个DataNode中可以存储属于多个block-pool的多个block.所

debian内核代码执行流程(三)

接续<debian内核代码执行流程(二)>未完成部分 下面这行输出信息是启动udevd进程产生的输出信息: [ 3.306217] udevd[49]: starting version 175 175是udevd的版本号. 根据<essential linux device drivers>中关于udev的说明(英文书140页),设备可以分成热插拔和冷插拔. 热插拔是在已经运行的系统中连接的设备,冷插拔是系统启动前插入的设备. 当系统检测到热插拔设备时,系统使用netlink s

代码上线流程以及版本发布小结

之前的上线流程很简单粗暴如图: 这简直是灾难性质的,上传 SVN,在测试服务器上看看正在调试的接口没问题,直接 sync 到线上服务器.代码无法回滚,只能覆盖.而客户端的同学需要稳当的 api 作为调试,最初的做法,他们需要新数据,我们就需要上线代码.这很坑爹,也许某人某段代码正写了一半,又正好提交.被另外一个人上线了,那么就线上出了严重 BUG.对此我们很头疼,所以做了如下规划: 首先建立三个版本库 开发服务版本库(对应图片中 dev,假设为 http://211.155.84.144/top

随便聊聊 SOA &amp; SOAP &amp; WebService 的一些东西,以及客户端开发的代码逻辑解析

http://blog.csdn.net/hikaliv/article/details/6459779 一天的时间调通了一个 WebService 的 Java 端的 C/S.一个 Android 端的 C/S,调通了而已,很不爽,很闷.因为刚刚上手 JAVA & Eclipse,对于我这个用惯了 VS 2010 的同学来说,感觉大大的不好.被迫和陌生的感觉很容易让我这个巨蟹座的男人直接地由然而生强烈的抵触情绪.不过话说回来了,网络方面的东西我一直很感兴趣,苦于没有项目参与.谁让项目要求我 A