GNOME Bugzilla – Bug 774811
vaapi: drm: cannot find render node in a hybrid graphics
Last modified: 2016-12-06 17:32:41 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.
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 ??
(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 > > ??
Created attachment 340542 [details] vaapi trace results
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?
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?
Created attachment 340622 [details] vaapi trace results with correct path
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.
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.
(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?
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?
(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.
Okay then, I'll make a patch and test it in our environment before uploading. Should be sometime next week.
Cool. Thanks! Another interesting task would be to asses the use of libgudev instead of libudev
(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.
Created attachment 341067 [details] [review] Proposed Patch Here's the patch I promised. It seems to work.
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
(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.
Created attachment 341418 [details] [review] Fixing memory leakage of patch I've added vaTerminate when vaInitialize fails and tested it.
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>
I had simplified a bit your patch. Let me know if it works for you.
(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
Attachment 341493 [details] pushed as 7aeefb0 - libs: drm: find render node in hybrid system