Jellyfin Forum
Hardware acceleration - workaround discovered - Printable Version

+- Jellyfin Forum (https://forum.jellyfin.org)
+-- Forum: Support (https://forum.jellyfin.org/f-support)
+--- Forum: Troubleshooting (https://forum.jellyfin.org/f-troubleshooting)
+--- Thread: Hardware acceleration - workaround discovered (/t-hardware-acceleration-workaround-discovered)



Hardware acceleration - workaround discovered - Android Marchand - 2024-08-31

It's a bit convoluted but it worked, bear with me.

First my setup: I have proxmox running on a computer with a built-in Intel Xeon e3-1200 v3 GPU, plus a separate AMD HD 3450 rv620 LE. Both are quite old but only support a handful of hw decoding. Only the Intel supports hw encoding.

Jellyfin is running as a privileged LXC

I edited the conf so that it has access to both GPUs, as such:
Code:
lxc.cgroup2.devices.allow: c 226:* rwm
lxc.mount.entry: /dev/dri/renderD128 dev/dri/renderD128 none bind,optional,create=file
lxc.mount.entry: /dev/dri/renderD129 dev/dri/renderD129 none bind,optional,create=file
lxc.mount.entry: /dev/dri/card0 dev/dri/card0 none bind,optional,create=file
lxc.mount.entry: /dev/dri/card1 dev/dri/card1 none bind,optional,create=file
lxc.cgroup2.devices.allow: c 238:* rwm 
lxc.mount.entry: /dev/kfd dev/kfd none bind,optional,create=file
lxc.apparmor.profile: unconfined

(The last 3 lines are not important)

In my setup renderD128 is the AMD and renderD129 is the Intel. I want to use the Intel as it supports decode and encode, which is what you want for transcoding.

I also let the jellyfin user part of the video, render, and kvm groups on the LXC and I opened the permissions:
Code:
usermod -aG video,render,kvm jellyfin
chmod  777 /dev/dri/renderD12[89]

Now the critical parts. Verify the GPU is seen properly on the host:
Code:
vainfo --display drm --device /dev/dri/renderD129

If it works, try it also on the LXC.
If it fails, you might have to install missing drivers. I had to run in both the host and the LXC:
Code:
apt-get install --reinstall i965-va-driver:amd64 intel-media-va-driver:amd64

ffmpeg somehow forced the use of the iHD driver rather than the i965 driver, but my card uses the i965 one so on the LXC, I went to
Code:
cd /usr/lib/jellyfin-ffmpeg/lib/dri/
ln -f i965_drv_video.so iHD_drv_video.so
(it will remove the iHD but you can make a copy first if you care)

Now I could get hw acceleration, but only from the command line (not in Jellyfin), by running this command:
Code:
ffmpeg -hwaccel vaapi -hwaccel_device /dev/dri/renderD129 -hwaccel_output_format vaapi -i input_video.mkv -c:v h264_vaapi -b:v 2M -maxrate 2M ~/test.mp4

Turns out the MOST IMPORTANT parameter was -hwaccel_device /dev/dri/renderD129. Without it, no hw acceleration. The question was then how do I make jellyfin add this parameter everytime it calls ffmpeg?

At first, I resorted to a hack: I renamed
Code:
mv /usr/lib/jellyfin-ffmpeg/ffmpeg /usr/lib/jellyfin-ffmpeg/ffmpeg.bin
and created a shell script called
Code:
nano /usr/lib/jellyfin-ffmpeg/ffmpeg
that contained the following:
Code:
#!/bin/bash
/usr/lib/jellyfin-ffmpeg/ffmpeg.bin -hwaccel_device /dev/dri/renderD129 "$@"

but this failed as jellyfin called ffmpeg for other stuff, like getting the version number and my installation of jellyfin couldn't read any more videos.

So I changed the script to do this:
Code:
#!/bin/bash

# Check if any of the arguments is "-hwaccel"
ADD_EXTRA_PARAM=false

for arg in "$@"; do
  if [ "$arg" == "-hwaccel" ]; then
    ADD_EXTRA_PARAM=true
    break
  fi
done

# If -hwaccel is found, add the extra parameter
if [ "$ADD_EXTRA_PARAM" == true ]; then
        /usr/lib/jellyfin-ffmpeg/ffmpeg.bin -hwaccel_device /dev/dri/renderD129 "$@"
else
        /usr/lib/jellyfin-ffmpeg/ffmpeg.bin "$@"
fi

Now, if I detect that we want hw acceleration, I could force the very important parameter.

After restarting Jellyfin, I launched a video that would require transcoding and it worked!
intel_gpu_top shows the GPU was used for both decoding and encoding, and my CPU had the slightest load ever.