キャプチャ フィルターでのデータの生成
[このページに関連付けられている機能 DirectShow は、従来の機能です。 MediaPlayer、IMFMediaEngine、Media Foundation のオーディオ/ビデオ キャプチャに置き換わりました。 これらの機能は、Windows 10とWindows 11用に最適化されています。 新しいコードでは、可能であれば、DirectShow ではなく Media Foundation で MediaPlayer、IMFMediaEngine、Audio/Video Capture を使用することを強くお勧めします。 Microsoft は、レガシ API を使用する既存のコードを、可能であれば新しい API を使用するように書き換えるよう提案しています。]
このトピックでは、カスタム DirectShow キャプチャ フィルターで出力データを生成する方法について説明します。
状態の変更をフィルター処理する
キャプチャ フィルターは、フィルターが実行されている場合にのみデータを生成する必要があります。 フィルターが一時停止されている場合は、ピンからデータを送信しないでください。 また、フィルター が 一時停止しているときに CBaseFilter::GetState メソッドからVFW_S_CANT_CUEを返します。 この戻り値は、フィルターが一時停止されている間、フィルターからのデータを待機しないことをフィルター グラフ マネージャーに通知します。 詳細については、「 フィルターの状態」を参照してください。
次のコードは、 IMediaFilter::GetState メソッドを実装する方法を示しています。
CMyVidcapFilter::GetState(DWORD dw, FILTER_STATE *pState)
{
CheckPointer(pState, E_POINTER);
*pState = m_State;
if (m_State == State_Paused)
{
return VFW_S_CANT_CUE;
}
else
{
return S_OK;
}
}
個々のストリームの制御
キャプチャ フィルターの出力ピンは、アプリケーションが各ピンを個別にオンまたはオフにできるように、 IAMStreamControl インターフェイスをサポートする必要があります。 たとえば、キャプチャせずにアプリケーションをプレビューし、フィルター グラフを再構築せずにキャプチャ モードに切り替えることができます。 CBaseStreamControl クラスを使用して、このインターフェイスを実装できます。
タイム スタンプ
フィルターがサンプルをキャプチャする場合は、現在のストリーム時刻を使用してサンプルにタイム スタンプを設定します。 終了時刻は開始時刻と期間です。 たとえば、フィルターが 1 秒あたり 10 個のサンプルでキャプチャしていて、フィルターがサンプルをキャプチャするときにストリーム時間が 200,000,000 単位である場合、タイム スタンプは 2000000000 と 201000000 である必要があります。 (1 秒あたり 10,000,000 単位があります。
ストリーム時間を計算するには、 IReferenceClock::GetTime メソッドを呼び出して現在の参照時刻を取得し、元の開始時刻をサブストラクトします。 または、同じ計算を実行する CBaseFilter::StreamTime メソッドを呼び出します。 サンプルにタイム スタンプを設定するには、 IMediaSample::SetTime メソッドを呼び出します。
ただし、フィルターにプレビュー ピンがある場合は、プレビュー ピンのサンプルにタイム スタンプを含めないようにする必要があります。 その理由は、キャプチャ時の少し後にサンプルが常にレンダラーに到達するということです。 サンプルにタイム スタンプが設定されている場合、レンダラーはそれらを遅延として処理し、サンプルをドロップして追いつこうとする場合があります。 (詳細については、「 DirectShow ビデオ キャプチャ フィルター」を参照してください)。 IAMStreamControl インターフェイスでは、サンプル時間を追跡するためにピンが必要であることに注意してください。 プレビュー ピンの場合は、タイム スタンプに依存しないように実装を変更する必要がある場合があります。
タイム スタンプは、常に 1 つのサンプルから次のサンプルに増加する必要があります。 これは、フィルターが一時停止した場合でも当てはまります。 フィルターを実行し、一時停止してから再度実行する場合、一時停止後の最初のサンプルは、一時停止前の最後のサンプルよりも大きなタイム スタンプを持つ必要があります。
キャプチャするデータによっては、サンプルにメディア時間を設定することが適切な場合があります。
詳細については、「 DirectShow の時刻と時計」を参照してください。
関連トピック