Эффективный способ обработки выходного буфера Avcapture через OpenGL

Вот что я пытаюсь сделать вкратце:
— выход камеры захвата используя AVCaptureVideoDataOutputSampleBufferDelegate
— затем обработайте кадры изнутри метода делегата captureOutput через openGL.

Теперь в соответствии с примерами Apple, способ получить эту работу с помощью этих шагов:

  • созданиеCVOpenGLESTextureCache

  • использование CVOpenGLESTextureCacheCreateTextureFromImageдля создания текстуры с помощью кэша текстур и предоставленного буфера образцов

  • воздействуя на эту текстуру, перейдя в OpenGL

  • текстура также освобождается и кэш текстур сбрасывается каждый кадр

Теперь, с самого начала, это не кажется самым эффективным способом сделать это, но кажется, что это все еще самый быстрый способ сделать это.

Тем не менее, я наткнулся на пару вопросов здесь, которые говорят о том, что текстуры не должны быть освобождены и воссозданы каждый раз, когда новый образец буфера приобретается.

OpenGL ES to video in iOS (рендеринг в текстуру с помощью кэша текстур iOS 5)

Более быстрая альтернатива glReadPixels в iPhone OpenGL ES 2.0

Я пробовал этот метод, но текстура, кажется, не обновляется. Что, в моем понимании, кажется правильным, так как я не вижу, как текстура будет автоматически обновляться, так как каждый раз есть новый образец буфера.

Правильно ли я понимаю это, и путь Apple-это путь к этому, или действительно возможно не воссоздавать текстуру и все еще обновлять ее каждый раз, когда есть новый образец буфера?

Спасибо!

1 ответ

  1. Я использовал этот метод, который вы описали, и он работал хорошо. В моем 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));
    

    Также я не вызываю setNeedsDisplay в моем glkView внутри didOutputSampleBuffer. Может, это поможет.