我通过以下方式从相机中获取帧:
func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
guard let imageBuffer: CVImageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else { return }
}
来自Apple documentation ...
如果需要在此方法范围之外引用CMSampleBuffer对象,则必须CFRetain它,然后在完成后再发送它。 为了保持最佳性能,某些样本缓冲区直接引用可能需要由设备系统和其他捕获输入重用的内存池。对于未压缩的设备本机捕获,通常会出现这种情况,其中尽可能少地复制内存块。如果多个样本缓冲区长时间引用此类内存池,则输入将无法再将新样本复制到内存中,并且这些样本将被丢弃。
在没有明确设置CVImageBuffer
的情况下,是否可以保留对sampleBuffer = nil
的引用?我只是问,因为最新版本的Swift自动内存管理CF数据结构,因此CFRetain
和CFRelease
不可用。
此外,背后的原因是“对于未压缩的设备本机捕获,情况经常发生这种情况,尽可能少地复制内存块。” ?为什么首先要复制一个内存块?
答案 0 :(得分:1)
在没有明确设置sampleBuffer = nil的情况下保持对CVImageBuffer的引用是否可以?
如果您要保留对图像缓冲区的引用,那么保持对其“包含”CMSampleBuffer
的引用肯定不会受到伤害。如果你保留对CVImageBuffer
但不是CMSampleBuffer
的引用,那么“正确的事情”会被完成吗?也许
此外,背后的原因是“对于未压缩的设备本机捕获,情况经常发生这种情况,尽可能少地复制内存块。” ?为什么首先要复制一个内存块?
有关于how to do a deep copy on an image CMSampleBuffer
的SO的问题,答案并不简单,因此无意中复制一个内存块的可能性非常低。我认为本文档的目的是告诉您AVCaptureVideoDataOutput
是有效的!如果长时间挂在太多CMSampleBuffer
上,这种效率(通过固定大小的帧池)可能会产生令人惊讶的丢帧效果,所以不要这样做。
然而,警告稍微多余,因为即使没有丢帧的幽灵,未压缩的视频CMSampleBuffer
由于它们的大小和频率已经是非常热的土豆。您只需要花费几秒钟就可以使用数GB的RAM,因此必须尽可能快地处理它们,然后释放/无任何对它们的引用。