I'm making a video effect on iOS (using Metal) that requires accessing pixel data from the current video frame as well as some number of previous frames. To do this I'm storing pixel buffers in an Array property that behaves like a stack. When rendering, I cycle through the pixel buffers and create a MTLTexture for each. These textures then get sent to my Metal shader as a texture2d_array.
It all works great, except that as soon as I try display data from more than 12 distinct pixel buffers at a time, new frames stop getting sent from my capture output and the video appears frozen. There are no warnings or crashes. I've been using an iPhone 8.
It seems like I'm hitting some clear limit, though I haven't been able to determine what the nature of that limit is. I'm fairly new to graphics programming, so I very well may be doing something bad. I would be enormously grateful for any help or ideas.
Here's my pixel buffer stack:
// 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
}
}
Here's where I create the textures:
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)!
}
See this code in context here: https://gist.github.com/peeinears/5444692079d011a0ca3947c4e49efd47
I'm happy to share more if it's helpful.
Thanks!