Как преобразовать MTLTexture в CVpixelBuffer для записи в AVAssetWriter?
У меня есть требование применить фильтры к живому видео, и я пытаюсь сделать это в металле.
Но я столкнулся с проблемой при преобразовании 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 и последующего сохранения его в библиотеке.
1 ответ
Не вычислять bytesPerRow
себя так. Это передано в Металл, чтобы Металл знал, как расположить ряды. Вы хотите, чтобы Метал устроил им путь CVPixelBuffer
ожидает их. Поэтому вы должны использовать CVPixelBufferGetBytesPerRow()
определить стоимость.