2011-10-25 15 views
5

Estoy usando glReadPixels para leer los datos en un CVPixelBufferRef. Uso el CVPixelBufferRef como entrada en un AVAssetWriter. Lamentablemente, los formatos de píxeles parecen no coincidir.Formatos de píxeles, CVPixelBufferRefs y glReadPixels

creo glReadPixels está volviendo datos de píxeles en formato RGBA mientras AVAssetWriter quiere datos de píxeles en formato ARGB. ¿Cuál es la mejor forma de convertir RGBA en ARGB?

Aquí es lo que he probado hasta ahora:

manipulación
  • poco a lo largo de las líneas de ARGB = (RGBA >> 8) | (RGBA < < 24)
  • usando un CGImageRef como un paso intermedio

La manipulación de bits no funcionó porque CVPixelBufferRef no parece apoyar subíndices. El paso intermedio CGImageRef funciona ... pero prefiero no tener 50 líneas adicionales de código que podrían ser un golpe de rendimiento.

+2

¿Cómo está obteniendo su CVPixelBufferRef?¿Estás llamando a CVPixelBufferCreate? Si es así, ¿qué estás pasando como el parámetro pixelFormatType? ¿Qué formato estás pasando a glReadPixels? –

+0

Estoy pasando 'kCVPixelFormatType_32ARGB' a' CVPixelBufferCreate'. Paso 'GL_RBGA' a' glReadPixels'. Traté de pasar un formato RBGA a 'CVPixelBufferCreate', pero no funcionó (los colores no son buenos o la aplicación se bloqueó). – MrDatabase

Respuesta

6

Mejor que el uso de la CPU para intercambiar los componentes sería escribir un simple fragment shader que hacer de manera eficiente en la GPU a medida que renderiza la imagen.

Y la mejor manera es eliminar por completo la etapa de copia utilizando un iOS5 CoreVideo CVOpenGLESTextureCache que le permite pasar directamente a CVPixelBufferRef, eliminando la llamada a glReadPixels.

p.s. Estoy bastante seguro de que AVAssetWriter quiere datos en formato BGRA (en realidad, probablemente lo quiera en youtube, pero esa es otra historia).

ACTUALIZACIÓN: En cuanto a los enlaces, el mana parece estar todavía bajo NDA, pero hay dos trozos de código de ejemplo pueden descargarse libremente disponibles:

GLCameraRipple y RosyWriter

Los archivos de cabecera sí mismos contienen una buena documentación, y el equivalente de mac es muy similar (CVOpenGLTextureCache), por lo que debe tener suficiente para comenzar.

+0

' OpenGLTextureCache' suena increíble. ¿Tiene enlaces a documentos relevantes? – MrDatabase

+1

si tiene un inicio de sesión de ADC puede obtener los documentos, agregó algunos ejemplos código para responder –

+0

¡Parece realmente interesante! Gracias :-) – MrDatabase

2

Es una especie de tiro en la oscuridad, pero ¿ha intentado GL_BGRA para glReadPixels con kCVPixelFormatType_32BGRA para CVPixelBufferCreate?

Sugiero esto porque Technical Q&A QA1501 no enumera ningún formato RGBA como es compatible.

+0

Desafortunadamente al pasar GL_BGRA a 'glReadPixels' hace que los datos del píxel de salida sean todos cero :-( – MrDatabase

6

En cuanto a la manipulación de bits, se puede obtener un puntero a los datos en bruto de la memoria intermedia de píxeles:

CVPixelBufferLockBaseAddress(buffer, 0); 
size_t stride = CVPixelBufferGetBytesPerRow(buffer); 
char *data = (char *)CVPixelBufferGetBaseAddress(buffer); 
for (size_t y = 0; y < CVPixelBufferGetHeight(buffer); ++y) { 
    uint32_t *pixels = (uint32_t *)(data + stride * y); 
    for (size_t x = 0; x < CVPixelBufferGetWidth(buffer); ++x) 
     pixels[x] = (pixels[x] >> 8) | (pixels[x] << 24); 
} 
CVPixelBufferUnlockBaseAddress(buffer, 0); 
1

glReadPixels (0, 0, w * s, h * s, GL_BGRA, GL_UNSIGNED_BYTE, memoria intermedia);

Usa GL_BGRA en glReadPixels. Funciona, solo lo probé yo mismo.

+0

¿Recibió datos distintos de cero? en el buffer de salida? – MrDatabase

+0

GL_BGRA crea una carga de errores opengl. – emrahgunduz

1
glReadPixels(0, 0, width, height, GL_BGRA, GL_UNSIGNED_BYTE, _buffer); 
    CVPixelBufferRef buffer = NULL; 
    CVReturn ret = CVPixelBufferCreateWithBytes(kCFAllocatorDefault,_size.width,_size.height,kCVPixelFormatType_32BGRA,glubyte,_size.width*4,NULL,NULL,NULL,&buffer); 
Cuestiones relacionadas