From b4851d4789be94796b7bf964d5dba26bd2d82388 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 21 Sep 2017 17:36:19 -0400 Subject: separate deinterlacing params by video codec --- MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs') diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index 657b9c959..642a42c8e 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -796,12 +796,13 @@ namespace MediaBrowser.Controller.MediaEncoding if (videoStream.IsInterlaced) { - if (request.DeInterlace) + if (state.DeInterlace(videoStream.Codec)) { return false; } } + if (videoStream.IsAnamorphic ?? false) { if (request.RequireNonAnamorphic) @@ -1357,7 +1358,7 @@ namespace MediaBrowser.Controller.MediaEncoding filters.Add("hwupload"); } - if (state.DeInterlace && !string.Equals(outputVideoCodec, "h264_vaapi", StringComparison.OrdinalIgnoreCase)) + if (state.DeInterlace("h264") && !string.Equals(outputVideoCodec, "h264_vaapi", StringComparison.OrdinalIgnoreCase)) { if (string.Equals(options.DeinterlaceMethod, "bobandweave", StringComparison.OrdinalIgnoreCase)) { @@ -1799,11 +1800,6 @@ namespace MediaBrowser.Controller.MediaEncoding state.InternalSubtitleStreamOffset = mediaStreams.Where(i => i.Type == MediaStreamType.Subtitle && !i.IsExternal).ToList().IndexOf(state.SubtitleStream); } - if (state.VideoStream != null && state.VideoStream.IsInterlaced) - { - state.DeInterlace = true; - } - EnforceResolutionLimit(state); NormalizeSubtitleEmbed(state); -- cgit v1.2.3 From 978eedbcb7a778248acd03b7f924260db70cd406 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 25 Sep 2017 01:06:15 -0400 Subject: improve support for compressed xmltv --- Emby.Dlna/Didl/DidlBuilder.cs | 12 +- Emby.Dlna/PlayTo/PlayToController.cs | 7 +- Emby.Server.Implementations/Archiving/ZipClient.cs | 17 +++ .../Emby.Server.Implementations.csproj | 4 +- .../LiveTv/Listings/XmlTvListingsProvider.cs | 42 ++++--- Emby.Server.Implementations/packages.config | 2 +- .../MediaEncoding/EncodingHelper.cs | 29 +++-- .../MediaEncoding/EncodingJobInfo.cs | 98 +++++++++++++-- .../MediaEncoding/EncodingJobOptions.cs | 15 +-- MediaBrowser.Model/Dlna/CodecProfile.cs | 21 +++- MediaBrowser.Model/Dlna/StreamBuilder.cs | 54 ++++---- MediaBrowser.Model/Dlna/StreamInfo.cs | 136 +++++++++++++++++---- MediaBrowser.Model/IO/IZipClient.cs | 2 + .../MediaBrowser.Server.Mono.csproj | 5 +- MediaBrowser.Server.Mono/packages.config | 2 +- .../MediaBrowser.ServerApplication.csproj | 5 +- MediaBrowser.ServerApplication/packages.config | 2 +- 17 files changed, 327 insertions(+), 126 deletions(-) (limited to 'MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs') diff --git a/Emby.Dlna/Didl/DidlBuilder.cs b/Emby.Dlna/Didl/DidlBuilder.cs index 1cb9a24fb..5e200428a 100644 --- a/Emby.Dlna/Didl/DidlBuilder.cs +++ b/Emby.Dlna/Didl/DidlBuilder.cs @@ -209,8 +209,8 @@ namespace Emby.Dlna.Didl var targetHeight = streamInfo.TargetHeight; var contentFeatureList = new ContentFeatureBuilder(_profile).BuildVideoHeader(streamInfo.Container, - streamInfo.TargetVideoCodec, - streamInfo.TargetAudioCodec, + streamInfo.TargetVideoCodec.FirstOrDefault(), + streamInfo.TargetAudioCodec.FirstOrDefault(), targetWidth, targetHeight, streamInfo.TargetVideoBitDepth, @@ -353,8 +353,8 @@ namespace Emby.Dlna.Didl } var mediaProfile = _profile.GetVideoMediaProfile(streamInfo.Container, - streamInfo.TargetAudioCodec, - streamInfo.TargetVideoCodec, + streamInfo.TargetAudioCodec.FirstOrDefault(), + streamInfo.TargetVideoCodec.FirstOrDefault(), streamInfo.TargetAudioBitrate, targetWidth, targetHeight, @@ -554,7 +554,7 @@ namespace Emby.Dlna.Didl } var mediaProfile = _profile.GetAudioMediaProfile(streamInfo.Container, - streamInfo.TargetAudioCodec, + streamInfo.TargetAudioCodec.FirstOrDefault(), targetChannels, targetAudioBitrate, targetSampleRate, @@ -567,7 +567,7 @@ namespace Emby.Dlna.Didl : mediaProfile.MimeType; var contentFeatures = new ContentFeatureBuilder(_profile).BuildAudioHeader(streamInfo.Container, - streamInfo.TargetAudioCodec, + streamInfo.TargetAudioCodec.FirstOrDefault(), targetAudioBitrate, targetSampleRate, targetChannels, diff --git a/Emby.Dlna/PlayTo/PlayToController.cs b/Emby.Dlna/PlayTo/PlayToController.cs index 95b164212..ba1d3a6de 100644 --- a/Emby.Dlna/PlayTo/PlayToController.cs +++ b/Emby.Dlna/PlayTo/PlayToController.cs @@ -13,6 +13,7 @@ using MediaBrowser.Model.System; using System; using System.Collections.Generic; using System.Globalization; +using System.Linq; using System.Threading; using System.Threading.Tasks; using MediaBrowser.Common.Configuration; @@ -515,7 +516,7 @@ namespace Emby.Dlna.PlayTo { return new ContentFeatureBuilder(profile) .BuildAudioHeader(streamInfo.Container, - streamInfo.TargetAudioCodec, + streamInfo.TargetAudioCodec.FirstOrDefault(), streamInfo.TargetAudioBitrate, streamInfo.TargetAudioSampleRate, streamInfo.TargetAudioChannels, @@ -529,8 +530,8 @@ namespace Emby.Dlna.PlayTo { var list = new ContentFeatureBuilder(profile) .BuildVideoHeader(streamInfo.Container, - streamInfo.TargetVideoCodec, - streamInfo.TargetAudioCodec, + streamInfo.TargetVideoCodec.FirstOrDefault(), + streamInfo.TargetAudioCodec.FirstOrDefault(), streamInfo.TargetWidth, streamInfo.TargetHeight, streamInfo.TargetVideoBitDepth, diff --git a/Emby.Server.Implementations/Archiving/ZipClient.cs b/Emby.Server.Implementations/Archiving/ZipClient.cs index 3218d56c6..d7d37bb61 100644 --- a/Emby.Server.Implementations/Archiving/ZipClient.cs +++ b/Emby.Server.Implementations/Archiving/ZipClient.cs @@ -4,6 +4,7 @@ using SharpCompress.Archives.Rar; using SharpCompress.Archives.SevenZip; using SharpCompress.Archives.Tar; using SharpCompress.Readers; +using SharpCompress.Readers.GZip; using SharpCompress.Readers.Zip; namespace Emby.Server.Implementations.Archiving @@ -72,6 +73,22 @@ namespace Emby.Server.Implementations.Archiving } } + public void ExtractAllFromGz(Stream source, string targetPath, bool overwriteExistingFiles) + { + using (var reader = GZipReader.Open(source)) + { + var options = new ExtractionOptions(); + options.ExtractFullPath = true; + + if (overwriteExistingFiles) + { + options.Overwrite = true; + } + + reader.WriteAllToDirectory(targetPath, options); + } + } + /// /// Extracts all from7z. /// diff --git a/Emby.Server.Implementations/Emby.Server.Implementations.csproj b/Emby.Server.Implementations/Emby.Server.Implementations.csproj index ccff29eef..41a62a417 100644 --- a/Emby.Server.Implementations/Emby.Server.Implementations.csproj +++ b/Emby.Server.Implementations/Emby.Server.Implementations.csproj @@ -667,8 +667,8 @@ ..\packages\ServiceStack.Text.4.5.8\lib\net45\ServiceStack.Text.dll True - - ..\packages\SharpCompress.0.14.0\lib\net45\SharpCompress.dll + + ..\packages\SharpCompress.0.18.2\lib\net45\SharpCompress.dll ..\packages\SimpleInjector.4.0.8\lib\net45\SimpleInjector.dll diff --git a/Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs b/Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs index fb8308cda..55500df6e 100644 --- a/Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs +++ b/Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs @@ -65,14 +65,15 @@ namespace Emby.Server.Implementations.LiveTv.Listings if (!path.StartsWith("http", StringComparison.OrdinalIgnoreCase)) { - return path; + return UnzipIfNeeded(path, path); } var cacheFilename = DateTime.UtcNow.DayOfYear.ToString(CultureInfo.InvariantCulture) + "-" + DateTime.UtcNow.Hour.ToString(CultureInfo.InvariantCulture) + ".xml"; var cacheFile = Path.Combine(_config.ApplicationPaths.CachePath, "xmltv", cacheFilename); if (_fileSystem.FileExists(cacheFile)) { - return UnzipIfNeeded(path, cacheFile); + //return UnzipIfNeeded(path, cacheFile); + return cacheFile; } _logger.Info("Downloading xmltv listings from {0}", path); @@ -112,28 +113,29 @@ namespace Emby.Server.Implementations.LiveTv.Listings } _logger.Debug("Returning xmltv path {0}", cacheFile); - return UnzipIfNeeded(path, cacheFile); + return cacheFile; + //return UnzipIfNeeded(path, cacheFile); } private string UnzipIfNeeded(string originalUrl, string file) { - //var ext = Path.GetExtension(originalUrl); - - //if (string.Equals(ext, ".gz", StringComparison.OrdinalIgnoreCase)) - //{ - // using (var stream = _fileSystem.OpenRead(file)) - // { - // var tempFolder = Path.Combine(_config.ApplicationPaths.TempDirectory, Guid.NewGuid().ToString()); - // _fileSystem.CreateDirectory(tempFolder); - - // _zipClient.ExtractAllFromZip(stream, tempFolder, true); - - // return _fileSystem.GetFiles(tempFolder, true) - // .Where(i => string.Equals(i.Extension, ".xml", StringComparison.OrdinalIgnoreCase)) - // .Select(i => i.FullName) - // .FirstOrDefault(); - // } - //} + var ext = Path.GetExtension(originalUrl.Split('?')[0]); + + if (string.Equals(ext, ".gz", StringComparison.OrdinalIgnoreCase)) + { + using (var stream = _fileSystem.OpenRead(file)) + { + var tempFolder = Path.Combine(_config.ApplicationPaths.TempDirectory, Guid.NewGuid().ToString()); + _fileSystem.CreateDirectory(tempFolder); + + _zipClient.ExtractAllFromGz(stream, tempFolder, true); + + return _fileSystem.GetFiles(tempFolder, true) + .Where(i => string.Equals(i.Extension, ".xml", StringComparison.OrdinalIgnoreCase)) + .Select(i => i.FullName) + .FirstOrDefault(); + } + } return file; } diff --git a/Emby.Server.Implementations/packages.config b/Emby.Server.Implementations/packages.config index c27b8ac26..d27722fef 100644 --- a/Emby.Server.Implementations/packages.config +++ b/Emby.Server.Implementations/packages.config @@ -2,7 +2,7 @@ - + diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index 642a42c8e..7be3c3754 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -691,22 +691,26 @@ namespace MediaBrowser.Controller.MediaEncoding param += string.Format(" -r {0}", framerate.Value.ToString(_usCulture)); } - var request = state.BaseRequest; + var targetVideoCodec = state.ActualOutputVideoCodec; - if (!string.IsNullOrEmpty(request.Profile)) + var request = state.BaseRequest; + var profile = state.GetRequestedProfiles(targetVideoCodec).FirstOrDefault(); + if (!string.IsNullOrEmpty(profile)) { if (!string.Equals(videoEncoder, "h264_omx", StringComparison.OrdinalIgnoreCase) && !string.Equals(videoEncoder, "h264_vaapi", StringComparison.OrdinalIgnoreCase) && !string.Equals(videoEncoder, "h264_v4l2m2m", StringComparison.OrdinalIgnoreCase)) { // not supported by h264_omx - param += " -profile:v " + request.Profile; + param += " -profile:v " + profile; } } - if (!string.IsNullOrEmpty(request.Level)) + var level = state.GetRequestedLevel(targetVideoCodec); + + if (!string.IsNullOrEmpty(level)) { - var level = NormalizeTranscodingLevel(state.OutputVideoCodec, request.Level); + level = NormalizeTranscodingLevel(state.OutputVideoCodec, level); // h264_qsv and h264_nvenc expect levels to be expressed as a decimal. libx264 supports decimal and non-decimal format // also needed for libx264 due to https://trac.ffmpeg.org/ticket/3307 @@ -756,7 +760,6 @@ namespace MediaBrowser.Controller.MediaEncoding { param += " -level " + level; } - } if (string.Equals(videoEncoder, "libx264", StringComparison.OrdinalIgnoreCase)) @@ -834,18 +837,21 @@ namespace MediaBrowser.Controller.MediaEncoding return false; } + var requestedProfiles = state.GetRequestedProfiles(videoStream.Codec); + // If client is requesting a specific video profile, it must match the source - if (!string.IsNullOrEmpty(request.Profile)) + if (requestedProfiles.Length > 0) { if (string.IsNullOrEmpty(videoStream.Profile)) { //return false; } - if (!string.IsNullOrEmpty(videoStream.Profile) && !string.Equals(request.Profile, videoStream.Profile, StringComparison.OrdinalIgnoreCase)) + var requestedProfile = requestedProfiles[0]; + if (!string.IsNullOrEmpty(videoStream.Profile) && !string.Equals(requestedProfile, videoStream.Profile, StringComparison.OrdinalIgnoreCase)) { var currentScore = GetVideoProfileScore(videoStream.Profile); - var requestedScore = GetVideoProfileScore(request.Profile); + var requestedScore = GetVideoProfileScore(requestedProfile); if (currentScore == -1 || currentScore > requestedScore) { @@ -910,11 +916,12 @@ namespace MediaBrowser.Controller.MediaEncoding } // If a specific level was requested, the source must match or be less than - if (!string.IsNullOrEmpty(request.Level)) + var level = state.GetRequestedLevel(videoStream.Codec); + if (!string.IsNullOrEmpty(level)) { double requestLevel; - if (double.TryParse(request.Level, NumberStyles.Any, _usCulture, out requestLevel)) + if (double.TryParse(level, NumberStyles.Any, _usCulture, out requestLevel)) { if (!videoStream.Level.HasValue) { diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs b/MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs index fb8aa9767..450bbf7c1 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs @@ -180,6 +180,61 @@ namespace MediaBrowser.Controller.MediaEncoding return false; } + public string[] GetRequestedProfiles(string codec) + { + if (!string.IsNullOrWhiteSpace(BaseRequest.Profile)) + { + return BaseRequest.Profile.Split(new[] { '|', ',' }, StringSplitOptions.RemoveEmptyEntries); + } + + if (!string.IsNullOrWhiteSpace(codec)) + { + var profile = BaseRequest.GetOption(codec, "profile"); + + if (!string.IsNullOrWhiteSpace(profile)) + { + return profile.Split(new[] { '|', ',' }, StringSplitOptions.RemoveEmptyEntries); + } + } + + return new string[] { }; + } + + public string GetRequestedLevel(string codec) + { + if (!string.IsNullOrWhiteSpace(BaseRequest.Level)) + { + return BaseRequest.Level; + } + + if (!string.IsNullOrWhiteSpace(codec)) + { + return BaseRequest.GetOption(codec, "level"); + } + + return null; + } + + public int? GetRequestedMaxRefFrames(string codec) + { + if (!string.IsNullOrWhiteSpace(BaseRequest.Level)) + { + return BaseRequest.MaxRefFrames; + } + + if (!string.IsNullOrWhiteSpace(codec)) + { + var value = BaseRequest.GetOption(codec, "maxrefframes"); + int result; + if (!string.IsNullOrWhiteSpace(value) && int.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out result)) + { + return result; + } + } + + return null; + } + public bool IsVideoRequest { get; set; } public TranscodingJobType TranscodingType { get; set; } @@ -188,7 +243,7 @@ namespace MediaBrowser.Controller.MediaEncoding _logger = logger; TranscodingType = jobType; RemoteHttpHeaders = new Dictionary(StringComparer.OrdinalIgnoreCase); - PlayableStreamFileNames = new string[]{}; + PlayableStreamFileNames = new string[] { }; SupportedAudioCodecs = new List(); SupportedVideoCodecs = new List(); SupportedSubtitleCodecs = new List(); @@ -338,12 +393,19 @@ namespace MediaBrowser.Controller.MediaEncoding { get { - var stream = VideoStream; - var request = BaseRequest; + if (BaseRequest.Static) + { + return VideoStream == null ? null : VideoStream.Level; + } + + var level = GetRequestedLevel(ActualOutputVideoCodec); + double result; + if (!string.IsNullOrWhiteSpace(level) && double.TryParse(level, NumberStyles.Any, CultureInfo.InvariantCulture, out result)) + { + return result; + } - return !string.IsNullOrEmpty(request.Level) && !request.Static - ? double.Parse(request.Level, CultureInfo.InvariantCulture) - : stream == null ? null : stream.Level; + return null; } } @@ -367,8 +429,12 @@ namespace MediaBrowser.Controller.MediaEncoding { get { - var stream = VideoStream; - return stream == null || !BaseRequest.Static ? null : stream.RefFrames; + if (BaseRequest.Static) + { + return VideoStream == null ? null : VideoStream.RefFrames; + } + + return null; } } @@ -423,10 +489,18 @@ namespace MediaBrowser.Controller.MediaEncoding { get { - var stream = VideoStream; - return !string.IsNullOrEmpty(BaseRequest.Profile) && !BaseRequest.Static - ? BaseRequest.Profile - : stream == null ? null : stream.Profile; + if (BaseRequest.Static) + { + return VideoStream == null ? null : VideoStream.Profile; + } + + var requestedProfile = GetRequestedProfiles(ActualOutputVideoCodec).FirstOrDefault(); + if (!string.IsNullOrWhiteSpace(requestedProfile)) + { + return requestedProfile; + } + + return null; } } diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingJobOptions.cs b/MediaBrowser.Controller/MediaEncoding/EncodingJobOptions.cs index cb675ba68..bac2a6e65 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingJobOptions.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingJobOptions.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Globalization; +using System.Linq; using MediaBrowser.Model.Dlna; using MediaBrowser.Model.Services; @@ -39,18 +40,16 @@ namespace MediaBrowser.Controller.MediaEncoding MaxWidth = info.MaxWidth; MaxHeight = info.MaxHeight; MaxFramerate = info.MaxFramerate; - Profile = info.VideoProfile; ItemId = info.ItemId; MediaSourceId = info.MediaSourceId; - AudioCodec = info.TargetAudioCodec; + AudioCodec = info.TargetAudioCodec.FirstOrDefault(); MaxAudioChannels = info.MaxAudioChannels; AudioBitRate = info.AudioBitrate; AudioSampleRate = info.TargetAudioSampleRate; DeviceProfile = deviceProfile; - VideoCodec = info.TargetVideoCodec; + VideoCodec = info.TargetVideoCodec.FirstOrDefault(); VideoBitRate = info.VideoBitrate; AudioStreamIndex = info.AudioStreamIndex; - MaxRefFrames = info.MaxRefFrames; MaxVideoBitDepth = info.MaxVideoBitDepth; SubtitleMethod = info.SubtitleDeliveryMethod; Context = info.Context; @@ -60,11 +59,7 @@ namespace MediaBrowser.Controller.MediaEncoding { SubtitleStreamIndex = info.SubtitleStreamIndex; } - - if (info.VideoLevel.HasValue) - { - Level = info.VideoLevel.Value.ToString(_usCulture); - } + StreamOptions = info.StreamOptions; } } @@ -231,7 +226,7 @@ namespace MediaBrowser.Controller.MediaEncoding SetOption(qualifier + "-" + name, value); } - public Dictionary StreamOptions { get; private set; } + public Dictionary StreamOptions { get; set; } public void SetOption(string name, string value) { diff --git a/MediaBrowser.Model/Dlna/CodecProfile.cs b/MediaBrowser.Model/Dlna/CodecProfile.cs index d75547adb..6d143962d 100644 --- a/MediaBrowser.Model/Dlna/CodecProfile.cs +++ b/MediaBrowser.Model/Dlna/CodecProfile.cs @@ -36,7 +36,12 @@ namespace MediaBrowser.Model.Dlna return ContainerProfile.ContainsContainer(Container, container); } - public bool ContainsCodec(string codec, string container) + public bool ContainsAnyCodec(string codec, string container) + { + return ContainsAnyCodec(ContainerProfile.SplitValue(codec), container); + } + + public bool ContainsAnyCodec(string[] codec, string container) { if (!ContainsContainer(container)) { @@ -44,8 +49,20 @@ namespace MediaBrowser.Model.Dlna } var codecs = GetCodecs(); + if (codecs.Length == 0) + { + return true; + } + + foreach (var val in codec) + { + if (ListHelper.ContainsIgnoreCase(codecs, val)) + { + return true; + } + } - return codecs.Length == 0 || ListHelper.ContainsIgnoreCase(codecs, ContainerProfile.SplitValue(codec)[0]); + return false; } } } diff --git a/MediaBrowser.Model/Dlna/StreamBuilder.cs b/MediaBrowser.Model/Dlna/StreamBuilder.cs index 3b68db802..dfc9317fd 100644 --- a/MediaBrowser.Model/Dlna/StreamBuilder.cs +++ b/MediaBrowser.Model/Dlna/StreamBuilder.cs @@ -283,7 +283,7 @@ namespace MediaBrowser.Model.Dlna var conditions = new List(); foreach (CodecProfile i in options.Profile.CodecProfiles) { - if (i.Type == CodecType.Audio && i.ContainsCodec(audioCodec, item.Container)) + if (i.Type == CodecType.Audio && i.ContainsAnyCodec(audioCodec, item.Container)) { bool applyConditions = true; foreach (ProfileCondition applyCondition in i.ApplyConditions) @@ -375,7 +375,7 @@ namespace MediaBrowser.Model.Dlna var audioCodecProfiles = new List(); foreach (CodecProfile i in options.Profile.CodecProfiles) { - if (i.Type == CodecType.Audio && i.ContainsCodec(transcodingProfile.AudioCodec, transcodingProfile.Container)) + if (i.Type == CodecType.Audio && i.ContainsAnyCodec(transcodingProfile.AudioCodec, transcodingProfile.Container)) { audioCodecProfiles.Add(i); } @@ -772,7 +772,7 @@ namespace MediaBrowser.Model.Dlna var isFirstAppliedCodecProfile = true; foreach (CodecProfile i in options.Profile.CodecProfiles) { - if (i.Type == CodecType.Video && i.ContainsCodec(transcodingProfile.VideoCodec, transcodingProfile.Container)) + if (i.Type == CodecType.Video && i.ContainsAnyCodec(transcodingProfile.VideoCodec, transcodingProfile.Container)) { bool applyConditions = true; foreach (ProfileCondition applyCondition in i.ApplyConditions) @@ -797,7 +797,7 @@ namespace MediaBrowser.Model.Dlna var transcodingVideoCodecs = ContainerProfile.SplitValue(transcodingProfile.VideoCodec); foreach (var transcodingVideoCodec in transcodingVideoCodecs) { - if (i.ContainsCodec(transcodingVideoCodec, transcodingProfile.Container)) + if (i.ContainsAnyCodec(transcodingVideoCodec, transcodingProfile.Container)) { ApplyTranscodingConditions(playlistItem, i.Conditions, transcodingVideoCodec, !isFirstAppliedCodecProfile); isFirstAppliedCodecProfile = false; @@ -810,7 +810,7 @@ namespace MediaBrowser.Model.Dlna var audioTranscodingConditions = new List(); foreach (CodecProfile i in options.Profile.CodecProfiles) { - if (i.Type == CodecType.VideoAudio && i.ContainsCodec(playlistItem.TargetAudioCodec, transcodingProfile.Container)) + if (i.Type == CodecType.VideoAudio && i.ContainsAnyCodec(playlistItem.TargetAudioCodec, transcodingProfile.Container)) { bool applyConditions = true; foreach (ProfileCondition applyCondition in i.ApplyConditions) @@ -899,8 +899,10 @@ namespace MediaBrowser.Model.Dlna return 192000; } - private int GetAudioBitrate(string subProtocol, long? maxTotalBitrate, int? targetAudioChannels, string targetAudioCodec, MediaStream audioStream) + private int GetAudioBitrate(string subProtocol, long? maxTotalBitrate, int? targetAudioChannels, string[] targetAudioCodecs, MediaStream audioStream) { + var targetAudioCodec = targetAudioCodecs.Length == 0 ? null : targetAudioCodecs[0]; + int defaultBitrate = audioStream == null ? 192000 : audioStream.BitRate ?? GetDefaultAudioBitrateIfUnknown(audioStream); // Reduce the bitrate if we're downmixing @@ -1064,7 +1066,7 @@ namespace MediaBrowser.Model.Dlna conditions = new List(); foreach (CodecProfile i in profile.CodecProfiles) { - if (i.Type == CodecType.Video && i.ContainsCodec(videoCodec, container)) + if (i.Type == CodecType.Video && i.ContainsAnyCodec(videoCodec, container)) { bool applyConditions = true; foreach (ProfileCondition applyCondition in i.ApplyConditions) @@ -1120,7 +1122,7 @@ namespace MediaBrowser.Model.Dlna foreach (CodecProfile i in profile.CodecProfiles) { - if (i.Type == CodecType.VideoAudio && i.ContainsCodec(audioCodec, container)) + if (i.Type == CodecType.VideoAudio && i.ContainsAnyCodec(audioCodec, container)) { bool applyConditions = true; foreach (ProfileCondition applyCondition in i.ApplyConditions) @@ -1260,13 +1262,13 @@ namespace MediaBrowser.Model.Dlna } // Look for an external or hls profile that matches the stream type (text/graphical) and doesn't require conversion - return GetExternalSubtitleProfile(subtitleStream, subtitleProfiles, playMethod, transcoderSupport, false) ?? - GetExternalSubtitleProfile(subtitleStream, subtitleProfiles, playMethod, transcoderSupport, true) ?? + return GetExternalSubtitleProfile(subtitleStream, subtitleProfiles, playMethod, transcoderSupport, false) ?? + GetExternalSubtitleProfile(subtitleStream, subtitleProfiles, playMethod, transcoderSupport, true) ?? new SubtitleProfile - { - Method = SubtitleDeliveryMethod.Encode, - Format = subtitleStream.Codec - }; + { + Method = SubtitleDeliveryMethod.Encode, + Format = subtitleStream.Codec + }; } private static bool IsSubtitleEmbedSupported(MediaStream subtitleStream, SubtitleProfile subtitleProfile, string transcodingSubProtocol, string transcodingContainer) @@ -1555,7 +1557,7 @@ namespace MediaBrowser.Model.Dlna } case ProfileConditionValue.RefFrames: { - if (qualifiedOnly) + if (string.IsNullOrWhiteSpace(qualifier)) { continue; } @@ -1565,15 +1567,15 @@ namespace MediaBrowser.Model.Dlna { if (condition.Condition == ProfileConditionType.Equals) { - item.MaxRefFrames = num; + item.SetOption(qualifier, "maxrefframes", StringHelper.ToStringCultureInvariant(num)); } else if (condition.Condition == ProfileConditionType.LessThanEqual) { - item.MaxRefFrames = Math.Min(num, item.MaxRefFrames ?? num); + item.SetOption(qualifier, "maxrefframes", StringHelper.ToStringCultureInvariant(Math.Min(num, item.GetTargetRefFrames(qualifier) ?? num))); } else if (condition.Condition == ProfileConditionType.GreaterThanEqual) { - item.MaxRefFrames = Math.Max(num, item.MaxRefFrames ?? num); + item.SetOption(qualifier, "maxrefframes", StringHelper.ToStringCultureInvariant(Math.Max(num, item.GetTargetRefFrames(qualifier) ?? num))); } } break; @@ -1605,12 +1607,16 @@ namespace MediaBrowser.Model.Dlna } case ProfileConditionValue.VideoProfile: { - if (qualifiedOnly) + if (string.IsNullOrWhiteSpace(qualifier)) { continue; } - item.VideoProfile = (value ?? string.Empty).Split('|')[0]; + if (!string.IsNullOrWhiteSpace(value)) + { + // change from split by | to comma + item.SetOption(qualifier, "profile", string.Join(",", value.Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries))); + } break; } case ProfileConditionValue.Height: @@ -1690,7 +1696,7 @@ namespace MediaBrowser.Model.Dlna } case ProfileConditionValue.VideoLevel: { - if (qualifiedOnly) + if (string.IsNullOrWhiteSpace(qualifier)) { continue; } @@ -1700,15 +1706,15 @@ namespace MediaBrowser.Model.Dlna { if (condition.Condition == ProfileConditionType.Equals) { - item.VideoLevel = num; + item.SetOption(qualifier, "level", StringHelper.ToStringCultureInvariant(num)); } else if (condition.Condition == ProfileConditionType.LessThanEqual) { - item.VideoLevel = Math.Min(num, item.VideoLevel ?? num); + item.SetOption(qualifier, "level", StringHelper.ToStringCultureInvariant(Math.Min(num, item.GetTargetVideoLevel(qualifier) ?? num))); } else if (condition.Condition == ProfileConditionType.GreaterThanEqual) { - item.VideoLevel = Math.Max(num, item.VideoLevel ?? num); + item.SetOption(qualifier, "level", StringHelper.ToStringCultureInvariant(Math.Max(num, item.GetTargetVideoLevel(qualifier) ?? num))); } } break; diff --git a/MediaBrowser.Model/Dlna/StreamInfo.cs b/MediaBrowser.Model/Dlna/StreamInfo.cs index 3e7ff9c3d..fe5aaa739 100644 --- a/MediaBrowser.Model/Dlna/StreamInfo.cs +++ b/MediaBrowser.Model/Dlna/StreamInfo.cs @@ -64,8 +64,6 @@ namespace MediaBrowser.Model.Dlna public long StartPositionTicks { get; set; } - public string VideoProfile { get; set; } - public int? SegmentLength { get; set; } public int? MinSegments { get; set; } public bool BreakOnNonKeyFrames { get; set; } @@ -88,13 +86,10 @@ namespace MediaBrowser.Model.Dlna public int? VideoBitrate { get; set; } - public int? VideoLevel { get; set; } - public int? MaxWidth { get; set; } public int? MaxHeight { get; set; } public int? MaxVideoBitDepth { get; set; } - public int? MaxRefFrames { get; set; } public float? MaxFramerate { get; set; } @@ -274,11 +269,34 @@ namespace MediaBrowser.Model.Dlna list.Add(new NameValuePair("StartTimeTicks", StringHelper.ToStringCultureInvariant(startPositionTicks))); } - list.Add(new NameValuePair("Level", item.VideoLevel.HasValue ? StringHelper.ToStringCultureInvariant(item.VideoLevel.Value) : string.Empty)); + if (isDlna) + { + // hack alert + // dlna needs to be update to support the qualified params + var level = item.GetTargetVideoLevel("h264"); + + list.Add(new NameValuePair("Level", level.HasValue ? StringHelper.ToStringCultureInvariant(level.Value) : string.Empty)); + } + + if (isDlna) + { + // hack alert + // dlna needs to be update to support the qualified params + var refframes = item.GetTargetRefFrames("h264"); + + list.Add(new NameValuePair("MaxRefFrames", refframes.HasValue ? StringHelper.ToStringCultureInvariant(refframes.Value) : string.Empty)); + } - list.Add(new NameValuePair("MaxRefFrames", item.MaxRefFrames.HasValue ? StringHelper.ToStringCultureInvariant(item.MaxRefFrames.Value) : string.Empty)); list.Add(new NameValuePair("MaxVideoBitDepth", item.MaxVideoBitDepth.HasValue ? StringHelper.ToStringCultureInvariant(item.MaxVideoBitDepth.Value) : string.Empty)); - list.Add(new NameValuePair("Profile", item.VideoProfile ?? string.Empty)); + + if (isDlna) + { + // hack alert + // dlna needs to be update to support the qualified params + var profile = item.GetOption("h264", "profile"); + + list.Add(new NameValuePair("Profile", profile ?? string.Empty)); + } // no longer used list.Add(new NameValuePair("Cabac", string.Empty)); @@ -559,8 +577,19 @@ namespace MediaBrowser.Model.Dlna { get { - MediaStream stream = TargetVideoStream; - return stream == null || !IsDirectStream ? null : stream.RefFrames; + if (IsDirectStream) + { + return TargetVideoStream == null ? (int?)null : TargetVideoStream.RefFrames; + } + + var targetVideoCodecs = TargetVideoCodec; + var videoCodec = targetVideoCodecs.Length == 0 ? null : targetVideoCodecs[0]; + if (!string.IsNullOrWhiteSpace(videoCodec)) + { + return GetTargetRefFrames(videoCodec); + } + + return TargetVideoStream == null ? (int?)null : TargetVideoStream.RefFrames; } } @@ -585,11 +614,54 @@ namespace MediaBrowser.Model.Dlna { get { - MediaStream stream = TargetVideoStream; - return VideoLevel.HasValue && !IsDirectStream - ? VideoLevel - : stream == null ? null : stream.Level; + if (IsDirectStream) + { + return TargetVideoStream == null ? (double?)null : TargetVideoStream.Level; + } + + var targetVideoCodecs = TargetVideoCodec; + var videoCodec = targetVideoCodecs.Length == 0 ? null : targetVideoCodecs[0]; + if (!string.IsNullOrWhiteSpace(videoCodec)) + { + return GetTargetVideoLevel(videoCodec); + } + + return TargetVideoStream == null ? (double?)null : TargetVideoStream.Level; + } + } + + public double? GetTargetVideoLevel(string codec) + { + var value = GetOption(codec, "level"); + if (string.IsNullOrWhiteSpace(value)) + { + return null; } + + double result; + if (double.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out result)) + { + return result; + } + + return null; + } + + public int? GetTargetRefFrames(string codec) + { + var value = GetOption(codec, "maxrefframes"); + if (string.IsNullOrWhiteSpace(value)) + { + return null; + } + + int result; + if (int.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out result)) + { + return result; + } + + return null; } /// @@ -613,10 +685,19 @@ namespace MediaBrowser.Model.Dlna { get { - MediaStream stream = TargetVideoStream; - return !string.IsNullOrEmpty(VideoProfile) && !IsDirectStream - ? VideoProfile - : stream == null ? null : stream.Profile; + if (IsDirectStream) + { + return TargetVideoStream == null ? null : TargetVideoStream.Profile; + } + + var targetVideoCodecs = TargetVideoCodec; + var videoCodec = targetVideoCodecs.Length == 0 ? null : targetVideoCodecs[0]; + if (!string.IsNullOrWhiteSpace(videoCodec)) + { + return GetOption(videoCodec, "profile"); + } + + return TargetVideoStream == null ? null : TargetVideoStream.Profile; } } @@ -676,7 +757,7 @@ namespace MediaBrowser.Model.Dlna /// /// Predicts the audio codec that will be in the output stream /// - public string TargetAudioCodec + public string[] TargetAudioCodec { get { @@ -686,22 +767,22 @@ namespace MediaBrowser.Model.Dlna if (IsDirectStream) { - return inputCodec; + return string.IsNullOrWhiteSpace(inputCodec) ? new string[] { } : new[] { inputCodec }; } foreach (string codec in AudioCodecs) { if (StringHelper.EqualsIgnoreCase(codec, inputCodec)) { - return codec; + return string.IsNullOrWhiteSpace(codec) ? new string[] { } : new[] { codec }; } } - return AudioCodecs.Length == 0 ? null : AudioCodecs[0]; + return AudioCodecs; } } - public string TargetVideoCodec + public string[] TargetVideoCodec { get { @@ -711,18 +792,18 @@ namespace MediaBrowser.Model.Dlna if (IsDirectStream) { - return inputCodec; + return string.IsNullOrWhiteSpace(inputCodec) ? new string[] { } : new[] { inputCodec }; } foreach (string codec in VideoCodecs) { if (StringHelper.EqualsIgnoreCase(codec, inputCodec)) { - return codec; + return string.IsNullOrWhiteSpace(codec) ? new string[] { } : new[] { codec }; } } - return VideoCodecs.Length == 0 ? null : VideoCodecs[0]; + return VideoCodecs; } } @@ -813,7 +894,8 @@ namespace MediaBrowser.Model.Dlna return TargetVideoStream == null ? (bool?)null : TargetVideoStream.IsInterlaced; } - var videoCodec = TargetVideoCodec; + var targetVideoCodecs = TargetVideoCodec; + var videoCodec = targetVideoCodecs.Length == 0 ? null : targetVideoCodecs[0]; if (!string.IsNullOrWhiteSpace(videoCodec)) { if (string.Equals(GetOption(videoCodec, "deinterlace"), "true", StringComparison.OrdinalIgnoreCase)) diff --git a/MediaBrowser.Model/IO/IZipClient.cs b/MediaBrowser.Model/IO/IZipClient.cs index ac57d58a6..2dc4880c2 100644 --- a/MediaBrowser.Model/IO/IZipClient.cs +++ b/MediaBrowser.Model/IO/IZipClient.cs @@ -23,6 +23,8 @@ namespace MediaBrowser.Model.IO /// if set to true [overwrite existing files]. void ExtractAll(Stream source, string targetPath, bool overwriteExistingFiles); + void ExtractAllFromGz(Stream source, string targetPath, bool overwriteExistingFiles); + /// /// Extracts all from zip. /// diff --git a/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj b/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj index d2ce0b40d..365977530 100644 --- a/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj +++ b/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj @@ -55,9 +55,8 @@ ..\packages\ServiceStack.Text.4.5.8\lib\net45\ServiceStack.Text.dll True - - ..\packages\SharpCompress.0.14.0\lib\net45\SharpCompress.dll - True + + ..\packages\SharpCompress.0.18.2\lib\net45\SharpCompress.dll ..\packages\SimpleInjector.4.0.8\lib\net45\SimpleInjector.dll diff --git a/MediaBrowser.Server.Mono/packages.config b/MediaBrowser.Server.Mono/packages.config index cff873f1f..dfa3dc75d 100644 --- a/MediaBrowser.Server.Mono/packages.config +++ b/MediaBrowser.Server.Mono/packages.config @@ -2,7 +2,7 @@ - + diff --git a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj index 23db82cf1..9e4f52489 100644 --- a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj +++ b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj @@ -77,9 +77,8 @@ ..\packages\ServiceStack.Text.4.5.8\lib\net45\ServiceStack.Text.dll True - - ..\packages\SharpCompress.0.14.0\lib\net45\SharpCompress.dll - True + + ..\packages\SharpCompress.0.18.2\lib\net45\SharpCompress.dll ..\packages\SimpleInjector.4.0.8\lib\net45\SimpleInjector.dll diff --git a/MediaBrowser.ServerApplication/packages.config b/MediaBrowser.ServerApplication/packages.config index 85d2613bb..c7b98700e 100644 --- a/MediaBrowser.ServerApplication/packages.config +++ b/MediaBrowser.ServerApplication/packages.config @@ -1,7 +1,7 @@  - + -- cgit v1.2.3 From d43508a8989240aabdad7225073e0231f5634380 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 25 Sep 2017 15:15:01 -0400 Subject: update applyconditions --- .../MediaEncoding/EncodingHelper.cs | 3 +- MediaBrowser.Model/Dlna/StreamBuilder.cs | 54 +++++++++++----------- 2 files changed, 29 insertions(+), 28 deletions(-) (limited to 'MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs') diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index 7be3c3754..368c0cf32 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -1367,7 +1367,8 @@ namespace MediaBrowser.Controller.MediaEncoding if (state.DeInterlace("h264") && !string.Equals(outputVideoCodec, "h264_vaapi", StringComparison.OrdinalIgnoreCase)) { - if (string.Equals(options.DeinterlaceMethod, "bobandweave", StringComparison.OrdinalIgnoreCase)) + // If it is already 60fps then it will create an output framerate that is much too high for roku and others to handle + if (string.Equals(options.DeinterlaceMethod, "bobandweave", StringComparison.OrdinalIgnoreCase) && (state.VideoStream.RealFrameRate ?? 60) <= 30) { filters.Add("yadif=1:-1:0"); } diff --git a/MediaBrowser.Model/Dlna/StreamBuilder.cs b/MediaBrowser.Model/Dlna/StreamBuilder.cs index dfc9317fd..67d9b834f 100644 --- a/MediaBrowser.Model/Dlna/StreamBuilder.cs +++ b/MediaBrowser.Model/Dlna/StreamBuilder.cs @@ -777,16 +777,28 @@ namespace MediaBrowser.Model.Dlna bool applyConditions = true; foreach (ProfileCondition applyCondition in i.ApplyConditions) { - bool? isSecondaryAudio = audioStream == null ? null : item.IsSecondaryAudio(audioStream); - int? inputAudioBitrate = audioStream == null ? null : audioStream.BitRate; - int? audioChannels = audioStream == null ? null : audioStream.Channels; - string audioProfile = audioStream == null ? null : audioStream.Profile; - int? inputAudioSampleRate = audioStream == null ? null : audioStream.SampleRate; - int? inputAudioBitDepth = audioStream == null ? null : audioStream.BitDepth; + int? width = videoStream == null ? null : videoStream.Width; + int? height = videoStream == null ? null : videoStream.Height; + int? bitDepth = videoStream == null ? null : videoStream.BitDepth; + int? videoBitrate = videoStream == null ? null : videoStream.BitRate; + double? videoLevel = videoStream == null ? null : videoStream.Level; + string videoProfile = videoStream == null ? null : videoStream.Profile; + float? videoFramerate = videoStream == null ? null : videoStream.AverageFrameRate ?? videoStream.AverageFrameRate; + bool? isAnamorphic = videoStream == null ? null : videoStream.IsAnamorphic; + bool? isInterlaced = videoStream == null ? (bool?)null : videoStream.IsInterlaced; + string videoCodecTag = videoStream == null ? null : videoStream.CodecTag; + bool? isAvc = videoStream == null ? null : videoStream.IsAVC; - if (!conditionProcessor.IsVideoAudioConditionSatisfied(applyCondition, audioChannels, inputAudioBitrate, inputAudioSampleRate, inputAudioBitDepth, audioProfile, isSecondaryAudio)) + TransportStreamTimestamp? timestamp = videoStream == null ? TransportStreamTimestamp.None : item.Timestamp; + int? packetLength = videoStream == null ? null : videoStream.PacketLength; + int? refFrames = videoStream == null ? null : videoStream.RefFrames; + + int? numAudioStreams = item.GetStreamCount(MediaStreamType.Audio); + int? numVideoStreams = item.GetStreamCount(MediaStreamType.Video); + + if (!conditionProcessor.IsVideoConditionSatisfied(applyCondition, width, height, bitDepth, videoBitrate, videoProfile, videoLevel, videoFramerate, packetLength, timestamp, isAnamorphic, isInterlaced, refFrames, numVideoStreams, numAudioStreams, videoCodecTag, isAvc)) { - LogConditionFailure(options.Profile, "VideoAudioCodecProfile", applyCondition, item); + LogConditionFailure(options.Profile, "VideoCodecProfile", applyCondition, item); applyConditions = false; break; } @@ -815,26 +827,14 @@ namespace MediaBrowser.Model.Dlna bool applyConditions = true; foreach (ProfileCondition applyCondition in i.ApplyConditions) { - int? width = videoStream == null ? null : videoStream.Width; - int? height = videoStream == null ? null : videoStream.Height; - int? bitDepth = videoStream == null ? null : videoStream.BitDepth; - int? videoBitrate = videoStream == null ? null : videoStream.BitRate; - double? videoLevel = videoStream == null ? null : videoStream.Level; - string videoProfile = videoStream == null ? null : videoStream.Profile; - float? videoFramerate = videoStream == null ? null : videoStream.AverageFrameRate ?? videoStream.AverageFrameRate; - bool? isAnamorphic = videoStream == null ? null : videoStream.IsAnamorphic; - bool? isInterlaced = videoStream == null ? (bool?)null : videoStream.IsInterlaced; - string videoCodecTag = videoStream == null ? null : videoStream.CodecTag; - bool? isAvc = videoStream == null ? null : videoStream.IsAVC; - - TransportStreamTimestamp? timestamp = videoStream == null ? TransportStreamTimestamp.None : item.Timestamp; - int? packetLength = videoStream == null ? null : videoStream.PacketLength; - int? refFrames = videoStream == null ? null : videoStream.RefFrames; - - int? numAudioStreams = item.GetStreamCount(MediaStreamType.Audio); - int? numVideoStreams = item.GetStreamCount(MediaStreamType.Video); + bool? isSecondaryAudio = audioStream == null ? null : item.IsSecondaryAudio(audioStream); + int? inputAudioBitrate = audioStream == null ? null : audioStream.BitRate; + int? audioChannels = audioStream == null ? null : audioStream.Channels; + string audioProfile = audioStream == null ? null : audioStream.Profile; + int? inputAudioSampleRate = audioStream == null ? null : audioStream.SampleRate; + int? inputAudioBitDepth = audioStream == null ? null : audioStream.BitDepth; - if (!conditionProcessor.IsVideoConditionSatisfied(applyCondition, width, height, bitDepth, videoBitrate, videoProfile, videoLevel, videoFramerate, packetLength, timestamp, isAnamorphic, isInterlaced, refFrames, numVideoStreams, numAudioStreams, videoCodecTag, isAvc)) + if (!conditionProcessor.IsVideoAudioConditionSatisfied(applyCondition, audioChannels, inputAudioBitrate, inputAudioSampleRate, inputAudioBitDepth, audioProfile, isSecondaryAudio)) { LogConditionFailure(options.Profile, "VideoCodecProfile", applyCondition, item); applyConditions = false; -- cgit v1.2.3 From f55b138e1dab42ef691374f872ff22ee3b947f55 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 27 Sep 2017 10:52:01 -0400 Subject: update deinterlace param --- .../LiveTv/TunerHosts/BaseTunerHost.cs | 3 +++ .../LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs | 9 +++++++++ .../LiveTv/TunerHosts/HdHomerun/HdHomerunUdpStream.cs | 4 ++-- MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs | 5 ++--- MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs | 13 +++++++++++-- 5 files changed, 27 insertions(+), 7 deletions(-) (limited to 'MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs') diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs index 4b4f61d53..787dcb5d3 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/BaseTunerHost.cs @@ -247,7 +247,10 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts try { var liveStream = await GetChannelStream(host, channelId, streamId, cancellationToken).ConfigureAwait(false); + var startTime = DateTime.UtcNow; await liveStream.Open(cancellationToken).ConfigureAwait(false); + var endTime = DateTime.UtcNow; + Logger.Info("Live stream opened after {0}ms", (endTime - startTime).TotalMilliseconds); return liveStream; } catch (Exception ex) diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs index f974b5c2c..b9a58a011 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs @@ -347,6 +347,15 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun videoCodec = "h264"; videoBitrate = 1000000; } + else + { + // This is for android tv's 1200 condition. Remove once not needed anymore so that we can avoid possible side effects of dummying up this data + if ((channelInfo.IsHD ?? true)) + { + width = 1920; + height = 1080; + } + } if (channelInfo != null) { diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunUdpStream.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunUdpStream.cs index c530d48c2..bf3febaf2 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunUdpStream.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunUdpStream.cs @@ -48,7 +48,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun _tempFilePath = Path.Combine(appPaths.TranscodingTempPath, UniqueId + ".ts"); } - protected override async Task OpenInternal(CancellationToken openCancellationToken) + protected override Task OpenInternal(CancellationToken openCancellationToken) { _liveStreamCancellationTokenSource.Token.ThrowIfCancellationRequested(); @@ -73,7 +73,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun //OpenedMediaSource.SupportsDirectStream = true; //OpenedMediaSource.SupportsTranscoding = true; - await taskCompletionSource.Task.ConfigureAwait(false); + return taskCompletionSource.Task; //await Task.Delay(5000).ConfigureAwait(false); } diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index 368c0cf32..ee7b9f080 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -799,13 +799,12 @@ namespace MediaBrowser.Controller.MediaEncoding if (videoStream.IsInterlaced) { - if (state.DeInterlace(videoStream.Codec)) + if (state.DeInterlace(videoStream.Codec, false)) { return false; } } - if (videoStream.IsAnamorphic ?? false) { if (request.RequireNonAnamorphic) @@ -1365,7 +1364,7 @@ namespace MediaBrowser.Controller.MediaEncoding filters.Add("hwupload"); } - if (state.DeInterlace("h264") && !string.Equals(outputVideoCodec, "h264_vaapi", StringComparison.OrdinalIgnoreCase)) + if (state.DeInterlace("h264", true) && !string.Equals(outputVideoCodec, "h264_vaapi", StringComparison.OrdinalIgnoreCase)) { // If it is already 60fps then it will create an output framerate that is much too high for roku and others to handle if (string.Equals(options.DeinterlaceMethod, "bobandweave", StringComparison.OrdinalIgnoreCase) && (state.VideoStream.RealFrameRate ?? 60) <= 30) diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs b/MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs index 450bbf7c1..cf067ddf4 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs @@ -161,7 +161,7 @@ namespace MediaBrowser.Controller.MediaEncoding public int? OutputAudioBitrate; public int? OutputAudioChannels; - public bool DeInterlace(string videoCodec) + public bool DeInterlace(string videoCodec, bool forceDeinterlaceIfSourceIsInterlaced) { // Support general param if (BaseRequest.DeInterlace) @@ -177,6 +177,15 @@ namespace MediaBrowser.Controller.MediaEncoding } } + if (forceDeinterlaceIfSourceIsInterlaced) + { + var videoStream = VideoStream; + if (videoStream != null && videoStream.IsInterlaced) + { + return true; + } + } + return false; } @@ -559,7 +568,7 @@ namespace MediaBrowser.Controller.MediaEncoding return VideoStream == null ? (bool?)null : VideoStream.IsInterlaced; } - if (DeInterlace(ActualOutputVideoCodec)) + if (DeInterlace(ActualOutputVideoCodec, true)) { return false; } -- cgit v1.2.3 From 134e74414d2644f1c345a2ef8876504aaaa69027 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 29 Sep 2017 02:13:05 -0400 Subject: update translations --- .../MediaEncoding/EncodingHelper.cs | 36 ++++++---------------- SharedVersion.cs | 2 +- 2 files changed, 11 insertions(+), 27 deletions(-) (limited to 'MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs') diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index ee7b9f080..861f4467d 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -1531,11 +1531,18 @@ namespace MediaBrowser.Controller.MediaEncoding /// System.Int32. public int GetNumberOfThreads(EncodingJobInfo state, EncodingOptions encodingOptions, bool isWebm) { - var threads = GetNumberOfThreadsInternal(state, encodingOptions, isWebm); + if (isWebm) + { + // Recommended per docs + return Math.Max(Environment.ProcessorCount - 1, 2); + } + + var threads = state.BaseRequest.CpuCoreLimit ?? encodingOptions.EncodingThreadCount; - if (state.BaseRequest.CpuCoreLimit.HasValue && state.BaseRequest.CpuCoreLimit.Value > 0) + // Automatic + if (threads <= 0 || threads >= Environment.ProcessorCount) { - threads = Math.Min(threads, state.BaseRequest.CpuCoreLimit.Value); + return 0; } return threads; @@ -1957,29 +1964,6 @@ namespace MediaBrowser.Controller.MediaEncoding return null; } - /// - /// Gets the number of threads. - /// - /// System.Int32. - private int GetNumberOfThreadsInternal(EncodingJobInfo state, EncodingOptions encodingOptions, bool isWebm) - { - var threads = encodingOptions.EncodingThreadCount; - - if (isWebm) - { - // Recommended per docs - return Math.Max(Environment.ProcessorCount - 1, 2); - } - - // Automatic - if (threads == -1) - { - return 0; - } - - return threads; - } - public string GetSubtitleEmbedArguments(EncodingJobInfo state) { if (state.SubtitleStream == null || state.SubtitleDeliveryMethod != SubtitleDeliveryMethod.Embed) diff --git a/SharedVersion.cs b/SharedVersion.cs index e1a18d590..ea2c94924 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,3 +1,3 @@ using System.Reflection; -[assembly: AssemblyVersion("3.2.32.10")] +[assembly: AssemblyVersion("3.2.32.11")] -- cgit v1.2.3 From 4e4c145855bb2f58492f62b9bfbb6a3f7c1d232f Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 29 Sep 2017 16:10:13 -0400 Subject: update hls query string --- MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs | 10 ++++++---- MediaBrowser.Model/Dlna/StreamBuilder.cs | 7 ++++++- MediaBrowser.Model/Dlna/StreamInfo.cs | 8 ++++++-- 3 files changed, 18 insertions(+), 7 deletions(-) (limited to 'MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs') diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index 861f4467d..6be68043f 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -346,7 +346,8 @@ namespace MediaBrowser.Controller.MediaEncoding "Constrained High" }; - return Array.FindIndex(list.ToArray(), t => string.Equals(t, profile, StringComparison.OrdinalIgnoreCase)); + // strip spaces because they may be stripped out on the query string + return Array.FindIndex(list.ToArray(), t => string.Equals(t.Replace(" ", ""), profile.Replace(" ", ""), StringComparison.OrdinalIgnoreCase)); } public string GetInputPathArgument(EncodingJobInfo state) @@ -831,7 +832,7 @@ namespace MediaBrowser.Controller.MediaEncoding } // Source and target codecs must match - if (string.IsNullOrEmpty(videoStream.Codec) || !state.SupportedVideoCodecs.Contains(videoStream.Codec, StringComparer.OrdinalIgnoreCase)) + if (string.IsNullOrWhiteSpace(videoStream.Codec) || !state.SupportedVideoCodecs.Contains(videoStream.Codec, StringComparer.OrdinalIgnoreCase)) { return false; } @@ -841,13 +842,14 @@ namespace MediaBrowser.Controller.MediaEncoding // If client is requesting a specific video profile, it must match the source if (requestedProfiles.Length > 0) { - if (string.IsNullOrEmpty(videoStream.Profile)) + if (string.IsNullOrWhiteSpace(videoStream.Profile)) { //return false; } var requestedProfile = requestedProfiles[0]; - if (!string.IsNullOrEmpty(videoStream.Profile) && !string.Equals(requestedProfile, videoStream.Profile, StringComparison.OrdinalIgnoreCase)) + // strip spaces because they may be stripped out on the query string as well + if (!string.IsNullOrWhiteSpace(videoStream.Profile) && !requestedProfiles.Contains(videoStream.Profile.Replace(" ", ""), StringComparer.OrdinalIgnoreCase)) { var currentScore = GetVideoProfileScore(videoStream.Profile); var requestedScore = GetVideoProfileScore(requestedProfile); diff --git a/MediaBrowser.Model/Dlna/StreamBuilder.cs b/MediaBrowser.Model/Dlna/StreamBuilder.cs index 67d9b834f..95a80c34c 100644 --- a/MediaBrowser.Model/Dlna/StreamBuilder.cs +++ b/MediaBrowser.Model/Dlna/StreamBuilder.cs @@ -1615,7 +1615,12 @@ namespace MediaBrowser.Model.Dlna if (!string.IsNullOrWhiteSpace(value)) { // change from split by | to comma - item.SetOption(qualifier, "profile", string.Join(",", value.Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries))); + + // strip spaces to avoid having to encode + var values = value + .Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries); + + item.SetOption(qualifier, "profile", string.Join(",", values)); } break; } diff --git a/MediaBrowser.Model/Dlna/StreamInfo.cs b/MediaBrowser.Model/Dlna/StreamInfo.cs index 2019acd0d..5a059e91d 100644 --- a/MediaBrowser.Model/Dlna/StreamInfo.cs +++ b/MediaBrowser.Model/Dlna/StreamInfo.cs @@ -297,7 +297,10 @@ namespace MediaBrowser.Model.Dlna // dlna needs to be update to support the qualified params var profile = item.GetOption("h264", "profile"); - list.Add(new NameValuePair("Profile", profile ?? string.Empty)); + // Avoid having to encode + profile = (profile ?? string.Empty).Replace(" ", ""); + + list.Add(new NameValuePair("Profile", profile)); } // no longer used @@ -372,7 +375,8 @@ namespace MediaBrowser.Model.Dlna continue; } - list.Add(new NameValuePair(pair.Key, pair.Value)); + // strip spaces to avoid having to encode h264 profile names + list.Add(new NameValuePair(pair.Key, pair.Value.Replace(" ", ""))); } } -- cgit v1.2.3 From a452bc23b299b26cff3ff585862796c04ac5bc93 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 1 Oct 2017 20:13:12 -0400 Subject: adjust params when burning in subtitles --- MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs | 6 ++++-- MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs | 11 +++++++++-- 2 files changed, 13 insertions(+), 4 deletions(-) (limited to 'MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs') diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index 6be68043f..8b612f809 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -530,7 +530,8 @@ namespace MediaBrowser.Controller.MediaEncoding { var seconds = Math.Round(TimeSpan.FromTicks(state.StartTimeTicks ?? 0).TotalSeconds); - var setPtsParam = state.CopyTimestamps + // hls always copies timestamps + var setPtsParam = state.CopyTimestamps || state.TranscodingType != TranscodingJobType.Progressive ? string.Empty : string.Format(",setpts=PTS -{0}/TB", seconds.ToString(_usCulture)); @@ -1083,7 +1084,8 @@ namespace MediaBrowser.Controller.MediaEncoding } } - if (state.SubtitleStream != null && state.SubtitleStream.IsTextSubtitleStream && state.SubtitleDeliveryMethod == SubtitleDeliveryMethod.Encode && !state.CopyTimestamps) + var isCopyingTimestamps = state.CopyTimestamps || state.TranscodingType != TranscodingJobType.Progressive; + if (state.SubtitleStream != null && state.SubtitleStream.IsTextSubtitleStream && state.SubtitleDeliveryMethod == SubtitleDeliveryMethod.Encode && !isCopyingTimestamps) { var seconds = TimeSpan.FromTicks(state.StartTimeTicks ?? 0).TotalSeconds; diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs b/MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs index cf067ddf4..506fce3ca 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs @@ -163,6 +163,14 @@ namespace MediaBrowser.Controller.MediaEncoding public bool DeInterlace(string videoCodec, bool forceDeinterlaceIfSourceIsInterlaced) { + var videoStream = VideoStream; + var isInputInterlaced = videoStream != null && videoStream.IsInterlaced; + + if (!isInputInterlaced) + { + return false; + } + // Support general param if (BaseRequest.DeInterlace) { @@ -179,8 +187,7 @@ namespace MediaBrowser.Controller.MediaEncoding if (forceDeinterlaceIfSourceIsInterlaced) { - var videoStream = VideoStream; - if (videoStream != null && videoStream.IsInterlaced) + if (isInputInterlaced) { return true; } -- cgit v1.2.3