如何将MTLTexture转换为CVpixelBuffer写入AVAssetWriter?

我有一个要求,在实时video应用filter,我想在金属做。

但是,在将滤镜编码到目标滤镜之后,我遇到了将MTLTexture转换为CVPixelBuffer的问题。 参考( https://github.com/oklyc/MetalCameraSample-master-2 )

这是我的代码。

if let pixelBuffer = pixelBuffer { CVPixelBufferLockBaseAddress(pixelBuffer, CVPixelBufferLockFlags.init(rawValue: 0)) let region = MTLRegionMake2D(0, 0, Int(currentDrawable.layer.drawableSize.width), Int(currentDrawable.layer.drawableSize.height)) let bytesPerPixel = 4; let bytesPerRow = CGFloat(bytesPerPixel) * currentDrawable.layer.drawableSize.width let tempBuffer = CVPixelBufferGetBaseAddress(pixelBuffer) destinationTexture.getBytes(tempBuffer!, bytesPerRow: Int(bytesPerRow), from: region1, mipmapLevel: 0) let image = self.imageFromCVPixelBuffer(buffer: pixelBuffer) CVPixelBufferUnlockBaseAddress(pixelBuffer, CVPixelBufferLockFlags.init(rawValue: 0)) } 

imageFromCVPixelBuffer方法看起来像这样。

 func imageFromCVPixelBuffer(buffer: CVPixelBuffer) -> UIImage { let ciimage = CIImage(cvPixelBuffer: buffer) let context = CIContext(options: nil) let cgimgage = context.createCGImage(ciimage, from: CGRect(x: 0, y: 0, width: CVPixelBufferGetWidth(buffer), height: CVPixelBufferGetHeight(buffer))) let uiimage = UIImage(cgImage: cgimgage!) return uiimage } 

这里是通过金属渲染图像的屏幕截图

在这里输入图像说明

这里是将MTLTexture转换为CVPixelBuffer的相同图像的屏幕截图。

在这里输入图像说明

将MTLtexture转换为CVPixelBuffer需要写入AVAssetWriter,然后将其保存到库中。

不要像这样计算bytesPerRow 。 它被传递给Metal让Metal知道如何排列行。 您希望Metal按照CVPixelBuffer预期的方式CVPixelBuffer它们。 因此,您应该使用CVPixelBufferGetBytesPerRow()来确定值。