8.2.6 HDR 渲染:色调映射入门(HDR & Tone Mapping)

8.2.4 的渲染管线有一个未经声明的前提:画面遵循 BT.709 的色彩体系,亮度上限大约 100 nits。这个前提统治了显示工业几十年,直到 HDR 内容的普及把它打破。今天的片源越来越多地带着另一套参数抵达播放器,本节的任务,就是讲清这套新参数是什么,以及播放器该如何对待它。

HDR(High Dynamic Range,高动态范围) 指一组超越 BT.709 体系的画面描述能力。它并不是简单的"更亮",而是三个维度的同步拓宽 [11]

维度 SDR(BT.709 体系) HDR(BT.2100 体系)
传递函数 gamma ≈ 2.4 PQ 或 HLG
色域 BT.709 BT.2020(可装下 Display P3)
位深 / 峰值亮度 8 bit / 约 100 nits 10 bit / 1000~10000 nits

第二章讲色度学时我们建立过色域的概念,BT.2020 的三角形比 BT.709 大出整整一圈。而亮度维度的拓宽更激进:SDR 里最白的白约 100 nits,HDR 内容里一盏太阳灯可以标到 4000 nits。问题是,观众手里的屏幕未必跟得上,于是一套新的矛盾登场了。

PQ 与 HLG:两条传递函数路线

HDR 的亮度编码有两条路线,哲学截然不同 [11]

PQ(Perceptual Quantizer,感知量化) 由 SMPTE ST 2084 定义,是一条绝对亮度曲线:码值直接映射到物理亮度,上限 10000 nits [12]。它的电光转换逆函数写作:

L=(max(V1/m2c1, 0)c2c3V1/m2)1/m1 L = \left( \frac{\max\left( V^{1/m_2} - c_1,\ 0 \right)}{c_2 - c_3 \cdot V^{1/m_2}} \right)^{1/m_1}

其中 m1=2610/16384m_1 = 2610/16384m2=2523/32m_2 = 2523/32c1=3424/4096c_1 = 3424/4096c2=2413/128c_2 = 2413/128c3=2392/128c_3 = 2392/128VV 为归一化码值,LL 为归一化亮度(1.0 对应 10000 nits)。绝对体系的好处是创作意图精确:调色师说 1000 nits,就是 1000 nits;代价是显示端若够不到这个亮度,必须有人来决定怎么办,元数据为此而生。

HLG(Hybrid Log-Gamma,混合对数伽马) 由 BBC 与 NHK 联合提出,是一条相对亮度曲线:低半段走伽马、高半段走对数,码值表达的是相对亮度关系,不需要任何元数据 [11]。HLG 信号落在 SDR 电视上也能正常显示,只是高光层次被自然压缩,这个"向后兼容"的特性让它成为广播电视的宠儿。路线之争的实质是场景之争:影视点播要忠实还原创作意图,选 PQ;直播广播要一条信号喂饱新旧所有电视,选 HLG。

三种内容形态:元数据的贫富

传递函数之上,内容形态按元数据的贫富分三档:

  • HDR10:PQ + BT.2020 + 静态元数据。整部影片共享一组数字:调色显示器的参数(ST 2086),外加两个内容统计量,MaxCLL(全片最亮像素的亮度)与 MaxFALL(最高的单帧平均亮度)[13]。显示端拿着这组数字,决定把多亮的内容滚降到自己的能力范围内
  • HDR10+ / Dolby Vision动态元数据,逐场景甚至逐帧更新亮度统计(SMPTE ST 2094 系列)。静态元数据被迫用全片最亮的一帧代表所有场景,暗场戏因此吃亏;动态元数据让每个场景各报各的数。Dolby Vision 走得更远,码流分基线层与增强层,附一份私有的 RPU 动态元数据,全链路受控,代价是设备厂商要交授权费
  • HLG 内容:无元数据,如前述

元数据的用途值得说透:它不是用来"增强"画面的,而是用来降级的。调色母版在 1000~4000 nits 的监视器上完成,观众电视可能只有 500 nits,元数据告诉电视内容的亮度分布长什么样,电视据此设计自己的滚降曲线,尽量少牺牲一点创作意图。

色调映射:把大世界装进小屏幕

当 HDR 内容遇上 SDR 屏幕(或亮度不够的 HDR 屏幕),播放器或显示端必须执行 色调映射(Tone Mapping):把宽亮度域、宽色域的内容,压缩进显示设备的能力圈。

最粗暴的做法是硬裁剪,超过屏幕能力的亮度一律削平,高光糊成一片,暗部压成一团。体面的做法是一条带肩部滚降的映射曲线:中低亮度尽量保真,接近峰值时温柔地压缩。ITU-R BT.2390 给出了一条参考曲线(EETF),工程界常用的算法族还有 Reinhard、Hable、ACES,以及 ITU-R BT.2446 为 HDR 与 SDR 互转定义的三套方法 [14]

色调映射之外还有一步容易漏掉的操作:色域转换。BT.2020 的像素值直接当 BT.709 显示,颜色会发灰发淡,必须过一道转换矩阵(ITU-R BT.2087 给出的系数):

[R709G709B709]=[1.66050.58760.07290.12461.13290.00830.01820.10061.1187][R2020G2020B2020] \begin{bmatrix} R_{709} \\ G_{709} \\ B_{709} \end{bmatrix} = \begin{bmatrix} 1.6605 & -0.5876 & -0.0729 \\ -0.1246 & \phantom{-}1.1329 & -0.0083 \\ -0.0182 & -0.1006 & \phantom{-}1.1187 \end{bmatrix} \begin{bmatrix} R_{2020} \\ G_{2020} \\ B_{2020} \end{bmatrix}

两步的顺序不可颠倒:先在线性光域做色调映射,再转色域、加伽马。跳过任何一步,结果就是我们熟悉的"HDR 转 SDR 翻车现场":画面发灰、高光裁切、暗部死黑。FFmpeg 里一条 zscaletonemap 滤镜链可以完成整套流程,GPU 侧则有 libplacebo 这样的现代实现 [1]

播放器的两种角色

面对 HDR 内容,播放器要做一道选择题。透传:如果显示链路支持 HDR(HDMI 2.0a 之后的接口、系统级 HDR 开关),播放器把 PQ/HLG 信号连同元数据原样交给显示设备,映射由电视完成,这是最保真的路径。自映射:如果屏幕是 SDR 的,播放器就得自己执行色调映射与色域转换,8.2.4 的色彩转换环节在此升级为 HDR 版本。判断走哪条路的前提,是正确读取码流里的色彩信息,传递函数、色域、元数据,一样都不能漏读。

至此,8.2 的版图扩到了六块:水位、主时钟、缓冲、渲染,加上字幕与 HDR 这两条常客的进阶支线。纸上得来终觉浅,8.3 我们亲手把这些零件装成整机:用 PyAV 造一台两百行的简易播放器,再让实测数据替 8.2.2 的同步理论作证。

Copyright © Since 2021 李述博 (Arikan.Li) , All Rights Reserved all right reserved,powered by GitbookLast Updated: 2026-08-27 21:51:22

results matching ""

    No results matching ""