Swift 对captureOutput应用过滤器非常缓慢,并且在特定时间后崩溃

Swift 对captureOutput应用过滤器非常缓慢,并且在特定时间后崩溃,swift,xcode,avfoundation,avkit,Swift,Xcode,Avfoundation,Avkit,我已经成功地在我的相机预览上实现了一个过滤器。以下是viewDidLoad()中的初始化: 我的captureOutput: lazy var context = CIContext() func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) { let videoPreviewLayerOrie

我已经成功地在我的相机预览上实现了一个过滤器。以下是viewDidLoad()中的初始化:

我的captureOutput:

lazy var context = CIContext()

func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
    let videoPreviewLayerOrientation = viewPreview.videoPreviewLayer.connection?.videoOrientation
    print("capture output called")
    connection.videoOrientation = videoPreviewLayerOrientation!

    let comicEffect = CIFilter(name: "CIComicEffect")
    let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer)
    let cameraImage = CIImage(cvImageBuffer: pixelBuffer!)

    comicEffect!.setValue(cameraImage, forKey: kCIInputImageKey)

    let cgImage = self.context.createCGImage(comicEffect!.outputImage!, from: cameraImage.extent)!

    DispatchQueue.main.async {
        let filteredImage = UIImage(cgImage: cgImage)
        self.imageView.image = filteredImage
    }
}
现在应用的过滤器工作正常,但有时非常滞后,我收到这些消息,一段时间后,预览结束,我只收到以下消息:

2020-04-08 15:59:36.242047+0200 Bumi[28519:6238030]由于执行过程中出现错误,命令缓冲区的执行被中止。导致GPU超时错误(IOAF代码2)

感觉captureOutput每秒调用很多次

我知道我应该实现videoOutput.setSampleBufferDelegate的队列,如下所示:

DispatchQueue(label: "video data queue",
                                    qos: .userInitiated,
                                    attributes: [],
                                    autoreleaseFrequency: .workItem)

但由于我在sessionQueue中初始化了它,这是不可能的


我的问题在哪里?

我强烈建议您查看苹果的示例项目。它包括使用
MTKView
高效显示处理过的帧,以及使用高级核心图像或低级金属过滤视频帧。

“但由于我在会话队列中初始化了它,这是不可能的”为什么?您确实不应该使用主队列来获取和处理帧。此外,在这种情况下使用
UIImageView
并不理想,它并不意味着每秒显示这么多不同的图像。尝试渲染成一个
MTKView
。嗨,弗兰克,我将查看MTKView并对其进行更改。关于队列的东西:我制作了一个视频,在我打开应用程序上的相机并相应地实现了队列之后发生了什么:这是我第一次实现过滤器和其他东西,所以我不知道从哪里开始。也许视频有帮助,为什么我不能使用会话队列中的队列?链接:啊,访问
viewPreview.videoPreviewLayer
主线程外部会导致主线程检查器打印这些警告。解决这个问题的简单方法是直接(而不是通过
viewPreview
)保留对
videoPreviewLayer
的引用,并使用它。
DispatchQueue(label: "video data queue",
                                    qos: .userInitiated,
                                    attributes: [],
                                    autoreleaseFrequency: .workItem)