1. 主页 > 用户投稿

2022前端最新面试题(2022前端最新面试题知乎)

什么是HEVC?简单说就是一种比H264压缩效率更高的现代视频编码格式,它支持8K,支持HDR,支持广色域,支持最高16bit的色彩深度,最高YUV444的色彩抽样,总之一句话,是一种用来取代现有H264的更高效、现代的视频编码格式,且目前已经被各类硬件广泛支持。

然而因为版权和技术派别等原因,这种格式一直没有被浏览器很好支持,尤其是目前市占率最高的Chrome,一月初看到了一条B站用户吐槽HEVC解码性能/发热问题的新闻(感谢B站在HEVCWASM解码方案上的探索),考虑到这也是困扰业界很久的问题,大量依赖HEVC的Web项目均被迫产出了各种各样Workaround方案,但效果一直都不是最理想的,心想不如帮Chromium实现一下HEVC硬解吧。

本文简述了Web解码方案现状,介绍了作者为Chromium浏览器实现&完善硬解过程中遇到的问题和实现原理,并在文末附加了测试结果,预编译版本供参考,希望可以解决FrontEnd苦HEVC久矣的问题。

2022前端最新面试题(2022前端最新面试题知乎)

也可以提前下载ChromeCanary(),体验HEVC硬解功能(ChromeOS、Android、Mac、Windows需要添加启动参数--enable-features=PlatformHEVCDecoderSupport,Linux版本暂未支持)。

在2015年,苹果的iPhone6s就已经在其A9芯片内首次实现了HEVC硬解能力,同年,Intel在第六代Skylake的HD500系列核显上,NVIDIA在GTX900系列独显上,也先后支持了HEVC硬解。

在2017年发布的iOS11,macOS10.13上,苹果继续完成了其VideoToolbox编解码框架对HEVC编解码能力的支持,微软也发布了HEVCVideoExtension作为WindowsPC环境HEVC解码的能力对标。

从此HEVC成为苹果,安卓默认视频格式,成为绝大多数单反/无人机/摄像设备的主推格式。

直到今年,也就是2022年,iPhone已经出到了13,芯片技术已经提升到了5纳米,然而我们所使用的大部分浏览器依然无法播放HEVC视频。

所谓硬解,即指使用GPU内专用于解码的芯片来处理解码工作,由于GPU多核心低频且专一的优势,在解码视频时发热和功耗显著低于CPU。

通过将CPU从繁重的解码工作中解放,可极大程度降低系统卡顿。

且GPU天生适合进行图形解码工作,解码性能秒杀CPU,视频分辨率越高,显卡解码越可以做到不掉帧输出,因此“永远不要指望单纯靠CPU软解可以流畅播放8K60帧的HEVC视频”。

HEVC是目前桌面端或手机端播放器最主流的编码格式,考虑到其编码复杂度高,解码更耗费资源,因此为其实现硬解非常必要。

首先先来看看Web侧解码的现状:

H265

VP8

VP9

MPEG4

AV1

Chrome102

硬+软解

不支持

软解

硬+软解

不支持

硬+软解

Firefox101

硬+软解

不支持

软解

软解

不支持

硬+软解

Edge102

硬+软解

硬+软解(需装扩展)

软解

硬+软解

不支持

硬解(需装扩展)

H264

H265

VP8

VP9

MPEG4

AV1

Chrome102

硬+软解

不支持

软解

硬+软解

不支持

软解

Firefox101

硬+软解

不支持

软解

硬+软解

不支持

软解

Edge102

硬+软解

不支持

软解

硬+软解

不支持

不支持

Safari15.3

硬+软解

硬+软解(仅部分)

不支持

不支持

硬+软解

不支持

目前业内常用的WebHEVC解码方案大致可以分为两种:“换浏览器”或“WASM软解”,他们各自有各自的优势和使用场景。

Chromium内核的Edge在Windows系统下,额外支持了硬解HEVC视频,但必须满足如下条件:

3.版本号必须大于等于Edge99。

在安装插件后,进入edge://gpu页面,可以查看Edge对于HEVC硬解支持的Profile:

出现上图所示的字样,则证明硬解开启成功。

指标:

优势:

劣势:

由于Apple是HEVC标准的主要推动者,因此早在17年的Safari11即完成了HEVC视频硬解的支持,无需安装任何插件开箱即用。

指标:

优势:

劣势:

此类方案绝大部分基于WASM+FFMPEG编译实现,支持所有支持WASM的浏览器。

指标:

