У меня есть несколько автоматических тестов, которые пытаются декодировать несколько файлов m4a в данные PCM, используя Android MediaDecoder
и MediaExtractor
.Файлы генерируются различными кодировщиками: fdk-aac , ffmpeg (с fdk или кодировщиком aac по умолчанию), iOS.
В Android 9 тест не пройден для клипов, созданных с помощью ffmpeg
, что приводит к пустым файлам PCM.Те же клипы прекрасно декодируются на старых версиях Android.
Я дважды проверил свой код, и процесс декодирования идет так, как ожидалось:
- Я извлекаю сжатые данные, используя
MediaExtractor
- Поставьте его в кодек
- Очистите буфер вывода из кодека.
Проблема в том, что к тому времени, когда последний доступный входной буфер ставится в очередь и выходной буфер с MediaCodec.BUFFER_FLAG_END_OF_STREAM
удаляется, все выходные буферы пусты!
Затем я заметил, что информация MediaFormat
, извлеченная из аудиофайла с помощью MediaExtractor.getTrackFormat(int track)
, содержит недокументированную клавишу "encoder-delay"
.
Для android 8 и ниже эта клавиша присутствует только для клипов m4a, закодированных с информацией тега iTunSMPB
.Вот сводка значений, которые я получаю для своих тестовых файлов:
iOS-encoded file: 2112 frames
fdkaac with iTunSMPB tag: 2048 frames
fdkaac with ISO delay info: key not present
ffmpeg: key not present
ffmpeg (fdk): key not present
На Android 9 вместо этого я получаю следующие результаты:
iOS-encoded file: 2112 frames
fdkaac with iTunSMPB tag: 2048 frames
fdkaac with ISO delay info: 2048 frames
ffmpeg: 45158 frames
ffmpeg (fdk): 90317 frames
Itпохоже, что что-то изменилось и MediaExtractor
теперь может получить задержку кодировщика для всех тестируемых файлов.Это хорошо в теории, поскольку файлы без информации "encoder-delay"
показывают задержку в декодированных данных PCM (это была известная проблема).
Но ... в то время как значение для «fdkaac with ISO delay info» регистр правильный и приводит к правильному файлу PCM без начального заполнения (наконец-то!), значения для сгенерированных ffmpeg файлов выглядят огромными и, вероятно, неверными!
Iзнаю, что реальные значения задержки кодировщика равны 1024 для случая ffmpeg и 2048 для случая ffmpeg (fdk) , и я думаю, что высокое значение для ключа в извлеченном формате является причинойпочему файл пуст.
На самом деле, если я попытаюсь установить ключ "encoder-delay"
на 0 в формате непосредственно перед передачей его на MediaCodec.configure(...)
, я получу правильные несжатые данные с ожидаемой задержкой.
На данный момент я предполагаю, что при получении значения задержки энкодера MediaExtractor
есть какая-то ошибка, но, возможно, я что-то упускаю из виду.
Поскольку ffmpeg довольно популярен, вполне вероятно, что многие пользователи моего приложения попытаются импортировать сгенерированные с его помощью файлы, и на данный момент я не вижу надежного решения этой проблемы.
У кого-нибудь есть предложение / обходной путь?