【发布时间】:2024-01-20 11:30:01
【问题描述】:
我正在尝试创建一个由 AVCaptureVideoDataOutputSampleBufferDelegate 中的 captureOutput 返回的 CMSampleBuffer 的副本。
由于 CMSampleBuffers 来自 (15) 个缓冲区的预分配池,如果我附加对它们的引用,它们将无法被重新收集。这会导致所有剩余的帧都被丢弃。
为保持最佳性能,一些样本缓冲区直接引用可能需要由设备系统和其他捕获输入重用的内存池。对于未压缩的设备本机捕获,这种情况经常发生,其中内存块被复制得越少越好。如果多个样本缓冲区引用此类内存池的时间过长,输入将不再能够将新样本复制到内存中,并且这些样本将被丢弃。
如果您的应用程序由于保留提供的 CMSampleBufferRef 对象太久而导致样本被丢弃,但它需要长时间访问样本数据,请考虑将数据复制到新缓冲区中,然后释放样本缓冲区(如果它以前被保留),以便它引用的内存可以被重用。
显然我必须复制 CMSampleBuffer 但 CMSampleBufferCreateCopy() 只会创建一个浅拷贝。因此我得出结论,我必须使用 CMSampleBufferCreate()。我填了12!构造函数需要的参数,但遇到了我的 CMSampleBuffers 不包含 blockBuffer 的问题(不完全确定那是什么,但它似乎很重要)。
这个问题已经被问了好几次,但没有回答。
Deep Copy of CMImageBuffer or CVImageBuffer 和 Create a copy of CMSampleBuffer in Swift 2.0
一个可能的答案是“我终于想出了如何使用它来创建深度克隆。所有的复制方法都重用了堆中的数据,这些数据会锁定 AVCaptureSession。所以我不得不将数据提取到 NSMutableData对象,然后创建一个新的样本缓冲区。” credit to Rob on SO。但是,我不知道如何正确执行此操作。
如果你有兴趣,this 是print(sampleBuffer) 的输出。没有提到 blockBuffer,也就是 CMSampleBufferGetDataBuffer 返回 nil。有一个 imageBuffer,但是使用 CMSampleBufferCreateForImageBuffer 创建一个“副本”似乎也不能释放 CMSampleBuffer。
编辑:自从发布了这个问题以来,我一直在尝试更多复制内存的方法。
我做了用户Kametrixom 尝试过的同样的事情。 This 是我尝试相同的想法,首先复制 CVPixelBuffer 然后使用 CMSampleBufferCreateForImageBuffer 创建最终的样本缓冲区。但是,这会导致以下两个错误之一:
- memcpy 指令上的 EXC_BAD_ACCESS。 AKA 尝试访问应用程序内存之外的段错误。
- 或者,内存将成功复制,但
CMSampleBufferCreateReadyWithImageBuffer()将失败,结果代码为 -12743,“表示给定媒体的格式与给定的格式描述不匹配。例如,与 CVImageBuffer 配对的格式描述CMVideoFormatDescriptionMatchesImageBuffer 失败。”
您可以看到,Kametrixom 和我都使用CMSampleBufferGetFormatDescription(sampleBuffer) 来尝试复制源缓冲区的格式描述。因此,我不确定为什么给定媒体的格式与给定的格式描述不匹配。
【问题讨论】:
标签: ios swift deep-copy pool cmsamplebuffer