像素格式,CVPixelBufferRefs和glReadPixels

我使用glReadPixels将数据读入CVPixelBufferRef 。 我使用CVPixelBufferRef作为CVPixelBufferRef的input。 不幸的是,像素格式似乎是不匹配的。

我认为glReadPixels正在返回RGBA格式的像素数据,而AVAssetWriter ARGB格式的像素数据。 将RGBA转换成ARGB的最佳方法是什么?

以下是我迄今为止所尝试的:

  • 按照argb =(rgba >> 8)|的方式进行位操作 (rgba << 24)
  • 使用CGImageRef作为中间步骤

位操作不起作用,因为CVPixelBufferRef似乎不支持下标。 CGImageRef中间步骤可以工作,但是我不希望有50多行代码可能会影响性能。

比使用CPU来交换组件更好的是编写一个简单的片段着色器,以便在渲染图像时在GPU上高效地执行。

最好的方法是使用iOS5 CoreVideo CVOpenGLESTextureCache完全删除复制阶段,它允许您直接渲染到CVPixelBufferRef,从而消除对glReadPixels的调用。

ps我很确定AVAssetWriter需要BGRA格式的数据(实际上它可能需要它在yuv,但这是另一回事)。

更新:至于链接,doco似乎仍然是在NDA下,但有两个免费下载的示例代码可用:

GLCameraRipple和RosyWriter

头文件本身包含很好的文档,而且mac的等价物非常相似(CVOpenGLTextureCache),所以你应该有足够的东西让你开始。

关于位操作,你可以得到一个指向像素缓冲区的原始数据的指针:

 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); 

这是在黑暗中的一种,但你有没有尝试GL_BGRA glReadPixelskCVPixelFormatType_32BGRACVPixelBufferCreate

我build议这是因为技术问答QA1501没有列出支持的任何RGBA格式。

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

在glReadPixels中使用GL_BGRA。 它的作品,只是自己试了一下。

  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);