CGBitmapContextCreateImage - ошибка vm_copy - iPhone SDK - PullRequest
10 голосов
/ 30 июля 2010

У меня проблема с использованием CGBitmapContextCreateImage в приложении для iPhone.

Я использую 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);

} 

Однако я вижуошибка в консоли отладки при ее запуске:

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

Кто-нибудь когда-либо видел это?Комментируя строки, я сузил строку проблемы до:

CGImageRef newImage = CGBitmapContextCreateImage(newContext);

, но я не уверен, как от нее избавиться.Функционально работает отлично.Ясно, что CGImage создается, но мне нужно знать, что является причиной ошибки, чтобы она не влияла на другие части.

Большое спасибо.Любая помощь / совет будет отличным!Brett

1 Ответ

11 голосов
/ 30 июля 2010

Отказ от ответственности: это чистое предположение. Больше нет.

vm_copy() - это вызов ядра для копирования виртуальной памяти из одного места в другое ( manpage ).

Возвращаемое значение: 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);
...