diff mbox

[FFmpeg-devel] Add wayland support for VAAPI

Message ID 1498545523-5725-1-git-send-email-contact@hardening-consulting.com
State New
Headers show

Commit Message

David Fort June 27, 2017, 6:38 a.m. UTC
Wayland environment became quite popular with gnome 3. This patch adds the ability to
initialize the VAAPI accelerator from a wayland display.

Signed-off-by: David Fort <contact@hardening-consulting.com>
---
 configure                   |  4 ++++
 libavutil/hwcontext_vaapi.c | 33 +++++++++++++++++++++++++++++++++
 2 files changed, 37 insertions(+)

Comments

Mark Thompson June 27, 2017, 7:54 a.m. UTC | #1
On 27/06/17 07:38, David Fort wrote:
> Wayland environment became quite popular with gnome 3. This patch adds the ability to
> initialize the VAAPI accelerator from a wayland display.

Is there some specific use-case which needs this?  The X11 support mainly exists because of old systems (*cough* Intel Media SDK *cough*) which don't support render nodes, and therefore have to connect to a DRM master device - if X11 is running then it has to use the DRI2 authentication ritual to do that.

Anything recent should be connecting via the render node, which allows it to be used independently of any other system and has clear control over what hardware you are using on systems with multiple possibilities.

Thanks,

- Mark
David Fort June 27, 2017, 12:13 p.m. UTC | #2
Le 27/06/2017 à 09:54, Mark Thompson a écrit :
> On 27/06/17 07:38, David Fort wrote:
>> Wayland environment became quite popular with gnome 3. This patch adds the ability to
>> initialize the VAAPI accelerator from a wayland display.
> 
> Is there some specific use-case which needs this?  The X11 support mainly exists because of old systems (*cough* Intel Media SDK *cough*) which don't support render nodes, and therefore have to connect to a DRM master device - if X11 is running then it has to use the DRI2 authentication ritual to do that.
> 
> Anything recent should be connecting via the render node, which allows it to be used independently of any other system and has clear control over what hardware you are using on systems with multiple possibilities.
> 

Hi,

my final goal is to have a h264 video rendered directly in a surface
(using ffmpeg as a library). If render nodes surfaces can be displayed
on the screen then I'm fine with it and forget about that patch.

I did some tests and I had the impression that when the rendering was
done with a DRI render node, it was slower than when the VADisplay was
grabbeb from wayland (F25 with gnome3). But it may be just an impression
or a test bias.

Best regards.
Mark Thompson June 27, 2017, 4:08 p.m. UTC | #3
On 27/06/17 13:13, Hardening wrote:
> Le 27/06/2017 à 09:54, Mark Thompson a écrit :
>> On 27/06/17 07:38, David Fort wrote:
>>> Wayland environment became quite popular with gnome 3. This patch adds the ability to
>>> initialize the VAAPI accelerator from a wayland display.
>>
>> Is there some specific use-case which needs this?  The X11 support mainly exists because of old systems (*cough* Intel Media SDK *cough*) which don't support render nodes, and therefore have to connect to a DRM master device - if X11 is running then it has to use the DRI2 authentication ritual to do that.
>>
>> Anything recent should be connecting via the render node, which allows it to be used independently of any other system and has clear control over what hardware you are using on systems with multiple possibilities.
>>
> 
> Hi,
> 
> my final goal is to have a h264 video rendered directly in a surface
> (using ffmpeg as a library).

Note that the hardware decoders are not in general able to render to a surface which can go directly to scanout.  You'll always want some intermediate here - typically this is done with OpenGL (see video players, e.g. mpv), though you can also do it inside VAAPI by using the VPP mechanism.

With ffmpeg + Wayland only, it should be doable by using the decoder along with the scale_vaapi filter (really doing format conversion, though as the name suggests it can scale as well) - allow the decoder to allocate its frames internally, but supply your own VAAPI surfaces as the output of the filter made from the Wayland surfaces using DRM PRIME sharing.

>                              If render nodes surfaces can be displayed
> on the screen then I'm fine with it and forget about that patch.

Yes - surfaces are not distinguished by the context they come from, only by the actual underlying hardware device they exist on and what format they are.

> I did some tests and I had the impression that when the rendering was
> done with a DRI render node, it was slower than when the VADisplay was
> grabbeb from wayland (F25 with gnome3). But it may be just an impression
> or a test bias.

