# FFmpeg:互联网视频背后的不可思议技术 | Lex Fridman Podcast #496
类型:字幕 语言:英语
- 让-巴蒂斯特:重要的是,你的代码好不好?我们在意的是优秀的代码。我们不在乎你是谁。比如你也许是一条狗,我也不在乎,对吧?我不在乎你从哪里来。我需要看你的代码。哦,是的,但我是意大利、德国、美国某家超大型公司的工程师。我们不在乎。我们在乎的是你代码的质量,因为这定义了我们的社区;这也意味着,我们有很多贡献者来自非常不同的背景,而且非常内向。当然。但这没问题,对吧?
- 基兰:FFmpeg 可能是全世界最大的 CPU 使用者之一。过去几分钟里我们刚说过的每一句话,都是某个人一生的工作。每一句话都能写成书。所以很多情况下,它的复杂程度高得惊人。
- 莱克斯:FFmpeg 为所有编解码器写了十万行汇编。
- 基兰:所有编解码器。嗯。
- 基兰:而光这一个就有二十四万行。每一个周期都重要。我们说的可能是三十亿台设备,它们会不停地解码视频。比如现在 Netflix 的视频有 30% 是 AV1,YouTube 有 50%。
- 基兰:顶级视频编解码器就该是这个样子:79.9% 汇编,19.6% C,0.5% 其他。
- 基兰:不可思议的是,这些推文说的都是事实,但人们会发疯。
- 基兰:过去两年里,他们一直发疯。说,不,内建函数就很好。编译器……
- 基兰:你可以优化你的编译器。自动向量化,是你的错。是你不懂。可我们早就试过了,对吧?
- 基兰:两年了,两年以后,给他们看了上百个手写汇编的例子,他们还是说:不,不,不,是你做错了,编译器可以做到。情报机构也试过来问:你能不能在 VLC 里放一个后门?
- 让-巴蒂斯特:是的。有两个机构。
- 莱克斯:那你怎么回答?
- 让-巴蒂斯特:不。当然,我当时没这么客气。
- 莱克斯:基本上就是说,“绝对不行”。
- 让-巴蒂斯特:如果我们不得不让自己的软件妥协,我们就会把它关掉。这一点很明确。
- 莱克斯:基兰,有什么推文是你后悔发的吗?
- 基兰:我后悔的推文?
- 莱克斯:还是像那首法国歌怎么唱的?毫无悔意。
- 基兰:什么都不后悔。不,因为后悔是对你心智的攻击。
- 莱克斯:下面这段对话,全部围绕 FFmpeg 和 VLC 展开,嘉宾是让-巴蒂斯特·肯普夫和基兰·昆亚。FFmpeg 是一个开源软件系统,是 YouTube、Netflix、Chrome、VLC、Discord,以及基本上互联网上所有触及视频或音频的平台背后那条看不见的骨干。它可以解码、编码、转码、流式传输和播放几乎所有曾被创造出来的视频或音频格式。对我来说,它是有史以来最不可思议的软件系统之一,而且这一切都由志愿者完成。VLC 也是一款传奇软件。它是一个开源媒体播放器,基本上你扔给它什么,它都能播放;任何格式、任何平台、没有广告、没有追踪。它的下载量已经超过 60 亿次。再说一次,对我而言,它一直是我最喜欢的软件之一,还有那个最传奇的标志。所以在这场对话里,我当然必须全程戴着 VLC 交通锥帽,向它致敬。最重要的是,再次感谢那些了不起的志愿工程师。他们把心血和灵魂投入到这份代码里,而这份代码被数十亿人使用和喜爱。谢谢你们。至于本期和我对谈的两位伟大工程师和人,让-巴蒂斯特是 VideoLAN 的主席,也是 VLC 和 FFmpeg 背后的关键人物。基兰是一位长期从事编解码器工作的工程师、FFmpeg 贡献者,也就是现在已经声名狼藉的 Twitter/X 上 FFmpeg 账号背后的人。我建议所有人都关注那个账号,看迷因,也看它毫不道歉地赞美开源和伟大的底层软件工程。我还想说,现代文明有这么多部分建立在这样一种软件之上,这令人振奋,也令人谦卑:这些软件的作者并不追逐名声或金钱,而是迷恋工程这门手艺。我们生活在一个每天有数十亿人消费视频的世界里,却几乎没人会想到它下面那台看不见的机器。但那台机器很重要。开源基础设施很重要。它是一个伟大的例子:人类安静地跨越国界协作,为我们其他人建造出有用、耐久、优雅的东西。所以这场对话不只是关于编解码器和媒体管线,也关乎一种更深层的工程精神和慷慨精神,正是这种精神让 FFmpeg 这样的项目成为可能。我再怎么说都不嫌多:谢谢你们。这里是 Lex Fridman Podcast。若想支持本节目,请查看简介里的赞助商;那里也有联系我、提问、反馈等链接。现在,亲爱的朋友们,有请让-巴蒂斯特·肯普夫和基兰·昆亚。传说中 VLC 什么都能打开。你们知道它能打开的最怪的东西是什么?
- 让-巴蒂斯特:你知道,有很多人用 VLC 来录 VHS 录像,对吧?就是把它接到采集卡上,然后基本上就能录 VHS 视频。
- 莱克斯:这是怎么工作的?
- 让-巴蒂斯特:基本上,就是那种采集卡,你可以插 Peritel,或者 RCA。你接上之后,VLC 实际上可以播放这类采集卡;还有一个模块可以直接控制某些 VCR 摄像机。我们最近还支持了 DVD-Audio,对吧?我们花了一个夏天做 DVD-Audio 支持。而现在基本没人还在做什么 DVD-Audio 支持了。那里还有自定义的加密方案。
- 莱克斯:Lucasfilm 的那个呢?
- 让-巴蒂斯特:哦,对,当然还有各种奇怪的编解码器支持,FFmpeg 支持的游戏编解码器。
- 基兰:有一款 Star Wars 电子游戏,它开头那十秒钟的片段,有人专门去实现了它,并确保它在当年某一张光盘上的那一小段游戏序列里达到比特级精确。
- 让-巴蒂斯特:还有个有趣的事,有一次 VideoLAN 大会上,我们办了个比赛,让大家做出最奇怪、最糟糕的文件,看看 VLC 能不能播放。
- 莱克斯:最后是什么?那个文件是什么?
- 让-巴蒂斯特:那是 Derek 做的一个 MKV 文件。每一帧都在改变分辨率、宽高比、旋转角度,反正就是……
- 莱克斯:它能播放吗?
- 让-巴蒂斯特:能。还有另一个,整段视频其实都是动画字幕,对吧?SSA,对吧?所以……
- 基兰:对,我记得那个。
- 让-巴蒂斯特:每一帧都是黑帧,但上面有一个每帧都会动的字幕。
- 基兰:还有一个文件,同时既是合法的 ZIP,又是合法的 MP3,或者类似这样的东西。
- 让-巴蒂斯特:所以是的,我们办了一个愚蠢文件比赛。
- 莱克斯:而且它成功了。所有这些愚蠢文件它都打开了。
- 让-巴蒂斯特:是的。
- 莱克斯:顺便说一下,给不熟悉的人解释一下,我现在戴着一顶帽子。公平地说,这个交通锥是不是史上最好也最糟糕的标志?
- 让-巴蒂斯特:是的,绝对是,对吧?VLC 的标志太有辨识度了。我们团队人数很少,但这个图标到处都有人知道。我去印度或中国很偏远的地方,人们也认识这个交通锥,对吧?而我们主网站 25% 的流量来自 “cone player” 这个搜索词。所以很多人其实不知道 VLC,对吧?他们知道的是那个交通锥播放器。
- 莱克斯:他们在 Google 上搜的就是 cone player。
- 让-巴蒂斯特:对。他们去 Google 输入 cone player,然后下载 VLC,对吧?所以它很有标志性。有一次我们开玩笑想改掉它,对吧?我们说它要变成某种 Caterpillar 工程机械的样子,而且是在 4 月 1 日说的。结果我们收到了大约一万封邮件,说“不,别改标志”,之类的。所以它真的很有标志性,很独特。你如果要做一个视频播放器,通常会在电视上放一个播放按钮,对吧?那就是 YouTube 的标志,对吧?很没新意。而这个是橙色的,对吧?
- 莱克斯:是的。
- 让-巴蒂斯特:它很亮,而且很怪。
- 莱克斯:它很荒诞,很离谱,也很好笑。它变成了迷因,而迷因又变成了文化。对。
- 让-巴蒂斯特:然后你就一直保留它。你知道,再过 20 年,你还是会有那些交通锥,还会想起:哦,对,那曾经是一个视频播放器。
- 莱克斯:是的。我们还会谈到 FFmpeg 的使命中有某种归档的层面。所以你可以想象,1000 年以后,我们会有所有这些只有 VLC 才能打开的视频。人类文明已经毁灭过很多次,最后剩下的只有这种东西:蟑螂到处爬,旁边是 VLC 标志,还有一些 VLC 能打开的归档影像。外星人来了,按下播放键,就能看到这一切,因为……
- 让-巴蒂斯特:嗯,真的、真的希望如此,对吧?但还有很多迷因,人们会说:“我敢肯定,我把一块煎饼塞进 DVD 光驱里,VLC 也能播放。”比如……
- 莱克斯:他们能吗?
- 让-巴蒂斯特:不能,我们试过。不行。嗯……
- 莱克斯:不行。
- 让-巴蒂斯特:但我们确实有一段我们尝试的视频。没成功。
- 莱克斯:给物理现实写一个编解码器,我都不知道那会是什么样。
- 让-巴蒂斯特:有人做过类似的事,对吧?他打印了一个小交通锥,就像我们当作纪念品发的那种,里面放了一个 RFID 芯片,作为他播放电影的方式。于是他把这个东西放到 RFID 读取器上,一放上去,它就会播放像最后一部 Star Wars 之类的电影。所以他不是摆一堆 DVD 盒子,而是周围放满了 VLC 交通锥;他把它接上,这就成了物理对象。
- 莱克斯:所以我们要谈的,是围绕视频编解码器、视频编码、视频解码、视频流、我现在戴在头上的这个视频播放器客户端,以及整个让自由媒体成为可能的生态系统。我们会谈 FFmpeg,会谈 VideoLAN、VLC,以及所有那些可能被数十亿人使用的不可思议的视频技术。JB,你是传奇 VLC 播放器背后的主要开发者。基兰,在很多事情之外,你还是 Twitter 上传奇 FFmpeg 账号背后的主要开发者。你们两位都有一些很辛辣的观点,我会这么说。所以今天我们想谈 FFmpeg 和 VLC。给不了解背景的人一点上下文:我确信基本上所有正在听的人,都经常用过这两项技术,只是可能并不知道。FFmpeg 基本上支撑着互联网上大多数视频,包括 YouTube、Netflix、Chrome、Firefox,当然还有 VLC,以及无数其他视频平台。据估计,线上和线下超过 90% 的视频处理工作流都涉及 FFmpeg。VLC 的下载量至少有 65 亿次。但这个数字很可能还要高得多,因为真的没法准确统计。几乎任何操作系统都支持它,几乎任何媒体格式也都支持它。限制是它打不开煎饼。那么,我们能不能先讲一些基础,帮助大家理解这里面都涉及什么?当我们在像 VLC 这样的视频播放器上按下播放时,会发生什么?它是怎样从文件或流,变成屏幕上的像素和扬声器里的声音的?有哪些主要阶段需要知道?
- 让-巴蒂斯特:这里有几个阶段,对吧?第一阶段,是从一个地址,也就是某种 URL,拿到字节流。比如 HTTP、文件、DVD,对吧?你给出媒体的路径,它给你一串数据流。
- 基兰:这股流需要由所谓的容器、解复用器或 demux 来切分。我们会尽量少用术语,但它需要开始标记视频帧和音频帧。它只是从操作系统一次一块地拿数据,然后要开始把这些帧切成压缩数据。接着它需要对视频帧做一些简单解析,主要是弄清这个编解码器能不能由 GPU 解码,还是需要回退到软件解码。我们现在很习惯假定 GPU 会播放所有这些东西,会有硬件加速。我认为多达 45% 的文件其实不能由 GPU 解码。所以这些东西必须被探测、被检测。某个给定编解码器可能有不同变体,其中一部分能在 GPU 上解码。不同 GPU 厂商的能力也可能不同,所以也要检测。如果它支持 GPU,就把它传给 GPU 这个黑盒。那如果需要软件回退,一开始首先要做的是去熵编码,也就是去掉比特流里的数学编码。这会用到哈夫曼编码或算术编码之类的能力,实际解压比特流的数学层。然后我们要开始读取用于帧内预测的语法元素。帧内预测就像视频里的静态图像,也就是你的 I 帧。它在空域中工作和运算。所以你在空域做帧内预测。你会得到一个残差,因为你的预测并没有完全匹配现实。你做了一个预测,但还剩下一点差异,那就是所谓残差。它存储在频域中,并通过量化来压缩空间。然后我们需要做反变换,把它们带回空域,再应用这些残差。
- 莱克斯:所以解码过程很大一部分是:这个东西被压缩了,而你必须预测本该放在那里的最高质量内容。I 帧是在空间上你拥有的最佳表示。然后根据编解码器不同,还可以发生大量时间维度上的压缩,之后你就在预测。你预测的是当初以最原始形式被捕捉到的现实。
- 让-巴蒂斯特:是的,因为人们没有意识到,视频和音频的压缩率是一百倍,对吧?人们没有意识到我们压缩得有多厉害。音频方面,从普通音频到 MP3,你大概压缩十倍,对吧?到了视频,你需要一百倍、两百倍。所以你必须移除大量细节,但那些是你并不在意的细节。因为我们做的所有压缩,这点非常重要但常被遗忘,都是为了让人类观看。所有编解码器,无论音频还是视频,基本上都在模拟你的耳朵如何工作,对吧?有很多关于耳朵响应的东西;眼睛也是一样。所以比如视频里,我们不在 RGB 上工作,对吧?大家都以为会用 RGB。我们不用。我们转到 YUV,基本上一个是亮度,另一些是颜色。这和你的眼睛相匹配:你的眼睛里有视锥细胞和视杆细胞,对吧?其中一些看亮度,另一些更多看颜色。所以我们需要大幅压缩,也就需要劣化。但为了劣化,我们必须匹配人类感知,这就是它这么困难的原因。然后我们还要使用最大的能力、数学能力,以及非常复杂的技术。就像基兰说的,我们转到频域。我们做大量反量化,为了得到最好的压缩,但看起来仍然不错。
- 莱克斯:你是在试图压缩,同时让人类感知到的质量尽可能最高。
- 让-巴蒂斯特:没错。而且这非常重要,对吧?压缩不是 ZIP。ZIP 是数据进去,数据出来,对吧?你用各种 ZIP 压缩去接近极限。这里我们是在劣化信号,对吧?所以我们必须以尽可能好的方式劣化音频和视频信号。我们可以做到,但它首先涉及大量关于眼睛如何工作的理论知识,也涉及大量数学变化、大量数学技巧。比如从 RGB 转到 YUV 时,我们经常做的一件事,是把颜色的分辨率相对于亮度降下来。大多数时候,即使不做别的压缩,光是这一步就能把大小减半,但大多数人看不出来,对吧?诸如此类。然后你会进入非常复杂的数学变化。当然有傅里叶变换,虽然事实上它们不是傅里叶变换,更像是离散余弦变换,但思想是一样的。到了频域,我们把视频按块拆开,对吧?所以当解码错误时,你会看到那些块;编码不好时,你也会看到那些块,等等。最终达到极高的压缩状态。每一代编解码器,在同等质量下大概能再少 30%。这需要巨大的计算能力。
- 基兰:不,不,你应该展开讲。它是好 30%,但要多一个数量级,甚至可能多两个数量级的压缩算力。这才是巨大的差别。
- 莱克斯:你说压缩算力是什么意思?
- 基兰:抱歉,是达到那种压缩水平所需的 CPU 算力。
- 莱克斯:哦,对。所以你必须能够利用 CPU,有时也要利用 GPU,就像你提到的。我们也应该提一下,大量这类编程都是在尽可能底层的栈上完成的,无论是 C,当然还有就像那个传奇 Twitter 账号一遍遍强调的,大量汇编。
- 让-巴蒂斯特:整体上会发生的是,你有一个地址,对吧?它通过操作系统给你一串字节流、一串数据流。这是第一步。第二步是解复用,也就是把音频、视频、字幕分离成不同轨道。然后在每条轨道上,你会把它们解压、解码:音频用音频编解码器,视频用视频编解码器,字幕用字幕编解码器。等你把这些东西解压出来之后,你就有了原始图像、原始数据,然后你会和显卡、屏幕交互,把它显示出来。音频也一样,你会和声卡交互,再由声卡转成模拟信号送到扬声器。
- 基兰:而我们过去几分钟里刚说过的每一句话,都是某个人一生的工作。每一句话都有书在讲。所以很多情况下,复杂度高得离谱。你知道,每一句话背后都有整个行业里成千上万的人在工作,有书为它而写。所以这里有很多细节、很多微妙之处,既有学术现实,也有工程实践中的现实,两者都很重要。
- 莱克斯:呃,我们提到了编解码器,但我想你还没提到容器。所以我们谈到的这些东西,实际的容器是什么?大家可能熟悉 MP4、MOV、MKV。那么,容器和放在里面的东西到底有什么区别?
- 让-巴蒂斯特:容器也就是我们说的复用器,对吧?我说解复用时,意思就是把它从容器里拆出来。实际上如果你看,mux 指的是 multiplexer,也就是复用器;demux 是 demultiplexer,也就是解复用器。mux 和 demux 就是这些。同样,codec 实际上是 coder 和 decoder,也就是编码器和解码器。所以容器是一组多条轨道的集合。普通人会把它叫作文件格式,但它比这个要微妙一点。最知名的当然是 MP4,但我刚开始的时候是 AVI。AVI 是微软的视频格式,而 MOV,也就是 M-O-V,后来变成 MP4,是苹果的格式。在开源社区里,VideoLAN 现在仍然活跃的一位成员叫 Steve Lhomme,他创立了 Matroska 格式,它更复杂一点,也更面向未来。还有很多其他格式。
- 莱克斯:所以,这是个很常见的事,甚至这场对话里也可能发生:人们会把容器和编解码器混淆,对吧?比如把 MP4 和 H.264 混在一起。这算是很严重的违规吗?
- 让-巴蒂斯特:不,不算,因为从技术上说,H.264 的名字是 MPEG-4 Part 10。因为 MPEG-4 实际上是一个元规范,里面包含好几种东西。比如有 Part 2;里面也有音频编解码器,对吧?AAC 事实上是 MP4 audio 之类的东西。MPEG-4 规范里实际上有好几种视频编解码器。其中一个是 MPEG-4 Part 10,也叫 AVC,也叫 H.264。对吧?所以这完全是行业自己的错,把事情弄得很难理解。于是人们很难搞清楚:为什么有时你说 MPEG-4 Part 10,其实指的是 H.264;又为什么它不是 MP4。
- 莱克斯:所以从技术上讲,你可以把各种不同编解码器硬塞进容器里,而且可以塞得很糟糕。
- 基兰:但大体上说,MP4 通常被理解为 H.264 加 AAC 音频。99% 的时候就是这样,剩下的影响很小,可以说只是边缘效应。所以这不是世界末日。确实有人会为此恼火。但现实里,比如 VLC,我只想指出,文件可能写着 .MP4,但它可能完全是另一种东西。这也是 FFmpeg 和 VLC 面临的挑战之一:真实世界和一个三个字母的文件格式完全是两回事。
- 让-巴蒂斯特:这一点非常重要,对吧?比如在 VLC 和 FFmpeg 里,我们会丢开文件格式本身,对吧?我们查看文件内部,理解里面到底是什么。因为很多人会说:“哦,这是个视频,那它应该必须是 MP4。”但从技术上讲,它可能是 MOV,也可能是 MKV。所以我们会实时分析手上所有内容,不相信格式。
- 莱克斯:那么 .MP4 这个事实到底给了你什么信息?
- 让-巴蒂斯特:它有帮助,对吧?它给你一个提示。比如,哦,它以 .MP4 结尾。我会先用 MP4 容器解复用器打开并探测它,看看它是不是应该是这个。但我不信任它。如果我迷失了,我会说:“好吧,也许我要试试别的。”所以它会提高某个模块的优先级。
- 莱克斯:那你们是怎么做到的……这里稍微岔开一下。你知道,比较笨的情况是,如果你尝试按 MP4 处理,但结果发现它是一个和你预期不同的编解码器,大多数播放器就会在那里崩掉。
- 让-巴蒂斯特:是的。
- 基兰:是的。
- 莱克斯:所以你们怎么做到不崩?从哲学上讲,我相信一路上有很多绊脚石,很容易就崩掉、停下、惊慌,然后结束。VLC 是怎么不这样的?
- 让-巴蒂斯特:这就是 VLC 受欢迎的原因。但原因其实是,VLC 原本只是一个叫 VideoLAN 的流媒体解决方案的客户端,那已经是很久以前的事了,从 90 年代末开始。当你播放 UDP 网络上的视频时,它们可能会损坏,对吧?所以你不能信任你的输入。这在安全上也非常重要:不要信任输入。因此 VLC 里的一切都准备好和损坏文件一起工作。这是从一开始就有的哲学理念,而且所有东西都按这个理念工程化了。它是一种文化。所以,比如说,VLC 因此变得很流行。很久以前,人们会盗版内容,今天少得多了……
- 莱克斯:我们中当然没人干过这种事……
- 让-巴蒂斯特:当然没有。嗯,有些文件,比如 AVI,用来播放的元数据在文件末尾,对吧?当你还在下载时,你拿不到那部分。所以 VLC 就会说:“嘿,这个文件坏了,但我还是要试着解释它。”这非常有用。
- 莱克斯:我们已经暗示了各个阶段的厉害之处,也暗示了编解码器的厉害之处,以及其中的深度、丰富性和复杂度。那我们试着定义一下:什么是视频编解码器?里面涉及什么?压缩某个东西意味着什么?你已经开始暗示这一点了,但我们能不能再展开一点?
- 基兰:任何视频里都有大量冗余,包括空间冗余和时间冗余;任何视频编解码器的目的,就是移除这些冗余数据,并把数学性质用作这个削减过程的一部分。很多时候,压缩会使用多出好几个数量级的计算量,因为压缩比解压缩成本更高,无论是财务成本还是 CPU 资源成本都是如此。所以在这个意义上它是不对称的。常见情况是,压缩只做一次,但另一个文件可能会有很多观看者。所以你要把这些信息压缩 100 倍、200 倍,移除冗余信息,并利用数学性质把它变小,同时还要具备错误恢复等属性。就像 JB 提到的,VLC 一开始被用来播放 UDP 网络源,而 UDP 网络源会丢包。因此,编解码器的一些设计目标也是要能够恢复。你实际上需要能够加入一条流。它不一定是文件。你需要加入,进入解码过程,然后开始解码。
- 让-巴蒂斯特:为了给不熟悉的人一个更形象的说法,对吧?当你看任何类型的电影时,对吧?你会看到摄像机在平移、在移动。你会意识到,比如说,整个背景在一分钟里都是一样的,对吧?或者三十秒里都是一样的。所以你可以复用背景里看到的那朵云,从一帧复用到下一帧,对吧?因此,你拥有的内存越多、算力越强、能做的比较越多,就能压缩得越厉害。大多数现代编解码器基本上都在做这件事。
- 莱克斯:为了把它说得更明确一点:什么是视频?视频就是一堆像素,通常是 RGB。你有三个数值,有一个像素网格,然后每秒有二十四帧、三十帧或者六十帧。也就是说,这些像素一遍遍重复,每秒三十次显示不同的东西。所以问题,无论从哲学上还是技术上说,都是:我怎么把这一切压缩,把这一切以 100 倍的效率存储下来?
- 让-巴蒂斯特:对。或者 1,000 倍,对吧?
- 莱克斯:1,000 倍。
- 让-巴蒂斯特:目标就是 1,000 倍,对吧?
- 莱克斯:而目标在于,当你说“冗余”时,什么是冗余?也就是说,最好是那些即使缺失了,人类也不会注意到的东西。
- 让-巴蒂斯特:比如说,你有一张云的画面,对吧?到下一帧,它大概率还是同一片云,所以这就是冗余。你可以只放一次,不再重复。或者比如我身后是一片黑色背景,整张画面里的黑色都是一样的。于是你可以说:“好,在这张图里,左上角的像素和右上角的像素,我不再给具体数值,只告诉你它和左上角一样。”然后,对于第一帧,你还可以复用上一帧、上上一帧里的某些东西,如此反复。基本上,这种思路可以无限延伸,但它又会受内存或算力限制。比如,如果你要在 4K 分辨率下比较两百帧之前的像素,那计算量就非常巨大。
- 莱克斯:然后播放的时候,你还得把这一切解压出来。所以编解码器里的编码和解码,是不是一个耦合开发的过程?
- 让-巴蒂斯特:是的,完全是。而且这里有两套不同的取舍。你是要压缩得更多,但让解码更困难?还是要做一个编码更复杂、解码更容易的编解码器?或者做一个更容易编码的编解码器,因为你需要速度,但客户端,也就是播放器,要花更多时间?这就是为什么会有这么多不同类型的编解码器,因为这从来不简单。更复杂的是,像 AV1、AV2 或 VVC 这样的现代编解码器,其实并不是一个单一的编解码器。它们是一组工具。一个编解码器里有多个工具、多个“编解码器”,根据图像内容选择更高的压缩率。
- 基兰:稍微展开一下,AV1、VVC 这样的编解码器面向的使用场景非常广。它可能处理屏幕共享内容,也可能处理视频,或者动画。这些都需要不同的编码工具。所以现在的做法是,把一组工具放在一起,称作 AV1、AV2 或 VVC,以支持不同场景。比如你在 Zoom 上共享 PowerPoint,接着又需要给观众播放一段视频。这个编解码器就必须根据内容改变它的工具集,用不同方式压缩。
- 莱克斯:就像你说的,AV1 里的每一部分、组成这些工具的每一部分背后,都有一群非常厉害的工程师。我们其实已经绕着这个话题讲了一圈,聊了 VLC、标志、那顶帽子。现在来聊 FFmpeg。FFmpeg 到底是什么?
- 让-巴蒂斯特:FFmpeg 基本上是一组用于编解码器的底层库,也就是压缩和解压缩、复用器和解复用器,以及过滤器。核心就是这些。除此之外,它还有几个工具,可以让你创建某种管线来处理各种视频文件。它作为库被用在几乎所有东西内部,从 VLC 到 Chrome,到你的智能电视,基本上你在网上看到的任何视频,通常都用到了 FFmpeg。FFmpeg 里有所有这些工具,有时也依赖其他库,比如 x264、libvpx 等等。所以它现在确实是处理图像的事实标准工具。
- 基兰:从哲学层面看,我觉得很不可思议:你的家庭录像、你祖母的家庭录像,和万亿美元公司的视频,实际上都在使用同一套技术栈,站在同一个水平线上。那些大公司有三千行长的 FFmpeg 命令也不会让人意外。有些公司用 API,但也有些就是使用很长的命令行。
- 莱克斯:是的,它有一堆工具,真正的命令行工具,比如 FFmpeg,当然还有 FFprobe。还有各种库,libavcodec、libavformat、libavfilter。但命令行里的 FFmpeg 简直是传奇,因为你可以剪切,可以做太多事。参数非常多,你几乎可以把一切都定制到极致。
- 基兰:它是一门语言。它真的是一门语言。
- 莱克斯:它确实是,对,你可以把它看成一种编程语言。
- 让-巴蒂斯特:当然,我也这么认为。因为大多数人会拿 FFmpeg,输入一个文件,输出一个文件,然后指定格式,对吧?但你也可以写出几千个字符的命令。我们也见过有人用程序生成命令行来调用 FFmpeg。现在还有很多人用 AI 来生成 FFmpeg 命令行,因为你根本不知道那些参数都是什么。但你可以在命令行里指定非常多的过滤器。所以 FFmpeg 就是这样一套用于多媒体处理的工具箱,所有人都在用。每个观看你视频的人也都在用。你在 YouTube 上看视频,服务器端很可能用了 FFmpeg。客户端大概是 Chrome,那你同样也在用 FFmpeg。你用 OBS 录制,也是 FFmpeg。你用很多重要的大型专业设备,里面某个部分也很可能正在运行 FFmpeg。
- 莱克斯:我的意思是,有太多例子了。为了让大家有个概念,我在各种事情上都经常用 FFmpeg。哪怕是很琐碎的事,比如拿一段视频,加上片头和片尾,让一个淡入另一个,那个叫什么来着?dip to black,也就是淡到黑场,再显示下一段视频,音频也做同样处理。音频会交叉溶解,先变小声,再重新变大声。还有很多事,比如把字幕显示在画面上,也就是把字幕烘进视频里。你可以自定义字体,可以做各种音频和视频的叠层。能做的事有一百万种,而且所有这一切基本上能神奇地适配任何编解码器。音频和视频端,只要你塞进去的东西,它都能工作。
- 让-巴蒂斯特:如果你看一看,比如说,你可以在 FFmpeg 的命令行里做一些原本要用 Adobe After Effects 才能做的事。这很有意思,因为在图像领域并没有这样的工具。也有几个工具,但没有 FFmpeg 这种广度。
- 莱克斯:ImageMagick 有类似的……
- 让-巴蒂斯特:是的,但你不会……
- 莱克斯:……精神,但是它……
- 让-巴蒂斯特:……做不到一些过滤器,复杂过滤器。你没有一个命令行版的 Photoshop,对吧?但在视频领域,你有命令行里的 FFmpeg。
- 莱克斯:对。这太不可思议了。它就像一个例子:一群优秀的人聚到一起,有一个愿景,并且多年坚持这个愿景,这很了不起。
- 让-巴蒂斯特:而背后的愿景,对 VLC 和 FFmpeg 都一样,就是把非常复杂的东西做得让普通人、让每个人都容易使用。我们的目标,是把技术上极其复杂的东西变得易用。人们用 VLC,把一个文件拖进去。他们并不知道这个文件有多复杂,但它就是能播放。或者人们把各种东西放进 FFmpeg,配上复杂过滤器,它就像魔法一样工作。这就是我们的使命:把非常复杂的东西做好。
- 莱克斯:如果这还需要传统电视演播室那一整套配置,我们不会坐在这里,这个播客也不会在这里。正是 FFmpeg 这样的工具让这件事民主化了。播客和流媒体革命、YouTube 革命,都与此有关。FFmpeg 是其中的重要角色,因为它让一项过去在九十年代需要几十万美元设备才能完成的压缩技术变得人人可用。那时设备有汽车那么大,而现在每个人几乎都站在完全相同的起跑线上,这非常了不起。
- 基兰:它让很多人有了发声的能力。顺便澄清一下,我们说“你不会在这里”,指的不是作为人的你,而是这个播客。
- 莱克斯:这个播客。哦,抱歉。我说的“你”是……抱歉。
- 让-巴蒂斯特:我还是会存在的。VLC 在生物学层面上并没有参与创造我这个人。
- 让-巴蒂斯特:但你也会意识到,一切都从文本转向图像,又从图像转向视频。看看社交网络,视频无处不在。它是最强大的媒介。你看 Shorts、Reels 和 TikTok,视频在传递信息方面强大得惊人。但它的复杂性也很高。
- 莱克斯:这正是人们没有意识到的地方。它真的把力量交给了全世界的个体,那是真正的自由。我觉得难以置信的是,我们居然还没提到对不熟悉的人来说最显而易见的一点:它是开源的,背后有一个由用户和开发者组成的开源社区。所以它其实是一场运动。后面我们会从很多角度谈它背后的社区。但你能不能谈谈开源这个元素?也就是说,当我们说 FFmpeg 是什么时,它是一个开源项目。
- 让-巴蒂斯特:是的。FFmpeg、VLC、x264、VideoLAN,我们做的一切都是完全开源的。对于不了解开源的人,我通常用巧克力芝士蛋糕来类比。通常,当你想买芝士蛋糕时,你去面包店,他们把蛋糕给你。另一种得到芝士蛋糕的方式,是你祖母给你一份制作配方。我们做开源时,会把巧克力蛋糕给你,也会把配方给你,让你真的能重新做出同样的蛋糕;同时还会告诉你怎么造烤箱,以及你可以如何修改配方、再把它卖给别人。这是因为软件本质上只是一份很长的、由小指令组成的配方。计算机并不聪明,它只是跑得非常非常快。所以一个普通程序有数百亿条指令,而你的巧克力食谱可能只有几十条。很多软件行业做的,是卖软件,也就是只给你最后的芝士蛋糕。开源则是把一切都给你,这也让很多人能够一起工作。因为你决定要做出最好的程序,做出关于视频的最好配方,于是你创建社区。从 FFmpeg 一开始到现在,大概有两千到三千……
- 基兰:几千人,对。
- 让-巴蒂斯特:……从一开始就参与贡献。它和 Linux 内核完全一样。Linux 内核大概有一万人在各处贡献,他们聚在一起,当然主要是在线上聚在一起,为某件事创造最好的工具。在 FFmpeg 和 VLC 里也是这样:这个编解码器不能工作,那我就去改这个编解码器;我要把这个文件的支持加入 FFmpeg,这样所有人都会受益。因为再说一次,我们是为了更大的善而工作。我们为每个人工作,这就是开源。
- 莱克斯:我们还应该提到,根据许可证不同,你很可能可以围绕这些基础东西,做一个价值十亿美元、甚至万亿美元的公司,作为一个外层封装来……
- 让-巴蒂斯特:是的,确实有人这么做。人们确实这么做。过去有很多问题,主要是云服务商基本上在云端运行一些开源工具,然后只给你 API 去访问。因此很多数据库项目,比如 Mongo 或 Elastic,都修改了许可证,以避免这类场景。
- 基兰:这是 FFmpeg 经常被问到的问题:“你们为什么不这么做?”答案是,你不能这么做。我们有成千上万的贡献者,其中有些甚至已经不在人世了。要这么做,需要得到他们所有人的同意。JB 也许稍后会讲,在 VLC 里做重新授权的过程有多难。
- 让-巴蒂斯特:许可证是社区事实上意义上的卢梭式社会契约。除了许可证,社区在很多事情上并没有共识。人们围绕许可证聚集、讨论,而许可证也允许产生分叉。有时社区会分裂,但正是因为许可证,这种分裂才可能发生,也才可能再合并回来。我们已经见过很多次了。过去的 GCC 和 EGCS;还有所有网页浏览器的例子,它们从 KHTML 开始,变成 WebKit,然后又变成 Blink。开源许可证就是社区的核心。人们来自世界各地,宗教不同,政治边界不同,却以同样方式在一个项目上工作,解决一个特定问题。而我们要解决的问题,就是让多媒体对每个人都变得容易。
- 莱克斯:我在 Perplexity 上查一下这些开源许可证。大多数主流开源许可证分成两大类:宽松型,条件很少;以及著佐权类,也就是要求衍生作品以相同方式共享。下面是你在现实中常见许可证的简短实用总结。MIT 许可证、BSD、ISC、Apache、GNU GPL、GNU AGPL。LGPL 在哪?对,LGPL。再看,还有 Mozilla Public License、Eclipse Public License。还有很多很多。我觉得真正流行的是 MIT、GPL、LGPL……
- 让-巴蒂斯特:对,还有 BSD。BSD。
- 莱克斯:……还有 BSD、Apache。有时你会看到……
- 让-巴蒂斯特:还有 Apache。
- 莱克斯:……Apache。Unlicense 也是一个选项。它试图把代码贡献到公有领域,同时提供一个备用的宽松许可证。
- 让-巴蒂斯特:有很多许可证,对应很多不同的事情。人们不理解的是,公有领域这个概念并不是全世界都存在。所以所有开源许可证都使用版权法,也就是国际版权法,来赋予你如何使用或修改软件的权利。它事实上是一份你给最终用户或开发者的版权许可合同。第一类基本上非常宽松,比如 MIT、BSD。你给出代码,然后对方基本上想怎么做都可以。拿走、修改、做任何想做的事。这在 JavaScript 和 BSD 操作系统这类领域很流行。
- 莱克斯:其中一个参数是是否要求署名,也就是如果你使用这段代码,你必须说明……
- 让-巴蒂斯特:对。在这类宽松许可证里,有些要求你说明你用了它,这叫署名;有些不要求。另一类许可证是著佐权类,你需要把你的修改回馈给社区,并附带不同条件。有一些弱著佐权许可证,比如 Mozilla Public License;也有一些更强一点的,比如 GPL;甚至还有非常强的,比如 AGPL。这些都是不同类型的许可证,取决于你的目标,以及你希望如何组织社区。这也是我为什么说它是社会契约,因为这点非常重要。FFmpeg 和 VLC 主要是 GPL 或 LGPL。Linux 内核是 GPL,但 Android 是 Apache。大量 JavaScript 框架主要是 MIT。所有 BSD 内核,OpenBSD、NetBSD,当然都是 BSD。所以这是一种关于你希望人们如何回馈贡献的哲学选择。
- 莱克斯:你刚才好像提到过,在某个时候,你把项目的某些部分从 GPL 改成了 LGPL。你能描述一下两者的区别吗?以及如果要转向更宽松的许可证,需要做什么?因为这个方向是更宽松,LGPL 比 GPL 更宽松。
- 让-巴蒂斯特:是的。你要意识到,你总是可以从更宽松走向更不宽松。因为这些许可证基本上是声明,所以如果要加限制,你总可以加更多限制。在 GPL 项目里,你可以拿 MIT 代码进来,但反过来不行,因为 GPL 的约束更强。确实,我把 libVLC 的核心,也就是 VLC 的引擎,从 GPL 改成了 LGPL。原因有两个。第一个是让人们可以在第三方应用里使用 VLC 引擎 libVLC。所以很多在手机或平板上播放视频的应用,里面其实都有 VLC 引擎,而它内部又会调用 FFmpeg。这也让我创建了其中一家公司,做这类应用的咨询和集成,把 VLC 集成到第三方解决方案里,比如游戏引擎之类。用 GPL 的话你不能这么做,因为那意味着你必须把所有东西都开源,而很多商业公司并不想这样。
- 莱克斯:所以用 LGPL,你可以围绕它创办公司。
- 让-巴蒂斯特:是的。
- 莱克斯:你可以做商业项目,不必把它开源。这是一个很大的跃迁。
- 基兰:所以你可以在游戏里播放视频。
- 让-巴蒂斯特:是的。
- 基兰:问题在于,我是一个游戏开发者,我想播放一些视频,但我不想仅仅为了播放这些视频,就被迫把整个游戏开源。所以咨询业务、libVLC 的 LGPL 许可证,让你可以这样做。LGPL,也就是过去所说的库 GPL,允许你这样做。
- 让-巴蒂斯特:FFmpeg 也是完全一样。LGPL 要求你把你对这个组件、这个库所做的修改回馈出来,这也是为什么它叫库 GPL。因此你可以把 LGPL 形式的 FFmpeg 用在几乎任何类型的应用里,即便是不开源应用,但你需要回馈你对 FFmpeg 所做的修改。libVLC 也是一样。
- 莱克斯:从开源角度看,选择 GPL 会不会带来限制?因为如果你的库、你的代码是 GPL,就意味着你基本上是在劝退那些想围绕它建立业务的公司……
- 让-巴蒂斯特:是的。
- 莱克斯:……对吧?这么说公平吗?
- 让-巴蒂斯特:这取决于公司。但如果那家公司的商业模式要求源代码、要求应用本身保持闭源,那么是的,它会有限制。所以这就是为什么我把它改成 LGPL。第二个原因更隐晦一些:Apple App Store,也就是 iOS 的 Apple App Store 的条款和条件,让 GPL 应用上架变得非常复杂,而 LGPL 应用相对容易一些。所以 Windows、Mac 和 Linux 上的 VLC 是 GPL,核心是 LGPL。但 iOS 上的 iPhone 版本和 Apple TV 版本使用一种不同的许可证,叫 MPL。是的,我确实去改了许可证,那是一个很长的故事。
- 基兰:对。基本上,要更改许可证,你必须联系所有贡献者。
- 让-巴蒂斯特:是的。非常重要的一点是,开源项目在美国版权法里叫共同作品,在大陆法系里叫集体作品或协作作品。也就是说,大家为了同一个目标一起工作,然后创造出一个软件,也就是一个发布版本。但版权仍由所有个人持有。有些开源项目不是这样,它们会强制版权转让,但我们不这么做。我们是社区。所以每个人基本上都对自己改动的部分拥有版权。即便最后你的贡献被删掉了,这份版权也依然存在,因为新的贡献是建立在你之前的贡献之上的。所以,如果你想正确地重新授权,你就需要找到所有贡献者。当时,我必须联系三百五十多人。有时,他们只留下一个邮箱。所以你真的需要追踪他们。我实际上还去过一些地方找人,那是我在网上找到的一个人。我去了他的工作地点,对他说:“你当时用这个许可证授权了这些代码。你愿意从 GPL 改成 LGPL 吗?”大多数时候,他们甚至不太在意。他们只是想帮助 VLC。但这也让我遇到非常复杂的情况。我去到一个人的工作地点,他是一名工厂工人。我说:“我需要你签这个。”因为真正写下那段代码的是他的儿子,而他的儿子已经去世了。所以我必须解释所有这些开源意味着什么,解释我不是一家公司,并不是想把他儿子写下的那两行或五行代码抢走。那几行代码很有用,整个社区也同意这样做,而他对此完全没有概念。我当时还年轻很多,那是十四年前,我几乎要落泪。这真的很难。我们谈论的是人的一生。他向我解释,我们还聊到他儿子的照片。所以重要的是要把这件事做对,正确地做。但这确实意味着你要追踪一切,因为每一份贡献都有效。有些项目并不尊重这一点,会以比较激进的方式重新授权。但正如我说的,这会摧毁社区的核心,因为我们唯一真正达成共识的就是许可证,所以它很重要。
- 基兰:我想强调的是,这个社区由非常广泛的人组成。有些人在叙利亚战区,电力供应时有时无。也有人来自各行各业,有富有的,也有贫穷的;有年轻的,也有年长的。所以,让这样一群人围绕某件事达成一致,本身就是相当了不起的成就。
- 莱克斯:是的,这很不可思议。而且其中很多人是内向者,所以你要找到他们,让他们回复邮件,可能会相当困难。
- 让-巴蒂斯特:我们大多数人都是内向者,对吧?你需要说得更准确一点。这里有极度内向、非常极度内向,以及内向者。这就是一个由不同人组成的完整光谱。那并不重要。重要的是,你的代码好吗?你的代码优秀吗?你的技术优秀吗?我们关心的是卓越的代码。我们不关心你是谁。抱歉,我们也没办法检查。我们无法核实。也许你是一条狗,我也不在乎。我不在乎你来自哪里。我需要看你的代码。这很重要,因为人们不理解这一点。他们来到社区,发来一些补丁,结果被拒绝了,他们不喜欢这样。因为我们只能说:“抱歉,这达不到我们的标准。”“哦,可我是意大利、德国、美国某家大公司的工程师。”我们不在乎。我们关心的是你的代码质量,因为这定义了我们的社区。这也意味着,有很多贡献者来自非常不同的背景,而且当然,很多人很内向。但这没关系。
- 莱克斯:这个社区的传奇人物之一,当然是 Linus Torvalds。他创造了 Linux,也是 Linux 内核长期以来的维护者。传说中,在这种精英主义式的代码评审过程中,他会相当严厉,会直接说代码还不够好。你能谈谈 Linus Torvalds 这个传奇吗?
- 让-巴蒂斯特:Linus 是独一无二的。我甚至会说,他在 Git 上做的事情,比他在 Linux 内核上做的事情更有意思。他确实很严厉,但人们通常没有看到的是,当他严厉时,对象往往是内核某一部分的维护者。也就是说,他们认识他。所以他并不是对每个人都那样严厉。关键在于,他在自己房间里创造出来的东西,基本上支撑了互联网上的每一台服务器。即便是 Microsoft 的云 Azure,我也很确定有百分之七十、八十的服务器运行的是 Linux。你所有的 Android 手机都运行 Linux。他借助开源的力量所做的事情,当然非常惊人。是的,Linux 内核的质量非常高;是的,它很难;但我们不能在这上面妥协。我们不能在质量上妥协。因为归根结底,你必须理解:VLC 的核心社区只有五个人。FFmpeg 的核心社区有十到十五个人,而我们就是那些将来要维护你代码的人。因为一千个贡献者走过时间线,最后只有十个留下来,这意味着一个人来了并留下的概率只有百分之一。百分之一。所以你会换工作,会有婚姻变化,会有孩子,会遇到人生意外。你会换工作,或者发生别的事。你很可能不会再回来。所以最终要维护你代码的是我们。它必须可维护,必须优秀。是的,有时这意味着你需要返工,因为它是好的,但还不够卓越。而我们需要卓越,因为维护这个对整体至关重要的东西的人非常少。
- 莱克斯:但我们也应该提一下,有时候为了维持这种很高的卓越标准,语言里会有一些火药味,一些尖锐甚至严厉的表达。对此有什么可说的吗?
- 让-巴蒂斯特:这是真的,对吧?还有一个事实是,比如我们做的是很底层的东西,技术性极强。你进入这个社区之后,语气会变得很像某种……它是一种亚文化,对吧?所以从外部进来的人,基本上并不被这个亚文化所熟悉。FFmpeg 和 VLC 周围的大多数人,我们每年都会办 VideoLAN DevDays,也就是 VDD。他们在现实生活中非常有趣,而且真的热爱这件事。但确实,在线上时,有时候那种语气,你自己意识不到它听起来是什么样。不过这也没关系。
- 莱克斯:这是一种文化。你在游戏文化里也会看到这种东西。人们沟通的方式相当严厉、强烈,而且……大家都明白,不同社区里表达喜爱和尊重的方式看起来就是不一样。有时候要看环境。如果是读书会,大家通常会温柔得多。如果是一个风险很高、被数百万人使用的开源项目……
- 让-巴蒂斯特:但它并不像你在游戏里看到的那样经常是侮辱,对吧?所以 Linus 的语气,即使在开源社区里也有点不寻常。它更像是对结果更严厉,说“不是,这不行,这是垃圾”。你会看到的是这类话。
- 莱克斯:尽量不要针对人,要针对代码。
- 让-巴蒂斯特:对。
- 基兰:这非常、非常就事论事。我觉得你必须从这个角度看:著名的 FFmpeg 几乎完全由志愿者开发,这是真的。你得想象,有人白天在自己的工作里辛苦干了一整天,回到家。措辞简短、直接可能就是这样,对吧?这不应该被当成人身冒犯。
- 莱克斯:你很累,你很忙,但你仍然关心这些开源的东西。只是你未必有能力在每一个微妙细节上都解释清楚、手把手带别人。
- 让-巴蒂斯特:而且你还必须意识到,大多数人的母语不是英语。对 FFmpeg 和 VLC 这样的开源项目尤其如此,它们基本上以欧洲为中心。有时候来自美国的人,或者有些人会非常不喜欢那种语气,但很多时候也是因为他们不知道该怎么做得更好,对吧?这很难。语言就是……英语是一门很难的语言。里面有太多细微差别、语气等等,而你未必掌握这些,对吧?所以在这类社区里,不同文化和语言之间的差异也常常很难处理。
- 莱克斯:所以按传说来说,JB,你曾经多次拒绝数百万美元,只为让 VLC 对所有人保持开源、免费、无广告。带我讲讲这个决定背后的推理吧,为什么要把几百万美元留在桌上不要。
- 让-巴蒂斯特:是的,这几乎已经成了 Reddit 上的一个 meme,对吧,或者……
- 莱克斯:Reddit 上真的有一个 meme。
- 让-巴蒂斯特:9GAG 上也有,对,对。你看,那里有……
- 莱克斯:你戴着 VLC 帽子,在 Reddit 上看起来像个巫师。文字是:这是 JB,VLC media player 的创造者。他拒绝了数千万美元,只为让 VLC 保持无广告。谢谢你,Jean-Baptiste Kempf。你甚至可以在 Reddit 上召唤他。
- 让-巴蒂斯特:对。通常如果你看到,对吧,大家通常会 tag 我。然后我出现,说一句“早上好”。我拿到了 2.4 万个 upvote,这很棒,对吧?我在 Reddit 上的 karma 非常惊人,至少那个账号是这样。所以这个问题首先要回答的是:VLC 的故事到底是什么,对吧?因为是的,这是真的,我拒绝过数千万美元,是的,不止一次。是的,我本来可以成为千万富翁,在某个海滩上待着。但我没有这么做,因为我认为那不道德,也不是正确的事。对我来说,这一点非常重要:我要为更大的善工作,为人们工作,而且我不想……这也不只是我一个人的事。原因还在于,我并不觉得自己完全有资格这么做。让我解释一下为什么。VLC 的故事非常奇怪。在法国,我们有大学,也有一种顶尖学院,这些卓越院校包括工程学院、商学院,基本上还有法律和医学,对吧?但它们在大学体系之外。为了进入这些学校,你要花两年时间疯狂学数学和物理,才能进入最好的工程学院。其中一所学校叫 École Centrale Paris。它后来改名了,但当时叫 École Centrale Paris。因为它叫 Centrale,所以二战之后校园太小了,他们必须搬迁;他们想把它搬到法国中部,一个叫 Clermont-Ferrand 的地方。校友们认为这不行,对吧?这是 Eiffel,也就是建造 Eiffel Tower 的那个人上过的学校,对吧?所以他们说:“不行,不行,我们是一所了不起的好学校,不能这样。”于是他们在巴黎南边、离巴黎很近的地方买了一块地。那是一个由校友非营利组织管理的校园,明白吗?因为这个原因,校园里的所有事情都由学生管理。大学什么都不管,对吧?广播、电视、超市、图书馆、决定谁住哪个房间,所有事情都是学生管理的。
- 莱克斯:这太了不起了。那真是一个惊人的实验,而且它居然没有很快一团糟,反而不知怎么蓬勃发展起来了。
- 让-巴蒂斯特:它运转得很好,而我在这些课外活动中学到了人生里非常多的东西,对吧?因为你二十二岁,你必须运营自己的校园,否则就没有电,对吧?所以你会在乎这些,对吧?不过无论如何,在 80 年代,他们做了一次完整的网络部署实验,主要由 IBM 和 3Com 赞助,是一个 token ring 网络。所以 token ring 这个东西,现在可能几乎没人知道了。它是一种网络技术,没有路由器,对吧?每个人都连接在一起,真的像一个环。当你想发一条消息时,你跟邻居说,邻居把消息传给下一个人,下一个人再传给下一个人,按环的方式传。token ring 的问题当然是它很慢,因为网络上的每台电脑都需要打开这条消息,看它是否正确:是给我的吗?不是,然后再把它传回去,就像一个 token 在环上旅行。80 年代,你在大学里做一些 Telnet、发邮件,这没问题,对吧?但到了 90 年代,电子游戏开始出现;在电子游戏里,如果延迟很高,你基本上就死了,对吧?所以在 1994 年、1995 年左右,Doom 和 Duke Nukem 出来了,他们想要更快的网络。于是学生们去找大学,说:“你知道吗?我们想要更快的网络。我们需要工作,也需要玩电子游戏。”大学告诉他们,基本上是:“哦,抱歉,我们帮不了你们,因为你们明白,校园不是我们的。是你们在管理,所以你们自己想办法。你们应该去找这所大学的一些合作伙伴。”基本上就是让他们走开。他们去了,而且真的去见了 Bouygues 的 CIO。Bouygues 是一家法国大公司,在法国也做电视。他说:“好吧,你们知道吗?视频的未来是卫星。”今天我们知道并不是这样,但至少那是个不错的想法。1995 年,他说,与其让 1500 名学生每人都有一个卫星锅和一个大解码器,不如你们架一个巨大的锅,只用一个解码器,然后直接把视频发到网络上。而这需要一个非常快的网络。今天这很显然,但在当时,那几乎是最早做视频流的一批。所以他们建了这个项目,叫 Network 2000。当然,对吧,我们在 90 年代,对吧?
- 让-巴蒂斯特:所有……有未来感的东西都叫 2000,比如……
- 莱克斯:对,2000,对。
- 让-巴蒂斯特:于是他们做了 Network 2000 项目。它完全是 hack 出来的。45 秒后就会崩溃。没关系,演示只有 40 秒。它会内存泄漏。没关系,他们把 RAM 从常见的 8 或 16 MB 换成了 64 MB。演示本来就应该到那里结束。那就是学生们做的 Network 2000 项目。
- 莱克斯:他们当时要处理的视频是什么格式?
- 让-巴蒂斯特:MPEG-2,因为卫星当时是 MPEG-2 TS 传输流、MPEG-2 视频和 MPEG-2 音频。这个项目本来应该就到此为止。所有人都很开心。他们有一个很棒的 ATM 网络,速度是每秒 155 兆比特。当时他们可能拥有欧洲最好的网络之一,然后他们停止了这个项目。六个月或者一年后,两个学生来了,说:“好吧,你知道吗?也许还有别人关心在本地网络上传输视频。”于是他们创建了 VideoLAN 项目,VideoLAN。其中一个人叫 Christophe Massiot,他是我和 Kieran 的好朋友。他们启动了这个项目。它甚至还不是开源的,他们花了大约三年时间才让学校同意把它开源。因为大学想从中得到一些东西……因为学生的 IP 和版权,大学基本上想把这些 MPEG-2 解码器变现。
- 莱克斯:只是为了说清楚,当时的主要应用是什么?是在本地网络上做流媒体吗?
- 让-巴蒂斯特:是在本地网络上做流媒体。
- 莱克斯:顺便说一句,这只是把显而易见的事说出来:这是在 YouTube 之前。这是在……
- 让-巴蒂斯特:比 YouTube 早十年。你有一台 Pentium 60 或 75,对吧?当时的主流机器是 33 MHz 的 486DX,对吧?
- 基兰:别忘了,那时候电视是视频的主要形式。你可以收到新频道。在 90 年代,如果你从小只有四个频道,哪怕多一个新频道,有第五个或第六个,都是大事。所以有这样一个卫星服务,能带来几十个、甚至上百个频道,是非常突破性的。
- 让-巴蒂斯特:尤其因为这是一所大学,有很多不同国籍的人,对吧?所以有很多人想要……所以最后,他们在不同类型的卫星上有了好几个锅,对吧?比如很多人来自马格里布或中东,所以他们会去接不同类型的卫星。无论如何,这个方案运转得很好,他们开始了 VideoLAN 项目。VideoLAN 项目包含好几个部分,其中有些方案完全疯狂,比如如何在单播网络上创建 multicast,但我们先不讲那个,太复杂了。VideoLAN client 这个部分后来变成了 VLC。实际上,他们基本上是强迫大学把它开源,因为大学并不理解这件事。2001 年,这仍然很早。但基本上,是的,大学在 2001 年初同意把它开源。我在 2003 年加入这个项目,因为那时我进了这所学校。所以第一件事是:我不是创造 VLC 的那个人,因为实际上没有某一个人创造了它,对吧?
- 莱克斯:它有点像是从 VideoLAN 项目里自然生长出来的。我们也应该提一下,你刚才已经说过,但为了说清楚,VideoLAN 后来在当时变成的是围绕视频的一组技术,而 VLC,你所说的 client,就是大多数普通人……
- 让-巴蒂斯特:没错,而且……
- 莱克斯:……会想到的那个东西,也就是你点击一个视频、播放它时弹出来的那个东西。
- 让-巴蒂斯特:所以我在 2003 年来了,然后我创建了名为 VideoLAN 的开源非营利组织,把一切从大学里拿出来,变成一个非营利项目,一个可持续的东西。是的,的确,我在 VLC 和 VideoLAN 上投入的时间比任何人都多,这一点毫无疑问。但它是之前那个项目 VideoLAN 的延续,也就是学生项目;而那个项目又是 Network 2000 项目的延续;再往前又是一连串事情的延续。
- 莱克斯:我相信在这个过程中,你一定有过一些时刻会思考:从开源角度看,这件事的未来是什么?因为随着互联网爆炸式发展,也出现了很多公司……我是说,对那些不记得的人来说,当时有很多公司赚了大钱。
- 让-巴蒂斯特:我可以告诉你,2005 年这个项目本该死掉,是我让它继续了下去。有一段时间,我们只有两个活跃开发者。我觉得这是一项很棒的技术,很有用,而且将来还会有用,于是我把我的人生和时间都投入进去。我让它从几十万用户、几百万用户,成长到今天我们所拥有的规模:全世界可能有数十亿个 VLC 版本,在各处被使用。所以这大概就是 VLC 的故事。围绕它还有很多非常有趣的故事。世界各地很多人在参与,比如你说的,在叙利亚,或者印度某个偏僻地方。但一路上,我收到过好几次 offer,要么是捆绑 toolbar,对吧?你记得那些可怕的 toolbar……它们基本上就是 spyware;要么是更改你的浏览器或搜索引擎,甚至是在 VLC 里面放广告。我不喜欢那些,对吧?我……人们不理解这一点。不是说我反对钱,对吧?我很乐意赚钱。我创办过几家 startup,其中一家我希望会发展得很好。关键是我相信赚钱必须合乎伦理。做这件事有正确的方式,而偷偷摸摸做广告或窃取数据,不是正确的方式,对吧?比如,如果 Netflix 在某个时候来找我们说:“好吧,我们想把 Netflix 放进 VLC 里。”故事可能就会不一样,对吧?但他们没有。来找我们的只有那些可疑的广告公司。如果我那么做,对吧,我会有很多钱,对吧?然后三年后,项目就没了,对吧?有人会 fork 它,然后发生别的事。
- 莱克斯:所以问题甚至不一定是广告本身,或者那些东西本身,而是那种可疑……那种不诚实。所以你有很好的雷达,有一个很好的阈值,能说:“不,这会损害它本应代表的精神。”
- 让-巴蒂斯特:但这也对我自己很重要,对吧?我非常自私地说,我晚上需要能上床睡觉,并且对自己做过的事感到开心,对吧?也许是我的成长环境,也许是我父母的错,或者随便什么原因,对吧?但我相信有对有错,对吧?这在当时是正确的决定,现在仍然是。我想为自己做过的事感到骄傲。如果我出卖了它,我就背叛了许多在这里工作过的其他人。
- 莱克斯:是的,我应该说,我和互联网上的大多数人都感谢你做了这个决定。我认为这也激励了其他推动开源运动前进的人:如果你相信这是对的,做出这种巨大的牺牲是可以的。我觉得在那个案例里,它确实是对的,也正是 VLC 能够如此成功的原因,因为它是一种体现,是自由以及开源社区能够创造什么的象征。
- 让-巴蒂斯特:是的,而且它为世界各地这么多人服务,这一点很重要。
- 莱克斯:我们应该强调一下,在 2000 年代,下载一个程序然后它偷偷安装某种 spyware,真的是很正常的事。它会藏在非常不起眼的文字里,或者藏在没人会读的许可文本框底部……“哦,我将安装这个 toolbar……并更改所有这些东西。”在当时,你安装一个程序来做任何事情时,这都非常常见。
- 基兰:如果把自己放到当时一个开发者的心态里,我觉得这很容易。对所有听众来说,当时说服自己拿几千美元……拿几千美元去做这件事,是非常容易的。拒绝多得多的钱……需要胆量,也需要眼光。
- 让-巴蒂斯特:我收到的最后一个 offer 简直夸张到离谱。他们说:“是啊,但想象一下,有了这么多钱,你就可以构建新的开源东西了”,对吧?这有点像心理操纵,确实很难。但对我来说,它就是:“不,事情不是这样运作的,或者说这不是正确的事,所以我不做。”再次强调,对吧,不是我不喜欢钱或怎样,只是它不对。
- 莱克斯:再一次,我代表我自己,也代表互联网的其他人,谢谢你。让我再多谈一点开源运动,谈谈你们一遍又一遍说的那个事实:FFmpeg,以及许多开源项目,都是由志愿者构建的。所以最近网上,在 Twitter 上,有一点戏剧事件,Kieran。你在 Twitter 上的风格很有火药味,我觉得你很好地表达并赞美了所有这些不可思议的开发者、开发工作和代码,尤其是构建一些编解码器、构建这些惊人技术时涉及的汇编。但这也把我们带到了最近发生的一场小风波。给我讲讲 Google 安全工程师那件事的完整来龙去脉。
- 基兰:先说清楚,Google 是开源领域最大的支持者之一。他们长期以来都是如此。只是我觉得这一次有些事情有点过头了。FFmpeg 本身,这并不是什么秘密,首页上就写着,它处理不可信数据。解析不可信数据时可能出现安全问题,这是很正常的。但最近改变的是,Google 开始使用 AI 为开源项目 FFmpeg 生成安全报告。志愿者必须处理这些报告。他们确实提供了非常有限的资金,甚至在问题能够修复之前,就先去媒体那里宣布他们的 AI 有多好。
- 莱克斯:而且这是在公开论坛上。
- 基兰:对,这些都是公开的。
- 莱克斯:所以就是报告一个问题,用 AI 在代码里找到一个安全漏洞,然后在你们能够修复它之前,就公开报告出来。
- 基兰:对。是宣布他们的 AI 有多好,说他们给出了行业标准的 90 天期限,却没有真正理解志愿者驱动开发的性质。除此之外,这个漏洞是在一个很冷门的 90 年代游戏编解码器里。我们先从他们的立场来看这件事,好吧……
- 莱克斯:好。你能带我站在他们那边看吗?
- 基兰:可以。他们有大量资源在为无处不在的开源项目做安全工作。他们用了很多算力来做这件事,成本很高,也有非常有能力的安全研究人员参与。从他们的视角看,他们是在通过这种方式做贡献。但我认为分歧就在这里。它揭开了很多有趣的裂缝,我会这么说。看起来安全社区里有一部分人有点像建筑设计师,却从来不用去工地。你知道,去工地这件事对他们来说有点低人一等,也就是实际的日常施工。他们负责做自己的安全事项,剩下就是别人的问题。安全行业对事情的语气也往往非常有攻击性。他们使用的语言极其激烈,会用非常强的措辞,比如“You will get popped”。对普通公众来说,get popped 听起来意味着很糟糕的事;对他们来说,它的意思是被黑。以我个人的看法,这有点像你家门上的挂锁。你家门上的挂锁,或者说你家里的锁,是用来防护它本来需要防护的能力范围。它不是用来保护核机密的,也不是用来保护 Fort Knox 的。而他们现在可以被看作是在用 AI 以某种规模去撬这些锁,然后说:“嘿,你的锁不安全。你需要处理这个。”但实际上,他们才是有资源修复这些问题的人。可他们似乎既不愿意用补丁形式贡献,也不愿意在资金上贡献。AI 的规模才是问题所在。那些 bug report 非常冗长,非常、非常……它几乎像是由 AI 生成的 bug report 对很小众的编解码器发起的一种 denial of service。安全社区的另一个问题是,所有东西都被标成高优先级。你会看到:“这是世界上最重要的事,你必须处理。高、高、高,漏洞、可怕、可怕、可怕。”而对象只是一个 1993 年某张光盘上用过的游戏编解码器。矛盾就在这里。到处告诉所有人他们的挂锁不安全,可那其实是某个人的 hobby project。这个编解码器的安全性,应该与那个人认为它需要承担的安全等级相称。那是他的爱好。对它做安全分析是好事,但它不需要一个巨大吓人的警告:“这是一个 critical vulnerability。”我们最近也可能看到另一个所谓的“漏洞”。这次不是 Google,但有个 filter 可能 overflow,发生 integer overflow,然后你的某个像素可能颜色不对。这个被标成高危,红色的 7.5 severity。到某个时候,安全行业必须意识到,你不能一直这样喊“狼来了”,因为这只会让人们做出等价于把密码贴纸贴在电脑上的事。你不能每天都喊“狼来了”。我理解,他们的 modus operandi 就是制造尽可能多的惊吓和恐惧。但从 Google 的角度看,归根结底,他们需要用资金或者补丁做贡献。Google 使用 FFmpeg 的规模,可能是你我都无法想象的,数百万个 CPU core。是的,他们在一些领域有贡献,主要是和他们自己的产品有关,比如 VP9、AV1。但从更广的意义上讲,贡献程度并不成比例。是的,他们资助学生。是的,他们资助 Summer of Code。我想 Alex Strange 是一名前 FFmpeg 开发者,我认为他是以个人身份发帖的。
- 莱克斯:所以他在 Hacker News 上发了一段关于安全工程师的评论。他的帖子写道:“一般来说,安全报告的问题在于,安全人士是横行无忌的自我推销者,(括号里,Linus 曾经用更难听的话称呼过他们)。想象一下,你是一个谦逊的志愿开源开发者。如果安全研究员在你的代码里发现一个 bug,他们会给它编一个可爱的名字,做一个带 logo 的网站。Google 会给他们一百万美元赏金。他们会去 DEF CON 拿奖,而且我猜还会去参加某种秘密安全人士狂欢,所有人都穿得像在 The Matrix 里一样。你修复它的时候,没人会为你做这些事。”这基本上是在评论参与其中的不同人之间,激励机制如何不同、又如何错位。
- 让-巴蒂斯特:这里的问题在于,发现问题所投入的手段,和修补问题所投入的手段之间完全不成比例,对吧?这就是最大的问题,对吧?那场风波之后,Google 的确做了一些改变。
- 基兰:他们现在开始发送补丁了,这……
- 让-巴蒂斯特:而且他们现在也有了奖励修复问题的工具。所以因为那场风波,情况有所改变。这很好,对吧?但我们也看到过,我们谈的是 Google,可我们也见过其他一些大公司说:“哦,你需要修复这个 bug,因为它在我们的产品里是 critical。”
- 莱克斯:你能解释一下 XZ 风波吗?FFmpeg 那条推文写道:“XZ 风波说明,依赖无偿志愿者会造成重大问题。万亿美元公司期待志愿者提供免费而紧急的支持。Microsoft Teams 在一个全是志愿者的 bug tracker 上发帖,说他们的问题优先级很高。在我们礼貌地请 Microsoft 为长期维护签一份支持合同之后,他们却只提出一次性支付几千美元。这不可接受。我们不是编出来的,这就是 Microsoft Teams 实际做过的事。”然后你们还贴出了图片和细节之类的内容,说明这些万亿美元公司并没有给多少钱,也没有提供多少支持。
- 基兰:他们以为开源项目就是传统供应商,以为自己和你有 SLA。他们以为公共 bug tracker 实际上是某个第三方供应商的 Jira,可以在里面做所有这些事。它不是。它是用来报告 bug 的。我觉得这件事特别恶劣的一点,是他们搬出了 Microsoft 的名号,还强调这是一个可见度很高的产品。如果这只是普通 bug 报告,我觉得情况会好很多。
- 莱克斯:是的,所以他们几乎是直接说:“这事很重要,因为 Microsoft 内部有很多人在用它。”我好奇这里面心理上发生了什么。我觉得这些公司里发生的事情,也许你们可以纠正我,就是他们……你说得对。他们只是把 FFmpeg 当成一个供应商,而且以为 Microsoft 肯定给了 FFmpeg 一大笔钱。他们在互动时默认了这一点,而整个链条上没有任何人停下来想:“等一下,我们是不是应该给 FFmpeg 几百万美元?”
- 让-巴蒂斯特:这在大公司里是一个非常大的问题。我们现在说的是某几家公司,但其实到处都一样,对吧?很多这类公司都是这样。比如我们和那个人沟通时,他只是 Microsoft Teams 某个项目上的经理,对吧?他从来没有真正和开源社区打过交道,他完全不知道,对吧?问题在于,这类公司里通常有所谓 OSPO,也就是开源项目办公室,他们本来应该负责和开源供应商,或者说开源社区沟通。但他们经常没有在内部把这件事解释清楚,对吧?而这里的核心就是:我们不是你的供应商。如果你想让我成为你的供应商,我非常乐意,对吧?我会给你发合同和 SLA。我围绕开源项目创办过五家公司,就是做这个的,所以这没问题。
- 莱克斯:我们应该说一下,基兰,你参与发的一些辛辣推文,以及这场风波,确实产生了结果。
- 基兰:是的。
- 莱克斯:是正面的结果。
- 基兰:捐款大幅增加了。虽然仍然不够覆盖哪怕一名全职开发者,但无论从认知层面还是技术层面,人们对 FFmpeg 的重要性都有了明显更多的了解。这是 X 以及整件事带来的结果。可以说,它达到了目的。人们意识到了 FFmpeg 的重要程度。
- 让-巴蒂斯特:VideoLAN 这边也一样,对吧?举个非常简单的例子。有一年多时间,因为 Android Play Store 上的一个 bug,我们无法更新 Android 版 VLC。我们唯一能让对方有人回应的办法,就是像你说的那样,发一条非常辛辣的推文,说我们准备停止分发 Android 版 VLC,对吧?而我们大概有 1 亿人在用它。然后 Android 那边才真的有人来和我们沟通。我们在 Microsoft 那边也遇到过同样的问题,比如说我们要停止在 Windows Store 分发 VLC。很遗憾,我们太小了,解决这类问题时手里唯一很强的力量,就是在社交网络上点名批评,因为它会滚雪球,然后他们才会听我们说话。大公司经常很难和我们对话。比如 VLC,它很可能是 Windows 上使用量前十的软件之一,但我并不是 Microsoft ISV 计划的一员,也没有 Microsoft 的联系人。
我确信其他任何软件,比如 Adobe、Spotify,都会有联系人。但我没有,对吧?所以提高关注度是有效的。有时会非常辛辣,会有很多戏剧性。好吧,X 和 Twitter 很适合做这件事,而且确实有效。
- 莱克斯:所以正在收听的每个人,都应该去 Twitter、X 上关注 FFmpeg,关注 VideoLAN。去捐款。捐……给 FFmpeg。
- 基兰:也谢谢你,Lex。这些年来,好几年里,你一直在 X 上支持 FFmpeg 和 VideoLAN。你给我们喊话,也赞赏我们做的事情。
- 莱克斯:FFmpeg 一生推。
- 让-巴蒂斯特:比如 Tim Sweeney、Carmack,还有其他几位很高层级的人,也在我们的 X 账号上提高了大家的关注度,这也帮了很大的忙。
- 莱克斯:Karpathy 也是。
- 让-巴蒂斯特:Karpathy,是的。
- 莱克斯:Karpathy 也是,对。
- 莱克斯:是的。我的意思是,除了那么多人在用它、它对世界影响巨大之外,它也是一个伟大开源项目的绝佳代表。比如汇编和 C 的价值,以及在真实世界系统里真正严肃对待编程这件事。
- 基兰:不只是这个。我们稍后肯定会谈汇编,因为那本身就是一个完整话题。但这也意味着要赞颂像 Andreas Rheinhardt 这样做维护的人。我相信他是无偿的,作为志愿者在做。他在做大规模重构。Andreas Rheinhardt 和 Anton Khirnov 正在用线程重写 ffmpeg.c。要赞颂这些人,赞颂那些投入其中、却从用户角度看不出任何变化的无名劳动。文件还是完全一样,但哇,那架飞机是在空中被重建了一遍。
- 莱克斯:Christian Garcia 说:“作为一个青少年在运营这个账号”,指的是 FFmpeg 的账号,然后你回复说:“青少年在 FFmpeg 里写的汇编,比 Google 工程师还多。”但这也指出了一点:有很多不可思议的贡献者其实是青少年。
- 基兰:就像 JB 说的,我们不在乎你是谁、来自哪里、做什么。多年来,青少年写了成千上万行汇编。也向当年的 Daniel Kang 致敬。还要突出像 Ruikai Peng 这样的人所做的工作。这是一个 16 岁的孩子,他对 FFmpeg 的一些最初贡献,实际上让某些所谓“安全研究员”相形见绌,因为他真的找出了问题并修复了它们,而且他才 16 岁。这里没有门槛。没有门槛说你必须在大学里跟着某个人学习,必须懂这些东西。你可以学 C,老实说,就是从 K&R 那本书开始。学 C。你可以学汇编。我们之后也许会谈到这一点。你可以为世界级技术做贡献。
- 让-巴蒂斯特:VLC 里最早的贡献者之一叫 Felix,他负责 Mac 和 iOS 上的一切。他开始为 VLC 工作时才 16 岁。我们还有一个叫 Edward Wong 的人,曾经是 Google Summer of Code 的学生,后来在 VideoLAN 待了三年。他当时 14 岁,对吧?Google Summer of Code 和 Google Code-in 这些项目,基本上就是让学生或高中生参与。我们为 x264、VLC 和 FFmpeg 写了大量汇编。所以每个人都可以贡献。
- 基兰:而且他做得很好,因为他没有玩那种危言耸听的 CVE 抢戏套路:创建一个 CVE,也就是公开披露安全问题,再搞出那些吓人的红色 7.5 高优先级。他只是在三天后在 Git 里修了一个问题,就把它修好了。他不需要跑出去围绕它制造一场巨大的安全戏剧。我当时大概发了句“孩子们没问题”。而有一部分安全社区,我不是说所有安全人员都这样,但正如莱克斯说的,确实有一部分人喜欢通过制造戏剧性来抬高自己。他们会很乐意把一个其实只存在于 Git 里的问题说成“这是一个高优先级 CVE 8.0”之类。它甚至不在发布版里,只在开发中,三天后就修好了。
- 莱克斯:我也想在这里表达一点善意,哪怕是对那些大公司。也非常爱和尊重 Google 工程师。就像你说的,他们当中有一些是世界上最好的软件工程师,而且他们也贡献了很多,甚至在安全方面也是如此。另外,我也是 Theo 的粉丝。也向 Theo 表达敬意。他稍微卷入了这场风波和戏剧。我觉得如果把视角拉远,放到人类历史的宏大弧线上看,这场戏剧对所有参与者都产生了正面作用。捐款上升了。它让这个话题得到更多关注,让大家以一种争吵的方式互动,而这种争吵最终让他们弄清楚 FFmpeg 到底是什么。
- 基兰:所以我们看这件事的方式是,到头来它就是一场说唱 battle,你知道吗?不,但它确实是。我们说些话,彼此放话,但我们可以把它留在 X 上。X 是国际说唱 battle 的绝佳场地。你说点什么,我说点你妈妈的事,但这并不意味着我真的和她有什么私人恩怨。事情看起来就是这样。Theo 那件事,JB 也许可以展开说说,确实有点走得太远,也有一点……但你知道,这只是有点好玩。就是一点说唱 battle。像 WWE 一样。大家在 X 上玩得开心一点而已。没必要太当真。青少年那件事也是一样。所以那个人是 Google 员工,他说:“嘿,运营开源业务还有别的方式。”你就会想,哎呀,放轻松一点,找点乐子嘛。
这就是这个账号的意义所在。而且更进一步,如果你能通过这种方式教人们了解开源项目、汇编等等,我觉得这里有很多价值。它不是为了嘲讽而嘲讽。它真正展示出来的故事,我认为 X 学到的是:这些不是大型企业开源项目。这不是 Kubernetes,背后有几百人、也许几千人拿工资开发这些东西。这些只是一些人在地下室里利用业余时间做出来的东西。如果你能以一种有趣、好玩的方式讨论这个话题,我觉得这就是好事,也就是 X 的价值,以及我们现在能触达这么多人的价值。
- 让-巴蒂斯特:老实说,对吧,即使在 Google 内部,Google 是一个实体,但里面有非常多不同的人。我们一直和大量 Google 工程师合作,而且从 YouTube 到 Chrome,到 Chrome Media,再到 Google 其他部分,它们都是非常不同的实体。但我们做的事是有效的。比如 Theo 那件事,确实有点走得太远。我让大家冷静下来。我和他通了电话。我们说:“好吧,这样太过了”,等等。但最终,是的,这是一场说唱 battle,不过它对项目是正面的。我们现在对开源的关注度,我指的是来自社区的真正开源,在过去两年里大幅提高了,而这是有用的。
- 莱克斯:你们觉得我们一直在谈的这些了不起的贡献者,动力是什么?引擎是什么?这件事看起来太有意思了。
- 让-巴蒂斯特:所以……
- 莱克斯:就像你说的,他们坐在地下室里。驱动力是什么?引擎是什么?
- 让-巴蒂斯特:驱动力有很多,但很奇怪,最主要的一个是,我们在多媒体领域做的事情能播放视频,而视频很酷,对吧?比如社区里有很多人加入,是因为他们喜欢看动漫,对吧?当人们问我“我应该在开源里做什么?我该怎么开始?”时,我给的建议一直一样:做你热爱的东西。我做 VLC,是因为我爱电影,对吧?我喜欢一遍又一遍看同一部电影,哪怕我这么做时我妻子会烦我。因为这很有意思,对吧?因为这是你喜欢的话题。这通常是人们来到 VLC 和 FFmpeg 的第一件事。第二件事是,从技术上说,因为我们追求卓越,这里是最好的学校。
这是最好的编程学校。如果你在 FFmpeg 里精通 C,如果你懂得怎么写汇编,我向你保证,即使你后来去写 TypeScript,也会成为最好的程序员之一,因为这是最了不起的事情。你会接受一些最老练程序员的 review,他们会查看你代码的每个部分,并告诉你为什么它还不够好。就像我们是你在编程上遇到过的最好的老师,对吧?
- 基兰:Andrew Kelley 创立了 Zig。他曾经是 FFmpeg 开发者,在他的 FFmpeg 学校之后创立了 Zig。我的意思是,这是学习真实世界编程诸多方面的地方,而且你做的是一个被数十亿人使用的东西。你无处可藏。你必须公开而诚实地面对自己的缺陷,思考如何学习、如何变得更好。
- 让-巴蒂斯特:多媒体里还有一件有趣的事:你只有 16 毫秒来显示一帧。它不像游戏引擎,基本上可以慢下来等一帧。所以你必须足够好,对吧?
没有选择,否则你的视频就没了。而且由于编解码器的工作方式,如果你漏掉一帧,就会破坏视频的观感。所以你必须足够好。你必须完美,才能得到正确的结果。但还有一点,它不只是数学意义上的纯编程,对吧?
很多人不理解,要想在开源多媒体社区里正确编程,你需要理解计算机如何工作。写汇编时,你需要理解 CPU 流水线,对吧?你需要理解 SIMD 如何工作,ALU 如何工作,对吧?你需要理解 IO 如何工作,对吧?我认为这正是今天很多工程师和软件工程师缺少的东西,也就是我们所说的计算机体系结构。说真的,有些争论会是:我们应该用这个汇编调用还是那个?有人会说:“不,在这种 CPU 上它会是三个周期,而这个会……”这会对输出产生巨大影响,对吧?
- 基兰:我们应该展开一下。FFmpeg 可能是世界上最大的 CPU 使用者之一。我们说话的此刻,它很可能正在运行在轻松达到 1 亿量级的 CPU 上,也许甚至是 10 亿个 CPU。所以每一条指令都重要。没有……至少从 CPU 角度看,我们做的每件事影响都非常大。
- 让-巴蒂斯特:所以一开始你来,是因为这是一个有趣的主题;然后你留下,是因为这里追求卓越;最后你会非常为它骄傲,因为它在每个人手里。很多人会说:“哦,我在某某咨询公司工作,做一个给你的 PG&E 下载发票的门户。”哇,很棒。很多工作都是这样的。你不会跑去和奶奶说这个。但如果你去见奶奶,说“我做的是让你能在笔记本电脑上播放视频”,她听得懂。这非常重要,对吧?因为你做的是 VLC、FFmpeg、H.264。它在数亿人手里,你产生了影响。所以你可以为自己骄傲。因此我认为,除了能写出一份很棒的简历之外,所有这些都是人们贡献的原因。
- 基兰:是的,那些都是副作用。关于这个话题,我最喜欢的一句话来自 John Collison。他说:“世界是一座激情项目的博物馆。”你知道,外面的一切都是激情项目。开源多媒体,以及一般意义上的开源,能让你快得多地做到这一点。网络效应快得多。
我可以开一家咖啡馆,把它当作我的激情项目,但我得通过建筑规范,我得建一栋楼,我得找地点,我得做各种各样的事。而在软件世界里,那个激情项目可以快速移动,可以被网络效应放大,而且这种放大可以大于各部分之和。你可以找到对极其冷门的东西感兴趣的人,形成网络效应,做出真正了不起的东西。
- 莱克斯:说到激情项目,Tim Sweeney 其实在回复一条赞美 JB 的推文时说过一句话。他说:“世界上很多事情之所以发生,只是因为某个了不起的人决定去做。VLC 就是这样。”这对我来说指向了一件很有意思的事:在软件世界里,似乎少数几个人,有时甚至一个人,就能创造出不可思议的东西。就像你一遍又一遍说的。我觉得 JavaScript 是一个不可思议的东西,最初由一个人创造。一些编程语言,比如 Python、C、Java,也都是一个人有了愿景、有了设计,然后把它带到世界上,有时最初的火花就在一个周末里出现。
- 基兰:是的,Linus 两周就做出了 Git。哇。
- 莱克斯:Git 改变了世界。我的意思是,它真的改变了世界。
- 基兰:Linus 的激情项目。“嘿,我把这个 tarball 上传到 FTP 了,你们看着办。”
- 让-巴蒂斯特:但对我来说,这不只是在软件里,对吧?我相信那些会改变世界的个人。就像你说的,带着一个好的愿景。我想做这个。它有用,它会有用。不管是建火车、汽车、火箭,还是别的什么,我相信那些相信自己并拥有愿景的人,能够对人类产生巨大影响。
- 莱克斯:我们先把视角拉远一点,然后再拉回来。我们会继续在整个技术栈上上下下地谈。所以,你知道,我们一直在来回谈 VLC 和 FFmpeg。基兰,你说 FFmpeg、VideoLAN、VLC 是共存的,没有单一的中心重要性。你把它称为双星系统。它们因为彼此而成功。你能解释一下它们的区别、它们如何互动吗?它们是……竞争对手吗?
- 基兰:我不认为它们是竞争对手。简单答案,也就是在我展开细节之前的短答案是:VLC 之于 FFmpeg,就像 Android 之于 Linux。所以它们相互依赖,也因为彼此而共存。我用的比喻就是双星系统。
- 莱克斯:顺便说一句,我直到最近才知道离我们最近的恒星系统半人马座阿尔法是一个三星系统,这让我感觉很糟。
- 基兰:而当你开始算里面的物理时,那就是噩梦,对吧?不过,不过,不过……
- 基兰:所以才有三体问题。总之,很多 FFmpeg 流水线都会涉及 x264 项目,而 x264 是一个 VideoLAN 项目。我凭直觉估一下,会说 80% 以上的这些流水线都依赖一个 VideoLAN 项目。显然,如我们讨论过的,VLC 也是一个 VideoLAN 项目,它使用 FFmpeg,给 FFmpeg 带来触达和曝光,也让 FFmpeg 接触到奇怪文件,历史上还用一部分捐款资助过 FFmpeg 开发。我们之后也许会谈到一些逆向工程。所以这是一个双星系统。它们彼此协作、彼此滋养。许多开发者是共享的。没有一个中心位置。这是一个共同运转的良性循环。
- 莱克斯:我们也应该说明,x264 是 H.264 视频标准的编码器。所以 H.264 是标准。x264……
- 基兰:是这个标准的开源实现。
- 莱克斯:……基本上被所有人用于所有事情。它是这件事的主要驱动力。当你想到一个里面有 H.264 编解码器的 MP4 文件时……
- 基兰:如果它来自一个软件环境,比如数据中心或类似地方,它很可能是用 x264 创建的。
- 莱克斯:而它归在 VideoLAN 旗帜之下。
- 基兰:它是一个 VideoLAN 项目。所以在 VideoLAN 的图谱里,它位于 VideoLAN 的世界中。
- 莱克斯:而 VideoLAN 里面有一堆东西。去 VideoLAN 网站看,会看到很多图标。
- 让-巴蒂斯特:如果你去看,会发现里面有非常多库,对吧?
- 基兰:libdvdcss、libdvdnav、libdvdpsi,当然还有 libvlc、vlc-unity、libblu、Blu-ray。是的,还有很多。
- 让-巴蒂斯特:而且还有更多,对吧?最近,我们也许会谈到的 dav1d 项目,是 VideoLAN 最近的一个项目。它无处不在,对吧?我们最近还宣布了 libspatialaudio。我们还有一个……
- 基兰:checkasm。
- 让-巴蒂斯特:checkasm……
- 基兰:我们稍后会谈到它。
- 让-巴蒂斯特:……这是一个疯狂的项目,但非常棒。所以 x264 是这些 VideoLAN 项目之一。在我看来,比如说,x264 曾经是,也仍然是有史以来设计得最了不起的编码器,这帮助了 FFmpeg 的采用。很多人和大公司是因为想用 x264 才接触 FFmpeg,而 x264 提升了 FFmpeg 的流行度。同时,VLC 也因为它能播放很多由 FFmpeg 处理出来的文件而流行起来,对吧?所以这是许多相互交织、共同工作的项目。
- 基兰:是的。遗憾的是,X 上有一种现象:一提到 VLC,就会有人说:“友情提醒,真正干活的是里面的 FFmpeg。”而这就像我说的,并不是那样。我们是在一起工作。
- 让-巴蒂斯特:给你一个概念,对吧?当我为 Windows 编译 VLC 时,我大概要编译 1600 万行代码,对吧?其中 100 万行在 VLC 仓库里,而 FFmpeg 总共大概是 200 万行左右。也就是说,很多依赖都在外部。如果你再看 FFmpeg 本身,FFmpeg 也在集成第三方库,比如 x264、LibOpus,以及很多其他库,对吧?
所以我们都相互依赖。
- 莱克斯:是的,这就是为什么我希望像现在这样做这一期,把 FFmpeg 和 VLC 放在一起谈,因为它们真的,真的像你说的那样,是同一个双星系统里的两颗星,而我们都只是在围绕它运行。我们能不能顺便向一路上的一些人致敬?我们还没有真正谈到 FFmpeg 的历史。所以也许你能讲讲 Fabrice?能讲讲 Michael Niedermayer?能讲讲这里的一些关键人物吗?
- 基兰:我们就谈谈 FFmpeg 的几个时代吧,因为这里有一些关键时代,也有一些关键人物让这一切成为可能。你刚才提到的 Fabrice Bellard 创造了这个概念。然后大概在 2000 年代,我会把 FFmpeg 的“时代巡演”里的 2000 年代称为 Michael Niedermayer 时代。他完成的关键事情包括:对当时的 DivX 和 Xvid 提供了全面支持,以及对各种被称为 MPEG-4 Part 2 的奇怪变体提供支持。这早于我们熟悉的 MPEG-4 Part 10。所以那是 2000 年代的视频编解码器时代,当时有一堆又一堆奇怪解码器的不同口味。在 2000 年代,你需要一个新播放器来播放每一种不同的文件格式。Windows Media Player 用来播放 Windows Media 格式,RealPlayer 用来播放 RealMedia 格式。那时 FFmpeg 里的另一个关键点,就是为这些格式提供原生解码器。我确实记得自己十几岁时发现有这么一个播放器,它可以播放、可以解码这些文件,而不需要那些彼此独立又臃肿的播放器。因为当时你下载 RealPlayer,里面会带一大堆其他东西,一大堆广告和其他内容。而一个简单、快速的库带来了这种可能。然后我认为 2008 年是一个,2008 年之后是一个很大的变化,因为那时 H.264 走向成熟,而我希望我们之后能多谈一点。这是高清视频的开端。所以 H.264 是其中关键的解码器。我会把那称为 2000 年代后期和 2010 年代,也就是那些伟大的逆向工程师登场、真正做出惊人工作的时期。最初,能有一个播放器可以播放 Xvid、DivX、Windows Media 和 RealPlayer,本身就已经是巨大成就了,而且不需要 codec pack,不需要下载那些奇怪的、带着古怪广告和 spyware 的东西。
- 让-巴蒂斯特:VLC 1.0 就是在那些时期发布的,2000、2009、2010。也就是那时候它爆发了。
- 莱克斯:是的,不需要 codec pack,它就是能用,能跨越所有这些不同的……
- 让-巴蒂斯特:事实上,所有那些 codec pack 基本上就是 VLC 里的 FFmpeg,再加上我们为各种其他编解码器写的模块。
- 基兰:但在当时,情况不是这样。2000 年代有各种奇怪的 codec pack,里面有从这个地方来的 DLL、从那个地方来的 DLL……
- 让-巴蒂斯特:还有很多 spyware。
- 基兰:……带着 spyware,带着你知道的那些东西。它不可靠,你不知道里面有什么。而能有一个开源的单一播放器,或者一个开源的单一播放模块/播放器来做这件事,是很重要的。但我想强调的是,Michael 在 2000 年代做的这项任务是西西弗斯式的。它真的如此。边缘情况的数量多到难以理解。你可能会遇到一个中国 CCTV 系统,它用了 MPEG-4 Part 2,也就是所谓 MPEG-4 ASP 的某个奇怪变体,而你必须修好这个变体,同时不能破坏其他所有人的东西,然后这样的情况乘以一百万。
- 莱克斯:所以你说很多逆向工程就是在那里发生的。
- 基兰:它从 2000 年代的 Windows Media 开始,因为那是专有的。然后是 RealMedia,和 Benjamin Larsson 有关。
- 让-巴蒂斯特:Kostya Shishkov。
- 基兰:Kostya Shishkov,那个时代。那些是关键人物,那是关键基础。然后到 2010 年代,大概就是 Paul Mahol、Kostya 那个时代,他们在做一些最困难的编解码器。JB 也许可以讲讲 GoToMeeting 4 和 GoToMeeting 5,还有……
- 莱克斯:什么?GoToMeeting 是什么?
- 让-巴蒂斯特:那么,我们来谈谈这个了不起的乌克兰人 Kostya。他当时住在德国,而且热爱瑞典,对吧?他……这个人是最……社区里很多人都很聪明,而他属于那种接近天才边缘的人,对吧?
他能够逆向工程极其复杂的编解码器。他做这件事,我和基兰也会做一点逆向工程,但显然远远不到这个水平。
- 嘉宾:不,不,是的。
- 莱克斯:嗯,他逆向工程的是二进制 blob,对吧?有 20 MB?
- 基兰:对。作为参照,逆向一个 1 MB 的二进制 blob,大概就是一个月量级的工作;而这个人做的是 20、30 MB 的 blob。也许我们一会儿可以聊聊这件事的细微之处,聊聊到底怎么做。但他是在为非常困难、非常冷门的编解码器做这件事。
- 让-巴蒂斯特:而且他是为了好玩才做的,对吧?所以 GoToMeeting 当时对 VLC 是个大问题,因为很长一段时间里,这是排名第一的功能请求。于是我放了一个赏金。后来那个人有一天说:“好吧,JB,我来做。”两个月之内他就做完了,然后还解释了自己是怎么做的。他就像是在说:“哦,我看了看代码,这个看起来像我以前在 WMV 里见过的 DCT 之类的东西。”他就这么做了。最有意思的是,他写的代码里有一大堆玩笑。里面有大量关于 JB,也就是我的名字,还有 Kempf、Kempf 和 Kostya 的笑话。那段代码很漂亮,对吧?
- 莱克斯:我想评论的一件事是,我有机会和一些开发者聊过,也和一些汇编语言层面的人聊过。他们总是把一切说得好像挺容易。这里面有一种谦逊。也许是因为做这些事本身要求太高,所以其他一切看起来都容易了。我想这就是可以带走的经验。
- 让-巴蒂斯特:在这个社区里,最令人印象深刻的一些人,是做逆向工程的人,以及做汇编的那批人,对吧?嗯,这两类人都非常了不起。比如 x264 之所以变得那么出色,是因为一个叫 Loren Merritt 的人。他好像来自华盛顿大学。
- 基兰:当时是的。
- 让-巴蒂斯特:他让一切都变得又好又快,写了大量汇编。嗯,是的。所以我想那就是黄金时代,很多事情都是在那个时期完成的。
- 基兰:所以,如果你看 Kostya,比如说,他看待世界的方式就是把它当成一份二进制规格说明。他不需要文档或任何东西。他的态度是:“我有一个二进制文件,我能把这一切弄明白。”他经常用“二进制规格说明”这个说法。“啊,你知道的,这不是问题。”然后他会离开,过一阵回来,做出很有意思的东西。
- 莱克斯:你能具体讲讲,或者补充一点细节和质感吗?逆向一个 blob 到底需要什么?
- 基兰:可以。我们就拿 GoToMeeting 举例,这个例子很好。比如我在 GoToMeeting 上录了一场会议。那我怎样才能不需要 GoToMeeting 播放器就回放它?甚至可能根本没有播放器。我可能需要把一段会议录音发给一个没有播放器的人,或者类似情况。所以首先,那里还有大量其他东西。它其实是一个视频会议客户端。你需要去找到真正负责解压缩的模块,这件事可能容易,也可能不容易。你需要一种办法,把这个模块里的 YUV 数据实际 dump 出来。所以通常这会涉及把它放进反汇编器里打开,试着猜 hook 应该放在哪里,才能接入这个模块,并原生运行这个模块来解码一个样本文件。也就是弄清楚这个模块在哪里执行解码过程,再找到一种 hook 进去并输出原始 YUV 数据的办法。因为你之后真正做逆向工程时,需要拿它作为对照点;你需要做到 bit exact,或者在某些情况下接近 bit exact。然后你打开反汇编器,靠大量直觉去判断 DCT 在哪里,熵编码在哪里。这里没有一本规则书,但总有某种模式。比如 GoToMeeting,你会知道它会有很多屏幕编解码器工具。它也有不同变体,所以我记得常见的是 GoToMeeting 4、5?
- 让-巴蒂斯特:嗯,2 或 3、4,我想。
- 基兰:2、3、4。
- 莱克斯:所以像你这里提到的,查 Perplexity 会看到,GoToMeeting 过去为较老的录制会话使用自己的专有编解码器,这些会话历史上存储在 WMV 文件里,需要一个特殊解码器才能在 Windows 上正常播放。如果没有安装这个解码器,Windows Media Player 和一些编辑器就无法解码视频轨道,所以你可能只能听到音频,或者看到黑屏。天啊,我太记得这个了。而这里做的就是把它逆向出来。
- 让-巴蒂斯特:这很关键,对吧?因为 GoToMeeting 现在已经不是很多人知道的东西了。现在你知道 Zoom、Teams 之类的东西。但如果我们快进 10 年、15 年,这就是一个 Windows 32 位的 GoToMeeting.exe,对吧?你会说,哦,是啊,可我在 Android 上,我在 iPad 上,我在别的地方,对吧?你要怎么做?我会在 RISC-V 上,在 Arm 上。这些都被挡住了。但有大量文件是我们为了未来必须支持的。这就是为什么这类工作对人类极其有用。
- 莱克斯:不过我必须说,这个逆向工程过程太震撼了。太疯狂了。它有点像,我最近读了很多考古,也采访了考古学家。你的信号实在太少了。是,是,随着时间推移你会积累大量经验,你会理解原始代码的结构,所以你可以开始推断一些基本东西。但你就像考古学家拿着一把小刷子,试图重建整个人类文明。
- 让-巴蒂斯特:基兰太谦虚了,其实基兰也做过一些逆向工程。
- 基兰:当时做过 CineForm,嗯……
- 莱克斯:CineForm,不错。
- 基兰:……是的,当时那项工作后来实际上促成了开源。嗯,所以在做二进制那一侧的同时,你显然也有样本。很多情况下,你没有很多样本,所以你必须弄清楚所有不同的 flavor 是什么。以 CineForm 为例,它其实是这个编解码器内部不同方法和工具包的集合,因为它常常是自然生长出来的。困难的地方在于找到一个样本,让你能从某个地方开始,而不必先实现另外 10 种不同的东西。所以先从那里开始。幸好当时我纯属偶然找到一个样本,里面有很多平坦的块。那是动画,所以帮助很大,因为它没有使用特别复杂的编码工具等等。你能有一个切入点,然后不断往上搭,直到你弄明白:“嘿,这里有几个 bit,我漏掉了这个。我漏掉了这个 if 分支。”然后你会说:“哦。”我们说的样本,指的是样本视频。然后你在追踪,试着通过观察样本,同时看机器码,来推断这个编解码器到底在做什么。
- 基兰:机器码在告诉你……
- 莱克斯:看机器码。
- 基兰:……“啊,我有一个字节,这个字节是 6。走这个分支。”换一个样本,又会是……
- 莱克斯:这太离谱了,伙计。
- 基兰:然后……
- 莱克斯:太离谱了。
- 让-巴蒂斯特:……所以你看,这已经很离谱了。然后你再去看 GoToMeeting 这样的东西。
- 基兰:对,对。
- 让-巴蒂斯特:那就像是……
- 基兰:我那个算简单的,对吧?
- 让-巴蒂斯特:……想象一下……
- 基兰:对,是吧。
- 让-巴蒂斯特:……复杂度再高两个数量级。德国某个地方的一个人,一个人就在做这件事。而且很长一段时间里,你是在一个黑箱里工作,因为一个解码器有太多步骤:熵解码、帧内预测、运动预测、IDCT 等等。很长一段时间里,你什么都看不到,对吧?所以你完全是在内存里调试。
- 基兰:调试猜测本身。
- 基兰:你可能把存放系数的 buffer 完全搞错了,于是你可能沿着一条完全错误的路钻下去,以为它是这个东西,结果发现,糟糕,不是,那是别的东西,然后……
- 莱克斯:而且你做这些,面对的是几十 MB 的二进制文件,里面有数百万条指令,对吧?
- 基兰:所以你是在调试器里一步一步往前走,一条指令一条指令地看,说:“嘿,这条指令改变了这个。这个做了这件事。”
- 莱克斯:在 CPU 层面暂停程序。就像是……
- 基兰:对,在 CPU 层面暂停,观察发生了什么,试着弄明白……
- 让-巴蒂斯特:有时候你需要在 VM 里做,这样你才能暂停 VM。
- 基兰:对,暂停 VM,把内存 dump 出来,因为有些编解码器可能带加密。那里可能有 DRM。所以你需要从虚拟机里 dump 内存。
- 让-巴蒂斯特:我 2003 年进入 École Centrale Paris 的时候,Jon Lech Johansen 基本上破解了 DVD 规格,并创建了 DeCSS。他还给我们展示他是怎样破解 DRM 的,那是 Apple 的 MP4 FairPlay。他在自己的笔记本上做这件事,而我当时还年轻,21 岁,真的被震撼到了。因为他基本上是在某种 VM 里调试 Windows,还带着各种扩展……就像,哇。这太不可思议了。令人震撼,也很有启发。从你们的经验,以及你们在社区里看到的情况来看,这会让人气馁吗?会不会……
- 基兰:人们会帮你。人们会给你发样本。大家很热心。有时候你拿不到编码器,这就更难了,因为你只能去问,只能请求别人给样本。我记得 VideoLAN 曾经有一段时间会发推求样本:“嘿,我需要这个冷门样本。”然后……
- 让-巴蒂斯特:很长一段时间里我都是:“哦,我需要这个编解码器,我需要那个编解码器。”
- 基兰:如果你非常幸运,你会找到那种……如果不走运,你要么什么都没有,要么只有一两个。然后有时候你会发现一座金矿。比如有人说:“是的,我们公司有 100,000 个这种文件,因为我们因为某种原因依赖它。”嗯,这些就是最好的情况。因为这样他们就可以在大量编码工具范围内测试 bit exactness。
- 莱克斯:你能解释一下 bit exactness 吗?
- 基兰:bit exactness,也就是位精确性。大多数视频编解码器,不是全部,但至少从 2000 年前后开始,都有一个位精确的定义,所以每一个实现都必须产生完全相同的 bit,也就是从解码器输出的数据必须逐 bit 完全一致。
- 莱克斯:对于大量样本来说?
- 基兰:对于给定的一个样本来说。所以 Lex 的实现、JB 的实现和我的 H.264 实现,必须 bit 完全一致。90 年代的 MPEG-2 不是这样。可以说,那可能是视频行业犯过的最大错误之一。我想 1992 年在那个房间里的人,我们两人大概多数或都还穿着尿布,但他们也承认了这一点。我想特别提一下 Yuri Reznik,他承认那是那个时代的一大错误。
- 莱克斯:你的意思是,编码器需要能够运行测试,然后验证 bit exactness。bit exactness。我的意思是,这确实是一个很好的保证。这里有一种和 Web 浏览器工作方式平行的发展路径。浏览器接收 HTML 并显示出来,但不同引擎之间没有 bit exactness。
- 基兰:我倒想指出,FFmpeg 实际上很独特,因为从某种意义上说,它已经变成了赢家通吃的局面。你有……浏览器是一个很好的类比,因为它也必须解析很多不同内容,并以特定方式渲染出来,就像解码器一样。但浏览器仍然有多个引擎。有 Firefox 的引擎,有 Chrome 的引擎,还有几个相当不错的日本引擎。可是在多媒体领域,尤其跨越大量编解码器时,情况总体上不是这样。FFmpeg 在某种意义上几乎赢下了全部。我想这是因为,每新增一个编解码器,它带来的价值实际上超过这个编解码器本身的价值,因为它让整个系统都变得更好。
- 莱克斯:天啊,这真的很酷。查 Perplexity,Yuriy Reznik 是一位多媒体和信号处理研究者,在基辅大学获得计算机科学博士学位,发表过 150 多篇论文,拥有 80 多项已授权美国专利,参与了包括 H.264、MPEG-4、AVC-H.265、MPEG-4 ALS、G.718 在内的主要多媒体标准,还有……
- 基兰:G.71 是电信领域的东西。电信。
- 莱克斯:哦。所以他和公司联系更紧密。
- 基兰:RealAudio、RealVideo,对吧?那在当时……
- 莱克斯:哦,对。
- 基兰:……非常重要。
- 莱克斯:……Zencoder、Brightcove、Contex。天啊,我得和 Yuriy 多待待。他是真厉害。而且他像是最友善的人之一……
- 基兰:Slack 那位,对。
- 让-巴蒂斯特:……没错。比如我现在在做的创业公司叫 Kyber,对吧?我认识 Yuriy,是因为我每年都会在丹佛的 Mile High Video Conference 上见到他。他给了我很多非常好的想法和建议。他真的是一个非常了不起的人。
- 基兰:他会告诉我们,能认识我们有多么、多么棒。然后我们就会想,你看着这一切,会觉得其实应该反过来才对,Yuriy。
- 莱克斯:这让我想起你跟我提过的 FATE 测试,以及 FFmpeg 纳入任何东西时使用的那套极其严格的测试流程。你能带我走一遍这个测试流程吗?
- 基兰:可以。FFmpeg 有一个叫 FATE 的系统,也就是 FFmpeg 自动化测试环境。因为 FFmpeg 运行在非常多不同的 OS 上,也可以用非常多不同的编译器来编译,所以配置数量非常疯狂。你可以看到荒诞的组合:编译器变体、操作系统变体、指令集。你可以看到顶部 macOS 有大量不同变体,因为它有 iOS,也有 tvOS。
- 莱克斯:我正在看一个页面,fate.ffmpeg.org。81 分钟前,76 分钟前。这里列着不同架构、操作系统、不同编译器,Apple Clang 版本……
- 基兰:组合太疯狂了。
- 莱克斯:……这个组合太离谱了。RISC……
- 基兰:这些都是志愿者跑的,所以它们全都是志愿者系统。比如最上面的那些 Mac 是我放在办公室里托管的,托管各种不同东西。其他人托管其他东西。它真正的作用是确保……因为 FFmpeg 有相当复杂的 C 代码,比如说,你确实会遇到误编译。所以编译器有时会把 C 代码错误地编译出来。比如这种事偶尔会发生。
- 莱克斯:哦,这里还有所有编译的日志。
- 基兰:对,所有编译、所有测试的日志。我想另一个页面会显示所有测试都通过了。
- 莱克斯:如果你点击,你可以看到所有测试……回来了。所有测试成功。
- 基兰:在日志测试里,对。所以你看到,所有这些测试都通过了,涵盖所有不同编解码器、所有不同滤镜变换、所有……这个规模真的很疯狂。
- 莱克斯:哦,太离谱了。
- 基兰:覆盖所有组合。到这个程度已经不只是一个矩阵了,它像是不同组合的透视表。
- 莱克斯:太离谱了。
- 基兰:这是我们工作里的关键部分。因为你可能能在本地测试某个东西,你做了一个改动,但实际上它会破坏 Mac 上的 GCC 11 之类的组合,而你可以据此修复。我们也会遇到误编译,所以 C 代码有时会因为编译器里有 bug 而产生错误输出。由于视频帧之间存在依赖关系,这有时会产生相当大的影响。输出里即便是一个很小的变化,也可能级联成非常大的画面故障。
- 莱克斯:你能看到 PowerPC,能看到 RISC,能看到 ARM。
- 基兰:过去有 PowerPC,有 RISC,也有一些奇怪的东西,比如 DEC Alpha。还有……
- 莱克斯:你能看到 Visual Studio,不同版本的 Clang 或 GCC。
- 基兰:Visual Studio、Intel 编译器、Apple Clang,应有尽有。
- 莱克斯:有哪些痛点?比如你们有没有一些情绪触发点,或者关于某个特定操作系统、特定容器、编解码器组合的噩梦?
- 基兰:对我来说这很简单,因为我有一份本职工作。我创办的公司做的是广播设备,比如在电视体育场馆和演播室之间传输体育比赛。我们必须处理 10-bit 视频,而 10-bit 视频有一组挑战:你无法在 CPU 上原生处理 10-bit 数据。所以你必须把它放进 16 bit 里。这就意味着有 6 bit 被浪费了。因此会有不同的打包格式,用来更高效地打包数据,因为当你通过网络发送它时,你会损失……你需要省下那 40%。比如在 PCI Express 上,你可能只有那么多总线带宽可用。所以我想我们内部大概有……有些是行业格式,有些是我们自己构建的硬件内部格式。我们有一个大概 5 乘 5 或 6 乘 6 的矩阵,覆盖每一种格式到其他每一种格式的转换。事实上,其中一个我发给你看过,它们全都是用手写汇编写的,而且都支持不同 CPU 世代。所以处理这些不同组合再乘以一百万,真的很有心理创伤。
- 莱克斯:顺便说一句,你说的公司是 Open Broadcast Systems。
- 基兰:对,不过它和免费的 OBS 串流服务没有关系。但 JB 和我都创办了大体围绕 FFmpeg、VLC 精神的公司,所以那是真正底层的工作。在大多数公司里,这不会用汇编写。大家会接受 C 足够快。可你从那个例子可以看到,C 并不快。
- 莱克斯:这里写着比 C 快 62 倍。
- 基兰:对。所以这是把那种做底层编程、实时编程的精神拿过来,用在商业应用上。JB 和我都围绕它创办了公司,很多时候还会从开源社区招聘开发者,使用这种精神。所以这是我们正在做的一些事情的绝佳例子。在大多数公司,人们会说:“哦,我用 C 写,这已经很快了,我们完事。”但实际上你可以做得好得多。
- 让-巴蒂斯特:对我来说,我们的一些头疼问题来自某些很难支持的 OS,对吧?因为如果你看 VLC,多亏了 FATE 和 FFmpeg,我们可以运行在……最新版本的 VLC 运行在 Windows XP 上,而且现在仍然能跑;也运行在 Windows 11 上。我们支持从 macOS 10.7 到最新的 macOS,不管现在是哪个版本,对吧,26。我们从 iOS 9 开始支持 iOS,嗯,现在其实到 iOS 26,对吧?我们支持很多类型的 Linux、BSD、Solaris。最新版本仍然能跑在 OS/2 上,对吧?世界上可能只有 10 个 OS/2 用户,其中一个在维护 VLC。然后你会意识到,围绕 VLC 的这个非常小的团队,借助 FFmpeg 编解码器和其他组件,支持的 OS 数量比 Microsoft、Google 或 Apple 还多,而那些公司拥有几乎无限的力量和资源。举例来说,最糟糕的是 iOS。为了能在 iOS 9 上构建,我们需要非常巧妙地混合好几个版本的 Apple Xcode IDE 和 SDK,来自多个版本,然后做出一种科学怪人式的拼合版本,这样我们才能继续支持 iOS 9;Apple 的编译器完全不支持它,但我们仍然要在 iOS 9 的 Arm32 上运行。你在 FATE 上也看到了,它仍然支持 iOS 9,对吧?所以,我的头疼主要和支持这么多 OS 有关。这很重要,因为我们收到过太多人说:“嘿,谢谢你。我还有一台 iPad 2 用来看电影。”而它仍然能在 iOS 9 上运行,对吧?这也有一种影响:当硬件本来还能正常工作,只要你正确优化,就不必强迫人们去买新硬件。这又把我们带回到刚才说的汇编。它也是在对抗那种你必须不停买新东西的事实,而其实你本可以优化得更多。可这是一门正在失落的技艺。
- 莱克斯:你得跟我讲讲这门失落的技艺,或者说这些汇编之火的传承者。什么是汇编?它为什么美?为什么难?它是怎么工作的?
- 基兰:当你写汇编代码时,你是直接使用实际处理器所用的指令来写。大多数时候,你会用某种语言来写,比如 C 是个很好的例子。编译器会根据你的 C 代码,为你生成汇编语言和机器码指令。我们在 FFmpeg 里使用一种特定风格的汇编,叫 SIMD,也就是单指令多数据。意思是,比如说,我想给一个数加 5。在标量汇编里,也就是处理单个元素的方式。比如我有数字 10,想加 5。我使用 add 指令,把 5 加到 10 上,得到 15。而用 SIMD,我可以有一整组 16 个不同数字的向量。它们可以全都不同。如果我想给它们加 5,我可以运行一条指令,而这一条指令会把 16 个元素全部相加。你可以想象,这非常适合视频。视频是像素网格,所以我可以同时对多个像素执行操作。FFmpeg 的关键不同在于,我们不使用抽象,或者不在它上面使用任何主要抽象。世界上有一部分人使用所谓的 intrinsics,也就是内建函数。这些是 C 函数,行为和手写汇编非常相似,但并不完全一样。数据在 CPU 上存放的寄存器由编译器替你分配。所以理解我们写 SIMD 时的关键在于,我们得到的是 10 倍,而且不是百分比,是 10 到 50 倍的速度提升。那个函数是 62 倍,嗯……
- 莱克斯:太离谱了。
- 基兰:……FFmpeg 账号你也知道,经常发布、发推讲这些,想告诉大家:“嘿,我们正在做这些东西。”
- 莱克斯:你是一个能看到汇编之美的人。但对这类应用来说,它也极其有用,真的能显著超过 C 的性能,这太疯狂了。
- 让-巴蒂斯特:它是必要的,对吧?因为我们需要谈的项目之一叫 dav1d,对吧?dav1d 是一个解码器,面向开放媒体联盟制定的格式,也就是一个叫 AV1 的视频解码器。
- 莱克斯:给不了解的人解释一下,我们前面一直在谈 H.264。AV1 是另一个极其流行的标准和编解码器,正在越来越多地接管互联网。
- 让-巴蒂斯特:当这个格式发布时,很多人说,尤其甚至来自开放媒体联盟内部的人,对吧,也就是 Google、Netflix、Amazon、Mozilla,他们说:“嗯,这个格式太复杂了,解码必须用硬件来做。”对吧?然后我和另外几个人来了,主要是 Ronald、Henrik 和 Martin,我们说:“我们需要一个极其优秀的软件解码器,因为硬件出现还需要时间。”于是我们写了这个项目,而这个项目疯狂到难以形容。我们说的是 30,000 行 C,但有 240,000 行手写汇编,对吧?
- 莱克斯:手写汇编,240,000 行。太不可思议了。这意味着,我是说,我们讨论的这些东西里,它可能是最大的汇编代码库之一。
- 让-巴蒂斯特:给你一个概念,基兰可以纠正我,但我觉得 FFmpeg 为所有编解码器加起来大概有 100,000 行汇编。
- 基兰:所有编解码器加起来。嗯哼。
- 让-巴蒂斯特:而单这个项目就有 240,000 行。它当然是一个 VideoLAN 项目。它被优化到了极限,因为我们启动这个项目时的格言是“每一个周期都重要”,对吧?每一个周期都重要。每一个周期都重要,因为 dav1d 被用于 VLC,也被用于一些软件 AV1 播放栈。我们说的可能是 30 亿台设备,它们会不停地解码视频。比如现在 Netflix 的 30% 视频是 AV1,YouTube 的 50% 也是,对吧?而你通常没有硬件解码器,因为没有多少设备有硬件解码器。借助 dav1d,我们发现用一两个核心就可以正确解码 720p。所以它真的是……
- 基兰:对,那就是 dav1d。
- 让-巴蒂斯特:……令人难以置信,对吧?
- 基兰:那就是 dav1d。Lex,看这个。
- 莱克斯:嗯,是的,这是你另一条很火辣的推文。“巅峰视频编解码器就应该是这样:79.9% assembly……”
- 基兰:那几乎是……
- 莱克斯:……19.6% C,0.5% 其他。
- 让-巴蒂斯特:而令人惊讶的是,这些推文都是事实,但人们会发疯。他们很不高兴,对吧?他们会说……
- 基兰:过去一年,或者说过去两年,他们一直很激动:“不,intrinsics 就够了。编译器是……”哦,他们会说:“我从来没有……”
- 让-巴蒂斯特:“你可以优化你的编译器,自动向量化,这是你的错,你不懂。”而我们早就试过这些了,对吧?
- 基兰:两年来,两年之后,当我们展示了数百个手写汇编的例子,他们还是说:“不,不,不,你们做错了。编译器能做到这个。”
- 莱克斯:所以我们其实应该把这点说得更清楚一些。软件工程师们的直觉是,当你有这样的代码……好吧,我们就拿 C++ 举例。有一个编译器会做大量优化。
- 基兰:是的。
- 莱克斯:于是大家的预设是,如果你有一个足够好的编译器,如果你持续改进编译器,它就会生成代码,达到接近最优的性能。你不可能战胜它。
- 基兰:对。是的。
- 莱克斯:而你们一直在挑战这个想法。也就是说,如果你做……
- 基兰:高出几个数量级。
- 莱克斯:……高出几个数量级……手工打造的汇编可以超过 C。
- 基兰:他们告诉我们的两件事是:“是的,但现代编译器有自动向量化,对吧?”因为我们做的 SIMD 就是向量化。但它根本不接近,对吧?根本不接近,对吧?不是慢 5%、10% 这种程度。它是慢好几倍。
- 莱克斯:所以我们能不能……我不知道你能不能从哲学上说点什么。因为有很多优秀的软件工程师、优秀的工程师、优秀的机器学习人。Karpathy 会听这期节目,然后说:“我应该从这里得到什么直觉?我们应该……”
- 让-巴蒂斯特:顺便说一句,Karpathy 是因为那些推文才学汇编的。我只是……他开始了。他说:“哦,我觉得这是一场运动。”
- 莱克斯:他会说:“让我弄明白这里发生了什么。”
- 让-巴蒂斯特:不,不,他,还有你知道他记录自己工作的方式之类的。
- 基兰:从哲学上说,重要的是要意识到,硬件速度大幅提升的时代已经过去了,对吧?我们正处在摩尔定律的尽头。我们在 AI、内存方面都有限制。你需要往技术栈更底层走,做更多优化,从已有的东西里榨出更多能力。因为我们对算力、CPU 算力、GPU 算力的需求正在爆炸,而硬件速度并没有爆炸式增长,对吧?所以人们会做的是增加更多核心,对吧?但基本上,到某个点你可以加 250 个核心,对吧?而我们做的是把机器的每一寸能力都用起来。
- 让-巴蒂斯特:不只是这样,不只是这样。我们是在“滥用”机器。我们会用创造者没有预料到的方式去使用机器。有时候,我们会用一条和手头任务完全无关的指令。比如在视频处理中使用一条密码学指令,却做的不是任何密码学相关的事情。
- 让-巴蒂斯特:我们还会做另一件事,比如在 dav1d 里,这有点疯狂,就是我们不使用操作系统提供的函数调用约定。
- 莱克斯:这个我们应该解释一下。
- 让-巴蒂斯特:这极其……复杂。但基本上,通常当你在代码里从一个函数跳到另一个函数时,会有一种方式保存寄存器,也就是 CPU 的状态,然后进入另一个函数。这是标准做法。
- 基兰:这有点复杂。我稍微简化一下。dav1d 会做一些事情来“滥用”调用约定。所谓调用约定,可以这样理解:我写了一个函数,现在想调用另一个函数,那么两个函数之间怎么共享数据?因为这里有一个约定,也就是所谓 calling convention。dav1d 为了最优性能,有时候会创建自己的调用约定。比如我要调用莱克斯·弗里德曼的库,我们就得先约定好,在汇编语言这个空间里,我怎么把数据传给你。汇编的挑战之一是,每个操作系统……倒也不是每个操作系统,但至少在 x86 上我能想到四种:Linux 32 位、Windows 32 位、Windows 64 位、Linux 64 位。它们都有自己的调用约定。我们之前提到过的 Loren Merritt 做过一件很了不起的事:他创建了一个非常轻量的抽象层,让你只写一次汇编代码,它就帮你处理所有调用约定相关的东西。以前这一直是个问题,因为你得管理四个不同变体。但 dav1d 又往前走了一步:为了速度,它在内部使用自己的调用约定,绕过函数规则这一类东西,然后说:“好吧,实际上我要用这种方式调用函数,因为我知道它就在我的库里面。”
- 莱克斯:它必须针对每一个操作系统都做特殊处理吗?
- 基兰:如果是自定义的,那就不用。但一般来说,挑战确实在这里,而且还和每一种指令集有关。还要强调的是,我们会在每一种指令集上都这么做。也就是说,每一种指令集都有自己的手写汇编,这就更疯狂了。而且这张矩阵这几年变得更大了,因为有 RISC-V,有 ARM64,有新的 SVE,还有 SME。x86 这边有 AVX-512、AVX。所以我们会做运行时处理器检测,看看 FFmpeg 或 dav1d 正在运行的那台机器具备什么能力,因为你可能是在一台 2008 年的笔记本电脑上运行,这些指令并不存在。运行时检测之后,我们相应地设置函数指针。然后从那一刻起,就一路跑下去。
- 莱克斯:或者你也可能在一台 RISC-V 机器上。
- 让-巴蒂斯特:对。而在这一切里面,为了更快,我们甚至不遵守操作系统的调用约定。因为我们知道,这些函数会从我们自己的二进制文件内部被调用,所以我们可以共享数据,而不必用通用方式保存所有寄存器。那样会导致在 CPU 的 L1、L2 缓存上加载和保存寄存器;我们这样做就能更快。所以我才说,理解 CPU 架构、理解计算机架构是关键。这也是为什么它必须手写。我不知道还有哪个项目会像 dav1d 这样做,我从没听说过。所以基兰说它是一门艺术,对吧?它确实是一门艺术。
- 基兰:我觉得在大众世界里,没有什么东西能像这样跑在数十亿台设备上。我知道有些专业行业会这么做。比如高频交易,他们非常认真地对待这件事:他们从市场接收数据流,必须在若干微秒内做出反应,所以指令很重要。但那不是一个面向大众、会批量出现在十亿台设备上的东西。那是高度专业化的场景,运行在高度专业化的硬件上。而我们运行在所有硬件上,从……
- 莱克斯:抱歉我一直追着这个问题问,但这里有一个非常反直觉、几乎像革命性的想法:汇编有巨大的价值。我们到底应该从中得到什么启发?你知道,有很多人在听这期节目,他们基本上会想,包括我自己也是:我用 C/C++ 编程很多很多年,一路跟着 C++ 标准往上走,爱上了 C++,甚至包括元编程等等。然后大约 15 年前,因为机器学习,我越来越多地转向 Python。所以对我来说,在这个 Python 世界、JavaScript 世界、如今还有 vibe coding 的世界里,我只是用自然语言,坐在按摩浴缸里,喝着饮料,跟电脑说话……然后画面突然停住。为什么还要回到这么底层?它的直觉是什么?
- 让-巴蒂斯特:因为你可以让每投入一美元得到更多算力,对吧?有时候问题会受限于硬件。一个很好的类比是 LLM 里的量化。人们会说:“我要用 FP8,或者 FP4,或者像 Microsoft Phi 那样做一些疯狂的东西,做到 1.5。”因为你受内存约束,受能运行的机器约束。因为在某个时刻,我们是在做实时系统,而且我相信这也会发生在 AI 推理上:到某个时刻,你必须变得更快,而你不能总是靠更强、更大的硬件,对吧?所以你需要分析代码,看看哪里是任务关键路径,哪些东西会被不停调用。比如 dav1d 就是一个好例子。它每天会被运行数十亿小时,所以这么做有意义。但在 FFmpeg 的胶水层……
- 基兰:没有。
- 让-巴蒂斯特:……比如 CLI 那里,这么做就没有意义。它在那个地方才有意义。
- 莱克斯:是的,这也和你们新的努力、你的新公司 Kyber 有关。它就在为超低延迟做这类事情,口号是:“每一毫秒都很重要。”当你确实在某个维度上受到极强约束时……
- 让-巴蒂斯特:我们也正在走到这样一个节点:我们已经做了很多很棒的事情,但硬件开始反过来限制我们了,对吧?因为成本在上升,因为我们需要更多算力,所以你会受 CPU、RAM 或网络限制,你必须优化,而价值就会出现在这里。尤其是,AI 会帮助完成商业编程这一类事情,对吧?所以你无法用 vibe coding 完成的核心工作,就是针对硬件做优化,让它尽可能快。
- 莱克斯:我很想跟你们聊聊谁应该学汇编、怎么学汇编,但首先,我觉得我们需要休息去一下洗手间。用十秒钟快速感谢一下我们的赞助商。请在简介里查看他们的信息。这真的是支持本播客最好的方式。访问 lexfridman.com/sponsors。现在回到节目。好了,我们回来了。有一个很不错的仓库,里面是汇编课程。首先,你们认为开发者应该学习如何用汇编编程吗?如果要学,你会怎么学?这个 asm-lessons 是什么?
- 基兰:我个人一直不太满意书本和网上教授汇编的方式,因为它们非常偏语法。而通常来说,你不会靠学习语法和结构来掌握一门语言。你会先问别人叫什么名字,然后从那里开始,去解决真实的沟通问题。你不是先学句子结构、疑问句、副词等等。但几乎所有汇编书都像是在这么做:把每一条指令过一遍,甚至包括那些并不真正相关的指令,解释它们都做什么、怎么做……其实变化并没有那么大。我们社区里的另一个问题是,汇编基本上是手把手教的,人与人之间传授,有点像铁匠学徒一对一学艺。这是我能想到的唯一合理类比,但它在网上并不能规模化,也很难扩展到其他事情。所以我开始写一组汇编课程,讲的是 FFmpeg 里那种写法。它和一般意义上的汇编有点不同。我在想另一个汇编的大型使用场景,大概是嵌入式设备,非常低功耗、便宜的设备;那和我们这里做的事情完全不同。我觉得最好能强调一下要求,其实很简单:高中数学和 C。甚至严格说,连 C 都不完全需要,真正关键的是指针。要强调的是,没错,我们讨论了这些东西多么精妙,但像 Daniel Kang 这样的高中生也给 FFmpeg 写过汇编。我认为已经有人因为这些课程贡献过代码。所以这件事本质上是在努力让这门正在消失的技艺延续下去,因为 dav1d 已经证明,用它可以做出惊人的东西。FFmpeg 里仍然有很多编解码器可能只做了部分汇编优化。所以它确实是从基础开始,继续解释很多行话、很多语法。它并不试图向你解释中断处理器、中断指令,以及各种不同的跳转目标;它实际上非常聚焦于向量。
- 莱克斯:它还描述了各种寄存器:通用寄存器、向量寄存器,还有非常好的例子。哦,这个很酷。
- 基兰:这是 FFmpeg 的经典例子。但其中一些汇编语言真的很美。我觉得它美,是因为它有点像驾驶一架“喷火”战斗机。这是最纯粹的航空体验,同时也把飞机推到设计者认为不可能达到的边界之外。比如我们有时候会“滥用”密码学指令去做某些事情。这里有一种美感和艺术感:真的就是你和处理器,中间没有任何东西。就像你坐在驾驶舱里,手握操纵杆,你移动操纵杆,而它和副翼有物理连接。你可以把那架飞机推到它正常情况下做不到的程度。这里面确实有一种美,一种令人惊叹的东西。但我不认为那种一对一传授的汇编方式能长期奏效。有人教了我,我也教过好几个人,但因为我们做的是一种非常特定的风味和方式,这种方法走不远。
- 莱克斯:这简直就是……我本来想说像巫师在代代相传。嗯,我意识到我戴着这顶帽子,看起来确实像个巫师。但你们基本上就像智者、睿智的长者在传承这门手艺。我能问问 LLM 吗?它们能帮上忙吗?
- 基兰:它们的理解比我预想得更多,但仍然……我问过它一些问题,它还是会开始幻觉……倒也不是幻觉,而是做一些修改。然后我问:“这和原来是 bit-exact 吗?”它说:“不是。”我说:“修好它。”然后它又继续做同样的事情。问题在于,没有像 Stack Overflow 那样庞大的信息语料可供它学习。
- 让-巴蒂斯特:没有足够的数据可以训练。这是最大的问题。其实我职业生涯一开始做过一些 Itanium(安腾)的汇编。Itanium 是一种已经死掉的处理器类型,是很久以前 Intel 和 HP 想做 64 位时弄出来的。后来他们输了,我们得到了 AMD 做的 AMD64,也就是后来的 x86-64。但 Itanium 非常有意思,因为那类处理器有大量计算能力可以做浮点和 FMA,这和我们现在做 LLM 所需要的东西有点类似,对吧?
你可以把三条操作打包到一行里加载。所以基本上,你每秒可以有大约六十亿次操作的输出,但总线,也就是内存总线,只允许十五亿,对吧?也就是说 CPU 快了四倍,所以你必须做一些疯狂的事情,把东西打包进内存,或者复用寄存器。这类语义没有任何语言能表达,对吧?我有那本 Itanium 编程书,因为 Intel 出过非常棒的书。但这正是基兰所说的:如果你不知道自己要做什么,它根本不可能读懂,对吧?里面全是大量行话等等。而这些课程很棒,是因为它们面向一个真实问题,而且你可以自己动手做。
- 基兰:而且确实有人这么做了。有人提交了补丁,然后说:“我学了你的课程,这是我的第一次修改。”
- 莱克斯:这太棒了。
- 让-巴蒂斯特:这些课程里还有一部分是一个叫 x86inc 的框架,是 Loren 在做 x264 时写的。它让你可以做更多类似的事情,创造出一种不太需要关心不同调用约定的类型。很久以前,我们也有很多学生用它给 x264 提交代码,对吧?
所以这真的做得到。而且我相信,即使你不经常写汇编,理解汇编语言也是必要的,因为它能让你明白计算机内部发生了什么,这会让你成为更好的程序员。我可以向你保证,因为做这件事会让你理解计算机内部的一些内存架构,对吧?
理解寄存器、L1、L2、L3、RAM、SSD、磁盘等等,这些都非常重要。因为这样你会形成良好的编程素养,而这会让你成为更好的程序员。
- 莱克斯:你们怎么看 Rust 编程语言?因为这有点像个 meme。
- 让-巴蒂斯特:我和基兰对此有非常不同的看法。
- 基兰:我觉得他们在内存安全这个概念上做的事情是有价值的。
- 莱克斯:它能达到汇编所实现的那种加速吗?
- 基兰:哦,手写汇编那种肯定不行。我觉得这是显然的。C 也许可以,但我看它有一种很强的世界语气质。就像“我们要解决这个问题,而且要用这种特定方式来解决”。
- 莱克斯:意思是它有点过于乌托邦?
- 基兰:它有很多关注点放在自我重要性上,而不是解决现实世界的问题。它让我想起 Sinclair C5。Sinclair Computers 的 Sir Clive Sinclair 做过一辆车,然后他说:“哦,以后每个人都会开这种电动车到处跑。”Rust 让我想起那个。我觉得这个社区没有完全理解:要让人们迁移,你必须构建一个至少和现有东西一样好,甚至更好的东西。是的,人们在做 Rust 重写,但如果它们只能做到我们需要的功能集的 85%、90%,比如 coreutils 这种东西,那最后 1% 会花掉 99% 的时间。套用 Elon 那句名言:“原型很简单。”这类东西很容易。但要做出一辆真正的电动车,你必须造出一辆至少和我们现在拥有的车一样好、甚至更好的车。Rust 还没到那个阶段。我不认为有人会反对在 FFmpeg 里看到 Rust 代码,但它需要和其他所有东西一样好用,支持同样的单元测试。它必须无懈可击,不能莫名其妙地坏掉。他们不能想什么时候破坏 ABI 就什么时候破坏。它需要有更多……我觉得它现在仍然只有一个编译器实现。所以它必须至少同样好,甚至更好。只说“嘿,这是我的内存安全乌托邦”还不够,尽管我们大概都会同意那是目标。
- 让-巴蒂斯特:我写过大量 Rust。我遇到的两个主要话题,一个是在 VLC 里加入 Rust 模块。VLC 之所以流行,其中一个原因,也是它最主要的架构决策之一,是 VLC 有一个非常小的核心和大量模块,对吧?所以你可以用 C、C++、Objective-C 写模块,也可以用任何基本上能和 C 互操作的东西写模块。因此我们做过一些 Rust 模块,我在这方面有经验,也写过其中一部分。另外,我的新创业公司 Kyber 是一个主要用 Rust 写的开源项目。Rust 极其擅长的地方在于,它是一个更好的 C++,会关心内存,并且允许你处理内存所有权,这是迄今为止没有其他语言能做到的。不过,当你从零开始一个新项目,并且所有东西都用 Rust 写时,它非常棒。但当你要和现有部分互操作时,它非常不好用。而 Rust 社区里有一部分人相信他们需要重写一切,而且一切用 Rust 重写都会更好。答案是:不。在我作为工程师、管理者、创业公司 CTO 等等的这些年里,我几乎总是说,不要重写,对吧?
- 莱克斯:这是不是很多人刚进入一个代码库时的初始本能?也许在 LLM 出现之前就是这样,因为他们还不理解过去那些做法背后的智慧。他们会说:“好吧,我们需要重写它。”这也解释了为什么会有一千个 JavaScript 框架。
- 让-巴蒂斯特:原因是这样的,而且这一点非常重要:写代码比读代码容易一个数量级。你在 LLM 身上也能看到这一点。它们能写代码,但分析代码要困难得多。所以当你来到一段非常复杂的代码面前时,你不理解它,对吧?理解别人写的代码要费力得多,因为你没有经历当时的思考过程。嗯,我还经常拿一些语言开玩笑,主要是 Perl,比如它的语法非常复杂。想象一下,我在编程时处于自己智力效率的最高点,对吧?
然后我写出了有史以来最好的代码。六个月后,我自己也理解不了,对吧?因为读代码更难。所以你经常会来到一个地方,看不懂所有智慧、所有业务逻辑、当初这样做的原因,而这些原因也许没有文档。然后你说:“好吧,我要重写它。”但事实是,不,你不会的,对吧?
因为就像基兰说的:我要用 Rust 重写 coreutils。然后当然,你很快就做到 80%,再做到 90% 要多花一点时间,最后还剩那些尾巴,对吧?
另一方面,对新项目来说,它非常好。所有和解析文件、网络相关的东西,因为有内存检查器、边界检查器,Rust 很惊人,没有别的东西能做到。换个角度回答我们这里的问题:假设我拿 dav1d 或 x264 这样的软件,对吧?它有大量运行时间花在汇编上,对吧?
嗯,我把 C 部分用 Rust 重写,对吧?这样更安全。是的。但随后你进入汇编层,你可以跳到内存中的任何地方,因为我们写的是手写汇编。所以即使我为了安全把 C 部分用 Rust 重写,只要你写手写汇编,你就会破坏所有安全性,因为我们可以跳到任何地方。因此在我看来,我们需要做的是某种安全汇编,对吧?也就是在编译期检查汇编。这类似于我们在 dav1d 和 x264 里与 VideoLAN 一起做的 checkasm 项目:开始在编译期对你的汇编做插桩和检查,确认它没有跳到内存中的任意位置。否则,你可能用 Rust 重写了一部分 C,但如果你想获得同样的性能,你就会使用内联汇编,于是你摧毁了整个安全模型。这就是我对 Rust 的一点看法。
- 基兰:不,我只是想说……从个人层面讲,我对汇编真的非常敬畏。实际上……每隔一段时间,看到 62 倍的速度提升,这种感觉永远不会过时。有些月份,从个人层面讲,我会在工作中跑我们的内部测试套件,然后只是看着它。我仍然会为我们获得的提升感到敬畏。
- 莱克斯:编程带来快乐和幸福有很多不同来源。但我认为最大的快乐之一,就是优化代码。而听起来,你们就处在这件事的最前沿。
- 基兰:我当时就想:“哇,这太酷了。”
- 让-巴蒂斯特:在社区里,我想讲两位汇编大师。他们两个人实际上都生活在北欧,一个在瑞典,一个在芬兰。Henrik Gramner 对 Intel x86 汇编了解太深了,以至于当我们向 Intel 提问时,他们会说:“你们为什么来问我们 Intel?
你们有 Henrik。Henrik 比我们更懂。”他知道几乎所有 CPU 世代上几乎所有 SIMD 指令的周期数。“哦,对,这是 P4,这是 Nehalem,这是 Core 2”,等等。这个人就像是世界上最懂汇编的人。而且他也是你见过的最友善的人,非常……他来了,你根本看不出他有多厉害。另一个人叫 Martin,Martin Storsjö。他们主要在 Arm 上做同样的事情,对吧?也就是 Neon,对吧?以及 iPhone、Android 等等。他会在手机上写汇编,用那种糟糕的虚拟键盘编辑,同时看着自己的孩子在游乐场玩,对吧?
这简直就是大师级。所以这两个人就像……
- 莱克斯:是的。所以当你在那种高水平上写汇编时,其中一部分就是要了解你正在编程的架构。
- 让-巴蒂斯特:是的。尤其是在 Arm 上,是的。
- 莱克斯:尤其是在 Arm 上。但 x86,我的意思是,这些架构也很复杂,对吧?
- 基兰:是的。但 Arm 在某些方面更复杂。带乱序执行的 x86 还不算太糟。Arm 上,你真的需要理解不同世代的 Arm 处理器,因为它们都不一样。有 A72,等等等等。还有 Apple 的变体,有这个变体、那个变体,而你需要写出能在所有这些变体上都高效运行的代码。x86 的话,粗略地说,你有 Intel、AMD,也有一些子变体,但总体来说,某个快速的东西大概率会在所有变体上继续快速;而在 Arm 上,这是一个复杂得多的局面。
- 莱克斯:我们正在用一种非线性的方式穿越历史,但我们现在聊到了 Michael Niedermayer。我想问问这件事。曾经有一段时间,FFmpeg 和 Libav 分裂了。
- 让-巴蒂斯特:是的。在开源项目里,有时候你们会产生分歧,对吧?嗯……
- 莱克斯:你说得真温柔,是的。
- 让-巴蒂斯特:好处是,因为有许可证,你基本上被允许自己做一套,对吧?这是正常的,而且一直都在发生。某个时候,在 GCC 2 的时代,有 GCC 和 EGCS,后者后来变成了 GCC 3,对吧?
还有我们说过的 KHTML 到 WebKit,再到 Blink。嗯,这是同一个过程。还有,比如今天我想在 VLC 里做一个新功能,我会 fork,自己先做,然后再合并回社区。所以 FFmpeg 的开源社区里确实发生过一次分裂,变成了 Libav 和 FFmpeg。几年后,社区又合并回来,人们继续往前走。这有点像开源社区里正常会出现的戏剧性事件。但 fork 甚至……它们很重要,因为它们会改变一个社区的现状。这里不是在谈 FFmpeg 和 Libav,而是说 GCC 那个 fork 让 GCC 变好了很多,因为有些人想从根本上改变架构,让它更快。当然,这总是人与人之间的问题等等,但最终你会发现,今天的 FFmpeg 比 fork 之前更好。而现在,我们又都回到一起了,对吧?我在社区里花了很多时间,基兰也可以说说。老实讲,这件事通常没有被解释得很好,因为很多原因并不公开。但我觉得这是正常的,也是好的。
- 莱克斯:是的。我的意思是,你把它说得很温和,但开源项目内部确实会有斗争,而且会有相当激烈的斗争。这是一个非常有激情的社区,而你们又必须以一种分布式的方式定义事情的方向。我这里看一下 Perplexity:“FFmpeg 和 Libav 在 2011 年分裂,主要是因为项目治理、领导风格和开发流程,而不是因为根本性的技术分歧。FFmpeg 实际上吸收了 Libav 的工作,而 Libav 逐渐衰落,大多数发行版和开发者又回到了 FFmpeg。”是的,那是一段奇怪的经历,因为从一个 Linux 用户的角度来说,我是 Linux 用户,所以不管是 Ubuntu 还是别的系统,突然之间,我记得有一小段时间,Ubuntu 是不是切换到了 Libav?我记得对吗?
- 让-巴蒂斯特:12、14 之类的版本。是的,差不多。
- 莱克斯:然后他们又切回 FFmpeg。我当时想:“这到底发生了什么?”所以作为用户,你会感受到那些内部辩论带来的涟漪效应。
- 基兰:公平地说,在 Apple 上,当你输入 GCC,得到的是 Clang。他们也做过类似的事情。
- 让-巴蒂斯特:是的。所以对我来说,那个 fork 确实是一场很激烈的戏剧性事件,但 Libav 的大部分开发成果都合并回了 FFmpeg,对吧?
因此事实上,FFmpeg 变成了 Libav 的一个超集。这给了用户更多东西,因为归根结底,我们是为用户工作的:更多功能,以及许多曾经被讨论过的事情。比如关于 review 的争论,关于我们如何 push 的争论,现在在 FFmpeg 里已经完全稳定下来,并且基本遵循社区里大多数人认同的方式,对吧?所以事实上,所有曾经活跃在 Libav 的人都回到了 FFmpeg 工作,因为分歧被解决了。最终,FFmpeg 比过去更强了,对吧?而且……我知道人们喜欢戏剧性事件,但是,嗯……
- 莱克斯:嗯,我最主要的担忧,我理解,而且回看这段漫长历史,它整体上是好事。但我确实担心,因为对开源项目成功至关重要的人类太少了。我见过这会给人带来心理负担,而且有时候会导致倦怠。你有这些不可思议的人,他们位于开源项目的核心。然后某个时刻会发生这样的事,因为问题是:做这件事的动力到底是什么?
归根结底,是因为你热爱它,它让你快乐。然后到了某个点,你醒来发现:“这场戏剧里的火力有点太猛了。”所以在项目层面,项目会继续,甚至经常会繁荣。但有时候,会有这些具体的人,他们只是……
- 让-巴蒂斯特:但是……
- 莱克斯:……我受够了。
- 让-巴蒂斯特:是的,但这不只是 fork 的问题,对吧?所以这是一个非常……你指的,是今天开源里最具挑战性、也最有意思的问题之一:维护者倦怠,对吧?
- 让-巴蒂斯特:AI 因此成了一个问题。Daniel Stenberg 是 curl 的维护者,可能也是世界上最会推广开源的人之一。顺便说一句,他和我一样也是欧洲开源学院的成员,所以能和他在同一个社群里,我真的很荣幸。他反对他所说的“AI 垃圾内容”,因为它会带来大量虚假报告,或者说糟糕的报告、糟糕的补丁,然后很多维护者就背上了维护软件的额外负担。这比 fork 更严重地消耗开源开发者的心力。比如 XZ 那次事件,就是因为只有一个人在维护它,然后他基本上被两个攻击者轮番轰炸,对方在半夜这些奇怪的时间不停地问他问题,试图拖住他。到某个时刻他受够了,说“好吧,我做不了了”,于是把提交权限给了攻击者。所以,开源社区里的倦怠是真实存在的,但它主要和维护工作有关。
- 莱克斯:确实如此。但我在想,我们该怎么帮这些人?因为这些人太重要了。人,这些具体的人,是这些项目核心中的核心。
- 让-巴蒂斯特:比如说,现在我正在维护大量多媒体和非多媒体库,因为原来的维护者已经受够了。有些在 VideoLAN 里面,有些在 VideoLAN 之外。因为有时候你得脸皮很厚。你会收到很多反馈,倒也不一定是攻击,但总是“这个不能用,那个不能用”,你会把它当成对自己的指责。这也是为什么资源问题,或者 Google 那次风波,会成为问题。他们没有意识到,归根结底,这就像那张图:你看到上面有一大堆东西,最底下却只是某个随便的开源项目在支撑整个——
- 莱克斯:内布拉斯加那个梗,对。
- 让-巴蒂斯特:——互联网。你知道那张图,对吧?那个——
- 莱克斯:对,就是那个 meme。它适用于很多开源项目。但这里说的是整个现代数字多媒体基础设施,而所有东西最底下依赖的那个东西就是 FFmpeg。这是真的。而通常真正维护它的,也就那么一小撮人。
- 让-巴蒂斯特:而 FFmpeg 或者 VLC,对吧,有 10 到 15 个核心开发者组成的社区,这还不是最糟糕的开源项目。XZ 安装得更多,却只有一个人。就是一个人——
- 基兰:libxml 也是,呃——
- 让-巴蒂斯特:对,libxml。它基本上大停摆了。现在已经没人再维护 libxml 了,而它是一个解析器,是那个到处都能解析 XML 的库。
- 基兰:XML 在各种荒唐情况下有一堆疯狂的边界情况,然后安全研究人员还会攻击他们,因为还有另一个他们没想到的疯狂边界情况。你会觉得,是啊,可是真正要解决这些问题,所需要的知识量是巨大的。
- 让-巴蒂斯特:还有一个人一直在为所有人维护全部时区,他住在中部某个地方,我想是内布拉斯加还是——
- 莱克斯:对,有可能。
- 让-巴蒂斯特:——南达科他?开源维护者的心理健康,是大公司不关心,或者根本看不见的东西。他们只会说:“哦,对,我只是做一份开源报告。”诸如此类。
- 莱克斯:嗯。有一部分确实是钱的问题,而且大家确实应该在财务上支持开源,方方面面都应该支持。但另一部分也像是某种基本人性层面的精神问题。你看 FFmpeg 这幅图,看见互联网上这么多东西都依赖它,人们却几乎会对那些推动这些项目、维护这些项目的人居高临下地说话。
- 基兰:在安全社区里,他们确实这么做过。我觉得当时争论里冒出来的一点就是,安全社区中有一部分人会说:“不,这些人写的是烂代码。他们得修好自己的烂代码。”我就想:“不,不,不,不。这是某个人的业余项目。你们有一个安全机器人跑过去,找到了一些 AI 生成的东西。那个人写的不是烂代码,只是到了 99.99999 百分位之外的边界情况,他没有想到而已,因为这只是他解码《星球大战》游戏的业余项目。”
- 莱克斯:先不说它是不是业余项目。它本身就是艰苦的工作,而且很美。正确的态度应该是赞美这些人,赞美他们做了不可思议的工作。真的太不可思议了,人们站出来,起初也许没有报酬,甚至永远没有报酬,只是出于热爱去做这些事。人类文明就是靠这样的人运转的。我们应该赞美他们。
- 让-巴蒂斯特:给你一个概念吧,我在 VideoLAN 收到过死亡威胁。然后,呃——
- 莱克斯:你跟我提过这件事。那背后到底是什么?
- 让-巴蒂斯特:那大概是 2009 年或者 2010 年。Apple 是在从 PowerPC 转向 Core Duo,那可能是 2006 年的事。到了 2009 或 2010 年,我决定 VLC 不再为 PowerPC 发布新版本。当时 VLC 接近 1.0 版本发布,我们一共就四个人。我们当时就觉得:“不,这不可能继续做。”于是我收到了一封死亡威胁,里面还夹着一些粉末。你记得当时有一些炭疽威胁,对吧?就是因为我决定不再维护 PowerPC 移植版。当然,那不是炭疽,当然不是。只是某种面粉之类的东西。但我收到的是一封信,里面写着:“你这个混蛋,你该死,PowerPC 万岁。”诸如此类。那是 2009 或 2010 年。我当时还年轻,只觉得:“为什么?我做了什么?”
- 莱克斯:是啊,那会摧毁一个人的精神。你会想,为什么——
- 让-巴蒂斯特:我母亲吓坏了。我们不得不去报警之类的。现在我会说,我其实挺庆幸这件事发生在那个时候。它很大程度上塑造了我。现在我可以承受很多针对我的仇恨,我还好。
- 莱克斯:现实里有这样的部分,真的很糟。因为所有喜欢 VLC、喜欢 FFmpeg 的人,比如我,我这辈子真的有几百次,可能上千次,因为 FFmpeg 而露出笑容。就是这样。但我有多少次机会说出来?零次。直到我发现它有一个 Twitter 账号。于是我偶尔会去给它发消息。
- 让-巴蒂斯特:关于 Reddit 上那个关于我的 meme,有一件事我挺喜欢,虽然因为很多原因我并不喜欢那个 meme。有人说:“哦,JB 在 Reddit 上。”我确实在,对吧。然后我出来打招呼。接着就有很多人说:“谢谢你做 VLC。”我会截图,然后发到 Signal,发到 IRC。是的,我们在不同的——
- 莱克斯:稍微岔开一下,我看到你说过 IRC 就像给老年人用的 Slack。所以你现在还用 IRC?
- 让-巴蒂斯特:当然。
- 基兰:对,我手机上也有。
- 让-巴蒂斯特:当然。
- 基兰:每天用。
- 让-巴蒂斯特:用得很好。
- 莱克斯:哇。还用得很好,是吧?
- 让-巴蒂斯特:用得很好,没错。
- 莱克斯:我猜还得用摇把给它上发条。
- 让-巴蒂斯特:不是,但它没有——
- 莱克斯:还有 AOL。AOL 就是你的社交媒体。
- 让-巴蒂斯特:它没有广告,没有追踪,什么都没有。就是,呃——
- 基兰:说实话,和 Slack 相比最大的问题是它没有线程。这很烦。也没有用表情反应的功能。有时候有这些会挺好。
- 让-巴蒂斯特:IRCv3 有。
- 基兰:是,v3 有,但没人用,而且你不能编辑自己的消息。对吧?除此之外,它可以永远完美运转。
- 莱克斯:可是没有 emoji 你们怎么交流?
- 让-巴蒂斯特:所以我才说它是给老年人用的。
- 莱克斯:老年人。好吧。
- 让-巴蒂斯特:而且我们会用那种表情符号,你知道,冒号、短横线、括号这种。
- 莱克斯:老派。总之,你们在 IRC 上交流。你刚才到底说到哪儿了?
- 让-巴蒂斯特:对,我们在说死亡威胁,还有——
- 莱克斯:噢,糟糕。
- 让-巴蒂斯特:——也在说有人感谢你。有时候有人会给我发消息,说“谢谢你做 VLC”。我总是会回复,因为我想确认这件事:你应该感谢开源社区。
- 莱克斯:是的。请所有正在听的人,赞美 FFmpeg,赞美 VLC,赞美所有不可思议的开源项目,Linux,以及一切。真的太多了,太多了。而且你知道吗,即使在开源之外,也要赞美那些创造出你经常使用、而且热爱的软件的公司。
- 基兰:赞美人的事业。赞美人类的努力,不只是做出一个还可以的东西,而是做出一个真正非常好的东西。
- 让-巴蒂斯特:是的,这很重要。因为就像我们说的,我们做技术,是在为普通人做非常复杂的事情。我们希望自己在技术上的卓越能对每个人有用。这就是我们工作的原因。我早上醒来的原因,就是希望人们使用我们的东西,因为它让每个人的生活更容易。
- 莱克斯:想解决难题。做有意思的东西,处理一些有意思的技术挑战。
- 让-巴蒂斯特:作为工程师,我们喜欢构建东西。很小的时候,我就知道我想构建东西,想成为工程师。我想做汽车。也许某一天我还会回去做汽车。但本质上就是这样:我们想做又酷又有用的东西。而且它们需要有挑战,因为你希望自己的大脑被点亮。
- 莱克斯:你们两个人第一次爱上编程、构建和工程是什么时候?
- 让-巴蒂斯特:基兰,你第一次编程是什么时候?
- 基兰:Microsoft QBasic。当时我用的是 Windows 3.1 和 Windows 95 上的 Microsoft QBasic。
- 莱克斯:哇。哇。你做了什么?
- 基兰:呃,像乘法,或者只是数循环,比如 10、20、30、40。
- 莱克斯:不错。
- 基兰:然后我就觉得自己什么都能做了。我从那一步直接跳到“我要做一个 soccer,不,football,足球视频游戏”。我把所有东西都画出来了,心想:“我要做出来。”但我当时没有真正理解,从 BASIC 和画几张图跳到一款视频游戏,其实是一个巨大的工程。不过就是这样。
- 让-巴蒂斯特:对。我好像也是 BASIC,然后是 Turbo Pascal,那应该是在小学快结束的时候。但我第一次真正认真编程,是在你们叫中学的第一年,也就是 11 岁的时候?我当时在意大利佛罗伦萨住了一年,那是很棒的一年。数学老师让我们用一种叫 Logo 的编程语言,里面有一只小海龟,会在屏幕上画东西,你可以让它左转右转。到最后,我们用它做了非常复杂的编程,因为当然,你可以做很多事。那件事改变了我,因为我那时就知道,我想用计算机做东西,想编程。
- 莱克斯:我觉得我们还没有真正好好聊 H.264。我们聊过 dav1d。我们能不能回到——
- 嘉宾:当然。
- 莱克斯:——稍微回到 H.264,回到这个基本上支撑了互联网上所有视频的东西?所以,你能讲讲 H.264 的故事吗?基兰,你实际上也是贡献者——
- 基兰:对,x264。x264 是 H.264 视频标准的一个视频编码器。它主导了互联网视频,也主导了其他领域,比如 Blu-ray 光盘。Blu-ray 光盘很有意思,因为做这些碟的人真的想要最高质量。有一些非常酷的高端电影,用它编码后用于播出和各种其他场景。H.264 是一次巨大的跃迁,因为它也刚好出现在正确的时间。很多开发发生在 HD 视频出现的时候,Intel Core 2 和 Nehalem CPU 也变快了,你可以做实时视频。但最重要的是,它把重点放在视觉指标上。在此之前 20 年里,产业界和学术界一直迷恋数学指标,也就是所谓的峰值信噪比。也就是均方误差、均方误差的对数。那带来了大量问题,因为均方误差会导致模糊:你为了最小化它,会倾向于给所有地方都加一点点误差,而不是让某个地方出现一个大误差,结果就是大量模糊。但爱好者们逆着这个趋势走。他们是为了自己的个人视频,主要是 anime。于是他们做了两件不同的事,而且和社区之间有一个很大的迭代反馈循环。他们确实做了一些不一样的东西。两个大的东西,一个是心理视觉率失真,也就是利用块能量,在做决策时试图补偿人类感知。
- 莱克斯:所以心理视觉失真就是关键的东西。就是它。我是说,这有点革命性,因为我们可以重新思考。不要把压缩做成那种纯理论的东西,而是让它完全围绕——
- 基兰:让眼睛看起来舒服。
- 莱克斯:对,对。也就是用一种方式压缩,让对我们人类重要的东西损失最少的信息。
- 基兰:没错。与此相反的是产业界的做法,有些产业界的人到现在还迷恋这个,也就是那些现实里看起来并不好看的数学数字。另一个大的东西是自适应量化,它会相对于复杂区域调整比特分配,并把比特重新分配到草地这类没那么复杂的区域。草地有一些高频,但整体上和更复杂的东西相比,它并没有那么复杂。这是围绕 ParkJoy 发展出来的。所以 ParkJoy 真的是一个经典样片,就是在公园里奔跑的那段。
- 莱克斯:这个。
- 基兰:对。这个样片真的很关键。它是瑞典电视台在 HD 初期制作的,用胶片拍摄,在制作质量上不惜成本,而且免费开放。它真的很重要。这个样片能看出真功夫,因为里面有树、水、草、运动,还有各种挑战。我觉得直到今天,公开测试序列里也没有比它更好的。
- 莱克斯:给只是在听的人说明一下,我们现在看到的是一群人沿着河跑,画面里有倒影,到处都是信息量很高的纹理,树叶、光线在树叶上的变化,所有这些东西。
- 基兰:你可以很清楚地看到,高 PSNR 的编码器——
- 莱克斯:会把一切都抹糊。
- 基兰:——会把一切都抹糊。而且你真的能看到,我打开心理视觉相关的东西,打开自适应量化,画面就会好看得多。但你的指标呢?这些指标当时被视为神圣不可侵犯。这些就是不可触碰的神圣指标。PSNR 是最重要的东西。
- 莱克斯:呃,你能讲讲怎样衡量心理视觉相关的东西吗?比如,怎样把一种压缩对人眼来说有多悦目,变成一个数字?这真的可能吗?
- 基兰:这就是 Netflix 一直尝试用 VMAF 做的事。他们说自己用了一个机器学习模型。
- 莱克斯:那是更近一些的事情。但回到 x264 开发的时候,基本上就是靠眼睛看——
- 基兰:就是靠眼睛看。开发者在自己的笔记本电脑上看。不是说有什么大公司,配着专业屏幕之类的。其实这也是目标之一。当时的开发者,尤其是 Loren Merritt,说过:“我不想在三万美元的屏幕上测试它。我希望它在某个人家里的笔记本电脑上看起来好。”
- 莱克斯:对。太精彩了。
- 让-巴蒂斯特:还有另一个样片,是《Planet Earth》的杀手级样片,我特别喜欢。你马上就会知道为什么。
- 基兰:对,你会喜欢这个的。
- 让-巴蒂斯特:呃,就是很多鸟在飞,而且越往后鸟越多,到最后几乎像是有几百万只鸟。这是有史以来最复杂的编码对象之一。然后你现在是在 YouTube 上看,所以你其实能看到 YouTube 的编码有多糟。这个样片非常适合用来优化,在恒定比特率下争取完美质量。很长时间里,Loren 也做了很多优化,主要是在 anime 上。很长一段时间,anime 的编码很差,因为有大量色带问题。你会看到这些问题,还有很多别的问题。所以 x264 就是这样。而且直到今天,它仍然是任何新编码器的参照对象,AV1、AV2、VVC、HEVC,所有人都会和 x264 比。
- 基兰:我最喜欢的电影之一是《天堂电影院》。我认识制作那张 Blu-ray 的工程师,他给我看过 x264 和其他方案的对比,结果完全不同。我觉得 Blu-ray 圈子里有一批人后来开始用 x264。大的例子应该是 Warner Brothers 的 Chris Henderson,他用它做了整套《危机边缘》套装。也就是说,这是普通人真的会观看、也希望它好看的东西。所以他们在自己的工作里其实冒了一点风险,因为他们在大公司。那种大公司想买什么都能买。但他们说:“不,不,不,我想用这个免费而开源的东西,这样我的客户看到的东西才会好看,才是最好的。”直到今天,我个人仍然尽量避免在流媒体服务上看最有电影感的影片,而会去买实体碟,因为它们看起来很好,甚至不需要买昂贵的电视。我觉得这是关键。
- 让-巴蒂斯特:而 x264 又是另一个开源项目的例子。它最初由 Laurent Ehrsam 在巴黎中央理工学院就读时启动,VLC 也是在那里诞生的。然后你有了一代人,比如 Loren、Jason、Måns,还有很多很多人——
- 基兰:Henrik 来自——
- 让-巴蒂斯特:Henrik,呃——
- 基兰:Anton,呃。
- 让-巴蒂斯特:——还有 Anton。这也就是我们现在在 FFmpeg、dav1d 等项目里使用的那套汇编传统诞生的地方。x264 是一个非常了不起的项目,参与者遍布全世界,而且我觉得他们中的大多数人从来没有见过彼此。
- 莱克斯:但按基兰的说法,他们所有人,或者很大一部分人,都喜欢日本动画。有几样东西我一直没能入门,其中一个就是日本动画,我得——
- 基兰:我看日本动画看得很多,尤其是在那个时候。那时很多日本动画内容并没有商业化供应,对吧?那是在 Crunchyroll 之前。所以通常会发生的事是,喜欢日本动画的人会从日本拿到一些 DVD,然后把它们翻录出来,因为没有商业发行。有些人,我们称之为粉丝字幕制作者,基本上会自己翻译、做字幕。当时你下载这些东西完全是非法的,但那是唯一的办法。所有这些东西都是手工制作的,而且很契合开源社区,因为他们需要工具来编码,需要工具来做粉丝字幕。字幕领域最了不起的开源项目之一叫 Aegisub,它是一个字幕工具,最初是为日本动画,以及亚洲语言和日语相关需求而做的。
- 基兰:日本动画里有一些奇怪的纹理,我觉得在真实拍摄内容里不会遇到。这是一个关键点,也就是要优化这些奇怪的纹理,因为日本动画不是用普通方式制作的。
- 让-巴蒂斯特:对。它的制作方式不一样。最近这些年,你基本上是在屏幕上制作它,对吧?里面有很多颜色渐变,因为这些渐变用数字方式很容易做出来,但在真实世界里非常复杂。字幕也很复杂,因为你经常既需要日语,又需要变音符号,对吧?还有我们所说的 ruby,也就是给汉字标注的平假名和片假名。除此之外,你当然有官方字幕,但你还需要英文字幕或者法文字幕,因为你想学习那些内容。字幕里有太多疯狂的东西,我们也见过各种疯狂的字幕样本。所以这是文化中很重要的一部分,也是因为当时没有官方供应,没有别的办法。
- 莱克斯:呃,你能讲讲 H.264 和 AV1 的区别,以及 x264 和 dav1d 的区别吗?这是很大的一步。你能不能帮大家理解一下,某些流媒体网站是不是正在更多地往 AV1 这个方向走?
- 让-巴蒂斯特:说实话,从 MPEG-2 video 以来,所有这些编解码器用的都是同一套概念。反变换、帧内预测、运动补偿、熵编码,都是这些概念。不过每一代都会在同等质量下带来 25% 到 50% 的压缩提升。所以你有 MPEG-2,有 DivX 时代,有 H.264,它改变了很多。H.264 提升非常大。然后又有了更多东西。你有 HEVC,也有和 HEVC 同期的 VP9。VP9 在压缩质量上有点类似 HEVC,但它是免版税的。因为多媒体领域有大量专利,而 H.264 之后的许可问题变得失控了,每年可能要花数亿美元。所以那没有意义。于是 Google 做了 VP9,开放媒体联盟做了一个叫 AV1 的新编解码器。你可以这样理解:在相同视觉质量下,AV1 比 H.264 可以少用 40% 到 60% 的带宽。
- 莱克斯:在给定比特率下。
- 让-巴蒂斯特:在给定比特率下,对。也就是说,你要么固定比特率并提高质量,要么固定质量并降低比特率。但因为现在我们从 SD 到 HD,从 HD 到 4K,再从 4K 到 4K HDR,数据规模会增加两倍、三倍、四倍。所以你需要更好的压缩,才能让它保持在可管理的范围内。
- 基兰:它有更多编码工具、更大的块,每个块里有更多子分区。复杂度就是指数级上升。
- 让-巴蒂斯特:它更复杂,是因为编码器需要搜索更多可能性。举一个容易理解的例子,要用一个块去预测另一个颜色块,你会有方向,对吧?你可以向左、向右、向下、向上,然后还有其他象限,也就是我所说的北、东北、西北等等。那是八个方向。然后你可以有更多方向,16 个、69 个或者 128 个。每一次,你的编码器都要花更多时间去看:哦,这个块正好是这个方向,这些工具也可以拿来用。编码器需要检查哪些工具能让你压缩得更好。所以我猜 AV1 编码在 CPU 周期上比 H.264 多两个数量级。数量级,对吧?
- 基兰:对。而且就像我们讨论过的,CPU 并没有变得更快。你只是往这个问题上堆更多核心。
- 让-巴蒂斯特:但还有一个事实是,你只编码一次,然后会有数亿用户观看。比如 YouTube 就是很好的例子。YouTube 几乎所有东西都会用 H.264 编码,但热门视频会被重新编码成 AV1,因为编码当然更贵,但你只编码一次,然后把它发送给几百万人。这就是编码时间和复杂度、服务器端 CPU 使用量、客户端 CPU 使用量之间的权衡。因为最后,如果你把一个视频分发给几十万人,而它的大小只有另一种方案的一半,那就更好。对你的电池更好,对你的 modem 更好,等等等等。
- 莱克斯:所以我们可以列一下,比如前五种编解码器和容器组合:MP4 容器里的 H.264,MP4 或 WebM 容器里的 AV1,用于非线性编辑的 ProRes,放在 MOV 容器里。对于不了解的人来说,我猜 ProRes 是——
- 基兰:它是 Apple 的编辑用编解码器,最初是为 Final Cut Pro 做的。它设计成解码很快、定位很快,因为剪辑师需要非常快速地移动。所以它和分发场景是不同的用例。
- 莱克斯:它没有,或者只有非常少的时间压缩,对吧,在——
- 基兰:没有,对,ProRes 里没有。所以你可以剪切,可以做剪辑。
- 让-巴蒂斯特:这就是我们所说的纯帧内编解码器。那我来快速解释一下什么是 IPB 帧。
- 莱克斯:请讲。
- 让-巴蒂斯特:I 帧通常也叫关键帧,但它是完整帧。它就像一张图像,像 JPEG。你有了它,就可以从这里开始,看到全部内容。然后下一张图像可以是 P 帧,也就是预测帧。你会取前一张图像里的某些部分,比如说:“好,我需要第 5 块、第 7 块和第 42 块。”然后替换它,再只给出额外的信息。但这意味着,为了解码这个 P 帧,你需要访问之前的某个 I 帧。当然,还有更复杂的 B 帧,也就是双向预测帧,它可以依赖不同类型的帧,有些在过去,有些在未来。所以 ProRes 是纯帧内编解码器。对于能看到画面的人来说,这就是——
- 嘉宾:对,这是个很好的例子。
- 嘉宾:……非常好的例子,对吧?所以 I 帧是完整帧。嗯,P 帧基本上只依赖 I 帧,而 B 帧可以依赖前面的帧。
- 莱克斯:而这个 GOP,也就是图像组,我记得 FFmpeg 对 H.264 的默认值好像是 250 帧左右,差不多这样。
- 嘉宾:对。
- 莱克斯:对我来说,这简直像魔法一样:你竟然可以预测,竟然可以每隔……
- 嘉宾:隔几秒才有一帧,也就是说。
- 莱克斯:……隔几秒才有一帧完整帧,然后中间仍然可以靠一串预测撑起来。像我这样的人能用 FFmpeg 压缩一个东西,而压缩后的结果播放起来仍然流畅到我察觉不到,这真的像魔法。
- 让-巴蒂斯特:你甚至还可以有一种东西,我们在 Kyber 里大量使用,叫 intra-refresh,也就是帧内刷新。基本上它里面没有 I 帧。
- 让-巴蒂斯特:不是完全没有 I……开头有一个。然后你再也不发送 I 帧。你得到的是一种……
- 莱克斯:这是怎么工作的?它到底是什么?
- 让-巴蒂斯特:随着流不断往前走,你逐步把一帧 I 帧构建出来,所以……
- 莱克斯:啊,所以你是在刷新图像的某些部分……
- 让-巴蒂斯特:对。所以你从来没有真正的一整帧 I 帧。这就是我们用的 intra-refresh,对吧?
- 莱克斯:这甚至更聪明。
- 让-巴蒂斯特:但对我来说,我刚开始接触时最震撼的是 B 帧。B 帧,也就是双向预测帧,可以依赖未来才会出现的帧。这意味着,为了解码这一帧 B 帧,你需要等下一帧,也就是它依赖的那一帧……
- 嘉宾:对。
- 让-巴蒂斯特:……把那一帧缓存起来,先解码它,这样你才能解码 B 帧,对吧?所以你解码帧的方式,也就是解码顺序,和显示顺序并不一样。对吧?这意味着编码器必须非常聪明,要决定:“好吧,我要依赖未来的东西。”所以这就像……
- 莱克斯:太不可思议了。
- 让-巴蒂斯特:……太震撼了。
- 基兰:它每天都能这么流畅地工作,这件事从某种意义上说挺奇迹的。它运转得如此……你可以有一条流,在世界各地不同厂商的解码器上播放,在美国的一个解码器上、在这里的另一个解码器上播放,结果逐比特生成完全相同的素材。这相当了不起。它们还在做非常复杂的事情,而且复杂度越来越高,却仍然能做到逐比特精确。背后有大量工作。
- 莱克斯:整个过程中有很多旋钮可以调。FFmpeg 给你完整开放了很多非常迷人的参数,这些年我也越来越了解它们。也许你们可以讲讲其中一些。首先很显然,我们可以降低分辨率,可以降低帧率,可以使用不同类型的编解码器,就像我们提到的,从 H.264 到 AV1。也可以调节码率和质量之间的取舍,前面我们也说过。比如可以用恒定码率,也可以用恒定质量,比如 CRF、QP。还可以使用更长或更短的 GOP,也就是我们提到的图像组。诸如此类,太疯狂了。还有 B 帧的数量。
- 让-巴蒂斯特:对。疯狂之处在于,有大量人的工作就是优化这些参数,对吧?你在 YouTube、Netflix、Meta 等公司看到的很多人,他们并不是在写编解码器。他们只是在为手头的文件、手头的格式寻找合适的参数,对吧?因为电影、手机拍出来的用户生成内容、屏幕录制,或者你要拿去做视频剪辑的素材,它们需要的东西并不一样。有成千上万人的工作,就是优化这一整套东西。
- 基兰:对,他们都是巫师。向他们致敬。嗯,YouTube,还有其实所有流媒体网站,要做到大规模分发。YouTube 特别像魔法,因为它不只是做 Netflix 那种单向广播式的事情。它还必须接收来自各个地方上传的视频。所以他们也在大规模做编码……哪怕那个视频最后可能只有五个人看。它仍然必须几乎随时就能把视频送出来,不能有延迟,什么都不能有。也不是完全没有……但延迟非常低。而且还要以各种不同分辨率提供。YouTube 基本上就是网页版 VLC。
- 让-巴蒂斯特:对。其实这挺有意思,因为 Google Video,也就是 Google 收购 YouTube 之前做的那个产品,实际上用过 VLC 插件。你可以通过 ActiveX 插件在网页浏览器里运行 VLC。所以它能在 Internet Explorer 里工作,你实际上是在浏览器里运行 VLC。这很有趣,因为今天我们反过来了:现在有 VLC WebAssembly,我们把整个 VLC 和 FFmpeg 都编译进去,用 WebAssembly 在 JavaScript 虚拟机里解码、运行 VLC。
- 莱克斯:好,有个传奇故事是你指给我看的。它是通过 WikiLeaks 发布的 Vault 7 文件被发现的。CIA 用了一个修改版 VLC,基本上想诱骗人们,做什么?窃取他们的数据?
- 让-巴蒂斯特:对,正是这样。
- 莱克斯:那你能解释一下到底发生了什么吗?这是……
- 让-巴蒂斯特:所以,这件事当时是个惊讶,对吧?因为某个时候,WikiLeaks 提到了一些文件。其中有几个和 Blu-ray、VLC 有关,但最有意思的是 CIA Vault 7。如果我理解得没错,就是 CIA 有一个定制版 VLC,里面有一个特定插件。对,没错。这就是……我们当时还不得不为此写一份新闻稿。
- 莱克斯:嗯,VideoLAN 写了一份新闻稿,说获取 VLC media player 的唯一安全来源是 VideoLAN 官方网站。我想,这基本上是任何开源软件都会有的安全漏洞。有人可以骗你。
- 让-巴蒂斯特:骗你去一个假网站下载……或者通过定向广告,对吧?那就是定向广告:它告诉你,要观看某个特定文件,你需要用这个定制版 VLC。它其实是普通的 VLC 二进制文件,只是他们加了一个 DLL,我记得是 psapi.dll……它基本上会读取你的文档文件夹,加密后发出去。说实话,这件事很聪明,因为当你在看电影时,对吧,你会看两个小时,而且不会碰电脑。有时因为是 HD 视频,你的风扇转起来,“呼呼”地响,CPU 占用很高,这也很正常,因为你在用 VLC,对吧?这都正常。但问题是,你看不见的地方,其实运行的是 CIA 使用的一个增强版 VLC。我们也遇到过完全一样的问题,是中国黑客针对印度用户,最后导致 VLC 在印度被封禁,直到我不得不在印度法院和印度政府周旋,才让 VLC 解禁。他们并没有真正使用 VLC。他们只是拿了一个 DLL,因为我们正确签名了那个 DLL,然后他们用那个 DLL 去做另一个程序。所以你看到 vlc.exe 在调用 libVLC,但它其实调用进了一个假的东西。他们用这个来攻击目标。嗯,实际上我们很难阻止这类攻击。
- 莱克斯:对,我觉得对于所有开源软件,甚至所有软件来说,大家都应该注意自己到底是从哪里下载的。
- 让-巴蒂斯特:对,因为这意味着他们不是从我们的网站下载的。
- 莱克斯:搜索引擎会帮你们吗?
- 让-巴蒂斯特:不会。
- 莱克斯:我只是想澄清一下,因为为了防止有人操纵 SEO,把链接顶上去,然后试图……
- 让-巴蒂斯特:完全不会,对吧?我们有一个持续了十多年的大问题:德国有一个假的 VLC 版本,到现在已经被举报 12 年了,而 Google 基本上决定不处理。他们知道里面有什么,但那个二进制文件对他们的病毒分析器来说太大了,分析不了。所以如果你人在德国,可以访问一个假冒 VLC 的网站,它带有一个定制安装器,而且在德国非常流行,因为它的网站是德语,Google 还把它排在 VideoLAN 前面。最奇怪的是,它会在你的机器上三周什么都不做。因为他们就是这样躲检测的。三周后,一个同时安装的小程序服务会醒来,开始下载间谍软件和广告软件。Google 知道这件事,但他们决定什么也不做。那些人有一段时间在德国用暗黑 SEO 做这件事。这伤害很大,对吧?因为它们下载的东西里,有一种实际上会替换你机器里的广告,对吧?
- 莱克斯:这其实出乎意料地有效。不管是谁在 Twitter 和 X 上这么做。就 X 而言,我会收到一些邮件,说“你的 X 账号被黑了”。不管他们怎么措辞,它至少会让我点开邮件,当然不会继续按它说的做。然后你会想:“天啊,他们用这些心理手段来骗你,还真挺厉害。”
- 让-巴蒂斯特:也会有一个所谓 VLC 安全版本,对吧?你收到一封邮件说:“嘿,VLC 有一个安全版本更新。现在就更新吧,因为……它可能会入侵你的电脑。”你点进去。网站看起来还不错,然后你下载了。一个新版 VLC。太好了。你并不知道发生了什么。一个月后,你被黑了。你完全不知道。你已经成了 botnet 的一部分。
- 莱克斯:对。所以无论你在哪里下载东西,都要确认它是合法来源。我已经是 botnet 的一部分了。说到这个,你提到过 VLC sandboxing,也就是 VLC 沙盒化,是你们正在做的事情,而且这其实相当有挑战。为什么它重要?为什么它困难?
- 让-巴蒂斯特:VLC 是一个核心加大约 500 个插件,对吧?其中一个就是 FFmpeg,但我们还支持很多其他格式。我们支持新协议,支持新滤镜,支持奇怪的架构。在这个版本的 VLC 里,有些模块会调用你的驱动,对吧?主要是硬件解码器,它们会调用你的 Intel、NVIDIA、AMD 驱动。还有调用 FFmpeg,对吧?这里可能有安全问题。shader 里可能有安全问题,VLC 里可能有安全问题,FFmpeg 里也可能有安全问题,最后基本上会崩溃。问题是你运行 VLC,就像运行任何其他程序,比如 Adobe 一样,对吧?它运行在你的机器上,并且能访问你所有文档,对吧?所以我们的想法是一定要做沙盒,让我们能防住自己,因为 VLC 进程里跑着一些甚至不是我们的代码。要么是我们集成进 VLC 的其他开源项目代码,要么是你的 GPU 驱动,或者某个其他人提供的东西在里面。所以当我们崩溃时,我们希望不要让别人借机做坏事,对吧?黑客攻击人的常见方式之一,就是让一个程序崩溃。这通常发生在网页浏览器里,也常发生在 PDF 文件里,多媒体里少一些,但也可能发生。当它崩溃时,就会在用户机器上启动某个东西。可能是勒索软件,可能是 botnet,对吧?所以桌面应用的安全很重要。在移动端,情况稍微不一样,因为大多数移动应用都运行在自己的沙盒里。但对于 VLC,我们当然可以把它放进一个沙盒运行,问题是我们需要访问太多东西,以至于基本上会把所有权限都要过来,对吧?如果你有一个沙盒,却到处打洞,那就失去了意义,对吧?所以我们正在尝试、也确实已经在做的是,把 VLC 拆成多个进程。一个负责解码,一个负责解复用,一个负责滤镜,它们都运行在各自的沙盒里。这样如果整个 VLC 的某一部分崩溃,就像 Chrome 某个标签页崩溃一样,对吧?它会崩溃,但不会让整个程序崩掉。这就是我们想做的。而难点在于,这个沙盒需要承受每秒数 Gb 的内存拷贝……它不是一个 5 MB 或 10 MB 的网站。我们说的是每秒数百 Mb。所以这就是它很有挑战的原因。这也是我们正在研究的课题:怎样做出安全的多媒体播放器。
- 莱克斯:当有数百万人在使用时,这些都是你必须考虑的事情。你曾经在某个地方提到过 VLC 的各种功能:当使用人数多到这种程度,真的会有人用到每一个功能,而且他们会告诉你。
- 让-巴蒂斯特:VLC 里最好的功能叫拼图滤镜,对吧?你点一下拼图滤镜,它就会把你的视频变成拼图,对吧?
- 莱克斯:不错。
- 让-巴蒂斯特:然后你可以点击、移动那些拼图块,对吧?当你在看法国电影时,这非常非常有用,对吧?你会无聊……因为那类电影通常特别长,或者又是一个三角恋故事,对吧?我们已经看过太多次了,对吧?但是你还是得看,因为有人,你的妻子或者……
- 莱克斯:为了补课。
- 让-巴蒂斯特:……或者你的男朋友让你看。所以你就在看,对吧?然后你可以点击并把那些拼图块挪来挪去。它绝对没用,对吧?谁会在乎这个?最早这是法国南部一位高中数学老师写的,用来教学生 Bézier 曲线,而这是每个人都应该了解的东西,对吧?它很有用。但代码很干净,所以就进了 VLC。它是在 2010 年合并的。五年后,我收到一封邮件,说:“你好,JB。我使用 VLC 时遇到一个问题。这个拼图太简单了。”我当时就:“什么?”是的,当时 UI 里拼图最多只能到 16 乘 16,对吧?只有 256 块。然后他说:“不好意思,但我看电影时喜欢拼图,这个太简单了。”对吧?所以有一个我提交的 commit,你可以在网上查到,是 JB 把维度改成了 256 乘 256。
- 莱克斯:对。
- 让-巴蒂斯特:但我的意思是,很多没人用的功能,其实也会被少数人使用,对吧?有一种方法可以在命令行里看 VLC 电影,不需要任何 UI,对吧?它是……
- 莱克斯:我看到了。你可以用 ASCII。
- 让-巴蒂斯特:ASCII art。它有用吗?非常有用。想象一下你在调试……想象你在调试一个组播网络,对吧?你有成千上万个非常复杂、非常复杂的网络栈,对吧?你可以 SSH 到所有路由器上,在没有 UI 的情况下运行 VLC,然后你能看到画面是不是黑的,对吧?所以你能看到它是不是全绿,或者是不是不全绿,对吧?所以你可以看出……
- 莱克斯:太棒了。
- 让-巴蒂斯特:对吧。
- 莱克斯:这很有意思。
- 让-巴蒂斯特:人们没有意识到 VLC 里有这么多东西,它们是有用的,而且确实有用户。因为一旦你有数亿用户,就会有人使用每一个功能。
- 莱克斯:我想稍微放大一点,更多谈谈下载一个文件并离线观看,与流媒体播放之间的区别。也就是流媒体的复杂性和挑战。关于流式传输文件到底需要什么,我们能不能说点什么?因为我们一直在谈编解码器……我觉得其中很多内容都暗含了编码和解码,但不需要通过网络通信……
- 嘉宾:当然。
- 莱克斯:当然。所以你能展开讲讲吗?要做网络相关的事情,需要什么?
- 让-巴蒂斯特:可以。但和我们前面谈过的所有东西相比,它其实没有看起来那么复杂。尤其是因为最复杂的事情,并不是今天流媒体服务意义上的 streaming,而是当年真正通过卫星广播时做的那些事情。因为在大多数现代广播服务里,你可以暂停,然后继续播放。但当你发送直播流时,不管是广播式直播,还是流媒体服务里的直播,这要困难得多,因为你需要实时编码。当你走卫星链路时,链路有一个固定大小,对吧?哪怕一秒钟,你也不能有带宽突发,对吧?因为你的总文件里没有这种空间。不过,这里确实有不同类型的挑战,也很有意思,但我认为它们没有 90 年代末和 2000 年代初那种围绕卫星广播和流媒体的挑战复杂。
- 基兰:它们不一样。它们是控制系统方面的挑战,而另一些更偏数学。我觉得区别就在这里。
- 让-巴蒂斯特:在流媒体世界里,你会遇到所谓 adaptive streaming,也就是自适应流媒体。因为困难在于……而这并不真是一个视频问题,更多是 CDN 问题:可能有太多人同时观看同一个东西,网络就会拥塞,对吧?所以播放器很难足够快地下载内容来播放。于是本地播放器会读取较低分辨率的版本……当然有一些非常聪明的算法来做这件事,但老实说,大部分其实相当基础。
- 莱克斯:甚至在缓冲这边,也挺基础。
- 让-巴蒂斯特:对。你开始下载一个 segment,也就是我们说的分片,然后计时,对吧?如果下载一个分片花掉的时间超过这个分片时长的 50%,你就往下降……对吧。更难的是,你什么时候把带宽和质量升上去。但这并不是特别复杂。编码时,你会编码出七种分辨率,对吧?然后给出码率。难点是让你的编码器给出相同码率,但它不像过去那么严格了。所以……
- 莱克斯:嗯,YouTube 大概还得弄清楚人的心理那一面:比如码率很低的时候,你会多生气?连接已经变好了,它应该等多久再提高码率?因为也许码率的变化本身,才是会在心理上影响你的东西。
- 基兰:不,我觉得真正有意思的是音频。
- 莱克斯:确实。
- 基兰:你能隐约注意到它们从完整规格 AAC 切到使用 Spectral Band Replication 的压缩版 AAC。你会感觉声音有点发薄,而这种上下切换非常刺耳。视频那边平滑得多,不那么容易注意到。真正是音频,你绝对能感觉到它把你从一个音频 profile 切到了另一个。我不知道。我们对跳过音频故障的容忍度出奇地高。我很惊讶,我认识的那些不是视频工程师的人,竟然那么能忍,能忍受用 30 FPS 看体育比赛,而它其实应该是 60 FPS。世界对这类事情宽容得多。但音频方面,人非常……它有一个即时反馈机制:“哦,有东西变了。”
- 莱克斯:如果你听到一个 glitch,你会立刻意识到。我想我现在越来越充分地意识到这一点。我越来越多听音频时害怕的一件事,是我会注意到每一个微小细节,然后过度执着;而一般人其实能够某种程度上模糊地消费内容。他们能越过某些瑕疵继续看或听。
- 让-巴蒂斯特:但如果你把一个事件组合起来,比如一场体育赛事,它可能要经过卫星,或者……经过别的地方,再到一个中心点进行编码,然后你需要实时编码所有这些分辨率。你没有时间做 QA。你需要把它推送到 CDN。你可能还要加 DRM 做保护。你需要让它跑在大量不同设备上。那确实很复杂。而且你还可能是在网页浏览器里,或者在许多非常不同的电视设备上;不像过去电视里有一个定义好的机顶盒或有线电视盒,你知道那是什么,并且能端到端控制。所以这是挑战,但它没有那么……我觉得只要你接受 10 到 20 秒延迟,网络部分并不是很难。
- 莱克斯:说到网络和延迟,你的新项目,也就是我们提到的 Kyber,目标是超低延迟。就像你说的,每一毫秒都重要。你把它应用在远程控制机器上,比如机器人、无人机、计算机。你能讲讲它吗?
- 让-巴蒂斯特:当然。如果从我们过去的位置说起,对吧?过去你会用 FFmpeg 来编码文件,对吧?然后我们用 FFmpeg 和 VLC 来为流媒体服务编码,对吧?接着你需要把延迟压得越来越低。问题是,我们最多能做到哪里?这个问题非常重要,因为有很多用例要求你必须很快,也就是存在反馈交互的时候,对吧?我们不只是听某个东西,你实际上是在控制它,对吧?因为……和我们之前做过的事情相比,最大的区别在于,我需要视频来反馈某个正在实时发生的事情。不管是无人机在飞,还是远程控制一个人形机器人,还是控制一个 hover 设备,还是在云游戏里玩视频游戏。因为这就是我上一份工作做过的事情,对吧?我曾是一家云游戏创业公司的 CTO。这是一个非常有意思的主题,因为你把网络推到了极限。你需要关心的不是我们在视频里讨论、在 H.264 里讨论的那种质量,而是延迟。因为当你控制一辆车时,一毫秒都有意义,对吧?嗯,你见过也用过 Waymo,对吧?当 Waymo 无法正常工作时,即便这种情况只有 1%,也会有一个人基本上在远程控制它。而这正是我们正在构建的东西。它其实是一个 SDK 平台,用来做机器的端到端控制。
- 莱克斯:所以这件事在机器人领域的很多不同语境里都会出现。显然,teleoperation,也就是远程操作,正变得越来越重要,包括用机器学习训练机器人。
- 让-巴蒂斯特:对。我们做的事情和其他人有点不同:我们只用一个 socket,一个连接,也就是一个基于 UDP 的 QUIC 协议。它很有意思,因为它就是为低延迟设计的。它没有我们所说的 TCP 队头阻塞问题,也没有 HTTP 队头阻塞问题。它默认加密,但在同一条线路上,我们发送多个流,也就是多个轨道。我们发送音频,发送视频,也发送命令,对吧?鼠标、键盘、手柄等等。我们在保持一致性的同时做这些,也就是保持同步。因为人们没有意识到,所有时钟实际上都会漂移。当你控制一个机器人时,一个机器人可能有两台摄像机、五台摄像机、十台摄像机,还有大量传感器、GPS 等等。如果你想正确训练你的机器人 AI 模型,你需要让这些数据同步并且保持当前状态。我们所做的,以及我们从 VLC 的实时广播、从 Kieran 很熟悉的 MPEG-TS 里学到的所有东西,就是把时钟漂移考虑进去。所以当我录制一条 Kyber 流、录制一个机器人时,我能确定它在回放方式上是可预测的。因此当你要录制并训练 AI 模型时,你必须确保每次基于数据重新训练时,数据都会保持一致。时钟确实会漂移。现有方案用一台摄像机时可以工作;一旦你上到五台或六台,就复杂多了。
- 莱克斯:嗯,所以你想确保那个视觉快照,和它实际发生的时间完全匹配。
- 让-巴蒂斯特:没错。而且,如果你要控制,对吧,我对机器人做了某个操作,我需要确定它确实发生在那个精确时刻,对吧?所以在服务器端,也就是机器人端,我们有一个类似重新打时间戳的机制,会把时钟漂移计算进去,对吧?这是 Kyber 的一个用例,用来控制机器人。嗯,我也想到远程无人机,不管是国防还是非国防场景,还有远程汽车、远程潜艇。工业里有很多地方,或者远程手术里,专家无法到达机器所在的每个地方,因为那里要么危险,要么成本太高,对吧?所以你让人们身边有机器,对吧?Kyber 的目标是让距离消失,因为它要么是技能的投射,要么是力量的投射,对吧?想象一下我们都像……你看过 Meta Ray-Ban,还有其他人的设备,对吧?你需要在那里做流式传输,对吧?因为你不可能在那上面运行任何东西,对吧?所以你需要 GPU 算力,不管是在云端还是在手机上,用来把内容流式传过去。所有这些用例关注的不是极端低延迟,而是视频的实时延迟。所以这意味着我们需要……我们会摆弄编码器,让编码器在 4 毫秒内编码一帧。而且 Kieran 和他的公司也会做到这种级别的延迟,因为你需要把本地延迟优化到极限,对吧?因为这里有解码器、编码器等等。因为这段时间会叠加到你的网络时间上。所以……它不只是低延迟,还关乎可靠性。我们会做一些聪明的事情,比如 forward error correction,也就是前向纠错,对吧?前向纠错就是你多传一点数据,对吧,多传几个百分点;通过多传,你就允许丢失一些包。因为在互联网网络上做这些非常困难,你会跨越很远的距离。如果你检查所有包是否都送达了,就会增加大量延迟。如果你不想要延迟,我们的做法是多传一些数据,当客户端有东西损坏时,可以在客户端重构出来,对吧?所以……几天、几周前,我们在 CES 期间围绕拉斯维加斯做演示。我们有一辆完全 3D 打印的 rover。它很简单,就是一辆车,对吧?一辆带伸缩臂的小车,而且它实际上是从法国被控制的,对吧?视频来自一个 webcam 和一个很小的 server,对吧?一块小小的 PCB 基本上就在运行,并把数据发给地球另一端的人。所以这里有非常多用例。你也可以想象让 AI 去控制很多无人机等等。从技术上说,我们需要在视频上做到非常出色,需要在网络上做到非常出色,需要关心网络、编码时间、解码时间里的每一毫秒,而且还需要做非常底层的集成。
- 莱克斯:所以要把所有东西很好地同步起来。但具体怎么做到呢?你能把延迟做到什么程度?你说毫秒级的时候,目标到底是什么?
- 让-巴蒂斯特:我的目标是 4 毫秒的 glass-to-glass 延迟。
- 莱克斯:glass-to-glass 是什么意思?
- 让-巴蒂斯特:其实很简单。你有一台电脑在运行一个程序,可能是一款电子游戏,而这个程序确实正在运行。它也可以是一个机器人的例子。然后你通过网络复制这一切。你希望如果拿一台 1000 Hz 的摄像机拍一张照片,这个过程能在 4 毫秒内完成。4 毫秒意味着 240 Hz,对吧?
- 莱克斯:对。太疯狂了。
- 让-巴蒂斯特:目前我们从 Windows 到 Windows,或者从 Windows 到 Mac,已经做到 7 毫秒。如果你看时间分布,大部分大概是 NVIDIA 硬件编码器内部 3.5 毫秒左右,Intel 解码器上大概 2 毫秒。也就是说,编码器加解码器已经是 6 毫秒了。要继续降下去,我们要么需要别的编解码器,要么需要更快、更好的编码器。但 4 毫秒会是圣杯。
- 莱克斯:这真的很疯狂。不过我很喜欢。我觉得以前还没人做到过,对吧?这太快了。
- 让-巴蒂斯特:用定制硬件可以做到,比如 SDI,或者专业硬件。但我希望它能在互联网上工作。我希望它能适用于任何机器人,比如里面只有一个小小的 Jetson Nano 或者 N150。因为未来会有数百万台机器人,或者无人机,说到底就是会滚动的机器人、会飞的机器人、会游泳的机器人。它就是一台由你控制的机器。你要么需要远程操作它们;等一切完全自动化之后,你也需要远程观察它们,检查正在发生什么。在我看来,未来所有这些远程汽车都会由一个 AI 模型来远程观察,它只会说:“一切正常。”一旦不正常,它就说:“嘿,这里有问题。”然后再让一名操作员介入。这关乎安全。当你有一个人形机器人照顾你的奶奶或者我的奶奶时,我想确保一切顺利,而不是陷入那种机器人变得危险的可怕场景。或者当我开车时,我希望车该停的时候就停;如果需要,就有人来处理。所以关于实时性的场景太多了。Kyber 的目标就是让机器的实时控制成为可能,让距离消失。
- 莱克斯:太不可思议了。而且我们正在讨论的某些同类技术、同类想法,也和你正在做的事情连在一起。
- 让-巴蒂斯特:对我来说,这挑战大得惊人。视频方面我会说自己还做得不错,但网络方面我还有太多东西要学,比如拥塞协议、实时码率自适应。不过这也挺有意思。所以我创建了这个项目,当然也在美国融了资。但它是开源的。这一点很重要,我们还没有说过:Kyber 的一切都是开源的。
- 莱克斯:那你怎么赚钱?
- 让-巴蒂斯特:它是双许可证,商业许可和 AGPL。你还记得前面说过许可证的事吧。基本上,如果你想在自己的产品里使用 Kyber,你的整个产品就必须开源。如果你想使用这项很棒的技术,但不想开源,那就购买商业许可。所以小团队、爱好者以及很小的开发者如果想做这件事,也可以使用这项技术,构建一些开源又有趣的东西。
- 莱克斯:这太棒了。
- 让-巴蒂斯特:如果你是一家大公司,你会得到支持、所有知识产权、修改权等等。所以是的,这真的很酷。而且我也在造机器人,我很喜欢。比如我们的 rover 是 3D 打印的。我们正在完成一个演示,那是一副真正的机翼,类似无人机机翼,也完全是 3D 打印的。我们还在尝试做一艘 3D 打印的帆船。之后还会做人形机器人。当然,它们不会是特别好的机器人,这不是我们的本职工作,但我们在这里是为了让每个人都能造机器人。很酷。
- 莱克斯:啊,那你找对人了。我爱机器人。楼上就有一堆。远程操作会非常非常重要,尤其是当机器人数量在全球范围内扩张时。完全同意。我们来聊聊多媒体的未来。FFmpeg、VLC,还有一些编解码器。我们还没有真正提到 AV2。能不能先说清楚,AV2 是什么?大家对它有什么期待?H.265、H.266 又是什么?
- 让-巴蒂斯特:AV1 是 Alliance for Open Media 做出来的编解码器,里面有 Google、Netflix、Amazon、Apple、VideoLAN。我们试图做一个免版税、质量很好的编解码器。现在它正在部署。但实际上,这个编解码器在 2018 年就完成了,只是一个编解码器要在广泛场景里被使用,需要很多年。AV2 就是这个编解码器的下一代。它好 30%。也就是说,如果保持相同画质,相比 AV1 可以减少 30% 的带宽。
- 莱克斯:它和 dav1d、AV2 之间是什么关系?
- 让-巴蒂斯特:我们会做一个 dav1d 2,我把它叫作 Devid,因为 deux 在法语里是“二”。
- 莱克斯:啊,漂亮。
- 让-巴蒂斯特:你还得知道,dav1d 其实是一个递归缩写。它的意思是:D,也就是 dav1d,是一个 AV1 decoder。
- 莱克斯:哦,不错。真不错。我甚至都没想到这个。大家也应该知道,dav1d 里面写的是数字 1。
- 让-巴蒂斯特:对。就是这样。所以 dav1d 2...
- 莱克斯:会用数字 2 来拼。请告诉我们。
- 让-巴蒂斯特:会写成 D-A-V-2-D。抱歉,我不知道该怎么发音。而且我们在 CES 上做过一个演示:VLC 运行了 AV2 的第一个演示。
- 莱克斯:你能不能给我解释一下 AV2 的规范,以及编码和解码?
- 让-巴蒂斯特:当然。规范就是一份文档,解释这个编解码器应该如何工作。
- 莱克斯:那才是真正的 AV2。
- 让-巴蒂斯特:那就是 AV2,就像 H.264 一样。然后你有编码器。当前的编码器叫 AVM,未来很可能还会有其他编码器,也许会有一个叫 SVT-AV2,它们就是编码器。就像 x264 是 H.264 的编码器,x265 是 H.265 编解码器的编码器。AV1 的解码器是 dav1d。AV2 的解码器是 dav1d2。H.264 的解码器是 FFmpeg 里的 ffh264。HEVC 的解码器是 FFmpeg 里的 ffhevc。MPEG 世界里,在 H.264、H.265 之后还有下一代编解码器,叫 H.266,也叫 VVC。
- 莱克斯:所以 HEVC 是 H.265,VVC 是 H.266。为什么 H.266 这么性感,这么好?
- 让-巴蒂斯特:我们经常遇到的一个问题是,为什么会有两个名字?因为大多数时候,这是 ISO 世界和 ITU,也就是国际电信联盟,联合工作的结果。
- 莱克斯:这是两个监管机构。
- 基兰:不是。一个是私人实体,一个是联合国机构。
- 莱克斯:哪个是私人的?
- 基兰:ISO 是私人的。
- 基兰:理论上,H.264 是 MPEG-4 Part 10,H.264/AVC。这是它的完整名称。
- 基兰:所以它是 ISO 名称和 ITU 名称的拼接,虽然他们是一起工作的。这是政治,也是历史,你懂的。
- 基兰:HEVC 的话,是 MPEG-H、H.265、HEVC。还有 H.266,也叫 VVC。
- 莱克斯:有没有一个高层次的说法,概括它们的改进?
- 基兰:每一代提升 30%,这是最好的总结。
- 莱克斯:这对 AV 系列编解码器,以及 H.264、H.265、H.266 都成立吗?
- 让-巴蒂斯特:正在听我们的专业人士可能会想杀了我们,因为他们会说:“不,是 35%,25%。”
- 莱克斯:“不,是 50,60。”
- 让-巴蒂斯特:对,“是 50%”,诸如此类。但总体上,你需要知道,HEVC 比 H.264 好 30%,H.266 比 H.265 好 30%,因为案例和场景太多了。比如有些场景,尤其是屏幕录制,收益巨大,因为它正好有为这种场景准备的工具。所以对某个具体视频来说,新一代可能带来 70% 或 80% 的收益。过去曾经有多得多的编解码器,但现在用于传输的两大主线,一条是 H.264、H.265、H.266,另一条是 AV1、AV2。
- 莱克斯:我猜主要区别会是编码成本。
- 基兰:对,还有专利版税。这也是你会看到 AV 这一系列编解码器的原因,因为它们试图尽可能免版税,也就是尽可能没有专利成本。你需要知道的是,虽然我们到现在还没谈到,多媒体就是我们所谓的专利雷区。专利最多的两个地方,一个是所有和 3G、4G、5G、RF 相关的东西,另一个就是多媒体。因为它非常数学化,你可以取得很大的收益等等。所以 Google、Meta、Netflix 想要一种免版税的东西。也有人说外面仍然有他们的专利,但那些是边缘专利。所以说它基本上无专利,大体是真的。
- 基兰:哦,你应该再展开一点。AV1、AV2 的标准化过程中会做专利检查,而在 MPEG 世界里,专利甚至不被讨论。专利完全是题外话。
- 莱克斯:你能给我讲讲专利这边的情况吗?
- 让-巴蒂斯特:通常是这样,MPEG 制定一种格式。然后所有人都围上来说:“好吧,我对这个格式拥有这些专利。”他们通常会组成一个联盟,叫 MPEG LA,也就是 MPEG Licensing Association。你把所有专利放进去,然后要求所有使用这个格式的人付费。
- 莱克斯:等等,能展开说说吗?拥有一个编解码器的专利是什么意思?为什么会有这么多专利?
- 让-巴蒂斯特:想象一下,我做一件事,不再用正方形的块,而是用矩形。
- 莱克斯:哦,所以每一个想法都会有人去申请专利。天啊。天啊。人类和他们的这些东西。到底养活了多少律师?
- 让-巴蒂斯特:我是说,这确实养活了很多律师。
- 让-巴蒂斯特:最大的问题还不是这个。因为在 H.264 的时代,专利可以说还算正常。但那里有太多钱了,以至于到了 HEVC,很多东西被塞进了规范里,其中很多在 99.9% 的情况下都没用,只是为了让某个人能给它加一个专利。所以 HEVC 授权变成了 MPEG LA 加上另一个叫 HEVC Advance 的专利池,再加上...
- 莱克斯:那个。
- 让-巴蒂斯特:还有,我想 Nokia 当时在专利池之外。
- 基兰:对,其中有几个在外面,还有另一些也是。
- 让-巴蒂斯特:所以它变得根本没法授权。我记得几个月前,HP 决定从他们的 Windows 笔记本里移除对 HEVC 的支持,因为这些专利的成本正在上涨。事情发展到了一个程度,而且还有不封顶的专利费用。对 YouTube 或 Netflix 来说,我们可能谈的是每年数亿美元的专利授权费。于是他们说:“你知道吗?每年一亿美元的话,我可以自己做一个编解码器。”他们确实这么做了。所以我们有了 Open Media alliance,也就是 Alliance for Open Media,我们也是其中一员。它创建了 AV1,也在创建 AV2。我们也创建音频编解码器。是的,主要区别就是这个。因为你需要绕开专利,或者做一些没有被专利覆盖的事情,所以很多东西都会不同。30 年前 MPEG-2 里做的那些基础东西,当然已经过了专利期。但比如 golden frame、S frame,或者不同类型的...
- 莱克斯:这些全都是被专利保护的想法。
- 基兰:对,不是,那就像“I can't believe it's not butter”。换句话说,就是“我真不敢相信这不是 B 帧”。某种意义上,它就是类似的东西。
- 莱克斯:哦,所以它是 B 帧的另一种变体。
- 基兰:对,就是为了试着绕开。类似这样的东西。
- 让-巴蒂斯特:所以你需要双重创造力。一方面要在效率上更有创造力,另一方面也要确保自己不侵犯现有专利。比如 VVC 拥有 HEVC 的所有专利,再加上新的专利。这就是为什么 AV2 试图尽可能免版税。
- 莱克斯:FFmpeg 和 VLC 在多大程度上需要考虑这类东西?
- 让-巴蒂斯特:我们不考虑。VLC 在法国的原因之一,就是法国拒绝软件专利。所以大多数这类专利在法国都是非法的。我曾经算过,如果我必须为 VLC 支付所有授权费,那么每个用户我要付超过 200 欧元,换成美元也差不多。但大多数这类专利在欧洲无效,因为它们基本上是数学专利或者思想专利,而这些在欧洲无效。
- 莱克斯:我想从高层次问一个纯好奇的问题。网上的梗,X 和 Twitter 这些地方的说法,再加上我自己也有一些欧洲朋友,大家的感觉是欧洲对创业不友好,监管过度,官僚主义太多,等等。有什么积极的东西可以说吗?欧洲未来的创业还有希望吗?
- 让-巴蒂斯特:有。
- 莱克斯:从科技角度看,欧洲是不是已经结束了?
- 基兰:看看我们两个就行了。这个播客里有两个来自欧洲大陆的人在谈视频,这件事本身就很说明问题。公平地说,这个社区的欧洲权重很高。
- 让-巴蒂斯特:你现在可能还没有看到的是,欧洲出现了新一代创业者,尤其是在法国。英国很早以前就做到了,因为它更像盎格鲁-撒克逊式的商业,重视商业。但特别是在法国发生的变化,当然有时候所有东西都被叫作 French Tech,多少有点过头,可今天进入市场的大多数人都想创建初创公司。15 年前不是这样。那时每个人都想去大公司工作。因为在法国,比如 20 年前、15 年前,如果你失败了,毁掉了自己的公司,而这对初创公司来说是正常的,你就不被允许再创办新公司。有很多污名。现在这种污名消失了。法国在 AI 等领域正在发生很多事情。当然,监管过度确实存在。我知道,我是创业者。但它也有一些好的方面。
- 莱克斯:我是说,有没有一些令人瘫痪的方面?比如我看一个和我关系变得很近的人,帕维尔·杜罗夫,他因为自己的所谓“平台”托管的内容,被法国政府直接归咎。我能想象同样的事情也可能发生,比如 VLC 因为人们正在观看的某类视频而被归咎。
- 让-巴蒂斯特:但他们确实试过。我们遇到过麻烦。
- 莱克斯:我的意思是,这就是人们担心的压力,因为如果你必须思考这种事,而你其实只是沉迷于...
- 让-巴蒂斯特:不,你不会去想它。这样也没问题。
- 莱克斯:但如果他们来了呢?如果他们真的出现,然后...
- 让-巴蒂斯特:没有办公室。VideoLAN 没有办公室。
- 莱克斯:我是说,帕维尔就是这样。他们逮捕了他,对吧?因为平台上分享的某些视频,或者某些特定内容逮捕了他。
- 让-巴蒂斯特:当然。但我没有任何平台。一切都在客户端。
- 莱克斯:是的,但他们仍然可以逮捕你。
- 让-巴蒂斯特:凭什么理由?我没有分享任何东西。内容也不经过我的东西。
- 莱克斯:当然,但仍然会有律师费。这才是问题。
- 让-巴蒂斯特:对,这没错。
- 莱克斯:是文书工作。也就是说,事实上,如果你有无限多、以万亿计的钱,你会轻松赢,因为你站在正确的一边。但问题是,他们可以在某种程度上用文书工作把你窒息掉。这就是官僚主义的坏处,通过文书、通过流程。你懂的,就是卡夫卡式的东西。
- 让-巴蒂斯特:你必须意识到,比如在法国或者欧洲大多数地方,一个好处是,回应法院命令不会让你破产。不像在美国,那真的可能让你破产。法律系统运作的方式是,我每周都会收到律师信。我可以告诉你,VideoLAN 每年的律师费用不到 1 万美元。所以这其实并不吓人。
- 莱克斯:我是说,和帕维尔类似。情报机构有没有试着说:“你能在 VLC 里放一个后门吗?”
- 让-巴蒂斯特:有。两个机构。
- 莱克斯:你怎么回答?
- 让-巴蒂斯特:不。不过我当时远没这么礼貌。
- 莱克斯:我懂。对,对。你基本上是在说:“绝不。”
- 让-巴蒂斯特:如果我们必须破坏自己的软件,我们就会把它关掉。这一点很明确。
- 莱克斯:那“破坏”怎么定义?比如允许某个政府放一个后门?
- 让-巴蒂斯特:没有任何我们无法控制的代码会进入 VLC。至于我们编译 VLC 的方式,你可能会说我完全偏执。我们在离线机器上编译,而且从编译编译器开始。我们在从未连接过互联网的地方离线完成一切。我们签名的方式也有双重签名。尤其是因为,比如我们见过一次,我们相信那是一个非西方世界的政府机构,试图把一个假的二进制文件推到我们自己的服务器里,这让我们非常害怕。VideoLAN 是开源的,你怎么杀死它?我搬到哪里去,对吧?我搬到马耳他。我搬到不知道哪里,开曼群岛,然后改个域名,重新开始。VLC 是一个工具。它是一个帮助人们做事的工具。我们不是平台。至于专利,很抱歉,但大多数专利,你不应该能够给数学和矩阵申请专利。这是不对的。
- 莱克斯:那么 VLC 有没有可能根据视频内容,审查它能播放或者不能播放哪些视频?
- 让-巴蒂斯特:不会,从来不会。我们从不这样做。因为 VLC 完全离线。它不会和任何服务器通信,所以我们不知道你用这个软件做什么。
- 莱克斯:所以同样,没有任何政府可以说,比如法国政府进来说:“我们不想要,呃,我觉得动漫对社会有破坏性。我们不允许任何动漫被...”
- 让-巴蒂斯特:不,他们不能这么做。而且他们还试过这样说:“嘿,我想知道那个人有没有看过那种视频。”答案就是:“不知道。”
- 莱克斯:所以这也不行。监控方面也不行。
- 让-巴蒂斯特:不,不行。因为我们唯一的基础设施是下载基础设施。VLC 里没有遥测。
- 莱克斯:这会很困难,因为它有国际性质。你很难把那种代码塞进去,因为 VideoLAN 里有英国的人、德国的人、美国的人,他们都能看到。那会极其困难。
- 让-巴蒂斯特:我们唯一能做的,而且确实发生过的,是这样一种情况:美国有些警察说:“我们有一个谋杀案。”他们说:“这个文件损坏了,或者在那个版本的 VLC 里无法播放。你能帮我们吗?”我们从来不会接触视频。这就像普通支持一样。
- 莱克斯:哦,它真正的问题只是播放这个文件?
- 让-巴蒂斯特:对。我记得在阿富汗战争期间,我收到过一封军队里某个人发来的邮件。我不记得军衔了。他大概说:“我们遇到了一个大问题,最新版 VLC 不能正确播放我们一个 RTSP 服务器上的文件,而那里有所有电影。”他说 VLC 对地面部队的士气非常重要。因为到了晚上我猜可能会很无聊。所以他们在那里有一批视频或者电影可以看。当然,是我做了一次更新,破坏了某些 RTSP 支持。所以我给了他们另一个版本,专门给他们用。因为这很重要。而且因为 VLC 完全开源,我想它是被允许安装在美国陆军笔记本上的。因为我猜美国军方里确实有人看过它,然后说:“嗯,没问题。”我们记录处理流程的方式也让他们觉得可以。所以我们和当局合作的唯一方式,就是帮他们做支持。
- 莱克斯:这太棒了。这个故事太棒了。
- 让-巴蒂斯特:我们看不到人们如何使用 VLC 发生了什么,这一点很坚固。
- 莱克斯:你会感受到这种压力吗?首先,有数百万人在用它。其次,军方也在用它。也许有时候还会有来自政府的压力。
- 让-巴蒂斯特:会。
- 莱克斯:这会不会... 那是一个很小的团队,对吧?
- 让-巴蒂斯特:是,但...
- 莱克斯:VLC 有多大?核心贡献者大概有多少?
- 让-巴蒂斯特:六个,八个。但法律上的一切只有我。所有法律事务都只有我。
- 莱克斯:你不会为此感到压力吗?
- 让-巴蒂斯特:我以前对此压力很大。但问题是,我们在为每个人、为更大的善做我们能做的事。我们把一些极其复杂的技术变得人人容易使用。我们是一个工具,而每一种工具都会被用于好事,也会被用于坏事。我认为你不能责怪一个工具。这对我们非常重要。我以前压力非常大。现在不再是了。
- 莱克斯:你的禅意秘诀是什么?我的意思是,今天和你聊天,一次又一次,哪怕谈到非常紧张的话题,你也很淡定。这种禅意的来源是什么?
- 让-巴蒂斯特:我总是会思考最坏的情况是什么。最后答案是,如果我像一个棋手那样看问题,最终,我死了吗?是还是不是?我会不停这样想。我做创业公司也是这样。我来到这里是为了做成一件事。最坏情况是什么?公司破产。生活就是这样。公司会活,公司会死。这没关系。所以我的道德判断总是:最后我会死吗?我会伤害别人吗?如果答案是否定的,那就太糟糕了。哦,有些律师会不高兴。他们能做什么?拿走 VideoLAN 的所有钱?哇,他们会拿到 5 万美元。太惊人了,对吧?他们拿这些钱又能做什么?源代码已经在那里了。它无法被阻止。也是因为我们做的是好事,是为所有人做的。
- 莱克斯:这很美。基兰,你说过有一个活跃的归档保存社区?我觉得这特别迷人。你写过,他们预算很紧,但他们看到 FFmpeg 极端重要,就像一块罗塞塔石碑,让一千年后的多媒体仍然可以被播放。我的意思是,把 FFmpeg、VLC 看成保存视觉知识的工具,这是一种很美的看法。
- 基兰:是的,没错。开源多媒体里最酷的社区之一,就是档案保存社区,主要由 Dave Rice 这样的人推动;我也想特别提一下他,他好像来自纽约城市大学。他们做了大量工作。他们重视开源,一方面是因为预算有限,另一方面是因为他们看到,保存影像对全世界很重要,但能否播放这些影像本身就是一个大问题。英国有个著名案例叫 New Domesday Book,他们把大量资料保存在 BBC Micro 计算机上。十到十五年后,已经没人有合适的软件来播放它了。我记得大概二十年之类,后来有人不得不去逆向工程,前后差不多二十年。想象一下,一千年后会怎样。我觉得 FFmpeg 伟大的一点,是它用 C 写成。C 大概已经是你能接近数学的最近形式了。最接近逻辑的是——
- 莱克斯:你觉得一千年后我们还会有 C 编译器吗?
- 基兰:会。我们已经有一些存在了很久、变化不大的语言;数学记号也一直存在。它会像拉丁语一样。C 会像拉丁语:你会把它当作来自过去的东西来学习,但它在某些语境里仍然能用。所以档案保存社区在实践上真的很棒。他们的资金同样有限,但他们资助了 FFV1 编解码器的开发;那是一个无损编解码器。档案社区非常担心压缩这个动作会丢东西,而且他们有道理。如果压得太狠,素材呈现出来的样子可能会被改变,某些地方可能会有细微差异。所以他们关心的不只是压缩得好,还必须无损,而且要快。于是他们和 FFmpeg 合作,开发了一个全新的编解码器,专为快速的软件编码而设计。他们也很在意韧性:如果内容存放在磁带或硬盘上,丢了几个比特,我需要能快速恢复,不能因为丢了一点东西就损失整个 GOP 之类。所以他们真是一群了不起的人。他们还资助了 FFmpeg 里的 GPU 编码,让 FFV1 编码更快。归根到底,这是以一种可使用的方式保存世界的多媒体遗产。世界各地有很多优秀团队和档案组织都选择 FFmpeg 和 FFV1 作为归档方案。他们也能给我们提供极其专业的建议,比如解释:“啊,20 世纪 50 年代,在这种特定磁带上,色度学是这样处理的,所以这里有一个特殊情况你必须处理;这种知识你在别处根本找不到。”
- 让-巴蒂斯特:你看,他们懂很多我们不懂的视频知识。每次我和……是 Dave 吗——
- 基兰:Dave Rice。
- 让-巴蒂斯特:……或者英国的那些人,呃——
- 基兰:British Film,呃——
- 让-巴蒂斯特:……Film。每次我都会学到新东西,而我做视频已经二十年了。他们尤其懂色度学和色彩。
- 基兰:还有存储,以及这些东西。
- 莱克斯:我的意思是,他们对内容本身、对视频本身有非常非常深的敬意。尤其当你想到无损时,他们害怕丢掉作品里某种本质的东西。也正因为这样,他们会非常深入地理解那个要被保存的对象。而当你沉迷于编码技术本身等等时,有时未必会这样去想。
- 让-巴蒂斯特:而且一旦你进入胶片扫描仪这个兔子洞,对吧?你把那些东西数字化,这本身就是一个巨大话题,光这个话题就可以再聊五个小时播客。
- 基兰:还有胶片本身,很多胶片都需要归档。胶片会老化,也许并没有保存在合适环境里。另外,因为这是开源,他们还会把自己的工作流免费分享给那些负担不起档案机构的国家;在那些地方,归档工作靠志愿者和其他方式完成。他们会去教学,比如在印度教孩子们写 FFmpeg 命令。他们真的很棒。他们就是我们想实现的那种模范社区、模范精神。他们是一群非常好的人,特别愿意参与,愿意成为更大事业的一部分,因为他们明白,他们今天做的工作会在一千年后讲述很多东西。你知道,一千年后我们也许会被 AI 垃圾内容淹没。这些东西必须重要起来,而且要好好归档。那时的人会问:当年的生活是什么样的?
- 莱克斯:是啊,记录 20 世纪和 21 世纪感觉至关重要,因为这像是一个转折点:我们从数据稀缺走向了垃圾内容,走向垃圾内容的海洋。这个转折点值得被归档。
- 让-巴蒂斯特:很重要,是的。
- 让-巴蒂斯特:但人们没有意识到,我们今天正在失去大量电影。30 年代、40 年代、50 年代有很多东西,因为没有商业价值——
- 基兰:还有磁带。70 年代和 80 年代的资料在磁带上,而全世界已经没有足够的磁头——
- 让-巴蒂斯特:去读取所有磁带。
- 基兰:……也没有足够的设备把它们重新转录出来,所以他们必须决定要归档什么,然后把剩下的磁带扔掉。围绕这个话题有巨大的道德风险,我姑且这样说吧,因为这是人类历史的数字记录,而他们必须做出选择。还有所谓数字托管吧,我也只是临时造了这个说法,不一定是真术语。重点是确保世界能以人人都能播放的形式拥有这些信息,而不是只能在某个早已不存在的设备上播放。
- 莱克斯:现实地说,这也像在干草堆里找针:把所有影像都归档本身就很有价值,随后随着时间推移,再从中发现那些我们现在还不知道存在的珍宝。
- 让-巴蒂斯特:嘿,那个角落里其实有个东西,只是我们当时没——
- 莱克斯:嗯,没错。
- 让-巴蒂斯特:而那个东西本来会因为只是个小细节就被压缩掉。结果你会说,哇,那里竟然有东西。
- 基兰:就是这样。
- 基兰:而这正是他们确保无损的意义。他们可以用数学证明它是无损的。他们可以针对比特腐烂做不同取舍:如果丢了一个比特,单个比特翻转了,我可以确保只丢掉某一帧的一部分。我们可以做错误恢复,他们也可以从前面的帧做错误恢复。他们能做各种各样的事情。
- 莱克斯:你们觉得 VLC 和 FFmpeg 一百年后还会存在吗?
- 基兰:FFmpeg,会。
- 让-巴蒂斯特:对,FFmpeg 会。
- 基兰:VLC,也许吧。
- 莱克斯:未来会怎样?FFmpeg 会走向哪里?VLC 会走向哪里?比如未来五年、十年、二十年,你们怎么看?
- 让-巴蒂斯特:五年、十年很容易。问题在更之后,对吧?问题是,我们会不会抵达某种叫全息影像的东西?
- 莱克斯:是,所以 VLC 和 FFmpeg 会扩展到任何——
- 让-巴蒂斯特:多媒体。
- 莱克斯:……多媒体。不好意思,这个话题扩展得有点像大麻脑洞,但如果你看 Neuralink 这样的脑机接口,很可能我们开始消费的“多媒体”,会变成任何编解码器、任何数据,只要是我们的大脑想通过脑机接口消费的东西。这是一方面。当然还有虚拟现实。
- 让-巴蒂斯特:你会有给 Neuralink 用的 VLC。
- 基兰:对,你还会有 `FFmpeg -i 人脑输入格式`。
- 莱克斯:是啊,会有给大脑用的编解码器。
- 基兰:当然,百分之百。
- 让-巴蒂斯特:当然。
- 莱克斯:对,用来压缩神经信息。
- 让-巴蒂斯特:我的意思是,今天已经有一些新的编解码器用于——
- 莱克斯:哇。
- 让-巴蒂斯特:……比如我们所说的点云,或者体积视频,对吧?还有很多关于 RGBD 的研究,也就是面向深度信息的编解码器;这对机器人和 3D 场景很有用。
- 莱克斯:不错。
- 让-巴蒂斯特:也有大量用于压缩 3D 元素的编解码器。
- 基兰:还有用于天文学的压缩。
- 让-巴蒂斯特:比如在 VLC 里,我们已经有 VR 和 XR 版本的 VLC。另外还有 Kyber,对吧?我们说到 Kyber。我们在 Kyber 里也会为算力不足的眼镜,或者 Apple Vision、Quest 这类设备,做 XR 内容流式传输。所以我们已经在做 3D、XR、交互式、低延迟的流媒体。有一种东西叫体积视频,还有点云视频,所以这不会停下来。是的,某个时候 VLC 和 FFmpeg 里会管理 3D 数据,这很显然。
- 莱克斯:所以方向就是那里,社区是开放的。
- 让-巴蒂斯特:不是社区里的每个人都看得到这一点,但基兰和我都是创业者,我们知道它会走向哪里。我们看得到,对吧?
- 莱克斯:所以我想 FFmpeg 内部大概会有一种张力。有人会说:“听着,伙计们,我们真的很擅长做视频和音频,为什么还要扩展?就把我们很擅长的事做好吧。”
- 让-巴蒂斯特:要回答这个问题,我们必须先回答“多媒体”的定义。多媒体是人类多种感官流的数字表示。而我们会做这件事,对吧?想象现在有一种方式,不再是麦克风,而是气味传感器和气味扩散器。它会进入 FFmpeg。
- 莱克斯:所以你的解复用器要来了。
- 让-巴蒂斯特:对,对。当然,你的解复用器会有一种新的轨道类型,本质上就是气味,对吧?而且你已经有——
- 莱克斯:嗅觉、触觉。
- 基兰:这就像音频。你会有左鼻轨和右鼻轨。音频有左右声道,对吧?很简单。
- 让-巴蒂斯特:是的,当然。
- 莱克斯:立体声气味。
- 基兰:立体声气味,对。
- 让-巴蒂斯特:比如在 VLC 里,我们已经有一个触觉插件。它主要用于所谓 4D 影院,对吧?就是那种装在液压……我不知道英语怎么说。所有那些液压——
- 基兰:液压臂。液压,嗯——
- 让-巴蒂斯特:机械臂。所有东西都会动,就像主题公园里的那种,对吧?然后有一条同步的数据流,基本上是在传输这些信息。
- 莱克斯:这个已经有标准了吗?
- 让-巴蒂斯特:有很多标准,对吧。嗯——
- 莱克斯:这……你让我太开心了。
- 让-巴蒂斯特:所以当然,我们有一个插件,它不在 VLC 的普通版本里——
- 莱克斯:那挺好。
- 让-巴蒂斯特:……基本上就是传输这类运动,也就是物理运动、触觉运动,对吧?它是一种人类感官,所以它会进来。
- 莱克斯:这是个非常令人兴奋的未来。可是……我是说,这只是一个很小的开发者社区。你们怎么做到?如果你是 FFmpeg 或 VLC 的贡献者,感觉会很有压力。光看 Twitter 就会觉得,为了让它在所有这些不同操作系统上运行,工作量巨大,努力程度惊人。
- 让-巴蒂斯特:不,要反过来看。我们不是贡献者,我们是维护者,对吧?我们为所有人维护。比如每年大概有 150 人给 VLC 贡献代码,也许有 300 人给 FFmpeg 贡献代码。我们这个小团队的目标,是把所有贡献合进去。所以如果使用量更大,就会有更多贡献,而那些人会去做正确的模块、新格式等等。我们关心的是 VLC 的架构、FFmpeg 的架构,对吧?现在我们在 VLC 里做空间音频。我们不久前做过演示。那需要架构上的改动,于是我们做了第一个空间音频模块。等要加第二个时就会容易,第三个也会容易,对吧?我们的目标,对其他东西比如触觉也是一样,就是调整架构,让模块可以被添加进来,带来未来能力。所以是的,我们会继续走下去。我们是多媒体框架,不只是音频和视频。它是一切有时间轴、并且表示某种你能感知到的东西。如果是脑电波,那就会是脑电波。
- 基兰:我觉得这是不可避免的。抱歉。
- 莱克斯:我从很多层面都喜欢这一点,因为 FFmpeg 和 VLC 正在推动公司、推动世界走向标准化。比如标准化脑电波,对吧?也就是推动标准化。我希望 Neuralink 能为通过脑机接口实现的多媒体,或者为带触觉的机器人,提出一种标准。
- 让-巴蒂斯特:按经验看,事情总是一样的,对吧?一开始,这是一个新话题。会有五种不同标准,因为每个人都开始做。热度降下来之后,每次热度下降,人们就会开始说:“好吧,你知道吗?我们需要一个标准。”通常不是领头者,而是两三家跟随者去制定标准,然后我们实现这个标准,曲线也就到了末端,事情开始更多地停留在纸面上。
- 莱克斯:然后领头者也会被某种程度上推过去,因为采用标准确实更好。对。
- 让-巴蒂斯特:比如 3D 音频,对吧?六七年前,一切都围绕 3D。你有 Android 上的 Cardboard。你有两种音频格式。它们现在都死了,对吧?现在它带着实际用例回来了,我们也从过去标准的错误里学到了东西。所以到处都会是这样。
- 莱克斯:并且尽量避免封闭。我在某处看到,你对 Dolby 没说太多好话。
- 让-巴蒂斯特:没有,我确实没有。嗯——
- 莱克斯:你能不能给我讲讲为什么?他们走偏在哪里?他们做了什么让你生气?
- 让-巴蒂斯特:它曾经是一家了不起的公司,做了大量伟大的事情,拥有很棒的工程师。他们定义了声音是什么。可现在它主要是——
- 基兰:律师。
- 让-巴蒂斯特:……律师和授权许可这些东西。
- 莱克斯:哦,所以他们是在把东西封闭起来,试图靠授权赚钱。
- 让-巴蒂斯特:不,只是他们不像过去那样创新了——
- 莱克斯:明白。
- 让-巴蒂斯特:……等等。有点像,抱歉这么说,就像 HP,对吧?
- 莱克斯:非常真实。
- 莱克斯:既然我们在不同语境里聊了不少 Twitter,你们在 VideoLAN 或 FFmpeg 的 Twitter 上,有没有最喜欢的一条推文?或者最不喜欢、最尴尬的一条?
- 基兰:我最喜欢的有两条。一条是“少说空话,提交补丁”。我觉得它体现了很多东西:就像我们聊过的,没人动手,东西就不会被造出来;它不会从空气里凭空出现。另一条我喜欢的是“FFmpeg,无所不能”。我想那来自一个美国军用卫星任务徽章,他们好像发明了某种能看到全世界的监控系统,然后这个东西被发布了。
- 莱克斯:是不是还有一件事,FFmpeg 跑在火星车上?
- 基兰:对,FFmpeg 被 Mars 2020 火星车用来压缩图片。他们确实想这么做,还写了一篇论文;他们非常希望尽可能多地使用商用现成技术。
- 莱克斯:哦,这很酷。
- 基兰:FFmpeg 在火星上运行,所以我们是一个多行星开源库。
- 莱克斯:漂亮。
- 让-巴蒂斯特:我们也经常看到——
- 莱克斯:漂亮。
- 让-巴蒂斯特:……有人发推说在各种奇怪地方使用 VLC。很多做 Formula 1 的人,在所有维修区里都会用 VLC 播放实时信号。我们见过欧洲航天局这样用,见过 SpaceX 用 VLC 监控发射。那真的会让你很开心,对吧。所以——
- 基兰:我还见过粒子加速器。
- 让-巴蒂斯特:哦,对,对。我经历过的最棒的事情之一,是去 CERN 的 LHC。他们用 VLC 监控环形隧道上的所有传感器,因为那个环有 27 公里长。所以他们有一些模拟摄像机,又用一些采集卡把模拟信号接入 VLC,这样 VLC 就能在他们的组播网络上流式传输,整个 CERN 都能访问。我 2010 年和 Laurent 去参观过那里,我们大概一个小时就帮他们修好了问题,对吧?因为当时有些参数可能文档写得不够好。他说:“好吧,接下来一整天你们想做什么?”于是我们参观了所有东西,像反物质、对撞机之类。对我这种物理背景的人来说,那是最精彩的一天之一。
- 莱克斯:是啊,它真的到处都在被用。基兰,有没有哪条推文你后悔发过?
- 基兰:我后悔的推文?
- 莱克斯:或者就像那首法国歌怎么唱的?毫不后悔。
- 让-巴蒂斯特:“Je ne regrette rien。”对。
- 让-巴蒂斯特:是的。这对我很重要,对吧?不要后悔任何事。因为后悔是对你心智征税,对吧?从错误中学习,但不要后悔。事情已经发生了,除非你有时间机器可以回到过去,否则不要后悔。它只会给你的大脑加税。从错误中学习,当然;但不要后悔。
- 莱克斯:这让我想起……这句话很美,是对大脑征税。它让我想起我看到的一句 Johnny Depp 的话,他说:“恨,你知道,我不恨。恨是一种非常昂贵的情绪。”
- 让-巴蒂斯特:你是在把我和 Johnny Depp 相比吗?那会是你的第一条后悔。
- 莱克斯:两位,正如我说过的,我永远感谢你们两位以及更大的社区参与构建的这些软件:FFmpeg、VLC,还有其他一切。我永远感谢那些辛辣推文,永远别停。我也感谢你们今天愿意和我聊天,还送我这顶性感帽子。我感觉自己像个巫师,很特别。能有机会聊天并庆祝这款多年来给我带来如此多快乐的软件,我也觉得很特别。所以谢谢你们做的一切,也谢谢你们今天来聊。
- 让-巴蒂斯特:谢谢你邀请我们。
- 基兰:非常感谢。
- 莱克斯:感谢你收听这场与 Jean-Baptiste Kempf 和 Kieran Kunhya 的对话。要支持本播客,请查看简介里的赞助商信息;那里也有联系我、提问、反馈等链接。最后,让我用传奇人物 Linus Torvalds 的一句话结束:“大多数优秀程序员写程序,不是因为他们期待得到报酬或公众赞美,而是因为编程很有趣。”感谢收听,希望下次再见。