优势:

劣势:

本文尝试直接为Chromium实现硬解,因为尽管Safari和Edge均已经实现了HEVC硬解,但它们均为闭源软件,无法被各种开源框架集成,而因为Chromium是开源的,这可以确保所有人可自行编译支持Windows/macOS/Linux硬解的Chromium/Electron/CEF,考虑到实现原理部分较长,因此如果你感兴趣,可直接下载预编译版本(-chromium-hevc-hardware-decoding/releases)进行测试(未来会被包含在Chrome正式版本内,预编译版本可供大家尝鲜提前试用,也可下载ChromeCanary),或跳到测评部分查看与Edge/Safari的对比。

正是因为如上瓶颈,“让专业的人做专业的事”这句话同样适用视频解码,GPU硬解是很有必要的。GPU解码的存在正是为了让解码工作可以充分利用显卡内部专用芯片,分担CPU解码时的压力,因此支持更多格式的硬解能力,已然成为众多显卡厂商的一大卖点。

首先我们需要做一些调研,研究下目前硬解框架是如何存在,并支持哪些“系统”or“GPU”。

下表来自FFMPEG项目对不同解码框架硬解支持情况的总结(来源:)

(硬解框架的支持情况,表格内容来自FFmpeg官网)

可以看到硬解框架五花八门,不同的显卡厂商和设备有各自的专用解码框架,操作系统也有定义好的通用解码框架,由于显卡厂商众多,因此大部分播放器一般均基于通用框架实现硬解,少部分播放器在人力充裕的情况可能会为了更好的性能(显卡厂商自己的框架一般比通用框架性能更好,但也不绝对)额外对专用框架二次实现。

其中Windows平台通用的解码框架有MediaFoundation,Direct3D11,DXVA2,以及OpenCL。macOS平台通用的解码框架只有一个,也就是苹果自己的VideoToolbox。Linux平台的通用解码框架有VAAPI和OpenCL。

显然,对于Chrome而言,为了更好的兼容性和稳定性,基于通用硬解框架实现硬解,更符合最小成本最大收益的目标,并提升了可维护性。

根据ChromiumMedia模块简介可知,浏览器将音视频播放一共抽象成三种类型,我们比较常见的有:VideoElement标签,MSEAPI。此外还有支持加密视频播放的EMEAPI,这三种在底层又存在多种复用关系。

(Chromium的解码流程,图片来自Chromium代码仓库)

那么到了最底层的解码模块,整体逻辑大概可以简述为:

因此,为了实现HEVC硬解,我们首先需要找到各个平台的通用硬解Decoder:

在了解了大致背景后,便可以开始探索实现HEVC硬解实现了,考虑到Apple其最新AppleSilicon芯片专门实现了支持H.264、HEVC和ProRes的专用编解码媒体处理引擎,看在Apple这么努力的份上,我首先挑选了macOS平台来进行尝试。

虽然Chrome没有直接实现HEVC解码能力,但由于其实现了FFMpegVideoDecoder,因此本质上任何FFMPEG可以播的视频,只要利用修改Chromium的方式为其添加FFMPEG解码器的入口,理论上均可以实现播放,此方案其实是本文硬解实现前开源社区最广为流传的一种方案,@斯杰的文章()内已有详尽介绍,由于当时的版本是基于Chromium79,目前最新的Chromium版本号为104,因此里面的一些实现有所变动,但整体逻辑并没有明显改变,通过修改Chromium104依然可以实现软解。

优点有很多:由于是CPU软解且使用行业最标准的FFMPEG解码,最终结果是:不挑系统,容错性好,支持任何CPU架构、操作系统,性能虽比不过硬解,但依然比前端WASM方案性能更好,且原生支持MSE和VideoElement。

缺点也很明显:普通的四核笔记本电脑,即使分辨率只有1080P,在快进或快退时也会感到明显的卡顿,同时伴随比较高的CPU占用,抢占渲染进程CPU资源,另外这种方法是否有版权有待评估,但可以确定一点,使用平台提供的解码是合规且没有版权风险的。

当分辨率达到4K甚至8K级别,8核甚至更多核的CPU也会卡到掉帧。

(FFMPEG的解码流程,图片来自知乎@我是小北挖哈哈)

根据FFMPEG的解码流程如上图(参考:),可知道,FFMPEG除了实现了软解,其实已经完整实现了硬解功能,然而Chromium的FFMpegVideoDecoder并不支持硬解,因此,同组同学@豪爽,首先尝试FFMpegVideoDecoder内尝试配置hw_device_ctx,以开启其硬解能力,具体步骤如下:

