首页 > 解决方案 > 使用本机插件在 Unity3D 中将 YUV 转换为 RGB 的更好方法

问题描述

我有一个在 UI 上播放视频的 Unity3D 应用程序。我发现自己需要找到一种将 YUV 视频缓冲区转换为 RGB 缓冲区的更好方法。我的情况是这样的:

我的 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);
}

标签: c++unity3dgpucpugstreamer

解决方案


推荐阅读