Поделиться через


Рекомендуемые 8-разрядные форматы YUV для отрисовки видео

Гэри Салливан и Стивен Эстроп

Корпорация Майкрософт

Апрель 2002 г., обновленный ноябрь 2008 г.

В этом разделе описаны 8-разрядные форматы цветов YUV, которые рекомендуется для отрисовки видео в операционной системе Windows. В этой статье представлены методы преобразования между форматами YUV и RGB, а также методы повышения разрешения форматов YUV. Эта статья предназначена для всех пользователей, работающих с декодированием или отрисовкой YUV-видео в Windows.

Введение

Многочисленные форматы YUV определяются во всей видеоиндустрии. В этой статье определены 8-разрядные форматы YUV, рекомендуемые для отрисовки видео в Windows. Поставщики декодеров и дисплеев призываются поддерживать форматы, описанные в этой статье. В этой статье не рассматриваются другие способы использования цвета YUV, такие как фотосъёмка.

Форматы, описанные в этой статье, используют 8 битов на каждую точку пикселя для кодирования канала Y (также называемого каналом яркости) и 8 битов на выборку для кодирования каждого компонента цветности U или V. Однако большинство форматов YUV используют в среднем менее 24 бит на пиксель, так как они содержат меньше выборок каналов U и V, чем Y. В этой статье не рассматриваются форматы YUV с 10-битными или более высокими каналами Y.

Замечание

В целях этой статьи термин U эквивалентен Cb, и термин V эквивалентен Cr.

 

В этой статье рассматриваются следующие разделы:

Выборка YUV

Каналы Chroma могут иметь более низкую частоту выборки, чем канал luma, без каких-либо драматических потерь перцептуального качества. Нотация под названием "A:B:C" используется для описания того, как часто U и V выбираются по отношению к Y.

  • 4:4:4 означает отсутствие понижения цветовых каналов.
  • 4:2:2 означает горизонтальную дискретизацию с коэффициентом 2:1, без вертикальной дискретизации. Каждая строка сканирования содержит четыре примера Y для каждых двух примеров U или V.
  • 4:2:0 означает горизонтальное понижение разрешения соотношением 2:1 и вертикальное понижение в том же соотношении 2:1.
  • 4:1:1 означает горизонтальную субдискретизацию 4:1, без вертикальной субдискретизации. Каждая строка сканирования содержит четыре образца Y для каждого образца U и V. Выборка 4:1:1 менее распространена, чем другие форматы, и подробно не рассматривается в этой статье.

На следующих схемах показано, как цветность дискретизируется для каждой из частот дискретизации. Примеры Luma представлены крестом, а образцы хрома представлены кругом.

рис. 1. Цветовая субдискретизация

Доминирующая форма выборки 4:2:2 определена в ITU-R Рекомендации BT.601. Существует два распространенных варианта выборки 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.

Определения Surface

В этом разделе описываются 8-разрядные форматы YUV, рекомендуемые для отрисовки видео. Они делятся на несколько категорий:

Во-первых, следует учитывать следующие понятия, чтобы понять следующее:

  • Происхождение Surface. Для форматов YUV, описанных в этой статье, источник (0,0) всегда является левым верхним углом поверхности.
  • Шаг. Шаг поверхности, иногда называемый питчем, — это ширина поверхности в байтах. С учетом того, что начало поверхности находится в левом верхнем углу, шаг всегда положительный.
  • Выравнивание. Выравнивание поверхности осуществляется по усмотрению драйвера графического дисплея. Поверхность всегда должна быть выровнена по границе DWORD; то есть отдельные линии в поверхности гарантированно начинаются на 32-битной (DWORD) границе. Однако, в зависимости от потребностей оборудования, выравнивание может быть более 32 бит.
  • Упакованный формат против планарного формата. Форматы YUV делятся на упакованные форматы и планарные форматы. В упакованном формате компоненты Y, U и V хранятся в одном массиве. Пиксели организованы в группы макропикселей, структура которых зависит от формата. В планарном формате компоненты Y, U и V хранятся в виде трех отдельных плоскостей.

