Как преобразовать 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() определить стоимость.

Другие вопросы по тегам