[Spice-devel] [PATCH] Fix LZ4 supported image formats.
Javier Celaya
javier.celaya at flexvm.es
Thu Jan 22 00:58:35 PST 2015
Hello
El Miércoles, 21 de enero de 2015 17:05:00 Christophe Fergeau escribió:
> Hey,
>
> Sorry for the late review...
>
> On Thu, Jan 15, 2015 at 12:50:21PM +0100, Javier Celaya wrote:
> > This patch limits the LZ4 algorithm to RGB formats. Other formats are
> > compressed with LZ. It also sends the top_down flag and the original
> > format to the client, so that it can create the right kind of pixman
> > surface.
>
> Looking at the other compression formats, it seems they don't send a
> top down flag, but instead 'revert' the image before sending it, any
> reason this is not being done here?
It depends on the compression format. JPEG, for instance, reverts the image,
but LZ does send the top down flag (see spice-common/common/lz.c). I suppose it
is simpler, since pixman can hadle both direction in the client. The JPEG
format, on the other hand, probably forces the top-down direction.
>
> This patch breaks the wire protocol which was used in spice-gtk 0.27,
> which we usually don't do, but since what was in the release was
> crashing when being used, I'd say this is fine to change.
Yes, I thought the same...
>
> This commit could have easily been split in different ones (limit lz4 to
> RGB formats, send the original format to the client, ...
I can split it if you want.
>
> Apart from these comments, this looks good.
Thanks
Javi
>
> Christophe
>
> > ---
> >
> > server/lz4_encoder.c | 21 +++++++++++----------
> > server/lz4_encoder.h | 7 +++----
> > server/red_worker.c | 21 +++++++--------------
> > 3 files changed, 21 insertions(+), 28 deletions(-)
> >
> > diff --git a/server/lz4_encoder.c b/server/lz4_encoder.c
> > index 531ab4b..bb8e98a 100644
> > --- a/server/lz4_encoder.c
> > +++ b/server/lz4_encoder.c
> > @@ -49,22 +49,23 @@ void lz4_encoder_destroy(Lz4EncoderContext* encoder)
> >
> > free(encoder);
> >
> > }
> >
> > -int lz4_encode(Lz4EncoderContext *lz4, int height, int stride,
> > - uint8_t *io_ptr, unsigned int num_io_bytes)
> > +int lz4_encode(Lz4EncoderContext *lz4, int height, int stride, uint8_t
> > *io_ptr, + unsigned int num_io_bytes, int top_down, uint8_t
> > format)>
> > {
> >
> > Lz4Encoder *enc = (Lz4Encoder *)lz4;
> > uint8_t *lines;
> > int num_lines = 0;
> > int total_lines = 0;
> >
> > - int in_size, enc_size, out_size = 0, already_copied;
> > - int stride_abs = abs(stride);
> > + int in_size, enc_size, out_size, already_copied;
> >
> > uint8_t *in_buf, *compressed_lines;
> > uint8_t *out_buf = io_ptr;
> > LZ4_stream_t *stream = LZ4_createStream();
> >
> > - // Encode direction
> > - *(out_buf++) = stride < 0 ? 1 : 0;
> > - num_io_bytes--;
> > + // Encode direction and format
> > + *(out_buf++) = top_down ? 1 : 0;
> > + *(out_buf++) = format;
> > + out_size = 2;
> > + num_io_bytes -= 2;
> >
> > do {
> >
> > num_lines = enc->usr->more_lines(enc->usr, &lines);
> >
> > @@ -73,9 +74,9 @@ int lz4_encode(Lz4EncoderContext *lz4, int height, int
> > stride,>
> > LZ4_freeStream(stream);
> > return 0;
> >
> > }
> >
> > - in_buf = stride < 0 ? lines - (stride_abs * (num_lines - 1)) :
> > lines; - lines += stride * num_lines;
> > - in_size = stride_abs * num_lines;
> > + in_buf = lines;
> > + in_size = stride * num_lines;
> > + lines += in_size;
> >
> > compressed_lines = (uint8_t *) malloc(LZ4_compressBound(in_size)
> > + 4);
> > enc_size = LZ4_compress_continue(stream, (const char *) in_buf,
> >
> > (char *) compressed_lines + 4,
> > in_size);
> >
> > diff --git a/server/lz4_encoder.h b/server/lz4_encoder.h
> > index f3359c0..f1de12a 100644
> > --- a/server/lz4_encoder.h
> > +++ b/server/lz4_encoder.h
> > @@ -43,8 +43,7 @@ struct Lz4EncoderUsrContext {
> >
> > Lz4EncoderContext* lz4_encoder_create(Lz4EncoderUsrContext *usr);
> > void lz4_encoder_destroy(Lz4EncoderContext *encoder);
> >
> > -/* returns the total size of the encoded data. Images must be supplied
> > from the - top line to the bottom */
> > -int lz4_encode(Lz4EncoderContext *lz4, int height, int stride,
> > - uint8_t *io_ptr, unsigned int num_io_bytes);
> > +/* returns the total size of the encoded data. */
> > +int lz4_encode(Lz4EncoderContext *lz4, int height, int stride, uint8_t
> > *io_ptr, + unsigned int num_io_bytes, int top_down, uint8_t
> > format);>
> > #endif
> >
> > diff --git a/server/red_worker.c b/server/red_worker.c
> > index a18987a..16411a7 100644
> > --- a/server/red_worker.c
> > +++ b/server/red_worker.c
> > @@ -6422,7 +6422,6 @@ static int
> > red_lz4_compress_image(DisplayChannelClient *dcc, SpiceImage *dest,>
> > Lz4Data *lz4_data = &worker->lz4_data;
> > Lz4EncoderContext *lz4 = worker->lz4;
> > int lz4_size = 0;
> >
> > - int stride;
> >
> > #ifdef COMPRESS_STAT
> >
> > stat_time_t start_time = stat_now();
> >
> > @@ -6454,20 +6453,12 @@ static int
> > red_lz4_compress_image(DisplayChannelClient *dcc, SpiceImage *dest,>
> > lz4_data->data.u.lines_data.chunks = src->data;
> > lz4_data->data.u.lines_data.stride = src->stride;
> >
> > + lz4_data->data.u.lines_data.next = 0;
> > + lz4_data->data.u.lines_data.reverse = 0;
> >
> > lz4_data->usr.more_lines = lz4_usr_more_lines;
> >
> > -
> > - if ((src->flags & SPICE_BITMAP_FLAGS_TOP_DOWN)) {
> > - lz4_data->data.u.lines_data.next = 0;
> > - lz4_data->data.u.lines_data.reverse = 0;
> > - stride = src->stride;
> > - } else {
> > - lz4_data->data.u.lines_data.next = src->data->num_chunks - 1;
> > - lz4_data->data.u.lines_data.reverse = 1;
> > - stride = -src->stride;
> > - }
> > -
> > - lz4_size = lz4_encode(lz4, src->y, stride,
> > (uint8_t*)lz4_data->data.bufs_head->buf, -
> > sizeof(lz4_data->data.bufs_head->buf)); + lz4_size = lz4_encode(lz4,
> > src->y, src->stride, (uint8_t*)lz4_data->data.bufs_head->buf, +
> > sizeof(lz4_data->data.bufs_head->buf),
> > + src->flags & SPICE_BITMAP_FLAGS_TOP_DOWN,
> > src->format);>
> > // the compressed buffer is bigger than the original data
> > if (lz4_size > (src->y * src->stride)) {
> >
> > @@ -6678,6 +6669,7 @@ static inline int
> > red_compress_image(DisplayChannelClient *dcc,>
> > if (!glz) {
> >
> > #ifdef USE_LZ4
> >
> > if (image_compression == SPICE_IMAGE_COMPRESS_LZ4 &&
> >
> > + bitmap_fmt_is_rgb(src->format) &&
> >
> > red_channel_client_test_remote_cap(&dcc->common.base,
> >
> > SPICE_DISPLAY_CAP_LZ4_COMPRESSION)) {
> >
> > ret = red_lz4_compress_image(dcc, dest, src, o_comp_data,
> >
> > @@ -8918,6 +8910,7 @@ static void red_marshall_image(RedChannelClient
> > *rcc, SpiceMarshaller *m, ImageI>
> > } else {
> >
> > #ifdef USE_LZ4
> >
> > if (comp_mode == SPICE_IMAGE_COMPRESS_LZ4 &&
> >
> > + bitmap_fmt_is_rgb(bitmap.format) &&
> >
> > red_channel_client_test_remote_cap(&dcc->common.base,
> >
> > SPICE_DISPLAY_CAP_LZ4_COMPRESSION)) {
> >
> > comp_succeeded = red_lz4_compress_image(dcc, &red_image,
> > &bitmap,
More information about the Spice-devel
mailing list