From: "Daniel P. Berrangé" <berrange@redhat.com>
To: Dietmar Maurer <dietmar@proxmox.com>
Cc: marcandre.lureau@redhat.com, qemu-devel@nongnu.org
Subject: Re: [PATCH v3 2/9] add vnc h264 encoder
Date: Thu, 24 Apr 2025 17:39:20 +0100 [thread overview]
Message-ID: <aAppOBppJI0PPXnw@redhat.com> (raw)
In-Reply-To: <20250418112953.1744442-3-dietmar@proxmox.com>
On Fri, Apr 18, 2025 at 01:29:46PM +0200, Dietmar Maurer wrote:
> This patch implements H264 support for VNC. The RFB protocol
> extension is defined in:
>
> https://github.com/rfbproto/rfbproto/blob/master/rfbproto.rst#open-h-264-encoding
>
> Currently the Gstreamer x264enc plugin (software encoder) is used
> to encode the video stream.
>
> The gstreamer pipe is:
>
> appsrc -> videoconvert -> x264enc -> appsink
>
> Note: videoconvert is required for RGBx to YUV420 conversion.
>
> The code still use the VNC server framebuffer change detection,
> and only encodes and sends video frames if there are changes.
>
> Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
> ---
> ui/meson.build | 1 +
> ui/vnc-enc-h264.c | 282 ++++++++++++++++++++++++++++++++++++++++++++++
> ui/vnc-jobs.c | 49 +++++---
> ui/vnc.c | 21 ++++
> ui/vnc.h | 21 ++++
> 5 files changed, 359 insertions(+), 15 deletions(-)
> create mode 100644 ui/vnc-enc-h264.c
>
> diff --git a/ui/meson.build b/ui/meson.build
> index 35fb04cadf..34f1f33699 100644
> --- a/ui/meson.build
> +++ b/ui/meson.build
> @@ -46,6 +46,7 @@ vnc_ss.add(files(
> ))
> vnc_ss.add(zlib, jpeg)
> vnc_ss.add(when: sasl, if_true: files('vnc-auth-sasl.c'))
> +vnc_ss.add(when: gstreamer, if_true: files('vnc-enc-h264.c'))
> system_ss.add_all(when: [vnc, pixman], if_true: vnc_ss)
> system_ss.add(when: vnc, if_false: files('vnc-stubs.c'))
>
> diff --git a/ui/vnc-enc-h264.c b/ui/vnc-enc-h264.c
> new file mode 100644
> index 0000000000..3abe6a1528
> --- /dev/null
> +++ b/ui/vnc-enc-h264.c
> diff --git a/ui/vnc.c b/ui/vnc.c
> index 9241caaad9..aed25b0183 100644
> --- a/ui/vnc.c
> +++ b/ui/vnc.c
> @@ -972,6 +972,9 @@ int vnc_send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
> case VNC_ENCODING_ZYWRLE:
> n = vnc_zywrle_send_framebuffer_update(vs, x, y, w, h);
> break;
> + case VNC_ENCODING_H264:
> + n = vnc_h264_send_framebuffer_update(vs, x, y, w, h);
> + break;
Needs protecting with #ifdef CONFIG_GSTREAMER otherwise I'd
expect a linker error
> default:
> vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_RAW);
> n = vnc_raw_send_framebuffer_update(vs, x, y, w, h);
> @@ -1326,6 +1329,10 @@ void vnc_disconnect_finish(VncState *vs)
> vnc_tight_clear(vs);
> vnc_zrle_clear(vs);
>
> +#ifdef CONFIG_GSTREAMER
> + vnc_h264_clear(vs);
> +#endif
> +
> #ifdef CONFIG_VNC_SASL
> vnc_sasl_client_cleanup(vs);
> #endif /* CONFIG_VNC_SASL */
> @@ -2181,6 +2188,16 @@ static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings)
> vnc_set_feature(vs, VNC_FEATURE_ZYWRLE);
> vs->vnc_encoding = enc;
> break;
> +#ifdef CONFIG_GSTREAMER
> + case VNC_ENCODING_H264:
> + if (vnc_h264_encoder_init(vs)) {
> + vnc_set_feature(vs, VNC_FEATURE_H264);
> + vs->vnc_encoding = enc;
> + } else {
> + VNC_DEBUG("vnc_h264_encoder_init failed\n");
> + }
> + break;
> +#endif
> case VNC_ENCODING_DESKTOPRESIZE:
> vnc_set_feature(vs, VNC_FEATURE_RESIZE);
> break;
> @@ -4291,6 +4308,10 @@ int vnc_init_func(void *opaque, QemuOpts *opts, Error **errp)
> Error *local_err = NULL;
> char *id = (char *)qemu_opts_id(opts);
>
> +#ifdef CONFIG_GSTREAMER
> + gst_init(NULL, NULL);
> +#endif
> +
> assert(id);
> vnc_display_init(id, &local_err);
> if (local_err) {
> diff --git a/ui/vnc.h b/ui/vnc.h
> index acc53a2cc1..a0d336738d 100644
> --- a/ui/vnc.h
> +++ b/ui/vnc.h
> @@ -46,6 +46,10 @@
> #include "vnc-enc-zrle.h"
> #include "ui/kbd-state.h"
>
> +#ifdef CONFIG_GSTREAMER
> +#include <gst/gst.h>
> +#endif
> +
> // #define _VNC_DEBUG 1
>
> #ifdef _VNC_DEBUG
> @@ -231,6 +235,14 @@ typedef struct VncZywrle {
> int buf[VNC_ZRLE_TILE_WIDTH * VNC_ZRLE_TILE_HEIGHT];
> } VncZywrle;
>
> +#ifdef CONFIG_GSTREAMER
> +typedef struct VncH264 {
> + GstElement *pipeline, *source, *gst_encoder, *sink, *convert;
> + size_t width;
> + size_t height;
> +} VncH264;
> +#endif
> +
> struct VncRect
> {
> int x;
> @@ -344,6 +356,9 @@ struct VncState
> VncHextile hextile;
> VncZrle *zrle;
> VncZywrle zywrle;
> +#ifdef CONFIG_GSTREAMER
> + VncH264 *h264;
> +#endif
>
> Notifier mouse_mode_notifier;
>
> @@ -404,6 +419,7 @@ enum {
> #define VNC_ENCODING_TRLE 0x0000000f
> #define VNC_ENCODING_ZRLE 0x00000010
> #define VNC_ENCODING_ZYWRLE 0x00000011
> +#define VNC_ENCODING_H264 0x00000032 /* 50 */
> #define VNC_ENCODING_COMPRESSLEVEL0 0xFFFFFF00 /* -256 */
> #define VNC_ENCODING_QUALITYLEVEL0 0xFFFFFFE0 /* -32 */
> #define VNC_ENCODING_XCURSOR 0xFFFFFF10 /* -240 */
> @@ -464,6 +480,7 @@ enum VncFeatures {
> VNC_FEATURE_XVP,
> VNC_FEATURE_CLIPBOARD_EXT,
> VNC_FEATURE_AUDIO,
> + VNC_FEATURE_H264,
> };
>
>
> @@ -625,6 +642,10 @@ int vnc_zrle_send_framebuffer_update(VncState *vs, int x, int y, int w, int h);
> int vnc_zywrle_send_framebuffer_update(VncState *vs, int x, int y, int w, int h);
> void vnc_zrle_clear(VncState *vs);
>
> +bool vnc_h264_encoder_init(VncState *vs);
> +int vnc_h264_send_framebuffer_update(VncState *vs, int x, int y, int w, int h);
> +void vnc_h264_clear(VncState *vs);
> +
> /* vnc-clipboard.c */
> void vnc_server_cut_text_caps(VncState *vs);
> void vnc_client_cut_text(VncState *vs, size_t len, uint8_t *text);
> --
> 2.39.5
>
>
With regards,
Daniel
--
|: https://berrange.com -o- https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o- https://fstop138.berrange.com :|
|: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|
next prev parent reply other threads:[~2025-04-24 16:39 UTC|newest]
Thread overview: 47+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-04-18 11:29 [PATCH v3 0/9] Add VNC Open H.264 Encoding Dietmar Maurer
2025-04-18 11:29 ` [PATCH v3 1/9] new configure option to enable gstreamer Dietmar Maurer
2025-04-19 5:11 ` Marc-André Lureau
2025-04-23 12:14 ` Daniel P. Berrangé
2025-04-18 11:29 ` [PATCH v3 2/9] add vnc h264 encoder Dietmar Maurer
2025-04-19 5:24 ` Marc-André Lureau
2025-04-23 11:46 ` Dietmar Maurer
2025-04-23 11:57 ` Marc-André Lureau
2025-04-24 6:19 ` Dietmar Maurer
2025-04-24 8:32 ` Daniel P. Berrangé
2025-04-24 9:28 ` Dietmar Maurer
2025-04-24 9:34 ` Daniel P. Berrangé
2025-04-23 12:10 ` Daniel P. Berrangé
2025-04-23 12:25 ` Daniel P. Berrangé
2025-04-24 7:32 ` Dietmar Maurer
2025-04-24 8:43 ` Dietmar Maurer
2025-04-24 8:58 ` Daniel P. Berrangé
2025-04-24 10:39 ` Dietmar Maurer
2025-04-24 10:45 ` Daniel P. Berrangé
2025-04-24 11:01 ` Dietmar Maurer
2025-04-24 16:39 ` Daniel P. Berrangé [this message]
2025-04-18 11:29 ` [PATCH v3 3/9] vnc: h264: send additional frames after the display is clean Dietmar Maurer
2025-04-19 5:26 ` Marc-André Lureau
2025-04-23 12:39 ` Daniel P. Berrangé
2025-04-18 11:29 ` [PATCH v3 4/9] h264: search for available h264 encoder Dietmar Maurer
2025-04-23 12:43 ` Daniel P. Berrangé
2025-04-24 10:30 ` Daniel P. Berrangé
2025-04-18 11:29 ` [PATCH v3 5/9] h264: new vnc option to configure h264 at server side Dietmar Maurer
2025-04-21 10:06 ` Marc-André Lureau
2025-04-23 12:47 ` Daniel P. Berrangé
2025-04-25 8:02 ` Dietmar Maurer
2025-04-18 11:29 ` [PATCH v3 6/9] h264: add hardware encoders Dietmar Maurer
2025-04-23 12:49 ` Daniel P. Berrangé
2025-04-18 11:29 ` [PATCH v3 7/9] h264: do not reduce vnc update speed while we have an active h264 stream Dietmar Maurer
2025-04-23 12:50 ` Daniel P. Berrangé
2025-04-18 11:29 ` [PATCH v3 8/9] vnc: initialize gst during argument processing Dietmar Maurer
2025-04-21 10:09 ` Marc-André Lureau
2025-04-23 12:52 ` Daniel P. Berrangé
2025-04-18 11:29 ` [PATCH v3 9/9] h264: register shutdown notifiers, stop pipeline in destroy_encoder_context Dietmar Maurer
2025-04-21 10:14 ` Marc-André Lureau
2025-04-22 6:35 ` Dietmar Maurer
2025-04-22 6:39 ` Marc-André Lureau
2025-04-22 7:03 ` Dietmar Maurer
2025-04-22 7:07 ` Marc-André Lureau
2025-04-22 7:17 ` Dietmar Maurer
2025-04-23 12:58 ` Daniel P. Berrangé
2025-04-23 12:57 ` Daniel P. Berrangé
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=aAppOBppJI0PPXnw@redhat.com \
--to=berrange@redhat.com \
--cc=dietmar@proxmox.com \
--cc=marcandre.lureau@redhat.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.