|
|
@ -93,19 +93,10 @@ namespace MediaBrowser.Model.Dlna
|
|
|
|
return GetOptimalStream(streams, options.GetMaxBitrate(false) ?? 0);
|
|
|
|
return GetOptimalStream(streams, options.GetMaxBitrate(false) ?? 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private StreamInfo GetOptimalStream(List<StreamInfo> streams, long maxBitrate)
|
|
|
|
private static StreamInfo GetOptimalStream(List<StreamInfo> streams, long maxBitrate)
|
|
|
|
{
|
|
|
|
=> SortMediaSources(streams, maxBitrate).FirstOrDefault();
|
|
|
|
var sorted = SortMediaSources(streams, maxBitrate);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
foreach (StreamInfo stream in sorted)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return stream;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return null;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private StreamInfo[] SortMediaSources(List<StreamInfo> streams, long maxBitrate)
|
|
|
|
private static IOrderedEnumerable<StreamInfo> SortMediaSources(List<StreamInfo> streams, long maxBitrate)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
return streams.OrderBy(i =>
|
|
|
|
return streams.OrderBy(i =>
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -151,25 +142,21 @@ namespace MediaBrowser.Model.Dlna
|
|
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
|
|
}).ThenBy(streams.IndexOf).ToArray();
|
|
|
|
}).ThenBy(streams.IndexOf);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private TranscodeReason? GetTranscodeReasonForFailedCondition(ProfileCondition condition)
|
|
|
|
private static TranscodeReason? GetTranscodeReasonForFailedCondition(ProfileCondition condition)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
switch (condition.Property)
|
|
|
|
switch (condition.Property)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
case ProfileConditionValue.AudioBitrate:
|
|
|
|
case ProfileConditionValue.AudioBitrate when condition.Condition == ProfileConditionType.LessThanEqual:
|
|
|
|
if (condition.Condition == ProfileConditionType.LessThanEqual)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return TranscodeReason.AudioBitrateNotSupported;
|
|
|
|
return TranscodeReason.AudioBitrateNotSupported;
|
|
|
|
}
|
|
|
|
case ProfileConditionValue.AudioBitrate:
|
|
|
|
return TranscodeReason.AudioBitrateNotSupported;
|
|
|
|
return TranscodeReason.AudioBitrateNotSupported;
|
|
|
|
|
|
|
|
|
|
|
|
case ProfileConditionValue.AudioChannels:
|
|
|
|
case ProfileConditionValue.AudioChannels when condition.Condition == ProfileConditionType.LessThanEqual:
|
|
|
|
if (condition.Condition == ProfileConditionType.LessThanEqual)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return TranscodeReason.AudioChannelsNotSupported;
|
|
|
|
return TranscodeReason.AudioChannelsNotSupported;
|
|
|
|
}
|
|
|
|
case ProfileConditionValue.AudioChannels:
|
|
|
|
return TranscodeReason.AudioChannelsNotSupported;
|
|
|
|
return TranscodeReason.AudioChannelsNotSupported;
|
|
|
|
|
|
|
|
|
|
|
|
case ProfileConditionValue.AudioProfile:
|
|
|
|
case ProfileConditionValue.AudioProfile:
|
|
|
@ -246,7 +233,7 @@ namespace MediaBrowser.Model.Dlna
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public static string NormalizeMediaSourceFormatIntoSingleContainer(string inputContainer, string unused1, DeviceProfile profile, DlnaProfileType type)
|
|
|
|
public static string NormalizeMediaSourceFormatIntoSingleContainer(string inputContainer, string _, DeviceProfile profile, DlnaProfileType type)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (string.IsNullOrEmpty(inputContainer))
|
|
|
|
if (string.IsNullOrEmpty(inputContainer))
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -266,25 +253,21 @@ namespace MediaBrowser.Model.Dlna
|
|
|
|
{
|
|
|
|
{
|
|
|
|
foreach (var directPlayProfile in profile.DirectPlayProfiles)
|
|
|
|
foreach (var directPlayProfile in profile.DirectPlayProfiles)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (directPlayProfile.Type == type)
|
|
|
|
if (directPlayProfile.Type == type
|
|
|
|
{
|
|
|
|
&& directPlayProfile.SupportsContainer(format))
|
|
|
|
if (directPlayProfile.SupportsContainer(format))
|
|
|
|
|
|
|
|
{
|
|
|
|
{
|
|
|
|
return format;
|
|
|
|
return format;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return formats[0];
|
|
|
|
return formats[0];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private StreamInfo BuildAudioItem(MediaSourceInfo item, AudioOptions options)
|
|
|
|
private StreamInfo BuildAudioItem(MediaSourceInfo item, AudioOptions options)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
var transcodeReasons = new List<TranscodeReason>();
|
|
|
|
StreamInfo playlistItem = new StreamInfo
|
|
|
|
|
|
|
|
|
|
|
|
var playlistItem = new StreamInfo
|
|
|
|
|
|
|
|
{
|
|
|
|
{
|
|
|
|
ItemId = options.ItemId,
|
|
|
|
ItemId = options.ItemId,
|
|
|
|
MediaType = DlnaProfileType.Audio,
|
|
|
|
MediaType = DlnaProfileType.Audio,
|
|
|
@ -313,9 +296,7 @@ namespace MediaBrowser.Model.Dlna
|
|
|
|
var directPlayInfo = GetAudioDirectPlayMethods(item, audioStream, options);
|
|
|
|
var directPlayInfo = GetAudioDirectPlayMethods(item, audioStream, options);
|
|
|
|
|
|
|
|
|
|
|
|
var directPlayMethods = directPlayInfo.Item1;
|
|
|
|
var directPlayMethods = directPlayInfo.Item1;
|
|
|
|
transcodeReasons.AddRange(directPlayInfo.Item2);
|
|
|
|
var transcodeReasons = directPlayInfo.Item2.ToList();
|
|
|
|
|
|
|
|
|
|
|
|
var conditionProcessor = new ConditionProcessor();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int? inputAudioChannels = audioStream?.Channels;
|
|
|
|
int? inputAudioChannels = audioStream?.Channels;
|
|
|
|
int? inputAudioBitrate = audioStream?.BitDepth;
|
|
|
|
int? inputAudioBitrate = audioStream?.BitDepth;
|
|
|
@ -335,7 +316,7 @@ namespace MediaBrowser.Model.Dlna
|
|
|
|
bool applyConditions = true;
|
|
|
|
bool applyConditions = true;
|
|
|
|
foreach (ProfileCondition applyCondition in i.ApplyConditions)
|
|
|
|
foreach (ProfileCondition applyCondition in i.ApplyConditions)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (!conditionProcessor.IsAudioConditionSatisfied(applyCondition, inputAudioChannels, inputAudioBitrate, inputAudioSampleRate, inputAudioBitDepth))
|
|
|
|
if (!ConditionProcessor.IsAudioConditionSatisfied(applyCondition, inputAudioChannels, inputAudioBitrate, inputAudioSampleRate, inputAudioBitDepth))
|
|
|
|
{
|
|
|
|
{
|
|
|
|
LogConditionFailure(options.Profile, "AudioCodecProfile", applyCondition, item);
|
|
|
|
LogConditionFailure(options.Profile, "AudioCodecProfile", applyCondition, item);
|
|
|
|
applyConditions = false;
|
|
|
|
applyConditions = false;
|
|
|
@ -353,7 +334,7 @@ namespace MediaBrowser.Model.Dlna
|
|
|
|
bool all = true;
|
|
|
|
bool all = true;
|
|
|
|
foreach (ProfileCondition c in conditions)
|
|
|
|
foreach (ProfileCondition c in conditions)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (!conditionProcessor.IsAudioConditionSatisfied(c, inputAudioChannels, inputAudioBitrate, inputAudioSampleRate, inputAudioBitDepth))
|
|
|
|
if (!ConditionProcessor.IsAudioConditionSatisfied(c, inputAudioChannels, inputAudioBitrate, inputAudioSampleRate, inputAudioBitDepth))
|
|
|
|
{
|
|
|
|
{
|
|
|
|
LogConditionFailure(options.Profile, "AudioCodecProfile", c, item);
|
|
|
|
LogConditionFailure(options.Profile, "AudioCodecProfile", c, item);
|
|
|
|
var transcodeReason = GetTranscodeReasonForFailedCondition(c);
|
|
|
|
var transcodeReason = GetTranscodeReasonForFailedCondition(c);
|
|
|
@ -382,15 +363,14 @@ namespace MediaBrowser.Model.Dlna
|
|
|
|
TranscodingProfile transcodingProfile = null;
|
|
|
|
TranscodingProfile transcodingProfile = null;
|
|
|
|
foreach (var i in options.Profile.TranscodingProfiles)
|
|
|
|
foreach (var i in options.Profile.TranscodingProfiles)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (i.Type == playlistItem.MediaType && i.Context == options.Context)
|
|
|
|
if (i.Type == playlistItem.MediaType
|
|
|
|
{
|
|
|
|
&& i.Context == options.Context
|
|
|
|
if (_transcoderSupport.CanEncodeToAudioCodec(i.AudioCodec ?? i.Container))
|
|
|
|
&& _transcoderSupport.CanEncodeToAudioCodec(i.AudioCodec ?? i.Container))
|
|
|
|
{
|
|
|
|
{
|
|
|
|
transcodingProfile = i;
|
|
|
|
transcodingProfile = i;
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (transcodingProfile != null)
|
|
|
|
if (transcodingProfile != null)
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -418,7 +398,7 @@ namespace MediaBrowser.Model.Dlna
|
|
|
|
bool applyConditions = true;
|
|
|
|
bool applyConditions = true;
|
|
|
|
foreach (var applyCondition in i.ApplyConditions)
|
|
|
|
foreach (var applyCondition in i.ApplyConditions)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (!conditionProcessor.IsAudioConditionSatisfied(applyCondition, inputAudioChannels, inputAudioBitrate, inputAudioSampleRate, inputAudioBitDepth))
|
|
|
|
if (!ConditionProcessor.IsAudioConditionSatisfied(applyCondition, inputAudioChannels, inputAudioBitrate, inputAudioSampleRate, inputAudioBitDepth))
|
|
|
|
{
|
|
|
|
{
|
|
|
|
LogConditionFailure(options.Profile, "AudioCodecProfile", applyCondition, item);
|
|
|
|
LogConditionFailure(options.Profile, "AudioCodecProfile", applyCondition, item);
|
|
|
|
applyConditions = false;
|
|
|
|
applyConditions = false;
|
|
|
@ -460,7 +440,7 @@ namespace MediaBrowser.Model.Dlna
|
|
|
|
return playlistItem;
|
|
|
|
return playlistItem;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private long? GetBitrateForDirectPlayCheck(MediaSourceInfo item, AudioOptions options, bool isAudio)
|
|
|
|
private static long? GetBitrateForDirectPlayCheck(MediaSourceInfo item, AudioOptions options, bool isAudio)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (item.Protocol == MediaProtocol.File)
|
|
|
|
if (item.Protocol == MediaProtocol.File)
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -533,7 +513,7 @@ namespace MediaBrowser.Model.Dlna
|
|
|
|
return (playMethods, transcodeReasons);
|
|
|
|
return (playMethods, transcodeReasons);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private List<TranscodeReason> GetTranscodeReasonsFromDirectPlayProfile(MediaSourceInfo item, MediaStream videoStream, MediaStream audioStream, IEnumerable<DirectPlayProfile> directPlayProfiles)
|
|
|
|
private static List<TranscodeReason> GetTranscodeReasonsFromDirectPlayProfile(MediaSourceInfo item, MediaStream videoStream, MediaStream audioStream, IEnumerable<DirectPlayProfile> directPlayProfiles)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
var containerSupported = false;
|
|
|
|
var containerSupported = false;
|
|
|
|
var audioSupported = false;
|
|
|
|
var audioSupported = false;
|
|
|
@ -576,20 +556,19 @@ namespace MediaBrowser.Model.Dlna
|
|
|
|
return list;
|
|
|
|
return list;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private int? GetDefaultSubtitleStreamIndex(MediaSourceInfo item, SubtitleProfile[] subtitleProfiles)
|
|
|
|
private static int? GetDefaultSubtitleStreamIndex(MediaSourceInfo item, SubtitleProfile[] subtitleProfiles)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
int highestScore = -1;
|
|
|
|
int highestScore = -1;
|
|
|
|
|
|
|
|
|
|
|
|
foreach (var stream in item.MediaStreams)
|
|
|
|
foreach (var stream in item.MediaStreams)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (stream.Type == MediaStreamType.Subtitle && stream.Score.HasValue)
|
|
|
|
if (stream.Type == MediaStreamType.Subtitle
|
|
|
|
{
|
|
|
|
&& stream.Score.HasValue
|
|
|
|
if (stream.Score.Value > highestScore)
|
|
|
|
&& stream.Score.Value > highestScore)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
highestScore = stream.Score.Value;
|
|
|
|
highestScore = stream.Score.Value;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var topStreams = new List<MediaStream>();
|
|
|
|
var topStreams = new List<MediaStream>();
|
|
|
|
foreach (var stream in item.MediaStreams)
|
|
|
|
foreach (var stream in item.MediaStreams)
|
|
|
@ -619,7 +598,7 @@ namespace MediaBrowser.Model.Dlna
|
|
|
|
return item.DefaultSubtitleStreamIndex;
|
|
|
|
return item.DefaultSubtitleStreamIndex;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void SetStreamInfoOptionsFromTranscodingProfile(StreamInfo playlistItem, TranscodingProfile transcodingProfile)
|
|
|
|
private static void SetStreamInfoOptionsFromTranscodingProfile(StreamInfo playlistItem, TranscodingProfile transcodingProfile)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (string.IsNullOrEmpty(transcodingProfile.AudioCodec))
|
|
|
|
if (string.IsNullOrEmpty(transcodingProfile.AudioCodec))
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -659,14 +638,12 @@ namespace MediaBrowser.Model.Dlna
|
|
|
|
}
|
|
|
|
}
|
|
|
|
playlistItem.SubProtocol = transcodingProfile.Protocol;
|
|
|
|
playlistItem.SubProtocol = transcodingProfile.Protocol;
|
|
|
|
|
|
|
|
|
|
|
|
if (!string.IsNullOrEmpty(transcodingProfile.MaxAudioChannels))
|
|
|
|
if (!string.IsNullOrEmpty(transcodingProfile.MaxAudioChannels)
|
|
|
|
{
|
|
|
|
&& int.TryParse(transcodingProfile.MaxAudioChannels, NumberStyles.Any, CultureInfo.InvariantCulture, out int transcodingMaxAudioChannels))
|
|
|
|
if (int.TryParse(transcodingProfile.MaxAudioChannels, NumberStyles.Any, CultureInfo.InvariantCulture, out var transcodingMaxAudioChannels))
|
|
|
|
|
|
|
|
{
|
|
|
|
{
|
|
|
|
playlistItem.TranscodingMaxAudioChannels = transcodingMaxAudioChannels;
|
|
|
|
playlistItem.TranscodingMaxAudioChannels = transcodingMaxAudioChannels;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private StreamInfo BuildVideoItem(MediaSourceInfo item, VideoOptions options)
|
|
|
|
private StreamInfo BuildVideoItem(MediaSourceInfo item, VideoOptions options)
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -675,9 +652,7 @@ namespace MediaBrowser.Model.Dlna
|
|
|
|
throw new ArgumentNullException(nameof(item));
|
|
|
|
throw new ArgumentNullException(nameof(item));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var transcodeReasons = new List<TranscodeReason>();
|
|
|
|
StreamInfo playlistItem = new StreamInfo
|
|
|
|
|
|
|
|
|
|
|
|
var playlistItem = new StreamInfo
|
|
|
|
|
|
|
|
{
|
|
|
|
{
|
|
|
|
ItemId = options.ItemId,
|
|
|
|
ItemId = options.ItemId,
|
|
|
|
MediaType = DlnaProfileType.Video,
|
|
|
|
MediaType = DlnaProfileType.Video,
|
|
|
@ -710,6 +685,8 @@ namespace MediaBrowser.Model.Dlna
|
|
|
|
isEligibleForDirectPlay,
|
|
|
|
isEligibleForDirectPlay,
|
|
|
|
isEligibleForDirectStream);
|
|
|
|
isEligibleForDirectStream);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var transcodeReasons = new List<TranscodeReason>();
|
|
|
|
|
|
|
|
|
|
|
|
if (isEligibleForDirectPlay || isEligibleForDirectStream)
|
|
|
|
if (isEligibleForDirectPlay || isEligibleForDirectStream)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
// See if it can be direct played
|
|
|
|
// See if it can be direct played
|
|
|
@ -776,8 +753,6 @@ namespace MediaBrowser.Model.Dlna
|
|
|
|
|
|
|
|
|
|
|
|
SetStreamInfoOptionsFromTranscodingProfile(playlistItem, transcodingProfile);
|
|
|
|
SetStreamInfoOptionsFromTranscodingProfile(playlistItem, transcodingProfile);
|
|
|
|
|
|
|
|
|
|
|
|
var conditionProcessor = new ConditionProcessor();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var isFirstAppliedCodecProfile = true;
|
|
|
|
var isFirstAppliedCodecProfile = true;
|
|
|
|
foreach (var i in options.Profile.CodecProfiles)
|
|
|
|
foreach (var i in options.Profile.CodecProfiles)
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -805,7 +780,7 @@ namespace MediaBrowser.Model.Dlna
|
|
|
|
int? numAudioStreams = item.GetStreamCount(MediaStreamType.Audio);
|
|
|
|
int? numAudioStreams = item.GetStreamCount(MediaStreamType.Audio);
|
|
|
|
int? numVideoStreams = item.GetStreamCount(MediaStreamType.Video);
|
|
|
|
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))
|
|
|
|
if (!ConditionProcessor.IsVideoConditionSatisfied(applyCondition, width, height, bitDepth, videoBitrate, videoProfile, videoLevel, videoFramerate, packetLength, timestamp, isAnamorphic, isInterlaced, refFrames, numVideoStreams, numAudioStreams, videoCodecTag, isAvc))
|
|
|
|
{
|
|
|
|
{
|
|
|
|
//LogConditionFailure(options.Profile, "VideoCodecProfile.ApplyConditions", applyCondition, item);
|
|
|
|
//LogConditionFailure(options.Profile, "VideoCodecProfile.ApplyConditions", applyCondition, item);
|
|
|
|
applyConditions = false;
|
|
|
|
applyConditions = false;
|
|
|
@ -849,7 +824,7 @@ namespace MediaBrowser.Model.Dlna
|
|
|
|
int? inputAudioSampleRate = audioStream == null ? null : audioStream.SampleRate;
|
|
|
|
int? inputAudioSampleRate = audioStream == null ? null : audioStream.SampleRate;
|
|
|
|
int? inputAudioBitDepth = audioStream == null ? null : audioStream.BitDepth;
|
|
|
|
int? inputAudioBitDepth = audioStream == null ? null : audioStream.BitDepth;
|
|
|
|
|
|
|
|
|
|
|
|
if (!conditionProcessor.IsVideoAudioConditionSatisfied(applyCondition, audioChannels, inputAudioBitrate, inputAudioSampleRate, inputAudioBitDepth, audioProfile, isSecondaryAudio))
|
|
|
|
if (!ConditionProcessor.IsVideoAudioConditionSatisfied(applyCondition, audioChannels, inputAudioBitrate, inputAudioSampleRate, inputAudioBitDepth, audioProfile, isSecondaryAudio))
|
|
|
|
{
|
|
|
|
{
|
|
|
|
//LogConditionFailure(options.Profile, "VideoCodecProfile.ApplyConditions", applyCondition, item);
|
|
|
|
//LogConditionFailure(options.Profile, "VideoCodecProfile.ApplyConditions", applyCondition, item);
|
|
|
|
applyConditions = false;
|
|
|
|
applyConditions = false;
|
|
|
@ -1016,29 +991,27 @@ namespace MediaBrowser.Model.Dlna
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var conditionProcessor = new ConditionProcessor();
|
|
|
|
int? width = videoStream?.Width;
|
|
|
|
|
|
|
|
int? height = videoStream?.Height;
|
|
|
|
int? width = videoStream == null ? null : videoStream.Width;
|
|
|
|
int? bitDepth = videoStream?.BitDepth;
|
|
|
|
int? height = videoStream == null ? null : videoStream.Height;
|
|
|
|
int? videoBitrate = videoStream?.BitRate;
|
|
|
|
int? bitDepth = videoStream == null ? null : videoStream.BitDepth;
|
|
|
|
double? videoLevel = videoStream?.Level;
|
|
|
|
int? videoBitrate = videoStream == null ? null : videoStream.BitRate;
|
|
|
|
string videoProfile = videoStream?.Profile;
|
|
|
|
double? videoLevel = videoStream == null ? null : videoStream.Level;
|
|
|
|
|
|
|
|
string videoProfile = videoStream == null ? null : videoStream.Profile;
|
|
|
|
|
|
|
|
float videoFramerate = videoStream == null ? 0 : videoStream.AverageFrameRate ?? videoStream.AverageFrameRate ?? 0;
|
|
|
|
float videoFramerate = videoStream == null ? 0 : videoStream.AverageFrameRate ?? videoStream.AverageFrameRate ?? 0;
|
|
|
|
bool? isAnamorphic = videoStream == null ? null : videoStream.IsAnamorphic;
|
|
|
|
bool? isAnamorphic = videoStream?.IsAnamorphic;
|
|
|
|
bool? isInterlaced = videoStream == null ? (bool?)null : videoStream.IsInterlaced;
|
|
|
|
bool? isInterlaced = videoStream?.IsInterlaced;
|
|
|
|
string videoCodecTag = videoStream == null ? null : videoStream.CodecTag;
|
|
|
|
string videoCodecTag = videoStream?.CodecTag;
|
|
|
|
bool? isAvc = videoStream == null ? null : videoStream.IsAVC;
|
|
|
|
bool? isAvc = videoStream?.IsAVC;
|
|
|
|
|
|
|
|
|
|
|
|
int? audioBitrate = audioStream == null ? null : audioStream.BitRate;
|
|
|
|
int? audioBitrate = audioStream?.BitRate;
|
|
|
|
int? audioChannels = audioStream == null ? null : audioStream.Channels;
|
|
|
|
int? audioChannels = audioStream?.Channels;
|
|
|
|
string audioProfile = audioStream == null ? null : audioStream.Profile;
|
|
|
|
string audioProfile = audioStream?.Profile;
|
|
|
|
int? audioSampleRate = audioStream == null ? null : audioStream.SampleRate;
|
|
|
|
int? audioSampleRate = audioStream?.SampleRate;
|
|
|
|
int? audioBitDepth = audioStream == null ? null : audioStream.BitDepth;
|
|
|
|
int? audioBitDepth = audioStream?.BitDepth;
|
|
|
|
|
|
|
|
|
|
|
|
TransportStreamTimestamp? timestamp = videoStream == null ? TransportStreamTimestamp.None : mediaSource.Timestamp;
|
|
|
|
TransportStreamTimestamp? timestamp = videoStream == null ? TransportStreamTimestamp.None : mediaSource.Timestamp;
|
|
|
|
int? packetLength = videoStream == null ? null : videoStream.PacketLength;
|
|
|
|
int? packetLength = videoStream?.PacketLength;
|
|
|
|
int? refFrames = videoStream == null ? null : videoStream.RefFrames;
|
|
|
|
int? refFrames = videoStream?.RefFrames;
|
|
|
|
|
|
|
|
|
|
|
|
int? numAudioStreams = mediaSource.GetStreamCount(MediaStreamType.Audio);
|
|
|
|
int? numAudioStreams = mediaSource.GetStreamCount(MediaStreamType.Audio);
|
|
|
|
int? numVideoStreams = mediaSource.GetStreamCount(MediaStreamType.Video);
|
|
|
|
int? numVideoStreams = mediaSource.GetStreamCount(MediaStreamType.Video);
|
|
|
@ -1046,7 +1019,7 @@ namespace MediaBrowser.Model.Dlna
|
|
|
|
// Check container conditions
|
|
|
|
// Check container conditions
|
|
|
|
foreach (ProfileCondition i in conditions)
|
|
|
|
foreach (ProfileCondition i in conditions)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (!conditionProcessor.IsVideoConditionSatisfied(i, width, height, bitDepth, videoBitrate, videoProfile, videoLevel, videoFramerate, packetLength, timestamp, isAnamorphic, isInterlaced, refFrames, numVideoStreams, numAudioStreams, videoCodecTag, isAvc))
|
|
|
|
if (!ConditionProcessor.IsVideoConditionSatisfied(i, width, height, bitDepth, videoBitrate, videoProfile, videoLevel, videoFramerate, packetLength, timestamp, isAnamorphic, isInterlaced, refFrames, numVideoStreams, numAudioStreams, videoCodecTag, isAvc))
|
|
|
|
{
|
|
|
|
{
|
|
|
|
LogConditionFailure(profile, "VideoContainerProfile", i, mediaSource);
|
|
|
|
LogConditionFailure(profile, "VideoContainerProfile", i, mediaSource);
|
|
|
|
|
|
|
|
|
|
|
@ -1069,7 +1042,7 @@ namespace MediaBrowser.Model.Dlna
|
|
|
|
bool applyConditions = true;
|
|
|
|
bool applyConditions = true;
|
|
|
|
foreach (ProfileCondition applyCondition in i.ApplyConditions)
|
|
|
|
foreach (ProfileCondition applyCondition in i.ApplyConditions)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (!conditionProcessor.IsVideoConditionSatisfied(applyCondition, width, height, bitDepth, videoBitrate, videoProfile, videoLevel, videoFramerate, packetLength, timestamp, isAnamorphic, isInterlaced, refFrames, numVideoStreams, numAudioStreams, videoCodecTag, isAvc))
|
|
|
|
if (!ConditionProcessor.IsVideoConditionSatisfied(applyCondition, width, height, bitDepth, videoBitrate, videoProfile, videoLevel, videoFramerate, packetLength, timestamp, isAnamorphic, isInterlaced, refFrames, numVideoStreams, numAudioStreams, videoCodecTag, isAvc))
|
|
|
|
{
|
|
|
|
{
|
|
|
|
//LogConditionFailure(profile, "VideoCodecProfile.ApplyConditions", applyCondition, mediaSource);
|
|
|
|
//LogConditionFailure(profile, "VideoCodecProfile.ApplyConditions", applyCondition, mediaSource);
|
|
|
|
applyConditions = false;
|
|
|
|
applyConditions = false;
|
|
|
@ -1089,14 +1062,14 @@ namespace MediaBrowser.Model.Dlna
|
|
|
|
|
|
|
|
|
|
|
|
foreach (ProfileCondition i in conditions)
|
|
|
|
foreach (ProfileCondition i in conditions)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (!conditionProcessor.IsVideoConditionSatisfied(i, width, height, bitDepth, videoBitrate, videoProfile, videoLevel, videoFramerate, packetLength, timestamp, isAnamorphic, isInterlaced, refFrames, numVideoStreams, numAudioStreams, videoCodecTag, isAvc))
|
|
|
|
if (!ConditionProcessor.IsVideoConditionSatisfied(i, width, height, bitDepth, videoBitrate, videoProfile, videoLevel, videoFramerate, packetLength, timestamp, isAnamorphic, isInterlaced, refFrames, numVideoStreams, numAudioStreams, videoCodecTag, isAvc))
|
|
|
|
{
|
|
|
|
{
|
|
|
|
LogConditionFailure(profile, "VideoCodecProfile", i, mediaSource);
|
|
|
|
LogConditionFailure(profile, "VideoCodecProfile", i, mediaSource);
|
|
|
|
|
|
|
|
|
|
|
|
var transcodeReason = GetTranscodeReasonForFailedCondition(i);
|
|
|
|
var transcodeReason = GetTranscodeReasonForFailedCondition(i);
|
|
|
|
var transcodeReasons = transcodeReason.HasValue
|
|
|
|
var transcodeReasons = transcodeReason.HasValue
|
|
|
|
? new List<TranscodeReason> { transcodeReason.Value }
|
|
|
|
? new List<TranscodeReason> { transcodeReason.Value }
|
|
|
|
: new List<TranscodeReason> { };
|
|
|
|
: new List<TranscodeReason>();
|
|
|
|
|
|
|
|
|
|
|
|
return new Tuple<PlayMethod?, List<TranscodeReason>>(null, transcodeReasons);
|
|
|
|
return new Tuple<PlayMethod?, List<TranscodeReason>>(null, transcodeReasons);
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -1116,7 +1089,7 @@ namespace MediaBrowser.Model.Dlna
|
|
|
|
bool applyConditions = true;
|
|
|
|
bool applyConditions = true;
|
|
|
|
foreach (ProfileCondition applyCondition in i.ApplyConditions)
|
|
|
|
foreach (ProfileCondition applyCondition in i.ApplyConditions)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (!conditionProcessor.IsVideoAudioConditionSatisfied(applyCondition, audioChannels, audioBitrate, audioSampleRate, audioBitDepth, audioProfile, isSecondaryAudio))
|
|
|
|
if (!ConditionProcessor.IsVideoAudioConditionSatisfied(applyCondition, audioChannels, audioBitrate, audioSampleRate, audioBitDepth, audioProfile, isSecondaryAudio))
|
|
|
|
{
|
|
|
|
{
|
|
|
|
//LogConditionFailure(profile, "VideoAudioCodecProfile.ApplyConditions", applyCondition, mediaSource);
|
|
|
|
//LogConditionFailure(profile, "VideoAudioCodecProfile.ApplyConditions", applyCondition, mediaSource);
|
|
|
|
applyConditions = false;
|
|
|
|
applyConditions = false;
|
|
|
@ -1136,14 +1109,14 @@ namespace MediaBrowser.Model.Dlna
|
|
|
|
|
|
|
|
|
|
|
|
foreach (ProfileCondition i in conditions)
|
|
|
|
foreach (ProfileCondition i in conditions)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (!conditionProcessor.IsVideoAudioConditionSatisfied(i, audioChannels, audioBitrate, audioSampleRate, audioBitDepth, audioProfile, isSecondaryAudio))
|
|
|
|
if (!ConditionProcessor.IsVideoAudioConditionSatisfied(i, audioChannels, audioBitrate, audioSampleRate, audioBitDepth, audioProfile, isSecondaryAudio))
|
|
|
|
{
|
|
|
|
{
|
|
|
|
LogConditionFailure(profile, "VideoAudioCodecProfile", i, mediaSource);
|
|
|
|
LogConditionFailure(profile, "VideoAudioCodecProfile", i, mediaSource);
|
|
|
|
|
|
|
|
|
|
|
|
var transcodeReason = GetTranscodeReasonForFailedCondition(i);
|
|
|
|
var transcodeReason = GetTranscodeReasonForFailedCondition(i);
|
|
|
|
var transcodeReasons = transcodeReason.HasValue
|
|
|
|
var transcodeReasons = transcodeReason.HasValue
|
|
|
|
? new List<TranscodeReason> { transcodeReason.Value }
|
|
|
|
? new List<TranscodeReason> { transcodeReason.Value }
|
|
|
|
: new List<TranscodeReason> { };
|
|
|
|
: new List<TranscodeReason>();
|
|
|
|
|
|
|
|
|
|
|
|
return new Tuple<PlayMethod?, List<TranscodeReason>>(null, transcodeReasons);
|
|
|
|
return new Tuple<PlayMethod?, List<TranscodeReason>>(null, transcodeReasons);
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -1170,7 +1143,8 @@ namespace MediaBrowser.Model.Dlna
|
|
|
|
mediaSource.Path ?? "Unknown path");
|
|
|
|
mediaSource.Path ?? "Unknown path");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private (bool directPlay, TranscodeReason? reason) IsEligibleForDirectPlay(MediaSourceInfo item,
|
|
|
|
private (bool directPlay, TranscodeReason? reason) IsEligibleForDirectPlay(
|
|
|
|
|
|
|
|
MediaSourceInfo item,
|
|
|
|
long maxBitrate,
|
|
|
|
long maxBitrate,
|
|
|
|
MediaStream subtitleStream,
|
|
|
|
MediaStream subtitleStream,
|
|
|
|
VideoOptions options,
|
|
|
|
VideoOptions options,
|
|
|
|