From 7b862bba5aad345f0bc8d76bfb950590471ae232 Mon Sep 17 00:00:00 2001 From: nyanmisaka Date: Sat, 25 Jul 2020 00:57:34 +0800 Subject: [PATCH 01/15] add Tonemapping relaying on nvdec and ocl --- .../MediaEncoding/EncodingHelper.cs | 109 ++++++++++++++++-- .../Probing/MediaStreamInfo.cs | 14 +++ .../Probing/ProbeResultNormalizer.cs | 10 ++ .../Configuration/EncodingOptions.cs | 29 ++++- MediaBrowser.Model/Entities/MediaStream.cs | 18 ++- 5 files changed, 166 insertions(+), 14 deletions(-) diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index 0242338b70..4a33f22e63 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -454,6 +454,7 @@ namespace MediaBrowser.Controller.MediaEncoding var isVaapiEncoder = outputVideoCodec.IndexOf("vaapi", StringComparison.OrdinalIgnoreCase) != -1; var isQsvDecoder = videoDecoder.IndexOf("qsv", StringComparison.OrdinalIgnoreCase) != -1; var isQsvEncoder = outputVideoCodec.IndexOf("qsv", StringComparison.OrdinalIgnoreCase) != -1; + var isNvencHevcDecoder = videoDecoder.IndexOf("hevc_cuvid", StringComparison.OrdinalIgnoreCase) != -1; var isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows); var isLinux = RuntimeInformation.IsOSPlatform(OSPlatform.Linux); @@ -511,6 +512,25 @@ namespace MediaBrowser.Controller.MediaEncoding } } } + + if (state.IsVideoRequest + && string.Equals(encodingOptions.HardwareAccelerationType, "nvenc", StringComparison.OrdinalIgnoreCase)) + { + var codec = state.VideoStream.Codec.ToLowerInvariant(); + var isColorDepth10 = IsColorDepth10(state); + + if (isNvencHevcDecoder && isColorDepth10 + && _mediaEncoder.SupportsHwaccel("opencl") + && encodingOptions.EnableTonemapping + && !string.IsNullOrEmpty(state.VideoStream.VideoRange) + && state.VideoStream.VideoRange.Contains("HDR", StringComparison.OrdinalIgnoreCase)) + { + arg.Append("-init_hw_device opencl=ocl:") + .Append(encodingOptions.OpenclDevice) + .Append(' ') + .Append("-filter_hw_device ocl "); + } + } } arg.Append("-i ") @@ -994,11 +1014,33 @@ namespace MediaBrowser.Controller.MediaEncoding if (!string.Equals(videoEncoder, "h264_omx", StringComparison.OrdinalIgnoreCase) && !string.Equals(videoEncoder, "h264_qsv", StringComparison.OrdinalIgnoreCase) && !string.Equals(videoEncoder, "h264_vaapi", StringComparison.OrdinalIgnoreCase) + && !string.Equals(videoEncoder, "h264_nvenc", StringComparison.OrdinalIgnoreCase) && !string.Equals(videoEncoder, "h264_v4l2m2m", StringComparison.OrdinalIgnoreCase)) { param = "-pix_fmt yuv420p " + param; } + if (string.Equals(videoEncoder, "h264_nvenc", StringComparison.OrdinalIgnoreCase)) + { + var videoDecoder = GetHardwareAcceleratedVideoDecoder(state, encodingOptions) ?? string.Empty; + var videoStream = state.VideoStream; + var isColorDepth10 = IsColorDepth10(state); + + if (videoDecoder.IndexOf("hevc_cuvid", StringComparison.OrdinalIgnoreCase) != -1 + && isColorDepth10 + && _mediaEncoder.SupportsHwaccel("opencl") + && encodingOptions.EnableTonemapping + && !string.IsNullOrEmpty(videoStream.VideoRange) + && videoStream.VideoRange.Contains("HDR", StringComparison.OrdinalIgnoreCase)) + { + param = "-pix_fmt nv12 " + param; + } + else + { + param = "-pix_fmt yuv420p " + param; + } + } + if (string.Equals(videoEncoder, "h264_v4l2m2m", StringComparison.OrdinalIgnoreCase)) { param = "-pix_fmt nv21 " + param; @@ -1599,46 +1641,54 @@ namespace MediaBrowser.Controller.MediaEncoding { outputSizeParam = GetOutputSizeParam(state, options, outputVideoCodec).TrimEnd('"'); - var index = outputSizeParam.IndexOf("hwdownload", StringComparison.OrdinalIgnoreCase); + var index = outputSizeParam.IndexOf("hwupload,tonemap_opencl", StringComparison.OrdinalIgnoreCase); if (index != -1) { outputSizeParam = outputSizeParam.Substring(index); } else { - index = outputSizeParam.IndexOf("hwupload=extra_hw_frames", StringComparison.OrdinalIgnoreCase); + index = outputSizeParam.IndexOf("hwdownload", StringComparison.OrdinalIgnoreCase); if (index != -1) { outputSizeParam = outputSizeParam.Substring(index); } else { - index = outputSizeParam.IndexOf("format", StringComparison.OrdinalIgnoreCase); + index = outputSizeParam.IndexOf("hwupload=extra_hw_frames", StringComparison.OrdinalIgnoreCase); if (index != -1) { outputSizeParam = outputSizeParam.Substring(index); } else { - index = outputSizeParam.IndexOf("yadif", StringComparison.OrdinalIgnoreCase); + index = outputSizeParam.IndexOf("format", StringComparison.OrdinalIgnoreCase); if (index != -1) { outputSizeParam = outputSizeParam.Substring(index); } else { - index = outputSizeParam.IndexOf("scale", StringComparison.OrdinalIgnoreCase); + index = outputSizeParam.IndexOf("yadif", StringComparison.OrdinalIgnoreCase); if (index != -1) { outputSizeParam = outputSizeParam.Substring(index); } else { - index = outputSizeParam.IndexOf("vpp", StringComparison.OrdinalIgnoreCase); + index = outputSizeParam.IndexOf("scale", StringComparison.OrdinalIgnoreCase); if (index != -1) { outputSizeParam = outputSizeParam.Substring(index); } + else + { + index = outputSizeParam.IndexOf("vpp", StringComparison.OrdinalIgnoreCase); + if (index != -1) + { + outputSizeParam = outputSizeParam.Substring(index); + } + } } } } @@ -2058,12 +2108,58 @@ namespace MediaBrowser.Controller.MediaEncoding var isVaapiH264Encoder = outputVideoCodec.IndexOf("h264_vaapi", StringComparison.OrdinalIgnoreCase) != -1; var isQsvH264Encoder = outputVideoCodec.IndexOf("h264_qsv", StringComparison.OrdinalIgnoreCase) != -1; var isNvdecH264Decoder = videoDecoder.IndexOf("h264_cuvid", StringComparison.OrdinalIgnoreCase) != -1; + var isNvdecHevcDecoder = videoDecoder.IndexOf("hevc_cuvid", StringComparison.OrdinalIgnoreCase) != -1; var isLibX264Encoder = outputVideoCodec.IndexOf("libx264", StringComparison.OrdinalIgnoreCase) != -1; var isLinux = RuntimeInformation.IsOSPlatform(OSPlatform.Linux); + var isColorDepth10 = IsColorDepth10(state); var hasTextSubs = state.SubtitleStream != null && state.SubtitleStream.IsTextSubtitleStream && state.SubtitleDeliveryMethod == SubtitleDeliveryMethod.Encode; var hasGraphicalSubs = state.SubtitleStream != null && !state.SubtitleStream.IsTextSubtitleStream && state.SubtitleDeliveryMethod == SubtitleDeliveryMethod.Encode; + // Currently only with the use of NVENC decoder can we get a decent performance. + // Currently only the HEVC/H265 format is supported. + // NVIDIA Pascal and Turing or higher are recommended. + if (isNvdecHevcDecoder && isColorDepth10 + && _mediaEncoder.SupportsHwaccel("opencl") + && options.EnableTonemapping + && !string.IsNullOrEmpty(videoStream.VideoRange) + && videoStream.VideoRange.Contains("HDR", StringComparison.OrdinalIgnoreCase)) + { + var parameters = "tonemap_opencl=format=nv12:primaries=bt709:transfer=bt709:matrix=bt709:tonemap={0}:desat={1}:threshold={2}:peak={3}"; + + if (options.TonemappingParam != 0) + { + parameters += ":param={4}"; + } + + if (!string.Equals(options.TonemappingRange, "auto", StringComparison.OrdinalIgnoreCase)) + { + parameters += ":range={5}"; + } + + // Upload the HDR10 or HLG data to the OpenCL device, + // use tonemap_opencl filter for tone mapping, + // and then download the SDR data to memory. + filters.Add("hwupload"); + filters.Add( + string.Format( + CultureInfo.InvariantCulture, + parameters, + options.TonemappingAlgorithm, + options.TonemappingDesat, + options.TonemappingThreshold, + options.TonemappingPeak, + options.TonemappingParam, + options.TonemappingRange)); + filters.Add("hwdownload"); + + if (hasGraphicalSubs || state.DeInterlace("h265", true) || state.DeInterlace("hevc", true) + || string.Equals(outputVideoCodec, "libx264", StringComparison.OrdinalIgnoreCase)) + { + filters.Add("format=nv12"); + } + } + // When the input may or may not be hardware VAAPI decodable if (isVaapiH264Encoder) { @@ -2081,7 +2177,6 @@ namespace MediaBrowser.Controller.MediaEncoding else if (IsVaapiSupported(state) && isVaapiDecoder && isLibX264Encoder) { var codec = videoStream.Codec.ToLowerInvariant(); - var isColorDepth10 = IsColorDepth10(state); // Assert 10-bit hardware VAAPI decodable if (isColorDepth10 && (string.Equals(codec, "hevc", StringComparison.OrdinalIgnoreCase) diff --git a/MediaBrowser.MediaEncoding/Probing/MediaStreamInfo.cs b/MediaBrowser.MediaEncoding/Probing/MediaStreamInfo.cs index a2ea0766a8..d9658cba24 100644 --- a/MediaBrowser.MediaEncoding/Probing/MediaStreamInfo.cs +++ b/MediaBrowser.MediaEncoding/Probing/MediaStreamInfo.cs @@ -279,6 +279,20 @@ namespace MediaBrowser.MediaEncoding.Probing [JsonPropertyName("disposition")] public IReadOnlyDictionary Disposition { get; set; } + /// + /// Gets or sets the color range. + /// + /// The color range. + [JsonPropertyName("color_range")] + public string ColorRange { get; set; } + + /// + /// Gets or sets the color space. + /// + /// The color space. + [JsonPropertyName("color_space")] + public string ColorSpace { get; set; } + /// /// Gets or sets the color transfer. /// diff --git a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs index c85d963ed1..3815e00d47 100644 --- a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs +++ b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs @@ -703,6 +703,16 @@ namespace MediaBrowser.MediaEncoding.Probing stream.RefFrames = streamInfo.Refs; } + if (!string.IsNullOrEmpty(streamInfo.ColorRange)) + { + stream.ColorRange = streamInfo.ColorRange; + } + + if (!string.IsNullOrEmpty(streamInfo.ColorSpace)) + { + stream.ColorSpace = streamInfo.ColorSpace; + } + if (!string.IsNullOrEmpty(streamInfo.ColorTransfer)) { stream.ColorTransfer = streamInfo.ColorTransfer; diff --git a/MediaBrowser.Model/Configuration/EncodingOptions.cs b/MediaBrowser.Model/Configuration/EncodingOptions.cs index 9a30f7e9f0..843ff3ff9c 100644 --- a/MediaBrowser.Model/Configuration/EncodingOptions.cs +++ b/MediaBrowser.Model/Configuration/EncodingOptions.cs @@ -29,6 +29,22 @@ namespace MediaBrowser.Model.Configuration public string VaapiDevice { get; set; } + public string OpenclDevice { get; set; } + + public bool EnableTonemapping { get; set; } + + public string TonemappingAlgorithm { get; set; } + + public string TonemappingRange { get; set; } + + public double TonemappingDesat { get; set; } + + public double TonemappingThreshold { get; set; } + + public double TonemappingPeak { get; set; } + + public double TonemappingParam { get; set; } + public int H264Crf { get; set; } public int H265Crf { get; set; } @@ -53,8 +69,19 @@ namespace MediaBrowser.Model.Configuration EnableThrottling = false; ThrottleDelaySeconds = 180; EncodingThreadCount = -1; - // This is a DRM device that is almost guaranteed to be there on every intel platform, plus it's the default one in ffmpeg if you don't specify anything + // This is a DRM device that is almost guaranteed to be there on every intel platform, + // plus it's the default one in ffmpeg if you don't specify anything VaapiDevice = "/dev/dri/renderD128"; + // This is the OpenCL device that is used for tonemapping. + // The left side of the dot is the platform number, and the right side is the device number on the platform. + OpenclDevice = "0.0"; + EnableTonemapping = false; + TonemappingAlgorithm = "reinhard"; + TonemappingRange = "auto"; + TonemappingDesat = 0; + TonemappingThreshold = 0.8; + TonemappingPeak = 0; + TonemappingParam = 0; H264Crf = 23; H265Crf = 28; DeinterlaceMethod = "yadif"; diff --git a/MediaBrowser.Model/Entities/MediaStream.cs b/MediaBrowser.Model/Entities/MediaStream.cs index 1b37cfc939..19eb79acc4 100644 --- a/MediaBrowser.Model/Entities/MediaStream.cs +++ b/MediaBrowser.Model/Entities/MediaStream.cs @@ -35,6 +35,18 @@ namespace MediaBrowser.Model.Entities /// The language. public string Language { get; set; } + /// + /// Gets or sets the color range. + /// + /// The color range. + public string ColorRange { get; set; } + + /// + /// Gets or sets the color space. + /// + /// The color space. + public string ColorSpace { get; set; } + /// /// Gets or sets the color transfer. /// @@ -47,12 +59,6 @@ namespace MediaBrowser.Model.Entities /// The color primaries. public string ColorPrimaries { get; set; } - /// - /// Gets or sets the color space. - /// - /// The color space. - public string ColorSpace { get; set; } - /// /// Gets or sets the comment. /// From 5716453542172443124db43790d4fde0f0abff10 Mon Sep 17 00:00:00 2001 From: nyanmisaka Date: Sat, 25 Jul 2020 01:03:34 +0800 Subject: [PATCH 02/15] minor changes --- MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index 668411342b..42b89be023 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -1686,7 +1686,7 @@ namespace MediaBrowser.Controller.MediaEncoding index = outputSizeParam.IndexOf("vpp", StringComparison.OrdinalIgnoreCase); if (index != -1) { - outputSizeParam = outputSizeParam.Substring(index); + outputSizeParam = outputSizeParam.Slice(index); } } } @@ -1771,9 +1771,9 @@ namespace MediaBrowser.Controller.MediaEncoding */ if (isLinux) { - retStr = !outputSizeParam.IsEmpty ? - " -filter_complex \"[{0}:{1}]{4}[sub];[0:{2}]{3}[base];[base][sub]overlay_qsv\"" : - " -filter_complex \"[{0}:{1}]{4}[sub];[0:{2}][sub]overlay_qsv\""; + retStr = !outputSizeParam.IsEmpty + ? " -filter_complex \"[{0}:{1}]{4}[sub];[0:{2}]{3}[base];[base][sub]overlay_qsv\"" + : " -filter_complex \"[{0}:{1}]{4}[sub];[0:{2}][sub]overlay_qsv\""; } } From 95b961c8647b9db98d52631561cfc98224b905f7 Mon Sep 17 00:00:00 2001 From: Nyanmisaka Date: Sun, 26 Jul 2020 12:38:57 +0800 Subject: [PATCH 03/15] remove unused line --- MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index 42b89be023..1cdc8b736d 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -516,7 +516,6 @@ namespace MediaBrowser.Controller.MediaEncoding if (state.IsVideoRequest && string.Equals(encodingOptions.HardwareAccelerationType, "nvenc", StringComparison.OrdinalIgnoreCase)) { - var codec = state.VideoStream.Codec.ToLowerInvariant(); var isColorDepth10 = IsColorDepth10(state); if (isNvencHevcDecoder && isColorDepth10 From 17527d68dfe2fa6fb7755f819f03ada5165cb23d Mon Sep 17 00:00:00 2001 From: Nyanmisaka Date: Mon, 27 Jul 2020 14:11:05 +0800 Subject: [PATCH 04/15] fix build --- MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index 323fc5f75d..a04ddbaa0f 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -530,6 +530,7 @@ namespace MediaBrowser.Controller.MediaEncoding .Append(' ') .Append("-filter_hw_device ocl "); } + } if (state.IsVideoRequest && string.Equals(encodingOptions.HardwareAccelerationType, "videotoolbox", StringComparison.OrdinalIgnoreCase)) From 7b3f76b81fd92d30ac8783508fb7b6793d32ec95 Mon Sep 17 00:00:00 2001 From: Nyanmisaka Date: Mon, 3 Aug 2020 14:55:28 +0800 Subject: [PATCH 05/15] resolve conflicts --- .../MediaEncoding/EncodingHelper.cs | 61 +++++-------------- 1 file changed, 15 insertions(+), 46 deletions(-) diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index a04ddbaa0f..9433d33b4a 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -1647,57 +1647,26 @@ namespace MediaBrowser.Controller.MediaEncoding { outputSizeParam = GetOutputSizeParam(state, options, outputVideoCodec).TrimEnd('"'); - var index = outputSizeParam.IndexOf("hwupload,tonemap_opencl", StringComparison.OrdinalIgnoreCase); - if (index != -1) + // All possible beginning of video filters + // Don't break the order + string[] beginOfParam = new[] { - outputSizeParam = outputSizeParam.Slice(index); - } - else + "hwupload,tonemap_opencl", + "hwupload=extra_hw_frames", + "vpp", + "hwdownload", + "format", + "yadif", + "scale" + }; + + for (int i = 0, index = -1; i < beginOfParam.Length; i++) { - index = outputSizeParam.IndexOf("hwdownload", StringComparison.OrdinalIgnoreCase); + index = outputSizeParam.IndexOf(beginOfParam[i], StringComparison.OrdinalIgnoreCase); if (index != -1) { outputSizeParam = outputSizeParam.Slice(index); - } - else - { - index = outputSizeParam.IndexOf("hwupload=extra_hw_frames", StringComparison.OrdinalIgnoreCase); - if (index != -1) - { - outputSizeParam = outputSizeParam.Slice(index); - } - else - { - index = outputSizeParam.IndexOf("format", StringComparison.OrdinalIgnoreCase); - if (index != -1) - { - outputSizeParam = outputSizeParam.Slice(index); - } - else - { - index = outputSizeParam.IndexOf("yadif", StringComparison.OrdinalIgnoreCase); - if (index != -1) - { - outputSizeParam = outputSizeParam.Slice(index); - } - else - { - index = outputSizeParam.IndexOf("scale", StringComparison.OrdinalIgnoreCase); - if (index != -1) - { - outputSizeParam = outputSizeParam.Slice(index); - } - else - { - index = outputSizeParam.IndexOf("vpp", StringComparison.OrdinalIgnoreCase); - if (index != -1) - { - outputSizeParam = outputSizeParam.Slice(index); - } - } - } - } - } + break; } } } From 1ae3dc202ce2fbd40565e0d776b2d77abcd0f1f5 Mon Sep 17 00:00:00 2001 From: cvium Date: Tue, 11 Aug 2020 22:04:41 +0200 Subject: [PATCH 06/15] Populate ThemeVideoIds and ThemeSongIds --- MediaBrowser.Controller/Entities/BaseItem.cs | 51 ++++++++++++++++++-- 1 file changed, 46 insertions(+), 5 deletions(-) diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index f34309c400..32b8cea6c0 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -58,8 +58,6 @@ namespace MediaBrowser.Controller.Entities protected BaseItem() { - ThemeSongIds = Array.Empty(); - ThemeVideoIds = Array.Empty(); Tags = Array.Empty(); Genres = Array.Empty(); Studios = Array.Empty(); @@ -98,12 +96,52 @@ namespace MediaBrowser.Controller.Entities }; [JsonIgnore] - public Guid[] ThemeSongIds { get; set; } + public Guid[] ThemeSongIds + { + get + { + if (_themeSongIds == null) + { + _themeSongIds = GetExtras() + .Where(extra => extra.ExtraType == Model.Entities.ExtraType.ThemeSong) + .Select(song => song.Id) + .ToArray(); + } + + return _themeSongIds; + } + + private set + { + _themeSongIds = value; + } + } + [JsonIgnore] - public Guid[] ThemeVideoIds { get; set; } + public Guid[] ThemeVideoIds + { + get + { + if (_themeVideoIds == null) + { + _themeVideoIds = GetExtras() + .Where(extra => extra.ExtraType == Model.Entities.ExtraType.ThemeVideo) + .Select(song => song.Id) + .ToArray(); + } + + return _themeVideoIds; + } + + private set + { + _themeVideoIds = value; + } + } [JsonIgnore] public string PreferredMetadataCountryCode { get; set; } + [JsonIgnore] public string PreferredMetadataLanguage { get; set; } @@ -633,6 +671,9 @@ namespace MediaBrowser.Controller.Entities } private string _sortName; + private Guid[] _themeSongIds; + private Guid[] _themeVideoIds; + /// /// Gets the name of the sort. /// @@ -2909,7 +2950,7 @@ namespace MediaBrowser.Controller.Entities public IEnumerable GetThemeSongs() { - return ThemeVideoIds.Select(LibraryManager.GetItemById).Where(i => i.ExtraType.Equals(Model.Entities.ExtraType.ThemeSong)).OrderBy(i => i.SortName); + return ThemeSongIds.Select(LibraryManager.GetItemById).Where(i => i.ExtraType.Equals(Model.Entities.ExtraType.ThemeSong)).OrderBy(i => i.SortName); } public IEnumerable GetThemeVideos() From e10693cbe033652ecd6da66b48ec3a2be23e7a29 Mon Sep 17 00:00:00 2001 From: cvium Date: Wed, 12 Aug 2020 22:14:14 +0200 Subject: [PATCH 07/15] Remove some LINQ queries --- MediaBrowser.Controller/Entities/BaseItem.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index 32b8cea6c0..72574d6136 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -2950,12 +2950,12 @@ namespace MediaBrowser.Controller.Entities public IEnumerable GetThemeSongs() { - return ThemeSongIds.Select(LibraryManager.GetItemById).Where(i => i.ExtraType.Equals(Model.Entities.ExtraType.ThemeSong)).OrderBy(i => i.SortName); + return ThemeSongIds.Select(LibraryManager.GetItemById); } public IEnumerable GetThemeVideos() { - return ThemeVideoIds.Select(LibraryManager.GetItemById).Where(i => i.ExtraType.Equals(Model.Entities.ExtraType.ThemeVideo)).OrderBy(i => i.SortName); + return ThemeVideoIds.Select(LibraryManager.GetItemById); } /// From 54349fc94597824714f623b8c31583fc044274aa Mon Sep 17 00:00:00 2001 From: nyanmisaka Date: Thu, 20 Aug 2020 19:08:36 +0800 Subject: [PATCH 08/15] fix outputSize --- .../MediaEncoding/EncodingHelper.cs | 60 +++++++++++-------- 1 file changed, 35 insertions(+), 25 deletions(-) diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index 9433d33b4a..7ceb25bade 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -1639,35 +1639,45 @@ namespace MediaBrowser.Controller.MediaEncoding var outputSizeParam = ReadOnlySpan.Empty; var request = state.BaseRequest; - // Add resolution params, if specified - if (request.Width.HasValue - || request.Height.HasValue - || request.MaxHeight.HasValue - || request.MaxWidth.HasValue) + outputSizeParam = GetOutputSizeParam(state, options, outputVideoCodec).TrimEnd('"'); + + // All possible beginning of video filters + // Don't break the order + string[] beginOfOutputSizeParam = new[] { - outputSizeParam = GetOutputSizeParam(state, options, outputVideoCodec).TrimEnd('"'); + // for tonemap_opencl + "hwupload,tonemap_opencl", - // All possible beginning of video filters - // Don't break the order - string[] beginOfParam = new[] - { - "hwupload,tonemap_opencl", - "hwupload=extra_hw_frames", - "vpp", - "hwdownload", - "format", - "yadif", - "scale" - }; + // hwupload=extra_hw_frames=64,vpp_qsv (for overlay_qsv on linux) + "hwupload=extra_hw_frames", - for (int i = 0, index = -1; i < beginOfParam.Length; i++) + // vpp_qsv + "vpp", + + // hwdownload,format=p010le (hardware decode + software encode for vaapi) + "hwdownload", + + // format=nv12|vaapi,hwupload,scale_vaapi + "format", + + // bwdif,scale=expr + "bwdif", + + // yadif,scale=expr + "yadif", + + // scale=expr + "scale" + }; + + var index = -1; + foreach (var param in beginOfOutputSizeParam) + { + index = outputSizeParam.IndexOf(param, StringComparison.OrdinalIgnoreCase); + if (index != -1) { - index = outputSizeParam.IndexOf(beginOfParam[i], StringComparison.OrdinalIgnoreCase); - if (index != -1) - { - outputSizeParam = outputSizeParam.Slice(index); - break; - } + outputSizeParam = outputSizeParam.Slice(index); + break; } } From 2ca8d31b20d2494422570bb73c59ab3d79344743 Mon Sep 17 00:00:00 2001 From: crobibero Date: Thu, 20 Aug 2020 11:17:27 -0600 Subject: [PATCH 09/15] clean up output formatters --- Jellyfin.Api/BaseJellyfinApiController.cs | 5 ++++- Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs | 4 ++++ Jellyfin.Server/Formatters/CamelCaseJsonProfileFormatter.cs | 2 +- Jellyfin.Server/Formatters/PascalCaseJsonProfileFormatter.cs | 5 +++-- Jellyfin.Server/Formatters/XmlOutputFormatter.cs | 3 ++- 5 files changed, 14 insertions(+), 5 deletions(-) diff --git a/Jellyfin.Api/BaseJellyfinApiController.cs b/Jellyfin.Api/BaseJellyfinApiController.cs index a34f9eb62f..6288fb7e34 100644 --- a/Jellyfin.Api/BaseJellyfinApiController.cs +++ b/Jellyfin.Api/BaseJellyfinApiController.cs @@ -8,7 +8,10 @@ namespace Jellyfin.Api /// [ApiController] [Route("[controller]")] - [Produces(MediaTypeNames.Application.Json)] + [Produces( + MediaTypeNames.Application.Json, + MediaTypeNames.Application.Json + "; profile=\"CamelCase\"", + MediaTypeNames.Application.Json + "; profile=\"PascalCase\"")] public class BaseJellyfinApiController : ControllerBase { } diff --git a/Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs b/Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs index 2e2bfea684..c933a298e3 100644 --- a/Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs +++ b/Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs @@ -150,6 +150,10 @@ namespace Jellyfin.Server.Extensions .AddMvc(opts => { opts.UseGeneralRoutePrefix(baseUrl); + + // Allow requester to change between camelCase and PascalCase + opts.RespectBrowserAcceptHeader = true; + opts.OutputFormatters.Insert(0, new CamelCaseJsonProfileFormatter()); opts.OutputFormatters.Insert(0, new PascalCaseJsonProfileFormatter()); diff --git a/Jellyfin.Server/Formatters/CamelCaseJsonProfileFormatter.cs b/Jellyfin.Server/Formatters/CamelCaseJsonProfileFormatter.cs index 9b347ae2c2..cac89416eb 100644 --- a/Jellyfin.Server/Formatters/CamelCaseJsonProfileFormatter.cs +++ b/Jellyfin.Server/Formatters/CamelCaseJsonProfileFormatter.cs @@ -15,7 +15,7 @@ namespace Jellyfin.Server.Formatters public CamelCaseJsonProfileFormatter() : base(JsonDefaults.GetCamelCaseOptions()) { SupportedMediaTypes.Clear(); - SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse("application/json;profile=\"CamelCase\"")); + SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse("application/json; profile=\"CamelCase\"")); } } } diff --git a/Jellyfin.Server/Formatters/PascalCaseJsonProfileFormatter.cs b/Jellyfin.Server/Formatters/PascalCaseJsonProfileFormatter.cs index 0024708bad..2ba2241561 100644 --- a/Jellyfin.Server/Formatters/PascalCaseJsonProfileFormatter.cs +++ b/Jellyfin.Server/Formatters/PascalCaseJsonProfileFormatter.cs @@ -1,3 +1,4 @@ +using System.Net.Mime; using MediaBrowser.Common.Json; using Microsoft.AspNetCore.Mvc.Formatters; using Microsoft.Net.Http.Headers; @@ -16,8 +17,8 @@ namespace Jellyfin.Server.Formatters { SupportedMediaTypes.Clear(); // Add application/json for default formatter - SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse("application/json")); - SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse("application/json;profile=\"PascalCase\"")); + SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse(MediaTypeNames.Application.Json)); + SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse("application/json; profile=\"PascalCase\"")); } } } diff --git a/Jellyfin.Server/Formatters/XmlOutputFormatter.cs b/Jellyfin.Server/Formatters/XmlOutputFormatter.cs index 58319657d6..01d99d7c87 100644 --- a/Jellyfin.Server/Formatters/XmlOutputFormatter.cs +++ b/Jellyfin.Server/Formatters/XmlOutputFormatter.cs @@ -16,8 +16,9 @@ namespace Jellyfin.Server.Formatters /// public XmlOutputFormatter() { + SupportedMediaTypes.Clear(); SupportedMediaTypes.Add(MediaTypeNames.Text.Xml); - SupportedMediaTypes.Add("text/xml;charset=UTF-8"); + SupportedEncodings.Add(Encoding.UTF8); SupportedEncodings.Add(Encoding.Unicode); } From 4a64819277b98ac98ba0051c49fcf0cbfe16319c Mon Sep 17 00:00:00 2001 From: crobibero Date: Fri, 21 Aug 2020 11:10:29 -0600 Subject: [PATCH 10/15] Fix dlna produces type --- Jellyfin.Api/Controllers/DlnaServerController.cs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/Jellyfin.Api/Controllers/DlnaServerController.cs b/Jellyfin.Api/Controllers/DlnaServerController.cs index 0100d642be..e775c05a09 100644 --- a/Jellyfin.Api/Controllers/DlnaServerController.cs +++ b/Jellyfin.Api/Controllers/DlnaServerController.cs @@ -1,6 +1,7 @@ using System; using System.Diagnostics.CodeAnalysis; using System.IO; +using System.Net.Mime; using System.Threading.Tasks; using Emby.Dlna; using Emby.Dlna.Main; @@ -17,8 +18,6 @@ namespace Jellyfin.Api.Controllers [Route("Dlna")] public class DlnaServerController : BaseJellyfinApiController { - private const string XMLContentType = "text/xml; charset=UTF-8"; - private readonly IDlnaManager _dlnaManager; private readonly IContentDirectory _contentDirectory; private readonly IConnectionManager _connectionManager; @@ -44,7 +43,7 @@ namespace Jellyfin.Api.Controllers /// An containing the description xml. [HttpGet("{serverId}/description")] [HttpGet("{serverId}/description.xml", Name = "GetDescriptionXml_2")] - [Produces(XMLContentType)] + [Produces(MediaTypeNames.Text.Xml)] [ProducesResponseType(StatusCodes.Status200OK)] public ActionResult GetDescriptionXml([FromRoute] string serverId) { @@ -62,7 +61,7 @@ namespace Jellyfin.Api.Controllers /// An containing the dlna content directory xml. [HttpGet("{serverId}/ContentDirectory")] [HttpGet("{serverId}/ContentDirectory.xml", Name = "GetContentDirectory_2")] - [Produces(XMLContentType)] + [Produces(MediaTypeNames.Text.Xml)] [ProducesResponseType(StatusCodes.Status200OK)] [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "serverId", Justification = "Required for DLNA")] public ActionResult GetContentDirectory([FromRoute] string serverId) @@ -77,7 +76,7 @@ namespace Jellyfin.Api.Controllers /// Dlna media receiver registrar xml. [HttpGet("{serverId}/MediaReceiverRegistrar")] [HttpGet("{serverId}/MediaReceiverRegistrar.xml", Name = "GetMediaReceiverRegistrar_2")] - [Produces(XMLContentType)] + [Produces(MediaTypeNames.Text.Xml)] [ProducesResponseType(StatusCodes.Status200OK)] [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "serverId", Justification = "Required for DLNA")] public ActionResult GetMediaReceiverRegistrar([FromRoute] string serverId) @@ -92,7 +91,7 @@ namespace Jellyfin.Api.Controllers /// Dlna media receiver registrar xml. [HttpGet("{serverId}/ConnectionManager")] [HttpGet("{serverId}/ConnectionManager.xml", Name = "GetConnectionManager_2")] - [Produces(XMLContentType)] + [Produces(MediaTypeNames.Text.Xml)] [ProducesResponseType(StatusCodes.Status200OK)] [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "serverId", Justification = "Required for DLNA")] public ActionResult GetConnectionManager([FromRoute] string serverId) From abc527329d16bb33aefa051a48e0d0cefe5f2df7 Mon Sep 17 00:00:00 2001 From: Claus Vium Date: Thu, 3 Sep 2020 14:49:02 +0200 Subject: [PATCH 11/15] Sort by SortName after scanning --- MediaBrowser.Controller/Entities/BaseItem.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index 72574d6136..2cc4824add 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -1621,7 +1621,8 @@ namespace MediaBrowser.Controller.Entities await Task.WhenAll(tasks).ConfigureAwait(false); - item.ThemeVideoIds = newThemeVideoIds; + // They are expected to be sorted by SortName + item.ThemeVideoIds = newThemeVideos.OrderBy(i => i.SortName).Select(i => i.Id).ToArray(); return themeVideosChanged; } @@ -1658,7 +1659,8 @@ namespace MediaBrowser.Controller.Entities await Task.WhenAll(tasks).ConfigureAwait(false); - item.ThemeSongIds = newThemeSongIds; + // They are expected to be sorted by SortName + item.ThemeSongIds = newThemeSongs.OrderBy(i => i.SortName).Select(i => i.Id).ToArray(); return themeSongsChanged; } From 1d3303fa0a4a106dc74065ed37f9353ef763a52a Mon Sep 17 00:00:00 2001 From: crobibero Date: Thu, 3 Sep 2020 12:15:24 -0600 Subject: [PATCH 12/15] Move json profiles to constant strings. --- Jellyfin.Api/BaseJellyfinApiController.cs | 5 +++-- .../Formatters/CamelCaseJsonProfileFormatter.cs | 2 +- .../Formatters/PascalCaseJsonProfileFormatter.cs | 2 +- MediaBrowser.Common/Json/JsonDefaults.cs | 10 ++++++++++ 4 files changed, 15 insertions(+), 4 deletions(-) diff --git a/Jellyfin.Api/BaseJellyfinApiController.cs b/Jellyfin.Api/BaseJellyfinApiController.cs index 6288fb7e34..1c1fc71d79 100644 --- a/Jellyfin.Api/BaseJellyfinApiController.cs +++ b/Jellyfin.Api/BaseJellyfinApiController.cs @@ -1,4 +1,5 @@ using System.Net.Mime; +using MediaBrowser.Common.Json; using Microsoft.AspNetCore.Mvc; namespace Jellyfin.Api @@ -10,8 +11,8 @@ namespace Jellyfin.Api [Route("[controller]")] [Produces( MediaTypeNames.Application.Json, - MediaTypeNames.Application.Json + "; profile=\"CamelCase\"", - MediaTypeNames.Application.Json + "; profile=\"PascalCase\"")] + JsonDefaults.CamelCaseMediaType, + JsonDefaults.PascalCaseMediaType)] public class BaseJellyfinApiController : ControllerBase { } diff --git a/Jellyfin.Server/Formatters/CamelCaseJsonProfileFormatter.cs b/Jellyfin.Server/Formatters/CamelCaseJsonProfileFormatter.cs index cac89416eb..8043989b1e 100644 --- a/Jellyfin.Server/Formatters/CamelCaseJsonProfileFormatter.cs +++ b/Jellyfin.Server/Formatters/CamelCaseJsonProfileFormatter.cs @@ -15,7 +15,7 @@ namespace Jellyfin.Server.Formatters public CamelCaseJsonProfileFormatter() : base(JsonDefaults.GetCamelCaseOptions()) { SupportedMediaTypes.Clear(); - SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse("application/json; profile=\"CamelCase\"")); + SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse(JsonDefaults.CamelCaseMediaType)); } } } diff --git a/Jellyfin.Server/Formatters/PascalCaseJsonProfileFormatter.cs b/Jellyfin.Server/Formatters/PascalCaseJsonProfileFormatter.cs index 2ba2241561..d0110b125c 100644 --- a/Jellyfin.Server/Formatters/PascalCaseJsonProfileFormatter.cs +++ b/Jellyfin.Server/Formatters/PascalCaseJsonProfileFormatter.cs @@ -18,7 +18,7 @@ namespace Jellyfin.Server.Formatters SupportedMediaTypes.Clear(); // Add application/json for default formatter SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse(MediaTypeNames.Application.Json)); - SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse("application/json; profile=\"PascalCase\"")); + SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse(JsonDefaults.PascalCaseMediaType)); } } } diff --git a/MediaBrowser.Common/Json/JsonDefaults.cs b/MediaBrowser.Common/Json/JsonDefaults.cs index 5867cd4a0c..67f7e8f14a 100644 --- a/MediaBrowser.Common/Json/JsonDefaults.cs +++ b/MediaBrowser.Common/Json/JsonDefaults.cs @@ -9,6 +9,16 @@ namespace MediaBrowser.Common.Json /// public static class JsonDefaults { + /// + /// Pascal case json profile media type. + /// + public const string PascalCaseMediaType = "application/json; profile=\"PascalCase\""; + + /// + /// Camel case json profile media type. + /// + public const string CamelCaseMediaType = "application/json; profile=\"CamelCase\""; + /// /// Gets the default options. /// From 4df47dea47b787a20526117e0e40f91a7802561b Mon Sep 17 00:00:00 2001 From: crobibero Date: Thu, 3 Sep 2020 13:44:49 -0600 Subject: [PATCH 13/15] Use efcore library for health check --- .../HealthChecks/JellyfinDbHealthCheck.cs | 36 ------------------- Jellyfin.Server/Jellyfin.Server.csproj | 1 + Jellyfin.Server/Startup.cs | 4 +-- 3 files changed, 3 insertions(+), 38 deletions(-) delete mode 100644 Jellyfin.Server/HealthChecks/JellyfinDbHealthCheck.cs diff --git a/Jellyfin.Server/HealthChecks/JellyfinDbHealthCheck.cs b/Jellyfin.Server/HealthChecks/JellyfinDbHealthCheck.cs deleted file mode 100644 index aea6844798..0000000000 --- a/Jellyfin.Server/HealthChecks/JellyfinDbHealthCheck.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Threading; -using System.Threading.Tasks; -using Jellyfin.Server.Implementations; -using Microsoft.Extensions.Diagnostics.HealthChecks; - -namespace Jellyfin.Server.HealthChecks -{ - /// - /// Checks connectivity to the database. - /// - public class JellyfinDbHealthCheck : IHealthCheck - { - private readonly JellyfinDbProvider _dbProvider; - - /// - /// Initializes a new instance of the class. - /// - /// The jellyfin db provider. - public JellyfinDbHealthCheck(JellyfinDbProvider dbProvider) - { - _dbProvider = dbProvider; - } - - /// - public async Task CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default) - { - await using var jellyfinDb = _dbProvider.CreateContext(); - if (await jellyfinDb.Database.CanConnectAsync(cancellationToken).ConfigureAwait(false)) - { - return HealthCheckResult.Healthy("Database connection successful."); - } - - return HealthCheckResult.Unhealthy("Unable to connect to the database."); - } - } -} diff --git a/Jellyfin.Server/Jellyfin.Server.csproj b/Jellyfin.Server/Jellyfin.Server.csproj index 24ba8369a6..85d5f2a3f5 100644 --- a/Jellyfin.Server/Jellyfin.Server.csproj +++ b/Jellyfin.Server/Jellyfin.Server.csproj @@ -44,6 +44,7 @@ + diff --git a/Jellyfin.Server/Startup.cs b/Jellyfin.Server/Startup.cs index 1a34de2695..d053764703 100644 --- a/Jellyfin.Server/Startup.cs +++ b/Jellyfin.Server/Startup.cs @@ -3,7 +3,7 @@ using System.ComponentModel; using System.Net.Http.Headers; using Jellyfin.Api.TypeConverters; using Jellyfin.Server.Extensions; -using Jellyfin.Server.HealthChecks; +using Jellyfin.Server.Implementations; using Jellyfin.Server.Middleware; using Jellyfin.Server.Models; using MediaBrowser.Common.Net; @@ -79,7 +79,7 @@ namespace Jellyfin.Server .ConfigurePrimaryHttpMessageHandler(x => new DefaultHttpClientHandler()); services.AddHealthChecks() - .AddCheck("JellyfinDb"); + .AddDbContextCheck(); } /// From 583f47ea28853ba84258b399e2093cd7dd5c3a55 Mon Sep 17 00:00:00 2001 From: crobibero Date: Fri, 4 Sep 2020 07:04:06 -0600 Subject: [PATCH 14/15] Remove GenerateDocumentationFile --- Dockerfile | 2 +- Dockerfile.arm | 2 +- Dockerfile.arm64 | 2 +- debian/rules | 2 +- deployment/Dockerfile.docker.amd64 | 2 +- deployment/Dockerfile.docker.arm64 | 2 +- deployment/Dockerfile.docker.armhf | 2 +- deployment/build.linux.amd64 | 2 +- deployment/build.macos | 2 +- deployment/build.portable | 2 +- deployment/build.windows.amd64 | 2 +- fedora/jellyfin.spec | 2 +- 12 files changed, 12 insertions(+), 12 deletions(-) diff --git a/Dockerfile b/Dockerfile index 4fdffc7400..69af9b77b5 100644 --- a/Dockerfile +++ b/Dockerfile @@ -14,7 +14,7 @@ COPY . . ENV DOTNET_CLI_TELEMETRY_OPTOUT=1 # because of changes in docker and systemd we need to not build in parallel at the moment # see https://success.docker.com/article/how-to-reserve-resource-temporarily-unavailable-errors-due-to-tasksmax-setting -RUN dotnet publish Jellyfin.Server --disable-parallel --configuration Release --output="/jellyfin" --self-contained --runtime linux-x64 "-p:GenerateDocumentationFile=true;DebugSymbols=false;DebugType=none" +RUN dotnet publish Jellyfin.Server --disable-parallel --configuration Release --output="/jellyfin" --self-contained --runtime linux-x64 "-p:DebugSymbols=false;DebugType=none" FROM debian:buster-slim diff --git a/Dockerfile.arm b/Dockerfile.arm index 751ab86119..efeed25dff 100644 --- a/Dockerfile.arm +++ b/Dockerfile.arm @@ -21,7 +21,7 @@ ENV DOTNET_CLI_TELEMETRY_OPTOUT=1 # Discard objs - may cause failures if exists RUN find . -type d -name obj | xargs -r rm -r # Build -RUN dotnet publish Jellyfin.Server --configuration Release --output="/jellyfin" --self-contained --runtime linux-arm "-p:GenerateDocumentationFile=true;DebugSymbols=false;DebugType=none" +RUN dotnet publish Jellyfin.Server --configuration Release --output="/jellyfin" --self-contained --runtime linux-arm "-p:DebugSymbols=false;DebugType=none" FROM multiarch/qemu-user-static:x86_64-arm as qemu diff --git a/Dockerfile.arm64 b/Dockerfile.arm64 index 0d2e91d91c..1f2c2ec36d 100644 --- a/Dockerfile.arm64 +++ b/Dockerfile.arm64 @@ -21,7 +21,7 @@ ENV DOTNET_CLI_TELEMETRY_OPTOUT=1 # Discard objs - may cause failures if exists RUN find . -type d -name obj | xargs -r rm -r # Build -RUN dotnet publish Jellyfin.Server --configuration Release --output="/jellyfin" --self-contained --runtime linux-arm64 "-p:GenerateDocumentationFile=true;DebugSymbols=false;DebugType=none" +RUN dotnet publish Jellyfin.Server --configuration Release --output="/jellyfin" --self-contained --runtime linux-arm64 "-p:DebugSymbols=false;DebugType=none" FROM multiarch/qemu-user-static:x86_64-aarch64 as qemu FROM arm64v8/debian:buster-slim diff --git a/debian/rules b/debian/rules index 6c7fbb779d..96541f41b8 100755 --- a/debian/rules +++ b/debian/rules @@ -40,7 +40,7 @@ override_dh_clistrip: override_dh_auto_build: dotnet publish --configuration $(CONFIG) --output='$(CURDIR)/usr/lib/jellyfin/bin' --self-contained --runtime $(DOTNETRUNTIME) \ - "-p:GenerateDocumentationFile=true;DebugSymbols=false;DebugType=none" Jellyfin.Server + "-p:DebugSymbols=false;DebugType=none" Jellyfin.Server override_dh_auto_clean: dotnet clean -maxcpucount:1 --configuration $(CONFIG) Jellyfin.Server || true diff --git a/deployment/Dockerfile.docker.amd64 b/deployment/Dockerfile.docker.amd64 index cf09014045..e04442606e 100644 --- a/deployment/Dockerfile.docker.amd64 +++ b/deployment/Dockerfile.docker.amd64 @@ -12,4 +12,4 @@ ENV DOTNET_CLI_TELEMETRY_OPTOUT=1 # because of changes in docker and systemd we need to not build in parallel at the moment # see https://success.docker.com/article/how-to-reserve-resource-temporarily-unavailable-errors-due-to-tasksmax-setting -RUN dotnet publish Jellyfin.Server --disable-parallel --configuration Release --output="${ARTIFACT_DIR}" --self-contained --runtime linux-x64 "-p:GenerateDocumentationFile=true;DebugSymbols=false;DebugType=none" +RUN dotnet publish Jellyfin.Server --disable-parallel --configuration Release --output="${ARTIFACT_DIR}" --self-contained --runtime linux-x64 "-p:DebugSymbols=false;DebugType=none" diff --git a/deployment/Dockerfile.docker.arm64 b/deployment/Dockerfile.docker.arm64 index 5454ef0247..a7ac40492a 100644 --- a/deployment/Dockerfile.docker.arm64 +++ b/deployment/Dockerfile.docker.arm64 @@ -12,4 +12,4 @@ ENV DOTNET_CLI_TELEMETRY_OPTOUT=1 # because of changes in docker and systemd we need to not build in parallel at the moment # see https://success.docker.com/article/how-to-reserve-resource-temporarily-unavailable-errors-due-to-tasksmax-setting -RUN dotnet publish Jellyfin.Server --disable-parallel --configuration Release --output="${ARTIFACT_DIR}" --self-contained --runtime linux-arm64 "-p:GenerateDocumentationFile=true;DebugSymbols=false;DebugType=none" +RUN dotnet publish Jellyfin.Server --disable-parallel --configuration Release --output="${ARTIFACT_DIR}" --self-contained --runtime linux-arm64 "-p:DebugSymbols=false;DebugType=none" diff --git a/deployment/Dockerfile.docker.armhf b/deployment/Dockerfile.docker.armhf index d99fa2a85c..b5a42f55ff 100644 --- a/deployment/Dockerfile.docker.armhf +++ b/deployment/Dockerfile.docker.armhf @@ -12,4 +12,4 @@ ENV DOTNET_CLI_TELEMETRY_OPTOUT=1 # because of changes in docker and systemd we need to not build in parallel at the moment # see https://success.docker.com/article/how-to-reserve-resource-temporarily-unavailable-errors-due-to-tasksmax-setting -RUN dotnet publish Jellyfin.Server --disable-parallel --configuration Release --output="${ARTIFACT_DIR}" --self-contained --runtime linux-arm "-p:GenerateDocumentationFile=true;DebugSymbols=false;DebugType=none" +RUN dotnet publish Jellyfin.Server --disable-parallel --configuration Release --output="${ARTIFACT_DIR}" --self-contained --runtime linux-arm "-p:DebugSymbols=false;DebugType=none" diff --git a/deployment/build.linux.amd64 b/deployment/build.linux.amd64 index d0a5c1747a..a1e7f661a5 100755 --- a/deployment/build.linux.amd64 +++ b/deployment/build.linux.amd64 @@ -16,7 +16,7 @@ else fi # Build archives -dotnet publish Jellyfin.Server --configuration Release --self-contained --runtime linux-x64 --output dist/jellyfin-server_${version}/ "-p:GenerateDocumentationFile=true;DebugSymbols=false;DebugType=none;UseAppHost=true" +dotnet publish Jellyfin.Server --configuration Release --self-contained --runtime linux-x64 --output dist/jellyfin-server_${version}/ "-p:DebugSymbols=false;DebugType=none;UseAppHost=true" tar -czf jellyfin-server_${version}_linux-amd64.tar.gz -C dist jellyfin-server_${version} rm -rf dist/jellyfin-server_${version} diff --git a/deployment/build.macos b/deployment/build.macos index 8bb8b2ebdb..6255c80cb2 100755 --- a/deployment/build.macos +++ b/deployment/build.macos @@ -16,7 +16,7 @@ else fi # Build archives -dotnet publish Jellyfin.Server --configuration Release --self-contained --runtime osx-x64 --output dist/jellyfin-server_${version}/ "-p:GenerateDocumentationFile=true;DebugSymbols=false;DebugType=none;UseAppHost=true" +dotnet publish Jellyfin.Server --configuration Release --self-contained --runtime osx-x64 --output dist/jellyfin-server_${version}/ "-p:DebugSymbols=false;DebugType=none;UseAppHost=true" tar -czf jellyfin-server_${version}_macos-amd64.tar.gz -C dist jellyfin-server_${version} rm -rf dist/jellyfin-server_${version} diff --git a/deployment/build.portable b/deployment/build.portable index 4c81d5672c..ea40ade5d9 100755 --- a/deployment/build.portable +++ b/deployment/build.portable @@ -16,7 +16,7 @@ else fi # Build archives -dotnet publish Jellyfin.Server --configuration Release --output dist/jellyfin-server_${version}/ "-p:GenerateDocumentationFile=true;DebugSymbols=false;DebugType=none;UseAppHost=true" +dotnet publish Jellyfin.Server --configuration Release --output dist/jellyfin-server_${version}/ "-p:DebugSymbols=false;DebugType=none;UseAppHost=true" tar -czf jellyfin-server_${version}_portable.tar.gz -C dist jellyfin-server_${version} rm -rf dist/jellyfin-server_${version} diff --git a/deployment/build.windows.amd64 b/deployment/build.windows.amd64 index 47cfa2cd6f..afe4905769 100755 --- a/deployment/build.windows.amd64 +++ b/deployment/build.windows.amd64 @@ -23,7 +23,7 @@ fi output_dir="dist/jellyfin-server_${version}" # Build binary -dotnet publish Jellyfin.Server --configuration Release --self-contained --runtime win-x64 --output ${output_dir}/ "-p:GenerateDocumentationFile=true;DebugSymbols=false;DebugType=none;UseAppHost=true" +dotnet publish Jellyfin.Server --configuration Release --self-contained --runtime win-x64 --output ${output_dir}/ "-p:DebugSymbols=false;DebugType=none;UseAppHost=true" # Prepare addins addin_build_dir="$( mktemp -d )" diff --git a/fedora/jellyfin.spec b/fedora/jellyfin.spec index 291017d947..37b573e505 100644 --- a/fedora/jellyfin.spec +++ b/fedora/jellyfin.spec @@ -54,7 +54,7 @@ The Jellyfin media server backend. export DOTNET_CLI_TELEMETRY_OPTOUT=1 export DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1 dotnet publish --configuration Release --output='%{buildroot}%{_libdir}/jellyfin' --self-contained --runtime %{dotnet_runtime} \ - "-p:GenerateDocumentationFile=true;DebugSymbols=false;DebugType=none" Jellyfin.Server + "-p:DebugSymbols=false;DebugType=none" Jellyfin.Server %{__install} -D -m 0644 LICENSE %{buildroot}%{_datadir}/licenses/jellyfin/LICENSE %{__install} -D -m 0644 %{SOURCE15} %{buildroot}%{_sysconfdir}/systemd/system/jellyfin.service.d/override.conf %{__install} -D -m 0644 Jellyfin.Server/Resources/Configuration/logging.json %{buildroot}%{_sysconfdir}/jellyfin/logging.json From 021e218f754af8a1cf7f35e2a1d8286e813884e1 Mon Sep 17 00:00:00 2001 From: crobibero Date: Fri, 4 Sep 2020 07:58:27 -0600 Subject: [PATCH 15/15] Remove MvcRoutePrefix --- Jellyfin.Api/MvcRoutePrefix.cs | 56 ---------------------------------- 1 file changed, 56 deletions(-) delete mode 100644 Jellyfin.Api/MvcRoutePrefix.cs diff --git a/Jellyfin.Api/MvcRoutePrefix.cs b/Jellyfin.Api/MvcRoutePrefix.cs deleted file mode 100644 index e009730947..0000000000 --- a/Jellyfin.Api/MvcRoutePrefix.cs +++ /dev/null @@ -1,56 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.Mvc.ApplicationModels; - -namespace Jellyfin.Api -{ - /// - /// Route prefixing for ASP.NET MVC. - /// - public static class MvcRoutePrefix - { - /// - /// Adds route prefixes to the MVC conventions. - /// - /// The MVC options. - /// The list of prefixes. - public static void UseGeneralRoutePrefix(this MvcOptions opts, params string[] prefixes) - { - opts.Conventions.Insert(0, new RoutePrefixConvention(prefixes)); - } - - private class RoutePrefixConvention : IApplicationModelConvention - { - private readonly AttributeRouteModel[] _routePrefixes; - - public RoutePrefixConvention(IEnumerable prefixes) - { - _routePrefixes = prefixes.Select(p => new AttributeRouteModel(new RouteAttribute(p))).ToArray(); - } - - public void Apply(ApplicationModel application) - { - foreach (var controller in application.Controllers) - { - if (controller.Selectors == null) - { - continue; - } - - var newSelectors = new List(); - foreach (var selector in controller.Selectors) - { - newSelectors.AddRange(_routePrefixes.Select(routePrefix => new SelectorModel(selector) - { - AttributeRouteModel = AttributeRouteModel.CombineAttributeRouteModel(routePrefix, selector.AttributeRouteModel) - })); - } - - controller.Selectors.Clear(); - newSelectors.ForEach(selector => controller.Selectors.Add(selector)); - } - } - } - } -}