一个教你为 Chrome / Edge 启用 HEVC 硬解码 & 硬编码,或编译 Chromium / Electron 使其支持 HEVC 硬、软解码 & 硬编码功能的教程。
HEVC Main (最高支持 8192x8192 px)
HEVC Main 10 (最高支持 8192x8192 px)
HEVC Main Still Picture (最高支持 8192x8192 px)
HEVC Rext (部分支持,细节见下表,最高支持 8192x8192 px)
| GPU | 8b 420 | 8b 422 | 8b 444 | 10b 420 | 10b 422 | 10b 444 | 12b 420 | 12b 422 | 12b 444 |
|---|---|---|---|---|---|---|---|---|---|
| Apple Silicon (macOS) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ |
| Intel ICL ~ TGLx (Win) | ✅ | ✅[4] | ✅[3] | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ |
| Intel TGLx+ (Win) | ✅ | ✅[4] | ✅[3] | ✅ | ✅ | ✅ | ✅ | ✅[3] | ✅[3] |
| NVIDIA Turing ~ Ada (Win) | ✅[6] | ❌ | ✅[6] | ✅[6] | ❌ | ✅[6] | ✅[6] | ❌ | ✅[6] |
| NVIDIA Blackwell (Win) | ✅[6] | ✅[6] | ✅[6] | ✅[6] | ✅[6] | ✅[6] | ✅[6] | ✅[6] | ✅[6] |
✅:显卡+软件都支持 ❌:显卡不支持
注1:Intel Mac 支持软解 HEVC Rext 8 ~ 12b 400, 420, 422, 444 的内容。Apple Silicon Mac 支持硬解 HEVC Rext 8 ~ 10b 400, 420, 422, 444 的内容,软解 HEVC Rext 12b 400, 420, 422, 444 的内容。
注2:Intel 10 代 GPU 支持硬解 HEVC Rext 8b 420, 8b 422, 8b 444, 10b 420, 10b 422, 10b 444 的内容。11 代及以后的 GPU 还支持硬解 HEVC Rext 12b 420, 12b 422, 12b 444 的内容。
注3:Windows HEVC 8b 444, 12b 422, 12b 444 支持需要 Chrome >= 117.0.5866.0。
注4:Windows HEVC 8b 422 支持需要 Chrome >= 118.0.5956.0。
注5:保留原始 4:2:2/4:4:4 色度抽样, 需要 Chrome >= 125.0.6408.0。
注6:从 Chrome 137 开始,NVIDIA GPU 支持 HEVC Rext 8 ~ 12b 硬解码。(显卡驱动需要 572.16 或更高版本)
HEVC Main (macOS & Windows & Android, macOS 最高支持取决于硬件[4], Windows 最高支持取决于硬件[3], 安卓最高支持取决于硬件)
注1:Chrome >= 130.0.6703.0 默认启用,无需启动参数,< 130.0.6703.0 时需要通过 Chrome Switch(--enable-features=PlatformHEVCEncoderSupport)的方式测试使用,测试页面。
注2: Windows / Mac 须确保 Chrome 版本号 >= 109.0.5397.0,Android 须确保 Chrome 版本号 >= 117.0.5899.0。
注3: Windows Chrome >= 131.0.6759.0 时最高分辨率与帧率组合,基于 MF 获取值计算,取决于硬件,最高分辨率可达 7680x4320,最高帧率可达 300fps,< 130.0.6703.0 时统一为 1920x1088 & 30fps。
注4: Mac Chrome >= 131.0.6771.0 时,最高分辨率取决于硬件,Apple Silicon 芯片的 Mac,最高支持到 8192x4352 & 120fps,否则,最高支持到 4096x2304 & 120fps
macOS Big Sur (11.0) 及以上
Windows 8 及以上
Android 5.0 及以上
Chrome OS (仅支持 VAAPI, V4L2 接口支持的 GPU,比如:Intel 核显)
Linux (版本号须 >= 108.0.5354.0, 仅支持 VAAPI 接口支持的 GPU,比如:Intel 核显)
视频解码:支持 File, Media Source Extensions, WebCodec (8Bit >= 107.0.5272.0, 10Bit + HEVC with Alpha >= 108.0.5343.0), Clearkey 以及 Widevine L1 (不支持L3) Encrypted Media Extensions, WebRTC (Chrome >= 136.0.7077.0 默认开启,一些可用的测试地址供参考:Media Capabilities, Demo)。
视频编码:支持 WebCodec (支持 macOS, Windows, Android, Chrome >= 130.0.6703.0 版本默认启用), WebRTC (支持 macOS, Windows, Android, Chrome >= 136.0.7077.0 版本默认启用),MediaRecorder (Windows, macOS, and Android, Chrome >= 136.0.7064.0 版本默认启用,Chrome 133 ~ 135 版本,需传入 --enable-features=MediaRecorderHEVCSupport 启用,Demo)。
Intel DG1 及以上
NVIDIA GT635, GTX645 及以上
AMD RX460 及以上
Intel HD4400, HD515 及以上
AMD Radeon R7, Vega M 及以上
Apple M1, M1 Pro, M1 Max, M1 Ultra 及以上
Qualcomm Adreno 618 及以上
| PQ | HDR10 | HDR10+ | HLG | DV P5 | DV P8.1 | DV P8.4 | |
|---|---|---|---|---|---|---|---|
| Chrome Mac | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ |
| Chrome Win | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ |
| Edge Mac | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ |
| Edge Win | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ |
| Safari Mac | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| Firefox Win[1] | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
在 Windows 平台,Chrome 支持 PQ、HDR10 (含静态元数据的 PQ)、HLG,会基于静态元数据(如果存在)自动进行 Tone-mapping。HDR10+ 的 SEI 动态元数据在解码时会被忽略,并以 HDR10 降级播放。
在 macOS 平台,Chrome 支持 PQ、HDR10 (含静态元数据的 PQ)、HLG。在 SDR / HDR / 自动模式下,macOS 系统会自动进行 EDR 以确保 HDR 显示正确,Chrome / Edge 实现相同,支持情况一致,Safari 同样支持上述所有 HDR 格式。
注1:Firefox >= 133 默认启用 HEVC 解码支持 (仅 Windows 平台),支持 HEVC Main 以及 Main10 profile (通常 HDR 视频以 Main10 profile 编码),但无法正常渲染 HLG/PQ HDR
这里情况分为两种: 1. 第一种:支持 RPU 动态元数据,支持 Profile 5(IPTPQc2)播放。 2. 第二种:支持 Profile 8/9 等 Cross-compatible Profile,以 HDR10/HLG/SDR 渲染播放。
对于第一种,目前仅 Chromecast 和 Windows 平台具有有限的支持,在 Windows 平台,Chrome 支持加密杜比视界内容。Chrome >= 110 的版本,手动传入 --enable-features=PlatformEncryptedDolbyVision 启动参数,在系统已安装杜比视界插件 + HEVC视频扩展插件的情况下,支持 Profile 4/5/8,使用 API 查询时会返回“支持”(注:对于外置 HDR 显示器,如果开启 HDR 模式,微软的 MediaFoundation 存在Bug,不会返回“支持” 结果)。
对于第二种,例如具有 HLG, HDR10, SDR 兼容性的 Profile 8/9,在使用 API 以 dvh1, dvhe, dva1, dvav 查询时会返回 "不支持"(例如:MediaSource.isTypeSupported('video/mp4;codecs="dvh1.08.07"')),以 hvc1, hev1, avc1, avc3 查询时会返回"支持",具体版本的 Chrome,实现细节有所不同:
Chrome >= 122,正常情况,只要平台支持 HEVC,则支持,假定开发者使用的 API 是 MSE,则整体流程大致如下:
if (isTypeSupported('video/mp4;codecs="dvh1.08.07"')) {
if (use_rpu) {
// 播放成功,Chrome 内部认为 Codec 为 杜比视界,并使用 RPU 动态元数据。
source.addSourceBuffer('video/mp4;codecs="dvh1.08.07"');
...
} else if (dvcc.dv_bl_signal_compatibility_id === 1 ||
dvcc.dv_bl_signal_compatibility_id === 2 ||
dvcc.dv_bl_signal_compatibility_id === 4) {
// 播放成功,Chrome 内部认为 Codec 为 HEVC,忽略 RPU 动态元数据
// 并以 HLG/HDR10/SDR 格式解码渲染。
// 注意:如果是 Profile5,只能基于 `dvh1` 或 `dvhe` 创建 Source Buffer
source.addSourceBuffer('video/mp4;codecs="hev1.2.4.L120.90"');
...
} else {
// 播放失败,不向下兼容的杜比 Profile,不可以使用 HEVC 构造
// Source Buffer。
}
} else if (isTypeSupported('video/mp4;codecs="hev1.2.4.L120.90"')) {
if (dvcc.dv_bl_signal_compatibility_id === 1 ||
dvcc.dv_bl_signal_compatibility_id === 2 ||
dvcc.dv_bl_signal_compatibility_id === 4) {
// 播放成功,Chrome 内部认为 Codec 为 HEVC,忽略 RPU 动态元数据
// 并以 HLG/HDR10/SDR 渲染。
source.addSourceBuffer('video/mp4;codecs="hev1.2.4.L120.90"');
...
} else {
// 播放失败,例如 Chrome 不支持 Profile 5 时,但你使用 HEVC 构造
// 了 Source Buffer。
}
} else {
// 播放失败,HEVC 不支持。
}
110 ~ 121 版本的 Windows Chrome, 开发者需要注意,不管啥情况都是播不成的,这不是你的问题,是浏览器的问题。如果是其他平台的 Chrome, 比如:macOS, Android 等,可以正常以 hvc1, hev1, avc1, avc3 构建 SourceBuffer 并播放 Profile 8 等兼容杜比视界内容,只要视频的 Sample Entry 不是 dvh1, dvhe, dva1, dvav 就可以。
107 ~ 109 版本,可以正常以 hvc1, hev1, avc1, avc3 构建 SourceBuffer 并播放 Profile8 等兼容 Dolby Vision 内容,只要视频的 Sample Entry 不是 dvh1, dvhe, dva1, dvav 就可以。
Chrome 107 不支持提取 HEVC 静态元数据的能力,所有 HDR10 视频均以降级为 PQ 的方式播放。HLG 视频使用显卡厂商自带的 Video Processor API 进行 Tone-mapping,在部分笔记本上性能较差,播放 4K 视频可能会导致卡顿。
Chrome 108 支持了提取 HEVC 静态元数据的能力,对于容器内写入元数据的视频,播放效果很好,但有部分视频由于静态元数据没有写入容器,由于提取不到静态元数据,导致这部分 HDR10 视频被降级为 PQ 视频播放,高光细节可能会缺失。此外 Windows 平台的 HLG Tone-mapping 算法切换为了 Chrome 自己的算法,解决了卡顿的问题,但 Chrome 一直使用 8bit 做 Tone-mapping,这又导致 HLG Tone-mapping 结果存在对比度不足的问题。
Chrome 109 开始,HDR -> SDR 流程切换为 16bit + 零拷贝,提升了 Windows 下的 PQ Tone-mapping 的精准度,HLG 对比度不足问题也得以解决,还降低了大概 50% 的显存占用。
Chrome 110 主要解决静态元数据提取不完整的问题,支持从比特流和容器同时提取静态元数据,部分 HDR10 视频在 macOS 和 Windows 下高光部分不够亮的问题得以解决,至此所有 HDR 问题均已解决。
Chrome 119 解决了 Windows 平台 AMD 显卡 10bit 播放视频问题(SDR 模式下播放 HLG 视频黑屏,4K 卡顿,显存占用高,播放 PQ 视频可能导致全屏颜色变化,HDR 模式下播放 10bit SDR 视频崩溃)。
Chrome 122 主要解决了杜比视界 Profile8 兼容播放等问题。
Chrome 123 确保了 Windows 平台,PQ/HDR10 视频在显示器 HDR 模式下可以以绝对亮度渲染。还解决了连接多显示器时,窗口在 SDR 显示器/ HDR 显示器间拖动时,Tone-mapping 颜色异常的问题。
Chrome 124 解决了 Windows 平台,开启 NVIDIA RTX Auto HDR 功能后,页面滚动会导致视频亮度频繁切换的问题。
Chrome 125 在解决了 Intel HDR10 MPO 的各种问题后,重启启用了该功能。
Edge 125 解决了 Windows 平台 VDAVideoDecoder 解码 HEVC Main10 10bit 视频后,没有零拷贝输出的问题,PQ/HDR10/HLG Tone-mapping 异常的问题方可亦得到解决。后期版本的 HDR 渲染结果预期将与 Chrome 完全一致,由于统一由 Skia 渲染,最终各显卡厂商的渲染结果在 HDR 模式开启/关闭前后,都可以保持一致(在 HDR 模式开启后,11 代以后的 Intel GPU, Intel HDR10 MPO 可能会被启用,此时与 Skia 渲染的结果有少许不一致)。
const mediaConfig = {
/**
* 这里写 `file` 或 `media-source` 都可以, 结果一致。当要检测 `webrtc`
* 可用性时,`contentType` 应该被替换为 `video/h265`
*/
type: 'file',
video: {
/**
* 视频的 Profile
*
* Main: `hev1.1.6.L93.B0`
* Main 10: `hev1.2.4.L93.B0`
* Main still-picture: `hvc1.3.E.L93.B0`
* Range extensions: `hvc1.4.10.L93.B0`
*/
contentType : 'video/mp4;codecs="hev1.1.6.L120.90"',
/** 视频的宽度 */
width: 1920,
/** 视频的高度 */
height: 1080,
/** 随便写 */
bitrate: 10000,
/** 随便写 */
framerate: 30
}
}
navigator.mediaCapabilities.decodingInfo(mediaConfig)
.then(result => {
/** 指定的 Profile + 宽高的视频是否可解码 */
if (result.supported) {
console.log('Video can decode!');
} else {
console.log('Video can\'t decode!');
}
});
if (MediaSource.isTypeSupported('video/mp4;codecs="hev1.1.6.L120.90"')) {
console.log('HEVC main profile is supported!');
}
if (MediaSource.isTypeSupported('video/mp4;codecs="hev1.2.4.L120.90"')) {
console.log('HEVC main 10 profile is supported!');
}
if (MediaSource.isTypeSupported('video/mp4;codecs="hev1.3.E.L120.90"')) {
console.log('HEVC main still-picture profile is supported!');
}
if (MediaSource.isTypeSupported('video/mp4;codecs="hev1.4.10.L120.90"')) {
console.log('HEVC range extensions profile is supported!');
}
const video = document.createElement('video');
if (video.canPlayType('video/mp4;codecs="hev1.1.6.L120.90"') === 'probably') {
console.log('HEVC main profile is supported!');
}
if (video.canPlayType('video/mp4;codecs="hev1.2.4.L120.90"') === 'probably') {
console.log('HEVC main 10 profile is supported!');
}
if (video.canPlayType('video/mp4;codecs="hev1.3.E.L120.90"') === 'probably') {
console.log('HEVC main still-picture profile is supported!');
}
if (video.canPlayType('video/mp4;codecs="hev1.4.10.L120.90"') === 'probably') {
console.log('HEVC range extensions profile is supported!');
}
const videoConfig = {
/**
* 视频的 Profile
*
* Main: `hev1.1.6.L93.B0`
* Main 10: `hev1.2.4.L93.B0`
* Main still-picture: `hvc1.3.E.L93.B0`
* Range extensions: `hvc1.4.10.L93.B0`
*/
codec: 'hev1.1.6.L120.90',
/** HEVC 只支持硬解 */
hardwareAcceleration: 'prefer-hardware',
/** 视频的宽度 */
codedWidth: 1280,
/** 视频的高度 */
codedHeight: 720,
}
try {
const result = await VideoDecoder.isConfigSupported(videoConfig);
/** 指定的 Profile + 宽高的视频是否可解码 */
if (result.supported) {
console.log('Video can decode!');
} else {
console.log('Video can\'t decode!');
}
} catch (e) {
/** 老版本 Chromium 可能对不支持的 Profile, throw Error */
console.log('Video can\'t decode!');
}
注1:上述四种 API 均已经将 --disable-gpu, --disable-accelerated-video-decode,gpu-workaround,设置-系统-使用硬件加速模式(如果可用),操作系统版本号 等影响因素考虑在内了,只要确保 Chrome 版本号 >= 107.0.5304.0 (Windows 平台 Chrome 108 及之前版本存在一个 Bug,如果设备特定的GPU驱动程序版本因为一些原因导致 D3D11VideoDecoder 被禁用,尽管硬解已不可用,但此时 isTypeSupported 等 API 仍然会返回 “支持”,该问题已在 Chrome 109 修复), 且系统是 macOS 或 Windows,则可保证结果准确性。
注2:安卓平台存在一个 Bug,Chrome < 112.0.5612.0 的版本没有返回实际硬件支持情况(安卓 5.0 之后的版本尽管默认支持 HEVC main profile 软解,但 main10 profile 是否支持由则由具体硬件来决定),永远认为支持所有 Profile 和分辨率的 HEVC 视频。Chrome >= 112.0.5612.0 版本解决了这个问题,并会根据设备实际支持的情况返回正确的结果,和 macoS, Windows 一样支持上述三种 API,且各种影响因素均会被考虑在内。
注3:相比 MediaSource.isTypeSupported() 或 CanPlayType(),更推荐使用 MediaCapabilities,MediaCapabilities 除了会将 设置-系统-使用硬件加速模式(如果可用) 等等上述影响因素加入考虑外,还会考虑 视频分辨率 是否支持,不同的 GPU 所支持的最高分辨率是不一样的,比如部分 AMD GPU 最高只支持到 4096 * 2048,一些老的 GPU 只能支持到 1080P。
```javascript /* Detect HEVC Widevine L1 support (only Windows is supported). / try { await navigator.requestMediaKeySystemAccess('com.widevine.alpha.experiment', [ { initDataTypes: ['cenc'], distinctiveIdentifier: 'required', persistentState: 'required', sessionTypes: ['temporary'], videoCapabilities: [ { robustness: 'HW_SECURE_ALL', contentType: 'video/mp4; codecs="hev1.1.6.L120.90"', }, ], }, ]); console.log('Widevine L1 HEVC main profile is supported!'); } catch (e) { console.log('Widevine L1 HEVC main profile is not supported!'); }
/*
* Detect Dolby Vision Widevine L1 support (only Windows is supported, and only if
* --enable-features=PlatformEncryptedDolbyVision switch has been passed).
/
try {
await navigator.requestMediaKeySystemAccess('com.widevine.alpha.experiment', [
{
initData
$ claude mcp add enable-chromium-hevc-hardware-decoding \
-- python -m otcore.mcp_server <graph>