技术实践 | 网易云信视频转码提速之分片转码
導(dǎo)讀:視頻轉(zhuǎn)碼作為媒體處理的核心功能,在對大視頻文件轉(zhuǎn)碼時(shí),通常需要花費(fèi)較長時(shí)間,為了提升服務(wù)質(zhì)量,我們將重點(diǎn)提升視頻轉(zhuǎn)碼的速率。
文|羅微恒
網(wǎng)易云信高級服務(wù)端開發(fā)工程師
在媒體內(nèi)容傳播行業(yè)中,視頻作為信息傳播的載體,其重要性占比越來越高。通常,為了應(yīng)對不同的播放場景,視頻需要修改封裝容器格式、編碼格式以及分辨率、碼率等媒體流屬性,這些處理的過程我們統(tǒng)稱其為視頻轉(zhuǎn)碼。
網(wǎng)易云信集網(wǎng)易 21 年 IM 以及音視頻技術(shù),對外提供行業(yè)一流的融合通信云服務(wù)。其中,云信的點(diǎn)播服務(wù),基于分布式處理集群和大規(guī)模分發(fā)系統(tǒng)資源,可滿足全終端設(shè)備的播放需求,為企業(yè)用戶提供極速穩(wěn)定的視頻上傳、存儲、轉(zhuǎn)碼、播放和下載等云服務(wù)功能。云信的分布式任務(wù)處理系統(tǒng),則承載了其中的媒體處理這一能力,主要功能有音視頻的轉(zhuǎn)封裝、轉(zhuǎn)碼、合并、截圖、加密、加減水印等,以及圖像伸縮、圖像增強(qiáng)、音量歸一化等一系列前處理功能。
本次文章將以分片轉(zhuǎn)碼為主,介紹網(wǎng)易云信在轉(zhuǎn)碼提速方面的努力與效果提升。
轉(zhuǎn)碼性能的影響因子與優(yōu)化
常見的視頻轉(zhuǎn)碼流程,一般如下圖所示:
在轉(zhuǎn)碼過程中,瓶頸主要在視頻流,因此我們對速度提升的討論主要針對視頻流處理,音頻流處理暫不在考慮范圍內(nèi)。針對視頻流處理的環(huán)節(jié),從以下幾個(gè)方面展開討論:
源視頻:一般源視頻越長,那么編解碼所需時(shí)間則越長。
封裝與編解碼:對于視頻轉(zhuǎn)封裝、關(guān)鍵幀片段裁剪等不需要解碼編碼的處理,其所需計(jì)算量很小,一般耗時(shí)在1~2s。若需要重新編解碼,則根據(jù)源視頻、編碼輸出參數(shù)的不同,所耗時(shí)間也不同。常見的有編碼格式以及碼率、分辨率、幀率,比如不同編碼算法的壓縮率與計(jì)算復(fù)雜度不一樣,導(dǎo)致所需耗時(shí)也有所不同,舉例來說 AV1 編碼時(shí)間就大于 H.264 的編碼時(shí)間。目標(biāo)碼率、分辨率、幀率等參數(shù)越大,通常計(jì)算耗時(shí)更大。
計(jì)算資源的水平與垂直伸縮:通用處理器的單核計(jì)算能力越強(qiáng),轉(zhuǎn)碼耗時(shí)肯定越小。利用 GPU 這類更適合圖像計(jì)算處理的專用處理器,也有利于降低轉(zhuǎn)碼耗時(shí)。提升轉(zhuǎn)碼執(zhí)行流的并發(fā)計(jì)算度,也有利于降低轉(zhuǎn)碼耗時(shí)。這里的并發(fā)路數(shù)可以是多線程和多進(jìn)程,多線程指單進(jìn)程內(nèi)以多線程的方式提升,多進(jìn)程則為通過對文件切片后,多進(jìn)程對多個(gè)切片文件計(jì)算。
集群任務(wù)調(diào)度:多租戶的云服務(wù)系統(tǒng),通常都是基于租戶間資源分配優(yōu)先級和租戶內(nèi)轉(zhuǎn)碼任務(wù)優(yōu)先級綜合而設(shè)計(jì)的調(diào)度算法,調(diào)度效率主要在以下幾個(gè)方面體現(xiàn):如何用更少的時(shí)間調(diào)度多的任務(wù),如何用更少的集群資源實(shí)現(xiàn)高吞吐量,如何做好優(yōu)先級和防饑餓的權(quán)衡設(shè)計(jì)。
針對上述的影響因素,我們提出以下幾個(gè)優(yōu)化方向:提升硬件能力、優(yōu)化編碼、分片轉(zhuǎn)碼以及提升集群調(diào)度效率。
?專用硬件加速?
多媒體處理是典型的計(jì)算密集型場景,優(yōu)化多媒體應(yīng)用程序的整體計(jì)算性能至關(guān)重要。CPU 是一種通用計(jì)算資源,將視頻圖像類運(yùn)算 offload 到專用硬件上是一種常見的方案。目前,業(yè)內(nèi)諸如 Intel、NVIDIA、AMD、ARM、TI 等芯片廠商都有相應(yīng)的多媒體硬件加速方案,提升高碼率、高分辨率等視頻場景的編碼效率。
我們的轉(zhuǎn)碼系統(tǒng)主要基于 FFmpeg 多媒體處理框架,在 Linux 平臺上支持的廠商方案有諸如 Intel 的 VA-API (Video Acceleration API)和 Nvidia 的 VDPAU (Video Decode and Presentation API for Unix ),同時(shí)兩家廠商也支持了相對更私有的 Intel Quick Sync Video 和 NVENC/NVDEC 加速方案。目前我們主要采用了 Intel 核芯顯卡的視頻加速能力,結(jié)合 FFmpeg 社區(qū)的 QSV Plugin 和 VAPPI Plugin 兩種方式,針對 AVDecoder、AVFilter、AVEncoder 三個(gè)模塊做了硬件加速。硬件加速相關(guān)技術(shù),相關(guān)廠商和社區(qū)都在持續(xù)優(yōu)化,在我們的后續(xù)系列文章中,我們也會詳細(xì)介紹這塊的進(jìn)一步實(shí)踐。
?AMD 大核服務(wù)器?
這里主要指搭載了 AMD EPYC 系列處理器的服務(wù)器,相對于我們此前線上的服務(wù)器,其單核計(jì)算力更強(qiáng),并行計(jì)算能力更優(yōu)異。單核計(jì)算力的提升讓我們在解碼、前處理、編碼能有整體性的通用提升,而搭載超大核則是讓我們的分片轉(zhuǎn)碼方案中的單機(jī)多進(jìn)程場景更加如虎添翼,大大避免了媒體數(shù)據(jù)的跨機(jī)器IO通信。
?自研 Codec?
NE264/NE265 是網(wǎng)易云信自主研發(fā)的視頻編碼器,在云信的 NERTC、直播點(diǎn)播中都有所應(yīng)用。除了編碼性能的提升之外,NE264 更重要的技術(shù)優(yōu)勢是低帶寬高畫質(zhì),其適用于高碼率高清晰度直播場景(如:游戲直播、線上演唱會、產(chǎn)品發(fā)布會等),可以確保人眼主觀畫面質(zhì)量不變的情況下,平均節(jié)省 20%~30% 的碼率。這里不再展開介紹,有興趣的可以關(guān)注文末相關(guān)閱讀。
?分片轉(zhuǎn)碼?
如果說上面的幾種性能優(yōu)化手段是垂直的,那么本節(jié)所說的分片轉(zhuǎn)碼則是水平的。視頻流本質(zhì)就是一連串的圖像組成,并以 IDR 幀為邊界劃分成一串 GOP,每個(gè) GOP 就是獨(dú)立的一組圖像集。視頻文件的這一內(nèi)容特點(diǎn),決定了我們可以參考 MapReduce 的算法思路,將視頻文件切割為多個(gè)分片,然后并行地對分片進(jìn)行轉(zhuǎn)碼,最后再合并成一個(gè)完整的文件。
?任務(wù)調(diào)度?
除了對單個(gè)轉(zhuǎn)碼計(jì)算執(zhí)行流優(yōu)化之外,我們也需要提升集群資源的整體調(diào)度效率。在調(diào)度算法這塊,調(diào)度節(jié)點(diǎn)既要接收任務(wù)提交,又要完成任務(wù)下發(fā)的關(guān)鍵流程,這個(gè)任務(wù)下發(fā)的算法設(shè)計(jì)需要做好多租戶分配、任務(wù)優(yōu)先級搶占和盡量提升集群資源利用率的多方平衡。
我們設(shè)計(jì)了兩種任務(wù)下發(fā)的機(jī)制:
1. Master 節(jié)點(diǎn) push 任務(wù)到計(jì)算節(jié)點(diǎn)
2. 計(jì)算節(jié)點(diǎn)主動來 Master 節(jié)點(diǎn) pull 任務(wù)
前者的優(yōu)點(diǎn)是實(shí)時(shí)性更高,缺點(diǎn)則是 Master 對計(jì)算節(jié)點(diǎn)的資源視角是一種 snapshot 快照,有些情況下該快照信息的滯后性會導(dǎo)致部分節(jié)點(diǎn)的過載現(xiàn)象。后者的優(yōu)點(diǎn)則是節(jié)點(diǎn)按需取任務(wù)來執(zhí)行,不會出現(xiàn)部分節(jié)點(diǎn)過載的現(xiàn)象,同時(shí)在任務(wù)選擇性這塊的可編程性更加便利,而缺點(diǎn)則是 Master 對全局資源分配的實(shí)時(shí)力度掌控性不足。
分片轉(zhuǎn)碼方案實(shí)踐
?媒體流程?
媒體處理的簡易流程如下圖所示,主要分四個(gè)步驟:分片前轉(zhuǎn)封裝(按需)、視頻分片、并行轉(zhuǎn)碼、視頻合并。
?分片流程?
在集群資源充足的情況下,即任務(wù)的調(diào)度與分發(fā)一般不會有積壓和資源搶占現(xiàn)象,這種情況下視頻流本身的處理計(jì)算,一般會消耗整個(gè)任務(wù)周期 80%-90% 的時(shí)間,所以針對這一階段進(jìn)行優(yōu)化,可以有更高性價(jià)比的收益。
提升硬件能力、優(yōu)化編碼這兩個(gè)維度是針對提升單個(gè)轉(zhuǎn)碼進(jìn)程的計(jì)算效率,但是單進(jìn)程能調(diào)用的資源有限,對大視頻文件的速率提升也是很有限。因此,在這里我們探討如何采用分布式 MapReduce 的思想,縮短一個(gè)轉(zhuǎn)碼任務(wù)所消耗的時(shí)間。接下來的章節(jié)將詳細(xì)講述實(shí)現(xiàn)分片轉(zhuǎn)碼技術(shù)方案。
分片轉(zhuǎn)碼流程基礎(chǔ)架構(gòu)如上圖,我們首先介紹以下幾個(gè)概念:
父任務(wù):類似于 Hadoop 中的 Job,客戶端提交的轉(zhuǎn)碼 Job,需將其待轉(zhuǎn)碼的視頻拆分成多個(gè)小分片;
子任務(wù):類似于 Hadoop 中的 Task,將多個(gè)小分片包裝成可以獨(dú)立調(diào)度和執(zhí)行的 Task 子任務(wù);
父 Worker:執(zhí)行父任務(wù)的計(jì)算節(jié)點(diǎn);
子 Worker:執(zhí)行子任務(wù)的計(jì)算節(jié)點(diǎn)。
分片轉(zhuǎn)碼的主要流程:
Dispatch center 給 worker0 派發(fā)一個(gè)轉(zhuǎn)碼 job,worker0 根據(jù)總開關(guān)、job 配置、視頻文件大小等策略判斷是否進(jìn)行分片轉(zhuǎn)碼;
如果確定進(jìn)行分片轉(zhuǎn)碼,則進(jìn)行分成 n 片;
包裝成 n 個(gè)轉(zhuǎn)碼Task提交給 Dispatch center;
Dispatch center 將這 n 個(gè)轉(zhuǎn)碼子任務(wù)調(diào)度給符合要求的 n 個(gè) worker;
worker1~n 轉(zhuǎn)碼完成后,給 worker0 發(fā)送回調(diào);
worker0 分別從 n 個(gè) worker 上下載轉(zhuǎn)碼后的分片視頻,待所有分片轉(zhuǎn)碼完成,將轉(zhuǎn)碼后的分片合并在一起;
發(fā)送回調(diào)給 client。
?子任務(wù)調(diào)度?
在調(diào)度系統(tǒng)中,每個(gè)用戶的任務(wù)隊(duì)列是獨(dú)立的,并分別設(shè)置任務(wù)限額。當(dāng) Dispatch center接收到計(jì)算節(jié)點(diǎn)的 fetch job 請求時(shí),調(diào)度線程先從多個(gè)用戶隊(duì)列中,選出已使用限額比例(比較簡單的算法模型可以是,已調(diào)度任務(wù)數(shù)量/用戶總限額)最小的用戶隊(duì)列,然后從隊(duì)列頭部取出一個(gè)符合該計(jì)算節(jié)點(diǎn)條件的子任務(wù)返回。子任務(wù)調(diào)度和普通任務(wù)調(diào)度在調(diào)度優(yōu)先級、節(jié)點(diǎn)選擇上有所不同,需要單獨(dú)設(shè)計(jì),這里我們簡單介紹一下。
子任務(wù)優(yōu)先級
子任務(wù)不需要在各自用戶隊(duì)列里重新排隊(duì),子任務(wù)調(diào)度的目標(biāo)是希望可以第一時(shí)間被調(diào)度到。該父任務(wù)其實(shí)已經(jīng)被調(diào)度到了,而系統(tǒng)處于加快該任務(wù)執(zhí)行的目的,在系統(tǒng)設(shè)計(jì)上將其再次派發(fā),如果還要和其他未被調(diào)度的任務(wù)一起競爭,那對這個(gè)任務(wù)來說是不公平的,也減弱了加速的作用。所以針對分片子任務(wù),會將其放置到一個(gè)全局高優(yōu)先級隊(duì)列,優(yōu)先被選擇調(diào)度。
子任務(wù)調(diào)度節(jié)點(diǎn)選擇
影響到子任務(wù)調(diào)度節(jié)點(diǎn)主要有以下因素:
1. 機(jī)器類型
機(jī)器類型分為硬件轉(zhuǎn)碼機(jī)器與普通轉(zhuǎn)碼機(jī)器,由于兩個(gè)環(huán)境中使用的編碼器不一樣,所以可能導(dǎo)致合并分片后的視頻會有瑕疵,因此我們選擇將子任務(wù)調(diào)度到與父任務(wù)相同的機(jī)器類型。
2. 代碼版本
不同版本的代碼可能導(dǎo)致轉(zhuǎn)出的分片無法很好的合并在一起,所以當(dāng)出現(xiàn)這樣的版本迭代后,可以通過計(jì)算節(jié)點(diǎn) worker 上的代碼版本,來確定子任務(wù)能調(diào)度到哪些其他計(jì)算節(jié)點(diǎn)上。
3. 數(shù)據(jù)存儲
當(dāng)父 worker 上的任務(wù)并發(fā)大時(shí),就會同時(shí)進(jìn)行多個(gè)上傳下載的網(wǎng)絡(luò)傳輸,這樣會導(dǎo)致分片文件 IO 階段耗時(shí)增加,因此優(yōu)先選擇將子任務(wù)放在父 worker 上執(zhí)行,就會節(jié)省網(wǎng)絡(luò) IO 與上傳下載耗時(shí)。
?掉隊(duì)者問題?
在分片轉(zhuǎn)碼場景中,掉隊(duì)者問題(straggler problems)是指在多個(gè)子任務(wù)中,如果大部分子任務(wù)已執(zhí)行完成,但還剩少數(shù)子任務(wù)遲遲未完成,父 worker 久久無法進(jìn)入到下一個(gè)流程,從而導(dǎo)致該任務(wù)被阻塞住。這在分布式系統(tǒng)中是一種較為常見的現(xiàn)象,針對該問題的系統(tǒng)領(lǐng)域研究論文也是屢見不鮮。
對這個(gè)問題的解決方案很大程度會影響系統(tǒng)的效率。如果父 worker 選擇一直等待子任務(wù),就可能出現(xiàn)任務(wù)過長時(shí)間的等待,這違背了我們提速的初衷。因此,基于保證該任務(wù)在有限時(shí)間內(nèi)能被完成的原則,有以下幾個(gè)優(yōu)化方向:
1.冗余調(diào)度
這個(gè)方案參考了 Hadoop 中 MapReduce 對掉隊(duì)者問題的解決方案:當(dāng)達(dá)到超時(shí)標(biāo)準(zhǔn)時(shí),子任務(wù)還未完成,則父 worker 會針對同一個(gè)分片文件再次發(fā)送一個(gè)新 Tsak 子任務(wù)給 Dispatch center,讓其重新調(diào)度,并重新執(zhí)行。當(dāng)有其中一個(gè)子任務(wù)完成則取消另一個(gè)。
這種做法是用空間換時(shí)間,不把希望只放在一個(gè)節(jié)點(diǎn)上,而是采取賽馬機(jī)制。但是,當(dāng)這樣的情況發(fā)生較多時(shí),則會產(chǎn)生大量的任務(wù)冗余,而且也不能保證新起的子任務(wù)不阻塞。
2.父 worker 接替完成
為了解決冗余調(diào)度中的不足之處,我們對其進(jìn)行了優(yōu)化。當(dāng)達(dá)到超時(shí)標(biāo)準(zhǔn),而子任務(wù)還未完成時(shí),則父 worker 會挑選完成進(jìn)度最少的分片進(jìn)行轉(zhuǎn)碼。同樣,其中一個(gè)任務(wù)完成則取消另一個(gè)冗余的任務(wù)。若還有子任務(wù)未完成,則繼續(xù)挑選,自己完成轉(zhuǎn)碼,直到所有子任務(wù)完成為止。
上述第二種方案較第一種方案的區(qū)別在于冗余任務(wù)不會重新調(diào)度到其他 worker 上執(zhí)行,而是優(yōu)先讓父 worker 來冗余執(zhí)行。這樣,父 worker 上會持續(xù)對分片進(jìn)行轉(zhuǎn)碼,直到整個(gè) job 完全完成。最大的優(yōu)點(diǎn)是:在不會無限制的消耗資源下,保證父 worker 不會處于無限等待狀態(tài)中,只有在少數(shù)情況下,當(dāng)父 worker 負(fù)載較高時(shí),會考慮使用其他擁有空閑資源的 worker。
?子任務(wù)進(jìn)度跟蹤?
在父 worker 挑選子任務(wù)執(zhí)行時(shí),需要收集子任務(wù)的進(jìn)度后選擇進(jìn)度最慢的子任務(wù)進(jìn)行冗余執(zhí)行。在計(jì)算任務(wù)進(jìn)度時(shí),我們將一次轉(zhuǎn)碼分為這四個(gè)階段:等待調(diào)度、下載與準(zhǔn)備、轉(zhuǎn)碼計(jì)算執(zhí)行、上傳與收尾。
不同階段的開始,表示到達(dá)不同的進(jìn)度:
等待調(diào)度0% → 下載與準(zhǔn)備20% → 轉(zhuǎn)碼計(jì)算執(zhí)行30% → 上傳與收尾90% → 結(jié)束100%
其中,轉(zhuǎn)碼計(jì)算執(zhí)行占70%,也是執(zhí)行速度無法保證的一個(gè)階段,所以需要詳細(xì)計(jì)算進(jìn)度,轉(zhuǎn)碼執(zhí)行流會定期輸出 metric 日志,并進(jìn)行監(jiān)控計(jì)算,當(dāng)前轉(zhuǎn)碼進(jìn)度 = 已轉(zhuǎn)碼時(shí)長(time 字段)/ 需轉(zhuǎn)碼時(shí)長 。
?HLS/DASH 封裝?
HLS 格式與其他封裝格式不同之處在于其會有多個(gè) ts 文件與 m3u8 文件,對轉(zhuǎn)出 HLS 視頻的任務(wù)進(jìn)行分片轉(zhuǎn)碼,會增加分片視頻傳輸與管理的復(fù)雜性。因此我們對此問題的解決方案是先將源視頻轉(zhuǎn)成 mp4 視頻,然后在父 Worker 上合并后,再對整個(gè)視頻轉(zhuǎn)換 HLS 封裝。
測試數(shù)據(jù)
通過記錄并對比同一個(gè)視頻轉(zhuǎn)為不同分辨率視頻的速率,我們可以發(fā)現(xiàn)各個(gè)單個(gè)的優(yōu)化措施對轉(zhuǎn)碼速度都有不同程度的提升。在實(shí)際線上場景,我們通常會根據(jù)用戶設(shè)定、視頻屬性決定綜合使用某幾項(xiàng)優(yōu)化方式。
測試視頻1屬性:
Duration: 00:47:19.21, bitrate: 6087 kb/s
Stream #0:0: Video: h264 (High), yuv420p, 2160x1216, 5951 kb/s, 30 fps
Stream #0:1: Audio: aac (LC), 44100 Hz, stereo, fltp, 127 kb/s
測試視頻2屬性:
Duration: 02:00:00.86,bitrate: 4388 kb/s
Stream #0:0: Video: h264 (High), yuvj420p, 1920x1080, 4257 kb/s, 25 fps
Stream #0:1: Audio: aac (LC), 48000 Hz, stereo, fltp, 125 kb/s
結(jié)語
以上就是本文的全部內(nèi)容,網(wǎng)易云信轉(zhuǎn)碼團(tuán)隊(duì)主要通過調(diào)度優(yōu)化、硬件能力、自研編碼、分片轉(zhuǎn)碼等維度切入,提升視頻轉(zhuǎn)碼速度,測試結(jié)果顯示轉(zhuǎn)碼提速效果顯著。另外著重介紹了云信轉(zhuǎn)碼系統(tǒng)中對分片轉(zhuǎn)碼模塊的主要設(shè)計(jì)。我們也會持續(xù)進(jìn)行技術(shù)探索,實(shí)現(xiàn)提速以及更多的場景覆蓋。后續(xù)的系列文章中,我們還會對集群資源調(diào)度算法、硬件轉(zhuǎn)碼實(shí)踐等其他方面的內(nèi)容進(jìn)行分享,也歡迎持續(xù)關(guān)注我們。
?作者介紹?
羅微恒,網(wǎng)易云信高級服務(wù)端開發(fā)工程師,碩士畢業(yè)于武漢大學(xué)計(jì)算機(jī)學(xué)院,網(wǎng)易云信轉(zhuǎn)碼團(tuán)隊(duì)核心成員,目前負(fù)責(zé)云信媒體任務(wù)處理系統(tǒng)設(shè)計(jì)與開發(fā)工作,致力于提升云信視頻轉(zhuǎn)碼服務(wù)質(zhì)量。
?相關(guān)推薦閱讀?
技術(shù)系列課回顧 | 直播點(diǎn)播窄帶高清之 JND 感知編碼技術(shù)
技術(shù)系列課回顧 | 網(wǎng)易云信線上萬人連麥技術(shù)大揭秘
技術(shù)干貨 | 網(wǎng)易云信大規(guī)模聊天室系統(tǒng)架構(gòu)解析
總結(jié)
以上是生活随笔為你收集整理的技术实践 | 网易云信视频转码提速之分片转码的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 预告丨大型出海知识盛宴,邀您一起 enj
- 下一篇: 资讯|WebRTC M92 更新