私は、ビデオとオーディオを組み合わせ、2 つの間の正確な同期を必要とする (Windows 用の) プレーヤー アプリケーションを多数作成しました。Windows オーディオでは、基本的にバッファー (オーディオ サンプル値の単なる配列) を準備し、再生のためにオーディオ サブシステムのキューに入れます。サブシステムは、各バッファーが再生を完了するたびにアプリへのコールバックを作成し、アプリは各コールバックを使用して、1) 次のフレームを画面にレンダリングし、2) 次のオーディオ チャンクをオーディオ サブシステムのキューに入れる準備をします。
たとえば、1 秒あたり 2 バイト、1 秒あたり 44,100 サンプルのモノラルのオーディオと同期して、1 秒あたり 50 フレームで再生したいビデオのフレームがメモリにあるとします。つまり、オーディオ バッファーはそれぞれ 882 サンプルのサイズ (44,100 / 50 = 882) である必要があるため、各バッファーは 882 要素の短い (2 バイト) 整数の配列にすぎません。少なくとも 2 つのバッファーが必要ですが、実際には、より多くのバッファーが必要です (バッファーとのトレードオフは、開始時の遅延が長くなり、メモリ フットプリントが大きくなるという代償を払って、よりスムーズな再生を意味することです)。
ビデオのフレームは、少なくとも 1 つのフレームが常にレンダリングされる準備ができているように、同じ方法で「バッファリング」する必要があります。1 つの画像を PC 画面に転送するのは非常に高速であるため、事実上瞬時であり、心配する必要はありません。唯一の懸念事項は、フレームを抽出または構成する方法です。これらのメソッドは、少なくとも再生速度に追いつくのに十分な速さである必要があるか、再生の前に十分にバッファリングする必要があります。これにより、起動の遅延が長くなり、メモリ フットプリントが大きくなります (これらの問題は、適切な解像度のオーディオ用です)。
アプリが再生を開始すると、すべてのバッファーにオーディオがプリロードされ、再生のためにキューに入れられます。次に、同時に再生を開始し、最初のフレームを画面にレンダリングします。ユーザーは最初のフレームを見て、オーディオの最初の 20 ミリ秒 (20 ミリ秒 = 1/50 秒) を聞きます。この時点で、オーディオ サブシステムは再生を最初のバッファーから 2 番目のバッファーに切り替え、アプリケーションへのコールバックを行います。次に、アプリは 2 番目のフレームを画面にレンダリングし、最初のバッファーを次に利用可能なオーディオのチャンクで満たし、この最初のバッファーを再びオーディオ サブシステムのキューに入れます。
アプリケーションがバッファとフレームを埋め続けるために使用できるオーディオとビデオのデータを持っている限り、このプロセスは継続し、ビデオを見たり聞いたりします。