From nobody Sun Nov 16 00:58:32 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 17458274814211022.6819509563977; Mon, 28 Apr 2025 01:04:41 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1u9JSw-0004lH-22; Mon, 28 Apr 2025 04:03:50 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1u9JSs-0004hp-Mi for qemu-devel@nongnu.org; Mon, 28 Apr 2025 04:03:47 -0400 Received: from [94.136.29.99] (helo=zilli.proxmox.com) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1u9JSp-00051R-C6 for qemu-devel@nongnu.org; Mon, 28 Apr 2025 04:03:46 -0400 Received: by zilli.proxmox.com (Postfix, from userid 1000) id DD7C61C0A60; Mon, 28 Apr 2025 10:03:38 +0200 (CEST) From: Dietmar Maurer To: marcandre.lureau@redhat.com, qemu-devel@nongnu.org Cc: Dietmar Maurer Subject: [PATCH v4 4/8] vnc: h264: send additional frames after the display is clean Date: Mon, 28 Apr 2025 10:03:32 +0200 Message-Id: <20250428080336.2574852-5-dietmar@proxmox.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250428080336.2574852-1-dietmar@proxmox.com> References: <20250428080336.2574852-1-dietmar@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Host-Lookup-Failed: Reverse DNS lookup failed for 94.136.29.99 (failed) Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: none client-ip=94.136.29.99; envelope-from=dietmar@zilli.proxmox.com; helo=zilli.proxmox.com X-Spam_score_int: -10 X-Spam_score: -1.1 X-Spam_bar: - X-Spam_report: (-1.1 / 5.0 requ) BAYES_00=-1.9, NO_DNS_FOR_FROM=0.001, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RDNS_NONE=0.793, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZM-MESSAGEID: 1745827491265019100 Content-Type: text/plain; charset="utf-8" The vnc implementation only sends frames when it detects changes in the server's framebuffer. This leads to artifacts when there are no further changes, as the internal H264 encoder may still contain data. This patch modifies the code to send a few additional frames in such situations to flush the H264 encoder data. Signed-off-by: Dietmar Maurer --- ui/vnc.c | 13 ++++++++++++- ui/vnc.h | 3 +++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/ui/vnc.c b/ui/vnc.c index c1f2c3ae15..0efdc9ec39 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -3236,6 +3236,7 @@ static void vnc_refresh(DisplayChangeListener *dcl) VncDisplay *vd =3D container_of(dcl, VncDisplay, dcl); VncState *vs, *vn; int has_dirty, rects =3D 0; + bool keep_dirty =3D false; =20 if (QTAILQ_EMPTY(&vd->clients)) { update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_MAX); @@ -3253,11 +3254,21 @@ static void vnc_refresh(DisplayChangeListener *dcl) vnc_unlock_display(vd); =20 QTAILQ_FOREACH_SAFE(vs, &vd->clients, next, vn) { +#ifdef CONFIG_GSTREAMER + if (vs->h264) { + if (has_dirty) { + vs->h264->keep_dirty =3D VNC_H264_KEEP_DIRTY; + } else if (vs->h264->keep_dirty > 0) { + keep_dirty =3D true; + vs->h264->keep_dirty--; + } + } +#endif rects +=3D vnc_update_client(vs, has_dirty); /* vs might be free()ed here */ } =20 - if (has_dirty && rects) { + if ((has_dirty && rects) || keep_dirty) { vd->dcl.update_interval /=3D 2; if (vd->dcl.update_interval < VNC_REFRESH_INTERVAL_BASE) { vd->dcl.update_interval =3D VNC_REFRESH_INTERVAL_BASE; diff --git a/ui/vnc.h b/ui/vnc.h index 0fe9a9ab16..29012b75c7 100644 --- a/ui/vnc.h +++ b/ui/vnc.h @@ -236,10 +236,13 @@ typedef struct VncZywrle { } VncZywrle; =20 #ifdef CONFIG_GSTREAMER +/* Number of frames we send after the display is clean. */ +#define VNC_H264_KEEP_DIRTY 10 typedef struct VncH264 { GstElement *pipeline, *source, *gst_encoder, *sink, *convert; size_t width; size_t height; + guint keep_dirty; } VncH264; #endif =20 --=20 2.39.5