本文主要说明自托管媒体库(以 Octans 一类播放子系统为例)在协商 DirectPlay / DirectStream / Transcode 时,为何「能解码」不等于「能正确显示」:动态范围与色彩管线应作为独立事实进入 Planner,DirectStream 的视频 copy 不能自动修 HDR,tone mapping 属于完整转码,以及 Dolby Vision 为何必须按 profile / fallback 保守处理。

扫描阶段能标出「HDR10」「DV P8.1」很有价值,但播放侧真正危险的是另一类错误:API 成功、播放器起播、用户也能看到画面,颜色却已经错了——发灰、发淡、高光炸、暗部糊,或 Dolby Vision Profile 5 在不支持的链路上出现绿紫异常。根因通常不是容器或 H.264 认不出来,而是决策只看了:

container + videoCodec + audioCodec

却漏掉了动态范围、传递函数、色彩原色、位深、HDR 元数据与 DV profile。下面把问题收敛成媒体服务器可用的概念管线,而不是 HDR 标准百科。

四层兼容,不是一层「能不能播」

播放兼容性至少应拆成:

1. 容器兼容
2. 视频 / 音频解码兼容
3. 动态范围与色彩管线兼容
4. 字幕与输出策略兼容

前两层决定「有没有声画」;第三层决定「声画是否按制作意图落在正确的亮度与色域上」。Web 场景尤其容易踩坑:浏览器可能解码 10-bit HEVC / H.264 HDR,但显示器、OS、浏览器与 canPlayType() 并不能保证整条显示链路按 HDR 正确映射。

工程上一句话:

能解出帧 ≠ 客户端能正确呈现该 dynamicRange / color pipeline
  ≠ 服务端可以安全 remux / copy 该视频流

色彩事实模型:先拆三组,再谈策略

标题里的「色彩管线」是播放决策用的统称,不等于媒体字段里的 colorRange = limited / full。服务端在扫描、补强探针或播放协商阶段,至少应建立三组事实:

组别典型字段回答什么
动态范围dynamicRangehdrMetadataTypedolbyVisionProfile、fallback 标志SDR / HDR10 / HLG / DV 等是什么形态
色彩管线colorPrimariestransferFunctionmatrixCoefficientsBT.709 / BT.2020、PQ / HLG 等怎么解释像素
采样与量化pixelFormatbitDepthcolorRange8/10-bit、yuv420p 等如何采样

字段名表达方向即可,不必绑定某一版本 API。方向性枚举例如:

字段示例值
dynamicRangeSdrHdr10Hdr10PlusHlgDolbyVisionUnknown
transferFunctionbt709smpte2084(PQ)、arib-std-b67(HLG)
colorPrimariesbt709bt2020
dolbyVisionProfile578.18.2 等(展示与结构化字段应拆开)
fallbackhasHdr10FallbackhasSdrFallback

这些事实从哪来、如何保守分类、何时二次探针,属于扫描与轨事实层,见 媒体库轨识别与动态范围MediaInfo / ffprobe 分工。本文只消费结果:Planner 必须看见它们,而不能只看见 codec 字符串

客户端侧不能只靠 canPlayType

Web 能力探测建议组合多信号,而不是单一 MIME 断言:

来源作用边界
HTMLMediaElement.canPlayType()低层 MIME / codec 辅助,不能单独证明 HDR 显示正确
MediaCapabilities.decodingInfo()解码平滑度与功耗相关信号
CSS dynamic-range粗判 UA / 输出设备是否宣称高动态范围
用户设置允许关闭 HDR 直放、强制 SDR tone mapping
服务端策略未知 HDR / DV 默认不直放
可选真实短片探针用样片验证,而不是只信 API 字符串

在能力未验证前,未知按不支持处理比「能播就直放」更安全。

三条播放路径各自能改什么

路径典型动作对动态范围 / 色彩
DirectPlay原文件 HTTP 直出不改视频内容;要求客户端整条链路兼容
DirectStream视频 copy,容器 / 音频可调,常出 HLS不改视频动态范围;copy 前必须证明色彩仍安全
Transcode重解 / 滤镜 / 重编可做 HDR→SDR tone mapping 与色域转换

DirectPlay:条件要从三字段扩成五条件

不宜再只写:

containerSupported && videoCodecSupported && audioCodecSupported

