diff options
Diffstat (limited to 'MediaBrowser.Model/Dlna/ContentFeatureBuilder.cs')
| -rw-r--r-- | MediaBrowser.Model/Dlna/ContentFeatureBuilder.cs | 236 |
1 files changed, 236 insertions, 0 deletions
diff --git a/MediaBrowser.Model/Dlna/ContentFeatureBuilder.cs b/MediaBrowser.Model/Dlna/ContentFeatureBuilder.cs new file mode 100644 index 000000000..966c4a8ce --- /dev/null +++ b/MediaBrowser.Model/Dlna/ContentFeatureBuilder.cs @@ -0,0 +1,236 @@ +using MediaBrowser.Model.MediaInfo; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace MediaBrowser.Model.Dlna +{ + public class ContentFeatureBuilder + { + private readonly DeviceProfile _profile; + + public ContentFeatureBuilder(DeviceProfile profile) + { + _profile = profile; + } + + public string BuildImageHeader(string container, + int? width, + int? height, + bool isDirectStream, + string orgPn = null) + { + string orgOp = ";DLNA.ORG_OP=" + DlnaMaps.GetImageOrgOpValue(); + + // 0 = native, 1 = transcoded + var orgCi = isDirectStream ? ";DLNA.ORG_CI=0" : ";DLNA.ORG_CI=1"; + + DlnaFlags flagValue = DlnaFlags.BackgroundTransferMode | + DlnaFlags.InteractiveTransferMode | + DlnaFlags.DlnaV15; + + string dlnaflags = string.Format(";DLNA.ORG_FLAGS={0}", + DlnaMaps.FlagsToString(flagValue)); + + ResponseProfile mediaProfile = _profile.GetImageMediaProfile(container, + width, + height); + + if (string.IsNullOrEmpty(orgPn)) + { + orgPn = mediaProfile == null ? null : mediaProfile.OrgPn; + } + + if (string.IsNullOrEmpty(orgPn)) + { + orgPn = GetImageOrgPnValue(container, width, height); + } + + string contentFeatures = string.IsNullOrEmpty(orgPn) ? string.Empty : "DLNA.ORG_PN=" + orgPn; + + return (contentFeatures + orgOp + orgCi + dlnaflags).Trim(';'); + } + + public string BuildAudioHeader(string container, + string audioCodec, + int? audioBitrate, + int? audioSampleRate, + int? audioChannels, + int? audioBitDepth, + bool isDirectStream, + long? runtimeTicks, + TranscodeSeekInfo transcodeSeekInfo) + { + // 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 > 0, isDirectStream, transcodeSeekInfo); + + // 0 = native, 1 = transcoded + string orgCi = isDirectStream ? ";DLNA.ORG_CI=0" : ";DLNA.ORG_CI=1"; + + DlnaFlags flagValue = DlnaFlags.StreamingTransferMode | + DlnaFlags.BackgroundTransferMode | + DlnaFlags.InteractiveTransferMode | + DlnaFlags.DlnaV15; + + //if (isDirectStream) + //{ + // flagValue = flagValue | DlnaFlags.ByteBasedSeek; + //} + //else if (runtimeTicks.HasValue) + //{ + // flagValue = flagValue | DlnaFlags.TimeBasedSeek; + //} + + string dlnaflags = string.Format(";DLNA.ORG_FLAGS={0}", + DlnaMaps.FlagsToString(flagValue)); + + ResponseProfile mediaProfile = _profile.GetAudioMediaProfile(container, + audioCodec, + audioChannels, + audioBitrate, + audioSampleRate, + audioBitDepth); + + string orgPn = mediaProfile == null ? null : mediaProfile.OrgPn; + + if (string.IsNullOrEmpty(orgPn)) + { + orgPn = GetAudioOrgPnValue(container, audioBitrate, audioSampleRate, audioChannels); + } + + string contentFeatures = string.IsNullOrEmpty(orgPn) ? string.Empty : "DLNA.ORG_PN=" + orgPn; + + return (contentFeatures + orgOp + orgCi + dlnaflags).Trim(';'); + } + + public List<string> BuildVideoHeader(string container, + string videoCodec, + string audioCodec, + int? width, + int? height, + int? bitDepth, + int? videoBitrate, + TransportStreamTimestamp timestamp, + bool isDirectStream, + long? runtimeTicks, + string videoProfile, + double? videoLevel, + float? videoFramerate, + int? packetLength, + TranscodeSeekInfo transcodeSeekInfo, + bool? isAnamorphic, + bool? isInterlaced, + int? refFrames, + int? numVideoStreams, + int? numAudioStreams, + string videoCodecTag, + bool? isAvc) + { + // 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 > 0, isDirectStream, transcodeSeekInfo); + + // 0 = native, 1 = transcoded + string orgCi = isDirectStream ? ";DLNA.ORG_CI=0" : ";DLNA.ORG_CI=1"; + + DlnaFlags flagValue = DlnaFlags.StreamingTransferMode | + DlnaFlags.BackgroundTransferMode | + DlnaFlags.InteractiveTransferMode | + DlnaFlags.DlnaV15; + + //if (isDirectStream) + //{ + // flagValue = flagValue | DlnaFlags.ByteBasedSeek; + //} + //else if (runtimeTicks.HasValue) + //{ + // flagValue = flagValue | DlnaFlags.TimeBasedSeek; + //} + + string dlnaflags = string.Format(";DLNA.ORG_FLAGS={0}", + DlnaMaps.FlagsToString(flagValue)); + + ResponseProfile mediaProfile = _profile.GetVideoMediaProfile(container, + audioCodec, + videoCodec, + width, + height, + bitDepth, + videoBitrate, + videoProfile, + videoLevel, + videoFramerate, + packetLength, + timestamp, + isAnamorphic, + isInterlaced, + refFrames, + numVideoStreams, + numAudioStreams, + videoCodecTag, + isAvc); + + List<string> orgPnValues = new List<string>(); + + if (mediaProfile != null && !string.IsNullOrEmpty(mediaProfile.OrgPn)) + { + orgPnValues.AddRange(mediaProfile.OrgPn.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)); + } + else + { + foreach (string s in GetVideoOrgPnValue(container, videoCodec, audioCodec, width, height, timestamp)) + { + orgPnValues.Add(s); + break; + } + } + + List<string> contentFeatureList = new List<string>(); + + foreach (string orgPn in orgPnValues) + { + string contentFeatures = string.IsNullOrEmpty(orgPn) ? string.Empty : "DLNA.ORG_PN=" + orgPn; + + var value = (contentFeatures + orgOp + orgCi + dlnaflags).Trim(';'); + + contentFeatureList.Add(value); + } + + if (orgPnValues.Count == 0) + { + string contentFeatures = string.Empty; + + var value = (contentFeatures + orgOp + orgCi + dlnaflags).Trim(';'); + + contentFeatureList.Add(value); + } + + return contentFeatureList; + } + + private string GetImageOrgPnValue(string container, int? width, int? height) + { + MediaFormatProfile? format = new MediaFormatProfileResolver() + .ResolveImageFormat(container, + width, + height); + + return format.HasValue ? format.Value.ToString() : null; + } + + private string GetAudioOrgPnValue(string container, int? audioBitrate, int? audioSampleRate, int? audioChannels) + { + MediaFormatProfile? format = new MediaFormatProfileResolver() + .ResolveAudioFormat(container, + audioBitrate, + audioSampleRate, + audioChannels); + + return format.HasValue ? format.Value.ToString() : null; + } + + private string[] GetVideoOrgPnValue(string container, string videoCodec, string audioCodec, int? width, int? height, TransportStreamTimestamp timestamp) + { + return new MediaFormatProfileResolver().ResolveVideoFormat(container, videoCodec, audioCodec, width, height, timestamp); + } + } +} |
