我正在尝试创建由AVCaptureAudioDataOutputSampleBufferDelegate
中的captureOutput返回的CMSampleBuffer的副本。
我的问题是,当我将从委托方法captureOutput:didOutputSampleBuffer:fromConnection:
返回的帧保留在CFArray
中一段时间后,它们就会被丢弃。
显然,我需要创建传入缓冲区的深层副本以进行进一步处理。 我也知道CMSampleBufferCreateCopy
只会创建浅层副本。
有几个相关问题在SO上提出:
- 从CMSampleBuffer中提取数据以创建深度副本
- 创建CMSampleBuffer的副本在Swift中返回OSStatus -12743(无效媒体格式)
- CMImageBuffer或CVImageBuffer的深层副本
但是,它们都不能帮助我正确使用具有12个参数的CMSampleBufferCreate函数。
CMSampleBufferRef copyBuffer;
CMBlockBufferRef data = CMSampleBufferGetDataBuffer(sampleBuffer);
CMFormatDescriptionRef formatDescription = CMSampleBufferGetFormatDescription(sampleBuffer);
CMItemCount itemCount = CMSampleBufferGetNumSamples(sampleBuffer);
CMTime duration = CMSampleBufferGetDuration(sampleBuffer);
CMTime presentationStamp = CMSampleBufferGetPresentationTimeStamp(sampleBuffer);
CMSampleTimingInfo timingInfo;
timingInfo.duration = duration;
timingInfo.presentationTimeStamp = presentationStamp;
timingInfo.decodeTimeStamp = CMSampleBufferGetDecodeTimeStamp(sampleBuffer);
size_t sampleSize = CMBlockBufferGetDataLength(data);
CMBlockBufferRef sampleData;
if (CMBlockBufferCopyDataBytes(data, 0, sampleSize, &sampleData) != kCMBlockBufferNoErr) {
VLog(@"error during copying sample buffer");
}
// Here I tried data and sampleData CMBlockBuffer instance, but no success
OSStatus status = CMSampleBufferCreate(kCFAllocatorDefault, data, isDataReady, nil, nil, formatDescription, itemCount, 1, &timingInfo, 1, &sampleSize, ©Buffer);
if (!self.sampleBufferArray) {
self.sampleBufferArray = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
//EXC_BAD_ACCESS crash when trying to add sampleBuffer to the array
CFArrayAppendValue(self.sampleBufferArray, copyBuffer);
} else {
CFArrayAppendValue(self.sampleBufferArray, copyBuffer);
}
如何深拷贝音频CMSampleBuffer?在您的答案中,可以使用任何语言(Swift/Objective-C)。
CMSampleBufferCreateCopy
会发生什么?CMSampleBufferCopySampleBufferForRange
是否会给你一个深拷贝?你真的需要CMSampleBuffer
进行进一步处理吗?如果你正在进行自己的处理,长度+指针可能更方便。 - Rhythmic FistmanCMSampleBufferCreateCopy
来复制样本,并在CFArray
中保留复制的样本超过1秒钟,那么didOutputSampleBuffer
将停止被调用。你可以通过这个问题轻松地重现它。我将使用CMSampleBufferCopySampleBufferForRange
检查其行为,并向你更新。 - Neil Galiaskarov