Каждый из форматов YUV, описанных в этой статье, имеет назначенный код FOURCC. Код FOURCC — это 32-разрядное целое число без знака, созданное путем объединения четырех символов ASCII.

4:4:4 Форматы, 32 бита на пиксель

AYUV

Рекомендуется использовать один формат 4:4:4 с кодом FOURCC AYUV. Это упакованный формат, в котором каждый пиксель закодирован в виде четырех последовательных байтов, расположенных в последовательности, показанной на следующем рисунке.

рис. 2. Макет памяти ayuv

Байты, помеченные «A», содержат значения для альфа-канала.

4:4:4 Форматы, 24 бита на пиксель

I444

В формате I444 все значения Y сначала отображаются в памяти в виде массива беззнаковых байтов. За этим массивом сразу следуют все образцы U (Cb). Шаг самолета U является тем же шагом плоскости Y; и плоскость U содержит то же количество строк, что и плоскость Y. Следом за плоскостью U сразу идут все образцы V (Cr) с таким же шагом и числом строк, как у плоскости U. Нет заполнения для плоскостей Y/U/V.

Схема, иллюстрирующая макет памяти I444.

4:2:2 Форматы, 16 бит на пиксель

Рекомендуется использовать два формата 4:2:2 со следующими кодами FOURCC:

  • YUY2
  • UYVY

Оба являются упакованными форматами, где каждый макропиксель кодирован в виде четырех последовательных байт. Это приводит к горизонтальному понижению хрома на два фактора.

YUY2

В формате YUY2 данные можно рассматривать как массив неподписанных значений char , где первый байт содержит первый пример Y, второй байт содержит первый пример U (Cb), третий байт содержит второй пример Y, а четвертый байт содержит первый образец V (Cr), как показано на следующей схеме.

Схема, иллюстрирующая макет памяти yuy2

Если изображение рассматривается как массив значений WORD в формате little-endian, первое значение WORD содержит первый образец Y в наименее значимых битах (LSB) и первый образец U (Cb) в наиболее значимых битах (MSB). Второе WORD содержит второй образец Y в LSB и первый образец V (Cr) в MSB.

YuY2 — это предпочтительный формат пикселей 4:2:2 для ускорения видео Microsoft DirectX (VA). Ожидается, что это промежуточное требование для акселераторов VA DirectX, поддерживающих видео 4:2:2.

UYVY

Этот формат совпадает с форматом YUY2, за исключением обратного порядка байтов, то есть chroma и luma байты перевернуты (рис. 4). Если изображение обрабатывается как массив из двух значений младшего порядка байтов WORD, первое WORD содержит U в младших значащих битах и Y0 в старших значащих битах, а второе WORD содержит V в младших значащих битах и Y1 в старших значащих битах.

Схема, иллюстрирующая макет памяти uyvy

I422

В формате I422 все образцы Y сначала появляются в памяти в виде массива значений типа unsigned char. За этим массивом сразу следуют все образцы U (Cb). Шаг плоскости U составляет половину шага плоскости Y; и плоскость U содержит то же количество линий, что и плоскость Y. За плоскостью U сразу же следуют все образцы V (Cr), с таким же шагом и числом строк, как показано на следующем рисунке. Нет заполнения для плоскостей Y/U/V.

Схема, иллюстрирующая макет памяти I422.

4:2:0 Форматы, 16 бит на пиксель

Рекомендуется использовать два формата 4:2:0 16 бит на пиксель (bpp) со следующими кодами FOURCC:

  • IMC1
  • IMC3

Оба этих формата YUV являются планарными форматами. Каналы хрома субдискретизированы с коэффициентом два по горизонтальному и вертикальному направлениям.

IMC1

Все примеры Y сначала отображаются в памяти в виде массива неподписанных значений char . За этим следует все примеры V (Cr), а затем все примеры U (Cb). Плоскости V и U имеют тот же шаг, что и плоскость Y, в результате чего появляются неиспользуемые области памяти, как показано на рис. 5. Плоскости U и V должны начинаться с границ памяти, которые являются кратными 16 строкам. На рисунке 5 показано происхождение U и V для кадра видео размером 352 x 240. Начальные адреса плоскостей U и V вычисляются следующим образом:

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

