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 --- MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'MediaBrowser.MediaEncoding/Encoder') 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. /// -- 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.MediaEncoding/Encoder') 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 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.MediaEncoding/Encoder') 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 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.MediaEncoding/Encoder') 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.MediaEncoding/Encoder') 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.MediaEncoding/Encoder') 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