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

Ios 通过OpenGL处理AVCapture输出样本缓冲区的有效方法,ios,iphone,camera,opengl-es-2.0,avcapture,Ios,Iphone,Camera,Opengl Es 2.0,Avcapture,简单来说,我想做的是: -使用AVCaptureVideoDataOutputSampleBufferDelegate -然后通过openGL处理captureOutput委托方法内部的帧 现在根据苹果的例子,实现这一点的方法是使用以下步骤: 创建CVOpenGLESTextureCache 使用CVOpenGLESTextureCacheCreateTextureFromImage使用纹理缓存和提供的样本缓冲区创建纹理 通过传递到OpenGL对该纹理进行操作 纹理也会被释放,并且纹理缓存会在

简单来说,我想做的是: -使用
AVCaptureVideoDataOutputSampleBufferDelegate
-然后通过openGL处理captureOutput委托方法内部的帧

现在根据苹果的例子,实现这一点的方法是使用以下步骤:

  • 创建
    CVOpenGLESTextureCache

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

  • 通过传递到OpenGL对该纹理进行操作

  • 纹理也会被释放,并且纹理缓存会在每帧刷新一次

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

然而,我在这里遇到了几个问题,这些问题说明了这样一个事实,即每次购买新的样本缓冲区时,不需要释放和重新创建纹理

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

我是否正确地理解了这一点,苹果公司的方法是实现这一点的方法,还是真的有可能不重新创建纹理,并且在每次有新的样本缓冲区时仍对其进行更新


谢谢

我使用了您描述的这种方法,效果很好。在mydidOutputSampleBuffer中,如下所示:

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

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

我使用了您描述的这种方法,效果很好。在mydidOutputSampleBuffer中,如下所示:

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));
此外,我不在didOutputSampleBuffer内的glkView中调用setNeedsDisplay。也许这会有帮助