AudioStreamPacketDescription

AudioStreamPacketDescription

尝试一次我得到CrashIfClientProvidedBogusAudioBufferList异常AudioConverterFillComplexBuffer回调返回。为什么会引发此异常的可能原因是什么?

供引用,这是我的电话

AudioConverterFillComplexBuffer(audioConverterRef,
fillComplexCallback,
&convertInfo,
&framesToDecode,
&localPcmBufferList,

和回调:
func fillComplexxCallback(myConverter: AudioConverterRef, packetNumber: UnsafeMutablePointer<UInt32>,
ioData: UnsafeMutablePointer<AudioBufferList>, aspd: UnsafeMutablePointer<UnsafeMutablePointer<AudioStreamPacketDescription>>,
userInfo: UnsafeMutablePointer<Void>) -> OSStatus {

    var convertInfo = UnsafeMutablePointer<AudioConvertInfo>(userInfo).memory

    if (packetNumber.memory > (convertInfo.audioBuffer.mDataByteSize / convertInfo.numberOfPackets)) {
        packetNumber.memory = (convertInfo.audioBuffer.mDataByteSize / convertInfo.numberOfPackets)
    }

    ioData.memory.mNumberBuffers = 1
    var buffer = AudioBuffer(mNumberChannels: 2, mDataByteSize: convertInfo.audioBuffer.mDataByteSize, mData: ioData.memory.mBuffers.mData)
    ioData.memory.mBuffers = buffer

     /* if the following is uncommented out, a exception is thrown */
    // aspd.memory = convertInfo.packetDescriptions
    packetNumber.memory = convertInfo.numberOfPackets
    convertInfo.done = true

        return 0
}

这是AudioConvertInfo's结构:
struct AudioConvertInfo {
    var done: Bool! //conversion of audio is finished
    var numberOfPackets: UInt32!
    var audioBuffer: AudioBuffer!
    var audioPlayer: CCPlayer!
    var packetDescriptions: AudioStreamPacketDescription!

    init(done: Bool?, numberOfPackets: UInt32?, audioBuffer: AudioBuffer?, packetDescriptions: AudioStreamPacketDescription!, audioPlayer: CCPlayer!) {
        self.done = done
        self.numberOfPackets = numberOfPackets
        self.audioBuffer = audioBuffer
        self.packetDescriptions = packetDescriptions
        self.audioPlayer = audioPlayer
    }
}

我似乎找不到任何可靠的文档。我注意到aspd(AudioStreamPacketDescription)返回nil。确定音频数据缓冲区中一个数据包大小不同或音频数据包之间存在非音频数据的数据包,这一点很重要。此代码将在aspd.memory = convertInfo.packetDescriptions上引发异常,但是如果注释掉该代码,则会抛出CrashIfClientProvidedBogusAudioBufferList。我的理论是,如果我弄清楚为什么AudioStreamPacketDescription为nil,则此回调将正常工作

最佳答案

好像AudioStreamPacketDescription is nil没问题。
根据Apple文档,它可以为零,基本上取决于音频格式:
AudioConverterComplexInputDataProc



AudioConverterFillComplexBuffer



真正的问题在这一行中的AudioConvertInfo结构中:

var packetDescriptions: AudioStreamPacketDescription!

结构仅保留单个AudioStreamPacketDescription结构。
然后在fillComplexCallback函数中使用它:
outDataPacketDescription.memory.memory = convertInfo.packetDescriptions

因此,您尝试将单个AudioStreamPacketDescription结构设置为需要outDataPacketDescription结构数组的参数AudioStreamPacketDescription(而不仅仅是单个实例)。

可以通过保留和使用AudioStreamPacketDescription结构数组来解决此问题。AudioConvertInfo结构的更新版本:
struct AudioConvertInfo {
    var done: Bool!
    var numberOfPackets: UInt32!
    var audioBuffer: AudioBuffer!
    var audioPlayer: CCPlayer!
    var packetDescriptions: UnsafeMutablePointer<AudioStreamPacketDescription>!

    init(done: Bool?, numberOfPackets: UInt32?, audioBuffer: AudioBuffer?, packetDescriptions: UnsafeMutablePointer<AudioStreamPacketDescription>!, audioPlayer: CCPlayer!) {
        self.done = done
        self.numberOfPackets = numberOfPackets
        self.audioBuffer = audioBuffer
        self.packetDescriptions = packetDescriptions
        self.audioPlayer = audioPlayer
    }
}

// Usage:
convertInfo = AudioConvertInfo(done: false, numberOfPackets: numberPackets, audioBuffer: AudioBuffer(mNumberChannels: 2, mDataByteSize: numberBytes, mData: &iData), packetDescriptions: packetDescriptions, audioPlayer: self)
fillComplexCallback函数的更新版本:
func fillComplexCallback(inAudioConverter: AudioConverterRef, ioNumberDataPackets: UnsafeMutablePointer<UInt32>, ioData: UnsafeMutablePointer<AudioBufferList>, outDataPacketDescription: UnsafeMutablePointer<UnsafeMutablePointer<AudioStreamPacketDescription>>, inUserData: UnsafeMutablePointer<Void>) -> OSStatus {
    var convertInfo = UnsafeMutablePointer<AudioConvertInfo>(inUserData).memory

    if convertInfo.done == true {
        ioNumberDataPackets.memory = 0
        return 100
    }
    ioData.memory.mNumberBuffers = 1
    let buffer = convertInfo.audioBuffer
    ioData.memory.mBuffers = buffer

    if outDataPacketDescription != nil {
        outDataPacketDescription.memory = convertInfo.packetDescriptions
    }

    ioNumberDataPackets.memory = convertInfo.numberOfPackets
    convertInfo.done = true

    return 0
}

// Usage:
status = AudioConverterFillComplexBuffer(audioConverterRef, fillComplexCallback, &convertInfo!, &framesToDecode, &localPcmBufferList!, nil)

希望它能解决您的问题。

关于ios - (快速)如何在AudioStreamPacketDescription为nil时调试CrashIfClientProvidedBogusAudioBufferList?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31708398/

10-10 20:43