zrle: Keep the stream alive per connection

Otherwise the client doesn't want to play with the server.
tight-png
Andri Yngvason 2019-09-01 18:40:11 +00:00 committed by Andri Yngvason
parent 46dc074370
commit ff67e2fed3
6 changed files with 31 additions and 23 deletions

View File

@ -3,6 +3,7 @@
#include "util.h"
#include "vec.h"
#include "neatvnc.h"
#include "miniz.h"
#include <stdlib.h>
#include <libdrm/drm_fourcc.h>
@ -39,15 +40,21 @@ int run_benchmark(const char *image)
struct vec frame;
vec_init(&frame, fb.width * fb.height * 3 / 2);
z_stream zs = { 0 };
deflateInit(&zs, Z_DEFAULT_COMPRESSION);
uint64_t start_time = gettime_us(CLOCK_PROCESS_CPUTIME_ID);
rc = zrle_encode_frame(&frame, &pixfmt, fb.addr, &pixfmt,
rc = zrle_encode_frame(&zs, &frame, &pixfmt, fb.addr, &pixfmt,
fb.width, fb.height, &region);
uint64_t end_time = gettime_us(CLOCK_PROCESS_CPUTIME_ID);
printf("Encoding %s took %"PRIu64" micro seconds\n", image,
end_time - start_time);
deflateEnd(&zs);
if (rc < 0)
goto failure;

View File

@ -50,7 +50,7 @@ void on_pointer_event(struct nvnc_client *client, uint16_t x, uint16_t y,
struct pixman_region16 region;
pixman_region_init_rect(&region, 0, 0, draw->fb.width,
draw->fb.height);
// pixman_region_init_rect(&region, x, y, 1, 1);
pixman_region_intersect_rect(&region, &region, x, y, 1, 1);
nvnc_update_fb(server, &draw->fb, &region);
pixman_region_fini(&region);
}

View File

@ -132,7 +132,6 @@ struct rfb_server_fb_update_msg {
uint8_t type;
uint8_t padding;
uint16_t n_rects;
struct rfb_server_fb_rect rects[0];
} RFB_PACKED;
static inline int rfb_send_security_types(void *client)

View File

@ -4,6 +4,8 @@
#include <stdint.h>
#include <unistd.h>
#include "miniz.h"
struct rfb_pixel_format;
struct pixman_region16;
struct vec;
@ -14,7 +16,8 @@ void pixel32_to_cpixel(uint8_t *restrict dst,
const struct rfb_pixel_format* src_fmt,
size_t bytes_per_cpixel, size_t len);
int zrle_encode_frame(struct vec *dst,
int zrle_encode_frame(z_stream *zs,
struct vec *dst,
const struct rfb_pixel_format *dst_fmt,
const uint8_t *src,
const struct rfb_pixel_format *src_fmt,

View File

@ -55,6 +55,7 @@ struct nvnc_client {
LIST_ENTRY(nvnc_client) link;
struct pixman_region16 requested_region;
nvnc_client_fn cleanup_fn;
z_stream z_stream;
size_t buffer_index;
size_t buffer_len;
uint8_t msg_buffer[MSG_BUFFER_SIZE];
@ -113,6 +114,8 @@ static void cleanup_client(uv_handle_t* handle)
if (fn)
fn(client);
deflateEnd(&client->z_stream);
LIST_REMOVE(client, link);
pixman_region_fini(&client->requested_region);
free(client);
@ -655,6 +658,11 @@ static void on_connection(uv_stream_t *server_stream, int status)
client->server = server;
if (deflateInit(&client->z_stream, Z_DEFAULT_COMPRESSION) != Z_OK) {
free(client);
return;
}
pixman_region_init(&client->requested_region);
uv_tcp_init(uv_default_loop(), &client->stream_handle);
@ -771,8 +779,9 @@ int nvnc_update_fb(struct nvnc *self, const struct nvnc_fb *fb,
pixman_region_intersect(cregion, cregion, &region);
zrle_encode_frame(&frame, &client->pixfmt, fb->addr,
&server_fmt, fb->width, fb->height, &region);
zrle_encode_frame(&client->z_stream, &frame, &client->pixfmt,
fb->addr, &server_fmt, fb->width, fb->height,
&region);
pixman_region_clear(cregion);

View File

@ -180,36 +180,30 @@ int zrle_deflate(struct vec* dst, const struct vec* src, z_stream* zs,
zs->next_out = ((Bytef*)dst->data) + dst->len;
zs->avail_out = dst->cap - dst->len;
r = deflate(zs, flush ? Z_FINISH : Z_NO_FLUSH);
r = deflate(zs, flush ? Z_SYNC_FLUSH : Z_NO_FLUSH);
assert(r != Z_STREAM_ERROR);
dst->len = zs->next_out - (Bytef*)dst->data;
} while (zs->avail_out == 0);
assert(zs->avail_in == 0);
assert(!flush || r == Z_STREAM_END);
return 0;
}
int zrle_encode_box(struct vec* out, const struct rfb_pixel_format *dst_fmt,
const uint8_t *src, const struct rfb_pixel_format *src_fmt,
int x, int y, int stride, int width, int height)
int x, int y, int stride, int width, int height,
z_stream* zs)
{
int r = -1;
int bytes_per_cpixel = dst_fmt->depth / 8;
int chunk_size = 1 + bytes_per_cpixel * 64 * 64;
z_stream zs = { 0 };
struct vec in;
if (vec_init(&in, 1 + bytes_per_cpixel * 64 * 64) < 0)
goto failure;
r = deflateInit(&zs, Z_DEFAULT_COMPRESSION);
if (r != Z_OK)
goto failure;
struct rfb_server_fb_rect rect = {
.encoding = htonl(RFB_ENCODING_ZRLE),
.x = htons(x),
@ -239,16 +233,11 @@ int zrle_encode_box(struct vec* out, const struct rfb_pixel_format *dst_fmt,
((uint32_t*)src) + x + tile_x + (y + tile_y) * stride,
src_fmt, stride, tile_width, tile_height);
r = zrle_deflate(out, &in, &zs, i == n_tiles - 1);
r = zrle_deflate(out, &in, zs, i == n_tiles - 1);
if (r < 0)
goto failure;
}
deflateEnd(&zs);
/* There seems to be something extra at the end */
out->len -= 4;
uint32_t out_size = htonl(out->len - size_index - 4);
memcpy(((uint8_t*)out->data) + size_index, &out_size, sizeof(out_size));
@ -258,7 +247,8 @@ failure:
#undef CHUNK
}
int zrle_encode_frame(struct vec* dst,
int zrle_encode_frame(z_stream *zs,
struct vec* dst,
const struct rfb_pixel_format *dst_fmt,
const uint8_t *src,
const struct rfb_pixel_format *src_fmt,
@ -290,7 +280,7 @@ int zrle_encode_frame(struct vec* dst,
int box_height = box[i].y2 - y;
rc = zrle_encode_box(dst, dst_fmt, src, src_fmt, x, y,
width, box_width, box_height);
width, box_width, box_height, zs);
if (rc < 0)
return -1;
}