What I am trying to do: use Android's MediaCodec to encode raw PCM audio samples into a raw AAC file.
The problem I have: when I use FFMPEG to pack the generated raw AAC file into an M4A container, FFMPEG complains about missing codec parameters in the file.
Details:
Since I can't find any MediaCodec sample code for the audio encoder that generates an output AAC file, I tried to modify the video encoder into an audio encoder. The original code is here: source_code
I configured the audio encoder like this:
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); Then I feed the encoder with 10ms worth of PCM samples per frame. The encoder takes each frame, generates a frame of bitstream, and I write the bitstream into an FileOutputStream. The loop continues until the end of the input file.
The code runs to the finish. I do 'adb pull' to get the generated AAC file from the device to my PC, and use FFMPEG to read it. Below is the command and the error FFMPEG spits out:
$ 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 My questions:
- I've configured the encoder before calling codec.start(). Why does the generated AAC file lack the codec parameters?
- In the original video codec example, parameters "csd-0" are passed from the encoder to decoder, but are not written into the bitstream file explicitly. Do I need to write them into the AAC file explicitly?
- I divide the input PCM samples into 10ms per frame, which does not necessarily produce a complete output packet. For each input frame, I just write whatever the encoder outputs into the file. Is that a cause for concern?
Any helps will be deeply appreciated. It'd be great if there is a sample project that does what I'm trying to do here. If my source code can help you help me, I'll post it. I need to do some cleanup. Thanks!
Edit: Changed the title from "Elementary AAC file generated by MediaCodec missing codec parameters" to "How to generate the AAC ADTS elementary stream with Android MediaCodec"