@@ -3239,7 +3239,30 @@ static void vnc_refresh(DisplayChangeListener *dcl)
vnc_unlock_display(vd);
QTAILQ_FOREACH_SAFE(vs, &vd->clients, next, vn) {
- rects += vnc_update_client(vs, has_dirty);
+ int client_dirty = has_dirty;
+ if (vs->h264) {
+ if (client_dirty) {
+ vs->h264->keep_dirty = VNC_H264_KEEP_DIRTY;
+ } else {
+ if (vs->h264->keep_dirty > 0) {
+ client_dirty = 1;
+ vs->h264->keep_dirty--;
+ }
+ }
+ }
+
+ int count = vnc_update_client(vs, client_dirty);
+ rects += count;
+
+ if (vs->h264 && !count && vs->h264->keep_dirty) {
+ VncJob *job = vnc_job_new(vs);
+ int height = pixman_image_get_height(vd->server);
+ int width = pixman_image_get_width(vd->server);
+ vs->job_update = vs->update;
+ vs->update = VNC_STATE_UPDATE_NONE;
+ vnc_job_add_rect(job, 0, 0, width, height);
+ vnc_job_push(job);
+ }
/* vs might be free()ed here */
}
@@ -236,10 +236,13 @@ typedef struct VncZywrle {
} VncZywrle;
#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
The H264 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 <dietmar@proxmox.com> --- ui/vnc.c | 25 ++++++++++++++++++++++++- ui/vnc.h | 3 +++ 2 files changed, 27 insertions(+), 1 deletion(-)