Где pY — это байтовый указатель на начало массива памяти, как показано на следующей схеме.

Схема, иллюстрирующая макет памяти imc1 (пример)

IMC3

Этот формат идентичен IMC1, за исключением того, что плоскости U и V поменяны местами, как показано на следующей схеме.

Схема, иллюстрирующая макет памяти 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. На следующем рисунке показан этот процесс.

Схема, иллюстрирующая макет памяти imc2

IMC4

Этот формат идентичен IMC2, за исключением того, что порядок U (Cb) и V (Cr) изменён, как показано на следующей иллюстрации.

Схема, иллюстрирующая макет памяти imc4

YV12

Все примеры Y сначала отображаются в памяти в виде массива неподписанных значений char . За этим массивом непосредственно следуют все образцы V (Cr). Шаг V плоскости составляет половину шага плоскости Y; и плоскость V содержит половину строк, как плоскость Y. За плоскостью V сразу же идут все образцы U (Cb) с таким же шагом и количеством строк, как показано на следующем рисунке.

Схема, иллюстрирующая макет памяти yv12

NV12

Все примеры Y сначала отображаются в памяти в виде массива неподписанных значений char с четным числом строк. За плоскостем Y следует сразу массив неподписанных значений char , содержащих упакованные образцы U (Cb) и V (Cr). При обращении к объединенному массиву U-V как к массиву little-endian значений WORD, младшие биты (LSB) содержат значения U, а старшие биты (MSB) содержат значения V. NV12 — это предпочтительный формат пикселей 4:2:0 для DirectX VA. Ожидается, что это промежуточное требование для акселераторов VA DirectX, поддерживающих видео 4:2:0. На следующем рисунке показана Y-плоскость и массив, содержащий упакованные выборки U и V.

Схема, иллюстрирующая макет памяти nv12

Преобразование частоты выборки Chroma и цветового пространства

В этом разделе приведены рекомендации по преобразованию между YUV и RGB и преобразованием между различными форматами YUV. Мы рассмотрим две схемы кодирования RGB в этом разделе: 8-разрядный компьютер RGB, также известный как sRGB или "полномасштабный" RGB , а также "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). Однако фактические значения могут выпасть за пределы этого диапазона.

