共用方式為


影片渲染的建議 8 位元 YUV 格式

加里·沙利文和斯蒂芬·埃斯特羅普

Microsoft公司

2002 年 4 月,更新日期為 2008 年 11 月

本主題描述 Windows作系統中針對視訊轉譯所建議的 8 位 YUV 色彩格式。 本文提供在 YUV 和 RGB 格式之間轉換的技術,也提供將 YUV 格式向上取樣的技術。 本文適用於在 Windows 中使用 YUV 視訊譯碼或轉譯的人員。

介紹

整個視訊產業都定義了許多 YUV 格式。 本文會識別 Windows 中針對視訊轉譯所建議的 8 位 YUV 格式。 建議譯碼器廠商和顯示廠商支援本文所述的格式。 本文不會解決 YUV 色彩的其他用途,例如靜止攝影。

本文所述的格式全都使用每個圖元位置 8 位來編碼 Y 通道(也稱為 luma 通道),並使用每個樣本 8 位來編碼每個 U 或 V 色度樣本。 不過,大部分 YUV 格式平均每圖元使用少於 24 位,因為它們的 U 和 V 的樣本比 Y 的少。本文未涵蓋 10 位以上 Y 通道的 YUV 格式。

注意

為了本文的目的,U 一詞相當於 Cb,而 V 一詞相當於 Cr。

 

本文涵蓋下列主題:

YUV 取樣

色度通道的取樣率可能低於 luma 通道,而不會大幅喪失感知品質。 稱為 “A:B:C” 表示法的記號用來描述 U 及 V 相對於 Y 的取樣頻率。

  • 4:4:4 表示沒有色度通道的下取樣。
  • 4:2:2 表示 2:1 水準向下取樣,沒有垂直向下取樣。 每個掃描線每兩個U或 V 樣本都包含四個 Y 樣本。
  • 4:2:0 表示水平方向2:1的向下取樣,垂直方向2:1的向下取樣。
  • 4:1:1 表示 4:1 水準向下取樣,沒有垂直向下取樣。 每個掃描行都包含四個 Y 樣本對應於每個 U 和 V 樣本。 4:1:1 取樣比其他格式不太常見,本文不會詳細討論。

下列圖表顯示了每種下取樣速率的色度取樣方式。 Luma 樣本是以十字表示,色度樣本則以圓形表示。

圖 1。色度取樣

4:2:2 取樣的主要形式定義於建議 BT.601 ITU-R。 4:2:0 取樣有兩種常見的變體。 其中一個用於 MPEG-2 視訊,另一個用於 MPEG-1 和 ITU-T 建議標準 H.261 和 H.263。

相較於 MPEG-1 配置,在 MPEG-2 配置和針對 4:2:2 和 4:4:4 格式定義的取樣方格之間轉換比較簡單。 基於這個理由,MPEG-2 配置在 Windows 中是慣用的,而且應該被視為 4:2:0 格式的默認解譯。

表面定義

本節說明建議用於視訊轉譯的 8 位 YUV 格式。 這些分為數個類別:

首先,您應該注意下列概念,以瞭解下列內容:

  • 表面原點。 針對本文所述的 YUV 格式,原點 (0,0) 一律是表面左上角。
  • Stride。 表面的步幅,有時稱為音調,是表面的寬度,以位元組為單位。 鑒於左上角的表面原點,步幅一律為正數。
  • 對齊。 表面的對齊方式是圖形顯示驅動程式的任意選擇。 表面必須始終對齊至 DWORD; 也就是說,表面內的每一行都保證從32位 (DWORD) 邊界開始。 對齊可能大於32位,不過,這取決於硬體的需求。
  • 包裝格式與平面格式。 YUV 格式分為 打包 格式和 平面 格式。 在封裝格式中,Y、U 和 V 元件會儲存在單一陣列中。 圖元會組織成巨集像素群組,其配置取決於格式。 在平面格式中,Y、U 和 V 元件會儲存為三個不同的平面。

本文所述的每個 YUV 格式都有指派的 FOURCC 程式代碼。 FOURCC 程式代碼是串連四個 ASCII 字元所建立的 32 位無符號整數。

4:4:4 格式,每個像素 32 位元

