add ios dts workaround

This commit is contained in:
Luke Pulverenti 2016-12-13 12:04:37 -05:00
parent 81d685b882
commit afabbfa22b
13 changed files with 104 additions and 19 deletions

View File

@ -207,7 +207,8 @@ namespace Emby.Dlna.Didl
streamInfo.TargetVideoStreamCount, streamInfo.TargetVideoStreamCount,
streamInfo.TargetAudioStreamCount, streamInfo.TargetAudioStreamCount,
streamInfo.TargetVideoCodecTag, streamInfo.TargetVideoCodecTag,
streamInfo.IsTargetAVC); streamInfo.IsTargetAVC,
streamInfo.AllAudioCodecs);
foreach (var contentFeature in contentFeatureList) foreach (var contentFeature in contentFeatureList)
{ {
@ -347,7 +348,8 @@ namespace Emby.Dlna.Didl
streamInfo.TargetVideoStreamCount, streamInfo.TargetVideoStreamCount,
streamInfo.TargetAudioStreamCount, streamInfo.TargetAudioStreamCount,
streamInfo.TargetVideoCodecTag, streamInfo.TargetVideoCodecTag,
streamInfo.IsTargetAVC); streamInfo.IsTargetAVC,
streamInfo.AllAudioCodecs);
var filename = url.Substring(0, url.IndexOf('?')); var filename = url.Substring(0, url.IndexOf('?'));

View File

@ -541,7 +541,8 @@ namespace Emby.Dlna.PlayTo
streamInfo.TargetVideoStreamCount, streamInfo.TargetVideoStreamCount,
streamInfo.TargetAudioStreamCount, streamInfo.TargetAudioStreamCount,
streamInfo.TargetVideoCodecTag, streamInfo.TargetVideoCodecTag,
streamInfo.IsTargetAVC); streamInfo.IsTargetAVC,
streamInfo.AllAudioCodecs);
return list.FirstOrDefault(); return list.FirstOrDefault();
} }

View File

@ -2358,7 +2358,8 @@ namespace MediaBrowser.Api.Playback
state.TargetVideoStreamCount, state.TargetVideoStreamCount,
state.TargetAudioStreamCount, state.TargetAudioStreamCount,
state.TargetVideoCodecTag, state.TargetVideoCodecTag,
state.IsTargetAVC); state.IsTargetAVC,
state.AllAudioCodecs);
if (mediaProfile != null) if (mediaProfile != null)
{ {
@ -2580,7 +2581,8 @@ namespace MediaBrowser.Api.Playback
state.TargetVideoStreamCount, state.TargetVideoStreamCount,
state.TargetAudioStreamCount, state.TargetAudioStreamCount,
state.TargetVideoCodecTag, state.TargetVideoCodecTag,
state.IsTargetAVC state.IsTargetAVC,
state.AllAudioCodecs
).FirstOrDefault() ?? string.Empty; ).FirstOrDefault() ?? string.Empty;
} }

View File

