Thefrank / jellyfin-server-freebsd

jellyfin-server component for freebsd
185 stars 16 forks source link

drm and dri exposed but no hardware acceleration #56

Open gmsotavio opened 11 months ago

gmsotavio commented 11 months ago

Hello guys,

I would like to share my situation. I've been trying to enable hardware acceleration for my Jellyfin server using the instructions provided in this file Installation_TrueNAS_GUI.md. While I can see the dri and drm nodes inside my jails, videos requiring transcoding simply do not load. Below are the configurations of my system and the procedures I've followed:

System Configuration

Procedures Performed (Host)

Jail Creation and Jellyfin Installation

  1. Created the Jail with vnet=on and allow_mlock=1:

    iocage create -n jellyfin vnet=on allow_mlock=1 \
    ip4_addr="vnet0|192.168.31.131/24" \
    defaultrouter="192.168.31.1" \
    interfaces="vnet0:vm-public" \
    --release 13.2-RELEASE
  2. Installed Jellyfin inside the Jail:

    iocage pkg jellyfin update
    iocage pkg jellyfin install -y jellyfin
    iocage exec jellyfin mkdir /mnt/media
    iocage fstab --add jellyfin /tank2/media /mnt/media nullfs rw 0 0
    iocage exec jellyfin sysrc jellyfin_enable=TRUE
    iocage exec jellyfin service jellyfin start

drm-kmod Installation and Module Loading

  1. Installed the drm-kmod package:

    pkg install drm-kmod
  2. Added i915kms to the kld_list in /etc/rc.conf:

    sysrc kld_list+=i915kms
  3. Rebooted the system to load the new modules.

Verification of Loaded Modules and Device Nodes

  1. Confirmed that the modules i915kms and drm were loaded using kldstat:

    # kldstat
    Id Refs Address                Size Name
    1   86 0xffffffff80200000  1f3e2d0 kernel
    2    1 0xffffffff8213f000   579de0 vmm.ko
    3    1 0xffffffff826ba000     a4a0 cryptodev.ko
    4    1 0xffffffff826c5000   59dfa8 zfs.ko
    5    1 0xffffffff83210000   1858b8 i915kms.ko
    6    1 0xffffffff83396000    739e0 drm.ko
    7    2 0xffffffff8340a000     5220 linuxkpi_gplv2.ko
    8    3 0xffffffff83410000     62d8 dmabuf.ko
    9    1 0xffffffff83417000     3378 acpi_wmi.ko
    10    1 0xffffffff8341b000     3250 ichsmb.ko
    11    1 0xffffffff8341f000     2180 smbus.ko
    12    1 0xffffffff83422000    31a80 linux.ko
    13    4 0xffffffff83454000     be88 linux_common.ko
    14    1 0xffffffff83460000    14b98 netlink.ko
    15    1 0xffffffff83475000    2dca0 linux64.ko
    16    1 0xffffffff834a3000     2260 pty.ko
    17    1 0xffffffff834a6000     3530 fdescfs.ko
    18    1 0xffffffff834aa000     73b0 linprocfs.ko
    19    1 0xffffffff834b2000     3284 linsysfs.ko
    20    1 0xffffffff834b6000     21cc nmdm.ko
    21    1 0xffffffff834b9000     7638 if_bridge.ko
    22    1 0xffffffff834c1000     60d8 bridgestp.ko
    23    1 0xffffffff834c8000     2a08 mac_ntpd.ko
    24    1 0xffffffff834cb000     4700 nullfs.ko
  2. Verified the creation of the nodes /dev/drm and /dev/dri:

    # ls -la /dev/dr
    dri/ drm/
    # ls -la /dev/dr*
    /dev/dri:
    total 1
    dr-xr-xr-x   2 root  wheel  512 Jul 30 23:33 .
    dr-xr-xr-x  13 root  wheel  512 Jul 30 20:33 ..
    lrwxr-xr-x   1 root  wheel    8 Jul 30 23:33 card0 -> ../drm/0
    lrwxr-xr-x   1 root  wheel   10 Jul 30 23:33 renderD128 -> ../drm/128

