10

私は現在、ビデオフレームをキャッシュする必要があるAndroidアプリを作成しているため、ほとんどまたはまったく遅延なく簡単に行き来できます。

MediaCodec現在、オブジェクトの Configure 呼び出しに Surface を提供releaseOutputBufferし、render フラグを に設定して呼び出して、Android にビデオ フレームをデコードさせていますtrue

デコードされたサーフェス データにアクセスするために見つけた唯一の方法 (形式がデバイスに依存しているように見える、返されたバイトバッファーをデコードする以外に) は、サーフェスにリンクされた を呼び出し、これをターゲットにアタッチし、updateTeximage作成したターゲット テクスチャにレンダリングすることです。それをキャッシュするために自分自身。SurfaceTextureGL_TEXTURE_EXTERNAL_OESGL_TEXTURE2D

このキャッシュ プロセスを最適化し、別のスレッドでフレームをデコードできるようにしたいと考えています。現在の方法を使用すると、これは、ビデオ デコーダー用に別の EGL コンテキストを作成し、コンテキストを共有する必要があることを意味します...

私の質問は:を呼び出さずに、Surface に関連付けられた EGL イメージまたはネイティブ バッファ データにアクセスすることは可能 updateTexImageですか?

そうすれば、egl イメージをキャッシュすることができます (これは、 に従って EGL コンテキストを必要としませんEGL_ANDROID_image_native_buffer)。これは、現在キャッシュしている未加工の RGB テクスチャよりもはるかにストレージ効率の高い YUV 形式でもキャッシュされます。

4

1 に答える 1

6

短い答え:いいえ。

より長い答え:は buffers のキューをSurfaceカプセル化します。(編集:システムはここで詳細に説明されています。) を呼び出すと、データの新しいフレームが利用可能な場合、先頭のバッファが削除され、キュー内の次のバッファが現在のバッファになります。連続するフレームを表示するには呼び出しが必要です。ヘッド以外のバッファを調べるメカニズムはありません。updateTexImage()updateTexImage()

AはGLConsumerSurfaceTextureのインスタンスをラップします。このコンシューマーは、プロデューサー (ビデオ デコーダー) が「ハードウェア テクスチャ」として使用できる形式、つまりデバイスの GL 実装が理解できる形式でデータを生成することを要求します。YUV である場合とそうでない場合があります。つまり、データに直接アクセスできると想定することはできません。つまり、GLES を使用する必要があります。(フラグの完全なリストについては、 gralloc ヘッダーを参照してください。)

ここでいいのは、バッファを先頭からBufferQueue別のデータ構造体(BufferArrayList?)にフォーマット変換せずにコピーできる機能ですが、現在(Android 4.3)ではそのような仕組みはありません。あなたが説明したものよりも良い方法を知りません(共有EGLコンテキストなど)。

更新:私のオフィスメイトから提案がありました: シェーダーを使用して、バッファーを 2 つのテクスチャ (Y 用と CbCr 用) にレンダリングします (GLES 3 では RG テクスチャを使用できます)。これにより、完全な RGB に拡張することなく、すべての操作が GLES に保持されます。内部的には、MediaCodec出力を RGB に変換し、それを 2 回処理しますが、ユーザー空間にコピーして CPU で自分で行うよりもおそらく安価です。

于 2013-09-12T20:10:52.497 に答える