Почему я не могу читать более 12 CVPixelBuffers одновременно? - PullRequest
0 голосов
/ 03 марта 2019

Я делаю видеоэффект на iOS (используя Metal), который требует доступа к данным пикселей текущего видеокадра, а также некоторого количества предыдущих кадров.Для этого я храню пиксельные буферы в свойстве Array, которое ведет себя как стек.При рендеринге я перебираю пиксельные буферы и создаю текстуру MTL для каждого.Затем эти текстуры отправляются в мой металлический шейдер в качестве texture2d_array.

Все это прекрасно работает, за исключением того, что как только я пытаюсь отображать данные из более чем 12 отдельных пиксельных буферов одновременно, новые кадры перестают отправляться смой вывод захвата и видео кажется замороженным.Там нет предупреждений или сбоев.Я использую iPhone 8.

Кажется, что я нахожусь в некотором четком пределе, хотя я не смог определить, какова природа этого предела.Я довольно новичок в графическом программировании, поэтому я вполне могу делать что-то плохое.Я был бы чрезвычайно признателен за любую помощь или идеи.

Вот мой стек пиксельного буфера:

// 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

Я рад поделиться с вами, если это будет полезно.

Спасибо!

...