4. HDR 视频基础:HDR 标准概览

做 8K HDR 编码,绕不开 HDR 标准。说实话,我刚接触 HDR 时也被一堆名词搞晕过——HDR10、HLG、Dolby Vision,还有 PQ 曲线、HLG 曲线,再加上 SMPTE ST 2086、MaxFALL、MaxCLL 这些元数据。今天咱们把这些东西理清楚。

4.1 三大 HDR 标准:HDR10、HLG、Dolby Vision

目前主流 HDR 标准就三个。我习惯把它们分成两类:静态元数据和动态元数据。

标准 元数据方式 传输曲线 色深 典型应用
HDR10 静态(整部影片一套) PQ(ST 2084) 10-bit 蓝光、流媒体、YouTube
HLG 无元数据(兼容 SDR) HLG(ARIB STD-B67) 10-bit 广播电视、直播
Dolby Vision 动态(逐场景) PQ(ST 2084) 12-bit 影院、高端流媒体

HDR10 是最基础的。它是开放标准,所有 HDR 设备都支持。但它的元数据是静态的——整部影片只给一组亮度、色域信息。我在项目里遇到过一个问题:一部电影有的场景很亮,有的很暗,HDR10 只能取一个折中值,暗场细节可能就丢了。

HLG 是 BBC 和 NHK 搞的。它最大的特点是兼容 SDR 显示设备。你想想看,电视台不可能让观众换电视才能看 HDR 节目。HLG 的信号在 SDR 电视上显示正常,在 HDR 电视上显示高动态范围。我参与过几个广电项目,HLG 在直播场景下确实省心——不需要元数据,直接推流就行。

Dolby Vision 是杜比家的,动态元数据是它的杀手锏。它会分析每个场景甚至每帧的亮度信息,逐场景调整映射。效果确实好,但需要授权费。我记得有一次对比测试,同一部片子用 HDR10 和 Dolby Vision 分别编码,暗部细节差距肉眼可见。

核心结论:做 8K HDR 编码,HDR10 是底线支持,HLG 适合广电场景,Dolby Vision 追求极致画质。AV1 编码器对这三种标准都支持,但元数据传递方式有差异,后面章节会细讲。

4.2 PQ 与 HLG 曲线

HDR 和 SDR 最大的区别是什么?亮度范围。SDR 只有 0.1~100 cd/m²,HDR 能到 0.005~10,000 cd/m²。但 10-bit 只有 1024 个灰度级,怎么分配这些亮度值?这就靠 电光转换函数(EOTF) 了。

4.2.1 PQ 曲线(Perceptual Quantizer)

PQ 曲线是 SMPTE ST 2084 标准定义的。它的核心思想是:人眼对暗部变化更敏感,对亮部变化不敏感。所以 PQ 曲线在暗部分配更多码值,亮部分配更少。

PQ 曲线的数学表达式是这样的:

L = ((max(L_pq^(1/m2) - c1, 0)) / (c2 - c3 * L_pq^(1/m2)))^(1/m1)

其中:
L_pq = 归一化的电信号值(0~1)
L = 亮度值(cd/m²)
m1 = 2610/4096 × 1/4 ≈ 0.1593
m2 = 2523/4096 × 128 ≈ 78.8438
c1 = 3424/4096 = 0.8359
c2 = 2413/4096 × 32 ≈ 18.8516
c3 = 2392/4096 × 32 ≈ 18.6875

嗯,公式看着复杂。但你只要记住:PQ 曲线是亮度映射。什么意思?一个 PQ 码值对应一个亮度值,不管显示设备是什么。比如 PQ 码值 512 对应约 100 cd/m²,在任何 PQ 显示器上都一样。

我的经验:做 8K HDR 编码时,PQ 曲线对码率分配影响很大。暗部细节多的地方需要更多码率,因为 PQ 在暗部分配了更多码值。我曾经在编码一个夜景场景时,默认码率控制导致暗部出现条带,后来调整了码率分配策略才解决。

4.2.2 HLG 曲线(Hybrid Log-Gamma)

HLG 曲线是另一种思路。它把信号分成两部分:

  • 对数部分(Log):处理高光区域
  • 伽马部分(Gamma):处理暗部区域

HLG 的数学表达式相对简单:

E' = sqrt(3 * E)  for 0 ≤ E ≤ 1/12
E' = a * ln(12 * E - b) + c  for 1/12 < E ≤ 1

其中:
a = 0.17883277
b = 0.28466892
c = 0.55991073

HLG 和 PQ 最大的区别:HLG 是相对亮度映射。它不指定亮度值,而是根据显示设备的能力自适应。SDR 电视看到 SDR 效果,HDR 电视看到 HDR 效果。这也是为什么 HLG 不需要元数据。

特性 PQ(ST 2084) HLG
亮度映射方式 亮度 相对亮度
峰值亮度 10,000 cd/m² 取决于设备(通常 1,000~2,000)
SDR 兼容性 不兼容 原生兼容
元数据需求 需要 不需要
典型应用 流媒体、蓝光 广播电视、直播

