对于整整3天,我一直在尝试改进基于glReadPixels的AVAssetWriter的性能。我已经浏览了Apple的RosyWriter和Camera Ripple代码以及Brad Larson的GPUImage,但我仍然在挠头。我也一直在尝试使用这些链接放下实现:CVOpenGLESTextureCacheCreateTextureFromImage而不是glReadPixels
rendering-to-a-texture-with-ios-5-texture-cache-api
faster-alternative-to-glreadpixels-in-iphone-opengl-es-2-0
...等等,但不管我怎么努力,我只是无法得到它上班。视频最终没有得到处理,或者出现黑屏,或者出现各种错误。我不会在这里完成所有的事情。
为了简化我的问题,我想我会专注于从屏幕上的OpenGL预览FBO抓取快照。如果我能得到这个工作的单一实现,我应该能够解决其余的问题。我尝试从上面的第一个链接看起来像这样的实现:
CVOpenGLESTextureCacheCreate(kCFAllocatorDefault, NULL, [glView context],
NULL, &texCacheRef);
CFDictionaryRef empty = CFDictionaryCreate(kCFAllocatorDefault,
NULL,
NULL,
0,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
CFMutableDictionaryRef attrs = CFDictionaryCreateMutable(kCFAllocatorDefault,
1,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
CFDictionarySetValue(attrs,
kCVPixelBufferIOSurfacePropertiesKey,
empty);
CVPixelBufferRef renderTarget = NULL;
CVPixelBufferCreate(kCFAllocatorDefault,
width,
height,
kCVPixelFormatType_32BGRA,
attrs,
&renderTarget);
CVOpenGLESTextureRef renderTexture;
CVOpenGLESTextureCacheCreateTextureFromImage (kCFAllocatorDefault,
texCacheRef,
renderTarget,
NULL,
GL_TEXTURE_2D,
GL_RGBA,
width,
height,
GL_BGRA,
GL_UNSIGNED_BYTE,
0,
&renderTexture);
CFRelease(attrs);
CFRelease(empty);
glBindTexture(CVOpenGLESTextureGetTarget(renderTexture), CVOpenGLESTextureGetName(renderTexture));
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
GLuint renderFrameBuffer;
glGenRenderbuffers(1, &renderFrameBuffer);
glBindFramebuffer(GL_FRAMEBUFFER, renderFrameBuffer);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D, CVOpenGLESTextureGetName(renderTexture), 0);
//Is this really how I pull pixels off my context?
CVPixelBufferLockBaseAddress(renderTarget, 0);
buffer = (GLubyte *)CVPixelBufferGetBaseAddress(renderTarget);
CVPixelBufferUnlockBaseAddress(renderTarget, 0);
究竟应该发生在这里?我的缓冲区结束了一堆零,所以我想我需要做额外的事情从上下文拉像素? ...或者我错过了什么?
所有我想要实现的是一个快速的等价物是什么我今天使用的:
int pixelsCount = w * h;
buffer = (GLubyte *) malloc(pixelsCount * 4);
glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
在上面的代码中不显示任何实际的渲染。一旦你有你的纹理支持的FBO,并且纹理缓存已经提供了纹理,你需要将你的内容渲染到该FBO中。只有这样你才能从用于支持FBO的纹理读回像素数据。您可能需要在读取缓冲区中的像素数据之前插入'glFinish()',以确保OpenGL ES有足够的时间完成渲染到纹理中。 –
啊,不敢相信我错过了。我在印象之下渲染主FBO就足够了,然后我可以从glReadPixels类似地拉出它。我只是试图用这个替换我的FBO,那就做到了这一点。非常感谢!如果你把你的评论作为回应,我会接受它。 – BlueVoodoo
虽然我知道它的工作原理,但我仍对CVOpenGLESTeureureCacheCreate调用感到困惑。在这里传入的EAGLContext是预期来自另一个FBO,我已经提出了......或者可以使用一个新的上下文以仅渲染一次(直接传递给上述代码中的一个)?只要我使用另一个上下文,我只在我的缓冲区中返回零。 – BlueVoodoo