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