From ced2d21f7b40c33a2b2874817f47dc250417f020 Mon Sep 17 00:00:00 2001
From: gnattu <gnattu@users.noreply.github.com>
Date: Sun, 8 Sep 2024 01:17:16 +0800
Subject: [PATCH] Add SUPPLEMENTAL-CODECS for Dolby Vision video with fallbacks
 (#12605)

---
 Jellyfin.Api/Helpers/DynamicHlsHelper.cs | 44 ++++++++++++++++++++++++
 1 file changed, 44 insertions(+)

diff --git a/Jellyfin.Api/Helpers/DynamicHlsHelper.cs b/Jellyfin.Api/Helpers/DynamicHlsHelper.cs
index a58da17d59..0e620e72a9 100644
--- a/Jellyfin.Api/Helpers/DynamicHlsHelper.cs
+++ b/Jellyfin.Api/Helpers/DynamicHlsHelper.cs
@@ -304,6 +304,8 @@ public class DynamicHlsHelper
 
         AppendPlaylistCodecsField(playlistBuilder, state);
 
+        AppendPlaylistSupplementalCodecsField(playlistBuilder, state);
+
         AppendPlaylistResolutionField(playlistBuilder, state);
 
         AppendPlaylistFramerateField(playlistBuilder, state);
@@ -406,6 +408,48 @@ public class DynamicHlsHelper
         }
     }
 
+    /// <summary>
+    /// Appends a SUPPLEMENTAL-CODECS field containing formatted strings of
+    /// the active streams output Dolby Vision Videos.
+    /// </summary>
+    /// <seealso cref="AppendPlaylist(StringBuilder, StreamState, string, int, string)"/>
+    /// <seealso cref="GetPlaylistVideoCodecs(StreamState, string, int)"/>
+    /// <param name="builder">StringBuilder to append the field to.</param>
+    /// <param name="state">StreamState of the current stream.</param>
+    private void AppendPlaylistSupplementalCodecsField(StringBuilder builder, StreamState state)
+    {
+        // Dolby Vision currently cannot exist when transcoding
+        if (!EncodingHelper.IsCopyCodec(state.OutputVideoCodec))
+        {
+            return;
+        }
+
+        var dvProfile = state.VideoStream.DvProfile;
+        var dvLevel = state.VideoStream.DvLevel;
+        var dvRangeString = state.VideoStream.VideoRangeType switch
+        {
+            VideoRangeType.DOVIWithHDR10 => "db1p",
+            VideoRangeType.DOVIWithHLG => "db4h",
+            _ => string.Empty
+        };
+
+        if (dvProfile is null || dvLevel is null || string.IsNullOrEmpty(dvRangeString))
+        {
+            return;
+        }
+
+        var dvFourCc = string.Equals(state.ActualOutputVideoCodec, "av1", StringComparison.OrdinalIgnoreCase) ? "dav1" : "dvh1";
+        builder.Append(",SUPPLEMENTAL-CODECS=\"")
+            .Append(dvFourCc)
+            .Append('.')
+            .Append(dvProfile.Value.ToString("D2", CultureInfo.InvariantCulture))
+            .Append('.')
+            .Append(dvLevel.Value.ToString("D2", CultureInfo.InvariantCulture))
+            .Append('/')
+            .Append(dvRangeString)
+            .Append('"');
+    }
+
     /// <summary>
     /// Appends a RESOLUTION field containing the resolution of the output stream.
     /// </summary>