- Вопрос или проблема
- Ответ или решение
- Причины сбоя при конвертации PCM в AAC в iOS 18
- 1. Проблема с выделением памяти
- 2. Безопасность потоков
- 3. Параметры AudioBufferList
- 4. Ошибки в обработчике encodeConverterComplexInputDataProc
- 5. Проверка адресации памяти и границ массива
- Рекомендации по исправлению
- Заключение
Вопрос или проблема
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 работает нормально в версиях iOS ниже 18, но в iOS 18 происходят сбои во время процесса преобразования. Консоль не предоставляет много полезной информации, и приложение выдает сбой на malloc(maxPacketSize) или AudioConverterFillComplexBuffer(), отображая сообщение AURemoteIO::IOThread (14): EXC_BAD_ACCESS (code=1, address=0x0). Пожалуйста, помогите установить причину сбоя.
Я надеюсь полностью решить эту проблему с сбоем.
Ответ или решение
Причины сбоя при конвертации PCM в AAC в iOS 18
При разработке приложений на iOS, особенно когда речь идет о работе с аудиоданными, могут возникать различные проблемы из-за изменений в системных библиотеках или изменениях в самой платформе. Описанный вами код, работавший должным образом в предыдущих версиях iOS, вызывает сбой при конвертации PCM в AAC в iOS 18. Давайте рассмотрим возможные причины этого сбоя и шаги по его исправлению.
1. Проблема с выделением памяти
Согласно предоставленному коду, проблема может возникать на этапе выполнения функции malloc(maxPacketSize)
. Система возвращает ошибку EXC_BAD_ACCESS, что указывает на проблему с доступом к памяти. Это может происходить по нескольким причинам:
- Некорректное значение maxPacketSize: Проверьте, корректно ли вы получаете значение
maxPacketSize
черезAudioConverterGetProperty
. Если это значение равно нулю или больше, чем размер доступной памяти, это приведет к сбою. - Проблемы с инициализацией AudioConverter: Убедитесь, что
_encodeConvertRef
инициализирован правильно до вызоваAudioConverterFillComplexBuffer()
. Неправильная или незавершенная инициализация может вызывать сбой.
2. Безопасность потоков
Вы используете pthread_mutex_lock()
и pthread_mutex_unlock()
, чтобы защитить доступ к pcm_buffer
. Убедитесь, что данные в pcm_buffer
корректны и доступны в момент вызова. Также проверьте, что поток, удерживающий мьютекс, не вызывает никаких блокировок или зависаний.
3. Параметры AudioBufferList
Ваша структура AudioBufferList
должна корректно соотноситься с ожидаемыми значениями в конфигурации кодировщика AAC. Проверьте, что mNumberChannels
и другие поля правильно установлены:
bufferList->mBuffers[0].mNumberChannels = _targetDes.mChannelsPerFrame;
// Убедитесь, что это значение соответствует вашим данным PCM
4. Ошибки в обработчике encodeConverterComplexInputDataProc
Убедитесь, что пользовательская функция обратного вызова encodeConverterComplexInputDataProc
возвращает корректные результаты. Неверная реализация этой функции может привести к неправильной интерпретации данных во время конвертации.
5. Проверка адресации памяти и границ массива
Использование bufferList
требует надлежащего обращения с памятью, чтобы избежать утечек или переполнения буфера. Убедитесь, что все выделенные массивы имеют правильные размеры и что вы не обращаетесь к области памяти за пределами выделенной.
Рекомендации по исправлению
-
Проверьте значения переменных: Включите тщательную отладку, чтобы убедиться, что
maxPacketSize
действительно имеет ожидаемое значение. Если оно равно нулю или низкому значению, исправьте это. -
Инициализация AudioConverter: Убедитесь, что
_encodeConvertRef
корректно инициализирован перед его использованием. -
Обработка ошибок: Улучшите обработку ошибок, выводите более подробные сообщения, что позволит легче выявлять источники ошибок.
-
Тестирование: Запустите ваш код в среде тестирования с различными конфигурациями аудио и наблюдайте за поведением на разных устройствах с iOS 18.
-
Обновления и исправления: Следите за обновлениями SDK и сравните их с предыдущими версиями, так как изменения могут затрагивать аудио API.
Заключение
Работа с аудио в iOS может быть сложной, и изменения в новых версиях системы иногда требуют гибкости в коде. Обратите внимание на указанные выше аспекты при поиске решения проблемы. Всесторонний подход к отладке и тестированию поможет в выявлении и устранении причин сбоя.