我正在 iOS 上制作视频效果(使用 Metal),它需要访问当前视频帧以及一些先前帧的像素数据。为此,我将像素缓冲区存储在一个类似于堆栈的 Array 属性中。渲染时,我循环遍历像素缓冲区并为每个缓冲区创建一个 MTLTexture。然后这些纹理作为 texture2d_array 发送到我的 Metal 着色器。
一切都很好,除了当我尝试一次显示来自超过 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
如果有帮助,我很乐意分享更多。
谢谢!