开启硬解宏:

设置硬件上下文:

取出解码数据:

将硬件解码得到的数据取出,即av_hwframe_transfer_data函数:

如上,经过多次尝试后,通过活动监视器可以观察到点击

探索过程中,阅读ChromiumMedia模块的文档后发现,使用FFMpegVideoDecoder不支持在Sandboxed的进程调用VT硬解框架,为了避免在错误的道路上投入过多精力,遂放弃。

上面的方式行不通,说明得换一种思路,需要看看正统的H264硬解流程是怎样的,通过使用Chrome的搜索引擎(),发现macOS的H264硬解实现均位于vt_video_decoder_accelerator.cc这个文件内。

由FFmpeg介绍可知,如我们想在macOS实现HEVC硬解,则一定需要使用苹果提供的媒体解码框架VideoToolbox来完成。

VideoToolboxisalow-levelframeworkthatprovidesdirectaccesstohardwareencodersanddecoders.Itprovidesservicesforvideocompressionanddecompression,andforconversionbetweenrasterimageformatsstoredinCoreVideopixelbuffers.Theseservicesareprovidedintheformofsessionobjects(compression,decompression,andpixeltransfer),whicharevendedasCoreFoundation(CF)types.AppsthatdontneeddirectaccesstohardwareencodersanddecodersshouldnotneedtouseVideoToolboxdirectly.

根据AppleDeveloper网站介绍()可知,VideoToolbox是苹果提供的直接用来进行编解码的底层框架,要实现硬解,大体解码流程可以理解为:Chromium->VDAVideoDecoder->VideoToolbox->GPU->VideoToolbox->VDAVideoDecoder->Chromium。

因此我们的目标就是正确按照VideoToolbox要求的方式,提交ImageBuffer,并等待VT将解码后的数据回传。

根据Chromium解码流程可知,Chromium对于特定Codec的视频首先会尝试查找硬解Decoder,如硬解Decoder不支持,则继续向后查找Fallback的软解Decoder。

通过观察可发现,在macOS下,某种编码格式是否支持硬解,取决于硬解Decoder内的SupportProfiles是否包含这种编码格式,其代码如下:

实现硬解,需要在Sandboxed的进程启用前创建解码Session预热,并根据系统版本与支持情况决定最终是否启用硬解:

如上,经过GPUworkaround、操作系统版本、Profile、编译开关、启动开关检查,最终如果校验通过,则HEVC解码逻辑会由VideoToolbox接管,并由VTDecoderXPCService进程最终实际负责解码。

NALU(networkabstractionlayerunit),即网络抽象层单元,是H.264/AVC和HEVC视频编码标准的核心定义,按白话理解,就是H264/HEVC为不同的视频单元定义了的不同的类型(参考),感兴趣可自行百科,这里不再赘述。对于H264,存在32种,其中保留Nalu有8种。到了HEVC,被扩展到了64种,保留Nalu有16种。

(H264的NaluUnit组成,图片来自Apple)

如想实现HEVC解码,首先需要拿到视频的元数据,这就需要通过解析NALU类型为32(VPS_NUT),33(SPS_NUT),34(PPS_NUT)的NaluHeader来获取。

举个最基本的例子,如果我们希望获取视频的宽高,则需要解析SPS_NUT的NaluHeader,并取sps->pic_width_in_luma_samples的值,以此类推。

通常媒体开发会使用一个叫做StreamAnalyzer的工具(链接:-analysis/stream-analyzer)快速解析视频NaluHeader,我们要做的事其实和这个软件做的差不多:

(StreamAnalyzer解析NaluHeader示意)

可以看到,SPS_NUT的NaluHeader解析后的数据如截图右侧区域显示,感谢Elecard开发的这款好用的工具,有了它对我们实现VPS解析有很大帮助。

观察Chromium的代码结构发现@JefferyKardatzke大佬已经于2020年底完成Linux平台VappiHEVC的硬解加速实现,和H265NaluParse的大部分逻辑实现,由于Linux平台硬解并不需要提取VPS参数,因为大佬没有实现VPS解析,但根据AppleDeveloper的说明,若我们使用CMVideoFormatDescriptionCreateFromHEVCParameterSetsAPI创建解码session,需要提供VPS,SPS,PPS三种类型的NaluData,因此实现macOS硬解的很大一部分工作即是完成VPSNALU的Header解析:

