After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 774811 - vaapi: drm: cannot find render node in a hybrid graphics
vaapi: drm: cannot find render node in a hybrid graphics
Status: RESOLVED FIXED
Product: GStreamer
Classification: Platform
Component: gstreamer-vaapi
1.10.0
Other Linux
: Normal enhancement
: git master
Assigned To: GStreamer Maintainers
GStreamer Maintainers
Depends on:
Blocks:
 
 
Reported: 2016-11-21 20:01 UTC by Stirling Westrup
Modified: 2016-12-06 17:32 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
vaapi trace results (72.74 KB, application/gzip)
2016-11-22 17:56 UTC, Reza Razavi
  Details
vaapi trace results with correct path (76.34 KB, application/gzip)
2016-11-23 17:15 UTC, Reza Razavi
  Details
Proposed Patch (6.42 KB, patch)
2016-11-30 15:58 UTC, Stirling Westrup
needs-work Details | Review
Fixing memory leakage of patch (6.45 KB, patch)
2016-12-05 18:17 UTC, Reza Razavi
none Details | Review
libs: drm: find render node in hybrid system (1.96 KB, patch)
2016-12-06 16:39 UTC, Víctor Manuel Jáquez Leal
committed Details | Review

Description Stirling Westrup 2016-11-21 20:01:10 UTC
We are trying to use gstreamer-vaapi on a headless server to accelerate operations on a remote video display. We have configured libva 1.7.3 for headless operation (--disable-glx --disable-x11 --disable-egl --disable-wayland) and recompiled it, and it works fine:

# vainfo
libva info: VA-API version 0.39.4
libva info: va_getDriverName() returns 0
libva info: Trying to open /usr/lib64/dri/i965_drv_video.so
libva info: Found init function __vaDriverInit_0_39
libva info: va_openDriver() returns 0
vainfo: VA-API version: 0.39 (libva 1.7.3)
vainfo: Driver version: Intel i965 driver for Intel(R) Skylake - 1.7.2
vainfo: Supported profile and entrypoints
     VAProfileMPEG2Simple            :    VAEntrypointVLD
     VAProfileMPEG2Simple            :    VAEntrypointEncSlice
     VAProfileMPEG2Main              :    VAEntrypointVLD
     VAProfileMPEG2Main              :    VAEntrypointEncSlice
     VAProfileH264ConstrainedBaseline:    VAEntrypointVLD
     VAProfileH264ConstrainedBaseline:    VAEntrypointEncSlice
     VAProfileH264ConstrainedBaseline:    VAEntrypointEncSliceLP
     VAProfileH264Main               :    VAEntrypointVLD
     VAProfileH264Main               :    VAEntrypointEncSlice
     VAProfileH264Main               :    VAEntrypointEncSliceLP
     VAProfileH264High               :    VAEntrypointVLD
     VAProfileH264High               :    VAEntrypointEncSlice
     VAProfileH264High               :    VAEntrypointEncSliceLP
     VAProfileH264MultiviewHigh      :    VAEntrypointVLD
     VAProfileH264MultiviewHigh      :    VAEntrypointEncSlice
     VAProfileH264StereoHigh         :    VAEntrypointVLD
     VAProfileH264StereoHigh         :    VAEntrypointEncSlice
     VAProfileVC1Simple              :    VAEntrypointVLD
     VAProfileVC1Main                :    VAEntrypointVLD
     VAProfileVC1Advanced            :    VAEntrypointVLD
     VAProfileNone                   :    VAEntrypointVideoProc
     VAProfileJPEGBaseline           :    VAEntrypointVLD
     VAProfileJPEGBaseline           :    VAEntrypointEncPicture
     VAProfileVP8Version0_3          :    VAEntrypointVLD
     VAProfileVP8Version0_3          :    VAEntrypointEncSlice
     VAProfileHEVCMain               :    VAEntrypointVLD
     VAProfileHEVCMain               :    VAEntrypointEncSlice

However, when we try to use gstreamer-vaapi it fails to initialize libva:

