How do I call CMSampleBufferGetAudioBufferListWithRetainedBlockBuffer?

后端 未结 6 1066
北荒
北荒 2021-01-13 04:10

I\'m trying to figure out how to call this AVFoundation function in Swift. I\'ve spent a ton of time fiddling with declarations and syntax, and got this far.

6条回答
  •  耶瑟儿~
    2021-01-13 05:04

    The answers posted here make assumptions about the size of the necessary AudioBufferList -- which may have allowed them to have work in their particular circumstance, but didn't work for me when receiving audio from a AVCaptureSession. (Apple's own sample code didn't work either.)

    The documentation on CMSampleBufferGetAudioBufferListWithRetainedBlockBuffer is not obvious, but it turns out you can ask the function it how big AudioListBuffer item should be first, and then call it a second time with an AudioBufferList allocated to the size it wants.

    Below is a C++ example (sorry, don't know Swift) that shows a more general solution that worked for me.

    // ask the function how big the audio buffer list should be for this
    // sample buffer ref
    size_t requiredABLSize = 0;
    err = CMSampleBufferGetAudioBufferListWithRetainedBlockBuffer(sampleBuffer,
                          &requiredABLSize,
                          NULL,
                          NULL,
                          kCFAllocatorSystemDefault,
                          kCFAllocatorSystemDefault,
                          kCMSampleBufferFlag_AudioBufferList_Assure16ByteAlignment,
                          NULL);
    
    // allocate an audio buffer list of the required size
    AudioBufferList* audioBufferList = (AudioBufferList*) malloc(requiredABLSize);
    // ensure that blockBuffer is NULL in case the function fails
    CMBlockBufferRef blockBuffer = NULL;
    
    // now let the function allocate fill in the ABL for you
    err = CMSampleBufferGetAudioBufferListWithRetainedBlockBuffer(sampleBuffer,
                          NULL,
                          audioBufferList,
                          requiredABLSize,
                          kCFAllocatorSystemDefault,
                          kCFAllocatorSystemDefault,
                          kCMSampleBufferFlag_AudioBufferList_Assure16ByteAlignment,
                          &blockBuffer);
    
    // if we succeeded...
    if (err == noErr) {
       // la la la... read your samples...
    }
    
    // release the allocated block buffer
    if (blockBuffer != NULL) {
        CFRelease(blockBuffer);
        blockBuffer = NULL;
    }
    
    // release the allocated ABL
    if (audioBufferList != NULL) {
        free(audioBufferList);
        audioBufferList = NULL;
    }
    

    I'll leave it up to the Swift experts to offer an implementation in that language.

提交回复
热议问题