像素格式,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
glReadPixels
与kCVPixelFormatType_32BGRA
的CVPixelBufferCreate
?
我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);