Reputation: 1846
I'm reading LPCM samples from a track in the iPod library, by means of the export functionality of AV Foundation. Most of my code is borrowed from Chris Adamson's example here.
I'm setting up a new CMBlockBufferRef
and retaining it with CMSampleBufferGetAudioBufferListWithRetainedBlockBuffer
. According to the apple CFType reference, I need to use CFRelease
on any object I explicitly retain.
The problem is that I can't seem to figure out where exactly to release the CMBlockBufferRef
object. If I don't release it at all, I get a large memory leak. If I try to release it anywhere inside my loop, the app crashes with a EXC_BAD_ACCESS error in my GrabAudioData method. If I try to initiate and release it outside of the loop, the memory leak is still there. I've tried testing to see if the blockBuffer
is NULL
, before releasing but that doesn't work. Please help!
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;
}
}
}
Upvotes: 1
Views: 1754
Reputation: 653
In addition to @sinn246's answer, you must also check the return of 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);
Upvotes: 1
Reputation: 21
blockBuffer is retained from nextBuffer, so it should be released BEFORE nextBuffer.
Upvotes: 2