整整 3 天,我一直在尝试提高基于 glReadPixels 的 AVAssetWriter 的性能。我已经浏览了 Apple 的 RosyWriter 和 Camera Ripple 代码以及 Brad Larson 的 GPUImage,但我仍然摸不着头脑。我也一直在尝试使用这些链接中的实现:
使用 ios-5-texture-cache-api 渲染到纹理
iphone-opengl-es-2-0 中的更快替代 glreadpixels
......还有更多,但无论我尝试什么,我都无法让它发挥作用。视频最终没有被处理,或者出现黑色,或者我收到各种错误。我不会在这里介绍所有内容。
为了简化我的问题,我想我会专注于从屏幕上的 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);