练习时长“2年半”,我的 Chromium 开源贡献经验分享

124 阅读13分钟

初始 “动机”

在 2021 年底,我在国际化内容安全平台团队,负责为公司的内容安全平台开发客户端。我们开发的客户端的一个主要任务是解决浏览器播放送审视频的兼容性问题。

如果想播放 HEVC 视频,一种方案是独立开发一个进程,引入 FFmpeg 并自行实现渲染。但这种方案首先要求团队熟练掌握 C++ 技能,其次需要放弃现有的 Web 播放技术栈。由于整个审核平台的技术栈以 Web 方向为主,播放器为我们公司的 JS 播放器西瓜播放器,因此这种方案不可行。

团队最早探索了基于定制浏览器实现 HEVC 软解码的方案,并将成果分享至社区,在 2022 年之前一直采用该方案。2022 年初,有同事发现审核 1080P 直播视频会导致电脑卡顿。基于这一需求,我开始研究硬解码与软解码的相关概念,并尝试参与 Chromium 开发,开启了 Chromium 开源贡献的持续探索。

为什么要参与 Chromium 建设?

深入理解浏览器工作原理

作为一个前端开发者,我们的代码都跑在浏览器里,有时候遇到了浏览器Bug,却不知道如何解决,不妨来看看 Chromium 是如何实现的。从横向角度看,JavaScript 运行在封闭的沙盒环境中,其功能受限于预定义的接口,技术边界较为明确,比如 OS API,前端是没有什么方式能调用到的,因此了解浏览器是如何运行的有助于提升技术理解, 明确技术的边界所在。

为什么 GPU 进程要开一个 Viz 线程去配合 Main 线程,为什么要有 Mojom(虽然很早就知道它了,但是一直似乎摸不到门道),浏览器 API 又是怎么通过 v8 binding 掉到渲染进程,Chrome 何时选择硬解码,何时选择软解码,如何到达整体效果最优,如果不去建设,亲身写代码,有时候很难理解,或者理解的不到位。

提升技术认知

最初开始参与 Chromium 开发时,我深刻感受到其复杂性与魅力。获得 CQ Dry Run 权限后,仿佛打开了技术探索的新篇章。

原来实现一个浏览器,有这么多种的测试:

  1. C++ 单元测试(验证最基本的逻辑正确性,比如平时开发遇到的 Media Unittests, Viz Unittests, Gfx Unittests)。

  2. GPU Test(验证多 GPU 下结果的一致性,比如测试 AMD/NVIDIA/Intel 编解码的不一致问题)。

  3. Color Test(验证色彩一致性的测试)。

  4. Fuzzer Test(模糊测试,基于随机测试集,对发现代码崩溃,死循环等问题非常好用)。

  5. Chrome Browser Test(会真的开启一个最小版本的 Chromium,来进行 Headless 测试)。

  6. Blink Web Test(浏览器测试,JS + HTML + Test Harness,对 Web API 进行验证的测试)。

  7. Web Platform Test(跨浏览器测试,Safari/Firefox/Chromium 共享一套测试集,由这三家共同维护,旨在解决多浏览器下,行为不一致的问题)。

  8. 多系统 + 多平台 + 多架构覆盖(顾名思义,Win/Mac/Linux/Cros/LarcOS/Android/iOS 的arm64,x64 等架构都会测到)。

有专门的机器,整个平台24小时循环不断的跑单元测试,有专人 24 小时(夸张,也要睡觉的)盯着所有平台的测试结果,负责 Revert 代码(Google 内部叫 Sherrif)。

CQ Dry Run 编译整个 Chromium 只需要十分钟(参考:我家的 AMD 5950x 完成这个过程需要 2小时+)。

崩溃自动检测系统功能强大且高效,当 Chrome Canary 发生 UAF 等崩溃时,它会直接判断崩溃数量是否超过阈值,会自动 Bisect 到是哪个 Commit 导致,自动拉群,自动 At 人,Assign 修复。

