support max audio bit depth

This commit is contained in:
Luke Pulverenti 2017-06-26 11:10:52 -04:00
parent c2c1451beb
commit a759b09577
14 changed files with 90 additions and 18 deletions

View File

@ -472,6 +472,7 @@ namespace Emby.Dlna.Didl
var targetAudioBitrate = streamInfo.TargetAudioBitrate; var targetAudioBitrate = streamInfo.TargetAudioBitrate;
var targetSampleRate = streamInfo.TargetAudioSampleRate; var targetSampleRate = streamInfo.TargetAudioSampleRate;
var targetChannels = streamInfo.TargetAudioChannels; var targetChannels = streamInfo.TargetAudioChannels;
var targetAudioBitDepth = streamInfo.TargetAudioBitDepth;
if (targetChannels.HasValue) if (targetChannels.HasValue)
{ {
@ -492,7 +493,8 @@ namespace Emby.Dlna.Didl
streamInfo.TargetAudioCodec, streamInfo.TargetAudioCodec,
targetChannels, targetChannels,
targetAudioBitrate, targetAudioBitrate,
targetSampleRate); targetSampleRate,
targetAudioBitDepth);
var filename = url.Substring(0, url.IndexOf('?')); var filename = url.Substring(0, url.IndexOf('?'));
@ -505,6 +507,7 @@ namespace Emby.Dlna.Didl
targetAudioBitrate, targetAudioBitrate,
targetSampleRate, targetSampleRate,
targetChannels, targetChannels,
targetAudioBitDepth,
streamInfo.IsDirectStream, streamInfo.IsDirectStream,
streamInfo.RunTimeTicks, streamInfo.RunTimeTicks,
streamInfo.TranscodeSeekInfo); streamInfo.TranscodeSeekInfo);

View File

@ -532,6 +532,7 @@ namespace Emby.Dlna.PlayTo
streamInfo.TargetAudioBitrate, streamInfo.TargetAudioBitrate,
streamInfo.TargetAudioSampleRate, streamInfo.TargetAudioSampleRate,
streamInfo.TargetAudioChannels, streamInfo.TargetAudioChannels,
streamInfo.TargetAudioBitDepth,
streamInfo.IsDirectStream, streamInfo.IsDirectStream,
streamInfo.RunTimeTicks, streamInfo.RunTimeTicks,
streamInfo.TranscodeSeekInfo); streamInfo.TranscodeSeekInfo);

View File

