So generieren Sie den AAC ADTS-Elementar-Stream mit Android MediaCodec

Was ich versuche zu tun: Verwenden Sie den MediaCodec von Android, um unformatierte PCM-Audiobeispiele in eine unformatierte AAC-Datei zu kodieren.

Das Problem, das ich habe: Wenn ich FFMPEG verwende, um die generierte rohe AAC-Datei in einen M4A-Container zu packen, beklagt sich FFMPEG über fehlende Codec-Parameter in der Datei.

Einzelheiten:

Da ich keinen MediaCodec-Beispielcode für den Audio-Encoder finde, der eine AAC-Ausgabedatei generiert, habe ich versucht, den Video-Encoder in einen Audio-Encoder umzuwandeln. Der Originalcode ist hier:Quellcode

Ich habe den Audio-Encoder folgendermaßen konfiguriert:

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

Dann versorge ich den Encoder mit 10ms PCM-Samples pro Frame. Der Encoder nimmt jeden Frame, generiert einen Frame mit Bitstream und ich schreibe den Bitstream in einen FileOutputStream. Die Schleife wird bis zum Ende der Eingabedatei fortgesetzt.

Der Code läuft bis zum Ende. Ich mache 'adb pull', um die generierte AAC-Datei vom Gerät auf meinen PC zu übertragen und benutze FFMPEG, um sie zu lesen. Unten ist der Befehl und der Fehler, den FFMPEG ausgibt:

$ 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

Meine Fragen:

Ich habe den Encoder vor dem Aufruf von codec.start () konfiguriert. Warum fehlen der generierten AAC-Datei die Codec-Parameter?Im ursprünglichen Videocodec-Beispiel werden die Parameter "csd-0" vom Codierer zum Decodierer übergeben, jedoch nicht explizit in die Bitstream-Datei geschrieben. Muss ich sie explizit in die AAC-Datei schreiben?Ich teile die Eingangs-PCM-Samples in 10 ms pro Frame auf, was nicht unbedingt ein vollständiges Ausgangspaket ergibt. Für jeden Eingaberahmen schreibe ich einfach alles, was der Encoder ausgibt, in die Datei. Ist das ein Grund zur Sorge?

Jede Hilfe wird sehr geschätzt. Es wäre toll, wenn es ein Beispielprojekt gäbe, das das tut, was ich hier versuche. Wenn mein Quellcode Ihnen helfen kann, werde ich es posten. Ich muss aufräumen. Vielen Dank!

Bearbeiten: Der Titel von "Elementare AAC-Datei, die durch fehlende Codec-Parameter in MediaCodec generiert wurde" wurde in "Generieren des AAC ADTS-Elementar-Streams mit Android MediaCodec" geändert.

Antworten auf die Frage(1)

Ihre Antwort auf die Frage