2016-08-26 11 views
0

OpenGLを使用してフレームバッファオブジェクトに描画し、その結果のテクスチャをディスプレイに描画してから、アプリケーションがエンコードしている場合はMediaCodec入力サーフェイスを描画するビデオエフェクトアプリケーションがあります。Android MediaCodec eglSwapBuffer非同期モードのGPUをブロックする

私は最初、API 18のエンコーダを同期モードで書いていました(大きなフレークの例に基づいています)。私は最近、API 21と非同期モードに切り替えました。

これはビデオをうまく記録しており、すべてが正しく設定されていると思います。しかし、eglSwapBuffersを呼び出すと、フレームレートが大幅に低下するようです。

他のすべてのOpenGL呼び出しを削除すると、よりうまく動作しますが、レンダリングするのは高価ではありません(フレームごとに複数回細かくレンダリングできます)。エンコーダの設定を変更すると(つまり、640x360 @ 2Mbpsから1920x1080 @ 16Mbpsに)、実質的に違いはありません。

実行を高速化する唯一の方法は、eglSwapBuffers(バッファデータをエンコーダに送信する)への呼び出しを削除することです。

私の理解では、出力バッファは以前と同じように非同期モードで呼び出しをブロックしません。私はこれについて間違っていますか?レンダラーを呼び出す方法、または別のスレッドで非同期にレンダリングする方法がありますか?

ご協力いただきありがとうございます!

答えて

2

非同期モードであっても、出力バッファはエンコーダをブロックします。非同期エンコーダ出力コールバックが呼び出された後、出力バッファをエンコーダに戻す必要があります。従来通り。

同期モードと非同期モードの唯一の違いは、これらのイベントをポーリングする必要はありませんが、代わりにコールバックが発生することです。

+0

ありがとうございました!それは間違いなく私の質問の一つに答えます。その場合、ビデオを非同期でエンコードすることはこれまで理にかなっていますか?私がすぐにコールバックでバッファを解放し、データで何もしない場合でも、レンダリングスレッドはまだeglSwapBuffersによってブロックされています。同期モードに戻り、出力バッファを解放してエンコーダを「ドレイン」にすると、同じ減速が発生します。 – Sam598

+0

一般に、はい、非同期モードは絶対に意味があります。一例として、面入力モードを使用しないエンコーダを考えてみましょう。任意の時点で、新しい空き入力バッファーを使用するか、出力バッファーを満たすのを待つ必要があります。両方のタイムアウト値をチェックすると、最高のスループットが得られますが、基本的にはビジーループになります。ゼロ以外のタイムアウトを待つと、ビジーループは発生しません。すべての入力バッファを満たしていれば、出力バッファを待ってそれを返すまで、新しい入力バッファは取得されません。 – mstorsjo

+0

つまり、同期モードでは、入力と出力を待つ時間の長さと、スループットとbusyloopingのバランスをとるというトレードオフがあります。非同期モードでは、できるだけ入力を続けるだけで、出力があれば排水してください。恐らく、eglSwapBuffersはエンコーダが描画するための自由な入力バッファを提供するのを待っている、つまり、GLパイプラインとビデオエンコーダがエンコードできる速度でブロックされているということです。スワップ自体はそれほど時間がかかりませんが、空き入力バッファがなくなると、それを待たなければなりません。 – mstorsjo

関連する問題