1

我正在尝试从 captureOutput:(AVCaptureOutput*)captureOutput didOutputSampleBuffer 获取样本缓冲区,对其进行处理,然后将其附加到 AVAssetWriter。整个代码都可以工作,但是它变得非常慢,而且我在旧设备上的 fps 很低。
我想将它放在 dispatch_async 中以提高性能,但是一旦访问样本缓冲区就会导致 EXC_BAD_ACCESS 错误。
我该如何修复它,同时将代码保留在后台?

queue1 = dispatch_queue_create("testqueue", DISPATCH_QUEUE_SERIAL);
...

-(void) captureOutput:(AVCaptureOutput*)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection*)connection{
    
dispatch_async(queue1, ^{
...
if(captureOutput == videoOutput){
//I process the buffer by appending an image to an adaptor
if([writerVideoInput isReadyForMoreMediaData] && recordingAssetWriter.status == 1)
    [adaptor appendPixelBuffer:pxBuffer withPresentationTime:CMSampleBufferGetPresentationTimeStamp(sampleBuffer)]) //<-- here I get EXC_BAD_ACCESS
}
if(captureOutput == audioOutput){
...
// I then append the audio buffer
if([assetWriterAudioInput isReadyForMoreMediaData] && recordingAssetWriter.status == 1)
    [assetWriterAudioInput appendSampleBuffer:sampleBuffer];
...
}
});

}

4

1 回答 1

1

从头文件中的captureOutput:didOutputSampleBuffer:fromConnection:讨论AVCaptureVideoDataOutput.h

CMSampleBuffer需要在此方法范围之外引用对象的客户端必须先引用CFRetain它,然后CFRelease在完成它时再引用它。

所以看起来你需要保留那些样本缓冲区,因为它们超出了范围!不要忘记稍后释放它们,否则会泄漏大量内存。

我忘记了 Objective-C 中的 ARC 不管理CoreFoundation对象。

然后头文件继续警告不要将样本缓冲区保留太久,以免丢帧。

于 2021-11-26T18:06:08.353 回答