AYUV

建議使用 FOURCC 代碼 AYUV 的單一 4:4:4 格式。 這是包裝格式,其中每個像素都會編碼為四個連續位元組,並依下圖所示的順序排列。

圖 2。ayuv 記憶體配置

標示為 A 的位元組包含 Alpha 的值。

4:2:2 格式,每個像素 16 位元

建議使用兩種 4:2:2 格式,使用下列 FOURCC 代碼:

  • YUY2
  • UYVY

兩者都是封裝格式,其中每個巨像素是將兩個像素編碼為四個連續位元組。 這會導致色度水準降低兩倍。

YUY2

在 YUY2 格式中,數據可以視為不帶正負號 char 值的陣列,其中第一個字節包含第一個 Y 樣本,第二個字節包含第一個 U (Cb) 樣本,第三個字節包含第二個 Y 樣本,而第四個字節包含第一個 V (Cr) 範例,如下圖所示。

圖 3。yuy2 記憶體配置

如果影像是以小端 WORD 值的陣列格式來存取,則第一個 WORD 包含最小有效位 (LSB) 的第一個 Y 樣本,以及最顯著位 (MSB) 的第一個 U (Cb) 樣本。 第二個 WORD 包含 LSB 中的第二個 Y 範例,以及 MSB 中的第一個 V (Cr) 範例。

YUY2 是 Microsoft DirectX 視訊加速 (DirectX VA) 慣用的 4:2:2 像素格式。 它必須是支援 4:2:2 影片的 DirectX VA 加速器的中期需求。

UYVY

此格式與 YUY2 格式相同,但位元節順序反轉,也就是說,色度和 luma 位元組會翻轉(圖 4)。 如果影像是以兩個字節 WORD 值的數位來尋址,則第一個 WORD 在 MSB 的 LSB 和 Y0 中包含 U,而第二個 WORD 在 MSB 的 LSB 和 Y1 中包含 V。

圖 4。uyvy 記憶體配置

4:2:0 格式,每像素 16 位元

建議使用以下 FOURCC 代碼的兩種 4:2:0 16 位元(bpp)格式:

  • IMC1
  • IMC3

這兩種 YUV 格式都是平面格式。 色度通道會由水平和垂直維度中的兩個因數進行子取樣。

IMC1

所有 Y 範例都會先以無符號 char 值陣列的形式出現在記憶體中。 接著是所有 V (Cr) 樣本,然後是所有 U (Cb) 樣本。 V 和 U 平面的步幅與 Y 平面相同,導致記憶體區域未使用,如圖 5 所示。 U 和 V 平面必須從 16 行倍數的記憶體邊界開始。 圖 5 顯示 352 x 240 視訊畫面的 U 和 V 的來源。 U和平面的起始地址計算如下:

BYTE* pV = pY + (((Height + 15) & ~15) * Stride);
BYTE* pU = pY + (((((Height * 3) / 2) + 15) & ~15) * Stride);

其中 pY 是指向記憶體陣列開頭的位址指標,如下圖所示。

圖 5。imc1 記憶體配置 (範例)

IMC3

此格式與 IMC1 相同,但 U 和 V 分量已互換,如下圖所示。

圖 6。imc3 記憶體配置

4:2:0 格式,每像素 12 位元

建議使用四個 4:2:0 12-bpp 格式,並使用下列 FOURCC 代碼:

  • IMC2
  • IMC4
  • YV12
  • NV12

在所有這些格式中,色度通道都會由水平和垂直維度中的兩個因數進行子取樣。

IMC2

除了下列差異之外,此格式與 IMC1 相同:V (Cr) 和 U (Cb) 線條交錯在半步界限。 換句話說,色度區域中的每個全步線都是以一行 V 樣本開始,後面接著一行 U 樣本,從下一個半步界限開始(圖 7)。 此配置比 IMC1 更有效率地使用地址空間。 它會將色度位址空間削減一半,因此總地址空間會減少 25%。 在 4:2:0 格式中,IMC2 是 NV12 之後的第二個慣用格式。 下方圖片說明此過程。

圖 7。imc2 記憶體配置

IMC4

