Почему jpegStillImageNSDataRepresentation генерирует исключение, когда буфер образца НЕ равен NULL?
В iOS я использую код для захвата из AVCaptureStillImageOutput таким образом:
[_captureStillOutput captureStillImageAsynchronouslyFromConnection: _captureConnection дополнения Handler: asyncCaptureCompletionHandler];
для простоты, чтобы свести мой код, мой блок asyncCaptureCompletionHandler выглядит так:
void(^asyncCaptureCompletionHandler)(CMSampleBufferRef imageDataSampleBuffer, NSError *error) =
^(CMSampleBufferRef imageDataSampleBuffer, NSError *error) {
if (CMSampleBufferIsValid(imageDataSampleBuffer)) {
NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];
UIImage *image = [[UIImage alloc] initWithData:imageData];
}
}
Я прошел через весь мой код и перекрестные ссылки с переполнением стека, и не нашел никаких предположений, почему действительный образец буфера будет захвачен без надлежащего JPEG.
_captureStillOutput = [[AVCaptureStillImageOutput alloc] init];
_captureStillOutput.outputSettings =
[NSDictionary dictionaryWithObjectsAndKeys:
AVVideoCodecJPEG, AVVideoCodecKey,
nil];
if ([session canAddOutput:_captureStillOutput]) {
[session addOutput:_captureStillOutput];
}
В отладчике есть дополнительная информация:* Завершающее приложение из-за необработанного исключения "NSInvalidArgumentException", причина: '* + [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:] - Не пример буфера jpeg.'
Поиск в Google и переполнение стека как "Не буфера сэмпла в формате jpeg" дали ноль результатов. Я застрял. бах.
2 ответа
Этот вопрос старый, но золотой. Я пришел из будущего и могу подтвердить, что это все еще произойдет в 2015 году. Я пытался пройти те же шаги, чтобы решить проблему, но безрезультатно. Однако этот вопрос заставил меня понять, что CMSampleBufferRef imageDataSampleBuffer
ведет себя странно, когда речь идет за пределами captureStillImageAsynchronouslyFromConnection
обработчик завершения.
В двух словах:
[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
}];
Предпочитаю делать это вместо этого:
[self.stillImageOutput captureStillImageAsynchronouslyFromConnection:connection
completionHandler:^( CMSampleBufferRef imageDataSampleBuffer, NSError *error )
{
//handle the buffer right here
NSData *data = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];
//works better
}];
Надеюсь, это кому-нибудь поможет.
Следующий шаг для этого решения состоял в том, чтобы зарегистрировать все данные, сообщенные в отладчике, используя:
po imageDataSampleBuffer
это всегда создавало много деталей, в то время как создавалось исключение, много информации о буфере семплов. Затем, после публикации этого сообщения в SO, я закомментировал некоторый код, затем раскомментировал его, и теперь он работает. В моем коде ничего не изменилось, однако я закрыл некоторые программы, работающие на Mac. Возможно, это была ошибка машины разработки. После этого я закрыл и снова открыл Xcode, и исключение не было выдано.