web-dev-qa-db-ja.com

Android NDK、OpenGL ES、FFmpegを使用するビデオプレーヤー

わかりましたので、ここまでです。 AndroidでFFmpegを構築しましたが、それをうまく使用できます。Javaから選択したファイル名を渡した後、FFmpegにビデオをロードすることができましたサイド。パフォーマンスを節約するために、FFmpegからJava= JNIを介してフレームを渡すのではなく、NDKでビデオプレーヤーを作成しています。ビデオからOpenGLサーフェスにフレームを送信したいのです。ビデオの各フレームを取得してOpenGLサーフェスにレンダリングする方法を理解するのに苦労しました。これを数週間、運が悪かったので、これを理解しようとして立ち往生しています。誰かが私を正しい方向に向けてくれることを願っています。

ありがとう!

28
DRiFTy

思い浮かぶ1つの方法は、フレームのピクセルをテクスチャに描画し、OpenGLを使用してそのテクスチャをレンダリングすることです。

これについては、昔ながらのピクセルベースのビデオゲームを主に対象として、ブログの投稿をしばらく書きましたが、状況にも当てはまります。投稿は CでのAndroidネイティブコーディング で、私は 例付きのgithubリポジトリ を設定しました。この手法を使用して、第1世代のハードウェアでも60 FPSを得ることができました。

[〜#〜] edit [〜#〜]このアプローチのglTexImage2DとglTexSubImage2Dについて。

GlTexImage2Dを呼び出すと、テクスチャにビデオメモリが割り当てられ、渡したピクセルがそのメモリにコピーされます(NULLを渡さない場合)。 glTexSubImage2Dを呼び出すと、割り当て済みのテクスチャで指定したピクセルが更新されます。

テクスチャのallを更新する場合、どちらを呼び出すかにはほとんど違いがなく、実際には通常glTexImage2Dの方が高速です。ただし、テクスチャの一部のみを更新する場合、glTexSubImage2Dは速度に勝ります。

2の累乗のテクスチャサイズを使用する必要があるため、高解像度デバイスで画面をカバーするには、1024x512テクスチャ、および中解像度で512x512テクスチャが必要です。テクスチャは画面領域よりも大きい(高解像度は800x400っぽい)。つまり、テクスチャの一部を更新するだけでよいので、glTexSubImage2Dが適しています。

21
richq