此格式與 IMC2 相同,但 U(Cb)和 V(Cr)行已互換,如下圖所示。

圖 8。imc4 記憶體配置

YV12

所有 Y 範例都會先以無符號 char 值陣列的形式出現在記憶體中。 此陣列緊接著所有 V (Cr) 範例。 V 平面的步幅是 Y 平面的步幅的一半,且 V 平面中包含的線條數量是 Y 平面的二分之一。 V 平面緊接著所有 U (Cb) 樣本,其步幅和行數與 V 平面相同,如下圖所示。

圖 9。yv12 記憶體配置

NV12

所有 Y 範例都會先以不帶正負號 字元陣列的形式出現在記憶體中, 具有偶數行的值。 Y 平面緊接著一個不帶正負號的 char 陣列,其 值中包含打包的 U (Cb) 和 V (Cr) 樣本。 當合併的U-V陣列被視為小端序 WORD 值的陣列時,LSB 包含U值,而 MSB 則包含 V 值。 NV12 是 DirectX VA 慣用的 4:2:0 像素格式。 預計會成為支援 4:2:0 影片的 DirectX VA 加速器的中期需求。 下圖顯示了 Y 平面和包含排列 U 和 V 樣本的陣列。

圖 10。nv12 記憶體配置

色彩空間範圍和色度取樣率轉換

本節提供在 YUV 與 RGB 之間轉換的指導方針,以及轉換某些不同 YUV 格式的指導方針。 在本節中,我們會考慮兩個 RGB 編碼配置:8 位計算機 RGB,也稱為 sRGB 或「完整縮放」RGB,以及 工作室視訊 RGB,或「具有前端室和 Toe-room 的 RGB」。這些定義如下:

  • 計算機 RGB 會針對每個紅色、綠色和藍色樣本使用 8 位。 黑色以 R = G = B = 0 表示,而白色則以 R = G = B = 255 表示。
  • 工作室視頻 RGB 對每個紅色、綠色和藍色樣本使用某些位數 N,其中 N 為 8 或更大。 工作室影像 RGB 使用不同於電腦 RGB 的縮放比例,並且具有偏移量。 黑色以 R = G = B = 16*2^(N-8) 表示,而白色則以 R = G = B = 235*2^(N-8) 表示。 不過,實際值可能超出此範圍。

在 Windows 中,Studio 視訊 RGB 是首選的 RGB 定義,而在非視訊應用程式中則首選電腦 RGB 定義。 在 RGB 的任一形式中,色度座標如在 ITU-R BT.709 中所指定的,用於定義 RGB 色彩基準。 R、G 和 B 的 (x,y) 座標分別為 (0.64、0.33)、(0.30、0.60)和 (0.15,0.06)。 參考白色是 D65,座標 (0.3127, 0.3290)。 名義伽瑪為 1/0.45 (約 2.2),精確伽瑪定義於 ITU-R BT.709。

RGB 與 4:4:4 YUV 之間的轉換

我們先描述 RGB 與 4:4:4 YUV 之間的轉換。 若要將 4:2:0 或 4:2:2 YUV 轉換成 RGB,建議將 YUV 數據轉換成 4:4:4 YUV,然後將 4:4:4 YUV 轉換成 RGB。 AYUV 格式是一種 4:4:4 格式,每一個 Y、U 和 V 色樣都使用 8 位元。 對於某些應用程式,您也可以使用每個範例 8 個以上的位來定義 YUV。

已為數位視訊定義來自 RGB 的兩個佔主導地位的 YUV 轉換。 兩者都是以稱為 ITU-R Recommendation BT.709 的規格為基礎。 第一個轉換是為 50 Hz 使用而在 BT.709 中定義的較舊 YUV 格式。 它與 ITU-R 建議 BT.601 中指定的關聯相同,也稱為其舊名稱 CCIR 601。 它應該被視為標準解析度電視(720 x 576)和較低解析度視訊的首選 YUV 格式。 其特徵是兩個常數的值,KrKb

Kr = 0.299
Kb = 0.114

在 BT.709 中定義的第二種轉換是針對 60-Hz 使用的較新 YUV 形式,應被視為超過 SDTV 的視訊解析度的首選格式。 其特徵是這兩個常數的不同值:

