10

OpenGL 処理パイプライン (シェーダーのコレクション) を持ち、同時にエンド ユーザーが未処理のカメラ プレビューを表示する必要があるアプリケーションを設計しています。

例として、ユーザーにカメラのプレビューを表示し、同時にカメラから受け取ったシーン内の赤いオブジェクトの数を数えたいとしますが、色相フィルタリングなどのオブジェクトを数えるために使用するシェーダーはすべて、などは使用者に見せてはいけません。

これを適切に設定するにはどうすればよいですか?

カメラ プレビューをセットアップし、コールバックで YUV 形式のカメラ フレーム データを受信し、それを OpenGL テクスチャにダンプしてフレームをそのように処理できることはわかっていますが、これにはパフォーマンスの問題が伴います。カメラ ハードウェアから VM にデータを往復させてから、GPU メモリに戻す必要があります。私はSurfaceTexture、OpenGL のわかりやすい形式でカメラから直接データを取得し、それをシェーダーに渡してこの問題を解決するために使用しています。

同じ未処理SurfaceTextureのものをエンドユーザーに表示できると思いましたが、レンダリングしたいものをTextureView渡すことができるコンストラクターまたはセッターがありません。SurfaceTexture常に独自のものを作成します。

これは私の現在のセットアップの概要です。

  • GLRenderThread: このクラスは Thread から拡張され、OpenGL コンテキスト、表示などをセットアップし、サーフェスとして SurfaceTexture を使用します (eglCreateWindowSurface の 3 番目のパラメーター)。
  • GLFilterChain: 入力テクスチャで検出を実行するシェーダーのコレクション。
  • カメラ: GLFilterChain の入力として使用される別の SurfaceTexture を使用し、カメラのプレビューを取得します
  • 最後に、GLRenderThread の SurfaceTexture を表示する TextureView

明らかに、この設定では、処理されたフレームをユーザーに表示していますが、これは私が望んでいるものではありません。さらに、フレームの処理はリアルタイムではありません。基本的に、カメラからの入力をチェーンで 1 回実行し、すべてのフィルターが完了したら、updateTexImageを呼び出してカメラから次のフレームを取得します。私の処理は、Nexus 4 で毎秒約 10 フレームです。

おそらく、リアルタイム プレビュー用と処理用の 2 つの GL コンテキストを使用する必要があると思いますが、確かではありません。誰かが私を正しい方向に押し上げてくれることを願っています。

4

2 に答える 2

0

処理がリアルタイムよりも遅くならない限り、答えは簡単です。元のカメラ テクスチャをそのままにして、処理された画像を別のテクスチャに計算し、両方を単一の GLView に並べてユーザーに表示します。とにかくすべての処理が GPU で行われるため、単一のスレッドを保持します。複数のスレッドは、ここでは問題を複雑にするだけです。

ユーザーに表示されない任意の数の中間テクスチャ (ピンポンも参照) が存在する可能性があるため、処理ステップの数は実際には問題ではありません。

ここでは、リアルタイムの概念がおそらく混乱を招きます。フレームは、分割できない時間のスナップショットと考えてください。そうすることで、画像がカメラから画面に移動するのにかかる遅延を無視できますが、インタラクティブなフレーム レート (少なくとも毎秒 20 フレームなど) を維持できる場合、これはほとんどの場合無視されます。

一方、処理が非常に遅い場合は、カメラ フィードに遅延を導入して N 番目のフレームごとにのみ処理するか、すべてのカメラ フレームをリアルタイムで表示し、次に処理されるフレームを遅らせるかを選択する必要があります。 . これを行うには、非同期処理を有効にするために 2 つの別個のレンダリング コンテキストが必要になる可能性がありますが、これは Android では実行が難しい可能性があります (または、コンテキスト間でデータを共有しなくても生活できるため、2 つ目の GLView を作成するのと同じくらい簡単かもしれません)。

于 2014-05-18T12:18:12.123 に答える