周六晚上,你熬完了又一個(gè)加班的周末,拖著疲憊的身體癱倒在沙發(fā)上,百無聊賴地刷著抖音。
刷累了短視頻,你又打開視頻平臺(tái),追起那部收藏已久卻一直沒時(shí)間看的電視劇。
臨睡前,你戴上耳機(jī),和遠(yuǎn)方的朋友打了一通視頻電話,聊聊最近的工作和生活。
這些平凡的生活場(chǎng)景看起來毫無關(guān)聯(lián),但是如果把這些產(chǎn)品背后的技術(shù)扒開,你就會(huì)發(fā)現(xiàn),每一個(gè)笑點(diǎn)視頻,每一幀畫面,在進(jìn)入你手機(jī)之前,都曾在某個(gè)服務(wù)器深處,被同一套工具悄悄地“重塑過”:
編碼、壓縮、裁剪、轉(zhuǎn)碼……
而那條最關(guān)鍵的指令,往往只是:
ffmpeg -i ...這就是FFmpeg,現(xiàn)在互聯(lián)網(wǎng)最龐大的“隱形巨人”。
0 1
諸侯割據(jù)的時(shí)代
讓我們把時(shí)鐘撥回到20多年前。
當(dāng)時(shí)互聯(lián)網(wǎng)正從“文字時(shí)代”邁向“音視頻時(shí)代”,寬帶開始普及,人們瘋狂下載歌曲、MV和電影。
為了爭(zhēng)奪未來的網(wǎng)絡(luò)媒體入口,各大廠商紛紛推出自己的媒體格式和播放器生態(tài):
![]()
微軟推出 ASF/WMV,希望借助 Windows 的優(yōu)勢(shì)推廣 Windows Media Player;
RealNetworks 的 RM/RMVB 一度成為網(wǎng)絡(luò)視頻事實(shí)標(biāo)準(zhǔn),RealPlayer 幾乎是裝機(jī)必備軟件;
蘋果則主推 MOV 格式和 QuickTime 生態(tài),在 Mac 和多媒體創(chuàng)作領(lǐng)域影響巨大。
各種“方言”導(dǎo)致了一個(gè)悲慘的結(jié)果:視頻/編碼高度碎片化,互不兼容,解碼器幾乎全是閉源、商業(yè)化的。
更糟糕的是,很多視頻格式在壓縮時(shí),深度依賴 Windows 系統(tǒng)的底層組件(如 DirectShow 或 VFW DLLs),這些組件是微軟操作系統(tǒng)的核心秘密,Linux 上根本沒有,巨頭公司根本不屑于為市場(chǎng)份額極小的 Linux 系統(tǒng)開發(fā)官方播放器。
不過,這難不倒聰明的 Linux 黑客。
他們想出了一個(gè)非常奇葩和極端的黑客辦法:“借尸還魂”。
他們編寫了一些特殊的底層補(bǔ)丁(著名的如早期 MPlayer 的 w32codec),在 Linux 中模擬部分 Windows 多媒體接口,強(qiáng)行加載 Windows 系統(tǒng)的 .dll 動(dòng)態(tài)鏈接庫文件。
這種做法雖然勉強(qiáng)能用,但是極不穩(wěn)定,極不安全,在法律上也是非常危險(xiǎn)的灰色地帶。
正是在這種“天下大亂、生態(tài)真空”的時(shí)刻,天才程序員Fabrice Bellard站了出來:
![]()
是時(shí)候搞一套屬于開源世界的,不依賴任何Windows技術(shù)的“多媒體底層普通話”了!
這個(gè)“普通話”就叫做FFmpeg,主要完成兩個(gè)事情:
1.完成一個(gè)精妙的頂層設(shè)計(jì),把容器和編碼徹底分開。
2.用純 C 語言,把市面上那些閉源的、復(fù)雜的商業(yè)視頻和音頻解碼算法,全部“逆向工程”并重新純手寫一遍!
這兩件事兒有多瘋狂呢,我們一個(gè)一個(gè)來看。
0 2
精妙的頂層設(shè)計(jì)
在多媒體領(lǐng)域,任何一個(gè)視頻文件其實(shí)都由兩部分組成,它們的職責(zé)完全不同。
![]()
容器的職責(zé)是“打包”。負(fù)責(zé)把音頻流、視頻流、字幕、甚至封面圖片以某種特定的數(shù)據(jù)結(jié)構(gòu)“捆綁”在一起,我們通常通過文件的后綴來區(qū)分(video.mp4, movie.avi)。
編碼的職責(zé)是“壓縮”,視頻用H.264或MPEG-2壓縮,音頻用MP3或AAC壓縮。
現(xiàn)在我們很容易想到,在實(shí)現(xiàn)軟件播放器的時(shí)候,應(yīng)該把這兩層分開,讓他們獨(dú)立變化。
但在當(dāng)時(shí)的商業(yè)多媒體領(lǐng)域,性能壓力和商業(yè)策略,讓大量播放器與 SDK 選擇了強(qiáng)耦合設(shè)計(jì),把容器和編碼綁死在了一起。
作為一個(gè)純粹的學(xué)院派加硬核極客,F(xiàn)abrice Bellard可不管你這那的,這兩者一定得分開:
1.libavformat
專注于容器的解包和打包,當(dāng)它讀取一個(gè) video.mkv 時(shí),唯一的任務(wù)就是拆開它,把一小段一小段的、依然處于壓縮狀態(tài)的二進(jìn)制原始數(shù)據(jù)( AVPacket)源源不斷地吐出來。
2.libavcodec
專注于解壓和壓縮,它是一個(gè)純粹的數(shù)學(xué)計(jì)算黑盒子,它只接受 libavformat 丟給它的壓縮數(shù)據(jù)(AVPacket),通過各種算法,把它們還原成一幀一幀沒有經(jīng)過壓縮的數(shù)據(jù)( AVFrame)。
不但如此,F(xiàn)abrice Bellard用天才的手法,用最接近硬件的手段(手寫 SIMD 匯編、查表法、緩存對(duì)齊)把計(jì)算性能壓榨到物理極限,甚至很多時(shí)候,F(xiàn)Fmpeg 比官方 SDK 還快。
但FFmpeg更偉大的地方,不僅僅是“支持很多格式”,它把整個(gè)音視頻世界抽象成了一套統(tǒng)一的數(shù)據(jù)流管道(就像Unix的數(shù)據(jù)流管道一樣)
以我們最常見的“視頻轉(zhuǎn)碼”(比如把一個(gè)高碼率的 AVI 視頻轉(zhuǎn)成手機(jī)能播放的 MP4 視頻)為例,在 FFmpeg 的管道里,數(shù)據(jù)是這樣像水流一樣流淌的:
![]()
無論任何格式,解碼,濾鏡,轉(zhuǎn)碼,都能在流水線任意組合,非常優(yōu)雅和漂亮,展示了Fabrice Bellard深厚的架構(gòu)功力。
0 3
瘋狂的逆向工程
前面說過,黑客們拿不到源代碼。他們只能通過反匯編工具,將機(jī)器碼翻譯成人能勉強(qiáng)看懂的匯編代碼:
![]()
然后用動(dòng)態(tài)調(diào)試等技術(shù)來進(jìn)行分析,例如讓 Windows 官方播放器慢動(dòng)作播放一個(gè)視頻,黑客在后臺(tái)死死盯著 CPU 的寄存器和內(nèi)存變化。
視頻壓縮本質(zhì)上是高等數(shù)學(xué)通過觀察匯編指令中的常數(shù)和循環(huán)結(jié)構(gòu),黑客們能夠反向推導(dǎo):“哦!原來 RealMedia 的音頻格式用的是改進(jìn)的離散余弦變換(MDCT),這里的參數(shù)是這樣設(shè)置的。”
他們還會(huì)制作一些極其特殊的測(cè)試視頻文件:
一個(gè)純黑、只有 1 像素、長(zhǎng)達(dá) 1 秒的視頻
一個(gè)純白、有 2 像素、長(zhǎng)達(dá) 2 秒的視頻
然后用十六進(jìn)制編輯器對(duì)比這兩個(gè)文件的二進(jìn)制數(shù)據(jù)。
“看,第一秒和第二秒的文件里,第 0x40 字節(jié)的數(shù)據(jù)從 01 變成了 02。這意味著這個(gè)位置存放的是視頻時(shí)長(zhǎng)!”
“這里有一串固定的字符 mdat,后面跟著一串?dāng)?shù)據(jù)。這說明 mdat 后面就是真正的音視頻原始數(shù)據(jù)(Media Data)了!”
當(dāng)然,很多所謂的“閉源商業(yè)格式”,其實(shí)是基于行業(yè)公開標(biāo)準(zhǔn)魔改出來的。
對(duì)于 Fabrice Bellard 這樣的頂級(jí)專家,他不需要從零去猜,他只需要把公開標(biāo)準(zhǔn)作為模版去比對(duì):“讓我看看微軟在這里到底改了哪幾個(gè)參數(shù)?” 一旦找出這些變動(dòng),逆向工程就容易多了。
正是用這種辦法,F(xiàn)abrice Bellard 和無數(shù)逆向工程師一點(diǎn)點(diǎn)拆開了巨頭們筑起的技術(shù)圍墻。
那些原本被鎖在閉源播放器里的格式規(guī)范、編碼算法和數(shù)據(jù)結(jié)構(gòu),被重新理解、重新實(shí)現(xiàn),最終變成了干凈、免費(fèi)、向全世界公開的 C 語言代碼。
0 4
貧窮的維護(hù)者
Fabrice Bellard是一個(gè)極度內(nèi)斂、低調(diào),甚至有些社恐的程序員。
但有人的地方就有江湖。只要開源軟件社區(qū)規(guī)模擴(kuò)大,勢(shì)必出現(xiàn)各種紛爭(zhēng)。
所以我們經(jīng)常看到這樣一個(gè)模式:Bellard把一個(gè)大廈的基座和主體完成后,就立刻放手,去挑戰(zhàn)另一個(gè)領(lǐng)域。
揮一揮衣袖,不帶走一片云彩。
這次也不例外。
FFmpeg走上正軌后,他把維護(hù)權(quán)交給了 Michael Niedermayer,自己轉(zhuǎn)身投入了另一個(gè)改變世界的基礎(chǔ)設(shè)施項(xiàng)目:QEMU(虛擬機(jī)模擬器)。
Michael這個(gè)人,比Bellard還要低調(diào),甚至可以說神秘。
他幾乎不參加技術(shù)會(huì)議或線下聚會(huì),所有交流都通過郵件列表。我在網(wǎng)上甚至找不到他的照片。
他本來是MPlayer播放器的開發(fā)者,但MPlayer底層高度依賴FFmpeg的解碼能力,他的核心代碼開始大量并入FFmpeg。
接管FFmpeg之后,他做出了一個(gè)讓世俗社會(huì)無法理解的決定:全職守護(hù)FFmpeg。
要知道,當(dāng)時(shí)視頻網(wǎng)站已經(jīng)興起,他但凡接受任何一家硅谷大廠的offer,或者開一家顧問公司,就能輕松獲得巨額年薪,但他都拒絕了。
共事多年的核心開發(fā)者Kostya(Konstantin Shishkov)曾回憶證實(shí):Michael長(zhǎng)期住在奧地利的鄉(xiāng)下,過著維持“最低收入”的生活。
他幾乎沒有任何商業(yè)贊助,全靠微薄的零星捐款和極低的個(gè)人開銷度日。
Michael甚至認(rèn)為,出去接私活或者為了生計(jì)去上班,是對(duì)優(yōu)化編解碼器的時(shí)間浪費(fèi)。
他每天工作十幾個(gè)小時(shí),一個(gè)人完成了FFmpeg中極其龐大且晦澀的匯編級(jí)優(yōu)化。
他是個(gè)瘋狂的Bug修復(fù)機(jī)——安全團(tuán)隊(duì)提交的上千個(gè)Bug中,有超過650個(gè)是他一個(gè)人修復(fù)的。
他長(zhǎng)期保持著日均1次核心Commit的高強(qiáng)度全職工作狀態(tài)。
0 5
技術(shù)政變:一個(gè)人對(duì)抗全世界
但是,技術(shù)天才Michael的管理風(fēng)格也有問題。
他過于強(qiáng)硬且保守,極其注重向下兼容和極致性能,經(jīng)常在核心代碼中加入各種特例。很多年輕開發(fā)者認(rèn)為,他的代碼風(fēng)格太“不現(xiàn)代”、太難維護(hù)。
社區(qū)開始積怨。
終于在2011年,一批核心開發(fā)者對(duì) Michael 忍無可忍,他們發(fā)動(dòng)了一場(chǎng)技術(shù)“政變”,反對(duì)派在未經(jīng)Michael同意的情況下,帶走了原項(xiàng)目的服務(wù)器、缺陷追蹤系統(tǒng)等基礎(chǔ)設(shè)施,另立門戶創(chuàng)建了一個(gè)叫做 Libav 的新分支項(xiàng)目。
幸運(yùn)的是,F(xiàn)abrice Bellard 依然控制著ffmpeg.org 的 DNS,并且拒絕交給“叛軍”,F(xiàn)Fmpeg的品牌可以保全,這一點(diǎn)非常關(guān)鍵。
重量級(jí)的Linux發(fā)行版(Debian、Ubuntu 等)站在了反對(duì)派一邊,將系統(tǒng)默認(rèn)的多媒體庫換成了 Libav,F(xiàn)Fmpeg 在 Linux 生態(tài)中的主導(dǎo)地位受到巨大沖擊。
面對(duì)“背叛”,Michael沒有去打口水仗,他的反擊非常純粹:瘋狂寫代碼。
他不僅瘋狂地優(yōu)化FFmpeg的代碼,更是緊盯libav,只要一出新功能,他幾天內(nèi)就能合并進(jìn)FFmpeg,并且利用恐怖的優(yōu)化能力寫得更好!而libav那邊處于政治原因,絕不合并FFmpeg的代碼。
Libav 陣營(yíng)為了追求所謂的“現(xiàn)代化重構(gòu)和干凈的 API”,導(dǎo)致開發(fā)速度極其緩慢;而FFmpeg 在 Michael 的死守下,“把事情做完”的效率高得驚人。
幾年下來,程序員們震驚地發(fā)現(xiàn),F(xiàn)Fmpeg 不僅完全兼容 Libav 的特性,而且由于 Michael 的瘋狂輸出,F(xiàn)Fmpeg 的性能更強(qiáng)、支持的格式更多、Bug 修復(fù)得更快。
2015年,Debian決定將系統(tǒng)默認(rèn)的多媒體庫 從Libav重新切換回FFmpeg。隨后,Ubuntu等所有主流發(fā)行版也紛紛跟進(jìn)。這成為了壓垮Libav的最后一根稻草。
2015 年 8 月,在帶領(lǐng) FFmpeg 徹底贏回主流生態(tài)、并將 Libav 的分裂風(fēng)波平息之后,身心俱疲的Michael決定辭職,他說:
我加入 FFmpeg 已經(jīng) 14 年了,擔(dān)任 Leader 也已經(jīng) 11 年。我感覺我并不是最適合繼續(xù)擔(dān)任 Leader 職位的人..... 我希望我的辭職能夠讓兩個(gè)團(tuán)隊(duì)重新找回彼此、走到一起,從而避免更徹底的分裂...... 合并工作(Merges)所帶來的巨大工作量和精神壓力,是我辭職的核心原因...... FFmpeg 是你們的,它是屬于每一個(gè)人的。
0 6
結(jié)語
20多年過去了,F(xiàn)Fmpeg早已成為互聯(lián)網(wǎng)隱形的基礎(chǔ)設(shè)施。
YouTube、Netflix、Chrome、抖音,快手,視頻號(hào),甚至你手機(jī)上的任何視頻應(yīng)用,每天都在使用FFmpeg,它是數(shù)字世界的空氣,你意識(shí)不到它,但是它無處不在。
但諷刺的是,開發(fā)FFmpeg的那幫極客們,長(zhǎng)期缺錢,幾乎沒有名氣,“近乎燃燒生命”,Michael Niedermayer 就是其中最典型的代表。
很多人不理解,他們能一直堅(jiān)持下來,圖的是啥呢?
我想主要有三層驅(qū)動(dòng)力:
1.興趣
這些極客們?cè)谧鲎约合矚g的事情,熱愛是無與倫比的驅(qū)動(dòng)力。
2.成長(zhǎng)
FFmpeg需要非常硬核的開發(fā)者,在這里,有最厲害的兩類人,1.寫匯編的 2.做逆向工程的。
想在這里做貢獻(xiàn),你得理解CPU架構(gòu)、內(nèi)存層級(jí)、IO機(jī)制這些底層的東西,你的代碼會(huì)被最資深的程序員逐行審查,在這種環(huán)境下成長(zhǎng)起來的開發(fā)者,往往會(huì)變得極其強(qiáng)悍。
3.成就感
你的代碼在幾十億的設(shè)備上運(yùn)行,被幾十億用戶使用,這種成就感是無與倫比的。
特別聲明:以上內(nèi)容(如有圖片或視頻亦包括在內(nèi))為自媒體平臺(tái)“網(wǎng)易號(hào)”用戶上傳并發(fā)布,本平臺(tái)僅提供信息存儲(chǔ)服務(wù)。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.