spice 图像压缩算法相关代码逻辑流程
2015-07-05 10:05
295 查看
下面是转载/article/8351817.html 内容,是对图像算法的简单介绍接流程
目前的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
static inline void marshall_qxl_drawable(RedChannelClient *rcc,SpiceMarshaller *m, DrawablePipeItem *dpi)
函数先判断图像是应该当做视频处理还是图像处理,如果是视频就调用
red_marshall_stream_data(rcc, m, item)
[cpp] view
plaincopy
red_marshall_stream_data(rcc, m, item)
如果是图像先判断是否采用jpeg压缩,是否采用jpeg压缩是在
static void red_init(RedWorker *worker, WorkerInitData *init_data)
[cpp] view
plaincopy
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
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算法 。。
http://lists.freedesktop.org/archives/spice-devel/2013-October/015156.html
目前的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
static inline void marshall_qxl_drawable(RedChannelClient *rcc,SpiceMarshaller *m, DrawablePipeItem *dpi)
函数先判断图像是应该当做视频处理还是图像处理,如果是视频就调用
red_marshall_stream_data(rcc, m, item)
[cpp] view
plaincopy
red_marshall_stream_data(rcc, m, item)
如果是图像先判断是否采用jpeg压缩,是否采用jpeg压缩是在
static void red_init(RedWorker *worker, WorkerInitData *init_data)
[cpp] view
plaincopy
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
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算法 。。
http://lists.freedesktop.org/archives/spice-devel/2013-October/015156.html
相关文章推荐
- (转)phpmyadmin操作技巧:如何在phpmyadmin里面复制mysql数据库?
- 数据预处理-PDB文件处理代码
- Python编写算法导论基本算法
- Asp.Net Ajax的两种基本开发模式
- 取整的一些方法总结(java)
- Asp.Net 用户验证(自定义IPrincipal和IIdentity)
- c++读书笔记——类的定义
- C# 理解泛型
- 读取生产环境go语言的最佳实践展示
- 在django template中设置临时变量
- 30、Java中Set集合之HashSet、TreeSet和EnumSet
- C# 类型基础
- 代理模式,JDK动态代理
- YII1.0中验证码刷新不更新的问题的解决。
- JAVA设计模式-辛格尔顿
- 使用Spring容器
- 1112 KGold
- 部署在Openshift云主机的Java开源论坛
- JAVA学习(五):Java面向对象编程基础
- JAVA学习(五):Java面向对象编程基础