Devfs Rules Configuration

  1. Created the file /etc/devfs.rules with the following content:

    # cat /etc/devfs.rules
    [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
  2. Restarted the devfs service:

    service devfs restart
  3. Applied the ruleset 10 to the Jellyfin Jail:

    iocage set devfs_ruleset=10 jellyfin

Inside the Jellyfin Jail

Properties of the Jellyfin jail:

# iocage get all jellyfin
********************************************************************************
fdescfs(5) is not mounted, performance may suffer. Please run:
mount -t fdescfs null /dev/fd
You can also permanently mount it in /etc/fstab with the following entry:
fdescfs /dev/fd  fdescfs  rw  0  0
********************************************************************************

CONFIG_VERSION:27
allow_chflags:0
allow_mlock:1
allow_mount:0
allow_mount_devfs:0
allow_mount_fusefs:0
allow_mount_nullfs:0
allow_mount_procfs:0
allow_mount_tmpfs:0
allow_mount_zfs:0
allow_quotas:0
allow_raw_sockets:0
allow_set_hostname:1
allow_socket_af:0
allow_sysvipc:0
allow_tun:0
allow_vmm:0
assign_localhost:0
available:readonly
basejail:0
boot:0
bpf:0
children_max:0
cloned_release:13.2-RELEASE
comment:none
compression:lz4
compressratio:readonly
coredumpsize:off
count:1
cpuset:off
cputime:off
datasize:off
dedup:off
defaultrouter:192.168.31.1
defaultrouter6:auto
depends:none
devfs_ruleset:1006
dhcp:0
enforce_statfs:2
exec_clean:1
exec_created:/usr/bin/true
exec_fib:0
exec_jail_user:root
exec_poststart:/usr/bin/true
exec_poststop:/usr/bin/true
exec_prestart:/usr/bin/true
exec_prestop:/usr/bin/true
exec_start:/bin/sh /etc/rc
exec_stop:/bin/sh /etc/rc.shutdown
exec_system_jail_user:0
exec_system_user:root
exec_timeout:60
host_domainname:none
host_hostname:jellyfin
host_hostuuid:jellyfin
host_time:1
hostid:611573d9-2402-ce1d-a84a-d8bbc1509368
hostid_strict_check:0
interfaces:vnet0:vm-public
ip4:new
ip4_addr:vnet0|192.168.31.131/24
ip4_saddrsel:1
ip6:new
ip6_addr:none
ip6_saddrsel:1
ip_hostname:0
jail_zfs:0
jail_zfs_dataset:iocage/jails/jellyfin/data
jail_zfs_mountpoint:none
last_started:2023-07-31 22:24:02
localhost_ip:none
login_flags:-f root
mac_prefix:1cfd08
maxproc:off
memorylocked:off
memoryuse:off
min_dyn_devfs_ruleset:1000
mount_devfs:1
mount_fdescfs:1
mount_linprocfs:0
mount_procfs:0
mountpoint:readonly
msgqqueued:off
msgqsize:off
nat:0
nat_backend:ipfw
nat_forwards:none
nat_interface:none
nat_prefix:172.16
nmsgq:off
notes:none
nsem:off
nsemop:off
nshm:off
nthr:off
openfiles:off
origin:readonly
owner:root
pcpu:off
plugin_name:none
plugin_repository:none
priority:99
pseudoterminals:off
quota:none
readbps:off
readiops:off
release:13.2-RELEASE
reservation:none
resolver:/etc/resolv.conf
rlimits:off
rtsold:0
securelevel:2
shmsize:off
stacksize:off
state:up
stop_timeout:30
swapuse:off
sync_state:none
sync_target:none
sync_tgt_zpool:none
sysvmsg:new
sysvsem:new
sysvshm:new
template:0
type:jail
used:readonly
vmemoryuse:off
vnet:1
vnet0_mac:1cfd0829d59a 1cfd0829d59b
vnet1_mac:none
vnet2_mac:none
vnet3_mac:none
vnet_default_interface:auto
vnet_interfaces:none
wallclock:off
writebps:off
writeiops:off

Starting the Jellyfin jail:

# iocage start jellyfin
********************************************************************************
fdescfs(5) is not mounted, performance may suffer. Please run:
mount -t fdescfs null /dev/fd
You can also permanently mount it in /etc/fstab with the following entry:
fdescfs /dev/fd  fdescfs  rw  0  0
********************************************************************************

No default gateway found for ipv6.
* Starting jellyfin
  + Started OK
  + Using devfs_ruleset: 1006 (cloned from devfs_ruleset 10)
  + Configuring VNET OK
  + Using IP options: vnet
  + Starting services OK
  + Executing poststart OK

Installing the packages:

pkg install ffmpeg
pkg install libva-utils
pkg install libva-intel-media-driver

Versions of the installed packages:

root@jellyfin:/dev # pkg info libva-utils ffmpeg libva-intel-media-driver jellyfin
libva-utils-2.18.1
ffmpeg-6.0,1
libva-intel-media-driver-22.4.3_1
jellyfin-10.8.10_1

FFmpeg config:

root@jellyfin:~ # ffmpeg 
ffmpeg version 6.0 Copyright (c) 2000-2023 the FFmpeg developers
  built with FreeBSD clang version 13.0.0 (git@github.com:llvm/llvm-project.git llvmorg-13.0.0-0-gd7b669b3a303)
  configuration: --prefix=/usr/local --mandir=/usr/local/man --datadir=/usr/local/share/ffmpeg --docdir=/usr/local/share/doc/ffmpeg --pkgconfigdir=/usr/local/libdata/pkgconfig --disable-static --disable-libcelt --enable-shared --enable-pic --enable-gpl --cc=cc --cxx=c++ --disable-alsa --disable-libopencore-amrnb --disable-libopencore-amrwb --enable-libaom --disable-libaribb24 --enable-asm --enable-libass --disable-libbs2b --disable-libcaca --disable-libcdio --disable-libcodec2 --enable-libdav1d --disable-libdavs2 --disable-libdc1394 --disable-debug --enable-htmlpages --enable-libdrm --disable-libfdk-aac --disable-libflite --enable-fontconfig --enable-libfreetype --enable-frei0r --disable-libfribidi --disable-gcrypt --disable-libglslang --disable-libgme --enable-gmp --enable-gnutls --enable-version3 --disable-libgsm --enable-iconv --disable-libilbc --disable-libjack --enable-libjxl --disable-libklvanc --disable-libkvazaar --disable-ladspa --enable-libmp3lame --enable-lcms2 --disable-liblensfun --disable-libbluray --enable-libplacebo --disable-librsvg --disable-librtmp --enable-libxml2 --disable-lto --disable-lv2 --disable-mbedtls --disable-libmfx --disable-libmodplug --disable-libmysofa --enable-network --disable-nonfree --enable-nvenc --disable-openal --disable-opencl --disable-opengl --disable-libopenh264 --disable-libopenjpeg --disable-libopenmpt --disable-openssl --disable-libopenvino --enable-optimizations --enable-libopus --disable-pocketsphinx --disable-libpulse --disable-librabbitmq --disable-librav1e --disable-librist --enable-runtime-cpudetect --disable-librubberband --disable-sdl2 --enable-libshaderc --disable-libsmbclient --disable-libsnappy --disable-sndio --disable-libsoxr --disable-libspeex --disable-libsrt --disable-libssh --enable-libsvtav1 --disable-libtensorflow --disable-libtesseract --disable-libtheora --disable-libtwolame --disable-libuavs3d --enable-libv4l2 --enable-vaapi --disable-vapoursynth --enable-vdpau --disable-libvidstab --enable-libvmaf --enable-libvorbis --disable-libvo-amrwbenc --disable-libvpl --enable-libvpx --enable-vulkan --enable-libwebp --enable-libx264 --enable-libx265 --disable-libxavs2 --enable-libxcb --disable-libxvid --disable-outdev=xv --disable-libzimg --disable-libzmq --disable-libzvbi
  libavutil      58.  2.100 / 58.  2.100
  libavcodec     60.  3.100 / 60.  3.100
  libavformat    60.  3.100 / 60.  3.100
  libavdevice    60.  1.100 / 60.  1.100
  libavfilter     9.  3.100 /  9.  3.100
  libswscale      7.  1.100 /  7.  1.100
  libswresample   4. 10.100 /  4. 10.100
  libpostproc    57.  1.100 / 57.  1.100
Hyper fast Audio and Video encoder
usage: ffmpeg [options] [[infile options] -i infile]... {[outfile options] outfile}...

Confirming that the jail can see the drm and dri nodes:

root@jellyfin:/dev # ls -la
total 11
dr-xr-xr-x  13 root  wheel       512 Jul 31 19:23 .
drwxr-xr-x  18 root  wheel        22 Jun 20 20:57 ..
crw-------   1 root  wheel      0x1f Jul 31 19:24 bpf
lrwxr-xr-x   1 root  wheel         3 Jul 31 19:23 bpf0 -> bpf
crw-rw-rw-   1 root  wheel      0x50 Jul 31 19:17 crypto
dr-xr-xr-x   2 root  wheel       512 Jul 31 19:23 dri
dr-xr-xr-x   2 root  wheel       512 Jul 31 19:23 drm
dr-xr-xr-x   2 root  wheel       512 Jul 31 19:17 fd
crw-rw-rw-   1 root  wheel      0x23 Jul 31 19:33 null
crw-rw-rw-   1 root  wheel     0x1e6 Jul 31 19:17 ptmx
dr-xr-xr-x   2 root  wheel       512 Jul 31 19:23 pts
crw-r--r--   1 root  wheel       0x7 Jul 31 16:17 random
lrwxr-xr-x   1 root  wheel         4 Jul 31 19:23 stderr -> fd/2
lrwxr-xr-x   1 root  wheel         4 Jul 31 19:23 stdin -> fd/0
lrwxr-xr-x   1 root  wheel         4 Jul 31 19:23 stdout -> fd/1
lrwxr-xr-x   1 root  wheel         6 Jul 31 19:23 urandom -> random
crw-rw-rw-   1 root  wheel      0x24 Jul 31 19:17 zero
crw-rw-rw-   1 root  operator   0x4d Jul 31 19:17 zfs
root@jellyfin:~ # ls -la /dev/dri
total 1
dr-xr-xr-x   2 root  wheel  512 Jul 31 19:23 .
dr-xr-xr-x  13 root  wheel  512 Jul 31 19:23 ..
lrwxr-xr-x   1 root  wheel    8 Jul 31 19:23 card0 -> ../drm/0
lrwxr-xr-x   1 root  wheel   10 Jul 31 19:23 renderD128 -> ../drm/128

Result of the command vainfo:

root@jellyfin:~ # vainfo 
Trying display: wayland
error: XDG_RUNTIME_DIR is invalid or not set in the environment.
Trying display: x11
error: can't connect to X server!
Trying display: drm
libva info: VA-API version 1.18.0
libva info: Trying to open /usr/local/lib/dri/iHD_drv_video.so
libva info: Found init function __vaDriverInit_1_18
libva info: va_openDriver() returns 0
vainfo: VA-API version: 1.18 (libva 2.18.1)
vainfo: Driver version: Intel iHD driver for Intel(R) Gen Graphics - 22.4.3 (intel-media-22.4.3)
vainfo: Supported profiles and entrypoints
      VAProfileNone                   : VAEntrypointVideoProc
      VAProfileNone                   : VAEntrypointStats
      VAProfileMPEG2Simple            : VAEntrypointVLD
      VAProfileMPEG2Simple            : VAEntrypointEncSlice
      VAProfileMPEG2Main              : VAEntrypointVLD
      VAProfileMPEG2Main              : VAEntrypointEncSlice
      VAProfileH264Main               : VAEntrypointVLD
      VAProfileH264Main               : VAEntrypointEncSlice
      VAProfileH264Main               : VAEntrypointFEI
      VAProfileH264Main               : VAEntrypointEncSliceLP
      VAProfileH264High               : VAEntrypointVLD
      VAProfileH264High               : VAEntrypointEncSlice
      VAProfileH264High               : VAEntrypointFEI
      VAProfileH264High               : VAEntrypointEncSliceLP
      VAProfileVC1Simple              : VAEntrypointVLD
      VAProfileVC1Main                : VAEntrypointVLD
      VAProfileVC1Advanced            : VAEntrypointVLD
      VAProfileJPEGBaseline           : VAEntrypointVLD
      VAProfileJPEGBaseline           : VAEntrypointEncPicture
      VAProfileH264ConstrainedBaseline: VAEntrypointVLD
      VAProfileH264ConstrainedBaseline: VAEntrypointEncSlice
      VAProfileH264ConstrainedBaseline: VAEntrypointFEI
      VAProfileH264ConstrainedBaseline: VAEntrypointEncSliceLP
      VAProfileVP8Version0_3          : VAEntrypointVLD
      VAProfileVP8Version0_3          : VAEntrypointEncSlice
      VAProfileHEVCMain               : VAEntrypointVLD
      VAProfileHEVCMain               : VAEntrypointEncSlice
      VAProfileHEVCMain               : VAEntrypointFEI
      VAProfileHEVCMain10             : VAEntrypointVLD
      VAProfileHEVCMain10             : VAEntrypointEncSlice
      VAProfileVP9Profile0            : VAEntrypointVLD
      VAProfileVP9Profile2            : VAEntrypointVLD

Added the user jellyfin to the group video:

pw groupmod -n video -m jellyfin

Created the file /usr/local/bin/lffmpeg with the following content:

root@jellyfin:~ # cat /usr/local/bin/lffmpeg

#!/bin/sh
echo "$@" > /tmp/params
ffmpeg -hwaccel vaapi "$@"

Added execute permission to the file /usr/local/bin/lffmpeg:

chmod +x /usr/local/bin/lffmpeg

root@jellyfin:~ # ls -la /usr/local/bin/lffmpeg:

-rwxr-xr-x  1 root  wheel  201 Jul 30 23:19 /usr/local/bin/lffmpeg

Playback settings on Jellyfin web:

Image 1

Image 2

When trying to load a movie, I notice that it never leaves the loading screen (it keeps spinning indefinitely with the loading circle):

Screenshot_20230731_194704

The transcode log:

[2023-07-31 19:44:38.289 -03:00] [INF] [115] Jellyfin.Api.Helpers.MediaInfoHelper: StreamBuilder.BuildVideoItem( Profile="Anonymous Profile", Path="/mnt/downloads/1917 (2019) [2160p] [4K] [BluRay] [7.1] [YTS.MX]/1917.2019.2160p.4K.BluRay.x265.10bit.AAC7.1-[YTS.MX].mkv", AudioStreamIndex=1, SubtitleStreamIndex=2 ) => ( PlayMethod=Transcode, TranscodeReason=VideoCodecNotSupported, AudioCodecNotSupported ) "media:/videos/f4601d32-8b44-0985-a3d4-ab66e93459b5/master.m3u8?MediaSourceId=f4601d328b440985a3d4ab66e93459b5&VideoCodec=h264&AudioCodec=aac&AudioStreamIndex=1&VideoBitrate=139616000&AudioBitrate=384000&AudioSampleRate=48000&MaxFramerate=23.976025&api_key=<token>&TranscodingMaxAudioChannels=2&RequireAvc=false&Tag=c5b1f3b099e2d7d1a2f27b9476348e46&SegmentContainer=ts&MinSegments=1&BreakOnNonKeyFrames=True&hevc-level=150&hevc-videobitdepth=10&hevc-profile=main10&hevc-audiochannels=8&aac-profile=lc&TranscodeReasons=VideoCodecNotSupported,%20AudioCodecNotSupported"
[2023-07-31 19:44:38.775 -03:00] [INF] [111] Jellyfin.Api.Controllers.DynamicHlsController: Current HLS implementation doesn't support non-keyframe breaks but one is requested, ignoring that request
[2023-07-31 19:44:38.776 -03:00] [INF] [111] Jellyfin.Api.Helpers.TranscodingJobHelper: "/usr/local/bin/lffmpeg" "-analyzeduration 200M  -i file:\"/mnt/downloads/1917 (2019) [2160p] [4K] [BluRay] [7.1] [YTS.MX]/1917.2019.2160p.4K.BluRay.x265.10bit.AAC7.1-[YTS.MX].mkv\" -map_metadata -1 -map_chapters -1 -threads 0 -map 0:0 -map 0:1 -map -0:s -codec:v:0 h264_vaapi -rc_mode VBR -b:v 6584206 -maxrate 6584206 -bufsize 13168412 -force_key_frames:0 \"expr:gte(t,0+n_forced*3)\" -vf \"setparams=color_primaries=bt709:color_trc=bt709:colorspace=bt709,scale=trunc(min(max(iw\,ih*a)\,min(3840\,1606*a))/2)*2:trunc(min(max(iw/a\,ih)\,min(3840/a\,1606))/2)*2,format=nv12,hwupload=derive_device=vaapi\" -codec:a:0 aac -ac 2 -ab 384000 -ar 48000 -af \"volume=2\" -copyts -avoid_negative_ts disabled -max_muxing_queue_size 2048 -f hls -max_delay 5000000 -hls_time 3 -hls_segment_type mpegts -start_number 0 -hls_segment_filename \"/var/db/jellyfin/transcodes/983a1407df13114b421e601e7585edcb%d.ts\" -hls_playlist_type vod -hls_list_size 0 -y \"/var/db/jellyfin/transcodes/983a1407df13114b421e601e7585edcb.m3u8\""

More logs:

/usr/local/bin/lffmpeg -analyzeduration 200M  -i file:"/mnt/downloads/1917 (2019) [2160p] [4K] [BluRay] [7.1] [YTS.MX]/1917.2019.2160p.4K.BluRay.x265.10bit.AAC7.1-[YTS.MX].mkv" -map_metadata -1 -map_chapters -1 -threads 0 -map 0:0 -map 0:1 -map -0:s -codec:v:0 h264_vaapi -rc_mode VBR -b:v 6584206 -maxrate 6584206 -bufsize 13168412 -force_key_frames:0 "expr:gte(t,0+n_forced*3)" -vf "setparams=color_primaries=bt709:color_trc=bt709:colorspace=bt709,scale=trunc(min(max(iw\,ih*a)\,min(3840\,1606*a))/2)*2:trunc(min(max(iw/a\,ih)\,min(3840/a\,1606))/2)*2,format=nv12,hwupload=derive_device=vaapi" -codec:a:0 aac -ac 2 -ab 384000 -ar 48000 -af "volume=2" -copyts -avoid_negative_ts disabled -max_muxing_queue_size 2048 -f hls -max_delay 5000000 -hls_time 3 -hls_segment_type mpegts -start_number 0 -hls_segment_filename "/var/db/jellyfin/transcodes/983a1407df13114b421e601e7585edcb%d.ts" -hls_playlist_type vod -hls_list_size 0 -y "/var/db/jellyfin/transcodes/983a1407df13114b421e601e7585edcb.m3u8"

ffmpeg version 6.0 Copyright (c) 2000-2023 the FFmpeg developers
  built with FreeBSD clang version 13.0.0 (git@github.com:llvm/llvm-project.git llvmorg-13.0.0-0-gd7b669b3a303)
  configuration: --prefix=/usr/local --mandir=/usr/local/man --datadir=/usr/local/share/ffmpeg --docdir=/usr/local/share/doc/ffmpeg --pkgconfigdir=/usr/local/libdata/pkgconfig --disable-static --disable-libcelt --enable-shared --enable-pic --enable-gpl --cc=cc --cxx=c++ --disable-alsa --disable-libopencore-amrnb --disable-libopencore-amrwb --enable-libaom --disable-libaribb24 --enable-asm --enable-libass --disable-libbs2b --disable-libcaca --disable-libcdio --disable-libcodec2 --enable-libdav1d --disable-libdavs2 --disable-libdc1394 --disable-debug --enable-htmlpages --enable-libdrm --disable-libfdk-aac --disable-libflite --enable-fontconfig --enable-libfreetype --enable-frei0r --disable-libfribidi --disable-gcrypt --disable-libglslang --disable-libgme --enable-gmp --enable-gnutls --enable-version3 --disable-libgsm --enable-iconv --disable-libilbc --disable-libjack --enable-libjxl --disable-libklvanc --disable-libkvazaar --disable-ladspa --enable-libmp3lame --enable-lcms2 --disable-liblensfun --disable-libbluray --enable-libplacebo --disable-librsvg --disable-librtmp --enable-libxml2 --disable-lto --disable-lv2 --disable-mbedtls --disable-libmfx --disable-libmodplug --disable-libmysofa --enable-network --disable-nonfree --enable-nvenc --disable-openal --disable-opencl --disable-opengl --disable-libopenh264 --disable-libopenjpeg --disable-libopenmpt --disable-openssl --disable-libopenvino --enable-optimizations --enable-libopus --disable-pocketsphinx --disable-libpulse --disable-librabbitmq --disable-librav1e --disable-librist --enable-runtime-cpudetect --disable-librubberband --disable-sdl2 --enable-libshaderc --disable-libsmbclient --disable-libsnappy --disable-sndio --disable-libsoxr --disable-libspeex --disable-libsrt --disable-libssh --enable-libsvtav1 --disable-libtensorflow --disable-libtesseract --disable-libtheora --disable-libtwolame --disable-libuavs3d --enable-libv4l2 --enable-vaapi --disable-vapoursynth --enable-vdpau --disable-libvidstab --enable-libvmaf --enable-libvorbis --disable-libvo-amrwbenc --disable-libvpl --enable-libvpx --enable-vulkan --enable-libwebp --enable-libx264 --enable-libx265 --disable-libxavs2 --enable-libxcb --disable-libxvid --disable-outdev=xv --disable-libzimg --disable-libzmq --disable-libzvbi
  libavutil      58.  2.100 / 58.  2.100
  libavcodec     60.  3.100 / 60.  3.100
  libavformat    60.  3.100 / 60.  3.100
  libavdevice    60.  1.100 / 60.  1.100
  libavfilter     9.  3.100 /  9.  3.100
  libswscale      7.  1.100 /  7.  1.100
  libswresample   4. 10.100 /  4. 10.100
  libpostproc    57.  1.100 / 57.  1.100
[matroska,webm @ 0x85ad3a280] Could not find codec parameters for stream 3 (Subtitle: hdmv_pgs_subtitle (pgssub)): unspecified size
Consider increasing the value for the 'analyzeduration' (200000000) and 'probesize' (5000000) options
[matroska,webm @ 0x85ad3a280] Could not find codec parameters for stream 4 (Subtitle: hdmv_pgs_subtitle (pgssub)): unspecified size
Consider increasing the value for the 'analyzeduration' (200000000) and 'probesize' (5000000) options
[matroska,webm @ 0x85ad3a280] Could not find codec parameters for stream 5 (Subtitle: hdmv_pgs_subtitle (pgssub)): unspecified size
Consider increasing the value for the 'analyzeduration' (200000000) and 'probesize' (5000000) options
Input #0, matroska,webm, from 'file:/mnt/downloads/1917 (2019) [2160p] [4K] [BluRay] [7.1] [YTS.MX]/1917.2019.2160p.4K.BluRay.x265.10bit.AAC7.1-[YTS.MX].mkv':
  Metadata:
    ENCODER         : Lavf58.41.100
  Duration: 01:58:59.51, start: 0.000000, bitrate: 6584 kb/s
  Stream #0:0: Video: hevc (Main 10), yuv420p10le(tv), 3840x1606 [SAR 1:1 DAR 1920:803], 23.98 fps, 23.98 tbr, 1k tbn (default)
    Metadata:
      ENCODER         : Lavc58.75.100 libx265
      DURATION        : 01:58:59.509000000
  Stream #0:1: Audio: aac (LC), 48000 Hz, 7.1, fltp (default)
    Metadata:
      ENCODER         : Lavc58.75.100 libfdk_aac
      DURATION        : 01:58:59.509000000
  Stream #0:2(eng): Subtitle: subrip (default)
    Metadata:
      title           : English-SRT
      BPS-eng         : 34
      DURATION-eng    : 01:45:44.619000000
      NUMBER_OF_FRAMES-eng: 934
      NUMBER_OF_BYTES-eng: 27417
      _STATISTICS_TAGS-eng: BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES
      DURATION        : 01:47:15.419000000
  Stream #0:3(eng): Subtitle: hdmv_pgs_subtitle
    Metadata:
      title           : English-SDH-PGS
      BPS-eng         : 27959
      DURATION-eng    : 01:45:49.468000000
      NUMBER_OF_FRAMES-eng: 2202
      NUMBER_OF_BYTES-eng: 22191030
      _STATISTICS_TAGS-eng: BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES
      DURATION        : 01:47:15.431000000
  Stream #0:4(fre): Subtitle: hdmv_pgs_subtitle
    Metadata:
      title           : French-PGS
      BPS-eng         : 22671
      DURATION-eng    : 01:57:50.856000000
      NUMBER_OF_FRAMES-eng: 1888
      NUMBER_OF_BYTES-eng: 20038011
      _STATISTICS_TAGS-eng: BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES
      DURATION        : 01:58:39.448000000
  Stream #0:5(spa): Subtitle: hdmv_pgs_subtitle
    Metadata:
      title           : Spanish-PGS
      BPS-eng         : 21293
      DURATION-eng    : 01:57:50.856000000
      NUMBER_OF_FRAMES-eng: 2022
      NUMBER_OF_BYTES-eng: 18820204
      _STATISTICS_TAGS-eng: BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES
      DURATION        : 01:58:39.448000000
Stream mapping:
  Stream #0:0 -> #0:0 (hevc (native) -> h264 (h264_vaapi))
  Stream #0:1 -> #0:1 (aac (native) -> aac (native))
Press [q] to stop, [?] for help

I appreciate any tips you may have to offer. Thank you in advance.

Thefrank commented 11 months ago

Everything looks like it SHOULD be working. try using the default path for FFmpeg instead of the one created by lffmpeg. does it use -hwaccel vaapi when being invoked?

gmsotavio commented 11 months ago

Hi @Thefrank

When attempting to use the default FFmpeg (6.0) on FreeBSD, an error occurs

image

The log displays the following command invocations:

ffmpeg -analyzeduration 200M -i file:"/mnt/downloads/Noah (2014) [2160p] [4K] [WEB] [5.1] [YTS.MX]/Noah.2014.2160p.4K.WEB.x265.10bit.AAC5.1-[YTS.MX].mkv" -map_metadata -1 -map_chapters -1 -threads 0 -map 0:0 -map 0:1 -map -0:s -codec:v:0 h264_vaapi -rc_mode VBR -b:v 6388419 -maxrate 6388419 -bufsize 12776838 -force_key_frames:0 "expr:gte(t,0+n_forced*3)" -vf "setparams=color_primaries=bt709:color_trc=bt709:colorspace=bt709,scale=trunc(min(max(iw\,ih*a)\,min(3658\,2074*a))/2)*2:trunc(min(max(iw/a\,ih)\,min(3658/a\,2074))/2)*2,format=nv12,hwupload=derive_device=vaapi" -codec:a:0 aac -ac 2 -ab 384000 -ar 48000 -af "volume=2" -copyts -avoid_negative_ts disabled -max_muxing_queue_size 2048 -f hls -max_delay 5000000 -hls_time 3 -hls_segment_type mpegts -start_number 0 -hls_segment_filename "/var/db/jellyfin/transcodes/d84f765d6274cffe000f265bd429c904%d.ts" -hls_playlist_type vod -hls_list_size 0 -y "/var/db/jellyfin/transcodes/d84f765d6274cffe000f265bd429c904.m3u8"

As we can see, -hwaccel vaapi is missing and the following error is printed int the log

Stream mapping:
  Stream #0:0 -> #0:0 (hevc (native) -> h264 (h264_vaapi))
  Stream #0:1 -> #0:1 (aac (native) -> aac (native))
Press [q] to stop, [?] for help
[hwupload @ 0x867e07c00] A hardware device reference is required to upload frames to.
[Parsed_hwupload_3 @ 0x860829e00] Query format failed for 'Parsed_hwupload_3': Invalid argument
Error reinitializing filters!
Failed to inject frame into filter network: Invalid argument
Error while processing the decoded data for stream #0:0
[aac @ 0x860963c00] Qavg: 65536.000
[aac @ 0x860963c00] 2 frames left in the queue on closing
Conversion failed!
gmsotavio commented 11 months ago

It appears that the following configuration is not being passed to FFmpeg. I am unsure how the device node path is handled by Jellyfin.

image

Thefrank commented 11 months ago

@gmsotavio hwupload=derive_device=vaapi. that line should be handling it but it does not appear to be but it also should do -init_hw_device at some point too. You can try changing the last line in lffmpeg to ffmpeg -init_hw_device vaapi=va:/dev/dri/renderD128 -filter_hw_device va -hwaccel vaapi -hwaccel_output_format vaapi "$@" and see if that is the nudge it needs

Thefrank commented 11 months ago

One final thing to try: pkg remove libva-intel-media-driver pkg install libva-intel-driver

gmsotavio commented 11 months ago

@gmsotavio hwupload=derive_device=vaapi. that line should be handling it but it does not appear to be but it also should do -init_hw_device at some point too. You can try changing the last line in lffmpeg to ffmpeg -init_hw_device vaapi=va:/dev/dri/renderD128 -filter_hw_device va -hwaccel vaapi -hwaccel_output_format vaapi "$@" and see if that is the nudge it needs

@Thefrank, thank you for your patience and support.

As you have suggested, I have been trying to use FFmpeg with the following command to utilize VA-API for hardware acceleration:

ffmpeg -init_hw_device vaapi=va:/dev/dri/renderD128 -filter_hw_device va -hwaccel vaapi -hwaccel_output_format vaapi "$@"

However, I encountered the following error message during the process:

Stream mapping:
  Stream #0:0 -> #0:0 (hevc (native) -> h264 (h264_vaapi))
  Stream #0:1 -> #0:1 (aac (native) -> aac (native))
Press [q] to stop, [?] for help
Impossible to convert between the formats supported by the filter 'Parsed_setparams_0' and the filter 'auto_scale_0'
Error reinitializing filters!
Failed to inject frame into filter network: Function not implemented
Error while processing the decoded data for stream #0:0
[aac @ 0x862899400] Qavg: 65536.000
[aac @ 0x862899400] 2 frames left in the queue on closing
Conversion failed!
gmsotavio commented 11 months ago

One final thing to try: pkg remove libva-intel-media-driver pkg install libva-intel-driver

For that test, I encountered the following error message:

root@jellyfin:~ # vainfo
Trying display: wayland
error: XDG_RUNTIME_DIR is invalid or not set in the environment.
Trying display: x11
error: can't connect to X server!
Trying display: drm
libva info: VA-API version 1.18.0
libva info: Trying to open /usr/local/lib/dri/iHD_drv_video.so
libva info: va_openDriver() returns -1
libva info: Trying to open /usr/local/lib/dri/i965_drv_video.so
libva info: Found init function __vaDriverInit_1_18
libva error: /usr/local/lib/dri/i965_drv_video.so init failed
libva info: va_openDriver() returns -1
vaInitialize failed with error code -1 (unknown libva error),exit

and

[AVHWDeviceContext @ 0x85c9b11c0] libva: /usr/local/lib/dri/i965_drv_video.so init failed
[AVHWDeviceContext @ 0x85c9b11c0] Failed to initialise VAAPI connection: -1 (unknown libva error).
Device creation failed: -5.
No device available for decoder: device type vaapi needed for codec hevc.
Stream mapping:
  Stream #0:0 -> #0:0 (hevc (native) -> h264 (h264_vaapi))
  Stream #0:1 -> #0:1 (aac (native) -> aac (native))
Device setup failed for decoder on input stream #0:0 : Input/output error
gmsotavio commented 11 months ago

I believe there might be an issue with FFmpeg. Jellyfin provides a package called ffmpeg-jellyfin, and I'm not sure how much it differs from the vanilla FFmpeg, but I'll need to research it. Have you had success with this process using any Intel iGPU?

Thefrank commented 11 months ago

@gmsotavio I don't have any hardware to test it on sadly. If you want to try a different (but not jellyfin's version) of FFmpeg, I make a static binary for it: https://github.com/Thefrank/ffmpeg-static-freebsd . I doubt it will work with hwaccel as that is very difficult to do via static linking