That should be identical.  The mechanism used by Wayland (and X11 DRI2) is to ask the server which DRM device node it should open, receiving a string path and a cookie it return.  It opens the node and authenticates with the cookie if necessary (i.e. if anything more than rendering is required, which it isn't for codec stuff).  (X11 DRI3 is different - that actually gives you a file descriptor to the DRM device directly.)

I'm not really against the patch, but it adds a new Wayland dependency to libavutil which is probably undesirable in general.

Thanks,

- Mark
wm4 June 28, 2017, 10:05 a.m. UTC | #4
On Tue, 27 Jun 2017 14:13:56 +0200
Hardening <rdp.effort@gmail.com> wrote:

> Le 27/06/2017 à 09:54, Mark Thompson a écrit :
> > On 27/06/17 07:38, David Fort wrote:  
> >> Wayland environment became quite popular with gnome 3. This patch adds the ability to
> >> initialize the VAAPI accelerator from a wayland display.  
> > 
> > Is there some specific use-case which needs this?  The X11 support mainly exists because of old systems (*cough* Intel Media SDK *cough*) which don't support render nodes, and therefore have to connect to a DRM master device - if X11 is running then it has to use the DRI2 authentication ritual to do that.
> > 
> > Anything recent should be connecting via the render node, which allows it to be used independently of any other system and has clear control over what hardware you are using on systems with multiple possibilities.
> >   
> 
> Hi,
> 
> my final goal is to have a h264 video rendered directly in a surface
> (using ffmpeg as a library). If render nodes surfaces can be displayed
> on the screen then I'm fine with it and forget about that patch.
> 
> I did some tests and I had the impression that when the rendering was
> done with a DRI render node, it was slower than when the VADisplay was
> grabbeb from wayland (F25 with gnome3). But it may be just an impression
> or a test bias.
> 
> Best regards.
> 

Although the hw context could create the VADisplay for you, you most
likely want to create it yourself based on your own wayland connection.
That would probably easier and more robust, because it couldn't
"accidentally" create a X or DRM VADisplay. (You can create a
AVHWDeviceContext based on an existing VADisplay.)
diff mbox

Patch

diff --git a/configure b/configure
index 6ca919b..b2e8b1c 100755
--- a/configure
+++ b/configure
@@ -2072,6 +2072,7 @@  HAVE_LIST="
     threads
     vaapi_drm
     vaapi_x11
+    vaapi_wayland
     vdpau_x11
     winrt
 "
@@ -6132,6 +6133,9 @@  enabled vaapi &&
     disable vaapi
 
 enabled vaapi &&
+    check_lib vaapi_wayland "va/va.h va/va_wayland.h" vaGetDisplayWl -lva -lva-wayland -lwayland-client
+
+enabled vaapi &&
     check_lib vaapi_drm "va/va.h va/va_drm.h" vaGetDisplayDRM -lva -lva-drm
 
 enabled vaapi &&
diff --git a/libavutil/hwcontext_vaapi.c b/libavutil/hwcontext_vaapi.c
index 3970726..5fb607f 100644
--- a/libavutil/hwcontext_vaapi.c
+++ b/libavutil/hwcontext_vaapi.c
@@ -24,6 +24,9 @@ 
 #if HAVE_VAAPI_DRM
 #   include <va/va_drm.h>
 #endif
+#if HAVE_VAAPI_WAYLAND
+#   include <va/va_wayland.h>
+#endif
 
 #include <fcntl.h>
 #if HAVE_UNISTD_H
@@ -47,6 +50,9 @@  typedef struct VAAPIDevicePriv {
 #endif
 
     int drm_fd;
+#if HAVE_VAAPI_WAYLAND
+    struct wl_display *wl_display;
+#endif
 } VAAPIDevicePriv;
 
 typedef struct VAAPISurfaceFormat {
@@ -905,6 +911,10 @@  static void vaapi_device_free(AVHWDeviceContext *ctx)
     if (hwctx->display)
         vaTerminate(hwctx->display);
 
+#if HAVE_VAAPI_WAYLAND
+    if (priv->wl_display)
+        wl_display_disconnect(priv->wl_display);
+#endif
 #if HAVE_VAAPI_X11
     if (priv->x11_display)
         XCloseDisplay(priv->x11_display);
@@ -934,6 +944,29 @@  static int vaapi_device_create(AVHWDeviceContext *ctx, const char *device,
     ctx->user_opaque = priv;
     ctx->free        = vaapi_device_free;
 
+#if HAVE_VAAPI_WAYLAND
+    // Try to open the device as a wayland display.
+    if (!display && !(device && device[0] == '/')) {
+		priv->wl_display = wl_display_connect(device);
+		if (!priv->wl_display) {
+			av_log(ctx, AV_LOG_VERBOSE, "Cannot open wayland display "
+							   "%s.\n", device);
+		} else {
+			wl_display_roundtrip (priv->wl_display);
+
+			display = vaGetDisplayWl(priv->wl_display);
+			if (!display) {
+				av_log(ctx, AV_LOG_ERROR, "Cannot open a VA display "
+					   "from wayland display %s.\n", device);
+				return AVERROR_UNKNOWN;
+			}
+
+			av_log(ctx, AV_LOG_VERBOSE, "Opened VA display via "
+				   "wayland display %s.\n", device);
+		}
+	}
+#endif
+
 #if HAVE_VAAPI_X11
     if (!display && !(device && device[0] == '/')) {
         // Try to open the device as an X11 display.