/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
/*
Copyright (C) 2009-2015 Red Hat, Inc.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, see .
*/
#ifndef DCC_ENCODERS_H_
#define DCC_ENCODERS_H_
#include
#include "common/marshaller.h"
#include "common/quic.h"
#include "red-channel.h"
#include "red-parse-qxl.h"
#include "image-cache.h"
#include "glz-encoder.h"
#include "jpeg-encoder.h"
#ifdef USE_LZ4
#include "lz4-encoder.h"
#endif
#include "zlib-encoder.h"
typedef struct RedCompressBuf RedCompressBuf;
typedef struct GlzDrawableInstanceItem GlzDrawableInstanceItem;
typedef struct RedGlzDrawable RedGlzDrawable;
void dcc_encoders_init (DisplayChannelClient *dcc);
void dcc_encoders_free (DisplayChannelClient *dcc);
void dcc_free_glz_drawable_instance (DisplayChannelClient *dcc,
GlzDrawableInstanceItem *item);
void dcc_free_glz_drawable (DisplayChannelClient *dcc,
RedGlzDrawable *drawable);
int dcc_free_some_independent_glz_drawables (DisplayChannelClient *dcc);
void dcc_free_glz_drawables (DisplayChannelClient *dcc);
void dcc_free_glz_drawables_to_free (DisplayChannelClient* dcc);
void dcc_freeze_glz (DisplayChannelClient *dcc);
void dcc_release_glz (DisplayChannelClient *dcc);
void marshaller_add_compressed (SpiceMarshaller *m,
RedCompressBuf *comp_buf,
size_t size);
#define RED_COMPRESS_BUF_SIZE (1024 * 64)
struct RedCompressBuf {
/* This buffer provide space for compression algorithms.
* Some algorithms access the buffer as an array of 32 bit words
* so is defined to make sure is always aligned that way.
*/
union {
uint8_t bytes[RED_COMPRESS_BUF_SIZE];
uint32_t words[RED_COMPRESS_BUF_SIZE / 4];
} buf;
RedCompressBuf *send_next;
};
typedef struct GlzSharedDictionary {
RingItem base;
GlzEncDictContext *dict;
uint32_t refs;
uint8_t id;
pthread_rwlock_t encode_lock;
int migrate_freeze;
RedClient *client; // channel clients of the same client share the dict
} GlzSharedDictionary;
GlzSharedDictionary* dcc_get_glz_dictionary (DisplayChannelClient *dcc,
uint8_t id, int window_size);
GlzSharedDictionary* dcc_restore_glz_dictionary (DisplayChannelClient *dcc,
uint8_t id,
GlzEncDictRestoreData *restore_data);
typedef struct {
DisplayChannelClient *dcc;
RedCompressBuf *bufs_head;
RedCompressBuf *bufs_tail;
jmp_buf jmp_env;
union {
struct {
SpiceChunks *chunks;
int next;
int stride;
int reverse;
} lines_data;
struct {
RedCompressBuf* next;
int size_left;
} compressed_data; // for encoding data that was already compressed by another method
} u;
char message_buf[512];
} EncoderData;
void encoder_data_init(EncoderData *data, DisplayChannelClient *dcc);
void encoder_data_reset(EncoderData *data);
typedef struct {
QuicUsrContext usr;
EncoderData data;
} QuicData;
typedef struct {
LzUsrContext usr;
EncoderData data;
} LzData;
typedef struct {
JpegEncoderUsrContext usr;
EncoderData data;
} JpegData;
#ifdef USE_LZ4
typedef struct {
Lz4EncoderUsrContext usr;
EncoderData data;
} Lz4Data;
#endif
typedef struct {
ZlibEncoderUsrContext usr;
EncoderData data;
} ZlibData;
typedef struct {
GlzEncoderUsrContext usr;
EncoderData data;
} GlzData;
#define MAX_GLZ_DRAWABLE_INSTANCES 2
/* for each qxl drawable, there may be several instances of lz drawables */
/* TODO - reuse this stuff for the top level. I just added a second level of multiplicity
* at the Drawable by keeping a ring, so:
* Drawable -> (ring of) RedGlzDrawable -> (up to 2) GlzDrawableInstanceItem
* and it should probably (but need to be sure...) be
* Drawable -> ring of GlzDrawableInstanceItem.
*/
struct GlzDrawableInstanceItem {
RingItem glz_link;
RingItem free_link;
GlzEncDictImageContext *context;
RedGlzDrawable *glz_drawable;
};
struct RedGlzDrawable {
RingItem link; // ordered by the time it was encoded
RingItem drawable_link;
RedDrawable *red_drawable;
Drawable *drawable;
GlzDrawableInstanceItem instances_pool[MAX_GLZ_DRAWABLE_INSTANCES];
Ring instances;
uint8_t instances_count;
DisplayChannelClient *dcc;
};
#define RED_RELEASE_BUNCH_SIZE 64
#endif /* DCC_ENCODERS_H_ */