Kr = 0.2126
Kb = 0.0722

將 RGB 轉換為 YUV 的過程可以從以下步驟開始:

L = Kr * R + Kb * B + (1 - Kr - Kb) * G

接著會取得 YUV 值,如下所示:

Y =                   floor(2^(M-8) * (219*(L-Z)/S + 16) + 0.5)
U = clip3(0, (2^M)-1, floor(2^(M-8) * (112*(B-L) / ((1-Kb)*S) + 128) + 0.5))
V = clip3(0, (2^M)-1, floor(2^(M-8) * (112*(R-L) / ((1-Kr)*S) + 128) + 0.5))

哪裡

  • M 是每個 YUV 範例的位數(M >= 8)。
  • Z 是黑色層級變數。 若為計算機 RGB,Z 等於 0。 若為工作室視訊 RGB,Z 等於 16*2^(N-8),其中 N 是每個 RGB 樣本的位數 (N >= 8)。
  • S 是縮放變數。 若為計算機 RGB,S 等於 255。 若為工作室視訊 RGB,S 等於 219*2^(N-8)。

函式 floor(x) 會傳回小於或等於 x 的最大整數。 函式 clip3(x, y, z) 的定義如下:

clip3(x, y, z) = ((z < x) ? x : ((z > y) ? y : z))

注意

clip3 應該實作為函式,而不是預處理器巨集;否則會導致對參數的多次評估。

 

Y 樣本代表亮度,而 U 和 V 樣本分別代表藍色和紅色的色彩偏差。 Y 的名義範圍是 16*2^(M-8) 到 235*2^(M-8)。 黑色以 16*2^(M-8)表示,白色則以 235*2^(M-8) 表示。 U 和 V 的名義範圍是 16*2^(M-8) 到 240*2^(M-8),值 128*2^(M-8) 代表中性色度。 不過,實際值可能超出這些範圍。

針對以工作室視頻 RGB 格式的輸入數據,必須執行裁剪操作,以保持 U 值和 V 值在 0 到 (2^M)-1 的範圍內。 如果輸入是計算機 RGB,則不需要剪輯作業,因為轉換公式無法產生超出此範圍的值。

這些是沒有近似的確切公式。 本文件後面的所有內容都是基於這些公式。 本節說明下列轉換:

將 RGB888 轉換為 YUV 4:4:4

在計算機 RGB 輸入和 8 位 BT.601 YUV 輸出的情況下,我們相信上一節中提供的公式可以合理近似於下列內容:

Y = ( (  66 * R + 129 * G +  25 * B + 128) >> 8) +  16
U = ( ( -38 * R -  74 * G + 112 * B + 128) >> 8) + 128
V = ( ( 112 * R -  94 * G -  18 * B + 128) >> 8) + 128

這些公式會使用不超過 8 位(不帶正負號)精確度的係數產生 8 位結果。 中間結果最多需要16位的精度。

將8位 YUV 轉換為 RGB888

從原始 RGB 到 YUV 公式,可以衍生 BT.601 的下列關聯性。

Y = round( 0.256788 * R + 0.504129 * G + 0.097906 * B) +  16 
U = round(-0.148223 * R - 0.290993 * G + 0.439216 * B) + 128
V = round( 0.439216 * R - 0.367788 * G - 0.071427 * B) + 128

因此,假設:

C = Y - 16
D = U - 128
E = V - 128

將 YUV 轉換為 RGB 的公式可以衍生如下:

R = clip( round( 1.164383 * C                   + 1.596027 * E  ) )
G = clip( round( 1.164383 * C - (0.391762 * D) - (0.812968 * E) ) )
B = clip( round( 1.164383 * C +  2.017232 * D                   ) )

其中 clip() 表示裁剪至範圍 [0..255]。 我們相信這些公式的近似方式如下:

R = clip(( 298 * C           + 409 * E + 128) >> 8)
G = clip(( 298 * C - 100 * D - 208 * E + 128) >> 8)
B = clip(( 298 * C + 516 * D           + 128) >> 8)

這些公式使用一些係數,需要超過8位的精度來產生每個8位的結果,而中間結果將需要超過16位的精度。