首先,参考T-REC-H.265-202108-I,以及FFMPEG定义好的H265RawVPSStructReference,我们需要定义好要解析的VPS结构体类型:

接着,我们需要完成H265VPS的解析逻辑:

完善编写UnitTest和FuzzerTest:

由于FFMPEG已经实现了VPS的解析逻辑,因此这里大部分逻辑与FFMPEG保持一致即可,经过UnitTest测试(编译步骤:autoninja-Cout/Release64media_unittests)确认无问题,对照StreamAnalyzer同样无问题后,完成VPS解析逻辑实现。

这里跳过SPS,PPS,SliceHeader的解析逻辑,因为代码量过大且琐碎,感兴趣可参考h265_parser.cc(+/main:media/video/h265_parser.cc)

我们知道H264/HEVC视频帧类型大体上有三种:I帧,P帧,B帧,其中I帧又称全帧压缩编码帧,为整个GOP(一个存在了I,P,B的帧组)内的第一帧,解码无需参考其他帧,P帧又称前向预测编码帧,解码需要参考前面的I,P帧解码,B帧又称双向预测内插编码帧,解码需要参考前面的I、P帧和后面的P帧。

一共存在的这三种帧,他们在编码时不一定会按顺序写入视频流,因此在解码时为了获取不同帧的正确顺序,需要计算图片的顺序即POC。

(StreamEye解析后的GOPPOC结果示意)

如上图StreamEye解析结果所示,POC呈现:0->4->2->1->3->8->6...规律。

不同帧的出现顺序对于解码来说至关重要,因此我们需要在不同帧解码后对帧按POC重新排序,最终确保解码图像按照实际顺序呈现给用户:0->1->2->3->4->5->6->7->8。

苹果的VideoToolbox并不会给我们实现这部分逻辑,因此我们需要自行计算POC顺序,并在之后重排序,代码实现如下:

POC的计算逻辑:

计算POC并解码后,为了确保视频帧按照正确的顺序展示给用户,需要对视频帧进行Reorder重排序,我们可以观察H264的最大Reorder数计算逻辑,发现很复杂:

幸运的是HEVC相比H264不需要如此繁杂的计算,HEVC在编码时已经提前将最大Reorder数算好了,我们只需按如下方式获取:

计算好Reorder数和POC后,继续复用H264的Reorder逻辑,即可正确完成排序。

下面我们正式开始解码逻辑实现,首先,需要提取SPS/PPS/VPS,并对其解析,缓存:

根据解析后的VPS,SPS,PPS,我们可以创建解码Format:

(VideoToolbox的解码流程,图片来自Apple)

在创建解码Format后,继续创建解码Session:

创建解码Session的逻辑:

这一步开始我们就要开始正式解码了,解码前首先需要提取视频帧的SliceHeader,并从缓存中拿到到该帧引用的SPS,PPS,VPS,计算POC和最大Reorder数。

(H264视频帧的SPS、PPS引用关系,图片来自Apple)

如果视频帧引用的VPS,PPS,SPS任一发生变化,则按照VideoToolbox的要求,需要重新配置解码Session:

鉴于我们需要支持HDR,因此需要判断一下视频是否为Main10/RextProfile,并调整输出为gfx::BufferFormat::P010

在上述步骤后,硬解关键流程基本完工,目前代码已合入Chromium104(main分支),macOS平台具体实现过程和代码Diff可以追溯Crbug()。

有了macOS硬解的开发经验,尝试Windows硬解相对变得容易了一些,尽管也踩了一些坑。

文章开头已经介绍了,实际上在Windows平台,如果你可以安装HEVC视频扩展,则是可以在Edge浏览器硬解HEVC的,因此我最初的思路也是和Edge一样,通过引导HEVC视频扩展,完成硬解支持。

首先,使用Edge,打开任意HEVC视频,发现,Edge使用VDAVideoDecoder进行HEVC硬解:

因此尝试搜索发现Windows平台VDAVideoDecoder代码实现均位于dxva_video_decode_accelerator_win.cc文件内,继续寻找蛛丝马迹,发现,在开源的Chromium项目内,并不存在HEVC硬解相关的任何实现,这说明Edge是自己基于某个时期的ChromiumMedia模块“魔改”出来的HEVC硬解支持,同时在这个过程发现了个有趣的现象:

好吧,尽管没少吐槽Edge,但是他确实是Windows平台唯一支持HEVC硬解的浏览器(当然,马上就不是了)。

