2013-08-26 12 views
10

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

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

これを正しく設定するにはどうすればよいですか?

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

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

  • GLRenderThread:

    これは私の現在の設定の概要を説明し、このクラスでは、スレッドから延びOpenGLコンテキストをセットアップ、ディスプレイ等の表面(eglCreateWindowSurfaceの3番目のパラメータ)としてSurfaceTextureを使用しています。

  • GLFilterChain:入力テクスチャの検出を実行するシェーダのコレクション。
  • カメラ:最後にGLRenderThreadのSurfaceTexture
  • 明らか

を表示TextureViewは、この設定で、私が示すよ

  • GLFilterChainの入力として使用されている別のSurfaceTextureを使用し、カメラのプレビューをつかみます処理したフレームをユーザに送信します。これは私が望むものではありません。さらに、フレームの処理はリアルタイムではない。基本的に、私はカメラからの入力をチェーンを通して1回実行し、すべてのフィルタが完了したら、updateTexImageに電話して、カメラから次のフレームを取得します。私の処理はNexus 4で約10フレーム/秒です。

    リアルタイムプレビュー用と処理用の2つのGLコンテキストを使用する必要があると思いますが、私は確信していません。私は誰かが私を正しい方向に押し込むことを望んでいる。

  • +0

    http://stackoverflow.com/questions/12519235/modifying-camera-output-using-surfacetexture-and-opengl –

    答えて

    0

    使用しているコードの一部をアップロードしてください。

    プレビューを最初に表示し、別のテクスチャを別のテクスチャにバインドして解析を行うために使用しているサーフェイスビュー用に作成されバインディングされたテクスチャに対してglDrawArraysを呼び出すことができます。

    カメラのプレビューsurfacetextureをテクスチャにバインドされている
    GLES20.glUseProgram(simpleProgram); 
    GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, textures[0]); 
    GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4); 
    
    GLES20.glUseProgram(crazyProgram); 
    GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, textures[1]); 
    GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4); 
    

    のようなもの[0]、その後、テクスチャ用に作成された別のsurfacetexture多分[1]

    +0

    私のコードは多くのクラスにわたっていますが、質問に要約を追加しようとします。あなたのアイデアをまとめると、simpleProgramはgl_FragColorを入力ピクセルの値に設定するだけです。 crazyProgramは実際の処理を行います。私はTextureViewをまったく使用せず、GLSurfaceViewを使ってプレビューをユーザに表示します。テクスチャ[0]をテクスチャにコピーするにはどうしたらいいですか?どのようにカメラのプレビューをリアルタイムで保持しますか?私の理解に基づき、crazyProgramを使用する前に、デフォルト以外のフレームバッファをバインドする必要があります。つまり、次のカメラプレビューは、crazyProgramがすべての処理を完了するまで待たなければなりません。 – Ameen

    0

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

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

    ここではリアルタイムの概念が混乱する可能性があります。フレームを解剖できない時間のスナップショットと考えるだけです。そうすることで、画像がカメラからスクリーンに移動するのにかかる遅延は無視されますが、インタラクティブフレームレート(1秒間に20フレーム以上)で保持できる場合は、無視される。

    一方、処理が非常に遅い場合は、カメラのフィードに遅延を導入し、N番目のフレームごとに処理するか、または各カメラフレームをリアルタイムで交互に表示し、次の処理されたフレーム遅れが生じる。これを行うには、おそらくAndroidでやるのが難しいかもしれない非同期処理を可能にするために2つの別々のレンダリングコンテキストが必要になるでしょう(あるいは、コンテキスト間でデータを共有することなく生きることができるので2番目のGLViewを作成するだけです)。

    関連する問題