gmsotavio commented 11 months ago

@Thefrank, I conducted some additional tests tonight. I attempted to isolate Jellyfin from FFmpeg. I took one of the movie files I was trying to play and manually performed an HEVC -> H.264 conversion using only FFmpeg with options for decoding using hwaccel@vaapi.

The command below worked:

ffmpeg -hwaccel vaapi -hwaccel_device /dev/dri/renderD128 -hwaccel_output_format vaapi -i input.mkv -filter:v "scale_vaapi=w=3840:h=2160:format=nv12" -c:v h264_vaapi -profile:v main output.mkv

root@jellyfin:/tmp # ffmpeg -hwaccel vaapi -hwaccel_device /dev/dri/renderD128 -hwaccel_output_format vaapi -i input.mkv -filter:v "scale_vaapi=w=3840:h=2160:format=nv12" -c:v h264_vaapi -profile:v main output.mkv
ffmpeg version 6.0 Copyright (c) 2000-2023 the FFmpeg developers
  built with FreeBSD clang version 13.0.0 (git@github.com:llvm/llvm-project.git llvmorg-13.0.0-0-gd7b669b3a303)
  configuration: --prefix=/usr/local --mandir=/usr/local/man --datadir=/usr/local/share/ffmpeg --docdir=/usr/local/share/doc/ffmpeg --pkgconfigdir=/usr/local/libdata/pkgconfig --disable-static --disable-libcelt --enable-shared --enable-pic --enable-gpl --cc=cc --cxx=c++ --disable-alsa --disable-libopencore-amrnb --disable-libopencore-amrwb --enable-libaom --disable-libaribb24 --enable-asm --enable-libass --disable-libbs2b --disable-libcaca --disable-libcdio --disable-libcodec2 --enable-libdav1d --disable-libdavs2 --disable-libdc1394 --disable-debug --enable-htmlpages --enable-libdrm --disable-libfdk-aac --disable-libflite --enable-fontconfig --enable-libfreetype --enable-frei0r --disable-libfribidi --disable-gcrypt --disable-libglslang --disable-libgme --enable-gmp --enable-gnutls --enable-version3 --disable-libgsm --enable-iconv --disable-libilbc --disable-libjack --enable-libjxl --disable-libklvanc --disable-libkvazaar --disable-ladspa --enable-libmp3lame --enable-lcms2 --disable-liblensfun --disable-libbluray --enable-libplacebo --disable-librsvg --disable-librtmp --enable-libxml2 --disable-lto --disable-lv2 --disable-mbedtls --disable-libmfx --disable-libmodplug --disable-libmysofa --enable-network --disable-nonfree --enable-nvenc --disable-openal --disable-opencl --disable-opengl --disable-libopenh264 --disable-libopenjpeg --disable-libopenmpt --disable-openssl --disable-libopenvino --enable-optimizations --enable-libopus --disable-pocketsphinx --disable-libpulse --disable-librabbitmq --disable-librav1e --disable-librist --enable-runtime-cpudetect --disable-librubberband --disable-sdl2 --enable-libshaderc --disable-libsmbclient --disable-libsnappy --disable-sndio --disable-libsoxr --disable-libspeex --disable-libsrt --disable-libssh --enable-libsvtav1 --disable-libtensorflow --disable-libtesseract --disable-libtheora --disable-libtwolame --disable-libuavs3d --enable-libv4l2 --enable-vaapi --disable-vapoursynth --enable-vdpau --disable-libvidstab --enable-libvmaf --enable-libvorbis --disable-libvo-amrwbenc --disable-libvpl --enable-libvpx --enable-vulkan --enable-libwebp --enable-libx264 --enable-libx265 --disable-libxavs2 --enable-libxcb --disable-libxvid --disable-outdev=xv --disable-libzimg --disable-libzmq --disable-libzvbi
  libavutil      58.  2.100 / 58.  2.100
  libavcodec     60.  3.100 / 60.  3.100
  libavformat    60.  3.100 / 60.  3.100
  libavdevice    60.  1.100 / 60.  1.100
  libavfilter     9.  3.100 /  9.  3.100
  libswscale      7.  1.100 /  7.  1.100
  libswresample   4. 10.100 /  4. 10.100
  libpostproc    57.  1.100 / 57.  1.100
