B站自研色彩空間轉(zhuǎn)換引擎
1.背景
色彩空間(Color Space)是一種數(shù)學模型,用于描述和表示顏色的方式。不同的色彩空間有不同的用途和特點,可以用于不同的應用,如圖像處理、計算機圖形、印刷、攝影等領(lǐng)域。它一般用于描述設(shè)備的色彩能力,或者視頻、圖片的色彩范圍。比如現(xiàn)在大部分人用的手機的屏幕,色彩空間大多為sRGB或者DCI-P3;網(wǎng)頁上常見的圖片或者視頻內(nèi)容,大多屬于sRGB色彩空間;B站客戶端播放的HDR視頻,則處于BT.2020色彩空間。
目前B站UP主投稿視頻是千變?nèi)f化的,它們包含各種不同的色彩參數(shù), 比如不同的色深,不同的色度采樣坐標,不同的色彩空間,不同的亮度傳遞函數(shù)等等(如下圖),而且每個用戶觀看這些視頻的終端也不一樣,這樣就產(chǎn)生了各種各樣的兼容性問題——很多時候用戶的設(shè)備并不能完全正確顯示UP主投稿的“原片”,而且老舊的設(shè)備或者瀏覽器也并不支持廣色域或者HDR視頻。為了考慮終端設(shè)備的兼容性和B站服務(wù)的完整性,我們會對用戶投稿的不同色彩空間的視頻進行統(tǒng)一處理。但是如何將各種不同色彩參數(shù)的視頻進行準確地統(tǒng)一處理,同時又能保證視頻的處理速度,這對于我們來說是一個巨大的挑戰(zhàn)。
色彩空間轉(zhuǎn)換中需要處理的參數(shù)
2.引擎架構(gòu)
為了處理各種不同色彩參數(shù)的視頻,我們研發(fā)了一套色彩空間的轉(zhuǎn)換引擎。該引擎會對各種不同色深、色彩空間、亮度傳遞函數(shù)的普通視頻統(tǒng)一轉(zhuǎn)換為標準的SDR視頻。除了SDR視頻, B站也會接收很多HDR視頻投稿,對于HDR投稿,B站會統(tǒng)一轉(zhuǎn)出一路標準的HDR視頻和一路標準的SDR視頻。
該圖像轉(zhuǎn)換引擎分為三層,包括濾鏡層,引擎層,和設(shè)備層。其中濾鏡層包含各種濾鏡,用于處理不同的色彩參數(shù)。引擎層的主要目的是做一些預計算與計算路徑優(yōu)化,比如有一些矩陣乘法只需要計算一次,那么就可以預先計算出來,而不是在像素處理的時候再去做。有一些GPU需要用到的矩陣參數(shù),則也可以進行預拷貝,防止出現(xiàn)CPU與GPU之間出現(xiàn)頻繁拷貝的情況,計算路徑優(yōu)化,則是用來去除一些不必要的步驟,來減少計算量。最后,設(shè)備層主要包含每種濾鏡在不同平臺的實現(xiàn),該引擎包含一個指令集優(yōu)化的X86版本和一個CUDA版本。接下來我介紹一下該濾鏡層的各種色彩轉(zhuǎn)換能力,包括坐標變換、量化、色度采樣,色調(diào)映射等等。
色彩空間處理引擎的基本架構(gòu)圖
2.1 坐標變換
很多時候,用戶投稿的視頻會有顯示矩陣(Display matrix),它表示視頻被旋轉(zhuǎn)、被翻轉(zhuǎn)、或者被轉(zhuǎn)置。如果我們在服務(wù)端檢測到這種視頻,那么就需要對輸入視頻按照顯示矩陣進行坐標變換。無論是軟解的CPU數(shù)據(jù)幀還是硬解的CUDA幀,該引擎都能將其準確地渲染出來。
2.2 量化與反量化
信號的量化主要用于連續(xù)的YUV信號轉(zhuǎn)為離散的Y’CbCr,而反量化是將輸入視頻不同的色深轉(zhuǎn)換為連續(xù)信號的過程。該引擎支持8bit、10bit、12bit等不同量化精度的Y’CbCr信號與YUV信號的互相轉(zhuǎn)換,同時也支持pc range、tv range的轉(zhuǎn)換。
2.3 色度采樣
色度采樣(Chroma subsampling)是一種用于減少圖像或視頻中色度信息采樣率的技術(shù)。在數(shù)字圖像和視頻編碼中,顏色信息通常由亮度分量(Y)和兩個色度分量(U和V)組成。由于人眼對亮度信息更加敏感,而對色度信息的感知相對較弱,因此可以通過減少色度分量的采樣率來降低數(shù)據(jù)量,同時盡量保持圖像或視頻的質(zhì)量。下圖為常見的像素格式Y(jié)UV420的采樣坐標。
為了色度采樣盡可能平滑,我們采用了雙線性(Bilinear)插值策略進行上采樣和下采樣。例如對YUV420像素格式的視頻進行色度的上采樣, 我們并不會簡單地將一個色度像素共享給4個亮度像素, 而是對其進行插值,否則最后輸出的視頻會有色度過渡的不均勻。同理,對于色度的下采樣,我們也會采用同樣的插值方法。
圖片
常見的色度采樣坐標(4:2:0 chroma format)
2.4 色彩矩陣轉(zhuǎn)換
視頻處理中的一個關(guān)鍵參數(shù)是色彩矩陣(Color matrix),有時也稱為色彩空間(Color space)。該參數(shù)主要用于確定信號如何轉(zhuǎn)換為RGB,色彩矩陣轉(zhuǎn)換是將輸入信號通過色彩矩陣映射到RGB色彩空間的過程。
舉例來說,常見的BT.709標準就屬于一種色彩矩陣,它指導了如何將YUV信號轉(zhuǎn)換為RGB,其轉(zhuǎn)換方式如下:
圖片
為什么選擇了上述的矩陣而不是其他的呢?這是因為BT.709協(xié)議所指定的色彩空間與sRGB相對應,通過sRGB的色域坐標可以推導出上述的轉(zhuǎn)換矩陣。不同的色彩空間對應不同的轉(zhuǎn)換矩陣,具體的矩陣根據(jù)輸入的色彩矩陣而定。如果需要將R'G'B'轉(zhuǎn)換為Y'U'V',則需要對上述矩陣進行逆運算。
而對于特殊信號,例如ICtCp信號,我們會首先將其轉(zhuǎn)換為L'M'S'信號,然后再進行后續(xù)的轉(zhuǎn)換操作。
2.5 亮度傳遞函數(shù)轉(zhuǎn)換
亮度傳遞函數(shù)是一種用于調(diào)整圖像或視頻信號亮度級別的函數(shù),分為兩種OETF(Opto-Electronic Transfer Function)和EOTF(Electro-Optical Transfer Function)。由于人眼對不同光線區(qū)域的敏感度不同,人眼對暗部細微亮度變化的敏銳程度較高,而對于高亮度的細微變化則較難察覺。為了以一種均勻的方式呈現(xiàn)信號,以符合人眼的感知,并且為了能夠編碼更多的信息,我們需要對信號進行OETF壓縮。相反地,如果我們需要解壓信號,則需要進行相反的處理,即EOTF。常見的EOTF曲線有Gamma2.4曲線和感知量化曲線(Perceptual Quantization,PQ),如下圖。感知量化曲線是一種最接近人眼感知的量化方法,因此它也被廣泛用作HDR視頻的主要亮度傳遞函數(shù)。
Gamma2.4和PQ的EOTF曲線
在該引擎中,我們實現(xiàn)了十幾種亮度傳遞函數(shù)的轉(zhuǎn)換,包括Gamma2.2,Gamma2.4,PQ,HLG等等。
2.6 色域映射
當涉及到色彩轉(zhuǎn)換或圖像處理時,色域映射是一個重要的概念。它指的是將一個色彩空間中的顏色值映射到另一個色彩空間中的過程。
假設(shè)有一個圖像,它使用BT.2020(一種廣色域)色彩空間進行編碼,但你希望在一個只支持sRGB色彩空間的設(shè)備上顯示這個圖像。由于這兩個色彩空間具有不同的色域范圍,直接將圖像的顏色值轉(zhuǎn)換為sRGB可能會導致顏色失真。在這種情況下,色域映射就派上用場了。色域映射算法會根據(jù)源色彩空間和目標色彩空間的特性,將圖像的顏色值進行適當?shù)霓D(zhuǎn)換,以確保在目標設(shè)備上顯示的圖像顏色盡可能接近原始圖像的顏色。
色域映射的方法一般有兩種,一種是基于Clip的方法,一種是基于壓縮的方法。首先介紹一下基于Clip方法的色域映射。想要做色域映射,首先需要將RGB線性信號轉(zhuǎn)換到XYZ色彩空間,具體轉(zhuǎn)換矩陣可以由r177協(xié)議得到。
比如BT.2020色域的RGB轉(zhuǎn)XYZ的公式如下:
圖片
要將XYZ信號轉(zhuǎn)換為BT.709 RGB信號,使用BT.709的XYZ到RGB的轉(zhuǎn)換矩陣就可以了,如下:
圖片
上述兩步過程就完成了最簡單的色域映射,它將廣色域的BT.2020 RGB轉(zhuǎn)換為了窄色域的BT.709 RGB。但是該方法有一個缺點,當廣色域轉(zhuǎn)換到窄色域會對信號進行截斷(Clip),從而丟失一些色彩信息,導致視頻的有些區(qū)域會過于飽和。一般來說,更好的色域映射方法是通過色域壓縮的方式進行。
色域壓縮可以選擇一個人眼看起來相對均勻的色彩空間進行壓縮,比如CIE Lab,CIE Luv,在飽和度為某個閾值內(nèi)的色彩不進行壓縮,過于飽和的色彩才進行壓縮。在色域壓縮的時候,還需要考慮到色相映射(Hue mapping),如果不考慮色相,信號處理的過程可能會有色偏。有些色域壓縮的算法的復雜度會非常高,甚至需要用GPU來加速。
下圖為BT.2407協(xié)議中一種色域映射后的效果圖,左圖為基于Clip的色域映射,右圖為基于壓縮方法的色域映射,可以看到優(yōu)秀的的色域映射算法可以呈現(xiàn)更豐富的細節(jié),它對最后的效果呈現(xiàn)影響非常大。
Clip方法和色域壓縮方法效果對比圖
我們的轉(zhuǎn)換引擎也實現(xiàn)了一套自研的色域壓縮算法,可以將廣色域的視頻壓縮至sRGB而不會產(chǎn)生色彩溢出,同時也會保留了高飽和區(qū)域的細節(jié)。
2.7 色調(diào)映射(Tone mapping)
HDR圖像包含比傳統(tǒng)SDR圖像更大的亮度范圍,可以捕捉到更多的細節(jié)和光照信息。然而,SDR顯示設(shè)備(如計算機顯示器或手機屏幕)的亮度范圍有限,無法直接顯示HDR圖像中的所有細節(jié)和對比度。這就需要通過色調(diào)映射(Tone mapping)技術(shù)將HDR圖像轉(zhuǎn)換為SDR圖像,使其在常規(guī)顯示設(shè)備上呈現(xiàn)出較好的視覺效果。
下圖展示了不同的Tone mapping算法對圖像的影響,b為原始HDR圖片的色階圖,含有低亮度區(qū)域和高光區(qū)域,c為歸一化(Normalization)方法的進行Tone mapping,雖然c的高光被壓縮了,但是它的暗部細節(jié)也被等比例壓縮,造成暗部細節(jié)丟失。d則是簡單地將高光進行截斷(Clipping),雖然暗部細節(jié)保留了,但是高光細節(jié)丟失了。e表征了一種更高級的方法,既可以保證暗部細節(jié)丟失很少,又可以保留一定的高光細節(jié)。
不同算法對HDR 高光區(qū)域渲染的效果
圖片來源:ITU-R BT.2390-3
基于Clipping和基于壓縮算法的Tone mapping效果
圖片來源:https://www.bilibili.com/video/BV1WA411E7i7
我們對比了幾種常用的Tone mapping算法,并最終選擇了BT.2390協(xié)議中的一種曲線作為我們Tone mapping的指導算法。BT.2390算法的主要思想是將輸入的線性信號轉(zhuǎn)換為PQ空間,以使輸入信號更符合人眼的感知特性。然后設(shè)定了一個閾值,保證小于該閾值的信號盡可能接近原始信號,大于該閾值的信號通過Hermite樣條曲線將其壓縮,從而保證了暗部和高光都丟失比較少的細節(jié)。
通過BT.2390將線性信號壓縮至不同范圍的曲線 圖片來源:ITU-R BT.2390-3
通過色域映射和色調(diào)映射,B站最終實現(xiàn)的HDR轉(zhuǎn)SDR效果如下,可以看到,對比于VLC的效果,B站的效果做到了比較好的色相還原,并且保證了飽和度和亮度不溢出,暗部的細節(jié)也還原得較好。
圖片
圖片
圖片
B站自研HDR轉(zhuǎn)SDR效果(左)與VLC的效果(右)對比
2.8 HDR動態(tài)元數(shù)據(jù)渲染
動態(tài)元數(shù)據(jù)是相對于靜態(tài)元數(shù)據(jù)的一個定義,首先介紹一下靜態(tài)元數(shù)據(jù)。靜態(tài)元數(shù)據(jù)主要包含了整個播放序列的一些參數(shù),包括最高亮度,最大平均亮度,色域信息等。
HDR視頻中靜態(tài)元數(shù)據(jù)不隨著視頻場景的變化而變化,整個播放序列維持著同一個值,終端可以根據(jù)靜態(tài)元數(shù)據(jù)來判斷自身的顯示能力能否顯示視頻內(nèi)容,一般地,優(yōu)秀的顯示軟件會根據(jù)自身的顯示能力對視頻信號進行Tone mapping處理,來保證不丟失高光細節(jié)。
靜態(tài)元數(shù)據(jù)的缺點是顯而易見的,通過靜態(tài)元數(shù)據(jù)進行Tone mapping的方法在整個播放序列中是不變的,以至于它不能適配復雜的場景。有時候它顯示高光細節(jié)是優(yōu)秀的,但卻無法還原暗部細節(jié);有時候它顯示暗部細節(jié)不錯,但顯示高光場景會過曝??偠灾?,通過靜態(tài)元數(shù)據(jù)進行Tone mapping,它無法識別視頻中每個場景的亮度,以至于無法有效地去針對每一個場景進行Tone mapping。
對比靜態(tài)元數(shù)據(jù),動態(tài)元數(shù)據(jù)則靈活很多。在擁有動態(tài)元數(shù)據(jù)的視頻中,視頻中的每個場景甚至每幀都會包含一組元數(shù)據(jù),來標識視頻的亮度信息,它還會對每幀內(nèi)容生成幾組調(diào)色曲線來適配不同亮度的顯示終端。終端在顯示該場景的時候,會根據(jù)自身的顯示能力來渲染調(diào)色曲線,從而讓每個場景,無論是暗部還是亮部,都能得到較完美的顯示,從而避免了暗部細節(jié)和高光細節(jié)的丟失。在服務(wù)端的色彩空間轉(zhuǎn)換模塊中,我們也會根據(jù)HDR的動態(tài)元數(shù)據(jù)來生成下變換后的SDR視頻,這樣生成的SDR視頻也會比全局的Tone mapping算法好很多。
包含HDR動態(tài)元數(shù)據(jù)的視頻主要包括杜比視界和國產(chǎn)高動態(tài)范圍視頻HDR Vivid,目前我們正在推動HDR Vivid在B站的上線。對于HDR Vivid在服務(wù)端的處理,我們除了正常編碼一路HDR Vivid,還會借助引擎中動態(tài)元數(shù)據(jù)渲染的能力,來生成一路SDR視頻,以適配不支持HDR 的手機。
HDR Vivid 視頻在服務(wù)端的轉(zhuǎn)換
3.工程化加速
對于該引擎的工程化加速,我們嘗試了很多辦法,具體大致有如下圖幾種:
工程化加速用到的方法
色彩空間轉(zhuǎn)換中,有很多參數(shù)是需要預先計算的,比如各種矩陣的參數(shù),圖像插值的數(shù)值,亮度傳遞函數(shù)中的一些常數(shù)等等。如果這些參數(shù)在像素處理的時候再去計算會極大地浪費計算資源,所以在引擎初始化的時候就將其計算出來是一個不錯的選擇。除此,在CUDA計算中,矩陣參數(shù)和插值參數(shù)也是需要進行預拷貝處理,這樣可以避免程序在像素處理中進行頻繁拷貝而影響性能。
計算路徑優(yōu)化的主要目的是為了消除重復計算,以找到一個色彩空間到另外一個色彩空間的最優(yōu)轉(zhuǎn)換路徑。舉例來說,如果一個視頻只需要進行range轉(zhuǎn)換,那么我們無需整個轉(zhuǎn)換路徑走一遍,從而避免了額外的色彩轉(zhuǎn)換和電光轉(zhuǎn)換,如下圖:
pc range信號轉(zhuǎn)tv range計算路徑優(yōu)化示意圖
對于CPU優(yōu)化來說,色彩空間轉(zhuǎn)換中的冪運算和矩陣乘法對CPU的消耗很大。為了提高程序的性能,在CPU處理中,我們對頻繁使用的矩陣乘法和冪運算進行了指令集優(yōu)化。這樣的優(yōu)化顯著提升了程序的性能。
在對冪運算進行指令集優(yōu)化的過程中,存在一個難點。常見的編譯器并沒有提供針對冪運算的向量化函數(shù),因此我們需要手動編寫一套冪運算函數(shù)。為了實現(xiàn)冪運算的向量化優(yōu)化,首先將pow函數(shù)寫成形如pow(x, m) = exp(m * log(x))的形式。然后,通過泰勒級數(shù)展開逐步實現(xiàn)了經(jīng)過AVX指令集加速的log(x)和exp(x)函數(shù)。
這種優(yōu)化策略充分利用了指令集的特性,以提高冪運算和矩陣乘法的計算效率。通過手動編寫冪運算函數(shù)并進行向量化優(yōu)化,我們能夠更好地利用CPU的計算能力,從而加速色彩空間轉(zhuǎn)換的處理過程。
除了使用指令集加速,我們還采用了查找表進行優(yōu)化,通過將復雜的計算提前存儲在查找表中,可以顯著減少計算量。
通過使用指令集優(yōu)化和使用查找表優(yōu)化策略,CPU端的性能提升達到如下:
CPU加速策略對性能的提升
將CPU端的代碼進行一系列優(yōu)化后,通過4K視頻在AMD Ryzen 9 5950X上的測試,我們的色彩空間轉(zhuǎn)換引擎的性能達到了如下指標:
CPU端色彩空間轉(zhuǎn)換性能實驗數(shù)據(jù)
對于CUDA端優(yōu)化來說,加速手段主要有C++模板和Kernel融合技術(shù)。由于色彩空間的屬性和種類非常多,需要寫很多if else分支,但是CUDA是天然不支持分支預測功能的,所以我們沒有將很多if else放在核函數(shù)內(nèi)部,而是使用C++模板來編譯kernel函數(shù),這樣可以防止kernel中出現(xiàn)很多分支,從而大大加快了GPU的處理速度。
此外,由于CUDA在執(zhí)行全局內(nèi)存(Gobal memory)的I/O操作時非常耗時,因此我們應避免為每個細小的操作編寫單獨的核函數(shù)(Kernel)。相反,我們可以將一些操作合并到一個核函數(shù)中以減少I/O開銷。例如,我們可以將range轉(zhuǎn)換和量化處理合并為一個核函數(shù),將色彩矩陣轉(zhuǎn)換和亮度傳遞函數(shù)的轉(zhuǎn)換也可以合并為一個核函數(shù)(如下圖所示)。通過合并核函數(shù),我們在一定程度上犧牲了一些通用性,但卻能大大節(jié)省GPU的I/O開銷。這樣做是一個明智的選擇,特別是在涉及I/O操作頻繁的情況下。
色彩空間轉(zhuǎn)換引擎中kernel融合示意圖
通過使用C++模板和使用Kernel融合策略,CUDA端的性能提升達到如下:
CUDA 加速策略對性能的提升
將CUDA端的代碼進行一系列優(yōu)化后,通過4K視頻在RTX2060上的測試,我們的色彩空間引擎轉(zhuǎn)換性能達到了225FPS+(未編碼),對比于CPU端,處理速度得到了很大的提升,詳細數(shù)據(jù)如下表:
CUDA端色彩空間轉(zhuǎn)換性能實驗數(shù)據(jù)(未包含編解碼耗時)
4.總結(jié)與展望
目前,我們的色彩空間轉(zhuǎn)換引擎已經(jīng)穩(wěn)定地在線上為成千上萬的用戶提供服務(wù)。在用戶的觀看體驗中,視頻的色彩質(zhì)量至關(guān)重要。因此,將視頻的色彩準確呈現(xiàn)在用戶眼前一直是我們追求的目標。我們將繼續(xù)致力于優(yōu)化色彩轉(zhuǎn)換效果,以提供更好的用戶體驗。
我們實現(xiàn)了一套HDR轉(zhuǎn)SDR的算法,但是當下并沒有一個好的算法可以準確評估HDR轉(zhuǎn)SDR的效果,像HDR-VDP(一種客觀的圖像質(zhì)量評估方法),它只能評估亮度、對比度、細節(jié)上的質(zhì)量,并無法評估兩張圖像在色度上的差異。色差公式CIEDE2000可以比較兩個像素在亮度、色度、飽和度上的差異,但是由于HDR和SDR之間存在巨大的亮度范圍差異,僅僅使用CIEDE2000公式計算的色差值無法準確反映HDR轉(zhuǎn)SDR后的差異。在實際應用中,評估HDR轉(zhuǎn)SDR的效果通常需要結(jié)合其他指標和方法,如亮部細節(jié)、暗部細節(jié)、色相差異等。結(jié)合這些指標可以更全面地衡量HDR與SDR之間的差異,以便更好地評估轉(zhuǎn)換后的圖像質(zhì)量和觀看體驗。
隨著高動態(tài)范圍的視頻內(nèi)容越來越普及,HDR協(xié)議也在擴充新的標準,最新的高動態(tài)范圍標準主要有杜比視界以及HDR Vivid。其中,HDR Vivid是中國超高清視頻產(chǎn)業(yè)聯(lián)盟發(fā)布的國產(chǎn)高動態(tài)范圍的視頻技術(shù)標準,目前最新的開源框架FFmpeg已經(jīng)集成了HDR Vivid元數(shù)據(jù)的解碼,我們正在將HDR Vivid元數(shù)據(jù)的渲染集成到我們自己的色彩轉(zhuǎn)換引擎中,來支持國產(chǎn)的動態(tài)范圍標準,相信未來的不久,大家就可以在B站客戶端上欣賞到來自國產(chǎn)高動態(tài)范圍標準的視頻了。
本期作者
羅引杰嗶哩嗶哩資深開發(fā)工程師
尹壯 嗶哩嗶哩資深開發(fā)工程師