diff options
Diffstat (limited to 'MediaBrowser.Controller')
35 files changed, 204 insertions, 104 deletions
diff --git a/MediaBrowser.Controller/Channels/ChannelLatestMediaSearch.cs b/MediaBrowser.Controller/Channels/ChannelLatestMediaSearch.cs index e02f42fa48..ebbe13763b 100644 --- a/MediaBrowser.Controller/Channels/ChannelLatestMediaSearch.cs +++ b/MediaBrowser.Controller/Channels/ChannelLatestMediaSearch.cs @@ -1,4 +1,4 @@ -#nullable disable +#nullable disable #pragma warning disable CS1591 diff --git a/MediaBrowser.Controller/Channels/IDisableMediaSourceDisplay.cs b/MediaBrowser.Controller/Channels/IDisableMediaSourceDisplay.cs index 0539b9048b..51a5ca8bfa 100644 --- a/MediaBrowser.Controller/Channels/IDisableMediaSourceDisplay.cs +++ b/MediaBrowser.Controller/Channels/IDisableMediaSourceDisplay.cs @@ -1,4 +1,4 @@ -namespace MediaBrowser.Controller.Channels +namespace MediaBrowser.Controller.Channels { /// <summary> /// Disable media source display. diff --git a/MediaBrowser.Controller/Channels/IHasFolderAttributes.cs b/MediaBrowser.Controller/Channels/IHasFolderAttributes.cs index 6c92785d21..39fac78d8c 100644 --- a/MediaBrowser.Controller/Channels/IHasFolderAttributes.cs +++ b/MediaBrowser.Controller/Channels/IHasFolderAttributes.cs @@ -1,4 +1,4 @@ -#pragma warning disable CA1819, CS1591 +#pragma warning disable CA1819, CS1591 namespace MediaBrowser.Controller.Channels { diff --git a/MediaBrowser.Controller/Channels/ISupportsDelete.cs b/MediaBrowser.Controller/Channels/ISupportsDelete.cs index 30798a4b28..0110bfa7a3 100644 --- a/MediaBrowser.Controller/Channels/ISupportsDelete.cs +++ b/MediaBrowser.Controller/Channels/ISupportsDelete.cs @@ -1,4 +1,4 @@ -#pragma warning disable CS1591 +#pragma warning disable CS1591 using System.Threading; using System.Threading.Tasks; diff --git a/MediaBrowser.Controller/Channels/ISupportsLatestMedia.cs b/MediaBrowser.Controller/Channels/ISupportsLatestMedia.cs index 8ecc68babf..1935ec0f5f 100644 --- a/MediaBrowser.Controller/Channels/ISupportsLatestMedia.cs +++ b/MediaBrowser.Controller/Channels/ISupportsLatestMedia.cs @@ -1,4 +1,4 @@ -#pragma warning disable CS1591 +#pragma warning disable CS1591 using System.Collections.Generic; using System.Threading; diff --git a/MediaBrowser.Controller/Channels/ISupportsMediaProbe.cs b/MediaBrowser.Controller/Channels/ISupportsMediaProbe.cs index bc7683125b..dbd256a6aa 100644 --- a/MediaBrowser.Controller/Channels/ISupportsMediaProbe.cs +++ b/MediaBrowser.Controller/Channels/ISupportsMediaProbe.cs @@ -1,4 +1,4 @@ -namespace MediaBrowser.Controller.Channels +namespace MediaBrowser.Controller.Channels { /// <summary> /// Channel supports media probe. diff --git a/MediaBrowser.Controller/ClientEvent/ClientEventLogger.cs b/MediaBrowser.Controller/ClientEvent/ClientEventLogger.cs index 2a7e6be0fd..14dc64dabd 100644 --- a/MediaBrowser.Controller/ClientEvent/ClientEventLogger.cs +++ b/MediaBrowser.Controller/ClientEvent/ClientEventLogger.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.IO; using System.Threading.Tasks; diff --git a/MediaBrowser.Controller/ClientEvent/IClientEventLogger.cs b/MediaBrowser.Controller/ClientEvent/IClientEventLogger.cs index ad8a1bd249..efb25457f6 100644 --- a/MediaBrowser.Controller/ClientEvent/IClientEventLogger.cs +++ b/MediaBrowser.Controller/ClientEvent/IClientEventLogger.cs @@ -1,4 +1,4 @@ -using System.IO; +using System.IO; using System.Threading.Tasks; namespace MediaBrowser.Controller.ClientEvent diff --git a/MediaBrowser.Controller/Collections/CollectionCreatedEventArgs.cs b/MediaBrowser.Controller/Collections/CollectionCreatedEventArgs.cs index 1797d15eac..456290f127 100644 --- a/MediaBrowser.Controller/Collections/CollectionCreatedEventArgs.cs +++ b/MediaBrowser.Controller/Collections/CollectionCreatedEventArgs.cs @@ -1,4 +1,4 @@ -#nullable disable +#nullable disable #pragma warning disable CS1591 diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index b2e5d7263f..83c19a54e1 100644 --- a/MediaBrowser.Controller/Entities/Folder.cs +++ b/MediaBrowser.Controller/Entities/Folder.cs @@ -1732,12 +1732,9 @@ namespace MediaBrowser.Controller.Entities return; } - if (itemDto is not null) + if (itemDto is not null && fields.ContainsField(ItemFields.RecursiveItemCount)) { - if (fields.ContainsField(ItemFields.RecursiveItemCount)) - { - itemDto.RecursiveItemCount = GetRecursiveChildCount(user); - } + itemDto.RecursiveItemCount = GetRecursiveChildCount(user); } if (SupportsPlayedStatus) diff --git a/MediaBrowser.Controller/Entities/LinkedChildComparer.cs b/MediaBrowser.Controller/Entities/LinkedChildComparer.cs index de8b168081..4f13ac61fe 100644 --- a/MediaBrowser.Controller/Entities/LinkedChildComparer.cs +++ b/MediaBrowser.Controller/Entities/LinkedChildComparer.cs @@ -1,4 +1,4 @@ -#nullable disable +#nullable disable #pragma warning disable CS1591 diff --git a/MediaBrowser.Controller/Entities/LinkedChildType.cs b/MediaBrowser.Controller/Entities/LinkedChildType.cs index d39e36ff28..3bd260a102 100644 --- a/MediaBrowser.Controller/Entities/LinkedChildType.cs +++ b/MediaBrowser.Controller/Entities/LinkedChildType.cs @@ -1,4 +1,4 @@ -namespace MediaBrowser.Controller.Entities +namespace MediaBrowser.Controller.Entities { /// <summary> /// The linked child type. diff --git a/MediaBrowser.Controller/Library/IDirectStreamProvider.cs b/MediaBrowser.Controller/Library/IDirectStreamProvider.cs index 96f8b7eba9..2dad58f6ea 100644 --- a/MediaBrowser.Controller/Library/IDirectStreamProvider.cs +++ b/MediaBrowser.Controller/Library/IDirectStreamProvider.cs @@ -1,4 +1,4 @@ -using System.IO; +using System.IO; namespace MediaBrowser.Controller.Library { diff --git a/MediaBrowser.Controller/Library/IUserDataManager.cs b/MediaBrowser.Controller/Library/IUserDataManager.cs index 43cccfc65c..f36fd393f7 100644 --- a/MediaBrowser.Controller/Library/IUserDataManager.cs +++ b/MediaBrowser.Controller/Library/IUserDataManager.cs @@ -1,7 +1,3 @@ -#nullable disable - -#pragma warning disable CA1002, CA1707, CS1591 - using System; using System.Collections.Generic; using System.Threading; @@ -21,18 +17,16 @@ namespace MediaBrowser.Controller.Library /// <summary> /// Occurs when [user data saved]. /// </summary> - event EventHandler<UserDataSaveEventArgs> UserDataSaved; + event EventHandler<UserDataSaveEventArgs>? UserDataSaved; /// <summary> /// Saves the user data. /// </summary> - /// <param name="userId">The user id.</param> + /// <param name="user">The user.</param> /// <param name="item">The item.</param> /// <param name="userData">The user data.</param> /// <param name="reason">The reason.</param> /// <param name="cancellationToken">The cancellation token.</param> - void SaveUserData(Guid userId, BaseItem item, UserItemData userData, UserDataSaveReason reason, CancellationToken cancellationToken); - void SaveUserData(User user, BaseItem item, UserItemData userData, UserDataSaveReason reason, CancellationToken cancellationToken); /// <summary> @@ -44,10 +38,14 @@ namespace MediaBrowser.Controller.Library /// <param name="reason">The reason.</param> void SaveUserData(User user, BaseItem item, UpdateUserItemDataDto userDataDto, UserDataSaveReason reason); + /// <summary> + /// Gets the user data. + /// </summary> + /// <param name="user">User to use.</param> + /// <param name="item">Item to use.</param> + /// <returns>User data.</returns> UserItemData GetUserData(User user, BaseItem item); - UserItemData GetUserData(Guid userId, BaseItem item); - /// <summary> /// Gets the user data dto. /// </summary> @@ -56,22 +54,15 @@ namespace MediaBrowser.Controller.Library /// <returns>User data dto.</returns> UserItemDataDto GetUserDataDto(BaseItem item, User user); - UserItemDataDto GetUserDataDto(BaseItem item, BaseItemDto itemDto, User user, DtoOptions options); - /// <summary> - /// Get all user data for the given user. - /// </summary> - /// <param name="userId">The user id.</param> - /// <returns>The user item data.</returns> - List<UserItemData> GetAllUserData(Guid userId); - - /// <summary> - /// Save the all provided user data for the given user. + /// Gets the user data dto. /// </summary> - /// <param name="userId">The user id.</param> - /// <param name="userData">The array of user data.</param> - /// <param name="cancellationToken">The cancellation token.</param> - void SaveAllUserData(Guid userId, UserItemData[] userData, CancellationToken cancellationToken); + /// <param name="item">Item to use.</param> + /// <param name="itemDto">Item dto to use.</param> + /// <param name="user">User to use.</param> + /// <param name="options">Dto options to use.</param> + /// <returns>User data dto.</returns> + UserItemDataDto GetUserDataDto(BaseItem item, BaseItemDto? itemDto, User user, DtoOptions options); /// <summary> /// Updates playstate for an item and returns true or false indicating if it was played to completion. diff --git a/MediaBrowser.Controller/Library/IUserManager.cs b/MediaBrowser.Controller/Library/IUserManager.cs index 6d6a532dba..1c115be857 100644 --- a/MediaBrowser.Controller/Library/IUserManager.cs +++ b/MediaBrowser.Controller/Library/IUserManager.cs @@ -117,11 +117,10 @@ namespace MediaBrowser.Controller.Library /// </summary> /// <param name="username">The user.</param> /// <param name="password">The password to use.</param> - /// <param name="passwordSha1">Hash of password.</param> /// <param name="remoteEndPoint">Remove endpoint to use.</param> /// <param name="isUserSession">Specifies if a user session.</param> /// <returns>User wrapped in awaitable task.</returns> - Task<User?> AuthenticateUser(string username, string password, string passwordSha1, string remoteEndPoint, bool isUserSession); + Task<User?> AuthenticateUser(string username, string password, string remoteEndPoint, bool isUserSession); /// <summary> /// Starts the forgot password process. diff --git a/MediaBrowser.Controller/LiveTv/ActiveRecordingInfo.cs b/MediaBrowser.Controller/LiveTv/ActiveRecordingInfo.cs index 1a81a8a31e..0e0f962914 100644 --- a/MediaBrowser.Controller/LiveTv/ActiveRecordingInfo.cs +++ b/MediaBrowser.Controller/LiveTv/ActiveRecordingInfo.cs @@ -1,4 +1,4 @@ -#nullable disable +#nullable disable #pragma warning disable CS1591 diff --git a/MediaBrowser.Controller/LiveTv/IListingsManager.cs b/MediaBrowser.Controller/LiveTv/IListingsManager.cs index bbf569575a..e2c0fbd67e 100644 --- a/MediaBrowser.Controller/LiveTv/IListingsManager.cs +++ b/MediaBrowser.Controller/LiveTv/IListingsManager.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; diff --git a/MediaBrowser.Controller/LiveTv/ITunerHostManager.cs b/MediaBrowser.Controller/LiveTv/ITunerHostManager.cs index 3df6066f66..8247066cc9 100644 --- a/MediaBrowser.Controller/LiveTv/ITunerHostManager.cs +++ b/MediaBrowser.Controller/LiveTv/ITunerHostManager.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; using MediaBrowser.Model.Dto; diff --git a/MediaBrowser.Controller/MediaEncoding/BaseEncodingJobOptions.cs b/MediaBrowser.Controller/MediaEncoding/BaseEncodingJobOptions.cs index 03ec6c658a..f77186e25c 100644 --- a/MediaBrowser.Controller/MediaEncoding/BaseEncodingJobOptions.cs +++ b/MediaBrowser.Controller/MediaEncoding/BaseEncodingJobOptions.cs @@ -1,4 +1,4 @@ -#nullable disable +#nullable disable #pragma warning disable CS1591 diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index db86a49f69..24cd141dcd 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -67,6 +67,8 @@ namespace MediaBrowser.Controller.MediaEncoding private readonly Version _minFFmpegWorkingVtHwSurface = new Version(7, 0, 1); private readonly Version _minFFmpegDisplayRotationOption = new Version(6, 0); private readonly Version _minFFmpegAdvancedTonemapMode = new Version(7, 0, 1); + private readonly Version _minFFmpegAlteredVaVkInterop = new Version(7, 0, 1); + private readonly Version _minFFmpegQsvVppTonemapOption = new Version(7, 0, 1); private static readonly Regex _validationRegex = new(ValidationRegex, RegexOptions.Compiled); @@ -296,14 +298,12 @@ namespace MediaBrowser.Controller.MediaEncoding if (state.VideoStream is null || !options.EnableTonemapping || GetVideoColorBitDepth(state) != 10 - || !_mediaEncoder.SupportsFilter("tonemapx") - || !(string.Equals(state.VideoStream?.ColorTransfer, "smpte2084", StringComparison.OrdinalIgnoreCase) || string.Equals(state.VideoStream?.ColorTransfer, "arib-std-b67", StringComparison.OrdinalIgnoreCase))) + || !_mediaEncoder.SupportsFilter("tonemapx")) { return false; } - return state.VideoStream.VideoRange == VideoRange.HDR - && state.VideoStream.VideoRangeType is VideoRangeType.HDR10 or VideoRangeType.HLG or VideoRangeType.DOVIWithHDR10 or VideoRangeType.DOVIWithHLG; + return state.VideoStream.VideoRange == VideoRange.HDR; } private bool IsHwTonemapAvailable(EncodingJobInfo state, EncodingOptions options) @@ -349,7 +349,7 @@ namespace MediaBrowser.Controller.MediaEncoding && GetVideoColorBitDepth(state) == 10; } - private bool IsVaapiVppTonemapAvailable(EncodingJobInfo state, EncodingOptions options) + private bool IsIntelVppTonemapAvailable(EncodingJobInfo state, EncodingOptions options) { if (state.VideoStream is null || !options.EnableVppTonemapping @@ -358,7 +358,14 @@ namespace MediaBrowser.Controller.MediaEncoding return false; } - // Native VPP tonemapping may come to QSV in the future. + // prefer 'tonemap_vaapi' over 'vpp_qsv' on Linux for supporting Gen9/KBLx. + // 'vpp_qsv' requires VPL, which is only supported on Gen12/TGLx and newer. + if (OperatingSystem.IsWindows() + && string.Equals(options.HardwareAccelerationType, "qsv", StringComparison.OrdinalIgnoreCase) + && _mediaEncoder.EncoderVersion < _minFFmpegQsvVppTonemapOption) + { + return false; + } return state.VideoStream.VideoRange == VideoRange.HDR && (state.VideoStream.VideoRangeType == VideoRangeType.HDR10 @@ -879,17 +886,23 @@ namespace MediaBrowser.Controller.MediaEncoding renderNodePath); } - private string GetQsvDeviceArgs(string alias) + private string GetQsvDeviceArgs(string renderNodePath, string alias) { var arg = " -init_hw_device qsv=" + (alias ?? QsvAlias); if (OperatingSystem.IsLinux()) { // derive qsv from vaapi device - return GetVaapiDeviceArgs(null, "iHD", "i915", null, VaapiAlias) + arg + "@" + VaapiAlias; + return GetVaapiDeviceArgs(renderNodePath, "iHD", "i915", null, VaapiAlias) + arg + "@" + VaapiAlias; } if (OperatingSystem.IsWindows()) { + // on Windows, the deviceIndex is an int + if (int.TryParse(renderNodePath, NumberStyles.Integer, CultureInfo.InvariantCulture, out int deviceIndex)) + { + return GetD3d11vaDeviceArgs(deviceIndex, string.Empty, D3d11vaAlias) + arg + "@" + D3d11vaAlias; + } + // derive qsv from d3d11va device return GetD3d11vaDeviceArgs(0, "0x8086", D3d11vaAlias) + arg + "@" + D3d11vaAlias; } @@ -1049,7 +1062,7 @@ namespace MediaBrowser.Controller.MediaEncoding return string.Empty; } - args.Append(GetQsvDeviceArgs(QsvAlias)); + args.Append(GetQsvDeviceArgs(options.QsvDevice, QsvAlias)); var filterDevArgs = GetFilterHwDeviceArgs(QsvAlias); // child device used by qsv. if (_mediaEncoder.SupportsHwaccel("vaapi") || _mediaEncoder.SupportsHwaccel("d3d11va")) @@ -1657,7 +1670,7 @@ namespace MediaBrowser.Controller.MediaEncoding var doOclTonemap = _mediaEncoder.SupportsHwaccel("qsv") && IsVaapiSupported(state) && IsOpenclFullSupported() - && !IsVaapiVppTonemapAvailable(state, encodingOptions) + && !IsIntelVppTonemapAvailable(state, encodingOptions) && IsHwTonemapAvailable(state, encodingOptions); enableWaFori915Hang = isIntelDecoder && doOclTonemap; @@ -3229,14 +3242,18 @@ namespace MediaBrowser.Controller.MediaEncoding doubleRateDeint ? "1" : "0"); } - public static string GetHwDeinterlaceFilter(EncodingJobInfo state, EncodingOptions options, string hwDeintSuffix) + public string GetHwDeinterlaceFilter(EncodingJobInfo state, EncodingOptions options, string hwDeintSuffix) { var doubleRateDeint = options.DeinterlaceDoubleRate && (state.VideoStream?.AverageFrameRate ?? 60) <= 30; if (hwDeintSuffix.Contains("cuda", StringComparison.OrdinalIgnoreCase)) { + var useBwdif = string.Equals(options.DeinterlaceMethod, "bwdif", StringComparison.OrdinalIgnoreCase) + && _mediaEncoder.SupportsFilter("bwdif_cuda"); + return string.Format( CultureInfo.InvariantCulture, - "yadif_cuda={0}:-1:0", + "{0}_cuda={1}:-1:0", + useBwdif ? "bwdif" : "yadif", doubleRateDeint ? "1" : "0"); } @@ -3276,14 +3293,31 @@ namespace MediaBrowser.Controller.MediaEncoding if (string.Equals(hwTonemapSuffix, "vaapi", StringComparison.OrdinalIgnoreCase)) { - args = "procamp_vaapi=b={1}:c={2},tonemap_vaapi=format={0}:p=bt709:t=bt709:m=bt709:extra_hw_frames=32"; + var doVaVppProcamp = false; + var procampParams = string.Empty; + if (options.VppTonemappingBrightness != 0 + && options.VppTonemappingBrightness >= -100 + && options.VppTonemappingBrightness <= 100) + { + procampParams += $"=b={options.VppTonemappingBrightness}"; + doVaVppProcamp = true; + } + + if (options.VppTonemappingContrast > 1 + && options.VppTonemappingContrast <= 10) + { + procampParams += doVaVppProcamp ? ":" : "="; + procampParams += $"c={options.VppTonemappingContrast}"; + doVaVppProcamp = true; + } + + args = "{0}tonemap_vaapi=format={1}:p=bt709:t=bt709:m=bt709:extra_hw_frames=32"; return string.Format( CultureInfo.InvariantCulture, args, - videoFormat ?? "nv12", - options.VppTonemappingBrightness, - options.VppTonemappingContrast); + doVaVppProcamp ? $"procamp_vaapi{procampParams}," : string.Empty, + videoFormat ?? "nv12"); } else { @@ -3369,15 +3403,7 @@ namespace MediaBrowser.Controller.MediaEncoding algorithm = "clip"; } - tonemapArg = ":tonemapping=" + algorithm; - - if (string.Equals(mode, "max", StringComparison.OrdinalIgnoreCase) - || string.Equals(mode, "rgb", StringComparison.OrdinalIgnoreCase)) - { - tonemapArg += ":tonemapping_mode=" + mode; - } - - tonemapArg += ":peak_detect=0:color_primaries=bt709:color_trc=bt709:colorspace=bt709"; + tonemapArg = ":tonemapping=" + algorithm + ":peak_detect=0:color_primaries=bt709:color_trc=bt709:colorspace=bt709"; if (string.Equals(range, "tv", StringComparison.OrdinalIgnoreCase) || string.Equals(range, "pc", StringComparison.OrdinalIgnoreCase)) @@ -3435,6 +3461,7 @@ namespace MediaBrowser.Controller.MediaEncoding var doDeintHevc = state.DeInterlace("h265", true) || state.DeInterlace("hevc", true); var doDeintH2645 = doDeintH264 || doDeintHevc; var doToneMap = IsSwTonemapAvailable(state, options); + var requireDoviReshaping = doToneMap && state.VideoStream.VideoRangeType == VideoRangeType.DOVI; var hasSubs = state.SubtitleStream is not null && state.SubtitleDeliveryMethod == SubtitleDeliveryMethod.Encode; var hasTextSubs = hasSubs && state.SubtitleStream.IsTextSubtitleStream; @@ -3472,11 +3499,13 @@ namespace MediaBrowser.Controller.MediaEncoding // sw scale mainFilters.Add(swScaleFilter); - // sw tonemap <= TODO: finish dovi tone mapping - + // sw tonemap if (doToneMap) { - var tonemapArgs = $"tonemapx=tonemap={options.TonemappingAlgorithm}:desat={options.TonemappingDesat}:peak={options.TonemappingPeak}:t=bt709:m=bt709:p=bt709:format={outFormat}"; + // tonemapx requires yuv420p10 input for dovi reshaping, let ffmpeg convert the frame when necessary + var tonemapFormat = requireDoviReshaping ? "yuv420p" : outFormat; + + var tonemapArgs = $"tonemapx=tonemap={options.TonemappingAlgorithm}:desat={options.TonemappingDesat}:peak={options.TonemappingPeak}:t=bt709:m=bt709:p=bt709:format={tonemapFormat}"; if (options.TonemappingParam != 0) { @@ -4012,7 +4041,9 @@ namespace MediaBrowser.Controller.MediaEncoding var doDeintH264 = state.DeInterlace("h264", true) || state.DeInterlace("avc", true); var doDeintHevc = state.DeInterlace("h265", true) || state.DeInterlace("hevc", true); var doDeintH2645 = doDeintH264 || doDeintHevc; - var doOclTonemap = IsHwTonemapAvailable(state, options); + var doVppTonemap = IsIntelVppTonemapAvailable(state, options); + var doOclTonemap = !doVppTonemap && IsHwTonemapAvailable(state, options); + var doTonemap = doVppTonemap || doOclTonemap; var hasSubs = state.SubtitleStream is not null && state.SubtitleDeliveryMethod == SubtitleDeliveryMethod.Encode; var hasTextSubs = hasSubs && state.SubtitleStream.IsTextSubtitleStream; @@ -4031,7 +4062,7 @@ namespace MediaBrowser.Controller.MediaEncoding /* Make main filters for video stream */ var mainFilters = new List<string>(); - mainFilters.Add(GetOverwriteColorPropertiesParam(state, doOclTonemap)); + mainFilters.Add(GetOverwriteColorPropertiesParam(state, doTonemap)); if (isSwDecoder) { @@ -4059,9 +4090,33 @@ namespace MediaBrowser.Controller.MediaEncoding } else if (isD3d11vaDecoder || isQsvDecoder) { + var doVppProcamp = false; + var procampParams = string.Empty; + if (doVppTonemap) + { + if (options.VppTonemappingBrightness != 0 + && options.VppTonemappingBrightness >= -100 + && options.VppTonemappingBrightness <= 100) + { + procampParams += $":brightness={options.VppTonemappingBrightness}"; + doVppProcamp = true; + } + + if (options.VppTonemappingContrast > 1 + && options.VppTonemappingContrast <= 10) + { + procampParams += $":contrast={options.VppTonemappingContrast}"; + doVppProcamp = true; + } + + procampParams += doVppProcamp ? ":procamp=1:async_depth=2" : string.Empty; + } + var outFormat = doOclTonemap ? (doVppTranspose ? "p010" : string.Empty) : "nv12"; + outFormat = (doVppTonemap && doVppProcamp) ? "p010" : outFormat; + var swapOutputWandH = doVppTranspose && swapWAndH; - var hwScalePrefix = doVppTranspose ? "vpp" : "scale"; + var hwScalePrefix = (doVppTranspose || doVppTonemap) ? "vpp" : "scale"; var hwScaleFilter = GetHwScaleFilter(hwScalePrefix, "qsv", outFormat, swapOutputWandH, swpInW, swpInH, reqW, reqH, reqMaxW, reqMaxH); if (!string.IsNullOrEmpty(hwScaleFilter) && doVppTranspose) @@ -4069,6 +4124,11 @@ namespace MediaBrowser.Controller.MediaEncoding hwScaleFilter += $":transpose={tranposeDir}"; } + if (!string.IsNullOrEmpty(hwScaleFilter) && doVppTonemap) + { + hwScaleFilter += doVppProcamp ? procampParams : ":tonemap=1"; + } + if (isD3d11vaDecoder) { if (!string.IsNullOrEmpty(hwScaleFilter) || doDeintH2645) @@ -4086,8 +4146,20 @@ namespace MediaBrowser.Controller.MediaEncoding mainFilters.Add(deintFilter); } - // hw transpose & scale + // hw transpose & scale & tonemap(w/o procamp) mainFilters.Add(hwScaleFilter); + + // hw tonemap(w/ procamp) + if (doVppTonemap && doVppProcamp) + { + mainFilters.Add("vpp_qsv=tonemap=1:format=nv12:async_depth=2"); + } + + // force bt709 just in case vpp tonemap is not triggered or using MSDK instead of VPL. + if (doVppTonemap) + { + mainFilters.Add(GetOverwriteColorPropertiesParam(state, false)); + } } if (doOclTonemap && isHwDecoder) @@ -4220,7 +4292,7 @@ namespace MediaBrowser.Controller.MediaEncoding var doDeintH264 = state.DeInterlace("h264", true) || state.DeInterlace("avc", true); var doDeintHevc = state.DeInterlace("h265", true) || state.DeInterlace("hevc", true); - var doVaVppTonemap = IsVaapiVppTonemapAvailable(state, options); + var doVaVppTonemap = IsIntelVppTonemapAvailable(state, options); var doOclTonemap = !doVaVppTonemap && IsHwTonemapAvailable(state, options); var doTonemap = doVaVppTonemap || doOclTonemap; var doDeintH2645 = doDeintH264 || doDeintHevc; @@ -4531,7 +4603,7 @@ namespace MediaBrowser.Controller.MediaEncoding var doDeintH264 = state.DeInterlace("h264", true) || state.DeInterlace("avc", true); var doDeintHevc = state.DeInterlace("h265", true) || state.DeInterlace("hevc", true); - var doVaVppTonemap = isVaapiDecoder && IsVaapiVppTonemapAvailable(state, options); + var doVaVppTonemap = isVaapiDecoder && IsIntelVppTonemapAvailable(state, options); var doOclTonemap = !doVaVppTonemap && IsHwTonemapAvailable(state, options); var doTonemap = doVaVppTonemap || doOclTonemap; var doDeintH2645 = doDeintH264 || doDeintHevc; @@ -4803,8 +4875,34 @@ namespace MediaBrowser.Controller.MediaEncoding if (doVkTranspose || doVkTonemap || hasSubs) { // map from vaapi to vulkan/drm via interop (Polaris/gfx8+). - mainFilters.Add("hwmap=derive_device=vulkan"); - mainFilters.Add("format=vulkan"); + if (_mediaEncoder.EncoderVersion >= _minFFmpegAlteredVaVkInterop) + { + if (doVkTranspose || !_mediaEncoder.IsVaapiDeviceSupportVulkanDrmModifier) + { + // disable the indirect va-drm-vk mapping since it's no longer reliable. + mainFilters.Add("hwmap=derive_device=drm"); + mainFilters.Add("format=drm_prime"); + mainFilters.Add("hwmap=derive_device=vulkan"); + mainFilters.Add("format=vulkan"); + + // workaround for libplacebo using the imported vulkan frame on gfx8. + if (!_mediaEncoder.IsVaapiDeviceSupportVulkanDrmModifier) + { + mainFilters.Add("scale_vulkan"); + } + } + else if (doVkTonemap || hasSubs) + { + // non ad-hoc libplacebo also accepts drm_prime direct input. + mainFilters.Add("hwmap=derive_device=drm"); + mainFilters.Add("format=drm_prime"); + } + } + else // legacy va-vk mapping that works only in jellyfin-ffmpeg6 + { + mainFilters.Add("hwmap=derive_device=vulkan"); + mainFilters.Add("format=vulkan"); + } } else { @@ -4839,6 +4937,7 @@ namespace MediaBrowser.Controller.MediaEncoding { var libplaceboFilter = GetLibplaceboFilter(options, "bgra", doVkTonemap, swpInW, swpInH, reqW, reqH, reqMaxW, reqMaxH); mainFilters.Add(libplaceboFilter); + mainFilters.Add("format=vulkan"); } if (doVkTonemap && !hasSubs) @@ -5135,13 +5234,15 @@ namespace MediaBrowser.Controller.MediaEncoding return (null, null, null); } + // ReSharper disable once InconsistentNaming var isMacOS = OperatingSystem.IsMacOS(); var vidDecoder = GetHardwareVideoDecoder(state, options) ?? string.Empty; + var isVtDecoder = vidDecoder.Contains("videotoolbox", StringComparison.OrdinalIgnoreCase); var isVtEncoder = vidEncoder.Contains("videotoolbox", StringComparison.OrdinalIgnoreCase); var isVtFullSupported = isMacOS && IsVideoToolboxFullSupported(); // legacy videotoolbox pipeline (disable hw filters) - if (!isVtEncoder + if (!(isVtEncoder || isVtDecoder) || !isVtFullSupported || !_mediaEncoder.SupportsFilter("alphasrc")) { @@ -5161,12 +5262,6 @@ namespace MediaBrowser.Controller.MediaEncoding var isVtEncoder = vidEncoder.Contains("videotoolbox", StringComparison.OrdinalIgnoreCase); var isVtDecoder = vidDecoder.Contains("videotoolbox", StringComparison.OrdinalIgnoreCase); - if (!isVtEncoder) - { - // should not happen. - return (null, null, null); - } - var inW = state.VideoStream?.Width; var inH = state.VideoStream?.Height; var reqW = state.BaseRequest.Width; @@ -5281,6 +5376,12 @@ namespace MediaBrowser.Controller.MediaEncoding if (usingHwSurface) { + if (!isVtEncoder) + { + mainFilters.Add("hwdownload"); + mainFilters.Add("format=nv12"); + } + return (mainFilters, subFilters, overlayFilters); } @@ -5294,6 +5395,12 @@ namespace MediaBrowser.Controller.MediaEncoding // this will pass-through automatically if in/out format matches. mainFilters.Insert(0, "hwupload"); mainFilters.Insert(0, "format=nv12|p010le|videotoolbox_vld"); + + if (!isVtEncoder) + { + mainFilters.Add("hwdownload"); + mainFilters.Add("format=nv12"); + } } return (mainFilters, subFilters, overlayFilters); diff --git a/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs b/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs index e36106e528..c767b4a519 100644 --- a/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs +++ b/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs @@ -66,6 +66,12 @@ namespace MediaBrowser.Controller.MediaEncoding /// <summary> /// Gets a value indicating whether the configured Vaapi device supports vulkan drm format modifier. /// </summary> + /// <value><c>true</c> if the Vaapi device supports vulkan drm format modifier, <c>false</c> otherwise.</value> + bool IsVaapiDeviceSupportVulkanDrmModifier { get; } + + /// <summary> + /// Gets a value indicating whether the configured Vaapi device supports vulkan drm interop via dma-buf. + /// </summary> /// <value><c>true</c> if the Vaapi device supports vulkan drm interop, <c>false</c> otherwise.</value> bool IsVaapiDeviceSupportVulkanDrmInterop { get; } diff --git a/MediaBrowser.Controller/MediaEncoding/TranscodingJob.cs b/MediaBrowser.Controller/MediaEncoding/TranscodingJob.cs index 2b6540ea88..fefa66cdb8 100644 --- a/MediaBrowser.Controller/MediaEncoding/TranscodingJob.cs +++ b/MediaBrowser.Controller/MediaEncoding/TranscodingJob.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Diagnostics; using System.Threading; using MediaBrowser.Model.Dto; diff --git a/MediaBrowser.Controller/MediaEncoding/TranscodingJobType.cs b/MediaBrowser.Controller/MediaEncoding/TranscodingJobType.cs index c1bb387e1a..fb0f0c0690 100644 --- a/MediaBrowser.Controller/MediaEncoding/TranscodingJobType.cs +++ b/MediaBrowser.Controller/MediaEncoding/TranscodingJobType.cs @@ -1,4 +1,4 @@ -namespace MediaBrowser.Controller.MediaEncoding +namespace MediaBrowser.Controller.MediaEncoding { /// <summary> /// Enum TranscodingJobType. diff --git a/MediaBrowser.Controller/MediaEncoding/TranscodingThrottler.cs b/MediaBrowser.Controller/MediaEncoding/TranscodingThrottler.cs index b95e6ed51f..1e7cd0b0a3 100644 --- a/MediaBrowser.Controller/MediaEncoding/TranscodingThrottler.cs +++ b/MediaBrowser.Controller/MediaEncoding/TranscodingThrottler.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Threading; using System.Threading.Tasks; using MediaBrowser.Common.Configuration; diff --git a/MediaBrowser.Controller/MediaSegements/IMediaSegmentManager.cs b/MediaBrowser.Controller/MediaSegements/IMediaSegmentManager.cs index 4fcf084e10..67384f6f64 100644 --- a/MediaBrowser.Controller/MediaSegements/IMediaSegmentManager.cs +++ b/MediaBrowser.Controller/MediaSegements/IMediaSegmentManager.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Threading.Tasks; using Jellyfin.Data.Entities; diff --git a/MediaBrowser.Controller/Net/WebSocketListenerState.cs b/MediaBrowser.Controller/Net/WebSocketListenerState.cs index 2410801d60..68f5c81be4 100644 --- a/MediaBrowser.Controller/Net/WebSocketListenerState.cs +++ b/MediaBrowser.Controller/Net/WebSocketListenerState.cs @@ -1,4 +1,4 @@ -#nullable disable +#nullable disable #pragma warning disable CS1591 diff --git a/MediaBrowser.Controller/Net/WebSocketMessages/InboundWebSocketMessage.cs b/MediaBrowser.Controller/Net/WebSocketMessages/InboundWebSocketMessage.cs index 8d6e821df8..50d7dcaab0 100644 --- a/MediaBrowser.Controller/Net/WebSocketMessages/InboundWebSocketMessage.cs +++ b/MediaBrowser.Controller/Net/WebSocketMessages/InboundWebSocketMessage.cs @@ -1,4 +1,4 @@ -namespace MediaBrowser.Controller.Net.WebSocketMessages; +namespace MediaBrowser.Controller.Net.WebSocketMessages; /// <summary> /// Inbound websocket message. diff --git a/MediaBrowser.Controller/Net/WebSocketMessages/InboundWebSocketMessageOfT.cs b/MediaBrowser.Controller/Net/WebSocketMessages/InboundWebSocketMessageOfT.cs index 4da5e7d31f..d0105bb8e1 100644 --- a/MediaBrowser.Controller/Net/WebSocketMessages/InboundWebSocketMessageOfT.cs +++ b/MediaBrowser.Controller/Net/WebSocketMessages/InboundWebSocketMessageOfT.cs @@ -1,4 +1,4 @@ -#pragma warning disable SA1649 // File name must equal class name. +#pragma warning disable SA1649 // File name must equal class name. namespace MediaBrowser.Controller.Net.WebSocketMessages; diff --git a/MediaBrowser.Controller/Net/WebSocketMessages/OutboundWebSocketMessage.cs b/MediaBrowser.Controller/Net/WebSocketMessages/OutboundWebSocketMessage.cs index 1782458516..a9d68e3892 100644 --- a/MediaBrowser.Controller/Net/WebSocketMessages/OutboundWebSocketMessage.cs +++ b/MediaBrowser.Controller/Net/WebSocketMessages/OutboundWebSocketMessage.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace MediaBrowser.Controller.Net.WebSocketMessages; diff --git a/MediaBrowser.Controller/Net/WebSocketMessages/OutboundWebSocketMessageOfT.cs b/MediaBrowser.Controller/Net/WebSocketMessages/OutboundWebSocketMessageOfT.cs index cce331805c..abc67c7395 100644 --- a/MediaBrowser.Controller/Net/WebSocketMessages/OutboundWebSocketMessageOfT.cs +++ b/MediaBrowser.Controller/Net/WebSocketMessages/OutboundWebSocketMessageOfT.cs @@ -1,4 +1,4 @@ -#pragma warning disable SA1649 // File name must equal class name. +#pragma warning disable SA1649 // File name must equal class name. using System; diff --git a/MediaBrowser.Controller/Providers/IExternalUrlProvider.cs b/MediaBrowser.Controller/Providers/IExternalUrlProvider.cs index 86a1806275..14f5771709 100644 --- a/MediaBrowser.Controller/Providers/IExternalUrlProvider.cs +++ b/MediaBrowser.Controller/Providers/IExternalUrlProvider.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using MediaBrowser.Controller.Entities; namespace MediaBrowser.Controller.Providers; diff --git a/MediaBrowser.Controller/Providers/RefreshPriority.cs b/MediaBrowser.Controller/Providers/RefreshPriority.cs index e4c39cea16..78304b56b3 100644 --- a/MediaBrowser.Controller/Providers/RefreshPriority.cs +++ b/MediaBrowser.Controller/Providers/RefreshPriority.cs @@ -1,4 +1,4 @@ -namespace MediaBrowser.Controller.Providers +namespace MediaBrowser.Controller.Providers { /// <summary> /// Provider refresh priority. diff --git a/MediaBrowser.Controller/Security/IAuthenticationManager.cs b/MediaBrowser.Controller/Security/IAuthenticationManager.cs index 070ab7a856..79b2a2444e 100644 --- a/MediaBrowser.Controller/Security/IAuthenticationManager.cs +++ b/MediaBrowser.Controller/Security/IAuthenticationManager.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using System.Threading.Tasks; namespace MediaBrowser.Controller.Security diff --git a/MediaBrowser.Controller/Streaming/ProgressiveFileStream.cs b/MediaBrowser.Controller/Streaming/ProgressiveFileStream.cs index f44dc92d71..d75ef7ad39 100644 --- a/MediaBrowser.Controller/Streaming/ProgressiveFileStream.cs +++ b/MediaBrowser.Controller/Streaming/ProgressiveFileStream.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Diagnostics; using System.IO; using System.Threading; diff --git a/MediaBrowser.Controller/Streaming/StreamingRequestDto.cs b/MediaBrowser.Controller/Streaming/StreamingRequestDto.cs index e47ef65f06..89eef28fab 100644 --- a/MediaBrowser.Controller/Streaming/StreamingRequestDto.cs +++ b/MediaBrowser.Controller/Streaming/StreamingRequestDto.cs @@ -1,4 +1,4 @@ -using MediaBrowser.Controller.MediaEncoding; +using MediaBrowser.Controller.MediaEncoding; namespace MediaBrowser.Controller.Streaming; |
