Использование MediaCodec для декодирования необработанных аудиоданных AAC работает на Android 4.4, но не на 4.3
Я успешно реализовал кодирование / декодирование необработанного AAC-LC с использованием MediaCodec. Я использую ту же технику, описанную здесь, для кодирования данных. Однако я сохраняю необработанные данные AAC (без заголовков), а затем присоединяю заголовки на лету, когда передаю данные через декодер MediaCodec. Все это прекрасно работает на Nexus 4 и Nexus 5, работающих под управлением Android 4.4. Однако на Galaxy Nexus (под управлением Android 4.3) я получаю:
W/SoftAAC2(1234): AAC decoder returned error 16388, substituting silence
Ошибка 16388 означает ошибку кадра декодирования.
Я пробовал с и без начального MediaCodec.BUFFER_FLAG_CODEC_CONFIG, но это не имеет значения.
Вот простейший случай (с использованием пакета конфигурации) для воспроизведения ошибки:
MediaFormat format = new MediaFormat();
format.setInteger(MediaFormat.KEY_SAMPLE_RATE, 44100);
format.setInteger(MediaFormat.KEY_CHANNEL_COUNT, 1);
format.setString(MediaFormat.KEY_MIME, "audio/mp4a-latm");
format.setInteger(MediaFormat.KEY_AAC_PROFILE, MediaCodecInfo.CodecProfileLevel.AACObjectLC);
format.setInteger(MediaFormat.KEY_IS_ADTS, 1);
byte[] bytes = new byte[]{(byte) 0x11, (byte)0x90};
ByteBuffer bb = ByteBuffer.wrap(bytes);
format.setByteBuffer("csd-0", bb);
MediaCodec codec = MediaCodec.createDecoderByType("audio/mp4a-latm");
codec.configure(format, null /* surface */, null /* crypto */, 0 /* flags */);
codec.start();
ByteBuffer[] codecInputBuffers = codec.getInputBuffers();
int inputBufIndex = codec.dequeueInputBuffer(TIMEOUT_US);
if (inputBufIndex >= 0) {
ByteBuffer dstBuf = codecInputBuffers[inputBufIndex];
byte[] data = {-1, -7, 80, 0, 1, 63, -4, 18, 8}; // values taken from SO answer linked above (chanCfg = 1, packetLen = 9)
dstBuf.clear();
dstBuf.put(data);
codec.queueInputBuffer(inputBufIndex, 0, data.length, 0, MediaCodec.BUFFER_FLAG_CODEC_CONFIG);
}
Очевидно, что в коде гораздо больше, чем этот, но это включает в себя весь исполняемый код до момента сообщения об ошибке.
1 ответ
Решение состоит в том, чтобы не включать заголовки ADTS. И 4.3, и 4.4 поддерживают пакеты без заголовков ADTS.