ResolutionNormalizer.cs 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. #nullable disable
  2. #pragma warning disable CS1591
  3. using System;
  4. using System.Linq;
  5. namespace MediaBrowser.Model.Dlna
  6. {
  7. public static class ResolutionNormalizer
  8. {
  9. // Please note: all bitrate here are in the scale of SDR h264 bitrate at 30fps
  10. private static readonly ResolutionConfiguration[] _configurations =
  11. [
  12. new ResolutionConfiguration(416, 365000),
  13. new ResolutionConfiguration(640, 730000),
  14. new ResolutionConfiguration(768, 1100000),
  15. new ResolutionConfiguration(960, 3000000),
  16. new ResolutionConfiguration(1280, 6000000),
  17. new ResolutionConfiguration(1920, 13500000),
  18. new ResolutionConfiguration(2560, 28000000),
  19. new ResolutionConfiguration(3840, 50000000)
  20. ];
  21. public static ResolutionOptions Normalize(
  22. int? inputBitrate,
  23. int outputBitrate,
  24. int h264EquivalentOutputBitrate,
  25. int? maxWidth,
  26. int? maxHeight,
  27. float? targetFps,
  28. bool isHdr = false) // We are not doing HDR transcoding for now, leave for future use
  29. {
  30. // If the bitrate isn't changing, then don't downscale the resolution
  31. if (inputBitrate.HasValue && outputBitrate >= inputBitrate.Value)
  32. {
  33. if (maxWidth.HasValue || maxHeight.HasValue)
  34. {
  35. return new ResolutionOptions
  36. {
  37. MaxWidth = maxWidth,
  38. MaxHeight = maxHeight
  39. };
  40. }
  41. }
  42. // Our reference bitrate is based on SDR h264 at 30fps
  43. var referenceFps = targetFps ?? 30.0f;
  44. var referenceScale = referenceFps <= 30.0f
  45. ? 30.0f / referenceFps
  46. : 1.0f / MathF.Sqrt(referenceFps / 30.0f);
  47. var referenceBitrate = h264EquivalentOutputBitrate * referenceScale;
  48. if (isHdr)
  49. {
  50. referenceBitrate *= 0.8f;
  51. }
  52. var resolutionConfig = GetResolutionConfiguration(Convert.ToInt32(referenceBitrate));
  53. if (resolutionConfig is null)
  54. {
  55. return new ResolutionOptions { MaxWidth = maxWidth, MaxHeight = maxHeight };
  56. }
  57. var originWidthValue = maxWidth;
  58. maxWidth = Math.Min(resolutionConfig.MaxWidth, maxWidth ?? resolutionConfig.MaxWidth);
  59. if (!originWidthValue.HasValue || originWidthValue.Value != maxWidth.Value)
  60. {
  61. maxHeight = null;
  62. }
  63. return new ResolutionOptions
  64. {
  65. MaxWidth = maxWidth,
  66. MaxHeight = maxHeight
  67. };
  68. }
  69. private static ResolutionConfiguration GetResolutionConfiguration(int outputBitrate)
  70. {
  71. return _configurations.FirstOrDefault(config => outputBitrate <= config.MaxBitrate);
  72. }
  73. }
  74. }