2012-09-01 22 views
6

Ich habe einige Code, der CMBlockBuffers erstellt und erstellt dann einen CMSampleBuffer und übergibt es an einen AVAssetWriterInput.CMBlockBufferCreate Speicherverwaltung

Was ist der Deal auf Speicherverwaltung hier? Laut der Apple-Dokumentation, anything you use with 'Create' in the name should be released with CFRelease.

Allerdings, wenn ich CFRelease verwenden, bricht meine App mit 'malloc: * Fehler für Objekt 0xblahblah: Zeiger wird freigegeben wurde nicht zugeordnet.

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

Also, in diesem Code, sollte ich mit CFRelease auf alles sein?

+0

Haben Sie jemals bekommen herausgefunden? – kevlar

+0

@kevlar Ich habe alles modifiziert, um asynchrone Komprimierung mit GCD zu machen. Ich musste diese Puffer freigeben. Ich bin mir immer noch nicht sicher, warum das stürzte. Wenn Sie befürchten, dass Sie Speicherlecks haben, profilieren Sie Ihren Code mithilfe von Instrumenten (Teil von XCode). – Pete

Antwort

8

Der Schlüssel ist der blockAllocator Parameter CMBlockBufferCreateWithMemoryBlock:

Zuweiser verwendet werden, um den Speicherblock für die Zuteilung, wenn Speicherblock NULL ist. Wenn memoryBlock nicht NULL ist, wird dieser Zuordner verwendet, um freizugeben, falls vorhanden. Wenn NULL übergeben wird, wird der Standardverteiler (wie zum Zeitpunkt des Anrufs festgelegt) verwendet. Übergeben Sie kCFAllocatorNull, wenn keine Freigabe erforderlich ist.

Da Sie die „Proben“ nicht wollen, ausgeplant werden, wenn Sie die CMBlockBuffer loslassen, möchten Sie wie so in kCFAllocatorNull als 4. Parameter zu übergeben:

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

sollte dies sein:

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

Möchten Sie näher erläutern, warum dies mit Speicherverwaltung und CFRelease zu tun hat? – Pete