Vdpau support in snaps on nvidia

Snapping a media playback application I notice a crash when running in nvidia based machines looking for libvdpau_nvidia.so. This file is in a different place to all the other so files for other vdpau implementations. Typically the vdpau drivers for most platforms live in /usr/lib/<triplet>/vdpau, however the nVidia binary driver puts their vapdu driver in /usr/lib/<driver-version>/vdpau which doesn’t seem to be exposed to the snap.

One implementation (kodi) went down the path of extracting the driver from the nvidia- package and shipping it in the snap. This seems flawed as it’ll likely break on driver updates on the host. Debian has nvidia-vdpau-driver which appears to ship the driver in the right place, but we don’t have such a package in Ubuntu 16.04.

Is there some magic voodoo we can do in snapd to expose the vdpau driver on the host to the snap as we do for the other GPU related drivers? Should we have a vdpau interface? What’s the best way forward here?

1 Like

With my most recent changes to snapd we can be sure that vdpau drivers will only exist in one of two places from the host:

/var/lib/snapd/lib/gl/vdpau (Multiarch)
/var/lib/snapd/lib/gl (biarch)

This is configurable in the environment by setting VDPAU_DRIVER_PATH=/usr/lib/vdpau:/var/lib/snapd/lib/gl/vdpau:/var/lib/snapd/lib/gl

Ref: https://github.com/solus-project/linux-steam-integration/blob/master/src/shim/shim.c#L221

I haven’t tested extensively with Ubuntu but this might require apparmor confinement policies to have a new one-liner added, and given the fact that the vdpau drivers exist in the root of the libdir on multiarch, should probably be just added to the opengl interface to ensure biarch/multiarch are at parity (otherwise stuff would work on other distros without other work but not Ubuntu)

1 Like

Thanks. Seems vlc (the app in question) ignores VDPAU_DRIVER_PATH. I set it in the environment for the application launcher, but it still looks everywhere but where I specified…

  vlc:
    environment:
      VDPAU_DRIVER_PATH: "/var/lib/snapd/lib/gl:/var/lib/snapd/lib/gl/vdpau"
    desktop: usr/share/applications/vlc.desktop
    command: bin/vlc-snap-wrapper.sh
    plugs:
      - unity7
      - network
      - network-bind
      - home
      - opengl
      - pulseaudio
      - mount-observe
      - optical-drive
      - camera
      - removable-media
      - screen-inhibit-control
      - x11

It looks in all the wrong places… (snippet from strace)

