我正在尝试在AVCaptureVideoDataOutputSampleBufferDelegate中创建captureOutput返回的CMSampleBuffer副本.
由于CMSampleBuffers来自预先分配的(15)缓冲池,如果我附加对它们的引用,则无法重新收集它们.这会导致所有剩余帧被丢弃.
为了保持最佳性能,某些样本缓冲区直接引用可能需要由设备系统和其他捕获输入重用的内存池.对于未压缩的设备本机捕获,通常会出现这种情况,其中尽可能少地复制内存块.如果多个样本缓冲区长时间引用此类内存池,则输入将无法再将新样本复制到内存中,并且这些样本将被丢弃.
如果您的应用程序通过保留提供的CMSampleBufferRef对象太久而导致丢弃样本,但需要长时间访问样本数据,请考虑将数据复制到新缓冲区中,然后释放样本缓冲区(如果它以前保留过)以便它引用的内存可以重用.
显然我必须复制CMSampleBuffer,但CMSampleBufferCreateCopy()只会创建一个浅拷贝.因此,我得出结论,我必须使用CMSampleBufferCreate().我填写了12个!构造函数需要的参数但遇到了我的CMSampleBuffers不包含blockBuffer的问题(不完全确定那是什么,但似乎很重要).
这个问题已被问过好几次但没有回答.
CMImageBuffer或CVImageBuffer的深层副本并在Swift 2.0中创建CMSampleBuffer的副本
一个可能的答案是"我终于想出如何使用它来创建一个深度克隆.所有复制方法都重用了堆中的数据,这些数据会保留AVCaptureSession.所以我不得不将数据拉入NSMutableData对象然后创建了一个新的样本缓冲区." 在SO上归功于Rob.但是,我不知道如何正确地做到这一点.
如果你有兴趣,这是输出print(sampleBuffer)
.没有提到blockBuffer,又名CMSampleBufferGetDataBuffer返回nil.有一个imageBuffer,但使用CMSampleBufferCreateForImageBuffer创建"副本"似乎也没有释放CMSampleBuffer.
编辑:由于这个问题已经发布,我一直在尝试更多的方式来复制内存.
我做了用户Kametrixom尝试的相同的事情.这是我尝试同样的想法,首先复制CVPixelBuffer然后使用CMSampleBufferCreateForImageBuffer创建最终的样本缓冲区.但是,这会导致两个错误之一:
CMSampleBufferCreateReadyWithImageBuffer()
将失败,结果代码为-12743,"表示给定媒体的格式与给定的格式描述不匹配.例如,与CVImageBuffer配对的格式描述与CMVideoFormatDescriptionMatchesImageBuffer失败."你可以看到Kametrixom和我都CMSampleBufferGetFormatDescription(sampleBuffer)
试图复制源缓冲区的格式描述.因此,我不确定为什么给定媒体的格式与给定的格式描述不匹配.