You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
DolbyVisionFelCurves: skip the curve fold when the display does not take Dolby Vision (and a per-load switch) #1018
Hi, thanks for the curve fold in 7.61.0 and for the clear write-up of when to pick it over the dual-layer route. We ship it on 7.62.1, on by default as the docs recommend.
What we found. On a display without Dolby Vision the fold still runs. The engine sees the display correctly and plays HDR10, but the Profile 7 source is still converted to Profile 8.1, so felLookaheadForRead() arms the fold (it checks only convertP7Active, !isLive and the absence of an enhancement-route tap):
[DisplayCapabilities] observed: hdr=true hdr10=true hlg=true dv=false
[AetherEngine] load ... source-format=dolbyVision effective-format=hdr10 rate=23.976
[FelCurves] FEL source: mapping kept in the Profile 8.1 RPU, enhancement-layer luma residual folded into its luma curve per scene
[HLSVideoEngine] prepared: codec=hvc1.2.4.H153.90,ec-3 supplemental=dvh1.08.06/db1p ... DV=profile7
[HLSVideoEngine] serving on ... (dvModeAvailable=false effectiveDvMode=false panelIsHDR=true ...)
The panel shows the HDR10 base layer, so the folded RPU never reaches a Dolby Vision decoder. We compared two builds of the same code, one with the trait and one without, on the same scene of a UHD Blu-ray FEL title (Apple TV 4K, 3rd generation, tvOS 27, an HDR10/HDR10+ TV, source over HTTPS from a remote server):
Start
Fold built in
Fold not built
From the beginning
3.09 s to first frame
(not measured; 4.3 s on 7.59.0 before the upgrade)
Resume at 65:00, run 1
7.01 s
3.10 s
Resume at 65:00, run 2
3.61 s
2.97 s
So a resume costs 0.5 to 4 s more with the fold. Watching both builds side by side twice, we saw no visible difference on this display, which is what we would expect if the RPU is not applied.
Suggestions.
Arm the fold only when the display takes Dolby Vision (the same signal behind dvModeAvailable), and skip the GOP hold-back and the two-layer decodes otherwise. A log line at load stating whether the fold is armed, and why not, would help reports.
A per-load switch in LoadOptions (for example foldDolbyVisionFEL: Bool, defaulting to true when the trait is built in, so today's behaviour is unchanged), read once per load by felLookaheadForRead() and carried into reloadAtCurrentPosition(). That would let a host turn the fold off for a title a viewer reports, and run A/B checks on one build. Without the trait the field would be ignored, like preferDualLayerDolbyVision without DualLayerDolbyVision.
Happy to test a branch on an Apple TV 4K (3rd generation) with this display.
This is related to #988, the request for an RPU-only FEL correction that the DolbyVisionFelCurves fold answers. On main, felLookaheadForRead() in Sources/AetherEngine/Video/HLSSegmentProducer.swift arms the fold based only on convertP7Active, !isLive and the absence of an enhancement-route tap, which matches what you describe. Whether to gate the fold on the display and add a per-load switch is a decision for the maintainer.
Automated triage by Quint (Claude). A maintainer reads every issue and will follow up.
Thanks for the measurements and the clear write-up. You were right about the waste, and I measured where it actually happens before gating it, because dvModeAvailable turned out to be the wrong signal.
On an Apple TV 4K (3rd generation, tvOS 27.2) at an HDR10 television without Dolby Vision, with a Profile 8.1 clip whose RPU darkens every other 2 s block:
Panel
Route
RPU applied
SDR (Match Content off)
media or master playlist
yes
HDR10 (Match Dynamic Range on)
master playlist
no, the base layer bit for bit
HDR10
forceDolbyVisionOnNonDVDisplay
yes
A Mac and a Dolby Vision display apply it too. So the fold is wasted in exactly your case: tvOS, no Dolby Vision, panel in HDR10, without forceDolbyVisionOnNonDVDisplay.
The fold pauses on its own in that case. The engine predicts it at load (range matching on, an HDR-capable display, HDR criteria written by the engine), confirms it when the HDR master reaches readyToPlay, and clears it if the display refuses the master. The lookahead re-reads this at every keyframe and passes packets through without holding a GOP back or decoding anything. Logged as [FelCurves] fold paused. From a P7 FEL source over the network on the same box, the first load went from 5.04 to 5.14 s down to 4.33 to 4.42 s, the same as with the fold off, and seeks match too.
LoadOptions.foldsDolbyVisionFEL (default true), the per-load switch you suggested, carried by reloadAtCurrentPosition(applying:) and ignored without the trait. The load logs [FelCurves] fold not armed: <reason>.
One more thing worth considering for your app: with forceDolbyVisionOnNonDVDisplay on, tvOS applies the RPU on an HDR10 panel, so the fold reaches the picture there instead of being skipped. The unedited frames came out identical to the plain route in my test (no colour shift). The engine default stays off; Sodalite now turns it on by default on tvOS.
If you can rerun your resume test once the release is out, I'd be glad to hear the numbers.
Activity
quint-aether commentedon Nov 10, 2026
This is related to #988, the request for an RPU-only FEL correction that the
DolbyVisionFelCurvesfold answers. Onmain,felLookaheadForRead()inSources/AetherEngine/Video/HLSSegmentProducer.swiftarms the fold based only onconvertP7Active,!isLiveand the absence of an enhancement-route tap, which matches what you describe. Whether to gate the fold on the display and add a per-load switch is a decision for the maintainer.Automated triage by Quint (Claude). A maintainer reads every issue and will follow up.
fix(dv): let an accepted HDR master tell the FEL fold gate the panel …
fix(dv): close the FEL fold gate from the first read when an HDR writ…
fix(dv): leave the FEL fold bypass only at a keyframe, document the l…
fix(dv): let a folding session enter the fold bypass at the next keyf…
Merge pull request #1019 from superuser404notfound/feat/issue-1018-fe…
superuser404notfound commentedon Nov 10, 2026
Thanks for the measurements and the clear write-up. You were right about the waste, and I measured where it actually happens before gating it, because
dvModeAvailableturned out to be the wrong signal.On an Apple TV 4K (3rd generation, tvOS 27.2) at an HDR10 television without Dolby Vision, with a Profile 8.1 clip whose RPU darkens every other 2 s block:
forceDolbyVisionOnNonDVDisplayA Mac and a Dolby Vision display apply it too. So the fold is wasted in exactly your case: tvOS, no Dolby Vision, panel in HDR10, without
forceDolbyVisionOnNonDVDisplay.Merged into
mainin #1019, in the next release:[FelCurves] fold paused. From a P7 FEL source over the network on the same box, the first load went from 5.04 to 5.14 s down to 4.33 to 4.42 s, the same as with the fold off, and seeks match too.LoadOptions.foldsDolbyVisionFEL(defaulttrue), the per-load switch you suggested, carried byreloadAtCurrentPosition(applying:)and ignored without the trait. The load logs[FelCurves] fold not armed: <reason>.One more thing worth considering for your app: with
forceDolbyVisionOnNonDVDisplayon, tvOS applies the RPU on an HDR10 panel, so the fold reaches the picture there instead of being skipped. The unedited frames came out identical to the plain route in my test (no colour shift). The engine default stays off; Sodalite now turns it on by default on tvOS.If you can rerun your resume test once the release is out, I'd be glad to hear the numbers.
feat(dv): pause the FEL curve fold where its RPU cannot reach the pic…