尝试在Metal和Core Image的帮助下,将简单的小插图滤镜应用于iPhone6的原始相机提要时,我发现在MTKView
中处理和渲染的帧之间存在很多滞后
我遵循的方法是(MetalViewController.swift):
AVCaptureVideoDataOutputSampleBufferDelegate
获取原始相机输出CMSampleBuffer
> CVPixelBuffer
> CGImage
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()
}
}
}
性能根本不是苹果在此文档中提到的:https://developer.apple.com/library/archive/documentation/GraphicsImaging/Conceptual/CoreImaging/ci_tasks/ci_tasks.html#//apple_ref/doc/uid/TP30001185-CH3-TPXREF101
我想念什么吗?
最佳答案
您的第2步太慢了,无法支持实时渲染...,看来您缺少了几个步骤。为了您的目的,通常会:
建立:
CVPixelBuffer
池-使用CVPixelBufferPoolCreate
CVMetalTextureCacheCreate
创建一个金属纹理池对于每一帧:
CMSampleBuffer
> CVPixelBuffer
> CIImage
CIImage
CVPixelBuffer
CVMetalTextureCacheCreateTextureFromImage
与过滤的CVPixelBuffer一起创建金属质感如果设置正确,所有这些步骤将确保您的图像数据保留在GPU上,而不是从GPU到CPU再回到GPU进行显示。
好消息是,所有这些都在Apple https://developer.apple.com/library/archive/samplecode/AVCamPhotoFilter/Introduction/Intro.html#//apple_ref/doc/uid/TP40017556的AVCamPhotoFilter示例代码中进行了演示。特别是请参见
RosyCIRenderer
类及其 super class FilterRenderer
。