2012-06-21 24 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之前被釋放。