更稳的门禁是:

containerSupported
&& videoCodecSupported
&& audioCodecSupported
&& dynamicRangeSupported
&& colorPipelineSupported

对当前以 Web SDR 为主 的媒体库主线,执行规则宜保守:

SDR
  → 继续按容器 / codec / 音频判断是否 DirectPlay

HDR / HLG / Dolby Vision
  → 不因「浏览器或许能解」就 DirectPlay
  → 无 tone mapping 能力时返回 RequiresToneMapping / UnsupportedDynamicRange

后续若开放 HDR 直放,应单独具备:客户端能力探针、显示链路确认、用户偏好、服务端策略与真实样例矩阵——而不是把 canPlayType('video/mp4; codecs=...') 当成色彩验收。

DirectStream:copy 解决不了 HDR 到 SDR

若第二层只是:

视频 copy +(音频 copy 或转 AAC)+ 容器进 HLS

则源视频的动态范围与色彩信息原样保留在视频流里。它能修的是容器、交付方式或音频兼容性,不能自动完成:

HDR / DV / BT.2020 / PQ / HLG  →  SDR / BT.709

因此:

  • 客户端不支持源 HDR / DV 形态时,应进入 Transcode + HLS + tone mapping
  • tone mapping 尚未就绪时,应返回明确失败原因,而不是「降级成 DirectStream 碰运气」;
  • 兼容性评估在视频 codec 之外,必须再判 dynamic range / color pipeline 是否可安全 copy。

Transcode:tone mapping 是视频处理,不是 remux

只要需要重算画面亮度与色域,就属于完整转码,占用视频处理资源,不应塞进 DirectStream。

概念管线:

源:HDR / DV / BT.2020 / PQ / HLG
  → 解码
  → tone mapping(动态范围落到 SDR)
  → 色彩转换(如 BT.2020 → BT.709)
  → 编码(如 H.264 + yuv420p + AAC)
  → HLS 交付
  → Web 播放器

普通转码阶段还应遵守:禁止把 HDR / DV 源静默当成 SDR 源硬编。没有 tone mapping 的「普通转码」会把错误色彩固化进输出。

硬件侧 VAAPI / OpenCL 如何选型、pure DOVI 与 HLG 如何分流,见 媒体库硬转码与 Tone Mapping。概念上软件侧常区分:

  • 非 DOVI HDR:常见 zscale + tonemap 一类路径(具体滤镜以运行时 FFmpeg 能力为准);
  • pure Dolby Vision(如 Profile 5):不能假装走「普通 HDR10 滤镜」;需要具备 DOVI reshaping / tonemapx 一类能力的构建,否则应明确 ToneMappingUnavailable

Web SDR 兜底输出基线

需要 tone mapping 时,面向浏览器的兜底输出宜固定,避免「只改编码器 tag、像素仍是 HDR 语义」:

输出项建议值
dynamicRangeSdr
colorPrimaries / transfer / matrixbt709
pixelFormatyuv420p
videoCodec / audioCodech264 / aac(按客户端基线)
deliveryHls
标记toneMapping: HdrToSdr

这是兼容兜底,不否定后续 HDR passthrough、HDR→HDR、HEVC/AV1 HLS 或 ABR。

决策矩阵(源 × 客户端 → 路径)

源媒体客户端 / 显示建议
SDR + 兼容容器 / 视音频普通 WebDirectPlay
SDR + 视频可解、容器或音频不兼容普通 WebDirectStream(视频 copy 安全)
HDR10 / HLG + 明确支持对应 HDR 输出已验证后续可评估直放 / copy;当前 Web SDR 主线宜先保守
HDR10 / HLG + 不支持或未知SDR 链路Transcode + tone mapping;无能力则明确失败
HDR10+不支持动态元数据有可消费 HDR10 降级则按 HDR10;否则转码或不支持
DV Profile 5(无兼容层)未明确支持该 profile不建议 DirectPlay;服务端 DV→SDR 或明确不支持
DV Profile 7.x / 8.1 + HDR10 fallback支持 HDR10 或仅 SDR可按 fallback 决策;SDR 主线按 fallback 再 tone map
DV Profile 8.2 + SDR fallback可确认 fallback可按 SDR Web 基线处理
DV profile / 能力未知未知不直放;UnsupportedDolbyVisionProfile
需要 tone map 但服务端无能力任意ToneMappingUnavailable,禁止静默直放或假普通转码

