From a2f1ec23cedd1238b809ec173c0af8e3255018a0 Mon Sep 17 00:00:00 2001 From: Cody Robibero Date: Mon, 4 Apr 2022 16:05:50 -0600 Subject: Merge pull request #7557 from jellyfin/pgs-qsv-iris655 (cherry picked from commit 620625c4c12ad59c0c36ca9bc3f405242ee3d83d) Signed-off-by: crobibero --- MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'MediaBrowser.Controller/MediaEncoding') diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index 633ba2d762..5030d55f60 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -3381,7 +3381,8 @@ namespace MediaBrowser.Controller.MediaEncoding } // qsv requires a fixed pool size. - subFilters.Add("hwupload=extra_hw_frames=32"); + // default to 64 otherwise it will fail on certain iGPU. + subFilters.Add("hwupload=extra_hw_frames=64"); var (overlayW, overlayH) = GetFixedOutputSize(inW, inH, reqW, reqH, reqMaxW, reqMaxH); var overlaySize = (overlayW.HasValue && overlayH.HasValue) @@ -3589,7 +3590,8 @@ namespace MediaBrowser.Controller.MediaEncoding } // qsv requires a fixed pool size. - subFilters.Add("hwupload=extra_hw_frames=32"); + // default to 64 otherwise it will fail on certain iGPU. + subFilters.Add("hwupload=extra_hw_frames=64"); var (overlayW, overlayH) = GetFixedOutputSize(inW, inH, reqW, reqH, reqMaxW, reqMaxH); var overlaySize = (overlayW.HasValue && overlayH.HasValue) -- cgit v1.2.3 From fe3dbabbff5aa4654c673eea13f225d311286b48 Mon Sep 17 00:00:00 2001 From: Cody Robibero Date: Tue, 12 Apr 2022 13:41:21 -0600 Subject: Merge pull request #7580 from jellyfin/external-audio-map (cherry picked from commit c5212a20a314adb3cf654bc1a08f03933377e519) Signed-off-by: Joshua Boniface --- MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'MediaBrowser.Controller/MediaEncoding') diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index 5030d55f60..162a821f5d 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -2244,7 +2244,8 @@ namespace MediaBrowser.Controller.MediaEncoding { if (state.AudioStream.IsExternal) { - int externalAudioMapIndex = state.SubtitleStream != null && state.SubtitleStream.IsExternal ? 2 : 1; + bool hasExternalGraphicsSubs = state.SubtitleStream != null && state.SubtitleStream.IsExternal && !state.SubtitleStream.IsTextSubtitleStream; + int externalAudioMapIndex = hasExternalGraphicsSubs ? 2 : 1; int externalAudioStream = state.MediaSource.MediaStreams.Where(i => i.Path == state.AudioStream.Path).ToList().IndexOf(state.AudioStream); args += string.Format( -- cgit v1.2.3 From 76cfb8c9037d836feb37634b8b9d3e0c23c05d87 Mon Sep 17 00:00:00 2001 From: Cody Robibero Date: Fri, 22 Apr 2022 16:40:53 -0600 Subject: Merge pull request #7643 from jellyfin/h264-level (cherry picked from commit 12f9132975a4415ab7df3be9dcc2b56d68082d5f) Signed-off-by: crobibero --- MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'MediaBrowser.Controller/MediaEncoding') diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index 162a821f5d..006fd88610 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -1062,10 +1062,12 @@ namespace MediaBrowser.Controller.MediaEncoding } else if (string.Equals(state.ActualOutputVideoCodec, "h264", StringComparison.OrdinalIgnoreCase)) { - // Clients may direct play higher than level 41, but there's no reason to transcode higher. - if (requestLevel >= 41) + // Transcode to level 5.1 and lower for maximum compatibility. + // h264 4k 30fps requires at least level 5.1 otherwise it will break on safari fmp4. + // https://en.wikipedia.org/wiki/Advanced_Video_Coding#Levels + if (requestLevel >= 51) { - return "41"; + return "51"; } } } -- cgit v1.2.3 From efcdab116f85a560c9362185a9e333c3fc9df41d Mon Sep 17 00:00:00 2001 From: Cody Robibero Date: Wed, 4 May 2022 08:20:48 -0600 Subject: Merge pull request #7529 from Shadowghost/strm-ffprobe-external-fix (cherry picked from commit 60affd096595d68728506149d0ffce6e84b6b015) Signed-off-by: crobibero --- .../Data/SqliteItemRepository.cs | 6 +-- .../Library/MediaSourceManager.cs | 6 ++- .../MediaEncoding/EncodingHelper.cs | 54 +++++++++++++++++----- .../MediaEncoding/IMediaEncoder.cs | 7 +++ MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs | 13 ++++++ .../Subtitles/SubtitleEncoder.cs | 19 ++++++-- .../MediaInfo/FFProbeVideoInfo.cs | 39 ++++++++++++---- 7 files changed, 115 insertions(+), 29 deletions(-) (limited to 'MediaBrowser.Controller/MediaEncoding') diff --git a/Emby.Server.Implementations/Data/SqliteItemRepository.cs b/Emby.Server.Implementations/Data/SqliteItemRepository.cs index 5729a70ace..cdc14c2605 100644 --- a/Emby.Server.Implementations/Data/SqliteItemRepository.cs +++ b/Emby.Server.Implementations/Data/SqliteItemRepository.cs @@ -5763,7 +5763,7 @@ AND Type = @InternalPersonType)"); { var itemIdBlob = id.ToByteArray(); - // First delete chapters + // Delete existing mediastreams db.Execute("delete from mediastreams where ItemId=@ItemId", itemIdBlob); InsertMediaStreams(itemIdBlob, streams, db); @@ -5867,10 +5867,10 @@ AND Type = @InternalPersonType)"); } /// - /// Gets the chapter. + /// Gets the media stream. /// /// The reader. - /// ChapterInfo. + /// MediaStream. private MediaStream GetMediaStream(IReadOnlyList reader) { var item = new MediaStream diff --git a/Emby.Server.Implementations/Library/MediaSourceManager.cs b/Emby.Server.Implementations/Library/MediaSourceManager.cs index d9a1a54872..c0aef18997 100644 --- a/Emby.Server.Implementations/Library/MediaSourceManager.cs +++ b/Emby.Server.Implementations/Library/MediaSourceManager.cs @@ -151,7 +151,11 @@ namespace Emby.Server.Implementations.Library { var mediaSources = GetStaticMediaSources(item, enablePathSubstitution, user); - if (allowMediaProbe && mediaSources[0].Type != MediaSourceType.Placeholder && !mediaSources[0].MediaStreams.Any(i => i.Type == MediaStreamType.Audio || i.Type == MediaStreamType.Video)) + // If file is strm or main media stream is missing, force a metadata refresh with remote probing + if (allowMediaProbe && mediaSources[0].Type != MediaSourceType.Placeholder + && (item.Path.EndsWith(".strm", StringComparison.OrdinalIgnoreCase) + || (item.MediaType == MediaType.Video && !mediaSources[0].MediaStreams.Any(i => i.Type == MediaStreamType.Video)) + || (item.MediaType == MediaType.Audio && !mediaSources[0].MediaStreams.Any(i => i.Type == MediaStreamType.Audio)))) { await item.RefreshMetadata( new MetadataRefreshOptions(_directoryService) diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index 006fd88610..1851a9f0c5 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -2215,13 +2215,13 @@ namespace MediaBrowser.Controller.MediaEncoding return state.IsInputVideo ? "-sn" : string.Empty; } - // We have media info, but we don't know the stream indexes + // We have media info, but we don't know the stream index if (state.VideoStream != null && state.VideoStream.Index == -1) { return "-sn"; } - // We have media info, but we don't know the stream indexes + // We have media info, but we don't know the stream index if (state.AudioStream != null && state.AudioStream.Index == -1) { return state.IsInputVideo ? "-sn" : string.Empty; @@ -2231,10 +2231,12 @@ namespace MediaBrowser.Controller.MediaEncoding if (state.VideoStream != null) { + int videoStreamIndex = FindIndex(state.MediaSource.MediaStreams, state.VideoStream); + args += string.Format( CultureInfo.InvariantCulture, "-map 0:{0}", - state.VideoStream.Index); + videoStreamIndex); } else { @@ -2244,24 +2246,24 @@ namespace MediaBrowser.Controller.MediaEncoding if (state.AudioStream != null) { + int audioStreamIndex = FindIndex(state.MediaSource.MediaStreams, state.AudioStream); if (state.AudioStream.IsExternal) { bool hasExternalGraphicsSubs = state.SubtitleStream != null && state.SubtitleStream.IsExternal && !state.SubtitleStream.IsTextSubtitleStream; int externalAudioMapIndex = hasExternalGraphicsSubs ? 2 : 1; - int externalAudioStream = state.MediaSource.MediaStreams.Where(i => i.Path == state.AudioStream.Path).ToList().IndexOf(state.AudioStream); args += string.Format( CultureInfo.InvariantCulture, " -map {0}:{1}", externalAudioMapIndex, - externalAudioStream); + audioStreamIndex); } else { args += string.Format( CultureInfo.InvariantCulture, " -map 0:{0}", - state.AudioStream.Index); + audioStreamIndex); } } else @@ -2276,14 +2278,21 @@ namespace MediaBrowser.Controller.MediaEncoding } else if (subtitleMethod == SubtitleDeliveryMethod.Embed) { + int subtitleStreamIndex = FindIndex(state.MediaSource.MediaStreams, state.SubtitleStream); + args += string.Format( CultureInfo.InvariantCulture, " -map 0:{0}", - state.SubtitleStream.Index); + subtitleStreamIndex); } else if (state.SubtitleStream.IsExternal && !state.SubtitleStream.IsTextSubtitleStream) { - args += " -map 1:0 -sn"; + int externalSubtitleStreamIndex = FindIndex(state.MediaSource.MediaStreams, state.SubtitleStream); + + args += string.Format( + CultureInfo.InvariantCulture, + " -map 1:{0} -sn", + externalSubtitleStreamIndex); } return args; @@ -4129,9 +4138,8 @@ namespace MediaBrowser.Controller.MediaEncoding string.Join(',', overlayFilters)); var mapPrefix = Convert.ToInt32(state.SubtitleStream.IsExternal); - var subtitleStreamIndex = state.SubtitleStream.IsExternal - ? 0 - : state.SubtitleStream.Index; + var subtitleStreamIndex = FindIndex(state.MediaSource.MediaStreams, state.SubtitleStream); + var videoStreamIndex = FindIndex(state.MediaSource.MediaStreams, state.VideoStream); if (hasSubs) { @@ -4152,7 +4160,7 @@ namespace MediaBrowser.Controller.MediaEncoding filterStr, mapPrefix, subtitleStreamIndex, - state.VideoStream.Index, + videoStreamIndex, mainStr, subStr, overlayStr); @@ -5389,6 +5397,28 @@ namespace MediaBrowser.Controller.MediaEncoding string.Empty).Trim(); } + public static int FindIndex(IReadOnlyList mediaStreams, MediaStream streamToFind) + { + var index = 0; + var length = mediaStreams.Count; + + for (var i = 0; i < length; i++) + { + var currentMediaStream = mediaStreams[i]; + if (currentMediaStream == streamToFind) + { + return index; + } + + if (string.Equals(currentMediaStream.Path, streamToFind.Path, StringComparison.Ordinal)) + { + index++; + } + } + + return -1; + } + public static bool IsCopyCodec(string codec) { return string.Equals(codec, "copy", StringComparison.OrdinalIgnoreCase); diff --git a/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs b/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs index 6bf3e7b469..dae30cd8b3 100644 --- a/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs +++ b/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs @@ -141,6 +141,13 @@ namespace MediaBrowser.Controller.MediaEncoding /// System.String. string GetInputArgument(string inputFile, MediaSourceInfo mediaSource); + /// + /// Gets the input argument for an external subtitle file. + /// + /// The input file. + /// System.String. + string GetExternalSubtitleInputArgument(string inputFile); + /// /// Gets the time parameter. /// diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs index c796ee7806..1bac4b1875 100644 --- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs @@ -411,6 +411,19 @@ namespace MediaBrowser.MediaEncoding.Encoder return EncodingUtils.GetInputArgument(prefix, inputFile, mediaSource.Protocol); } + /// + /// Gets the input argument for an external subtitle file. + /// + /// The input file. + /// System.String. + /// Unrecognized InputType. + public string GetExternalSubtitleInputArgument(string inputFile) + { + const string Prefix = "file"; + + return EncodingUtils.GetInputArgument(Prefix, inputFile, MediaProtocol.File); + } + /// /// Gets the media info internal. /// diff --git a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs index f4842d3682..f6b7efb1e9 100644 --- a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs +++ b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs @@ -195,7 +195,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles MediaStream subtitleStream, CancellationToken cancellationToken) { - if (!subtitleStream.IsExternal) + if (!subtitleStream.IsExternal || subtitleStream.Path.EndsWith(".mks", StringComparison.OrdinalIgnoreCase)) { string outputFormat; string outputCodec; @@ -224,7 +224,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles // Extract var outputPath = GetSubtitleCachePath(mediaSource, subtitleStream.Index, "." + outputFormat); - await ExtractTextSubtitle(mediaSource, subtitleStream.Index, outputCodec, outputPath, cancellationToken) + await ExtractTextSubtitle(mediaSource, subtitleStream, outputCodec, outputPath, cancellationToken) .ConfigureAwait(false); return new SubtitleInfo(outputPath, MediaProtocol.File, outputFormat, false); @@ -494,7 +494,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles /// Extracts the text subtitle. /// /// The mediaSource. - /// Index of the subtitle stream. + /// The subtitle stream. /// The output codec. /// The output path. /// The cancellation token. @@ -502,7 +502,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles /// Must use inputPath list overload. private async Task ExtractTextSubtitle( MediaSourceInfo mediaSource, - int subtitleStreamIndex, + MediaStream subtitleStream, string outputCodec, string outputPath, CancellationToken cancellationToken) @@ -511,12 +511,21 @@ namespace MediaBrowser.MediaEncoding.Subtitles await semaphore.WaitAsync(cancellationToken).ConfigureAwait(false); + var subtitleStreamIndex = EncodingHelper.FindIndex(mediaSource.MediaStreams, subtitleStream); + try { if (!File.Exists(outputPath)) { + var args = _mediaEncoder.GetInputArgument(mediaSource.Path, mediaSource); + + if (subtitleStream.IsExternal) + { + args = _mediaEncoder.GetExternalSubtitleInputArgument(subtitleStream.Path); + } + await ExtractTextSubtitleInternal( - _mediaEncoder.GetInputArgument(mediaSource.Path, mediaSource), + args, subtitleStreamIndex, outputCodec, outputPath, diff --git a/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs b/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs index 4a289b3ab4..8c08ab30ef 100644 --- a/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs +++ b/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs @@ -173,16 +173,30 @@ namespace MediaBrowser.Providers.MediaInfo IReadOnlyList mediaAttachments; ChapterInfo[] chapters; + mediaStreams = new List(); + + // Add external streams before adding the streams from the file to preserve stream IDs on remote videos + await AddExternalSubtitlesAsync(video, mediaStreams, options, cancellationToken).ConfigureAwait(false); + + await AddExternalAudioAsync(video, mediaStreams, options, cancellationToken).ConfigureAwait(false); + + var startIndex = mediaStreams.Count == 0 ? 0 : (mediaStreams.Max(i => i.Index) + 1); + if (mediaInfo != null) { - mediaStreams = mediaInfo.MediaStreams.ToList(); + foreach (var mediaStream in mediaInfo.MediaStreams) + { + mediaStream.Index = startIndex++; + mediaStreams.Add(mediaStream); + } + mediaAttachments = mediaInfo.MediaAttachments; video.TotalBitrate = mediaInfo.Bitrate; // video.FormatName = (mediaInfo.Container ?? string.Empty) // .Replace("matroska", "mkv", StringComparison.OrdinalIgnoreCase); - // For dvd's this may not always be accurate, so don't set the runtime if the item already has one + // For DVDs this may not always be accurate, so don't set the runtime if the item already has one var needToSetRuntime = video.VideoType != VideoType.Dvd || video.RunTimeTicks == null || video.RunTimeTicks.Value == 0; if (needToSetRuntime) @@ -213,15 +227,20 @@ namespace MediaBrowser.Providers.MediaInfo } else { - mediaStreams = new List(); + var currentMediaStreams = video.GetMediaStreams(); + foreach (var mediaStream in currentMediaStreams) + { + if (!mediaStream.IsExternal) + { + mediaStream.Index = startIndex++; + mediaStreams.Add(mediaStream); + } + } + mediaAttachments = Array.Empty(); chapters = Array.Empty(); } - await AddExternalSubtitlesAsync(video, mediaStreams, options, cancellationToken).ConfigureAwait(false); - - await AddExternalAudioAsync(video, mediaStreams, options, cancellationToken).ConfigureAwait(false); - var libraryOptions = _libraryManager.GetLibraryOptions(video); if (mediaInfo != null) @@ -254,7 +273,11 @@ namespace MediaBrowser.Providers.MediaInfo video.HasSubtitles = mediaStreams.Any(i => i.Type == MediaStreamType.Subtitle); _itemRepo.SaveMediaStreams(video.Id, mediaStreams, cancellationToken); - _itemRepo.SaveMediaAttachments(video.Id, mediaAttachments, cancellationToken); + + if (mediaAttachments.Any()) + { + _itemRepo.SaveMediaAttachments(video.Id, mediaAttachments, cancellationToken); + } if (options.MetadataRefreshMode == MetadataRefreshMode.FullRefresh || options.MetadataRefreshMode == MetadataRefreshMode.Default) -- cgit v1.2.3 From 1922ee153e4149530875686212353de578a2932a Mon Sep 17 00:00:00 2001 From: Cody Robibero Date: Sun, 8 May 2022 15:23:58 -0600 Subject: Merge pull request #7716 from Shadowghost/opus-fix Respect limited opus sampling rates when building trancoding command (cherry picked from commit 5a9afb0874b0862f6184478003332219796ee73b) Signed-off-by: crobibero --- MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'MediaBrowser.Controller/MediaEncoding') diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index 1851a9f0c5..54b41a6d25 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -5370,12 +5370,22 @@ namespace MediaBrowser.Controller.MediaEncoding audioTranscodeParams.Add("-ac " + state.OutputAudioChannels.Value.ToString(CultureInfo.InvariantCulture)); } - // opus will fail on 44100 if (!string.Equals(state.OutputAudioCodec, "opus", StringComparison.OrdinalIgnoreCase)) { - if (state.OutputAudioSampleRate.HasValue) + // opus only supports specific sampling rates + var sampleRate = state.OutputAudioSampleRate; + if (sampleRate.HasValue) { - audioTranscodeParams.Add("-ar " + state.OutputAudioSampleRate.Value.ToString(CultureInfo.InvariantCulture)); + var sampleRateValue = sampleRate.Value switch + { + <= 8000 => 8000, + <= 12000 => 12000, + <= 16000 => 16000, + <= 24000 => 24000, + _ => 48000 + }; + + audioTranscodeParams.Add("-ar " + sampleRateValue.ToString(CultureInfo.InvariantCulture)); } } -- cgit v1.2.3 From 8e9c02f4c61a4c73ad11f901e73df275d533d036 Mon Sep 17 00:00:00 2001 From: "Joshua M. Boniface" Date: Sun, 15 May 2022 20:22:24 -0400 Subject: Merge pull request #7736 from jellyfin/fix-swscale-pgs (cherry picked from commit 5da4bcc782c47c5bf64e1cc06eabd07b7f82de33) Signed-off-by: Joshua Boniface --- .../MediaEncoding/EncodingHelper.cs | 36 ++++++++++++++-------- 1 file changed, 24 insertions(+), 12 deletions(-) (limited to 'MediaBrowser.Controller/MediaEncoding') diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index 54b41a6d25..bffd3a1ca6 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -2521,7 +2521,7 @@ namespace MediaBrowser.Controller.MediaEncoding return string.Format( CultureInfo.InvariantCulture, - "scale=trunc(min(max(iw\\,ih*dar)\\,min({0}\\,{1}*dar))/{2})*{2}:trunc(min(max(iw/dar\\,ih)\\,min({0}/dar\\,{1}))/2)*2", + "scale=trunc(min(max(iw\\,ih*a)\\,min({0}\\,{1}*a))/{2})*{2}:trunc(min(max(iw/a\\,ih)\\,min({0}/a\\,{1}))/2)*2", maxWidthParam, maxHeightParam, scaleVal); @@ -2565,7 +2565,7 @@ namespace MediaBrowser.Controller.MediaEncoding return string.Format( CultureInfo.InvariantCulture, - "scale=trunc(min(max(iw\\,ih*dar)\\,{0})/{1})*{1}:trunc(ow/dar/2)*2", + "scale=trunc(min(max(iw\\,ih*a)\\,{0})/{1})*{1}:trunc(ow/a/2)*2", maxWidthParam, scaleVal); } @@ -2577,7 +2577,7 @@ namespace MediaBrowser.Controller.MediaEncoding return string.Format( CultureInfo.InvariantCulture, - "scale=trunc(oh*a/{1})*{1}:min(max(iw/dar\\,ih)\\,{0})", + "scale=trunc(oh*a/{1})*{1}:min(max(iw/a\\,ih)\\,{0})", maxHeightParam, scaleVal); } @@ -2626,7 +2626,7 @@ namespace MediaBrowser.Controller.MediaEncoding } else { - filter = "scale={0}:trunc({0}/dar/2)*2"; + filter = "scale={0}:trunc({0}/a/2)*2"; } } @@ -2780,8 +2780,8 @@ namespace MediaBrowser.Controller.MediaEncoding } else if (hasGraphicalSubs) { - // [0:s]scale=s=1280x720 - var subSwScaleFilter = GetCustomSwScaleFilter(inW, inH, reqW, reqH, reqMaxW, reqMaxH); + // [0:s]scale=expr + var subSwScaleFilter = GetSwScaleFilter(state, options, vidEncoder, inW, inH, threeDFormat, reqW, reqH, reqMaxW, reqMaxH); subFilters.Add(subSwScaleFilter); overlayFilters.Add("overlay=eof_action=endall:shortest=1:repeatlast=0"); } @@ -2967,7 +2967,9 @@ namespace MediaBrowser.Controller.MediaEncoding { if (hasGraphicalSubs) { - var subSwScaleFilter = GetCustomSwScaleFilter(inW, inH, reqW, reqH, reqMaxW, reqMaxH); + var subSwScaleFilter = isSwDecoder + ? GetSwScaleFilter(state, options, vidEncoder, inW, inH, threeDFormat, reqW, reqH, reqMaxW, reqMaxH) + : GetCustomSwScaleFilter(inW, inH, reqW, reqH, reqMaxW, reqMaxH); subFilters.Add(subSwScaleFilter); overlayFilters.Add("overlay=eof_action=endall:shortest=1:repeatlast=0"); } @@ -3165,7 +3167,9 @@ namespace MediaBrowser.Controller.MediaEncoding { if (hasGraphicalSubs) { - var subSwScaleFilter = GetCustomSwScaleFilter(inW, inH, reqW, reqH, reqMaxW, reqMaxH); + var subSwScaleFilter = isSwDecoder + ? GetSwScaleFilter(state, options, vidEncoder, inW, inH, threeDFormat, reqW, reqH, reqMaxW, reqMaxH) + : GetCustomSwScaleFilter(inW, inH, reqW, reqH, reqMaxW, reqMaxH); subFilters.Add(subSwScaleFilter); overlayFilters.Add("overlay=eof_action=endall:shortest=1:repeatlast=0"); } @@ -3411,7 +3415,9 @@ namespace MediaBrowser.Controller.MediaEncoding { if (hasGraphicalSubs) { - var subSwScaleFilter = GetCustomSwScaleFilter(inW, inH, reqW, reqH, reqMaxW, reqMaxH); + var subSwScaleFilter = isSwDecoder + ? GetSwScaleFilter(state, options, vidEncoder, inW, inH, threeDFormat, reqW, reqH, reqMaxW, reqMaxH) + : GetCustomSwScaleFilter(inW, inH, reqW, reqH, reqMaxW, reqMaxH); subFilters.Add(subSwScaleFilter); overlayFilters.Add("overlay=eof_action=endall:shortest=1:repeatlast=0"); } @@ -3620,7 +3626,9 @@ namespace MediaBrowser.Controller.MediaEncoding { if (hasGraphicalSubs) { - var subSwScaleFilter = GetCustomSwScaleFilter(inW, inH, reqW, reqH, reqMaxW, reqMaxH); + var subSwScaleFilter = isSwDecoder + ? GetSwScaleFilter(state, options, vidEncoder, inW, inH, threeDFormat, reqW, reqH, reqMaxW, reqMaxH) + : GetCustomSwScaleFilter(inW, inH, reqW, reqH, reqMaxW, reqMaxH); subFilters.Add(subSwScaleFilter); overlayFilters.Add("overlay=eof_action=pass:shortest=1:repeatlast=0"); } @@ -3867,7 +3875,9 @@ namespace MediaBrowser.Controller.MediaEncoding { if (hasGraphicalSubs) { - var subSwScaleFilter = GetCustomSwScaleFilter(inW, inH, reqW, reqH, reqMaxW, reqMaxH); + var subSwScaleFilter = isSwDecoder + ? GetSwScaleFilter(state, options, vidEncoder, inW, inH, threeDFormat, reqW, reqH, reqMaxW, reqMaxH) + : GetCustomSwScaleFilter(inW, inH, reqW, reqH, reqMaxW, reqMaxH); subFilters.Add(subSwScaleFilter); overlayFilters.Add("overlay=eof_action=pass:shortest=1:repeatlast=0"); @@ -4042,7 +4052,9 @@ namespace MediaBrowser.Controller.MediaEncoding { if (hasGraphicalSubs) { - var subSwScaleFilter = GetCustomSwScaleFilter(inW, inH, reqW, reqH, reqMaxW, reqMaxH); + var subSwScaleFilter = isSwDecoder + ? GetSwScaleFilter(state, options, vidEncoder, inW, inH, threeDFormat, reqW, reqH, reqMaxW, reqMaxH) + : GetCustomSwScaleFilter(inW, inH, reqW, reqH, reqMaxW, reqMaxH); subFilters.Add(subSwScaleFilter); overlayFilters.Add("overlay=eof_action=pass:shortest=1:repeatlast=0"); -- cgit v1.2.3 From c19c7872732e71b6879560de7d0344d0999f7d6b Mon Sep 17 00:00:00 2001 From: Bond-009 Date: Mon, 6 Jun 2022 17:29:39 +0200 Subject: Merge pull request #7828 from nyanmisaka/fix-dovi-tonemap Fix Dolby Vision profile 5 and 8 to SDR HW tone-mapping (cherry picked from commit 8595a979a872c05d0d06f9b87ed1b56c693c267d) Signed-off-by: crobibero --- Jellyfin.Api/Controllers/DynamicHlsController.cs | 21 +++++-- .../MediaEncoding/EncodingHelper.cs | 66 ++++++++++++++-------- MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs | 21 +++++-- MediaBrowser.Model/Entities/MediaStream.cs | 3 +- 4 files changed, 78 insertions(+), 33 deletions(-) (limited to 'MediaBrowser.Controller/MediaEncoding') diff --git a/Jellyfin.Api/Controllers/DynamicHlsController.cs b/Jellyfin.Api/Controllers/DynamicHlsController.cs index 6347b908ca..9173487dd8 100644 --- a/Jellyfin.Api/Controllers/DynamicHlsController.cs +++ b/Jellyfin.Api/Controllers/DynamicHlsController.cs @@ -1711,20 +1711,30 @@ namespace Jellyfin.Api.Controllers return audioTranscodeParams; } + // flac and opus are experimental in mp4 muxer + var strictArgs = string.Empty; + + if (string.Equals(state.ActualOutputAudioCodec, "flac", StringComparison.OrdinalIgnoreCase) + || string.Equals(state.ActualOutputAudioCodec, "opus", StringComparison.OrdinalIgnoreCase)) + { + strictArgs = " -strict -2"; + } + if (EncodingHelper.IsCopyCodec(audioCodec)) { var videoCodec = _encodingHelper.GetVideoEncoder(state, _encodingOptions); var bitStreamArgs = EncodingHelper.GetAudioBitStreamArguments(state, state.Request.SegmentContainer, state.MediaSource.Container); + var copyArgs = "-codec:a:0 copy" + bitStreamArgs + strictArgs; if (EncodingHelper.IsCopyCodec(videoCodec) && state.EnableBreakOnNonKeyFrames(videoCodec)) { - return "-codec:a:0 copy -strict -2 -copypriorss:a:0 0" + bitStreamArgs; + return copyArgs + " -copypriorss:a:0 0"; } - return "-codec:a:0 copy -strict -2" + bitStreamArgs; + return copyArgs; } - var args = "-codec:a:0 " + audioCodec; + var args = "-codec:a:0 " + audioCodec + strictArgs; var channels = state.OutputAudioChannels; @@ -1779,11 +1789,12 @@ namespace Jellyfin.Api.Controllers || string.Equals(codec, "hevc", StringComparison.OrdinalIgnoreCase)) { if (EncodingHelper.IsCopyCodec(codec) - && (string.Equals(state.VideoStream.CodecTag, "dvh1", StringComparison.OrdinalIgnoreCase) + && (string.Equals(state.VideoStream.CodecTag, "dovi", StringComparison.OrdinalIgnoreCase) + || string.Equals(state.VideoStream.CodecTag, "dvh1", StringComparison.OrdinalIgnoreCase) || string.Equals(state.VideoStream.CodecTag, "dvhe", StringComparison.OrdinalIgnoreCase))) { // Prefer dvh1 to dvhe - args += " -tag:v:0 dvh1"; + args += " -tag:v:0 dvh1 -strict -2"; } else { diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index bffd3a1ca6..eb344b5287 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -13,11 +13,13 @@ using System.Threading; using Jellyfin.Data.Enums; using Jellyfin.Extensions; using MediaBrowser.Common.Configuration; +using MediaBrowser.Controller.Extensions; using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Dlna; using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; using MediaBrowser.Model.MediaInfo; +using Microsoft.Extensions.Configuration; namespace MediaBrowser.Controller.MediaEncoding { @@ -32,6 +34,7 @@ namespace MediaBrowser.Controller.MediaEncoding private readonly IApplicationPaths _appPaths; private readonly IMediaEncoder _mediaEncoder; private readonly ISubtitleEncoder _subtitleEncoder; + private readonly IConfiguration _config; private static readonly string[] _videoProfilesH264 = new[] { @@ -54,11 +57,13 @@ namespace MediaBrowser.Controller.MediaEncoding public EncodingHelper( IApplicationPaths appPaths, IMediaEncoder mediaEncoder, - ISubtitleEncoder subtitleEncoder) + ISubtitleEncoder subtitleEncoder, + IConfiguration config) { _appPaths = appPaths; _mediaEncoder = mediaEncoder; _subtitleEncoder = subtitleEncoder; + _config = config; } public string GetH264Encoder(EncodingJobInfo state, EncodingOptions encodingOptions) @@ -144,15 +149,28 @@ namespace MediaBrowser.Controller.MediaEncoding private bool IsHwTonemapAvailable(EncodingJobInfo state, EncodingOptions options) { - if (state.VideoStream == null) + if (state.VideoStream == null + || !options.EnableTonemapping + || GetVideoColorBitDepth(state) != 10) { return false; } - return options.EnableTonemapping - && (string.Equals(state.VideoStream.ColorTransfer, "smpte2084", StringComparison.OrdinalIgnoreCase) - || string.Equals(state.VideoStream.ColorTransfer, "arib-std-b67", StringComparison.OrdinalIgnoreCase)) - && GetVideoColorBitDepth(state) == 10; + if (string.Equals(state.VideoStream.CodecTag, "dovi", StringComparison.OrdinalIgnoreCase) + || string.Equals(state.VideoStream.CodecTag, "dvh1", StringComparison.OrdinalIgnoreCase) + || string.Equals(state.VideoStream.CodecTag, "dvhe", StringComparison.OrdinalIgnoreCase)) + { + // Only native SW decoder and HW accelerator can parse dovi rpu. + var vidDecoder = GetHardwareVideoDecoder(state, options) ?? string.Empty; + var isSwDecoder = string.IsNullOrEmpty(vidDecoder); + var isNvdecDecoder = vidDecoder.Contains("cuda", StringComparison.OrdinalIgnoreCase); + var isVaapiDecoder = vidDecoder.Contains("vaapi", StringComparison.OrdinalIgnoreCase); + var isD3d11vaDecoder = vidDecoder.Contains("d3d11va", StringComparison.OrdinalIgnoreCase); + return isSwDecoder || isNvdecDecoder || isVaapiDecoder || isD3d11vaDecoder; + } + + return string.Equals(state.VideoStream.ColorTransfer, "smpte2084", StringComparison.OrdinalIgnoreCase) + || string.Equals(state.VideoStream.ColorTransfer, "arib-std-b67", StringComparison.OrdinalIgnoreCase); } private bool IsVaapiVppTonemapAvailable(EncodingJobInfo state, EncodingOptions options) @@ -516,8 +534,7 @@ namespace MediaBrowser.Controller.MediaEncoding if (string.Equals(codec, "flac", StringComparison.OrdinalIgnoreCase)) { - // flac is experimental in mp4 muxer - return "flac -strict -2"; + return "flac"; } return codec.ToLowerInvariant(); @@ -1024,7 +1041,8 @@ namespace MediaBrowser.Controller.MediaEncoding if (string.Equals(videoCodec, "h264_amf", StringComparison.OrdinalIgnoreCase) || string.Equals(videoCodec, "hevc_amf", StringComparison.OrdinalIgnoreCase)) { - return FormattableString.Invariant($" -qmin 18 -qmax 32 -b:v {bitrate} -maxrate {bitrate} -bufsize {bufsize}"); + // Override the too high default qmin 18 in transcoding preset + return FormattableString.Invariant($" -rc cbr -qmin 0 -qmax 32 -b:v {bitrate} -maxrate {bitrate} -bufsize {bufsize}"); } if (string.Equals(videoCodec, "h264_vaapi", StringComparison.OrdinalIgnoreCase) @@ -1222,10 +1240,9 @@ namespace MediaBrowser.Controller.MediaEncoding // Example: we encoded half of desired length, then codec detected // scene cut and inserted a keyframe; next forced keyframe would // be created outside of segment, which breaks seeking. - // -sc_threshold 0 is used to prevent the hardware encoder from post processing to break the set keyframe. gopArg = string.Format( CultureInfo.InvariantCulture, - " -g:v:0 {0} -keyint_min:v:0 {0} -sc_threshold:v:0 0", + " -g:v:0 {0} -keyint_min:v:0 {0}", Math.Ceiling(segmentLength * framerate.Value)); } @@ -1245,6 +1262,12 @@ namespace MediaBrowser.Controller.MediaEncoding || string.Equals(codec, "hevc_vaapi", StringComparison.OrdinalIgnoreCase)) { args += keyFrameArg; + + // prevent the libx264 from post processing to break the set keyframe. + if (string.Equals(codec, "libx264", StringComparison.OrdinalIgnoreCase)) + { + args += " -sc_threshold:v:0 0"; + } } else { @@ -4865,21 +4888,20 @@ namespace MediaBrowser.Controller.MediaEncoding public string GetInputModifier(EncodingJobInfo state, EncodingOptions encodingOptions, string segmentContainer) { var inputModifier = string.Empty; - var probeSizeArgument = string.Empty; + var analyzeDurationArgument = string.Empty; - string analyzeDurationArgument; - if (state.MediaSource.AnalyzeDurationMs.HasValue) - { - analyzeDurationArgument = "-analyzeduration " + (state.MediaSource.AnalyzeDurationMs.Value * 1000).ToString(CultureInfo.InvariantCulture); - } - else + // Apply -analyzeduration as per the environment variable, + // otherwise ffmpeg will break on certain files due to default value is 0. + // The default value of -probesize is more than enough, so leave it as is. + var ffmpegAnalyzeDuration = _config.GetFFmpegAnalyzeDuration() ?? string.Empty; + + if (!string.IsNullOrEmpty(ffmpegAnalyzeDuration)) { - analyzeDurationArgument = string.Empty; + analyzeDurationArgument = "-analyzeduration " + ffmpegAnalyzeDuration; } - - if (!string.IsNullOrEmpty(probeSizeArgument)) + else if (state.MediaSource.AnalyzeDurationMs.HasValue) { - inputModifier += " " + probeSizeArgument; + analyzeDurationArgument = "-analyzeduration " + (state.MediaSource.AnalyzeDurationMs.Value * 1000).ToString(CultureInfo.InvariantCulture); } if (!string.IsNullOrEmpty(analyzeDurationArgument)) diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs index 1bac4b1875..77b97c9b48 100644 --- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs @@ -16,6 +16,7 @@ using MediaBrowser.Common; using MediaBrowser.Common.Configuration; using MediaBrowser.Common.Extensions; using MediaBrowser.Controller.Configuration; +using MediaBrowser.Controller.Extensions; using MediaBrowser.Controller.MediaEncoding; using MediaBrowser.MediaEncoding.Probing; using MediaBrowser.Model.Dlna; @@ -49,6 +50,7 @@ namespace MediaBrowser.MediaEncoding.Encoder private readonly IServerConfigurationManager _configurationManager; private readonly IFileSystem _fileSystem; private readonly ILocalizationManager _localization; + private readonly IConfiguration _config; private readonly string _startupOptionFFmpegPath; private readonly SemaphoreSlim _thumbnailResourcePool = new SemaphoreSlim(2, 2); @@ -85,6 +87,7 @@ namespace MediaBrowser.MediaEncoding.Encoder _configurationManager = configurationManager; _fileSystem = fileSystem; _localization = localization; + _config = config; _startupOptionFFmpegPath = config.GetValue(Controller.Extensions.ConfigurationExtensions.FfmpegPathKey) ?? string.Empty; _jsonSerializerOptions = JsonDefaults.Options; } @@ -371,8 +374,13 @@ namespace MediaBrowser.MediaEncoding.Encoder var inputFile = request.MediaSource.Path; string analyzeDuration = string.Empty; + string ffmpegAnalyzeDuration = _config.GetFFmpegAnalyzeDuration() ?? string.Empty; - if (request.MediaSource.AnalyzeDurationMs > 0) + if (!string.IsNullOrEmpty(ffmpegAnalyzeDuration)) + { + analyzeDuration = "-analyzeduration " + ffmpegAnalyzeDuration; + } + else if (request.MediaSource.AnalyzeDurationMs > 0) { analyzeDuration = "-analyzeduration " + (request.MediaSource.AnalyzeDurationMs * 1000).ToString(); @@ -629,10 +637,15 @@ namespace MediaBrowser.MediaEncoding.Encoder filters.Add("thumbnail=n=" + (useLargerBatchSize ? "50" : "24")); } - // Use SW tonemap on HDR video stream only when the zscale filter is available. - var enableHdrExtraction = string.Equals(videoStream?.VideoRange, "HDR", StringComparison.OrdinalIgnoreCase) && SupportsFilter("zscale"); - if (enableHdrExtraction) + // Use SW tonemap on HDR10/HLG video stream only when the zscale filter is available. + var enableHdrExtraction = false; + + if ((string.Equals(videoStream?.ColorTransfer, "smpte2084", StringComparison.OrdinalIgnoreCase) + || string.Equals(videoStream?.ColorTransfer, "arib-std-b67", StringComparison.OrdinalIgnoreCase)) + && SupportsFilter("zscale")) { + enableHdrExtraction = true; + filters.Add("zscale=t=linear:npl=100,format=gbrpf32le,zscale=p=bt709,tonemap=tonemap=hable:desat=0:peak=100,zscale=t=bt709:m=bt709,format=yuv420p"); } diff --git a/MediaBrowser.Model/Entities/MediaStream.cs b/MediaBrowser.Model/Entities/MediaStream.cs index 4742d21e9e..96b48ca52a 100644 --- a/MediaBrowser.Model/Entities/MediaStream.cs +++ b/MediaBrowser.Model/Entities/MediaStream.cs @@ -121,8 +121,7 @@ namespace MediaBrowser.Model.Entities var codecTag = CodecTag; - if (string.Equals(codecTag, "dva1", StringComparison.OrdinalIgnoreCase) - || string.Equals(codecTag, "dvav", StringComparison.OrdinalIgnoreCase) + if (string.Equals(codecTag, "dovi", StringComparison.OrdinalIgnoreCase) || string.Equals(codecTag, "dvh1", StringComparison.OrdinalIgnoreCase) || string.Equals(codecTag, "dvhe", StringComparison.OrdinalIgnoreCase) || string.Equals(codecTag, "dav1", StringComparison.OrdinalIgnoreCase)) -- cgit v1.2.3 From db8047136df68b6fd5e05acd8837bc47d97c7fd9 Mon Sep 17 00:00:00 2001 From: Cody Robibero Date: Tue, 14 Jun 2022 08:18:22 -0600 Subject: Merge pull request #7924 from jellyfin/improve-swdec-amf-tonemap (cherry picked from commit 288808009813fea527c9b06c3598c49eff3eace0) Signed-off-by: crobibero --- .../MediaEncoding/EncodingHelper.cs | 36 ++++++++++++---------- 1 file changed, 19 insertions(+), 17 deletions(-) (limited to 'MediaBrowser.Controller/MediaEncoding') diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index eb344b5287..07a20baa0b 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -2902,7 +2902,7 @@ namespace MediaBrowser.Controller.MediaEncoding // sw => hw if (doCuTonemap) { - mainFilters.Add("hwupload"); + mainFilters.Add("hwupload=derive_device=cuda"); } } @@ -2982,7 +2982,7 @@ namespace MediaBrowser.Controller.MediaEncoding subFilters.Add(subTextSubtitlesFilter); } - subFilters.Add("hwupload"); + subFilters.Add("hwupload=derive_device=cuda"); overlayFilters.Add("overlay_cuda=eof_action=endall:shortest=1:repeatlast=0"); } } @@ -3094,7 +3094,9 @@ namespace MediaBrowser.Controller.MediaEncoding // sw => hw if (doOclTonemap) { - mainFilters.Add("hwupload"); + mainFilters.Add("hwupload=derive_device=d3d11va:extra_hw_frames=16"); + mainFilters.Add("format=d3d11"); + mainFilters.Add("hwmap=derive_device=opencl"); } } @@ -3121,7 +3123,7 @@ namespace MediaBrowser.Controller.MediaEncoding var memoryOutput = false; var isUploadForOclTonemap = isSwDecoder && doOclTonemap; - if ((isD3d11vaDecoder && isSwEncoder) || isUploadForOclTonemap) + if (isD3d11vaDecoder && isSwEncoder) { memoryOutput = true; @@ -3133,7 +3135,7 @@ namespace MediaBrowser.Controller.MediaEncoding } // OUTPUT yuv420p surface - if (isSwDecoder && isAmfEncoder) + if (isSwDecoder && isAmfEncoder && !isUploadForOclTonemap) { memoryOutput = true; } @@ -3148,7 +3150,7 @@ namespace MediaBrowser.Controller.MediaEncoding } } - if (isDxInDxOut && !hasSubs) + if ((isDxInDxOut || isUploadForOclTonemap) && !hasSubs) { // OUTPUT d3d11(nv12) surface(vram) // reverse-mapping via d3d11-opencl interop. @@ -3159,7 +3161,7 @@ namespace MediaBrowser.Controller.MediaEncoding /* Make sub and overlay filters for subtitle stream */ var subFilters = new List(); var overlayFilters = new List(); - if (isDxInDxOut) + if (isDxInDxOut || isUploadForOclTonemap) { if (hasSubs) { @@ -3180,7 +3182,7 @@ namespace MediaBrowser.Controller.MediaEncoding subFilters.Add(subTextSubtitlesFilter); } - subFilters.Add("hwupload"); + subFilters.Add("hwupload=derive_device=opencl"); overlayFilters.Add("overlay_opencl=eof_action=endall:shortest=1:repeatlast=0"); overlayFilters.Add("hwmap=derive_device=d3d11va:reverse=1"); overlayFilters.Add("format=d3d11"); @@ -3314,7 +3316,7 @@ namespace MediaBrowser.Controller.MediaEncoding // sw => hw if (doOclTonemap) { - mainFilters.Add("hwupload"); + mainFilters.Add("hwupload=derive_device=opencl"); } } else if (isD3d11vaDecoder || isQsvDecoder) @@ -3421,7 +3423,7 @@ namespace MediaBrowser.Controller.MediaEncoding // qsv requires a fixed pool size. // default to 64 otherwise it will fail on certain iGPU. - subFilters.Add("hwupload=extra_hw_frames=64"); + subFilters.Add("hwupload=derive_device=qsv:extra_hw_frames=64"); var (overlayW, overlayH) = GetFixedOutputSize(inW, inH, reqW, reqH, reqMaxW, reqMaxH); var overlaySize = (overlayW.HasValue && overlayH.HasValue) @@ -3511,7 +3513,7 @@ namespace MediaBrowser.Controller.MediaEncoding // sw => hw if (doOclTonemap) { - mainFilters.Add("hwupload"); + mainFilters.Add("hwupload=derive_device=opencl"); } } else if (isVaapiDecoder || isQsvDecoder) @@ -3632,7 +3634,7 @@ namespace MediaBrowser.Controller.MediaEncoding // qsv requires a fixed pool size. // default to 64 otherwise it will fail on certain iGPU. - subFilters.Add("hwupload=extra_hw_frames=64"); + subFilters.Add("hwupload=derive_device=qsv:extra_hw_frames=64"); var (overlayW, overlayH) = GetFixedOutputSize(inW, inH, reqW, reqH, reqMaxW, reqMaxH); var overlaySize = (overlayW.HasValue && overlayH.HasValue) @@ -3695,7 +3697,7 @@ namespace MediaBrowser.Controller.MediaEncoding var newfilters = new List(); var noOverlay = swFilterChain.OverlayFilters.Count == 0; newfilters.AddRange(noOverlay ? swFilterChain.MainFilters : swFilterChain.OverlayFilters); - newfilters.Add("hwupload"); + newfilters.Add("hwupload=derive_device=vaapi"); var mainFilters = noOverlay ? newfilters : swFilterChain.MainFilters; var overlayFilters = noOverlay ? swFilterChain.OverlayFilters : newfilters; @@ -3776,7 +3778,7 @@ namespace MediaBrowser.Controller.MediaEncoding // sw => hw if (doOclTonemap) { - mainFilters.Add("hwupload"); + mainFilters.Add("hwupload=derive_device=opencl"); } } else if (isVaapiDecoder) @@ -3881,7 +3883,7 @@ namespace MediaBrowser.Controller.MediaEncoding subFilters.Add(subTextSubtitlesFilter); } - subFilters.Add("hwupload"); + subFilters.Add("hwupload=derive_device=vaapi"); var (overlayW, overlayH) = GetFixedOutputSize(inW, inH, reqW, reqH, reqMaxW, reqMaxH); var overlaySize = (overlayW.HasValue && overlayH.HasValue) @@ -3972,7 +3974,7 @@ namespace MediaBrowser.Controller.MediaEncoding // sw => hw if (doOclTonemap) { - mainFilters.Add("hwupload"); + mainFilters.Add("hwupload=derive_device=opencl"); } } else if (isVaapiDecoder) @@ -4002,7 +4004,7 @@ namespace MediaBrowser.Controller.MediaEncoding { mainFilters.Add("hwdownload"); mainFilters.Add("format=p010le"); - mainFilters.Add("hwupload"); + mainFilters.Add("hwupload=derive_device=opencl"); } } -- cgit v1.2.3 From 9c5d30c2174ad1e31b3143de164d1557adb32700 Mon Sep 17 00:00:00 2001 From: Cody Robibero Date: Mon, 13 Jun 2022 16:27:45 -0600 Subject: Merge pull request #7925 from nyanmisaka/remove-mpeg4-amf (cherry picked from commit b295b0478c3bb8dd1b9d9ab7f15e7326c3eda2fe) Signed-off-by: crobibero --- MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs | 5 ----- 1 file changed, 5 deletions(-) (limited to 'MediaBrowser.Controller/MediaEncoding') diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index 07a20baa0b..1755b872f4 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -4686,11 +4686,6 @@ namespace MediaBrowser.Controller.MediaEncoding { return GetHwaccelType(state, options, "vc1", bitDepth, hwSurface); } - - if (string.Equals("mpeg4", videoStream.Codec, StringComparison.OrdinalIgnoreCase)) - { - return GetHwaccelType(state, options, "mpeg4", bitDepth, hwSurface); - } } if (is8_10bitSwFormatsAmf) -- cgit v1.2.3 From a168040cc8c0067c35801ec0469af80729c03487 Mon Sep 17 00:00:00 2001 From: Cody Robibero Date: Wed, 15 Jun 2022 15:27:07 -0600 Subject: Merge pull request #7941 from jellyfin/fix-overflow (cherry picked from commit fd4ffc6ba3317987856629088b759db8c1128ecd) Signed-off-by: Joshua Boniface --- Jellyfin.Api/Helpers/DynamicHlsHelper.cs | 2 +- MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs | 10 +++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) (limited to 'MediaBrowser.Controller/MediaEncoding') diff --git a/Jellyfin.Api/Helpers/DynamicHlsHelper.cs b/Jellyfin.Api/Helpers/DynamicHlsHelper.cs index 02af2e4353..83c9141a93 100644 --- a/Jellyfin.Api/Helpers/DynamicHlsHelper.cs +++ b/Jellyfin.Api/Helpers/DynamicHlsHelper.cs @@ -216,7 +216,7 @@ namespace Jellyfin.Api.Helpers var sdrVideoUrl = ReplaceProfile(playlistUrl, "hevc", string.Join(',', requestedVideoProfiles), "main"); sdrVideoUrl += "&AllowVideoStreamCopy=false"; - var sdrOutputVideoBitrate = _encodingHelper.GetVideoBitrateParamValue(state.VideoRequest, state.VideoStream, state.OutputVideoCodec) ?? 0; + var sdrOutputVideoBitrate = _encodingHelper.GetVideoBitrateParamValue(state.VideoRequest, state.VideoStream, state.OutputVideoCodec); var sdrOutputAudioBitrate = _encodingHelper.GetAudioBitrateParam(state.VideoRequest, state.AudioStream) ?? 0; var sdrTotalBitrate = sdrOutputAudioBitrate + sdrOutputVideoBitrate; diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index 1755b872f4..04778e6993 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -1893,7 +1893,7 @@ namespace MediaBrowser.Controller.MediaEncoding return request.EnableAutoStreamCopy; } - public int? GetVideoBitrateParamValue(BaseEncodingJobOptions request, MediaStream videoStream, string outputVideoCodec) + public int GetVideoBitrateParamValue(BaseEncodingJobOptions request, MediaStream videoStream, string outputVideoCodec) { var bitrate = request.VideoBitRate; @@ -1925,7 +1925,8 @@ namespace MediaBrowser.Controller.MediaEncoding } } - return bitrate; + // Cap the max target bitrate to intMax/2 to satisify the bufsize=bitrate*2. + return Math.Min(bitrate ?? 0, int.MaxValue / 2); } private int GetMinBitrate(int sourceBitrate, int requestedBitrate) @@ -2272,7 +2273,10 @@ namespace MediaBrowser.Controller.MediaEncoding int audioStreamIndex = FindIndex(state.MediaSource.MediaStreams, state.AudioStream); if (state.AudioStream.IsExternal) { - bool hasExternalGraphicsSubs = state.SubtitleStream != null && state.SubtitleStream.IsExternal && !state.SubtitleStream.IsTextSubtitleStream; + bool hasExternalGraphicsSubs = state.SubtitleStream != null + && state.SubtitleDeliveryMethod == SubtitleDeliveryMethod.Encode + && state.SubtitleStream.IsExternal + && !state.SubtitleStream.IsTextSubtitleStream; int externalAudioMapIndex = hasExternalGraphicsSubs ? 2 : 1; args += string.Format( -- cgit v1.2.3 From 38102499cb21cae8cd177ebc6b98037b3bc3f620 Mon Sep 17 00:00:00 2001 From: Cody Robibero Date: Fri, 17 Jun 2022 10:01:06 -0600 Subject: Merge pull request #7947 from nyanmisaka/video-range-condition (cherry picked from commit f1d56aa5cef4c60021e0b29c5d9fb3adf384fda7) Signed-off-by: Joshua Boniface --- Emby.Dlna/Didl/DidlBuilder.cs | 2 + Emby.Dlna/PlayTo/PlayToController.cs | 1 + Jellyfin.Api/Helpers/StreamingHelpers.cs | 3 +- .../MediaEncoding/BaseEncodingJobOptions.cs | 6 ++ .../MediaEncoding/EncodingHelper.cs | 14 +++++ .../MediaEncoding/EncodingJobInfo.cs | 42 +++++++++++++ MediaBrowser.Model/Dlna/ConditionProcessor.cs | 3 + MediaBrowser.Model/Dlna/ContentFeatureBuilder.cs | 2 + MediaBrowser.Model/Dlna/DeviceProfile.cs | 4 +- MediaBrowser.Model/Dlna/ProfileConditionValue.cs | 3 +- MediaBrowser.Model/Dlna/StreamBuilder.cs | 45 ++++++++++++-- MediaBrowser.Model/Dlna/StreamInfo.cs | 23 +++++++ MediaBrowser.Model/Entities/MediaStream.cs | 71 +++++++++++++++------- MediaBrowser.Model/Session/TranscodeReason.cs | 1 + 14 files changed, 190 insertions(+), 30 deletions(-) (limited to 'MediaBrowser.Controller/MediaEncoding') diff --git a/Emby.Dlna/Didl/DidlBuilder.cs b/Emby.Dlna/Didl/DidlBuilder.cs index 6ab5843c15..df6539a5a6 100644 --- a/Emby.Dlna/Didl/DidlBuilder.cs +++ b/Emby.Dlna/Didl/DidlBuilder.cs @@ -221,6 +221,7 @@ namespace Emby.Dlna.Didl streamInfo.IsDirectStream, streamInfo.RunTimeTicks ?? 0, streamInfo.TargetVideoProfile, + streamInfo.TargetVideoRangeType, streamInfo.TargetVideoLevel, streamInfo.TargetFramerate ?? 0, streamInfo.TargetPacketLength, @@ -376,6 +377,7 @@ namespace Emby.Dlna.Didl targetHeight, streamInfo.TargetVideoBitDepth, streamInfo.TargetVideoProfile, + streamInfo.TargetVideoRangeType, streamInfo.TargetVideoLevel, streamInfo.TargetFramerate ?? 0, streamInfo.TargetPacketLength, diff --git a/Emby.Dlna/PlayTo/PlayToController.cs b/Emby.Dlna/PlayTo/PlayToController.cs index e27a8975b7..b73ce00b6f 100644 --- a/Emby.Dlna/PlayTo/PlayToController.cs +++ b/Emby.Dlna/PlayTo/PlayToController.cs @@ -561,6 +561,7 @@ namespace Emby.Dlna.PlayTo streamInfo.IsDirectStream, streamInfo.RunTimeTicks ?? 0, streamInfo.TargetVideoProfile, + streamInfo.TargetVideoRangeType, streamInfo.TargetVideoLevel, streamInfo.TargetFramerate ?? 0, streamInfo.TargetPacketLength, diff --git a/Jellyfin.Api/Helpers/StreamingHelpers.cs b/Jellyfin.Api/Helpers/StreamingHelpers.cs index 34dab75b82..c96ca87a56 100644 --- a/Jellyfin.Api/Helpers/StreamingHelpers.cs +++ b/Jellyfin.Api/Helpers/StreamingHelpers.cs @@ -312,7 +312,7 @@ namespace Jellyfin.Api.Helpers responseHeaders.Add( "contentFeatures.dlna.org", - ContentFeatureBuilder.BuildVideoHeader(profile, state.OutputContainer, videoCodec, audioCodec, state.OutputWidth, state.OutputHeight, state.TargetVideoBitDepth, state.OutputVideoBitrate, state.TargetTimestamp, isStaticallyStreamed, state.RunTimeTicks, state.TargetVideoProfile, state.TargetVideoLevel, state.TargetFramerate, state.TargetPacketLength, state.TranscodeSeekInfo, state.IsTargetAnamorphic, state.IsTargetInterlaced, state.TargetRefFrames, state.TargetVideoStreamCount, state.TargetAudioStreamCount, state.TargetVideoCodecTag, state.IsTargetAVC).FirstOrDefault() ?? string.Empty); + ContentFeatureBuilder.BuildVideoHeader(profile, state.OutputContainer, videoCodec, audioCodec, state.OutputWidth, state.OutputHeight, state.TargetVideoBitDepth, state.OutputVideoBitrate, state.TargetTimestamp, isStaticallyStreamed, state.RunTimeTicks, state.TargetVideoProfile, state.TargetVideoRangeType, state.TargetVideoLevel, state.TargetFramerate, state.TargetPacketLength, state.TranscodeSeekInfo, state.IsTargetAnamorphic, state.IsTargetInterlaced, state.TargetRefFrames, state.TargetVideoStreamCount, state.TargetAudioStreamCount, state.TargetVideoCodecTag, state.IsTargetAVC).FirstOrDefault() ?? string.Empty); } } @@ -533,6 +533,7 @@ namespace Jellyfin.Api.Helpers state.TargetVideoBitDepth, state.OutputVideoBitrate, state.TargetVideoProfile, + state.TargetVideoRangeType, state.TargetVideoLevel, state.TargetFramerate, state.TargetPacketLength, diff --git a/MediaBrowser.Controller/MediaEncoding/BaseEncodingJobOptions.cs b/MediaBrowser.Controller/MediaEncoding/BaseEncodingJobOptions.cs index 462585ce35..fb4e7bd1f5 100644 --- a/MediaBrowser.Controller/MediaEncoding/BaseEncodingJobOptions.cs +++ b/MediaBrowser.Controller/MediaEncoding/BaseEncodingJobOptions.cs @@ -75,6 +75,12 @@ namespace MediaBrowser.Controller.MediaEncoding /// The profile. public string Profile { get; set; } + /// + /// Gets or sets the video range type. + /// + /// The video range type. + public string VideoRangeType { get; set; } + /// /// Gets or sets the level. /// diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index 04778e6993..d5b0aca3c3 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -1753,6 +1753,20 @@ namespace MediaBrowser.Controller.MediaEncoding } } + var requestedRangeTypes = state.GetRequestedRangeTypes(videoStream.Codec); + if (requestedProfiles.Length > 0) + { + if (string.IsNullOrEmpty(videoStream.VideoRangeType)) + { + return false; + } + + if (!requestedRangeTypes.Contains(videoStream.VideoRangeType, StringComparison.OrdinalIgnoreCase)) + { + return false; + } + } + // Video width must fall within requested value if (request.MaxWidth.HasValue && (!videoStream.Width.HasValue || videoStream.Width.Value > request.MaxWidth.Value)) diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs b/MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs index 0824590f22..491662861f 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs @@ -366,6 +366,28 @@ namespace MediaBrowser.Controller.MediaEncoding } } + /// + /// Gets the target video range type. + /// + public string TargetVideoRangeType + { + get + { + if (BaseRequest.Static || EncodingHelper.IsCopyCodec(OutputVideoCodec)) + { + return VideoStream?.VideoRangeType; + } + + var requestedRangeType = GetRequestedRangeTypes(ActualOutputVideoCodec).FirstOrDefault(); + if (!string.IsNullOrEmpty(requestedRangeType)) + { + return requestedRangeType; + } + + return null; + } + } + public string TargetVideoCodecTag { get @@ -579,6 +601,26 @@ namespace MediaBrowser.Controller.MediaEncoding return Array.Empty(); } + public string[] GetRequestedRangeTypes(string codec) + { + if (!string.IsNullOrEmpty(BaseRequest.VideoRangeType)) + { + return BaseRequest.VideoRangeType.Split(new[] { '|', ',' }, StringSplitOptions.RemoveEmptyEntries); + } + + if (!string.IsNullOrEmpty(codec)) + { + var rangetype = BaseRequest.GetOption(codec, "rangetype"); + + if (!string.IsNullOrEmpty(rangetype)) + { + return rangetype.Split(new[] { '|', ',' }, StringSplitOptions.RemoveEmptyEntries); + } + } + + return Array.Empty(); + } + public string GetRequestedLevel(string codec) { if (!string.IsNullOrEmpty(BaseRequest.Level)) diff --git a/MediaBrowser.Model/Dlna/ConditionProcessor.cs b/MediaBrowser.Model/Dlna/ConditionProcessor.cs index 8d03b4c0b3..5734224167 100644 --- a/MediaBrowser.Model/Dlna/ConditionProcessor.cs +++ b/MediaBrowser.Model/Dlna/ConditionProcessor.cs @@ -16,6 +16,7 @@ namespace MediaBrowser.Model.Dlna int? videoBitDepth, int? videoBitrate, string? videoProfile, + string? videoRangeType, double? videoLevel, float? videoFramerate, int? packetLength, @@ -42,6 +43,8 @@ namespace MediaBrowser.Model.Dlna return IsConditionSatisfied(condition, videoLevel); case ProfileConditionValue.VideoProfile: return IsConditionSatisfied(condition, videoProfile); + case ProfileConditionValue.VideoRangeType: + return IsConditionSatisfied(condition, videoRangeType); case ProfileConditionValue.VideoCodecTag: return IsConditionSatisfied(condition, videoCodecTag); case ProfileConditionValue.PacketLength: diff --git a/MediaBrowser.Model/Dlna/ContentFeatureBuilder.cs b/MediaBrowser.Model/Dlna/ContentFeatureBuilder.cs index 6e129246b0..47c36494bd 100644 --- a/MediaBrowser.Model/Dlna/ContentFeatureBuilder.cs +++ b/MediaBrowser.Model/Dlna/ContentFeatureBuilder.cs @@ -128,6 +128,7 @@ namespace MediaBrowser.Model.Dlna bool isDirectStream, long? runtimeTicks, string videoProfile, + string videoRangeType, double? videoLevel, float? videoFramerate, int? packetLength, @@ -176,6 +177,7 @@ namespace MediaBrowser.Model.Dlna bitDepth, videoBitrate, videoProfile, + videoRangeType, videoLevel, videoFramerate, packetLength, diff --git a/MediaBrowser.Model/Dlna/DeviceProfile.cs b/MediaBrowser.Model/Dlna/DeviceProfile.cs index 6170ff5bd6..79ae951708 100644 --- a/MediaBrowser.Model/Dlna/DeviceProfile.cs +++ b/MediaBrowser.Model/Dlna/DeviceProfile.cs @@ -423,6 +423,7 @@ namespace MediaBrowser.Model.Dlna /// The bit depth. /// The video bitrate. /// The video profile. + /// The video range type. /// The video level. /// The video framerate. /// The packet length. @@ -444,6 +445,7 @@ namespace MediaBrowser.Model.Dlna int? bitDepth, int? videoBitrate, string videoProfile, + string videoRangeType, double? videoLevel, float? videoFramerate, int? packetLength, @@ -483,7 +485,7 @@ namespace MediaBrowser.Model.Dlna var anyOff = false; foreach (ProfileCondition c in i.Conditions) { - if (!ConditionProcessor.IsVideoConditionSatisfied(GetModelProfileCondition(c), width, height, bitDepth, videoBitrate, videoProfile, videoLevel, videoFramerate, packetLength, timestamp, isAnamorphic, isInterlaced, refFrames, numVideoStreams, numAudioStreams, videoCodecTag, isAvc)) + if (!ConditionProcessor.IsVideoConditionSatisfied(GetModelProfileCondition(c), width, height, bitDepth, videoBitrate, videoProfile, videoRangeType, videoLevel, videoFramerate, packetLength, timestamp, isAnamorphic, isInterlaced, refFrames, numVideoStreams, numAudioStreams, videoCodecTag, isAvc)) { anyOff = true; break; diff --git a/MediaBrowser.Model/Dlna/ProfileConditionValue.cs b/MediaBrowser.Model/Dlna/ProfileConditionValue.cs index eb81fde751..a32433e185 100644 --- a/MediaBrowser.Model/Dlna/ProfileConditionValue.cs +++ b/MediaBrowser.Model/Dlna/ProfileConditionValue.cs @@ -26,6 +26,7 @@ namespace MediaBrowser.Model.Dlna IsAvc = 20, IsInterlaced = 21, AudioSampleRate = 22, - AudioBitDepth = 23 + AudioBitDepth = 23, + VideoRangeType = 24 } } diff --git a/MediaBrowser.Model/Dlna/StreamBuilder.cs b/MediaBrowser.Model/Dlna/StreamBuilder.cs index fe9ff2ebe8..fdb9fd5d54 100644 --- a/MediaBrowser.Model/Dlna/StreamBuilder.cs +++ b/MediaBrowser.Model/Dlna/StreamBuilder.cs @@ -221,6 +221,9 @@ namespace MediaBrowser.Model.Dlna case ProfileConditionValue.VideoProfile: return TranscodeReason.VideoProfileNotSupported; + case ProfileConditionValue.VideoRangeType: + return TranscodeReason.VideoRangeTypeNotSupported; + case ProfileConditionValue.VideoTimestamp: // TODO return 0; @@ -748,9 +751,9 @@ namespace MediaBrowser.Model.Dlna var appliedVideoConditions = options.Profile.CodecProfiles .Where(i => i.Type == CodecType.Video && i.ContainsAnyCodec(videoCodec, container) && - i.ApplyConditions.All(applyCondition => ConditionProcessor.IsVideoConditionSatisfied(applyCondition, videoStream?.Width, videoStream?.Height, videoStream?.BitDepth, videoStream?.BitRate, videoStream?.Profile, videoStream?.Level, videoFramerate, videoStream?.PacketLength, timestamp, videoStream?.IsAnamorphic, videoStream?.IsInterlaced, videoStream?.RefFrames, numVideoStreams, numAudioStreams, videoStream?.CodecTag, videoStream?.IsAVC))) + i.ApplyConditions.All(applyCondition => ConditionProcessor.IsVideoConditionSatisfied(applyCondition, videoStream?.Width, videoStream?.Height, videoStream?.BitDepth, videoStream?.BitRate, videoStream?.Profile, videoStream?.VideoRangeType, videoStream?.Level, videoFramerate, videoStream?.PacketLength, timestamp, videoStream?.IsAnamorphic, videoStream?.IsInterlaced, videoStream?.RefFrames, numVideoStreams, numAudioStreams, videoStream?.CodecTag, videoStream?.IsAVC))) .Select(i => - i.Conditions.All(condition => ConditionProcessor.IsVideoConditionSatisfied(condition, videoStream?.Width, videoStream?.Height, videoStream?.BitDepth, videoStream?.BitRate, videoStream?.Profile, videoStream?.Level, videoFramerate, videoStream?.PacketLength, timestamp, videoStream?.IsAnamorphic, videoStream?.IsInterlaced, videoStream?.RefFrames, numVideoStreams, numAudioStreams, videoStream?.CodecTag, videoStream?.IsAVC))); + i.Conditions.All(condition => ConditionProcessor.IsVideoConditionSatisfied(condition, videoStream?.Width, videoStream?.Height, videoStream?.BitDepth, videoStream?.BitRate, videoStream?.Profile, videoStream?.VideoRangeType, videoStream?.Level, videoFramerate, videoStream?.PacketLength, timestamp, videoStream?.IsAnamorphic, videoStream?.IsInterlaced, videoStream?.RefFrames, numVideoStreams, numAudioStreams, videoStream?.CodecTag, videoStream?.IsAVC))); // An empty appliedVideoConditions means that the codec has no conditions for the current video stream var conditionsSatisfied = appliedVideoConditions.All(satisfied => satisfied); @@ -834,6 +837,7 @@ namespace MediaBrowser.Model.Dlna int? videoBitrate = videoStream?.BitRate; double? videoLevel = videoStream?.Level; string videoProfile = videoStream?.Profile; + string videoRangeType = videoStream?.VideoRangeType; float videoFramerate = videoStream == null ? 0 : videoStream.AverageFrameRate ?? videoStream.AverageFrameRate ?? 0; bool? isAnamorphic = videoStream?.IsAnamorphic; bool? isInterlaced = videoStream?.IsInterlaced; @@ -850,7 +854,7 @@ namespace MediaBrowser.Model.Dlna var appliedVideoConditions = options.Profile.CodecProfiles .Where(i => i.Type == CodecType.Video && i.ContainsAnyCodec(videoCodec, container) && - i.ApplyConditions.All(applyCondition => ConditionProcessor.IsVideoConditionSatisfied(applyCondition, width, height, bitDepth, videoBitrate, videoProfile, videoLevel, videoFramerate, packetLength, timestamp, isAnamorphic, isInterlaced, refFrames, numVideoStreams, numAudioStreams, videoCodecTag, isAvc))); + i.ApplyConditions.All(applyCondition => ConditionProcessor.IsVideoConditionSatisfied(applyCondition, width, height, bitDepth, videoBitrate, videoProfile, videoRangeType, videoLevel, videoFramerate, packetLength, timestamp, isAnamorphic, isInterlaced, refFrames, numVideoStreams, numAudioStreams, videoCodecTag, isAvc))); var isFirstAppliedCodecProfile = true; foreach (var i in appliedVideoConditions) { @@ -1081,6 +1085,7 @@ namespace MediaBrowser.Model.Dlna int? videoBitrate = videoStream?.BitRate; double? videoLevel = videoStream?.Level; string videoProfile = videoStream?.Profile; + string videoRangeType = videoStream?.VideoRangeType; float videoFramerate = videoStream == null ? 0 : videoStream.AverageFrameRate ?? videoStream.AverageFrameRate ?? 0; bool? isAnamorphic = videoStream?.IsAnamorphic; bool? isInterlaced = videoStream?.IsInterlaced; @@ -1098,7 +1103,7 @@ namespace MediaBrowser.Model.Dlna int? numVideoStreams = mediaSource.GetStreamCount(MediaStreamType.Video); var checkVideoConditions = (ProfileCondition[] conditions) => - conditions.Where(applyCondition => !ConditionProcessor.IsVideoConditionSatisfied(applyCondition, width, height, bitDepth, videoBitrate, videoProfile, videoLevel, videoFramerate, packetLength, timestamp, isAnamorphic, isInterlaced, refFrames, numVideoStreams, numAudioStreams, videoCodecTag, isAvc)); + conditions.Where(applyCondition => !ConditionProcessor.IsVideoConditionSatisfied(applyCondition, width, height, bitDepth, videoBitrate, videoProfile, videoRangeType, videoLevel, videoFramerate, packetLength, timestamp, isAnamorphic, isInterlaced, refFrames, numVideoStreams, numAudioStreams, videoCodecTag, isAvc)); // Check container conditions var containerProfileReasons = AggregateFailureConditions( @@ -1852,6 +1857,38 @@ namespace MediaBrowser.Model.Dlna break; } + case ProfileConditionValue.VideoRangeType: + { + if (string.IsNullOrEmpty(qualifier)) + { + continue; + } + + // change from split by | to comma + // strip spaces to avoid having to encode + var values = value + .Split('|', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries); + + if (condition.Condition == ProfileConditionType.Equals) + { + item.SetOption(qualifier, "rangetype", string.Join(',', values)); + } + else if (condition.Condition == ProfileConditionType.EqualsAny) + { + var currentValue = item.GetOption(qualifier, "rangetype"); + if (!string.IsNullOrEmpty(currentValue) && values.Any(v => string.Equals(v, currentValue, StringComparison.OrdinalIgnoreCase))) + { + item.SetOption(qualifier, "rangetype", currentValue); + } + else + { + item.SetOption(qualifier, "rangetype", string.Join(',', values)); + } + } + + break; + } + case ProfileConditionValue.Height: { if (!enableNonQualifiedConditions) diff --git a/MediaBrowser.Model/Dlna/StreamInfo.cs b/MediaBrowser.Model/Dlna/StreamInfo.cs index da089602f1..0c66351c70 100644 --- a/MediaBrowser.Model/Dlna/StreamInfo.cs +++ b/MediaBrowser.Model/Dlna/StreamInfo.cs @@ -280,6 +280,29 @@ namespace MediaBrowser.Model.Dlna } } + /// + /// Gets the target video range type that will be in the output stream. + /// + public string TargetVideoRangeType + { + get + { + if (IsDirectStream) + { + return TargetVideoStream?.VideoRangeType; + } + + var targetVideoCodecs = TargetVideoCodec; + var videoCodec = targetVideoCodecs.Length == 0 ? null : targetVideoCodecs[0]; + if (!string.IsNullOrEmpty(videoCodec)) + { + return GetOption(videoCodec, "rangetype"); + } + + return TargetVideoStream?.VideoRangeType; + } + } + /// /// Gets the target video codec tag. /// diff --git a/MediaBrowser.Model/Entities/MediaStream.cs b/MediaBrowser.Model/Entities/MediaStream.cs index 96b48ca52a..48408e5847 100644 --- a/MediaBrowser.Model/Entities/MediaStream.cs +++ b/MediaBrowser.Model/Entities/MediaStream.cs @@ -104,32 +104,23 @@ namespace MediaBrowser.Model.Entities { get { - if (Type != MediaStreamType.Video) - { - return null; - } - - var colorTransfer = ColorTransfer; + var (videoRange, _) = GetVideoColorRange(); - if (string.Equals(colorTransfer, "smpte2084", StringComparison.OrdinalIgnoreCase) - || string.Equals(colorTransfer, "arib-std-b67", StringComparison.OrdinalIgnoreCase)) - { - return "HDR"; - } - - // For some Dolby Vision files, no color transfer is provided, so check the codec - - var codecTag = CodecTag; + return videoRange; + } + } - if (string.Equals(codecTag, "dovi", StringComparison.OrdinalIgnoreCase) - || string.Equals(codecTag, "dvh1", StringComparison.OrdinalIgnoreCase) - || string.Equals(codecTag, "dvhe", StringComparison.OrdinalIgnoreCase) - || string.Equals(codecTag, "dav1", StringComparison.OrdinalIgnoreCase)) - { - return "HDR"; - } + /// + /// Gets the video range type. + /// + /// The video range type. + public string VideoRangeType + { + get + { + var (_, videoRangeType) = GetVideoColorRange(); - return "SDR"; + return videoRangeType; } } @@ -571,5 +562,39 @@ namespace MediaBrowser.Model.Entities return true; } + + public (string VideoRange, string VideoRangeType) GetVideoColorRange() + { + if (Type != MediaStreamType.Video) + { + return (null, null); + } + + var colorTransfer = ColorTransfer; + + if (string.Equals(colorTransfer, "smpte2084", StringComparison.OrdinalIgnoreCase)) + { + return ("HDR", "HDR10"); + } + + if (string.Equals(colorTransfer, "arib-std-b67", StringComparison.OrdinalIgnoreCase)) + { + return ("HDR", "HLG"); + } + + // For some Dolby Vision files, no color transfer is provided, so check the codec + + var codecTag = CodecTag; + + if (string.Equals(codecTag, "dovi", StringComparison.OrdinalIgnoreCase) + || string.Equals(codecTag, "dvh1", StringComparison.OrdinalIgnoreCase) + || string.Equals(codecTag, "dvhe", StringComparison.OrdinalIgnoreCase) + || string.Equals(codecTag, "dav1", StringComparison.OrdinalIgnoreCase)) + { + return ("HDR", "DOVI"); + } + + return ("SDR", "SDR"); + } } } diff --git a/MediaBrowser.Model/Session/TranscodeReason.cs b/MediaBrowser.Model/Session/TranscodeReason.cs index 9da9f3323b..bbdf4536b7 100644 --- a/MediaBrowser.Model/Session/TranscodeReason.cs +++ b/MediaBrowser.Model/Session/TranscodeReason.cs @@ -17,6 +17,7 @@ namespace MediaBrowser.Model.Session // Video Constraints VideoProfileNotSupported = 1 << 6, + VideoRangeTypeNotSupported = 1 << 24, VideoLevelNotSupported = 1 << 7, VideoResolutionNotSupported = 1 << 8, VideoBitDepthNotSupported = 1 << 9, -- cgit v1.2.3 From a65397ae147d09703bfc2c5508e6e61b4c2998e3 Mon Sep 17 00:00:00 2001 From: Cody Robibero Date: Fri, 17 Jun 2022 10:01:37 -0600 Subject: Merge pull request #7950 from nyanmisaka/brighter-vpp-tonemap (cherry picked from commit b36543275f8e1c380f5c247a04a48d5d96eb5836) Signed-off-by: Joshua Boniface --- MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs | 14 +++++++++++++- MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs | 1 + MediaBrowser.Model/Configuration/EncodingOptions.cs | 6 ++++++ 3 files changed, 20 insertions(+), 1 deletion(-) (limited to 'MediaBrowser.Controller/MediaEncoding') diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index d5b0aca3c3..2a5018c057 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -125,6 +125,7 @@ namespace MediaBrowser.Controller.MediaEncoding && _mediaEncoder.SupportsFilter("scale_vaapi") && _mediaEncoder.SupportsFilter("deinterlace_vaapi") && _mediaEncoder.SupportsFilter("tonemap_vaapi") + && _mediaEncoder.SupportsFilter("procamp_vaapi") && _mediaEncoder.SupportsFilterWithOption(FilterOptionType.OverlayVaapiFrameSync) && _mediaEncoder.SupportsFilter("hwupload_vaapi"); } @@ -2718,7 +2719,18 @@ namespace MediaBrowser.Controller.MediaEncoding var args = "tonemap_{0}=format={1}:p=bt709:t=bt709:m=bt709"; - if (!hwTonemapSuffix.Contains("vaapi", StringComparison.OrdinalIgnoreCase)) + if (hwTonemapSuffix.Contains("vaapi", StringComparison.OrdinalIgnoreCase)) + { + args += ",procamp_vaapi=b={2}:c={3}:extra_hw_frames=16"; + return string.Format( + CultureInfo.InvariantCulture, + args, + hwTonemapSuffix, + videoFormat ?? "nv12", + options.VppTonemappingBrightness, + options.VppTonemappingContrast); + } + else { args += ":tonemap={2}:peak={3}:desat={4}"; diff --git a/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs b/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs index 20d372d7aa..d378c6e134 100644 --- a/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs +++ b/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs @@ -100,6 +100,7 @@ namespace MediaBrowser.MediaEncoding.Encoder "scale_vaapi", "deinterlace_vaapi", "tonemap_vaapi", + "procamp_vaapi", "overlay_vaapi", "hwupload_vaapi" }; diff --git a/MediaBrowser.Model/Configuration/EncodingOptions.cs b/MediaBrowser.Model/Configuration/EncodingOptions.cs index fce0b6d6f6..73ebfba70e 100644 --- a/MediaBrowser.Model/Configuration/EncodingOptions.cs +++ b/MediaBrowser.Model/Configuration/EncodingOptions.cs @@ -26,6 +26,8 @@ namespace MediaBrowser.Model.Configuration TonemappingThreshold = 0.8; TonemappingPeak = 100; TonemappingParam = 0; + VppTonemappingBrightness = 0; + VppTonemappingContrast = 1.2; H264Crf = 23; H265Crf = 28; DeinterlaceDoubleRate = false; @@ -89,6 +91,10 @@ namespace MediaBrowser.Model.Configuration public double TonemappingParam { get; set; } + public double VppTonemappingBrightness { get; set; } + + public double VppTonemappingContrast { get; set; } + public int H264Crf { get; set; } public int H265Crf { get; set; } -- cgit v1.2.3 From fe32b5e33353e6154e067c5fb196a36cdecc0cea Mon Sep 17 00:00:00 2001 From: "Joshua M. Boniface" Date: Sun, 26 Jun 2022 20:55:36 -0400 Subject: Merge pull request #7964 from jellyfin/dovi-side-data (cherry picked from commit 39d185c7b19ed2da1ae46566152fb1cf182266cd) Signed-off-by: Joshua Boniface --- .../Data/SqliteItemRepository.cs | 70 +++++++++++++- .../MediaEncoding/EncodingHelper.cs | 20 ++-- .../Probing/MediaStreamInfo.cs | 7 ++ .../Probing/MediaStreamInfoSideData.cs | 74 +++++++++++++++ .../Probing/ProbeResultNormalizer.cs | 21 +++++ MediaBrowser.Model/Entities/MediaStream.cs | 101 ++++++++++++++++++++- .../Probing/ProbeResultNormalizerTests.cs | 8 ++ .../Test Data/Probing/video_metadata.json | 15 ++- 8 files changed, 301 insertions(+), 15 deletions(-) create mode 100644 MediaBrowser.MediaEncoding/Probing/MediaStreamInfoSideData.cs (limited to 'MediaBrowser.Controller/MediaEncoding') diff --git a/Emby.Server.Implementations/Data/SqliteItemRepository.cs b/Emby.Server.Implementations/Data/SqliteItemRepository.cs index 964a630b26..4361440d75 100644 --- a/Emby.Server.Implementations/Data/SqliteItemRepository.cs +++ b/Emby.Server.Implementations/Data/SqliteItemRepository.cs @@ -170,7 +170,15 @@ namespace Emby.Server.Implementations.Data "CodecTimeBase", "ColorPrimaries", "ColorSpace", - "ColorTransfer" + "ColorTransfer", + "DvVersionMajor", + "DvVersionMinor", + "DvProfile", + "DvLevel", + "RpuPresentFlag", + "ElPresentFlag", + "BlPresentFlag", + "DvBlSignalCompatibilityId" }; private static readonly string _mediaStreamSaveColumnsInsertQuery = @@ -341,7 +349,7 @@ namespace Emby.Server.Implementations.Data public void Initialize(SqliteUserDataRepository userDataRepo, IUserManager userManager) { const string CreateMediaStreamsTableCommand - = "create table if not exists mediastreams (ItemId GUID, StreamIndex INT, StreamType TEXT, Codec TEXT, Language TEXT, ChannelLayout TEXT, Profile TEXT, AspectRatio TEXT, Path TEXT, IsInterlaced BIT, BitRate INT NULL, Channels INT NULL, SampleRate INT NULL, IsDefault BIT, IsForced BIT, IsExternal BIT, Height INT NULL, Width INT NULL, AverageFrameRate FLOAT NULL, RealFrameRate FLOAT NULL, Level FLOAT NULL, PixelFormat TEXT, BitDepth INT NULL, IsAnamorphic BIT NULL, RefFrames INT NULL, CodecTag TEXT NULL, Comment TEXT NULL, NalLengthSize TEXT NULL, IsAvc BIT NULL, Title TEXT NULL, TimeBase TEXT NULL, CodecTimeBase TEXT NULL, ColorPrimaries TEXT NULL, ColorSpace TEXT NULL, ColorTransfer TEXT NULL, PRIMARY KEY (ItemId, StreamIndex))"; + = "create table if not exists mediastreams (ItemId GUID, StreamIndex INT, StreamType TEXT, Codec TEXT, Language TEXT, ChannelLayout TEXT, Profile TEXT, AspectRatio TEXT, Path TEXT, IsInterlaced BIT, BitRate INT NULL, Channels INT NULL, SampleRate INT NULL, IsDefault BIT, IsForced BIT, IsExternal BIT, Height INT NULL, Width INT NULL, AverageFrameRate FLOAT NULL, RealFrameRate FLOAT NULL, Level FLOAT NULL, PixelFormat TEXT, BitDepth INT NULL, IsAnamorphic BIT NULL, RefFrames INT NULL, CodecTag TEXT NULL, Comment TEXT NULL, NalLengthSize TEXT NULL, IsAvc BIT NULL, Title TEXT NULL, TimeBase TEXT NULL, CodecTimeBase TEXT NULL, ColorPrimaries TEXT NULL, ColorSpace TEXT NULL, ColorTransfer TEXT NULL, DvVersionMajor INT NULL, DvVersionMinor INT NULL, DvProfile INT NULL, DvLevel INT NULL, RpuPresentFlag INT NULL, ElPresentFlag INT NULL, BlPresentFlag INT NULL, DvBlSignalCompatibilityId INT NULL, PRIMARY KEY (ItemId, StreamIndex))"; const string CreateMediaAttachmentsTableCommand = "create table if not exists mediaattachments (ItemId GUID, AttachmentIndex INT, Codec TEXT, CodecTag TEXT NULL, Comment TEXT NULL, Filename TEXT NULL, MIMEType TEXT NULL, PRIMARY KEY (ItemId, AttachmentIndex))"; @@ -555,6 +563,15 @@ namespace Emby.Server.Implementations.Data AddColumn(db, "MediaStreams", "ColorPrimaries", "TEXT", existingColumnNames); AddColumn(db, "MediaStreams", "ColorSpace", "TEXT", existingColumnNames); AddColumn(db, "MediaStreams", "ColorTransfer", "TEXT", existingColumnNames); + + AddColumn(db, "MediaStreams", "DvVersionMajor", "INT", existingColumnNames); + AddColumn(db, "MediaStreams", "DvVersionMinor", "INT", existingColumnNames); + AddColumn(db, "MediaStreams", "DvProfile", "INT", existingColumnNames); + AddColumn(db, "MediaStreams", "DvLevel", "INT", existingColumnNames); + AddColumn(db, "MediaStreams", "RpuPresentFlag", "INT", existingColumnNames); + AddColumn(db, "MediaStreams", "ElPresentFlag", "INT", existingColumnNames); + AddColumn(db, "MediaStreams", "BlPresentFlag", "INT", existingColumnNames); + AddColumn(db, "MediaStreams", "DvBlSignalCompatibilityId", "INT", existingColumnNames); }, TransactionMode); @@ -5859,6 +5876,15 @@ AND Type = @InternalPersonType)"); statement.TryBind("@ColorPrimaries" + index, stream.ColorPrimaries); statement.TryBind("@ColorSpace" + index, stream.ColorSpace); statement.TryBind("@ColorTransfer" + index, stream.ColorTransfer); + + statement.TryBind("@DvVersionMajor" + index, stream.DvVersionMajor); + statement.TryBind("@DvVersionMinor" + index, stream.DvVersionMinor); + statement.TryBind("@DvProfile" + index, stream.DvProfile); + statement.TryBind("@DvLevel" + index, stream.DvLevel); + statement.TryBind("@RpuPresentFlag" + index, stream.RpuPresentFlag); + statement.TryBind("@ElPresentFlag" + index, stream.ElPresentFlag); + statement.TryBind("@BlPresentFlag" + index, stream.BlPresentFlag); + statement.TryBind("@DvBlSignalCompatibilityId" + index, stream.DvBlSignalCompatibilityId); } statement.Reset(); @@ -6030,6 +6056,46 @@ AND Type = @InternalPersonType)"); item.ColorTransfer = colorTransfer; } + if (reader.TryGetInt32(35, out var dvVersionMajor)) + { + item.DvVersionMajor = dvVersionMajor; + } + + if (reader.TryGetInt32(36, out var dvVersionMinor)) + { + item.DvVersionMinor = dvVersionMinor; + } + + if (reader.TryGetInt32(37, out var dvProfile)) + { + item.DvProfile = dvProfile; + } + + if (reader.TryGetInt32(38, out var dvLevel)) + { + item.DvLevel = dvLevel; + } + + if (reader.TryGetInt32(39, out var rpuPresentFlag)) + { + item.RpuPresentFlag = rpuPresentFlag; + } + + if (reader.TryGetInt32(40, out var elPresentFlag)) + { + item.ElPresentFlag = elPresentFlag; + } + + if (reader.TryGetInt32(41, out var blPresentFlag)) + { + item.BlPresentFlag = blPresentFlag; + } + + if (reader.TryGetInt32(42, out var dvBlSignalCompatibilityId)) + { + item.DvBlSignalCompatibilityId = dvBlSignalCompatibilityId; + } + if (item.Type == MediaStreamType.Subtitle) { item.LocalizedUndefined = _localization.GetLocalizedString("Undefined"); diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index 2a5018c057..f795bf2aa8 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -157,9 +157,9 @@ namespace MediaBrowser.Controller.MediaEncoding return false; } - if (string.Equals(state.VideoStream.CodecTag, "dovi", StringComparison.OrdinalIgnoreCase) - || string.Equals(state.VideoStream.CodecTag, "dvh1", StringComparison.OrdinalIgnoreCase) - || string.Equals(state.VideoStream.CodecTag, "dvhe", StringComparison.OrdinalIgnoreCase)) + if (string.Equals(state.VideoStream.Codec, "hevc", StringComparison.OrdinalIgnoreCase) + && string.Equals(state.VideoStream.VideoRange, "HDR", StringComparison.OrdinalIgnoreCase) + && string.Equals(state.VideoStream.VideoRangeType, "DOVI", StringComparison.OrdinalIgnoreCase)) { // Only native SW decoder and HW accelerator can parse dovi rpu. var vidDecoder = GetHardwareVideoDecoder(state, options) ?? string.Empty; @@ -170,22 +170,24 @@ namespace MediaBrowser.Controller.MediaEncoding return isSwDecoder || isNvdecDecoder || isVaapiDecoder || isD3d11vaDecoder; } - return string.Equals(state.VideoStream.ColorTransfer, "smpte2084", StringComparison.OrdinalIgnoreCase) - || string.Equals(state.VideoStream.ColorTransfer, "arib-std-b67", StringComparison.OrdinalIgnoreCase); + return string.Equals(state.VideoStream.VideoRange, "HDR", StringComparison.OrdinalIgnoreCase) + && (string.Equals(state.VideoStream.VideoRangeType, "HDR10", StringComparison.OrdinalIgnoreCase) + || string.Equals(state.VideoStream.VideoRangeType, "HLG", StringComparison.OrdinalIgnoreCase)); } private bool IsVaapiVppTonemapAvailable(EncodingJobInfo state, EncodingOptions options) { - if (state.VideoStream == null) + if (state.VideoStream == null + || !options.EnableVppTonemapping + || GetVideoColorBitDepth(state) != 10) { return false; } // Native VPP tonemapping may come to QSV in the future. - return options.EnableVppTonemapping - && string.Equals(state.VideoStream.ColorTransfer, "smpte2084", StringComparison.OrdinalIgnoreCase) - && GetVideoColorBitDepth(state) == 10; + return string.Equals(state.VideoStream.VideoRange, "HDR", StringComparison.OrdinalIgnoreCase) + && string.Equals(state.VideoStream.VideoRangeType, "HDR10", StringComparison.OrdinalIgnoreCase); } /// diff --git a/MediaBrowser.MediaEncoding/Probing/MediaStreamInfo.cs b/MediaBrowser.MediaEncoding/Probing/MediaStreamInfo.cs index c9c8c34c2e..eab8f79bb3 100644 --- a/MediaBrowser.MediaEncoding/Probing/MediaStreamInfo.cs +++ b/MediaBrowser.MediaEncoding/Probing/MediaStreamInfo.cs @@ -310,5 +310,12 @@ namespace MediaBrowser.MediaEncoding.Probing /// The color primaries. [JsonPropertyName("color_primaries")] public string ColorPrimaries { get; set; } + + /// + /// Gets or sets the side_data_list. + /// + /// The side_data_list. + [JsonPropertyName("side_data_list")] + public IReadOnlyList SideDataList { get; set; } } } diff --git a/MediaBrowser.MediaEncoding/Probing/MediaStreamInfoSideData.cs b/MediaBrowser.MediaEncoding/Probing/MediaStreamInfoSideData.cs new file mode 100644 index 0000000000..095757bef7 --- /dev/null +++ b/MediaBrowser.MediaEncoding/Probing/MediaStreamInfoSideData.cs @@ -0,0 +1,74 @@ +using System.Collections.Generic; +using System.Text.Json.Serialization; + +namespace MediaBrowser.MediaEncoding.Probing +{ + /// + /// Class MediaStreamInfoSideData. + /// + public class MediaStreamInfoSideData + { + /// + /// Gets or sets the SideDataType. + /// + /// The SideDataType. + [JsonPropertyName("side_data_type")] + public string? SideDataType { get; set; } + + /// + /// Gets or sets the DvVersionMajor. + /// + /// The DvVersionMajor. + [JsonPropertyName("dv_version_major")] + public int? DvVersionMajor { get; set; } + + /// + /// Gets or sets the DvVersionMinor. + /// + /// The DvVersionMinor. + [JsonPropertyName("dv_version_minor")] + public int? DvVersionMinor { get; set; } + + /// + /// Gets or sets the DvProfile. + /// + /// The DvProfile. + [JsonPropertyName("dv_profile")] + public int? DvProfile { get; set; } + + /// + /// Gets or sets the DvLevel. + /// + /// The DvLevel. + [JsonPropertyName("dv_level")] + public int? DvLevel { get; set; } + + /// + /// Gets or sets the RpuPresentFlag. + /// + /// The RpuPresentFlag. + [JsonPropertyName("rpu_present_flag")] + public int? RpuPresentFlag { get; set; } + + /// + /// Gets or sets the ElPresentFlag. + /// + /// The ElPresentFlag. + [JsonPropertyName("el_present_flag")] + public int? ElPresentFlag { get; set; } + + /// + /// Gets or sets the BlPresentFlag. + /// + /// The BlPresentFlag. + [JsonPropertyName("bl_present_flag")] + public int? BlPresentFlag { get; set; } + + /// + /// Gets or sets the DvBlSignalCompatibilityId. + /// + /// The DvBlSignalCompatibilityId. + [JsonPropertyName("dv_bl_signal_compatibility_id")] + public int? DvBlSignalCompatibilityId { get; set; } + } +} diff --git a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs index 3f78d0d42c..74d7341e91 100644 --- a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs +++ b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs @@ -841,6 +841,27 @@ namespace MediaBrowser.MediaEncoding.Probing { stream.ColorPrimaries = streamInfo.ColorPrimaries; } + + if (streamInfo.SideDataList != null) + { + foreach (var data in streamInfo.SideDataList) + { + // Parse Dolby Vision metadata from side_data + if (string.Equals(data.SideDataType, "DOVI configuration record", StringComparison.OrdinalIgnoreCase)) + { + stream.DvVersionMajor = data.DvVersionMajor; + stream.DvVersionMinor = data.DvVersionMinor; + stream.DvProfile = data.DvProfile; + stream.DvLevel = data.DvLevel; + stream.RpuPresentFlag = data.RpuPresentFlag; + stream.ElPresentFlag = data.ElPresentFlag; + stream.BlPresentFlag = data.BlPresentFlag; + stream.DvBlSignalCompatibilityId = data.DvBlSignalCompatibilityId; + + break; + } + } + } } else { diff --git a/MediaBrowser.Model/Entities/MediaStream.cs b/MediaBrowser.Model/Entities/MediaStream.cs index 48408e5847..58988b6fae 100644 --- a/MediaBrowser.Model/Entities/MediaStream.cs +++ b/MediaBrowser.Model/Entities/MediaStream.cs @@ -72,6 +72,54 @@ namespace MediaBrowser.Model.Entities /// The color primaries. public string ColorPrimaries { get; set; } + /// + /// Gets or sets the Dolby Vision version major. + /// + /// The Dolby Vision version major. + public int? DvVersionMajor { get; set; } + + /// + /// Gets or sets the Dolby Vision version minor. + /// + /// The Dolby Vision version minor. + public int? DvVersionMinor { get; set; } + + /// + /// Gets or sets the Dolby Vision profile. + /// + /// The Dolby Vision profile. + public int? DvProfile { get; set; } + + /// + /// Gets or sets the Dolby Vision level. + /// + /// The Dolby Vision level. + public int? DvLevel { get; set; } + + /// + /// Gets or sets the Dolby Vision rpu present flag. + /// + /// The Dolby Vision rpu present flag. + public int? RpuPresentFlag { get; set; } + + /// + /// Gets or sets the Dolby Vision el present flag. + /// + /// The Dolby Vision el present flag. + public int? ElPresentFlag { get; set; } + + /// + /// Gets or sets the Dolby Vision bl present flag. + /// + /// The Dolby Vision bl present flag. + public int? BlPresentFlag { get; set; } + + /// + /// Gets or sets the Dolby Vision bl signal compatibility id. + /// + /// The Dolby Vision bl signal compatibility id. + public int? DvBlSignalCompatibilityId { get; set; } + /// /// Gets or sets the comment. /// @@ -124,6 +172,47 @@ namespace MediaBrowser.Model.Entities } } + /// + /// Gets the video dovi title. + /// + /// The video dovi title. + public string VideoDoViTitle + { + get + { + var dvProfile = DvProfile; + var rpuPresentFlag = RpuPresentFlag == 1; + var blPresentFlag = BlPresentFlag == 1; + var dvBlCompatId = DvBlSignalCompatibilityId; + + if (rpuPresentFlag + && blPresentFlag + && (dvProfile == 4 + || dvProfile == 5 + || dvProfile == 7 + || dvProfile == 8 + || dvProfile == 9)) + { + var title = "DV Profile " + dvProfile; + + if (dvBlCompatId > 0) + { + title += "." + dvBlCompatId; + } + + return dvBlCompatId switch + { + 1 => title + " (HDR10)", + 2 => title + " (SDR)", + 4 => title + " (HLG)", + _ => title + }; + } + + return null; + } + } + public string LocalizedUndefined { get; set; } public string LocalizedDefault { get; set; } @@ -582,11 +671,17 @@ namespace MediaBrowser.Model.Entities return ("HDR", "HLG"); } - // For some Dolby Vision files, no color transfer is provided, so check the codec - var codecTag = CodecTag; + var dvProfile = DvProfile; + var rpuPresentFlag = RpuPresentFlag == 1; + var blPresentFlag = BlPresentFlag == 1; + var dvBlCompatId = DvBlSignalCompatibilityId; + + var isDoViHDRProfile = dvProfile == 5 || dvProfile == 7 || dvProfile == 8; + var isDoViHDRFlag = rpuPresentFlag && blPresentFlag && (dvBlCompatId == 0 || dvBlCompatId == 1 || dvBlCompatId == 4); - if (string.Equals(codecTag, "dovi", StringComparison.OrdinalIgnoreCase) + if ((isDoViHDRProfile && isDoViHDRFlag) + || string.Equals(codecTag, "dovi", StringComparison.OrdinalIgnoreCase) || string.Equals(codecTag, "dvh1", StringComparison.OrdinalIgnoreCase) || string.Equals(codecTag, "dvhe", StringComparison.OrdinalIgnoreCase) || string.Equals(codecTag, "dav1", StringComparison.OrdinalIgnoreCase)) diff --git a/tests/Jellyfin.MediaEncoding.Tests/Probing/ProbeResultNormalizerTests.cs b/tests/Jellyfin.MediaEncoding.Tests/Probing/ProbeResultNormalizerTests.cs index 53e1550ed1..13cfe885f8 100644 --- a/tests/Jellyfin.MediaEncoding.Tests/Probing/ProbeResultNormalizerTests.cs +++ b/tests/Jellyfin.MediaEncoding.Tests/Probing/ProbeResultNormalizerTests.cs @@ -75,6 +75,14 @@ namespace Jellyfin.MediaEncoding.Tests.Probing Assert.Equal(1, res.VideoStream.RefFrames); Assert.Equal("1/1000", res.VideoStream.TimeBase); Assert.Equal(MediaStreamType.Video, res.VideoStream.Type); + Assert.Equal(1, res.VideoStream.DvVersionMajor); + Assert.Equal(0, res.VideoStream.DvVersionMinor); + Assert.Equal(5, res.VideoStream.DvProfile); + Assert.Equal(6, res.VideoStream.DvLevel); + Assert.Equal(1, res.VideoStream.RpuPresentFlag); + Assert.Equal(0, res.VideoStream.ElPresentFlag); + Assert.Equal(1, res.VideoStream.BlPresentFlag); + Assert.Equal(0, res.VideoStream.DvBlSignalCompatibilityId); Assert.Empty(res.Chapters); Assert.Equal("Just color bars", res.Overview); diff --git a/tests/Jellyfin.MediaEncoding.Tests/Test Data/Probing/video_metadata.json b/tests/Jellyfin.MediaEncoding.Tests/Test Data/Probing/video_metadata.json index 720fc5c8fa..519d81179c 100644 --- a/tests/Jellyfin.MediaEncoding.Tests/Test Data/Probing/video_metadata.json +++ b/tests/Jellyfin.MediaEncoding.Tests/Test Data/Probing/video_metadata.json @@ -47,7 +47,20 @@ "tags": { "ENCODER": "Lavc57.107.100 libx264", "DURATION": "00:00:01.000000000" - } + }, + "side_data_list": [ + { + "side_data_type": "DOVI configuration record", + "dv_version_major": 1, + "dv_version_minor": 0, + "dv_profile": 5, + "dv_level": 6, + "rpu_present_flag": 1, + "el_present_flag": 0, + "bl_present_flag": 1, + "dv_bl_signal_compatibility_id": 0 + } + ] } ], "chapters": [ -- cgit v1.2.3 From 074d7dc6b6d38bb808e4daceec35da617aa1a174 Mon Sep 17 00:00:00 2001 From: Bond-009 Date: Thu, 23 Jun 2022 15:32:35 +0200 Subject: Merge pull request #7968 from jellyfin/fix-hwa-bluray (cherry picked from commit 5f15339919ebf5db0a9a05c4c98a955e5ca1f4b7) Signed-off-by: Joshua Boniface --- MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'MediaBrowser.Controller/MediaEncoding') diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index f795bf2aa8..50ffcee116 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -4319,14 +4319,18 @@ namespace MediaBrowser.Controller.MediaEncoding protected string GetHardwareVideoDecoder(EncodingJobInfo state, EncodingOptions options) { var videoStream = state.VideoStream; - if (videoStream == null) + var mediaSource = state.MediaSource; + if (videoStream == null || mediaSource == null) { return null; } - // Only use alternative encoders for video files. - var videoType = state.MediaSource.VideoType ?? VideoType.VideoFile; - if (videoType != VideoType.VideoFile) + // HWA decoders can handle both video files and video folders. + var videoType = mediaSource.VideoType; + if (videoType != VideoType.VideoFile + && videoType != VideoType.Iso + && videoType != VideoType.Dvd + && videoType != VideoType.BluRay) { return null; } -- cgit v1.2.3 From 7dab8b8f88d413fcb7833b7bdf47f17844b33271 Mon Sep 17 00:00:00 2001 From: Bond-009 Date: Thu, 23 Jun 2022 15:33:14 +0200 Subject: Merge pull request #7975 from jellyfin/libva-driver-env (cherry picked from commit 910df89ccefd3f9ddef4a189715f90dcb4191e7f) Signed-off-by: Joshua Boniface --- MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs | 3 +++ 1 file changed, 3 insertions(+) (limited to 'MediaBrowser.Controller/MediaEncoding') diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index 50ffcee116..2b33ed5a16 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -716,6 +716,9 @@ namespace MediaBrowser.Controller.MediaEncoding } else if (_mediaEncoder.IsVaapiDeviceInteli965) { + // Only override i965 since it has lower priority than iHD in libva lookup. + Environment.SetEnvironmentVariable("LIBVA_DRIVER_NAME", "i965"); + Environment.SetEnvironmentVariable("LIBVA_DRIVER_NAME_JELLYFIN", "i965"); args.Append(GetVaapiDeviceArgs(null, "i965", null, VaapiAlias)); } else -- cgit v1.2.3 From 9c97c533eff94d25463fb649c9572234da4af1ea Mon Sep 17 00:00:00 2001 From: "Joshua M. Boniface" Date: Sun, 26 Jun 2022 20:53:03 -0400 Subject: Merge pull request #7994 from nyanmisaka/fix-throttler (cherry picked from commit a7d45b5d3aa5b16b0aeeece690396f91fb7b7e3e) Signed-off-by: Joshua Boniface --- Jellyfin.Api/Controllers/DynamicHlsController.cs | 4 ++-- Jellyfin.Api/Controllers/VideosController.cs | 2 +- Jellyfin.Api/Helpers/TranscodingJobHelper.cs | 21 +++++++-------------- Jellyfin.Api/Models/StreamingDtos/StreamState.cs | 8 -------- MediaBrowser.Controller/MediaEncoding/JobLogger.cs | 2 +- 5 files changed, 11 insertions(+), 26 deletions(-) (limited to 'MediaBrowser.Controller/MediaEncoding') diff --git a/Jellyfin.Api/Controllers/DynamicHlsController.cs b/Jellyfin.Api/Controllers/DynamicHlsController.cs index 8127193c20..365e44e1a3 100644 --- a/Jellyfin.Api/Controllers/DynamicHlsController.cs +++ b/Jellyfin.Api/Controllers/DynamicHlsController.cs @@ -285,7 +285,7 @@ namespace Jellyfin.Api.Controllers // Due to CTS.Token calling ThrowIfDisposed (https://github.com/dotnet/runtime/issues/29970) we have to "cache" the token // since it gets disposed when ffmpeg exits var cancellationToken = cancellationTokenSource.Token; - using var state = await StreamingHelpers.GetStreamingState( + var state = await StreamingHelpers.GetStreamingState( streamingRequest, Request, _authContext, @@ -1432,7 +1432,7 @@ namespace Jellyfin.Api.Controllers var cancellationTokenSource = new CancellationTokenSource(); var cancellationToken = cancellationTokenSource.Token; - using var state = await StreamingHelpers.GetStreamingState( + var state = await StreamingHelpers.GetStreamingState( streamingRequest, Request, _authContext, diff --git a/Jellyfin.Api/Controllers/VideosController.cs b/Jellyfin.Api/Controllers/VideosController.cs index 62c05331ed..4e28959345 100644 --- a/Jellyfin.Api/Controllers/VideosController.cs +++ b/Jellyfin.Api/Controllers/VideosController.cs @@ -427,7 +427,7 @@ namespace Jellyfin.Api.Controllers StreamOptions = streamOptions }; - using var state = await StreamingHelpers.GetStreamingState( + var state = await StreamingHelpers.GetStreamingState( streamingRequest, Request, _authContext, diff --git a/Jellyfin.Api/Helpers/TranscodingJobHelper.cs b/Jellyfin.Api/Helpers/TranscodingJobHelper.cs index 416418dc68..13dc878c1b 100644 --- a/Jellyfin.Api/Helpers/TranscodingJobHelper.cs +++ b/Jellyfin.Api/Helpers/TranscodingJobHelper.cs @@ -654,8 +654,8 @@ namespace Jellyfin.Api.Helpers { if (EnableThrottling(state)) { - transcodingJob.TranscodingThrottler = state.TranscodingThrottler = new TranscodingThrottler(transcodingJob, new Logger(new LoggerFactory()), _serverConfigurationManager, _fileSystem); - state.TranscodingThrottler.Start(); + transcodingJob.TranscodingThrottler = new TranscodingThrottler(transcodingJob, new Logger(new LoggerFactory()), _serverConfigurationManager, _fileSystem); + transcodingJob.TranscodingThrottler.Start(); } } @@ -663,18 +663,11 @@ namespace Jellyfin.Api.Helpers { var encodingOptions = _serverConfigurationManager.GetEncodingOptions(); - // enable throttling when NOT using hardware acceleration - if (string.IsNullOrEmpty(encodingOptions.HardwareAccelerationType)) - { - return state.InputProtocol == MediaProtocol.File && - state.RunTimeTicks.HasValue && - state.RunTimeTicks.Value >= TimeSpan.FromMinutes(5).Ticks && - state.IsInputVideo && - state.VideoType == VideoType.VideoFile && - !EncodingHelper.IsCopyCodec(state.OutputVideoCodec); - } - - return false; + return state.InputProtocol == MediaProtocol.File && + state.RunTimeTicks.HasValue && + state.RunTimeTicks.Value >= TimeSpan.FromMinutes(5).Ticks && + state.IsInputVideo && + state.VideoType == VideoType.VideoFile; } /// diff --git a/Jellyfin.Api/Models/StreamingDtos/StreamState.cs b/Jellyfin.Api/Models/StreamingDtos/StreamState.cs index cbabf087bc..192f33ebd1 100644 --- a/Jellyfin.Api/Models/StreamingDtos/StreamState.cs +++ b/Jellyfin.Api/Models/StreamingDtos/StreamState.cs @@ -47,11 +47,6 @@ namespace Jellyfin.Api.Models.StreamingDtos } } - /// - /// Gets or sets the transcoding throttler. - /// - public TranscodingThrottler? TranscodingThrottler { get; set; } - /// /// Gets the video request. /// @@ -191,11 +186,8 @@ namespace Jellyfin.Api.Models.StreamingDtos { _mediaSourceManager.CloseLiveStream(MediaSource.LiveStreamId).GetAwaiter().GetResult(); } - - TranscodingThrottler?.Dispose(); } - TranscodingThrottler = null; TranscodingJob = null; _disposed = true; diff --git a/MediaBrowser.Controller/MediaEncoding/JobLogger.cs b/MediaBrowser.Controller/MediaEncoding/JobLogger.cs index 8b2837ee3c..d8475f12ae 100644 --- a/MediaBrowser.Controller/MediaEncoding/JobLogger.cs +++ b/MediaBrowser.Controller/MediaEncoding/JobLogger.cs @@ -111,7 +111,7 @@ namespace MediaBrowser.Controller.MediaEncoding percent = 100.0 * currentMs / totalMs; - transcodingPosition = val; + transcodingPosition = TimeSpan.FromMilliseconds(currentMs); } } else if (part.StartsWith("size=", StringComparison.OrdinalIgnoreCase)) -- cgit v1.2.3 From 3e2fbb2685ab41827e6a34dd85162b2fe9bd5b67 Mon Sep 17 00:00:00 2001 From: Claus Vium Date: Fri, 24 Jun 2022 14:49:27 +0200 Subject: Merge pull request #8001 from jellyfin/fix-yuvj420p-hwdec Fix yuvj420p pixel format hardware decoding (cherry picked from commit d342b79218b06c2f2cd51bc1ddd08b7fc377c62c) Signed-off-by: Joshua Boniface --- MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'MediaBrowser.Controller/MediaEncoding') diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index 2b33ed5a16..6fb5c88740 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -4290,6 +4290,7 @@ namespace MediaBrowser.Controller.MediaEncoding return videoStream.BitDepth.Value; } else if (string.Equals(videoStream.PixelFormat, "yuv420p", StringComparison.OrdinalIgnoreCase) + || string.Equals(videoStream.PixelFormat, "yuvj420p", StringComparison.OrdinalIgnoreCase) || string.Equals(videoStream.PixelFormat, "yuv444p", StringComparison.OrdinalIgnoreCase)) { return 8; @@ -4580,7 +4581,8 @@ namespace MediaBrowser.Controller.MediaEncoding var hwSurface = (isIntelDx11OclSupported || isIntelVaapiOclSupported) && _mediaEncoder.SupportsFilter("alphasrc"); - var is8bitSwFormatsQsv = string.Equals("yuv420p", videoStream.PixelFormat, StringComparison.OrdinalIgnoreCase); + var is8bitSwFormatsQsv = string.Equals("yuv420p", videoStream.PixelFormat, StringComparison.OrdinalIgnoreCase) + || string.Equals("yuvj420p", videoStream.PixelFormat, StringComparison.OrdinalIgnoreCase); var is8_10bitSwFormatsQsv = is8bitSwFormatsQsv || string.Equals("yuv420p10le", videoStream.PixelFormat, StringComparison.OrdinalIgnoreCase); // TODO: add more 8/10bit and 4:4:4 formats for Qsv after finishing the ffcheck tool @@ -4639,7 +4641,8 @@ namespace MediaBrowser.Controller.MediaEncoding } var hwSurface = IsCudaFullSupported() && _mediaEncoder.SupportsFilter("alphasrc"); - var is8bitSwFormatsNvdec = string.Equals("yuv420p", videoStream.PixelFormat, StringComparison.OrdinalIgnoreCase); + var is8bitSwFormatsNvdec = string.Equals("yuv420p", videoStream.PixelFormat, StringComparison.OrdinalIgnoreCase) + || string.Equals("yuvj420p", videoStream.PixelFormat, StringComparison.OrdinalIgnoreCase); var is8_10bitSwFormatsNvdec = is8bitSwFormatsNvdec || string.Equals("yuv420p10le", videoStream.PixelFormat, StringComparison.OrdinalIgnoreCase); // TODO: add more 8/10/12bit and 4:4:4 formats for Nvdec after finishing the ffcheck tool @@ -4705,7 +4708,8 @@ namespace MediaBrowser.Controller.MediaEncoding var hwSurface = _mediaEncoder.SupportsHwaccel("d3d11va") && IsOpenclFullSupported() && _mediaEncoder.SupportsFilter("alphasrc"); - var is8bitSwFormatsAmf = string.Equals("yuv420p", videoStream.PixelFormat, StringComparison.OrdinalIgnoreCase); + var is8bitSwFormatsAmf = string.Equals("yuv420p", videoStream.PixelFormat, StringComparison.OrdinalIgnoreCase) + || string.Equals("yuvj420p", videoStream.PixelFormat, StringComparison.OrdinalIgnoreCase); var is8_10bitSwFormatsAmf = is8bitSwFormatsAmf || string.Equals("yuv420p10le", videoStream.PixelFormat, StringComparison.OrdinalIgnoreCase); if (is8bitSwFormatsAmf) @@ -4761,7 +4765,8 @@ namespace MediaBrowser.Controller.MediaEncoding && IsVaapiFullSupported() && IsOpenclFullSupported() && _mediaEncoder.SupportsFilter("alphasrc"); - var is8bitSwFormatsVaapi = string.Equals("yuv420p", videoStream.PixelFormat, StringComparison.OrdinalIgnoreCase); + var is8bitSwFormatsVaapi = string.Equals("yuv420p", videoStream.PixelFormat, StringComparison.OrdinalIgnoreCase) + || string.Equals("yuvj420p", videoStream.PixelFormat, StringComparison.OrdinalIgnoreCase); var is8_10bitSwFormatsVaapi = is8bitSwFormatsVaapi || string.Equals("yuv420p10le", videoStream.PixelFormat, StringComparison.OrdinalIgnoreCase); if (is8bitSwFormatsVaapi) @@ -4818,7 +4823,8 @@ namespace MediaBrowser.Controller.MediaEncoding return null; } - var is8bitSwFormatsVt = string.Equals("yuv420p", videoStream.PixelFormat, StringComparison.OrdinalIgnoreCase); + var is8bitSwFormatsVt = string.Equals("yuv420p", videoStream.PixelFormat, StringComparison.OrdinalIgnoreCase) + || string.Equals("yuvj420p", videoStream.PixelFormat, StringComparison.OrdinalIgnoreCase); var is8_10bitSwFormatsVt = is8bitSwFormatsVt || string.Equals("yuv420p10le", videoStream.PixelFormat, StringComparison.OrdinalIgnoreCase); if (is8bitSwFormatsVt) -- cgit v1.2.3 From 54b3debd2774caedf92a531a2461b42d7bb37af1 Mon Sep 17 00:00:00 2001 From: Joseph <1315585+joseph39@users.noreply.github.com> Date: Mon, 18 Jul 2022 23:30:27 -0700 Subject: Add referer parameter to ffmpeg As of https://trac.ffmpeg.org/ticket/2179, ffmpeg supports referer parameter which injects Referer header to the HTTP request for remote content. Have EncodingHelper pass this in if it's included in RemoteHttpHeaders. --- .../MediaEncoding/EncodingHelper.cs | 24 ++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'MediaBrowser.Controller/MediaEncoding') diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index 6fb5c88740..ab2daf7a50 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -255,6 +255,21 @@ namespace MediaBrowser.Controller.MediaEncoding return string.Empty; } + /// + /// Gets the referer param. + /// + /// The state. + /// System.String. + public string GetRefererParam(EncodingJobInfo state) + { + if (state.RemoteHttpHeaders.TryGetValue("Referer", out string referer)) + { + return "-referer \"" + referer + "\""; + } + + return string.Empty; + } + public static string GetInputFormat(string container) { if (string.IsNullOrEmpty(container)) @@ -4962,6 +4977,15 @@ namespace MediaBrowser.Controller.MediaEncoding inputModifier = inputModifier.Trim(); + var refererParam = GetRefererParam(state); + + if (!string.IsNullOrEmpty(refererParam)) + { + inputModifier += " " + refererParam; + } + + inputModifier = inputModifier.Trim(); + inputModifier += " " + GetFastSeekCommandLineParameter(state, encodingOptions, segmentContainer); inputModifier = inputModifier.Trim(); -- cgit v1.2.3 From a9449d0f23db890d8a251504afa1b262dae2a513 Mon Sep 17 00:00:00 2001 From: Joshua Boniface Date: Wed, 20 Jul 2022 19:29:06 -0400 Subject: Backport pull request #8078 from jellyfin/release-10.8.z fix copy&paste error for requestedRangeTypes preventing stream copy Authored-by: Andy Walsh Merged-by: Bond-009 Original-merge: 47c2c536e45792ffe0b5c70d02758463e0c1d407 --- MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'MediaBrowser.Controller/MediaEncoding') diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index 6fb5c88740..684ea157fd 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -1713,6 +1713,7 @@ namespace MediaBrowser.Controller.MediaEncoding // Can't stream copy if we're burning in subtitles if (request.SubtitleStreamIndex.HasValue + && request.SubtitleStreamIndex.Value >= 0 && state.SubtitleDeliveryMethod == SubtitleDeliveryMethod.Encode) { return false; @@ -1760,7 +1761,7 @@ namespace MediaBrowser.Controller.MediaEncoding } var requestedRangeTypes = state.GetRequestedRangeTypes(videoStream.Codec); - if (requestedProfiles.Length > 0) + if (requestedRangeTypes.Length > 0) { if (string.IsNullOrEmpty(videoStream.VideoRangeType)) { -- cgit v1.2.3 From adc08b5b4c49a1f8b4e5588d184d06454c1d0791 Mon Sep 17 00:00:00 2001 From: Joshua Boniface Date: Wed, 20 Jul 2022 19:29:07 -0400 Subject: Backport pull request #8092 from jellyfin/release-10.8.z Change allow higher opus, vorbis transcode bitrates Authored-by: Andy Walsh Merged-by: Bond-009 Original-merge: 7ef9e95d75aff2f273c9a98ef83a4fb1df754dd5 --- MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs | 2 ++ 1 file changed, 2 insertions(+) (limited to 'MediaBrowser.Controller/MediaEncoding') diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index 684ea157fd..91acca0a75 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -2027,6 +2027,8 @@ namespace MediaBrowser.Controller.MediaEncoding { if (string.Equals(audioCodec, "aac", StringComparison.OrdinalIgnoreCase) || string.Equals(audioCodec, "mp3", StringComparison.OrdinalIgnoreCase) + || string.Equals(audioCodec, "opus", StringComparison.OrdinalIgnoreCase) + || string.Equals(audioCodec, "vorbis", StringComparison.OrdinalIgnoreCase) || string.Equals(audioCodec, "ac3", StringComparison.OrdinalIgnoreCase) || string.Equals(audioCodec, "eac3", StringComparison.OrdinalIgnoreCase)) { -- cgit v1.2.3 From 76f7a80a97f19adc6126eaef02dc64fe9a581b48 Mon Sep 17 00:00:00 2001 From: Joshua Boniface Date: Sun, 24 Jul 2022 12:35:46 -0400 Subject: Backport pull request #8152 from jellyfin/release-10.8.z Fix support for rtsp streams over tcp Authored-by: Bill Thornton Merged-by: Cody Robibero Original-merge: b2fb96ffed73dd9fcbc90b4645577f860ad4daf1 --- MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'MediaBrowser.Controller/MediaEncoding') diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index 91acca0a75..15afde601d 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -4970,7 +4970,7 @@ namespace MediaBrowser.Controller.MediaEncoding if (state.InputProtocol == MediaProtocol.Rtsp) { - inputModifier += " -rtsp_transport tcp -rtsp_transport udp -rtsp_flags prefer_tcp"; + inputModifier += " -rtsp_transport tcp+udp -rtsp_flags prefer_tcp"; } if (!string.IsNullOrEmpty(state.InputAudioSync)) -- cgit v1.2.3 From 3e24b8943da60008a06bec325c075c35142da4be Mon Sep 17 00:00:00 2001 From: Joshua Boniface Date: Mon, 1 Aug 2022 14:25:41 -0400 Subject: Backport pull request #8061 from jellyfin/release-10.8.z Fix intel dx11-ocl interop taking too long to initialize on windows Authored-by: nyanmisaka Merged-by: Claus Vium Original-merge: 9854751137db1578c31f1b8cefcbb1a1bc1ff206 --- MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'MediaBrowser.Controller/MediaEncoding') diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index 15afde601d..f1f79a8633 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -4506,7 +4506,9 @@ namespace MediaBrowser.Controller.MediaEncoding if (isD3d11Supported && isCodecAvailable) { - return " -hwaccel d3d11va" + (outputHwSurface ? " -hwaccel_output_format d3d11" : string.Empty) + (isAv1 ? " -c:v av1" : string.Empty); + // set -threads 3 to intel d3d11va decoder explicitly. Lower threads may result in dead lock. + // on newer devices such as Xe, the larger the init_pool_size, the longer the initialization time for opencl to derive from d3d11. + return " -hwaccel d3d11va" + (outputHwSurface ? " -hwaccel_output_format d3d11" : string.Empty) + " -threads 3" + (isAv1 ? " -c:v av1" : string.Empty); } } else -- cgit v1.2.3 From 38f6f589d96803d6f015a069ed7ad2bc958acf92 Mon Sep 17 00:00:00 2001 From: Joshua Boniface Date: Mon, 1 Aug 2022 14:25:43 -0400 Subject: Backport pull request #8127 from jellyfin/release-10.8.z Workaround for linux 5.18+ i915 hang at cost of performance Authored-by: Nyanmisaka Merged-by: Claus Vium Original-merge: 484427b4aa9b94a1864bc7dfc104fa52d6b38f0e --- .../MediaEncoding/EncodingHelper.cs | 28 ++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'MediaBrowser.Controller/MediaEncoding') diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index f1f79a8633..1d65f9a345 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -35,6 +35,7 @@ namespace MediaBrowser.Controller.MediaEncoding private readonly IMediaEncoder _mediaEncoder; private readonly ISubtitleEncoder _subtitleEncoder; private readonly IConfiguration _config; + private readonly Version _minKernelVersioni915Hang = new Version(5, 18); private static readonly string[] _videoProfilesH264 = new[] { @@ -1302,6 +1303,10 @@ namespace MediaBrowser.Controller.MediaEncoding // which will reduce overhead in performance intensive tasks such as 4k transcoding and tonemapping. var intelLowPowerHwEncoding = false; + // Workaround for linux 5.18+ i915 hang at cost of performance. + // https://github.com/intel/media-driver/issues/1456 + var enableWaFori915Hang = false; + if (string.Equals(encodingOptions.HardwareAccelerationType, "vaapi", StringComparison.OrdinalIgnoreCase)) { var isIntelVaapiDriver = _mediaEncoder.IsVaapiDeviceInteliHD || _mediaEncoder.IsVaapiDeviceInteli965; @@ -1317,6 +1322,20 @@ namespace MediaBrowser.Controller.MediaEncoding } else if (string.Equals(encodingOptions.HardwareAccelerationType, "qsv", StringComparison.OrdinalIgnoreCase)) { + if (OperatingSystem.IsLinux() && Environment.OSVersion.Version >= _minKernelVersioni915Hang) + { + var vidDecoder = GetHardwareVideoDecoder(state, encodingOptions) ?? string.Empty; + var isIntelDecoder = vidDecoder.Contains("qsv", StringComparison.OrdinalIgnoreCase) + || vidDecoder.Contains("vaapi", StringComparison.OrdinalIgnoreCase); + var doOclTonemap = _mediaEncoder.SupportsHwaccel("qsv") + && IsVaapiSupported(state) + && IsOpenclFullSupported() + && !IsVaapiVppTonemapAvailable(state, encodingOptions) + && IsHwTonemapAvailable(state, encodingOptions); + + enableWaFori915Hang = isIntelDecoder && doOclTonemap; + } + if (string.Equals(videoEncoder, "h264_qsv", StringComparison.OrdinalIgnoreCase)) { intelLowPowerHwEncoding = encodingOptions.EnableIntelLowPowerH264HwEncoder; @@ -1325,6 +1344,10 @@ namespace MediaBrowser.Controller.MediaEncoding { intelLowPowerHwEncoding = encodingOptions.EnableIntelLowPowerHevcHwEncoder; } + else + { + enableWaFori915Hang = false; + } } if (intelLowPowerHwEncoding) @@ -1332,6 +1355,11 @@ namespace MediaBrowser.Controller.MediaEncoding param += " -low_power 1"; } + if (enableWaFori915Hang) + { + param += " -async_depth 1"; + } + var isVc1 = string.Equals(state.VideoStream?.Codec, "vc1", StringComparison.OrdinalIgnoreCase); var isLibX265 = string.Equals(videoEncoder, "libx265", StringComparison.OrdinalIgnoreCase); -- cgit v1.2.3 From d5ea136dc5cf41c824eb0c09afca93f5804db4be Mon Sep 17 00:00:00 2001 From: Joshua Boniface Date: Mon, 1 Aug 2022 14:25:45 -0400 Subject: Backport pull request #8174 from jellyfin/release-10.8.z Disable auto inserted SW scaler for HW decoders Authored-by: nyanmisaka Merged-by: Bond-009 Original-merge: 7297431f23a0fa1ab5aa15df93d91096a09c4f21 --- Jellyfin.Api/Controllers/DynamicHlsController.cs | 3 ++- MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs | 7 +++++++ 2 files changed, 9 insertions(+), 1 deletion(-) (limited to 'MediaBrowser.Controller/MediaEncoding') diff --git a/Jellyfin.Api/Controllers/DynamicHlsController.cs b/Jellyfin.Api/Controllers/DynamicHlsController.cs index 365e44e1a3..1e8d038751 100644 --- a/Jellyfin.Api/Controllers/DynamicHlsController.cs +++ b/Jellyfin.Api/Controllers/DynamicHlsController.cs @@ -1790,7 +1790,8 @@ namespace Jellyfin.Api.Controllers || string.Equals(codec, "hevc", StringComparison.OrdinalIgnoreCase)) { if (EncodingHelper.IsCopyCodec(codec) - && (string.Equals(state.VideoStream.CodecTag, "dovi", StringComparison.OrdinalIgnoreCase) + && (string.Equals(state.VideoStream.VideoRangeType, "DOVI", StringComparison.OrdinalIgnoreCase) + || string.Equals(state.VideoStream.CodecTag, "dovi", StringComparison.OrdinalIgnoreCase) || string.Equals(state.VideoStream.CodecTag, "dvh1", StringComparison.OrdinalIgnoreCase) || string.Equals(state.VideoStream.CodecTag, "dvhe", StringComparison.OrdinalIgnoreCase))) { diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index 1d65f9a345..7c59fa300d 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -931,6 +931,13 @@ namespace MediaBrowser.Controller.MediaEncoding arg.Append(" -i \"").Append(state.AudioStream.Path).Append('"'); } + // Disable auto inserted SW scaler for HW decoders in case of changed resolution. + var isSwDecoder = string.IsNullOrEmpty(GetHardwareVideoDecoder(state, options)); + if (!isSwDecoder) + { + arg.Append(" -autoscale 0"); + } + return arg.ToString(); } -- cgit v1.2.3 From 3e5cf9395fb9493a4a4324c1dde5390fb85870a4 Mon Sep 17 00:00:00 2001 From: Shadowghost Date: Sat, 13 Aug 2022 21:46:33 -0400 Subject: Backport pull request #8182 from jellyfin/release-10.8.z Extract external subs from container before determining characterset Original-merge: 1faee43b1103428392d305cb0d1b46ff3ab6b5fc Merged-by: Bond-009 Backported-by: Joshua Boniface --- .../MediaEncoding/EncodingHelper.cs | 13 ++-- .../MediaEncoding/ISubtitleEncoder.cs | 9 ++- .../Subtitles/SubtitleEncoder.cs | 89 ++++++++++++---------- 3 files changed, 60 insertions(+), 51 deletions(-) (limited to 'MediaBrowser.Controller/MediaEncoding') diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index 7c59fa300d..e5aae620ac 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -1152,16 +1152,15 @@ namespace MediaBrowser.Controller.MediaEncoding if (state.SubtitleStream.IsExternal) { - var subtitlePath = state.SubtitleStream.Path; var charsetParam = string.Empty; if (!string.IsNullOrEmpty(state.SubtitleStream.Language)) { var charenc = _subtitleEncoder.GetSubtitleFileCharacterSet( - subtitlePath, - state.SubtitleStream.Language, - state.MediaSource.Protocol, - CancellationToken.None).GetAwaiter().GetResult(); + state.SubtitleStream, + state.SubtitleStream.Language, + state.MediaSource, + CancellationToken.None).GetAwaiter().GetResult(); if (!string.IsNullOrEmpty(charenc)) { @@ -1173,7 +1172,7 @@ namespace MediaBrowser.Controller.MediaEncoding return string.Format( CultureInfo.InvariantCulture, "subtitles=f='{0}'{1}{2}{3}{4}{5}", - _mediaEncoder.EscapeSubtitleFilterPath(subtitlePath), + _mediaEncoder.EscapeSubtitleFilterPath(state.SubtitleStream.Path), charsetParam, alphaParam, sub2videoParam, @@ -5536,7 +5535,7 @@ namespace MediaBrowser.Controller.MediaEncoding return index; } - if (string.Equals(currentMediaStream.Path, streamToFind.Path, StringComparison.Ordinal)) + if (string.Equals(currentMediaStream.Path, streamToFind.Path, StringComparison.Ordinal)) { index++; } diff --git a/MediaBrowser.Controller/MediaEncoding/ISubtitleEncoder.cs b/MediaBrowser.Controller/MediaEncoding/ISubtitleEncoder.cs index 4483cf708a..5bf83a9e31 100644 --- a/MediaBrowser.Controller/MediaEncoding/ISubtitleEncoder.cs +++ b/MediaBrowser.Controller/MediaEncoding/ISubtitleEncoder.cs @@ -6,7 +6,8 @@ using System.IO; using System.Threading; using System.Threading.Tasks; using MediaBrowser.Controller.Entities; -using MediaBrowser.Model.MediaInfo; +using MediaBrowser.Model.Dto; +using MediaBrowser.Model.Entities; namespace MediaBrowser.Controller.MediaEncoding { @@ -37,11 +38,11 @@ namespace MediaBrowser.Controller.MediaEncoding /// /// Gets the subtitle language encoding parameter. /// - /// The path. + /// The subtitle stream. /// The language. - /// The protocol. + /// The media source. /// The cancellation token. /// System.String. - Task GetSubtitleFileCharacterSet(string path, string language, MediaProtocol protocol, CancellationToken cancellationToken); + Task GetSubtitleFileCharacterSet(MediaStream subtitleStream, string language, MediaSourceInfo mediaSource, CancellationToken cancellationToken); } } diff --git a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs index 50c4d92103..6112fda680 100644 --- a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs +++ b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs @@ -241,7 +241,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles // Convert var outputPath = GetSubtitleCachePath(mediaSource, subtitleStream.Index, ".srt"); - await ConvertTextSubtitleToSrt(subtitleStream.Path, subtitleStream.Language, mediaSource, outputPath, cancellationToken).ConfigureAwait(false); + await ConvertTextSubtitleToSrt(subtitleStream, mediaSource, outputPath, cancellationToken).ConfigureAwait(false); return new SubtitleInfo(outputPath, MediaProtocol.File, "srt", true); } @@ -320,13 +320,12 @@ namespace MediaBrowser.MediaEncoding.Subtitles /// /// Converts the text subtitle to SRT. /// - /// The input path. - /// The language. + /// The subtitle stream. /// The input mediaSource. /// The output path. /// The cancellation token. /// Task. - private async Task ConvertTextSubtitleToSrt(string inputPath, string language, MediaSourceInfo mediaSource, string outputPath, CancellationToken cancellationToken) + private async Task ConvertTextSubtitleToSrt(MediaStream subtitleStream, MediaSourceInfo mediaSource, string outputPath, CancellationToken cancellationToken) { var semaphore = GetLock(outputPath); @@ -336,7 +335,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles { if (!File.Exists(outputPath)) { - await ConvertTextSubtitleToSrtInternal(inputPath, language, mediaSource, outputPath, cancellationToken).ConfigureAwait(false); + await ConvertTextSubtitleToSrtInternal(subtitleStream, mediaSource, outputPath, cancellationToken).ConfigureAwait(false); } } finally @@ -348,8 +347,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles /// /// Converts the text subtitle to SRT internal. /// - /// The input path. - /// The language. + /// The subtitle stream. /// The input mediaSource. /// The output path. /// The cancellation token. @@ -357,8 +355,9 @@ namespace MediaBrowser.MediaEncoding.Subtitles /// /// The inputPath or outputPath is null. /// - private async Task ConvertTextSubtitleToSrtInternal(string inputPath, string language, MediaSourceInfo mediaSource, string outputPath, CancellationToken cancellationToken) + private async Task ConvertTextSubtitleToSrtInternal(MediaStream subtitleStream, MediaSourceInfo mediaSource, string outputPath, CancellationToken cancellationToken) { + var inputPath = subtitleStream.Path; if (string.IsNullOrEmpty(inputPath)) { throw new ArgumentNullException(nameof(inputPath)); @@ -371,7 +370,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles Directory.CreateDirectory(Path.GetDirectoryName(outputPath) ?? throw new ArgumentException($"Provided path ({outputPath}) is not valid.", nameof(outputPath))); - var encodingParam = await GetSubtitleFileCharacterSet(inputPath, language, mediaSource.Protocol, cancellationToken).ConfigureAwait(false); + var encodingParam = await GetSubtitleFileCharacterSet(subtitleStream, subtitleStream.Language, mediaSource, cancellationToken).ConfigureAwait(false); // FFmpeg automatically convert character encoding when it is UTF-16 // If we specify character encoding, it rejects with "do not specify a character encoding" and "Unable to recode subtitle event" @@ -389,18 +388,18 @@ namespace MediaBrowser.MediaEncoding.Subtitles int exitCode; using (var process = new Process + { + StartInfo = new ProcessStartInfo { - StartInfo = new ProcessStartInfo - { - CreateNoWindow = true, - UseShellExecute = false, - FileName = _mediaEncoder.EncoderPath, - Arguments = string.Format(CultureInfo.InvariantCulture, "{0} -i \"{1}\" -c:s srt \"{2}\"", encodingParam, inputPath, outputPath), - WindowStyle = ProcessWindowStyle.Hidden, - ErrorDialog = false - }, - EnableRaisingEvents = true - }) + CreateNoWindow = true, + UseShellExecute = false, + FileName = _mediaEncoder.EncoderPath, + Arguments = string.Format(CultureInfo.InvariantCulture, "{0} -i \"{1}\" -c:s srt \"{2}\"", encodingParam, inputPath, outputPath), + WindowStyle = ProcessWindowStyle.Hidden, + ErrorDialog = false + }, + EnableRaisingEvents = true + }) { _logger.LogInformation("{0} {1}", process.StartInfo.FileName, process.StartInfo.Arguments); @@ -540,7 +539,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles var processArgs = string.Format( CultureInfo.InvariantCulture, - "-i {0} -map 0:{1} -an -vn -c:s {2} \"{3}\"", + "-i {0} -copyts -map 0:{1} -an -vn -c:s {2} \"{3}\"", inputPath, subtitleStreamIndex, outputCodec, @@ -549,18 +548,18 @@ namespace MediaBrowser.MediaEncoding.Subtitles int exitCode; using (var process = new Process + { + StartInfo = new ProcessStartInfo { - StartInfo = new ProcessStartInfo - { - CreateNoWindow = true, - UseShellExecute = false, - FileName = _mediaEncoder.EncoderPath, - Arguments = processArgs, - WindowStyle = ProcessWindowStyle.Hidden, - ErrorDialog = false - }, - EnableRaisingEvents = true - }) + CreateNoWindow = true, + UseShellExecute = false, + FileName = _mediaEncoder.EncoderPath, + Arguments = processArgs, + WindowStyle = ProcessWindowStyle.Hidden, + ErrorDialog = false + }, + EnableRaisingEvents = true + }) { _logger.LogInformation("{File} {Arguments}", process.StartInfo.FileName, process.StartInfo.Arguments); @@ -698,9 +697,19 @@ namespace MediaBrowser.MediaEncoding.Subtitles } /// - public async Task GetSubtitleFileCharacterSet(string path, string language, MediaProtocol protocol, CancellationToken cancellationToken) + public async Task GetSubtitleFileCharacterSet(MediaStream subtitleStream, string language, MediaSourceInfo mediaSource, CancellationToken cancellationToken) { - using (var stream = await GetStream(path, protocol, cancellationToken).ConfigureAwait(false)) + var subtitleCodec = subtitleStream.Codec; + var path = subtitleStream.Path; + + if (path.EndsWith(".mks", StringComparison.OrdinalIgnoreCase)) + { + path = GetSubtitleCachePath(mediaSource, subtitleStream.Index, "." + subtitleCodec); + await ExtractTextSubtitle(mediaSource, subtitleStream, subtitleCodec, path, cancellationToken) + .ConfigureAwait(false); + } + + using (var stream = await GetStream(path, mediaSource.Protocol, cancellationToken).ConfigureAwait(false)) { var charset = CharsetDetector.DetectFromStream(stream).Detected?.EncodingName ?? string.Empty; @@ -723,12 +732,12 @@ namespace MediaBrowser.MediaEncoding.Subtitles switch (protocol) { case MediaProtocol.Http: - { - using var response = await _httpClientFactory.CreateClient(NamedClient.Default) - .GetAsync(new Uri(path), cancellationToken) - .ConfigureAwait(false); - return await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false); - } + { + using var response = await _httpClientFactory.CreateClient(NamedClient.Default) + .GetAsync(new Uri(path), cancellationToken) + .ConfigureAwait(false); + return await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false); + } case MediaProtocol.File: return AsyncFile.OpenRead(path); -- cgit v1.2.3 From 9ec2870b1034e0b64ebde3e29a3779c7f6bb2ac4 Mon Sep 17 00:00:00 2001 From: luz paz Date: Mon, 15 Aug 2022 06:48:34 -0400 Subject: Fix various typos Found via `codespell -q 3 -S ./Emby.Server.Implementations/Localization -L allready,doesnt,inh,receivedfrom,whoknows` --- Emby.Dlna/Didl/DidlBuilder.cs | 2 +- Emby.Dlna/DlnaManager.cs | 2 +- Emby.Dlna/IDlnaEventManager.cs | 4 ++-- Emby.Server.Implementations/Library/LibraryManager.cs | 2 +- .../Library/Resolvers/Movies/MovieResolver.cs | 2 +- Emby.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs | 2 +- Emby.Server.Implementations/Session/SessionManager.cs | 2 +- .../Session/SessionWebSocketListener.cs | 2 +- Jellyfin.Api/Controllers/AudioController.cs | 2 +- Jellyfin.Api/Controllers/DynamicHlsController.cs | 4 ++-- Jellyfin.Api/Controllers/SearchController.cs | 6 +++--- Jellyfin.Api/Controllers/UserController.cs | 2 +- Jellyfin.Api/Models/StreamingDtos/StreamState.cs | 2 +- .../Models/SyncPlayDtos/RemoveFromPlaylistRequestDto.cs | 4 ++-- Jellyfin.Drawing.Skia/SkiaHelper.cs | 2 +- Jellyfin.Networking/Configuration/NetworkConfiguration.cs | 2 +- Jellyfin.Networking/Manager/NetworkManager.cs | 2 +- MediaBrowser.Controller/Entities/TV/Season.cs | 2 +- MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs | 4 ++-- .../SyncPlay/GroupStates/WaitingGroupState.cs | 2 +- .../PlaybackRequests/RemoveFromPlaylistGroupRequest.cs | 4 ++-- MediaBrowser.Controller/SyncPlay/Queue/PlayQueueManager.cs | 4 ++-- MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs | 4 ++-- MediaBrowser.Model/Dlna/ContentFeatureBuilder.cs | 2 +- MediaBrowser.Model/Dto/BaseItemDto.cs | 6 +++--- MediaBrowser.Model/Entities/MediaStream.cs | 2 +- MediaBrowser.Model/SyncPlay/GroupStateType.cs | 2 +- MediaBrowser.Model/Tasks/ITaskManager.cs | 10 +++++----- MediaBrowser.Model/Tasks/ITaskTrigger.cs | 4 ++-- MediaBrowser.Providers/Manager/ProviderManager.cs | 2 +- .../Plugins/MusicBrainz/MusicBrainzAlbumProvider.cs | 2 +- MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs | 2 +- src/Jellyfin.Extensions/SplitStringExtensions.cs | 2 +- src/Jellyfin.Extensions/StringExtensions.cs | 2 +- tests/Jellyfin.Model.Tests/Cryptography/PasswordHashTests.cs | 6 +++--- tests/Jellyfin.Networking.Tests/NetworkParseTests.cs | 2 +- .../LiveTv/SchedulesDirect/SchedulesDirectDeserializeTests.cs | 2 +- .../Test Data/Updates/manifest-stable.json | 2 +- 38 files changed, 56 insertions(+), 56 deletions(-) (limited to 'MediaBrowser.Controller/MediaEncoding') diff --git a/Emby.Dlna/Didl/DidlBuilder.cs b/Emby.Dlna/Didl/DidlBuilder.cs index df6539a5a6..8e3a335c66 100644 --- a/Emby.Dlna/Didl/DidlBuilder.cs +++ b/Emby.Dlna/Didl/DidlBuilder.cs @@ -446,7 +446,7 @@ namespace Emby.Dlna.Didl /// /// /// If context is a season, this will return a string containing just episode number and name. - /// Otherwise the result will include series nams and season number. + /// Otherwise the result will include series names and season number. /// /// The episode. /// Current context. diff --git a/Emby.Dlna/DlnaManager.cs b/Emby.Dlna/DlnaManager.cs index fe78d74ee7..74624334bb 100644 --- a/Emby.Dlna/DlnaManager.cs +++ b/Emby.Dlna/DlnaManager.cs @@ -123,7 +123,7 @@ namespace Emby.Dlna /// /// Attempts to match a device with a profile. /// Rules: - /// - If the profile field has no value, the field matches irregardless of its contents. + /// - If the profile field has no value, the field matches regardless of its contents. /// - the profile field can be an exact match, or a reg exp. /// /// The of the device. diff --git a/Emby.Dlna/IDlnaEventManager.cs b/Emby.Dlna/IDlnaEventManager.cs index 33cf0896ba..eea030d6d1 100644 --- a/Emby.Dlna/IDlnaEventManager.cs +++ b/Emby.Dlna/IDlnaEventManager.cs @@ -16,7 +16,7 @@ namespace Emby.Dlna /// /// The subscription identifier. /// The notification type. - /// The requested timeout as a sting. + /// The requested timeout as a string. /// The callback url. /// The response. EventSubscriptionResponse RenewEventSubscription(string subscriptionId, string notificationType, string requestedTimeoutString, string callbackUrl); @@ -25,7 +25,7 @@ namespace Emby.Dlna /// Creates the event subscription. /// /// The notification type. - /// The requested timeout as a sting. + /// The requested timeout as a string. /// The callback url. /// The response. EventSubscriptionResponse CreateEventSubscription(string notificationType, string requestedTimeoutString, string callbackUrl); diff --git a/Emby.Server.Implementations/Library/LibraryManager.cs b/Emby.Server.Implementations/Library/LibraryManager.cs index 2843fb8f83..6796845525 100644 --- a/Emby.Server.Implementations/Library/LibraryManager.cs +++ b/Emby.Server.Implementations/Library/LibraryManager.cs @@ -2529,7 +2529,7 @@ namespace Emby.Server.Implementations.Library } catch (Exception ex) { - _logger.LogError(ex, "Error reading the episode informations with ffprobe. Episode: {EpisodeInfo}", episodeInfo.Path); + _logger.LogError(ex, "Error reading the episode information with ffprobe. Episode: {EpisodeInfo}", episodeInfo.Path); } var changed = false; diff --git a/Emby.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs b/Emby.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs index a60251dacd..b2f388a667 100644 --- a/Emby.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs +++ b/Emby.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs @@ -387,7 +387,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies if (!string.IsNullOrEmpty(item.Path)) { - // check for imdb id - we use full media path, as we can assume, that this will match in any use case (wither id in parent dir or in file name) + // check for imdb id - we use full media path, as we can assume, that this will match in any use case (either id in parent dir or in file name) var imdbid = item.Path.AsSpan().GetAttributeValue("imdbid"); if (!string.IsNullOrWhiteSpace(imdbid)) diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs index 708ff52d79..be06356a4f 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs @@ -199,7 +199,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts if (string.IsNullOrWhiteSpace(numberString)) { // Using this as a fallback now as this leads to Problems with channels like "5 USA" - // where 5 isn't ment to be the channel number + // where 5 isn't meant to be the channel number // Check for channel number with the format from SatIp // #EXTINF:0,84. VOX Schweiz // #EXTINF:0,84.0 - VOX Schweiz diff --git a/Emby.Server.Implementations/Session/SessionManager.cs b/Emby.Server.Implementations/Session/SessionManager.cs index d25376297f..7f927e2709 100644 --- a/Emby.Server.Implementations/Session/SessionManager.cs +++ b/Emby.Server.Implementations/Session/SessionManager.cs @@ -1242,7 +1242,7 @@ namespace Emby.Server.Implementations.Session if (item == null) { - _logger.LogError("A non-existant item Id {0} was passed into TranslateItemForPlayback", id); + _logger.LogError("A non-existent item Id {0} was passed into TranslateItemForPlayback", id); return Array.Empty(); } diff --git a/Emby.Server.Implementations/Session/SessionWebSocketListener.cs b/Emby.Server.Implementations/Session/SessionWebSocketListener.cs index a085ee546d..fccf50f60f 100644 --- a/Emby.Server.Implementations/Session/SessionWebSocketListener.cs +++ b/Emby.Server.Implementations/Session/SessionWebSocketListener.cs @@ -37,7 +37,7 @@ namespace Emby.Server.Implementations.Session private const float ForceKeepAliveFactor = 0.75f; /// - /// Lock used for accesing the KeepAlive cancellation token. + /// Lock used for accessing the KeepAlive cancellation token. /// private readonly object _keepAliveLock = new object(); diff --git a/Jellyfin.Api/Controllers/AudioController.cs b/Jellyfin.Api/Controllers/AudioController.cs index 54ac06276e..94f7a7b827 100644 --- a/Jellyfin.Api/Controllers/AudioController.cs +++ b/Jellyfin.Api/Controllers/AudioController.cs @@ -207,7 +207,7 @@ namespace Jellyfin.Api.Controllers /// Optional. The dlna device profile id to utilize. /// The play session id. /// The segment container. - /// The segment lenght. + /// The segment length. /// The minimum number of segments. /// The media version id, if playing an alternate version. /// The device id of the client requesting. Used to stop encoding processes when needed. diff --git a/Jellyfin.Api/Controllers/DynamicHlsController.cs b/Jellyfin.Api/Controllers/DynamicHlsController.cs index 1e8d038751..3ed80f6621 100644 --- a/Jellyfin.Api/Controllers/DynamicHlsController.cs +++ b/Jellyfin.Api/Controllers/DynamicHlsController.cs @@ -121,7 +121,7 @@ namespace Jellyfin.Api.Controllers /// Optional. The dlna device profile id to utilize. /// The play session id. /// The segment container. - /// The segment lenght. + /// The segment length. /// The minimum number of segments. /// The media version id, if playing an alternate version. /// The device id of the client requesting. Used to stop encoding processes when needed. @@ -1832,7 +1832,7 @@ namespace Jellyfin.Api.Controllers // Set the key frame params for video encoding to match the hls segment time. args += _encodingHelper.GetHlsVideoKeyFrameArguments(state, codec, state.SegmentLength, isEventPlaylist, startNumber); - // Currenly b-frames in libx265 breaks the FMP4-HLS playback on iOS, disable it for now. + // Currently b-frames in libx265 breaks the FMP4-HLS playback on iOS, disable it for now. if (string.Equals(codec, "libx265", StringComparison.OrdinalIgnoreCase)) { args += " -bf 0"; diff --git a/Jellyfin.Api/Controllers/SearchController.cs b/Jellyfin.Api/Controllers/SearchController.cs index 07e113ad3e..3b1f7a52ab 100644 --- a/Jellyfin.Api/Controllers/SearchController.cs +++ b/Jellyfin.Api/Controllers/SearchController.cs @@ -60,9 +60,9 @@ namespace Jellyfin.Api.Controllers /// Optional. The maximum number of records to return. /// Optional. Supply a user id to search within a user's library or omit to search all. /// The search term to filter on. - /// If specified, only results with the specified item types are returned. This allows multiple, comma delimeted. - /// If specified, results with these item types are filtered out. This allows multiple, comma delimeted. - /// If specified, only results with the specified media types are returned. This allows multiple, comma delimeted. + /// If specified, only results with the specified item types are returned. This allows multiple, comma delimited. + /// If specified, results with these item types are filtered out. This allows multiple, comma delimited. + /// If specified, only results with the specified media types are returned. This allows multiple, comma delimited. /// If specified, only children of the parent are returned. /// Optional filter for movies. /// Optional filter for series. diff --git a/Jellyfin.Api/Controllers/UserController.cs b/Jellyfin.Api/Controllers/UserController.cs index 82c8563a80..d1109bebc8 100644 --- a/Jellyfin.Api/Controllers/UserController.cs +++ b/Jellyfin.Api/Controllers/UserController.cs @@ -502,7 +502,7 @@ namespace Jellyfin.Api.Controllers if (isLocal) { - _logger.LogWarning("Password reset proccess initiated from outside the local network with IP: {IP}", ip); + _logger.LogWarning("Password reset process initiated from outside the local network with IP: {IP}", ip); } var result = await _userManager.StartForgotPasswordProcess(forgotPasswordRequest.EnteredUsername, isLocal).ConfigureAwait(false); diff --git a/Jellyfin.Api/Models/StreamingDtos/StreamState.cs b/Jellyfin.Api/Models/StreamingDtos/StreamState.cs index 192f33ebd1..8182e3c9e8 100644 --- a/Jellyfin.Api/Models/StreamingDtos/StreamState.cs +++ b/Jellyfin.Api/Models/StreamingDtos/StreamState.cs @@ -169,7 +169,7 @@ namespace Jellyfin.Api.Models.StreamingDtos /// /// Disposes the stream state. /// - /// Whether the object is currently beeing disposed. + /// Whether the object is currently being disposed. protected virtual void Dispose(bool disposing) { if (_disposed) diff --git a/Jellyfin.Api/Models/SyncPlayDtos/RemoveFromPlaylistRequestDto.cs b/Jellyfin.Api/Models/SyncPlayDtos/RemoveFromPlaylistRequestDto.cs index 02ce5a0488..226a584e1d 100644 --- a/Jellyfin.Api/Models/SyncPlayDtos/RemoveFromPlaylistRequestDto.cs +++ b/Jellyfin.Api/Models/SyncPlayDtos/RemoveFromPlaylistRequestDto.cs @@ -17,9 +17,9 @@ namespace Jellyfin.Api.Models.SyncPlayDtos } /// - /// Gets or sets the playlist identifiers ot the items. Ignored when clearing the playlist. + /// Gets or sets the playlist identifiers of the items. Ignored when clearing the playlist. /// - /// The playlist identifiers ot the items. + /// The playlist identifiers of the items. public IReadOnlyList PlaylistItemIds { get; set; } /// diff --git a/Jellyfin.Drawing.Skia/SkiaHelper.cs b/Jellyfin.Drawing.Skia/SkiaHelper.cs index c001c32b8c..0478fc7c31 100644 --- a/Jellyfin.Drawing.Skia/SkiaHelper.cs +++ b/Jellyfin.Drawing.Skia/SkiaHelper.cs @@ -13,7 +13,7 @@ namespace Jellyfin.Drawing.Skia /// /// The current skia encoder. /// The list of image paths. - /// The current checked indes. + /// The current checked index. /// The new index. /// A valid bitmap, or null if no bitmap exists after currentIndex. public static SKBitmap? GetNextValidImage(SkiaEncoder skiaEncoder, IReadOnlyList paths, int currentIndex, out int newIndex) diff --git a/Jellyfin.Networking/Configuration/NetworkConfiguration.cs b/Jellyfin.Networking/Configuration/NetworkConfiguration.cs index 61db223d92..361dbc8142 100644 --- a/Jellyfin.Networking/Configuration/NetworkConfiguration.cs +++ b/Jellyfin.Networking/Configuration/NetworkConfiguration.cs @@ -193,7 +193,7 @@ namespace Jellyfin.Networking.Configuration public bool AutoDiscovery { get; set; } = true; /// - /// Gets or sets the filter for remote IP connectivity. Used in conjuntion with . + /// Gets or sets the filter for remote IP connectivity. Used in conjunction with . /// public string[] RemoteIPFilter { get; set; } = Array.Empty(); diff --git a/Jellyfin.Networking/Manager/NetworkManager.cs b/Jellyfin.Networking/Manager/NetworkManager.cs index 4b7b87814c..fd0665dbdd 100644 --- a/Jellyfin.Networking/Manager/NetworkManager.cs +++ b/Jellyfin.Networking/Manager/NetworkManager.cs @@ -944,7 +944,7 @@ namespace Jellyfin.Networking.Manager // Add virtual machine interface names to the list of bind exclusions, so that they are auto-excluded. if (config.IgnoreVirtualInterfaces) { - // each virtual interface name must be pre-pended with the exclusion symbol ! + // each virtual interface name must be prepended with the exclusion symbol ! var virtualInterfaceNames = config.VirtualInterfaceNames.Split(',').Select(p => "!" + p).ToArray(); if (lanAddresses.Length > 0) { diff --git a/MediaBrowser.Controller/Entities/TV/Season.cs b/MediaBrowser.Controller/Entities/TV/Season.cs index bd8df2facb..599d35da64 100644 --- a/MediaBrowser.Controller/Entities/TV/Season.cs +++ b/MediaBrowser.Controller/Entities/TV/Season.cs @@ -244,7 +244,7 @@ namespace MediaBrowser.Controller.Entities.TV /// /// This is called before any metadata refresh and returns true or false indicating if changes were made. /// - /// true to replace metdata, false to not. + /// true to replace metadata, false to not. /// true if XXXX, false otherwise. public override bool BeforeMetadataRefresh(bool replaceAllMetadata) { diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index e5aae620ac..17e410fe13 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -194,7 +194,7 @@ namespace MediaBrowser.Controller.MediaEncoding /// /// Gets the name of the output video codec. /// - /// Encording state. + /// Encoding state. /// Encoding options. /// Encoder string. public string GetVideoEncoder(EncodingJobInfo state, EncodingOptions encodingOptions) @@ -1980,7 +1980,7 @@ namespace MediaBrowser.Controller.MediaEncoding } } - // Cap the max target bitrate to intMax/2 to satisify the bufsize=bitrate*2. + // Cap the max target bitrate to intMax/2 to satisfy the bufsize=bitrate*2. return Math.Min(bitrate ?? 0, int.MaxValue / 2); } diff --git a/MediaBrowser.Controller/SyncPlay/GroupStates/WaitingGroupState.cs b/MediaBrowser.Controller/SyncPlay/GroupStates/WaitingGroupState.cs index a0c38b3097..2164945560 100644 --- a/MediaBrowser.Controller/SyncPlay/GroupStates/WaitingGroupState.cs +++ b/MediaBrowser.Controller/SyncPlay/GroupStates/WaitingGroupState.cs @@ -549,7 +549,7 @@ namespace MediaBrowser.Controller.SyncPlay.GroupStates if (InitialState.Equals(GroupStateType.Playing)) { - // Group went from playing to waiting state and a pause request occured while waiting. + // Group went from playing to waiting state and a pause request occurred while waiting. var pauseRequest = new PauseGroupRequest(); pausedState.HandleRequest(pauseRequest, context, Type, session, cancellationToken); } diff --git a/MediaBrowser.Controller/SyncPlay/PlaybackRequests/RemoveFromPlaylistGroupRequest.cs b/MediaBrowser.Controller/SyncPlay/PlaybackRequests/RemoveFromPlaylistGroupRequest.cs index 2f38d6adc3..619294e957 100644 --- a/MediaBrowser.Controller/SyncPlay/PlaybackRequests/RemoveFromPlaylistGroupRequest.cs +++ b/MediaBrowser.Controller/SyncPlay/PlaybackRequests/RemoveFromPlaylistGroupRequest.cs @@ -27,9 +27,9 @@ namespace MediaBrowser.Controller.SyncPlay.PlaybackRequests } /// - /// Gets the playlist identifiers ot the items. + /// Gets the playlist identifiers of the items. /// - /// The playlist identifiers ot the items. + /// The playlist identifiers of the items. public IReadOnlyList PlaylistItemIds { get; } /// diff --git a/MediaBrowser.Controller/SyncPlay/Queue/PlayQueueManager.cs b/MediaBrowser.Controller/SyncPlay/Queue/PlayQueueManager.cs index f49876cca4..3a7685f347 100644 --- a/MediaBrowser.Controller/SyncPlay/Queue/PlayQueueManager.cs +++ b/MediaBrowser.Controller/SyncPlay/Queue/PlayQueueManager.cs @@ -102,7 +102,7 @@ namespace MediaBrowser.Controller.SyncPlay.Queue } /// - /// Appends new items to the playlist. The specified order is mantained. + /// Appends new items to the playlist. The specified order is maintained. /// /// The items to add to the playlist. public void Queue(IReadOnlyList items) @@ -197,7 +197,7 @@ namespace MediaBrowser.Controller.SyncPlay.Queue } /// - /// Adds new items to the playlist right after the playing item. The specified order is mantained. + /// Adds new items to the playlist right after the playing item. The specified order is maintained. /// /// The items to add to the playlist. public void QueueNext(IReadOnlyList items) diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs index 77b97c9b48..7f301a9d8b 100644 --- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs @@ -619,9 +619,9 @@ namespace MediaBrowser.MediaEncoding.Encoder Video3DFormat.HalfSideBySide => "crop=iw/2:ih:0:0,scale=(iw*2):ih,setdar=dar=a,crop=min(iw\\,ih*dar):min(ih\\,iw/dar):(iw-min(iw\\,iw*sar))/2:(ih - min (ih\\,ih/sar))/2,setsar=sar=1", // fsbs crop width in half,set the display aspect,crop out any black bars we may have made Video3DFormat.FullSideBySide => "crop=iw/2:ih:0:0,setdar=dar=a,crop=min(iw\\,ih*dar):min(ih\\,iw/dar):(iw-min(iw\\,iw*sar))/2:(ih - min (ih\\,ih/sar))/2,setsar=sar=1", - // htab crop heigh in half,scale to correct size, set the display aspect,crop out any black bars we may have made + // htab crop height in half,scale to correct size, set the display aspect,crop out any black bars we may have made Video3DFormat.HalfTopAndBottom => "crop=iw:ih/2:0:0,scale=(iw*2):ih),setdar=dar=a,crop=min(iw\\,ih*dar):min(ih\\,iw/dar):(iw-min(iw\\,iw*sar))/2:(ih - min (ih\\,ih/sar))/2,setsar=sar=1", - // ftab crop heigt in half, set the display aspect,crop out any black bars we may have made + // ftab crop height in half, set the display aspect,crop out any black bars we may have made Video3DFormat.FullTopAndBottom => "crop=iw:ih/2:0:0,setdar=dar=a,crop=min(iw\\,ih*dar):min(ih\\,iw/dar):(iw-min(iw\\,iw*sar))/2:(ih - min (ih\\,ih/sar))/2,setsar=sar=1", _ => "scale=trunc(iw*sar):ih" }; diff --git a/MediaBrowser.Model/Dlna/ContentFeatureBuilder.cs b/MediaBrowser.Model/Dlna/ContentFeatureBuilder.cs index 47c36494bd..c32c1c108c 100644 --- a/MediaBrowser.Model/Dlna/ContentFeatureBuilder.cs +++ b/MediaBrowser.Model/Dlna/ContentFeatureBuilder.cs @@ -157,7 +157,7 @@ namespace MediaBrowser.Model.Dlna flagValue |= DlnaFlags.ByteBasedSeek; } - // Time based seek is curently disabled when streaming. On LG CX3 adding DlnaFlags.TimeBasedSeek and orgPn causes the DLNA playback to fail (format not supported). Further investigations are needed before enabling the remaining code paths. + // Time based seek is currently disabled when streaming. On LG CX3 adding DlnaFlags.TimeBasedSeek and orgPn causes the DLNA playback to fail (format not supported). Further investigations are needed before enabling the remaining code paths. // else if (runtimeTicks.HasValue) // { // flagValue = flagValue | DlnaFlags.TimeBasedSeek; diff --git a/MediaBrowser.Model/Dto/BaseItemDto.cs b/MediaBrowser.Model/Dto/BaseItemDto.cs index 094dc73b27..fdb84fa320 100644 --- a/MediaBrowser.Model/Dto/BaseItemDto.cs +++ b/MediaBrowser.Model/Dto/BaseItemDto.cs @@ -294,13 +294,13 @@ namespace MediaBrowser.Model.Dto public NameGuidPair[] GenreItems { get; set; } /// - /// Gets or sets wether the item has a logo, this will hold the Id of the Parent that has one. + /// Gets or sets whether the item has a logo, this will hold the Id of the Parent that has one. /// /// The parent logo item id. public Guid? ParentLogoItemId { get; set; } /// - /// Gets or sets wether the item has any backdrops, this will hold the Id of the Parent that has one. + /// Gets or sets whether the item has any backdrops, this will hold the Id of the Parent that has one. /// /// The parent backdrop item id. public Guid? ParentBackdropItemId { get; set; } @@ -506,7 +506,7 @@ namespace MediaBrowser.Model.Dto public string ParentLogoImageTag { get; set; } /// - /// Gets or sets wether the item has fan art, this will hold the Id of the Parent that has one. + /// Gets or sets whether the item has fan art, this will hold the Id of the Parent that has one. /// /// The parent art item id. public Guid? ParentArtItemId { get; set; } diff --git a/MediaBrowser.Model/Entities/MediaStream.cs b/MediaBrowser.Model/Entities/MediaStream.cs index ae8f3b0edf..90a60cf470 100644 --- a/MediaBrowser.Model/Entities/MediaStream.cs +++ b/MediaBrowser.Model/Entities/MediaStream.cs @@ -606,7 +606,7 @@ namespace MediaBrowser.Model.Entities <= 1024 when Height <= 576 => IsInterlaced ? "576i" : "576p", // 1280x720 <= 1280 when Height <= 962 => IsInterlaced ? "720i" : "720p", - // 2560x1080 (FHD ultra wide 21:9) using 1440px width to accomodate WQHD + // 2560x1080 (FHD ultra wide 21:9) using 1440px width to accommodate WQHD <= 2560 when Height <= 1440 => IsInterlaced ? "1080i" : "1080p", // 4K <= 4096 when Height <= 3072 => "4K", diff --git a/MediaBrowser.Model/SyncPlay/GroupStateType.cs b/MediaBrowser.Model/SyncPlay/GroupStateType.cs index 7aa454f928..96364cacc7 100644 --- a/MediaBrowser.Model/SyncPlay/GroupStateType.cs +++ b/MediaBrowser.Model/SyncPlay/GroupStateType.cs @@ -11,7 +11,7 @@ namespace MediaBrowser.Model.SyncPlay Idle = 0, /// - /// The group is in wating state. Playback is paused. Will start playing when users are ready. + /// The group is in waiting state. Playback is paused. Will start playing when users are ready. /// Waiting = 1, diff --git a/MediaBrowser.Model/Tasks/ITaskManager.cs b/MediaBrowser.Model/Tasks/ITaskManager.cs index a86bf2a1c8..13bebc479e 100644 --- a/MediaBrowser.Model/Tasks/ITaskManager.cs +++ b/MediaBrowser.Model/Tasks/ITaskManager.cs @@ -22,7 +22,7 @@ namespace MediaBrowser.Model.Tasks /// /// Cancels if running and queue. /// - /// An implementatin of . + /// An implementation of . /// Task options. void CancelIfRunningAndQueue(TaskOptions options) where T : IScheduledTask; @@ -30,21 +30,21 @@ namespace MediaBrowser.Model.Tasks /// /// Cancels if running and queue. /// - /// An implementatin of . + /// An implementation of . void CancelIfRunningAndQueue() where T : IScheduledTask; /// /// Cancels if running. /// - /// An implementatin of . + /// An implementation of . void CancelIfRunning() where T : IScheduledTask; /// /// Queues the scheduled task. /// - /// An implementatin of . + /// An implementation of . /// Task options. void QueueScheduledTask(TaskOptions options) where T : IScheduledTask; @@ -52,7 +52,7 @@ namespace MediaBrowser.Model.Tasks /// /// Queues the scheduled task. /// - /// An implementatin of . + /// An implementation of . void QueueScheduledTask() where T : IScheduledTask; diff --git a/MediaBrowser.Model/Tasks/ITaskTrigger.cs b/MediaBrowser.Model/Tasks/ITaskTrigger.cs index 8c3ec6626c..0536f4ef77 100644 --- a/MediaBrowser.Model/Tasks/ITaskTrigger.cs +++ b/MediaBrowser.Model/Tasks/ITaskTrigger.cs @@ -21,10 +21,10 @@ namespace MediaBrowser.Model.Tasks /// /// Stars waiting for the trigger action. /// - /// Result of the last run triggerd task. + /// Result of the last run triggered task. /// The . /// The name of the task. - /// Wheter or not this is is fired during startup. + /// Whether or not this is is fired during startup. void Start(TaskResult? lastResult, ILogger logger, string taskName, bool isApplicationStartup); /// diff --git a/MediaBrowser.Providers/Manager/ProviderManager.cs b/MediaBrowser.Providers/Manager/ProviderManager.cs index 01ff473f0c..bbb33ddf0e 100644 --- a/MediaBrowser.Providers/Manager/ProviderManager.cs +++ b/MediaBrowser.Providers/Manager/ProviderManager.cs @@ -926,7 +926,7 @@ namespace MediaBrowser.Providers.Manager } catch (Exception ex) { - _logger.LogError(ex, "Error in {0}.Suports", i.GetType().Name); + _logger.LogError(ex, "Error in {0}.Supports", i.GetType().Name); return false; } }); diff --git a/MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzAlbumProvider.cs b/MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzAlbumProvider.cs index 4bf66c0988..915fb97fd2 100644 --- a/MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzAlbumProvider.cs +++ b/MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzAlbumProvider.cs @@ -36,7 +36,7 @@ namespace MediaBrowser.Providers.Music /// /// The Jellyfin user-agent is unrestricted but source IP must not exceed /// one request per second, therefore we rate limit to avoid throttling. - /// Be prudent, use a value slightly above the minimun required. + /// Be prudent, use a value slightly above the minimum required. /// https://musicbrainz.org/doc/XML_Web_Service/Rate_Limiting. /// private readonly long _musicBrainzQueryIntervalMs; diff --git a/MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs b/MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs index 09ff84044d..da348239a1 100644 --- a/MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs +++ b/MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs @@ -1330,7 +1330,7 @@ namespace MediaBrowser.XbmcMetadata.Parsers }; /// - /// Used to split names of comma or pipe delimeted genres and people. + /// Used to split names of comma or pipe delimited genres and people. /// /// The value. /// IEnumerable{System.String}. diff --git a/src/Jellyfin.Extensions/SplitStringExtensions.cs b/src/Jellyfin.Extensions/SplitStringExtensions.cs index 1d1c377f56..a4dc9fc6b1 100644 --- a/src/Jellyfin.Extensions/SplitStringExtensions.cs +++ b/src/Jellyfin.Extensions/SplitStringExtensions.cs @@ -55,7 +55,7 @@ namespace Jellyfin.Extensions public static Enumerator Split(this ReadOnlySpan str, char separator) => new(str, separator); /// - /// Provides an enumerator for the substrings seperated by the separator. + /// Provides an enumerator for the substrings separated by the separator. /// [StructLayout(LayoutKind.Auto)] public ref struct Enumerator diff --git a/src/Jellyfin.Extensions/StringExtensions.cs b/src/Jellyfin.Extensions/StringExtensions.cs index dadc9f1d5c..59fb038a75 100644 --- a/src/Jellyfin.Extensions/StringExtensions.cs +++ b/src/Jellyfin.Extensions/StringExtensions.cs @@ -40,7 +40,7 @@ namespace Jellyfin.Extensions } /// - /// Checks wether or not the specified string has diacritics in it. + /// Checks whether or not the specified string has diacritics in it. /// /// The string to check. /// True if the string has diacritics, false otherwise. diff --git a/tests/Jellyfin.Model.Tests/Cryptography/PasswordHashTests.cs b/tests/Jellyfin.Model.Tests/Cryptography/PasswordHashTests.cs index 6948280a3d..162f53e567 100644 --- a/tests/Jellyfin.Model.Tests/Cryptography/PasswordHashTests.cs +++ b/tests/Jellyfin.Model.Tests/Cryptography/PasswordHashTests.cs @@ -152,9 +152,9 @@ namespace Jellyfin.Model.Tests.Cryptography [InlineData("$PBKDF2$$62FBA410AFCA5B4475F35137AB2E8596B127E4D927BA23F6CC05C067E897042D")] // Empty segment [InlineData("$PBKDF2$iterations=1000$$62FBA410AFCA5B4475F35137AB2E8596B127E4D927BA23F6CC05C067E897042D")] // Empty salt segment [InlineData("$PBKDF2$iterations=1000$69F420$")] // Empty hash segment - [InlineData("$PBKDF2$=$62FBA410AFCA5B4475F35137AB2E8596B127E4D927BA23F6CC05C067E897042D")] // Invalid parmeter - [InlineData("$PBKDF2$=1000$62FBA410AFCA5B4475F35137AB2E8596B127E4D927BA23F6CC05C067E897042D")] // Invalid parmeter - [InlineData("$PBKDF2$iterations=$62FBA410AFCA5B4475F35137AB2E8596B127E4D927BA23F6CC05C067E897042D")] // Invalid parmeter + [InlineData("$PBKDF2$=$62FBA410AFCA5B4475F35137AB2E8596B127E4D927BA23F6CC05C067E897042D")] // Invalid parameter + [InlineData("$PBKDF2$=1000$62FBA410AFCA5B4475F35137AB2E8596B127E4D927BA23F6CC05C067E897042D")] // Invalid parameter + [InlineData("$PBKDF2$iterations=$62FBA410AFCA5B4475F35137AB2E8596B127E4D927BA23F6CC05C067E897042D")] // Invalid parameter [InlineData("$PBKDF2$iterations=1000$62FBA410AFCA5B4475F35137AB2E8596B127E4D927BA23F6CC05C067E897042D$")] // Ends on $ [InlineData("$PBKDF2$iterations=1000$69F420$62FBA410AFCA5B4475F35137AB2E8596B127E4D927BA23F6CC05C067E897042D$")] // Extra segment [InlineData("$PBKDF2$iterations=1000$69F420$62FBA410AFCA5B4475F35137AB2E8596B127E4D927BA23F6CC05C067E897042D$anotherone")] // Extra segment diff --git a/tests/Jellyfin.Networking.Tests/NetworkParseTests.cs b/tests/Jellyfin.Networking.Tests/NetworkParseTests.cs index 6b93974373..52b0e5a955 100644 --- a/tests/Jellyfin.Networking.Tests/NetworkParseTests.cs +++ b/tests/Jellyfin.Networking.Tests/NetworkParseTests.cs @@ -393,7 +393,7 @@ namespace Jellyfin.Networking.Tests // User on external network, internal binding only - so assumption is a proxy forward, return external override. [InlineData("jellyfin.org", "192.168.1.0/24", "eth16", false, "0.0.0.0=http://helloworld.com", "http://helloworld.com")] - // User on external network, no binding - so result is the 1st external which is overriden. + // User on external network, no binding - so result is the 1st external which is overridden. [InlineData("jellyfin.org", "192.168.1.0/24", "", false, "0.0.0.0 = http://helloworld.com", "http://helloworld.com")] // User assumed to be internal, no binding - so result is the 1st internal. diff --git a/tests/Jellyfin.Server.Implementations.Tests/LiveTv/SchedulesDirect/SchedulesDirectDeserializeTests.cs b/tests/Jellyfin.Server.Implementations.Tests/LiveTv/SchedulesDirect/SchedulesDirectDeserializeTests.cs index 3b3e38bd1f..e1d2bb2d58 100644 --- a/tests/Jellyfin.Server.Implementations.Tests/LiveTv/SchedulesDirect/SchedulesDirectDeserializeTests.cs +++ b/tests/Jellyfin.Server.Implementations.Tests/LiveTv/SchedulesDirect/SchedulesDirectDeserializeTests.cs @@ -18,7 +18,7 @@ namespace Jellyfin.Server.Implementations.Tests.LiveTv.SchedulesDirect } /// - /// /token reponse. + /// /token response. /// [Fact] public void Deserialize_Token_Response_Live_Success() diff --git a/tests/Jellyfin.Server.Implementations.Tests/Test Data/Updates/manifest-stable.json b/tests/Jellyfin.Server.Implementations.Tests/Test Data/Updates/manifest-stable.json index b766e668e3..fa8fbd8d2c 100644 --- a/tests/Jellyfin.Server.Implementations.Tests/Test Data/Updates/manifest-stable.json +++ b/tests/Jellyfin.Server.Implementations.Tests/Test Data/Updates/manifest-stable.json @@ -253,7 +253,7 @@ "versions": [ { "version": "5.0.0.0", - "changelog": "Updated to use NextPVR API v5, no longer compatable with API v4.\n", + "changelog": "Updated to use NextPVR API v5, no longer compatible with API v4.\n", "targetAbi": "10.7.0.0", "sourceUrl": "https://repo.jellyfin.org/releases/plugin/nextpvr/nextpvr_5.0.0.0.zip", "checksum": "d70f694d14bf9462ba2b2ebe110068d3", -- cgit v1.2.3 From 0309c5622e31df7593a07880e2669bd623b71f88 Mon Sep 17 00:00:00 2001 From: nyanmisaka Date: Fri, 23 Sep 2022 23:09:35 -0400 Subject: Backport pull request #8213 from jellyfin/release-10.8.z Fix high single thread usage in throttler Original-merge: ba026716c1609941ec50a26e50ef5e68cc84d0c0 Merged-by: Claus Vium Backported-by: Joshua M. Boniface --- Jellyfin.Api/Helpers/TranscodingJobHelper.cs | 2 +- .../Models/PlaybackDtos/TranscodingThrottler.cs | 15 ++++++-- .../MediaEncoding/IMediaEncoder.cs | 6 +++ .../Encoder/EncoderValidator.cs | 43 ++++++++++++++++++---- MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs | 6 +++ 5 files changed, 59 insertions(+), 13 deletions(-) (limited to 'MediaBrowser.Controller/MediaEncoding') diff --git a/Jellyfin.Api/Helpers/TranscodingJobHelper.cs b/Jellyfin.Api/Helpers/TranscodingJobHelper.cs index 13dc878c1b..2adb006e48 100644 --- a/Jellyfin.Api/Helpers/TranscodingJobHelper.cs +++ b/Jellyfin.Api/Helpers/TranscodingJobHelper.cs @@ -654,7 +654,7 @@ namespace Jellyfin.Api.Helpers { if (EnableThrottling(state)) { - transcodingJob.TranscodingThrottler = new TranscodingThrottler(transcodingJob, new Logger(new LoggerFactory()), _serverConfigurationManager, _fileSystem); + transcodingJob.TranscodingThrottler = new TranscodingThrottler(transcodingJob, new Logger(new LoggerFactory()), _serverConfigurationManager, _fileSystem, _mediaEncoder); transcodingJob.TranscodingThrottler.Start(); } } diff --git a/Jellyfin.Api/Models/PlaybackDtos/TranscodingThrottler.cs b/Jellyfin.Api/Models/PlaybackDtos/TranscodingThrottler.cs index 7a1ca252cf..99376873c0 100644 --- a/Jellyfin.Api/Models/PlaybackDtos/TranscodingThrottler.cs +++ b/Jellyfin.Api/Models/PlaybackDtos/TranscodingThrottler.cs @@ -2,6 +2,7 @@ using System.Threading; using System.Threading.Tasks; using MediaBrowser.Common.Configuration; +using MediaBrowser.Controller.MediaEncoding; using MediaBrowser.Model.Configuration; using MediaBrowser.Model.IO; using Microsoft.Extensions.Logging; @@ -17,6 +18,7 @@ namespace Jellyfin.Api.Models.PlaybackDtos private readonly ILogger _logger; private readonly IConfigurationManager _config; private readonly IFileSystem _fileSystem; + private readonly IMediaEncoder _mediaEncoder; private Timer? _timer; private bool _isPaused; @@ -27,12 +29,14 @@ namespace Jellyfin.Api.Models.PlaybackDtos /// Instance of the interface. /// Instance of the interface. /// Instance of the interface. - public TranscodingThrottler(TranscodingJobDto job, ILogger logger, IConfigurationManager config, IFileSystem fileSystem) + /// Instance of the interface. + public TranscodingThrottler(TranscodingJobDto job, ILogger logger, IConfigurationManager config, IFileSystem fileSystem, IMediaEncoder mediaEncoder) { _job = job; _logger = logger; _config = config; _fileSystem = fileSystem; + _mediaEncoder = mediaEncoder; } /// @@ -55,7 +59,8 @@ namespace Jellyfin.Api.Models.PlaybackDtos try { - await _job.Process!.StandardInput.WriteLineAsync().ConfigureAwait(false); + var resumeKey = _mediaEncoder.IsPkeyPauseSupported ? "u" : Environment.NewLine; + await _job.Process!.StandardInput.WriteAsync(resumeKey).ConfigureAwait(false); _isPaused = false; } catch (Exception ex) @@ -125,11 +130,13 @@ namespace Jellyfin.Api.Models.PlaybackDtos { if (!_isPaused) { - _logger.LogDebug("Sending pause command to ffmpeg"); + var pauseKey = _mediaEncoder.IsPkeyPauseSupported ? "p" : "c"; + + _logger.LogDebug("Sending pause command [{Key}] to ffmpeg", pauseKey); try { - await _job.Process!.StandardInput.WriteAsync("c").ConfigureAwait(false); + await _job.Process!.StandardInput.WriteAsync(pauseKey).ConfigureAwait(false); _isPaused = true; } catch (Exception ex) diff --git a/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs b/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs index dae30cd8b3..69d0bf45cc 100644 --- a/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs +++ b/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs @@ -37,6 +37,12 @@ namespace MediaBrowser.Controller.MediaEncoding /// The version of encoder. Version EncoderVersion { get; } + /// + /// Whether p key pausing is supported. + /// + /// true if p key pausing is supported, false otherwise. + bool IsPkeyPauseSupported { get; } + /// /// Gets a value indicating whether the configured Vaapi device is from AMD(radeonsi/r600 Mesa driver). /// diff --git a/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs b/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs index d378c6e134..9b4b1db947 100644 --- a/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs +++ b/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs @@ -153,7 +153,7 @@ namespace MediaBrowser.MediaEncoding.Encoder string output; try { - output = GetProcessOutput(_encoderPath, "-version", false); + output = GetProcessOutput(_encoderPath, "-version", false, null); } catch (Exception ex) { @@ -234,7 +234,7 @@ namespace MediaBrowser.MediaEncoding.Encoder string output; try { - output = GetProcessOutput(_encoderPath, "-version", false); + output = GetProcessOutput(_encoderPath, "-version", false, null); } catch (Exception ex) { @@ -341,7 +341,7 @@ namespace MediaBrowser.MediaEncoding.Encoder try { - var output = GetProcessOutput(_encoderPath, "-v verbose -hide_banner -init_hw_device vaapi=va:" + renderNodePath, true); + var output = GetProcessOutput(_encoderPath, "-v verbose -hide_banner -init_hw_device vaapi=va:" + renderNodePath, true, null); return output.Contains(driverName, StringComparison.Ordinal); } catch (Exception ex) @@ -356,7 +356,7 @@ namespace MediaBrowser.MediaEncoding.Encoder string? output = null; try { - output = GetProcessOutput(_encoderPath, "-hwaccels", false); + output = GetProcessOutput(_encoderPath, "-hwaccels", false, null); } catch (Exception ex) { @@ -384,7 +384,7 @@ namespace MediaBrowser.MediaEncoding.Encoder string output; try { - output = GetProcessOutput(_encoderPath, "-h filter=" + filter, false); + output = GetProcessOutput(_encoderPath, "-h filter=" + filter, false, null); } catch (Exception ex) { @@ -402,13 +402,34 @@ namespace MediaBrowser.MediaEncoding.Encoder return false; } + public bool CheckSupportedRuntimeKey(string keyDesc) + { + if (string.IsNullOrEmpty(keyDesc)) + { + return false; + } + + string output; + try + { + output = GetProcessOutput(_encoderPath, "-hide_banner -f lavfi -i nullsrc=s=1x1:d=500 -f null -", true, "?"); + } + catch (Exception ex) + { + _logger.LogError(ex, "Error checking supported runtime key"); + return false; + } + + return output.Contains(keyDesc, StringComparison.Ordinal); + } + private IEnumerable GetCodecs(Codec codec) { string codecstr = codec == Codec.Encoder ? "encoders" : "decoders"; string output; try { - output = GetProcessOutput(_encoderPath, "-" + codecstr, false); + output = GetProcessOutput(_encoderPath, "-" + codecstr, false, null); } catch (Exception ex) { @@ -439,7 +460,7 @@ namespace MediaBrowser.MediaEncoding.Encoder string output; try { - output = GetProcessOutput(_encoderPath, "-filters", false); + output = GetProcessOutput(_encoderPath, "-filters", false, null); } catch (Exception ex) { @@ -477,7 +498,7 @@ namespace MediaBrowser.MediaEncoding.Encoder return dict; } - private string GetProcessOutput(string path, string arguments, bool readStdErr) + private string GetProcessOutput(string path, string arguments, bool readStdErr, string? testKey) { using (var process = new Process() { @@ -487,6 +508,7 @@ namespace MediaBrowser.MediaEncoding.Encoder UseShellExecute = false, WindowStyle = ProcessWindowStyle.Hidden, ErrorDialog = false, + RedirectStandardInput = !string.IsNullOrEmpty(testKey), RedirectStandardOutput = true, RedirectStandardError = true } @@ -496,6 +518,11 @@ namespace MediaBrowser.MediaEncoding.Encoder process.Start(); + if (!string.IsNullOrEmpty(testKey)) + { + process.StandardInput.Write(testKey); + } + return readStdErr ? process.StandardError.ReadToEnd() : process.StandardOutput.ReadToEnd(); } } diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs index 7f301a9d8b..4e9f33bd92 100644 --- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs @@ -67,6 +67,8 @@ namespace MediaBrowser.MediaEncoding.Encoder private List _filters = new List(); private IDictionary _filtersWithOption = new Dictionary(); + private bool _isPkeyPauseSupported = false; + private bool _isVaapiDeviceAmd = false; private bool _isVaapiDeviceInteliHD = false; private bool _isVaapiDeviceInteli965 = false; @@ -100,6 +102,8 @@ namespace MediaBrowser.MediaEncoding.Encoder public Version EncoderVersion => _ffmpegVersion; + public bool IsPkeyPauseSupported => _isPkeyPauseSupported; + public bool IsVaapiDeviceAmd => _isVaapiDeviceAmd; public bool IsVaapiDeviceInteliHD => _isVaapiDeviceInteliHD; @@ -154,6 +158,8 @@ namespace MediaBrowser.MediaEncoding.Encoder _threads = EncodingHelper.GetNumberOfThreads(null, options, null); + _isPkeyPauseSupported = validator.CheckSupportedRuntimeKey("p pause transcoding"); + // Check the Vaapi device vendor if (OperatingSystem.IsLinux() && SupportsHwaccel("vaapi") -- cgit v1.2.3 From e8c12e5078448b3ca8cd6a043cd529b70053b0c5 Mon Sep 17 00:00:00 2001 From: Bill Thornton Date: Fri, 23 Sep 2022 23:09:36 -0400 Subject: Backport pull request #8280 from jellyfin/release-10.8.z Fix ffmpeg analyze duration env var taking priority over media source Original-merge: 632fb05f467a935da5765fccd1595dfd501247d0 Merged-by: Claus Vium Backported-by: Joshua M. Boniface --- MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs | 8 ++++---- MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs | 10 +++++----- 2 files changed, 9 insertions(+), 9 deletions(-) (limited to 'MediaBrowser.Controller/MediaEncoding') diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index 1d10777168..42c5517f9d 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -4991,13 +4991,13 @@ namespace MediaBrowser.Controller.MediaEncoding // The default value of -probesize is more than enough, so leave it as is. var ffmpegAnalyzeDuration = _config.GetFFmpegAnalyzeDuration() ?? string.Empty; - if (!string.IsNullOrEmpty(ffmpegAnalyzeDuration)) + if (state.MediaSource.AnalyzeDurationMs > 0) { - analyzeDurationArgument = "-analyzeduration " + ffmpegAnalyzeDuration; + analyzeDurationArgument = "-analyzeduration " + (state.MediaSource.AnalyzeDurationMs.Value * 1000).ToString(CultureInfo.InvariantCulture); } - else if (state.MediaSource.AnalyzeDurationMs.HasValue) + else if (!string.IsNullOrEmpty(ffmpegAnalyzeDuration)) { - analyzeDurationArgument = "-analyzeduration " + (state.MediaSource.AnalyzeDurationMs.Value * 1000).ToString(CultureInfo.InvariantCulture); + analyzeDurationArgument = "-analyzeduration " + ffmpegAnalyzeDuration; } if (!string.IsNullOrEmpty(analyzeDurationArgument)) diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs index 4e9f33bd92..757a01715a 100644 --- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs @@ -382,15 +382,15 @@ namespace MediaBrowser.MediaEncoding.Encoder string analyzeDuration = string.Empty; string ffmpegAnalyzeDuration = _config.GetFFmpegAnalyzeDuration() ?? string.Empty; - if (!string.IsNullOrEmpty(ffmpegAnalyzeDuration)) - { - analyzeDuration = "-analyzeduration " + ffmpegAnalyzeDuration; - } - else if (request.MediaSource.AnalyzeDurationMs > 0) + if (request.MediaSource.AnalyzeDurationMs > 0) { analyzeDuration = "-analyzeduration " + (request.MediaSource.AnalyzeDurationMs * 1000).ToString(); } + else if (!string.IsNullOrEmpty(ffmpegAnalyzeDuration)) + { + analyzeDuration = "-analyzeduration " + ffmpegAnalyzeDuration; + } var forceEnableLogging = request.MediaSource.Protocol != MediaProtocol.File; -- cgit v1.2.3 From 4edeccc5e0ff391a5f8c35f5f9b81a5ca0e228de Mon Sep 17 00:00:00 2001 From: Hannes Braun Date: Wed, 28 Sep 2022 16:17:08 +0200 Subject: Remove redundant using directives --- Emby.Server.Implementations/HttpServer/Security/SessionContext.cs | 1 - Emby.Server.Implementations/HttpServer/WebSocketConnection.cs | 1 - Emby.Server.Implementations/Library/LibraryManager.cs | 1 - Emby.Server.Implementations/Session/SessionWebSocketListener.cs | 1 - Emby.Server.Implementations/Sorting/StudioComparer.cs | 1 - MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs | 1 - MediaBrowser.Controller/Net/IWebSocketConnection.cs | 1 - MediaBrowser.Controller/Playlists/Playlist.cs | 1 - MediaBrowser.MediaEncoding/Probing/MediaStreamInfoSideData.cs | 1 - MediaBrowser.MediaEncoding/Subtitles/SubtitleEditParser.cs | 2 -- MediaBrowser.Model/Branding/BrandingOptions.cs | 1 - MediaBrowser.Model/Configuration/EncodingOptions.cs | 2 -- MediaBrowser.Model/Dlna/StreamInfo.cs | 1 - src/Jellyfin.Extensions/StringExtensions.cs | 1 - src/Jellyfin.MediaEncoding.Hls/Extractors/IKeyframeExtractor.cs | 1 - tests/Jellyfin.MediaEncoding.Tests/Subtitles/AssParserTests.cs | 1 - tests/Jellyfin.MediaEncoding.Tests/Subtitles/SrtParserTests.cs | 1 - tests/Jellyfin.MediaEncoding.Tests/Subtitles/SsaParserTests.cs | 1 - tests/Jellyfin.Naming.Tests/Video/MultiVersionTests.cs | 1 - tests/Jellyfin.Naming.Tests/Video/VideoListResolverTests.cs | 1 - .../Sorting/ParentIndexNumberComparerTests.cs | 1 - tests/Jellyfin.Server.Integration.Tests/JellyfinApplicationFactory.cs | 1 - tests/Jellyfin.XbmcMetadata.Tests/Parsers/MovieNfoParserTests.cs | 1 - 23 files changed, 25 deletions(-) (limited to 'MediaBrowser.Controller/MediaEncoding') diff --git a/Emby.Server.Implementations/HttpServer/Security/SessionContext.cs b/Emby.Server.Implementations/HttpServer/Security/SessionContext.cs index 15ab363fe6..e0d20e2100 100644 --- a/Emby.Server.Implementations/HttpServer/Security/SessionContext.cs +++ b/Emby.Server.Implementations/HttpServer/Security/SessionContext.cs @@ -1,6 +1,5 @@ #pragma warning disable CS1591 -using System; using System.Threading.Tasks; using Jellyfin.Data.Entities; using MediaBrowser.Common.Extensions; diff --git a/Emby.Server.Implementations/HttpServer/WebSocketConnection.cs b/Emby.Server.Implementations/HttpServer/WebSocketConnection.cs index 818ccbb1b8..d095248fab 100644 --- a/Emby.Server.Implementations/HttpServer/WebSocketConnection.cs +++ b/Emby.Server.Implementations/HttpServer/WebSocketConnection.cs @@ -11,7 +11,6 @@ using Jellyfin.Extensions.Json; using MediaBrowser.Controller.Net; using MediaBrowser.Model.Net; using MediaBrowser.Model.Session; -using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Logging; namespace Emby.Server.Implementations.HttpServer diff --git a/Emby.Server.Implementations/Library/LibraryManager.cs b/Emby.Server.Implementations/Library/LibraryManager.cs index 250e7619fb..67f9c57658 100644 --- a/Emby.Server.Implementations/Library/LibraryManager.cs +++ b/Emby.Server.Implementations/Library/LibraryManager.cs @@ -46,7 +46,6 @@ using MediaBrowser.Model.Library; using MediaBrowser.Model.Querying; using MediaBrowser.Model.Tasks; using Microsoft.Extensions.Caching.Memory; -using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Episode = MediaBrowser.Controller.Entities.TV.Episode; using EpisodeInfo = Emby.Naming.TV.EpisodeInfo; diff --git a/Emby.Server.Implementations/Session/SessionWebSocketListener.cs b/Emby.Server.Implementations/Session/SessionWebSocketListener.cs index fccf50f60f..35fd5caae7 100644 --- a/Emby.Server.Implementations/Session/SessionWebSocketListener.cs +++ b/Emby.Server.Implementations/Session/SessionWebSocketListener.cs @@ -6,7 +6,6 @@ using System.Linq; using System.Net.WebSockets; using System.Threading; using System.Threading.Tasks; -using MediaBrowser.Common.Extensions; using MediaBrowser.Controller.Net; using MediaBrowser.Controller.Session; using MediaBrowser.Model.Net; diff --git a/Emby.Server.Implementations/Sorting/StudioComparer.cs b/Emby.Server.Implementations/Sorting/StudioComparer.cs index 4d89cfa8b2..c917daaad1 100644 --- a/Emby.Server.Implementations/Sorting/StudioComparer.cs +++ b/Emby.Server.Implementations/Sorting/StudioComparer.cs @@ -3,7 +3,6 @@ #pragma warning disable CS1591 using System; -using System.Linq; using Jellyfin.Extensions; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Sorting; diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs b/MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs index 491662861f..c9625cf1da 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs @@ -6,7 +6,6 @@ using System; using System.Collections.Generic; using System.Globalization; using System.Linq; -using System.Text.Json.Serialization; using Jellyfin.Data.Entities; using MediaBrowser.Model.Dlna; using MediaBrowser.Model.Drawing; diff --git a/MediaBrowser.Controller/Net/IWebSocketConnection.cs b/MediaBrowser.Controller/Net/IWebSocketConnection.cs index 43c7ce3708..4f2492b891 100644 --- a/MediaBrowser.Controller/Net/IWebSocketConnection.cs +++ b/MediaBrowser.Controller/Net/IWebSocketConnection.cs @@ -6,7 +6,6 @@ using System.Net.WebSockets; using System.Threading; using System.Threading.Tasks; using MediaBrowser.Model.Net; -using Microsoft.AspNetCore.Http; namespace MediaBrowser.Controller.Net { diff --git a/MediaBrowser.Controller/Playlists/Playlist.cs b/MediaBrowser.Controller/Playlists/Playlist.cs index 828ecb2c51..7ae9ff7463 100644 --- a/MediaBrowser.Controller/Playlists/Playlist.cs +++ b/MediaBrowser.Controller/Playlists/Playlist.cs @@ -4,7 +4,6 @@ using System; using System.Collections.Generic; -using System.Globalization; using System.IO; using System.Linq; using System.Text.Json.Serialization; diff --git a/MediaBrowser.MediaEncoding/Probing/MediaStreamInfoSideData.cs b/MediaBrowser.MediaEncoding/Probing/MediaStreamInfoSideData.cs index 095757bef7..5dbc438e44 100644 --- a/MediaBrowser.MediaEncoding/Probing/MediaStreamInfoSideData.cs +++ b/MediaBrowser.MediaEncoding/Probing/MediaStreamInfoSideData.cs @@ -1,4 +1,3 @@ -using System.Collections.Generic; using System.Text.Json.Serialization; namespace MediaBrowser.MediaEncoding.Probing diff --git a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEditParser.cs b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEditParser.cs index eb8ff96246..0d4489517e 100644 --- a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEditParser.cs +++ b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEditParser.cs @@ -3,12 +3,10 @@ using System.Collections.Generic; using System.Globalization; using System.IO; using System.Linq; -using System.Reflection; using Jellyfin.Extensions; using MediaBrowser.Model.MediaInfo; using Microsoft.Extensions.Logging; using Nikse.SubtitleEdit.Core.Common; -using Nikse.SubtitleEdit.Core.SubtitleFormats; using SubtitleFormat = Nikse.SubtitleEdit.Core.SubtitleFormats.SubtitleFormat; namespace MediaBrowser.MediaEncoding.Subtitles diff --git a/MediaBrowser.Model/Branding/BrandingOptions.cs b/MediaBrowser.Model/Branding/BrandingOptions.cs index a0adb56ef7..695267d46d 100644 --- a/MediaBrowser.Model/Branding/BrandingOptions.cs +++ b/MediaBrowser.Model/Branding/BrandingOptions.cs @@ -1,5 +1,4 @@ using System.Text.Json.Serialization; -using System.Xml.Serialization; namespace MediaBrowser.Model.Branding; diff --git a/MediaBrowser.Model/Configuration/EncodingOptions.cs b/MediaBrowser.Model/Configuration/EncodingOptions.cs index 73ebfba70e..f4cd2f0065 100644 --- a/MediaBrowser.Model/Configuration/EncodingOptions.cs +++ b/MediaBrowser.Model/Configuration/EncodingOptions.cs @@ -1,5 +1,3 @@ -using System; - #nullable disable #pragma warning disable CS1591 diff --git a/MediaBrowser.Model/Dlna/StreamInfo.cs b/MediaBrowser.Model/Dlna/StreamInfo.cs index 0c66351c70..5cfa2e7e3c 100644 --- a/MediaBrowser.Model/Dlna/StreamInfo.cs +++ b/MediaBrowser.Model/Dlna/StreamInfo.cs @@ -4,7 +4,6 @@ using System; using System.Collections.Generic; using System.Globalization; -using System.Linq; using MediaBrowser.Model.Drawing; using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; diff --git a/src/Jellyfin.Extensions/StringExtensions.cs b/src/Jellyfin.Extensions/StringExtensions.cs index 59fb038a75..b19be071bf 100644 --- a/src/Jellyfin.Extensions/StringExtensions.cs +++ b/src/Jellyfin.Extensions/StringExtensions.cs @@ -1,5 +1,4 @@ using System; -using System.Diagnostics; using System.Globalization; using System.Text; using System.Text.RegularExpressions; diff --git a/src/Jellyfin.MediaEncoding.Hls/Extractors/IKeyframeExtractor.cs b/src/Jellyfin.MediaEncoding.Hls/Extractors/IKeyframeExtractor.cs index 497210f417..083e93de1a 100644 --- a/src/Jellyfin.MediaEncoding.Hls/Extractors/IKeyframeExtractor.cs +++ b/src/Jellyfin.MediaEncoding.Hls/Extractors/IKeyframeExtractor.cs @@ -1,4 +1,3 @@ -using System; using System.Diagnostics.CodeAnalysis; using Jellyfin.MediaEncoding.Keyframes; diff --git a/tests/Jellyfin.MediaEncoding.Tests/Subtitles/AssParserTests.cs b/tests/Jellyfin.MediaEncoding.Tests/Subtitles/AssParserTests.cs index e14850eed7..fe0d7fc90f 100644 --- a/tests/Jellyfin.MediaEncoding.Tests/Subtitles/AssParserTests.cs +++ b/tests/Jellyfin.MediaEncoding.Tests/Subtitles/AssParserTests.cs @@ -1,7 +1,6 @@ using System; using System.Globalization; using System.IO; -using System.Threading; using MediaBrowser.MediaEncoding.Subtitles; using Microsoft.Extensions.Logging.Abstractions; using Xunit; diff --git a/tests/Jellyfin.MediaEncoding.Tests/Subtitles/SrtParserTests.cs b/tests/Jellyfin.MediaEncoding.Tests/Subtitles/SrtParserTests.cs index 0038b18736..2aebee5562 100644 --- a/tests/Jellyfin.MediaEncoding.Tests/Subtitles/SrtParserTests.cs +++ b/tests/Jellyfin.MediaEncoding.Tests/Subtitles/SrtParserTests.cs @@ -1,7 +1,6 @@ using System; using System.Globalization; using System.IO; -using System.Threading; using MediaBrowser.MediaEncoding.Subtitles; using Microsoft.Extensions.Logging.Abstractions; using Xunit; diff --git a/tests/Jellyfin.MediaEncoding.Tests/Subtitles/SsaParserTests.cs b/tests/Jellyfin.MediaEncoding.Tests/Subtitles/SsaParserTests.cs index 3b9a71690c..6abf2d26cb 100644 --- a/tests/Jellyfin.MediaEncoding.Tests/Subtitles/SsaParserTests.cs +++ b/tests/Jellyfin.MediaEncoding.Tests/Subtitles/SsaParserTests.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.Globalization; using System.IO; using System.Text; -using System.Threading; using MediaBrowser.MediaEncoding.Subtitles; using MediaBrowser.Model.MediaInfo; using Microsoft.Extensions.Logging.Abstractions; diff --git a/tests/Jellyfin.Naming.Tests/Video/MultiVersionTests.cs b/tests/Jellyfin.Naming.Tests/Video/MultiVersionTests.cs index 9a9a57be47..79f2366b89 100644 --- a/tests/Jellyfin.Naming.Tests/Video/MultiVersionTests.cs +++ b/tests/Jellyfin.Naming.Tests/Video/MultiVersionTests.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.Linq; using Emby.Naming.Common; using Emby.Naming.Video; -using MediaBrowser.Model.IO; using Xunit; namespace Jellyfin.Naming.Tests.Video diff --git a/tests/Jellyfin.Naming.Tests/Video/VideoListResolverTests.cs b/tests/Jellyfin.Naming.Tests/Video/VideoListResolverTests.cs index b761878426..cc9cfdd7dd 100644 --- a/tests/Jellyfin.Naming.Tests/Video/VideoListResolverTests.cs +++ b/tests/Jellyfin.Naming.Tests/Video/VideoListResolverTests.cs @@ -3,7 +3,6 @@ using System.Linq; using Emby.Naming.Common; using Emby.Naming.Video; using MediaBrowser.Model.Entities; -using MediaBrowser.Model.IO; using Xunit; namespace Jellyfin.Naming.Tests.Video diff --git a/tests/Jellyfin.Server.Implementations.Tests/Sorting/ParentIndexNumberComparerTests.cs b/tests/Jellyfin.Server.Implementations.Tests/Sorting/ParentIndexNumberComparerTests.cs index 40f271d61b..261092e019 100644 --- a/tests/Jellyfin.Server.Implementations.Tests/Sorting/ParentIndexNumberComparerTests.cs +++ b/tests/Jellyfin.Server.Implementations.Tests/Sorting/ParentIndexNumberComparerTests.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; using Emby.Server.Implementations.Sorting; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Audio; diff --git a/tests/Jellyfin.Server.Integration.Tests/JellyfinApplicationFactory.cs b/tests/Jellyfin.Server.Integration.Tests/JellyfinApplicationFactory.cs index adaf624a91..48c49bf848 100644 --- a/tests/Jellyfin.Server.Integration.Tests/JellyfinApplicationFactory.cs +++ b/tests/Jellyfin.Server.Integration.Tests/JellyfinApplicationFactory.cs @@ -11,7 +11,6 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Serilog; using Serilog.Extensions.Logging; -using static MediaBrowser.Controller.Extensions.ConfigurationExtensions; namespace Jellyfin.Server.Integration.Tests { diff --git a/tests/Jellyfin.XbmcMetadata.Tests/Parsers/MovieNfoParserTests.cs b/tests/Jellyfin.XbmcMetadata.Tests/Parsers/MovieNfoParserTests.cs index 7c99520308..988abce812 100644 --- a/tests/Jellyfin.XbmcMetadata.Tests/Parsers/MovieNfoParserTests.cs +++ b/tests/Jellyfin.XbmcMetadata.Tests/Parsers/MovieNfoParserTests.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; using System.Linq; using System.Threading; using Jellyfin.Data.Entities; -- cgit v1.2.3 From a9a5fcde81060c9da2096235d61128006339a2ee Mon Sep 17 00:00:00 2001 From: Bond_009 Date: Thu, 6 Oct 2022 20:21:23 +0200 Subject: Use ArgumentNullException.ThrowIfNull helper method Did a simple search/replace on the whole repo (except the RSSDP project) This reduces LOC and should improve performance (methods containing a throw statement don't get inlined) ``` if \((\w+) == null\) \s+\{ \s+throw new ArgumentNullException\((.*)\); \s+\} ``` ``` ArgumentNullException.ThrowIfNull($1); ``` --- .../ContentDirectory/ContentDirectoryService.cs | 5 +- Emby.Dlna/ContentDirectory/ControlHandler.cs | 10 +-- Emby.Dlna/DlnaManager.cs | 10 +-- Emby.Dlna/PlayTo/Device.cs | 15 +--- Emby.Dlna/PlayTo/TransportCommands.cs | 5 +- Emby.Dlna/PlayTo/UpnpContainer.cs | 5 +- Emby.Dlna/PlayTo/uBaseObject.cs | 5 +- .../AppBase/BaseConfigurationManager.cs | 5 +- .../Channels/ChannelManager.cs | 5 +- .../Data/SqliteExtensions.cs | 5 +- .../Data/SqliteItemRepository.cs | 85 +++++----------------- .../Data/SqliteUserDataRepository.cs | 15 +--- .../Library/LibraryManager.cs | 47 +++--------- .../Library/MediaSourceManager.cs | 5 +- .../Library/Resolvers/PhotoResolver.cs | 5 +- .../Library/UserDataManager.cs | 15 +--- .../LiveTv/EmbyTV/EmbyTV.cs | 10 +-- .../LiveTv/EmbyTV/ItemDataProvider.cs | 10 +-- .../LiveTv/TunerHosts/M3uParser.cs | 5 +- Emby.Server.Implementations/Net/SocketFactory.cs | 5 +- Emby.Server.Implementations/Net/UdpSocket.cs | 10 +-- .../Plugins/PluginManager.cs | 20 +---- .../ScheduledTasks/ScheduledTaskWorker.cs | 30 ++------ .../Session/SessionManager.cs | 35 ++------- .../Sorting/AiredEpisodeOrderComparer.cs | 10 +-- .../Sorting/CommunityRatingComparer.cs | 10 +-- .../Sorting/DateCreatedComparer.cs | 10 +-- .../Sorting/IndexNumberComparer.cs | 10 +-- .../Sorting/NameComparer.cs | 10 +-- .../Sorting/OfficialRatingComparer.cs | 12 +-- .../Sorting/ParentIndexNumberComparer.cs | 10 +-- .../Sorting/RuntimeComparer.cs | 10 +-- .../Sorting/SortNameComparer.cs | 10 +-- .../Sorting/StudioComparer.cs | 10 +-- .../Updates/InstallationManager.cs | 5 +- Jellyfin.Drawing.Skia/StripCollageBuilder.cs | 5 +- Jellyfin.Networking/Manager/NetworkManager.cs | 15 +--- .../Devices/DeviceManager.cs | 5 +- .../Users/UserManager.cs | 10 +-- MediaBrowser.Common/Net/IPNetAddress.cs | 5 +- MediaBrowser.Common/Net/IPObject.cs | 25 ++----- MediaBrowser.Common/Net/NetworkExtensions.cs | 20 +---- MediaBrowser.Common/Plugins/BasePluginOfT.cs | 5 +- .../Entities/AggregateFolder.cs | 5 +- MediaBrowser.Controller/Entities/BaseItem.cs | 35 ++------- .../Entities/BaseItemExtensions.cs | 10 +-- MediaBrowser.Controller/Entities/Folder.cs | 20 +---- MediaBrowser.Controller/Entities/PeopleHelper.cs | 5 +- MediaBrowser.Controller/IO/FileData.cs | 5 +- .../MediaEncoding/EncodingHelper.cs | 10 +-- .../Net/BasePeriodicWebSocketListener.cs | 10 +-- .../Parsers/BaseItemXmlParser.cs | 5 +- .../Attachments/AttachmentExtractor.cs | 5 +- .../Probing/FFProbeHelpers.cs | 5 +- .../Subtitles/SubtitleEncoder.cs | 5 +- MediaBrowser.Model/Cryptography/PasswordHash.cs | 5 +- MediaBrowser.Model/Dlna/StreamBuilder.cs | 5 +- .../Entities/ProviderIdsExtensions.cs | 15 +--- src/Jellyfin.Extensions/EnumerableExtensions.cs | 5 +- .../Jellyfin.Networking.Tests/NetworkParseTests.cs | 60 +++------------ 60 files changed, 156 insertions(+), 618 deletions(-) (limited to 'MediaBrowser.Controller/MediaEncoding') diff --git a/Emby.Dlna/ContentDirectory/ContentDirectoryService.cs b/Emby.Dlna/ContentDirectory/ContentDirectoryService.cs index 9020dea994..319a9f5500 100644 --- a/Emby.Dlna/ContentDirectory/ContentDirectoryService.cs +++ b/Emby.Dlna/ContentDirectory/ContentDirectoryService.cs @@ -103,10 +103,7 @@ namespace Emby.Dlna.ContentDirectory /// public Task ProcessControlRequestAsync(ControlRequest request) { - if (request == null) - { - throw new ArgumentNullException(nameof(request)); - } + ArgumentNullException.ThrowIfNull(request); var profile = _dlna.GetProfile(request.Headers) ?? _dlna.GetDefaultProfile(); diff --git a/Emby.Dlna/ContentDirectory/ControlHandler.cs b/Emby.Dlna/ContentDirectory/ControlHandler.cs index 57170bb316..fc69960fd6 100644 --- a/Emby.Dlna/ContentDirectory/ControlHandler.cs +++ b/Emby.Dlna/ContentDirectory/ControlHandler.cs @@ -114,15 +114,9 @@ namespace Emby.Dlna.ContentDirectory /// protected override void WriteResult(string methodName, IReadOnlyDictionary methodParams, XmlWriter xmlWriter) { - if (xmlWriter == null) - { - throw new ArgumentNullException(nameof(xmlWriter)); - } + ArgumentNullException.ThrowIfNull(xmlWriter); - if (methodParams == null) - { - throw new ArgumentNullException(nameof(methodParams)); - } + ArgumentNullException.ThrowIfNull(methodParams); const string DeviceId = "test"; diff --git a/Emby.Dlna/DlnaManager.cs b/Emby.Dlna/DlnaManager.cs index 74624334bb..57864d2780 100644 --- a/Emby.Dlna/DlnaManager.cs +++ b/Emby.Dlna/DlnaManager.cs @@ -100,10 +100,7 @@ namespace Emby.Dlna /// public DeviceProfile? GetProfile(DeviceIdentification deviceInfo) { - if (deviceInfo == null) - { - throw new ArgumentNullException(nameof(deviceInfo)); - } + ArgumentNullException.ThrowIfNull(deviceInfo); var profile = GetProfiles() .FirstOrDefault(i => i.Identification != null && IsMatch(deviceInfo, i.Identification)); @@ -170,10 +167,7 @@ namespace Emby.Dlna /// public DeviceProfile? GetProfile(IHeaderDictionary headers) { - if (headers == null) - { - throw new ArgumentNullException(nameof(headers)); - } + ArgumentNullException.ThrowIfNull(headers); var profile = GetProfiles().FirstOrDefault(i => i.Identification != null && IsMatch(headers, i.Identification)); if (profile == null) diff --git a/Emby.Dlna/PlayTo/Device.cs b/Emby.Dlna/PlayTo/Device.cs index 0b480f5ab0..34981bd3f4 100644 --- a/Emby.Dlna/PlayTo/Device.cs +++ b/Emby.Dlna/PlayTo/Device.cs @@ -931,10 +931,7 @@ namespace Emby.Dlna.PlayTo private static UBaseObject CreateUBaseObject(XElement container, string trackUri) { - if (container == null) - { - throw new ArgumentNullException(nameof(container)); - } + ArgumentNullException.ThrowIfNull(container); var url = container.GetValue(UPnpNamespaces.Res); @@ -958,10 +955,7 @@ namespace Emby.Dlna.PlayTo private static string[] GetProtocolInfo(XElement container) { - if (container == null) - { - throw new ArgumentNullException(nameof(container)); - } + ArgumentNullException.ThrowIfNull(container); var resElement = container.Element(UPnpNamespaces.Res); @@ -1183,10 +1177,7 @@ namespace Emby.Dlna.PlayTo #nullable enable private static DeviceIcon CreateIcon(XElement element) { - if (element == null) - { - throw new ArgumentNullException(nameof(element)); - } + ArgumentNullException.ThrowIfNull(element); var width = element.GetDescendantValue(UPnpNamespaces.Ud.GetName("width")); var height = element.GetDescendantValue(UPnpNamespaces.Ud.GetName("height")); diff --git a/Emby.Dlna/PlayTo/TransportCommands.cs b/Emby.Dlna/PlayTo/TransportCommands.cs index d373b57f55..9c3a9103be 100644 --- a/Emby.Dlna/PlayTo/TransportCommands.cs +++ b/Emby.Dlna/PlayTo/TransportCommands.cs @@ -61,10 +61,7 @@ namespace Emby.Dlna.PlayTo private static Argument ArgumentFromXml(XElement container) { - if (container == null) - { - throw new ArgumentNullException(nameof(container)); - } + ArgumentNullException.ThrowIfNull(container); return new Argument { diff --git a/Emby.Dlna/PlayTo/UpnpContainer.cs b/Emby.Dlna/PlayTo/UpnpContainer.cs index 05f27603fb..017d51e606 100644 --- a/Emby.Dlna/PlayTo/UpnpContainer.cs +++ b/Emby.Dlna/PlayTo/UpnpContainer.cs @@ -10,10 +10,7 @@ namespace Emby.Dlna.PlayTo { public static UBaseObject Create(XElement container) { - if (container == null) - { - throw new ArgumentNullException(nameof(container)); - } + ArgumentNullException.ThrowIfNull(container); return new UBaseObject { diff --git a/Emby.Dlna/PlayTo/uBaseObject.cs b/Emby.Dlna/PlayTo/uBaseObject.cs index 02d2da58d6..2e0f2063be 100644 --- a/Emby.Dlna/PlayTo/uBaseObject.cs +++ b/Emby.Dlna/PlayTo/uBaseObject.cs @@ -54,10 +54,7 @@ namespace Emby.Dlna.PlayTo public bool Equals(UBaseObject obj) { - if (obj == null) - { - throw new ArgumentNullException(nameof(obj)); - } + ArgumentNullException.ThrowIfNull(obj); return string.Equals(Id, obj.Id, StringComparison.Ordinal); } diff --git a/Emby.Server.Implementations/AppBase/BaseConfigurationManager.cs b/Emby.Server.Implementations/AppBase/BaseConfigurationManager.cs index c42cec593a..26b4649dd8 100644 --- a/Emby.Server.Implementations/AppBase/BaseConfigurationManager.cs +++ b/Emby.Server.Implementations/AppBase/BaseConfigurationManager.cs @@ -210,10 +210,7 @@ namespace Emby.Server.Implementations.AppBase /// newConfiguration is null. public virtual void ReplaceConfiguration(BaseApplicationConfiguration newConfiguration) { - if (newConfiguration == null) - { - throw new ArgumentNullException(nameof(newConfiguration)); - } + ArgumentNullException.ThrowIfNull(newConfiguration); ValidateCachePath(newConfiguration); diff --git a/Emby.Server.Implementations/Channels/ChannelManager.cs b/Emby.Server.Implementations/Channels/ChannelManager.cs index 92a85e8626..6837cce5cc 100644 --- a/Emby.Server.Implementations/Channels/ChannelManager.cs +++ b/Emby.Server.Implementations/Channels/ChannelManager.cs @@ -1188,10 +1188,7 @@ namespace Emby.Server.Implementations.Channels internal IChannel GetChannelProvider(Channel channel) { - if (channel == null) - { - throw new ArgumentNullException(nameof(channel)); - } + ArgumentNullException.ThrowIfNull(channel); var result = GetAllChannels() .FirstOrDefault(i => GetInternalChannelId(i.Name).Equals(channel.ChannelId) || string.Equals(i.Name, channel.Name, StringComparison.OrdinalIgnoreCase)); diff --git a/Emby.Server.Implementations/Data/SqliteExtensions.cs b/Emby.Server.Implementations/Data/SqliteExtensions.cs index 381eb92a88..736b8125d7 100644 --- a/Emby.Server.Implementations/Data/SqliteExtensions.cs +++ b/Emby.Server.Implementations/Data/SqliteExtensions.cs @@ -54,10 +54,7 @@ namespace Emby.Server.Implementations.Data public static void RunQueries(this SQLiteDatabaseConnection connection, string[] queries) { - if (queries == null) - { - throw new ArgumentNullException(nameof(queries)); - } + ArgumentNullException.ThrowIfNull(queries); connection.RunInTransaction(conn => { diff --git a/Emby.Server.Implementations/Data/SqliteItemRepository.cs b/Emby.Server.Implementations/Data/SqliteItemRepository.cs index 1b176e60d7..9c9fa73830 100644 --- a/Emby.Server.Implementations/Data/SqliteItemRepository.cs +++ b/Emby.Server.Implementations/Data/SqliteItemRepository.cs @@ -583,10 +583,7 @@ namespace Emby.Server.Implementations.Data public void SaveImages(BaseItem item) { - if (item == null) - { - throw new ArgumentNullException(nameof(item)); - } + ArgumentNullException.ThrowIfNull(item); CheckDisposed(); @@ -617,10 +614,7 @@ namespace Emby.Server.Implementations.Data /// public void SaveItems(IEnumerable items, CancellationToken cancellationToken) { - if (items == null) - { - throw new ArgumentNullException(nameof(items)); - } + ArgumentNullException.ThrowIfNull(items); cancellationToken.ThrowIfCancellationRequested(); @@ -2085,10 +2079,7 @@ namespace Emby.Server.Implementations.Data throw new ArgumentNullException(nameof(id)); } - if (chapters == null) - { - throw new ArgumentNullException(nameof(chapters)); - } + ArgumentNullException.ThrowIfNull(chapters); var idBlob = id.ToByteArray(); @@ -2557,10 +2548,7 @@ namespace Emby.Server.Implementations.Data public int GetCount(InternalItemsQuery query) { - if (query == null) - { - throw new ArgumentNullException(nameof(query)); - } + ArgumentNullException.ThrowIfNull(query); CheckDisposed(); @@ -2613,10 +2601,7 @@ namespace Emby.Server.Implementations.Data public List GetItemList(InternalItemsQuery query) { - if (query == null) - { - throw new ArgumentNullException(nameof(query)); - } + ArgumentNullException.ThrowIfNull(query); CheckDisposed(); @@ -2794,10 +2779,7 @@ namespace Emby.Server.Implementations.Data public QueryResult GetItems(InternalItemsQuery query) { - if (query == null) - { - throw new ArgumentNullException(nameof(query)); - } + ArgumentNullException.ThrowIfNull(query); CheckDisposed(); @@ -3174,10 +3156,7 @@ namespace Emby.Server.Implementations.Data public List GetItemIdsList(InternalItemsQuery query) { - if (query == null) - { - throw new ArgumentNullException(nameof(query)); - } + ArgumentNullException.ThrowIfNull(query); CheckDisposed(); @@ -4837,10 +4816,7 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type public List GetPeopleNames(InternalPeopleQuery query) { - if (query == null) - { - throw new ArgumentNullException(nameof(query)); - } + ArgumentNullException.ThrowIfNull(query); CheckDisposed(); @@ -4880,10 +4856,7 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type public List GetPeople(InternalPeopleQuery query) { - if (query == null) - { - throw new ArgumentNullException(nameof(query)); - } + ArgumentNullException.ThrowIfNull(query); CheckDisposed(); @@ -4999,10 +4972,7 @@ AND Type = @InternalPersonType)"); throw new ArgumentNullException(nameof(itemId)); } - if (ancestorIds == null) - { - throw new ArgumentNullException(nameof(ancestorIds)); - } + ArgumentNullException.ThrowIfNull(ancestorIds); CheckDisposed(); @@ -5175,10 +5145,7 @@ AND Type = @InternalPersonType)"); private QueryResult<(BaseItem Item, ItemCounts ItemCounts)> GetItemValues(InternalItemsQuery query, int[] itemValueTypes, string returnType) { - if (query == null) - { - throw new ArgumentNullException(nameof(query)); - } + ArgumentNullException.ThrowIfNull(query); if (!query.Limit.HasValue) { @@ -5531,10 +5498,7 @@ AND Type = @InternalPersonType)"); throw new ArgumentNullException(nameof(itemId)); } - if (values == null) - { - throw new ArgumentNullException(nameof(values)); - } + ArgumentNullException.ThrowIfNull(values); CheckDisposed(); @@ -5607,10 +5571,7 @@ AND Type = @InternalPersonType)"); throw new ArgumentNullException(nameof(itemId)); } - if (people == null) - { - throw new ArgumentNullException(nameof(people)); - } + ArgumentNullException.ThrowIfNull(people); CheckDisposed(); @@ -5710,10 +5671,7 @@ AND Type = @InternalPersonType)"); { CheckDisposed(); - if (query == null) - { - throw new ArgumentNullException(nameof(query)); - } + ArgumentNullException.ThrowIfNull(query); var cmdText = _mediaStreamSaveColumnsSelectQuery; @@ -5766,10 +5724,7 @@ AND Type = @InternalPersonType)"); throw new ArgumentNullException(nameof(id)); } - if (streams == null) - { - throw new ArgumentNullException(nameof(streams)); - } + ArgumentNullException.ThrowIfNull(streams); cancellationToken.ThrowIfCancellationRequested(); @@ -6107,10 +6062,7 @@ AND Type = @InternalPersonType)"); { CheckDisposed(); - if (query == null) - { - throw new ArgumentNullException(nameof(query)); - } + ArgumentNullException.ThrowIfNull(query); var cmdText = _mediaAttachmentSaveColumnsSelectQuery; @@ -6152,10 +6104,7 @@ AND Type = @InternalPersonType)"); throw new ArgumentException("Guid can't be empty.", nameof(id)); } - if (attachments == null) - { - throw new ArgumentNullException(nameof(attachments)); - } + ArgumentNullException.ThrowIfNull(attachments); cancellationToken.ThrowIfCancellationRequested(); diff --git a/Emby.Server.Implementations/Data/SqliteUserDataRepository.cs b/Emby.Server.Implementations/Data/SqliteUserDataRepository.cs index ba86dc156e..8d78d644dc 100644 --- a/Emby.Server.Implementations/Data/SqliteUserDataRepository.cs +++ b/Emby.Server.Implementations/Data/SqliteUserDataRepository.cs @@ -133,10 +133,7 @@ namespace Emby.Server.Implementations.Data /// public void SaveUserData(long userId, string key, UserItemData userData, CancellationToken cancellationToken) { - if (userData == null) - { - throw new ArgumentNullException(nameof(userData)); - } + ArgumentNullException.ThrowIfNull(userData); if (userId <= 0) { @@ -154,10 +151,7 @@ namespace Emby.Server.Implementations.Data /// public void SaveAllUserData(long userId, UserItemData[] userData, CancellationToken cancellationToken) { - if (userData == null) - { - throw new ArgumentNullException(nameof(userData)); - } + ArgumentNullException.ThrowIfNull(userData); if (userId <= 0) { @@ -304,10 +298,7 @@ namespace Emby.Server.Implementations.Data public UserItemData GetUserData(long userId, List keys) { - if (keys == null) - { - throw new ArgumentNullException(nameof(keys)); - } + ArgumentNullException.ThrowIfNull(keys); if (keys.Count == 0) { diff --git a/Emby.Server.Implementations/Library/LibraryManager.cs b/Emby.Server.Implementations/Library/LibraryManager.cs index 67f9c57658..ee94670eb0 100644 --- a/Emby.Server.Implementations/Library/LibraryManager.cs +++ b/Emby.Server.Implementations/Library/LibraryManager.cs @@ -281,10 +281,7 @@ namespace Emby.Server.Implementations.Library public void RegisterItem(BaseItem item) { - if (item == null) - { - throw new ArgumentNullException(nameof(item)); - } + ArgumentNullException.ThrowIfNull(item); if (item is IItemByName) { @@ -311,10 +308,7 @@ namespace Emby.Server.Implementations.Library public void DeleteItem(BaseItem item, DeleteOptions options, bool notifyParentItem) { - if (item == null) - { - throw new ArgumentNullException(nameof(item)); - } + ArgumentNullException.ThrowIfNull(item); var parent = item.GetOwner() ?? item.GetParent(); @@ -323,10 +317,7 @@ namespace Emby.Server.Implementations.Library public void DeleteItem(BaseItem item, DeleteOptions options, BaseItem parent, bool notifyParentItem) { - if (item == null) - { - throw new ArgumentNullException(nameof(item)); - } + ArgumentNullException.ThrowIfNull(item); if (item.SourceType == SourceType.Channel) { @@ -509,10 +500,7 @@ namespace Emby.Server.Implementations.Library throw new ArgumentNullException(nameof(key)); } - if (type == null) - { - throw new ArgumentNullException(nameof(type)); - } + ArgumentNullException.ThrowIfNull(type); string programDataPath = _configurationManager.ApplicationPaths.ProgramDataPath; if (key.StartsWith(programDataPath, StringComparison.Ordinal)) @@ -544,10 +532,7 @@ namespace Emby.Server.Implementations.Library string collectionType = null, LibraryOptions libraryOptions = null) { - if (fileInfo == null) - { - throw new ArgumentNullException(nameof(fileInfo)); - } + ArgumentNullException.ThrowIfNull(fileInfo); var fullPath = fileInfo.FullName; @@ -1854,10 +1839,7 @@ namespace Emby.Server.Implementations.Library /// public async Task UpdateImagesAsync(BaseItem item, bool forceUpdate = false) { - if (item == null) - { - throw new ArgumentNullException(nameof(item)); - } + ArgumentNullException.ThrowIfNull(item); var outdated = forceUpdate ? item.ImageInfos.Where(i => i.Path != null).ToArray() @@ -2296,10 +2278,7 @@ namespace Emby.Server.Implementations.Library string viewType, string sortName) { - if (parent == null) - { - throw new ArgumentNullException(nameof(parent)); - } + ArgumentNullException.ThrowIfNull(parent); var name = parent.Name; var parentId = parent.Id; @@ -2779,7 +2758,7 @@ namespace Emby.Server.Implementations.Library } }) .Where(i => i != null) - .Where(i => query.User == null ? + .Where(i => query.User == null ? true : i.IsVisible(query.User)) .ToList(); @@ -2983,10 +2962,7 @@ namespace Emby.Server.Implementations.Library private void AddMediaPathInternal(string virtualFolderName, MediaPathInfo pathInfo, bool saveLibraryOptions) { - if (pathInfo == null) - { - throw new ArgumentNullException(nameof(pathInfo)); - } + ArgumentNullException.ThrowIfNull(pathInfo); var path = pathInfo.Path; @@ -3033,10 +3009,7 @@ namespace Emby.Server.Implementations.Library public void UpdateMediaPath(string virtualFolderName, MediaPathInfo mediaPath) { - if (mediaPath == null) - { - throw new ArgumentNullException(nameof(mediaPath)); - } + ArgumentNullException.ThrowIfNull(mediaPath); var rootFolderPath = _configurationManager.ApplicationPaths.DefaultUserViewsPath; var virtualFolderPath = Path.Combine(rootFolderPath, virtualFolderName); diff --git a/Emby.Server.Implementations/Library/MediaSourceManager.cs b/Emby.Server.Implementations/Library/MediaSourceManager.cs index c0aef18997..bfccc7db72 100644 --- a/Emby.Server.Implementations/Library/MediaSourceManager.cs +++ b/Emby.Server.Implementations/Library/MediaSourceManager.cs @@ -322,10 +322,7 @@ namespace Emby.Server.Implementations.Library public List GetStaticMediaSources(BaseItem item, bool enablePathSubstitution, User user = null) { - if (item == null) - { - throw new ArgumentNullException(nameof(item)); - } + ArgumentNullException.ThrowIfNull(item); var hasMediaSources = (IHasMediaSources)item; diff --git a/Emby.Server.Implementations/Library/Resolvers/PhotoResolver.cs b/Emby.Server.Implementations/Library/Resolvers/PhotoResolver.cs index bc2915db62..af4abfb805 100644 --- a/Emby.Server.Implementations/Library/Resolvers/PhotoResolver.cs +++ b/Emby.Server.Implementations/Library/Resolvers/PhotoResolver.cs @@ -91,10 +91,7 @@ namespace Emby.Server.Implementations.Library.Resolvers internal static bool IsImageFile(string path, IImageProcessor imageProcessor) { - if (path == null) - { - throw new ArgumentNullException(nameof(path)); - } + ArgumentNullException.ThrowIfNull(path); var filename = Path.GetFileNameWithoutExtension(path); diff --git a/Emby.Server.Implementations/Library/UserDataManager.cs b/Emby.Server.Implementations/Library/UserDataManager.cs index 3810a76c45..aecab7d9c8 100644 --- a/Emby.Server.Implementations/Library/UserDataManager.cs +++ b/Emby.Server.Implementations/Library/UserDataManager.cs @@ -53,15 +53,9 @@ namespace Emby.Server.Implementations.Library public void SaveUserData(User user, BaseItem item, UserItemData userData, UserDataSaveReason reason, CancellationToken cancellationToken) { - if (userData == null) - { - throw new ArgumentNullException(nameof(userData)); - } + ArgumentNullException.ThrowIfNull(userData); - if (item == null) - { - throw new ArgumentNullException(nameof(item)); - } + ArgumentNullException.ThrowIfNull(item); cancellationToken.ThrowIfCancellationRequested(); @@ -194,10 +188,7 @@ namespace Emby.Server.Implementations.Library /// is null. private UserItemDataDto GetUserItemDataDto(UserItemData data) { - if (data == null) - { - throw new ArgumentNullException(nameof(data)); - } + ArgumentNullException.ThrowIfNull(data); return new UserItemDataDto { diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index 065309688c..4da6776369 100644 --- a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -1223,10 +1223,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV private async Task RecordStream(TimerInfo timer, DateTime recordingEndDate, ActiveRecordingInfo activeRecordingInfo) { - if (timer == null) - { - throw new ArgumentNullException(nameof(timer)); - } + ArgumentNullException.ThrowIfNull(timer); LiveTvProgram programInfo = null; @@ -2347,10 +2344,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV private IEnumerable GetTimersForSeries(SeriesTimerInfo seriesTimer) { - if (seriesTimer == null) - { - throw new ArgumentNullException(nameof(seriesTimer)); - } + ArgumentNullException.ThrowIfNull(seriesTimer); var query = new InternalItemsQuery { diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/ItemDataProvider.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/ItemDataProvider.cs index 46979bfc57..58b798ce67 100644 --- a/Emby.Server.Implementations/LiveTv/EmbyTV/ItemDataProvider.cs +++ b/Emby.Server.Implementations/LiveTv/EmbyTV/ItemDataProvider.cs @@ -84,10 +84,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV public virtual void Update(T item) { - if (item == null) - { - throw new ArgumentNullException(nameof(item)); - } + ArgumentNullException.ThrowIfNull(item); lock (_fileDataLock) { @@ -107,10 +104,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV public virtual void Add(T item) { - if (item == null) - { - throw new ArgumentNullException(nameof(item)); - } + ArgumentNullException.ThrowIfNull(item); lock (_fileDataLock) { diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs index be06356a4f..a423ec8f48 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs @@ -44,10 +44,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts public async Task GetListingsStream(TunerHostInfo info, CancellationToken cancellationToken) { - if (info == null) - { - throw new ArgumentNullException(nameof(info)); - } + ArgumentNullException.ThrowIfNull(info); if (!info.Url.StartsWith("http", StringComparison.OrdinalIgnoreCase)) { diff --git a/Emby.Server.Implementations/Net/SocketFactory.cs b/Emby.Server.Implementations/Net/SocketFactory.cs index 21795c8f86..303875df55 100644 --- a/Emby.Server.Implementations/Net/SocketFactory.cs +++ b/Emby.Server.Implementations/Net/SocketFactory.cs @@ -63,10 +63,7 @@ namespace Emby.Server.Implementations.Net /// public ISocket CreateUdpMulticastSocket(IPAddress ipAddress, int multicastTimeToLive, int localPort) { - if (ipAddress == null) - { - throw new ArgumentNullException(nameof(ipAddress)); - } + ArgumentNullException.ThrowIfNull(ipAddress); if (multicastTimeToLive <= 0) { diff --git a/Emby.Server.Implementations/Net/UdpSocket.cs b/Emby.Server.Implementations/Net/UdpSocket.cs index 2c20daa57f..c3994fc040 100644 --- a/Emby.Server.Implementations/Net/UdpSocket.cs +++ b/Emby.Server.Implementations/Net/UdpSocket.cs @@ -35,10 +35,7 @@ namespace Emby.Server.Implementations.Net public UdpSocket(Socket socket, int localPort, IPAddress ip) { - if (socket == null) - { - throw new ArgumentNullException(nameof(socket)); - } + ArgumentNullException.ThrowIfNull(socket); _socket = socket; _localPort = localPort; @@ -51,10 +48,7 @@ namespace Emby.Server.Implementations.Net public UdpSocket(Socket socket, IPEndPoint endPoint) { - if (socket == null) - { - throw new ArgumentNullException(nameof(socket)); - } + ArgumentNullException.ThrowIfNull(socket); _socket = socket; _socket.Connect(endPoint); diff --git a/Emby.Server.Implementations/Plugins/PluginManager.cs b/Emby.Server.Implementations/Plugins/PluginManager.cs index 45ef36441d..ec4e0dbeb9 100644 --- a/Emby.Server.Implementations/Plugins/PluginManager.cs +++ b/Emby.Server.Implementations/Plugins/PluginManager.cs @@ -234,10 +234,7 @@ namespace Emby.Server.Implementations.Plugins /// Outcome of the operation. public bool RemovePlugin(LocalPlugin plugin) { - if (plugin == null) - { - throw new ArgumentNullException(nameof(plugin)); - } + ArgumentNullException.ThrowIfNull(plugin); if (DeletePlugin(plugin)) { @@ -288,10 +285,7 @@ namespace Emby.Server.Implementations.Plugins /// The of the plug to disable. public void EnablePlugin(LocalPlugin plugin) { - if (plugin == null) - { - throw new ArgumentNullException(nameof(plugin)); - } + ArgumentNullException.ThrowIfNull(plugin); if (ChangePluginState(plugin, PluginStatus.Active)) { @@ -306,10 +300,7 @@ namespace Emby.Server.Implementations.Plugins /// The of the plug to disable. public void DisablePlugin(LocalPlugin plugin) { - if (plugin == null) - { - throw new ArgumentNullException(nameof(plugin)); - } + ArgumentNullException.ThrowIfNull(plugin); // Update the manifest on disk if (ChangePluginState(plugin, PluginStatus.Disabled)) @@ -326,10 +317,7 @@ namespace Emby.Server.Implementations.Plugins public void FailPlugin(Assembly assembly) { // Only save if disabled. - if (assembly == null) - { - throw new ArgumentNullException(nameof(assembly)); - } + ArgumentNullException.ThrowIfNull(assembly); var plugin = _plugins.FirstOrDefault(p => p.DllFiles.Contains(assembly.Location)); if (plugin == null) diff --git a/Emby.Server.Implementations/ScheduledTasks/ScheduledTaskWorker.cs b/Emby.Server.Implementations/ScheduledTasks/ScheduledTaskWorker.cs index 2c4d6884d2..b370e06efa 100644 --- a/Emby.Server.Implementations/ScheduledTasks/ScheduledTaskWorker.cs +++ b/Emby.Server.Implementations/ScheduledTasks/ScheduledTaskWorker.cs @@ -92,25 +92,13 @@ namespace Emby.Server.Implementations.ScheduledTasks /// public ScheduledTaskWorker(IScheduledTask scheduledTask, IApplicationPaths applicationPaths, ITaskManager taskManager, ILogger logger) { - if (scheduledTask == null) - { - throw new ArgumentNullException(nameof(scheduledTask)); - } + ArgumentNullException.ThrowIfNull(scheduledTask); - if (applicationPaths == null) - { - throw new ArgumentNullException(nameof(applicationPaths)); - } + ArgumentNullException.ThrowIfNull(applicationPaths); - if (taskManager == null) - { - throw new ArgumentNullException(nameof(taskManager)); - } + ArgumentNullException.ThrowIfNull(taskManager); - if (logger == null) - { - throw new ArgumentNullException(nameof(logger)); - } + ArgumentNullException.ThrowIfNull(logger); ScheduledTask = scheduledTask; _applicationPaths = applicationPaths; @@ -249,10 +237,7 @@ namespace Emby.Server.Implementations.ScheduledTasks get => _triggers; set { - if (value == null) - { - throw new ArgumentNullException(nameof(value)); - } + ArgumentNullException.ThrowIfNull(value); // Cleanup current triggers if (_triggers != null) @@ -281,10 +266,7 @@ namespace Emby.Server.Implementations.ScheduledTasks set { - if (value == null) - { - throw new ArgumentNullException(nameof(value)); - } + ArgumentNullException.ThrowIfNull(value); // This null check is not great, but is needed to handle bad user input, or user mucking with the config file incorrectly var triggerList = value.Where(i => i != null).ToArray(); diff --git a/Emby.Server.Implementations/Session/SessionManager.cs b/Emby.Server.Implementations/Session/SessionManager.cs index 7f927e2709..0d1029882b 100644 --- a/Emby.Server.Implementations/Session/SessionManager.cs +++ b/Emby.Server.Implementations/Session/SessionManager.cs @@ -665,10 +665,7 @@ namespace Emby.Server.Implementations.Session { CheckDisposed(); - if (info == null) - { - throw new ArgumentNullException(nameof(info)); - } + ArgumentNullException.ThrowIfNull(info); var session = GetSession(info.SessionId); @@ -762,10 +759,7 @@ namespace Emby.Server.Implementations.Session { CheckDisposed(); - if (info == null) - { - throw new ArgumentNullException(nameof(info)); - } + ArgumentNullException.ThrowIfNull(info); var session = GetSession(info.SessionId); @@ -897,10 +891,7 @@ namespace Emby.Server.Implementations.Session { CheckDisposed(); - if (info == null) - { - throw new ArgumentNullException(nameof(info)); - } + ArgumentNullException.ThrowIfNull(info); if (info.PositionTicks.HasValue && info.PositionTicks.Value < 0) { @@ -1341,15 +1332,9 @@ namespace Emby.Server.Implementations.Session private static void AssertCanControl(SessionInfo session, SessionInfo controllingSession) { - if (session == null) - { - throw new ArgumentNullException(nameof(session)); - } + ArgumentNullException.ThrowIfNull(session); - if (controllingSession == null) - { - throw new ArgumentNullException(nameof(controllingSession)); - } + ArgumentNullException.ThrowIfNull(controllingSession); } /// @@ -1688,10 +1673,7 @@ namespace Emby.Server.Implementations.Session /// private BaseItemDto GetItemInfo(BaseItem item, MediaSourceInfo mediaSource) { - if (item == null) - { - throw new ArgumentNullException(nameof(item)); - } + ArgumentNullException.ThrowIfNull(item); var dtoOptions = _itemInfoDtoOptions; @@ -1802,10 +1784,7 @@ namespace Emby.Server.Implementations.Session /// public Task GetSessionByAuthenticationToken(Device info, string deviceId, string remoteEndpoint, string appVersion) { - if (info == null) - { - throw new ArgumentNullException(nameof(info)); - } + ArgumentNullException.ThrowIfNull(info); var user = info.UserId.Equals(default) ? null diff --git a/Emby.Server.Implementations/Sorting/AiredEpisodeOrderComparer.cs b/Emby.Server.Implementations/Sorting/AiredEpisodeOrderComparer.cs index db8b689491..2d21bd9c2a 100644 --- a/Emby.Server.Implementations/Sorting/AiredEpisodeOrderComparer.cs +++ b/Emby.Server.Implementations/Sorting/AiredEpisodeOrderComparer.cs @@ -24,15 +24,9 @@ namespace Emby.Server.Implementations.Sorting /// System.Int32. public int Compare(BaseItem? x, BaseItem? y) { - if (x == null) - { - throw new ArgumentNullException(nameof(x)); - } + ArgumentNullException.ThrowIfNull(x); - if (y == null) - { - throw new ArgumentNullException(nameof(y)); - } + ArgumentNullException.ThrowIfNull(y); var episode1 = x as Episode; var episode2 = y as Episode; diff --git a/Emby.Server.Implementations/Sorting/CommunityRatingComparer.cs b/Emby.Server.Implementations/Sorting/CommunityRatingComparer.cs index 5f142fa4bb..5cb11ab465 100644 --- a/Emby.Server.Implementations/Sorting/CommunityRatingComparer.cs +++ b/Emby.Server.Implementations/Sorting/CommunityRatingComparer.cs @@ -23,15 +23,9 @@ namespace Emby.Server.Implementations.Sorting /// System.Int32. public int Compare(BaseItem? x, BaseItem? y) { - if (x == null) - { - throw new ArgumentNullException(nameof(x)); - } + ArgumentNullException.ThrowIfNull(x); - if (y == null) - { - throw new ArgumentNullException(nameof(y)); - } + ArgumentNullException.ThrowIfNull(y); return (x.CommunityRating ?? 0).CompareTo(y.CommunityRating ?? 0); } diff --git a/Emby.Server.Implementations/Sorting/DateCreatedComparer.cs b/Emby.Server.Implementations/Sorting/DateCreatedComparer.cs index 8b460166ca..6133aaccc6 100644 --- a/Emby.Server.Implementations/Sorting/DateCreatedComparer.cs +++ b/Emby.Server.Implementations/Sorting/DateCreatedComparer.cs @@ -24,15 +24,9 @@ namespace Emby.Server.Implementations.Sorting /// System.Int32. public int Compare(BaseItem? x, BaseItem? y) { - if (x == null) - { - throw new ArgumentNullException(nameof(x)); - } + ArgumentNullException.ThrowIfNull(x); - if (y == null) - { - throw new ArgumentNullException(nameof(y)); - } + ArgumentNullException.ThrowIfNull(y); return DateTime.Compare(x.DateCreated, y.DateCreated); } diff --git a/Emby.Server.Implementations/Sorting/IndexNumberComparer.cs b/Emby.Server.Implementations/Sorting/IndexNumberComparer.cs index c5b00afb15..1bcaccd8a3 100644 --- a/Emby.Server.Implementations/Sorting/IndexNumberComparer.cs +++ b/Emby.Server.Implementations/Sorting/IndexNumberComparer.cs @@ -24,15 +24,9 @@ namespace Emby.Server.Implementations.Sorting /// System.Int32. public int Compare(BaseItem? x, BaseItem? y) { - if (x == null) - { - throw new ArgumentNullException(nameof(x)); - } + ArgumentNullException.ThrowIfNull(x); - if (y == null) - { - throw new ArgumentNullException(nameof(y)); - } + ArgumentNullException.ThrowIfNull(y); if (!x.IndexNumber.HasValue && !y.IndexNumber.HasValue) { diff --git a/Emby.Server.Implementations/Sorting/NameComparer.cs b/Emby.Server.Implementations/Sorting/NameComparer.cs index c2875eeb97..93bec4db99 100644 --- a/Emby.Server.Implementations/Sorting/NameComparer.cs +++ b/Emby.Server.Implementations/Sorting/NameComparer.cs @@ -24,15 +24,9 @@ namespace Emby.Server.Implementations.Sorting /// System.Int32. public int Compare(BaseItem? x, BaseItem? y) { - if (x == null) - { - throw new ArgumentNullException(nameof(x)); - } + ArgumentNullException.ThrowIfNull(x); - if (y == null) - { - throw new ArgumentNullException(nameof(y)); - } + ArgumentNullException.ThrowIfNull(y); return string.Compare(x.Name, y.Name, StringComparison.OrdinalIgnoreCase); } diff --git a/Emby.Server.Implementations/Sorting/OfficialRatingComparer.cs b/Emby.Server.Implementations/Sorting/OfficialRatingComparer.cs index a81f78ebfc..ce44f99a69 100644 --- a/Emby.Server.Implementations/Sorting/OfficialRatingComparer.cs +++ b/Emby.Server.Implementations/Sorting/OfficialRatingComparer.cs @@ -31,15 +31,9 @@ namespace Emby.Server.Implementations.Sorting /// System.Int32. public int Compare(BaseItem? x, BaseItem? y) { - if (x == null) - { - throw new ArgumentNullException(nameof(x)); - } - - if (y == null) - { - throw new ArgumentNullException(nameof(y)); - } + ArgumentNullException.ThrowIfNull(x); + + ArgumentNullException.ThrowIfNull(y); var levelX = string.IsNullOrEmpty(x.OfficialRating) ? 0 : _localization.GetRatingLevel(x.OfficialRating) ?? 0; var levelY = string.IsNullOrEmpty(y.OfficialRating) ? 0 : _localization.GetRatingLevel(y.OfficialRating) ?? 0; diff --git a/Emby.Server.Implementations/Sorting/ParentIndexNumberComparer.cs b/Emby.Server.Implementations/Sorting/ParentIndexNumberComparer.cs index 8c408bb4d2..c54750843e 100644 --- a/Emby.Server.Implementations/Sorting/ParentIndexNumberComparer.cs +++ b/Emby.Server.Implementations/Sorting/ParentIndexNumberComparer.cs @@ -24,15 +24,9 @@ namespace Emby.Server.Implementations.Sorting /// System.Int32. public int Compare(BaseItem? x, BaseItem? y) { - if (x == null) - { - throw new ArgumentNullException(nameof(x)); - } + ArgumentNullException.ThrowIfNull(x); - if (y == null) - { - throw new ArgumentNullException(nameof(y)); - } + ArgumentNullException.ThrowIfNull(y); if (!x.ParentIndexNumber.HasValue && !y.ParentIndexNumber.HasValue) { diff --git a/Emby.Server.Implementations/Sorting/RuntimeComparer.cs b/Emby.Server.Implementations/Sorting/RuntimeComparer.cs index e32e5552e4..646bafbb54 100644 --- a/Emby.Server.Implementations/Sorting/RuntimeComparer.cs +++ b/Emby.Server.Implementations/Sorting/RuntimeComparer.cs @@ -26,15 +26,9 @@ namespace Emby.Server.Implementations.Sorting /// System.Int32. public int Compare(BaseItem x, BaseItem y) { - if (x == null) - { - throw new ArgumentNullException(nameof(x)); - } + ArgumentNullException.ThrowIfNull(x); - if (y == null) - { - throw new ArgumentNullException(nameof(y)); - } + ArgumentNullException.ThrowIfNull(y); return (x.RunTimeTicks ?? 0).CompareTo(y.RunTimeTicks ?? 0); } diff --git a/Emby.Server.Implementations/Sorting/SortNameComparer.cs b/Emby.Server.Implementations/Sorting/SortNameComparer.cs index 79be9a89a4..628b9b3dda 100644 --- a/Emby.Server.Implementations/Sorting/SortNameComparer.cs +++ b/Emby.Server.Implementations/Sorting/SortNameComparer.cs @@ -26,15 +26,9 @@ namespace Emby.Server.Implementations.Sorting /// System.Int32. public int Compare(BaseItem x, BaseItem y) { - if (x == null) - { - throw new ArgumentNullException(nameof(x)); - } + ArgumentNullException.ThrowIfNull(x); - if (y == null) - { - throw new ArgumentNullException(nameof(y)); - } + ArgumentNullException.ThrowIfNull(y); return string.Compare(x.SortName, y.SortName, StringComparison.OrdinalIgnoreCase); } diff --git a/Emby.Server.Implementations/Sorting/StudioComparer.cs b/Emby.Server.Implementations/Sorting/StudioComparer.cs index c917daaad1..457c062714 100644 --- a/Emby.Server.Implementations/Sorting/StudioComparer.cs +++ b/Emby.Server.Implementations/Sorting/StudioComparer.cs @@ -26,15 +26,9 @@ namespace Emby.Server.Implementations.Sorting /// System.Int32. public int Compare(BaseItem x, BaseItem y) { - if (x == null) - { - throw new ArgumentNullException(nameof(x)); - } + ArgumentNullException.ThrowIfNull(x); - if (y == null) - { - throw new ArgumentNullException(nameof(y)); - } + ArgumentNullException.ThrowIfNull(y); return AlphanumericComparator.CompareValues(x.Studios.FirstOrDefault(), y.Studios.FirstOrDefault()); } diff --git a/Emby.Server.Implementations/Updates/InstallationManager.cs b/Emby.Server.Implementations/Updates/InstallationManager.cs index 40c386e823..550f0e0755 100644 --- a/Emby.Server.Implementations/Updates/InstallationManager.cs +++ b/Emby.Server.Implementations/Updates/InstallationManager.cs @@ -294,10 +294,7 @@ namespace Emby.Server.Implementations.Updates /// public async Task InstallPackage(InstallationInfo package, CancellationToken cancellationToken) { - if (package == null) - { - throw new ArgumentNullException(nameof(package)); - } + ArgumentNullException.ThrowIfNull(package); var innerCancellationTokenSource = new CancellationTokenSource(); diff --git a/Jellyfin.Drawing.Skia/StripCollageBuilder.cs b/Jellyfin.Drawing.Skia/StripCollageBuilder.cs index 6bece9db6e..b55a994056 100644 --- a/Jellyfin.Drawing.Skia/StripCollageBuilder.cs +++ b/Jellyfin.Drawing.Skia/StripCollageBuilder.cs @@ -29,10 +29,7 @@ namespace Jellyfin.Drawing.Skia /// The image format. public static SKEncodedImageFormat GetEncodedFormat(string outputPath) { - if (outputPath == null) - { - throw new ArgumentNullException(nameof(outputPath)); - } + ArgumentNullException.ThrowIfNull(outputPath); var ext = Path.GetExtension(outputPath); diff --git a/Jellyfin.Networking/Manager/NetworkManager.cs b/Jellyfin.Networking/Manager/NetworkManager.cs index fd0665dbdd..9e06cdfe71 100644 --- a/Jellyfin.Networking/Manager/NetworkManager.cs +++ b/Jellyfin.Networking/Manager/NetworkManager.cs @@ -353,10 +353,7 @@ namespace Jellyfin.Networking.Manager public string GetBindInterface(IPObject source, out int? port) { port = null; - if (source == null) - { - throw new ArgumentNullException(nameof(source)); - } + ArgumentNullException.ThrowIfNull(source); // Do we have a source? bool haveSource = !source.Address.Equals(IPAddress.None); @@ -476,10 +473,7 @@ namespace Jellyfin.Networking.Manager /// public bool IsInLocalNetwork(IPAddress address) { - if (address == null) - { - throw new ArgumentNullException(nameof(address)); - } + ArgumentNullException.ThrowIfNull(address); if (address.Equals(IPAddress.None)) { @@ -499,10 +493,7 @@ namespace Jellyfin.Networking.Manager /// public bool IsPrivateAddressRange(IPObject address) { - if (address == null) - { - throw new ArgumentNullException(nameof(address)); - } + ArgumentNullException.ThrowIfNull(address); // See conversation at https://github.com/jellyfin/jellyfin/pull/3515. if (TrustAllIP6Interfaces && address.AddressFamily == AddressFamily.InterNetworkV6) diff --git a/Jellyfin.Server.Implementations/Devices/DeviceManager.cs b/Jellyfin.Server.Implementations/Devices/DeviceManager.cs index 3203bed183..0728f11799 100644 --- a/Jellyfin.Server.Implementations/Devices/DeviceManager.cs +++ b/Jellyfin.Server.Implementations/Devices/DeviceManager.cs @@ -201,10 +201,7 @@ namespace Jellyfin.Server.Implementations.Devices /// public bool CanAccessDevice(User user, string deviceId) { - if (user == null) - { - throw new ArgumentNullException(nameof(user)); - } + ArgumentNullException.ThrowIfNull(user); if (string.IsNullOrEmpty(deviceId)) { diff --git a/Jellyfin.Server.Implementations/Users/UserManager.cs b/Jellyfin.Server.Implementations/Users/UserManager.cs index 6a2ef74dd2..ed90e81c6f 100644 --- a/Jellyfin.Server.Implementations/Users/UserManager.cs +++ b/Jellyfin.Server.Implementations/Users/UserManager.cs @@ -130,10 +130,7 @@ namespace Jellyfin.Server.Implementations.Users /// public async Task RenameUser(User user, string newName) { - if (user == null) - { - throw new ArgumentNullException(nameof(user)); - } + ArgumentNullException.ThrowIfNull(user); ThrowIfInvalidUsername(newName); @@ -267,10 +264,7 @@ namespace Jellyfin.Server.Implementations.Users /// public async Task ChangePassword(User user, string newPassword) { - if (user == null) - { - throw new ArgumentNullException(nameof(user)); - } + ArgumentNullException.ThrowIfNull(user); await GetAuthenticationProvider(user).ChangePassword(user, newPassword).ConfigureAwait(false); await UpdateUserAsync(user).ConfigureAwait(false); diff --git a/MediaBrowser.Common/Net/IPNetAddress.cs b/MediaBrowser.Common/Net/IPNetAddress.cs index f1428d4bef..98d1c2d97b 100644 --- a/MediaBrowser.Common/Net/IPNetAddress.cs +++ b/MediaBrowser.Common/Net/IPNetAddress.cs @@ -160,10 +160,7 @@ namespace MediaBrowser.Common.Net /// public override bool Contains(IPAddress address) { - if (address == null) - { - throw new ArgumentNullException(nameof(address)); - } + ArgumentNullException.ThrowIfNull(address); if (address.IsIPv4MappedToIPv6) { diff --git a/MediaBrowser.Common/Net/IPObject.cs b/MediaBrowser.Common/Net/IPObject.cs index 3a5187bc3d..37385972f7 100644 --- a/MediaBrowser.Common/Net/IPObject.cs +++ b/MediaBrowser.Common/Net/IPObject.cs @@ -55,10 +55,7 @@ namespace MediaBrowser.Common.Net /// IPAddress. public static (IPAddress Address, byte PrefixLength) NetworkAddressOf(IPAddress address, byte prefixLength) { - if (address == null) - { - throw new ArgumentNullException(nameof(address)); - } + ArgumentNullException.ThrowIfNull(address); if (address.IsIPv4MappedToIPv6) { @@ -109,10 +106,7 @@ namespace MediaBrowser.Common.Net /// True if it is. public static bool IsIP6(IPAddress address) { - if (address == null) - { - throw new ArgumentNullException(nameof(address)); - } + ArgumentNullException.ThrowIfNull(address); if (address.IsIPv4MappedToIPv6) { @@ -129,10 +123,7 @@ namespace MediaBrowser.Common.Net /// True if it contains a private address. public static bool IsPrivateAddressRange(IPAddress address) { - if (address == null) - { - throw new ArgumentNullException(nameof(address)); - } + ArgumentNullException.ThrowIfNull(address); if (!address.Equals(IPAddress.None)) { @@ -179,10 +170,7 @@ namespace MediaBrowser.Common.Net /// public static bool IsIPv6LinkLocal(IPAddress address) { - if (address == null) - { - throw new ArgumentNullException(nameof(address)); - } + ArgumentNullException.ThrowIfNull(address); if (address.IsIPv4MappedToIPv6) { @@ -226,10 +214,7 @@ namespace MediaBrowser.Common.Net /// Byte CIDR representing the mask. public static byte MaskToCidr(IPAddress mask) { - if (mask == null) - { - throw new ArgumentNullException(nameof(mask)); - } + ArgumentNullException.ThrowIfNull(mask); byte cidrnet = 0; if (!mask.Equals(IPAddress.Any)) diff --git a/MediaBrowser.Common/Net/NetworkExtensions.cs b/MediaBrowser.Common/Net/NetworkExtensions.cs index 264bfacb49..7ad0058540 100644 --- a/MediaBrowser.Common/Net/NetworkExtensions.cs +++ b/MediaBrowser.Common/Net/NetworkExtensions.cs @@ -61,10 +61,7 @@ namespace MediaBrowser.Common.Net return false; } - if (item == null) - { - throw new ArgumentNullException(nameof(item)); - } + ArgumentNullException.ThrowIfNull(item); if (item.IsIPv4MappedToIPv6) { @@ -96,10 +93,7 @@ namespace MediaBrowser.Common.Net return false; } - if (item == null) - { - throw new ArgumentNullException(nameof(item)); - } + ArgumentNullException.ThrowIfNull(item); foreach (var i in source) { @@ -153,10 +147,7 @@ namespace MediaBrowser.Common.Net /// Collection{IPObject} object containing the subnets. public static Collection AsNetworks(this Collection source) { - if (source == null) - { - throw new ArgumentNullException(nameof(source)); - } + ArgumentNullException.ThrowIfNull(source); Collection res = new Collection(); @@ -239,10 +230,7 @@ namespace MediaBrowser.Common.Net return new Collection(); } - if (target == null) - { - throw new ArgumentNullException(nameof(target)); - } + ArgumentNullException.ThrowIfNull(target); Collection nc = new Collection(); diff --git a/MediaBrowser.Common/Plugins/BasePluginOfT.cs b/MediaBrowser.Common/Plugins/BasePluginOfT.cs index afda83a7c5..0da5592d38 100644 --- a/MediaBrowser.Common/Plugins/BasePluginOfT.cs +++ b/MediaBrowser.Common/Plugins/BasePluginOfT.cs @@ -164,10 +164,7 @@ namespace MediaBrowser.Common.Plugins /// public virtual void UpdateConfiguration(BasePluginConfiguration configuration) { - if (configuration == null) - { - throw new ArgumentNullException(nameof(configuration)); - } + ArgumentNullException.ThrowIfNull(configuration); Configuration = (TConfigurationType)configuration; diff --git a/MediaBrowser.Controller/Entities/AggregateFolder.cs b/MediaBrowser.Controller/Entities/AggregateFolder.cs index 77a857b785..e671e5c711 100644 --- a/MediaBrowser.Controller/Entities/AggregateFolder.cs +++ b/MediaBrowser.Controller/Entities/AggregateFolder.cs @@ -171,10 +171,7 @@ namespace MediaBrowser.Controller.Entities /// Throws if child is null. public void AddVirtualChild(BaseItem child) { - if (child == null) - { - throw new ArgumentNullException(nameof(child)); - } + ArgumentNullException.ThrowIfNull(child); _virtualChildren.Add(child); } diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index 9461b01e31..41fce67fa7 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -1101,10 +1101,7 @@ namespace MediaBrowser.Controller.Entities private MediaSourceInfo GetVersionInfo(bool enablePathSubstitution, BaseItem item, MediaSourceType type) { - if (item == null) - { - throw new ArgumentNullException(nameof(item)); - } + ArgumentNullException.ThrowIfNull(item); var protocol = item.PathProtocol; @@ -1544,10 +1541,7 @@ namespace MediaBrowser.Controller.Entities /// If user is null. public bool IsParentalAllowed(User user) { - if (user == null) - { - throw new ArgumentNullException(nameof(user)); - } + ArgumentNullException.ThrowIfNull(user); if (!IsVisibleViaTags(user)) { @@ -1667,10 +1661,7 @@ namespace MediaBrowser.Controller.Entities /// is null. public virtual bool IsVisible(User user) { - if (user == null) - { - throw new ArgumentNullException(nameof(user)); - } + ArgumentNullException.ThrowIfNull(user); return IsParentalAllowed(user); } @@ -1842,10 +1833,7 @@ namespace MediaBrowser.Controller.Entities DateTime? datePlayed, bool resetPosition) { - if (user == null) - { - throw new ArgumentNullException(nameof(user)); - } + ArgumentNullException.ThrowIfNull(user); var data = UserDataManager.GetUserData(user, this); @@ -1876,10 +1864,7 @@ namespace MediaBrowser.Controller.Entities /// Throws if user is null. public virtual void MarkUnplayed(User user) { - if (user == null) - { - throw new ArgumentNullException(nameof(user)); - } + ArgumentNullException.ThrowIfNull(user); var data = UserDataManager.GetUserData(user, this); @@ -2110,10 +2095,7 @@ namespace MediaBrowser.Controller.Entities /// Image index. public int GetImageIndex(ItemImageInfo image) { - if (image == null) - { - throw new ArgumentNullException(nameof(image)); - } + ArgumentNullException.ThrowIfNull(image); if (image.Type == ImageType.Chapter) { @@ -2320,10 +2302,7 @@ namespace MediaBrowser.Controller.Entities public virtual bool IsUnplayed(User user) { - if (user == null) - { - throw new ArgumentNullException(nameof(user)); - } + ArgumentNullException.ThrowIfNull(user); var userdata = UserDataManager.GetUserData(user, this); diff --git a/MediaBrowser.Controller/Entities/BaseItemExtensions.cs b/MediaBrowser.Controller/Entities/BaseItemExtensions.cs index e0583e6308..948eb43754 100644 --- a/MediaBrowser.Controller/Entities/BaseItemExtensions.cs +++ b/MediaBrowser.Controller/Entities/BaseItemExtensions.cs @@ -71,15 +71,9 @@ namespace MediaBrowser.Controller.Entities where T : BaseItem where TU : BaseItem { - if (source == null) - { - throw new ArgumentNullException(nameof(source)); - } + ArgumentNullException.ThrowIfNull(source); - if (dest == null) - { - throw new ArgumentNullException(nameof(dest)); - } + ArgumentNullException.ThrowIfNull(dest); var destProps = typeof(TU).GetProperties().Where(x => x.CanWrite).ToList(); diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index 92d12a86ca..808f918104 100644 --- a/MediaBrowser.Controller/Entities/Folder.cs +++ b/MediaBrowser.Controller/Entities/Folder.cs @@ -1023,10 +1023,7 @@ namespace MediaBrowser.Controller.Entities IServerConfigurationManager configurationManager, ICollectionManager collectionManager) { - if (items == null) - { - throw new ArgumentNullException(nameof(items)); - } + ArgumentNullException.ThrowIfNull(items); if (CollapseBoxSetItems(query, queryParent, user, configurationManager)) { @@ -1273,20 +1270,14 @@ namespace MediaBrowser.Controller.Entities public List GetChildren(User user, bool includeLinkedChildren) { - if (user == null) - { - throw new ArgumentNullException(nameof(user)); - } + ArgumentNullException.ThrowIfNull(user); return GetChildren(user, includeLinkedChildren, null); } public virtual List GetChildren(User user, bool includeLinkedChildren, InternalItemsQuery query) { - if (user == null) - { - throw new ArgumentNullException(nameof(user)); - } + ArgumentNullException.ThrowIfNull(user); // the true root should return our users root folder children if (IsPhysicalRoot) @@ -1367,10 +1358,7 @@ namespace MediaBrowser.Controller.Entities public virtual IEnumerable GetRecursiveChildren(User user, InternalItemsQuery query) { - if (user == null) - { - throw new ArgumentNullException(nameof(user)); - } + ArgumentNullException.ThrowIfNull(user); var result = new Dictionary(); diff --git a/MediaBrowser.Controller/Entities/PeopleHelper.cs b/MediaBrowser.Controller/Entities/PeopleHelper.cs index 687ce1ec8d..8571bfcea5 100644 --- a/MediaBrowser.Controller/Entities/PeopleHelper.cs +++ b/MediaBrowser.Controller/Entities/PeopleHelper.cs @@ -11,10 +11,7 @@ namespace MediaBrowser.Controller.Entities { public static void AddPerson(List people, PersonInfo person) { - if (person == null) - { - throw new ArgumentNullException(nameof(person)); - } + ArgumentNullException.ThrowIfNull(person); if (string.IsNullOrEmpty(person.Name)) { diff --git a/MediaBrowser.Controller/IO/FileData.cs b/MediaBrowser.Controller/IO/FileData.cs index 2429ac42db..71feae536c 100644 --- a/MediaBrowser.Controller/IO/FileData.cs +++ b/MediaBrowser.Controller/IO/FileData.cs @@ -40,10 +40,7 @@ namespace MediaBrowser.Controller.IO throw new ArgumentNullException(nameof(path)); } - if (args == null) - { - throw new ArgumentNullException(nameof(args)); - } + ArgumentNullException.ThrowIfNull(args); var entries = directoryService.GetFileSystemEntries(path); diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index 42c5517f9d..d0362b128c 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -5105,15 +5105,9 @@ namespace MediaBrowser.Controller.MediaEncoding MediaSourceInfo mediaSource, string requestedUrl) { - if (state == null) - { - throw new ArgumentNullException(nameof(state)); - } + ArgumentNullException.ThrowIfNull(state); - if (mediaSource == null) - { - throw new ArgumentNullException(nameof(mediaSource)); - } + ArgumentNullException.ThrowIfNull(mediaSource); var path = mediaSource.Path; var protocol = mediaSource.Protocol; diff --git a/MediaBrowser.Controller/Net/BasePeriodicWebSocketListener.cs b/MediaBrowser.Controller/Net/BasePeriodicWebSocketListener.cs index eadc09fd4b..647de50030 100644 --- a/MediaBrowser.Controller/Net/BasePeriodicWebSocketListener.cs +++ b/MediaBrowser.Controller/Net/BasePeriodicWebSocketListener.cs @@ -38,10 +38,7 @@ namespace MediaBrowser.Controller.Net protected BasePeriodicWebSocketListener(ILogger> logger) { - if (logger == null) - { - throw new ArgumentNullException(nameof(logger)); - } + ArgumentNullException.ThrowIfNull(logger); Logger = logger; } @@ -77,10 +74,7 @@ namespace MediaBrowser.Controller.Net /// Task. public Task ProcessMessageAsync(WebSocketMessageInfo message) { - if (message == null) - { - throw new ArgumentNullException(nameof(message)); - } + ArgumentNullException.ThrowIfNull(message); if (message.MessageType == StartType) { diff --git a/MediaBrowser.LocalMetadata/Parsers/BaseItemXmlParser.cs b/MediaBrowser.LocalMetadata/Parsers/BaseItemXmlParser.cs index 777fe67746..a9e1b4a51e 100644 --- a/MediaBrowser.LocalMetadata/Parsers/BaseItemXmlParser.cs +++ b/MediaBrowser.LocalMetadata/Parsers/BaseItemXmlParser.cs @@ -53,10 +53,7 @@ namespace MediaBrowser.LocalMetadata.Parsers /// Item is null. public void Fetch(MetadataResult item, string metadataFile, CancellationToken cancellationToken) { - if (item == null) - { - throw new ArgumentNullException(nameof(item)); - } + ArgumentNullException.ThrowIfNull(item); if (string.IsNullOrEmpty(metadataFile)) { diff --git a/MediaBrowser.MediaEncoding/Attachments/AttachmentExtractor.cs b/MediaBrowser.MediaEncoding/Attachments/AttachmentExtractor.cs index 142571e8f6..22abf93ac3 100644 --- a/MediaBrowser.MediaEncoding/Attachments/AttachmentExtractor.cs +++ b/MediaBrowser.MediaEncoding/Attachments/AttachmentExtractor.cs @@ -52,10 +52,7 @@ namespace MediaBrowser.MediaEncoding.Attachments /// public async Task<(MediaAttachment Attachment, Stream Stream)> GetAttachment(BaseItem item, string mediaSourceId, int attachmentStreamIndex, CancellationToken cancellationToken) { - if (item == null) - { - throw new ArgumentNullException(nameof(item)); - } + ArgumentNullException.ThrowIfNull(item); if (string.IsNullOrWhiteSpace(mediaSourceId)) { diff --git a/MediaBrowser.MediaEncoding/Probing/FFProbeHelpers.cs b/MediaBrowser.MediaEncoding/Probing/FFProbeHelpers.cs index a9e753726d..205e84153b 100644 --- a/MediaBrowser.MediaEncoding/Probing/FFProbeHelpers.cs +++ b/MediaBrowser.MediaEncoding/Probing/FFProbeHelpers.cs @@ -15,10 +15,7 @@ namespace MediaBrowser.MediaEncoding.Probing /// The result. public static void NormalizeFFProbeResult(InternalMediaInfoResult result) { - if (result == null) - { - throw new ArgumentNullException(nameof(result)); - } + ArgumentNullException.ThrowIfNull(result); if (result.Format?.Tags != null) { diff --git a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs index 115f085ff8..9185faf67b 100644 --- a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs +++ b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs @@ -120,10 +120,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles async Task ISubtitleEncoder.GetSubtitles(BaseItem item, string mediaSourceId, int subtitleStreamIndex, string outputFormat, long startTimeTicks, long endTimeTicks, bool preserveOriginalTimestamps, CancellationToken cancellationToken) { - if (item == null) - { - throw new ArgumentNullException(nameof(item)); - } + ArgumentNullException.ThrowIfNull(item); if (string.IsNullOrWhiteSpace(mediaSourceId)) { diff --git a/MediaBrowser.Model/Cryptography/PasswordHash.cs b/MediaBrowser.Model/Cryptography/PasswordHash.cs index eec5410411..32a34d23c1 100644 --- a/MediaBrowser.Model/Cryptography/PasswordHash.cs +++ b/MediaBrowser.Model/Cryptography/PasswordHash.cs @@ -29,10 +29,7 @@ namespace MediaBrowser.Model.Cryptography public PasswordHash(string id, byte[] hash, byte[] salt, Dictionary parameters) { - if (id == null) - { - throw new ArgumentNullException(nameof(id)); - } + ArgumentNullException.ThrowIfNull(id); if (id.Length == 0) { diff --git a/MediaBrowser.Model/Dlna/StreamBuilder.cs b/MediaBrowser.Model/Dlna/StreamBuilder.cs index fdb9fd5d54..b121a29058 100644 --- a/MediaBrowser.Model/Dlna/StreamBuilder.cs +++ b/MediaBrowser.Model/Dlna/StreamBuilder.cs @@ -565,10 +565,7 @@ namespace MediaBrowser.Model.Dlna private StreamInfo BuildVideoItem(MediaSourceInfo item, VideoOptions options) { - if (item == null) - { - throw new ArgumentNullException(nameof(item)); - } + ArgumentNullException.ThrowIfNull(item); StreamInfo playlistItem = new StreamInfo { diff --git a/MediaBrowser.Model/Entities/ProviderIdsExtensions.cs b/MediaBrowser.Model/Entities/ProviderIdsExtensions.cs index 62a2f3ce84..d3b8400f34 100644 --- a/MediaBrowser.Model/Entities/ProviderIdsExtensions.cs +++ b/MediaBrowser.Model/Entities/ProviderIdsExtensions.cs @@ -28,10 +28,7 @@ namespace MediaBrowser.Model.Entities /// true if a provider id with the given name was found; otherwise false. public static bool HasProviderId(this IHasProviderIds instance, string name) { - if (instance == null) - { - throw new ArgumentNullException(nameof(instance)); - } + ArgumentNullException.ThrowIfNull(instance); return instance.TryGetProviderId(name, out _); } @@ -56,10 +53,7 @@ namespace MediaBrowser.Model.Entities /// true if a provider id with the given name was found; otherwise false. public static bool TryGetProviderId(this IHasProviderIds instance, string name, [NotNullWhen(true)] out string? id) { - if (instance == null) - { - throw new ArgumentNullException(nameof(instance)); - } + ArgumentNullException.ThrowIfNull(instance); if (instance.ProviderIds == null) { @@ -121,10 +115,7 @@ namespace MediaBrowser.Model.Entities /// The value. public static void SetProviderId(this IHasProviderIds instance, string name, string? value) { - if (instance == null) - { - throw new ArgumentNullException(nameof(instance)); - } + ArgumentNullException.ThrowIfNull(instance); // If it's null remove the key from the dictionary if (string.IsNullOrEmpty(value)) diff --git a/src/Jellyfin.Extensions/EnumerableExtensions.cs b/src/Jellyfin.Extensions/EnumerableExtensions.cs index b5fe933571..a31a57dc65 100644 --- a/src/Jellyfin.Extensions/EnumerableExtensions.cs +++ b/src/Jellyfin.Extensions/EnumerableExtensions.cs @@ -18,10 +18,7 @@ namespace Jellyfin.Extensions /// The source is null. public static bool Contains(this IEnumerable source, ReadOnlySpan value, StringComparison stringComparison) { - if (source == null) - { - throw new ArgumentNullException(nameof(source)); - } + ArgumentNullException.ThrowIfNull(source); if (source is IList list) { diff --git a/tests/Jellyfin.Networking.Tests/NetworkParseTests.cs b/tests/Jellyfin.Networking.Tests/NetworkParseTests.cs index 52b0e5a955..166bc0513a 100644 --- a/tests/Jellyfin.Networking.Tests/NetworkParseTests.cs +++ b/tests/Jellyfin.Networking.Tests/NetworkParseTests.cs @@ -103,10 +103,7 @@ namespace Jellyfin.Networking.Tests "[192.158.0.0/16,192.0.0.0/8]")] public void TestCollections(string settings, string result1, string result2, string result3, string result4, string result5) { - if (settings == null) - { - throw new ArgumentNullException(nameof(settings)); - } + ArgumentNullException.ThrowIfNull(settings); var conf = new NetworkConfiguration() { @@ -155,20 +152,11 @@ namespace Jellyfin.Networking.Tests [InlineData("127.0.0.1", "127.0.0.1/8", "[127.0.0.1/32]")] public void UnionCheck(string settings, string compare, string result) { - if (settings == null) - { - throw new ArgumentNullException(nameof(settings)); - } + ArgumentNullException.ThrowIfNull(settings); - if (compare == null) - { - throw new ArgumentNullException(nameof(compare)); - } + ArgumentNullException.ThrowIfNull(compare); - if (result == null) - { - throw new ArgumentNullException(nameof(result)); - } + ArgumentNullException.ThrowIfNull(result); var conf = new NetworkConfiguration() { @@ -264,20 +252,11 @@ namespace Jellyfin.Networking.Tests public void TestCollectionEquality(string source, string dest, string result) { - if (source == null) - { - throw new ArgumentNullException(nameof(source)); - } + ArgumentNullException.ThrowIfNull(source); - if (dest == null) - { - throw new ArgumentNullException(nameof(dest)); - } + ArgumentNullException.ThrowIfNull(dest); - if (result == null) - { - throw new ArgumentNullException(nameof(result)); - } + ArgumentNullException.ThrowIfNull(result); var conf = new NetworkConfiguration() { @@ -331,20 +310,11 @@ namespace Jellyfin.Networking.Tests [InlineData("", "", false, "eth16")] public void TestBindInterfaces(string source, string bindAddresses, bool ipv6enabled, string result) { - if (source == null) - { - throw new ArgumentNullException(nameof(source)); - } + ArgumentNullException.ThrowIfNull(source); - if (bindAddresses == null) - { - throw new ArgumentNullException(nameof(bindAddresses)); - } + ArgumentNullException.ThrowIfNull(bindAddresses); - if (result == null) - { - throw new ArgumentNullException(nameof(result)); - } + ArgumentNullException.ThrowIfNull(result); var conf = new NetworkConfiguration() { @@ -403,15 +373,9 @@ namespace Jellyfin.Networking.Tests [InlineData("192.168.1.1", "192.168.1.0/24", "", false, "eth16=http://helloworld.com", "http://helloworld.com")] public void TestBindInterfaceOverrides(string source, string lan, string bindAddresses, bool ipv6enabled, string publishedServers, string result) { - if (lan == null) - { - throw new ArgumentNullException(nameof(lan)); - } + ArgumentNullException.ThrowIfNull(lan); - if (bindAddresses == null) - { - throw new ArgumentNullException(nameof(bindAddresses)); - } + ArgumentNullException.ThrowIfNull(bindAddresses); var conf = new NetworkConfiguration() { -- cgit v1.2.3