5

在 iOS 中,我使用代码从 AVCaptureStillImageOutput 捕获,因此:

[_captureStillOutput captureStillImageAsynchronouslyFromConnection: _captureConnection completionHandler: 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 样本缓冲区。”

在谷歌和堆栈溢出中搜索“不是 jpeg 样本缓冲区”产生的结果为零。我被困住了。呸。

4

2 回答 2

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
    }]; 

希望这可以帮助某人。

于 2015-11-16T09:35:11.473 回答
0

此解决方案的下一步是使用以下命令记录调试器中报告的所有数据:

po imageDataSampleBuffer

在抛出异常时,这总是会产生很多细节,在样本缓冲区中会产生很多信息。然后自从将其发布到 SO 后,我注释掉了一些代码,然后取消注释它,现在它正在工作。我的代码没有任何变化,但是,我确实关闭了一些在 mac 上运行的程序。也许这是一个开发机器错误。在这之后,我关闭并重新打开了Xcode,并没有抛出异常。

于 2012-09-10T16:59:29.210 回答