Input #0, matroska,webm, from 'input.mkv':
  Metadata:
    ENCODER         : Lavf59.33.100
  Duration: 02:17:53.18, start: -0.043000, bitrate: 6388 kb/s
  Chapters:
    Chapter #0:0: start 0.000000, end 9.000000
    Chapter #0:1: start 9.000000, end 42.000000
    Chapter #0:2: start 42.000000, end 132.000000
    Chapter #0:3: start 132.000000, end 289.000000
    Chapter #0:4: start 289.000000, end 297.000000
    Chapter #0:5: start 297.000000, end 477.000000
    Chapter #0:6: start 477.000000, end 525.000000
    Chapter #0:7: start 525.000000, end 636.000000
    Chapter #0:8: start 636.000000, end 750.000000
    Chapter #0:9: start 750.000000, end 803.000000
    Chapter #0:10: start 803.000000, end 831.000000
    Chapter #0:11: start 831.000000, end 1029.000000
    Chapter #0:12: start 1029.000000, end 1131.000000
    Chapter #0:13: start 1131.000000, end 1253.000000
    Chapter #0:14: start 1253.000000, end 1413.000000
    Chapter #0:15: start 1413.000000, end 1807.000000
    Chapter #0:16: start 1807.000000, end 1935.000000
    Chapter #0:17: start 1935.000000, end 2081.000000
    Chapter #0:18: start 2081.000000, end 2180.000000
    Chapter #0:19: start 2180.000000, end 2255.000000
    Chapter #0:20: start 2255.000000, end 2469.000000
    Chapter #0:21: start 2469.000000, end 2571.000000
    Chapter #0:22: start 2571.000000, end 2968.000000
    Chapter #0:23: start 2968.000000, end 2998.000000
    Chapter #0:24: start 2998.000000, end 3081.000000
    Chapter #0:25: start 3081.000000, end 3117.000000
    Chapter #0:26: start 3117.000000, end 3284.000000
    Chapter #0:27: start 3284.000000, end 3430.000000
    Chapter #0:28: start 3430.000000, end 3655.000000
    Chapter #0:29: start 3655.000000, end 3817.000000
    Chapter #0:30: start 3817.000000, end 3961.000000
    Chapter #0:31: start 3961.000000, end 4142.000000
    Chapter #0:32: start 4142.000000, end 4327.000000
    Chapter #0:33: start 4327.000000, end 4923.000000
    Chapter #0:34: start 4923.000000, end 5086.000000
    Chapter #0:35: start 5086.000000, end 5267.000000
    Chapter #0:36: start 5267.000000, end 5446.000000
    Chapter #0:37: start 5446.000000, end 5551.000000
    Chapter #0:38: start 5551.000000, end 5650.000000
    Chapter #0:39: start 5650.000000, end 5745.000000
    Chapter #0:40: start 5745.000000, end 5913.000000
    Chapter #0:41: start 5913.000000, end 6162.000000
    Chapter #0:42: start 6162.000000, end 6344.000000
    Chapter #0:43: start 6344.000000, end 6966.000000
    Chapter #0:44: start 6966.000000, end 7244.000000
    Chapter #0:45: start 7244.000000, end 7327.000000
    Chapter #0:46: start 7327.000000, end 7449.000000
    Chapter #0:47: start 7449.000000, end 7496.000000
    Chapter #0:48: start 7496.000000, end 7643.000000
    Chapter #0:49: start 7643.000000, end 7764.000000
    Chapter #0:50: start 7764.000000, end 7900.000000
    Chapter #0:51: start 7900.000000, end 8273.152000
  Stream #0:0: Video: hevc (Main 10), yuv420p10le(tv, bt709, progressive), 3658x2074 [SAR 1:1 DAR 1829:1037], 23.98 fps, 23.98 tbr, 1k tbn (default) (original)
    Metadata:
      ENCODER         : Lavc59.48.100 libx265
      DURATION        : 02:17:52.640000000
  Stream #0:1: Audio: aac (LC), 48000 Hz, 5.1, fltp (default) (original)
    Metadata:
      ENCODER         : Lavc59.48.100 libfdk_aac
      DURATION        : 02:17:53.184000000
  Stream #0:2(eng): Subtitle: subrip (default) (original)
    Metadata:
      DURATION        : 02:10:31.323000000
  Stream #0:3(eng): Subtitle: subrip (original) (hearing impaired)
    Metadata:
      title           : SDH
      DURATION        : 02:10:31.323000000
  Stream #0:4(ara): Subtitle: subrip
    Metadata:
      DURATION        : 02:17:51.378000000
  Stream #0:5(dan): Subtitle: subrip
    Metadata:
      DURATION        : 02:17:51.462000000
  Stream #0:6(ger): Subtitle: subrip
    Metadata:
      DURATION        : 02:17:51.577000000
  Stream #0:7(spa): Subtitle: subrip
    Metadata:
      DURATION        : 02:13:02.971000000
  Stream #0:8(spa): Subtitle: subrip
    Metadata:
      DURATION        : 02:17:51.592000000
  Stream #0:9(fin): Subtitle: subrip
    Metadata:
      DURATION        : 02:17:51.637000000
  Stream #0:10(fil): Subtitle: subrip
    Metadata:
      DURATION        : 02:17:41.750000000
  Stream #0:11(fre): Subtitle: subrip
    Metadata:
      DURATION        : 02:17:51.542000000
  Stream #0:12(hin): Subtitle: subrip
    Metadata:
      DURATION        : 02:17:51.652000000
  Stream #0:13(ita): Subtitle: subrip
    Metadata:
      DURATION        : 02:17:51.584000000
  Stream #0:14(jpn): Subtitle: subrip
    Metadata:
      DURATION        : 02:10:31.329000000
  Stream #0:15(kor): Subtitle: subrip
    Metadata:
      DURATION        : 02:17:51.693000000
  Stream #0:16(may): Subtitle: subrip
    Metadata:
      DURATION        : 02:10:31.576000000
  Stream #0:17(dut): Subtitle: subrip
    Metadata:
      DURATION        : 02:17:51.612000000
  Stream #0:18(nor): Subtitle: subrip
    Metadata:
      DURATION        : 02:17:51.543000000
  Stream #0:19(pol): Subtitle: subrip
    Metadata:
      DURATION        : 02:17:51.577000000
  Stream #0:20(por): Subtitle: subrip
    Metadata:
      DURATION        : 02:13:02.993000000
  Stream #0:21(por): Subtitle: subrip
    Metadata:
      DURATION        : 02:17:51.533000000
  Stream #0:22(rum): Subtitle: subrip
    Metadata:
      DURATION        : 02:10:31.780000000
  Stream #0:23(rus): Subtitle: subrip
    Metadata:
      DURATION        : 02:17:51.615000000
  Stream #0:24(swe): Subtitle: subrip
    Metadata:
      DURATION        : 02:17:51.585000000
  Stream #0:25(tur): Subtitle: subrip
    Metadata:
      DURATION        : 02:17:51.519000000
  Stream #0:26(chi): Subtitle: subrip
    Metadata:
      DURATION        : 02:10:31.510000000
  Stream #0:27(chi): Subtitle: subrip
    Metadata:
      DURATION        : 02:17:51.767000000
File 'output.mkv' already exists. Overwrite? [y/N] y
Stream mapping:
  Stream #0:0 -> #0:0 (hevc (native) -> h264 (h264_vaapi))
  Stream #0:1 -> #0:1 (aac (native) -> vorbis (libvorbis))
  Stream #0:2 -> #0:2 (subrip (srt) -> ass (ssa))
