git: 0da0b753e5de - main - multimedia/jellyfin-ffmpeg: opencl needed for Jellyfin's HDR tone mapping

From: Olivier Cochard <olivier_at_FreeBSD.org>
Date: Fri, 25 Sep 2026 21:21:31 UTC
The branch main has been updated by olivier:

URL: https://cgit.FreeBSD.org/ports/commit/?id=0da0b753e5de47efa15eba722e70960635595184

commit 0da0b753e5de47efa15eba722e70960635595184
Author:     Olivier Cochard <olivier@FreeBSD.org>
AuthorDate: 2026-09-25 18:27:57 +0000
Commit:     Olivier Cochard <olivier@FreeBSD.org>
CommitDate: 2026-09-25 21:18:24 +0000

    multimedia/jellyfin-ffmpeg: opencl needed for Jellyfin's HDR tone mapping
    
    Jellyfin does AMD VAAPI HDR tone mapping with libplacebo, not OpenCL. However,
    EncodingHelper.GetVaapiVidFilterChain() has an early-exit guard before it ever
    selects the AMD branch
    
    It need 2 patches:
    - OpenCL (Jellyfin's IsOpenclFullSupported gate)
    - overlay_vulkan framesync patch (Jellyfin's IsVulkanFullSupported gate)
    
    PR:             298857
    Approved by:    Michael Johnson <michaeljohnson@ahze.net> (maintainer)
---
 multimedia/jellyfin-ffmpeg/Makefile                | 10 +++++--
 .../files/extra-patch-overlay_vulkan-framesync     | 34 ++++++++++++++++++++++
 2 files changed, 42 insertions(+), 2 deletions(-)

diff --git a/multimedia/jellyfin-ffmpeg/Makefile b/multimedia/jellyfin-ffmpeg/Makefile
index 32a40449e5f4..3f0908f87cf5 100644
--- a/multimedia/jellyfin-ffmpeg/Makefile
+++ b/multimedia/jellyfin-ffmpeg/Makefile
@@ -1,5 +1,6 @@
 PORTNAME=	jellyfin-ffmpeg
 PORTVERSION=	8.1.2.5
+PORTREVISION=	1
 CATEGORIES=	multimedia
 
 MAINTAINER=	michaeljohnson@ahze.net
@@ -15,9 +16,11 @@ ONLY_FOR_ARCHS_REASON=	upstream jellyfin-ffmpeg targets 64-bit; 32-bit builds no
 BUILD_DEPENDS=	nasm:devel/nasm \
 		${LOCALBASE}/include/fftw3.h:math/fftw3 \
 		${LOCALBASE}/lib/libfftw3f.a:math/fftw3-float \
-		${LOCALBASE}/include/vulkan/vulkan.h:graphics/vulkan-headers
+		${LOCALBASE}/include/vulkan/vulkan.h:graphics/vulkan-headers \
+		${LOCALBASE}/include/CL/cl.h:devel/opencl
 PATCH_DEPENDS=	quilt:devel/quilt
-LIB_DEPENDS=	libass.so:multimedia/libass \
+LIB_DEPENDS=	libOpenCL.so:devel/ocl-icd \
+		libass.so:multimedia/libass \
 		libbluray.so:multimedia/libbluray \
 		libdav1d.so:multimedia/dav1d \
 		libfdk-aac.so:audio/fdk-aac \
@@ -68,6 +71,8 @@ JFFMPEG_DIR=	${PREFIX}/lib/jellyfin-ffmpeg8
 post-patch:
 	cd ${WRKSRC} && QUILT_PATCHES=debian/patches quilt push -a || \
 	    QUILT_PATCHES=debian/patches quilt applied | ${GREP} -q 0098
+	cd ${WRKSRC} && ${PATCH} -p0 --forward --quiet \
+	    < ${FILESDIR}/extra-patch-overlay_vulkan-framesync
 
 # Static chromaprint on fftw3f, as upstream's builder does: audio/chromaprint
 # links multimedia/ffmpeg for its FFT, dragging a second FFmpeg and ~30 other
@@ -138,6 +143,7 @@ CONFIGURE_ARGS=	--prefix="${JFFMPEG_DIR}" \
 		--enable-libx265 \
 		--enable-libzimg \
 		--enable-libzvbi \
+		--enable-opencl \
 		--enable-libplacebo \
 		--enable-libshaderc \
 		--enable-vulkan \
diff --git a/multimedia/jellyfin-ffmpeg/files/extra-patch-overlay_vulkan-framesync b/multimedia/jellyfin-ffmpeg/files/extra-patch-overlay_vulkan-framesync
new file mode 100644
index 000000000000..7d24333c7d2b
--- /dev/null
+++ b/multimedia/jellyfin-ffmpeg/files/extra-patch-overlay_vulkan-framesync
@@ -0,0 +1,34 @@
+Expose the framesync options on overlay_vulkan.
+
+The filter already drives framesync internally (ff_framesync_init_dualinput,
+ff_framesync_configure, ff_framesync_activate) but declares its AVClass with
+AVFILTER_DEFINE_CLASS, so eof_action/shortest/repeatlast are never advertised
+and framesync's option defaults are never initialised. Every other overlay_*
+filter (overlay, overlay_vaapi, overlay_opencl, overlay_cuda) uses
+FRAMESYNC_DEFINE_CLASS together with a .preinit callback.
+
+Beyond the missing functionality, Jellyfin probes overlay_vulkan for the
+"Action to take when encountering EOF from secondary input" option to decide
+whether the Vulkan filter chain is usable. Without it IsVulkanFullSupported()
+returns false, Jellyfin falls back to a VAAPI pipeline with no HDR tone
+mapping, and HDR content is transcoded to SDR untonemapped (washed out).
+
+--- libavfilter/vf_overlay_vulkan.c.orig
++++ libavfilter/vf_overlay_vulkan.c
+@@ -231,7 +231,7 @@
+     { NULL },
+ };
+ 
+-AVFILTER_DEFINE_CLASS(overlay_vulkan);
++FRAMESYNC_DEFINE_CLASS(overlay_vulkan, OverlayVulkanContext, fs);
+ 
+ static const AVFilterPad overlay_vulkan_inputs[] = {
+     {
+@@ -265,6 +265,7 @@
+     .init           = &overlay_vulkan_init,
+     .uninit         = &overlay_vulkan_uninit,
+     .activate       = &overlay_vulkan_activate,
++    .preinit        = overlay_vulkan_framesync_preinit,
+     FILTER_INPUTS(overlay_vulkan_inputs),
+     FILTER_OUTPUTS(overlay_vulkan_outputs),
+     FILTER_SINGLE_PIXFMT(AV_PIX_FMT_VULKAN),