2010-07-29 7 views
10

Ich habe ein Problem mit CGBitmapContextCreateImage in meiner iPhone App.CGBitmapContextCreateImage - vm_copy ist fehlgeschlagen - iPhone SDK

I AV Foundation-Framework bin mit Kamerarahmen mit dieser Methode greifen:

- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection { 
    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); 
    CVPixelBufferUnlockBaseAddress(imageBuffer,0); 
    CGContextRelease(newContext); 
    CGColorSpaceRelease(colorSpace); 

    UIImage *image= [UIImage imageWithCGImage:newImage scale:1.0 orientation:UIImageOrientationRight]; 
    self.imageView.image = image; 

    CGImageRelease(newImage); 

} 

Ich bin jedoch einen Fehler in der Debug-Konsole als seine Läufe zu sehen:

<Error>: CGDataProviderCreateWithCopyOfData: vm_copy failed: status 2. 

Hat jemand jemals das gesehen? Durch Auskommen Linien habe ich das Problem Linie verengt, um:

CGImageRef newImage = CGBitmapContextCreateImage(newContext); 

aber ich bin nicht sicher, wie man es loswerden. Funktional funktioniert es super. Es wird also klarerweise das CGImage erstellt, aber ich muss wissen, was den Fehler verursacht, so dass andere Teile davon nicht betroffen sind.

Vielen Dank. Jede Hilfe/Beratung wäre großartig! Brett

+1

Ich habe das gleiche Problem mit dem gleichen Code. Aber das Problem tritt nur auf iPhone 3G-Geräten auf iOS 4 auf. Es funktioniert ohne Probleme auf einem iPhone 4 oder iPhone 3GS. Kannst du das bestätigen? –

+1

Ich kann bestätigen, dass die unten beschriebene Lösung funktioniert. Ich habe die vm_copy Nachricht auf einem 3G mit iOS 4. – mvds

Antwort

11

Haftungsausschluss: Dies ist reine Spekulation. Nicht mehr.

vm_copy() ist ein Kernel-Aufruf zum Kopieren von virtuellem Speicher von einem Ort zu einem anderen (manpage).

Der zurückgegebene Wert ist KERN_PROTECTION_FAILURE, "Die Quellregion ist schreibgeschützt oder die Zielregion ist schreibgeschützt."

Aus irgendeinem Grund ruft CGDataProviderCreateWithCopyOfData dies auf, um Speicher zu kopieren, und schlägt fehl. vielleicht es ist nur vm_copy als eine schnelle Methode zuerst versuchen, und dann fällt zurück auf eine langsamere Methode (da Sie sagen, alles funktioniert).

Wenn Sie einen Teil des Speichers, den Speicher von baseAddress in Ihren eigenen Speicher memcpy und verwenden, um das Bild zu erstellen, verschwindet die Warnung. Also:

uint8_t *tmp = (uint8_t *)CVPixelBufferGetBaseAddress(imageBuffer); 
int bytes = ... // determine number of bytes from height * bytesperrow 
uint8_t *baseAddress = malloc(bytes); 
memcpy(baseAddress,tmp,bytes); 

// unlock the memory, do other stuff, but don't forget: 
free(baseAddress); 
+0

ps. Ja, ich weiß, dass die Manpage ein zufälliger Link zu Mac OS X ist, aber ich denke, dass es auch für iOS gilt. – mvds