Конвертировать YUY2 в YV12

Я почти уверен, что это намного проще, чем я думаю, но я искал интернет гораздо дольше, чем хочу признаться, чтобы попытаться выяснить, как фриг конвертирует эти два формата. Я могу извлечь данные Y0, Cb, Y1, Cr из потока байтов без знака (без знака), но я понятия не имею, как эти байты расположены в YV12 — подразумевается ли в этом документе, что различные значения на самом деле содержатся в разных строках?

Я буквально весь день искал такие вещи, как «c ++ convert YUY2 to YV12», и не нашел абсолютно никаких учебных пособий или примеров кода. Я бы подумал, что это будет какая-то форма документации, которую я мог бы использовать, но информации по этому конкретному вопросу, похоже, мало.

4

Решение

Выглядит как связанная запись на YUY2 вместе с Статья в Википедии о YV12 делает это довольно ясно:

  • YUY2 сохраняет каждые два соседних горизонтальных пикселя как четыре байта, [Y1, U, Y2, V],

  • YV12 хранит весь M × N кадр в непрерывном массиве M*N + 2 * (M/2 * N/2) байт. Давайте назовем массив byte frame[M * N * 3 / 2], У нас есть:

    • frame[i] за i в [0, M * N) являются Y-значения пикселей.
    • frame[j] за j в [M * N, M * N * 5/4) являются В-значения каждой плитки размером 2 × 2 пикселя.
    • frame[j] за k в [M * N * 5/4, M * N * 6/4) являются U-значения каждой плитки размером 2 × 2 пикселя.

Поэтому, когда вы конвертируете из YUY2 в YV12, вы должны вдвое уменьшить U— а также В-данные, возможно, взяв среднее значение двух соседних строк.

Пример:

byte YUY2Source[M * N * 2] = /* source frame */;
byte YV12Dest[M * N * 3/2];

for (unsigned int i = 0; i != M * N; ++i)
{
YV12Dest[i] = YUY2Source[2 * i];
}

for (unsigned int j = 0; j != M * N / 4; ++j)
{
YV12Dest[M * N + j]       = ( YUY2Source[N*(j / N/2    ) + 4 * j + 3]
+ YUY2Source[N*(j / N/2 + 1) + 4 * j + 3] ) / 2;

YV12Dest[M * N * 5/4 + j] = ( YUY2Source[N*(j / N/2    ) + 4 * j + 1]
+ YUY2Source[N*(j / N/2 + 1) + 4 * j + 1] ) / 2;
}
4

Другие решения

  1. Разделите значения Y, U и V на отдельные массивы.
  2. Усредните вместе значения из четных и нечетных строк массивов U и V, чтобы объединить две строки в одну. Это сократит высоту этих массивов пополам. Массив Y будет w * hи теперь массивы U и V будут w/2 * h/2,
  3. Объединить массивы Y, V и U.
3

По вопросам рекламы [email protected]