У меня есть приложение Unity3D, которое воспроизводит видео в пользовательском интерфейсе. Мне нужно найти лучший способ преобразовать видеобуфер YUV в буфер RGB. Моя ситуация такова:
- Unity3D с изображением пользовательского интерфейса, который воспроизводит видео
- Внешний процесс Gstreamer, который фактически воспроизводит видео
- Aродной плагин, вызываемый из Unity3D для преобразования видеобуфера YUV в RGBA-код
Моя часть кода C ++ / Native, связанная с преобразованием YUV-> RGBA:
unsigned char * rgba = (unsigned char*) obj->g_RgbaBuff;
unsigned char * yuv = (unsigned char*) obj->g_Buffer;
while ( ta < obj->g_BufferLength)
{
int ty = (int)yuv[i];
int tu = (int)yuv[i + 1];
int tY2 = (int)yuv[i + 2];
int tv = (int)yuv[i + 3];
int tp1 = (int)(1.164f * (ty - 16));
int tr = Clamp((int)tp1 + 1.596f * (tv - 128));
int tg = Clamp((int)tp1 - 0.813f * (tv - 128) - 0.391f * (tu - 128));
int tb = Clamp((int)tp1 + 2.018f * (tu - 128));
rgba[ta] = tb;
rgba[ta + 1] = tg;
rgba[ta + 2] = tr;
ta += 4;
int tp2 = (int)(1.164f * (tY2 - 16));
int tr2 = Clamp((int)tp2 + 1.596f * (tv - 128));
int tg2 = Clamp((int)tp2 - 0.813f * (tv - 128) - 0.391f * (tu - 128));
int tb2 = Clamp((int)tp2 + 2.018f * (tu - 128));
rgba[ta] = tb2;
rgba[ta + 1] = tg2;
rgba[ta + 2] = tr2;
ta += 4;
}
Этот код вызывается Unity3D в цикле while для постоянного обновления вывода моего изображения, которое правильно показывает видео. Дело в том, что это действительно медленно. Когда я открываю более одного видео, мой FPS падает с 60 до 30 ниже всего с тремя видео 720p. Есть ли способ сделать это на GPU? Или более разумный способ сделать это. Должен ли я подойти к нему по-другому?
Чтобы визуализировать буфер в текстуру, я использую этот код в своем собственном коде, есть рендеринг, выполняемый каждый кадр с использованием Unity GL.IssuePluginEvent ()
static void ModifyTexturePixels(void* textureHandle, int w, int h, void* rgbaBuff)
{
int textureRowPitch;
glBindTexture(GL_TEXTURE_2D, (GLuint)(size_t)textureHandle);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, rgbaBuff);
}