$ grep libvdpau vlc.trace
27137 getdents(4, [{d_ino=7523, d_off=1, d_reclen=24, d_name=".", d_type=DT_DIR}, {d_ino=7211, d_off=3, d_reclen=24, d_name="..", d_type=DT_DIR}, {d_ino=7524, d_off=48, d_reclen=48, d_name="libvdpau_adjust_plugin.so", d_type=DT_REG}, {d_ino=7525, d_off=82, d_reclen=48, d_name="libvdpau_avcodec_plugin.so", d_type=DT_REG}, {d_ino=7526, d_off=115, d_reclen=48, d_name="libvdpau_chroma_plugin.so", d_type=DT_REG}, {d_ino=7527, d_off=153, d_reclen=56, d_name="libvdpau_deinterlace_plugin.so", d_type=DT_REG}, {d_ino=7528, d_off=187, d_reclen=48, d_name="libvdpau_display_plugin.so", d_type=DT_REG}, {d_ino=7529, d_off=221, d_reclen=48, d_name="libvdpau_sharpen_plugin.so", d_type=DT_REG}], 32768) = 344
27137 stat("/snap/vlc/x2/usr/lib/vlc/plugins/vdpau/libvdpau_adjust_plugin.so", {st_dev=makedev(7, 38), st_ino=7524, st_mode=S_IFREG|0755, st_nlink=1, st_uid=0, st_gid=0, st_blksize=1024, st_blocks=27, st_size=13712, st_atime=2017/11/22-22:11:18, st_mtime=2017/11/22-22:11:18, st_ctime=2017/11/22-22:11:18}) = 0
27137 stat("/snap/vlc/x2/usr/lib/vlc/plugins/vdpau/libvdpau_avcodec_plugin.so", {st_dev=makedev(7, 38), st_ino=7525, st_mode=S_IFREG|0755, st_nlink=1, st_uid=0, st_gid=0, st_blksize=1024, st_blocks=36, st_size=18048, st_atime=2017/11/22-22:11:19, st_mtime=2017/11/22-22:11:19, st_ctime=2017/11/22-22:11:19}) = 0
27137 stat("/snap/vlc/x2/usr/lib/vlc/plugins/vdpau/libvdpau_chroma_plugin.so", {st_dev=makedev(7, 38), st_ino=7526, st_mode=S_IFREG|0755, st_nlink=1, st_uid=0, st_gid=0, st_blksize=1024, st_blocks=54, st_size=27192, st_atime=2017/11/22-22:11:18, st_mtime=2017/11/22-22:11:18, st_ctime=2017/11/22-22:11:18}) = 0
27137 stat("/snap/vlc/x2/usr/lib/vlc/plugins/vdpau/libvdpau_deinterlace_plugin.so", {st_dev=makedev(7, 38), st_ino=7527, st_mode=S_IFREG|0755, st_nlink=1, st_uid=0, st_gid=0, st_blksize=1024, st_blocks=26, st_size=13296, st_atime=2017/11/22-22:11:17, st_mtime=2017/11/22-22:11:17, st_ctime=2017/11/22-22:11:17}) = 0
27137 stat("/snap/vlc/x2/usr/lib/vlc/plugins/vdpau/libvdpau_display_plugin.so", {st_dev=makedev(7, 38), st_ino=7528, st_mode=S_IFREG|0755, st_nlink=1, st_uid=0, st_gid=0, st_blksize=1024, st_blocks=56, st_size=28384, st_atime=2017/11/22-22:11:18, st_mtime=2017/11/22-22:11:18, st_ctime=2017/11/22-22:11:18}) = 0
27137 stat("/snap/vlc/x2/usr/lib/vlc/plugins/vdpau/libvdpau_sharpen_plugin.so", {st_dev=makedev(7, 38), st_ino=7529, st_mode=S_IFREG|0755, st_nlink=1, st_uid=0, st_gid=0, st_blksize=1024, st_blocks=27, st_size=13736, st_atime=2017/11/22-22:11:18, st_mtime=2017/11/22-22:11:18, st_ctime=2017/11/22-22:11:18}) = 0
27284 open("/var/lib/snapd/lib/gl/tls/libvdpau.so.1", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
27284 open("/var/lib/snapd/lib/gl/libvdpau.so.1", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
27284 open("/var/lib/snapd/void/libvdpau.so.1", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
27284 open("/snap/vlc/x2/lib/x86_64-linux-gnu/libvdpau.so.1", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
27284 open("/snap/vlc/x2/usr/lib/libvdpau.so.1", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
27284 open("/snap/vlc/x2/usr/lib/vlc/libvdpau.so.1", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
27284 open("/snap/vlc/x2/usr/lib/x86_64-linux-gnu/libvdpau.so.1", O_RDONLY|O_CLOEXEC) = 14
27288 open("/snap/vlc/x2/usr/lib/vlc/plugins/vdpau/libvdpau_chroma_plugin.so", O_RDONLY|O_CLOEXEC) = 14
27298 open("/snap/vlc/x2/usr/lib/x86_64-linux-gnu/libvdpau.so.1.0.0", O_RDONLY <unfinished ...>
27298 open("/snap/vlc/x2/usr/lib/vlc/plugins/vdpau/libvdpau_chroma_plugin.so", O_RDONLY) = 15
27298 open("/var/lib/snapd/lib/gl:/var/lib/snapd/lib/gl/vdpau/libvdpau_nvidia.so.1", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
27298 open("/snap/vlc/x2/usr/lib/x86_64-linux-gnu/vdpau/libvdpau_nvidia.so.1", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
27298 open("/usr/lib/x86_64-linux-gnu/vdpau/libvdpau_nvidia.so.1", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
27298 open("/usr/lib/vdpau/libvdpau_nvidia.so.1", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
27298 open("/var/lib/snapd/lib/gl/tls/libvdpau_nvidia.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
27298 open("/var/lib/snapd/lib/gl/libvdpau_nvidia.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
27298 open("/var/lib/snapd/void/libvdpau_nvidia.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
27298 open("/snap/vlc/x2/lib/x86_64-linux-gnu/libvdpau_nvidia.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
27298 open("/snap/vlc/x2/usr/lib/libvdpau_nvidia.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
27298 open("/snap/vlc/x2/usr/lib/vlc/libvdpau_nvidia.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
27298 open("/snap/vlc/x2/usr/lib/x86_64-linux-gnu/libvdpau_nvidia.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
27298 open("/snap/vlc/x2/usr/lib/x86_64-linux-gnu/mesa/libvdpau_nvidia.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
27298 open("/snap/vlc/x2/usr/lib/x86_64-linux-gnu/mesa-egl/libvdpau_nvidia.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
27298 open("/snap/vlc/x2/usr/lib/x86_64-linux-gnu/pulseaudio/libvdpau_nvidia.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
27298 open("/snap/vlc/x2/usr/lib/x86_64-linux-gnu/samba/libvdpau_nvidia.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
27298 open("tls/x86_64/libvdpau_nvidia.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
27298 open("tls/libvdpau_nvidia.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
27298 open("x86_64/libvdpau_nvidia.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
27298 open("libvdpau_nvidia.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
27298 open("/snap/vlc/x2/lib/libvdpau_nvidia.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
27298 open("/snap/vlc/x2/usr/lib/x86_64-linux-gnu/dri/libvdpau_nvidia.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
27298 open("/usr/lib/libvdpau_nvidia.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
27298 open("/lib/x86_64-linux-gnu/libvdpau_nvidia.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
27298 open("/usr/lib/x86_64-linux-gnu/libvdpau_nvidia.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
27298 open("/lib/libvdpau_nvidia.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
27298 open("/usr/lib/libvdpau_nvidia.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)

27298 open("/var/lib/snapd/lib/gl:/var/lib/snapd/lib/gl/vdpau/libvdpau_nvidia.so.1", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)

Ah. OK so it’s not going to handle tokenized paths. For now just set to /var/lib/snapd/lib/gl/vdpau and allow LD_LIBRARY_PATH to handle the dlopen for biarch (non-ubuntu) cases

2 Likes

Interesting! Thanks for spotting that. That made progress. It no longer errors looking for the vdpau driver in nVidia, but still crashes anyway.

So now it runs on Intel (17.10), but can’t find va-api drivers - specifically /usr/lib/x86_64-linux-gnu/dri/i965_drv_video.so, but plays videos anyway, I assume un-accelerated. On nVidia (16.04) it segfaults.

http://paste.ubuntu.com/26026642/

There are two apparmor failures (one for screensaver inhibit (in progress to be fixed) and one for reading /etc/vdpau_wrapper.cfg) but launching in devmode passes these and still crashes as above. Any suggestions most welcome! :slight_smile:

I’d try to install vdpau-va-driver and i965-va-driver via stage-packages (shipping i965_drv_video.so for intel and vdpau_drv_video.so for nvidia in the snap)

Ok, some progress. Adding those packages, helped @ogra, thanks.

However, it’s now annoyingly only able to look in one place at a time for VDPAU drivers. So either I specify VDPAU_DRIVER_PATH: "/var/lib/snapd/lib/gl/vdpau" and it works on nVidia, or I don’t specify it and it works on Intel, but not vice versa.

I guess I could maybe add a check in the launcher to dynamically set the environment variable on each launch. Not sure I can even detect what GPU you have from inside the snap?

add mesa-utils too … then use something like:

if glxinfo | grep "OpenGL vendor" | grep -q NVIDIA; then
  echo "NVIDIA"
else
  echo "not NVIDIA"
fi

the OpenGL interface should provide enough access for running glxinfo

1 Like

That worked a treat for nVidia and Intel. Just getting a friend to try AMD now too. Currently it looks like this.

case "$SNAP_ARCH" in
	"amd64") ARCH='x86_64-linux-gnu'
	;;
	"i386") ARCH='i386-linux-gnu'
	;;
	*)
		echo "Unsupported architecture for this app build"
		exit 1
	;;
esac

export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$SNAP/usr/lib/vlc"
if glxinfo | grep "OpenGL vendor" | grep -q NVIDIA; then
  export VDPAU_DRIVER_PATH="/var/lib/snapd/lib/gl/vdpau"
else
  export LIBVA_DRIVERS_PATH="$SNAP/usr/lib/$ARCH/dri"
fi

1 Like

Simpler solution - we’ll only mount /var/lib/snapd/lib/gl under “proper” snaps, if it exists, you’re using NVIDIA. Then rest of the check is “am I classic”. Vendoring would mean just setting to the vendored libdir, classic would mean not setting at all. Then you wouldn’t need to execute glxinfo

Years after, running into these issue too. VLC via Snap wont use HW-Acceleration on AMD. Without Snap it works as intended.

/usr/share/libdrm/amdgpu.ids: No such file or directory libva info: Trying to open /snap/vlc/x1/usr/lib/x86_64-linux-gnu/dri/radeonsi_drv_video.so Failed to open VDPAU backend libvdpau_radeonsi.so: cannot open shared object file: No such file or directory amdgpu: os_same_file_description couldn’t determine if two DRM fds reference the same file description.

Any Help here?