RGB студийного видео является предпочтительным форматом RGB для видео в Windows, а компьютерное RGB является предпочтительным форматом RGB для приложений, не связанных с видео. В любой форме RGB координаты хроматичности указаны согласно ITU-R BT.709 для определения основных цветов модели RGB. Координаты (x,y) R, G и B : (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, использует 8 бит для примеров Y, U и V. YUV также можно определить с использованием более 8 бит на образец для некоторых приложений.

Для цифрового видео определены два доминирующих преобразования YUV из RGB. Оба основаны на спецификации, известной как рекомендация BT.709 ITU-R. Первое преобразование — это старая форма YUV, определенная для использования с частотой 50 Гц в BT.709. Такое же соотношение, как и в рекомендации ITU-R BT.601, также известной под старым названием CCIR 601. Следует учитывать предпочтительный формат YUV для разрешения телевизора стандартного определения (720 x 576) и видео с более низким разрешением. Он характеризуется значениями двух констант Kr и Kb:

Kr = 0.299
Kb = 0.114

Второе преобразование — это новая форма YUV, определенная для использования с частотой 60 Гц в BT.709, и должна рассматриваться как предпочтительный формат для разрешений видео выше уровня 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-to-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 требует вертикального масштабирования в два раза. В этом разделе описывается пример метода выполнения преобразования вверх. Этот метод предполагает, что изображения видео являются прогрессивным сканированием.

Замечание

Процесс преобразования из 4:2:0 в 4:2:2 представляет нетипичные проблемы и трудно реализуется. В этой статье не рассматривается проблема преобразования чересстрочной развертки с 4:2:0 до 4:2:2.

 

Пусть каждая вертикальная линия входных образцов хромы — это массив Cin[], с диапазоном от 0 до N - 1. Соответствующая вертикальная линия на выходном изображении будет массивом 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 интерполяции, также известного как интерполяция кубической свертки.

Схема, иллюстрирующая повышающую дискретизацию с 4:2:0 на 4:2:2

В терминах обработки сигналов вертикальная конвертация должна в идеале включать компенсацию фазового сдвига, чтобы учитывать вертикальное смещение на полпикселя (относительно выходной сетки дискретизации 4:2:2) между расположениями линий выборки 4:2:0 и расположением каждой второй линии выборки 4:2:2. Однако введение этого смещения приведет к увеличению объема обработки, необходимого для создания образцов, и сделает невозможным восстановление исходных образцов 4:2:0 из апсемплированного изображения 4:2:2. Кроме того, было бы невозможно декодировать видео непосредственно в поверхности 4:2:2, а затем использовать эти поверхности в качестве эталонных рисунков для декодирования последующих рисунков в потоке. Поэтому указанный здесь метод не учитывает точное вертикальное выравнивание выборок. Это, вероятно, не является визуально вредным при достаточно высоких разрешениях рисунков.

Если начать с видео 4:2:0, использующего сетку выборки, определенную в H.261, H.263 или MPEG-1, фаза выходных хрома-сигналов 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. Вы также можете изменить порядок двух процессов преобразования вверх, так как порядок выполнения операций не имеет значения для визуального качества результата.

Преобразование YUY2 в I422

Для цветового формата 4:2:2 некоторые декодеры могут выводить MFVideoFormat_YUY2 по умолчанию, что является упакованным форматом. Однако многие кодировщики ожидают входных данных в планарном формате MFVideoFormat_I422. В таких случаях трансформацию Transcoding Video Processor Media Foundation (обычно называемую "XVP") можно вставить в конвейер обработки для преобразования MFVideoFormat_YUY2 в MFVideoFormat_I422. Дополнительные сведения см. в разделе "Транскодирование видеопроцессоров Media Foundation Transform". В этом примере показано, как использовать XVP для выполнения этого преобразования для рабочих процессов кодирования.

#include <mfapi.h> 
#include <wmcodecdsp.h>  // CLSID_VideoProcessorMFT 

using Microsoft::WRL; 

HRESULT ConvertYUY2toI422WithXVP( 
    _In_ IMFSample* inputSample, 
    _In_ MFT_OUTPUT_DATA_BUFFER* outputBuffer, 
    UINT32 width, 
    UINT32 height)
{ 
    RETURN_HR_IF_NULL(E_INVALIDARG, inputSample);     
    RETURN_HR_IF_NULL(E_INVALIDARG, outputBuffer);     

    ComPtr<IMFTransform> xvp; 
    RETURN_IF_FAILED(CoCreateInstance( 
        CLSID_VideoProcessorMFT, 
        nullptr, 
        CLSCTX_INPROC_SERVER, 
        IID_PPV_ARGS(&xvp))); 

    // Set input type: MFVideoFormat_YUY2 
    ComPtr<IMFMediaType> inputType; 
    RETURN_IF_FAILED(MFCreateMediaType(&inputType)); 
    RETURN_IF_FAILED(inputType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video)); 
    RETURN_IF_FAILED(inputType->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_YUY2)); 
    RETURN_IF_FAILED(MFSetAttributeSize(inputType.Get(), MF_MT_FRAME_SIZE, width, height)); 
    RETURN_IF_FAILED(spXVP->SetInputType(0, inputType.Get(), 0)); 

    // Set output type: MFVideoFormat_I422 
    ComPtr<IMFMediaType> outputType; 
    RETURN_IF_FAILED(MFCreateMediaType(&outputType)); 
    RETURN_IF_FAILED(outputType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video)); 
    RETURN_IF_FAILED(outputType->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_I422)); 
    RETURN_IF_FAILED(MFSetAttributeSize(outputType.Get(), MF_MT_FRAME_SIZE, width, height)); 
    RETURN_IF_FAILED(xvp->SetOutputType(0, outputType.Get(), 0)); 

    // Submit input sample 
    RETURN_IF_FAILED(xvp->ProcessInput(0, inputSample, 0)); 

    // Request the converted output sample 
    DWORD status = 0; 
    return xvp->ProcessOutput(0, 1, outputBuffer, &status);
} 

