|
@@ -105,8 +105,99 @@ namespace MediaBrowser.Model.Dlna
|
|
return null;
|
|
return null;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ private TranscodeReason? GetTranscodeReasonForFailedCondition(ProfileCondition condition)
|
|
|
|
+ {
|
|
|
|
+ switch (condition.Property)
|
|
|
|
+ {
|
|
|
|
+ case ProfileConditionValue.AudioBitrate:
|
|
|
|
+ if (condition.Condition == ProfileConditionType.LessThanEqual)
|
|
|
|
+ {
|
|
|
|
+ return TranscodeReason.AudioBitrateNotSupported;
|
|
|
|
+ }
|
|
|
|
+ return TranscodeReason.AudioBitrateNotSupported;
|
|
|
|
+
|
|
|
|
+ case ProfileConditionValue.AudioChannels:
|
|
|
|
+ if (condition.Condition == ProfileConditionType.LessThanEqual)
|
|
|
|
+ {
|
|
|
|
+ return TranscodeReason.AudioChannelsNotSupported;
|
|
|
|
+ }
|
|
|
|
+ return TranscodeReason.AudioChannelsNotSupported;
|
|
|
|
+
|
|
|
|
+ case ProfileConditionValue.AudioProfile:
|
|
|
|
+ return TranscodeReason.AudioProfileNotSupported;
|
|
|
|
+
|
|
|
|
+ case ProfileConditionValue.AudioSampleRate:
|
|
|
|
+ return TranscodeReason.AudioSampleRateNotSupported;
|
|
|
|
+
|
|
|
|
+ case ProfileConditionValue.Has64BitOffsets:
|
|
|
|
+ // TODO
|
|
|
|
+ return null;
|
|
|
|
+
|
|
|
|
+ case ProfileConditionValue.Height:
|
|
|
|
+ return TranscodeReason.VideoResolutionNotSupported;
|
|
|
|
+
|
|
|
|
+ case ProfileConditionValue.IsAnamorphic:
|
|
|
|
+ return TranscodeReason.AnamorphicVideoNotSupported;
|
|
|
|
+
|
|
|
|
+ case ProfileConditionValue.IsAvc:
|
|
|
|
+ // TODO
|
|
|
|
+ return null;
|
|
|
|
+
|
|
|
|
+ case ProfileConditionValue.IsInterlaced:
|
|
|
|
+ return TranscodeReason.InterlacedVideoNotSupported;
|
|
|
|
+
|
|
|
|
+ case ProfileConditionValue.IsSecondaryAudio:
|
|
|
|
+ return TranscodeReason.SecondaryAudioNotSupported;
|
|
|
|
+
|
|
|
|
+ case ProfileConditionValue.NumAudioStreams:
|
|
|
|
+ // TODO
|
|
|
|
+ return null;
|
|
|
|
+
|
|
|
|
+ case ProfileConditionValue.NumVideoStreams:
|
|
|
|
+ // TODO
|
|
|
|
+ return null;
|
|
|
|
+
|
|
|
|
+ case ProfileConditionValue.PacketLength:
|
|
|
|
+ // TODO
|
|
|
|
+ return null;
|
|
|
|
+
|
|
|
|
+ case ProfileConditionValue.RefFrames:
|
|
|
|
+ return TranscodeReason.RefFramesNotSupported;
|
|
|
|
+
|
|
|
|
+ case ProfileConditionValue.VideoBitDepth:
|
|
|
|
+ return TranscodeReason.VideoBitDepthNotSupported;
|
|
|
|
+
|
|
|
|
+ case ProfileConditionValue.VideoBitrate:
|
|
|
|
+ return TranscodeReason.VideoBitrateNotSupported;
|
|
|
|
+
|
|
|
|
+ case ProfileConditionValue.VideoCodecTag:
|
|
|
|
+ return TranscodeReason.VideoCodecNotSupported;
|
|
|
|
+
|
|
|
|
+ case ProfileConditionValue.VideoFramerate:
|
|
|
|
+ return TranscodeReason.VideoFramerateNotSupported;
|
|
|
|
+
|
|
|
|
+ case ProfileConditionValue.VideoLevel:
|
|
|
|
+ return TranscodeReason.VideoLevelNotSupported;
|
|
|
|
+
|
|
|
|
+ case ProfileConditionValue.VideoProfile:
|
|
|
|
+ return TranscodeReason.VideoProfileNotSupported;
|
|
|
|
+
|
|
|
|
+ case ProfileConditionValue.VideoTimestamp:
|
|
|
|
+ // TODO
|
|
|
|
+ return null;
|
|
|
|
+
|
|
|
|
+ case ProfileConditionValue.Width:
|
|
|
|
+ return TranscodeReason.VideoResolutionNotSupported;
|
|
|
|
+
|
|
|
|
+ default:
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
private StreamInfo BuildAudioItem(MediaSourceInfo item, AudioOptions options)
|
|
private StreamInfo BuildAudioItem(MediaSourceInfo item, AudioOptions options)
|
|
{
|
|
{
|
|
|
|
+ List<TranscodeReason> transcodeReasons = new List<TranscodeReason>();
|
|
|
|
+
|
|
StreamInfo playlistItem = new StreamInfo
|
|
StreamInfo playlistItem = new StreamInfo
|
|
{
|
|
{
|
|
ItemId = options.ItemId,
|
|
ItemId = options.ItemId,
|
|
@@ -133,7 +224,10 @@ namespace MediaBrowser.Model.Dlna
|
|
|
|
|
|
MediaStream audioStream = item.GetDefaultAudioStream(null);
|
|
MediaStream audioStream = item.GetDefaultAudioStream(null);
|
|
|
|
|
|
- List<PlayMethod> directPlayMethods = GetAudioDirectPlayMethods(item, audioStream, options);
|
|
|
|
|
|
+ var directPlayInfo = GetAudioDirectPlayMethods(item, audioStream, options);
|
|
|
|
+
|
|
|
|
+ List<PlayMethod> directPlayMethods = directPlayInfo.Item1;
|
|
|
|
+ transcodeReasons.AddRange(directPlayInfo.Item2);
|
|
|
|
|
|
ConditionProcessor conditionProcessor = new ConditionProcessor();
|
|
ConditionProcessor conditionProcessor = new ConditionProcessor();
|
|
|
|
|
|
@@ -180,6 +274,11 @@ namespace MediaBrowser.Model.Dlna
|
|
if (!conditionProcessor.IsAudioConditionSatisfied(c, inputAudioChannels, inputAudioBitrate, inputAudioSampleRate))
|
|
if (!conditionProcessor.IsAudioConditionSatisfied(c, inputAudioChannels, inputAudioBitrate, inputAudioSampleRate))
|
|
{
|
|
{
|
|
LogConditionFailure(options.Profile, "AudioCodecProfile", c, item);
|
|
LogConditionFailure(options.Profile, "AudioCodecProfile", c, item);
|
|
|
|
+ var transcodeReason = GetTranscodeReasonForFailedCondition(c);
|
|
|
|
+ if (transcodeReason.HasValue)
|
|
|
|
+ {
|
|
|
|
+ transcodeReasons.Add(transcodeReason.Value);
|
|
|
|
+ }
|
|
all = false;
|
|
all = false;
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
@@ -292,9 +391,9 @@ namespace MediaBrowser.Model.Dlna
|
|
|
|
|
|
var longBitrate = Math.Min(transcodingBitrate, playlistItem.AudioBitrate ?? transcodingBitrate);
|
|
var longBitrate = Math.Min(transcodingBitrate, playlistItem.AudioBitrate ?? transcodingBitrate);
|
|
playlistItem.AudioBitrate = longBitrate > int.MaxValue ? int.MaxValue : Convert.ToInt32(longBitrate);
|
|
playlistItem.AudioBitrate = longBitrate > int.MaxValue ? int.MaxValue : Convert.ToInt32(longBitrate);
|
|
-
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ playlistItem.TranscodeReasons = transcodeReasons;
|
|
return playlistItem;
|
|
return playlistItem;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -308,8 +407,10 @@ namespace MediaBrowser.Model.Dlna
|
|
return options.GetMaxBitrate(isAudio);
|
|
return options.GetMaxBitrate(isAudio);
|
|
}
|
|
}
|
|
|
|
|
|
- private List<PlayMethod> GetAudioDirectPlayMethods(MediaSourceInfo item, MediaStream audioStream, AudioOptions options)
|
|
|
|
|
|
+ private Tuple<List<PlayMethod>, List<TranscodeReason>> GetAudioDirectPlayMethods(MediaSourceInfo item, MediaStream audioStream, AudioOptions options)
|
|
{
|
|
{
|
|
|
|
+ List<TranscodeReason> transcodeReasons = new List<TranscodeReason>();
|
|
|
|
+
|
|
DirectPlayProfile directPlayProfile = null;
|
|
DirectPlayProfile directPlayProfile = null;
|
|
foreach (DirectPlayProfile i in options.Profile.DirectPlayProfiles)
|
|
foreach (DirectPlayProfile i in options.Profile.DirectPlayProfiles)
|
|
{
|
|
{
|
|
@@ -325,27 +426,134 @@ namespace MediaBrowser.Model.Dlna
|
|
if (directPlayProfile != null)
|
|
if (directPlayProfile != null)
|
|
{
|
|
{
|
|
// While options takes the network and other factors into account. Only applies to direct stream
|
|
// While options takes the network and other factors into account. Only applies to direct stream
|
|
- if (item.SupportsDirectStream && IsAudioEligibleForDirectPlay(item, options.GetMaxBitrate(true), PlayMethod.DirectStream) && options.EnableDirectStream)
|
|
|
|
|
|
+ if (item.SupportsDirectStream)
|
|
{
|
|
{
|
|
- playMethods.Add(PlayMethod.DirectStream);
|
|
|
|
|
|
+ if (IsAudioEligibleForDirectPlay(item, options.GetMaxBitrate(true), PlayMethod.DirectStream))
|
|
|
|
+ {
|
|
|
|
+ if (options.EnableDirectStream)
|
|
|
|
+ {
|
|
|
|
+ playMethods.Add(PlayMethod.DirectStream);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ transcodeReasons.Add(TranscodeReason.ContainerBitrateExceedsLimit);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
// The profile describes what the device supports
|
|
// The profile describes what the device supports
|
|
// If device requirements are satisfied then allow both direct stream and direct play
|
|
// If device requirements are satisfied then allow both direct stream and direct play
|
|
- if (item.SupportsDirectPlay &&
|
|
|
|
- IsAudioEligibleForDirectPlay(item, GetBitrateForDirectPlayCheck(item, options, true), PlayMethod.DirectPlay) && options.EnableDirectPlay)
|
|
|
|
|
|
+ if (item.SupportsDirectPlay)
|
|
{
|
|
{
|
|
- playMethods.Add(PlayMethod.DirectPlay);
|
|
|
|
|
|
+ if (IsAudioEligibleForDirectPlay(item, GetBitrateForDirectPlayCheck(item, options, true), PlayMethod.DirectPlay))
|
|
|
|
+ {
|
|
|
|
+ if (options.EnableDirectPlay)
|
|
|
|
+ {
|
|
|
|
+ playMethods.Add(PlayMethod.DirectPlay);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ transcodeReasons.Add(TranscodeReason.ContainerBitrateExceedsLimit);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
else
|
|
{
|
|
{
|
|
|
|
+ transcodeReasons.InsertRange(0, GetTranscodeReasonsFromDirectPlayProfile(item, null, audioStream, options.Profile.DirectPlayProfiles));
|
|
|
|
+
|
|
_logger.Info("Profile: {0}, No direct play profiles found for Path: {1}",
|
|
_logger.Info("Profile: {0}, No direct play profiles found for Path: {1}",
|
|
options.Profile.Name ?? "Unknown Profile",
|
|
options.Profile.Name ?? "Unknown Profile",
|
|
item.Path ?? "Unknown path");
|
|
item.Path ?? "Unknown path");
|
|
}
|
|
}
|
|
|
|
|
|
- return playMethods;
|
|
|
|
|
|
+ if (playMethods.Count > 0)
|
|
|
|
+ {
|
|
|
|
+ transcodeReasons.Clear();
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ transcodeReasons = transcodeReasons.Distinct().ToList();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return new Tuple<List<PlayMethod>, List<TranscodeReason>>(playMethods, transcodeReasons);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private List<TranscodeReason> GetTranscodeReasonsFromDirectPlayProfile(MediaSourceInfo item, MediaStream videoStream, MediaStream audioStream, IEnumerable<DirectPlayProfile> directPlayProfiles)
|
|
|
|
+ {
|
|
|
|
+ var list = new List<TranscodeReason>();
|
|
|
|
+ var containerSupported = false;
|
|
|
|
+ var audioSupported = false;
|
|
|
|
+ var videoSupported = false;
|
|
|
|
+
|
|
|
|
+ foreach (var profile in directPlayProfiles)
|
|
|
|
+ {
|
|
|
|
+ if (profile.Container.Length > 0)
|
|
|
|
+ {
|
|
|
|
+ // Check container type
|
|
|
|
+ string mediaContainer = item.Container ?? string.Empty;
|
|
|
|
+ foreach (string i in profile.GetContainers())
|
|
|
|
+ {
|
|
|
|
+ if (StringHelper.EqualsIgnoreCase(i, mediaContainer))
|
|
|
|
+ {
|
|
|
|
+ containerSupported = true;
|
|
|
|
+
|
|
|
|
+ if (videoStream != null)
|
|
|
|
+ {
|
|
|
|
+ // Check video codec
|
|
|
|
+ List<string> videoCodecs = profile.GetVideoCodecs();
|
|
|
|
+ if (videoCodecs.Count > 0)
|
|
|
|
+ {
|
|
|
|
+ string videoCodec = videoStream.Codec;
|
|
|
|
+ if (!string.IsNullOrEmpty(videoCodec) && ListHelper.ContainsIgnoreCase(videoCodecs, videoCodec))
|
|
|
|
+ {
|
|
|
|
+ videoSupported = true;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ videoSupported = true;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (audioStream != null)
|
|
|
|
+ {
|
|
|
|
+ // Check audio codec
|
|
|
|
+ List<string> audioCodecs = profile.GetAudioCodecs();
|
|
|
|
+ if (audioCodecs.Count > 0)
|
|
|
|
+ {
|
|
|
|
+ string audioCodec = audioStream.Codec;
|
|
|
|
+ if (!string.IsNullOrEmpty(audioCodec) && ListHelper.ContainsIgnoreCase(audioCodecs, audioCodec))
|
|
|
|
+ {
|
|
|
|
+ audioSupported = true;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ audioSupported = true;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (!containerSupported)
|
|
|
|
+ {
|
|
|
|
+ list.Add(TranscodeReason.ContainerNotSupported);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (videoStream != null && !videoSupported)
|
|
|
|
+ {
|
|
|
|
+ list.Add(TranscodeReason.VideoCodecNotSupported);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (audioStream != null && !audioSupported)
|
|
|
|
+ {
|
|
|
|
+ list.Add(TranscodeReason.VideoCodecNotSupported);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return list;
|
|
}
|
|
}
|
|
|
|
|
|
private int? GetDefaultSubtitleStreamIndex(MediaSourceInfo item, SubtitleProfile[] subtitleProfiles)
|
|
private int? GetDefaultSubtitleStreamIndex(MediaSourceInfo item, SubtitleProfile[] subtitleProfiles)
|
|
@@ -393,6 +601,8 @@ namespace MediaBrowser.Model.Dlna
|
|
|
|
|
|
private StreamInfo BuildVideoItem(MediaSourceInfo item, VideoOptions options)
|
|
private StreamInfo BuildVideoItem(MediaSourceInfo item, VideoOptions options)
|
|
{
|
|
{
|
|
|
|
+ List<TranscodeReason> transcodeReasons = new List<TranscodeReason>();
|
|
|
|
+
|
|
StreamInfo playlistItem = new StreamInfo
|
|
StreamInfo playlistItem = new StreamInfo
|
|
{
|
|
{
|
|
ItemId = options.ItemId,
|
|
ItemId = options.ItemId,
|
|
@@ -428,7 +638,8 @@ namespace MediaBrowser.Model.Dlna
|
|
if (isEligibleForDirectPlay || isEligibleForDirectStream)
|
|
if (isEligibleForDirectPlay || isEligibleForDirectStream)
|
|
{
|
|
{
|
|
// See if it can be direct played
|
|
// See if it can be direct played
|
|
- PlayMethod? directPlay = GetVideoDirectPlayProfile(options, item, videoStream, audioStream, isEligibleForDirectPlay, isEligibleForDirectStream);
|
|
|
|
|
|
+ var directPlayInfo = GetVideoDirectPlayProfile(options, item, videoStream, audioStream, isEligibleForDirectPlay, isEligibleForDirectStream);
|
|
|
|
+ var directPlay = directPlayInfo.Item1;
|
|
|
|
|
|
if (directPlay != null)
|
|
if (directPlay != null)
|
|
{
|
|
{
|
|
@@ -445,6 +656,8 @@ namespace MediaBrowser.Model.Dlna
|
|
|
|
|
|
return playlistItem;
|
|
return playlistItem;
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ transcodeReasons.AddRange(directPlayInfo.Item2);
|
|
}
|
|
}
|
|
|
|
|
|
// Can't direct play, find the transcoding profile
|
|
// Can't direct play, find the transcoding profile
|
|
@@ -618,6 +831,8 @@ namespace MediaBrowser.Model.Dlna
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ playlistItem.TranscodeReasons = transcodeReasons;
|
|
|
|
+
|
|
return playlistItem;
|
|
return playlistItem;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -677,7 +892,7 @@ namespace MediaBrowser.Model.Dlna
|
|
return Math.Min(defaultBitrate, encoderAudioBitrateLimit);
|
|
return Math.Min(defaultBitrate, encoderAudioBitrateLimit);
|
|
}
|
|
}
|
|
|
|
|
|
- private PlayMethod? GetVideoDirectPlayProfile(VideoOptions options,
|
|
|
|
|
|
+ private Tuple<PlayMethod?, List<TranscodeReason>> GetVideoDirectPlayProfile(VideoOptions options,
|
|
MediaSourceInfo mediaSource,
|
|
MediaSourceInfo mediaSource,
|
|
MediaStream videoStream,
|
|
MediaStream videoStream,
|
|
MediaStream audioStream,
|
|
MediaStream audioStream,
|
|
@@ -688,11 +903,11 @@ namespace MediaBrowser.Model.Dlna
|
|
|
|
|
|
if (options.ForceDirectPlay)
|
|
if (options.ForceDirectPlay)
|
|
{
|
|
{
|
|
- return PlayMethod.DirectPlay;
|
|
|
|
|
|
+ return new Tuple<PlayMethod?, List<TranscodeReason>>(PlayMethod.DirectPlay, new List<TranscodeReason>());
|
|
}
|
|
}
|
|
if (options.ForceDirectStream)
|
|
if (options.ForceDirectStream)
|
|
{
|
|
{
|
|
- return PlayMethod.DirectStream;
|
|
|
|
|
|
+ return new Tuple<PlayMethod?, List<TranscodeReason>>(PlayMethod.DirectStream, new List<TranscodeReason>());
|
|
}
|
|
}
|
|
|
|
|
|
if (videoStream == null)
|
|
if (videoStream == null)
|
|
@@ -701,7 +916,7 @@ namespace MediaBrowser.Model.Dlna
|
|
profile.Name ?? "Unknown Profile",
|
|
profile.Name ?? "Unknown Profile",
|
|
mediaSource.Path ?? "Unknown path");
|
|
mediaSource.Path ?? "Unknown path");
|
|
|
|
|
|
- return null;
|
|
|
|
|
|
+ return new Tuple<PlayMethod?, List<TranscodeReason>>(null, new List<TranscodeReason> { TranscodeReason.UnknownVideoStreamInfo });
|
|
}
|
|
}
|
|
|
|
|
|
// See if it can be direct played
|
|
// See if it can be direct played
|
|
@@ -721,7 +936,7 @@ namespace MediaBrowser.Model.Dlna
|
|
profile.Name ?? "Unknown Profile",
|
|
profile.Name ?? "Unknown Profile",
|
|
mediaSource.Path ?? "Unknown path");
|
|
mediaSource.Path ?? "Unknown path");
|
|
|
|
|
|
- return null;
|
|
|
|
|
|
+ return new Tuple<PlayMethod?, List<TranscodeReason>>(null, GetTranscodeReasonsFromDirectPlayProfile(mediaSource, videoStream, audioStream, profile.DirectPlayProfiles));
|
|
}
|
|
}
|
|
|
|
|
|
string container = mediaSource.Container;
|
|
string container = mediaSource.Container;
|
|
@@ -784,7 +999,7 @@ namespace MediaBrowser.Model.Dlna
|
|
profile.Name ?? "Unknown Profile",
|
|
profile.Name ?? "Unknown Profile",
|
|
mediaSource.Path ?? "Unknown path");
|
|
mediaSource.Path ?? "Unknown path");
|
|
|
|
|
|
- return null;
|
|
|
|
|
|
+ return new Tuple<PlayMethod?, List<TranscodeReason>>(null, new List<TranscodeReason> { TranscodeReason.UnknownVideoStreamInfo });
|
|
}
|
|
}
|
|
|
|
|
|
conditions = new List<ProfileCondition>();
|
|
conditions = new List<ProfileCondition>();
|
|
@@ -819,7 +1034,12 @@ namespace MediaBrowser.Model.Dlna
|
|
{
|
|
{
|
|
LogConditionFailure(profile, "VideoCodecProfile", i, mediaSource);
|
|
LogConditionFailure(profile, "VideoCodecProfile", i, mediaSource);
|
|
|
|
|
|
- return null;
|
|
|
|
|
|
+ var transcodeReason = GetTranscodeReasonForFailedCondition(i);
|
|
|
|
+ var transcodeReasons = transcodeReason.HasValue
|
|
|
|
+ ? new List<TranscodeReason> { transcodeReason.Value }
|
|
|
|
+ : new List<TranscodeReason> { };
|
|
|
|
+
|
|
|
|
+ return new Tuple<PlayMethod?, List<TranscodeReason>>(null, transcodeReasons);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -833,7 +1053,7 @@ namespace MediaBrowser.Model.Dlna
|
|
profile.Name ?? "Unknown Profile",
|
|
profile.Name ?? "Unknown Profile",
|
|
mediaSource.Path ?? "Unknown path");
|
|
mediaSource.Path ?? "Unknown path");
|
|
|
|
|
|
- return null;
|
|
|
|
|
|
+ return new Tuple<PlayMethod?, List<TranscodeReason>>(null, new List<TranscodeReason> { TranscodeReason.UnknownAudioStreamInfo });
|
|
}
|
|
}
|
|
|
|
|
|
conditions = new List<ProfileCondition>();
|
|
conditions = new List<ProfileCondition>();
|
|
@@ -870,17 +1090,22 @@ namespace MediaBrowser.Model.Dlna
|
|
{
|
|
{
|
|
LogConditionFailure(profile, "VideoAudioCodecProfile", i, mediaSource);
|
|
LogConditionFailure(profile, "VideoAudioCodecProfile", i, mediaSource);
|
|
|
|
|
|
- return null;
|
|
|
|
|
|
+ var transcodeReason = GetTranscodeReasonForFailedCondition(i);
|
|
|
|
+ var transcodeReasons = transcodeReason.HasValue
|
|
|
|
+ ? new List<TranscodeReason> { transcodeReason.Value }
|
|
|
|
+ : new List<TranscodeReason> { };
|
|
|
|
+
|
|
|
|
+ return new Tuple<PlayMethod?, List<TranscodeReason>>(null, transcodeReasons);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
if (isEligibleForDirectStream && mediaSource.SupportsDirectStream)
|
|
if (isEligibleForDirectStream && mediaSource.SupportsDirectStream)
|
|
{
|
|
{
|
|
- return PlayMethod.DirectStream;
|
|
|
|
|
|
+ return new Tuple<PlayMethod?, List<TranscodeReason>>(PlayMethod.DirectStream, new List<TranscodeReason>());
|
|
}
|
|
}
|
|
|
|
|
|
- return null;
|
|
|
|
|
|
+ return new Tuple<PlayMethod?, List<TranscodeReason>>(null, new List<TranscodeReason> { TranscodeReason.ContainerBitrateExceedsLimit });
|
|
}
|
|
}
|
|
|
|
|
|
private void LogConditionFailure(DeviceProfile profile, string type, ProfileCondition condition, MediaSourceInfo mediaSource)
|
|
private void LogConditionFailure(DeviceProfile profile, string type, ProfileCondition condition, MediaSourceInfo mediaSource)
|
|
@@ -1047,12 +1272,12 @@ namespace MediaBrowser.Model.Dlna
|
|
// Don't restrict by bitrate if coming from an external domain
|
|
// Don't restrict by bitrate if coming from an external domain
|
|
if (item.IsRemote)
|
|
if (item.IsRemote)
|
|
{
|
|
{
|
|
- return true;
|
|
|
|
|
|
+ return true;
|
|
}
|
|
}
|
|
|
|
|
|
if (!maxBitrate.HasValue)
|
|
if (!maxBitrate.HasValue)
|
|
{
|
|
{
|
|
- _logger.Info("Cannot "+ playMethod + " due to unknown supported bitrate");
|
|
|
|
|
|
+ _logger.Info("Cannot " + playMethod + " due to unknown supported bitrate");
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|