Better bitrate and resolution normalization (#12644)

pull/12679/head
gnattu 5 months ago committed by GitHub
parent c97c2217a5
commit 56cf1a581c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -219,11 +219,17 @@ public static class StreamingHelpers
} }
else else
{ {
var h264EquivalentBitrate = EncodingHelper.ScaleBitrate(
state.OutputVideoBitrate.Value,
state.ActualOutputVideoCodec,
"h264");
var resolution = ResolutionNormalizer.Normalize( var resolution = ResolutionNormalizer.Normalize(
state.VideoStream?.BitRate, state.VideoStream?.BitRate,
state.OutputVideoBitrate.Value, state.OutputVideoBitrate.Value,
h264EquivalentBitrate,
state.VideoRequest.MaxWidth, state.VideoRequest.MaxWidth,
state.VideoRequest.MaxHeight); state.VideoRequest.MaxHeight,
state.TargetFramerate);
state.VideoRequest.MaxWidth = resolution.MaxWidth; state.VideoRequest.MaxWidth = resolution.MaxWidth;
state.VideoRequest.MaxHeight = resolution.MaxHeight; state.VideoRequest.MaxHeight = resolution.MaxHeight;

@ -2400,7 +2400,7 @@ namespace MediaBrowser.Controller.MediaEncoding
return 1; return 1;
} }
private static int ScaleBitrate(int bitrate, string inputVideoCodec, string outputVideoCodec) public static int ScaleBitrate(int bitrate, string inputVideoCodec, string outputVideoCodec)
{ {
var inputScaleFactor = GetVideoBitrateScaleFactor(inputVideoCodec); var inputScaleFactor = GetVideoBitrateScaleFactor(inputVideoCodec);
var outputScaleFactor = GetVideoBitrateScaleFactor(outputVideoCodec); var outputScaleFactor = GetVideoBitrateScaleFactor(outputVideoCodec);
@ -2424,6 +2424,12 @@ namespace MediaBrowser.Controller.MediaEncoding
{ {
scaleFactor = Math.Max(scaleFactor, 2); scaleFactor = Math.Max(scaleFactor, 2);
} }
else if (bitrate >= 30000000)
{
// Don't scale beyond 30Mbps, it is hardly visually noticeable for most codecs with our prefer speed encoding
// and will cause extremely high bitrate to be used for av1->h264 transcoding that will overload clients and encoders
scaleFactor = 1;
}
return Convert.ToInt32(scaleFactor * bitrate); return Convert.ToInt32(scaleFactor * bitrate);
} }

@ -2,28 +2,33 @@
#pragma warning disable CS1591 #pragma warning disable CS1591
using System; using System;
using System.Linq;
namespace MediaBrowser.Model.Dlna namespace MediaBrowser.Model.Dlna
{ {
public static class ResolutionNormalizer public static class ResolutionNormalizer
{ {
private static readonly ResolutionConfiguration[] Configurations = // Please note: all bitrate here are in the scale of SDR h264 bitrate at 30fps
new[] private static readonly ResolutionConfiguration[] _configurations =
{ [
new ResolutionConfiguration(426, 320000), new ResolutionConfiguration(416, 365000),
new ResolutionConfiguration(640, 400000), new ResolutionConfiguration(640, 730000),
new ResolutionConfiguration(720, 950000), new ResolutionConfiguration(768, 1100000),
new ResolutionConfiguration(1280, 2500000), new ResolutionConfiguration(960, 3000000),
new ResolutionConfiguration(1920, 4000000), new ResolutionConfiguration(1280, 6000000),
new ResolutionConfiguration(2560, 20000000), new ResolutionConfiguration(1920, 13500000),
new ResolutionConfiguration(3840, 35000000) new ResolutionConfiguration(2560, 28000000),
}; new ResolutionConfiguration(3840, 50000000)
];
public static ResolutionOptions Normalize( public static ResolutionOptions Normalize(
int? inputBitrate, int? inputBitrate,
int outputBitrate, int outputBitrate,
int h264EquivalentOutputBitrate,
int? maxWidth, int? maxWidth,
int? maxHeight) int? maxHeight,
float? targetFps,
bool isHdr = false) // We are not doing HDR transcoding for now, leave for future use
{ {
// If the bitrate isn't changing, then don't downscale the resolution // If the bitrate isn't changing, then don't downscale the resolution
if (inputBitrate.HasValue && outputBitrate >= inputBitrate.Value) if (inputBitrate.HasValue && outputBitrate >= inputBitrate.Value)
@ -38,16 +43,26 @@ namespace MediaBrowser.Model.Dlna
} }
} }
var resolutionConfig = GetResolutionConfiguration(outputBitrate); var referenceBitrate = h264EquivalentOutputBitrate * (30.0f / (targetFps ?? 30.0f));
if (resolutionConfig is not null)
if (isHdr)
{ {
var originvalValue = maxWidth; referenceBitrate *= 0.8f;
}
maxWidth = Math.Min(resolutionConfig.MaxWidth, maxWidth ?? resolutionConfig.MaxWidth); var resolutionConfig = GetResolutionConfiguration(Convert.ToInt32(referenceBitrate));
if (!originvalValue.HasValue || originvalValue.Value != maxWidth.Value)
{ if (resolutionConfig is null)
maxHeight = null; {
} return new ResolutionOptions { MaxWidth = maxWidth, MaxHeight = maxHeight };
}
var originWidthValue = maxWidth;
maxWidth = Math.Min(resolutionConfig.MaxWidth, maxWidth ?? resolutionConfig.MaxWidth);
if (!originWidthValue.HasValue || originWidthValue.Value != maxWidth.Value)
{
maxHeight = null;
} }
return new ResolutionOptions return new ResolutionOptions
@ -59,19 +74,7 @@ namespace MediaBrowser.Model.Dlna
private static ResolutionConfiguration GetResolutionConfiguration(int outputBitrate) private static ResolutionConfiguration GetResolutionConfiguration(int outputBitrate)
{ {
ResolutionConfiguration previousOption = null; return _configurations.FirstOrDefault(config => outputBitrate <= config.MaxBitrate);
foreach (var config in Configurations)
{
if (outputBitrate <= config.MaxBitrate)
{
return previousOption ?? config;
}
previousOption = config;
}
return null;
} }
} }
} }

Loading…
Cancel
Save