像素格式、CVPixelBufferRefs 和 glReadPixels
我正在使用 glReadPixels
将数据读入 CVPixelBufferRef
。我使用 CVPixelBufferRef
作为 AVAssetWriter
的输入。不幸的是,像素格式似乎不匹配。
我认为 glReadPixels
返回 RGBA 格式的像素数据,而 AVAssetWriter
想要 ARGB 格式的像素数据。将 RGBA 转换为 ARGB 的最佳方法是什么?
这是我到目前为止所尝试过的:
- 按照 argb = (rgba >> 8) | 行进行位操作(rgba << 24)
- 使用 CGImageRef 作为中间步骤
位操作不起作用,因为 CVPixelBufferRef 似乎不支持下标。 CGImageRef 中间步骤确实有效...但我不希望有 50 行额外的代码,因为这可能会影响性能。
I'm using glReadPixels
to read data into a CVPixelBufferRef
. I use the CVPixelBufferRef
as the input into an AVAssetWriter
. Unfortunately the pixel formats seem to be mismatched.
I think glReadPixels
is returning pixel data in RGBA format while AVAssetWriter
wants pixel data in ARGB format. What's the best way to convert RGBA to ARGB?
Here's what I've tried so far:
- bit manipulation along the lines of argb = (rgba >> 8) | (rgba << 24)
- using a
CGImageRef
as an intermediate step
The bit manipulation didn't work because CVPixelBufferRef doesn't seem to support subscripts. The CGImageRef
intermediate step does work... but I'd prefer not to have 50 extra lines of code that could potentially be a performance hit.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
比使用 CPU 交换组件更好的方法是编写一个简单的片段着色器,以便在渲染图像时在 GPU 上高效地完成此操作。
最好的方法是使用 iOS5 CoreVideo CVOpenGLESTextureCache 完全消除复制阶段,它允许您直接渲染到 CVPixelBufferRef,从而消除对 glReadPixels 的调用。
ps 我很确定 AVAssetWriter 想要 BGRA 格式的数据(实际上它可能想要 yuv 格式的数据,但那是另一个故事了)。
更新:至于链接,doco似乎仍处于NDA之下,但有两段可免费下载的示例代码:
GLCameraRipple 和 RosyWriter
头文件本身包含很好的文档,并且 mac等效项非常相似(CVOpenGLTextureCache),因此您应该有足够的知识来帮助您入门。
Better than using the CPU to swap the components would be to write a simple fragment shader to efficiently do it on the GPU as you render the image.
And the best bestest way is to completely remove the copying stage by using an iOS5 CoreVideo CVOpenGLESTextureCache which allows you to render straight to the CVPixelBufferRef, eliminating the call to glReadPixels.
p.s. I'm pretty sure AVAssetWriter wants data in BGRA format (actually it probably wants it in yuv, but that's another story).
UPDATE: as for links, the doco seems to still be under NDA, but there are two pieces of freely downloadable example code available:
GLCameraRipple and RosyWriter
The header files themselves contain good documentation, and the mac equivalent is very similar (CVOpenGLTextureCache), so you should have plenty to get you started.
关于位操作,您可以获得指向像素缓冲区原始数据的指针:
Regarding the bit manipulation, you can get a pointer to the pixel buffer's raw data:
这有点盲目,但您是否尝试过将
GL_BGRA
用于glReadPixels
并使用kCVPixelFormatType_32BGRA
用于CVPixelBufferCreate
?我建议这样做是因为 技术问答 QA1501 没有列出支持的所有 RGBA 格式。
It's kind of a shot in the dark, but have you tried
GL_BGRA
forglReadPixels
withkCVPixelFormatType_32BGRA
forCVPixelBufferCreate
?I suggest this because Technical Q&A QA1501 doesn't list any RGBA format as supported.
glReadPixels(0, 0, w*s, h*s, GL_BGRA, GL_UNSIGNED_BYTE, 缓冲区);
在 glReadPixels 中使用 GL_BGRA。
确实有效,刚刚亲自尝试过。
glReadPixels(0, 0, w*s, h*s, GL_BGRA, GL_UNSIGNED_BYTE, buffer);
Use GL_BGRA in glReadPixels.
It works, just tried it myself.