aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Model
diff options
context:
space:
mode:
Diffstat (limited to 'MediaBrowser.Model')
-rw-r--r--MediaBrowser.Model/Dlna/ContentFeatureBuilder.cs130
-rw-r--r--MediaBrowser.Model/Dlna/DeviceProfile.cs4
-rw-r--r--MediaBrowser.Model/Dlna/MediaFormatProfileResolver.cs4
-rw-r--r--MediaBrowser.Model/Dlna/StreamInfo.cs67
-rw-r--r--MediaBrowser.Model/MediaBrowser.Model.csproj1
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" />