@ -869,7 +869,7 @@ namespace MediaBrowser.Api.Playback
var videoCodec = state.ActualOutputVideoCodec; var videoCodec = state.ActualOutputVideoCodec;
var mediaProfile = state.VideoRequest == null ? var mediaProfile = state.VideoRequest == null ?
profile.GetAudioMediaProfile(state.OutputContainer, audioCodec, state.OutputAudioChannels, state.OutputAudioBitrate, state.OutputAudioSampleRate) : profile.GetAudioMediaProfile(state.OutputContainer, audioCodec, state.OutputAudioChannels, state.OutputAudioBitrate, state.OutputAudioSampleRate, state.OutputAudioBitDepth) :
profile.GetVideoMediaProfile(state.OutputContainer, profile.GetVideoMediaProfile(state.OutputContainer,
audioCodec, audioCodec,
videoCodec, videoCodec,
@ -966,6 +966,7 @@ namespace MediaBrowser.Api.Playback
state.OutputAudioBitrate, state.OutputAudioBitrate,
state.OutputAudioSampleRate, state.OutputAudioSampleRate,
state.OutputAudioChannels, state.OutputAudioChannels,
state.OutputAudioBitDepth,
isStaticallyStreamed, isStaticallyStreamed,
state.RunTimeTicks, state.RunTimeTicks,
state.TranscodeSeekInfo state.TranscodeSeekInfo

View File

@ -52,6 +52,7 @@ namespace MediaBrowser.Api.Playback
public string TranscodingContainer { get; set; } public string TranscodingContainer { get; set; }
public string TranscodingProtocol { get; set; } public string TranscodingProtocol { get; set; }
public int? MaxAudioSampleRate { get; set; } public int? MaxAudioSampleRate { get; set; }
public int? MaxAudioBitDepth { get; set; }
public bool EnableRedirection { get; set; } public bool EnableRedirection { get; set; }
public bool EnableRemoteMedia { get; set; } public bool EnableRemoteMedia { get; set; }
@ -164,6 +165,18 @@ namespace MediaBrowser.Api.Playback
}); });
} }
if (request.MaxAudioBitDepth.HasValue)
{
// codec profile
conditions.Add(new ProfileCondition
{
Condition = ProfileConditionType.LessThanEqual,
IsRequired = false,
Property = ProfileConditionValue.AudioBitDepth,
Value = request.MaxAudioBitDepth.Value.ToString(CultureInfo.InvariantCulture)
});
}
if (request.MaxAudioChannels.HasValue) if (request.MaxAudioChannels.HasValue)
{ {
// codec profile // codec profile
@ -266,6 +279,7 @@ namespace MediaBrowser.Api.Playback
Static = isStatic, Static = isStatic,
SegmentContainer = request.TranscodingContainer, SegmentContainer = request.TranscodingContainer,
AudioSampleRate = request.MaxAudioSampleRate, AudioSampleRate = request.MaxAudioSampleRate,
MaxAudioBitDepth = request.MaxAudioBitDepth,
BreakOnNonKeyFrames = transcodingProfile.BreakOnNonKeyFrames, BreakOnNonKeyFrames = transcodingProfile.BreakOnNonKeyFrames,
TranscodeReasons = mediaSource.TranscodeReasons == null ? null : string.Join(",", mediaSource.TranscodeReasons.Select(i => i.ToString()).ToArray()) TranscodeReasons = mediaSource.TranscodeReasons == null ? null : string.Join(",", mediaSource.TranscodeReasons.Select(i => i.ToString()).ToArray())
}; };
@ -310,6 +324,7 @@ namespace MediaBrowser.Api.Playback
StartTimeTicks = request.StartTimeTicks, StartTimeTicks = request.StartTimeTicks,
Static = isStatic, Static = isStatic,
AudioSampleRate = request.MaxAudioSampleRate, AudioSampleRate = request.MaxAudioSampleRate,
MaxAudioBitDepth = request.MaxAudioBitDepth,
TranscodeReasons = mediaSource.TranscodeReasons == null ? null : string.Join(",", mediaSource.TranscodeReasons.Select(i => i.ToString()).ToArray()) TranscodeReasons = mediaSource.TranscodeReasons == null ? null : string.Join(",", mediaSource.TranscodeReasons.Select(i => i.ToString()).ToArray())
}; };

View File

@ -284,6 +284,29 @@ namespace MediaBrowser.Controller.MediaEncoding
} }
} }
public int? OutputAudioBitDepth
{
get
{
if (BaseRequest.Static || string.Equals(OutputAudioCodec, "copy", StringComparison.OrdinalIgnoreCase))
{
if (AudioStream != null)
{
return AudioStream.BitDepth;
}
}
//else if (BaseRequest.AudioSampleRate.HasValue)
//{
// // Don't exceed what the encoder supports
// // Seeing issues of attempting to encode to 88200
// return Math.Min(44100, BaseRequest.AudioSampleRate.Value);
//}
return null;
}
}
/// <summary> /// <summary>
/// Predicts the audio sample rate that will be in the output stream /// Predicts the audio sample rate that will be in the output stream
/// </summary> /// </summary>

View File

@ -83,6 +83,8 @@ namespace MediaBrowser.Controller.MediaEncoding
[ApiMember(Name = "AudioSampleRate", Description = "Optional. Specify a specific audio sample rate, e.g. 44100", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")] [ApiMember(Name = "AudioSampleRate", Description = "Optional. Specify a specific audio sample rate, e.g. 44100", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")]
public int? AudioSampleRate { get; set; } public int? AudioSampleRate { get; set; }
public int? MaxAudioBitDepth { get; set; }
/// <summary> /// <summary>
/// Gets or sets the audio bit rate. /// Gets or sets the audio bit rate.
/// </summary> /// </summary>

View File

