對於整整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