CGBitmapContextCreateImage - vm_copy失败 - iPhone SDK

Bre*_*ett 10 iphone objective-c cgimage

我在我的iPhone应用程序中使用CGBitmapContextCreateImage时遇到问题.

我正在使用AV Foundation Framework使用此方法抓取相机帧:

- (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);

} 
Run Code Online (Sandbox Code Playgroud)

但是,我在调试控制台中看到一个错误:

<Error>: CGDataProviderCreateWithCopyOfData: vm_copy failed: status 2.
Run Code Online (Sandbox Code Playgroud)

有没有人见过这个?通过注释掉我的问题,我将问题排成一行:

CGImageRef newImage = CGBitmapContextCreateImage(newContext);
Run Code Online (Sandbox Code Playgroud)

但我不知道如何摆脱它.从功能上讲,它很棒.很明显,CGImage正在创建,但我需要知道是什么导致错误,所以它不会影响其他部分.

非常感谢.任何帮助/建议都会很棒!布雷特

mvd*_*vds 11

免责声明:这是纯粹的猜测.不再.

vm_copy()是一个内核调用,用于将虚拟内存从一个地方复制到另一个地方(联机帮助页).

您获得的返回值是KERN_PROTECTION_FAILURE,"源区域受到保护以防止读取,或者目标区域受到保护以防止写入."

所以由于某种原因CGDataProviderCreateWithCopyOfData调用它来复制一些内存,并失败.也许它只是首先尝试将vm_copy作为快速方法,然后再回到较慢的方法(因为你说一切正常).

如果你malloc是一块内存,将内存从baseAddress记忆到你自己的内存,并使用它来创建图像,警告就会消失.所以:

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);
Run Code Online (Sandbox Code Playgroud)