12

Android で MediaCodec API を使用して AAC ストリームをデコードしようとしています。(生の AAC です。) MediaFormat.createAudioFormat() を使用して、MediaCodec.configure() に渡すフォーマット オブジェクトを作成しようとしましたが、AAC (audio/mp4a-latm) を使用するとエラーが発生し続けました。(MP3 (オーディオ/mpeg) でも動作しますが...)

最後に、AAC ファイル用の MediaExtractor を作成し、それが生成するフォーマット オブジェクトを調べました。両方とも値が 0x12 の 2 バイトで構成される ByteBuffer のキー「csd-0」が含まれていることがわかりました。AAC コーデックの構成に使用したフォーマット オブジェクトにそのキーと値を含めると、すべてが機能します。

何が起こっているのか誰にも分かりますか?ドキュメントには、そのキーを構成するべきではないと記載されています。MediaExtractor を使用してフォーマット オブジェクトを生成せずに AAC ファイルをデコードするための MediaCodec の例へのポインタを持っている人はいますか?

4

3 に答える 3

4

はい、コーデック設定の 2 バイトが最初に受け取ります。はい、それは生のaacデータブロックです。エンコード中に以下の形式を導出する方法を確認できます。私は最初、latm形式であると述べたドキュメントに従って、それを解析しようとしました。次に、出力が実際に生のブロックであると述べたAndroidドキュメントで「差分」を見つけました。それを知っていれば、自分のニーズに合った容器を選ぶだけの問題でした. 特に、flv や mp4 ではなく、adts コンテナーが必要でした。

ペイロード データをコンテナーに十分な大きさの配列にコピーし、ビットを追加するだけです。したがって、インターネットでソリューションを探した後、次のコードを作成しました。

profile = (configParams[0]>>3)&0x1f;

frequency_index = (this.configParams[0]&0x7) <<1 | (this.configParams[1]>>7) &0x1;

channel_config = (this.configParams[1]>>3) &0xf;

int finallength = encoded_length + 7;       
ENCodedByteArray[0] = (byte) 0xff;
ENCodedByteArray[1] = (byte) 0xf1;
ENCodedByteArray[2] = (byte) ( ((profile - 1) << 6) + (frequency_index << 2) +(channel_config >> 2));
ENCodedByteArray[3] = (byte) (((channel_config & 0x3) << 6) + (finallength >> 11));
ENCodedByteArray[4] = (byte)( (finallength & 0x7ff) >> 3);
ENCodedByteArray[5] = (byte) (((finallength & 7) << 5) + 0x1f) ;
ENCodedByteArray[6] = (byte) 0xfc;

次のようなものを使用します。

byte chunkADTS[]=new byte[info.size + 7];
fillInADTSHeader(chunkADTS,info.size);
outputBuffers[bR].get(chunkADTS,7,info.size);
buffer.pushData(chunkADTS);
于 2013-06-28T03:55:10.910 に答える
2

私は次のコードを使用し、ADTS ヘッダーを削除した ES を追加しました。うまく動作する可能性がありますが、「csd-0」を設定する必要がある理由がわかりません。そうしないと、コーデック エラーが発生します。

      decoder = MediaCodec.createDecoderByType("audio/mp4a-latm");
      mMediaFormat = MediaFormat.createAudioFormat("audio/mp4a-latm", 44100,2);
      byte[] bytes = new byte[]{(byte) 0x12, (byte)0x12};
      ByteBuffer bb = ByteBuffer.wrap(bytes);
      mMediaFormat.setByteBuffer("csd-0", bb);
于 2014-03-12T03:10:46.343 に答える