7

glReadPixels用来将数据读入CVPixelBufferRef. 我将CVPixelBufferRef用作 的输入AVAssetWriter。不幸的是,像素格式似乎不匹配。

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

这是我到目前为止所尝试的:

  • 沿 argb = (rgba >> 8) | 行的位操作 (RGB << 24)
  • 使用 aCGImageRef作为中间步骤

位操作不起作用,因为 CVPixelBufferRef 似乎不支持下标。中间CGImageRef步骤确实有效......但我不希望有 50 行可能会影响性能的额外代码。

4

5 回答 5

7

关于位操作,您可以获得指向像素缓冲区原始数据的指针:

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);
于 2011-10-25T22:58:58.253 回答
7

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

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

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

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

GLCameraRippleRosyWriter

头文件本身包含很好的文档,mac 等效文件非常相似(CVOpenGLTextureCache),所以你应该有足够的东西来帮助你开始。

于 2011-10-26T11:38:56.207 回答
2

这有点像在黑暗中拍摄,但你试过GL_BGRAforglReadPixels吗?kCVPixelFormatType_32BGRACVPixelBufferCreate

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

于 2011-10-25T22:35:52.660 回答
1

glReadPixels(0, 0, w*s, h*s, GL_BGRA, GL_UNSIGNED_BYTE, 缓冲区);

在 glReadPixels 中使用 GL_BGRA。可以的,我自己试了一下。

于 2011-11-12T00:06:40.600 回答
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);
于 2012-12-21T20:59:36.837 回答