feat(transcode): tonemap HDR sources to SDR (zscale-gated)
HDR (HDR10/HLG/Dolby Vision) transcoded to SDR came out washed-out and desaturated because the filter chain never tonemapped. buildHLSFFmpegArgsAt now inserts a zscale linearise -> hable tonemap -> BT.709 chain after the scale and before format=, but only when the source is HDR and the ffmpeg build has zscale (FFmpegSupportsZscale, cached). Builds without zimg keep the old behaviour (plays, just desaturated) instead of erroring. It's a CPU filter, valid for every encoder here: the decode hwaccel deliberately leaves frames in system memory (no -hwaccel_output_format), so zscale runs ahead of format=/hwupload exactly like the existing scale filter. Verified on a real 4K HDR10 file — vivid colour and deep blacks vs the washed-out baseline.
This commit is contained in:
parent
445da233c0
commit
e4373454ba
6 changed files with 211 additions and 5 deletions
|
|
@ -1347,16 +1347,23 @@ func buildHLSFFmpegArgsAt(cfg HLSSessionConfig, probe *StreamProbe, tmpDir strin
|
|||
hwUploadTail = ",hwupload"
|
||||
colorTail = ""
|
||||
}
|
||||
// HDR→SDR tonemap, inserted after the scale (downscale-first = fewer pixels
|
||||
// to tonemap) and before format=. Only for an HDR source on a zscale-capable
|
||||
// ffmpeg; the trailing comma in hdrTonemapChain slots it in front of format=.
|
||||
tonemap := ""
|
||||
if probe.HDR != "" && cfg.Transcode.TonemapHDR {
|
||||
tonemap = hdrTonemapChain
|
||||
}
|
||||
var filterChain string
|
||||
if maxH > 0 && probe.Height > maxH {
|
||||
filterChain = fmt.Sprintf(
|
||||
"scale=-2:%d:force_original_aspect_ratio=decrease,scale=trunc(iw/2)*2:trunc(ih/2)*2,format=%s%s%s",
|
||||
maxH, pixFormat, colorTail, hwUploadTail,
|
||||
"scale=-2:%d:force_original_aspect_ratio=decrease,scale=trunc(iw/2)*2:trunc(ih/2)*2,%sformat=%s%s%s",
|
||||
maxH, tonemap, pixFormat, colorTail, hwUploadTail,
|
||||
)
|
||||
} else {
|
||||
filterChain = fmt.Sprintf(
|
||||
"scale=trunc(iw/2)*2:trunc(ih/2)*2,format=%s%s%s",
|
||||
pixFormat, colorTail, hwUploadTail,
|
||||
"scale=trunc(iw/2)*2:trunc(ih/2)*2,%sformat=%s%s%s",
|
||||
tonemap, pixFormat, colorTail, hwUploadTail,
|
||||
)
|
||||
}
|
||||
args = append(args, "-vf", filterChain)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue