B站自研色彩空間轉換引擎

架构师修行手册發表於2024-03-07

本期作者


B站自研色彩空間轉換引擎


羅引傑

嗶哩嗶哩資深開發工程師


尹壯

嗶哩嗶哩資深開發工程師

B站自研色彩空間轉換引擎



1. 背景


色彩空間(Color Space)是一種數學模型,用於描述和表示顏色的方式。不同的色彩空間有不同的用途和特點,可以用於不同的應用,如影像處理、計算機圖形、印刷、攝影等領域。它一般用於描述裝置的色彩能力,或者影片、圖片的色彩範圍。比如現在大部分人用的手機的螢幕,色彩空間大多為sRGB或者DCI-P3;網頁上常見的圖片或者影片內容,大多屬於sRGB色彩空間;B站客戶端播放的HDR影片,則處於BT.2020色彩空間。

目前B站UP主投稿影片是千變萬化的,它們包含各種不同的色彩引數, 比如不同的色深,不同的色度取樣座標,不同的色彩空間,不同的亮度傳遞函式等等(如下圖),而且每個使用者觀看這些影片的終端也不一樣,這樣就產生了各種各樣的相容性問題——很多時候使用者的裝置並不能完全正確顯示UP主投稿的“原片”,而且老舊的裝置或者瀏覽器也並不支援廣色域或者HDR影片。為了考慮終端裝置的相容性和B站服務的完整性,我們會對使用者投稿的不同色彩空間的影片進行統一處理。但是如何將各種不同色彩引數的影片進行準確地統一處理,同時又能保證影片的處理速度,這對於我們來說是一個巨大的挑戰。


B站自研色彩空間轉換引擎

色彩空間轉換中需要處理的引數


2. 引擎架構


為了處理各種不同色彩引數的影片,我們研發了一套色彩空間的轉換引擎。該引擎會對各種不同色深、色彩空間、亮度傳遞函式的普通影片統一轉換為標準的SDR影片。除了SDR影片, B站也會接收很多HDR影片投稿,對於HDR投稿,B站會統一轉出一路標準的HDR影片和一路標準的SDR影片。

該影像轉換引擎分為三層,包括濾鏡層,引擎層,和裝置層。其中濾鏡層包含各種濾鏡,用於處理不同的色彩引數。引擎層的主要目的是做一些預計算與計算路徑最佳化,比如有一些矩陣乘法只需要計算一次,那麼就可以預先計算出來,而不是在畫素處理的時候再去做。有一些GPU需要用到的矩陣引數,則也可以進行預複製,防止出現CPU與GPU之間出現頻繁複製的情況,計算路徑最佳化,則是用來去除一些不必要的步驟,來減少計算量。最後,裝置層主要包含每種濾鏡在不同平臺的實現,該引擎包含一個指令集最佳化的X86版本和一個CUDA版本。接下來我介紹一下該濾鏡層的各種色彩轉換能力,包括座標變換、量化、色度取樣,色調對映等等。


B站自研色彩空間轉換引擎

色彩空間處理引擎的基本架構圖


2.1 座標變換


很多時候,使用者投稿的影片會有顯示矩陣(Display matrix),它表示影片被旋轉、被翻轉、或者被轉置。如果我們在服務端檢測到這種影片,那麼就需要對輸入影片按照顯示矩陣進行座標變換。無論是軟解的CPU資料幀還是硬解的CUDA幀,該引擎都能將其準確地渲染出來。


2.2 量化與反量化


訊號的量化主要用於連續的YUV訊號轉為離散的Y’CbCr,而反量化是將輸入影片不同的色深轉換為連續訊號的過程。該引擎支援8bit、10bit、12bit等不同量化精度的Y’CbCr訊號與YUV訊號的互相轉換,同時也支援pc range、tv range的轉換。


2.3 色度取樣


色度取樣(Chroma subsampling)是一種用於減少影像或影片中色度資訊取樣率的技術。在數字影像和影片編碼中,顏色資訊通常由亮度分量(Y)和兩個色度分量(U和V)組成。由於人眼對亮度資訊更加敏感,而對色度資訊的感知相對較弱,因此可以透過減少色度分量的取樣率來降低資料量,同時儘量保持影像或影片的質量。下圖為常見的畫素格式YUV420的取樣座標。

為了色度取樣儘可能平滑,我們採用了雙線性(Bilinear)插值策略進行上取樣和下采樣。例如對YUV420畫素格式的影片進行色度的上取樣, 我們並不會簡單地將一個色度畫素共享給4個亮度畫素, 而是對其進行插值,否則最後輸出的影片會有色度過渡的不均勻。同理,對於色度的下采樣,我們也會採用同樣的插值方法。


B站自研色彩空間轉換引擎

常見的色度取樣座標(4:2:0 chroma format)


2.4 色彩矩陣轉換


影片處理中的一個關鍵引數是色彩矩陣(Color matrix),有時也稱為色彩空間(Color space)。該引數主要用於確定訊號如何轉換為RGB,色彩矩陣轉換是將輸入訊號透過色彩矩陣對映到RGB色彩空間的過程。

舉例來說,常見的BT.709標準就屬於一種色彩矩陣,它指導瞭如何將YUV訊號轉換為RGB,其轉換方式如下:


B站自研色彩空間轉換引擎


為什麼選擇了上述的矩陣而不是其他的呢?這是因為BT.709協議所指定的色彩空間與sRGB相對應,透過sRGB的色域座標可以推匯出上述的轉換矩陣。不同的色彩空間對應不同的轉換矩陣,具體的矩陣根據輸入的色彩矩陣而定。如果需要將R'G'B'轉換為Y'U'V',則需要對上述矩陣進行逆運算。

而對於特殊訊號,例如ICtCp訊號,我們會首先將其轉換為L'M'S'訊號,然後再進行後續的轉換操作。


2.5 亮度傳遞函式轉換


亮度傳遞函式是一種用於調整影像或影片訊號亮度級別的函式,分為兩種OETF(Opto-Electronic Transfer Function)和EOTF(Electro-Optical Transfer Function)。由於人眼對不同光線區域的敏感度不同,人眼對暗部細微亮度變化的敏銳程度較高,而對於高亮度的細微變化則較難察覺。為了以一種均勻的方式呈現訊號,以符合人眼的感知,並且為了能夠編碼更多的資訊,我們需要對訊號進行OETF壓縮。相反地,如果我們需要解壓訊號,則需要進行相反的處理,即EOTF。常見的EOTF曲線有Gamma2.4曲線和感知量化曲線(Perceptual Quantization,PQ),如下圖。感知量化曲線是一種最接近人眼感知的量化方法,因此它也被廣泛用作HDR影片的主要亮度傳遞函式。


B站自研色彩空間轉換引擎

Gamma2.4和PQ的EOTF曲線


在該引擎中,我們實現了十幾種亮度傳遞函式的轉換,包括Gamma2.2,Gamma2.4,PQ,HLG等等。


2.6色域對映


當涉及到色彩轉換或影像處理時,色域對映是一個重要的概念。它指的是將一個色彩空間中的顏色值對映到另一個色彩空間中的過程。

假設有一個影像,它使用BT.2020(一種廣色域)色彩空間進行編碼,但你希望在一個只支援sRGB色彩空間的裝置上顯示這個影像。由於這兩個色彩空間具有不同的色域範圍,直接將影像的顏色值轉換為sRGB可能會導致顏色失真。在這種情況下,色域對映就派上用場了。色域對映演算法會根據源色彩空間和目標色彩空間的特性,將影像的顏色值進行適當的轉換,以確保在目標裝置上顯示的影像顏色儘可能接近原始影像的顏色。

色域對映的方法一般有兩種,一種是基於Clip的方法,一種是基於壓縮的方法。首先介紹一下基於Clip方法的色域對映。想要做色域對映,首先需要將RGB線性訊號轉換到XYZ色彩空間,具體轉換矩陣可以由r177協議得到。

比如BT.2020色域的RGB轉XYZ的公式如下:


B站自研色彩空間轉換引擎


要將XYZ訊號轉換為BT.709 RGB訊號,使用BT.709的XYZ到RGB的轉換矩陣就可以了,如下:


B站自研色彩空間轉換引擎


上述兩步過程就完成了最簡單的色域對映,它將廣色域的BT.2020 RGB轉換為了窄色域的BT.709 RGB。但是該方法有一個缺點,當廣色域轉換到窄色域會對訊號進行截斷(Clip),從而丟失一些色彩資訊,導致影片的有些區域會過於飽和。一般來說,更好的色域對映方法是透過色域壓縮的方式進行。

色域壓縮可以選擇一個人眼看起來相對均勻的色彩空間進行壓縮,比如CIE Lab,CIE Luv,在飽和度為某個閾值內的色彩不進行壓縮,過於飽和的色彩才進行壓縮。在色域壓縮的時候,還需要考慮到色相對映(Hue mapping),如果不考慮色相,訊號處理的過程可能會有色偏。有些色域壓縮的演算法的複雜度會非常高,甚至需要用GPU來加速。

下圖為BT.2407協議中一種色域對映後的效果圖,左圖為基於Clip的色域對映,右圖為基於壓縮方法的色域對映,可以看到優秀的的色域對映演算法可以呈現更豐富的細節,它對最後的效果呈現影響非常大。


B站自研色彩空間轉換引擎

Clip方法和色域壓縮方法效果對比圖


我們的轉換引擎也實現了一套自研的色域壓縮演算法,可以將廣色域的影片壓縮至sRGB而不會產生色彩溢位,同時也會保留了高飽和區域的細節。


2.7 色調對映(Tone mapping)


HDR影像包含比傳統SDR影像更大的亮度範圍,可以捕捉到更多的細節和光照資訊。然而,SDR顯示裝置(如計算機顯示器或手機螢幕)的亮度範圍有限,無法直接顯示HDR影像中的所有細節和對比度。這就需要透過色調對映(Tone mapping)技術將HDR影像轉換為SDR影像,使其在常規顯示裝置上呈現出較好的視覺效果。

下圖展示了不同的Tone mapping演算法對影像的影響,b為原始HDR圖片的色階圖,含有低亮度區域和高光區域,c為歸一化(Normalization)方法的進行Tone mapping,雖然c的高光被壓縮了,但是它的暗部細節也被等比例壓縮,造成暗部細節丟失。d則是簡單地將高光進行截斷(Clipping),雖然暗部細節保留了,但是高光細節丟失了。e表徵了一種更高階的方法,既可以保證暗部細節丟失很少,又可以保留一定的高光細節。


B站自研色彩空間轉換引擎

不同演算法對HDR 高光區域渲染的效果


圖片來源:ITU-R BT.2390-3


B站自研色彩空間轉換引擎
B站自研色彩空間轉換引擎

基於Clipping和基於壓縮演算法的Tone mapping效果


圖片來源:

我們對比了幾種常用的Tone mapping演算法,並最終選擇了BT.2390協議中的一種曲線作為我們Tone mapping的指導演算法。BT.2390演算法的主要思想是將輸入的線性訊號轉換為PQ空間,以使輸入訊號更符合人眼的感知特性。然後設定了一個閾值,保證小於該閾值的訊號儘可能接近原始訊號,大於該閾值的訊號透過Hermite樣條曲線將其壓縮,從而保證了暗部和高光都丟失比較少的細節。


B站自研色彩空間轉換引擎

透過BT.2390將線性訊號壓縮至不同範圍的曲線


圖片來源:ITU-R BT.2390-3

透過色域對映和色調對映,B站最終實現的HDR轉SDR效果如下,可以看到,對比於VLC的效果,B站的效果做到了比較好的色相還原,並且保證了飽和度和亮度不溢位,暗部的細節也還原得較好。


B站自研色彩空間轉換引擎
B站自研色彩空間轉換引擎
B站自研色彩空間轉換引擎
B站自研色彩空間轉換引擎

B站自研HDR轉SDR效果(左)與VLC的效果(右)對比


2.8 HDR動態後設資料渲染


動態後設資料是相對於靜態後設資料的一個定義,首先介紹一下靜態後設資料。靜態後設資料主要包含了整個播放序列的一些引數,包括最高亮度,最大平均亮度,色域資訊等。

HDR影片中靜態後設資料不隨著影片場景的變化而變化,整個播放序列維持著同一個值,終端可以根據靜態後設資料來判斷自身的顯示能力能否顯示影片內容,一般地,優秀的顯示軟體會根據自身的顯示能力對影片訊號進行Tone mapping處理,來保證不丟失高光細節。

靜態後設資料的缺點是顯而易見的,透過靜態後設資料進行Tone mapping的方法在整個播放序列中是不變的,以至於它不能適配複雜的場景。有時候它顯示高光細節是優秀的,但卻無法還原暗部細節;有時候它顯示暗部細節不錯,但顯示高光場景會過曝。總而言之,透過靜態後設資料進行Tone mapping,它無法識別影片中每個場景的亮度,以至於無法有效地去針對每一個場景進行Tone mapping。

對比靜態後設資料,動態後設資料則靈活很多。在擁有動態後設資料的影片中,影片中的每個場景甚至每幀都會包含一組後設資料,來標識影片的亮度資訊,它還會對每幀內容生成幾組調色曲線來適配不同亮度的顯示終端。終端在顯示該場景的時候,會根據自身的顯示能力來渲染調色曲線,從而讓每個場景,無論是暗部還是亮部,都能得到較完美的顯示,從而避免了暗部細節和高光細節的丟失。在服務端的色彩空間轉換模組中,我們也會根據HDR的動態後設資料來生成下變換後的SDR影片,這樣生成的SDR影片也會比全域性的Tone mapping演算法好很多。

包含HDR動態後設資料的影片主要包括杜比視界和國產高動態範圍影片HDR Vivid,目前我們正在推動HDR Vivid在B站的上線。對於HDR Vivid在服務端的處理,我們除了正常編碼一路HDR Vivid,還會藉助引擎中動態後設資料渲染的能力,來生成一路SDR影片,以適配不支援HDR 的手機。


B站自研色彩空間轉換引擎

HDR Vivid 影片在服務端的轉換


3. 工程化加速


對於該引擎的工程化加速,我們嘗試了很多辦法,具體大致有如下圖幾種:


B站自研色彩空間轉換引擎

工程化加速用到的方法


色彩空間轉換中,有很多引數是需要預先計算的,比如各種矩陣的引數,影像插值的數值,亮度傳遞函式中的一些常數等等。如果這些引數在畫素處理的時候再去計算會極大地浪費計算資源,所以在引擎初始化的時候就將其計算出來是一個不錯的選擇。除此,在CUDA計算中,矩陣引數和插值引數也是需要進行預複製處理,這樣可以避免程式在畫素處理中進行頻繁複製而影響效能。

計算路徑最佳化的主要目的是為了消除重複計算,以找到一個色彩空間到另外一個色彩空間的最優轉換路徑。舉例來說,如果一個影片只需要進行range轉換,那麼我們無需整個轉換路徑走一遍,從而避免了額外的色彩轉換和電光轉換,如下圖。


B站自研色彩空間轉換引擎

pc range訊號轉tv range計算路徑最佳化示意圖


對於CPU最佳化來說,色彩空間轉換中的冪運算和矩陣乘法對CPU的消耗很大。為了提高程式的效能,在CPU處理中,我們對頻繁使用的矩陣乘法和冪運算進行了指令集最佳化。這樣的最佳化顯著提升了程式的效能。

在對冪運算進行指令集最佳化的過程中,存在一個難點。常見的編譯器並沒有提供針對冪運算的向量化函式,因此我們需要手動編寫一套冪運算函式。為了實現冪運算的向量化最佳化,首先將pow函式寫成形如pow(x, m) = exp(m * log(x))的形式。然後,透過泰勒級數展開逐步實現了經過AVX指令集加速的log(x)和exp(x)函式。

這種最佳化策略充分利用了指令集的特性,以提高冪運算和矩陣乘法的計算效率。透過手動編寫冪運算函式並進行向量化最佳化,我們能夠更好地利用CPU的計算能力,從而加速色彩空間轉換的處理過程。

除了使用指令集加速,我們還採用了查詢表進行最佳化,透過將複雜的計算提前儲存在查詢表中,可以顯著減少計算量。

透過使用指令集最佳化和使用查詢表最佳化策略,CPU端的效能提升達到如下


B站自研色彩空間轉換引擎

CPU加速策略對效能的提升


將CPU端的程式碼進行一系列最佳化後,透過4K影片在AMD Ryzen 9 5950X上的測試,我們的色彩空間轉換引擎的效能達到了如下指標:


B站自研色彩空間轉換引擎

CPU端色彩空間轉換效能實驗資料


