1

私の問題:

画面にopengles 2.0でレンダリングする必要があるビデオ(25FPSとしましょう)があります。ビデオを読み取るために、そのビデオを opengl es テクスチャにデコードするデコーダを使用します。レンダーパスを使用して、このテクスチャを画面に描画します。

私がしなければならないことは、デコーダーから画像を取得して GPU にアップロードし、shaderprogram を呼び出して画面に画像をレンダリングすることです。ビデオが 25 FPS の場合、画面を 40 ミリ秒単位 (1000 ミリ秒/25 FPS) で更新する必要があります。

各ステップで、次のことを行う必要があります。

  • デコーダーから画像を取得する
  • GPUメモリにプッシュします
  • 画面をレンダリングする
  • スワップバッファ

これまでのところ、それは機能しています。ここで、デコーダがフレームをデコードするのに 40 ミリ秒以上かかることがあります。それは常に起こるわけではありませんが、時々起こります。

解決策は、キャッシュを構築することです。つまり、最初の画像を表示する前に、つまり 5 つの画像をレンダリングします。これには問題が伴います。非同期に発生する必要があるため、キャッシュの構築と画面のレンダリングを同時に行うことができます。それが起こった場合、それはもはや「流動的」ではないため、ビデオでそれを見ることができます.

私の質問:

  • その解決策はありますか?
  • レンダーサーフェスのバックバッファーにコピー (?!) できる ?-buffer を作成して、その種類のバッファーでキャッシュを作成し、他のスレッドをブロックすることなくバックバッファーにコピーすることは可能ですか?このバッファを作成していますか?

また

  • バックバッファを別のバッファで埋める方法は?

私はすでに試しました:

  • フレームバッファ (テクスチャ) をキャッシュとしてレンダリングします。テクスチャもレンダリングする必要があることを除けば、これはほぼ完璧に機能します。これは、(非同期であるため) キャッシュフレームが構築され、画面の画像が構築される場合、rendermethods をミューテックス (/同期化) する必要があることを意味します。そうしないと、プログラムがクラッシュします。しかし、同期には、非同期で行うという要点が必要です。したがって、これは良い解決策ではありません。
4

1 に答える 1

1

OpenGL では、画面をクリアして再描画しないと、前のイメージが保持されることに注意してください。新しいフレームの準備が間に合わない場合は、何もしません。

フレームのデコードとレンダリングの 2 つのスレッドがあるようです。これで問題ありません。

render() が呼び出され、新しいフレームの準備が間に合わなかった場合、render メソッドはすぐに戻る必要があります。バッファをクリアまたはスワップしません。画面は保持されます。

現在、ユーザーは、フレームが 2 回繰り返されるときに時折問題が発生することに/気付くかもしれません。25 fps は不自然なフレーム レートであるため (OpenGL は 60/30/15 などしかサポートしていません)、画面のリフレッシュ レートと完全には一致しません。

これで問題ありません (ユーザーはおそらく気付かないでしょう)。または、フレームをバッファリングして、再生を 30 fps に強制することもできます。

デコーダとレンダラーの間にメッセージ キューを配置することをお勧めします。1 フレームまたは数フレームの深さになる可能性があります。配列、リンク リスト、またはリング バッファーのいずれかです。これにより、レンダリングが別のテクスチャを描画している間に、デコーダが多くのキャッシュされたテクスチャにアップロードできるようになります。

デコーダーはフレームを受信するとキューに追加します。レンダラーは固定レート (30 fps) で実行されます。N フレームがバッファリングされるまで、レンダリングを一時停止できます。

于 2014-01-08T20:51:56.117 に答える