高动态范围 (HDR) 视频是高品质视频解码的下一个前沿领域,可带来无与伦比的场景再现质量。它通过大幅增加亮度分量的动态范围(从目前的 100 cd/m 2 增加到 1000 多 cd/m 2 )并使用更宽广的色彩空间 (BT 2020) 来实现这一目标。这现在是电视领域 4K UHD 演进的核心要素。
Android 10 支持以下 HDR 视频。
- HDR10
- VP9
- HDR10+
从 Android 9 及更高版本开始,MediaCodec 会报告 HDR 元数据,无论是否处于隧道模式。您可以在非隧道模式下获取解码后的数据以及静态/动态元数据。对于使用静态元数据的 HDR10 和 VP9Profile2,这些元数据会在输出格式中通过键 KEY_HDR_STATIC_INFO
进行报告。对于使用动态元数据的 HDR10+,则会在输出格式中通过键 KEY_HDR10_PLUS_INFO
进行报告,并且可能针对每个输出帧发生变化。如需了解详情,请参阅多媒体隧道传输。
自 Android 7.0 起,初始 HDR 支持包括为 HDR 视频管道的发现和设置创建适当的常量。这意味着定义编解码器类型和显示模式,并指定 HDR 数据必须如何传递到 MediaCodec 并提供给 HDR 解码器。
本文档的目的是帮助应用开发者支持 HDR 流播放,并帮助 OEM 和 SOC 启用 HDR 功能。
受支持的 HDR 技术
从 Android 7.0 及更高版本开始,支持以下 HDR 技术。
技术 | Dolby-Vision | HDR10 | VP9-HLG | VP9-PQ |
---|---|---|---|---|
编解码器 | AVC/HEVC | HEVC | VP9 | VP9 |
传输函数 | ST-2084 | ST-2084 | HLG | ST-2084 |
HDR 元数据类型 | 动态 | 静态 | 无 | 静态 |
在 Android 7.0 中, 仅定义了通过隧道模式进行的 HDR 播放 ,但设备可能会添加对使用不透明视频缓冲区的 SurfaceView 上 HDR 播放的支持。换句话说
- 没有标准的 Android API 来检查是否支持使用非隧道解码器的 HDR 播放。
- 声明具有 HDR 播放能力的隧道视频解码器在连接到支持 HDR 的显示屏时,必须支持 HDR 播放。
- AOSP Android 7.0 版本不支持 HDR 内容的 GL 合成。
发现
HDR 播放需要支持 HDR 的解码器和与支持 HDR 的显示屏的连接。或者,某些技术需要特定的提取器。
显示
应用应使用新的 Display.getHdrCapabilities
API 来查询指定显示屏支持的 HDR 技术。这基本上是 CTA-861.3 中定义的 EDID 静态元数据数据块中的信息
public Display.HdrCapabilities getHdrCapabilities()
返回显示屏的 HDR 功能。Display.HdrCapabilities
封装给定显示屏的 HDR 功能。例如,它支持哪些 HDR 类型以及有关所需亮度数据的详细信息。
常量
int HDR_TYPE_DOLBY_VISION
Dolby Vision 支持。int HDR_TYPE_HDR10
HDR10 / PQ 支持。int HDR_TYPE_HDR10_PLUS
HDR10+ 支持。int HDR_TYPE_HLG
混合对数伽玛支持。float INVALID_LUMINANCE
无效的亮度值。
公共方法
float getDesiredMaxAverageLuminance()
返回此显示屏所需的平均帧最大亮度数据(单位为 cd/cd/m 2 )。float getDesiredMaxLuminance()
返回此显示屏所需的最大亮度数据(单位为 cd/cd/m 2 )。float getDesiredMinLuminance()
返回此显示屏所需的最小亮度数据(单位为 cd/cd/m 2 )。int[] getSupportedHdrTypes()
获取此显示屏支持的 HDR 类型(请参阅常量)。如果显示屏不支持 HDR,则返回空数组。
解码器
应用应使用现有的 CodecCapabilities.profileLevels
API 来验证对新的支持 HDR 的配置文件的支持
Dolby-Vision
MediaFormat
mime 常量
String MIMETYPE_VIDEO_DOLBY_VISION
MediaCodecInfo.CodecProfileLevel
配置文件常量
int DolbyVisionProfileDvavPen int DolbyVisionProfileDvavPer int DolbyVisionProfileDvheDen int DolbyVisionProfileDvheDer int DolbyVisionProfileDvheDtb int DolbyVisionProfileDvheDth int DolbyVisionProfileDvheDtr int DolbyVisionProfileDvheStn
Dolby Vision 视频层和元数据必须由视频应用连接到每个帧的单个缓冲区中。这由支持 Dolby Vision 的 MediaExtractor 自动完成。
HEVC HDR 10
MediaCodecInfo.CodecProfileLevel
配置文件常量
int HEVCProfileMain10HDR10 int HEVCProfileMain10HDR10Plus
VP9 HLG 和 PQ
MediaCodecInfo.CodecProfileLevel
配置文件常量
int VP9Profile2HDR int VP9Profile2HDR10Plus int VP9Profile3HDR int VP9Profile3HDR10Plus
如果平台支持支持 HDR 的解码器,则还应支持支持 HDR 的提取器。
只有隧道解码器才能保证播放 HDR 内容。通过非隧道解码器播放可能会导致 HDR 信息丢失,并且内容被展平为 SDR 色容积。
提取器
Android 7.0 上的各种 HDR 技术支持以下容器
技术 | Dolby-Vision | HDR10 | VP9-HLG | VP9-PQ |
---|---|---|---|---|
容器 | MP4 | MP4 | WebM | WebM |
平台不支持发现轨道(文件)是否需要 HDR 支持。应用可以解析编解码器特定的数据,以确定轨道是否需要特定的 HDR 配置文件。
摘要
下表显示了每种 HDR 技术的组件要求
技术 | Dolby-Vision | HDR10 | VP9-HLG | VP9-PQ |
---|---|---|---|---|
支持的 HDR 类型(显示屏) | HDR_TYPE_DOLBY_VISION | HDR_TYPE_HDR10 | HDR_TYPE_HLG | HDR_TYPE_HDR10 |
容器(提取器) | MP4 | MP4 | WebM | WebM |
解码器 | MIMETYPE_VIDEO_DOLBY_VISION | MIMETYPE_VIDEO_HEVC | MIMETYPE_VIDEO_VP9 | MIMETYPE_VIDEO_VP9 |
配置文件(解码器) | 其中一个 Dolby 配置文件 | HEVCProfileMain10HDR10 | VP9Profile2HDR 或 VP9Profile3HDR | VP9Profile2HDR 或 VP9Profile3HDR |
说明
- Dolby-Vision 比特流以 Dolby 定义的方式打包在 MP4 容器中。应用可以实现自己的 Dolby 功能提取器,只要它们按照 Dolby 的定义,将相应层中的访问单元打包到解码器的单个访问单元中。
- 平台可能支持支持 HDR 的提取器,但不支持相应的支持 HDR 的解码器。
播放
在应用验证了对 HDR 播放的支持后,它可以像播放非 HDR 内容一样播放 HDR 内容,但需注意以下事项
- 对于 Dolby-Vision,特定的媒体文件/轨道是否需要支持 HDR 的解码器不是立即可用的。应用必须提前掌握此信息,或者能够通过解析 MediaFormat 的编解码器特定数据部分来获取此信息。
CodecCapabilities.isFormatSupported
不考虑支持此类配置文件是否需要隧道解码器功能。
启用 HDR 平台支持
SoC 供应商和 OEM 必须执行额外的工作,才能为设备启用 HDR 平台支持。
Android 7.0 中针对 HDR 的平台变更
以下是 OEM 和 SOC 需要注意的平台(应用/原生层)中的一些主要变更。
显示
硬件合成
支持 HDR 的平台必须支持将 HDR 内容与非 HDR 内容混合。Android 7.0 版本未定义确切的混合特性和操作,但该过程通常遵循以下步骤
- 根据图层的颜色、母带制作和潜在的动态元数据,确定包含要合成的所有图层的线性色彩空间/容积。
如果直接合成到显示屏,则这可能是与显示屏的色容积相匹配的线性空间。 - 将所有图层转换为通用色彩空间。
- 执行混合。
- 如果通过 HDMI 显示
- 确定混合场景的颜色、母带制作和潜在的动态元数据。
- 将生成的混合场景转换为导出的色彩空间/容积。
- 如果直接显示到显示屏,则将生成的混合场景转换为生成该场景所需的显示屏信号。
显示屏发现
HDR 显示屏发现仅通过 HWC2 支持。设备实现者必须有选择地启用随 Android 7.0 发布的 HWC2 适配器,此功能才能正常工作。因此,平台必须添加对 HWC2 的支持,或扩展 AOSP 框架,以允许提供此信息的方式。HWC2 公开了一个新的 API,用于将 HDR 静态数据传播到框架和应用。
HDMI
- 连接的 HDMI 显示屏通过 HDMI EDID 声明其 HDR 功能,如 CTA-861.3 第 4.2 节中所定义。
- 应使用以下 EOTF 映射
- ET_0 传统伽玛 - SDR 亮度范围:未映射到任何 HDR 类型
- ET_1 传统伽玛 - HDR 亮度范围:未映射到任何 HDR 类型
- ET_2 SMPTE ST 2084 - 映射到 HDR 类型 HDR10
- 通过 HDMI 发出 Dolby Vision 或 HLG 支持信号,按照其相关机构的定义完成。
- 请注意,HWC2 API 使用浮点型所需亮度值,因此必须以适当的方式转换 8 位 EDID 值。
解码器
平台必须添加支持 HDR 的隧道解码器并声明其 HDR 支持。通常,支持 HDR 的解码器必须
- 支持隧道解码 (
FEATURE_TunneledPlayback
)。 - 支持 HDR 静态元数据 (
OMX.google.android.index.describeHDRColorInfo
) 及其向显示屏/硬件合成的传播。对于 HLG,必须将适当的元数据提交到显示屏。 - 支持颜色描述 (
OMX.google.android.index.describeColorAspects
) 及其向显示屏/硬件合成的传播。 - 支持 HDR 嵌入式元数据,如相关标准所定义。
Dolby Vision 解码器支持
为了支持 Dolby Vision,平台必须添加支持 Dolby-Vision 的 HDR OMX 解码器。考虑到 Dolby Vision 的具体细节,这通常是围绕一个或多个 AVC 和/或 HEVC 解码器以及合成器的封装解码器。此类解码器必须
- 支持 mime 类型“video/dolby-vision”。
- 声明支持的 Dolby Vision 配置文件/级别。
- 接受包含所有图层的子访问单元的访问单元,如 Dolby 所定义。
- 接受 Dolby 定义的编解码器特定数据。例如,包含 Dolby Vision 配置文件/级别的数据,以及内部解码器的编解码器特定数据。
- 支持 Dolby 定义的 Dolby Vision 配置文件/级别之间的自适应切换。
配置解码器时,实际的 Dolby 配置文件不会传达给编解码器。这仅在解码器启动后通过编解码器特定数据完成。平台可以选择支持多个 Dolby Vision 解码器:一个用于 AVC 配置文件,另一个用于 HEVC 配置文件,以便能够在配置期间初始化底层编解码器。如果单个 Dolby Vision 解码器支持这两种类型的配置文件,则它还必须支持以自适应方式动态地在这些配置文件之间切换。
如果平台除了通用 HDR 解码器支持之外还提供支持 Dolby-Vision 的解码器,则它必须
- 提供支持 Dolby-Vision 的提取器,即使它不支持 HDR 播放。
- 提供支持 Dolby 定义的 vision 配置文件的解码器。
HDR10 解码器支持
为了支持 HDR10,平台必须添加支持 HDR10 的 OMX 解码器。这通常是隧道 HEVC 解码器,它还支持解析和处理 HDMI 相关元数据。此类解码器(除了通用 HDR 解码器支持之外)必须
- 支持 mime 类型“video/hevc”。
- 声明支持的 HEVCMain10HDR10。HEVCMain10HRD10 配置文件支持还需要支持 HEVCMain10 配置文件,而这需要支持相同级别的 HEVCMain 配置文件。
- 支持解析母带制作元数据 SEI 块,以及 SPS 中包含的其他 HDR 相关信息。
VP9 解码器支持
为了支持 VP9 HDR,平台必须添加支持 VP9 Profile2 的 HDR OMX 解码器。这通常是隧道 VP9 解码器,它还支持处理 HDMI 相关元数据。此类解码器(除了通用 HDR 解码器支持之外)必须
- 支持 mime 类型“video/x-vnd.on2.vp9”。
- 声明支持的 VP9Profile2HDR。VP9Profile2HDR 配置文件支持还需要支持相同级别的 VP9Profile2 配置文件。
提取器
Dolby Vision 提取器支持
支持 Dolby Vision 解码器的平台必须为 Dolby 视频内容添加 Dolby 提取器(称为 Dolby Extractor)支持。
- 常规 MP4 提取器只能从文件中提取基本层,而不能提取增强层或元数据层。因此,需要特殊的 Dolby 提取器来从文件中提取数据。
- Dolby 提取器必须为每个 Dolby 视频轨道(组)公开 1 到 2 个轨道
- 具有“video/dolby-vision”类型的 Dolby Vision HDR 轨道,用于组合的 2/3 层 Dolby 流。HDR 轨道的访问单元格式(用于定义如何将基本/增强/元数据层中的访问单元打包到单个缓冲区中,以解码为单个 HDR 帧)将由 Dolby 定义。
- 如果 Dolby Vision 视频轨道包含单独的(向后兼容)基本层 (BL),则提取器还必须将其作为单独的“video/avc”或“video/hevc”轨道公开。提取器必须为此轨道提供常规 AVC/HEVC 访问单元。
- BL 轨道必须具有与 HDR 轨道相同的轨道唯一 ID (“track-ID”),以便应用了解这是同一视频的两种编码。
- 应用可以根据平台的功能决定选择哪个轨道。
- Dolby Vision 配置文件/级别必须在 HDR 轨道的轨道格式中公开。
- 如果平台提供支持 Dolby-Vision 的解码器,则即使它不支持 HDR 播放,也必须提供支持 Dolby-Vision 的提取器。
HDR10 和 VP9 HDR 提取器支持
支持 HDR10 或 VP9 HLG 没有额外的提取器要求。平台必须扩展 MP4 提取器以支持 MP4 中的 VP9 PQ。HDR 静态元数据必须在 VP9 PQ 比特流中传播,以便此元数据通过正常的 MediaExtractor => MediaCodec 管道传递到 VP9 PQ 解码器和显示屏。
Stagefright 扩展,用于 Dolby Vision 支持
平台必须将 Dolby Vision 格式支持添加到 Stagefright
- 支持压缩端口的端口定义查询。
- 支持 DV 解码器的配置文件/级别枚举。
- 支持公开 DV HDR 轨道的 DV 配置文件/级别。
特定于技术的实现细节
HDR10 解码器管道
图 1. HDR10 管道
HDR10 比特流打包在 MP4 容器中。应用使用常规 MP4 提取器来提取帧数据并将其发送到解码器。
- MPEG4 提取器
HDR10 比特流被 MPEG4Extractor 识别为普通 HEVC 流,并将提取类型为“video/HEVC”的 HDR 轨道。框架选择支持 Main10HDR10 配置文件的 HEVC 视频解码器来解码该轨道。 - HEVC 解码器
HDR 信息位于 SEI 或 SPS 中。HEVC 解码器首先接收包含 HDR 信息的帧。然后,解码器提取 HDR 信息并通知应用它正在解码 HDR 视频。HDR 信息被捆绑到解码器输出格式中,稍后会传播到 Surface。
供应商操作
- 声明支持的 HDR 解码器配置文件和级别 OMX 类型。示例
OMX_VIDEO_HEVCProfileMain10HDR10
(和Main10
) - 实现对索引的支持:'
OMX.google.android.index.describeHDRColorInfo
' - 实现对索引的支持:'
OMX.google.android.index.describeColorAspects
' - 实现对母带制作元数据的 SEI 解析的支持。
Dolby Vision 解码器管道
图 2. Dolby Vision 管道
Dolby 比特流按照 Dolby 的定义打包在 MP4 容器中。从理论上讲,应用可以使用常规 MP4 提取器来独立提取基本层、增强层和元数据层;但是,这不符合当前的 Android MediaExtractor/MediaCodec 模型。
- DolbyExtractor
- Dolby 比特流由 DolbyExtractor 识别,后者为每个杜比视频轨道(组)公开 1 到 2 个轨道
- 具有“video/dolby-vision”类型的 HDR 轨道,用于组合的 2/3 层杜比流。HDR 轨道的访问单元格式(用于定义如何将基本/增强/元数据层中的访问单元打包到单个缓冲区中,以解码为单个 HDR 帧)将由 Dolby 定义。
- (可选,仅当 BL 向后兼容时)BL 轨道仅包含基本层,该基本层必须可由常规 MediaCodec 解码器(例如,AVC/HEVC 解码器)解码。提取器应为此轨道提供常规 AVC/HEVC 访问单元。此 BL 轨道必须具有与 Dolby 轨道相同的轨道唯一 ID (“track-ID”),以便应用了解这是同一视频的两种编码。
- 应用可以根据平台的功能决定选择哪个轨道。
- 由于 HDR 轨道具有特定的 HDR 类型,因此框架将选择 Dolby 视频解码器来解码该轨道。BL 轨道将由常规 AVC/HEVC 视频解码器解码。
- Dolby 比特流由 DolbyExtractor 识别,后者为每个杜比视频轨道(组)公开 1 到 2 个轨道
- DolbyDecoder
- DolbyDecoder 接收包含所有层(EL+BL+MD 或 BL+MD)的所需访问单元的访问单元
- 各个层的 CSD(编解码器特定数据,例如 SPS+PPS+VPS)信息可以打包到 1 个 CSD 帧中,由 Dolby 定义。需要有一个 CSD 帧。
Dolby 操作
- 定义各种 Dolby 容器方案(例如 BL+EL+MD)的访问单元的打包,以用于抽象 Dolby 解码器(即 HDR 解码器期望的缓冲区格式)。
- 定义抽象 Dolby 解码器的 CSD 打包。
供应商操作
- 实现 Dolby 提取器。这也可以由 Dolby 完成。
- 将 DolbyExtractor 集成到框架中。入口点是
frameworks/av/media/libstagefright/MediaExtractor.cpp
。 - 声明 HDR 解码器配置文件和级别 OMX 类型。示例:
OMX_VIDEO_DOLBYPROFILETYPE
和OMX_VIDEO_DOLBYLEVELTYP
。 - 实现对索引的支持:
'OMX.google.android.index.describeColorAspects
' - 将动态 HDR 元数据传播到每个帧中的应用和 Surface。通常,此信息必须按照 Dolby 的定义打包到解码帧中,因为 HDMI 标准未提供将此信息传递到显示屏的方式。
VP9 解码器管道
图 3. VP9-PQ 管道
VP9 比特流以 WebM 团队定义的方式打包在 WebM 容器中。应用需要使用 WebM 提取器从比特流中提取 HDR 元数据,然后再将帧发送到解码器。
- WebM 提取器
- VP9 解码器
- 解码器接收 Profile2 比特流并将它们解码为普通 VP9 流。
- 解码器从框架接收任何 HDR 静态元数据。
- 解码器通过 VP9 PQ 流的比特流访问单元接收静态元数据。
- VP9 解码器必须能够将 HDR 静态/动态元数据传播到显示屏。
供应商操作
- 实现对索引的支持:
OMX.google.android.index.describeHDRColorInfo
- 实现对索引的支持:
OMX.google.android.index.describeColorAspects
- 传播 HDR 静态元数据