若要將 4:2:0 或 4:2:2 YUV 轉換成 RGB,建議將 YUV 數據轉換成 4:4:4 YUV,然後將 4:4:4 YUV 轉換成 RGB。 下列各節提供將 4:2:0 和 4:2:2 格式轉換成 4:4:4 格式的一些方法。

將 4:2:0 YUV 轉換為 4:2:2 YUV

將 4:2:0 YUV 轉換為 4:2:2 YUV 需要由兩個因素進行垂直向上轉換。 本節說明執行 upconversion 的範例方法。 方法假設影片圖片是漸進式掃描。

注意

4:2:0 到 4:2:2 交錯掃描轉換程式存在非典型問題,難以實作。 本文未解決將交錯掃描從 4:2:0 轉換為 4:2:2:2 的問題。

 

讓輸入色度樣本的每條垂直線構成一個範圍從 0 到 N - 1 的陣列 Cin[]。 輸出影像上的對應垂直線將是陣列 Cout[] 範圍從 0 到 2N - 1。 若要轉換每個垂直線,請執行下列程式:

Cout[0]     = Cin[0];
Cout[1]     = clip((9 * (Cin[0] + Cin[1]) - (Cin[0] + Cin[2]) + 8) >> 4);
Cout[2]     = Cin[1];
Cout[3]     = clip((9 * (Cin[1] + Cin[2]) - (Cin[0] + Cin[3]) + 8) >> 4);
Cout[4]     = Cin[2]
Cout[5]     = clip((9 * (Cin[2] + Cin[3]) - (Cin[1] + Cin[4]) + 8) >> 4);
...
Cout[2*i]   = Cin[i]
Cout[2*i+1] = clip((9 * (Cin[i] + Cin[i+1]) - (Cin[i-1] + Cin[i+2]) + 8) >> 4);
...
Cout[2*N-3] = clip((9 * (Cin[N-2] + Cin[N-1]) - (Cin[N-3] + Cin[N-1]) + 8) >> 4);
Cout[2*N-2] = Cin[N-1];
Cout[2*N-1] = clip((9 * (Cin[N-1] + Cin[N-1]) - (Cin[N-2] + Cin[N-1]) + 8) >> 4);

其中 clip() 表示裁剪至範圍 [0..255]。

注意

處理邊緣的方程式可以數學簡化。 它們以這種形式顯示,以說明圖片邊緣的夾緊效果。

 

實際上,這個方法會藉由將曲線插補到四個相鄰圖元上來計算每個遺漏值,其加權會指向兩個最接近圖元的值(圖 11)。 此範例中使用的特定插值方法是利用一種眾所周知的方法,稱為「Catmull-Rom 插值」,在半整數位置生成遺漏樣點,這亦稱為立方卷積插值。

圖 11。顯示 4:2:0 至 4:2:2 向上取樣的圖表

在信號處理術語中,垂直向上轉換應該理想地包含相位偏移補償,以考慮到 4:2:0 取樣線位置和每隔一條 4:2:2 取樣線之間相對於輸出 4:2:2 取樣網格的半個像素垂直位移。 不過,引入此位移會增加產生樣本所需的處理量,並使得無法從取樣的 4:2:2 影像重建原始的 4:2:0 樣本。 這也使得無法將視訊直接譯碼為 4:2:2 表面,然後使用這些表面作為參考圖片,以譯碼數據流中的後續圖片。 因此,此處提供的方法不會考慮樣本的精確垂直對齊方式。 在適當高的圖片解析度下這樣做可能不會對視覺造成危害。

如果您從使用 H.261、H.263 或 MPEG-1 視訊中定義的取樣網格的 4:2:0 視訊開始,輸出的 4:2:2 色度樣本的相位也會相對於 luma 取樣網格的間距發生半圖元的水平偏移(相對於 4:2:2 色度取樣網格的間距則是四分之一圖元偏移)。 不過,MPEG-2 格式的 4:2:0 視訊可能較常用在電腦上,而不會發生此問題。 此外,在相當高的圖片解析度上,區別可能不會造成視覺上的影響。 嘗試更正此問題會產生與垂直階段位移所討論的相同問題。

