textura para la conversión de YUV420 a RGB en OpenGL ES
opengl-es gpu (1)
Lo he implementado en el i.MX53 para varios formatos YUV y funciona muy bien. Tengo un artículo publicado al respecto, aunque se generalizó para abarcar más plataformas Android:
http://software.intel.com/en-us/articles/using-opengl-es-to-accelerate-apps-with-legacy-2d-guis
Sospecho que tu problema es que no estás vinculado al objetivo de textura correcto. Debería ser así:
glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, hEglImage[iTextureIndex]);
glBindTexture(GL_TEXTURE_EXTERNAL_OES, hTexture[iIndex]);
Y el eglImageAttributes debería ser uno de estos:
EGLint eglImageAttributes[] = {EGL_WIDTH, iTextureWidth, EGL_HEIGHT, iTextureHeight, EGL_IMAGE_FORMAT_FSL, EGL_FORMAT_YUV_YV12_FSL, EGL_NONE};
EGLint eglImageAttributes[] = {EGL_WIDTH, iTextureWidth, EGL_HEIGHT, iTextureHeight, EGL_IMAGE_FORMAT_FSL, EGL_FORMAT_YUV_NV21_FSL, EGL_NONE};
EGLint eglImageAttributes[] = {EGL_WIDTH, iTextureWidth, EGL_HEIGHT, iTextureHeight, EGL_IMAGE_FORMAT_FSL, EGL_FORMAT_YUV_UYVY_FSL, EGL_NONE};
hEglImage[iTextureIndex] = eglCreateImageKHR(eglDisplay, EGL_NO_CONTEXT, EGL_NEW_IMAGE_FSL, NULL, eglImageAttributes);
struct EGLImageInfoFSL EglImageInfo;
eglQueryImageFSL(eglDisplay, hEglImage[iTextureIndex], EGL_CLIENTBUFFER_TYPE_FSL, (EGLint *)&EglImageInfo);
Aunque esta característica de la plataforma Freescale i.MX53 hace que la conversión de espacio de color de YUV a RGB para video sea extremadamente rápida, tiene algunas limitaciones:
- Solo admite esos 3 formatos de YUV.
- eglCreateImageKHR () debe asignar los búferes. No hay forma de hacer que use los búferes existentes. Freescale confirmó que el puntero NULL no puede ser otra cosa, lo que técnicamente infringe la especificación de Khronos.
Freescale ha resuelto estos problemas en la plataforma i.MX6, aunque la arquitectura es realmente diferente. Espero que esto ayude.
Tengo que convertir y visualizar imágenes YUV420P en el espacio de color RGB usando la GPU AMD en un procesador Freescale iMX53 (OpenGL ES 2.0, EGL). Sistema operativo Linux, no X11. Para lograr esto, debería ser capaz de crear una imagen apropiada que contenga los datos del YUV420P: podría ser un tipo de imagen YUV420P / YV12 o 3 imágenes simples de 8 bits, una para cada componente (Y, U, V).
glTexImage2D está excluido porque es lento, las tramas YUV420P son el resultado de una decodificación de video en tiempo real a 25FPS y con glTexImage2D no podemos mantener la tasa de fotogramas deseada.
Hay una alternativa: eglCreateImageKHR / glEGLImageTargetTexture2DOES. El único problema es que no pueden manejar ningún formato de imagen que sea adecuado para los datos de 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 (...) falla. Si cambio la línea apropiada en ''attribs'' a esto:
EGL_IMAGE_FORMAT_FSL, EGL_FORMAT_RGB_565_FSL,
luego, la imagen se puede asignar a una textura OpenGL ES, pero no es apropiado que contenga datos de 8 bits (Y / U / V) o datos YUV420 / YV12. Buscando en la red (incluido el foro de la comunidad de Freescale) No he encontrado ninguna solución para esto.
¿Cómo puedo crear una imagen que:
- es rápido de crear;
- eventualmente puede asignarse a un búfer ya existente (se proporciona una dirección física o una dirección virtual);
- se puede usar en el programa de sombreador de fragmentos / vértices para realizar la conversión YUV -> RGB;
Restricción es evitar memcpy (...) innecesarios debido a razones de rendimiento.