對於CUDA端最佳化來說,加速手段主要有C++模板和Kernel融合技術。由於色彩空間的屬性和種類非常多,需要寫很多if else分支,但是CUDA是天然不支援分支預測功能的,所以我們沒有將很多if else放在核函式內部,而是使用C++模板來編譯kernel函式,這樣可以防止kernel中出現很多分支,從而大大加快了GPU的處理速度。

此外,由於CUDA在執行全域性記憶體(Gobal memory)的I/O操作時非常耗時,因此我們應避免為每個細小的操作編寫單獨的核函式(Kernel)。相反,我們可以將一些操作合併到一個核函式中以減少I/O開銷。例如,我們可以將range轉換和量化處理合併為一個核函式,將色彩矩陣轉換和亮度傳遞函式的轉換也可以合併為一個核函式(如下圖所示)。透過合併核函式,我們在一定程度上犧牲了一些通用性,但卻能大大節省GPU的I/O開銷。這樣做是一個明智的選擇,特別是在涉及I/O操作頻繁的情況下。


B站自研色彩空間轉換引擎

色彩空間轉換引擎中kernel融合示意圖


透過使用C++模板和使用Kernel融合策略,CUDA端的效能提升達到如下


B站自研色彩空間轉換引擎

CUDA 加速策略對效能的提升


將CUDA端的程式碼進行一系列最佳化後,透過4K影片在RTX2060上的測試,我們的色彩空間引擎轉換效能達到了225FPS+(未編碼),對比於CPU端,處理速度得到了很大的提升,詳細資料如下表


B站自研色彩空間轉換引擎

CUDA端色彩空間轉換效能實驗資料(未包含編解碼耗時)


4. 總結與展望


目前,我們的色彩空間轉換引擎已經穩定地線上上為成千上萬的使用者提供服務。在使用者的觀看體驗中,影片的色彩質量至關重要。因此,將影片的色彩準確呈現在使用者眼前一直是我們追求的目標。我們將繼續致力於最佳化色彩轉換效果,以提供更好的使用者體驗。

我們實現了一套HDR轉SDR的演算法,但是當下並沒有一個好的演算法可以準確評估HDR轉SDR的效果,像HDR-VDP(一種客觀的影像質量評估方法),它只能評估亮度、對比度、細節上的質量,並無法評估兩張影像在色度上的差異。色差公式CIEDE2000可以比較兩個畫素在亮度、色度、飽和度上的差異,但是由於HDR和SDR之間存在巨大的亮度範圍差異,僅僅使用CIEDE2000公式計算的色差值無法準確反映HDR轉SDR後的差異。在實際應用中,評估HDR轉SDR的效果通常需要結合其他指標和方法,如亮部細節、暗部細節、色相差異等。結合這些指標可以更全面地衡量HDR與SDR之間的差異,以便更好地評估轉換後的影像質量和觀看體驗。

隨著高動態範圍的影片內容越來越普及,HDR協議也在擴充新的標準,最新的高動態範圍標準主要有杜比視界以及HDR Vivid。其中,HDR Vivid是中國超高畫質影片產業聯盟釋出的國產高動態範圍的影片技術標準,目前最新的開源框架FFmpeg已經整合了HDR Vivid後設資料的解碼,我們正在將HDR Vivid後設資料的渲染整合到我們自己的色彩轉換引擎中,來支援國產的動態範圍標準,相信未來的不久,大家就可以在B站客戶端上欣賞到來自國產高動態範圍標準的影片了。


開發者問答

大家在影片色彩空間的處理中遇到過哪些問題?歡迎在留言區告訴我們。轉發並留言,小編將選取1則最有價值的評論,送出嗶哩嗶哩“一籠好運”新春禮盒(見下圖)。3月8日中午12點開獎。如果喜歡本期內容的話,歡迎點個“在看”吧!


B站自研色彩空間轉換引擎


往期精彩指路

  • 是什麼影響了影片的位元速率

  • B站畫質補完計劃(1):插幀提升《雍正王朝》等影片流暢度

  • B站畫質補完計劃(2):影片超分讓畫素細膩生動


通用工程大前端業務線

大資料AI多媒體



來自 “ ITPUB部落格 ” ,連結:https://blog.itpub.net/70027824/viewspace-3008330/,如需轉載,請註明出處,否則將追究法律責任。

相關文章