將 4:2:2 YUV 轉換為 4:4:4 YUV

將 4:2:2 YUV 轉換為 4:4:4 YUV 需要將水平方向升頻至兩倍。 先前所述的垂直向上轉換方法也可以套用至水平向上轉換。 針對 MPEG-2 和 ITU-R BT.601 影片,此方法會產生具有正確階段對齊方式的範例。

將 4:2:0 YUV 轉換為 4:4:4 YUV

若要將 4:2:0 YUV 轉換為 4:4:4 YUV,您可以直接遵循先前所述的兩種方法。 將 4:2:0 影像轉換為 4:2:2,然後將 4:2:2 影像轉換為 4:4:4: 4。 您也可以切換兩個向上轉換程式的順序,因為作業順序對結果的視覺品質並不重要。

其他 YUV 格式

其他較不常見的 YUV 格式包括下列各項:

  • AI44 是一種具有每個樣本 8 位的調色盤 YUV 格式。 每個樣本都包含 4 個最大有效位 (MSB) 中的索引,以及 4 個最小有效位 (LSB) 中的 Alpha 值。 索引指的是一個包含 YUV 調色板項目的陣列,這些項目必須在格式的媒體類型中定義。 此格式主要用於子圖片影像。
  • NV11 是 4:1:1 平面格式,每像素 12 位。 Y 範例會先出現在記憶體中。 Y 平面後面跟著一系列緊密排列的 U(Cb)和 V(Cr)取樣。 當合併的 U-V 陣列視為小端 WORD 值的陣列時,U 取樣會包含在每個 WORD的 LSB 中,而 V 取樣則包含在 MSB 中。 (雖然色度取樣不同,但此記憶體配置類似於 NV12。
  • Y41P 是一種 4:1:1 打包格式,其中 U 和 V 在水平上每隔四個像素取樣一次。 每個大像素包含於三個字節中的 8 個畫素,並具有下列位元組配置:U0 Y0 V0 Y1 U4 Y2 V4 Y3 Y4 Y5 Y6 Y7
  • Y41T 與 Y41P 相同,但每個 Y 樣本的最小有效位會指定色鍵(0 = 透明,1 = 不透明)。
  • Y42T 與 UYVY 相同,但每個 Y 樣本的最低有效位會指定色鍵(0 = 透明,1 = 不透明)。
  • YVYU 相當於 YUYV,但 U 和 V 採樣是互換的。

在 Media Foundation 中辨識 YUV 格式

本文所述的每個 YUV 格式都有指派的 FOURCC 程式代碼。 FOURCC 程式代碼是串連四個 ASCII 字元所建立的 32 位無符號整數。

有各種 C/C++巨集,可讓您更輕鬆地在原始程式碼中宣告 FOURCC 值。 例如,MAKEFOURCC 巨集是在 Mmsystem.h 中宣告,而 FCC 巨集則會在 Aviriff.h 中宣告。 使用它們,依下列方式:

DWORD fccYUY2 = MAKEFOURCC('Y','U','Y','2');
DWORD fccYUY2 = FCC('YUY2');

您也可以藉由反轉字元的順序,直接將FOURCC程式碼宣告為字串常值。 例如:

DWORD fccYUY2 = '2YUY';  // Declares the FOURCC 'YUY2'

因為 Windows 作業系統使用小端架構,因此需要反轉順序。 'Y' = 0x59、'U' = 0x55,而 '2' = 0x32,因此 '2YUY' 0x32595559。

在 Media Foundation 媒體基礎架構中,格式是由主要類型 GUID 和子類型 GUID 來識別。 電腦視訊格式的主要類型一律MFMediaType_Video 。 子類型可以藉由將FOURCC程式碼對應至 GUID 來建構,如下所示:

XXXXXXXX-0000-0010-8000-00AA00389B71 

其中 XXXXXXXX 是FOURCC程式碼。 因此,YUY2 的子類型 GUID 為:

32595559-0000-0010-8000-00AA00389B71 

最常見的 YUV 格式 GUID 常數定義於頭檔 mfapi.h 中。 如需這些常數的清單,請參閱 Video Subtype GUID

關於 YUV 視訊

視訊媒體類型