У меня есть несколько автоматических тестов, которые пытаются декодировать несколько файлов 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
Похоже, что-то изменилось, и теперь MediaExtractor
может получить задержку кодировщика для всех тестируемых файлов. Теоретически это хорошо, так как файлы без информации "encoder-delay"
показывают задержку в декодированных данных PCM (это была известная проблема).
Но... в то время как значение для случая "fdkaac с информацией о задержке ISO" является правильным и приводит к действительному файлу PCM без начального заполнения (наконец-то!), значения для файлов, сгенерированных ffmpeg выглядеть огромным и, вероятно, неправильно!
Я знаю, что реальные значения задержки кодировщика составляют 1024 для случая ffmpeg и 2048 для случая ffmpeg (fdk), и я думаю, что высокое значение для ключа в извлеченном формате является причиной того, что файл пуст.
На самом деле, если я попытаюсь установить ключ "encoder-delay"
в 0 в формате непосредственно перед передачей его в MediaCodec.configure(...)
, я получу правильные несжатые данные с ожидаемой задержкой.
На данный момент я предполагаю, что при извлечении значения задержки энкодера MediaExtractor
есть некоторая ошибка, но, возможно, я что-то упускаю из виду.
Поскольку ffmpeg довольно популярен, вполне вероятно, что многие пользователи моего приложения попытаются импортировать сгенерированные с его помощью файлы, и на данный момент я не вижу надежного решения проблемы.
У кого-нибудь есть предложение/обходной путь?