Press [q] to stop, [?] for help
[h264_vaapi @ 0x85bf5d400] No quality level set; using default (20).
Output #0, matroska, to 'output.mkv':
  Metadata:
    encoder         : Lavf60.3.100
  Chapters:
    Chapter #0:0: start 0.043000, end 9.043000
    Chapter #0:1: start 9.043000, end 42.043000
    Chapter #0:2: start 42.043000, end 132.043000
    Chapter #0:3: start 132.043000, end 289.043000
    Chapter #0:4: start 289.043000, end 297.043000
    Chapter #0:5: start 297.043000, end 477.043000
    Chapter #0:6: start 477.043000, end 525.043000
    Chapter #0:7: start 525.043000, end 636.043000
    Chapter #0:8: start 636.043000, end 750.043000
    Chapter #0:9: start 750.043000, end 803.043000
    Chapter #0:10: start 803.043000, end 831.043000
    Chapter #0:11: start 831.043000, end 1029.043000
    Chapter #0:12: start 1029.043000, end 1131.043000
    Chapter #0:13: start 1131.043000, end 1253.043000
    Chapter #0:14: start 1253.043000, end 1413.043000
    Chapter #0:15: start 1413.043000, end 1807.043000
    Chapter #0:16: start 1807.043000, end 1935.043000
    Chapter #0:17: start 1935.043000, end 2081.043000
    Chapter #0:18: start 2081.043000, end 2180.043000
    Chapter #0:19: start 2180.043000, end 2255.043000
    Chapter #0:20: start 2255.043000, end 2469.043000
    Chapter #0:21: start 2469.043000, end 2571.043000
    Chapter #0:22: start 2571.043000, end 2968.043000
    Chapter #0:23: start 2968.043000, end 2998.043000
    Chapter #0:24: start 2998.043000, end 3081.043000
    Chapter #0:25: start 3081.043000, end 3117.043000
    Chapter #0:26: start 3117.043000, end 3284.043000
    Chapter #0:27: start 3284.043000, end 3430.043000
    Chapter #0:28: start 3430.043000, end 3655.043000
    Chapter #0:29: start 3655.043000, end 3817.043000
    Chapter #0:30: start 3817.043000, end 3961.043000
    Chapter #0:31: start 3961.043000, end 4142.043000
    Chapter #0:32: start 4142.043000, end 4327.043000
    Chapter #0:33: start 4327.043000, end 4923.043000
    Chapter #0:34: start 4923.043000, end 5086.043000
    Chapter #0:35: start 5086.043000, end 5267.043000
    Chapter #0:36: start 5267.043000, end 5446.043000
    Chapter #0:37: start 5446.043000, end 5551.043000
    Chapter #0:38: start 5551.043000, end 5650.043000
    Chapter #0:39: start 5650.043000, end 5745.043000
    Chapter #0:40: start 5745.043000, end 5913.043000
    Chapter #0:41: start 5913.043000, end 6162.043000
    Chapter #0:42: start 6162.043000, end 6344.043000
    Chapter #0:43: start 6344.043000, end 6966.043000
    Chapter #0:44: start 6966.043000, end 7244.043000
    Chapter #0:45: start 7244.043000, end 7327.043000
    Chapter #0:46: start 7327.043000, end 7449.043000
    Chapter #0:47: start 7449.043000, end 7496.043000
    Chapter #0:48: start 7496.043000, end 7643.043000
    Chapter #0:49: start 7643.043000, end 7764.043000
    Chapter #0:50: start 7764.043000, end 7900.043000
    Chapter #0:51: start 7900.043000, end 8273.195000
  Stream #0:0: Video: h264 (Main) (H264 / 0x34363248), vaapi(tv, bt709, progressive), 3840x2160 [SAR 16461:16592 DAR 1829:1037], q=2-31, 23.98 fps, 1k tbn (default) (original)
    Metadata:
      DURATION        : 02:17:52.640000000
      encoder         : Lavc60.3.100 h264_vaapi
  Stream #0:1: Audio: vorbis (oV[0][0] / 0x566F), 48000 Hz, 5.1, fltp (default) (original)
    Metadata:
      DURATION        : 02:17:53.184000000
      encoder         : Lavc60.3.100 libvorbis
  Stream #0:2(eng): Subtitle: ass (default) (original)
    Metadata:
      DURATION        : 02:10:31.323000000
      encoder         : Lavc60.3.100 ssa
[libvorbis @ 0x85bf5dc00] Queue input is backward in time60 bitrate=   6.1kbits/s speed=2.96x    
frame=  364 fps= 67 q=-0.0 Lsize=   23179kB time=00:00:15.56 bitrate=12199.1kbits/s speed=2.88x  

As you can see in the image, the processor load is very low during the transcode, confirming the use of the iGPU:

image

Possibly, some of the filter parameters passed by Jellyfin are causing the issue. The thing is, it's not about problems with drivers or even issues with FFmpeg. Everything should be working. I'll be investigating further the parameters that Jellyfin passes to FFmpeg.

For instance, if I attempt to remove the parameter -filter:v "scale_vaapi=w=3840:h=2160:format=nv12" from the command mentioned above, the conversion will fail. So, a minor change in the filter parameters can lead to a total transcoding failure.

As we can see in the Jellyfin command issued to FFmepg, the filter selection is a bit complex and harder to grasp:

ffmpeg -hwaccel vaapi -hwaccel_device /dev/dri/renderD128 -hwaccel_output_format vaapi -analyzeduration 200M -i "file:/mnt/downloads/Noah (2014) [2160p] [4K] [WEB] [5.1] [YTS.MX]/Noah.2014.2160p.4K.WEB.x265.10bit.AAC5.1-[YTS.MX].mkv" -map_metadata -1 -map_chapters -1 -threads 0 -map 0:0 -map 0:1 -map -0:s -codec:v:0 h264_vaapi -rc_mode VBR -b:v 6388419 -maxrate 6388419 -bufsize 12776838 -force_key_frames:0 "expr:gte(t,0+n_forced*3)" -vf "setparams=color_primaries=bt709:color_trc=bt709:colorspace=bt709,scale=trunc(min(max(iw\,ih*a)\,min(3658\,2074*a))/2)*2:trunc(min(max(iw/a\,ih)\,min(3658/a\,2074))/2)*2,format=nv12,hwupload=derive_device=vaapi" -codec:a:0 aac -ac 2 -ab 384000 -ar 48000 -af "volume=2" -copyts -avoid_negative_ts disabled -max_muxing_queue_size 2048 -f hls -max_delay 5000000 -hls_time 3 -hls_segment_type mpegts -start_number 0 -hls_segment_filename "/var/db/jellyfin/transcodes/6165c611a2803daab963a55b0fe28af3%d.ts" -hls_playlist_type vod -hls_list_size 0 -y "/var/db/jellyfin/transcodes/6165c611a2803daab963a55b0fe28af3.m3u8"

For now, I appreciate the help and time dedicated to assist me.

gmsotavio commented 11 months ago

@Thefrank I managed to make it work (manually). I'm almost there.

Params that Jellyfin passes to lffmpeg:

-analyzeduration 200M -i "file:/mnt/downloads/Noah (2014) [2160p] [4K] [WEB] [5.1] [YTS.MX]/Noah.2014.2160p.4K.WEB.x265.10bit.AAC5.1-[YTS.MX].mkv" -map_metadata -1 -map_chapters -1 -threads 0 -map 0:0 -map 0:1 -map -0:s -codec:v:0 h264_vaapi -rc_mode VBR -b:v 6388419 -maxrate 6388419 -bufsize 12776838 -force_key_frames:0 "expr:gte(t,0+n_forced*3)" -vf "setparams=color_primaries=bt709:color_trc=bt709:colorspace=bt709,scale=trunc(min(max(iw\,ih*a)\,min(3658\,2074*a))/2)*2:trunc(min(max(iw/a\,ih)\,min(3658/a\,2074))/2)*2,format=nv12,hwupload=derive_device=vaapi" -codec:a:0 aac -ac 2 -ab 384000 -ar 48000 -af "volume=2" -copyts -avoid_negative_ts disabled -max_muxing_queue_size 2048 -f hls -max_delay 5000000 -hls_time 3 -hls_segment_type mpegts -start_number 0 -hls_segment_filename "/var/db/jellyfin/transcodes/6165c611a2803daab963a55b0fe28af3%d.ts" -hls_playlist_type vod -hls_list_size 0 -y "/var/db/jellyfin/transcodes/6165c611a2803daab963a55b0fe28af3.m3u8"

After making several modifications, the results are as follows:

-analyzeduration 200M -i "file:/mnt/downloads/Noah (2014) [2160p] [4K] [WEB] [5.1] [YTS.MX]/Noah.2014.2160p.4K.WEB.x265.10bit.AAC5.1-[YTS.MX].mkv" -map_metadata -1 -map_chapters -1 -threads 8 -map 0:0 -map 0:1 -map -0:s -codec:v:0 h264_vaapi -rc_mode VBR -b:v 6388419 -maxrate 6388419 -bufsize 12776838 -force_key_frames:0 "expr:gte(t,0+n_forced*3)" -vf "setparams=color_primaries=bt709:color_trc=bt709:colorspace=bt709,scale_vaapi=trunc(min(max(iw\,ih*a)\,min(3658\,2074*a))/2)*2:trunc(min(max(iw/a\,ih)\,min(3658/a\,2074))/2)*2:format=nv12" -codec:a:0 aac -ac 2 -ab 384000 -ar 48000 -af "volume=2" -copyts -avoid_negative_ts disabled -max_muxing_queue_size 2048 -f hls -max_delay 5000000 -hls_time 3 -hls_segment_type mpegts -start_number 0 -hls_segment_filename "/var/db/jellyfin/transcodes/6165c611a2803daab963a55b0fe28af3%d.ts" -hls_playlist_type vod -hls_list_size 0 -y "/var/db/jellyfin/transcodes/6165c611a2803daab963a55b0fe28af3.m3u8" Et voilà!

image

What I have changed

image

Aditionally, It will be necessary to add -hwaccel vaapi -hwaccel_device /dev/dri/renderD128 -hwaccel_output_format vaapi -analyzeduration to lffmpeg:

# cat /usr/local/bin/lffmpeg 
#!/bin/sh
echo "$@" > /tmp/params
ffmpeg -hwaccel vaapi -hwaccel_device /dev/dri/renderD128 -hwaccel_output_format vaapi "$@"

Now, I need to find a way to modify the parameters passed to lffmpeg before they are fed to the ffmpeg executable. I'm unsure if this is possible.

Thefrank commented 11 months ago

If jellyfin assumes that you are using FFmpeg v5 instead of v6 it might explain some of the args being passed oddly. The API between 4->5->6 are all slightly different

johndodigie commented 6 months ago

Hi @gmsotavio, currently having the same problem with the same hardware. Where you able to find a fix and make transcoding work?

gmsotavio commented 6 months ago

Hello @johndodigie,

I am still investigating the cause of the problem. Here are some clarifications:

My two assumptions when analyzing the Jellyfin source code are:

Currently, I am using software transcoding, but I would very much like to enable hardware transcoding, as I have already proven that it works perfectly in FreeBSD jails and would significantly alleviate the load on my processor.

Thefrank commented 6 months ago

I should have some free time after the holidays to deep-dive this issue. A quick glance seems to point at requiring some source changes to support VAAPI. As pointed out, it already does a good job of determine which version of FFmpeg is being used; it should be able to use .git builds or even builds with mangled versions.

https://github.com/jellyfin/jellyfin/blob/660165cd2ff6288061a90c968381eb014ec3b7fd/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs#L352-#L357

https://github.com/jellyfin/jellyfin/blob/660165cd2ff6288061a90c968381eb014ec3b7fd/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs#L200-#L207

This (hopefully) is just an || away from working. dotNET has understood what OperatingSystem.IsFreeBSD() is since NET5 https://learn.microsoft.com/en-us/dotnet/api/system.operatingsystem.isfreebsd?view=net-8.0 and OSPlatform.FreeBSD since Core 3.0 https://learn.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.osplatform.freebsd?view=net-8.0

Thefrank commented 6 months ago

@gmsotavio

https://github.com/Thefrank/jellyfin-server-freebsd/releases/tag/jellyfin-vaapi-test

Let me know if that resolves the issue. If it does, I will work on QSV next.

gmsotavio commented 6 months ago

@Thefrank

Thank you for sharing. I'll test your modifications and promptly share the results with you. I appreciate the efforts you've put into assisting us with this.

gmsotavio commented 6 months ago

@Thefrank

In the tests I conducted, I did not notice any difference. The parameters that Jellyfin passes to ffmpeg are exactly the same. I really don't know if I might be doing something wrong.

However, upon reviewing the code again, I came across this:

https://github.com/jellyfin/jellyfin/blob/e5dcaa6ed52a22360958e5d2054f55924f2a1512/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs#L4172C1-L4172C101

var isVaapiFullSupported = isLinux && IsVaapiSupported(state) && IsVaapiFullSupported();

It seems that Vaapi is only considered fully supported if the system is Linux. I don't know if this could be influencing the issue we are facing.

var isLinux = OperatingSystem.IsLinux();

Note that the hardware image scaling filter scale_vaapi is only enabled if IsVaapiFullSupported. Otherwise, only scale will be passed to ffmpeg instead of scale_vaapi.

   private bool IsVaapiFullSupported()
        {
            return _mediaEncoder.SupportsHwaccel("drm")
                   && _mediaEncoder.SupportsHwaccel("vaapi")
                   && _mediaEncoder.SupportsFilter("scale_vaapi")
                   && _mediaEncoder.SupportsFilter("deinterlace_vaapi")
                   && _mediaEncoder.SupportsFilter("tonemap_vaapi")
                   && _mediaEncoder.SupportsFilter("procamp_vaapi")
                   && _mediaEncoder.SupportsFilterWithOption(FilterOptionType.OverlayVaapiFrameSync)
                   && _mediaEncoder.SupportsFilter("hwupload_vaapi");
        }

Note that these are just observations. I do not know if this is the root of the problem, but they might indicate a potential issue. I am not an expert in drm, ffmpeg, or related subjects.

Thefrank commented 6 months ago

