Почему 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, и исключение не было выдано.

Другие вопросы по тегам