У меня есть собственный плагин в Unity, который декодирует кадры H264 в YUV420p с помощью FFMPEG.
Чтобы отобразить выходное изображение, я переставляю значения YUV в текстуру RGBA и преобразую YUV в RGB с помощью шейдера Unity (просто, чтобы сделать его быстрее).
Ниже приведен код перестановки в моем родном плагине:
unsigned char* yStartLocation = (unsigned char*)m_pFrame->data[0];
unsigned char* uStartLocation = (unsigned char*)m_pFrame->data[1];
unsigned char* vStartLocation = (unsigned char*)m_pFrame->data[2];
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
unsigned char* y = yStartLocation + ((y * width) + x);
unsigned char* u = uStartLocation + ((y * (width / 4)) + (x / 2));
unsigned char* v = vStartLocation + ((y * (width / 4)) + (x / 2));
//REF: https://en.wikipedia.org/wiki/YUV
// Write the texture pixel
dst[0] = y[0]; //R
dst[1] = u[0]; //G
dst[2] = v[0]; //B
dst[3] = 255; //A
// To next pixel
dst += 4;
// dst is the pointer to target texture RGBA data
}
}
Шейдер, который конвертирует YUV в RGB, отлично работает, и я использовал его в нескольких проектах.
Теперь я использую тот же код для декодирования на платформе iOS. Но по какой-то причине значения U и V теперь смещены:
Y Текстура
U Текстура
Есть что-то, чего мне не хватает специально для iOS или OpenGL?
Любая помощь с благодарностью.
Спасибо!
Обратите внимание, что я заполнил R = G = B = Y для первого снимка экрана и U для второго (если это имеет смысл)
Edit:
Вот вывод, который я получаю:
Edit2:
Основываясь на некоторых исследованиях, я думаю, что это как-то связано с чересстрочной разверткой.
ref: Ссылка
На данный момент я перешел на преобразование YUV-RGB на базе процессора с использованием sws_scale, и оно работает нормально.