@gmsotavio The changes I tried were to add OperatingSystem.IsFreeBSD() to the OS checks under the VAAPI support checks and to create and use a isFreeBSD to be added to cases where that is used over the OperatingSystem call. This should have been enough but clearly was not :(

If the Jellyfin version of FFmpeg has additonal filters, it might be why the checks are also failing but looking at the configure for FFmpeg 6.1 all of the same filters and filter options appear in it that jellyfin tries to find. Other media players on FreeBSD use VAAPI and/or QSV without issue. This is something very specific to Jellyfin that I missing.

I should have some more time over the weekend to dig into this.

rbev commented 3 months ago

Did you get any further with this, I'm pretty keen to get this working

Thefrank commented 2 months ago

Did you get any further with this, I'm pretty keen to get this working

I rebuild the server and web parts with some more patching if you want to try it: https://github.com/Thefrank/jellyfin-server-freebsd/releases/tag/jellyfin-vaapi-test

rbev commented 2 months ago

unfortunately it didn't work

from the logs it seems to have decided not to enable hardware acceleration

ffmpeg -analyzeduration 200M -probesize 1G -fflags +genpts  -i file:"/mnt/movies/REDACTED.mkv" -map_metadata -1 -map_chapters -1 -threads 0 -map 0:1 -map 0:0 -map -0:s -codec:v:0 copy -bsf:v h264_mp4toannexb -start_at_zero -codec:a:0 aac -ac 2 -ab 384000 -af "volume=2" -copyts -avoid_negative_ts disabled -max_muxing_queue_size 2048 -f hls -max_delay 5000000 -hls_time 6 -hls_segment_type fmp4 -hls_fmp4_init_filename "ae85d71fca545860cfb3aa43da9aa0fd-1.mp4" -start_number 0 -hls_segment_filename "/var/db/jellyfin/transcodes/ae85d71fca545860cfb3aa43da9aa0fd%d.mp4" -hls_playlist_type vod -hls_list_size 0 -y "/var/db/jellyfin/transcodes/ae85d71fca545860cfb3aa43da9aa0fd.m3u8"

ffmpeg version 6.1.1 Copyright (c) 2000-2023 the FFmpeg developers
  built with FreeBSD clang version 16.0.6 (https://github.com/llvm/llvm-project.git llvmorg-16.0.6-0-g7cbf1a259152)
  configuration: --prefix=/usr/local --mandir=/usr/local/share/man --datadir=/usr/local/share/ffmpeg --docdir=/usr/local/share/doc/ffmpeg --pkgconfigdir=/usr/local/libdata/pkgconfig --disable-static --disable-libcelt --enable-shared --enable-pic --enable-gpl --cc=cc --cxx=c++ --disable-alsa --disable-libopencore-amrnb --disable-libopencore-amrwb --enable-libaom --disable-libaribb24 --disable-libaribcaption --enable-asm --enable-libass --disable-libbs2b --disable-libcaca --disable-libcdio --disable-libcodec2 --enable-libdav1d --disable-libdavs2 --disable-libdc1394 --disable-debug --enable-htmlpages --enable-libdrm --disable-libfdk-aac --disable-libflite --enable-fontconfig --enable-libfreetype --enable-frei0r --disable-libfribidi --disable-gcrypt --disable-libglslang --disable-libgme --enable-gmp --enable-gnutls --enable-version3 --disable-libgsm --enable-libharfbuzz --enable-iconv --disable-libilbc --disable-libjack --enable-libjxl --disable-libklvanc --disable-libkvazaar --disable-ladspa --enable-libmp3lame --enable-lcms2 --disable-liblensfun --disable-libbluray --enable-libplacebo --disable-librsvg --disable-librtmp --enable-libxml2 --disable-lv2 --disable-mbedtls --disable-libmfx --disable-libmodplug --disable-libmysofa --enable-network --disable-nonfree --enable-nvenc --disable-openal --disable-opencl --disable-opengl --disable-libopenh264 --disable-libopenjpeg --disable-libopenmpt --disable-openssl --disable-libopenvino --enable-optimizations --enable-libopus --disable-pocketsphinx --disable-libpulse --disable-librabbitmq --disable-librav1e --disable-librist --enable-runtime-cpudetect --disable-librubberband --disable-sdl2 --enable-libshaderc --disable-libsmbclient --disable-libsnappy --disable-sndio --disable-libsoxr --disable-libspeex --disable-libsrt --disable-libssh --enable-libsvtav1 --disable-libtensorflow --disable-libtesseract --disable-libtheora --disable-libtwolame --disable-libuavs3d --enable-libv4l2 --enable-vaapi --disable-vapoursynth --enable-vdpau --disable-libvidstab --enable-libvmaf --enable-libvorbis --disable-libvo-amrwbenc --disable-libvpl --enable-libvpx --enable-vulkan --enable-libwebp --enable-libx264 --enable-libx265 --disable-libxavs2 --enable-libxcb --disable-libxvid --disable-outdev=xv --disable-libzimg --disable-libzmq --disable-libzvbi
  libavutil      58. 29.100 / 58. 29.100
  libavcodec     60. 31.102 / 60. 31.102
  libavformat    60. 16.100 / 60. 16.100
  libavdevice    60.  3.100 / 60.  3.100
  libavfilter     9. 12.100 /  9. 12.100
  libswscale      7.  5.100 /  7.  5.100
  libswresample   4. 12.100 /  4. 12.100
  libpostproc    57.  3.100 / 57.  3.100
Input #0, matroska,webm, from 'file:/mnt/movies/REDACTED.mkv':
  Metadata:
    title           : EVO
    encoder         : libebml v1.3.0 + libmatroska v1.4.1
    creation_time   : 2020-03-09T14:10:26.000000Z
  Duration: 01:58:58.62, start: 0.000000, bitrate: 4793 kb/s
  Chapters:
    Chapter #0:0: start 0.000000, end 300.342000
      Metadata:
        title           : 1
    Chapter #0:1: start 300.342000, end 500.333000
      Metadata:
        title           : 2
    Chapter #0:2: start 500.333000, end 807.556000
      Metadata:
        title           : 3
    Chapter #0:3: start 807.556000, end 999.705000
      Metadata:
        title           : 4
    Chapter #0:4: start 999.705000, end 1414.493000
      Metadata:
        title           : 5
    Chapter #0:5: start 1414.493000, end 1829.574000
      Metadata:
        title           : 6
    Chapter #0:6: start 1829.574000, end 2136.546000
      Metadata:
        title           : 7
    Chapter #0:7: start 2136.546000, end 2546.288000
      Metadata:
        title           : 8
    Chapter #0:8: start 2546.288000, end 3095.003000
      Metadata:
        title           : 9
    Chapter #0:9: start 3095.003000, end 3397.220000
      Metadata:
        title           : 10
    Chapter #0:10: start 3397.220000, end 3749.988000
      Metadata:
        title           : 11
    Chapter #0:11: start 3749.988000, end 3994.524000
      Metadata:
        title           : 12
    Chapter #0:12: start 3994.524000, end 4325.228000
      Metadata:
        title           : 13
    Chapter #0:13: start 4325.228000, end 4786.355000
      Metadata:
        title           : 14
    Chapter #0:14: start 4786.355000, end 5328.730000
      Metadata:
        title           : 15
    Chapter #0:15: start 5328.730000, end 5624.357000
      Metadata:
        title           : 16
    Chapter #0:16: start 5624.357000, end 5892.500000
      Metadata:
        title           : 17
    Chapter #0:17: start 5892.500000, end 6104.586000
      Metadata:
        title           : 18
    Chapter #0:18: start 6104.586000, end 6568.216000
      Metadata:
        title           : 19
    Chapter #0:19: start 6568.216000, end 7138.624000
      Metadata:
        title           : 20
  Stream #0:0(eng): Audio: ac3, 48000 Hz, 5.1(side), fltp, 384 kb/s (default)
  Stream #0:1(eng): Video: h264 (High), yuv420p(tv, bt709, progressive), 1920x798 [SAR 1:1 DAR 320:133], 23.98 fps, 23.98 tbr, 1k tbn (default)
Stream mapping:
  Stream #0:1 -> #0:0 (copy)
  Stream #0:0 -> #0:1 (ac3 (native) -> aac (native))
Press [q] to stop, [?] for help
[hls @ 0x14615e831500] Opening '/var/db/jellyfin/transcodes/ae85d71fca545860cfb3aa43da9aa0fd-1.mp4' for writing
Output #0, hls, to '/var/db/jellyfin/transcodes/ae85d71fca545860cfb3aa43da9aa0fd.m3u8':
  Metadata:
    encoder         : Lavf60.16.100
  Stream #0:0: Video: h264 (High), yuv420p(tv, bt709, progressive), 1920x798 [SAR 1:1 DAR 320:133], q=2-31, 23.98 fps, 23.98 tbr, 16k tbn (default)
  Stream #0:1: Audio: aac (LC), 48000 Hz, stereo, fltp, 384 kb/s (default)
    Metadata:
      encoder         : Lavc60.31.102 aac
Thefrank commented 2 months ago

That looks like it is not even trying to make any hw decoding.

I do not have any hardware that does hardware acceleration so it is rather hard to debug what it is seeing.

does ffmpeg correctly use hardware when run manually? Is this setup correctly in jellyfin either through the UI or the config file?

what does your startup look like? Here is mine where it just tests the results of -hwaccels. -filters, and the like

04:34:15] [INF] [1] MediaBrowser.MediaEncoding.Encoder.MediaEncoder: Found ffmpeg version 6.1.1
[04:34:15] [INF] [1] MediaBrowser.MediaEncoding.Encoder.MediaEncoder: Available decoders: ["libdav1d", "av1", "av1_cuvid", "h264", "h264_cuvid", "hevc", "hevc_cuvid", "mpeg2video", "mpeg2_cuvid", "mpeg4", "mpeg4_cuvid", "msmpeg4", "vc1_cuvid", "vp8", "libvpx", "vp8_cuvid", "vp9", "libvpx-vp9", "vp9_cuvid", "aac", "ac3", "dca", "flac", "mp3", "truehd"]
[04:34:15] [INF] [1] MediaBrowser.MediaEncoding.Encoder.MediaEncoder: Available encoders: ["libsvtav1", "av1_nvenc", "av1_vaapi", "libx264", "h264_nvenc", "h264_v4l2m2m", "h264_vaapi", "libx265", "hevc_nvenc", "hevc_vaapi", "mpeg4", "msmpeg4", "libvpx", "libvpx-vp9", "aac", "ac3", "dca", "flac", "libmp3lame", "libopus", "truehd", "libvorbis", "srt"]
[04:34:15] [INF] [1] MediaBrowser.MediaEncoding.Encoder.MediaEncoder: Available filters: ["deinterlace_vaapi", "hwupload_cuda", "libplacebo", "overlay_vaapi", "overlay_vulkan", "procamp_vaapi", "scale_vaapi", "scale_vulkan", "tonemap_vaapi"]
[04:34:15] [WRN] [1] MediaBrowser.MediaEncoding.Encoder.MediaEncoder: Filter: scale_cuda with option Output format (default "same") is not available
[04:34:15] [WRN] [1] MediaBrowser.MediaEncoding.Encoder.MediaEncoder: Filter: tonemap_cuda with option GPU accelerated HDR to SDR tonemapping is not available
[04:34:15] [WRN] [1] MediaBrowser.MediaEncoding.Encoder.MediaEncoder: Filter: tonemap_opencl with option bt2390 is not available
[04:34:15] [WRN] [1] MediaBrowser.MediaEncoding.Encoder.MediaEncoder: Filter: overlay_opencl with option Action to take when encountering EOF from secondary input is not available
[04:34:15] [INF] [1] MediaBrowser.MediaEncoding.Encoder.MediaEncoder: Available hwaccel types: ["vdpau", "cuda", "vaapi", "drm", "vulkan"]
[04:34:15] [INF] [1] MediaBrowser.MediaEncoding.Encoder.MediaEncoder: FFmpeg: ffmpeg

pinging @gmsotavio if you are still around and want to try another build

rbev commented 2 months ago
[2024-04-06 09:13:28.860 +08:00] [INF] [1] MediaBrowser.MediaEncoding.Encoder.MediaEncoder: Found ffmpeg version "6.1.1"
[2024-04-06 09:13:28.894 +08:00] [INF] [1] MediaBrowser.MediaEncoding.Encoder.MediaEncoder: Available "decoders": ["libdav1d", "av1", "av1_cuvid", "h264", "h264_cuvid", "hevc", "hevc_cuvid", "mpeg2video", "mpeg2_cuvid", "mpeg4", "mpeg4_cuvid", "msmpeg4", "vc1_cuvid", "vp8", "libvpx", "vp8_cuvid", "vp9", "libvpx-vp9", "vp9_cuvid", "aac", "ac3", "dca", "flac", "mp3", "truehd"]
[2024-04-06 09:13:28.919 +08:00] [INF] [1] MediaBrowser.MediaEncoding.Encoder.MediaEncoder: Available "encoders": ["libsvtav1", "av1_nvenc", "av1_vaapi", "libx264", "h264_nvenc", "h264_v4l2m2m", "h264_vaapi", "libx265", "hevc_nvenc", "hevc_vaapi", "mpeg4", "msmpeg4", "libvpx", "libvpx-vp9", "aac", "ac3", "dca", "flac", "libmp3lame", "libopus", "truehd", "libvorbis", "srt"]
[2024-04-06 09:13:29.002 +08:00] [INF] [1] MediaBrowser.MediaEncoding.Encoder.MediaEncoder: Available filters: ["deinterlace_vaapi", "hwupload_cuda", "libplacebo", "overlay_vaapi", "overlay_vulkan", "procamp_vaapi", "scale_vaapi", "scale_vulkan", "tonemap_vaapi"]
[2024-04-06 09:13:29.072 +08:00] [WRN] [1] MediaBrowser.MediaEncoding.Encoder.MediaEncoder: Filter: "scale_cuda" with option "Output format (default \"same\")" is not available
[2024-04-06 09:13:29.096 +08:00] [WRN] [1] MediaBrowser.MediaEncoding.Encoder.MediaEncoder: Filter: "tonemap_cuda" with option "GPU accelerated HDR to SDR tonemapping" is not available
[2024-04-06 09:13:29.117 +08:00] [WRN] [1] MediaBrowser.MediaEncoding.Encoder.MediaEncoder: Filter: "tonemap_opencl" with option "bt2390" is not available
[2024-04-06 09:13:29.139 +08:00] [WRN] [1] MediaBrowser.MediaEncoding.Encoder.MediaEncoder: Filter: "overlay_opencl" with option "Action to take when encountering EOF from secondary input" is not available
[2024-04-06 09:13:29.268 +08:00] [INF] [1] MediaBrowser.MediaEncoding.Encoder.MediaEncoder: Available hwaccel types: ["vdpau", "cuda", "vaapi", "drm", "vulkan"]
[2024-04-06 09:13:29.640 +08:00] [INF] [1] MediaBrowser.MediaEncoding.Encoder.MediaEncoder: VAAPI device "/dev/dri/renderD128" is Intel GPU (i965)
[2024-04-06 09:13:29.640 +08:00] [INF] [1] MediaBrowser.MediaEncoding.Encoder.MediaEncoder: FFmpeg: "ffmpeg"
[2024-04-06 09:13:29.641 +08:00] [INF] [1] Emby.Server.Implementations.ApplicationHost: ServerId: "ca427d64187040b080e5ee3edfeddf79"
[2024-04-06 09:13:29.641 +08:00] [INF] [1] Emby.Server.Implementations.ApplicationHost: Core startup complete
[2024-04-06 09:13:29.641 +08:00] [INF] [1] Main: Startup complete 0:00:12.8292809
[2024-04-06 09:13:31.682 +08:00] [INF] [8] Emby.Server.Implementations.ScheduledTasks.TaskManager: "Clean up collections and playlists" Completed after 0 minute(s) and 0 seconds
[2024-04-06 09:13:31.826 +08:00] [ERR] [8] Emby.Server.Implementations.Updates.InstallationManager: An error occurred while accessing the plugin manifest: "https://repo.jellyfin.org/files/plugin/manifest.json"
System.Net.Http.HttpRequestException: Name does not resolve (repo.jellyfin.org:443)

i wonder if my issue is the plugin repo not resolving - which is weird, the jail has raw sockets turned on and has perfectly working network otherwise.

i've also been trying to get opencl working to eliminate that, although i have tone mapping turned off so it shouldn't need it. I can't figure out why opencl doesn't want to work (even outside the jail)

# ffmpeg -v verbose -init_hw_device vaapi=va:/dev/dri/renderD128 -init_hw_device opencl
ffmpeg version 6.1.1 Copyright (c) 2000-2023 the FFmpeg developers
  built with FreeBSD clang version 16.0.6 (https://github.com/llvm/llvm-project.git llvmorg-16.0.6-0-g7cbf1a259152)
  configuration: --prefix=/usr/local --mandir=/usr/local/share/man --datadir=/usr/local/share/ffmpeg --docdir=/usr/local/share/doc/ffmpeg --pkgconfigdir=/usr/local/libdata/pkgconfig --disable-static --disable-libcelt --enable-shared --enable-pic --enable-gpl --cc=cc --cxx=c++ --disable-alsa --disable-libopencore-amrnb --disable-libopencore-amrwb --enable-libaom --disable-libaribb24 --disable-libaribcaption --enable-asm --enable-libass --disable-libbs2b --disable-libcaca --disable-libcdio --disable-libcodec2 --enable-libdav1d --disable-libdavs2 --disable-libdc1394 --disable-debug --enable-htmlpages --enable-libdrm --disable-libfdk-aac --disable-libflite --enable-fontconfig --enable-libfreetype --enable-frei0r --disable-libfribidi --disable-gcrypt --disable-libglslang --disable-libgme --enable-gmp --enable-gnutls --enable-version3 --disable-libgsm --enable-libharfbuzz --enable-iconv --disable-libilbc --disable-libjack --enable-libjxl --disable-libklvanc --disable-libkvazaar --disable-ladspa --enable-libmp3lame --enable-lcms2 --disable-liblensfun --disable-libbluray --enable-libplacebo --disable-librsvg --disable-librtmp --enable-libxml2 --disable-lv2 --disable-mbedtls --disable-libmfx --disable-libmodplug --disable-libmysofa --enable-network --disable-nonfree --enable-nvenc --disable-openal --disable-opencl --disable-opengl --disable-libopenh264 --disable-libopenjpeg --disable-libopenmpt --disable-openssl --disable-libopenvino --enable-optimizations --enable-libopus --disable-pocketsphinx --disable-libpulse --disable-librabbitmq --disable-librav1e --disable-librist --enable-runtime-cpudetect --disable-librubberband --disable-sdl2 --enable-libshaderc --disable-libsmbclient --disable-libsnappy --disable-sndio --disable-libsoxr --disable-libspeex --disable-libsrt --disable-libssh --enable-libsvtav1 --disable-libtensorflow --disable-libtesseract --disable-libtheora --disable-libtwolame --disable-libuavs3d --enable-libv4l2 --enable-vaapi --disable-vapoursynth --enable-vdpau --disable-libvidstab --enable-libvmaf --enable-libvorbis --disable-libvo-amrwbenc --disable-libvpl --enable-libvpx --enable-vulkan --enable-libwebp --enable-libx264 --enable-libx265 --disable-libxavs2 --enable-libxcb --disable-libxvid --disable-outdev=xv --disable-libzimg --disable-libzmq --disable-libzvbi
  libavutil      58. 29.100 / 58. 29.100
  libavcodec     60. 31.102 / 60. 31.102
  libavformat    60. 16.100 / 60. 16.100
  libavdevice    60.  3.100 / 60.  3.100
  libavfilter     9. 12.100 /  9. 12.100
  libswscale      7.  5.100 /  7.  5.100
  libswresample   4. 12.100 /  4. 12.100
  libpostproc    57.  3.100 / 57.  3.100
[AVHWDeviceContext @ 0x73855619100] libva: VA-API version 1.20.0
[AVHWDeviceContext @ 0x73855619100] libva: Trying to open /usr/local/lib/dri/iHD_drv_video.so
[AVHWDeviceContext @ 0x73855619100] libva: va_openDriver() returns -1
[AVHWDeviceContext @ 0x73855619100] libva: Trying to open /usr/local/lib/dri/i965_drv_video.so
[AVHWDeviceContext @ 0x73855619100] libva: Found init function __vaDriverInit_1_20
[AVHWDeviceContext @ 0x73855619100] libva: va_openDriver() returns 0
[AVHWDeviceContext @ 0x73855619100] Initialised VAAPI connection: version 1.20
[AVHWDeviceContext @ 0x73855619100] VAAPI driver: Intel i965 driver for Intel(R) Coffee Lake - 2.4.1.
[AVHWDeviceContext @ 0x73855619100] Driver not found in known nonstandard list, using standard behaviour.
Device creation failed: -12.
Failed to set value 'opencl' for option 'init_hw_device': Cannot allocate memory
Error parsing global options: Cannot allocate memory
rbev commented 2 months ago

host resolves fine inside the jail -

# ping repo.jellyfin.org
PING elb1.jellyfin.org (68.183.204.194): 56 data bytes
64 bytes from 68.183.204.194: icmp_seq=0 ttl=49 time=261.937 ms
64 bytes from 68.183.204.194: icmp_seq=1 ttl=49 time=260.705 ms
Thefrank commented 2 months ago

@rbev DNS name resolution errors (and some other network errors) can be caused by jellyfin's library monitoring. Try turning that off

The good news is that jellyfin DOES see a valid VAAPI device so it should be able to use it as a VAAPI device. Same with ffmpeg it does appear to see a VAAPI device. Neither jellyfin nor ffmpeg see a valid opencl device :(

rbev commented 2 months ago

Yeah i posted some logs on the freebsd forums puzzled about why i couldn't get opencl working on this igpu. I'd have to look at jellyfin's code but from what i can tell you don't need that working to use transcoding with VAAPI, only if you need to do tone mapping (which i've turned off)

In case it helps - here's my transcoding settings:

giant screenshot

rbev commented 2 months ago

I did another restart and it looks like i get a clean startup now


[2024-04-06 13:53:50.894 +08:00] [INF] [1] MediaBrowser.MediaEncoding.Encoder.MediaEncoder: Found ffmpeg version "6.1.1"
[2024-04-06 13:53:50.927 +08:00] [INF] [1] MediaBrowser.MediaEncoding.Encoder.MediaEncoder: Available "decoders": ["libdav1d", "av1", "av1_cuvid", "h264", "h264_cuvid", "hevc", "hevc_cuvid", "mpeg2video", "mpeg2_cuvid", "mpeg4", "mpeg4_cuvid", "msmpeg4", "vc1_cuvid", "vp8", "libvpx", "vp8_cuvid", "vp9", "libvpx-vp9", "vp9_cuvid", "aac", "ac3", "dca", "flac", "mp3", "truehd"]
[2024-04-06 13:53:50.949 +08:00] [INF] [1] MediaBrowser.MediaEncoding.Encoder.MediaEncoder: Available "encoders": ["libsvtav1", "av1_nvenc", "av1_vaapi", "libx264", "h264_nvenc", "h264_v4l2m2m", "h264_vaapi", "libx265", "hevc_nvenc", "hevc_vaapi", "mpeg4", "msmpeg4", "libvpx", "libvpx-vp9", "aac", "ac3", "dca", "flac", "libmp3lame", "libopus", "truehd", "libvorbis", "srt"]
[2024-04-06 13:53:50.984 +08:00] [INF] [1] MediaBrowser.MediaEncoding.Encoder.MediaEncoder: Available filters: ["deinterlace_vaapi", "hwupload_cuda", "libplacebo", "overlay_vaapi", "overlay_vulkan", "procamp_vaapi", "scale_vaapi", "scale_vulkan", "tonemap_vaapi"]
[2024-04-06 13:53:51.006 +08:00] [WRN] [1] MediaBrowser.MediaEncoding.Encoder.MediaEncoder: Filter: "scale_cuda" with option "Output format (default \"same\")" is not available
[2024-04-06 13:53:51.026 +08:00] [WRN] [1] MediaBrowser.MediaEncoding.Encoder.MediaEncoder: Filter: "tonemap_cuda" with option "GPU accelerated HDR to SDR tonemapping" is not available
[2024-04-06 13:53:51.045 +08:00] [WRN] [1] MediaBrowser.MediaEncoding.Encoder.MediaEncoder: Filter: "tonemap_opencl" with option "bt2390" is not available
[2024-04-06 13:53:51.064 +08:00] [WRN] [1] MediaBrowser.MediaEncoding.Encoder.MediaEncoder: Filter: "overlay_opencl" with option "Action to take when encountering EOF from secondary input" is not available
[2024-04-06 13:53:51.123 +08:00] [INF] [1] MediaBrowser.MediaEncoding.Encoder.MediaEncoder: Available hwaccel types: ["vdpau", "cuda", "vaapi", "drm", "vulkan"]
[2024-04-06 13:53:51.511 +08:00] [INF] [1] MediaBrowser.MediaEncoding.Encoder.MediaEncoder: VAAPI device "/dev/dri/renderD128" is Intel GPU (i965)
[2024-04-06 13:53:51.511 +08:00] [INF] [1] MediaBrowser.MediaEncoding.Encoder.MediaEncoder: FFmpeg: "ffmpeg"
[2024-04-06 13:53:51.513 +08:00] [INF] [1] Emby.Server.Implementations.ApplicationHost: ServerId: "ca427d64187040b080e5ee3edfeddf79"
[2024-04-06 13:53:51.513 +08:00] [INF] [1] Emby.Server.Implementations.ApplicationHost: Core startup complete
[2024-04-06 13:53:51.514 +08:00] [INF] [1] Main: Startup complete 0:00:05.0078485
[2024-04-06 13:53:53.890 +08:00] [INF] [10] Emby.Server.Implementations.ScheduledTasks.TaskManager: "Clean up collections and playlists" Completed after 0 minute(s) and 0 seconds
[2024-04-06 13:53:55.244 +08:00] [INF] [16] Emby.Server.Implementations.ScheduledTasks.TaskManager: "Update Plugins" Completed after 0 minute(s) and 1 seconds
[2024-04-06 13:53:56.151 +08:00] [INF] [18] Emby.Server.Implementations.HttpServer.WebSocketManager: WS "192.168.1.1" request

no plugin errors - but still not hwaccel

Thefrank commented 2 months ago

Hrm. I have no idea why it does not even bother to use hwaccel despite detecting it.

For your opencl try ffmpeg -v verbose -init_hw_device vaapi=va:/dev/dri/renderD128 -init_hw_device opencl@va

rbev commented 2 months ago

Same as above, vaapi works fine and then it prints this error for opencl:

Device creation failed: -12.
Failed to set value 'opencl@va' for option 'init_hw_device': Cannot allocate memory
Error parsing global options: Cannot allocate memory

and its the same thing outside the jail running as root

rbev commented 2 months ago
$ clinfo
Number of platforms                               0

ICD loader properties
  ICD loader Name                                 OpenCL ICD Loader
  ICD loader Vendor                               OCL Icd free software
  ICD loader Version                              2.3.1
  ICD loader Profile                              OpenCL 3.0
Thefrank commented 2 months ago

clinfo does not even see the device so things like ffmpeg and jellyfin wont see it either. Does jellyfin try to use VAAPI at all in the logs? I am confused why it does not even try to use vaapi

rbev commented 2 months ago

I see absolutely nothing in the logs about it attempting to use vaapi - it seems like it's deciding it can't use it.

[2024-04-06 13:56:34.093 +08:00] [INF] [3] Emby.Server.Implementations.HttpServer.WebSocketManager: WS "192.168.1.1" request
[2024-04-06 13:56:35.786 +08:00] [INF] [25] Jellyfin.Api.Helpers.MediaInfoHelper: User policy for "REDACTED". EnablePlaybackRemuxing: True EnableVideoPlaybackTranscoding: True EnableAudioPlaybackTranscoding: True
[2024-04-06 13:56:36.355 +08:00] [INF] [3] Jellyfin.Api.Controllers.DynamicHlsController: Current HLS implementation doesn't support non-keyframe breaks but one is requested, ignoring that request
[2024-04-06 13:56:36.366 +08:00] [INF] [3] MediaBrowser.MediaEncoding.Transcoding.TranscodeManager: "ffmpeg" "-analyzeduration 200M -probesize 1G -fflags +genpts  -i file:\"/mnt/movies/REDACTED.mkv\" -map_metadata -1 -map_chapters -1 -threads 0 -map 0:1 -map 0:0 -map -0:s -codec:v:0 copy -bsf:v h264_mp4toannexb -start_at_zero -codec:a:0 aac -ac 2 -ab 384000 -af \"volume=2\" -copyts -avoid_negative_ts disabled -max_muxing_queue_size 2048 -f hls -max_delay 5000000 -hls_time 6 -hls_segment_type fmp4 -hls_fmp4_init_filename \"7ef1ddf23b364357d8dd1b54a07d2bb5-1.mp4\" -start_number 0 -hls_segment_filename \"/var/db/jellyfin/transcodes/7ef1ddf23b364357d8dd1b54a07d2bb5%d.mp4\" -hls_playlist_type vod -hls_list_size 0 -y \"/var/db/jellyfin/transcodes/7ef1ddf23b364357d8dd1b54a07d2bb5.m3u8\""
[2024-04-06 13:56:43.828 +08:00] [INF] [3] Emby.Server.Implementations.HttpServer.WebSocketManager: WS "192.168.1.1" closed
[2024-04-06 13:56:44.464 +08:00] [INF] [3] Emby.Server.Implementations.HttpServer.WebSocketManager: WS "192.168.1.1" request
[2024-04-06 13:56:47.815 +08:00] [INF] [23] MediaBrowser.Controller.MediaEncoding.TranscodingJob: Stopping ffmpeg process with q command for "/var/db/jellyfin/transcodes/

and the transcode logs don't mention the drm device or vaapi outside of the printout of compile flags on startup (which i've pasted previously)

rbev commented 2 months ago

i can probably enable debug logging and restart - let me look up how to do that

edit: nothing enlightening in the debug logs

rbev commented 2 months ago

Doing some more reading of the jellyfin code it looks like the lack of openCL is my problem

https://github.com/jellyfin/jellyfin/blob/c87c26d33acbe63b623182112bf4ec6ddf0d2bbe/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs#L4405

from what i can tell here it falls back to a software decoding path unconditionally if there is no openCL available, and it's not doing the extra branch on line on 4425 to add the hardware encode to the end of it.

I'll spend some more time working out why opencl isn't working for me

rbev commented 2 months ago

I've started to lose hope -

I've narrowed my OpenCL issue down to this: https://github.com/FreeBSDDesktop/kms-drm/issues/197 which appears to be a problem I can't fix myself

jbeich commented 2 months ago

Try Rusticl instead as described in https://github.com/freebsd/freebsd-ports/commit/d8990eff958b

$ pkg install mesa-devel
$ export RUSTICL_ENABLE=iris
$ clinfo
rbev commented 2 months ago

ok, that fixes clinfo but it doesn't change ffmpeg's behaviour it's at least something to move forward on

MACVTi commented 2 months ago

I think there is a typo in the jellyfin.diff patch that is preventing hardware acceleration from being detected properly.

When Jellyfin checks if the operating system is Linux, it uses if(isLinux) for the positive case and if(!isLinux) for the negative case. When the patch adds FreeBSD to these checks, it uses if(isLinux || isFreeBSD) for the positive case which is correct, but uses if(!isLinux || !isFreeBSD) which is is incorrect.

Rephrasing this using De Morgan's (https://en.wikipedia.org/wiki/De_Morgan%27s_laws), This statement becomes if(!(isLinux && isFreeBSD), which is much easier to see the issues as the operating system can't be Linux and FreeBSD at the same time, resulting in the inner statement always being false, causing this if statement to always be taken. This causes the VAAPI checks to always return false and prevents the required flags being added to the FFMPEG command.

To fix this, The patch lines containing if(!isLinux || !isFreeBSD) should be converted to if(!(isLinux || isFreeBSD)), which will return true only if the OS isn't Linux or FreeBSD, which I believe is the intended behaviour of this patch.

For the patch file itself, line 17 adds +if ((!isLinux || !isFreeBSD) || !_mediaEncoder.SupportsHwaccel("vaapi"))and line 50 adds if ((!OperatingSystem.IsLinux() || !OperatingSystem.IsFreeBSD()) to MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs. Similarly, line 63if (!OperatingSystem.IsLinux() || !OperatingSystem.IsFreeBSD()) to MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs.

I don't have time to build the code with the fixes myself but I believe this should be enough to get VAAPI working.

Thefrank commented 2 months ago

@MACVTi good catch!

that diff is a bit out of date and does contain that logic flaw. The newest experimental binaries from ~2wk ago should have corrected logic.

Back in college I took a whole course on logic so it is rather embarrassing that it happened in the first place >.<

edit:

but yes ¬ ( a ∧ b ∧ c ) ∨ ¬ d is easier to parse by humans than ( ¬ a ∧ ¬ b ∧ ¬ c ) ∨ ¬ d

MACVTi commented 2 months ago

Don't worry, I had to do some googling to remember it too! 😄

I'm only after seeing the VAAPI test release there now after you mentioned that test build in your previous comment. I've tested it on my computer and I can confirm that VAAPI is working for my AMD Raven Ridge GPU (Integrated graphics on AMD 3200G) on FreeBSD 14 with drm-515-kmod and the Mesa Gallium driver 24.0.4. The device is also correctly detected in the logs.

[2024-04-23 10:44:12.345 +01:00] [INF] [1] MediaBrowser.MediaEncoding.Encoder.MediaEncoder: Available hwaccel types: ["vdpau", "cuda", "vaapi", "drm", "vulkan"] [2024-04-23 10:44:13.151 +01:00] [INF] [1] MediaBrowser.MediaEncoding.Encoder.MediaEncoder: VAAPI device "/dev/dri/renderD128" is AMD GPU [2024-04-23 10:44:13.152 +01:00] [INF] [1] MediaBrowser.MediaEncoding.Encoder.MediaEncoder: VAAPI device "/dev/dri/renderD128" supports Vulkan DRM interop [2024-04-23 10:44:13.152 +01:00] [INF] [1] MediaBrowser.MediaEncoding.Encoder.MediaEncoder: FFmpeg: "ffmpeg"

Is it possible to get this change merged into the binary that is distributed on the FreeBSD Ports or do you want testing from the other available VAAPI devices first? Looking at the logic of Jellyfin, they should work if the AMD GPU works, but I can understand if you'd prefer testing each device before adding it.

(I posted this by accident on my work account originally in case you see a duplicate comment @Thefrank )

Thefrank commented 2 months ago

@MACVTi

A couple of reason:

I want to make sure that I have correctly applied all of the patches before pushing out a new binary so it will remain a test until I get some feedback. QSV should work for Intel CPUs.

The test version is based off the upstream master branch which should be an actual release soon(tm).

The 10.8.x branch and tags throw NuGet security errors when building. These are easy to fix by bumping the versions of the depneds but I don't want to break something else while doing so.

MACVTi commented 2 months ago

That's understandable. Now that you say it, the version is 10.9.0, not 10.8.9 as I first read it. The release date on the Github page threw me off again! :)

If you want, I probably have a few Intel computers lying around so I should be able to try VA-API and QSV support for Intel in the next day or two if that's any help? I think that covers most of the configurations of HW Acceleration thats on FreeBSD anyway? (Maybe the raspberry pi but I'm not sure if drivers are available for FreeBSD). If you have a list of configurations that you'd like to get feedback on, I could see what I could do.

Also for my own curiosity, do you think there'd be much work in converting the port to be a true source port? I'm not too familiar with .NET myself to be honest. It would just be handy as we could submit pull requests with code we could test rather than having to hassle you!

Thefrank commented 2 months ago

If you want, I probably have a few Intel computers lying around so I should be able to try VA-API and QSV support for Intel in the next day or two if that's any help? I think that covers most of the configurations of HW Acceleration thats on FreeBSD anyway? (Maybe the raspberry pi but I'm not sure if drivers are available for FreeBSD). If you have a list of configurations that you'd like to get feedback on, I could see what I could do.

VAAPI and QSV are the ones mostly used by other mediaplayers on FreeBSD so those would be the best/first to try. If there is demand for it, I can look at CUDA and Vulkan.

Also for my own curiosity, do you think there'd be much work in converting the port to be a true source port?

It can be rather tedious to get setup initially. Maintaining is easier but requires manually updating all of the version numbers from the NuGet packages it uses. You can look at https://github.com/freebsd/freebsd-ports/tree/6dbb66a12e23526f7dc4f43f8c2cf7ae58f4be9f/devel/msbuild or https://github.com/Thefrank/freebsd-dotnet-sourcebuild/blob/main/PortWIP/dotNET8/Makefile if you want some examples. ASLR needs to be turned off and mlock needs to be allowed in the build environment for dotNET builds. Jellyfin is further complicated by using SkiaSharp which requires Google's tooling to build.

This SOUNDS very complicated but it is mostly just a massive time sink.

I'm not too familiar with .NET myself to be honest. It would just be handy as we could submit pull requests with code we could test rather than having to hassle you!

I need to get something setup to make contributions outside of documentation updates easier.