diff --git a/include/fb.h b/include/fb.h index 24444ca..2c80d56 100644 --- a/include/fb.h +++ b/include/fb.h @@ -19,6 +19,7 @@ #include #include #include +#include #include "neatvnc.h" #include "common.h" @@ -31,12 +32,12 @@ struct nvnc_fb { void* release_context; void* addr; enum nvnc_fb_flags flags; - size_t size; uint16_t width; uint16_t height; int32_t stride; uint32_t fourcc_format; uint64_t fourcc_modifier; + bool is_external; }; void nvnc_fb_hold(struct nvnc_fb* fb); diff --git a/include/neatvnc.h b/include/neatvnc.h index d10e5c9..f5af6bb 100644 --- a/include/neatvnc.h +++ b/include/neatvnc.h @@ -83,6 +83,8 @@ int nvnc_enable_auth(struct nvnc* self, const char* privkey_path, struct nvnc_fb* nvnc_fb_new(uint16_t width, uint16_t height, uint32_t fourcc_format, uint16_t stride); +struct nvnc_fb* nvnc_fb_from_buffer(void* buffer, uint16_t width, + uint16_t height, uint32_t fourcc_format, int32_t stride); void nvnc_fb_ref(struct nvnc_fb* fb); void nvnc_fb_unref(struct nvnc_fb* fb); diff --git a/src/fb.c b/src/fb.c index 789d6b9..bd15f82 100644 --- a/src/fb.c +++ b/src/fb.c @@ -40,15 +40,11 @@ struct nvnc_fb* nvnc_fb_new(uint16_t width, uint16_t height, fb->height = height; fb->fourcc_format = fourcc_format; fb->stride = stride; - fb->size = width * stride * 4; /* Assume 4 byte format for now */ + size_t size = width * stride * 4; /* Assume 4 byte format for now */ size_t alignment = MAX(4, sizeof(void*)); - size_t aligned_size = ALIGN_UP(fb->size, alignment); + size_t aligned_size = ALIGN_UP(size, alignment); - /* fb could be allocated in single allocation, but I want to reserve - * the possiblity to create an fb with a pixel buffer passed from the - * user. - */ fb->addr = aligned_alloc(alignment, aligned_size); if (!fb->addr) { free(fb); @@ -58,6 +54,25 @@ struct nvnc_fb* nvnc_fb_new(uint16_t width, uint16_t height, return fb; } +EXPORT +struct nvnc_fb* nvnc_fb_from_buffer(void* buffer, uint16_t width, uint16_t height, + uint32_t fourcc_format, int32_t stride) +{ + struct nvnc_fb* fb = calloc(1, sizeof(*fb)); + if (!fb) + return NULL; + + fb->ref = 1; + fb->addr = buffer; + fb->is_external = true; + fb->width = width; + fb->height = height; + fb->fourcc_format = fourcc_format; + fb->stride = stride; + + return fb; +} + EXPORT enum nvnc_fb_flags nvnc_fb_get_flags(const struct nvnc_fb* fb) { @@ -112,7 +127,9 @@ static void nvnc__fb_free(struct nvnc_fb* fb) if (cleanup) cleanup(fb->common.userdata); - free(fb->addr); + if (!fb->is_external) + free(fb->addr); + free(fb); }