2010-11-20 6 views
1

Ich versuche AVCaptureSession zu verwenden, um Bilder von der Frontkamera zur Verarbeitung zu erhalten. Bisher habe ich jedes Mal, wenn ein neuer Frame verfügbar war, diesen einfach einer Variablen zugewiesen und einen NSTimer ausgeführt, der jede Zehntelsekunde prüft, ob es einen neuen Frame gibt und ob dieser verarbeitet wird.Wie erfassen Sie nur ausgewählte Kamerabilder mit AVCaptureSession?

Ich würde gerne einen Rahmen bekommen, die Kamera einfrieren und den nächsten Frame bekommen, wann immer ich möchte. Etwas wie [captureSession getNextFrame] weißt du?

Hier ist ein Teil meines Codes, obwohl ich nicht sicher bin, wie nützlich es sein kann:

- (void)startFeed { 

loopTimerIndex = 0; 

    NSArray *captureDevices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]; 

    AVCaptureDeviceInput *captureInput = [AVCaptureDeviceInput 
              deviceInputWithDevice:[captureDevices objectAtIndex:1] 
              error:nil]; 

    AVCaptureVideoDataOutput *captureOutput = [[AVCaptureVideoDataOutput alloc] init]; 
    captureOutput.minFrameDuration = CMTimeMake(1, 10); 
    captureOutput.alwaysDiscardsLateVideoFrames = true; 

    dispatch_queue_t queue; 
    queue = dispatch_queue_create("cameraQueue", nil); 

    [captureOutput setSampleBufferDelegate:self queue:queue]; 
    dispatch_release(queue); 

    NSString *key = (NSString *)kCVPixelBufferPixelFormatTypeKey; 
    NSNumber *value = [NSNumber numberWithUnsignedInt:kCVPixelFormatType_32BGRA]; 
    NSDictionary *videoSettings = [NSDictionary dictionaryWithObject:value forKey:key]; 
    [captureOutput setVideoSettings:videoSettings]; 

    captureSession = [[AVCaptureSession alloc] init]; 
    captureSession.sessionPreset = AVCaptureSessionPresetLow; 
    [captureSession addInput:captureInput]; 
    [captureSession addOutput:captureOutput]; 

    imageView = [[UIImage alloc] init]; 

    [captureSession startRunning]; 

} 

- (void)captureOutput:(AVCaptureOutput *)captureOutput 
didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer 
     fromConnection:(AVCaptureConnection *)connection { 

loopTimerIndex++; 

    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 

    CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer); 
    CVPixelBufferLockBaseAddress(imageBuffer, 0); 

    uint8_t *baseAddress = (uint8_t *)CVPixelBufferGetBaseAddress(imageBuffer); 
    size_t bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer); 
    size_t width = CVPixelBufferGetWidth(imageBuffer); 
    size_t height = CVPixelBufferGetHeight(imageBuffer); 

    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 
    CGContextRef newContext = CGBitmapContextCreate(baseAddress, width, height, 8, bytesPerRow, colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst); 
    CGImageRef newImage = CGBitmapContextCreateImage(newContext); 

    CGContextRelease(newContext); 
    CGColorSpaceRelease(colorSpace); 

    imageView = [UIImage imageWithCGImage:newImage scale:1.0 orientation:UIImageOrientationLeftMirrored]; 
    [delegate updatePresentor:imageView]; 
    if(loopTimerIndex == 1) { 
     [delegate feedStarted]; 
    } 

    CGImageRelease(newImage); 
    CVPixelBufferUnlockBaseAddress(imageBuffer, 0); 

    [pool drain]; 

} 

Antwort

3

Sie nicht aktiv die Kamera abfragen Frames zurück zu bekommen, weil das nicht ist, wie der Capture-Prozess ist architekturiert. Wenn Sie stattdessen nur jede Zehntelsekunde statt jeder 1/30 Sekunde oder schneller anzeigen möchten, sollten Sie die dazwischen liegenden Frames ignorieren.

Sie könnten z. B. einen Zeitstempel erstellen, den Sie vergleichen würden, wenn -captureOutput:didOutputSampleBuffer:fromConnection: ausgelöst wurde. Wenn der Zeitstempel größer oder gleich 0,1 Sekunden von jetzt an ist, verarbeiten und zeigen Sie den Kamerarahmen an und setzen Sie den Zeitstempel auf die aktuelle Zeit zurück. Ansonsten ignoriere den Frame.

Verwandte Themen