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

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

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

2 ответа

Решение

Похоже, что связанная запись на 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) являются V- значениями каждого фрагмента размером 2 × 2 пикселя.
    • frame[j] за k в [M * N * 5/4, M * N * 6/4) являются значениями U каждого тайла размером 2 × 2 пикселя.

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

Пример:

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;
}
  1. Разделите значения Y, U и V на отдельные массивы.
  2. Усредните вместе значения из четных и нечетных строк массивов U и V, чтобы объединить две строки в одну. Это сократит высоту этих массивов пополам. Массив Y будет w * hи теперь массивы U и V будут w/2 * h/2,
  3. Объединить массивы Y, V и U.
Другие вопросы по тегам