Как преобразовать MTLTexture в CVpixelBuffer для записи в AVAssetWriter?

У меня есть требование применить фильтры к живому видео, и я пытаюсь сделать это в Metal.

Но у меня возникла проблема с преобразованием 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, а затем сохранения его в библиотеке.


person Shreesha Kedlaya    schedule 30.06.2017    source источник
comment
Прочтите При каких обстоятельствах я могу добавить к своему вопросу «срочно» или другие похожие фразы, чтобы получить более быстрые ответы? - Резюмируя, можно сказать, что это не идеальный способ обращения к волонтерам и, вероятно, контрпродуктивен для получения ответов. Пожалуйста, воздержитесь от добавления этого к своим вопросам.   -  person halfer    schedule 30.06.2017
comment
Я также пытаюсь использовать mtltexture с avassetwriter. Не могли бы вы поделиться своим окончательным кодом?   -  person Ömer Karışman    schedule 29.08.2017
comment
Я считаю, что преобразование в UIImage происходит довольно медленно и приведет к снижению производительности при создании видео. Очевидно, что для скриншота это совершенно нормально.   -  person drewster    schedule 09.01.2018


Ответы (1)


Не вычисляйте bytesPerRow себя так. Его передают в Metal, чтобы он знал, как расположить ряды. Вы хотите, чтобы Металл расположил их так, как CVPixelBuffer их ожидает. Следовательно, вы должны использовать CVPixelBufferGetBytesPerRow() для определения значения.

person Ken Thomases    schedule 30.06.2017
comment
Я считаю, что строки в CVPixelBuffer выровнены по 32 пикселя. Это приводит к проблемам, если вы начинаете делать предположения о том, что эти буферы не содержат байтов заполнения в конце каждой строки. - person zzyzy; 23.07.2017
comment
Подождите, а где вы копируете данные пикселей из mtltexture в cvpixelbuffer? - person Dimitrio; 20.06.2018