/* -*- 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_ */