$ gst-inspect-1.0 | grep vaapi
libva info: VA-API version 0.39.4
libva info: va_getDriverName() returns -1
libva error: va_getDriverName() failed with unknown libva error,driver_name=(null)
libva info: VA-API version 0.39.4
libva info: va_getDriverName() returns -1
libva error: va_getDriverName() failed with unknown libva error,driver_name=(null)

If we manually patch the function gst_vaapi_display_drm_new in gstvaapidisplay_drm.c to use a hardcoded device_path of /dev/dri/card0 then it works, but clearly this is a poor workaround and not a real fix.
Comment 1 Víctor Manuel Jáquez Leal 2016-11-22 14:05:00 UTC
Thanks for reporting this.

My guts tell me that this might a configuration problem.

When libva reports that "va_getDriverName() returns -1" it is because it could not find the drivers name. Normally, libva uses some hints to find this driver name. In the case of drm, it uses a try-and-error list[1].

1. https://cgit.freedesktop.org/libva/tree/va/drm/va_drm_utils.c#n39

Now, GstVaapiDisplayDRM only tries to open render nodes, not the render device itself. The render nodes are those called /dev/dri/renderD* [2]

2. https://dvdhrm.wordpress.com/2013/09/01/splitting-drm-and-kms-device-nodes/


The question is why libva is not finding the driver name. A workaround would be exporting the environment variable LIBVA_DRIVER_NAME set to "i915"

Could you upload the output of 

$ strace gst-inspect-1.0 /path/to/libgstvaapi.so  

