1

AV Foundationのエクスポート機能を使用して、iPodライブラリのトラックからLPCMサンプルを読み取っています。私のコードのほとんどは、ここにあるChrisAdamsonの例から借用しています。

私は新しいものを設定し、CMBlockBufferRefそれをで保持していCMSampleBufferGetAudioBufferListWithRetainedBlockBufferます。アップルのCFTypeリファレンスによると、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;
        }
    }    
}
4

2 に答える 2

2

blockBufferはnextBufferから保持されるため、nextBufferの前に解放する必要があります。

于 2012-07-11T06:18:25.610 に答える
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);
于 2012-09-27T02:02:22.297 に答える