zrle: Keep the stream alive per connection
Otherwise the client doesn't want to play with the server.tight-png
parent
46dc074370
commit
ff67e2fed3
|
@ -3,6 +3,7 @@
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "vec.h"
|
#include "vec.h"
|
||||||
#include "neatvnc.h"
|
#include "neatvnc.h"
|
||||||
|
#include "miniz.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <libdrm/drm_fourcc.h>
|
#include <libdrm/drm_fourcc.h>
|
||||||
|
@ -39,15 +40,21 @@ int run_benchmark(const char *image)
|
||||||
struct vec frame;
|
struct vec frame;
|
||||||
vec_init(&frame, fb.width * fb.height * 3 / 2);
|
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);
|
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, ®ion);
|
fb.width, fb.height, ®ion);
|
||||||
|
|
||||||
uint64_t end_time = gettime_us(CLOCK_PROCESS_CPUTIME_ID);
|
uint64_t end_time = gettime_us(CLOCK_PROCESS_CPUTIME_ID);
|
||||||
printf("Encoding %s took %"PRIu64" micro seconds\n", image,
|
printf("Encoding %s took %"PRIu64" micro seconds\n", image,
|
||||||
end_time - start_time);
|
end_time - start_time);
|
||||||
|
|
||||||
|
deflateEnd(&zs);
|
||||||
|
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
goto failure;
|
goto failure;
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,7 @@ void on_pointer_event(struct nvnc_client *client, uint16_t x, uint16_t y,
|
||||||
struct pixman_region16 region;
|
struct pixman_region16 region;
|
||||||
pixman_region_init_rect(®ion, 0, 0, draw->fb.width,
|
pixman_region_init_rect(®ion, 0, 0, draw->fb.width,
|
||||||
draw->fb.height);
|
draw->fb.height);
|
||||||
// pixman_region_init_rect(®ion, x, y, 1, 1);
|
pixman_region_intersect_rect(®ion, ®ion, x, y, 1, 1);
|
||||||
nvnc_update_fb(server, &draw->fb, ®ion);
|
nvnc_update_fb(server, &draw->fb, ®ion);
|
||||||
pixman_region_fini(®ion);
|
pixman_region_fini(®ion);
|
||||||
}
|
}
|
||||||
|
|
|
@ -132,7 +132,6 @@ struct rfb_server_fb_update_msg {
|
||||||
uint8_t type;
|
uint8_t type;
|
||||||
uint8_t padding;
|
uint8_t padding;
|
||||||
uint16_t n_rects;
|
uint16_t n_rects;
|
||||||
struct rfb_server_fb_rect rects[0];
|
|
||||||
} RFB_PACKED;
|
} RFB_PACKED;
|
||||||
|
|
||||||
static inline int rfb_send_security_types(void *client)
|
static inline int rfb_send_security_types(void *client)
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "miniz.h"
|
||||||
|
|
||||||
struct rfb_pixel_format;
|
struct rfb_pixel_format;
|
||||||
struct pixman_region16;
|
struct pixman_region16;
|
||||||
struct vec;
|
struct vec;
|
||||||
|
@ -14,7 +16,8 @@ void pixel32_to_cpixel(uint8_t *restrict dst,
|
||||||
const struct rfb_pixel_format* src_fmt,
|
const struct rfb_pixel_format* src_fmt,
|
||||||
size_t bytes_per_cpixel, size_t len);
|
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 struct rfb_pixel_format *dst_fmt,
|
||||||
const uint8_t *src,
|
const uint8_t *src,
|
||||||
const struct rfb_pixel_format *src_fmt,
|
const struct rfb_pixel_format *src_fmt,
|
||||||
|
|
13
src/server.c
13
src/server.c
|
@ -55,6 +55,7 @@ struct nvnc_client {
|
||||||
LIST_ENTRY(nvnc_client) link;
|
LIST_ENTRY(nvnc_client) link;
|
||||||
struct pixman_region16 requested_region;
|
struct pixman_region16 requested_region;
|
||||||
nvnc_client_fn cleanup_fn;
|
nvnc_client_fn cleanup_fn;
|
||||||
|
z_stream z_stream;
|
||||||
size_t buffer_index;
|
size_t buffer_index;
|
||||||
size_t buffer_len;
|
size_t buffer_len;
|
||||||
uint8_t msg_buffer[MSG_BUFFER_SIZE];
|
uint8_t msg_buffer[MSG_BUFFER_SIZE];
|
||||||
|
@ -113,6 +114,8 @@ static void cleanup_client(uv_handle_t* handle)
|
||||||
if (fn)
|
if (fn)
|
||||||
fn(client);
|
fn(client);
|
||||||
|
|
||||||
|
deflateEnd(&client->z_stream);
|
||||||
|
|
||||||
LIST_REMOVE(client, link);
|
LIST_REMOVE(client, link);
|
||||||
pixman_region_fini(&client->requested_region);
|
pixman_region_fini(&client->requested_region);
|
||||||
free(client);
|
free(client);
|
||||||
|
@ -655,6 +658,11 @@ static void on_connection(uv_stream_t *server_stream, int status)
|
||||||
|
|
||||||
client->server = server;
|
client->server = server;
|
||||||
|
|
||||||
|
if (deflateInit(&client->z_stream, Z_DEFAULT_COMPRESSION) != Z_OK) {
|
||||||
|
free(client);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
pixman_region_init(&client->requested_region);
|
pixman_region_init(&client->requested_region);
|
||||||
|
|
||||||
uv_tcp_init(uv_default_loop(), &client->stream_handle);
|
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, ®ion);
|
pixman_region_intersect(cregion, cregion, ®ion);
|
||||||
|
|
||||||
zrle_encode_frame(&frame, &client->pixfmt, fb->addr,
|
zrle_encode_frame(&client->z_stream, &frame, &client->pixfmt,
|
||||||
&server_fmt, fb->width, fb->height, ®ion);
|
fb->addr, &server_fmt, fb->width, fb->height,
|
||||||
|
®ion);
|
||||||
|
|
||||||
pixman_region_clear(cregion);
|
pixman_region_clear(cregion);
|
||||||
|
|
||||||
|
|
24
src/zrle.c
24
src/zrle.c
|
@ -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->next_out = ((Bytef*)dst->data) + dst->len;
|
||||||
zs->avail_out = dst->cap - 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);
|
assert(r != Z_STREAM_ERROR);
|
||||||
|
|
||||||
dst->len = zs->next_out - (Bytef*)dst->data;
|
dst->len = zs->next_out - (Bytef*)dst->data;
|
||||||
} while (zs->avail_out == 0);
|
} while (zs->avail_out == 0);
|
||||||
|
|
||||||
assert(zs->avail_in == 0);
|
assert(zs->avail_in == 0);
|
||||||
assert(!flush || r == Z_STREAM_END);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int zrle_encode_box(struct vec* out, const struct rfb_pixel_format *dst_fmt,
|
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,
|
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 r = -1;
|
||||||
int bytes_per_cpixel = dst_fmt->depth / 8;
|
int bytes_per_cpixel = dst_fmt->depth / 8;
|
||||||
int chunk_size = 1 + bytes_per_cpixel * 64 * 64;
|
int chunk_size = 1 + bytes_per_cpixel * 64 * 64;
|
||||||
z_stream zs = { 0 };
|
|
||||||
|
|
||||||
struct vec in;
|
struct vec in;
|
||||||
|
|
||||||
if (vec_init(&in, 1 + bytes_per_cpixel * 64 * 64) < 0)
|
if (vec_init(&in, 1 + bytes_per_cpixel * 64 * 64) < 0)
|
||||||
goto failure;
|
goto failure;
|
||||||
|
|
||||||
r = deflateInit(&zs, Z_DEFAULT_COMPRESSION);
|
|
||||||
if (r != Z_OK)
|
|
||||||
goto failure;
|
|
||||||
|
|
||||||
struct rfb_server_fb_rect rect = {
|
struct rfb_server_fb_rect rect = {
|
||||||
.encoding = htonl(RFB_ENCODING_ZRLE),
|
.encoding = htonl(RFB_ENCODING_ZRLE),
|
||||||
.x = htons(x),
|
.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,
|
((uint32_t*)src) + x + tile_x + (y + tile_y) * stride,
|
||||||
src_fmt, stride, tile_width, tile_height);
|
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)
|
if (r < 0)
|
||||||
goto failure;
|
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);
|
uint32_t out_size = htonl(out->len - size_index - 4);
|
||||||
memcpy(((uint8_t*)out->data) + size_index, &out_size, sizeof(out_size));
|
memcpy(((uint8_t*)out->data) + size_index, &out_size, sizeof(out_size));
|
||||||
|
|
||||||
|
@ -258,7 +247,8 @@ failure:
|
||||||
#undef CHUNK
|
#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 struct rfb_pixel_format *dst_fmt,
|
||||||
const uint8_t *src,
|
const uint8_t *src,
|
||||||
const struct rfb_pixel_format *src_fmt,
|
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;
|
int box_height = box[i].y2 - y;
|
||||||
|
|
||||||
rc = zrle_encode_box(dst, dst_fmt, src, src_fmt, x, 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)
|
if (rc < 0)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue