CMBlockBufferCreate内存管理

Pet*_*ete 7 iphone objective-c avfoundation core-media

我有一些代码创建CMBlockBuffers然后创建一个CMSampleBuffer并将其传递给AVAssetWriterInput.

这里有关于内存管理的优惠吗?根据Apple文档,您在名称中使用"创建"的任何内容都应与CFRelease一起发布.

但是,如果我使用CFRelease,那么我的应用程序将以对象0xblahblah的'malloc:*错误中止:未释放指针被释放.

CMBlockBufferRef tmp_bbuf = NULL;
CMBlockBufferRef bbuf = NULL;
CMSampleBufferRef sbuf = NULL;
status = CMBlockBufferCreateWithMemoryBlock(
                                            kCFAllocatorDefault, 
                                            samples, 
                                            buflen, 
                                            kCFAllocatorDefault, 
                                            NULL, 
                                            0, 
                                            buflen, 
                                            0, 
                                            &tmp_bbuf);

if (status != noErr || !tmp_bbuf) {
    NSLog(@"CMBlockBufferCreateWithMemoryBlock error");
    return -1;
}
// Copy the buffer so that we get a copy of the samples in memory.
// CMBlockBufferCreateWithMemoryBlock does not actually copy the data!
// 
status = CMBlockBufferCreateContiguous(kCFAllocatorDefault, tmp_bbuf, kCFAllocatorDefault, NULL, 0, buflen, kCMBlockBufferAlwaysCopyDataFlag, &bbuf);
//CFRelease(tmp_bbuf); // causes abort?!
if (status != noErr) {
    NSLog(@"CMBlockBufferCreateContiguous error");
    //CFRelease(bbuf);
    return -1;
}


CMTime timestamp = CMTimeMake(sample_position_, 44100);

status = CMAudioSampleBufferCreateWithPacketDescriptions(
    kCFAllocatorDefault, bbuf, TRUE, 0, NULL, audio_fmt_desc_, 1, timestamp, NULL, &sbuf);

sample_position_ += n;
if (status != noErr) {
    NSLog(@"CMSampleBufferCreate error");
    return -1;
}
BOOL r = [audioWriterInput appendSampleBuffer:sbuf]; // AVAssetWriterInput
//memset(&audio_buf_[0], 0, buflen);
if (!r) {
    NSLog(@"appendSampleBuffer error");
}
//CFRelease(bbuf);
//CFRelease(sbuf);
Run Code Online (Sandbox Code Playgroud)

所以,在这段代码中,我应该使用CFRelease什么吗?

小智 8

关键是CMBlockBufferCreateWithMemoryBlock的blockAllocator参数:

如果memoryBlock为NULL,则分配用于分配memoryBlock的分配器.如果memoryBlock为非NULL,则此分配器将用于在提供时解除分配.传递NULL将导致使用默认分配器(在调用时设置).如果不需要重新分配,则传递kCFAllocatorNull.

由于您不希望在释放CMBlockBuffer时释放"samples",因此您希望将kCFAllocatorNull作为第4个参数传递,如下所示:

status = CMBlockBufferCreateWithMemoryBlock(
                                            kCFAllocatorDefault, 
                                            samples, 
                                            buflen, 
                                            kCFAllocatorNull, 
                                            NULL, 
                                            0, 
                                            buflen, 
                                            0, 
                                            &tmp_bbuf);
Run Code Online (Sandbox Code Playgroud)