Android 9 AAC декодер выводит ноль выборок с файлами в кодировке ffmpeg - PullRequest
0 голосов
/ 23 октября 2018

У меня есть несколько автоматических тестов, которые пытаются декодировать несколько файлов 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 довольно популярен, вполне вероятно, что многие пользователи моего приложения попытаются импортировать сгенерированные с его помощью файлы, и на данный момент я не вижу надежного решения этой проблемы.

У кого-нибудь есть предложение / обходной путь?

1 Ответ

0 голосов
/ 25 октября 2018

Я открыл проблему на трекере проблем андроида: https://issuetracker.google.com/issues/118398811

И сейчас я только что реализовал обходной путь: когда значение «encoder-delay» присутствует в объекте MediaFormat и этоневозможно высокое значение, я просто установил его на ноль.Что-то вроде:

if (format.containsKey("encoder-delay") && format.getInteger("encoder-delay") > THRESHOLD) {
    format.setInteger("encoder-delay", 0);
}

NB: Это означает, что начальный разрыв не будет обрезан, но для файлов M4a, которые не имеют такой информации, это уже относится кустройства android-9.

...