残念ながら、個々のウィンドウのフレーム バッファをすばやくキャプチャする方法は見つかりませんでしたが、次善の方法を見つけました。これは、画面全体のライブ ビューを OpenGL にすばやくキャプチャする方法です。
AVFoundation のセットアップ
_session = [[AVCaptureSession alloc] init];
_session.sessionPreset = AVCaptureSessionPresetPhoto;
AVCaptureScreenInput *input = [[AVCaptureScreenInput alloc] initWithDisplayID:kCGDirectMainDisplay];
input.minFrameDuration = CMTimeMake(1, 60);
[_session addInput:input];
AVCaptureVideoDataOutput *output = [[AVCaptureVideoDataOutput alloc] init];
[output setAlwaysDiscardsLateVideoFrames:YES];
[output setSampleBufferDelegate:self queue:dispatch_get_main_queue()];
[_session addOutput:output];
[_session startRunning];
各AVCaptureVideoDataOutput
フレームで
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection {
CVPixelBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
const size_t bufferWidth = CVPixelBufferGetWidth(pixelBuffer);
const size_t bufferHeight = CVPixelBufferGetHeight(pixelBuffer);
CVOpenGLTextureRef texture;
CVOpenGLTextureCacheCreateTextureFromImage(kCFAllocatorDefault, _textureCache, pixelBuffer, NULL, &texture);
CVOpenGLTextureCacheFlush(_textureCache, 0);
// Manipulate and draw the texture however you want...
const GLenum target = CVOpenGLTextureGetTarget(texture);
const GLuint name = CVOpenGLTextureGetName(texture);
// ...
glEnable(target);
glBindTexture(target, name);
CVOpenGLTextureRelease(texture);
}
掃除
[_session stopRunning];
CVOpenGLTextureCacheRelease(_textureCache);
AVCaptureVideoDataOutput
画像をテクスチャとして OpenGL に取り込む他の実装との大きな違いはCVPixelBufferLockBaseAddress
、CVPixelBufferGetBaseAddress
、 、glTexImage2D
、およびCVPixelBufferUnlockBaseAddress
. このアプローチの問題は、通常、非常に冗長で遅いことです。CVPixelBufferLockBaseAddress
渡そうとしているメモリが GPU メモリではないことを確認し、すべてを汎用 CPU メモリにコピーします。これは悪いです!結局のところ、それを GPU にコピーして戻すだけglTexImage2D
です。
CVPixelBuffer
したがって、が既に GPU メモリにあるという事実を利用できますCVOpenGLTextureCacheCreateTextureFromImage
。
これが他の誰かの助けになることを願っています...CVOpenGLTextureCache
スイートはひどく文書化されており、対応するiOSCVOpenGLESTextureCache
はわずかに文書化されているだけです.
2560x1600 のデスクトップをキャプチャする 20% の CPU で 60fps!