diff --git a/build.yaml b/build.yaml index f1be4fbd614..a7aaf36da7c 100644 --- a/build.yaml +++ b/build.yaml @@ -1,7 +1,7 @@ --- # We just wrap `build` so this is really it name: "jellyfin-ffmpeg" -version: "6.0-4" +version: "6.0-5" packages: - buster-amd64 - buster-armhf diff --git a/builder/scripts.d/10-mingw-std-threads.sh b/builder/scripts.d/10-mingw-std-threads.sh index ad55011c5d2..a45c69e6a31 100755 --- a/builder/scripts.d/10-mingw-std-threads.sh +++ b/builder/scripts.d/10-mingw-std-threads.sh @@ -1,7 +1,7 @@ #!/bin/bash SCRIPT_REPO="https://github.com/meganz/mingw-std-threads.git" -SCRIPT_COMMIT="6c2061b7da41d6aa1b2162ff4383ec3ece864bc6" +SCRIPT_COMMIT="c931bac289dd431f1dd30fc4a5d1a7be36668073" ffbuild_enabled() { [[ $TARGET == win* ]] || return -1 diff --git a/builder/scripts.d/20-libxml2.sh b/builder/scripts.d/20-libxml2.sh index 81b7bb6c835..986d308e3ae 100755 --- a/builder/scripts.d/20-libxml2.sh +++ b/builder/scripts.d/20-libxml2.sh @@ -1,7 +1,7 @@ #!/bin/bash SCRIPT_REPO="https://github.com/GNOME/libxml2.git" -SCRIPT_COMMIT="884474477284474e0151280aaa275a18e3d7a036" +SCRIPT_COMMIT="58de9d31da4d0e8cb6bcf7f5e99714f9df2c4411" ffbuild_enabled() { return 0 diff --git a/builder/scripts.d/25-fftw3f.sh b/builder/scripts.d/25-fftw3f.sh index e1751e87dc3..c8d9abf25ef 100755 --- a/builder/scripts.d/25-fftw3f.sh +++ b/builder/scripts.d/25-fftw3f.sh @@ -1,7 +1,7 @@ #!/bin/bash SCRIPT_REPO="https://github.com/FFTW/fftw3.git" -SCRIPT_COMMIT="0842f00ae6b6e1f3aade155bc0edd17a7313fa6a" +SCRIPT_COMMIT="69f6c1a6ebd7ac5af33e7074134fb79fbc729c3d" ffbuild_enabled() { # Dependency of GPL-Only librubberband diff --git a/builder/scripts.d/25-freetype.sh b/builder/scripts.d/25-freetype.sh index bf1d9abcc6d..89f4af8a74b 100755 --- a/builder/scripts.d/25-freetype.sh +++ b/builder/scripts.d/25-freetype.sh @@ -1,7 +1,7 @@ #!/bin/bash SCRIPT_REPO="https://gitlab.freedesktop.org/freetype/freetype.git" -SCRIPT_COMMIT="e4586d960f339cf75e2e0b34aee30a0ed8353c0d" +SCRIPT_COMMIT="95a872085e5a79cf710acf6389dbd55b6e728aac" ffbuild_enabled() { return 0 diff --git a/builder/scripts.d/25-gmp.sh b/builder/scripts.d/25-gmp.sh index 23bbeb4e9f7..bcdd1d37b67 100755 --- a/builder/scripts.d/25-gmp.sh +++ b/builder/scripts.d/25-gmp.sh @@ -1,7 +1,7 @@ #!/bin/bash -SCRIPT_VERSION="6.2.1" -SCRIPT_SHA512="c99be0950a1d05a0297d65641dd35b75b74466f7bf03c9e8a99895a3b2f9a0856cd17887738fa51cf7499781b65c049769271cbcb77d057d2e9f1ec52e07dd84" +SCRIPT_VERSION="6.3.0" +SCRIPT_SHA512="e85a0dab5195889948a3462189f0e0598d331d3457612e2d3350799dba2e244316d256f8161df5219538eb003e4b5343f989aaa00f96321559063ed8c8f29fd2" SCRIPT_URL="https://ftp.gnu.org/gnu/gmp/gmp-${SCRIPT_VERSION}.tar.xz" ffbuild_enabled() { diff --git a/builder/scripts.d/25-openssl.sh b/builder/scripts.d/25-openssl.sh index 4e02ec113fc..435c5346a83 100755 --- a/builder/scripts.d/25-openssl.sh +++ b/builder/scripts.d/25-openssl.sh @@ -1,7 +1,7 @@ #!/bin/bash SCRIPT_REPO="https://github.com/openssl/openssl.git" -SCRIPT_COMMIT="OpenSSL_1_1_1u" +SCRIPT_COMMIT="OpenSSL_1_1_1v" SCRIPT_TAGFILTER="OpenSSL_1_1_1*" ffbuild_enabled() { diff --git a/builder/scripts.d/25-xz.sh b/builder/scripts.d/25-xz.sh index f5412c5ddd6..496f79884cc 100755 --- a/builder/scripts.d/25-xz.sh +++ b/builder/scripts.d/25-xz.sh @@ -1,7 +1,7 @@ #!/bin/bash SCRIPT_REPO="https://github.com/xz-mirror/xz.git" -SCRIPT_COMMIT="dbb3a536ed9873ffa0870321f6873e564c6a9da8" +SCRIPT_COMMIT="16068f6c30b888cdb873f6285af941d00f95741d" ffbuild_enabled() { return 0 diff --git a/builder/scripts.d/35-fontconfig.sh b/builder/scripts.d/35-fontconfig.sh index 6d2bdec3ec9..4d0b044a9e8 100755 --- a/builder/scripts.d/35-fontconfig.sh +++ b/builder/scripts.d/35-fontconfig.sh @@ -1,7 +1,7 @@ #!/bin/bash SCRIPT_REPO="https://gitlab.freedesktop.org/fontconfig/fontconfig.git" -SCRIPT_COMMIT="7e2a1b2577e8d90ea5be3f14091e809ac7742438" +SCRIPT_COMMIT="2fb3419a92156569bc1ec707401258c922cd0d99" ffbuild_enabled() { return 0 diff --git a/builder/scripts.d/45-harfbuzz.sh b/builder/scripts.d/45-harfbuzz.sh index 2832a5aa619..a36c5824bf7 100755 --- a/builder/scripts.d/45-harfbuzz.sh +++ b/builder/scripts.d/45-harfbuzz.sh @@ -1,7 +1,7 @@ #!/bin/bash SCRIPT_REPO="https://github.com/harfbuzz/harfbuzz.git" -SCRIPT_COMMIT="d4bbe3f48663944385f25f608438e1eb678fc4b7" +SCRIPT_COMMIT="1d665c2b521512cdd56964138fc601debd1f1177" ffbuild_enabled() { return 0 diff --git a/builder/scripts.d/45-x11/10-xcbproto.sh b/builder/scripts.d/45-x11/10-xcbproto.sh index 894477d4d81..50330efef03 100755 --- a/builder/scripts.d/45-x11/10-xcbproto.sh +++ b/builder/scripts.d/45-x11/10-xcbproto.sh @@ -1,7 +1,7 @@ #!/bin/bash SCRIPT_REPO="https://gitlab.freedesktop.org/xorg/proto/xcbproto.git" -SCRIPT_COMMIT="cfcc51836c1f2c174b67073cc8bed92e7e9c9569" +SCRIPT_COMMIT="b016df100111b56d7c1a2c63ea6791b2287a83e4" ffbuild_enabled() { [[ $TARGET != linux* ]] && return -1 diff --git a/builder/scripts.d/45-x11/10-xproto.sh b/builder/scripts.d/45-x11/10-xproto.sh index b79c2deaafd..ca041b5bf5f 100755 --- a/builder/scripts.d/45-x11/10-xproto.sh +++ b/builder/scripts.d/45-x11/10-xproto.sh @@ -1,7 +1,7 @@ #!/bin/bash SCRIPT_REPO="https://gitlab.freedesktop.org/xorg/proto/xorgproto.git" -SCRIPT_COMMIT="766967322209f2dcb72e6a8edea0c651f586201d" +SCRIPT_COMMIT="704a75eecdf177a8b18ad7e35813f2f979b0c277" ffbuild_enabled() { [[ $TARGET != linux* ]] && return -1 diff --git a/builder/scripts.d/45-x11/20-libxau.sh b/builder/scripts.d/45-x11/20-libxau.sh index 4c2e8beebbc..ab39b2c95c5 100755 --- a/builder/scripts.d/45-x11/20-libxau.sh +++ b/builder/scripts.d/45-x11/20-libxau.sh @@ -1,7 +1,7 @@ #!/bin/bash SCRIPT_REPO="https://gitlab.freedesktop.org/xorg/lib/libxau.git" -SCRIPT_COMMIT="df1bf4fe528a5a9eef420f78efb225e4696ac467" +SCRIPT_COMMIT="68e74d37b99f56bbd1a5f2fb8cb4ad6116f27bd3" ffbuild_enabled() { [[ $TARGET != linux* ]] && return -1 diff --git a/builder/scripts.d/45-x11/30-libxcb.sh b/builder/scripts.d/45-x11/30-libxcb.sh index 726f98f469c..f138fe14136 100755 --- a/builder/scripts.d/45-x11/30-libxcb.sh +++ b/builder/scripts.d/45-x11/30-libxcb.sh @@ -1,7 +1,7 @@ #!/bin/bash SCRIPT_REPO="https://gitlab.freedesktop.org/xorg/lib/libxcb.git" -SCRIPT_COMMIT="8935793f1f3751a6aa9d78955c7d6236177986de" +SCRIPT_COMMIT="038636786ad1914f3daf3503ae9611f40dffbb8f" ffbuild_enabled() { [[ $TARGET != linux* ]] && return -1 diff --git a/builder/scripts.d/45-x11/40-libx11.sh b/builder/scripts.d/45-x11/40-libx11.sh index abd0ae4d65d..cb7be7244fe 100755 --- a/builder/scripts.d/45-x11/40-libx11.sh +++ b/builder/scripts.d/45-x11/40-libx11.sh @@ -1,7 +1,7 @@ #!/bin/bash SCRIPT_REPO="https://gitlab.freedesktop.org/xorg/lib/libx11.git" -SCRIPT_COMMIT="ab0442d3fa835ce16559b29532ac7f674f8557f4" +SCRIPT_COMMIT="b2c3fb7b4dd4c4c7b9d28c7af7776cccc8e0a98b" ffbuild_enabled() { [[ $TARGET != linux* ]] && return -1 diff --git a/builder/scripts.d/45-x11/60-libxcursor.sh b/builder/scripts.d/45-x11/60-libxcursor.sh index 18e40570083..bf5543515a7 100755 --- a/builder/scripts.d/45-x11/60-libxcursor.sh +++ b/builder/scripts.d/45-x11/60-libxcursor.sh @@ -1,7 +1,7 @@ #!/bin/bash SCRIPT_REPO="https://gitlab.freedesktop.org/xorg/lib/libxcursor.git" -SCRIPT_COMMIT="a353f02a7ac4504ad5edb5407278c7a03c507aef" +SCRIPT_COMMIT="9c1b50ed98d354488329c99bc8bf77d1c6df657c" ffbuild_enabled() { [[ $TARGET != linux* ]] && return -1 diff --git a/builder/scripts.d/50-amf.sh b/builder/scripts.d/50-amf.sh index c8dd46f8069..e4933becbff 100755 --- a/builder/scripts.d/50-amf.sh +++ b/builder/scripts.d/50-amf.sh @@ -1,7 +1,7 @@ #!/bin/bash SCRIPT_REPO="https://github.com/GPUOpen-LibrariesAndSDKs/AMF.git" -SCRIPT_COMMIT="bd5db31d3d8ea1fae7002dd903898599bdb7d97a" +SCRIPT_COMMIT="68f2396f1a55a5b12767f5433411bb4093ea65ed" ffbuild_enabled() { [[ $TARGET == *arm64 ]] && return -1 diff --git a/builder/scripts.d/50-dav1d.sh b/builder/scripts.d/50-dav1d.sh index 319eb393acb..1e8cc359cea 100755 --- a/builder/scripts.d/50-dav1d.sh +++ b/builder/scripts.d/50-dav1d.sh @@ -1,7 +1,7 @@ #!/bin/bash SCRIPT_REPO="https://code.videolan.org/videolan/dav1d.git" -SCRIPT_COMMIT="2373fda303d46489c1ec269dc66369a31663cb25" +SCRIPT_COMMIT="e58afe4dd9057591882a01c31382c203e8a61c92" ffbuild_enabled() { return 0 diff --git a/builder/scripts.d/50-libass.sh b/builder/scripts.d/50-libass.sh index 07b278b7955..8eafaf6471e 100755 --- a/builder/scripts.d/50-libass.sh +++ b/builder/scripts.d/50-libass.sh @@ -1,7 +1,7 @@ #!/bin/bash SCRIPT_REPO="https://github.com/libass/libass.git" -SCRIPT_COMMIT="1a599b1db748dfc07df98cd37d8603edb87da2fd" +SCRIPT_COMMIT="91422bdb9497e8484b3248f5ae7eb50d41e2555d" ffbuild_enabled() { return 0 diff --git a/builder/scripts.d/50-libvpx.sh b/builder/scripts.d/50-libvpx.sh index 0c13af67d3e..14f941ae57f 100755 --- a/builder/scripts.d/50-libvpx.sh +++ b/builder/scripts.d/50-libvpx.sh @@ -1,7 +1,7 @@ #!/bin/bash SCRIPT_REPO="https://chromium.googlesource.com/webm/libvpx" -SCRIPT_COMMIT="14e52008edbf2e91386423fdd53310fe49654991" +SCRIPT_COMMIT="5556ebd894a9a9b07908c3c7fd0a7a87732a7635" ffbuild_enabled() { return 0 diff --git a/builder/scripts.d/50-libwebp.sh b/builder/scripts.d/50-libwebp.sh index b0ba227383f..1802af27a7c 100755 --- a/builder/scripts.d/50-libwebp.sh +++ b/builder/scripts.d/50-libwebp.sh @@ -1,7 +1,7 @@ #!/bin/bash SCRIPT_REPO="https://chromium.googlesource.com/webm/libwebp" -SCRIPT_COMMIT="08d60d60066eb30ab8e0e3ccfa0cd0b68f8cccc6" +SCRIPT_COMMIT="dd7364c3cefe0f5c0b3c18c3b1887d353f90fc1f" ffbuild_enabled() { return 0 diff --git a/builder/scripts.d/50-onevpl.sh b/builder/scripts.d/50-onevpl.sh index 6b4008082c6..b68d90477c3 100755 --- a/builder/scripts.d/50-onevpl.sh +++ b/builder/scripts.d/50-onevpl.sh @@ -1,7 +1,7 @@ #!/bin/bash SCRIPT_REPO="https://github.com/oneapi-src/oneVPL.git" -SCRIPT_COMMIT="e12ace9761bb52786409e830f619916b86e87fc5" +SCRIPT_COMMIT="ca5bbbb057a6e84b103aca807612afb693ad046c" ffbuild_enabled() { [[ $TARGET == *arm64 ]] && return -1 diff --git a/builder/scripts.d/50-openmpt.sh b/builder/scripts.d/50-openmpt.sh index 6bb161dbd0d..ca33a849328 100755 --- a/builder/scripts.d/50-openmpt.sh +++ b/builder/scripts.d/50-openmpt.sh @@ -1,7 +1,7 @@ #!/bin/bash SCRIPT_REPO="https://source.openmpt.org/svn/openmpt/trunk/OpenMPT" -SCRIPT_REV="19439" +SCRIPT_REV="19561" ffbuild_enabled() { return 0 diff --git a/builder/scripts.d/50-srt.sh b/builder/scripts.d/50-srt.sh index 9b809d47a63..b1fb85e3e7f 100755 --- a/builder/scripts.d/50-srt.sh +++ b/builder/scripts.d/50-srt.sh @@ -1,7 +1,7 @@ #!/bin/bash SCRIPT_REPO="https://github.com/Haivision/srt.git" -SCRIPT_COMMIT="9448e26fcd7602098b4bf9cd7fe535136e89e10b" +SCRIPT_COMMIT="88ca9ccca4984dbf61a5e1a06ac551b4dead5304" ffbuild_enabled() { return 0 diff --git a/builder/scripts.d/50-svtav1.sh b/builder/scripts.d/50-svtav1.sh index 34d2931e91a..aa566bedab1 100755 --- a/builder/scripts.d/50-svtav1.sh +++ b/builder/scripts.d/50-svtav1.sh @@ -1,7 +1,7 @@ #!/bin/bash SCRIPT_REPO="https://gitlab.com/AOMediaCodec/SVT-AV1.git" -SCRIPT_COMMIT="08c18ba0768ed3dbbff0903adc326fb3a7549bd9" +SCRIPT_COMMIT="903ff3add82744d586295c37ec1241dc51dab16e" ffbuild_enabled() { [[ $TARGET == win32 ]] && return -1 diff --git a/builder/scripts.d/50-vaapi/30-libpciaccess.sh b/builder/scripts.d/50-vaapi/30-libpciaccess.sh index ff55e48f670..21014c3acae 100755 --- a/builder/scripts.d/50-vaapi/30-libpciaccess.sh +++ b/builder/scripts.d/50-vaapi/30-libpciaccess.sh @@ -1,7 +1,7 @@ #!/bin/bash SCRIPT_REPO="https://gitlab.freedesktop.org/xorg/lib/libpciaccess.git" -SCRIPT_COMMIT="8980a39004b10298a7db1f1b0b711a19e8b73aee" +SCRIPT_COMMIT="03d0b467804bf033c2be259be3f091231f74cff9" ffbuild_enabled() { [[ $TARGET != linux* ]] && return -1 diff --git a/builder/scripts.d/50-vaapi/40-libdrm.sh b/builder/scripts.d/50-vaapi/40-libdrm.sh index 200aed91ed3..ed2ad7f41da 100755 --- a/builder/scripts.d/50-vaapi/40-libdrm.sh +++ b/builder/scripts.d/50-vaapi/40-libdrm.sh @@ -1,7 +1,7 @@ #!/bin/bash SCRIPT_REPO="https://gitlab.freedesktop.org/mesa/drm.git" -SCRIPT_COMMIT="98e1db501173303e58ef6a1def94ab7a2d84afc1" +SCRIPT_COMMIT="c6013245ce9ce287bb86d327f9b6420a320a08e6" ffbuild_enabled() { [[ $TARGET != linux* ]] && return -1 diff --git a/builder/scripts.d/50-vaapi/50-libva.sh b/builder/scripts.d/50-vaapi/50-libva.sh index 7de3784c960..a95bf59b259 100755 --- a/builder/scripts.d/50-vaapi/50-libva.sh +++ b/builder/scripts.d/50-vaapi/50-libva.sh @@ -1,7 +1,7 @@ #!/bin/bash SCRIPT_REPO="https://github.com/intel/libva.git" -SCRIPT_COMMIT="1c58941b93ba5013c68e8370a408efd630275c9c" +SCRIPT_COMMIT="7d6c7d482b9d2330b1f3a8bac13a6a3205f33382" ffbuild_enabled() { [[ $TARGET != linux* ]] && return -1 diff --git a/builder/scripts.d/50-vulkan/45-vulkan.sh b/builder/scripts.d/50-vulkan/45-vulkan.sh index a69706aea25..f0ccd85584d 100755 --- a/builder/scripts.d/50-vulkan/45-vulkan.sh +++ b/builder/scripts.d/50-vulkan/45-vulkan.sh @@ -1,7 +1,7 @@ #!/bin/bash SCRIPT_REPO="https://github.com/KhronosGroup/Vulkan-Headers.git" -SCRIPT_COMMIT="v1.3.246" +SCRIPT_COMMIT="v1.3.260" SCRIPT_TAGFILTER="v?.*.*" ffbuild_enabled() { diff --git a/builder/scripts.d/50-vulkan/50-shaderc.sh b/builder/scripts.d/50-vulkan/50-shaderc.sh index e254cca3b8a..7213ac961c6 100755 --- a/builder/scripts.d/50-vulkan/50-shaderc.sh +++ b/builder/scripts.d/50-vulkan/50-shaderc.sh @@ -1,7 +1,7 @@ #!/bin/bash SCRIPT_REPO="https://github.com/google/shaderc.git" -SCRIPT_COMMIT="e31c4c2e41544d63d90be28c46e4a4793a624240" +SCRIPT_COMMIT="4d98dac61ee4857ea0691a2b9a48aee44eb409db" ffbuild_enabled() { return 0 diff --git a/builder/scripts.d/50-vulkan/55-spirv-cross.sh b/builder/scripts.d/50-vulkan/55-spirv-cross.sh index 02f8f8d346f..8d027424272 100755 --- a/builder/scripts.d/50-vulkan/55-spirv-cross.sh +++ b/builder/scripts.d/50-vulkan/55-spirv-cross.sh @@ -1,7 +1,7 @@ #!/bin/bash SCRIPT_REPO="https://github.com/KhronosGroup/SPIRV-Cross.git" -SCRIPT_COMMIT="2d3a152081ca6e6bea7093940d0f81088fe4d01c" +SCRIPT_COMMIT="bccaa94db814af33d8ef05c153e7c34d8bd4d685" ffbuild_enabled() { return 0 diff --git a/builder/scripts.d/50-x265.sh b/builder/scripts.d/50-x265.sh index a5e4b2e4cc9..287ac5b8af8 100755 --- a/builder/scripts.d/50-x265.sh +++ b/builder/scripts.d/50-x265.sh @@ -1,7 +1,7 @@ #!/bin/bash SCRIPT_REPO="https://bitbucket.org/multicoreware/x265_git.git" -SCRIPT_COMMIT="34532bda12a3a3141880582aa186a59cd4538ae6" +SCRIPT_COMMIT="8f18e3ad32684eee95e885e718655f93951128c3" ffbuild_enabled() { [[ $VARIANT == lgpl* ]] && return -1 diff --git a/builder/scripts.d/50-zimg.sh b/builder/scripts.d/50-zimg.sh index 6bcfbc07000..c985a5cec07 100755 --- a/builder/scripts.d/50-zimg.sh +++ b/builder/scripts.d/50-zimg.sh @@ -1,7 +1,7 @@ #!/bin/bash SCRIPT_REPO="https://github.com/sekrit-twc/zimg.git" -SCRIPT_COMMIT="939a78cae6a8207ef778375dfcaa75511162a186" +SCRIPT_COMMIT="71431815950664f1e11b9ee4e5d4ba23d6d997f1" ffbuild_enabled() { return 0 diff --git a/debian/changelog b/debian/changelog index de8112c7cc4..bb64219e175 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,15 @@ +jellyfin-ffmpeg (6.0-5) unstable; urgency=medium + + * Add VUI info to the seq header of HEVC VA-API encoder + * Remove HDR metadata from tonemap_vaapi SDR output + * Backport QSV fixes from upstream + * Refine VA-API AV1 encoder v3 + * Fix VA-API import DRM prime2 planar formats + * Use contiguous linear Vulkan images for AMD encoder + * Update dependencies + + -- nyanmisaka Thu, 27 Jul 2023 21:54:12 +0800 + jellyfin-ffmpeg (6.0-4) unstable; urgency=medium * Allow VA-API import DRM prime2 planar formats diff --git a/debian/patches/0017-add-fixes-for-vaapi-tonemap.patch b/debian/patches/0017-add-fixes-for-vaapi-tonemap.patch index 8869eb93a0d..8b1cc0e88de 100644 --- a/debian/patches/0017-add-fixes-for-vaapi-tonemap.patch +++ b/debian/patches/0017-add-fixes-for-vaapi-tonemap.patch @@ -223,7 +223,7 @@ Index: jellyfin-ffmpeg/libavfilter/vf_tonemap_vaapi.c err = tonemap_vaapi_set_filter_params(avctx, input_frame); if (err < 0) -@@ -289,6 +408,18 @@ static int tonemap_vaapi_filter_frame(AV +@@ -289,6 +408,21 @@ static int tonemap_vaapi_filter_frame(AV if (ctx->color_matrix != AVCOL_SPC_UNSPECIFIED) output_frame->colorspace = ctx->color_matrix; @@ -237,12 +237,15 @@ Index: jellyfin-ffmpeg/libavfilter/vf_tonemap_vaapi.c + out_hdr_metadata.metadata_size = sizeof(VAHdrMetaDataHDR10); + + params.output_hdr_metadata = &out_hdr_metadata; ++ } else { ++ av_frame_remove_side_data(output_frame, AV_FRAME_DATA_CONTENT_LIGHT_LEVEL); ++ av_frame_remove_side_data(output_frame, AV_FRAME_DATA_MASTERING_DISPLAY_METADATA); + } + err = ff_vaapi_vpp_init_params(avctx, ¶ms, input_frame, output_frame); if (err < 0) -@@ -358,6 +489,60 @@ static av_cold int tonemap_vaapi_init(AV +@@ -358,6 +492,60 @@ static av_cold int tonemap_vaapi_init(AV STRING_OPTION(color_transfer, color_transfer, AVCOL_TRC_UNSPECIFIED); STRING_OPTION(color_matrix, color_space, AVCOL_SPC_UNSPECIFIED); @@ -303,7 +306,7 @@ Index: jellyfin-ffmpeg/libavfilter/vf_tonemap_vaapi.c return 0; } -@@ -383,10 +568,13 @@ static const AVOption tonemap_vaapi_opti +@@ -383,10 +571,13 @@ static const AVOption tonemap_vaapi_opti { "t", "Output color transfer characteristics set", OFFSET(color_transfer_string), AV_OPT_TYPE_STRING, { .str = NULL }, .flags = FLAGS, "transfer" }, diff --git a/debian/patches/0021-add-code-polishing-to-qsv-filters.patch b/debian/patches/0021-add-code-polishing-to-qsv-filters.patch index 4b96a979956..2ef607bedd3 100644 --- a/debian/patches/0021-add-code-polishing-to-qsv-filters.patch +++ b/debian/patches/0021-add-code-polishing-to-qsv-filters.patch @@ -203,7 +203,19 @@ Index: jellyfin-ffmpeg/libavfilter/vf_vpp_qsv.c INIT_MFX_EXTBUF(scale_conf, MFX_EXTBUFF_VPP_SCALING); SET_MFX_PARAM_FIELD(scale_conf, ScalingMode, mode); -@@ -602,6 +635,7 @@ not_ready: +@@ -582,6 +615,11 @@ static int activate(AVFilterContext *ctx + if (in->pts != AV_NOPTS_VALUE) + in->pts = av_rescale_q(in->pts, inlink->time_base, outlink->time_base); + ++ if (outlink->frame_rate.num && outlink->frame_rate.den) ++ in->duration = av_rescale_q(1, av_inv_q(outlink->frame_rate), outlink->time_base); ++ else ++ in->duration = 0; ++ + ret = ff_filter_frame(outlink, in); + if (ret < 0) + return ret; +@@ -602,6 +640,7 @@ not_ready: return FFERROR_NOT_READY; eof: @@ -211,7 +223,7 @@ Index: jellyfin-ffmpeg/libavfilter/vf_vpp_qsv.c ff_outlink_set_status(outlink, status, pts); return 0; } -@@ -685,20 +719,14 @@ static const AVOption vpp_options[] = { +@@ -685,20 +724,14 @@ static const AVOption vpp_options[] = { { "h", "Output video height(0=input video height, -1=keep input video aspect)", OFFSET(oh), AV_OPT_TYPE_STRING, { .str="w*ch/cw" }, 0, 255, .flags = FLAGS }, { "height", "Output video height(0=input video height, -1=keep input video aspect)", OFFSET(oh), AV_OPT_TYPE_STRING, { .str="w*ch/cw" }, 0, 255, .flags = FLAGS }, { "format", "Output pixel format", OFFSET(output_format_str), AV_OPT_TYPE_STRING, { .str = "same" }, .flags = FLAGS }, @@ -234,7 +246,7 @@ Index: jellyfin-ffmpeg/libavfilter/vf_vpp_qsv.c { "rate", "Generate output at frame rate or field rate, available only for deinterlace mode", OFFSET(field_rate), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, FLAGS, "rate" }, -@@ -707,6 +735,7 @@ static const AVOption vpp_options[] = { +@@ -707,6 +740,7 @@ static const AVOption vpp_options[] = { { "field", "Output at field rate (one frame of output for each field)", 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, 0, 0, FLAGS, "rate" }, @@ -242,7 +254,7 @@ Index: jellyfin-ffmpeg/libavfilter/vf_vpp_qsv.c { NULL } }; -@@ -751,19 +780,14 @@ static const AVOption qsvscale_options[] +@@ -751,19 +785,14 @@ static const AVOption qsvscale_options[] { "h", "Output video height(0=input video height, -1=keep input video aspect)", OFFSET(oh), AV_OPT_TYPE_STRING, { .str = "ih" }, .flags = FLAGS }, { "format", "Output pixel format", OFFSET(output_format_str), AV_OPT_TYPE_STRING, { .str = "same" }, .flags = FLAGS }, @@ -264,7 +276,7 @@ Index: jellyfin-ffmpeg/libavfilter/vf_vpp_qsv.c { NULL }, }; -@@ -788,6 +812,7 @@ static const AVOption qsvdeint_options[] +@@ -788,6 +817,7 @@ static const AVOption qsvdeint_options[] { "bob", "bob algorithm", 0, AV_OPT_TYPE_CONST, {.i64 = MFX_DEINTERLACING_BOB}, MFX_DEINTERLACING_BOB, MFX_DEINTERLACING_ADVANCED, FLAGS, "mode"}, { "advanced", "Motion adaptive algorithm", 0, AV_OPT_TYPE_CONST, {.i64 = MFX_DEINTERLACING_ADVANCED}, MFX_DEINTERLACING_BOB, MFX_DEINTERLACING_ADVANCED, FLAGS, "mode"}, diff --git a/debian/patches/0051-add-av1-vaapi-encoder-from-upstream-intel.patch b/debian/patches/0051-add-av1-vaapi-encoder-from-upstream-intel.patch index 68419a2a000..87f02275370 100644 --- a/debian/patches/0051-add-av1-vaapi-encoder-from-upstream-intel.patch +++ b/debian/patches/0051-add-av1-vaapi-encoder-from-upstream-intel.patch @@ -27,7 +27,7 @@ Index: jellyfin-ffmpeg/libavcodec/Makefile OBJS-$(CONFIG_AV1_MEDIACODEC_DECODER) += mediacodecdec.o OBJS-$(CONFIG_AV1_NVENC_ENCODER) += nvenc_av1.o nvenc.o OBJS-$(CONFIG_AV1_QSV_ENCODER) += qsvenc_av1.o -+OBJS-$(CONFIG_AV1_VAAPI_ENCODER) += vaapi_encode_av1.o av1_profile_level.o ++OBJS-$(CONFIG_AV1_VAAPI_ENCODER) += vaapi_encode_av1.o av1_levels.o OBJS-$(CONFIG_AVRN_DECODER) += avrndec.o OBJS-$(CONFIG_AVRP_DECODER) += r210dec.o OBJS-$(CONFIG_AVRP_ENCODER) += r210enc.o @@ -61,13 +61,13 @@ Index: jellyfin-ffmpeg/libavcodec/av1.h // Sequence Headers are actually unbounded because one can use // an arbitrary number of leading zeroes when encoding via uvlc. // The following estimate is based around using the lowest number -Index: jellyfin-ffmpeg/libavcodec/av1_profile_level.c +Index: jellyfin-ffmpeg/libavcodec/av1_levels.c =================================================================== --- /dev/null -+++ jellyfin-ffmpeg/libavcodec/av1_profile_level.c ++++ jellyfin-ffmpeg/libavcodec/av1_levels.c @@ -0,0 +1,92 @@ +/* -+ * Copyright (c) 2023 Fei Wang ++ * Copyright (c) 2023 Intel Corporation + * + * This file is part of FFmpeg. + * @@ -86,8 +86,9 @@ Index: jellyfin-ffmpeg/libavcodec/av1_profile_level.c + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + -+#include "libavutil/common.h" -+#include "av1_profile_level.h" ++#include ++#include "libavutil/macros.h" ++#include "av1_levels.h" + +/** ignore entries which named in spec but no details. Like level 2.2 and 7.0. */ +static const AV1LevelDescriptor av1_levels[] = { @@ -123,12 +124,11 @@ Index: jellyfin-ffmpeg/libavcodec/av1_profile_level.c + int pic_size; + uint64_t display_rate; + float max_br; -+ int i; + + pic_size = width * height; + display_rate = (uint64_t)pic_size * fps; + -+ for (i = 0; i < FF_ARRAY_ELEMS(av1_levels); i++) { ++ for (int i = 0; i < FF_ARRAY_ELEMS(av1_levels); i++) { + const AV1LevelDescriptor *level = &av1_levels[i]; + // Limitation: decode rate, header rate, compress rate, etc. are not considered. + if (pic_size > level->max_pic_size) @@ -158,13 +158,13 @@ Index: jellyfin-ffmpeg/libavcodec/av1_profile_level.c + + return NULL; +} -Index: jellyfin-ffmpeg/libavcodec/av1_profile_level.h +Index: jellyfin-ffmpeg/libavcodec/av1_levels.h =================================================================== --- /dev/null -+++ jellyfin-ffmpeg/libavcodec/av1_profile_level.h ++++ jellyfin-ffmpeg/libavcodec/av1_levels.h @@ -0,0 +1,58 @@ +/* -+ * Copyright (c) 2023 Fei Wang ++ * Copyright (c) 2023 Intel Corporation + * + * This file is part of FFmpeg. + * @@ -183,28 +183,28 @@ Index: jellyfin-ffmpeg/libavcodec/av1_profile_level.h + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + -+#ifndef AVCODEC_AV1_PROFILE_LEVEL_H -+#define AVCODEC_AV1_PROFILE_LEVEL_H ++#ifndef AVCODEC_AV1_LEVELS_H ++#define AVCODEC_AV1_LEVELS_H + +#include + +typedef struct AV1LevelDescriptor { -+ const char *name; -+ uint8_t level_idx; -+ -+ uint32_t max_pic_size; -+ uint32_t max_h_size; -+ uint32_t max_v_size; -+ uint64_t max_display_rate; -+ uint64_t max_decode_rate; -+ -+ uint32_t max_header_rate; -+ float main_mbps; -+ float high_mbps; -+ uint32_t main_cr; -+ uint32_t high_cr; -+ uint32_t max_tiles; -+ uint32_t max_tile_cols; ++ char name[4]; ++ uint8_t level_idx; ++ ++ uint32_t max_pic_size; ++ uint32_t max_h_size; ++ uint32_t max_v_size; ++ uint64_t max_display_rate; ++ uint64_t max_decode_rate; ++ ++ uint32_t max_header_rate; ++ float main_mbps; ++ float high_mbps; ++ uint32_t main_cr; ++ uint32_t high_cr; ++ uint32_t max_tiles; ++ uint32_t max_tile_cols; +} AV1LevelDescriptor; + +/** @@ -220,7 +220,7 @@ Index: jellyfin-ffmpeg/libavcodec/av1_profile_level.h + int tile_cols, + float fps); + -+#endif /* AVCODEC_AV1_PROFILE_LEVEL_H */ ++#endif /* AVCODEC_AV1_LEVELS_H */ Index: jellyfin-ffmpeg/libavcodec/cbs_av1_syntax_template.c =================================================================== --- jellyfin-ffmpeg.orig/libavcodec/cbs_av1_syntax_template.c @@ -241,7 +241,49 @@ Index: jellyfin-ffmpeg/libavcodec/vaapi_encode.c =================================================================== --- jellyfin-ffmpeg.orig/libavcodec/vaapi_encode.c +++ jellyfin-ffmpeg/libavcodec/vaapi_encode.c -@@ -650,14 +650,41 @@ fail_at_end: +@@ -276,21 +276,34 @@ static int vaapi_encode_issue(AVCodecCon + av_log(avctx, AV_LOG_DEBUG, "Issuing encode for pic %"PRId64"/%"PRId64" " + "as type %s.\n", pic->display_order, pic->encode_order, + picture_type_name[pic->type]); +- if (pic->nb_refs == 0) { ++ if (pic->nb_refs[0] == 0 && pic->nb_refs[1] == 0) { + av_log(avctx, AV_LOG_DEBUG, "No reference pictures.\n"); + } else { +- av_log(avctx, AV_LOG_DEBUG, "Refers to:"); +- for (i = 0; i < pic->nb_refs; i++) { ++ av_log(avctx, AV_LOG_DEBUG, "L0 refers to"); ++ for (i = 0; i < pic->nb_refs[0]; i++) { + av_log(avctx, AV_LOG_DEBUG, " %"PRId64"/%"PRId64, +- pic->refs[i]->display_order, pic->refs[i]->encode_order); ++ pic->refs[0][i]->display_order, pic->refs[0][i]->encode_order); + } + av_log(avctx, AV_LOG_DEBUG, ".\n"); ++ ++ if (pic->nb_refs[1]) { ++ av_log(avctx, AV_LOG_DEBUG, "L1 refers to"); ++ for (i = 0; i < pic->nb_refs[1]; i++) { ++ av_log(avctx, AV_LOG_DEBUG, " %"PRId64"/%"PRId64, ++ pic->refs[1][i]->display_order, pic->refs[1][i]->encode_order); ++ } ++ av_log(avctx, AV_LOG_DEBUG, ".\n"); ++ } + } + + av_assert0(!pic->encode_issued); +- for (i = 0; i < pic->nb_refs; i++) { +- av_assert0(pic->refs[i]); +- av_assert0(pic->refs[i]->encode_issued); ++ for (i = 0; i < pic->nb_refs[0]; i++) { ++ av_assert0(pic->refs[0][i]); ++ av_assert0(pic->refs[0][i]->encode_issued); ++ } ++ for (i = 0; i < pic->nb_refs[1]; i++) { ++ av_assert0(pic->refs[1][i]); ++ av_assert0(pic->refs[1][i]->encode_issued); + } + + av_log(avctx, AV_LOG_DEBUG, "Input surface is %#x.\n", pic->input_surface); +@@ -650,14 +663,45 @@ fail_at_end: return err; } @@ -251,6 +293,10 @@ Index: jellyfin-ffmpeg/libavcodec/vaapi_encode.c +{ + VAAPIEncodeContext *ctx = avctx->priv_data; + ++ // AV1 packs P frame and next B frame into one pkt, and uses the other ++ // repeat frame header pkt at the display order position of the P frame ++ // to indicate its frame index. Each frame has a corresponding pkt in its ++ // display order position. So don't need to consider delay for AV1 timestamp. + if (avctx->codec_id == AV_CODEC_ID_AV1) { + pkt->dts = pkt->pts - ctx->dts_pts_diff; + return 0; @@ -284,7 +330,7 @@ Index: jellyfin-ffmpeg/libavcodec/vaapi_encode.c int err; err = vaapi_encode_wait(avctx, pic); -@@ -677,11 +704,52 @@ static int vaapi_encode_output(AVCodecCo +@@ -677,11 +721,52 @@ static int vaapi_encode_output(AVCodecCo for (buf = buf_list; buf; buf = buf->next) total_size += buf->size; @@ -341,7 +387,7 @@ Index: jellyfin-ffmpeg/libavcodec/vaapi_encode.c for (buf = buf_list; buf; buf = buf->next) { av_log(avctx, AV_LOG_DEBUG, "Output buffer: %u bytes " -@@ -692,10 +760,10 @@ static int vaapi_encode_output(AVCodecCo +@@ -692,10 +777,10 @@ static int vaapi_encode_output(AVCodecCo } if (pic->type == PICTURE_TYPE_IDR) @@ -355,7 +401,7 @@ Index: jellyfin-ffmpeg/libavcodec/vaapi_encode.c vas = vaUnmapBuffer(ctx->hwctx->display, pic->output_buffer); if (vas != VA_STATUS_SUCCESS) { -@@ -708,8 +776,8 @@ static int vaapi_encode_output(AVCodecCo +@@ -708,8 +793,8 @@ static int vaapi_encode_output(AVCodecCo // for no-delay encoders this is handled in generic codec if (avctx->codec->capabilities & AV_CODEC_CAP_DELAY && avctx->flags & AV_CODEC_FLAG_COPY_OPAQUE) { @@ -366,7 +412,7 @@ Index: jellyfin-ffmpeg/libavcodec/vaapi_encode.c pic->opaque_ref = NULL; } -@@ -718,6 +786,9 @@ static int vaapi_encode_output(AVCodecCo +@@ -718,6 +803,9 @@ static int vaapi_encode_output(AVCodecCo av_log(avctx, AV_LOG_DEBUG, "Output read for pic %"PRId64"/%"PRId64".\n", pic->display_order, pic->encode_order); @@ -376,7 +422,169 @@ Index: jellyfin-ffmpeg/libavcodec/vaapi_encode.c return 0; fail_mapped: -@@ -1205,10 +1276,23 @@ fail: +@@ -811,8 +899,12 @@ static void vaapi_encode_add_ref(AVCodec + + if (is_ref) { + av_assert0(pic != target); +- av_assert0(pic->nb_refs < MAX_PICTURE_REFERENCES); +- pic->refs[pic->nb_refs++] = target; ++ av_assert0(pic->nb_refs[0] < MAX_PICTURE_REFERENCES && ++ pic->nb_refs[1] < MAX_PICTURE_REFERENCES); ++ if (target->display_order < pic->display_order) ++ pic->refs[0][pic->nb_refs[0]++] = target; ++ else ++ pic->refs[1][pic->nb_refs[1]++] = target; + ++refs; + } + +@@ -841,10 +933,16 @@ static void vaapi_encode_remove_refs(AVC + if (pic->ref_removed[level]) + return; + +- for (i = 0; i < pic->nb_refs; i++) { +- av_assert0(pic->refs[i]); +- --pic->refs[i]->ref_count[level]; +- av_assert0(pic->refs[i]->ref_count[level] >= 0); ++ for (i = 0; i < pic->nb_refs[0]; i++) { ++ av_assert0(pic->refs[0][i]); ++ --pic->refs[0][i]->ref_count[level]; ++ av_assert0(pic->refs[0][i]->ref_count[level] >= 0); ++ } ++ ++ for (i = 0; i < pic->nb_refs[1]; i++) { ++ av_assert0(pic->refs[1][i]); ++ --pic->refs[1][i]->ref_count[level]; ++ av_assert0(pic->refs[1][i]->ref_count[level] >= 0); + } + + for (i = 0; i < pic->nb_dpb_pics; i++) { +@@ -889,7 +987,7 @@ static void vaapi_encode_set_b_pictures( + vaapi_encode_add_ref(avctx, pic, end, 1, 1, 0); + vaapi_encode_add_ref(avctx, pic, prev, 0, 0, 1); + +- for (ref = end->refs[1]; ref; ref = ref->refs[1]) ++ for (ref = end->refs[1][0]; ref; ref = ref->refs[1][0]) + vaapi_encode_add_ref(avctx, pic, ref, 0, 1, 0); + } + *last = prev; +@@ -912,7 +1010,7 @@ static void vaapi_encode_set_b_pictures( + vaapi_encode_add_ref(avctx, pic, end, 1, 1, 0); + vaapi_encode_add_ref(avctx, pic, prev, 0, 0, 1); + +- for (ref = end->refs[1]; ref; ref = ref->refs[1]) ++ for (ref = end->refs[1][0]; ref; ref = ref->refs[1][0]) + vaapi_encode_add_ref(avctx, pic, ref, 0, 1, 0); + + if (i > 1) +@@ -926,11 +1024,44 @@ static void vaapi_encode_set_b_pictures( + } + } + ++static void vaapi_encode_add_next_prev(AVCodecContext *avctx, ++ VAAPIEncodePicture *pic) ++{ ++ VAAPIEncodeContext *ctx = avctx->priv_data; ++ int i; ++ ++ if (!pic) ++ return; ++ ++ if (pic->type == PICTURE_TYPE_IDR) { ++ for (i = 0; i < ctx->nb_next_prev; i++) { ++ --ctx->next_prev[i]->ref_count[0]; ++ ctx->next_prev[i] = NULL; ++ } ++ ctx->next_prev[0] = pic; ++ ++pic->ref_count[0]; ++ ctx->nb_next_prev = 1; ++ ++ return; ++ } ++ ++ if (ctx->nb_next_prev < MAX_PICTURE_REFERENCES) { ++ ctx->next_prev[ctx->nb_next_prev++] = pic; ++ ++pic->ref_count[0]; ++ } else { ++ --ctx->next_prev[0]->ref_count[0]; ++ for (i = 0; i < MAX_PICTURE_REFERENCES - 1; i++) ++ ctx->next_prev[i] = ctx->next_prev[i + 1]; ++ ctx->next_prev[i] = pic; ++ ++pic->ref_count[0]; ++ } ++} ++ + static int vaapi_encode_pick_next(AVCodecContext *avctx, + VAAPIEncodePicture **pic_out) + { + VAAPIEncodeContext *ctx = avctx->priv_data; +- VAAPIEncodePicture *pic = NULL, *next, *start; ++ VAAPIEncodePicture *pic = NULL, *prev = NULL, *next, *start; + int i, b_counter, closed_gop_end; + + // If there are any B-frames already queued, the next one to encode +@@ -941,11 +1072,18 @@ static int vaapi_encode_pick_next(AVCode + continue; + if (pic->type != PICTURE_TYPE_B) + continue; +- for (i = 0; i < pic->nb_refs; i++) { +- if (!pic->refs[i]->encode_issued) ++ for (i = 0; i < pic->nb_refs[0]; i++) { ++ if (!pic->refs[0][i]->encode_issued) + break; + } +- if (i == pic->nb_refs) ++ if (i != pic->nb_refs[0]) ++ continue; ++ ++ for (i = 0; i < pic->nb_refs[1]; i++) { ++ if (!pic->refs[1][i]->encode_issued) ++ break; ++ } ++ if (i == pic->nb_refs[1]) + break; + } + +@@ -1044,21 +1182,30 @@ static int vaapi_encode_pick_next(AVCode + + vaapi_encode_add_ref(avctx, pic, pic, 0, 1, 0); + if (pic->type != PICTURE_TYPE_IDR) { +- vaapi_encode_add_ref(avctx, pic, start, +- pic->type == PICTURE_TYPE_P, +- b_counter > 0, 0); +- vaapi_encode_add_ref(avctx, pic, ctx->next_prev, 0, 0, 1); ++ // TODO: apply both previous and forward multi reference for all vaapi encoders. ++ // And L0/L1 reference frame number can be set dynamically through query ++ // VAConfigAttribEncMaxRefFrames attribute. ++ if (avctx->codec_id == AV_CODEC_ID_AV1) { ++ for (i = 0; i < ctx->nb_next_prev; i++) ++ vaapi_encode_add_ref(avctx, pic, ctx->next_prev[i], ++ pic->type == PICTURE_TYPE_P, ++ b_counter > 0, 0); ++ } else ++ vaapi_encode_add_ref(avctx, pic, start, ++ pic->type == PICTURE_TYPE_P, ++ b_counter > 0, 0); ++ ++ vaapi_encode_add_ref(avctx, pic, ctx->next_prev[ctx->nb_next_prev - 1], 0, 0, 1); + } +- if (ctx->next_prev) +- --ctx->next_prev->ref_count[0]; + + if (b_counter > 0) { + vaapi_encode_set_b_pictures(avctx, start, pic, pic, 1, +- &ctx->next_prev); ++ &prev); + } else { +- ctx->next_prev = pic; ++ prev = pic; + } +- ++ctx->next_prev->ref_count[0]; ++ vaapi_encode_add_next_prev(avctx, prev); ++ + return 0; + } + +@@ -1205,10 +1352,23 @@ fail: int ff_vaapi_encode_receive_packet(AVCodecContext *avctx, AVPacket *pkt) { VAAPIEncodeContext *ctx = avctx->priv_data; @@ -401,7 +609,7 @@ Index: jellyfin-ffmpeg/libavcodec/vaapi_encode.c err = ff_encode_get_frame(avctx, frame); if (err < 0 && err != AVERROR_EOF) return err; -@@ -1228,8 +1312,6 @@ int ff_vaapi_encode_receive_packet(AVCod +@@ -1228,8 +1388,6 @@ int ff_vaapi_encode_receive_packet(AVCod } if (ctx->has_sync_buffer_func) { @@ -410,7 +618,7 @@ Index: jellyfin-ffmpeg/libavcodec/vaapi_encode.c if (av_fifo_can_write(ctx->encode_fifo)) { err = vaapi_encode_pick_next(avctx, &pic); if (!err) { -@@ -1255,7 +1337,6 @@ int ff_vaapi_encode_receive_packet(AVCod +@@ -1255,7 +1413,6 @@ int ff_vaapi_encode_receive_packet(AVCod av_fifo_read(ctx->encode_fifo, &pic, 1); ctx->encode_order = pic->encode_order + 1; } else { @@ -418,7 +626,7 @@ Index: jellyfin-ffmpeg/libavcodec/vaapi_encode.c err = vaapi_encode_pick_next(avctx, &pic); if (err < 0) return err; -@@ -1276,27 +1357,20 @@ int ff_vaapi_encode_receive_packet(AVCod +@@ -1276,27 +1433,21 @@ int ff_vaapi_encode_receive_packet(AVCod return err; } @@ -444,8 +652,9 @@ Index: jellyfin-ffmpeg/libavcodec/vaapi_encode.c + goto start; + +end: -+ av_log(avctx, AV_LOG_DEBUG, "Output packet: pts %"PRId64", dts %"PRId64", " -+ "size %u bytes.\n", pkt->pts, pkt->dts, pkt->size); ++ if (pkt->size) ++ av_log(avctx, AV_LOG_DEBUG, "Output packet: pts %"PRId64", dts %"PRId64", " ++ "size %u bytes.\n", pkt->pts, pkt->dts, pkt->size); + return 0; } @@ -454,7 +663,7 @@ Index: jellyfin-ffmpeg/libavcodec/vaapi_encode.c static av_cold void vaapi_encode_add_global_param(AVCodecContext *avctx, int type, void *buffer, size_t size) { -@@ -2597,6 +2671,12 @@ av_cold int ff_vaapi_encode_init(AVCodec +@@ -2597,6 +2748,12 @@ av_cold int ff_vaapi_encode_init(AVCodec ctx->device = (AVHWDeviceContext*)ctx->device_ref->data; ctx->hwctx = ctx->device->hwctx; @@ -467,7 +676,7 @@ Index: jellyfin-ffmpeg/libavcodec/vaapi_encode.c err = vaapi_encode_profile_entrypoint(avctx); if (err < 0) goto fail; -@@ -2789,9 +2869,11 @@ av_cold int ff_vaapi_encode_close(AVCode +@@ -2789,9 +2946,11 @@ av_cold int ff_vaapi_encode_close(AVCode } av_frame_free(&ctx->frame); @@ -483,7 +692,31 @@ Index: jellyfin-ffmpeg/libavcodec/vaapi_encode.h =================================================================== --- jellyfin-ffmpeg.orig/libavcodec/vaapi_encode.h +++ jellyfin-ffmpeg/libavcodec/vaapi_encode.h -@@ -131,6 +131,11 @@ typedef struct VAAPIEncodePicture { +@@ -49,6 +49,7 @@ enum { + // A.4.1: table A.6 allows at most 20 tile columns for any level. + MAX_TILE_COLS = 20, + MAX_ASYNC_DEPTH = 64, ++ MAX_REFERENCE_LIST_NUM = 2, + }; + + extern const AVCodecHWConfigInternal *const ff_vaapi_encode_hw_configs[]; +@@ -116,10 +117,11 @@ typedef struct VAAPIEncodePicture { + // but not if it isn't. + int nb_dpb_pics; + struct VAAPIEncodePicture *dpb[MAX_DPB_SIZE]; +- // The reference pictures used in decoding this picture. If they are +- // used by later pictures they will also appear in the DPB. +- int nb_refs; +- struct VAAPIEncodePicture *refs[MAX_PICTURE_REFERENCES]; ++ // The reference pictures used in decoding this picture. If they are ++ // used by later pictures they will also appear in the DPB. ref[0][] for ++ // previous reference frames. ref[1][] for future reference frames. ++ int nb_refs[MAX_REFERENCE_LIST_NUM]; ++ struct VAAPIEncodePicture *refs[MAX_REFERENCE_LIST_NUM][MAX_PICTURE_REFERENCES]; + // The previous reference picture in encode order. Must be in at least + // one of the reference list and DPB list. + struct VAAPIEncodePicture *prev; +@@ -131,6 +133,11 @@ typedef struct VAAPIEncodePicture { int nb_slices; VAAPIEncodeSlice *slices; @@ -495,7 +728,19 @@ Index: jellyfin-ffmpeg/libavcodec/vaapi_encode.h } VAAPIEncodePicture; typedef struct VAAPIEncodeProfile { -@@ -364,6 +369,13 @@ typedef struct VAAPIEncodeContext { +@@ -290,8 +297,9 @@ typedef struct VAAPIEncodeContext { + // Current encoding window, in display (input) order. + VAAPIEncodePicture *pic_start, *pic_end; + // The next picture to use as the previous reference picture in +- // encoding order. +- VAAPIEncodePicture *next_prev; ++ // encoding order. Order from small to large in encoding order. ++ VAAPIEncodePicture *next_prev[MAX_PICTURE_REFERENCES]; ++ int nb_next_prev; + + // Next input order index (display order). + int64_t input_order; +@@ -364,6 +372,13 @@ typedef struct VAAPIEncodeContext { AVFifo *encode_fifo; // Max number of frame buffered in encoder. int async_depth; @@ -513,8 +758,10 @@ Index: jellyfin-ffmpeg/libavcodec/vaapi_encode_av1.c =================================================================== --- /dev/null +++ jellyfin-ffmpeg/libavcodec/vaapi_encode_av1.c -@@ -0,0 +1,1235 @@ +@@ -0,0 +1,1229 @@ +/* ++ * Copyright (c) 2023 Intel Corporation ++ * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or @@ -541,7 +788,7 @@ Index: jellyfin-ffmpeg/libavcodec/vaapi_encode_av1.c +#include "cbs_av1.h" +#include "put_bits.h" +#include "codec_internal.h" -+#include "av1_profile_level.h" ++#include "av1_levels.h" +#include "vaapi_encode.h" + +#define AV1_MAX_QUANT 255 @@ -590,8 +837,7 @@ Index: jellyfin-ffmpeg/libavcodec/vaapi_encode_av1.c + int profile; + int level; + int tier; -+ int tile_cols; -+ int tile_rows; ++ int tile_cols, tile_rows; + int tile_groups; +} VAAPIEncodeAV1Context; + @@ -806,7 +1052,7 @@ Index: jellyfin-ffmpeg/libavcodec/vaapi_encode_av1.c + if (!frame_is_intra && sh->enable_order_hint) + put_bits(&pbc, 1, fh->frame_refs_short_signaling); + -+ for (i=0; i < AV1_REFS_PER_FRAME; i++) { ++ for (i = 0; i < AV1_REFS_PER_FRAME; i++) { + if (!fh->frame_refs_short_signaling) + put_bits(&pbc, 3, fh->ref_frame_idx[i]); + } @@ -845,14 +1091,14 @@ Index: jellyfin-ffmpeg/libavcodec/vaapi_encode_av1.c + } else { + int start_sb = 0; + int max_width, max_height; -+ for (int i = 0; start_sb < priv->sb_cols; i++) { ++ for (i = 0; start_sb < priv->sb_cols; i++) { + max_width = FFMIN(priv->sb_cols - start_sb, priv->max_tile_width_sb); + write_ns(&pbc, max_width, fh->width_in_sbs_minus_1[i]); + start_sb += fh->width_in_sbs_minus_1[i] + 1; + } + + start_sb = 0; -+ for (int i = 0; start_sb < priv->sb_rows; i++) { ++ for (i = 0; start_sb < priv->sb_rows; i++) { + max_height = FFMIN(priv->sb_rows - start_sb, priv->max_tile_height_sb); + write_ns(&pbc, max_height, fh->height_in_sbs_minus_1[i]); + start_sb += fh->height_in_sbs_minus_1[i] + 1; @@ -1064,10 +1310,17 @@ Index: jellyfin-ffmpeg/libavcodec/vaapi_encode_av1.c +{ + VAAPIEncodeAV1Context *priv = avctx->priv_data; + int mi_cols, mi_rows, sb_shift, sb_size; -+ int max_tile_area_sb, widest_tile_sb; -+ int tile_width_sb, tile_height_sb; ++ int max_tile_area_sb, max_tile_area_sb_varied; ++ int tile_width_sb, tile_height_sb, widest_tile_sb; + int min_log2_tiles; -+ int i; ++ int tile_rows_tmp, i; ++ ++ if (priv->tile_cols > AV1_MAX_TILE_COLS || ++ priv->tile_rows > AV1_MAX_TILE_ROWS) { ++ av_log(avctx, AV_LOG_ERROR, "Invalid tile number %dx%d, should less than %dx%d.\n", ++ priv->tile_cols, priv->tile_rows, AV1_MAX_TILE_COLS, AV1_MAX_TILE_ROWS); ++ return AVERROR(EINVAL); ++ } + + mi_cols = 2 * ((avctx->width + 7) >> 3); + mi_rows = 2 * ((avctx->height + 7) >> 3); @@ -1091,51 +1344,63 @@ Index: jellyfin-ffmpeg/libavcodec/vaapi_encode_av1.c + av_log(avctx, AV_LOG_WARNING, "Invalid tile cols, correct to %d.\n", priv->tile_cols); + } + -+ /** try uniformed tile mode first. */ + priv->tile_cols_log2 = tile_log2(1, priv->tile_cols); + tile_width_sb = (priv->sb_cols + (1 << priv->tile_cols_log2) - 1) >> + priv->tile_cols_log2; + -+ if ((priv->sb_cols + tile_width_sb - 1) / tile_width_sb == priv->tile_cols) { -+ for (i=0; i < priv->tile_cols - 1; i++) -+ priv->width_in_sbs_minus_1[i] = tile_width_sb - 1; -+ priv->width_in_sbs_minus_1[i] = priv->sb_cols - (priv->tile_cols - 1) * tile_width_sb - 1; -+ widest_tile_sb = tile_width_sb; -+ } else { ++ if (priv->tile_rows > priv->sb_rows) { ++ priv->tile_rows = priv->sb_rows; ++ av_log(avctx, AV_LOG_WARNING, "Invalid tile rows, correct to %d.\n", priv->tile_rows); ++ } ++ ++ for (tile_rows_tmp = priv->tile_rows; tile_rows_tmp <= priv->sb_rows && tile_rows_tmp <= AV1_MAX_TILE_ROWS; tile_rows_tmp++) { ++ /** try uniformed tile. */ ++ priv->tile_rows_log2 = tile_log2(1, tile_rows_tmp); ++ if ((priv->sb_cols + tile_width_sb - 1) / tile_width_sb == priv->tile_cols) { ++ for (i = 0; i < priv->tile_cols - 1; i++) ++ priv->width_in_sbs_minus_1[i] = tile_width_sb - 1; ++ priv->width_in_sbs_minus_1[i] = priv->sb_cols - (priv->tile_cols - 1) * tile_width_sb - 1; ++ ++ tile_height_sb = (priv->sb_rows + (1 << priv->tile_rows_log2) - 1) >> ++ priv->tile_rows_log2; ++ ++ if ((priv->sb_rows + tile_height_sb - 1) / tile_height_sb == tile_rows_tmp && ++ tile_height_sb <= max_tile_area_sb / tile_width_sb) { ++ for (i = 0; i < tile_rows_tmp - 1; i++) ++ priv->height_in_sbs_minus_1[i] = tile_height_sb - 1; ++ priv->height_in_sbs_minus_1[i] = priv->sb_rows - (tile_rows_tmp - 1) * tile_height_sb - 1; ++ ++ priv->uniform_tile = 1; ++ priv->min_log2_tile_rows = FFMAX(min_log2_tiles - priv->tile_cols_log2, 0); ++ ++ break; ++ } ++ } ++ ++ /** try non-uniformed tile. */ ++ widest_tile_sb = 0; + for (i = 0; i < priv->tile_cols; i++) { + priv->width_in_sbs_minus_1[i] = (i + 1) * priv->sb_cols / priv->tile_cols - i * priv->sb_cols / priv->tile_cols - 1; -+ widest_tile_sb = FFMIN(widest_tile_sb, priv->width_in_sbs_minus_1[i] + 1); ++ widest_tile_sb = FFMAX(widest_tile_sb, priv->width_in_sbs_minus_1[i] + 1); + } -+ } + -+ if (min_log2_tiles) -+ max_tile_area_sb = (priv->sb_rows * priv->sb_cols) >> (min_log2_tiles + 1); -+ else -+ max_tile_area_sb = priv->sb_rows * priv->sb_cols; -+ priv->max_tile_height_sb = FFMAX(1, max_tile_area_sb / widest_tile_sb); -+ -+ if (priv->tile_rows != av_clip(priv->tile_rows, (priv->sb_rows + priv->max_tile_height_sb - 1) / priv->max_tile_height_sb, priv->sb_rows)) { -+ priv->tile_rows = av_clip(priv->tile_rows, (priv->sb_rows + priv->max_tile_height_sb - 1) / priv->max_tile_height_sb, priv->sb_rows); -+ av_log(avctx, AV_LOG_WARNING, "Invalid tile rows, correct to %d.\n", priv->tile_rows); -+ } ++ if (min_log2_tiles) ++ max_tile_area_sb_varied = (priv->sb_rows * priv->sb_cols) >> (min_log2_tiles + 1); ++ else ++ max_tile_area_sb_varied = priv->sb_rows * priv->sb_cols; ++ priv->max_tile_height_sb = FFMAX(1, max_tile_area_sb_varied / widest_tile_sb); + -+ priv->tile_rows_log2 = tile_log2(1, priv->tile_rows); -+ tile_height_sb = (priv->sb_rows + (1 << priv->tile_rows_log2) - 1) >> -+ priv->tile_rows_log2; ++ if (tile_rows_tmp == av_clip(tile_rows_tmp, (priv->sb_rows + priv->max_tile_height_sb - 1) / priv->max_tile_height_sb, priv->sb_rows)) { ++ for (i = 0; i < tile_rows_tmp; i++) ++ priv->height_in_sbs_minus_1[i] = (i + 1) * priv->sb_rows / tile_rows_tmp - i * priv->sb_rows / tile_rows_tmp - 1; + -+ if ((priv->sb_rows + tile_height_sb - 1) / tile_height_sb == priv->tile_rows) { -+ for (i=0; i < priv->tile_rows - 1; i++) -+ priv->height_in_sbs_minus_1[i] = tile_height_sb - 1; -+ priv->height_in_sbs_minus_1[i] = priv->sb_rows - (priv->tile_rows - 1) * tile_height_sb - 1; -+ } else { -+ for (i = 0; i < priv->tile_rows; i++) -+ priv->height_in_sbs_minus_1[i] = (i + 1) * priv->sb_rows / priv->tile_rows - i * priv->sb_rows / priv->tile_rows - 1; ++ break; ++ } + } + -+ if ((priv->sb_cols + tile_width_sb - 1) / tile_width_sb == priv->tile_cols && -+ (priv->sb_rows + tile_height_sb - 1) / tile_height_sb == priv->tile_rows) { -+ priv->uniform_tile = 1; -+ priv->min_log2_tile_rows = FFMAX(min_log2_tiles - priv->tile_cols_log2, 0); ++ if (priv->tile_rows != tile_rows_tmp) { ++ priv->tile_rows = tile_rows_tmp; ++ av_log(avctx, AV_LOG_WARNING, "Invalid tile rows, correct to %d.\n", priv->tile_rows); + } + + /** check if tile cols/rows is supported by driver. */ @@ -1153,9 +1418,9 @@ Index: jellyfin-ffmpeg/libavcodec/vaapi_encode_av1.c + + /** check if tile group numbers is valid. */ + if (priv->tile_groups > priv->tile_cols * priv->tile_rows) { -+ priv->tile_groups = priv->tile_cols * priv->tile_rows; -+ av_log(avctx, AV_LOG_ERROR, "Invalid tile groups number %d, " ++ av_log(avctx, AV_LOG_WARNING, "Invalid tile groups number %d, " + "correct to %d.\n", priv->tile_groups, priv->tile_cols * priv->tile_rows); ++ priv->tile_groups = priv->tile_cols * priv->tile_rows; + } + + return 0; @@ -1197,7 +1462,7 @@ Index: jellyfin-ffmpeg/libavcodec/vaapi_encode_av1.c + sh->max_frame_width_minus_1 = avctx->width - 1; + sh->max_frame_height_minus_1 = avctx->height - 1; + sh->seq_tier[0] = priv->tier; -+ /** enable order hint and use maximum 7 by default. */ ++ /** enable order hint and reserve maximum 8 bits for it by default. */ + sh->enable_order_hint = 1; + sh->order_hint_bits_minus_1 = 7; + @@ -1209,6 +1474,7 @@ Index: jellyfin-ffmpeg/libavcodec/vaapi_encode_av1.c + .color_description_present_flag = (avctx->color_primaries != AVCOL_PRI_UNSPECIFIED || + avctx->color_trc != AVCOL_TRC_UNSPECIFIED || + avctx->colorspace != AVCOL_SPC_UNSPECIFIED), ++ .color_range = avctx->color_range == AVCOL_RANGE_JPEG, + .subsampling_x = desc->log2_chroma_w, + .subsampling_y = desc->log2_chroma_h, + }; @@ -1268,16 +1534,14 @@ Index: jellyfin-ffmpeg/libavcodec/vaapi_encode_av1.c +static int vaapi_encode_av1_init_picture_params(AVCodecContext *avctx, + VAAPIEncodePicture *pic) +{ -+ VAAPIEncodeContext *ctx = avctx->priv_data; -+ VAAPIEncodePicture *prev = pic->prev; -+ VAAPIEncodeAV1Picture *hprev = prev ? prev->priv_data : NULL; + VAAPIEncodeAV1Context *priv = avctx->priv_data; + VAAPIEncodeAV1Picture *hpic = pic->priv_data; + AV1RawOBU *fh_obu = &priv->fh; + AV1RawFrameHeader *fh = &fh_obu->obu.frame.header; + VAEncPictureParameterBufferAV1 *vpic = pic->codec_picture_params; + CodedBitstreamFragment *obu = &priv->current_obu; -+ VAAPIEncodeAV1Picture *href0, *href1; ++ VAAPIEncodePicture *ref; ++ VAAPIEncodeAV1Picture *href; + int slot, i; + int ret; + static const int8_t default_loop_filter_ref_deltas[AV1_TOTAL_REFS_PER_FRAME] = @@ -1290,92 +1554,68 @@ Index: jellyfin-ffmpeg/libavcodec/vaapi_encode_av1.c + + switch (pic->type) { + case PICTURE_TYPE_IDR: -+ av_assert0(pic->nb_refs == 0); ++ av_assert0(pic->nb_refs[0] == 0 || pic->nb_refs[1]); + fh->frame_type = AV1_FRAME_KEY; -+ fh->refresh_frame_flags = 0xff; ++ fh->refresh_frame_flags = 0xFF; + fh->base_q_idx = priv->q_idx_idr; + hpic->slot = 0; + hpic->last_idr_frame = pic->display_order; + break; + case PICTURE_TYPE_P: -+ av_assert0(pic->nb_refs == 1 && prev); ++ av_assert0(pic->nb_refs[0]); + fh->frame_type = AV1_FRAME_INTER; + fh->base_q_idx = priv->q_idx_p; -+ fh->reference_select = 1; -+ hpic->last_idr_frame = hprev->last_idr_frame; -+ href0 = pic->refs[0]->priv_data; -+ vpic->ref_frame_ctrl_l0.fields.search_idx0 = 1; -+ -+ av_assert0(href0->slot == 0 || href0->slot == 1); ++ ref = pic->refs[0][pic->nb_refs[0] - 1]; ++ href = ref->priv_data; ++ hpic->slot = !href->slot; ++ hpic->last_idr_frame = href->last_idr_frame; ++ fh->refresh_frame_flags = 1 << hpic->slot; + -+ if (ctx->max_b_depth > 0) { -+ hpic->slot = !href0->slot; -+ fh->refresh_frame_flags = 1 << hpic->slot | 0xfc; -+ for (i=0; i < AV1_NUM_REF_FRAMES; i++) { -+ fh->ref_order_hint[i] = pic->refs[0]->display_order - hpic->last_idr_frame; -+ } -+ -+ if (hpic->slot) { -+ for (i=0; i < AV1_REFS_PER_FRAME; i++) -+ fh->ref_frame_idx[i] = 0; -+ if (pic->refs[0]->refs[0]) -+ fh->ref_order_hint[1] = pic->refs[0]->refs[0]->display_order - hpic->last_idr_frame; -+ } else { -+ for (i=0; i < AV1_REFS_PER_FRAME; i++) -+ fh->ref_frame_idx[i] = 1; -+ fh->primary_ref_frame = 1; -+ if (pic->refs[0]->refs[0]) -+ fh->ref_order_hint[0] = pic->refs[0]->refs[0]->display_order - hpic->last_idr_frame; -+ } -+ } else { -+ hpic->slot = 0; -+ fh->refresh_frame_flags = 0xff; -+ for (i=0; i < AV1_NUM_REF_FRAMES; i++) -+ fh->ref_order_hint[i] = pic->refs[0]->display_order - hpic->last_idr_frame; ++ /** set the nearest frame in L0 as all reference frame. */ ++ for (i = 0; i < AV1_REFS_PER_FRAME; i++) { ++ fh->ref_frame_idx[i] = href->slot; ++ } ++ fh->primary_ref_frame = href->slot; ++ fh->ref_order_hint[href->slot] = ref->display_order - href->last_idr_frame; ++ vpic->ref_frame_ctrl_l0.fields.search_idx0 = AV1_REF_FRAME_LAST; ++ ++ /** set the 2nd nearest frame in L0 as Golden frame. */ ++ if (pic->nb_refs[0] > 1) { ++ ref = pic->refs[0][pic->nb_refs[0] - 2]; ++ href = ref->priv_data; ++ fh->ref_frame_idx[3] = href->slot; ++ fh->ref_order_hint[href->slot] = ref->display_order - href->last_idr_frame; ++ vpic->ref_frame_ctrl_l0.fields.search_idx1 = AV1_REF_FRAME_GOLDEN; + } + break; + case PICTURE_TYPE_B: -+ av_assert0(pic->nb_refs == 2 && prev); -+ href0 = pic->refs[0]->priv_data; -+ href1 = pic->refs[1]->priv_data; -+ av_assert0(href0->slot < pic->b_depth + 1 && -+ href1->slot < pic->b_depth + 1); ++ av_assert0(pic->nb_refs[0] && pic->nb_refs[1]); + fh->frame_type = AV1_FRAME_INTER; + fh->base_q_idx = priv->q_idx_b; + fh->refresh_frame_flags = 0x0; + fh->reference_select = 1; -+ hpic->last_idr_frame = hprev->last_idr_frame; -+ -+ /** Use LAST_FRAME and BWDREF_FRAME for reference by default. */ -+ vpic->ref_frame_ctrl_l0.fields.search_idx0 = 1; -+ vpic->ref_frame_ctrl_l1.fields.search_idx0 = 5; + + /** B frame will not be referenced, disable its recon frame. */ + vpic->picture_flags.bits.disable_frame_recon = 1; + -+ if (href0->slot) { -+ for (i=0; i < 4; i++) { -+ fh->ref_frame_idx[i] = 1; -+ } -+ for (i=4; i < 7; i++) { -+ fh->ref_frame_idx[i] = 0; -+ } -+ for (i=0; i < AV1_NUM_REF_FRAMES; i++) -+ fh->ref_order_hint[i] = pic->refs[1]->display_order - hpic->last_idr_frame; -+ fh->ref_order_hint[1] = pic->refs[0]->display_order - hpic->last_idr_frame; -+ fh->primary_ref_frame = 1; -+ } else { -+ for (i=0; i < 4; i++) { -+ fh->ref_frame_idx[i] = 0; -+ } -+ for (i=4; i < 7; i++) { -+ fh->ref_frame_idx[i] = 1; -+ } ++ /** Use LAST_FRAME and BWDREF_FRAME for reference. */ ++ vpic->ref_frame_ctrl_l0.fields.search_idx0 = AV1_REF_FRAME_LAST; ++ vpic->ref_frame_ctrl_l1.fields.search_idx0 = AV1_REF_FRAME_BWDREF; ++ ++ ref = pic->refs[0][pic->nb_refs[0] - 1]; ++ href = ref->priv_data; ++ hpic->last_idr_frame = href->last_idr_frame; ++ fh->primary_ref_frame = href->slot; ++ fh->ref_order_hint[href->slot] = ref->display_order - href->last_idr_frame; ++ for (i = 0; i < AV1_REF_FRAME_GOLDEN; i++) { ++ fh->ref_frame_idx[i] = href->slot; ++ } + -+ for (i=0; i < AV1_NUM_REF_FRAMES; i++) { -+ fh->ref_order_hint[i] = pic->refs[1]->display_order - hpic->last_idr_frame; -+ } -+ fh->ref_order_hint[0] = pic->refs[0]->display_order - hpic->last_idr_frame; ++ ref = pic->refs[1][pic->nb_refs[1] - 1]; ++ href = ref->priv_data; ++ fh->ref_order_hint[href->slot] = ref->display_order - href->last_idr_frame; ++ for (i = AV1_REF_FRAME_GOLDEN; i < AV1_REFS_PER_FRAME; i++) { ++ fh->ref_frame_idx[i] = href->slot; + } + break; + default: @@ -1405,18 +1645,17 @@ Index: jellyfin-ffmpeg/libavcodec/vaapi_encode_av1.c + else + return AVERROR(EINVAL); + -+ for (i=0; i < fh->tile_cols; i++) ++ for (i = 0; i < fh->tile_cols; i++) + fh->width_in_sbs_minus_1[i] = vpic->width_in_sbs_minus_1[i] = priv->width_in_sbs_minus_1[i]; + -+ for (i=0; i < fh->tile_rows; i++) ++ for (i = 0; i < fh->tile_rows; i++) + fh->height_in_sbs_minus_1[i] = vpic->height_in_sbs_minus_1[i] = priv->height_in_sbs_minus_1[i]; + + memcpy(fh->loop_filter_ref_deltas, default_loop_filter_ref_deltas, + AV1_TOTAL_REFS_PER_FRAME * sizeof(int8_t)); + -+ if (fh->frame_type == AV1_FRAME_KEY) { ++ if (fh->frame_type == AV1_FRAME_KEY && fh->show_frame) { + fh->error_resilient_mode = 1; -+ fh->refresh_frame_flags = (1 << AV1_NUM_REF_FRAMES) - 1; + } + + if (fh->frame_type == AV1_FRAME_KEY || fh->error_resilient_mode) @@ -1431,7 +1670,7 @@ Index: jellyfin-ffmpeg/libavcodec/vaapi_encode_av1.c + vpic->tile_cols = fh->tile_cols; + vpic->tile_rows = fh->tile_rows; + vpic->order_hint = fh->order_hint; -+#if VA_CHECK_VERSION(1, 16, 0) ++#if VA_CHECK_VERSION(1, 15, 0) + vpic->refresh_frame_flags = fh->refresh_frame_flags; +#endif + @@ -1452,16 +1691,19 @@ Index: jellyfin-ffmpeg/libavcodec/vaapi_encode_av1.c + + for (i = 0; i < FF_ARRAY_ELEMS(vpic->reference_frames); i++) + vpic->reference_frames[i] = VA_INVALID_SURFACE; -+ for (i = 0; i < pic->nb_refs; i++) { -+ VAAPIEncodePicture *ref_pic = pic->refs[i]; + -+ slot = ((VAAPIEncodeAV1Picture*)ref_pic->priv_data)->slot; -+ av_assert0(vpic->reference_frames[slot] == VA_INVALID_SURFACE); ++ for (i = 0; i < MAX_REFERENCE_LIST_NUM; i++) { ++ for (int j = 0; j < pic->nb_refs[i]; j++) { ++ VAAPIEncodePicture *ref_pic = pic->refs[i][j]; + -+ vpic->reference_frames[slot] = ref_pic->recon_surface; ++ slot = ((VAAPIEncodeAV1Picture*)ref_pic->priv_data)->slot; ++ av_assert0(vpic->reference_frames[slot] == VA_INVALID_SURFACE); ++ ++ vpic->reference_frames[slot] = ref_pic->recon_surface; ++ } + } + -+ /** pack frame header, and set va params offset like bit_offset_qindex etc. */ ++ /** pack frame header, and set va params offset like bit_offset_qindex etc. */ + ret = vaapi_encode_av1_write_frame_header(avctx, pic, priv->fh_data, &priv->fh_data_len); + if (ret < 0) + goto end; @@ -1501,19 +1743,19 @@ Index: jellyfin-ffmpeg/libavcodec/vaapi_encode_av1.c + CodedBitstreamFragment *obu = &priv->current_obu; + AV1RawOBU *fh_obu = &priv->fh; + AV1RawFrameHeader *rep_fh = &fh_obu->obu.frame_header; -+ VAAPIEncodeAV1Picture *href0; ++ VAAPIEncodeAV1Picture *href; + int ret = 0; + + pic->tail_size = 0; + /** Pack repeat frame header. */ + if (pic->display_order > pic->encode_order) { + memset(fh_obu, 0, sizeof(*fh_obu)); -+ href0 = pic->refs[0]->priv_data; ++ href = pic->refs[0][pic->nb_refs[0] - 1]->priv_data; + fh_obu->header.obu_type = AV1_OBU_FRAME_HEADER; + fh_obu->header.obu_has_size_field = 1; + + rep_fh->show_existing_frame = 1; -+ rep_fh->frame_to_show_map_idx = href0->slot == 0; ++ rep_fh->frame_to_show_map_idx = href->slot == 0; + rep_fh->frame_type = AV1_FRAME_INTER; + rep_fh->frame_width_minus_1 = avctx->width - 1; + rep_fh->frame_height_minus_1 = avctx->height - 1; @@ -1543,8 +1785,7 @@ Index: jellyfin-ffmpeg/libavcodec/vaapi_encode_av1.c + +static const VAAPIEncodeType vaapi_encode_type_av1 = { + .profiles = vaapi_encode_av1_profiles, -+ .flags = FLAG_B_PICTURES | -+ FLAG_B_PICTURE_REFERENCES, ++ .flags = FLAG_B_PICTURES, + .default_quality = 25, + .configure = &vaapi_encode_av1_configure, + @@ -1701,10 +1942,8 @@ Index: jellyfin-ffmpeg/libavcodec/vaapi_encode_av1.c + { LEVEL("6.3", 19) }, +#undef LEVEL + -+ { "tile_cols", "Number of tile columns", -+ OFFSET(tile_cols), AV_OPT_TYPE_INT, { .i64 = 1 }, 1, AV1_MAX_TILE_COLS, FLAGS }, -+ { "tile_rows", "Number of tile rows", -+ OFFSET(tile_rows), AV_OPT_TYPE_INT, { .i64 = 1 }, 1, AV1_MAX_TILE_ROWS, FLAGS }, ++ { "tiles", "Tile columns x rows", ++ OFFSET(tile_cols), AV_OPT_TYPE_IMAGE_SIZE, { .str = "1x1" }, 1, AV1_MAX_TILE_COLS, FLAGS }, + { "tile_groups", "Number of tile groups for encoding", + OFFSET(tile_groups), AV_OPT_TYPE_INT, { .i64 = 1 }, 1, AV1_MAX_TILE_ROWS * AV1_MAX_TILE_COLS, FLAGS }, + @@ -1749,3 +1988,398 @@ Index: jellyfin-ffmpeg/libavcodec/vaapi_encode_av1.c + .hw_configs = ff_vaapi_encode_hw_configs, + .p.wrapper_name = "vaapi", +}; +Index: jellyfin-ffmpeg/libavcodec/vaapi_encode_h264.c +=================================================================== +--- jellyfin-ffmpeg.orig/libavcodec/vaapi_encode_h264.c ++++ jellyfin-ffmpeg/libavcodec/vaapi_encode_h264.c +@@ -614,7 +614,7 @@ static int vaapi_encode_h264_init_pictur + VAAPIEncodePicture *prev = pic->prev; + VAAPIEncodeH264Picture *hprev = prev ? prev->priv_data : NULL; + VAEncPictureParameterBufferH264 *vpic = pic->codec_picture_params; +- int i; ++ int i, j = 0; + + if (pic->type == PICTURE_TYPE_IDR) { + av_assert0(pic->display_order == pic->encode_order); +@@ -715,24 +715,26 @@ static int vaapi_encode_h264_init_pictur + .TopFieldOrderCnt = hpic->pic_order_cnt, + .BottomFieldOrderCnt = hpic->pic_order_cnt, + }; +- +- for (i = 0; i < pic->nb_refs; i++) { +- VAAPIEncodePicture *ref = pic->refs[i]; +- VAAPIEncodeH264Picture *href; +- +- av_assert0(ref && ref->encode_order < pic->encode_order); +- href = ref->priv_data; +- +- vpic->ReferenceFrames[i] = (VAPictureH264) { +- .picture_id = ref->recon_surface, +- .frame_idx = href->frame_num, +- .flags = VA_PICTURE_H264_SHORT_TERM_REFERENCE, +- .TopFieldOrderCnt = href->pic_order_cnt, +- .BottomFieldOrderCnt = href->pic_order_cnt, +- }; ++ for (int k = 0; k < MAX_REFERENCE_LIST_NUM; k++) { ++ for (i = 0; i < pic->nb_refs[k]; i++) { ++ VAAPIEncodePicture *ref = pic->refs[k][i]; ++ VAAPIEncodeH264Picture *href; ++ ++ av_assert0(ref && ref->encode_order < pic->encode_order); ++ href = ref->priv_data; ++ ++ vpic->ReferenceFrames[j++] = (VAPictureH264) { ++ .picture_id = ref->recon_surface, ++ .frame_idx = href->frame_num, ++ .flags = VA_PICTURE_H264_SHORT_TERM_REFERENCE, ++ .TopFieldOrderCnt = href->pic_order_cnt, ++ .BottomFieldOrderCnt = href->pic_order_cnt, ++ }; ++ } + } +- for (; i < FF_ARRAY_ELEMS(vpic->ReferenceFrames); i++) { +- vpic->ReferenceFrames[i] = (VAPictureH264) { ++ ++ for (; j < FF_ARRAY_ELEMS(vpic->ReferenceFrames); j++) { ++ vpic->ReferenceFrames[j] = (VAPictureH264) { + .picture_id = VA_INVALID_ID, + .flags = VA_PICTURE_H264_INVALID, + }; +@@ -934,17 +936,17 @@ static int vaapi_encode_h264_init_slice_ + + if (pic->type == PICTURE_TYPE_P) { + int need_rplm = 0; +- for (i = 0; i < pic->nb_refs; i++) { +- av_assert0(pic->refs[i]); +- if (pic->refs[i] != def_l0[i]) ++ for (i = 0; i < pic->nb_refs[0]; i++) { ++ av_assert0(pic->refs[0][i]); ++ if (pic->refs[0][i] != def_l0[i]) + need_rplm = 1; + } + + sh->ref_pic_list_modification_flag_l0 = need_rplm; + if (need_rplm) { + int pic_num = hpic->frame_num; +- for (i = 0; i < pic->nb_refs; i++) { +- href = pic->refs[i]->priv_data; ++ for (i = 0; i < pic->nb_refs[0]; i++) { ++ href = pic->refs[0][i]->priv_data; + av_assert0(href->frame_num != pic_num); + if (href->frame_num < pic_num) { + sh->rplm_l0[i].modification_of_pic_nums_idc = 0; +@@ -963,28 +965,29 @@ static int vaapi_encode_h264_init_slice_ + } else { + int need_rplm_l0 = 0, need_rplm_l1 = 0; + int n0 = 0, n1 = 0; +- for (i = 0; i < pic->nb_refs; i++) { +- av_assert0(pic->refs[i]); +- href = pic->refs[i]->priv_data; +- av_assert0(href->pic_order_cnt != hpic->pic_order_cnt); +- if (href->pic_order_cnt < hpic->pic_order_cnt) { +- if (pic->refs[i] != def_l0[n0]) +- need_rplm_l0 = 1; +- ++n0; +- } else { +- if (pic->refs[i] != def_l1[n1]) +- need_rplm_l1 = 1; +- ++n1; +- } ++ for (i = 0; i < pic->nb_refs[0]; i++) { ++ av_assert0(pic->refs[0][i]); ++ href = pic->refs[0][i]->priv_data; ++ av_assert0(href->pic_order_cnt < hpic->pic_order_cnt); ++ if (pic->refs[0][i] != def_l0[n0]) ++ need_rplm_l0 = 1; ++ ++n0; ++ } ++ ++ for (i = 0; i < pic->nb_refs[1]; i++) { ++ av_assert0(pic->refs[1][i]); ++ href = pic->refs[1][i]->priv_data; ++ av_assert0(href->pic_order_cnt > hpic->pic_order_cnt); ++ if (pic->refs[1][i] != def_l1[n1]) ++ need_rplm_l1 = 1; ++ ++n1; + } + + sh->ref_pic_list_modification_flag_l0 = need_rplm_l0; + if (need_rplm_l0) { + int pic_num = hpic->frame_num; +- for (i = j = 0; i < pic->nb_refs; i++) { +- href = pic->refs[i]->priv_data; +- if (href->pic_order_cnt > hpic->pic_order_cnt) +- continue; ++ for (i = j = 0; i < pic->nb_refs[0]; i++) { ++ href = pic->refs[0][i]->priv_data; + av_assert0(href->frame_num != pic_num); + if (href->frame_num < pic_num) { + sh->rplm_l0[j].modification_of_pic_nums_idc = 0; +@@ -1005,10 +1008,8 @@ static int vaapi_encode_h264_init_slice_ + sh->ref_pic_list_modification_flag_l1 = need_rplm_l1; + if (need_rplm_l1) { + int pic_num = hpic->frame_num; +- for (i = j = 0; i < pic->nb_refs; i++) { +- href = pic->refs[i]->priv_data; +- if (href->pic_order_cnt < hpic->pic_order_cnt) +- continue; ++ for (i = j = 0; i < pic->nb_refs[1]; i++) { ++ href = pic->refs[1][i]->priv_data; + av_assert0(href->frame_num != pic_num); + if (href->frame_num < pic_num) { + sh->rplm_l1[j].modification_of_pic_nums_idc = 0; +@@ -1048,14 +1049,13 @@ static int vaapi_encode_h264_init_slice_ + vslice->RefPicList1[i].flags = VA_PICTURE_H264_INVALID; + } + +- av_assert0(pic->nb_refs <= 2); +- if (pic->nb_refs >= 1) { ++ if (pic->nb_refs[0]) { + // Backward reference for P- or B-frame. + av_assert0(pic->type == PICTURE_TYPE_P || + pic->type == PICTURE_TYPE_B); + vslice->RefPicList0[0] = vpic->ReferenceFrames[0]; + } +- if (pic->nb_refs >= 2) { ++ if (pic->nb_refs[1]) { + // Forward reference for B-frame. + av_assert0(pic->type == PICTURE_TYPE_B); + vslice->RefPicList1[0] = vpic->ReferenceFrames[1]; +Index: jellyfin-ffmpeg/libavcodec/vaapi_encode_h265.c +=================================================================== +--- jellyfin-ffmpeg.orig/libavcodec/vaapi_encode_h265.c ++++ jellyfin-ffmpeg/libavcodec/vaapi_encode_h265.c +@@ -765,7 +765,7 @@ static int vaapi_encode_h265_init_pictur + VAAPIEncodePicture *prev = pic->prev; + VAAPIEncodeH265Picture *hprev = prev ? prev->priv_data : NULL; + VAEncPictureParameterBufferHEVC *vpic = pic->codec_picture_params; +- int i; ++ int i, j = 0; + + if (pic->type == PICTURE_TYPE_IDR) { + av_assert0(pic->display_order == pic->encode_order); +@@ -790,8 +790,8 @@ static int vaapi_encode_h265_init_pictur + hpic->pic_type = 1; + } else { + VAAPIEncodePicture *irap_ref; +- av_assert0(pic->refs[0] && pic->refs[1]); +- for (irap_ref = pic; irap_ref; irap_ref = irap_ref->refs[1]) { ++ av_assert0(pic->refs[0][0] && pic->refs[1][0]); ++ for (irap_ref = pic; irap_ref; irap_ref = irap_ref->refs[1][0]) { + if (irap_ref->type == PICTURE_TYPE_I) + break; + } +@@ -916,24 +916,27 @@ static int vaapi_encode_h265_init_pictur + .flags = 0, + }; + +- for (i = 0; i < pic->nb_refs; i++) { +- VAAPIEncodePicture *ref = pic->refs[i]; +- VAAPIEncodeH265Picture *href; +- +- av_assert0(ref && ref->encode_order < pic->encode_order); +- href = ref->priv_data; +- +- vpic->reference_frames[i] = (VAPictureHEVC) { +- .picture_id = ref->recon_surface, +- .pic_order_cnt = href->pic_order_cnt, +- .flags = (ref->display_order < pic->display_order ? +- VA_PICTURE_HEVC_RPS_ST_CURR_BEFORE : 0) | +- (ref->display_order > pic->display_order ? +- VA_PICTURE_HEVC_RPS_ST_CURR_AFTER : 0), +- }; ++ for (int k = 0; k < MAX_REFERENCE_LIST_NUM; k++) { ++ for (i = 0; i < pic->nb_refs[k]; i++) { ++ VAAPIEncodePicture *ref = pic->refs[k][i]; ++ VAAPIEncodeH265Picture *href; ++ ++ av_assert0(ref && ref->encode_order < pic->encode_order); ++ href = ref->priv_data; ++ ++ vpic->reference_frames[j++] = (VAPictureHEVC) { ++ .picture_id = ref->recon_surface, ++ .pic_order_cnt = href->pic_order_cnt, ++ .flags = (ref->display_order < pic->display_order ? ++ VA_PICTURE_HEVC_RPS_ST_CURR_BEFORE : 0) | ++ (ref->display_order > pic->display_order ? ++ VA_PICTURE_HEVC_RPS_ST_CURR_AFTER : 0), ++ }; ++ } + } +- for (; i < FF_ARRAY_ELEMS(vpic->reference_frames); i++) { +- vpic->reference_frames[i] = (VAPictureHEVC) { ++ ++ for (; j < FF_ARRAY_ELEMS(vpic->reference_frames); j++) { ++ vpic->reference_frames[j] = (VAPictureHEVC) { + .picture_id = VA_INVALID_ID, + .flags = VA_PICTURE_HEVC_INVALID, + }; +@@ -1017,21 +1020,33 @@ static int vaapi_encode_h265_init_slice_ + memset(rps, 0, sizeof(*rps)); + + rps_pics = 0; +- for (i = 0; i < pic->nb_refs; i++) { +- strp = pic->refs[i]->priv_data; +- rps_poc[rps_pics] = strp->pic_order_cnt; +- rps_used[rps_pics] = 1; +- ++rps_pics; ++ for (i = 0; i < MAX_REFERENCE_LIST_NUM; i++) { ++ for (j = 0; j < pic->nb_refs[i]; j++) { ++ strp = pic->refs[i][j]->priv_data; ++ rps_poc[rps_pics] = strp->pic_order_cnt; ++ rps_used[rps_pics] = 1; ++ ++rps_pics; ++ } + } ++ + for (i = 0; i < pic->nb_dpb_pics; i++) { + if (pic->dpb[i] == pic) + continue; +- for (j = 0; j < pic->nb_refs; j++) { +- if (pic->dpb[i] == pic->refs[j]) ++ ++ for (j = 0; j < pic->nb_refs[0]; j++) { ++ if (pic->dpb[i] == pic->refs[0][j]) + break; + } +- if (j < pic->nb_refs) ++ if (j < pic->nb_refs[0]) + continue; ++ ++ for (j = 0; j < pic->nb_refs[1]; j++) { ++ if (pic->dpb[i] == pic->refs[1][j]) ++ break; ++ } ++ if (j < pic->nb_refs[1]) ++ continue; ++ + strp = pic->dpb[i]->priv_data; + rps_poc[rps_pics] = strp->pic_order_cnt; + rps_used[rps_pics] = 0; +@@ -1156,8 +1171,7 @@ static int vaapi_encode_h265_init_slice_ + vslice->ref_pic_list1[i].flags = VA_PICTURE_HEVC_INVALID; + } + +- av_assert0(pic->nb_refs <= 2); +- if (pic->nb_refs >= 1) { ++ if (pic->nb_refs[0]) { + // Backward reference for P- or B-frame. + av_assert0(pic->type == PICTURE_TYPE_P || + pic->type == PICTURE_TYPE_B); +@@ -1166,7 +1180,7 @@ static int vaapi_encode_h265_init_slice_ + // Reference for GPB B-frame, L0 == L1 + vslice->ref_pic_list1[0] = vpic->reference_frames[0]; + } +- if (pic->nb_refs >= 2) { ++ if (pic->nb_refs[1]) { + // Forward reference for B-frame. + av_assert0(pic->type == PICTURE_TYPE_B); + vslice->ref_pic_list1[0] = vpic->reference_frames[1]; +Index: jellyfin-ffmpeg/libavcodec/vaapi_encode_mpeg2.c +=================================================================== +--- jellyfin-ffmpeg.orig/libavcodec/vaapi_encode_mpeg2.c ++++ jellyfin-ffmpeg/libavcodec/vaapi_encode_mpeg2.c +@@ -458,12 +458,12 @@ static int vaapi_encode_mpeg2_init_pictu + break; + case PICTURE_TYPE_P: + vpic->picture_type = VAEncPictureTypePredictive; +- vpic->forward_reference_picture = pic->refs[0]->recon_surface; ++ vpic->forward_reference_picture = pic->refs[0][0]->recon_surface; + break; + case PICTURE_TYPE_B: + vpic->picture_type = VAEncPictureTypeBidirectional; +- vpic->forward_reference_picture = pic->refs[0]->recon_surface; +- vpic->backward_reference_picture = pic->refs[1]->recon_surface; ++ vpic->forward_reference_picture = pic->refs[0][0]->recon_surface; ++ vpic->backward_reference_picture = pic->refs[1][0]->recon_surface; + break; + default: + av_assert0(0 && "invalid picture type"); +Index: jellyfin-ffmpeg/libavcodec/vaapi_encode_vp8.c +=================================================================== +--- jellyfin-ffmpeg.orig/libavcodec/vaapi_encode_vp8.c ++++ jellyfin-ffmpeg/libavcodec/vaapi_encode_vp8.c +@@ -86,7 +86,7 @@ static int vaapi_encode_vp8_init_picture + switch (pic->type) { + case PICTURE_TYPE_IDR: + case PICTURE_TYPE_I: +- av_assert0(pic->nb_refs == 0); ++ av_assert0(pic->nb_refs[0] == 0 && pic->nb_refs[1] == 0); + vpic->ref_flags.bits.force_kf = 1; + vpic->ref_last_frame = + vpic->ref_gf_frame = +@@ -94,14 +94,14 @@ static int vaapi_encode_vp8_init_picture + VA_INVALID_SURFACE; + break; + case PICTURE_TYPE_P: +- av_assert0(pic->nb_refs == 1); ++ av_assert0(!pic->nb_refs[1]); + vpic->ref_flags.bits.no_ref_last = 0; + vpic->ref_flags.bits.no_ref_gf = 1; + vpic->ref_flags.bits.no_ref_arf = 1; + vpic->ref_last_frame = + vpic->ref_gf_frame = + vpic->ref_arf_frame = +- pic->refs[0]->recon_surface; ++ pic->refs[0][0]->recon_surface; + break; + default: + av_assert0(0 && "invalid picture type"); +Index: jellyfin-ffmpeg/libavcodec/vaapi_encode_vp9.c +=================================================================== +--- jellyfin-ffmpeg.orig/libavcodec/vaapi_encode_vp9.c ++++ jellyfin-ffmpeg/libavcodec/vaapi_encode_vp9.c +@@ -96,15 +96,15 @@ static int vaapi_encode_vp9_init_picture + + switch (pic->type) { + case PICTURE_TYPE_IDR: +- av_assert0(pic->nb_refs == 0); ++ av_assert0(pic->nb_refs[0] == 0 && pic->nb_refs[1] == 0); + vpic->ref_flags.bits.force_kf = 1; + vpic->refresh_frame_flags = 0xff; + hpic->slot = 0; + break; + case PICTURE_TYPE_P: +- av_assert0(pic->nb_refs == 1); ++ av_assert0(!pic->nb_refs[1]); + { +- VAAPIEncodeVP9Picture *href = pic->refs[0]->priv_data; ++ VAAPIEncodeVP9Picture *href = pic->refs[0][0]->priv_data; + av_assert0(href->slot == 0 || href->slot == 1); + + if (ctx->max_b_depth > 0) { +@@ -120,10 +120,10 @@ static int vaapi_encode_vp9_init_picture + } + break; + case PICTURE_TYPE_B: +- av_assert0(pic->nb_refs == 2); ++ av_assert0(pic->nb_refs[0] && pic->nb_refs[1]); + { +- VAAPIEncodeVP9Picture *href0 = pic->refs[0]->priv_data, +- *href1 = pic->refs[1]->priv_data; ++ VAAPIEncodeVP9Picture *href0 = pic->refs[0][0]->priv_data, ++ *href1 = pic->refs[1][0]->priv_data; + av_assert0(href0->slot < pic->b_depth + 1 && + href1->slot < pic->b_depth + 1); + +@@ -157,12 +157,14 @@ static int vaapi_encode_vp9_init_picture + for (i = 0; i < FF_ARRAY_ELEMS(vpic->reference_frames); i++) + vpic->reference_frames[i] = VA_INVALID_SURFACE; + +- for (i = 0; i < pic->nb_refs; i++) { +- VAAPIEncodePicture *ref_pic = pic->refs[i]; +- int slot; +- slot = ((VAAPIEncodeVP9Picture*)ref_pic->priv_data)->slot; +- av_assert0(vpic->reference_frames[slot] == VA_INVALID_SURFACE); +- vpic->reference_frames[slot] = ref_pic->recon_surface; ++ for (i = 0; i < MAX_REFERENCE_LIST_NUM; i++) { ++ for (int j = 0; j < pic->nb_refs[i]; j++) { ++ VAAPIEncodePicture *ref_pic = pic->refs[i][j]; ++ int slot; ++ slot = ((VAAPIEncodeVP9Picture*)ref_pic->priv_data)->slot; ++ av_assert0(vpic->reference_frames[slot] == VA_INVALID_SURFACE); ++ vpic->reference_frames[slot] = ref_pic->recon_surface; ++ } + } + + vpic->pic_flags.bits.frame_type = (pic->type != PICTURE_TYPE_IDR); diff --git a/debian/patches/0052-backport-upstream-qsvenc-fixes.patch b/debian/patches/0052-backport-upstream-qsvenc-fixes.patch index e49f9d6f2d2..f7f888dcebf 100644 --- a/debian/patches/0052-backport-upstream-qsvenc-fixes.patch +++ b/debian/patches/0052-backport-upstream-qsvenc-fixes.patch @@ -236,6 +236,15 @@ Index: jellyfin-ffmpeg/libavutil/hwcontext_qsv.c fail: #endif return ret; +@@ -1927,7 +1939,7 @@ static int qsv_map_to(AVHWFramesContext + case AV_PIX_FMT_VAAPI: + { + mfxHDLPair *pair = (mfxHDLPair*)hwctx->surfaces[i].Data.MemId; +- if (*(VASurfaceID*)pair->first == (VASurfaceID)src->data[3]) { ++ if (*(VASurfaceID*)pair->first == (VASurfaceID)(uintptr_t)src->data[3]) { + index = i; + break; + } @@ -2187,6 +2199,15 @@ static int qsv_device_derive(AVHWDeviceC AVDictionary *opts, int flags) { diff --git a/debian/patches/0053-allow-vaapi-import-drm-prime2-planar-formats.patch b/debian/patches/0053-allow-vaapi-import-drm-prime2-planar-formats.patch index 5553855d9fe..33cbc29a041 100644 --- a/debian/patches/0053-allow-vaapi-import-drm-prime2-planar-formats.patch +++ b/debian/patches/0053-allow-vaapi-import-drm-prime2-planar-formats.patch @@ -2,7 +2,15 @@ Index: jellyfin-ffmpeg/libavutil/hwcontext_vaapi.c =================================================================== --- jellyfin-ffmpeg.orig/libavutil/hwcontext_vaapi.c +++ jellyfin-ffmpeg/libavutil/hwcontext_vaapi.c -@@ -1021,9 +1021,11 @@ static const struct { +@@ -150,6 +150,7 @@ static const VAAPIFormatDescriptor vaapi + MAP(XRGB, RGB32, 0RGB, 0), + #ifdef VA_FOURCC_X2R10G10B10 + MAP(X2R10G10B10, RGB32_10, X2RGB10, 0), ++ MAP(X2B10G10R10, RGB32_10, X2BGR10, 0), + #endif + #ifdef VA_FOURCC_Y410 + // libva doesn't include a fourcc for XV30 and the driver only declares +@@ -1016,9 +1017,11 @@ static const struct { DRM_MAP(NV12, 1, DRM_FORMAT_NV12), #if defined(VA_FOURCC_P010) && defined(DRM_FORMAT_R16) DRM_MAP(P010, 2, DRM_FORMAT_R16, DRM_FORMAT_RG1616), @@ -14,7 +22,18 @@ Index: jellyfin-ffmpeg/libavutil/hwcontext_vaapi.c #endif DRM_MAP(BGRA, 1, DRM_FORMAT_ARGB8888), DRM_MAP(BGRX, 1, DRM_FORMAT_XRGB8888), -@@ -1099,12 +1101,6 @@ static int vaapi_map_from_drm(AVHWFrames +@@ -1030,6 +1033,10 @@ static const struct { + #endif + DRM_MAP(ARGB, 1, DRM_FORMAT_BGRA8888), + DRM_MAP(XRGB, 1, DRM_FORMAT_BGRX8888), ++#ifdef VA_FOURCC_X2R10G10B10 ++ DRM_MAP(X2R10G10B10, 1, DRM_FORMAT_XRGB2101010), ++ DRM_MAP(X2B10G10R10, 1, DRM_FORMAT_XBGR2101010), ++#endif + #if defined(VA_FOURCC_XYUV) && defined(DRM_FORMAT_XYUV8888) + DRM_MAP(XYUV, 1, DRM_FORMAT_XYUV8888), + #endif +@@ -1094,12 +1101,6 @@ static int vaapi_map_from_drm(AVHWFrames desc = (AVDRMFrameDescriptor*)src->data[0]; @@ -27,20 +46,7 @@ Index: jellyfin-ffmpeg/libavutil/hwcontext_vaapi.c va_fourcc = 0; for (i = 0; i < FF_ARRAY_ELEMS(vaapi_drm_format_map); i++) { if (desc->nb_layers != vaapi_drm_format_map[i].nb_layer_formats) -@@ -1213,6 +1209,12 @@ static int vaapi_map_from_drm(AVHWFrames - } - }; - -+ if (desc->nb_objects != 1) { -+ av_log(dst_fc, AV_LOG_ERROR, "VAAPI can only map frames " -+ "made from a single DRM object.\n"); -+ return AVERROR(EINVAL); -+ } -+ - buffer_handle = desc->objects[0].fd; - buffer_desc.pixel_format = va_fourcc; - buffer_desc.width = src_fc->width; -@@ -1244,6 +1246,12 @@ static int vaapi_map_from_drm(AVHWFrames +@@ -1239,6 +1240,12 @@ static int vaapi_map_from_drm(AVHWFrames buffer_attrs, FF_ARRAY_ELEMS(buffer_attrs)); } #else diff --git a/debian/patches/0055-use-contiguous-linear-vulkan-images-for-amd-encoder.patch b/debian/patches/0055-use-contiguous-linear-vulkan-images-for-amd-encoder.patch new file mode 100644 index 00000000000..0b03ebca565 --- /dev/null +++ b/debian/patches/0055-use-contiguous-linear-vulkan-images-for-amd-encoder.patch @@ -0,0 +1,203 @@ +Index: jellyfin-ffmpeg/libavutil/hwcontext_vulkan.c +=================================================================== +--- jellyfin-ffmpeg.orig/libavutil/hwcontext_vulkan.c ++++ jellyfin-ffmpeg/libavutil/hwcontext_vulkan.c +@@ -111,6 +111,9 @@ typedef struct VulkanDevicePriv { + + /* Intel */ + int dev_is_intel; ++ ++ /* Amd */ ++ int dev_is_amd; + } VulkanDevicePriv; + + typedef struct VulkanFramesPriv { +@@ -231,6 +234,7 @@ static const struct { + { AV_PIX_FMT_BGR32, { VK_FORMAT_A8B8G8R8_UNORM_PACK32 } }, + { AV_PIX_FMT_0BGR32, { VK_FORMAT_A8B8G8R8_UNORM_PACK32 } }, + ++ { AV_PIX_FMT_X2BGR10, { VK_FORMAT_A2B10G10R10_UNORM_PACK32 } }, + { AV_PIX_FMT_X2RGB10, { VK_FORMAT_A2R10G10B10_UNORM_PACK32 } }, + + { AV_PIX_FMT_GBRAP, { VK_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM } }, +@@ -1482,6 +1486,13 @@ static int vulkan_device_init(AVHWDevice + + p->dev_is_nvidia = (p->props.properties.vendorID == 0x10de); + p->dev_is_intel = (p->props.properties.vendorID == 0x8086); ++ p->dev_is_amd = (p->props.properties.vendorID == 0x1002); ++ ++#if CONFIG_LIBDRM ++ /* AMD encoder requires contiguous and linear images */ ++ if (p->dev_is_amd) ++ p->use_linear_images = 1; ++#endif + + vk->GetPhysicalDeviceQueueFamilyProperties(hwctx->phys_dev, &queue_num, NULL); + if (!queue_num) { +@@ -2292,7 +2303,7 @@ static int vulkan_frames_init(AVHWFrames + + if (!(hwctx->flags & AV_VK_FRAME_FLAG_NONE)) { + if (p->contiguous_planes == 1 || +- ((p->contiguous_planes == -1) && p->dev_is_intel)) ++ (p->contiguous_planes == -1 && (p->dev_is_intel || p->dev_is_amd))) + hwctx->flags |= AV_VK_FRAME_FLAG_CONTIGUOUS_MEMORY; + } + +@@ -2360,19 +2371,23 @@ static int vulkan_frames_init(AVHWFrames + /* Finally get all modifiers from the device */ + vk->GetPhysicalDeviceFormatProperties2(dev_hwctx->phys_dev, fmt[0], &prop); + +- /* Reject any modifiers that don't match our requirements */ +- for (int i = 0; i < mod_props_list.drmFormatModifierCount; i++) { +- if (!(mod_props[i].drmFormatModifierTilingFeatures & hwctx->usage)) +- continue; +- +- modifiers[modifier_count++] = mod_props[i].drmFormatModifier; +- } ++ if (p->use_linear_images) { ++ has_modifiers = 0; ++ modifiers[modifier_count++] = 0x0; ++ } else { ++ /* Reject any modifiers that don't match our requirements */ ++ for (int i = 0; i < mod_props_list.drmFormatModifierCount; i++) { ++ if (!(mod_props[i].drmFormatModifierTilingFeatures & hwctx->usage)) ++ continue; ++ modifiers[modifier_count++] = mod_props[i].drmFormatModifier; ++ } + +- if (!modifier_count) { +- av_log(hwfc, AV_LOG_ERROR, "None of the given modifiers supports" +- " the usage flags!\n"); +- av_freep(&mod_props); +- return AVERROR(EINVAL); ++ if (!modifier_count) { ++ av_log(hwfc, AV_LOG_ERROR, "None of the given modifiers supports" ++ " the usage flags!\n"); ++ av_freep(&mod_props); ++ return AVERROR(EINVAL); ++ } + } + + modifier_info->drmFormatModifierCount = modifier_count; +@@ -2465,9 +2480,11 @@ static void vulkan_unmap_frame(AVHWFrame + { + VulkanMapping *map = hwmap->priv; + AVVulkanDeviceContext *hwctx = hwfc->device_ctx->hwctx; ++ AVVulkanFramesContext *hwfctx = hwfc->hwctx; + const int planes = av_pix_fmt_count_planes(hwfc->sw_format); + VulkanDevicePriv *p = hwfc->device_ctx->internal->priv; + FFVulkanFunctions *vk = &p->vkfn; ++ int mem_planes = 0; + + /* Check if buffer needs flushing */ + if ((map->flags & AV_HWFRAME_MAP_WRITE) && +@@ -2489,7 +2506,8 @@ static void vulkan_unmap_frame(AVHWFrame + } + } + +- for (int i = 0; i < planes; i++) ++ mem_planes = hwfctx->flags & AV_VK_FRAME_FLAG_CONTIGUOUS_MEMORY ? 1 : planes; ++ for (int i = 0; i < mem_planes; i++) + vk->UnmapMemory(hwctx->act_dev, map->frame->mem[i]); + + av_free(map); +@@ -2638,6 +2656,10 @@ static const struct { + { DRM_FORMAT_XRGB8888, VK_FORMAT_B8G8R8A8_UNORM }, + { DRM_FORMAT_ABGR8888, VK_FORMAT_R8G8B8A8_UNORM }, + { DRM_FORMAT_XBGR8888, VK_FORMAT_R8G8B8A8_UNORM }, ++ { DRM_FORMAT_ARGB2101010, VK_FORMAT_A2R10G10B10_UNORM_PACK32 }, ++ { DRM_FORMAT_XRGB2101010, VK_FORMAT_A2R10G10B10_UNORM_PACK32 }, ++ { DRM_FORMAT_ABGR2101010, VK_FORMAT_A2B10G10R10_UNORM_PACK32 }, ++ { DRM_FORMAT_XBGR2101010, VK_FORMAT_A2B10G10R10_UNORM_PACK32 }, + + // All these DRM_FORMATs were added in the same libdrm commit. + #ifdef DRM_FORMAT_XYUV8888 +@@ -2672,6 +2694,7 @@ static int vulkan_map_from_drm_frame_des + const AVDRMFrameDescriptor *desc = (AVDRMFrameDescriptor *)src->data[0]; + VkBindImageMemoryInfo bind_info[AV_DRM_MAX_PLANES]; + VkBindImagePlaneMemoryInfo plane_info[AV_DRM_MAX_PLANES]; ++ const int has_modifiers = !!(p->extensions & FF_VK_EXT_DRM_MODIFIER_FLAGS); + + for (int i = 0; i < desc->nb_layers; i++) { + if (drm_to_vulkan_fmt(desc->layers[i].format) == VK_FORMAT_UNDEFINED) { +@@ -2681,13 +2704,22 @@ static int vulkan_map_from_drm_frame_des + } + } + ++ if (!has_modifiers && ++ desc->objects[0].format_modifier != DRM_FORMAT_MOD_INVALID && ++ desc->objects[0].format_modifier != DRM_FORMAT_MOD_LINEAR) { ++ av_log(ctx, AV_LOG_ERROR, "The driver can only import DRM frame with invalid/linear modifier!\n"); ++ err = AVERROR_EXTERNAL; ++ goto fail; ++ } ++ + if (!(f = av_vk_frame_alloc())) { + av_log(ctx, AV_LOG_ERROR, "Unable to allocate memory for AVVkFrame!\n"); + err = AVERROR(ENOMEM); + goto fail; + } + +- f->tiling = VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT; ++ f->tiling = has_modifiers ? VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT : ++ VK_IMAGE_TILING_LINEAR; + + for (int i = 0; i < desc->nb_layers; i++) { + const int planes = desc->layers[i].nb_planes; +@@ -2758,7 +2790,7 @@ static int vulkan_map_from_drm_frame_des + }; + VkPhysicalDeviceImageFormatInfo2 fmt_props = { + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2, +- .pNext = &props_ext, ++ .pNext = has_modifiers ? &props_ext : NULL, + .format = create_info.format, + .type = create_info.imageType, + .tiling = create_info.tiling, +@@ -2776,6 +2808,10 @@ static int vulkan_map_from_drm_frame_des + goto fail; + } + ++ /* Skip checking if the driver has no support for the DRM modifier extension */ ++ if (!has_modifiers && !fmt_props.pNext) ++ fmt_props.pNext = &props_ext; ++ + /* Set the image width/height */ + get_plane_wh(&create_info.extent.width, &create_info.extent.height, + hwfc->sw_format, src->width, src->height, i); +@@ -3328,6 +3364,7 @@ static int vulkan_map_to_drm(AVHWFramesC + AVVulkanDeviceContext *hwctx = hwfc->device_ctx->hwctx; + AVVulkanFramesContext *hwfctx = hwfc->hwctx; + const int planes = av_pix_fmt_count_planes(hwfc->sw_format); ++ const int has_modifiers = !!(p->extensions & FF_VK_EXT_DRM_MODIFIER_FLAGS); + VkImageDrmFormatModifierPropertiesEXT drm_mod = { + .sType = VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_PROPERTIES_EXT, + }; +@@ -3355,10 +3392,16 @@ static int vulkan_map_to_drm(AVHWFramesC + if (err < 0) + goto end; + +- ret = vk->GetImageDrmFormatModifierPropertiesEXT(hwctx->act_dev, f->img[0], ++ if (has_modifiers) { ++ ret = vk->GetImageDrmFormatModifierPropertiesEXT(hwctx->act_dev, f->img[0], + &drm_mod); +- if (ret != VK_SUCCESS) { +- av_log(hwfc, AV_LOG_ERROR, "Failed to retrieve DRM format modifier!\n"); ++ if (ret != VK_SUCCESS) { ++ av_log(hwfc, AV_LOG_ERROR, "Failed to retrieve DRM format modifier!\n"); ++ err = AVERROR_EXTERNAL; ++ goto end; ++ } ++ } else if (f->tiling != VK_IMAGE_TILING_LINEAR) { ++ av_log(hwfc, AV_LOG_ERROR, "The driver can only export linear images to DRM frame!\n"); + err = AVERROR_EXTERNAL; + goto end; + } +@@ -3380,7 +3423,7 @@ static int vulkan_map_to_drm(AVHWFramesC + + drm_desc->nb_objects++; + drm_desc->objects[i].size = f->size[i]; +- drm_desc->objects[i].format_modifier = drm_mod.drmFormatModifier; ++ drm_desc->objects[i].format_modifier = has_modifiers ? drm_mod.drmFormatModifier : 0x0; + } + + drm_desc->nb_layers = planes; diff --git a/debian/patches/0056-fix-libplacebo-filter-build-with-v6-api.patch b/debian/patches/0056-fix-libplacebo-filter-build-with-v6-api.patch new file mode 100644 index 00000000000..57621875c19 --- /dev/null +++ b/debian/patches/0056-fix-libplacebo-filter-build-with-v6-api.patch @@ -0,0 +1,37 @@ +Index: jellyfin-ffmpeg/libavfilter/vf_libplacebo.c +=================================================================== +--- jellyfin-ffmpeg.orig/libavfilter/vf_libplacebo.c ++++ jellyfin-ffmpeg/libavfilter/vf_libplacebo.c +@@ -98,7 +98,6 @@ typedef struct LibplaceboContext { + float polar_cutoff; + int disable_linear; + int disable_builtin; +- int force_icc_lut; + int force_dither; + int disable_fbos; + +@@ -138,6 +137,7 @@ typedef struct LibplaceboContext { + float desat_exp; + int gamut_warning; + int gamut_clipping; ++ int force_icc_lut; + + /* pl_dither_params */ + int dithering; +@@ -446,7 +446,6 @@ static int process_frames(AVFilterContex + .polar_cutoff = s->polar_cutoff, + .disable_linear_scaling = s->disable_linear, + .disable_builtin_scalers = s->disable_builtin, +- .force_icc_lut = s->force_icc_lut, + .force_dither = s->force_dither, + .disable_fbos = s->disable_fbos, + }; +@@ -774,7 +773,7 @@ static const AVOption libplacebo_options + { "polar_cutoff", "Polar LUT cutoff", OFFSET(polar_cutoff), AV_OPT_TYPE_FLOAT, {.dbl = 0}, 0.0, 1.0, DYNAMIC }, + { "disable_linear", "Disable linear scaling", OFFSET(disable_linear), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, DYNAMIC }, + { "disable_builtin", "Disable built-in scalers", OFFSET(disable_builtin), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, DYNAMIC }, +- { "force_icc_lut", "Force the use of a full ICC 3DLUT for color mapping", OFFSET(force_icc_lut), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, DYNAMIC }, ++ { "force_icc_lut", "Deprecated, does nothing", OFFSET(force_icc_lut), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, DYNAMIC | AV_OPT_FLAG_DEPRECATED }, + { "force_dither", "Force dithering", OFFSET(force_dither), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, DYNAMIC }, + { "disable_fbos", "Force-disable FBOs", OFFSET(disable_fbos), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, DYNAMIC }, + { NULL }, diff --git a/debian/patches/0057-fix-x86-mathops-assembly-build-with-newer-binutil.patch b/debian/patches/0057-fix-x86-mathops-assembly-build-with-newer-binutil.patch new file mode 100644 index 00000000000..5b1253b8c08 --- /dev/null +++ b/debian/patches/0057-fix-x86-mathops-assembly-build-with-newer-binutil.patch @@ -0,0 +1,60 @@ +Index: jellyfin-ffmpeg/libavcodec/x86/mathops.h +=================================================================== +--- jellyfin-ffmpeg.orig/libavcodec/x86/mathops.h ++++ jellyfin-ffmpeg/libavcodec/x86/mathops.h +@@ -35,12 +35,20 @@ + static av_always_inline av_const int MULL(int a, int b, unsigned shift) + { + int rt, dummy; ++ if (__builtin_constant_p(shift)) + __asm__ ( + "imull %3 \n\t" + "shrdl %4, %%edx, %%eax \n\t" + :"=a"(rt), "=d"(dummy) +- :"a"(a), "rm"(b), "ci"((uint8_t)shift) ++ :"a"(a), "rm"(b), "i"(shift & 0x1F) + ); ++ else ++ __asm__ ( ++ "imull %3 \n\t" ++ "shrdl %4, %%edx, %%eax \n\t" ++ :"=a"(rt), "=d"(dummy) ++ :"a"(a), "rm"(b), "c"((uint8_t)shift) ++ ); + return rt; + } + +@@ -113,19 +121,31 @@ __asm__ volatile(\ + // avoid +32 for shift optimization (gcc should do that ...) + #define NEG_SSR32 NEG_SSR32 + static inline int32_t NEG_SSR32( int32_t a, int8_t s){ ++ if (__builtin_constant_p(s)) + __asm__ ("sarl %1, %0\n\t" + : "+r" (a) +- : "ic" ((uint8_t)(-s)) ++ : "i" (-s & 0x1F) + ); ++ else ++ __asm__ ("sarl %1, %0\n\t" ++ : "+r" (a) ++ : "c" ((uint8_t)(-s)) ++ ); + return a; + } + + #define NEG_USR32 NEG_USR32 + static inline uint32_t NEG_USR32(uint32_t a, int8_t s){ ++ if (__builtin_constant_p(s)) + __asm__ ("shrl %1, %0\n\t" + : "+r" (a) +- : "ic" ((uint8_t)(-s)) ++ : "i" (-s & 0x1F) + ); ++ else ++ __asm__ ("shrl %1, %0\n\t" ++ : "+r" (a) ++ : "c" ((uint8_t)(-s)) ++ ); + return a; + } + diff --git a/debian/patches/series b/debian/patches/series index 333c4519fb6..8c5df728795 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -52,3 +52,6 @@ 0052-backport-upstream-qsvenc-fixes.patch 0053-allow-vaapi-import-drm-prime2-planar-formats.patch 0054-add-vui-info-to-the-seq-header-of-hevc-vaapi-encoder.patch +0055-use-contiguous-linear-vulkan-images-for-amd-encoder.patch +0056-fix-libplacebo-filter-build-with-v6-api.patch +0057-fix-x86-mathops-assembly-build-with-newer-binutil.patch diff --git a/docker-build-win64.sh b/docker-build-win64.sh index 7a965e356d3..9c1634be594 100755 --- a/docker-build-win64.sh +++ b/docker-build-win64.sh @@ -100,7 +100,7 @@ popd # GMP mkdir gmp pushd gmp -gmp_ver="6.2.1" +gmp_ver="6.3.0" gmp_link="https://ftp.gnu.org/gnu/gmp/gmp-${gmp_ver}.tar.xz" wget ${gmp_link} -O gmp.tar.gz tar xaf gmp.tar.gz @@ -159,7 +159,7 @@ popd popd # LZMA -git clone -b v5.4.3 --depth=1 https://github.com/xz-mirror/xz.git +git clone -b v5.4.4 --depth=1 https://github.com/xz-mirror/xz.git pushd xz ./autogen.sh --no-po4a --no-doxygen ./configure \ @@ -339,7 +339,7 @@ popd popd # LIBWEBP -git clone -b v1.3.0 --depth=1 https://chromium.googlesource.com/webm/libwebp +git clone -b v1.3.1 --depth=1 https://chromium.googlesource.com/webm/libwebp pushd libwebp ./autogen.sh ./configure \ @@ -557,7 +557,7 @@ mv * ${FF_DEPS_PREFIX}/include/AMF popd # VPL -git clone -b v2023.3.0 --depth=1 https://github.com/oneapi-src/oneVPL.git +git clone -b v2023.3.1 --depth=1 https://github.com/oneapi-src/oneVPL.git pushd oneVPL mkdir build && pushd build cmake \ diff --git a/docker-build.sh b/docker-build.sh index b7d5c879feb..93973562ae9 100755 --- a/docker-build.sh +++ b/docker-build.sh @@ -196,10 +196,10 @@ prepare_extra_amd64() { # LIBVA pushd ${SOURCE_DIR} - git clone -b 2.18.0 --depth=1 https://github.com/intel/libva.git + git clone -b 2.19.0 --depth=1 https://github.com/intel/libva.git pushd libva - sed -i 's|getenv("LIBVA_DRIVERS_PATH")|"/usr/lib/jellyfin-ffmpeg/lib/dri:/usr/lib/x86_64-linux-gnu/dri:/usr/lib/dri:/usr/local/lib/dri"|g' va/va.c - sed -i 's|getenv("LIBVA_DRIVER_NAME")|getenv("LIBVA_DRIVER_NAME_JELLYFIN")|g' va/va.c + sed -i 's|secure_getenv("LIBVA_DRIVERS_PATH")|"/usr/lib/jellyfin-ffmpeg/lib/dri:/usr/lib/x86_64-linux-gnu/dri:/usr/lib/dri:/usr/local/lib/dri"|g' va/va.c + sed -i 's|secure_getenv("LIBVA_DRIVER_NAME")|secure_getenv("LIBVA_DRIVER_NAME_JELLYFIN")|g' va/va.c ./autogen.sh ./configure \ --prefix=${TARGET_DIR} \ @@ -213,7 +213,7 @@ prepare_extra_amd64() { # LIBVA-UTILS pushd ${SOURCE_DIR} - git clone -b 2.18.2 --depth=1 https://github.com/intel/libva-utils.git + git clone -b 2.19.0 --depth=1 https://github.com/intel/libva-utils.git pushd libva-utils ./autogen.sh ./configure --prefix=${TARGET_DIR} @@ -237,7 +237,7 @@ prepare_extra_amd64() { # GMMLIB pushd ${SOURCE_DIR} - git clone -b intel-gmmlib-22.3.7 --depth=1 https://github.com/intel/gmmlib.git + git clone -b intel-gmmlib-22.3.9 --depth=1 https://github.com/intel/gmmlib.git pushd gmmlib mkdir build && pushd build cmake -DCMAKE_INSTALL_PREFIX=${TARGET_DIR} .. @@ -249,7 +249,6 @@ prepare_extra_amd64() { # MediaSDK (RT only) # Provides MSDK runtime (libmfxhw64.so.1) for 11th Gen Rocket Lake and older - # Provides MFX dispatcher (libmfx.so.1) for FFmpeg pushd ${SOURCE_DIR} git clone -b intel-mediasdk-23.2.2 --depth=1 https://github.com/Intel-Media-SDK/MediaSDK.git pushd MediaSDK @@ -267,8 +266,10 @@ prepare_extra_amd64() { popd # ONEVPL (dispatcher + header) + # Provides VPL header and dispatcher (libvpl.so.2) for FFmpeg + # Both MSDK and VPL runtime can be loaded by VPL dispatcher pushd ${SOURCE_DIR} - git clone -b v2023.3.0 --depth=1 https://github.com/oneapi-src/oneVPL.git + git clone -b v2023.3.1 --depth=1 https://github.com/oneapi-src/oneVPL.git pushd oneVPL sed -i 's|ParseEnvSearchPaths(ONEVPL_PRIORITY_PATH_VAR, searchDirList)|searchDirList.push_back("/usr/lib/jellyfin-ffmpeg/lib")|g' dispatcher/vpl/mfx_dispatcher_vpl_loader.cpp mkdir build && pushd build @@ -290,9 +291,8 @@ prepare_extra_amd64() { # ONEVPL-INTEL-GPU (RT only) # Provides VPL runtime (libmfx-gen.so.1.2) for 11th Gen Tiger Lake and newer - # Both MSDK and VPL runtime can be loaded by MFX dispatcher (libmfx.so.1) pushd ${SOURCE_DIR} - git clone -b intel-onevpl-23.2.3 --depth=1 https://github.com/oneapi-src/oneVPL-intel-gpu.git + git clone -b intel-onevpl-23.3.0 --depth=1 https://github.com/oneapi-src/oneVPL-intel-gpu.git pushd oneVPL-intel-gpu mkdir build && pushd build cmake -DCMAKE_INSTALL_PREFIX=${TARGET_DIR} \ @@ -312,14 +312,8 @@ prepare_extra_amd64() { # Full Feature Build: ENABLE_KERNELS=ON(Default) ENABLE_NONFREE_KERNELS=ON(Default) # Free Kernel Build: ENABLE_KERNELS=ON ENABLE_NONFREE_KERNELS=OFF pushd ${SOURCE_DIR} - git clone -b intel-media-23.2.3 --depth=1 https://github.com/intel/media-driver.git + git clone -b intel-media-23.3.0 --depth=1 https://github.com/intel/media-driver.git pushd media-driver - # Possible fix for TGLx timeout caused by 'HCP Scalability Decode' under heavy load - wget -q -O - https://github.com/intel/media-driver/commit/cbbd676f.patch | git apply - # Correct AV1 supported tx mode caps for the AV1 VA-API encoder - wget -q -O - https://github.com/intel/media-driver/commit/89201eaa.patch | git apply - # Fix the slow VPP tone-mapping on ADL-S and ADL-N - wget -q -O - https://github.com/intel/media-driver/commit/1097e39b.patch | git apply mkdir build && pushd build cmake -DCMAKE_INSTALL_PREFIX=${TARGET_DIR} \ -DENABLE_KERNELS=ON \ @@ -337,7 +331,7 @@ prepare_extra_amd64() { # Vulkan Headers pushd ${SOURCE_DIR} - git clone -b v1.3.246 --depth=1 https://github.com/KhronosGroup/Vulkan-Headers.git + git clone -b v1.3.260 --depth=1 https://github.com/KhronosGroup/Vulkan-Headers.git pushd Vulkan-Headers mkdir build && pushd build cmake \ @@ -350,7 +344,7 @@ prepare_extra_amd64() { # Vulkan ICD Loader pushd ${SOURCE_DIR} - git clone -b v1.3.246 --depth=1 https://github.com/KhronosGroup/Vulkan-Loader.git + git clone -b v1.3.260 --depth=1 https://github.com/KhronosGroup/Vulkan-Loader.git pushd Vulkan-Loader mkdir build && pushd build cmake \ @@ -371,7 +365,7 @@ prepare_extra_amd64() { # SHADERC pushd ${SOURCE_DIR} - git clone -b v2023.3 --depth=1 https://github.com/google/shaderc.git + git clone -b v2023.5 --depth=1 https://github.com/google/shaderc.git pushd shaderc ./utils/git-sync-deps mkdir build && pushd build