接着看dxva_video_decode_accelerator_win.cc的实现,从上述Edge解码需要安装AV1插件的逻辑反推,如果我们照着AV1的方式实现HEVC,是否可行?答案是肯定的。

观察SupportedProfile,然后将我们需要支持的HEVCPROFILE_MAIN、HEVCPROFILE_MAIN10加入:

之后按照AV1的逻辑,加入HEVCCodec,同时值得一提的是必须在调用SetOutput方法前设置分辨率(这块坑了我大概一天的时间Debug),代码如下:

接着实现一下HEVCDecoder的获取逻辑:

同时将HEVCMain,Main10Profile加入到supported_profile_helpers.cc:

最后,还需要修改一下引导逻辑,强制让HEVC编码格式使用VDAVideoDecoder而不是D3D11VideoDecoder:

后面省略了一些透传Profile的代码。

在上述步骤执行后,一切大功告成,代码实现基本完成,HEVC视频扩展帮我们处理了大部分的解码逻辑,所以实现过程相当简单。

但,问题来了!由于HEVC视频扩展插件在1.0.31823之后的版本存在抖动问题,而1.0.50361虽然解决了抖动的问题,但其官网文档并没有明确详述如何配置Decoder解决该问题(注:欢迎贡献配置方法),因此,如果我们需要用HEVC视频扩展的方案,则必须限制用户本地强行使用1.0.31823版本。

为此我尝试写过nsh脚本,试图在用户电脑存在非31823版本HEVC视频扩展的情况,强制卸载并重装1.0.31823版本的HEVC视频扩展,但,因为Windows商店会默认对Appx扩展自动更新,这导致如果希望用户电脑不更新HEVC视频扩展,则必须强迫用户关闭Windows商店的自动更新,这无疑意味着这个方案是个半成品,很可能需要换技术方案了,但我们的选择真的不多。

然而就在即将放弃的时候,我突然想到为啥不照着Chromium把D3D11VA的方案实现一遍呢?MediaFoundation绝不是唯一解!时间点是2022年的2月中旬,我抱着尝试的态度,打开了source.chromium.org这个网站,试图学习下其他格式D3D11VA的解码方法,并在media文件夹偶然间瞥到了一个叫d3d11_h265_accelerator.cc的文件,这是啥?怎么可能?Windows不是没有人实现过HEVC硬解么?然后我果断看了下提交时间,发现在2月8号,这个文件才被合入到Chromium!感谢作者@JianlinQiu(来自Intel的大佬),把Windows的D3D11硬解加速实现的差不多。

