public bool IsVideoConditionSatisfied(ProfileCondition condition, int?audioBitrate, int?audioChannels, int?width, int?height, int?bitDepth, int?videoBitrate, string videoProfile, double?videoLevel, double?videoFramerate, int?packetLength, TransportStreamTimestamp?timestamp) { switch (condition.Property) { case ProfileConditionValue.AudioProfile: // TODO: Implement return(true); case ProfileConditionValue.Has64BitOffsets: // TODO: Implement return(true); case ProfileConditionValue.VideoFramerate: return(IsConditionSatisfied(condition, videoFramerate)); case ProfileConditionValue.VideoLevel: return(IsConditionSatisfied(condition, videoLevel)); case ProfileConditionValue.VideoProfile: return(IsConditionSatisfied(condition, videoProfile)); case ProfileConditionValue.PacketLength: return(IsConditionSatisfied(condition, packetLength)); case ProfileConditionValue.AudioBitrate: return(IsConditionSatisfied(condition, audioBitrate)); case ProfileConditionValue.AudioChannels: return(IsConditionSatisfied(condition, audioChannels)); case ProfileConditionValue.VideoBitDepth: return(IsConditionSatisfied(condition, bitDepth)); case ProfileConditionValue.VideoBitrate: return(IsConditionSatisfied(condition, videoBitrate)); case ProfileConditionValue.Height: return(IsConditionSatisfied(condition, height)); case ProfileConditionValue.Width: return(IsConditionSatisfied(condition, width)); case ProfileConditionValue.VideoTimestamp: return(IsConditionSatisfied(condition, timestamp)); default: throw new ArgumentException("Unexpected condition on video file: " + condition.Property); } }
private bool IsConditionSatisfied(ProfileCondition condition, TransportStreamTimestamp?timestamp) { if (!timestamp.HasValue) { // If the value is unknown, it satisfies if not marked as required return(!condition.IsRequired); } TransportStreamTimestamp expected = (TransportStreamTimestamp)Enum.Parse(typeof(TransportStreamTimestamp), condition.Value, true); switch (condition.Condition) { case ProfileConditionType.Equals: return(timestamp == expected); case ProfileConditionType.NotEquals: return(timestamp != expected); default: throw new InvalidOperationException("Unexpected ProfileConditionType"); } }
private PlayMethod?GetVideoDirectPlayProfile(DeviceProfile profile, MediaSourceInfo mediaSource, MediaStream videoStream, MediaStream audioStream, bool isEligibleForDirectPlay, bool isEligibleForDirectStream) { if (videoStream == null) { _logger.Info("Profile: {0}, Cannot direct stream with no known video stream. Path: {1}", profile.Name ?? "Unknown Profile", mediaSource.Path ?? "Unknown path"); return(null); } // See if it can be direct played DirectPlayProfile directPlay = null; foreach (DirectPlayProfile i in profile.DirectPlayProfiles) { if (i.Type == DlnaProfileType.Video && IsVideoDirectPlaySupported(i, mediaSource, videoStream, audioStream)) { directPlay = i; break; } } if (directPlay == null) { _logger.Info("Profile: {0}, No direct play profiles found for Path: {1}", profile.Name ?? "Unknown Profile", mediaSource.Path ?? "Unknown path"); return(null); } string container = mediaSource.Container; List <ProfileCondition> conditions = new List <ProfileCondition>(); foreach (ContainerProfile i in profile.ContainerProfiles) { if (i.Type == DlnaProfileType.Video && ListHelper.ContainsIgnoreCase(i.GetContainers(), container)) { foreach (ProfileCondition c in i.Conditions) { conditions.Add(c); } } } ConditionProcessor conditionProcessor = new ConditionProcessor(); 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; string videoCodecTag = videoStream == null ? null : videoStream.CodecTag; int? audioBitrate = audioStream == null ? null : audioStream.BitRate; int? audioChannels = audioStream == null ? null : audioStream.Channels; string audioProfile = audioStream == null ? null : audioStream.Profile; TransportStreamTimestamp?timestamp = videoStream == null ? TransportStreamTimestamp.None : mediaSource.Timestamp; int?packetLength = videoStream == null ? null : videoStream.PacketLength; int?refFrames = videoStream == null ? null : videoStream.RefFrames; int?numAudioStreams = mediaSource.GetStreamCount(MediaStreamType.Audio); int?numVideoStreams = mediaSource.GetStreamCount(MediaStreamType.Video); // Check container conditions foreach (ProfileCondition i in conditions) { if (!conditionProcessor.IsVideoConditionSatisfied(i, width, height, bitDepth, videoBitrate, videoProfile, videoLevel, videoFramerate, packetLength, timestamp, isAnamorphic, refFrames, numVideoStreams, numAudioStreams, videoCodecTag)) { LogConditionFailure(profile, "VideoContainerProfile", i, mediaSource); return(null); } } string videoCodec = videoStream == null ? null : videoStream.Codec; if (string.IsNullOrEmpty(videoCodec)) { _logger.Info("Profile: {0}, DirectPlay=false. Reason=Unknown video codec. Path: {1}", profile.Name ?? "Unknown Profile", mediaSource.Path ?? "Unknown path"); return(null); } conditions = new List <ProfileCondition>(); foreach (CodecProfile i in profile.CodecProfiles) { if (i.Type == CodecType.Video && i.ContainsCodec(videoCodec, container)) { foreach (ProfileCondition c in i.Conditions) { conditions.Add(c); } } } foreach (ProfileCondition i in conditions) { if (!conditionProcessor.IsVideoConditionSatisfied(i, width, height, bitDepth, videoBitrate, videoProfile, videoLevel, videoFramerate, packetLength, timestamp, isAnamorphic, refFrames, numVideoStreams, numAudioStreams, videoCodecTag)) { LogConditionFailure(profile, "VideoCodecProfile", i, mediaSource); return(null); } } if (audioStream != null) { string audioCodec = audioStream.Codec; if (string.IsNullOrEmpty(audioCodec)) { _logger.Info("Profile: {0}, DirectPlay=false. Reason=Unknown audio codec. Path: {1}", profile.Name ?? "Unknown Profile", mediaSource.Path ?? "Unknown path"); return(null); } conditions = new List <ProfileCondition>(); foreach (CodecProfile i in profile.CodecProfiles) { if (i.Type == CodecType.VideoAudio && i.ContainsCodec(audioCodec, container)) { foreach (ProfileCondition c in i.Conditions) { conditions.Add(c); } } } foreach (ProfileCondition i in conditions) { bool?isSecondaryAudio = audioStream == null ? null : mediaSource.IsSecondaryAudio(audioStream); if (!conditionProcessor.IsVideoAudioConditionSatisfied(i, audioChannels, audioBitrate, audioProfile, isSecondaryAudio)) { LogConditionFailure(profile, "VideoAudioCodecProfile", i, mediaSource); return(null); } } } if (isEligibleForDirectPlay && mediaSource.SupportsDirectPlay) { if (mediaSource.Protocol == MediaProtocol.Http) { if (_localPlayer.CanAccessUrl(mediaSource.Path, mediaSource.RequiredHttpHeaders.Count > 0)) { return(PlayMethod.DirectPlay); } } else if (mediaSource.Protocol == MediaProtocol.File) { if (_localPlayer.CanAccessFile(mediaSource.Path)) { return(PlayMethod.DirectPlay); } } } if (isEligibleForDirectStream && mediaSource.SupportsDirectStream) { return(PlayMethod.DirectStream); } return(null); }
private PlayMethod?GetVideoDirectPlayProfile(VideoOptions options, DeviceProfile profile, MediaSourceInfo mediaSource, MediaStream videoStream, MediaStream audioStream) { // See if it can be direct played DirectPlayProfile directPlay = null; foreach (DirectPlayProfile i in profile.DirectPlayProfiles) { if (i.Type == DlnaProfileType.Video && IsVideoDirectPlaySupported(i, mediaSource, videoStream, audioStream)) { directPlay = i; break; } } if (directPlay == null) { return(null); } string container = mediaSource.Container; List <ProfileCondition> conditions = new List <ProfileCondition>(); foreach (ContainerProfile i in profile.ContainerProfiles) { if (i.Type == DlnaProfileType.Video && ListHelper.ContainsIgnoreCase(i.GetContainers(), container)) { foreach (ProfileCondition c in i.Conditions) { conditions.Add(c); } } } ConditionProcessor conditionProcessor = new ConditionProcessor(); 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? isCabac = videoStream == null ? null : videoStream.IsCabac; int? audioBitrate = audioStream == null ? null : audioStream.BitRate; int? audioChannels = audioStream == null ? null : audioStream.Channels; string audioProfile = audioStream == null ? null : audioStream.Profile; TransportStreamTimestamp?timestamp = videoStream == null ? TransportStreamTimestamp.None : mediaSource.Timestamp; int?packetLength = videoStream == null ? null : videoStream.PacketLength; int?refFrames = videoStream == null ? null : videoStream.RefFrames; // Check container conditions foreach (ProfileCondition i in conditions) { if (!conditionProcessor.IsVideoConditionSatisfied(i, audioBitrate, audioChannels, width, height, bitDepth, videoBitrate, videoProfile, videoLevel, videoFramerate, packetLength, timestamp, isAnamorphic, isCabac, refFrames)) { return(null); } } string videoCodec = videoStream == null ? null : videoStream.Codec; if (string.IsNullOrEmpty(videoCodec)) { return(null); } conditions = new List <ProfileCondition>(); foreach (CodecProfile i in profile.CodecProfiles) { if (i.Type == CodecType.Video && i.ContainsCodec(videoCodec)) { foreach (ProfileCondition c in i.Conditions) { conditions.Add(c); } } } foreach (ProfileCondition i in conditions) { if (!conditionProcessor.IsVideoConditionSatisfied(i, audioBitrate, audioChannels, width, height, bitDepth, videoBitrate, videoProfile, videoLevel, videoFramerate, packetLength, timestamp, isAnamorphic, isCabac, refFrames)) { return(null); } } if (audioStream != null) { string audioCodec = audioStream.Codec; if (string.IsNullOrEmpty(audioCodec)) { return(null); } conditions = new List <ProfileCondition>(); foreach (CodecProfile i in profile.CodecProfiles) { if (i.Type == CodecType.VideoAudio && i.ContainsCodec(audioCodec)) { foreach (ProfileCondition c in i.Conditions) { conditions.Add(c); } } } foreach (ProfileCondition i in conditions) { if (!conditionProcessor.IsVideoAudioConditionSatisfied(i, audioChannels, audioBitrate, audioProfile)) { return(null); } } } if (mediaSource.Protocol == MediaProtocol.Http) { if (_localPlayer.CanAccessUrl(mediaSource.Path, mediaSource.RequiredHttpHeaders.Count > 0)) { return(PlayMethod.DirectPlay); } } else if (mediaSource.Protocol == MediaProtocol.File) { if (_localPlayer.CanAccessFile(mediaSource.Path)) { return(PlayMethod.DirectPlay); } } if (!mediaSource.SupportsDirectStream) { return(null); } return(PlayMethod.DirectStream); }
public bool IsVideoConditionSatisfied(ProfileCondition condition, int?width, int?height, int?bitDepth, int?videoBitrate, string videoProfile, double?videoLevel, float?videoFramerate, int?packetLength, TransportStreamTimestamp?timestamp, bool?isAnamorphic, int?refFrames, int?numVideoStreams, int?numAudioStreams, string videoCodecTag) { switch (condition.Property) { case ProfileConditionValue.IsAnamorphic: return(IsConditionSatisfied(condition, isAnamorphic)); case ProfileConditionValue.VideoFramerate: return(IsConditionSatisfied(condition, videoFramerate)); case ProfileConditionValue.VideoLevel: return(IsConditionSatisfied(condition, videoLevel)); case ProfileConditionValue.VideoProfile: return(IsConditionSatisfied(condition, videoProfile)); case ProfileConditionValue.VideoCodecTag: return(IsConditionSatisfied(condition, videoCodecTag)); case ProfileConditionValue.PacketLength: return(IsConditionSatisfied(condition, packetLength)); case ProfileConditionValue.VideoBitDepth: return(IsConditionSatisfied(condition, bitDepth)); case ProfileConditionValue.VideoBitrate: return(IsConditionSatisfied(condition, videoBitrate)); case ProfileConditionValue.Height: return(IsConditionSatisfied(condition, height)); case ProfileConditionValue.Width: return(IsConditionSatisfied(condition, width)); case ProfileConditionValue.RefFrames: return(IsConditionSatisfied(condition, refFrames)); case ProfileConditionValue.NumAudioStreams: return(IsConditionSatisfied(condition, numAudioStreams)); case ProfileConditionValue.NumVideoStreams: return(IsConditionSatisfied(condition, numVideoStreams)); case ProfileConditionValue.VideoTimestamp: return(IsConditionSatisfied(condition, timestamp)); default: return(true); } }
private DirectPlayProfile GetVideoDirectPlayProfile(DeviceProfile profile, MediaSourceInfo mediaSource, MediaStream videoStream, MediaStream audioStream) { // See if it can be direct played DirectPlayProfile directPlay = null; foreach (DirectPlayProfile i in profile.DirectPlayProfiles) { if (i.Type == DlnaProfileType.Video && IsVideoDirectPlaySupported(i, mediaSource, videoStream, audioStream)) { directPlay = i; break; } } if (directPlay == null) { return(null); } string container = mediaSource.Container; List <ProfileCondition> conditions = new List <ProfileCondition>(); foreach (ContainerProfile i in profile.ContainerProfiles) { if (i.Type == DlnaProfileType.Video && ListHelper.ContainsIgnoreCase(i.GetContainers(), container)) { conditions.AddRange(i.Conditions); } } ConditionProcessor conditionProcessor = new ConditionProcessor(); 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; int? audioBitrate = audioStream == null ? null : audioStream.BitRate; int? audioChannels = audioStream == null ? null : audioStream.Channels; string audioProfile = audioStream == null ? null : audioStream.Profile; TransportStreamTimestamp?timestamp = videoStream == null ? TransportStreamTimestamp.None : mediaSource.Timestamp; int?packetLength = videoStream == null ? null : videoStream.PacketLength; // Check container conditions foreach (ProfileCondition i in conditions) { if (!conditionProcessor.IsVideoConditionSatisfied(i, audioBitrate, audioChannels, width, height, bitDepth, videoBitrate, videoProfile, videoLevel, videoFramerate, packetLength, timestamp)) { return(null); } } string videoCodec = videoStream == null ? null : videoStream.Codec; if (string.IsNullOrEmpty(videoCodec)) { return(null); } conditions = new List <ProfileCondition>(); foreach (CodecProfile i in profile.CodecProfiles) { if (i.Type == CodecType.Video && i.ContainsCodec(videoCodec)) { conditions.AddRange(i.Conditions); } } foreach (ProfileCondition i in conditions) { if (!conditionProcessor.IsVideoConditionSatisfied(i, audioBitrate, audioChannels, width, height, bitDepth, videoBitrate, videoProfile, videoLevel, videoFramerate, packetLength, timestamp)) { return(null); } } if (audioStream != null) { string audioCodec = audioStream.Codec; if (string.IsNullOrEmpty(audioCodec)) { return(null); } conditions = new List <ProfileCondition>(); foreach (CodecProfile i in profile.CodecProfiles) { if (i.Type == CodecType.VideoAudio && i.ContainsCodec(audioCodec)) { conditions.AddRange(i.Conditions); } } foreach (ProfileCondition i in conditions) { if (!conditionProcessor.IsVideoAudioConditionSatisfied(i, audioChannels, audioBitrate, audioProfile)) { return(null); } } } return(directPlay); }
public bool IsVideoConditionSatisfied(ProfileCondition condition, int?width, int?height, int?bitDepth, int?videoBitrate, string videoProfile, double?videoLevel, float?videoFramerate, int?packetLength, TransportStreamTimestamp?timestamp, bool?isAnamorphic, bool?isCabac, int?refFrames, int?numVideoStreams, int?numAudioStreams) { switch (condition.Property) { case ProfileConditionValue.AudioProfile: // TODO: Implement return(true); case ProfileConditionValue.Has64BitOffsets: // TODO: Implement return(true); case ProfileConditionValue.IsAnamorphic: return(IsConditionSatisfied(condition, isAnamorphic)); case ProfileConditionValue.IsCabac: return(IsConditionSatisfied(condition, isCabac)); case ProfileConditionValue.VideoFramerate: return(IsConditionSatisfied(condition, videoFramerate)); case ProfileConditionValue.VideoLevel: return(IsConditionSatisfied(condition, videoLevel)); case ProfileConditionValue.VideoProfile: return(IsConditionSatisfied(condition, videoProfile)); case ProfileConditionValue.PacketLength: return(IsConditionSatisfied(condition, packetLength)); case ProfileConditionValue.VideoBitDepth: return(IsConditionSatisfied(condition, bitDepth)); case ProfileConditionValue.VideoBitrate: return(IsConditionSatisfied(condition, videoBitrate)); case ProfileConditionValue.Height: return(IsConditionSatisfied(condition, height)); case ProfileConditionValue.Width: return(IsConditionSatisfied(condition, width)); case ProfileConditionValue.RefFrames: return(IsConditionSatisfied(condition, refFrames)); case ProfileConditionValue.NumAudioStreams: return(IsConditionSatisfied(condition, numAudioStreams)); case ProfileConditionValue.NumVideoStreams: return(IsConditionSatisfied(condition, numVideoStreams)); case ProfileConditionValue.VideoTimestamp: return(IsConditionSatisfied(condition, timestamp)); default: throw new ArgumentException("Unexpected condition on video file: " + condition.Property); } }