From 73987c2f1708f2f41f70749d022654979ff753d5 Mon Sep 17 00:00:00 2001 From: Andri Yngvason Date: Sun, 8 Sep 2019 15:09:35 +0000 Subject: [PATCH] Add modifier to do y-inversion during encoding --- bench/zrle-bench.c | 5 ++--- examples/png-server.c | 4 +++- inc/neatvnc.h | 6 ++++++ inc/zrle.h | 6 +++--- src/server.c | 3 +-- src/zrle.c | 28 +++++++++++++++++++--------- 6 files changed, 34 insertions(+), 18 deletions(-) diff --git a/bench/zrle-bench.c b/bench/zrle-bench.c index d31b3d6..ffba945 100644 --- a/bench/zrle-bench.c +++ b/bench/zrle-bench.c @@ -48,7 +48,7 @@ int run_benchmark(const char *image) { int rc = -1; - struct nvnc_fb fb; + struct nvnc_fb fb = { 0 }; rc = read_png_file(&fb, image); if (rc < 0) return -1; @@ -83,8 +83,7 @@ int run_benchmark(const char *image) free(dummy); start_time = gettime_us(CLOCK_PROCESS_CPUTIME_ID); - rc = zrle_encode_frame(&zs, &frame, &pixfmt, fb.addr, &pixfmt, - fb.width, fb.height, ®ion); + rc = zrle_encode_frame(&zs, &frame, &pixfmt, &fb, &pixfmt, ®ion); end_time = gettime_us(CLOCK_PROCESS_CPUTIME_ID); printf("Encoding %s took %"PRIu64" micro seconds\n", image, diff --git a/examples/png-server.c b/examples/png-server.c index 74820fb..514ea41 100644 --- a/examples/png-server.c +++ b/examples/png-server.c @@ -50,12 +50,14 @@ int main(int argc, char *argv[]) return 1; } - struct nvnc_fb fb; + struct nvnc_fb fb = { 0 }; if (read_png_file(&fb, file) < 0) { printf("Failed to read png file\n"); return 1; } + fb.nvnc_modifier = NVNC_MOD_Y_INVERT; + struct nvnc *server = nvnc_open("127.0.0.1", 5900); nvnc_set_dimensions(server, fb.width, fb.height, fb.fourcc_format); diff --git a/inc/neatvnc.h b/inc/neatvnc.h index 47b5998..c799992 100644 --- a/inc/neatvnc.h +++ b/inc/neatvnc.h @@ -31,6 +31,10 @@ enum nvnc_button_mask { NVNC_SCROLL_DOWN = 1 << 4, }; +enum nvnc_modifier { + NVNC_MOD_Y_INVERT = 1 << 0, +}; + struct nvnc_fb { void *addr; uint32_t size; @@ -38,6 +42,8 @@ struct nvnc_fb { uint16_t height; uint32_t fourcc_format; uint64_t fourcc_modifier; + enum nvnc_modifier nvnc_modifier; + uint32_t reserved[4]; }; typedef void (*nvnc_key_fn)(struct nvnc_client*, uint32_t keysym, bool is_pressed); diff --git a/inc/zrle.h b/inc/zrle.h index 39f73d4..8e85a68 100644 --- a/inc/zrle.h +++ b/inc/zrle.h @@ -21,6 +21,7 @@ #include "miniz.h" +struct nvnc_fb; struct rfb_pixel_format; struct pixman_region16; struct vec; @@ -32,9 +33,8 @@ void pixel32_to_cpixel(uint8_t *restrict dst, size_t bytes_per_cpixel, size_t len); int zrle_encode_frame(z_stream *zs, - struct vec *dst, + struct vec *dst, const struct rfb_pixel_format *dst_fmt, - const uint8_t *src, + const struct nvnc_fb *src, const struct rfb_pixel_format *src_fmt, - int width, int height, struct pixman_region16 *region); diff --git a/src/server.c b/src/server.c index aa8651c..a4eb229 100644 --- a/src/server.c +++ b/src/server.c @@ -810,8 +810,7 @@ int nvnc_update_fb(struct nvnc *self, const struct nvnc_fb *fb, goto failure; zrle_encode_frame(&client->z_stream, &frame, &client->pixfmt, - fb->addr, &server_fmt, fb->width, fb->height, - ®ion); + fb, &server_fmt, cregion); pixman_region_clear(cregion); diff --git a/src/zrle.c b/src/zrle.c index 60ab2c7..bde026c 100644 --- a/src/zrle.c +++ b/src/zrle.c @@ -19,6 +19,7 @@ #include "vec.h" #include "zrle.h" #include "miniz.h" +#include "neatvnc.h" #include #include @@ -260,10 +261,15 @@ void zrle_encode_packed_tile(struct vec *dst, } void zrle_copy_tile(uint32_t *dst, const uint32_t *src, int stride, - int width, int height) + int width, int height, enum nvnc_modifier mod) { - for (int y = 0; y < height; ++y) - memcpy(dst + y * width, src + y * stride, width * 4); + for (int y = 0; y < height; ++y) { + if (!(mod & NVNC_MOD_Y_INVERT)) + memcpy(dst + y * width, src + y * stride, width * 4); + else + memcpy(dst + (height - y - 1) * width, src + y * stride, + width * 4); + } } void zrle_encode_tile(struct vec *dst, const struct rfb_pixel_format *dst_fmt, @@ -324,7 +330,8 @@ int zrle_deflate(struct vec* dst, const struct vec* src, z_stream* zs, } 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 struct nvnc_fb *fb, + const struct rfb_pixel_format *src_fmt, int x, int y, int stride, int width, int height, z_stream* zs) { @@ -362,12 +369,16 @@ int zrle_encode_box(struct vec* out, const struct rfb_pixel_format *dst_fmt, int tile_x = (i % UDIV_UP(width, 64)) * 64; int tile_y = (i / UDIV_UP(width, 64)) * 64; + if (fb->nvnc_modifier & NVNC_MOD_Y_INVERT) + tile_y = (UDIV_UP(height, 64) - tile_y / 64 - 1) * 64; + int tile_width = width - tile_x >= 64 ? 64 : width - tile_x; int tile_height = height - tile_y >= 64 ? 64 : height - tile_y; zrle_copy_tile(tile, - ((uint32_t*)src) + x + tile_x + (y + tile_y) * stride, - stride, tile_width, tile_height); + ((uint32_t*)fb->addr) + x + tile_x + (y + tile_y) * stride, + stride, tile_width, tile_height, + fb->nvnc_modifier); zrle_encode_tile(&in, dst_fmt, tile, src_fmt, tile_width * tile_height); @@ -390,9 +401,8 @@ failure: int zrle_encode_frame(z_stream *zs, struct vec* dst, const struct rfb_pixel_format *dst_fmt, - const uint8_t *src, + const struct nvnc_fb *src, const struct rfb_pixel_format *src_fmt, - int width, int height, struct pixman_region16 *region) { int rc = -1; @@ -420,7 +430,7 @@ int zrle_encode_frame(z_stream *zs, int box_height = box[i].y2 - y; rc = zrle_encode_box(dst, dst_fmt, src, src_fmt, x, y, - width, box_width, box_height, zs); + src->width, box_width, box_height, zs); if (rc < 0) return -1; }