2012-06-21 27 views
1

我正在通过AV基金会的导出功能从iPod库中的曲目中读取LPCM样本。我的大部分代码都是从Chris Adamson's example here借用的。何时发布CMBlockBufferRef?

我正在创建一个新的CMBlockBufferRef并保留它CMSampleBufferGetAudioBufferListWithRetainedBlockBuffer。根据苹果CFType reference,我需要在我明确保留的任何对象上使用CFRelease

问题是,我似乎无法弄清楚究竟在哪里发布CMBlockBufferRef对象。如果我根本不释放它,则会发生大量内存泄漏。如果我尝试在循环中的任何位置释放它,则该应用会在我的GrabAudioData方法中发生EXC_BAD_ACCESS错误。如果我尝试在循环之外启动并释放它,内存泄漏仍然存在。我试过在发布之前检查blockBuffer是否为NULL,但这不起作用。请帮忙!

while (assetReader.status != AVAssetReaderStatusCompleted) 
{ 
    if (assetReader.status == AVAssetReaderStatusReading) 
    { 
     CMSampleBufferRef nextBuffer = [readerOutput copyNextSampleBuffer]; 

     if (nextBuffer) 
     { 
      AudioBufferList bufferList; 
      CMBlockBufferRef blockBuffer; 
      CMSampleBufferGetAudioBufferListWithRetainedBlockBuffer(nextBuffer, NULL, &bufferList, sizeof(bufferList), NULL, NULL, kCMSampleBufferFlag_AudioBufferList_Assure16ByteAlignment, &blockBuffer); 

      // Using the AudioBufferList 
      bufferManager->GrabAudioData(&bufferList); 

      CMSampleBufferInvalidate(nextBuffer); 
      CFRelease(nextBuffer); 

      // Releasing here causes a crash 
      // CFRelease(blockBuffer); 
     } 
     else 
     { 
      break; 
     } 
    }  
} 
+1

这是否[文章](http://stackoverflow.com/questions/4972677/reading-audio-samples-通过avassetreader)帮助? –

+0

感谢史蒂夫,我实际上一遍又一遍地重复了这篇文章,我似乎无法让我自己的特定代码工作。绝对是一个很好的资源。 – dpcasady

+0

我想知道这些问题是否真的存在于我正在处理的数据中,而不是实际发布的数据。 – dpcasady

回答

1

除了@ sinn246的回答,您还必须检查CMSampleBufferGetAudioBufferListWithRetainedBlockBuffer的回报:

OSStatus err = CMSampleBufferGetAudioBufferListWithRetainedBlockBuffer(nextBuffer, NULL, &bufferList, sizeof(bufferList), NULL, NULL, kCMSampleBufferFlag_AudioBufferList_Assure16ByteAlignment, &blockBuffer); 

if (!err && blockBuffer && bufferList.mBuffers[0].mData && (bufferList.mBuffers[0].mDataByteSize > 0)) 
{ 
    // Using the AudioBufferList 
    bufferManager->GrabAudioData(&bufferList); 
} 

if (blockBuffer) // Double check that what you are releasing actually exists! 
{ 
    CFRelease(blockBuffer); 
} 

CMSampleBufferInvalidate(nextBuffer); 
CFRelease(nextBuffer); 
2

blockBuffer从nextBuffer被保留,所以它应该在nextBuffer之前被释放。