2014-03-25 8 views
7

모든 윈도우의 라이브 표현을 집계하려고합니다. Mission Control (Exposé)과 매우 비슷하게, 나는 매우 빠르게에 주어진 NSWindow 또는 화면의 이미지 버퍼에 액세스하려고합니다. 이상적으로, 나는 자신의 OpenGL 컨텍스트에서이 라이브 이미지를 합성하여 (윈도우 화면 캡쳐를 조정하고 움직일 수 있도록) 조작 할 수 있습니다. 너무 느린모든 NSWindows를 Mac OS X의 Mission Control과 같은 활성 이미지로 캡처하십시오.

것들 :

  • CGDisplayCreateImage
  • CGWindowListCreateImage
  • CGDisplayIDToOpenGLDisplayMask & CGLCreateContext & CGBitmapContextCreate

다른 아이디어? 나는 60 fps 캡쳐/합성/출력을 달성하려고 노력하고 있지만,이 방법들 중 어느 것이 든 얻을 수있는 최선의 방법은 ~ 5 fps (전체 화면을 캡쳐하는 망막 디스플레이)입니다.

답변

5

불행히도 개별 창 프레임 버퍼를 빠르게 캡처하는 방법을 찾지 못했지만 다음으로 가장 좋은 점을 파악했습니다. 각 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); 
} 

정리에

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

이 빠르게 OpenGL을로 전체 화면 (들)의 라이브 뷰를 캡처하는 방법입니다

[_session stopRunning]; 
CVOpenGLTextureCacheRelease(_textureCache); 

텍스처들이 CVPixelBufferLockBaseAddress, CVPixelBufferGetBaseAddress, glTexImage2DCVPixelBufferUnlockBaseAddress를 사용할 수있는 그대로의 OpenGL에 AVCaptureVideoDataOutput 이미지를 얻을 다른 구현과 여기에 큰 차이. 이 접근 방식의 문제점은 일반적으로 대단히 중복되고 느린 것입니다. CVPixelBufferLockBaseAddress은 당신에게 건네 주려고하는 메모리가 GPU 메모리가 아닌지 확인하고 범용 CPU 메모리에이 메모리를 모두 복사합니다. 이것은 나쁘다! 결국, 우리는 단지 glTexImage2D으로 GPU에 다시 복사 할 것입니다.

그래서 CVPixelBuffer이 이미 GPU 메모리에 있으며 CVOpenGLTextureCacheCreateTextureFromImage 인 것을 활용할 수 있습니다.

다른 사람들에게 도움이 되었기를 바랍니다 ... CVOpenGLTextureCache 스위트는 끔찍하게 문서화되었으며 iOS 대응 물인 CVOpenGLESTextureCache은 문서화가 약간 개선되었습니다.

2560x1600 데스크톱을 캡처하는 20 % CPU에서 60fps!