我在尝试一次时遇到了 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 的
结构:
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
outDataPacketDescription: UnsafeMutablePointer<UnsafeMutablePointer<AudioStreamPacketDescription>>
- If not NULL on input, the audio converter expects this callback to provide an array of AudioStreamPacketDescription structures on output, one for each packet of audio data you are providing in the ioData parameter.
AudioConverterFillComplexBuffer
outPacketDescription: UnsafeMutablePointer<AudioStreamPacketDescription>
- On input, must point to a block of memory capable of holding the number of packet descriptions specified in the ioOutputDataPacketSize parameter. (See Audio Format Services Reference for functions that let you determine whether an audio format uses packet descriptions). If not NULL on output and if the audio converter’s output format uses packet descriptions, then this parameter contains an array of packet descriptions.
真正的问题放在了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/