Я успешно применил фильтр для предварительного просмотра камеры. Вот инициализация, в viewDidLoad ():
sessionQueue.async {
switch self.setupResult {
case .success:
// Only setup observers and start the session if setup succeeded.
self.addObservers()
// Buffer
let videoOutput = AVCaptureVideoDataOutput()
let dataOutputQueue = DispatchQueue(label: "video data queue",
qos: .userInitiated,
attributes: [],
autoreleaseFrequency: .workItem)
let x = DispatchQueue.main
videoOutput.setSampleBufferDelegate(self,
queue: x)
if self.session.canAddOutput(videoOutput) {
self.session.addOutput(videoOutput)
self.session.startRunning()
}
Мой 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 Буми [28519: 6238030] Выполнение буфера команд было прервано из-за к ошибке во время исполнения. Вызванная ошибка тайм-аута GPU (код IOAF 2)
Такое ощущение, что captureOutput вызывается много раз в секунду.
Я знаю, что должен реализовать очередь для videoOutput.setSampleBufferDelegate, как это:
DispatchQueue(label: "video data queue",
qos: .userInitiated,
attributes: [],
autoreleaseFrequency: .workItem)
Но так как я инициализирую его в своем сеансе-очереди, это невозможно.
Где здесь моя проблема?