@ -11,6 +11,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using System.IO; using System.IO;
using System.Linq;
using System.Threading; using System.Threading;
namespace MediaBrowser.Api.Playback namespace MediaBrowser.Api.Playback
@ -244,6 +245,17 @@ namespace MediaBrowser.Api.Playback
public int? OutputAudioBitrate; public int? OutputAudioBitrate;
public int? OutputVideoBitrate; public int? OutputVideoBitrate;
public List<string> AllAudioCodecs
{
get
{
return MediaSource.MediaStreams.Where(i => i.Type == MediaStreamType.Audio)
.Select(i => i.Codec)
.Where(i => !string.IsNullOrWhiteSpace(i))
.ToList();
}
}
public string ActualOutputVideoCodec public string ActualOutputVideoCodec
{ {
get get

View File

@ -11,6 +11,7 @@ using MediaBrowser.Model.Net;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -117,6 +118,17 @@ namespace MediaBrowser.MediaEncoding.Encoder
} }
} }
public List<string> AllAudioCodecs
{
get
{
return MediaSource.MediaStreams.Where(i => i.Type == MediaStreamType.Audio)
.Select(i => i.Codec)
.Where(i => !string.IsNullOrWhiteSpace(i))
.ToList();
}
}
private void DisposeIsoMount() private void DisposeIsoMount()
{ {
if (IsoMount != null) if (IsoMount != null)

View File

@ -846,7 +846,8 @@ namespace MediaBrowser.MediaEncoding.Encoder
state.TargetVideoStreamCount, state.TargetVideoStreamCount,
state.TargetAudioStreamCount, state.TargetAudioStreamCount,
state.TargetVideoCodecTag, state.TargetVideoCodecTag,
state.IsTargetAVC); state.IsTargetAVC,
state.AllAudioCodecs);
if (mediaProfile != null) if (mediaProfile != null)
{ {

View File

@ -1,7 +1,9 @@
using MediaBrowser.Model.Extensions; using MediaBrowser.Model.Extensions;
using MediaBrowser.Model.MediaInfo; using MediaBrowser.Model.MediaInfo;
using System; using System;
using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using System.Linq;
namespace MediaBrowser.Model.Dlna namespace MediaBrowser.Model.Dlna
{ {
@ -22,12 +24,15 @@ namespace MediaBrowser.Model.Dlna
int? numVideoStreams, int? numVideoStreams,
int? numAudioStreams, int? numAudioStreams,
string videoCodecTag, string videoCodecTag,
bool? isAvc) bool? isAvc,
List<string> allAudioCodecs )
{ {
switch (condition.Property) switch (condition.Property)
{ {
case ProfileConditionValue.IsAnamorphic: case ProfileConditionValue.IsAnamorphic:
return IsConditionSatisfied(condition, isAnamorphic); return IsConditionSatisfied(condition, isAnamorphic);
case ProfileConditionValue.HasAudioCodec:
return IsHasAudioCodecConditionSatisfied(condition, allAudioCodecs);
case ProfileConditionValue.IsAvc: case ProfileConditionValue.IsAvc:
return IsConditionSatisfied(condition, isAvc); return IsConditionSatisfied(condition, isAvc);
case ProfileConditionValue.VideoFramerate: case ProfileConditionValue.VideoFramerate:
@ -162,6 +167,25 @@ namespace MediaBrowser.Model.Dlna
} }
} }
private bool IsHasAudioCodecConditionSatisfied(ProfileCondition condition, List<string> allAudioCodecs)
{
if (allAudioCodecs.Count == 0)
{
// If the value is unknown, it satisfies if not marked as required
return !condition.IsRequired;
}
switch (condition.Condition)
{
case ProfileConditionType.Equals:
return allAudioCodecs.Contains(condition.Value, StringComparer.Ordinal);
case ProfileConditionType.NotEquals:
return !allAudioCodecs.Contains(condition.Value, StringComparer.Ordinal);
default:
throw new InvalidOperationException("Unexpected ProfileConditionType");
}
}
private bool IsConditionSatisfied(ProfileCondition condition, bool? currentValue) private bool IsConditionSatisfied(ProfileCondition condition, bool? currentValue)
{ {
if (!currentValue.HasValue) if (!currentValue.HasValue)

View File

@ -1,6 +1,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Xml.Serialization; using System.Xml.Serialization;
using MediaBrowser.Model.Dlna; using MediaBrowser.Model.Dlna;
using MediaBrowser.Model.Extensions;
namespace MediaBrowser.Model.Dlna namespace MediaBrowser.Model.Dlna
{ {
@ -27,5 +28,12 @@ namespace MediaBrowser.Model.Dlna
} }
return list; return list;
} }
public bool ContainsContainer(string container)
{
List<string> containers = GetContainers();
return containers.Count == 0 || ListHelper.ContainsIgnoreCase(containers, container ?? string.Empty);
}
} }
} }

View File

@ -119,7 +119,8 @@ namespace MediaBrowser.Model.Dlna
int? numVideoStreams, int? numVideoStreams,
int? numAudioStreams, int? numAudioStreams,
string videoCodecTag, string videoCodecTag,
bool? isAvc) bool? isAvc,
List<string> allAudioCodecs)
{ {
// first bit means Time based seek supported, second byte range seek supported (not sure about the order now), so 01 = only byte seek, 10 = time based, 11 = both, 00 = none // first bit means Time based seek supported, second byte range seek supported (not sure about the order now), so 01 = only byte seek, 10 = time based, 11 = both, 00 = none
string orgOp = ";DLNA.ORG_OP=" + DlnaMaps.GetOrgOpValue(runtimeTicks.HasValue, isDirectStream, transcodeSeekInfo); string orgOp = ";DLNA.ORG_OP=" + DlnaMaps.GetOrgOpValue(runtimeTicks.HasValue, isDirectStream, transcodeSeekInfo);
@ -161,7 +162,8 @@ namespace MediaBrowser.Model.Dlna
numVideoStreams, numVideoStreams,
numAudioStreams, numAudioStreams,
videoCodecTag, videoCodecTag,
isAvc); isAvc,
allAudioCodecs);
List<string> orgPnValues = new List<string>(); List<string> orgPnValues = new List<string>();

