タイム スタンプ
"タイム スタンプ" は、ストリーム タイムで示されるメディア サンプルの開始タイムと終了タイムを定義する。タイム スタンプは、"プレゼンテーション タイム" と呼ばれることもある。この後の説明では、すべてのフォーマットで同じようにタイム スタンプを使うわけではないことに注意する必要がある。たとえば、すべての MPEG サンプルにタイム スタンプがあるわけではない。MPEG フィルタ グラフでは、タイム スタンプはデコーダから出力されるまで、各フレームには適用されない。
サンプルを受け取ると、レンダリング フィルタはタイム スタンプに基づいてレンダリングをスケジュールする。サンプルの到着が遅れたり、タイム スタンプがない場合、フィルタは即座にそのサンプルのレンダリングを開始する。それ以外の場合、フィルタはサンプルの開始タイムまで待ってからそのサンプルのレンダリングを開始する。フィルタは、IReferenceClock::AdviseTime メソッドを呼び出して開始タイムを待つ。
ソース フィルタとパーサー フィルタは、処理対象のサンプルに適切なタイム スタンプを設定する役割を担う。以下のガイドラインを使う。
- ファイルの再生 :最初のサンプルには、ゼロの開始タイムのタイム スタンプが設定される。以降のタイム スタンプは、サンプルの長さと再生レートによって決定される。再生レート自体はファイル フォーマットによって決定される。ファイルを解析するフィルタ (AVI スプリッタ など) が、正しいタイム スタンプの計算を行う。
- ビデオおよびオーディオのキャプチャ :すべてのサンプルには、キャプチャが行われたストリーム タイムに等しい開始タイムのタイム スタンプが設定される。ただし、次の点に注意すること。
- キャプチャ ピンとは対称的に、プレビュー ピンからのビデオ フレームにはタイム スタンプはない。グラフ遅延時間があるために、キャプチャ タイムのタイム スタンプが設定されたビデオ フレームは必ず遅れてビデオ レンダラに到着する。この場合、レンダラは品質コントロールの目的でフレームをドロップする可能性がある。品質コントロールについては、「品質コントロールの管理」を参照すること。
- オーディオ キャプチャ :オーディオ キャプチャ フィルタは、オーディオ フィルタが使うものとは別に、独自のバッファのセットを使う。オーディオ ドライバは、一定間隔でキャプチャ フィルタのバッファに格納する。この間隔はドライバによって異なるが、一般的にはせいぜい 10 ミリ秒である。オーディオ サンプルのタイム スタンプは、ドライバがオーディオ キャプチャ フィルタのバッファに格納したタイムを反映する。これらのタイムは、特にアプリケーションが非常に小さなバッファ サイズを使っている場合に、若干不正確になることがある。ただし、メディア タイムはバッファ内のオーディオ サンプルの数を正確に反映する。
- Mux フィルタ :出力フォーマットによって、Mux フィルタはタイム スタンプを生成する必要がある場合と、必要がない場合がある。たとえば、AVI ファイル フォーマットはタイム スタンプのない固定フレーム レートを使うので、AVI Mux フィルタはサンプルがほぼ適切なタイムに到着すると想定している。ただし、受信タイム スタンプのギャップが 1 フレームよりも大きい場合、AVI Mux はサイズが 0 のインデックス エントリを書き込んでドロップされたフレームを示す。ファイルの再生では、前に説明したように、実行時に新しいタイム スタンプが生成される。
サンプルにタイム スタンプを設定するには、IMediaSample::SetTime メソッドを呼び出す。
オプションとして、フィルタはサンプルの "メディア タイム" を指定することもできる。ビデオ ストリームでは、メディア タイムはフレーム番号を表す。オーディオ ストリームでは、メディア タイムはパケット内のサンプル番号を表す。たとえば、各パケットには 44.1 キロヘルツ (kHz) オーディオの 1 秒が格納され、最初のパケットのメディア開始タイムは 0、メディア終了タイムは 44100 になる。シーク可能ストリームでは、メディア タイムは常にストリームの開始タイムから相対的になる。たとえば、15-fps のビデオ ストリームの開始から 2 秒をシークするとする。シーク後の最初のメディア サンプルのタイム スタンプは 0 になるが、メディア タイムは 30 である。
レンダリング フィルタおよび Mux フィルタはメディア タイムを使って、ギャップをチェックすることによって、フレームまたはサンプルがドロップされたかどうかを判別できる。ただし、フィルタはメディア タイムを設定する必要はない。サンプルのメディア タイムを設定するには、IMediaSample::SetMediaTime メソッドを呼び出す。