??
Comment 2 Reza Razavi 2016-11-22 17:55:36 UTC
(In reply to Víctor Manuel Jáquez Leal from comment #1)
Hi I'm working with Stirling Westrup, in latest releases of VAAPI, in gst/vaapi/gstvaapi.c before loading the plugin some routings are checking for GPU capabilities and supported decoding and encoding formats, in a headless system it fails right away there and plugin gets blacklisted. I'll attach a compress file to this bug first file in it contains what you asked for when we run it for the first time and second one is when it's blacklisted.

I should mention that when I modify code in gstvaapi.c and remove those queries and force it to just register plugins also in gst-libs/gst/vaapi/gstvaapidisplay_drm.c : gst_vaapi_display_drm_new function replace path with my desired path /dev/dri/card0 vaapi will work

> Thanks for reporting this.
> 
> My guts tell me that this might a configuration problem.
> 
> When libva reports that "va_getDriverName() returns -1" it is because it
> could not find the drivers name. Normally, libva uses some hints to find
> this driver name. In the case of drm, it uses a try-and-error list[1].
> 
> 1. https://cgit.freedesktop.org/libva/tree/va/drm/va_drm_utils.c#n39
> 
> Now, GstVaapiDisplayDRM only tries to open render nodes, not the render
> device itself. The render nodes are those called /dev/dri/renderD* [2]
> 
> 2.
> https://dvdhrm.wordpress.com/2013/09/01/splitting-drm-and-kms-device-nodes/
> 
> 
> The question is why libva is not finding the driver name. A workaround would
> be exporting the environment variable LIBVA_DRIVER_NAME set to "i915"
> 
> Could you upload the output of 
> 
> $ strace gst-inspect-1.0 /path/to/libgstvaapi.so  
> 
> ??
Comment 3 Reza Razavi 2016-11-22 17:56:01 UTC
Created attachment 340542 [details]
vaapi trace results
Comment 4 Víctor Manuel Jáquez Leal 2016-11-23 16:24:13 UTC
Thanks for the trace. 

But it is not useful :(

You copy&pasted the command

> $ strace gst-inspect-1.0 /path/to/libgstvaapi.so  

But what I meant with /path/to/libgstvaapi.so was the "absolute path to libgstvaapi.so" 

Sorry I wasn't clear.

Can you get the traces and upload it again?
Comment 5 Reza Razavi 2016-11-23 17:14:46 UTC
Sorry my bad I did not pay attention and assumed that it's correct path I'll upload new files.
thank you for your help and time.

(In reply to Víctor Manuel Jáquez Leal from comment #4)
> Thanks for the trace. 
> 
> But it is not useful :(
> 
> You copy&pasted the command
> 
> > $ strace gst-inspect-1.0 /path/to/libgstvaapi.so  
> 
> But what I meant with /path/to/libgstvaapi.so was the "absolute path to
> libgstvaapi.so" 
> 
> Sorry I wasn't clear.
> 
> Can you get the traces and upload it again?
Comment 6 Reza Razavi 2016-11-23 17:15:30 UTC
Created attachment 340622 [details]
vaapi trace results with correct path
Comment 7 Víctor Manuel Jáquez Leal 2016-11-23 22:10:22 UTC
Well, here's the issue:

open("/usr/lib64/dri/i915_drv_video.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
access("/usr/lib64/dri/i915_drv_video.so", F_OK) = -1 ENOENT (No such file or directory)


There is nothing where the driver library is expected: /usr/lib64/dri/i915_drv_video.so

Or, the user doesn't have permission to open it.
Comment 8 Reza Razavi 2016-11-24 17:25:54 UTC
LibVA Intel driver is just creating i965_drv_video.so, I'm compiling it from latest git and that is available in /usr/lib64/dri
for "strace vainfo" it uses /usr/lib64/dri/i965_drv_video.so

(In reply to Víctor Manuel Jáquez Leal from comment #7)
> Well, here's the issue:
> 
> open("/usr/lib64/dri/i915_drv_video.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No
> such file or directory)
> access("/usr/lib64/dri/i915_drv_video.so", F_OK) = -1 ENOENT (No such file
> or directory)
> 
> 
> There is nothing where the driver library is expected:
> /usr/lib64/dri/i915_drv_video.so
> 
> Or, the user doesn't have permission to open it.
Comment 9 Víctor Manuel Jáquez Leal 2016-11-24 18:05:05 UTC
(In reply to Reza Razavi from comment #8)
> LibVA Intel driver is just creating i965_drv_video.so, I'm compiling it from
> latest git and that is available in /usr/lib64/dri
> for "strace vainfo" it uses /usr/lib64/dri/i965_drv_video.so

Right. My bad. Sorry. When I said this

(In reply to Víctor Manuel Jáquez Leal from comment #1)
> The question is why libva is not finding the driver name. A workaround would
> be exporting the environment variable LIBVA_DRIVER_NAME set to "i915"

I meant i965.

What happen if you export it?
What happen if you don't export that envvar?
Comment 10 Reza Razavi 2016-11-24 18:24:35 UTC
This will not make any change, maybe I should give a brief about the hardware setup, It uses Intel igpu as default graphic card and Nvidia card as a secondary one, Intel wil come up as card0 and renderD128, Nvidia card is coming as card1 and renderD129. I have just installed libva Intel drivers as we intend to use that card with VAAPI.
I found out in get_default_device_path function in gstvaapidisplay_drm.c it's just giving card1 for legacy in first try and renderD129 as RENDERNODES in second try and as it has no driver it will fail.
If the function was trying card0 or renderD128 vaapi would successfully find the driver. 

(In reply to Víctor Manuel Jáquez Leal from comment #9)
> What happen if you export it?
> What happen if you don't export that envvar?
Comment 11 Víctor Manuel Jáquez Leal 2016-11-24 18:51:07 UTC
(In reply to Reza Razavi from comment #10)
> This will not make any change, maybe I should give a brief about the
> hardware setup, It uses Intel igpu as default graphic card and Nvidia card
> as a secondary one, Intel wil come up as card0 and renderD128, Nvidia card
> is coming as card1 and renderD129. I have just installed libva Intel drivers
> as we intend to use that card with VAAPI.
> I found out in get_default_device_path function in gstvaapidisplay_drm.c
> it's just giving card1 for legacy in first try and renderD129 as RENDERNODES
> in second try and as it has no driver it will fail.
> If the function was trying card0 or renderD128 vaapi would successfully find
> the driver. 

That makes sense. We haven't tested the element in a hybrid graphics setup. And we should. Maybe a try-and-error when DRM.

If you could make a patch in that way would be awesome.
Comment 12 Stirling Westrup 2016-11-24 20:53:44 UTC
Okay then, I'll make a patch and test it in our environment before uploading. Should be sometime next week.
Comment 13 Víctor Manuel Jáquez Leal 2016-11-25 07:02:52 UTC
Cool. Thanks!

Another interesting task would be to asses the use of libgudev instead of libudev
Comment 14 Stirling Westrup 2016-11-30 15:57:38 UTC
(In reply to Víctor Manuel Jáquez Leal from comment #13)
> Cool. Thanks!
> 
> Another interesting task would be to asses the use of libgudev instead of
> libudev

Yes, that might prove useful, but its beyond the scope of this bug. That would be better created as a feature request.

Meanwhile I've created a patch that fixes the hybrid initialization problem. We now generate a list of candidates and return the first device that we can open and that has libva support.

The code works in our main test environment, but has not undergone more testing than that.
Comment 15 Stirling Westrup 2016-11-30 15:58:40 UTC
Created attachment 341067 [details] [review]
Proposed Patch

Here's the patch I promised. It seems to work.
Comment 16 Víctor Manuel Jáquez Leal 2016-11-30 16:32:48 UTC
Review of attachment 341067 [details] [review]:

Thanks a lot!

Just a couple comments :)

::: gst-libs/gst/vaapi/gstvaapidisplay_drm.c
@@ +73,3 @@
+ */
+static gchar **
+vstrdupv (gchar *** paos, ...)

what about using GArray? It looks to me like the natural way to handle this.

@@ +298,3 @@
+        if (vaInitialize (va_dpy, &major_version,
+                &minor_version) == VA_STATUS_SUCCESS) {
+          vaTerminate (va_dpy);

here looks to me a memory leak, since the va_dpy is not vaTerminate if vaInitialize fails, but still there's a context allocated
Comment 17 Stirling Westrup 2016-12-01 06:44:38 UTC
(In reply to Víctor Manuel Jáquez Leal from comment #16)
> Review of attachment 341067 [details] [review] [review]:
> 
> Thanks a lot!
> 
> Just a couple comments :)
> 
> ::: gst-libs/gst/vaapi/gstvaapidisplay_drm.c
> @@ +73,3 @@
> + */
> +static gchar **
> +vstrdupv (gchar *** paos, ...)
> 
> what about using GArray? It looks to me like the natural way to handle this.

Sure, that would work. I just wanted to make the smallest possible patch to minimize the chance of breaking something, and this seemed smaller.
> 
> @@ +298,3 @@
> +        if (vaInitialize (va_dpy, &major_version,
> +                &minor_version) == VA_STATUS_SUCCESS) {
> +          vaTerminate (va_dpy);
> 
> here looks to me a memory leak, since the va_dpy is not vaTerminate if
> vaInitialize fails, but still there's a context allocated

Could be. A colleague gave me those lines, since I know libudev and glib, but not libva.
Comment 18 Reza Razavi 2016-12-05 18:17:23 UTC
Created attachment 341418 [details] [review]
Fixing memory leakage of patch

I've added vaTerminate when vaInitialize fails and tested it.
Comment 19 Víctor Manuel Jáquez Leal 2016-12-06 16:39:28 UTC
Created attachment 341493 [details] [review]
libs: drm: find render node in hybrid system

Originally the drm backend only tried to open the first render node
found. But in hybrid system this first render node might not support
VA-API (propietary Nvidia driver, for example).

This patch tries all the available nodes until a finding one with a
VA-API supported driver.

https://bugzilla.gnome.org/show_bug.cgi?id=774811

Original-patch-by: Stirling Westrup <swestrup@gmail.com> and
                   Reza Razavi <reza@userful.com>
Comment 20 Víctor Manuel Jáquez Leal 2016-12-06 16:40:16 UTC
I had simplified a bit your patch. Let me know if it works for you.
Comment 21 Reza Razavi 2016-12-06 17:21:44 UTC
(In reply to Víctor Manuel Jáquez Leal from comment #20)
> I had simplified a bit your patch. Let me know if it works for you.

I've tested new patch and it's working.
thanks
Comment 22 Víctor Manuel Jáquez Leal 2016-12-06 17:32:36 UTC
Attachment 341493 [details] pushed as 7aeefb0 - libs: drm: find render node in hybrid system