下面是轉載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)
- red_marshall_stream_data(rcc, m, item)
- static void red_init(RedWorker *worker, WorkerInitData *init_data)
如果想採用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)
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