@ -262,7 +262,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
var outputContainer = state.Options.OutputContainer; var outputContainer = state.Options.OutputContainer;
var mediaProfile = state.IsVideoRequest ? var mediaProfile = state.IsVideoRequest ?
profile.GetAudioMediaProfile(outputContainer, audioCodec, state.OutputAudioChannels, state.OutputAudioBitrate, state.OutputAudioSampleRate) : profile.GetAudioMediaProfile(outputContainer, audioCodec, state.OutputAudioChannels, state.OutputAudioBitrate, state.OutputAudioSampleRate, state.OutputAudioBitDepth) :
profile.GetVideoMediaProfile(outputContainer, profile.GetVideoMediaProfile(outputContainer,
audioCodec, audioCodec,
videoCodec, videoCodec,

View File

@ -12,7 +12,7 @@ namespace MediaBrowser.Model.Dlna
public bool IsVideoConditionSatisfied(ProfileCondition condition, public bool IsVideoConditionSatisfied(ProfileCondition condition,
int? width, int? width,
int? height, int? height,
int? bitDepth, int? videoBitDepth,
int? videoBitrate, int? videoBitrate,
string videoProfile, string videoProfile,
double? videoLevel, double? videoLevel,
@ -46,7 +46,7 @@ namespace MediaBrowser.Model.Dlna
case ProfileConditionValue.PacketLength: case ProfileConditionValue.PacketLength:
return IsConditionSatisfied(condition, packetLength); return IsConditionSatisfied(condition, packetLength);
case ProfileConditionValue.VideoBitDepth: case ProfileConditionValue.VideoBitDepth:
return IsConditionSatisfied(condition, bitDepth); return IsConditionSatisfied(condition, videoBitDepth);
case ProfileConditionValue.VideoBitrate: case ProfileConditionValue.VideoBitrate:
return IsConditionSatisfied(condition, videoBitrate); return IsConditionSatisfied(condition, videoBitrate);
case ProfileConditionValue.Height: case ProfileConditionValue.Height:
@ -79,7 +79,7 @@ namespace MediaBrowser.Model.Dlna
} }
} }
public bool IsAudioConditionSatisfied(ProfileCondition condition, int? audioChannels, int? audioBitrate, int? audioSampleRate) public bool IsAudioConditionSatisfied(ProfileCondition condition, int? audioChannels, int? audioBitrate, int? audioSampleRate, int? audioBitDepth)
{ {
switch (condition.Property) switch (condition.Property)
{ {
@ -89,6 +89,8 @@ namespace MediaBrowser.Model.Dlna
return IsConditionSatisfied(condition, audioChannels); return IsConditionSatisfied(condition, audioChannels);
case ProfileConditionValue.AudioSampleRate: case ProfileConditionValue.AudioSampleRate:
return IsConditionSatisfied(condition, audioSampleRate); return IsConditionSatisfied(condition, audioSampleRate);
case ProfileConditionValue.AudioBitDepth:
return IsConditionSatisfied(condition, audioBitDepth);
default: default:
throw new ArgumentException("Unexpected condition on audio file: " + condition.Property); throw new ArgumentException("Unexpected condition on audio file: " + condition.Property);
} }
@ -98,6 +100,7 @@ namespace MediaBrowser.Model.Dlna
int? audioChannels, int? audioChannels,
int? audioBitrate, int? audioBitrate,
int? audioSampleRate, int? audioSampleRate,
int? audioBitDepth,
string audioProfile, string audioProfile,
bool? isSecondaryTrack) bool? isSecondaryTrack)
{ {
@ -113,6 +116,8 @@ namespace MediaBrowser.Model.Dlna
return IsConditionSatisfied(condition, isSecondaryTrack); return IsConditionSatisfied(condition, isSecondaryTrack);
case ProfileConditionValue.AudioSampleRate: case ProfileConditionValue.AudioSampleRate:
return IsConditionSatisfied(condition, audioSampleRate); return IsConditionSatisfied(condition, audioSampleRate);
case ProfileConditionValue.AudioBitDepth:
return IsConditionSatisfied(condition, audioBitDepth);
default: default:
throw new ArgumentException("Unexpected condition on audio file: " + condition.Property); throw new ArgumentException("Unexpected condition on audio file: " + condition.Property);
} }

View File

@ -55,6 +55,7 @@ namespace MediaBrowser.Model.Dlna
int? audioBitrate, int? audioBitrate,
int? audioSampleRate, int? audioSampleRate,
int? audioChannels, int? audioChannels,
int? audioBitDepth,
bool isDirectStream, bool isDirectStream,
long? runtimeTicks, long? runtimeTicks,
TranscodeSeekInfo transcodeSeekInfo) TranscodeSeekInfo transcodeSeekInfo)
@ -86,7 +87,8 @@ namespace MediaBrowser.Model.Dlna
audioCodec, audioCodec,
audioChannels, audioChannels,
audioBitrate, audioBitrate,
audioSampleRate); audioSampleRate,
audioBitDepth);
string orgPn = mediaProfile == null ? null : mediaProfile.OrgPn; string orgPn = mediaProfile == null ? null : mediaProfile.OrgPn;

View File