Dolby Vision:不能只标「是 HDR」

DV 决策至少要看见:

profile / level
单层还是双层
是否有 HDR10 / HLG / SDR fallback
RPU / 元数据是否可被当前工具链消费
当前客户端是否真支持该 profile

默认原则:

除非明确确认客户端支持该 Dolby Vision profile,
否则不要把 DV 判成安全 DirectPlay。

有 HDR10 fallback 时可按 HDR10 路径决策;无 fallback 且客户端不明确支持时,只能 tone mapping 或返回明确错误。Profile 数字与 compatibility id、level 的展示语义不要混用(例如 P8.1dvhe.08.06 不是同一套「小数」含义)——扫描侧的拆分原则见轨与动态范围文,播放侧只要求:结构化事实够用,且未知时宁可不直放

PlayInfo 与失败原因要可观测

协商结果除了 method / delivery,建议同时暴露:

  • 媒体侧:源 dynamicRange、primaries / transfer / matrix、bitDepth、DV profile、fallback;
  • 输出侧:目标 dynamicRange、是否 tone mapping、输出色彩基线。

失败时避免模糊的「不支持播放」,可区分例如:

原因方向含义
UnsupportedDynamicRange客户端 / 策略不接受源动态范围
UnsupportedColorPrimaries / UnsupportedTransferFunction色彩管线不兼容
UnsupportedDolbyVisionProfile该 DV profile 不可安全直放
RequiresToneMapping需要服务端 tone map 才能正确显示
ToneMappingUnavailable需要 tone map 但运行时无此能力
DolbyVisionFallbackUnavailable无可用 fallback 且不能原生播

配置层方向性默认:未知 HDR / 未知 DV 不直放;Web 主线默认关闭「能力声称支持就 HDR 直放」;用户可强制 HDR→SDR;tone mapping 关闭时返回明确错误,而不是静默 copy。

最小验收样例(概念)

实现或回归时,至少覆盖:

样例期望方向
MP4 + H.264 + AAC + SDRDirectPlay
同封装 + HDR10,客户端 HDR 未知转码 tone map 或明确不支持,不是盲目 DirectPlay
MKV + 可解视频 + HDR,仅需改容器不应因 codec 可解就 DirectStream copy
DV Profile 5不 DirectPlay;有 tonemap 能力则服务端 DV→SDR
DV + HDR10 fallback按 fallback 决策,而非一律当 pure DV 或一律当 SDR
需要 tone map 但能力关闭 / 滤镜缺失ToneMappingUnavailable

和相邻文章的边界

本文不写什么去哪看
播放协商中的动态范围 / 色彩门禁与路径归属轨名启发式、stream index、分层探针细节轨识别与动态范围
为何 copy ≠ tone map、SDR 输出基线VAAPI / OpenCL 命令模板与 GPU 矩阵硬转码与 Tone Mapping
事实从探测进入 Planner 的消费关系MediaInfo vs ffprobe 速度与字段面对比探测选型

注意事项

  1. 本文是播放侧概念管线与决策口径,不是某一版本 API 契约,也不是 HDR 标准全书。
  2. 「浏览器解出画面」不能作为 DirectPlay 色彩验收通过的唯一证据。
  3. DirectStream 只解决 remux / 音频 / 交付,不解决 HDR→SDR。
  4. 无 tone mapping 时,宁可明确失败,也不要静默直放或把 HDR 当 SDR 硬转。
  5. Dolby Vision 必须带 profile / fallback 语义;未知即不直放。
  6. 内网样片路径、私有 FFmpeg 构建细节与对象存储位置不进入公开复现步骤。

相关阅读

同系列还可对照:

来源

本文综合改写自 Octans 项目研究文档中关于播放动态范围与色彩管线的专题结论(DirectPlay / DirectStream / Transcode 边界、色彩事实模型、DV 保守原则、tone mapping 归属与 Web SDR 输出基线),并与播放能力决策、DirectPlay 色彩安全及转码运行时计划中的同步口径对齐。实现类名、内网样片与版本号已抽象为通用工程表述;具体能力以目标 FFmpeg runtime 与客户端复测为准。