2012-09-10 22 views
5

En iOS, estoy usando código para capturar desde AVCaptureStillImageOutput así:¿Por qué jpegStillImageNSDataRepresentation lanza una excepción cuando el buffer de muestra NO es nulo?

[_captureStillOutput captureStillImageAsynchronouslyFromConnection: _captureConnection completionHandler: asyncCaptureCompletionHandler];

por simplicidad a hervir abajo de mi código, mi bloque asyncCaptureCompletionHandler se parece a esto:

void(^asyncCaptureCompletionHandler)(CMSampleBufferRef imageDataSampleBuffer, NSError *error) = 
^(CMSampleBufferRef imageDataSampleBuffer, NSError *error) { 
    if (CMSampleBufferIsValid(imageDataSampleBuffer)) { 
     NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer]; 
     UIImage *image = [[UIImage alloc] initWithData:imageData];                 
    } 
} 

He pasado por todo mi código y referencias cruzadas con el desbordamiento de pila, y no he encontrado ninguna sugerencia de por qué una muestra válida buffer sería capturado sin ser un JPEG correcto.

_captureStillOutput = [[AVCaptureStillImageOutput alloc] init]; 
_captureStillOutput.outputSettings = 
     [NSDictionary dictionaryWithObjectsAndKeys: 
     AVVideoCodecJPEG, AVVideoCodecKey, 
     nil]; 

if ([session canAddOutput:_captureStillOutput]) { 
      [session addOutput:_captureStillOutput]; 
} 

hay información suplementaria en el depurador: * Terminación de aplicación debido a excepción no detectada 'NSInvalidArgumentException', razón: '* + [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:] - No es un tampón de muestra jpeg'.

Las búsquedas en google y el desbordamiento de pila tanto para "No hay un búfer de muestra jpeg" produjeron cero resultados. Estoy atascado. Bah.

Respuesta

0

El siguiente paso para esta solución fue la de registrar todos los datos reportados en el depurador usando:

po imageDataSampleBuffer 

esto siempre produce una gran cantidad de detalles, mientras que la excepción se está lanzando, un montón de información sobre la muestra de amortiguación . Luego, desde que publiqué esto en SO, comenté un código, luego lo descomentaron y ahora está funcionando. Nada cambió en mi código, sin embargo, cerré algunos programas que se ejecutan en el mac. Tal vez fue un error de máquina de desarrollo. Después de esto, cerré y volví a abrir Xcode, y la excepción no se ha lanzado.

+0

Puedo confirmar, un buen '' rm -rf DerivedData/* 'y reiniciar Xcode solucionó este problema para mí. – Austin

+1

En realidad, el problema reapareció pero luego desapareció cuando cerré iTunes. Esta es una muy loca – Austin

+0

Gracias por la nota que reapareció y luego desapareció nuevamente. –

1

Esta pregunta es antigua pero dorada. Vengo del futuro y puedo confirmar que esto todavía sucede en 2015. Traté de seguir los mismos pasos para solucionar el problema, pero fue en vano. Sin embargo, esta pregunta me hizo darme cuenta de que el CMSampleBufferRef imageDataSampleBuffer se comporta de manera extraña cuando se trata fuera del controlador de finalización captureStillImageAsynchronouslyFromConnection.

En pocas palabras:

[self.stillImageOutput captureStillImageAsynchronouslyFromConnection:connection 
                 completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error) 
    { 
     //call another method to handle the sample buffer causes weird behaviour 
     //maybe the buffer is not being safely referenced by AVFoundation? 
     [self handleBufferSomewhereElse:imageDataSampleBuffer]; //will behave strangely 
     //even more so if you move to another thread 
    }]; 

Prefiero hacer esto en vez:

[self.stillImageOutput captureStillImageAsynchronouslyFromConnection:connection 
                 completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error) 
    { 
     //handle the buffer right here 
     NSData *data = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer]; 
     //works better 
    }]; 

Espero que esto ayude a alguien.

Cuestiones relacionadas