@ -185,7 +185,7 @@ namespace MediaBrowser.Model.Dlna
return null; return null;
} }
public ResponseProfile GetAudioMediaProfile(string container, string audioCodec, int? audioChannels, int? audioBitrate, int? audioSampleRate) public ResponseProfile GetAudioMediaProfile(string container, string audioCodec, int? audioChannels, int? audioBitrate, int? audioSampleRate, int? audioBitDepth)
{ {
container = StringHelper.TrimStart(container ?? string.Empty, '.'); container = StringHelper.TrimStart(container ?? string.Empty, '.');
@ -213,7 +213,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.IsAudioConditionSatisfied(GetModelProfileCondition(c), audioChannels, audioBitrate, audioSampleRate)) if (!conditionProcessor.IsAudioConditionSatisfied(GetModelProfileCondition(c), audioChannels, audioBitrate, audioSampleRate, audioBitDepth))
{ {
anyOff = true; anyOff = true;
break; break;

View File

@ -23,6 +23,7 @@
VideoCodecTag = 19, VideoCodecTag = 19,
IsAvc = 20, IsAvc = 20,
IsInterlaced = 21, IsInterlaced = 21,
AudioSampleRate = 22 AudioSampleRate = 22,
AudioBitDepth = 23
} }
} }

View File

