我必须使用 Freescale iMX53 处理器(OpenGL ES 2.0,EGL)上的 AMD GPU 将 YUV420P 图像转换并显示为 RGB 颜色空间。Linux 操作系统,没有 X11。为了实现这一点,我应该能够创建一个包含 YUV420P 数据的适当图像:这可以是 YUV420P/YV12 图像类型或 3 个简单的 8 位图像,每个分量(Y、U、V)一个。
glTexImage2D 被排除在外,因为它很慢,YUV420P 帧是实时视频解码@25FPS 的结果,使用 glTexImage2D 我们无法保持所需的帧速率。
还有一个替代方案:eglCreateImageKHR/glEGLImageTargetTexture2DOES。唯一的问题是这些不能处理任何适合 YUV420/YV12 数据的图像格式。
EGLint attribs[] = {
EGL_WIDTH, 800,
EGL_HEIGHT, 480,
EGL_IMAGE_FORMAT_FSL, EGL_FORMAT_YUV_YV12_FSL,
EGL_NONE
};
EGLint const req_attribs[] = {
EGL_RED_SIZE, 5,
EGL_GREEN_SIZE, 6,
EGL_BLUE_SIZE, 5,
EGL_ALPHA_SIZE, 0,
EGL_SAMPLES, 0,
EGL_COLOR_BUFFER_TYPE, EGL_RGB_BUFFER,
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
EGL_NONE
};
...
display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
eglInitialize(display, NULL, NULL);
eglBindAPI(EGL_OPENGL_ES_API);
eglChooseConfig(display, req_attribs, config, ARRAY_SIZE(config), &num_configs);
ctx = eglCreateContext(display, curr_config, NULL, NULL);
surface = eglCreateWindowSurface(display, curr_config, fb_handle, NULL);
...
EGLImageKHR yuv_img = eglCreateImageKHR(display, EGL_NO_CONTEXT, EGL_NEW_IMAGE_FSL, NULL, attribs);
eglQueryImageFSL(display, yuv_img, EGL_CLIENTBUFFER_TYPE_FSL, (EGLint *)&ptr);
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, yuv_img);
glEGLImageTargetTexture2DOES(...) 失败。如果我将“attribs”中的相应行更改为:
EGL_IMAGE_FORMAT_FSL、EGL_FORMAT_RGB_565_FSL、
然后可以将图像分配给 OpenGL ES 纹理,但不适合保存 8 位数据 (Y/U/V) 或 YUV420/YV12 数据。搜索网络(包括飞思卡尔社区论坛)我还没有找到任何解决方案。
如何创建一个图像:
- 快速创建;
- 最终可以分配给一个已经存在的缓冲区(给定物理地址或虚拟地址);
- 可用于片段/顶点着色器程序中进行 YUV --> RGB 转换;
约束是为了避免由于性能原因不必要的 memcpy(...)s。