0

現在のビデオ フレームと以前のいくつかのフレームからピクセル データにアクセスする必要がある iOS (Metal を使用) でビデオ エフェクトを作成しています。これを行うために、スタックのように動作する Array プロパティにピクセル バッファーを格納しています。レンダリングするときは、ピクセル バッファーを循環し、それぞれに MTLTexture を作成します。これらのテクスチャは、texture2d_array としてメタル シェーダに送信されます。

一度に 12 を超える個別のピクセル バッファからデータを表示しようとするとすぐに、キャプチャ出力から新しいフレームが送信されなくなり、ビデオがフリーズしたように見えることを除いて、すべてうまく機能します。警告やクラッシュはありません。iPhone8をずっと使っています。

その制限の性質を特定することはできませんでしたが、明確な制限に達しているようです。私はグラフィックプログラミングにかなり慣れていないので、何か悪いことをしている可能性があります。どんな助けやアイデアにも非常に感謝しています。

これが私のピクセルバッファスタックです:

// number of pixel buffers, anything over 12 causes "freeze"
let maxTextures = 12
var pixelBuffers: [CVPixelBuffer]?
var pixelBuffer: CVPixelBuffer? {
    set {
        if pixelBuffers == nil {
            pixelBuffers = Array(repeating: newValue!, count: maxTextures)
        }

        pixelBuffers!.append(newValue!)
        pixelBuffers!.removeFirst()

        DispatchQueue.main.async {
            self.setNeedsDisplay()
        }
    }
    get {
        return pixelBuffers?.last
    }
}

テクスチャを作成する場所は次のとおりです。

for i in 0..<maxTextures {

    guard let pixelBuffer = self.pixelBuffers?[i] else { return }

    width = CVPixelBufferGetWidth(pixelBuffer)
    height = CVPixelBufferGetHeight(pixelBuffer)

    var cvTextureOut: CVMetalTexture?
    CVMetalTextureCacheCreateTextureFromImage(kCFAllocatorDefault, self.textureCache!, pixelBuffer, nil, .bgra8Unorm, width, height, 0, &cvTextureOut)
    guard let cvTexture = cvTextureOut else {
        print("Failed to create metal texture")
        return
    }

    if textures == nil {
        textures = Array(repeating: CVMetalTextureGetTexture(cvTexture)!, count: maxTextures)
    }

    textures![i] = CVMetalTextureGetTexture(cvTexture)!

}

このコードをコンテキストで参照してください: https://gist.github.com/peeinears/5444692079d011a0ca3947c4e49efd47

参考になりましたら、またシェアさせていただきます。

ありがとう!

4

0 に答える 0