Open frusanov opened 2 years ago
It should work as long as: the kernel supports it (either directly or via modules), ffmpeg is compiled to support it, and the jail is able to expose the hardware correctly.
Unfortunately, I don't have any hardware to test support. My FreeBSD servers don't have any commodity hardware in them and NVIDIA Tesla-series cards are poorly supported by NVIDIA under FreeBSD.
What device would need to be passed on TrueNAS to get an AMD CPU with an iGPU to do hardware acceleration?
drm-kmod
or drm-510-kmod
should work. the jail will need dri*
and drm*
exposed
There's no dri*
and drm*
devices in /dev
on TrueNAS.
does lspci
list it? If yes, make sure the kernel module is loaded correctly.
Yes, I see the device. How do you load kernel modules on TrueNAS? There's no modprobe
like on Linux.
kldstat
for listing
kldload
to load
kldunload
for unloading
https://www.freebsd.org/cgi/man.cgi?query=kld&sektion=4
Those modules don't exist on TrueNAS.
oh yeah TrueNAS. It might have drm
and something like amdgpu
. If not, you have a much harder task of adding it back in every time TrueNAS restarts and every time you update it.
Have a look at https://github.com/kern2011/Freenas-Quicksync. The instructions are for Plex on FreeNAS 11.3, but the driver loading and devfs ruleset creation should be the same.
You will probably also need to install the VAAPI packages for your GPU inside the jail.
Ok, I have drm.ko
and I loaded it. I have a lot of AMD GPU modules for my CPU.
Which modules will I need to load? I loaded them all by hand and I have a lot of devices in /dev/drm
(257 in total).
@michaelburton That guide is a bit out of date for TrueNAS Core 13.0-U3.1. I've spend the past 30 minutes trying to get /dev/drm
to show up and it never doesn.
The instructions assume an Intel GPU. I don't have an AMD GPU to test with, and have no idea if it's possible at all.
I think I got it, I was able to get /dev/drm
to show up in the jail. I get about 41 FPS with trancoding "2001: A Space Odyssey".
In the ffmpeg log, I see this
Stream mapping:
Stream #0:0 -> #0:0 (hevc (native) -> h264 (libx264))
Stream #0:1 -> #0:1 (dts (dca) -> aac (native))
These are my settings for transcoding.
The log for ffmpeg
should have something about hwaccel type
(e.g., Using cuda hwaccel type dxva2 with new default device
)
I don't see that in the logs, also ffmpeg -hwaccels
shows only 3 options: vdpau
, vaapi
, and drm
.
There should be a noticeable difference (e.g., time to encode or CPU usage when de/encoding) between using and not using hwaccel
emby has a nice hw detection tool that you can try: https://mediabrowser.github.io/embytools/ffdetect-2022_05_07-x64_freebsd13.tar.xz It is however designed for FreeBSD and not FreeNAS/TrueNAS
It won't be DXVA because that's Windows-specific.
You'll probably have to install the libva-vdpau-driver
package inside your jail and use the libva acceleration option in your Jellyfin settings. Again, I don't have an AMD GPU so I have no idea if this will work.
It won't be DXVA because that's Windows-specific.
Yeah that was a bad example. I only have a GPU that can hwaccel in a Windows box right now and checked the output there >.< It should show something about it using hwaccel though
I can confirm that hardware encoding is working on Intel Gpu so it should work with Amd with the va drivers. Here's what I needed to do to make it work.
First in the JellyFin jail install theses packages :
pkg install libva-utils
pkg install libva-vdpau-driver
pkg install libva-intel-media-driver
Then on the host (ouside the jail) create a script file with this content :
#!/bin/sh
echo '[devfsrules_bpfjail=101]
add path 'bpf*' unhide
[plex_drm=10]
add include $devfsrules_hide_all
add include $devfsrules_unhide_basic
add include $devfsrules_unhide_login
add include $devfsrules_jail
add include $devfsrules_bpfjail
add path 'dri*' unhide
add path 'dri/*' unhide
add path 'drm*' unhide
add path 'drm/*' unhide' >> /etc/devfs.rules
service devfs restart
# Uncomment the correct line for intel vs amd drivers
#kldload /boot/modules/i915kms.ko # Intel
kldload /boot/modules/radeonkms.ko # Amd
It could be placed in the root user like /root/enable_hardware_encode_script.sh Then make it executable : chmod +x /root/enable_hardware_encode_script.sh and run the script : /root/enable_hardware_encode_script.sh
Now stop the jail and edit it. In the Jail Properties change the devfs_ruleset to 10 save then start the jail. Open the jail shell and make sure that vainfo returns at least : VAProfileH264Main : VAEntrypointEncSlice
Now hardware encoding with libva should work. But JellyFin will probably crash with an error about a non initialised gpu. I had to add a little script.
Here's the script to fix ffmpeg I'm not a python expert so I took inspiration from rffmpeg to make it work. The script will need to be added in the JellyFin jail at /usr/local/bin/lffmpeg.
#!/usr/bin/env python3.9
import subprocess
import sys
from subprocess import run, PIPE
#Fix missing ffmpeg init error on BSD Jellyfin
def add_missing_params(args):
args.insert(0, 'vaapi')
args.insert(0, '-hwaccel')
args.insert(0, 'ffmpeg')
def run_ffmpeg(args):
add_missing_params(args)
print("args: ", args)
subprocess.run(args)
# Entrypoint
all_args = sys.argv
cmd_name = all_args[0]
ffmpeg_args = all_args[1:]
run_ffmpeg(ffmpeg_args)
Once the script is created and made executable with chmod +x /usr/local/bin/lffmpeg, you'll have to tell JellyFin to use this one for transcoding in the Server-->Playback-->"FFmpeg path" option.
If everything work you can now add the "/root/enable_hardware_encode_script.sh" script PostInit script in the TrueNas Core UI in Tasks --> Init / Shutdown.
Big thanks to @Thefrank for the BSD package.
@spz2k9 thats a pretty cool solution! Would you be willing to make a PR here with that information?
Yes, I can check tomorrow for a PR. I'll only include Intel for now since Amd gpu hasn't been confirmed yet.
You can do the same thing as that Python script using the shell:
#!/bin/sh
ffmpeg -hwaccel vaapi "$@"
Unfortunately my Ivy Bridge CPU is too old for libva-intel-media-driver
, and I get an immediate kernel panic when trying to encode using libva-intel-driver
instead, so I can't provide any further feedback.
You can do the same thing as that Python script using the shell:
#!/bin/sh ffmpeg -hwaccel vaapi "$@"
Unfortunately my Ivy Bridge CPU is too old for
vaapi-intel-media-driver
, and I get an immediate kernel panic when trying to encode usinglibva-intel-driver
instead, so I can't provide any further feedback.
I don't know... my 4th gen intel isn't all that new and it will do h264 encoding. If I check ffmpeg page here. It states that Ivy Bridge has h264 encoding.
One thing I didn't note in the pull request... and it's hard to know if everything is really required... but maybe you could try changing thoses settings in the BIOS :
I also had kernel panic with TrueNas Core before doing thoses changes.... but It was working fine with a Windows 10 VM running on TrueNas Core... so I was sure there was a way to make it work... took a lot of time to find all the settings. Now I'm using a cheap Dummy HDMI on my integrated gpu... might not be needed but it works and it's like 8$.
https://en.wikipedia.org/wiki/Intel_Core
need to have a 4th gen I-series* or newer Intel CPU AFAIK edit typo
This is far more of a mess than I thought: https://github.com/intel/media-driver#decodingencoding-features
* Then... plug a monitor in the HDMI.
Looks like that made the difference for me, and I'll be adding a dummy HDMI plug to my shopping list. Thanks.
The user that Jellyfin runs as also needs to be a member of the video
group so that it has access to the contents of /dev/drm
.
There are two different Intel VAAPI driver packages available, libva-intel-media-driver
works with Broadwell (5th gen Core) and newer iGPUs, libva-intel-driver
works with older iGPUs including Sandy/Ivy Bridge and Haswell.
I've also been digging into the Jellyfin source to figure out why -init_hw_device
and -hwaccel
weren't being included in the ffmpeg arguments in the first place. The problem is that they check OperatingSystem.IsLinux()
as part of some of the VAAPI-related setup, e.g. in MediaBrowser.MediaEncoding.Encoder.MediaEncoder.SetFFmpegPath
, MediaBrowser.MediaEncoding.Encoder.EncoderValidator.CheckVaapiDeviceByDriver
, MediaBrowser.Controller.MediaEncoding.EncodingHelper.GetHwaccelType
among others.
I could potentially write a pull request to add a bunch of || OperatingSystem.IsFreeBSD()
where necessary, but I don't know whether the upstream project would accept them given that FreeBSD isn't officially supported.
Yes the information is hard to gather but it seems more like a 3rd gen and up... but driver compatibility might difer from Windows / linux / bsd.
I think I'll do another pull request to add the info at the end in the Troubleshooting section.
@michaelburton its worth a shot to open a PR with Jellyfin, but to be completely straightforward, it is unlikely to get merged as they do not officially support it. I would not mind being wrong :) Worst case is that you can just make a patch out of it and put it on this repo for GPL compliance.
I can also generate test builds manually.
The ffmpeg version they rely on is 5.0+(you can check on their official docker url), BSD seems to be 4.4.3. I know there's been a lot for cmd line change with 5.0... most script got broken on windows... so I think they'll probably just say it's an old version and not supported.
The user that Jellyfin runs as also needs to be a member of the
video
group so that it has access to the contents of/dev/drm
.
Yes... you're right, I think I forgot to include it in the documentation.
I've also been digging into the Jellyfin source to figure out why
-init_hw_device
and-hwaccel
weren't being included in the ffmpeg arguments in the first place. The problem is that they checkOperatingSystem.IsLinux()
as part of some of the VAAPI-related setup, e.g. inMediaBrowser.MediaEncoding.Encoder.MediaEncoder.SetFFmpegPath
,MediaBrowser.MediaEncoding.Encoder.EncoderValidator.CheckVaapiDeviceByDriver
,MediaBrowser.Controller.MediaEncoding.EncodingHelper.GetHwaccelType
among others.I could potentially write a pull request to add a bunch of
|| OperatingSystem.IsFreeBSD()
where necessary, but I don't know whether the upstream project would accept them given that FreeBSD isn't officially supported.
I completely misread that yesterday. I think they should just limit the dropdown options to that the OS offer rather than plaster the OS capability everywhere. VAAPI should only appear on BSD / Linux so if the option is only available on theses system they would not have to check for the command line options everytime.
I have an amd 5600g, what can I try to get hardware acceleration working? I have enabled AMD AMF but it seems to still use CPU for transcoding.
Update 1: Looking at the wiki https://jellyfin.org/docs/general/administration/hardware-acceleration/ it says "Jellyfin 10.9 enables full acceleration for AMD Vega and newer GPUs on Linux via VA-API and Vulkan interop."
Update2: Following guide Installation_TrueNAS_GUI vainfo Error Going to go though the guide again in cause i missed something
Update 3: Script returns can't load /boot/modules/radeonkms.ko: module already loaded or in kernel Only drm now shows under dev no dri and jellyfin needs to use /dev/dri/renderD128
Ok so the script for amd enable_gpu_jails.sh does not unhide dri
5600g... might not be supported yet. Truenas drivers are kinda old. Can you post a copy of dmesg we'll see what gets detected.
5600g... might not be supported yet. Truenas drivers are kinda old. Can you post a copy of dmesg we'll see what gets detected.
I've checked the logfile and there's no sign of radeonkms in it... there's only a generic vga...
vgapci0:
If it's the only one detected it could be the problem... maybe post the result of 'lspci -v' and a 'kldstat' that way we'll be able to see the all the modules got loaded correctly even if the script says the modules were loaded.
Also, I've seen posts where 5*00g GPU got mis detected by the driver... and it required an updated driver.
results of lspci -v and kldstat on Truenas core shell kldstat.txt lspciOutput.txt
pciconf -lv | grep -i vga
is usually a bit more informative than lspci -v
but it looks like the version of drivers are before that graphics chip was supported.
This is not an issue on stock FreeBSD as installing https://www.freshports.org/graphics/drm-510-kmod + https://www.freshports.org/graphics/gpu-firmware-amd-kmod should allow it work fine...HOWEVER it does not list Zen3 Cezanne
(or above) AND you cant really do that on TrueNAS anyways
@Thefrank Thanks, so to conclude The current amd GPU drivers in Truenas Core are too old to support the 5600g GPU.
So have we hit a roadblock? is there anything else can that be tried or do i just need to wait for truenas core to update the amd drivers?
@ageekhere Well, it should work with the correct drivers under FreeBSD 13.1+ (see here: https://bsd-hardware.info/?id=cpu:amd-25-80-0-ryzen-5-5600g-with-radeon-graphics) but might not work WELL (e.g., might output graphics in a desktop environment but might not work for hwaccel)
Trying to replace/change out kernel modules in TrueNAS is complex and likely to end in tears
edit: exact listing for JUST the graphics working/detected https://bsd-hardware.info/?id=pci:1002-1638-1002-1636
Trying to replace/change out kernel modules in TrueNAS is complex and likely to end in tears
Agreed, I can also add a GPU to the Truenas server at a later date.
For completeness here is the output for pciconf -lv | grep -i vga
and for future people...that relates to: https://bsd-hardware.info/?id=pci:1002-1638-1458-d000 which as of posting does not appear to be supported under TrueNAS, FreeBSD, or OPNSense.
Is hardware acceleration possible with this solution? Can you please add information about it in readme, i think it be very helpful.