Trace了下@JianlinQiu实现相关的crbug(#c18),合入其代码,简单做了下测试发现一半的视频可以播(早期版本有些小问题,目前均已解决)。

遂观察其实现逻辑,发现Windows的硬解实现逻辑与macOS完全不同,在macOS,尽管我会对SPS/PPS/VPS/SliceHeader进行Parse,但是实际上,最终调用CMVideoFormatDescriptionCreateFromHEVCParameterSets方法创建解码Format时,传给VT的参数是包含了VPS,SPS,PPS的NaluData的数组,也就是说理论上如果我们不计算POC,不Reorder,直接将NaluData塞给VideoToolbox,也可以解码,只是帧组会抖动罢了。

但到了Windows和Linux这里,实现起来要麻烦的多。

根据Mircosoft官网,可知D3D11VA硬解的实际流程可参考这篇文章(-us/windows/win32/medfound/supporting-direct3d-11-video-decoding-in-media-foundation#open-a-device-handle),总结起来其实主要工作在于对每一个视频帧的图片参数拼装。

GPU是否支持硬解,这里的逻辑,首先假定默认是不支持HEVCMain/Main10的,然后调用D3D11Device提供的GetVideoDecoderConfig方法,拿到支持的Codec列表,若列表中存在HEVC则认为支持:

如上流程可知,根据DXVAHEVCSpec,要正确实现解码,需要自己提前解析好其要的PictureParams,以HEVC的PictureParams为例,结构体如下,每一个参数都不能缺少,这本身工作量就不小,但好在@Jeffery大佬在实现Linux的H265Decoder和H265Parser时已经完成了大部分工作,因此@Jianlin大佬的工作主要是如何正确的将这些已经Parse好的Params拼装和计算,并塞给D3D11。

实现硬解加速本身不需要实现解码逻辑,因此其实H265Accelerator本身的功能主要在于拼装DXVA所要的PictureParams,并正确提交。这个过程,首先需要填充默认的PictureParams:

下面基本都是一些枯燥的流程,利用H265Parser解析后的结果,去填充PictureParams:

PictureParams还需要从PPS,SliceHeader,以及计算好的RefPicList,Picture填充,考虑到内容过于繁琐,这里暂时省略,整体思路可以概括为参数拼装。

现实中的实际视频,尤其是在WebRTC场景产生的视频,可能存在分辨率或者色彩深度突变的情况,因此,在实际实现Decoder的过程中,处理这种情况至关重要,如果处理不好,轻则会导致视频花屏、绿屏,重则会导致D3D11devicecontextlost,并最终导致GPU进程崩溃。

可以看到在返回kConfigChange后,实际上是重新创建了一个新的D3D11Decoder,这个过程用户在前端完全无感知,创建速度非常快,整体视频播放不会感受到一丝卡顿,是连贯的,相比VLC处理的体验更好。

根据HEVCSpec2021,HEVC一共存在11种Profile,具体视频使用哪种Profile可由SPS中的general_profile_idc的值来判断,由于之前Chromium没有定义其他8种Profile,导致其他Profile会被当作MainProfile,并使FFMpegVideoDecoder的兜底逻辑失败,因此在这个CL(-review.googlesource.com/c/chromium/src/+/3552293)中将其他几种Profile添加解决了这个问题。

HEVC的11种Profile:

Profile的赋值逻辑:

当Profile能力补齐后,就可以支持将硬解不支持的Profile自动fallback到FFMpegVideoDecoder软解的能力了,这样可以确保我们目前可见的所有HEVCProfile都可以正常播放(能走硬解走硬解,否则走软解)。

之前版本的Chromium提取色彩空间的逻辑要么是利用ffmpeg的avcodec_parameters_to_context获取,最终利用ffmpeg解析mov或者mp4container的逻辑获取,要么在demux阶段提取FOURCC_COLRBox获取,这样做对于标准的mov,mp4视频并没有什么问题,然而很多编码器在实现时并没有将色彩空间信息写入容器,导致Chromium的之前的逻辑无法正确提取到HEVC视频的色彩空间。

因此我们需要利用解析好的HEVCDecoderConfigurationRecord,在demux阶段对SPS进行解析,并提取其sps->vui_parameters->colour_primaries,sps->vui_parameters->transfer_characteristics,sps->vui_parameters->matrix_coeffs,以及sps->vui_parameters->video_full_range_flag以生成VideoColorSpace。

在与Edge进行对比后可以发现,Edge只通过容器读取色彩空间,而没有SPS读取的逻辑,这会导致HDR视频无法正确ToneMapping,最终渲染视频异常,而在Chromium内则一切正常。

(左图为Edge在处理HLG视频时ToneMapping异常的问题)

在上述步骤后,硬解步骤已完成的差不多,目前所有的CL和Fix已合入Chromium104(main分支),Windows平台具体实现过程和代码Diff也可以追溯这个Crbug()。

说了一堆技术实现可能会很枯燥,下面来到最有趣的环节:“与竞品对比”。为了公平起见,使用原生HTML+原生Video标签方式,排除一切外界干扰完成一个基础的测试页面,并收集了28个不同Profile、HDR/非HDR、不同位深的测试Case(测试素材来自网络:-cdn-tos.bytegoofy.com/obj/tcs-client/resources/video_demo_hevc.html),下面开始测试:

我们首先进行HDR能力测试,测试选择了多个PQ、HLGTransfer的HEVC视频。

毕竟不是所有人都使用HDR显示器,甚至可以说99.99%的用户仍在使用SDR显示器,因此HDR视频是否能在普通SDR显示器正确显示,是非常重要的,将HDR视频转换为SDR视频的过程一般被称作做ToneMapping,因此下述测试主要测试浏览器是否支持ToneMapping。

(左图:Edge102Windows,右图:Chromium104Windows)

可以看到在Windows平台,Edge在处理PQ曲线的HDR视频时存在ToneMapping异常的问题,而Chromium可以正常ToneMapping,这一轮Chromium胜。

(左图:Safari15.3macOS,右图:Chromium104macOS)

在macOS平台,Safari的对PQHDR视频的ToneMapping处理的很棒,Chromium104也同样不错,二者效果完全相同,而且由于macOS支持EDR(简介:),即使使用SDR显示器,其显示效果相比Windows平台更佳(Mac会适当扩展高光),两款浏览器这一轮打平。

(EDR简介,图片来自Apple)

接着我们将显示器调为HDR模式,并开启操作系统的HDR输出。

(左图:Edge102Windows,右图:Chromium104Windows)

可以看到,如果视频是mov,一般都会在封装容器会写入色彩空间,此时二者区别不大,都可以较好在HDR显示器以HDR效果显示PQHDR视频内容,但如果视频是mp4封装,则由于mp4一般不写入色彩空间到封装容器,Edge存在PQ视频显示异常的问题,这一轮Chromium胜。

接着我们测试macOS,在macOS播放HDR视频,无需任何设置,因为其支持EDR功能,我们选择支持HDR的XDR显示器Mac(新款M1Pro/MaxMacbookPro)进行测试,正确显示HDR视频无需任何设置。(注:如果需要为外置显示器强制启用HDR,需要使用支持的显示器并在设置-显示器面板开启“高动态范围”选项)

(左图:Safari15.3macOS,右图:Chromium104macOS)

可以看到在macOS平台,Safari对PQHDR视频的ToneMapping处理的很棒,Chromium104也同样不错,因此二者显示效果完全相同(由于macOS是默认EDR,无需额外设置),这一轮打平。

(左图:Edge102Windows,右图:Chromium104Windows)

可以看到Edge在处理HLG视频时,如果色彩空间没有写入封装容器,则无法正确读取色彩空间,导致存在偏色问题,而Chromium目前会通过容器读取色彩空间,如果不存在,则继续从SPS读取色彩空间,这可以保证所有HLG视频均可正确ToneMapping,这一轮Chromium胜。

(左图:Safari15.3macOS,右图:Chromium104macOS)

在macOS平台,Safari的对PQHDR视频的ToneMapping处理的很棒,Chromium104也同样不错,二者效果完全相同,而且由于macOS支持EDR(简介),即使使用SDR显示器,其处理效果相比Windows平台更佳(Mac不会强制压高光),两款浏览器这一轮打平。

(容器未写入色彩空间情况,左图:Edge102Windows,右图:Chromium104Windows)

(容器写入色彩空间情况,左图:Edge102Windows,右图:Chromium104Windows)

可以看到Edge在显示HLG视频时并未激活HDR输出,而Chromium可完美HDR输出(肉眼效果和截图不一致,截图比较亮,肉眼显示是正常的),同时,即使视频容器有写入色彩空间,Edge处理后的视频存在过曝问题,这一轮Chromium完胜。

(左图:Safari15.3macOS,右图:Chromium104macOS)

在macOS平台,Safari完全支持HLGHDR视频,Chromium104也不错,二者效果完全相同,均可良好支持HLGHDR在HDR显示器以HDR格式完美显示,这一轮打平。

根据上述测试结果,总结如下:

PQ(SDRDisplay)PQ(HDRDisplay)HLG(SDRDisplay)HLG(HDRDisplay)ChromiummacOS?(EDR)??(EDR)?SafarimacOS?(EDR)??(EDR)?ChromiumWindows????EdgeWindows?PartialPartial?

在macOS平台,Safari和Chromium的HDR表现均良好,且支持EDR。

在Windows平台,如果你想观看HDR内容,没有别的选择,Chromium是唯一完全支持HDR的浏览器。

在Windows平台,Edge与Windows均不支持HEVCRext,这是因为DXVA规范并没有制定除Main/Main10以外的Profile(尽管Intel和NVIDIA后期自己实现了422444Rext的硬解,但这不在规范里)。

(左图:Safari15.3macOS+IntelMac,右图:Chromium104macOS)

(左图:Safari15.3macOS+M1Mac,右图:Chromium104macOS)

如图所示,在macOS平台,Safari不完全支持HEVCRext(比如Intel就不支持,M1芯片的Mac支持一部分),而Chromium104支持硬/软解HEVCRext(AppleSilicon芯片支持10bitRext硬解,Intel芯片Mac支持Rext软解),Chromium胜在兼容性。

在Windows平台,结论是:这一轮Chromium和Edge打平,目前能找到的8K视频二者都可正常播放,因此这里暂时不放截图了。

(左图:Safari15.3macOS,右图:Chromium104macOS)

在macOS平台,诚然,Safari确实支持8K,这一点可以在B站的8KHEVC视频上验证,但是由于其“挑格式”的小毛病,测试页面“为数不多”的几个8K测试的视频团灭,因此这一轮Chromium胜。

在Windows平台,结论是:这一轮Chromium和Edge打平,目前我能找到的所有Main/Main10Profile的HEVC视频均可在二者正常播放,因此这里暂时不放截图了。

(左图:Safari15.3macOS,右图:Chromium104macOS)

在macOS平台,Safari彻底输了,40个测试视频约一半无法正常播放,这一波Chromium完胜。

BiliBili是目前官方支持HEVC的网站,通过使用UserAgent修改插件,并模拟成macOS的Safari,我们可以使B站优先使用HEVC播放视频,且最大支持8K。

如下图所示,开启硬解后的Chromium可以流畅播放8K60P的HEVC视频:

打开chrome://media-internals可以验证,视频是分辨率确实是7680*4320的HEVC。

性能如何?

为此我找了一台使用HD620GPU的LenovoThinkpadT14,尝试在B站播放8K60P的视频:

(Chromium104,HD620在播放8K60P视频时的GPUDecode占用率达到了100%)

可以看到HD620核显拼一拼还是可以播8K60P视频的(虽然偶尔有一点掉帧),同时也可以看到在播放8K视频时的系统CPU占用率只有16%,硬解带来的性能收益非常显著。

通过使用UserAgent修改插件,并模拟Edge18.19041,我们可以解锁B站的HDR模式,最大分辨率为4K。我们选择了一个支持HDR的视频,并对比Edge和Chromium。

(左图:Edge102Windows,右图:Chromium104Windows)

可以发现在Windows平台,Chromium是唯一良好支持B站HDR10的浏览器,而Edge无法正常显示。

(左图:Safari15.3macOS,右图:Chromium104macOS)

可以发现在macOS平台,Safari和Chromium均可良好支持B站的HDR10,在HDR支持上,二者无区别。

经过上述测评想必大家应该可以看到,在2022年的今天,终于,Chromium也可以完整支持硬解HEVC了,且相比Safari和Edge,在HDR支持,格式兼容性,性能,平台支持四个方面均表现良好,甚至小幅超越。

访问这里,可直接下载ChromeCanary()进行测试(启动参数--enable-features=PlatformHEVCDecoderSupport)。

在macOS,如果需要开启HEVC硬解功能,一种方式是以命令行的方式打开:

如果不喜欢命令行,也可以通过Automator建立启动自动操作的方式打开。

如何验证是否生效?打开chrome://gpu,如出现下图红圈所示的字样表示成功。

找到一个HEVC的视频并播放,打开chrome://media-internals页面,如视频解码出现VDAVideoDecoder字样,表示硬解成功:

打开活动监视器,搜索VTDecoderXPCService,播放视频时,观察到进程CPU占用率上涨也可说明硬解成功:

Windows的Chrome,在桌面快捷方式传入启动参数即可。

如何验证是否生效?打开chrome://gpu,如出现下图红圈所示的字样表示成功。

找到一个HEVC视频并播放,打开chrome://media-internals页面,如视频解码出现D3D11VideoDecoder字样,表示硬解成功:

打开Windows任务管理器-性能-GPU-VideoDecode区域,观察播放时的使用率是否上涨,如果上涨亦可说明硬解成功,如果占比为0%说明硬解失败。

在AMDGPU上,显示为“VideoCodec”。

方式类似,传启动参数即可支持,这里由于本人不使用Android设备,暂未贴出具体步骤。

最新测试版本已原生集成于OS,无需传启动参数。

如果你觉得传参很麻烦,也可访问这里,下载无需启动参数的预编译版本(-chromium-hevc-hardware-decoding/releases)进行测试(需要Google服务只能用ChromeCanary)。

HEVC硬解功能目前正在实验中,最早可能在Chrome105稳定版发布。

你可能希望把这个Feature编译到CEF、Electron等Framework内。如果是Electron20正式版(基于Chromium104,目前还是beta版本),则已集成好Mac,Windows平台的HEVC硬解功能,在启动时执行app.commandLine.appendSwitch(enable-features,PlatformHEVCDecoderSupport)即可启用硬解。如果是Electron20以下版本,需要自己手动CV大法集成。

可分别Trace这两个Issue(Windows:,macOS:)追踪后续进度。

如果有HEVC视频播放需求,不妨可以尝试一下ChromeCanary版本或预编译版本,如遇到Bug,请在crbug.com提交反馈。

本文内容由互联网用户自发贡献,该文观点仅代表作者本人。如发现本站有涉嫌抄袭侵权/违法违规的内容,请发送邮件至 203304862@qq.com

本文链接:https://www.jinnalai.com/n/151669.html

联系我们

在线咨询:点击这里给我发消息

微信号:

工作日:9:30-18:30,节假日休息