2012-09-01 16 views
6

CMBlockBuffersを作成し、CMSampleBufferを作成してAVAssetWriterInputに渡すコードがあります。CMBlockBufferメモリ管理を作成する

ここでのメモリ管理についてはどうですか?アップルのドキュメントによると、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を使用して非同期圧縮を行うために、すべてを修正しました。私はそれらのバッファを解放する必要がありました。なぜこれがクラッシュしたのかまだ分かりません。メモリリークが懸念される場合は、Instruments(XCodeの一部)を使用してコードをプロファイリングしてください。 – Pete

答えて

8

キーはCMBlockBufferCreateWithMemoryBlockにblockAllocatorパラメータである:

アロケータメモリブロックが 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