mirror of
https://github.com/jellyfin/jellyfin.git
synced 2026-01-15 08:23:28 -03:00
Improve dynamic HDR metadata handling (#13277)
* Add support for bitstream filter to remove dynamic hdr metadata * Add support for ffprobe's only_first_vframe for HDR10+ detection * Add BitStreamFilterOptionType for metadata removal check * Map HDR10+ metadata to VideoRangeType.cs Current implementation uses a hack that abuses the EL flag to avoid database schema changes. Should add proper field once EFCore migration is merged. * Add more Dolby Vision Range types Out of spec ones are problematic and should be marked as a dedicated invalid type and handled by the server to not crash the player. Profile 7 videos should not be treated as normal HDR10 videos at all and should remove the metadata before serving. * Remove dynamic hdr metadata when necessary * Allow direct playback of HDR10+ videos on HDR10 clients * Only use dovi codec tag when dovi metadata is not removed * Handle DV Profile 7 Videos better * Fix HDR10+ with new bitmask * Indicate the presence of HDR10+ in HLS SUPPLEMENTAL-CODECS * Fix Dovi 8.4 not labeled as HLG in HLS * Fallback to dovi_rpu bsf for av1 when possible * Fix dovi_rpu cli for av1 * Use correct EFCore db column for HDR10+ * Undo outdated migration * Add proper hdr10+ migration * Remove outdated migration * Rebase to new db code * Add migrations for Hdr10PlusPresentFlag * Directly use bsf enum * Add xmldocs for SupportsBitStreamFilterWithOption * Make `VideoRangeType.Unknown` explicitly default on api models. * Unset default for non-api model class * Use tuples for bsf dictionary for now
This commit is contained in:
@@ -345,6 +345,15 @@ namespace MediaBrowser.Model.Dlna
|
||||
return !condition.IsRequired;
|
||||
}
|
||||
|
||||
// Special case: HDR10 also satisfies if the video is HDR10Plus
|
||||
if (currentValue.Value == VideoRangeType.HDR10Plus)
|
||||
{
|
||||
if (IsConditionSatisfied(condition, VideoRangeType.HDR10))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
var conditionType = condition.Condition;
|
||||
if (conditionType == ProfileConditionType.EqualsAny)
|
||||
{
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
@@ -153,6 +153,8 @@ namespace MediaBrowser.Model.Entities
|
||||
/// <value>The title.</value>
|
||||
public string Title { get; set; }
|
||||
|
||||
public bool? Hdr10PlusPresentFlag { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the video range.
|
||||
/// </summary>
|
||||
@@ -172,6 +174,7 @@ namespace MediaBrowser.Model.Entities
|
||||
/// Gets the video range type.
|
||||
/// </summary>
|
||||
/// <value>The video range type.</value>
|
||||
[DefaultValue(VideoRangeType.Unknown)]
|
||||
public VideoRangeType VideoRangeType
|
||||
{
|
||||
get
|
||||
@@ -779,8 +782,8 @@ namespace MediaBrowser.Model.Entities
|
||||
var blPresentFlag = BlPresentFlag == 1;
|
||||
var dvBlCompatId = DvBlSignalCompatibilityId;
|
||||
|
||||
var isDoViProfile = dvProfile == 5 || dvProfile == 7 || dvProfile == 8 || dvProfile == 10;
|
||||
var isDoViFlag = rpuPresentFlag && blPresentFlag && (dvBlCompatId == 0 || dvBlCompatId == 1 || dvBlCompatId == 4 || dvBlCompatId == 2 || dvBlCompatId == 6);
|
||||
var isDoViProfile = dvProfile is 5 or 7 or 8 or 10;
|
||||
var isDoViFlag = rpuPresentFlag && blPresentFlag && dvBlCompatId is 0 or 1 or 4 or 2 or 6;
|
||||
|
||||
if ((isDoViProfile && isDoViFlag)
|
||||
|| string.Equals(codecTag, "dovi", StringComparison.OrdinalIgnoreCase)
|
||||
@@ -788,7 +791,7 @@ namespace MediaBrowser.Model.Entities
|
||||
|| string.Equals(codecTag, "dvhe", StringComparison.OrdinalIgnoreCase)
|
||||
|| string.Equals(codecTag, "dav1", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return dvProfile switch
|
||||
var dvRangeSet = dvProfile switch
|
||||
{
|
||||
5 => (VideoRange.HDR, VideoRangeType.DOVI),
|
||||
8 => dvBlCompatId switch
|
||||
@@ -796,32 +799,40 @@ namespace MediaBrowser.Model.Entities
|
||||
1 => (VideoRange.HDR, VideoRangeType.DOVIWithHDR10),
|
||||
4 => (VideoRange.HDR, VideoRangeType.DOVIWithHLG),
|
||||
2 => (VideoRange.SDR, VideoRangeType.DOVIWithSDR),
|
||||
// While not in Dolby Spec, Profile 8 CCid 6 media are possible to create, and since CCid 6 stems from Bluray (Profile 7 originally) an HDR10 base layer is guaranteed to exist.
|
||||
6 => (VideoRange.HDR, VideoRangeType.DOVIWithHDR10),
|
||||
// There is no other case to handle here as per Dolby Spec. Default case included for completeness and linting purposes
|
||||
_ => (VideoRange.SDR, VideoRangeType.SDR)
|
||||
// Out of Dolby Spec files should be marked as invalid
|
||||
_ => (VideoRange.HDR, VideoRangeType.DOVIInvalid)
|
||||
},
|
||||
7 => (VideoRange.HDR, VideoRangeType.HDR10),
|
||||
7 => (VideoRange.HDR, VideoRangeType.DOVIWithEL),
|
||||
10 => dvBlCompatId switch
|
||||
{
|
||||
0 => (VideoRange.HDR, VideoRangeType.DOVI),
|
||||
1 => (VideoRange.HDR, VideoRangeType.DOVIWithHDR10),
|
||||
2 => (VideoRange.SDR, VideoRangeType.DOVIWithSDR),
|
||||
4 => (VideoRange.HDR, VideoRangeType.DOVIWithHLG),
|
||||
// While not in Dolby Spec, Profile 8 CCid 6 media are possible to create, and since CCid 6 stems from Bluray (Profile 7 originally) an HDR10 base layer is guaranteed to exist.
|
||||
6 => (VideoRange.HDR, VideoRangeType.DOVIWithHDR10),
|
||||
// There is no other case to handle here as per Dolby Spec. Default case included for completeness and linting purposes
|
||||
_ => (VideoRange.SDR, VideoRangeType.SDR)
|
||||
// Out of Dolby Spec files should be marked as invalid
|
||||
_ => (VideoRange.HDR, VideoRangeType.DOVIInvalid)
|
||||
},
|
||||
_ => (VideoRange.SDR, VideoRangeType.SDR)
|
||||
};
|
||||
|
||||
if (Hdr10PlusPresentFlag == true)
|
||||
{
|
||||
return dvRangeSet.Item2 switch
|
||||
{
|
||||
VideoRangeType.DOVIWithHDR10 => (VideoRange.HDR, VideoRangeType.DOVIWithHDR10Plus),
|
||||
VideoRangeType.DOVIWithEL => (VideoRange.HDR, VideoRangeType.DOVIWithELHDR10Plus),
|
||||
_ => dvRangeSet
|
||||
};
|
||||
}
|
||||
|
||||
return dvRangeSet;
|
||||
}
|
||||
|
||||
var colorTransfer = ColorTransfer;
|
||||
|
||||
if (string.Equals(colorTransfer, "smpte2084", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return (VideoRange.HDR, VideoRangeType.HDR10);
|
||||
return Hdr10PlusPresentFlag == true ? (VideoRange.HDR, VideoRangeType.HDR10Plus) : (VideoRange.HDR, VideoRangeType.HDR10);
|
||||
}
|
||||
else if (string.Equals(colorTransfer, "arib-std-b67", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user