Merge pull request #18300 from theopeuchlestrade/fix-profile8-client-codec-tags

Use hvc1 for Dolby Vision profile 8
This commit is contained in:
Cody Robibero
2026-10-05 16:44:20 -06:00
committed by GitHub
2 changed files with 40 additions and 2 deletions
@@ -1777,6 +1777,16 @@ public class DynamicHlsController : BaseJellyfinApiController
return args;
}
/// <summary>
/// Selects the HEVC Dolby Vision sample entry tag.
/// </summary>
/// <param name="stream">The video stream.</param>
/// <returns>The MP4 sample entry tag.</returns>
internal static string GetDolbyVisionHevcCodecTag(MediaStream stream)
{
return stream.DvProfile == 8 ? "hvc1" : "dvh1";
}
/// <summary>
/// Gets the video arguments for transcoding.
/// </summary>
@@ -1819,8 +1829,7 @@ public class DynamicHlsController : BaseJellyfinApiController
{
if (isActualOutputVideoCodecHevc)
{
// Use hvc1 for 8.4. This is what Dolby uses for its official sample streams. Tagging with dvh1 would break some players with strict tag checking like Apple Safari.
var codecTag = state.VideoStream.VideoRangeType == VideoRangeType.DOVIWithHLG ? "hvc1" : "dvh1";
var codecTag = GetDolbyVisionHevcCodecTag(state.VideoStream);
args += $" -tag:v:0 {codecTag} -strict -2";
}
else if (isActualOutputVideoCodecAv1)
@@ -3,6 +3,7 @@ using System.Threading;
using System.Threading.Tasks;
using Jellyfin.Api.Controllers;
using MediaBrowser.Controller.MediaEncoding;
using MediaBrowser.Model.Entities;
using Microsoft.Extensions.Logging.Abstractions;
using Xunit;
@@ -10,6 +11,34 @@ namespace Jellyfin.Api.Tests.Controllers
{
public class DynamicHlsControllerTests
{
[Theory]
[InlineData(8, 1, "smpte2084", false, "hvc1")]
[InlineData(8, 1, "smpte2084", true, "hvc1")]
[InlineData(8, 2, "bt709", false, "hvc1")]
[InlineData(8, 4, "arib-std-b67", false, "hvc1")]
[InlineData(8, 6, "smpte2084", false, "hvc1")]
[InlineData(5, 0, "smpte2084", false, "dvh1")]
[InlineData(7, 6, "smpte2084", false, "dvh1")]
[InlineData(null, null, "smpte2084", false, "dvh1")]
public void GetDolbyVisionHevcCodecTag_SelectsTagForProfile(int? profile, int? compatibilityId, string transfer, bool hdr10Plus, string expected)
{
var stream = new MediaStream
{
Codec = "hevc",
Type = MediaStreamType.Video,
RpuPresentFlag = 1,
BlPresentFlag = 1,
ColorSpace = "bt2020nc",
ColorPrimaries = "bt2020",
ColorTransfer = transfer,
DvProfile = profile,
DvBlSignalCompatibilityId = compatibilityId,
Hdr10PlusPresentFlag = hdr10Plus
};
Assert.Equal(expected, DynamicHlsController.GetDolbyVisionHevcCodecTag(stream));
}
[Theory]
[MemberData(nameof(GetSegmentLengths_Success_TestData))]
public void GetSegmentLengths_Success(long runtimeTicks, int segmentlength, double[] expected)