Cómo generar el flujo elemental AAC ADTS con Android MediaCodec

Lo que estoy tratando de hacer: use el MediaCodec de Android para codificar muestras de audio PCM sin procesar en un archivo AAC sin formato.

El problema que tengo: cuando uso FFMPEG para empaquetar el archivo AAC sin procesar generado en un contenedor M4A, FFMPEG se queja de que faltan parámetros de códec en el archivo.

Detalles:

Como no puedo encontrar ningún código de muestra de MediaCodec para el codificador de audio que genera un archivo AAC de salida, intenté modificar el codificador de video para convertirlo en un codificador de audio. El código original está aquí:código fuente

Configuré el codificador de audio así:

    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);

Luego alimento el codificador con 10 ms de muestras de PCM por fotograma. El codificador toma cada cuadro, genera un cuadro de flujo de bits y escribo el flujo de bits en un FileOutputStream. El bucle continúa hasta el final del archivo de entrada.

El código se ejecuta hasta el final. Hago 'adb pull' para obtener el archivo AAC generado desde el dispositivo a mi PC y uso FFMPEG para leerlo. A continuación se muestra el comando y el error que escupe FFMPEG:

$ 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

Mis preguntas:

He configurado el codificador antes de llamar a codec.start (). ¿Por qué el archivo AAC generado carece de los parámetros del códec?En el ejemplo del códec de video original, los parámetros "csd-0" se pasan del codificador al decodificador, pero no se escriben explícitamente en el archivo de flujo de bits. ¿Necesito escribirlos explícitamente en el archivo AAC?Divido las muestras PCM de entrada en 10 ms por trama, lo que no necesariamente produce un paquete de salida completo. Para cada marco de entrada, solo escribo lo que sea que el codificador produzca en el archivo. ¿Es eso un motivo de preocupación?

Cualquier ayuda será profundamente apreciada. Sería genial si hubiera un proyecto de muestra que haga lo que estoy tratando de hacer aquí. Si mi código fuente puede ayudarlo a ayudarme, lo publicaré. Necesito hacer algo de limpieza. ¡Gracias!

Editar: Se cambió el título de "Archivo AAC elemental generado por los parámetros del códec de MediaCodec que faltan" a "Cómo generar la transmisión elemental AAC ADTS con Android MediaCodec"

Respuestas a la pregunta(1)

Su respuesta a la pregunta