diff options
Diffstat (limited to 'MediaBrowser.Model')
| -rw-r--r-- | MediaBrowser.Model/Dlna/ContentFeatureBuilder.cs | 130 | ||||
| -rw-r--r-- | MediaBrowser.Model/Dlna/DeviceProfile.cs | 4 | ||||
| -rw-r--r-- | MediaBrowser.Model/Dlna/MediaFormatProfileResolver.cs | 4 | ||||
| -rw-r--r-- | MediaBrowser.Model/Dlna/StreamInfo.cs | 67 | ||||
| -rw-r--r-- | MediaBrowser.Model/MediaBrowser.Model.csproj | 1 |
5 files changed, 201 insertions, 5 deletions
diff --git a/MediaBrowser.Model/Dlna/ContentFeatureBuilder.cs b/MediaBrowser.Model/Dlna/ContentFeatureBuilder.cs new file mode 100644 index 000000000..bd98704a9 --- /dev/null +++ b/MediaBrowser.Model/Dlna/ContentFeatureBuilder.cs @@ -0,0 +1,130 @@ +using System; + +namespace MediaBrowser.Model.Dlna +{ + public class ContentFeatureBuilder + { + private readonly DeviceProfile _profile; + + public ContentFeatureBuilder(DeviceProfile profile) + { + _profile = profile; + } + + public string BuildAudioHeader(string container, + string audioCodec, + int? audioBitrate, + int? audioSampleRate, + int? audioChannels, + 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 + var orgOp = ";DLNA.ORG_OP=" + DlnaMaps.GetOrgOpValue(runtimeTicks.HasValue, isDirectStream, transcodeSeekInfo); + + // 0 = native, 1 = transcoded + var orgCi = isDirectStream ? ";DLNA.ORG_CI=0" : ";DLNA.ORG_CI=1"; + + var flagValue = DlnaFlags.StreamingTransferMode | + DlnaFlags.BackgroundTransferMode | + DlnaFlags.DlnaV15; + + if (isDirectStream) + { + //flagValue = flagValue | DlnaFlags.DLNA_ORG_FLAG_BYTE_BASED_SEEK; + } + else if (runtimeTicks.HasValue) + { + //flagValue = flagValue | DlnaFlags.DLNA_ORG_FLAG_TIME_BASED_SEEK; + } + + var dlnaflags = string.Format(";DLNA.ORG_FLAGS={0}000000000000000000000000", + Enum.Format(typeof(DlnaFlags), flagValue, "x")); + + var mediaProfile = _profile.GetAudioMediaProfile(container, audioCodec); + + var orgPn = mediaProfile == null ? null : mediaProfile.OrgPn; + + if (string.IsNullOrEmpty(orgPn)) + { + orgPn = GetAudioOrgPnValue(container, audioBitrate, audioSampleRate, audioChannels); + } + + var contentFeatures = string.IsNullOrEmpty(orgPn) ? string.Empty : "DLNA.ORG_PN=" + orgPn; + + return (contentFeatures + orgOp + orgCi + dlnaflags).Trim(';'); + } + + public string BuildVideoHeader(string container, + string videoCodec, + string audioCodec, + int? width, + int? height, + int? bitrate, + TransportStreamTimestamp timestamp, + 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 + var orgOp = ";DLNA.ORG_OP=" + DlnaMaps.GetOrgOpValue(runtimeTicks.HasValue, isDirectStream, transcodeSeekInfo); + + // 0 = native, 1 = transcoded + var orgCi = isDirectStream ? ";DLNA.ORG_CI=0" : ";DLNA.ORG_CI=1"; + + var flagValue = DlnaFlags.StreamingTransferMode | + DlnaFlags.BackgroundTransferMode | + DlnaFlags.DlnaV15; + + if (isDirectStream) + { + //flagValue = flagValue | DlnaFlags.DLNA_ORG_FLAG_BYTE_BASED_SEEK; + } + else if (runtimeTicks.HasValue) + { + //flagValue = flagValue | DlnaFlags.DLNA_ORG_FLAG_TIME_BASED_SEEK; + } + + var dlnaflags = string.Format(";DLNA.ORG_FLAGS={0}000000000000000000000000", + Enum.Format(typeof(DlnaFlags), flagValue, "x")); + + var mediaProfile = _profile.GetVideoMediaProfile(container, audioCodec, videoCodec); + var orgPn = mediaProfile == null ? null : mediaProfile.OrgPn; + + if (string.IsNullOrEmpty(orgPn)) + { + orgPn = GetVideoOrgPnValue(container, videoCodec, audioCodec, width, height, bitrate, timestamp); + } + + var contentFeatures = string.IsNullOrEmpty(orgPn) ? string.Empty : "DLNA.ORG_PN=" + orgPn; + + return (contentFeatures + orgOp + orgCi + dlnaflags).Trim(';'); + } + + private string GetAudioOrgPnValue(string container, int? audioBitrate, int? audioSampleRate, int? audioChannels) + { + var 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, int? bitrate, TransportStreamTimestamp timestamp) + { + var videoFormat = new MediaFormatProfileResolver() + .ResolveVideoFormat(container, + videoCodec, + audioCodec, + width, + height, + bitrate, + timestamp); + + return videoFormat.HasValue ? videoFormat.Value.ToString() : null; + } + } +} diff --git a/MediaBrowser.Model/Dlna/DeviceProfile.cs b/MediaBrowser.Model/Dlna/DeviceProfile.cs index df717fd10..106ba75b0 100644 --- a/MediaBrowser.Model/Dlna/DeviceProfile.cs +++ b/MediaBrowser.Model/Dlna/DeviceProfile.cs @@ -159,7 +159,7 @@ namespace MediaBrowser.Model.Dlna }); } - public ResponseProfile GetAudioMediaProfile(string container, string audioCodec, MediaStream audioStream) + public ResponseProfile GetAudioMediaProfile(string container, string audioCodec) { container = (container ?? string.Empty).TrimStart('.'); @@ -186,7 +186,7 @@ namespace MediaBrowser.Model.Dlna }); } - public ResponseProfile GetVideoMediaProfile(string container, string audioCodec, string videoCodec, MediaStream audioStream, MediaStream videoStream) + public ResponseProfile GetVideoMediaProfile(string container, string audioCodec, string videoCodec) { container = (container ?? string.Empty).TrimStart('.'); diff --git a/MediaBrowser.Model/Dlna/MediaFormatProfileResolver.cs b/MediaBrowser.Model/Dlna/MediaFormatProfileResolver.cs index 7034aee72..02400a7ff 100644 --- a/MediaBrowser.Model/Dlna/MediaFormatProfileResolver.cs +++ b/MediaBrowser.Model/Dlna/MediaFormatProfileResolver.cs @@ -33,7 +33,7 @@ namespace MediaBrowser.Model.Dlna string.Equals(container, "m2ts", StringComparison.OrdinalIgnoreCase)) { - var list = ResolveVideoMPEG2TSFormat(videoCodec, audioCodec, width, height, bitrate, timestampType) + var list = ResolveVideoMPEG2TSFormat(videoCodec, audioCodec, width, height, timestampType) .ToList(); return list.Count > 0 ? list[0] : (MediaFormatProfile?)null; @@ -54,7 +54,7 @@ namespace MediaBrowser.Model.Dlna return null; } - private IEnumerable<MediaFormatProfile> ResolveVideoMPEG2TSFormat(string videoCodec, string audioCodec, int? width, int? height, int? bitrate, TransportStreamTimestamp timestampType) + private IEnumerable<MediaFormatProfile> ResolveVideoMPEG2TSFormat(string videoCodec, string audioCodec, int? width, int? height, TransportStreamTimestamp timestampType) { var suffix = ""; diff --git a/MediaBrowser.Model/Dlna/StreamInfo.cs b/MediaBrowser.Model/Dlna/StreamInfo.cs index a0cfe037b..c5589322d 100644 --- a/MediaBrowser.Model/Dlna/StreamInfo.cs +++ b/MediaBrowser.Model/Dlna/StreamInfo.cs @@ -1,4 +1,5 @@ -using MediaBrowser.Model.Dto; +using MediaBrowser.Model.Drawing; +using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; using System; using System.Collections.Generic; @@ -56,6 +57,8 @@ namespace MediaBrowser.Model.Dlna public MediaSourceInfo MediaSource { get; set; } + public TransportStreamTimestamp TargetTimestamp { get; set; } + public string MediaSourceId { get @@ -252,6 +255,68 @@ namespace MediaBrowser.Model.Dlna : stream == null ? null : stream.Channels; } } + + public int? TotalOutputBitrate + { + get + { + return (TargetAudioBitrate ?? 0) + (VideoBitrate ?? 0); + } + } + + public int? TargetWidth + { + get + { + var videoStream = TargetVideoStream; + + if (videoStream != null && videoStream.Width.HasValue && videoStream.Height.HasValue) + { + var size = new ImageSize + { + Width = videoStream.Width.Value, + Height = videoStream.Height.Value + }; + + var newSize = DrawingUtils.Resize(size, + null, + null, + MaxWidth, + MaxHeight); + + return Convert.ToInt32(newSize.Width); + } + + return MaxWidth; + } + } + + public int? TargetHeight + { + get + { + var videoStream = TargetVideoStream; + + if (videoStream != null && videoStream.Width.HasValue && videoStream.Height.HasValue) + { + var size = new ImageSize + { + Width = videoStream.Width.Value, + Height = videoStream.Height.Value + }; + + var newSize = DrawingUtils.Resize(size, + null, + null, + MaxWidth, + MaxHeight); + + return Convert.ToInt32(newSize.Height); + } + + return MaxHeight; + } + } } /// <summary> diff --git a/MediaBrowser.Model/MediaBrowser.Model.csproj b/MediaBrowser.Model/MediaBrowser.Model.csproj index c18d7e8dc..4d0214eb8 100644 --- a/MediaBrowser.Model/MediaBrowser.Model.csproj +++ b/MediaBrowser.Model/MediaBrowser.Model.csproj @@ -68,6 +68,7 @@ <Compile Include="Configuration\ServerConfiguration.cs" /> <Compile Include="Dlna\CodecProfile.cs" /> <Compile Include="Dlna\ContainerProfile.cs" /> + <Compile Include="Dlna\ContentFeatureBuilder.cs" /> <Compile Include="Dlna\DeviceIdentification.cs" /> <Compile Include="Dlna\DeviceProfile.cs" /> <Compile Include="Dlna\DeviceProfileInfo.cs" /> |