@ -167,6 +167,9 @@ namespace MediaBrowser.Model.Dlna
case ProfileConditionValue.VideoBitDepth: case ProfileConditionValue.VideoBitDepth:
return TranscodeReason.VideoBitDepthNotSupported; return TranscodeReason.VideoBitDepthNotSupported;
case ProfileConditionValue.AudioBitDepth:
return TranscodeReason.AudioBitDepthNotSupported;
case ProfileConditionValue.VideoBitrate: case ProfileConditionValue.VideoBitrate:
return TranscodeReason.VideoBitrateNotSupported; return TranscodeReason.VideoBitrateNotSupported;
@ -234,6 +237,7 @@ namespace MediaBrowser.Model.Dlna
int? inputAudioChannels = audioStream == null ? null : audioStream.Channels; int? inputAudioChannels = audioStream == null ? null : audioStream.Channels;
int? inputAudioBitrate = audioStream == null ? null : audioStream.BitDepth; int? inputAudioBitrate = audioStream == null ? null : audioStream.BitDepth;
int? inputAudioSampleRate = audioStream == null ? null : audioStream.SampleRate; int? inputAudioSampleRate = audioStream == null ? null : audioStream.SampleRate;
int? inputAudioBitDepth = audioStream == null ? null : audioStream.BitDepth;
if (directPlayMethods.Count > 0) if (directPlayMethods.Count > 0)
{ {
@ -250,7 +254,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.IsAudioConditionSatisfied(applyCondition, inputAudioChannels, inputAudioBitrate, inputAudioSampleRate)) if (!conditionProcessor.IsAudioConditionSatisfied(applyCondition, inputAudioChannels, inputAudioBitrate, inputAudioSampleRate, inputAudioBitDepth))
{ {
LogConditionFailure(options.Profile, "AudioCodecProfile", applyCondition, item); LogConditionFailure(options.Profile, "AudioCodecProfile", applyCondition, item);
applyConditions = false; applyConditions = false;
@ -271,7 +275,7 @@ namespace MediaBrowser.Model.Dlna
bool all = true; bool all = true;
foreach (ProfileCondition c in conditions) foreach (ProfileCondition c in conditions)
{ {
if (!conditionProcessor.IsAudioConditionSatisfied(c, inputAudioChannels, inputAudioBitrate, inputAudioSampleRate)) if (!conditionProcessor.IsAudioConditionSatisfied(c, inputAudioChannels, inputAudioBitrate, inputAudioSampleRate, inputAudioBitDepth))
{ {
LogConditionFailure(options.Profile, "AudioCodecProfile", c, item); LogConditionFailure(options.Profile, "AudioCodecProfile", c, item);
var transcodeReason = GetTranscodeReasonForFailedCondition(c); var transcodeReason = GetTranscodeReasonForFailedCondition(c);
@ -351,7 +355,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.IsAudioConditionSatisfied(applyCondition, inputAudioChannels, inputAudioBitrate, inputAudioSampleRate)) if (!conditionProcessor.IsAudioConditionSatisfied(applyCondition, inputAudioChannels, inputAudioBitrate, inputAudioSampleRate, inputAudioBitDepth))
{ {
LogConditionFailure(options.Profile, "AudioCodecProfile", applyCondition, item); LogConditionFailure(options.Profile, "AudioCodecProfile", applyCondition, item);
applyConditions = false; applyConditions = false;
@ -734,8 +738,9 @@ namespace MediaBrowser.Model.Dlna
int? audioChannels = audioStream == null ? null : audioStream.Channels; int? audioChannels = audioStream == null ? null : audioStream.Channels;
string audioProfile = audioStream == null ? null : audioStream.Profile; string audioProfile = audioStream == null ? null : audioStream.Profile;
int? inputAudioSampleRate = audioStream == null ? null : audioStream.SampleRate; int? inputAudioSampleRate = audioStream == null ? null : audioStream.SampleRate;
int? inputAudioBitDepth = audioStream == null ? null : audioStream.BitDepth;
if (!conditionProcessor.IsVideoAudioConditionSatisfied(applyCondition, audioChannels, inputAudioBitrate, inputAudioSampleRate, audioProfile, isSecondaryAudio)) if (!conditionProcessor.IsVideoAudioConditionSatisfied(applyCondition, audioChannels, inputAudioBitrate, inputAudioSampleRate, inputAudioBitDepth, audioProfile, isSecondaryAudio))
{ {
LogConditionFailure(options.Profile, "AudioCodecProfile", applyCondition, item); LogConditionFailure(options.Profile, "AudioCodecProfile", applyCondition, item);
applyConditions = false; applyConditions = false;
@ -972,6 +977,7 @@ namespace MediaBrowser.Model.Dlna
int? audioChannels = audioStream == null ? null : audioStream.Channels; int? audioChannels = audioStream == null ? null : audioStream.Channels;
string audioProfile = audioStream == null ? null : audioStream.Profile; string audioProfile = audioStream == null ? null : audioStream.Profile;
int? audioSampleRate = audioStream == null ? null : audioStream.SampleRate; int? audioSampleRate = audioStream == null ? null : audioStream.SampleRate;
int? audioBitDepth = audioStream == null ? null : audioStream.BitDepth;
TransportStreamTimestamp? timestamp = videoStream == null ? TransportStreamTimestamp.None : mediaSource.Timestamp; TransportStreamTimestamp? timestamp = videoStream == null ? TransportStreamTimestamp.None : mediaSource.Timestamp;
int? packetLength = videoStream == null ? null : videoStream.PacketLength; int? packetLength = videoStream == null ? null : videoStream.PacketLength;
@ -1066,7 +1072,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.IsVideoAudioConditionSatisfied(applyCondition, audioChannels, audioBitrate, audioSampleRate, audioProfile, isSecondaryAudio)) if (!conditionProcessor.IsVideoAudioConditionSatisfied(applyCondition, audioChannels, audioBitrate, audioSampleRate, audioBitDepth, audioProfile, isSecondaryAudio))
{ {
LogConditionFailure(profile, "VideoAudioCodecProfile", applyCondition, mediaSource); LogConditionFailure(profile, "VideoAudioCodecProfile", applyCondition, mediaSource);
applyConditions = false; applyConditions = false;
@ -1086,7 +1092,7 @@ namespace MediaBrowser.Model.Dlna
foreach (ProfileCondition i in conditions) foreach (ProfileCondition i in conditions)
{ {
if (!conditionProcessor.IsVideoAudioConditionSatisfied(i, audioChannels, audioBitrate, audioSampleRate, audioProfile, isSecondaryAudio)) if (!conditionProcessor.IsVideoAudioConditionSatisfied(i, audioChannels, audioBitrate, audioSampleRate, audioBitDepth, audioProfile, isSecondaryAudio))
{ {
LogConditionFailure(profile, "VideoAudioCodecProfile", i, mediaSource); LogConditionFailure(profile, "VideoAudioCodecProfile", i, mediaSource);

View File

@ -477,6 +477,18 @@ namespace MediaBrowser.Model.Dlna
} }
} }
/// <summary>
/// Predicts the audio sample rate that will be in the output stream
/// </summary>
public int? TargetAudioBitDepth
{
get
{
MediaStream stream = TargetAudioStream;
return stream == null ? null : stream.BitDepth;
}
}
/// <summary> /// <summary>
/// Predicts the audio sample rate that will be in the output stream /// Predicts the audio sample rate that will be in the output stream
/// </summary> /// </summary>

View File

@ -47,6 +47,7 @@ namespace MediaBrowser.Model.Session
VideoBitrateNotSupported = 16, VideoBitrateNotSupported = 16,
VideoFramerateNotSupported = 17, VideoFramerateNotSupported = 17,
VideoLevelNotSupported = 18, VideoLevelNotSupported = 18,
VideoProfileNotSupported = 19 VideoProfileNotSupported = 19,
AudioBitDepthNotSupported = 20
} }
} }