View File

@ -297,7 +297,8 @@ namespace MediaBrowser.Model.Dlna
int? numVideoStreams, int? numVideoStreams,
int? numAudioStreams, int? numAudioStreams,
string videoCodecTag, string videoCodecTag,
bool? isAvc) bool? isAvc,
List<string> allAudioCodecs)
{ {
container = StringHelper.TrimStart(container ?? string.Empty, '.'); container = StringHelper.TrimStart(container ?? string.Empty, '.');
@ -331,7 +332,7 @@ namespace MediaBrowser.Model.Dlna
var anyOff = false; var anyOff = false;
foreach (ProfileCondition c in i.Conditions) foreach (ProfileCondition c in i.Conditions)
{ {
if (!conditionProcessor.IsVideoConditionSatisfied(GetModelProfileCondition(c), width, height, bitDepth, videoBitrate, videoProfile, videoLevel, videoFramerate, packetLength, timestamp, isAnamorphic, refFrames, numVideoStreams, numAudioStreams, videoCodecTag, isAvc)) if (!conditionProcessor.IsVideoConditionSatisfied(GetModelProfileCondition(c), width, height, bitDepth, videoBitrate, videoProfile, videoLevel, videoFramerate, packetLength, timestamp, isAnamorphic, refFrames, numVideoStreams, numAudioStreams, videoCodecTag, isAvc, allAudioCodecs))
{ {
anyOff = true; anyOff = true;
break; break;

View File

@ -21,6 +21,7 @@
NumVideoStreams = 17, NumVideoStreams = 17,
IsSecondaryAudio = 18, IsSecondaryAudio = 18,
VideoCodecTag = 19, VideoCodecTag = 19,
IsAvc = 20 IsAvc = 20,
HasAudioCodec = 21
} }
} }

View File

@ -7,6 +7,7 @@ using MediaBrowser.Model.Session;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using System.Linq;
namespace MediaBrowser.Model.Dlna namespace MediaBrowser.Model.Dlna
{ {
@ -409,6 +410,9 @@ namespace MediaBrowser.Model.Dlna
audioStreamIndex = audioStream.Index; audioStreamIndex = audioStream.Index;
} }
var allMediaStreams = item.MediaStreams;
var allAudioCodecs = allMediaStreams.Where(i => i.Type == MediaStreamType.Audio).Select(i => i.Codec).Where(i => !string.IsNullOrWhiteSpace(i)).ToList();
MediaStream videoStream = item.VideoStream; MediaStream videoStream = item.VideoStream;
// TODO: This doesn't accout for situation of device being able to handle media bitrate, but wifi connection not fast enough // TODO: This doesn't accout for situation of device being able to handle media bitrate, but wifi connection not fast enough
@ -424,7 +428,7 @@ 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); PlayMethod? directPlay = GetVideoDirectPlayProfile(options, item, videoStream, audioStream, isEligibleForDirectPlay, isEligibleForDirectStream, allMediaStreams);
if (directPlay != null) if (directPlay != null)
{ {
@ -552,7 +556,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, refFrames, numVideoStreams, numAudioStreams, videoCodecTag, isAvc)) if (!conditionProcessor.IsVideoConditionSatisfied(applyCondition, width, height, bitDepth, videoBitrate, videoProfile, videoLevel, videoFramerate, packetLength, timestamp, isAnamorphic, refFrames, numVideoStreams, numAudioStreams, videoCodecTag, isAvc, allAudioCodecs))
{ {
LogConditionFailure(options.Profile, "VideoCodecProfile", applyCondition, item); LogConditionFailure(options.Profile, "VideoCodecProfile", applyCondition, item);
applyConditions = false; applyConditions = false;
@ -653,7 +657,8 @@ namespace MediaBrowser.Model.Dlna
MediaStream videoStream, MediaStream videoStream,
MediaStream audioStream, MediaStream audioStream,
bool isEligibleForDirectPlay, bool isEligibleForDirectPlay,
bool isEligibleForDirectStream) bool isEligibleForDirectStream,
List<MediaStream> allMediaStreams)
{ {
DeviceProfile profile = options.Profile; DeviceProfile profile = options.Profile;
@ -701,7 +706,7 @@ namespace MediaBrowser.Model.Dlna
foreach (ContainerProfile i in profile.ContainerProfiles) foreach (ContainerProfile i in profile.ContainerProfiles)
{ {
if (i.Type == DlnaProfileType.Video && if (i.Type == DlnaProfileType.Video &&
ListHelper.ContainsIgnoreCase(i.GetContainers(), container)) i.ContainsContainer(container))
{ {
foreach (ProfileCondition c in i.Conditions) foreach (ProfileCondition c in i.Conditions)
{ {
@ -734,10 +739,12 @@ namespace MediaBrowser.Model.Dlna
int? numAudioStreams = mediaSource.GetStreamCount(MediaStreamType.Audio); int? numAudioStreams = mediaSource.GetStreamCount(MediaStreamType.Audio);
int? numVideoStreams = mediaSource.GetStreamCount(MediaStreamType.Video); int? numVideoStreams = mediaSource.GetStreamCount(MediaStreamType.Video);
var allAudioCodecs = allMediaStreams.Where(i => i.Type == MediaStreamType.Audio).Select(i => i.Codec).Where(i => !string.IsNullOrWhiteSpace(i)).ToList();
// 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, refFrames, numVideoStreams, numAudioStreams, videoCodecTag, isAvc)) if (!conditionProcessor.IsVideoConditionSatisfied(i, width, height, bitDepth, videoBitrate, videoProfile, videoLevel, videoFramerate, packetLength, timestamp, isAnamorphic, refFrames, numVideoStreams, numAudioStreams, videoCodecTag, isAvc, allAudioCodecs))
{ {
LogConditionFailure(profile, "VideoContainerProfile", i, mediaSource); LogConditionFailure(profile, "VideoContainerProfile", i, mediaSource);
@ -764,7 +771,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, refFrames, numVideoStreams, numAudioStreams, videoCodecTag, isAvc)) if (!conditionProcessor.IsVideoConditionSatisfied(applyCondition, width, height, bitDepth, videoBitrate, videoProfile, videoLevel, videoFramerate, packetLength, timestamp, isAnamorphic, refFrames, numVideoStreams, numAudioStreams, videoCodecTag, isAvc, allAudioCodecs))
{ {
LogConditionFailure(profile, "VideoCodecProfile", applyCondition, mediaSource); LogConditionFailure(profile, "VideoCodecProfile", applyCondition, mediaSource);
applyConditions = false; applyConditions = false;
@ -784,7 +791,7 @@ 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, refFrames, numVideoStreams, numAudioStreams, videoCodecTag, isAvc)) if (!conditionProcessor.IsVideoConditionSatisfied(i, width, height, bitDepth, videoBitrate, videoProfile, videoLevel, videoFramerate, packetLength, timestamp, isAnamorphic, refFrames, numVideoStreams, numAudioStreams, videoCodecTag, isAvc, allAudioCodecs))
{ {
LogConditionFailure(profile, "VideoCodecProfile", i, mediaSource); LogConditionFailure(profile, "VideoCodecProfile", i, mediaSource);

View File

@ -6,6 +6,7 @@ using MediaBrowser.Model.MediaInfo;
using MediaBrowser.Model.Session; using MediaBrowser.Model.Session;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
namespace MediaBrowser.Model.Dlna namespace MediaBrowser.Model.Dlna
{ {
@ -412,6 +413,17 @@ namespace MediaBrowser.Model.Dlna
} }
} }
public List<string> AllAudioCodecs
{
get
{
return MediaSource.MediaStreams.Where(i => i.Type == MediaStreamType.Audio)
.Select(i => i.Codec)
.Where(i => !string.IsNullOrWhiteSpace(i))
.ToList();
}
}
/// <summary> /// <summary>
/// Returns the video stream that will be used /// Returns the video stream that will be used
/// </summary> /// </summary>