2010-07-29 23 views
10

Tengo un problema al utilizar CGBitmapContextCreateImage en mi aplicación de iPhone.CGBitmapContextCreateImage - vm_copy failed - iPhone SDK

estoy usando AV marco de la Fundación para tomar imágenes de cámara usando este método:

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

} 

Sin embargo, estoy viendo un error en la consola de depuración ya que sus carreras:

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

Alguien ha ¿visto esto? Comentando las líneas que he estrechado la línea problema a:

CGImageRef newImage = CGBitmapContextCreateImage(newContext); 

pero no estoy seguro de cómo deshacerse de él. Funcionalmente, funciona genial. Entonces, claramente, se está creando CGImage, pero necesito saber qué está causando el error para que no afecte a otras partes.

Muchas gracias. ¡Cualquier ayuda/consejo sería genial! Brett

+1

Estoy teniendo el mismo problema con el mismo código. Pero el problema solo aparece en los dispositivos iPhone 3G en iOS 4. Funciona sin problemas en un iPhone 4 o iPhone 3GS. ¿Puedes confirmar esto? –

+1

Puedo confirmar que la corrección que presenté a continuación funciona. Recibí el mensaje vm_copy en un 3G con iOS 4. – mvds

Respuesta

11

Descargo de responsabilidad: this is pure speculation. Ya no.

vm_copy() es una llamada al kernel para copiar la memoria virtual de un lugar a otro (manpage).

El valor de retorno que obtiene es KERN_PROTECTION_FAILURE, "La región de origen está protegida contra lectura, o la región de destino está protegida contra escritura".

Por lo tanto, por alguna razón CGDataProviderCreateWithCopyOfData lo llama para copiar algo de memoria y falla. quizás es solo probar vm_copy como un método rápido primero, y luego vuelve a un método más lento (ya que dice que todo funciona).

Si malloc un trozo de memoria, memcpy la memoria de baseAddress en su propia memoria, y la utiliza para crear la imagen, la advertencia desaparece. Entonces:

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

p. sí, sé que la página de manual es un enlace aleatorio sobre Mac OS X, pero supongo que también se aplica a iOS. – mvds