mirror of
https://github.com/jellyfin/jellyfin.git
synced 2026-03-18 16:16:17 +00:00
add setting to control transcodng throttle
This commit is contained in:
@@ -8,12 +8,16 @@ namespace MediaBrowser.Model.Configuration
|
||||
public double DownMixAudioBoost { get; set; }
|
||||
public string H264Encoder { get; set; }
|
||||
public bool EnableDebugLogging { get; set; }
|
||||
public bool EnableThrottling { get; set; }
|
||||
public int ThrottleThresholdSeconds { get; set; }
|
||||
|
||||
public EncodingOptions()
|
||||
{
|
||||
H264Encoder = "libx264";
|
||||
DownMixAudioBoost = 2;
|
||||
EncodingQuality = EncodingQuality.Auto;
|
||||
EnableThrottling = true;
|
||||
ThrottleThresholdSeconds = 120;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,9 @@ namespace MediaBrowser.Model.Dlna
|
||||
TransportStreamTimestamp? timestamp,
|
||||
bool? isAnamorphic,
|
||||
bool? isCabac,
|
||||
int? refFrames)
|
||||
int? refFrames,
|
||||
int? numVideoStreams,
|
||||
int? numAudioStreams)
|
||||
{
|
||||
switch (condition.Property)
|
||||
{
|
||||
@@ -56,6 +58,10 @@ namespace MediaBrowser.Model.Dlna
|
||||
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:
|
||||
@@ -92,7 +98,8 @@ namespace MediaBrowser.Model.Dlna
|
||||
public bool IsVideoAudioConditionSatisfied(ProfileCondition condition,
|
||||
int? audioChannels,
|
||||
int? audioBitrate,
|
||||
string audioProfile)
|
||||
string audioProfile,
|
||||
bool? isSecondaryTrack)
|
||||
{
|
||||
switch (condition.Property)
|
||||
{
|
||||
@@ -102,6 +109,8 @@ namespace MediaBrowser.Model.Dlna
|
||||
return IsConditionSatisfied(condition, audioBitrate);
|
||||
case ProfileConditionValue.AudioChannels:
|
||||
return IsConditionSatisfied(condition, audioChannels);
|
||||
case ProfileConditionValue.IsSecondaryAudio:
|
||||
return IsConditionSatisfied(condition, isSecondaryTrack);
|
||||
default:
|
||||
throw new ArgumentException("Unexpected condition on audio file: " + condition.Property);
|
||||
}
|
||||
|
||||
@@ -117,7 +117,9 @@ namespace MediaBrowser.Model.Dlna
|
||||
TranscodeSeekInfo transcodeSeekInfo,
|
||||
bool? isAnamorphic,
|
||||
bool? isCabac,
|
||||
int? refFrames)
|
||||
int? refFrames,
|
||||
int? numVideoStreams,
|
||||
int? numAudioStreams)
|
||||
{
|
||||
// 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.HasValue, isDirectStream, transcodeSeekInfo);
|
||||
@@ -158,7 +160,9 @@ namespace MediaBrowser.Model.Dlna
|
||||
timestamp,
|
||||
isAnamorphic,
|
||||
isCabac,
|
||||
refFrames);
|
||||
refFrames,
|
||||
numVideoStreams,
|
||||
numAudioStreams);
|
||||
|
||||
List<string> orgPnValues = new List<string>();
|
||||
|
||||
|
||||
@@ -281,7 +281,9 @@ namespace MediaBrowser.Model.Dlna
|
||||
TransportStreamTimestamp timestamp,
|
||||
bool? isAnamorphic,
|
||||
bool? isCabac,
|
||||
int? refFrames)
|
||||
int? refFrames,
|
||||
int? numVideoStreams,
|
||||
int? numAudioStreams)
|
||||
{
|
||||
container = StringHelper.TrimStart((container ?? string.Empty), '.');
|
||||
|
||||
@@ -315,7 +317,7 @@ namespace MediaBrowser.Model.Dlna
|
||||
var anyOff = false;
|
||||
foreach (ProfileCondition c in i.Conditions)
|
||||
{
|
||||
if (!conditionProcessor.IsVideoConditionSatisfied(c, audioBitrate, audioChannels, width, height, bitDepth, videoBitrate, videoProfile, videoLevel, videoFramerate, packetLength, timestamp, isAnamorphic, isCabac, refFrames))
|
||||
if (!conditionProcessor.IsVideoConditionSatisfied(c, audioBitrate, audioChannels, width, height, bitDepth, videoBitrate, videoProfile, videoLevel, videoFramerate, packetLength, timestamp, isAnamorphic, isCabac, refFrames, numVideoStreams, numAudioStreams))
|
||||
{
|
||||
anyOff = true;
|
||||
break;
|
||||
|
||||
@@ -17,6 +17,9 @@
|
||||
VideoTimestamp = 12,
|
||||
IsAnamorphic = 13,
|
||||
RefFrames = 14,
|
||||
IsCabac = 15
|
||||
IsCabac = 15,
|
||||
NumAudioStreams = 16,
|
||||
NumVideoStreams = 17,
|
||||
IsSecondaryAudio
|
||||
}
|
||||
}
|
||||
@@ -495,10 +495,13 @@ namespace MediaBrowser.Model.Dlna
|
||||
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, audioBitrate, audioChannels, width, height, bitDepth, videoBitrate, videoProfile, videoLevel, videoFramerate, packetLength, timestamp, isAnamorphic, isCabac, refFrames))
|
||||
if (!conditionProcessor.IsVideoConditionSatisfied(i, audioBitrate, audioChannels, width, height, bitDepth, videoBitrate, videoProfile, videoLevel, videoFramerate, packetLength, timestamp, isAnamorphic, isCabac, refFrames, numVideoStreams, numAudioStreams))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
@@ -525,7 +528,7 @@ namespace MediaBrowser.Model.Dlna
|
||||
|
||||
foreach (ProfileCondition i in conditions)
|
||||
{
|
||||
if (!conditionProcessor.IsVideoConditionSatisfied(i, audioBitrate, audioChannels, width, height, bitDepth, videoBitrate, videoProfile, videoLevel, videoFramerate, packetLength, timestamp, isAnamorphic, isCabac, refFrames))
|
||||
if (!conditionProcessor.IsVideoConditionSatisfied(i, audioBitrate, audioChannels, width, height, bitDepth, videoBitrate, videoProfile, videoLevel, videoFramerate, packetLength, timestamp, isAnamorphic, isCabac, refFrames, numVideoStreams, numAudioStreams))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
@@ -554,7 +557,8 @@ namespace MediaBrowser.Model.Dlna
|
||||
|
||||
foreach (ProfileCondition i in conditions)
|
||||
{
|
||||
if (!conditionProcessor.IsVideoAudioConditionSatisfied(i, audioChannels, audioBitrate, audioProfile))
|
||||
bool? isSecondaryAudio = audioStream == null ? null : mediaSource.IsSecondaryAudio(audioStream);
|
||||
if (!conditionProcessor.IsVideoAudioConditionSatisfied(i, audioChannels, audioBitrate, audioProfile, isSecondaryAudio))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
@@ -752,6 +756,9 @@ namespace MediaBrowser.Model.Dlna
|
||||
case ProfileConditionValue.AudioProfile:
|
||||
case ProfileConditionValue.Has64BitOffsets:
|
||||
case ProfileConditionValue.PacketLength:
|
||||
case ProfileConditionValue.NumAudioStreams:
|
||||
case ProfileConditionValue.NumVideoStreams:
|
||||
case ProfileConditionValue.IsSecondaryAudio:
|
||||
case ProfileConditionValue.VideoTimestamp:
|
||||
{
|
||||
// Not supported yet
|
||||
|
||||
@@ -672,6 +672,42 @@ namespace MediaBrowser.Model.Dlna
|
||||
}
|
||||
}
|
||||
|
||||
public int? TargetVideoStreamCount
|
||||
{
|
||||
get
|
||||
{
|
||||
if (IsDirectStream)
|
||||
{
|
||||
return GetMediaStreamCount(MediaStreamType.Video, int.MaxValue);
|
||||
}
|
||||
return GetMediaStreamCount(MediaStreamType.Video, 1);
|
||||
}
|
||||
}
|
||||
|
||||
public int? TargetAudioStreamCount
|
||||
{
|
||||
get
|
||||
{
|
||||
if (IsDirectStream)
|
||||
{
|
||||
return GetMediaStreamCount(MediaStreamType.Audio, int.MaxValue);
|
||||
}
|
||||
return GetMediaStreamCount(MediaStreamType.Audio, 1);
|
||||
}
|
||||
}
|
||||
|
||||
private int? GetMediaStreamCount(MediaStreamType type, int limit)
|
||||
{
|
||||
var count = MediaSource.GetStreamCount(type);
|
||||
|
||||
if (count.HasValue)
|
||||
{
|
||||
count = Math.Min(count.Value, limit);
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
public List<MediaStream> GetSelectableAudioStreams()
|
||||
{
|
||||
return GetSelectableStreams(MediaStreamType.Audio);
|
||||
|
||||
@@ -46,8 +46,8 @@ namespace MediaBrowser.Model.Dto
|
||||
public int? Bitrate { get; set; }
|
||||
|
||||
public TransportStreamTimestamp? Timestamp { get; set; }
|
||||
public Dictionary<string, string> RequiredHttpHeaders { get; set; }
|
||||
|
||||
public Dictionary<string, string> RequiredHttpHeaders { get; set; }
|
||||
|
||||
public string TranscodingUrl { get; set; }
|
||||
public string TranscodingSubProtocol { get; set; }
|
||||
public string TranscodingContainer { get; set; }
|
||||
@@ -135,5 +135,35 @@ namespace MediaBrowser.Model.Dto
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public int? GetStreamCount(MediaStreamType type)
|
||||
{
|
||||
int numMatches = 0;
|
||||
int numStreams = 0;
|
||||
|
||||
foreach (MediaStream i in MediaStreams)
|
||||
{
|
||||
numStreams++;
|
||||
if (i.Type == type)
|
||||
{
|
||||
numMatches++;
|
||||
}
|
||||
}
|
||||
|
||||
return numStreams == 0 ? (int?)null : numMatches;
|
||||
}
|
||||
|
||||
public bool? IsSecondaryAudio(MediaStream stream)
|
||||
{
|
||||
foreach (MediaStream currentStream in MediaStreams)
|
||||
{
|
||||
if (currentStream.Type == MediaStreamType.Audio)
|
||||
{
|
||||
return currentStream.Index != stream.Index;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user