Преобразование AYUV в I444

Для цветового формата 4:4:4 некоторые декодеры могут выводить MFVideoFormat_AYUV по умолчанию, что является упакованным форматом. Однако многие кодировщики ожидают входных данных в планарном формате MFVideoFormat_I444. В таких случаях в поток обработки можно вставить средство преобразования Media Foundation для транскодирования видео (XVP), чтобы преобразовать MFVideoFormat_AYUV в MFVideoFormat_I444. В этом примере показано, как использовать XVP для выполнения этого преобразования для рабочих процессов кодирования.

#include <mfapi.h> 
#include <wmcodecdsp.h>  // CLSID_VideoProcessorMFT 

using Microsoft::WRL; 

HRESULT ConvertAYUVtoI444WithXVP( 
    _In_ IMFSample* inputSample, 
    _In_ MFT_OUTPUT_DATA_BUFFER* outputBuffer, 
    UINT32 width, 
    UINT32 height) 
{ 
    RETURN_HR_IF_NULL(E_INVALIDARG, inputSample);     
    RETURN_HR_IF_NULL(E_INVALIDARG, outputBuffer);     

    ComPtr<IMFTransform> xvp; 
    RETURN_IF_FAILED(CoCreateInstance( 
        CLSID_VideoProcessorMFT, 
        nullptr, 
        CLSCTX_INPROC_SERVER, 
        IID_PPV_ARGS(&xvp))); 

    // Set input type: MFVideoFormat_AYUV 
    ComPtr<IMFMediaType> inputType; 
    RETURN_IF_FAILED(MFCreateMediaType(&inputType)); 
    RETURN_IF_FAILED(inputType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video)); 
    RETURN_IF_FAILED(inputType->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_AYUV)); 
    RETURN_IF_FAILED(MFSetAttributeSize(inputType.Get(), MF_MT_FRAME_SIZE, width, height)); 
    RETURN_IF_FAILED(xvp->SetInputType(0, inputType.Get(), 0)); 

    // Set output type: MFVideoFormat_I444 
    ComPtr<IMFMediaType> outputType; 
    RETURN_IF_FAILED(MFCreateMediaType(&outputType)); 
    RETURN_IF_FAILED(outputType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video)); 
    RETURN_IF_FAILED(outputType->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_I444)); 
    RETURN_IF_FAILED(MFSetAttributeSize(outputType.Get(), MF_MT_FRAME_SIZE, width, height)); 
    RETURN_IF_FAILED(xvp->SetOutputType(0, outputType.Get(), 0)); 

    // Submit input sample 
    RETURN_IF_FAILED(xvp->ProcessInput(0, inputSample, 0)); 

    // Request the converted output sample 
    DWORD status = 0; 
    return xvp->ProcessOutput(0, 1, outputBuffer, &status); 
} 

Другие форматы YUV

Некоторые другие, менее распространенные форматы YUV включают следующие:

  • AI44 — это палеттизированный формат YUV с 8 битами на выборку. Каждый пример содержит индекс в 4 наиболее значимых битах (MSBS) и альфа-значение в 4 наименее значимых битах (LSBS). Индекс относится к массиву записей палитры YUV, которые должны быть определены в медиатипе для этого формата. Этот формат используется в основном для изображений субкартинок.
  • NV11 — это формат плана 4:1:1 с 12 битами на пиксель. Примеры Y появляются первыми в памяти. За плоскостем Y следует массив упакованных образцов U (Cb) и V (Cr). При адресе объединенного массива U-V в виде массива маленьких значений WORD примеры U содержатся в LSBS каждого WORD, а примеры V содержатся в MSBS. (Эта структура памяти похожа на 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 поменяны местами.

Определение форматов YUV в Media Foundation

Каждый из форматов YUV, описанных в этой статье, имеет назначенный код FOURCC. Код FOURCC — это 32-разрядное целое число без знака, созданное путем объединения четырех символов ASCII.

Существуют различные макросы 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 определяются в файле заголовка mfapi.h. Список этих констант см. в разделе Идентификаторы GUID подтипа видео.

О видео YUV

Типы мультимедиа видео