Как применить Vignette CIFilter к каналу прямой трансляции с камеры в iOS? - PullRequest
0 голосов
/ 22 декабря 2018

Пытаясь применить простой фильтр виньетирования к исходному каналу камеры iPhone6 ​​с помощью Metal и Core Image, я вижу большое отставание между кадрами, обрабатываемыми и отображаемыми в MTKView

Подход, которым я придерживался, (MetalViewController.swift):

  1. Получить необработанный вывод с камеры, используя AVCaptureVideoDataOutputSampleBufferDelegate
  2. Преобразование CMSampleBuffer> CVPixelBuffer> CGImage
  3. Создайте MTLTexture с этим CGImage.

Точка №.2 и 3 находятся внутри метода с именем: fillMTLTextureToStoreTheImageData

Применение CIFilter к CIImage, полученному из MTLTexture в MTKViewDelegate
    func draw(in view: MTKView) {

        if let currentDrawable = view.currentDrawable {
            let commandBuffer = self.commandQueue.makeCommandBuffer()

            if let myTexture = self.sourceTexture{

                let inputImage = CIImage(mtlTexture: myTexture, options: nil)

                self.vignetteEffect.setValue(inputImage, forKey: kCIInputImageKey)

                self.coreImageContext.render(self.vignetteEffect.outputImage!, to: currentDrawable.texture, commandBuffer: commandBuffer, bounds: inputImage!.extent, colorSpace: self.colorSpace)

                commandBuffer?.present(currentDrawable)

                commandBuffer?.commit()
            }
        }
    }

Производительность совсем не та, что Apple упоминала в этом документе: https://developer.apple.com/library/archive/documentation/GraphicsImaging/Conceptual/CoreImaging/ci_tasks/ci_tasks.html#//apple_ref/doc/uid/TP30001185-CH3-TPXREF101

Я что-то упустил?

1 Ответ

0 голосов
/ 24 декабря 2018

Ваш шаг 2 слишком медленный, чтобы поддерживать рендеринг в реальном времени ... и, похоже, вы пропустили пару шагов.Для вашей цели вы обычно:

Настройка:

  1. создать пул CVPixelBuffer - используя CVPixelBufferPoolCreate
  2. создать пул металлических текстур, используяCVMetalTextureCacheCreate

Для каждого кадра:

convert CMSampleBuffer> CVPixelBuffer> CIImage Передача этого CIImage через конвейер фильтра рендеринг выходного изображения в CVPixelBuffer из пула, созданного вШаг 1 Используйте CVMetalTextureCacheCreateTextureFromImage, чтобы создать металлическую текстуру с вашим отфильтрованным CVPixelBuffer

При правильной настройке все эти шаги обеспечат сохранение данных изображения в графическом процессоре, в отличие отдля перехода от графического процессора к процессору и обратно к графическому процессору для отображения.

Хорошей новостью является то, что все это продемонстрировано в примере кода AVCamPhotoFilter от Apple https://developer.apple.com/library/archive/samplecode/AVCamPhotoFilter/Introduction/Intro.html#//apple_ref/doc/uid/TP40017556. В частности, смотрите класс RosyCIRenderer и его суперкласс FilterRenderer.

...