AudioBufferList* convertPCMToAAC (XDXRecorder *recoder) {
UInt32 maxPacketSize = 0;
UInt32 size = sizeof(maxPacketSize);
OSStatus status;
status = AudioConverterGetProperty(_encodeConvertRef,
kAudioConverterPropertyMaximumOutputPacketSize,
&size,
&maxPacketSize);
// log4cplus_info("AudioConverter","kAudioConverterPropertyMaximumOutputPacketSize status:%d \n",(int)status);
AudioBufferList *bufferList = (AudioBufferList *)malloc(sizeof(AudioBufferList));
bufferList->mNumberBuffers = 1;
bufferList->mBuffers[0].mNumberChannels = _targetDes.mChannelsPerFrame;
bufferList->mBuffers[0].mData = malloc(maxPacketSize);
bufferList->mBuffers[0].mDataByteSize = kTVURecoderPCMMaxBuffSize;
AudioStreamPacketDescription outputPacketDescriptions;
UInt32 inNumPackets = 1;
pthread_mutex_lock(&pcmBufferMutex);
status = AudioConverterFillComplexBuffer(_encodeConvertRef,
encodeConverterComplexInputDataProc,
pcm_buffer,
&inNumPackets,
bufferList,
&outputPacketDescriptions);
pthread_mutex_unlock(&pcmBufferMutex);
if(status != noErr){
// log4cplus_debug("Audio Recoder","set AudioConverterFillComplexBuffer status:%d inNumPackets:%d \n",(int)status, inNumPackets);
free(bufferList->mBuffers[0].mData);
free(bufferList);
return NULL;
}
if (recoder.needsVoiceDemo) {
OSStatus status = AudioFileWritePackets(recoder.mRecordFile,
FALSE,
bufferList->mBuffers[0].mDataByteSize,
&outputPacketDescriptions,
recoder.mRecordPacket,
&inNumPackets,
bufferList->mBuffers[0].mData);
// log4cplus_info("write file","write file status = %d",(int)status);
if (status == noErr) {
recoder.mRecordPacket += inNumPackets;
}
}
return bufferList;
}
上述将PCM转换为AAC的代码在18以下的iOS版本中工作正常,但在iOS 18中,转换过程中出现崩溃。控制台没有提供太多有用的信息,应用程序在 malloc(maxPacketSize) 或 AudioConverterFillComplexBuffer() 处崩溃,显示消息 AURemoteIO::IOThread (14): EXC_BAD_ACCESS (code=1, address=0x0)。请帮忙查明事故原因。
希望能够彻底解决这个崩溃问题。
为了加强更严格的内存安全,iOS 18 引入了新的内存分配功能:
系统内存分配器 (malloc(3)) 已针对大多数分配大小切换到新的实现。由于堆布局的变化、分配繁重的工作负载的性能差异以及碎片的变化,用户可能会遇到潜在的内存访问错误。 (127493322)
这可能包括如何处理零大小缓冲区的内存分配的变化,以防止信息泄露和其他内存安全问题。
根据 malloc 文档:
内存分配器的崩溃几乎总是与堆损坏有关,例如溢出分配的块......
您没有检查 AudioConverterGetProperty 函数的返回状态。 检查 maxPacketSize 是否已初始化,并且此调用的结果不是零。 还要检查尺寸是否确实足够。