通过OpenGL处理​​AVCapture输出样本缓冲区的有效方法

时间:2016-05-29 04:48:25

标签: ios iphone camera opengl-es-2.0 avcapture

以下是我要简要介绍的内容: - 使用AVCaptureVideoDataOutputSampleBufferDelegate捕获相机输出 - 然后通过openGL处理​​来自captureOutput委托方法内部的帧。

现在根据Apple的例子,使用这些步骤的方法是:

  • 创建CVOpenGLESTextureCache

  • 使用CVOpenGLESTextureCacheCreateTextureFromImage使用纹理缓存和提供的示例缓冲区创建纹理

  • 通过传递给OpenGL

  • 来处理此纹理
  • 纹理也被释放,纹理缓存每帧刷新

现在,从一开始这似乎不是最有效的方法,但似乎它仍然是做这类事情的最快方法..

但是,我在这里遇到了几个问题,这些问题说明每次采购新的样本缓冲区时都不需要释放和重新创建纹理。

OpenGL ES to video in iOS (rendering to a texture with iOS 5 texture cache)

Faster alternative to glReadPixels in iPhone OpenGL ES 2.0

我已尝试过这种方法,但纹理似乎没有更新。在我的理解中似乎是正确的,因为我不知道纹理将如何自动更新,因为每次都有一个新的样本缓冲区。

我是否正确地理解了这一点,Apple的方法是这样做的,或者是否真的有可能不重新创建纹理并且每次有新的样本缓冲区时仍然更新它?

谢谢!

1 个答案:

答案 0 :(得分:0)

我已经使用了你描述的这种方法并且工作正常。在我的 didOutputSampleBuffer 之后:

CVImageBufferRef cameraFrame = CMSampleBufferGetImageBuffer(sampleBuffer);
    int bufferHeight = (int)CVPixelBufferGetHeight(cameraFrame);
    int bufferWidth = (int)CVPixelBufferGetWidth(cameraFrame);

//clear cache
if (_textureCached) {
     CFRelease(_textureCached);
     _textureCached = NULL;
}
CVOpenGLESTextureCacheFlush(_videoTextureCache, 0);
CVReturn err;
glActiveTexture(GL_TEXTURE0);
err = CVOpenGLESTextureCacheCreateTextureFromImage(kCFAllocatorDefault, _videoTextureCache, cameraFrame, NULL, GL_TEXTURE_2D, GL_RGBA , bufferWidth, bufferHeight, GL_BGRA, GL_UNSIGNED_BYTE, 0, &_textureCached);
glBindTexture(CVOpenGLESTextureGetTarget(_textureCached), CVOpenGLESTextureGetName(_textureCached));

此外,我不会在我的glkView内部调用setNeedsDisplay,这是在didOutputSampleBuffer中。也许这有帮助。