2012-09-01 88 views
6

我有一些代碼創建CMBlockBuffers,然後創建一個CMSampleBuffer並將其傳遞給AVAssetWriterInput。CMBlockBuffer創建內存管理

什麼是內存管理這裏的交易嗎?根據Apple文檔,anything you use with 'Create' in the name should be released with CFRelease

但是,如果我使用CFRelease,那麼我的應用程序將終止'malloc:*錯誤對象0xblahblah:被釋放的指針未被分配。

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); 

所以,在這段代碼中,我應該用任何東西CFRelease

+0

你有沒有得到這個想通了? – kevlar

+0

@kevlar我最終修改了所有使用GCD的異步壓縮。我確實需要釋放這些緩衝區。我仍然不確定爲什麼這會崩潰。如果您擔心內存泄漏,請使用儀器(XCode的一部分)對您的代碼進行分析。 – Pete

回答

8

的關鍵是blockAllocator參數CMBlockBufferCreateWithMemoryBlock:

分配器用於分配MemoryBlock中,如果MemoryBlock中是 NULL。如果MemoryBlock中的非NULL,該分配器將用於如果提供它 解除分配。傳遞NULL將導致默認 分配器(如設定在通話時)使用。 通過 如果不需要重新分配,kCFAllocatorNull。

既然你不想要的「樣本」當你釋放CMBlockBuffer被釋放嗎,你想在kCFAllocatorNull通過像這樣的第四個參數:

status = CMBlockBufferCreateWithMemoryBlock(
              kCFAllocatorDefault, 
              samples, 
              buflen, 
              kCFAllocatorNull, 
              NULL, 
              0, 
              buflen, 
              0, 
              &tmp_bbuf); 
0
CMAudioSampleBufferCreateWithPacketDescriptions(kCFAllocatorDefault, bbuf, TRUE, 0, NULL, audio_fmt_desc_, 1, timestamp, NULL, &sbuf); 

這應該是:

CMAudioSampleBufferCreateWithPacketDescriptions(kCFAllocatorDefault, bbuf, TRUE, 0, NULL, audio_fmt_desc_, 1024, timestamp, NULL, &sbuf); 
+0

關注爲什麼這涉及內存管理和CFRelease? – Pete