如何借助AVFoundation写入RGB与深度帧且不丢失同步性
解决AVAssetWriter固定帧率导致RGB与深度帧不同步的问题
要让AVAssetWriter完全保留采集到的每帧RGB数据,不丢帧、不补帧,同时和深度帧精准匹配,你可以从以下几个关键环节入手:
1. 关闭AVAssetWriterInput的实时写入限制
默认情况下expectsMediaDataInRealTime设为YES,这会让AVAssetWriter为了维持实时帧率而丢弃或重复帧。把它设为NO,让写入器严格按照你传入的帧来处理:
// 创建RGB对应的AssetWriterInput AVAssetWriterInput *rgbInput = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeVideo outputSettings:rgbOutputSettings]; rgbInput.expectsMediaDataInRealTime = NO; // 关键:禁用实时帧率控制
2. 不指定固定预期帧率
在配置AVAssetWriterInput的outputSettings时,不要添加AVVideoExpectedFrameRateKey这个键。如果需要设置帧率相关参数,改用AVVideoAverageFrameRateKey来描述平均帧率,这样写入器会接受可变帧率的输入:
NSDictionary *rgbOutputSettings = @{ AVVideoCodecKey: AVVideoCodecTypeH264, AVVideoWidthKey: @1920, AVVideoHeightKey: @1080, AVVideoAverageFrameRateKey: @30 // 仅标记平均帧率,不强制固定 };
3. 直接使用采集帧的原始时间戳
AVCaptureDataOutputSynchronizer输出的同步帧组中,RGB帧和深度帧的时间戳是严格对齐的。写入RGB帧时,不要修改CMSampleBuffer的原始时间戳,直接传入appendSampleBuffer::
- (void)dataOutputSynchronizer:(AVCaptureDataOutputSynchronizer *)synchronizer didOutputSynchronizedDataCollection:(AVCaptureSynchronizedDataCollection *)collection { // 获取同步的RGB帧和深度帧 AVCapturedSynchronizedSampleBufferData *rgbData = [collection synchronizedDataForDataOutput:self.rgbOutput]; AVCapturedSynchronizedSampleBufferData *depthData = [collection synchronizedDataForDataOutput:self.depthOutput]; if (rgbData.sampleBuffer && depthData.sampleBuffer) { // 先保存深度帧原始数据 [self saveDepthFrameData:depthData.sampleBuffer]; // 直接写入RGB帧,用原始时间戳 if ([self.rgbInput isReadyForMoreMediaData]) { [self.rgbInput appendSampleBuffer:rgbData.sampleBuffer]; } } }
4. 严格同步处理帧组
必须在同步回调的同一个周期内完成深度帧保存和RGB帧写入,不要将其中一种操作异步处理(比如丢到后台队列),避免帧顺序错乱或丢失。确保每一组同步帧都被完整处理,不遗漏任何一对。
内容的提问来源于stack exchange,提问作者papekoja
相关产品推荐
相关产品推荐

