Jak wygenerować podstawowy strumień AAC ADTS z Android MediaCodec
Co próbuję zrobić: użyj MediaCodec Androida do zakodowania surowych próbek audio PCM w surowym pliku AAC.
Mam problem: kiedy używam FFMPEG do spakowania wygenerowanego surowego pliku AAC do kontenera M4A, FFMPEG skarży się na brak parametrów kodeka w pliku.
Detale:
Ponieważ nie mogę znaleźć żadnego przykładowego kodu MediaCodec dla kodera audio, który generuje wyjściowy plik AAC, próbowałem zmodyfikować koder wideo do kodera audio. Oryginalny kod jest tutaj:kod źródłowy
Skonfigurowałem koder audio w ten sposób:
mEncoderFormat = MediaFormat.createAudioFormat("audio/mp4a-latm", (int)mAudioSampleRate, 2);
// redundant?
mEncoderFormat.setString(MediaFormat.KEY_MIME, "audio/mp4a-latm");
mEncoderFormat.setInteger(MediaFormat.KEY_AAC_PROFILE,
MediaCodecInfo.CodecProfileLevel.AACObjectELD);
mEncoderFormat.setInteger(MediaFormat.KEY_SAMPLE_RATE, kSampleRates);
mEncoderFormat.setInteger(MediaFormat.KEY_BIT_RATE, kBitRates);
mEncoderFormat.setInteger(MediaFormat.KEY_CHANNEL_COUNT, 2);
testEncoderWithFormat("audio/mp4a-latm", mEncoderFormat);
try {
codec.configure(
mEncoderFormat,
null /* surface */,
null /* crypto */,
MediaCodec.CONFIGURE_FLAG_ENCODE);
} catch (IllegalStateException e) {
Log.e(TAG, "codec '" + componentName + "' failed configuration.");
return;
}
Log.d(TAG, " testEncoder configured with format = " + format);
Następnie zasilam koder próbkami PCM o wartości 10 ms na klatkę. Koder pobiera każdą ramkę, generuje ramkę strumienia bitów i zapisuję strumień bitów do pliku FileOutputStream. Pętla trwa do końca pliku wejściowego.
Kod działa do końca. Robię „adb pull”, aby uzyskać wygenerowany plik AAC z urządzenia na mój komputer i użyć FFMPEG do jego odczytania. Poniżej znajduje się polecenie, a błąd FFMPEG wypluwa:
$ ffmpeg -f aac -i BlessedNoColor_nexus7_api18.aac
ffmpeg version N-45739-g04bf2e7 Copyright (c) 2000-2012 the FFmpeg developers
built on Oct 20 2012 00:20:36 with gcc 4.7.2 (GCC)
configuration: --enable-gpl --enable-version3 --disable-pthreads --enable-runt
ime-cpudetect --enable-avisynth --enable-bzlib --enable-frei0r --enable-libass -
-enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libfreetype --enab
le-libgsm --enable-libmp3lame --enable-libnut --enable-libopenjpeg --enable-libo
pus --enable-librtmp --enable-libschroedinger --enable-libspeex --enable-libtheo
ra --enable-libutvideo --enable-libvo-aacenc --enable-libvo-amrwbenc --enable-li
bvorbis --enable-libvpx --enable-libx264 --enable-libxavs --enable-libxvid --ena
ble-zlib
libavutil 51. 76.100 / 51. 76.100
libavcodec 54. 67.100 / 54. 67.100
libavformat 54. 33.100 / 54. 33.100
libavdevice 54. 3.100 / 54. 3.100
libavfilter 3. 19.103 / 3. 19.103
libswscale 2. 1.101 / 2. 1.101
libswresample 0. 16.100 / 0. 16.100
libpostproc 52. 1.100 / 52. 1.100
[aac @ 00000000002efae0] channel element 2.0 is not allocated
[aac @ 00000000003cf520] decoding for stream 0 failed
[aac @ 00000000003cf520] Could not find codec parameters for stream 0 (Audio: aac, 0 channels, s16): unspecified sample rate
Consider increasing the value for the 'analyzeduration' and 'probesize' options
[aac @ 00000000003cf520] Estimating duration from bitrate, this may be inaccurate
BlessedNoColor_nexus7_api18.aac: could not find codec parameters
Moje pytania:
Skonfigurowałem koder przed wywołaniem codec.start (). Dlaczego wygenerowanemu plikowi AAC brakuje parametrów kodeków?W oryginalnym przykładzie kodeka wideo parametry „csd-0” są przekazywane z kodera do dekodera, ale nie są zapisywane bezpośrednio w pliku strumienia bitów. Czy muszę jawnie zapisać je w pliku AAC?Próbki wejściowe PCM dzielę na 10 ms na ramkę, co niekoniecznie daje kompletny pakiet wyjściowy. Dla każdej ramki wejściowej po prostu piszę, co koder wyprowadza do pliku. Czy to powód do niepokoju?Każda pomoc będzie głęboko doceniona. Byłoby wspaniale, gdyby istniał przykładowy projekt, który robi to, co próbuję tutaj zrobić. Jeśli mój kod źródłowy może ci pomóc, opublikuję go. Muszę trochę posprzątać. Dzięki!
Edytować: Zmieniono tytuł z „Elementarnego pliku AAC wygenerowanego przez brakujące parametry kodeka MediaCodec” na „Jak wygenerować podstawowy strumień AAC ADTS z Android MediaCodec”