Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package neatvnc for openSUSE:Factory checked in at 2026-11-09 16:07:45 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/neatvnc (Old) and /work/SRC/openSUSE:Factory/.neatvnc.new.3759290 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "neatvnc" Mon Nov 9 16:07:45 2026 rev:24 rq:1396294 version:1.0.4 Changes: -------- --- /work/SRC/openSUSE:Factory/neatvnc/neatvnc.changes 2026-10-08 15:14:43.575119096 +0200 +++ /work/SRC/openSUSE:Factory/.neatvnc.new.3759290/neatvnc.changes 2026-11-09 16:08:50.746376846 +0100 @@ -1,0 +2,15 @@ +Mon Nov 9 09:45:06 UTC 2026 - Michael Vetter <[email protected]> + +- Update to 1.0.4: + * enc: h264: ffmpeg: Import buffers via single object + * pixels: Allow all modifiers on AMD + * enc: h264: v4l2m2m: Use poll() instead of map to wait + * stream: ws: http: Add bounds checks for fields + * server: Validate client requested bpp + * enc: h264: ffmpeg: Release queued frames on destroy + * enc: h264: ffmpeg: Pass on empty packets + * enc: h264: Handle encoder creation failure + * enc: tight: Fail on JPEG too big for tile buffer + * enc: tight: Fall back to basic if JPEG fails + +------------------------------------------------------------------- Old: ---- neatvnc-1.0.3.tar.xz New: ---- neatvnc-1.0.4.tar.xz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ neatvnc.spec ++++++ --- /var/tmp/diff_new_pack.gKcqPl/_old 2026-11-09 16:08:51.523409395 +0100 +++ /var/tmp/diff_new_pack.gKcqPl/_new 2026-11-09 16:08:51.525409479 +0100 @@ -19,7 +19,7 @@ %define libsoname libneatvnc1 Name: neatvnc -Version: 1.0.3 +Version: 1.0.4 Release: 0 Summary: A VNC server library License: ISC ++++++ _service ++++++ --- /var/tmp/diff_new_pack.gKcqPl/_old 2026-11-09 16:08:51.557410819 +0100 +++ /var/tmp/diff_new_pack.gKcqPl/_new 2026-11-09 16:08:51.559410903 +0100 @@ -3,8 +3,8 @@ <service name="obs_scm" mode="manual"> <param name="scm">git</param> <param name="url">https://github.com/any1/neatvnc.git</param> - <param name="revision">783437adc56c2d7ce2cac1ec584acad798594267</param> - <param name="versionformat">1.0.3</param> + <param name="revision">ffce32d6d04e702d5d8055e28e038c7f68a0caf4</param> + <param name="versionformat">1.0.4</param> </service> <service name="tar" mode="manual"/> <service name="recompress" mode="manual"> ++++++ neatvnc-1.0.3.tar.xz -> neatvnc-1.0.4.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/neatvnc-1.0.3/meson.build new/neatvnc-1.0.4/meson.build --- old/neatvnc-1.0.3/meson.build 2026-10-03 18:25:04.000000000 +0200 +++ new/neatvnc-1.0.4/meson.build 2026-11-01 15:52:00.000000000 +0100 @@ -1,7 +1,7 @@ project( 'neatvnc', 'c', - version: '1.0.3', + version: '1.0.4', license: 'ISC', default_options: [ 'c_std=gnu11', diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/neatvnc-1.0.3/src/enc/h264/ffmpeg-impl.c new/neatvnc-1.0.4/src/enc/h264/ffmpeg-impl.c --- old/neatvnc-1.0.3/src/enc/h264/ffmpeg-impl.c 2026-10-03 18:25:04.000000000 +0200 +++ new/neatvnc-1.0.4/src/enc/h264/ffmpeg-impl.c 2026-11-01 15:52:00.000000000 +0100 @@ -124,9 +124,13 @@ struct gbm_bo* bo = fb->buffer->bo; int n_planes = gbm_bo_get_plane_count(bo); + int fd = gbm_bo_get_fd(bo); AVDRMFrameDescriptor* desc = calloc(1, sizeof(*desc)); - desc->nb_objects = n_planes; + desc->nb_objects = 1; + desc->objects[0].fd = fd; + desc->objects[0].size = lseek(fd, 0, SEEK_END); + desc->objects[0].format_modifier = gbm_bo_get_modifier(bo); desc->nb_layers = 1; desc->layers[0].format = gbm_bo_get_format(bo); @@ -135,12 +139,8 @@ for (int i = 0; i < n_planes; ++i) { uint32_t stride = gbm_bo_get_stride_for_plane(bo, i); - desc->objects[i].fd = gbm_bo_get_fd_for_plane(bo, i); - desc->objects[i].size = stride * fb->height; - desc->objects[i].format_modifier = gbm_bo_get_modifier(bo); - desc->layers[0].format = gbm_bo_get_format(bo); - desc->layers[0].planes[i].object_index = i; + desc->layers[0].planes[i].object_index = 0; desc->layers[0].planes[i].offset = gbm_bo_get_offset(bo, i); desc->layers[0].planes[i].pitch = stride; } @@ -568,10 +568,8 @@ return; } - if (self->current_packet.len == 0) { - nvnc_log(NVNC_LOG_WARNING, "Whoops, encoded packet length is 0"); - return; - } + if (self->current_packet.len == 0) + nvnc_log(NVNC_LOG_DEBUG, "Encoded packet length is 0"); void* userdata = self->base.userdata; @@ -665,6 +663,14 @@ return; } + while (true) { + struct nvnc_frame* fb = fb_queue_dequeue(&self->fb_queue); + if (!fb) + break; + + nvnc_frame_unref(fb); + } + vec_destroy(&self->current_packet); h264_encoder__teardown_pipeline(self); aml_unref(self->work); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/neatvnc-1.0.3/src/enc/h264/open-h264.c new/neatvnc-1.0.4/src/enc/h264/open-h264.c --- old/neatvnc-1.0.3/src/enc/h264/open-h264.c 2026-10-03 18:25:04.000000000 +0200 +++ new/neatvnc-1.0.4/src/enc/h264/open-h264.c 2026-11-01 15:52:00.000000000 +0100 @@ -262,22 +262,26 @@ return 0; } -static int open_h264_ctx_encode(struct open_h264_context* self, struct nvnc_frame* fb) +static int open_h264_ctx_prepare(struct open_h264_context* self, + struct nvnc_frame* fb) { - DTRACE_PROBE1(neatvnc, open_h264_encode, fb->pts); - if (fb->width != self->width || fb->height != self->height || fb->fourcc_format != self->format || - self->quality_changed) { - if (open_h264_resize(self, fb) < 0) - return -1; - } + self->quality_changed) + return open_h264_resize(self, fb); + + return 0; +} + +static void open_h264_ctx_encode(struct open_h264_context* self, + struct nvnc_frame* fb) +{ + DTRACE_PROBE1(neatvnc, open_h264_encode, fb->pts); assert(self->width && self->height); // TODO: encoder_feed should return an error code h264_encoder_feed(self->encoder, fb); - return 0; } static struct open_h264_context* open_h264_find_context(struct open_h264* self, @@ -346,6 +350,8 @@ self->frame_width = nvnc_composite_fb_width(composite); self->frame_height = nvnc_composite_fb_height(composite); + struct open_h264_context* contexts[NVNC_FB_COMPOSITE_MAX] = { 0 }; + for (int i = 0; i < composite->n_fbs; ++i) { struct nvnc_frame* fb = composite->fbs[i]; assert(fb); @@ -362,10 +368,20 @@ struct open_h264_context* ctx = open_h264_get_context(self, fb->x_off, fb->y_off); + if (!ctx) + return -1; + + if (open_h264_ctx_prepare(ctx, fb) < 0) + return -1; - int rc = open_h264_ctx_encode(ctx, fb); - nvnc_assert(rc == 0, "Failed to encode frame"); + contexts[i] = ctx; + } + + for (int i = 0; i < composite->n_fbs; ++i) { + if (!contexts[i]) + continue; + open_h264_ctx_encode(contexts[i], composite->fbs[i]); self->frame_barrier++; } @@ -385,7 +401,8 @@ for (int i = 0; i < self->n_contexts; ++i) { struct open_h264_context* ctx = self->context[i]; assert(ctx); - h264_encoder_request_keyframe(ctx->encoder); + if (ctx->encoder) + h264_encoder_request_keyframe(ctx->encoder); } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/neatvnc-1.0.3/src/enc/h264/v4l2m2m-impl.c new/neatvnc-1.0.4/src/enc/h264/v4l2m2m-impl.c --- old/neatvnc-1.0.3/src/enc/h264/v4l2m2m-impl.c 2026-10-03 18:25:04.000000000 +0200 +++ new/neatvnc-1.0.4/src/enc/h264/v4l2m2m-impl.c 2026-11-01 15:52:00.000000000 +0100 @@ -20,10 +20,12 @@ #include "pixels.h" #include <assert.h> +#include <errno.h> #include <string.h> #include <stdio.h> #include <inttypes.h> #include <fcntl.h> +#include <poll.h> #include <sys/mman.h> #include <sys/ioctl.h> #include <linux/videodev2.h> @@ -387,7 +389,6 @@ // TODO: This assumes that there's only one fd close(srcbuf->planes[0].m.fd); - nvnc_frame_unmap(srcbuf->fb); nvnc_frame_unref(srcbuf->fb); srcbuf->fb = NULL; } @@ -458,6 +459,16 @@ ioctl(self->fd, VIDIOC_S_CTRL, &ctrl); } +static void wait_for_dmabuf_writers(int fd) +{ + struct pollfd pollfd = { + .fd = fd, + .events = POLLIN, + }; + if (poll(&pollfd, 1, -1) < 0 && errno != EINTR) + nvnc_log(NVNC_LOG_ERROR, "Failed to wait for dmabuf fences: %m"); +} + static void encode_buffer(struct h264_encoder_v4l2m2m* self, struct nvnc_frame* fb) { @@ -471,12 +482,6 @@ nvnc_frame_ref(fb); - /* For some reason the v4l2m2m h264 encoder in the Rapberry Pi 4 gets - * really glitchy unless the buffer is mapped first. - * This should probably be handled by the driver, but it's not. - */ - nvnc_frame_map(fb); - srcbuf->fb = fb; struct gbm_bo* bo = nvnc_frame_get_gbm_bo(fb); @@ -503,6 +508,9 @@ force_key_frame(self); self->base.next_frame_should_be_keyframe = false; + /* V4L2 does not wait for implicit fences */ + wait_for_dmabuf_writers(fd); + int rc = v4l2_qbuf(self->fd, &srcbuf->buffer); if (rc < 0) { nvnc_log(NVNC_LOG_PANIC, "Failed to enqueue buffer: %m"); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/neatvnc-1.0.3/src/enc/tight.c new/neatvnc-1.0.4/src/enc/tight.c --- old/neatvnc-1.0.3/src/enc/tight.c 2026-10-03 18:25:04.000000000 +0200 +++ new/neatvnc-1.0.4/src/enc/tight.c 2026-11-01 15:52:00.000000000 +0100 @@ -419,6 +419,7 @@ if (size > MAX_TILE_SIZE) { nvnc_log(NVNC_LOG_ERROR, "Whoops, encoded JPEG was too big for the buffer"); + rc = -1; goto failure; } @@ -426,8 +427,8 @@ tile->size = size; rc = 0; - tjFree(buffer); failure: + tjFree(buffer); tjDestroy(handle); return rc; @@ -448,13 +449,10 @@ tile->size = 0; #ifdef HAVE_JPEG - if (self->quality >= 10) { + if (self->quality >= 10 || tight_encode_tile_jpeg(self, tile, + fb_index, x, y, width, height) < 0) tight_encode_tile_basic(self, tile, fb_index, x, y, width, height, gx % 4); - } else { - tight_encode_tile_jpeg(self, tile, fb_index, x, y, width, - height); - } #else tight_encode_tile_basic(self, tile, fb_index, x, y, width, height, gx % 4); #endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/neatvnc-1.0.3/src/pixels.c new/neatvnc-1.0.4/src/pixels.c --- old/neatvnc-1.0.3/src/pixels.c 2026-10-03 18:25:04.000000000 +0200 +++ new/neatvnc-1.0.4/src/pixels.c 2026-11-01 15:52:00.000000000 +0100 @@ -724,13 +724,6 @@ return POPCOUNT(r) + POPCOUNT(g) + POPCOUNT(b); } -// All AMD modifiers except DCC are allowed -static bool amd_format_modifier_is_allowed(uint64_t modifier) -{ - return !AMD_FMT_MOD_GET(DCC, modifier) && - !AMD_FMT_MOD_GET(DCC_RETILE, modifier); -} - static const uint64_t format_modifier_allow_list[] = { DRM_FORMAT_MOD_LINEAR, @@ -744,7 +737,7 @@ static bool format_modifier_is_allowed(uint64_t modifier) { if (fourcc_mod_is_vendor(modifier, AMD)) - return amd_format_modifier_is_allowed(modifier); + return true; for (size_t i = 0; i < sizeof(format_modifier_allow_list) / sizeof(format_modifier_allow_list[0]); ++i) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/neatvnc-1.0.3/src/server.c new/neatvnc-1.0.4/src/server.c --- old/neatvnc-1.0.3/src/server.c 2026-10-03 18:25:04.000000000 +0200 +++ new/neatvnc-1.0.4/src/server.c 2026-11-01 15:52:00.000000000 +0100 @@ -744,6 +744,15 @@ if (fmt->true_colour_flag) { nvnc_log(NVNC_LOG_DEBUG, "Using true colour for client %p", client); + + uint8_t bpp = fmt->bits_per_pixel; + if (bpp != 8 && bpp != 16 && bpp != 32) { + nvnc_log(NVNC_LOG_ERROR, "Client %p requested %"PRIu8" bits per pixel, which is not allowed; closing", + client, bpp); + client_close(client); + return -1; + } + fmt->red_max = ntohs(fmt->red_max); fmt->green_max = ntohs(fmt->green_max); fmt->blue_max = ntohs(fmt->blue_max); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/neatvnc-1.0.3/src/stream/ws/http.c new/neatvnc-1.0.4/src/stream/ws/http.c --- old/neatvnc-1.0.3/src/stream/ws/http.c 2026-10-03 18:25:04.000000000 +0200 +++ new/neatvnc-1.0.4/src/stream/ws/http.c 2026-11-01 15:52:00.000000000 +0100 @@ -20,6 +20,7 @@ #include <stdlib.h> #include <string.h> #include <ctype.h> +#include <assert.h> enum httplex_token_type { HTTPLEX_SOLIDUS, @@ -54,7 +55,7 @@ const char* next_pos; struct vec buffer; int accepted; - int errno_; + int failed; }; static int httplex_init(struct httplex* self, const char* input) @@ -402,6 +403,11 @@ if (tok->type != HTTPLEX_KEY) return 0; + if (req->field_index >= HTTP_FIELD_INDEX_MAX) { + lex->failed = 1; + return 0; + } + req->field[req->field_index].key = strdup(tok->value); return httplex_accept_token(lex); @@ -418,6 +424,7 @@ if (tok->type != HTTPLEX_VALUE) return 0; + assert(req->field_index < HTTP_FIELD_INDEX_MAX); req->field[req->field_index++].value = strdup(tok->value); return httplex_accept_token(lex); @@ -461,6 +468,9 @@ if (!http__header(req, &lex)) goto failure; + if (lex.failed) + goto failure; + req->header_length = lex.next_pos - input; httplex_destroy(&lex); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/neatvnc-1.0.3/src/vec.c new/neatvnc-1.0.4/src/vec.c --- old/neatvnc-1.0.3/src/vec.c 2026-10-03 18:25:04.000000000 +0200 +++ new/neatvnc-1.0.4/src/vec.c 2026-11-01 15:52:00.000000000 +0100 @@ -69,6 +69,9 @@ int vec_append(struct vec* vec, const void* data, size_t size) { + if (size == 0) + return 0; + if (unlikely(vec__grow(vec, size) < 0)) return -1; ++++++ neatvnc.obsinfo ++++++ --- /var/tmp/diff_new_pack.gKcqPl/_old 2026-11-09 16:08:51.680415972 +0100 +++ /var/tmp/diff_new_pack.gKcqPl/_new 2026-11-09 16:08:51.683416097 +0100 @@ -1,5 +1,5 @@ name: neatvnc -version: 1.0.3 -mtime: 1791044704 -commit: 783437adc56c2d7ce2cac1ec584acad798594267 +version: 1.0.4 +mtime: 1793544720 +commit: ffce32d6d04e702d5d8055e28e038c7f68a0caf4
