2017-06-30 3 views
2

私はライブビデオにフィルタを適用する必要があり、私はそれをMetalでやろうとしています。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 
} 

金属

ここ

enter image description here

を通してレンダリング画像のスクリーンショットはCVPixelBufferにMTLTexture変換同じ画像のスクリーンショットです。 CVPixelBufferにMTLtextureの変換

enter image description here

は、ライブラリに保存し、その後AVAssetWriterに書き込むために必要とされます。

+1

[もっと速い回答を得るために、どのような状況で「緊急」やその他の類似のフレーズを追加することができますか?](// meta.stackoverflow.com/q/326569) - 要約は、ボランティアに対処する理想的な方法ではなく、おそらく回答を得ることに逆効果があります。これをあなたの質問に追加しないでください。 – halfer

+0

私はavassetwriterでmtltextureも使用しようとしています。あなたの最終的なコードを教えてください。 –

+0

UIImageへの変換私はかなり遅いと思いますが、ビデオを作っているとパフォーマンスが悪くなります。明らかに、それはスクリーンショットのためにまったく問題ありません。 – drewster

答えて

4

このように自分でbytesPerRowを計算しないでください。 Metalに行を配置する方法を知らせるためにMetalに渡されています。あなたは、金属がそれらを手配するように、CVPixelBufferがそれらを期待するようにします。したがって、値を決定するのにCVPixelBufferGetBytesPerRow()を使用する必要があります。

+0

ありがとうございました。 –

+0

CVPixelBufferの行は32ピクセルで整列していると私は信じています。これは、各行の最後にパディングバイトを含まないこれらのバッファについての前提を作成し始めると問題になります。 – zzyzy

関連する問題