Video acceleration in Jellyfin inside a Proxmox container
Sun 01 October 2023 — download

For various reasons, including "video decoding is hard", "your web browser hates you" and "watching movies on a phone over 3G is a basic human necessity", enabling hardware-accelerated video decoding in Jellyfin is a desirable goal if you don't want your CPU to set your house on fire.

To attain it, one can mess around cryptic gid mappings, but granting every user on the hypervisor the right to read/write /dev/dri/renderD128 and /dev/dri/card0 is way easier, and it looks like this:

# cat > /etc/udev/rules.d/99-intel-chmod666.rules << 'EOF'
KERNEL=="renderD128", MODE="0666"
KERNEL=="card0", MODE="0666"
EOF
# udevadm control --reload-rules && udevadm trigger
#

It doesn't really worsen security, since: - the devices are only mounted inside my jellyfin container, which would have the same privileges as if I used gid mapping. - odds are that an attacker able to get a shell on the hypervisor wouldn't really need to have r/w access to the two devices to escalate their privileges anyway, since they would either be: - root already to escape from a container - root already to escape from a vm - whatever proxmox user and likely able to escalate to root trivially - other users are sandboxed via systemd and/or seccomp.

Speaking of mounting things inside the container:

# cat > /etc/pve/lxc/114.conf << 'EOF'
lxc.cgroup2.devices.allow: c 226:0 rwm
lxc.cgroup2.devices.allow: c 226:128 rwm
lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir
lxc.mount.entry: /dev/dri/renderD128 dev/renderD128 none bind,optional,create=file
EOF
#

You can now run vainfo inside the container and be delighted by the presence of the VA-API version number:

# vainfo 2>/dev/null | head -n 1
libva info: VA-API version 1.17.0
#

The last step is to tick all the boxes in Jellyfin's preferences and you're good to go. Don't forget to make some space on the disk for the transcoding cache, at least until this makes its way into a release.