diff options
Diffstat (limited to 'MediaBrowser.MediaEncoding')
6 files changed, 89 insertions, 78 deletions
diff --git a/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs b/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs index 8479b7d50..9e6134b52 100644 --- a/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs +++ b/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs @@ -56,6 +56,7 @@ namespace MediaBrowser.MediaEncoding.Encoder "libvpx", "libvpx-vp9", "aac", + "aac_at", "libfdk_aac", "ac3", "libmp3lame", @@ -106,7 +107,10 @@ namespace MediaBrowser.MediaEncoding.Encoder // vulkan "libplacebo", "scale_vulkan", - "overlay_vulkan" + "overlay_vulkan", + "hwupload_vaapi", + // videotoolbox + "yadif_videotoolbox" }; private static readonly IReadOnlyDictionary<int, string[]> _filterOptionsDict = new Dictionary<int, string[]> diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs index d2240b5af..cef02d5f8 100644 --- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs @@ -12,6 +12,7 @@ using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; using Jellyfin.Extensions.Json; +using Jellyfin.Extensions.Json.Converters; using MediaBrowser.Common; using MediaBrowser.Common.Configuration; using MediaBrowser.Common.Extensions; @@ -105,7 +106,9 @@ namespace MediaBrowser.MediaEncoding.Encoder _config = config; _serverConfig = serverConfig; _startupOptionFFmpegPath = config.GetValue<string>(Controller.Extensions.ConfigurationExtensions.FfmpegPathKey) ?? string.Empty; - _jsonSerializerOptions = JsonDefaults.Options; + + _jsonSerializerOptions = new JsonSerializerOptions(JsonDefaults.Options); + _jsonSerializerOptions.Converters.Add(new JsonBoolStringConverter()); } /// <inheritdoc /> diff --git a/MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj b/MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj index 93177298f..f4438fe19 100644 --- a/MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj +++ b/MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj @@ -22,21 +22,21 @@ </ItemGroup> <ItemGroup> - <PackageReference Include="libse" Version="3.6.10" /> - <PackageReference Include="Microsoft.Extensions.Http" Version="7.0.0" /> - <PackageReference Include="System.Text.Encoding.CodePages" Version="7.0.0" /> - <PackageReference Include="UTF.Unknown" Version="2.5.1" /> + <PackageReference Include="libse" /> + <PackageReference Include="Microsoft.Extensions.Http" /> + <PackageReference Include="System.Text.Encoding.CodePages" /> + <PackageReference Include="UTF.Unknown" /> </ItemGroup> <!-- Code Analyzers--> <ItemGroup Condition=" '$(Configuration)' == 'Debug' "> - <PackageReference Include="Microsoft.CodeAnalysis.BannedApiAnalyzers" Version="3.3.4"> + <PackageReference Include="Microsoft.CodeAnalysis.BannedApiAnalyzers"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> </PackageReference> - <PackageReference Include="SerilogAnalyzer" Version="0.15.0" PrivateAssets="All" /> - <PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.435" PrivateAssets="All" /> - <PackageReference Include="SmartAnalyzers.MultithreadingAnalyzer" Version="1.1.31" PrivateAssets="All" /> + <PackageReference Include="SerilogAnalyzer" PrivateAssets="All" /> + <PackageReference Include="StyleCop.Analyzers" PrivateAssets="All" /> + <PackageReference Include="SmartAnalyzers.MultithreadingAnalyzer" PrivateAssets="All" /> </ItemGroup> </Project> diff --git a/MediaBrowser.MediaEncoding/Probing/CodecType.cs b/MediaBrowser.MediaEncoding/Probing/CodecType.cs new file mode 100644 index 000000000..d7c68e5f3 --- /dev/null +++ b/MediaBrowser.MediaEncoding/Probing/CodecType.cs @@ -0,0 +1,32 @@ +namespace MediaBrowser.MediaEncoding.Probing; + +/// <summary> +/// FFmpeg Codec Type. +/// </summary> +public enum CodecType +{ + /// <summary> + /// Video. + /// </summary> + Video, + + /// <summary> + /// Audio. + /// </summary> + Audio, + + /// <summary> + /// Opaque data information usually continuous. + /// </summary> + Data, + + /// <summary> + /// Subtitles. + /// </summary> + Subtitle, + + /// <summary> + /// Opaque data information usually sparse. + /// </summary> + Attachment +} diff --git a/MediaBrowser.MediaEncoding/Probing/MediaStreamInfo.cs b/MediaBrowser.MediaEncoding/Probing/MediaStreamInfo.cs index eab8f79bb..294442324 100644 --- a/MediaBrowser.MediaEncoding/Probing/MediaStreamInfo.cs +++ b/MediaBrowser.MediaEncoding/Probing/MediaStreamInfo.cs @@ -43,7 +43,7 @@ namespace MediaBrowser.MediaEncoding.Probing /// </summary> /// <value>The codec_type.</value> [JsonPropertyName("codec_type")] - public string CodecType { get; set; } + public CodecType CodecType { get; set; } /// <summary> /// Gets or sets the sample_rate. @@ -228,11 +228,11 @@ namespace MediaBrowser.MediaEncoding.Probing public long StartPts { get; set; } /// <summary> - /// Gets or sets the is_avc. + /// Gets or sets a value indicating whether the stream is AVC. /// </summary> /// <value>The is_avc.</value> [JsonPropertyName("is_avc")] - public string IsAvc { get; set; } + public bool IsAvc { get; set; } /// <summary> /// Gets or sets the nal_length_size. diff --git a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs index 04bdbdf59..99310a75d 100644 --- a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs +++ b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs @@ -65,7 +65,8 @@ namespace MediaBrowser.MediaEncoding.Probing "K/DA", "22/7", "諭吉佳作/men", - "//dARTH nULL" + "//dARTH nULL", + "Phantom/Ghost", }; public MediaInfo GetMediaInfo(InternalMediaInfoResult data, VideoType? videoType, bool isAudio, string path, MediaProtocol protocol) @@ -106,9 +107,9 @@ namespace MediaBrowser.MediaEncoding.Probing } var tags = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); - var tagStreamType = isAudio ? "audio" : "video"; + var tagStreamType = isAudio ? CodecType.Audio : CodecType.Video; - var tagStream = data.Streams?.FirstOrDefault(i => string.Equals(i.CodecType, tagStreamType, StringComparison.OrdinalIgnoreCase)); + var tagStream = data.Streams?.FirstOrDefault(i => i.CodecType == tagStreamType); if (tagStream?.Tags is not null) { @@ -598,7 +599,7 @@ namespace MediaBrowser.MediaEncoding.Probing /// <returns>MediaAttachments.</returns> private MediaAttachment GetMediaAttachment(MediaStreamInfo streamInfo) { - if (!string.Equals(streamInfo.CodecType, "attachment", StringComparison.OrdinalIgnoreCase) + if (streamInfo.CodecType != CodecType.Attachment && streamInfo.Disposition?.GetValueOrDefault("attached_pic") != 1) { return null; @@ -650,20 +651,10 @@ namespace MediaBrowser.MediaEncoding.Probing PixelFormat = streamInfo.PixelFormat, NalLengthSize = streamInfo.NalLengthSize, TimeBase = streamInfo.TimeBase, - CodecTimeBase = streamInfo.CodecTimeBase + CodecTimeBase = streamInfo.CodecTimeBase, + IsAVC = streamInfo.IsAvc }; - if (string.Equals(streamInfo.IsAvc, "true", StringComparison.OrdinalIgnoreCase) || - string.Equals(streamInfo.IsAvc, "1", StringComparison.OrdinalIgnoreCase)) - { - stream.IsAVC = true; - } - else if (string.Equals(streamInfo.IsAvc, "false", StringComparison.OrdinalIgnoreCase) || - string.Equals(streamInfo.IsAvc, "0", StringComparison.OrdinalIgnoreCase)) - { - stream.IsAVC = false; - } - // Filter out junk if (!string.IsNullOrWhiteSpace(streamInfo.CodecTagString) && !streamInfo.CodecTagString.Contains("[0]", StringComparison.OrdinalIgnoreCase)) { @@ -677,18 +668,15 @@ namespace MediaBrowser.MediaEncoding.Probing stream.Title = GetDictionaryValue(streamInfo.Tags, "title"); } - if (string.Equals(streamInfo.CodecType, "audio", StringComparison.OrdinalIgnoreCase)) + if (streamInfo.CodecType == CodecType.Audio) { stream.Type = MediaStreamType.Audio; stream.Channels = streamInfo.Channels; - if (!string.IsNullOrEmpty(streamInfo.SampleRate)) + if (int.TryParse(streamInfo.SampleRate, NumberStyles.Any, CultureInfo.InvariantCulture, out var value)) { - if (int.TryParse(streamInfo.SampleRate, NumberStyles.Any, CultureInfo.InvariantCulture, out var value)) - { - stream.SampleRate = value; - } + stream.SampleRate = value; } stream.ChannelLayout = ParseChannelLayout(streamInfo.ChannelLayout); @@ -712,7 +700,7 @@ namespace MediaBrowser.MediaEncoding.Probing } } } - else if (string.Equals(streamInfo.CodecType, "subtitle", StringComparison.OrdinalIgnoreCase)) + else if (streamInfo.CodecType == CodecType.Subtitle) { stream.Type = MediaStreamType.Subtitle; stream.Codec = NormalizeSubtitleCodec(stream.Codec); @@ -732,7 +720,7 @@ namespace MediaBrowser.MediaEncoding.Probing } } } - else if (string.Equals(streamInfo.CodecType, "video", StringComparison.OrdinalIgnoreCase)) + else if (streamInfo.CodecType == CodecType.Video) { stream.AverageFrameRate = GetFrameRate(streamInfo.AverageFrameRate); stream.RealFrameRate = GetFrameRate(streamInfo.RFrameRate); @@ -853,13 +841,12 @@ namespace MediaBrowser.MediaEncoding.Probing } } } - else if (string.Equals(streamInfo.CodecType, "data", StringComparison.OrdinalIgnoreCase)) + else if (streamInfo.CodecType == CodecType.Data) { stream.Type = MediaStreamType.Data; } else { - _logger.LogError("Codec Type {CodecType} unknown. The stream (index: {Index}) will be ignored. Warning: Subsequential streams will have a wrong stream specifier!", streamInfo.CodecType, streamInfo.Index); return null; } @@ -894,29 +881,26 @@ namespace MediaBrowser.MediaEncoding.Probing // Extract bitrate info from tag "BPS" if possible. if (!stream.BitRate.HasValue - && (string.Equals(streamInfo.CodecType, "audio", StringComparison.OrdinalIgnoreCase) - || string.Equals(streamInfo.CodecType, "video", StringComparison.OrdinalIgnoreCase))) + && (streamInfo.CodecType == CodecType.Audio + || streamInfo.CodecType == CodecType.Video)) { var bps = GetBPSFromTags(streamInfo); if (bps > 0) { stream.BitRate = bps; } - } - - // Get average bitrate info from tag "NUMBER_OF_BYTES" and "DURATION" if possible. - if (!stream.BitRate.HasValue - && (string.Equals(streamInfo.CodecType, "audio", StringComparison.OrdinalIgnoreCase) - || string.Equals(streamInfo.CodecType, "video", StringComparison.OrdinalIgnoreCase))) - { - var durationInSeconds = GetRuntimeSecondsFromTags(streamInfo); - var bytes = GetNumberOfBytesFromTags(streamInfo); - if (durationInSeconds is not null && bytes is not null) + else { - var bps = Convert.ToInt32(bytes * 8 / durationInSeconds, CultureInfo.InvariantCulture); - if (bps > 0) + // Get average bitrate info from tag "NUMBER_OF_BYTES" and "DURATION" if possible. + var durationInSeconds = GetRuntimeSecondsFromTags(streamInfo); + var bytes = GetNumberOfBytesFromTags(streamInfo); + if (durationInSeconds is not null && bytes is not null) { - stream.BitRate = bps; + bps = Convert.ToInt32(bytes * 8 / durationInSeconds, CultureInfo.InvariantCulture); + if (bps > 0) + { + stream.BitRate = bps; + } } } } @@ -947,12 +931,8 @@ namespace MediaBrowser.MediaEncoding.Probing private void NormalizeStreamTitle(MediaStream stream) { - if (string.Equals(stream.Title, "cc", StringComparison.OrdinalIgnoreCase)) - { - stream.Title = null; - } - - if (stream.Type == MediaStreamType.EmbeddedImage) + if (string.Equals(stream.Title, "cc", StringComparison.OrdinalIgnoreCase) + || stream.Type == MediaStreamType.EmbeddedImage) { stream.Title = null; } @@ -983,7 +963,7 @@ namespace MediaBrowser.MediaEncoding.Probing return null; } - return input.Split('(').FirstOrDefault(); + return input.AsSpan().LeftPart('(').ToString(); } private string GetAspectRatio(MediaStreamInfo info) @@ -991,11 +971,11 @@ namespace MediaBrowser.MediaEncoding.Probing var original = info.DisplayAspectRatio; var parts = (original ?? string.Empty).Split(':'); - if (!(parts.Length == 2 && - int.TryParse(parts[0], NumberStyles.Any, CultureInfo.InvariantCulture, out var width) && - int.TryParse(parts[1], NumberStyles.Any, CultureInfo.InvariantCulture, out var height) && - width > 0 && - height > 0)) + if (!(parts.Length == 2 + && int.TryParse(parts[0], NumberStyles.Any, CultureInfo.InvariantCulture, out var width) + && int.TryParse(parts[1], NumberStyles.Any, CultureInfo.InvariantCulture, out var height) + && width > 0 + && height > 0)) { width = info.Width; height = info.Height; @@ -1076,12 +1056,6 @@ namespace MediaBrowser.MediaEncoding.Probing int index = value.IndexOf('/'); if (index == -1) { - // REVIEW: is this branch actually required? (i.e. does ffprobe ever output something other than a fraction?) - if (float.TryParse(value, NumberStyles.AllowThousands | NumberStyles.Float, CultureInfo.InvariantCulture, out var result)) - { - return result; - } - return null; } @@ -1097,7 +1071,7 @@ namespace MediaBrowser.MediaEncoding.Probing private void SetAudioRuntimeTicks(InternalMediaInfoResult result, MediaInfo data) { // Get the first info stream - var stream = result.Streams?.FirstOrDefault(s => string.Equals(s.CodecType, "audio", StringComparison.OrdinalIgnoreCase)); + var stream = result.Streams?.FirstOrDefault(s => s.CodecType == CodecType.Audio); if (stream is null) { return; @@ -1127,8 +1101,7 @@ namespace MediaBrowser.MediaEncoding.Probing } var bps = GetDictionaryValue(streamInfo.Tags, "BPS-eng") ?? GetDictionaryValue(streamInfo.Tags, "BPS"); - if (!string.IsNullOrEmpty(bps) - && int.TryParse(bps, NumberStyles.Integer, CultureInfo.InvariantCulture, out var parsedBps)) + if (int.TryParse(bps, NumberStyles.Integer, CultureInfo.InvariantCulture, out var parsedBps)) { return parsedBps; } @@ -1161,8 +1134,7 @@ namespace MediaBrowser.MediaEncoding.Probing var numberOfBytes = GetDictionaryValue(streamInfo.Tags, "NUMBER_OF_BYTES-eng") ?? GetDictionaryValue(streamInfo.Tags, "NUMBER_OF_BYTES"); - if (!string.IsNullOrEmpty(numberOfBytes) - && long.TryParse(numberOfBytes, NumberStyles.Integer, CultureInfo.InvariantCulture, out var parsedBytes)) + if (long.TryParse(numberOfBytes, NumberStyles.Integer, CultureInfo.InvariantCulture, out var parsedBytes)) { return parsedBytes; } @@ -1454,7 +1426,7 @@ namespace MediaBrowser.MediaEncoding.Probing { var disc = tags.GetValueOrDefault(tagName); - if (!string.IsNullOrEmpty(disc) && int.TryParse(disc.AsSpan().LeftPart('/'), out var discNum)) + if (int.TryParse(disc.AsSpan().LeftPart('/'), out var discNum)) { return discNum; } |