注意:HLG 虽然兼容 SDR,但 HDR 效果上限受限于显示设备。如果显示设备峰值亮度只有 400 cd/m²,HLG 的高光细节就出不来。PQ 则能保证内容创作者意图的亮度映射,前提是显示设备支持。

4.3 HDR 元数据:SMPTE ST 2086、MaxFALL、MaxCLL

元数据是 HDR 的「说明书」。显示设备靠它知道怎么正确显示 HDR 内容。HDR10 使用静态元数据,Dolby Vision 使用动态元数据。咱们先看静态元数据的三要素。

4.3.1 SMPTE ST 2086(Mastering Display Color Volume)

这个元数据描述的是调色监视器的能力。包含三个信息:

  • 主色度(Primaries):调色监视器的 R/G/B 色坐标
  • 白点(White Point):通常 D65
  • 最大亮度(MaxLum)和最小亮度(MinLum):调色监视器的亮度范围

举个例子:

Mastering display color volume:
  Primaries (x, y):
    R: (0.708, 0.292)
    G: (0.170, 0.797)
    B: (0.131, 0.046)
  White point (x, y): (0.3127, 0.3290)
  Max luminance: 1000 cd/m²
  Min luminance: 0.005 cd/m²

这个信息有什么用?显示设备可以根据它做色域映射。如果你的电视色域比调色监视器小,就需要把超出部分映射到可显示范围。我见过一些低端电视直接裁剪,导致颜色失真——这就是元数据没用好。

4.3.2 MaxFALL(Maximum Frame Average Light Level)

MaxFALL 是整部影片中,所有帧的平均亮度的最大值。计算方式:

  1. 对每一帧,计算所有像素亮度的平均值
  2. 取所有帧中这个平均值的最大值

这个值告诉显示设备:这部影片最亮的「平均场景」有多亮。显示设备可以用它来调整背光策略。比如 MaxFALL 是 400 cd/m²,电视就知道不需要全程开满背光。

4.3.3 MaxCLL(Maximum Content Light Level)

MaxCLL 是整部影片中,单个像素的最大亮度值。它代表影片的「峰值亮度」。比如一个爆炸场景中某个像素达到 1,000 cd/m²,MaxCLL 就是 1,000。

这两个值在编码时怎么用?我举个例子:

# 使用 FFmpeg 提取 HDR10 元数据
ffmpeg -i input.mkv -f lavfi -i "null" -vframes 1 -vf \
  "signalstats,metadata=print:file=-" -f null -

# 或者用 mediainfo 查看
mediainfo --Details=1 input.mkv | grep -i "max"

关键点:MaxFALL 和 MaxCLL 是内容分析出来的,不是调色师手动设置的。编码时如果这两个值设置不对,显示设备可能错误地调整亮度。我曾经遇到一个案例:MaxCLL 设得太低,导致高亮场景被削波;设得太高,又导致整体亮度被压低。正确做法是用工具逐帧分析。

4.4 HDR 元数据在 AV1 中的传递

AV1 编码时,HDR 元数据通过 SEI(Supplemental Enhancement Information) 消息传递。具体来说:

  • HDR10:使用 AV1 的 mastering_display_color_volume 和 content_light_level OBU(Open Bitstream Unit)
  • HLG:不需要元数据,但需要标记色彩原色和传输特性
  • Dolby Vision:使用 RPU(Reference Processing Unit)数据,通过私有 SEI 传递

用 SVT-AV1 编码 HDR10 内容的示例:

# 编码 HDR10 内容
SvtAv1EncApp -i input.y4m -b output.ivf \
  --color-primaries bt2020 \
  --transfer-characteristics smpte2084 \
  --matrix-coefficients bt2020-ncl \
  --mastering-display "G(0.170,0.797)B(0.131,0.046)R(0.708,0.292)WP(0.3127,0.3290)L(1000,0.005)" \
  --content-light "MaxFALL=400,MaxCLL=1000"

我的建议:编码前先用工具验证元数据是否正确。我习惯用 ffmpeg 的 showinfo 滤镜或者 exiftool 检查。元数据错了,解码端显示效果会出大问题——而且这种问题很难排查,因为编码过程没有报错。

HDR 视频基础知识体系 HDR 标准 HDR10(静态元数据) HLG(兼容 SDR) Dolby Vision(动态元数据) 传输曲线(EOTF) PQ(ST 2084)亮度 HLG(相对亮度) HDR 元数据 SMPTE ST 2086 MaxFALL MaxCLL AV1 编码中的 HDR 元数据传递 核心要点 • HDR10 用静态元数据,HLG 不需要元数据,Dolby Vision 用动态元数据 • PQ 是亮度映射,HLG 是相对亮度映射,应用场景不同

这张图把 HDR 基础的三块内容串起来了。左边是标准选择,中间是传输曲线,右边是元数据。这三块决定了你的 HDR 内容在编码端怎么处理、在解码端怎么显示。

避坑指南:我曾经在项目里遇到一个坑——编码时忘记设置 --color-primaries 和 --transfer-characteristics,结果解码器默认按 SDR 处理,颜色完全不对。HDR 编码时,色彩原色、传输特性、矩阵系数这三个参数必须显式设置,不要依赖默认值。