1

整整 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);
4

1 回答 1

1

正如布拉德指出的那样,我误解了这个概念并且没有进行任何实际渲染。当我添加它时工作正常。

于 2012-10-10T10:43:27.177 回答