2017-11-07 27 views
0

MediaMuxerとMediaCodecを使用して、ビデオ(H264)データとオーディオ(AAC-ファイル。しかしMediaMuxerオブジェクトが時々mediaMuxer.stop()でクラッシュし、エラーログがMediaMuxerを使用してMP4ファイルをエンコードしますが、mediaMuxer.stop()をコールするとクラッシュします。

11-03 16:28:36.956: A/DEBUG(711): Abort message: 'frameworks/av/media/libstagefright/MPEG4Writer.cpp:2983 CHECK_LT(mCodecSpecificDataSize + 23,128) failed: 399 vs. 128' 
11-03 16:28:36.957: A/DEBUG(711):  x0 0000000000000000 x1 0000000000001184 x2 0000000000000006 x3 0000000000000000 
11-03 16:28:36.957: A/DEBUG(711):  x4 0000000000000000 x5 0000000000000001 x6 0000000000000000 x7 0000000000000000 
11-03 16:28:36.957: A/DEBUG(711):  x8 0000000000000083 x9 0000000000000000 x10 0000000000000000 x11 0000007f91bb0df8 
11-03 16:28:36.958: A/DEBUG(711):  x12 0000007f91bb0cd0 x13 0000000000000077 x14 0000007f91bb0ea8 x15 0000000000000000 
11-03 16:28:36.958: A/DEBUG(711):  x16 0000007faca8d6a8 x17 0000007faca4fb2c x18 0000007face14418 x19 0000007f91bb3510 
11-03 16:28:36.959: A/DEBUG(711):  x20 0000007f91bb3450 x21 000000000000000b x22 0000000000000006 x23 00000055a17fd260 
11-03 16:28:36.959: A/DEBUG(711):  x24 0000007f91bb1c58 x25 0000007f91bb18b4 x26 0000007f91bb1f90 x27 0000007fa9715000 
11-03 16:28:36.960: A/DEBUG(711):  x28 0000007f91bb1898 x29 0000007f91bb0d60 x30 0000007faca4d2c8 
11-03 16:28:36.960: A/DEBUG(711):  sp 0000007f91bb0d60 pc 0000007faca4fb34 pstate 0000000020000000 

である私は、単一のトラック(ビデオまたはオーディオ)何回もエンコードしようとしました。 mediaMuxer.stop()の実行は全く問題ありませんでした。

なぜ2つのトラックをエンコードしたときにCHECK_LTが失敗したのですか?

答えて

0

私はここに自分自身を答えるために来ました。

24時間体制で作業した結果、AACトラックを多重化するときにMediaMuxer.stop()がクラッシュする原因が多数あることが判明しました。

クラッシュを避けるために、あなたはあなたの実装には、次の規則によって、より良いプレーだった:AACエンコードのための同期モードで使用MediaCodec

  1. を。シンクモードを使用すると、オーディオレコーダーからMediaCodecの入力バッファーにオーディオサンプル(DirectByteBuffer)を余分なメモリーコピーをすばやく入力することができます。あまりにも多くのサンプルをドロップすると、MediaMuxerがクラッシュします。

  2. 同期モードを使用するもう1つの理由は、あなたは常にあなたがMediaCodecへの書き込みサンプルについて実施し、あなたのwriteAudioSample方法で利用できる入力バッファを得ることができることを確認するためにMediaMuxer.dequeueInputBuffer(-1)を使用することができるということです。

  3. 同期モードを使用するもう1つの理由は、MediaMuxer.stop()の前にAACでエンコードされたデータをに転送する必要があることです。自分でMediaFormat.KEY_MAX_INPUT_SIZEを設定し、値がの倍数でなければならない(1024 16ビットサンプル、バイトのため、長さが2048である)

  4. (ルール9を参照)。私は通常、オーディオソースのサンプルレート、チャンネル数、アプリケーションとデバイスのパフォーマンスに応じて、に設定します。

  5. 入力サンプルにオーディオデータがいっぱいで、長さがMediaFormat.KEY_MAX_INPUT_SIZEに設定されていることを保証します。そして、提示時間をマイクロ秒単位で計算する。隣接する2つの入力サンプル間の提示時間の間隔は同じでなければならない。この式でサンプルの期間を計算します1_000_000L * KEY_MAX_INPUT_SIZE/SAMPLE_RATE/NUMBER_OF_CHANNELS/2。プレゼンテーション時間をに調整する必要はありません。 long initialTime = System.nanoTime()/1000Lを使用して初期時間を取得し、MediaCodecに渡すことを強くお勧めします。したがって、次回サンプルを書くときには、プレゼンテーション時間はinitialTime + 1_000_000L * KEY_MAX_INPUT_SIZE/SAMPLE_RATE/NUMBER_OF_CHANNELS/2でなければなりません。

  6. この部分は最大のピットです。オーディオサンプルをMediaCodecに入力するときに、すでにプレゼンテーション時間を設定していても、AACでエンコードされたデータをMediaMuxerに書き込むときのプレゼンテーション時間を確認してください。 AACで符号化されたデータの提示時間は時々増分しないことがある。最後に書き込んだプレゼンテーション時間をMediaMuxerに記録する必要があります。誤ったAACデータが見つかった場合は、提示時間をpresentationTime = ++lastPresentationTimeに調整してください。また、プレゼンテーションタイムゼロのAACデータを得ることもできます。それらを無視してください。 MediaMuxerには書き込まないでください。

  7. MediaMuxerに他のトラックがある場合は、各トラックのプレゼンテーション時間 が同じ範囲にあることを確認してください(秒間のエラーを許容します)。

  8. 1 1つのAAC MediaCodec 1つはMediaMuxerです。そして、出力MediaFormatオブジェクトを再利用しないでください。

  9. MediaMuxer.stop()を実行する前に、writeAudioSampleメソッドの呼び出しを停止し、を介してMediaCodecにEOSを送信してください。残りのAACデータをMediaCodecから排出してMediaMuxerに書き込みます。 MediaMuxer.stop()を実行し、何が起こっているかを見てください。

関連する問題