我正在通过AV Foundation的导出功能从iPod库中的轨道读取LPCM样本。我的大多数代码都是从Chris Adamson's example here借来的。
我正在设置一个新的CMBlockBufferRef
并将其保留为CMSampleBufferGetAudioBufferListWithRetainedBlockBuffer
。根据apple 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;
}
}
}
答案 0 :(得分:2)
blockBuffer是从nextBuffer中保留的,所以它应该在nextBuffer之前释放。
答案 1 :(得分: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);