我正在使用glReadPixels
将数据读入CVPixelBufferRef
。我使用CVPixelBufferRef
作为AVAssetWriter
的输入。不幸的是,像素格式似乎不匹配。
我认为glReadPixels
以 RGBA 格式返回像素数据,而AVAssetWriter
想要 ARGB 格式的像素数据。将 RGBA 转换为 ARGB 的最佳方式是什么?
这是我到目前为止所尝试的内容:
CGImageRef
作为中间步骤位操作不起作用,因为CVPixelBufferRef似乎不支持下标。 CGImageRef
中间步骤确实有效......但我不希望有50行额外的代码可能会影响性能。
答案 0 :(得分:6)
关于位操作,您可以获得指向像素缓冲区原始数据的指针:
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 :(得分:6)
比使用CPU交换组件更好的是编写一个简单的片段着色器,以便在渲染图像时在GPU上有效地执行此操作。
最好的方法是使用iOS5 CoreVideo CVOpenGLESTextureCache完全删除复制阶段,它允许您直接渲染到CVPixelBufferRef,从而消除对glReadPixels的调用。
P.S。我很确定AVAssetWriter想要BGRA格式的数据(实际上它可能想要它在yuv中,但这是另一个故事)。
更新:至于链接,doco似乎仍然在NDA下,但有两个可免费下载的示例代码:
头文件本身包含很好的文档,并且mac等价物非常相似(CVOpenGLTextureCache),所以你应该有足够的东西让你开始。
答案 2 :(得分:2)
这是一个黑暗中的镜头,但您是否GL_BGRA
glReadPixels
kCVPixelFormatType_32BGRA
CVPixelBufferCreate
{?}}?{/ 1>}
我建议这是因为Technical Q&A QA1501没有列出支持的任何RGBA格式。
答案 3 :(得分:1)
glReadPixels(0,0,w * s,h * s,GL_BGRA,GL_UNSIGNED_BYTE,缓冲区);
在glReadPixels中使用GL_BGRA。 它有效,只是自己尝试过。
答案 4 :(得分: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);