Explorar el Código

Add new VideoRangeTypes to fully support DoVi on webOS (#10469)

vedant hace 1 año
padre
commit
3bbb57eb83

+ 3 - 1
CONTRIBUTORS.md

@@ -177,10 +177,12 @@
  - [Chris-Codes-It](https://github.com/Chris-Codes-It)
  - [Pithaya](https://github.com/Pithaya)
  - [Çağrı Sakaoğlu](https://github.com/ilovepilav)
- _ [Barasingha](https://github.com/MaVdbussche)
+ - [Barasingha](https://github.com/MaVdbussche)
  - [Gauvino](https://github.com/Gauvino)
  - [felix920506](https://github.com/felix920506)
  - [btopherjohnson](https://github.com/btopherjohnson)
+ - [GeorgeH005](https://github.com/GeorgeH005)
+ - [Vedant](https://github.com/viktory36/)
 
 # Emby Contributors
 

+ 10 - 4
Jellyfin.Api/Controllers/DynamicHlsController.cs

@@ -1775,11 +1775,17 @@ public class DynamicHlsController : BaseJellyfinApiController
             || string.Equals(codec, "h265", StringComparison.OrdinalIgnoreCase)
             || string.Equals(codec, "hevc", StringComparison.OrdinalIgnoreCase))
         {
+            var requestedRange = state.GetRequestedRangeTypes(codec);
+            var requestHasDOVI = requestedRange.Contains(VideoRangeType.DOVI.ToString(), StringComparison.OrdinalIgnoreCase);
+            var requestHasDOVIWithHDR10 = requestedRange.Contains(VideoRangeType.DOVIWithHDR10.ToString(), StringComparison.OrdinalIgnoreCase);
+            var requestHasDOVIWithHLG = requestedRange.Contains(VideoRangeType.DOVIWithHLG.ToString(), StringComparison.OrdinalIgnoreCase);
+            var requestHasDOVIWithSDR = requestedRange.Contains(VideoRangeType.DOVIWithSDR.ToString(), StringComparison.OrdinalIgnoreCase);
+
             if (EncodingHelper.IsCopyCodec(codec)
-                && (state.VideoStream.VideoRangeType == VideoRangeType.DOVI
-                    || string.Equals(state.VideoStream.CodecTag, "dovi", StringComparison.OrdinalIgnoreCase)
-                    || string.Equals(state.VideoStream.CodecTag, "dvh1", StringComparison.OrdinalIgnoreCase)
-                    || string.Equals(state.VideoStream.CodecTag, "dvhe", StringComparison.OrdinalIgnoreCase)))
+                && ((state.VideoStream.VideoRangeType == VideoRangeType.DOVI && requestHasDOVI)
+                    || (state.VideoStream.VideoRangeType == VideoRangeType.DOVIWithHDR10 && requestHasDOVIWithHDR10)
+                    || (state.VideoStream.VideoRangeType == VideoRangeType.DOVIWithHLG && requestHasDOVIWithHLG)
+                    || (state.VideoStream.VideoRangeType == VideoRangeType.DOVIWithSDR && requestHasDOVIWithSDR)))
             {
                 // Prefer dvh1 to dvhe
                 args += " -tag:v:0 dvh1 -strict -2";

+ 16 - 1
Jellyfin.Data/Enums/VideoRangeType.cs

@@ -26,10 +26,25 @@ public enum VideoRangeType
     HLG,
 
     /// <summary>
-    /// Dolby Vision video range type (12bit).
+    /// Dolby Vision video range type (10bit encoded / 12bit remapped).
     /// </summary>
     DOVI,
 
+    /// <summary>
+    /// Dolby Vision with HDR10 video range fallback (10bit).
+    /// </summary>
+    DOVIWithHDR10,
+
+    /// <summary>
+    /// Dolby Vision with HLG video range fallback (10bit).
+    /// </summary>
+    DOVIWithHLG,
+
+    /// <summary>
+    /// Dolby Vision with SDR video range fallback (8bit / 10bit).
+    /// </summary>
+    DOVIWithSDR,
+
     /// <summary>
     /// HDR10+ video range type (10bit to 16bit).
     /// </summary>

+ 19 - 5
MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs

@@ -287,7 +287,9 @@ namespace MediaBrowser.Controller.MediaEncoding
 
             return state.VideoStream.VideoRange == VideoRange.HDR
                    && (state.VideoStream.VideoRangeType == VideoRangeType.HDR10
-                       || state.VideoStream.VideoRangeType == VideoRangeType.HLG);
+                       || state.VideoStream.VideoRangeType == VideoRangeType.HLG
+                       || state.VideoStream.VideoRangeType == VideoRangeType.DOVIWithHDR10
+                       || state.VideoStream.VideoRangeType == VideoRangeType.DOVIWithHLG);
         }
 
         private bool IsVulkanHwTonemapAvailable(EncodingJobInfo state, EncodingOptions options)
@@ -315,7 +317,8 @@ namespace MediaBrowser.Controller.MediaEncoding
             // Native VPP tonemapping may come to QSV in the future.
 
             return state.VideoStream.VideoRange == VideoRange.HDR
-                   && state.VideoStream.VideoRangeType == VideoRangeType.HDR10;
+                   && (state.VideoStream.VideoRangeType == VideoRangeType.HDR10
+                       || state.VideoStream.VideoRangeType == VideoRangeType.DOVIWithHDR10);
         }
 
         private bool IsVideoToolboxTonemapAvailable(EncodingJobInfo state, EncodingOptions options)
@@ -330,7 +333,7 @@ namespace MediaBrowser.Controller.MediaEncoding
             // Certain DV profile 5 video works in Safari with direct playing, but the VideoToolBox does not produce correct mapping results with transcoding.
             // All other HDR formats working.
             return state.VideoStream.VideoRange == VideoRange.HDR
-                   && state.VideoStream.VideoRangeType is VideoRangeType.HDR10 or VideoRangeType.HLG or VideoRangeType.HDR10Plus;
+                   && state.VideoStream.VideoRangeType is VideoRangeType.HDR10 or VideoRangeType.HLG or VideoRangeType.HDR10Plus or VideoRangeType.DOVIWithHDR10 or VideoRangeType.DOVIWithHLG;
         }
 
         /// <summary>
@@ -2206,7 +2209,16 @@ namespace MediaBrowser.Controller.MediaEncoding
                     return false;
                 }
 
-                if (!requestedRangeTypes.Contains(videoStream.VideoRangeType.ToString(), StringComparison.OrdinalIgnoreCase))
+                // DOVIWithHDR10 should be compatible with HDR10 supporting players. Same goes with HLG and of course SDR. So allow copy of those formats
+
+                var requestHasHDR10 = requestedRangeTypes.Contains(VideoRangeType.HDR10.ToString(), StringComparison.OrdinalIgnoreCase);
+                var requestHasHLG = requestedRangeTypes.Contains(VideoRangeType.HLG.ToString(), StringComparison.OrdinalIgnoreCase);
+                var requestHasSDR = requestedRangeTypes.Contains(VideoRangeType.SDR.ToString(), StringComparison.OrdinalIgnoreCase);
+
+                if (!requestedRangeTypes.Contains(videoStream.VideoRangeType.ToString(), StringComparison.OrdinalIgnoreCase)
+                     && !((requestHasHDR10 && videoStream.VideoRangeType == VideoRangeType.DOVIWithHDR10)
+                            || (requestHasHLG && videoStream.VideoRangeType == VideoRangeType.DOVIWithHLG)
+                            || (requestHasSDR && videoStream.VideoRangeType == VideoRangeType.DOVIWithSDR)))
                 {
                     return false;
                 }
@@ -6119,7 +6131,9 @@ namespace MediaBrowser.Controller.MediaEncoding
                                     && state.VideoStream.VideoRange == VideoRange.HDR
                                     && (state.VideoStream.VideoRangeType == VideoRangeType.HDR10
                                         || state.VideoStream.VideoRangeType == VideoRangeType.HLG
-                                        || (state.VideoStream.VideoRangeType == VideoRangeType.DOVI
+                                        || ((state.VideoStream.VideoRangeType == VideoRangeType.DOVI
+                                            || state.VideoStream.VideoRangeType == VideoRangeType.DOVIWithHDR10
+                                            || state.VideoStream.VideoRangeType == VideoRangeType.DOVIWithHLG)
                                             && string.Equals(state.VideoStream.Codec, "hevc", StringComparison.OrdinalIgnoreCase)));
 
             var useHwSurface = useOclToneMapping && IsVideoToolboxFullSupported() && _mediaEncoder.SupportsFilter("alphasrc");

+ 28 - 16
MediaBrowser.Model/Entities/MediaStream.cs

@@ -707,34 +707,46 @@ namespace MediaBrowser.Model.Entities
                 return (VideoRange.Unknown, VideoRangeType.Unknown);
             }
 
-            var colorTransfer = ColorTransfer;
-
-            if (string.Equals(colorTransfer, "smpte2084", StringComparison.OrdinalIgnoreCase))
-            {
-                return (VideoRange.HDR, VideoRangeType.HDR10);
-            }
-
-            if (string.Equals(colorTransfer, "arib-std-b67", StringComparison.OrdinalIgnoreCase))
-            {
-                return (VideoRange.HDR, VideoRangeType.HLG);
-            }
-
             var codecTag = CodecTag;
             var dvProfile = DvProfile;
             var rpuPresentFlag = RpuPresentFlag == 1;
             var blPresentFlag = BlPresentFlag == 1;
             var dvBlCompatId = DvBlSignalCompatibilityId;
 
-            var isDoViHDRProfile = dvProfile == 5 || dvProfile == 7 || dvProfile == 8;
-            var isDoViHDRFlag = rpuPresentFlag && blPresentFlag && (dvBlCompatId == 0 || dvBlCompatId == 1 || dvBlCompatId == 4);
+            var isDoViProfile = dvProfile == 5 || dvProfile == 7 || dvProfile == 8;
+            var isDoViFlag = rpuPresentFlag && blPresentFlag && (dvBlCompatId == 0 || dvBlCompatId == 1 || dvBlCompatId == 4 || dvBlCompatId == 2 || dvBlCompatId == 6);
 
-            if ((isDoViHDRProfile && isDoViHDRFlag)
+            if ((isDoViProfile && isDoViFlag)
                 || string.Equals(codecTag, "dovi", StringComparison.OrdinalIgnoreCase)
                 || string.Equals(codecTag, "dvh1", StringComparison.OrdinalIgnoreCase)
                 || string.Equals(codecTag, "dvhe", StringComparison.OrdinalIgnoreCase)
                 || string.Equals(codecTag, "dav1", StringComparison.OrdinalIgnoreCase))
             {
-                return (VideoRange.HDR, VideoRangeType.DOVI);
+                return dvProfile switch
+                {
+                    5 => (VideoRange.HDR, VideoRangeType.DOVI),
+                    8 => dvBlCompatId switch
+                    {
+                        1 => (VideoRange.HDR, VideoRangeType.DOVIWithHDR10),
+                        4 => (VideoRange.HDR, VideoRangeType.DOVIWithHLG),
+                        2 => (VideoRange.SDR, VideoRangeType.DOVIWithSDR),
+                        // There is no other case to handle here as per Dolby Spec. Default case included for completeness and linting purposes
+                        _ => (VideoRange.SDR, VideoRangeType.SDR)
+                    },
+                    7 => (VideoRange.HDR, VideoRangeType.HDR10),
+                    _ => (VideoRange.SDR, VideoRangeType.SDR)
+                };
+            }
+
+            var colorTransfer = ColorTransfer;
+
+            if (string.Equals(colorTransfer, "smpte2084", StringComparison.OrdinalIgnoreCase))
+            {
+                return (VideoRange.HDR, VideoRangeType.HDR10);
+            }
+            else if (string.Equals(colorTransfer, "arib-std-b67", StringComparison.OrdinalIgnoreCase))
+            {
+                return (VideoRange.HDR, VideoRangeType.HLG);
             }
 
             return (VideoRange.SDR, VideoRangeType.SDR);