Chromium 有一个叫 [bisect-builds.py](https://www.chromium.org/developers/bisect-builds-py/)[bisect_variation.py](https://chromium.googlesource.com/chromium/src/+/refs/heads/main/tools/variations/bisect_variations.py) 的东西,由于每次编译都会跑 CI 生成一份二进制,利用该工具,可以利用二分排查法测试有问题的版本区间范围,以最快速度定位到导致 Bug 的 Commit,该工具是我目前最常用的工具。

毕竟,纸上得来终觉浅,绝知此事要躬行。

结识全球开发者

我们平时开发代码一样,打交道的都是周围的同事,但当你参与开源社区建设时,可以与来自全球的开发者交流,拓展人脉。

协作的力量往往大于个体。例如,近期针对 Chromium 126 在 Apple Silicon Mac 上 H.264 播放失败的 Bug 分析,单靠个人可能难以快速定位问题。

通过这个过程,接触到的 Intel, AMD, NVIDIA, 微软, 谷歌, 杜比, 阿里巴巴, Opera 的开发者,会发现公司之间做事的方式的不同,这很有趣,大家也都有不懂的东西,遇到关键问题,谁都得老老实实查文献。

你的代码能跑 30 年

从某种角度上说,像 Chromium / FFmpeg 这种大型项目,一些核心的模块,如果你写完了,很多时候就没人动了,那你的提交记录会永远存在于系统,譬如我经常能看到 Chromium Media 内的代码是某某 10 年前写的,如果未来 Chromium 还保持现在的统治力的话,再跑 30 年也是有可能的。

参与开源建设的做事逻辑

客观的说,我认为要达成一件事,需要具备下述三点:

  1. 基本需求。

  2. 信念。

  3. 执行力。

第二点比较虚,我认为第一点,第三点其实是最重要的,但是往往却很难找到适合的需求来做,关于如何找事做,以及如何做,每个人理解不同,这里说说我的理解。

做 Chromium 不愿意做,但有趣的

了解什么是 Chromium 不愿意做的,即 Google 不愿意做的,毕竟整个 Chromium 项目是 Google 发起的,具有牢牢的把控能力,Google 的第一优先级一定是自家的东西,但是Google自家的不一定是字节跳动或者消费者,大众要的。所以这里的思路是,做 Google 不搞的方向。

HEVC 视频编解码

HEVC 并非 Chromium 的优先开发方向,但因公司业务需求,我们首先实现了 HEVC 解码支持。然后很自然就会想到继续去做编码,做 macOS 的 L1T1,当得知 macOS 14 beta2 + arm64 芯片可以实现 low latency encoding 后,就会马上想到给 Chromium 支持 HEVC L1T2,然后又会想去做 Android HEVC encoding。

做了 WebCodecs API 硬编码支持后,又会去想做 MediaRecorder API 的编码支持。

AC3/EC3 音频解码

AC3/EC3 是杜比的 Property Codec,虽然硬件早已付了专利费,软件可以集成,但 Chromium 一直不支持。但是 NAS 用户有这个需求,但凡有人喜欢用 Jellyfin / Plex 看电影,这事儿就值得做,尤其是考虑到所需代码量较少,实施成本较低。

因为做这个事,为支持这一开发,我开始研究多声道音频系统,并发现 Windows 和 macOS 实现多声道输出无需连接功放,仅需配备 USB 多声道声卡,结合二手市场购买的老款漫步者 5.1 音箱,总计花费 600 元(音响 500 元,声卡 100 元),即可满足开发测试需求,加上卖掉老音响回血的230元,只花费了330元,解决了我的 Mac/Windows 多声道开发测试需求,是个有意思的小众赛道。

漫步者多声道音箱

杜比视界

杜比视界是视频爱好者热衷讨论的高动态范围(HDR)技术,因其复杂性和争议性备受关注。,想去深入了解,最好的办法就是去研究它的代码,让 Chrome 去支持,或者适配。每次看到 B 站网友因为 Edge,Chrome 不支持杜比视界,尝试复杂的用户代理修改方案。通过实现原生支持,我们希望改善用户体验,提升浏览器功能。

最后通过写代码发现,只需要代码量不多的代码,就可以实现原生 <video> 播放 杜比视界 Profile5, 并且完全符合版权问题,尽管考虑到当前 Chrome 可能不会采用 MF for Clear 方案(个人推测)。

Windows 平台,原生 <video> 播放杜比视界 Profile5

要实现的上述功能也只是实验性质,进一步想到,MediaSource 在 Windows 平台无法播放杜比视界 Profile8 的问题是否能得到解决?毕竟对此功能需求反馈最为强烈的 B 站用户主要使用 Windows 平台。于是顺藤摸瓜发现,浏览器可以根据创建的 SourceBuffer 带的 Mimetype 来判断是不是杜比视界,这样杜比视界如果不支持,让开发者用 HEVCMimetype创建SourceBuffer 理论上就可以解决该问题,最终仅需300行+代码,B 站现在就可以全平台以 HEVC HDR10/HLG 模式播放杜比视界了,Chrome/我/广大网友皆大欢喜。

做 Chromium 做了但做不好的

HDR 支持

Chrome 早在 M100 版本之前就支持基本的 PQ/HDR10 HDR播放了,但效果仍有改进空间。原因在于 HDR、Media 和 GPU 相关的开发由不同团队负责,各自关注的重点有所不同。

所以可以由一个第三方角色,去优化它的小细节,来把事情搞好。

为了搞好这件事,需要有点付出,因为要确保所有品牌的显卡都能显示和渲染的非常到位,通过二手市场购置了多款显卡,包括 AMD、Intel、NVIDIA 和摩尔线程的型号,涵盖不同世代和性能级别,要达到的目标就是,确保所有的显卡,播放 HDR 视频时,不管是在开启还是关闭 Windows HDR 功能前后,都能拥有一致的色彩渲染结果,并且性能 OK。

由于 HDR 路径多,情况多,显卡厂商不尽一致,从 M105版本,直到最近的 M125 版本才实现了这个目标,关于 HDR 的 CL 可能不恰30个。

色彩管理

Chrome 浏览器为了在各平台上达到最好的渲染性能,通常需要要调用系统 API 来将渲染交接到 OS,以实现 MPO (Multi Plane Overlay), 而系统支持的 Color Space 往往没有 Skia Render 支持的多,又或者有些色彩空间的支持的有问题,又或者系统的 MPO 实现有 Bug,导致 Chrome 的很多视频渲染问题都是有 MPO 导致。

MPO 是由 GPU 团队维护的,而 GPU 团队像我刚才提到的一样,缺少对色彩管理细致的理解,很多时候视频渲染结果出异常,他们并不能感知到,因此这是我今年主要发力参与建设的目标,持续挖掘已有功能的潜力。

扣细节,服务社区

  1. Chromium 没有 Pull Request,所以可以每天早上看一下 Core Team 的 Incoming review,了解大家最近动向,在了解社区大方向的同时,关注是否有待完善的能力。

  2. 关注社区最新提的 Issue,短期的 Issue 比如最新版本的劣化,Bug之类的,提前 Assign 到自己,或者长期没人跟进的 issue,这种也不占少数,尽量可以服务好社区。

注重质量,积攒信誉度

  1. 除了尽量自身代码质量符合贡献要求外,仓库内的一些已有代码,也或多或少存在问题,平时经常阅读仓库的代码,往往会发现一些 Bug,或者有一些新的灵感,又或者对问题有新的理解。

  2. 应尽量避免出现问题,做到自测充分。尽管社区的基建和反馈机制,能发现绝大部分 Bug,但是有些 Bug 在 Canary 或者 Beta 阶段可能难以发现,最终导致 Stable 发布后出线上问题,这种问题会影响提交者的信誉度。

如何长久可持续发展

Work-Life Balance

最初两年,我投入大量时间参与社区工作,例如深夜回复代码审查问题。为保持健康,我逐渐调整习惯,确保工作与生活的平衡。后面戒掉了喝咖啡之后,也不再过于拼命,改不了就明天,后天,大后天,没什么是必须要做的,总结下来几个点:

  1. 业余时间为主,千万不要日常工作与生活。

  2. 尽量避免半夜回复 Comment,起床改 CR。

与工作结合

能与工作结合永远都是最好的。

  1. 对于绝大多数同学,参与建设的最主要方式是与工作结合。

  2. 工作之余反哺社区,拿到公司内的产出,又收获开源经验。

转化为兴趣导向

如果结合不了,工作内容和开源社区搞得完全没什么关系,可能会有些难度,比如我自己就是个例子,工作内容完全不相干,但是还是要想清楚自己想要什么:

  1. 钱,是没有的,最多拿来当当谈资。

  2. 是否能转换为兴趣点,能获得成就感,类似打游戏做任务,愿意持续投入。

总结

回顾过去,展望未来,个体在这个时代能做的事情是有限的,工作虽是点滴贡献,重在持续积累。在未来会继续用打造工具集的思路去贡献 Chromium,持续完善 Web 多媒体能力。如感兴趣欢迎联系交流,一同共建 Chromium 社区 👊🏻。

团队介绍

我们是字节跳动-国际化内容安全平台团队,致力于为字节跳动国际化产品的用户维护安全可信赖环境,通过开发、迭代机器学习模型和信息系统以更早、更快发掘风险、监控风险、响应紧急事件,以人工智能技术支持业务发展,力求更高效、更敏捷、更全能地维护站内生态安全。 2025.8.4 校招投递渠道已开启,欢迎私聊投简历发到邮箱:zhusida@bytedance.com,我的内推码:URNUMT8,投递链接:job.toutiao.com/s/\_ZSt2mBl…