IMediaFilter
COM公式ドキュメント
IMediaFilter インターフェースは、フィルターのストリーミング状態を制御します。すべての DirectShow フィルターがこのインターフェースを実装します。
メソッド 6
vtbl = vtable インデックス(0始まり)。HSP等からCOMメソッドをインデックス指定で呼ぶ際に使用します。0〜2 は IUnknown。
Stop メソッドは、フィルターを停止します。
戻り値
解説(Remarks)
フィルターが停止しているとき、サンプルの処理や配信を行わず、上流フィルターからのサンプルを拒否します。
状態遷移は非同期の場合があります。遷移が完了する前にメソッドが戻った場合、戻り値は S_FALSE になります。
このメソッドは、エラーコードを返す場合でも、常にフィルターの状態を State_Stopped に設定します。
Pause メソッドは、フィルターを一時停止します。
戻り値
解説(Remarks)
フィルターが一時停止しているとき、サンプルの受信、処理、配信を行うことができます。ただし、レンダラーフィルターは一時停止中に 1 つのサンプルしか受け付けません。そのため、フィルターグラフが一時停止すると、最初のサンプルがレンダラーに到達するまでサンプルはグラフ内を移動します。その時点で、IMediaFilter::Run メソッドが呼び出されるまでストリーミングは一時停止されます。ビデオレンダラーは、最初のサンプルを静止フレームとして表示します。
一時停止中、ライブキャプチャフィルターはサンプルを一切配信せず、実行中にのみ配信します。
状態遷移は非同期の場合があります。遷移が完了する前にメソッドが戻った場合、戻り値は S_FALSE になります。レンダラーフィルターは、(1) 1 つのサンプルを受信するか、(2) ストリーム終端通知を受信するまで、一時停止への遷移を完了しません。状態遷移が保留中の間、IMediaFilter::GetState は VFW_S_STATE_INTERMEDIATE を返します。
Run メソッドは、フィルターを実行します。
| tStart | LONGLONG | in | ストリーム時間 0 に対応する基準時間。 |
戻り値
解説(Remarks)
フィルターが実行中のとき、サンプルの受信、処理、配信を行うことができます。ソースフィルターは新しいサンプルを生成し、レンダラーフィルターはそれらをレンダリングします。
状態遷移は非同期の場合があります。遷移が完了する前にメソッドが戻った場合、戻り値は S_FALSE になります。
ストリーム時間は、現在の基準時間から tStart を差し引いた値として計算されます。メディアサンプルをいつレンダリングすべきかを計算するために、レンダラーはタイムスタンプを現在のストリーム時間と比較します。したがって、タイムスタンプが 0 のメディアサンプルは、時間 tStart にレンダリングされます。詳細については、Time and Clocks in DirectShow を参照してください。
アプリケーションが IMediaControl::Run メソッドを呼び出すと、Filter Graph Manager は各フィルターに対して IMediaFilter::Run を呼び出します。グラフのレイテンシを考慮して、tStart の値を少し未来に設定します。
GetState メソッドは、フィルターの状態(実行中、停止、一時停止)を取得します。
| dwMilliSecsTimeout | DWORD | in | タイムアウト間隔(ミリ秒単位)。無期限にブロックするには、値 INFINITE を使用します。 |
| State | FILTER_STATE* | out | フィルターの状態を示す FILTER_STATE 列挙型のメンバーを受け取ります。 |
戻り値
HRESULT 値を返します。取り得る値には、次の表に示すものが含まれます。
| リターンコード | 説明 |
|---|---|
| 成功しました。 | |
| NULL ポインター引数です。 | |
| 中間状態です。 | |
| フィルターはアクティブですが、データを配信できません。 |
解説(Remarks)
状態遷移は非同期の場合があります。フィルターが新しい状態へ遷移中で、遷移が完了する前にメソッドがタイムアウトした場合、メソッドは VFW_S_STATE_INTERMEDIATE を返します。
何らかの理由でフィルターがデータを配信できない場合、VFW_S_CANT_CUE を返します。ライブキャプチャフィルターは、一時停止状態ではデータを配信しないため、一時停止中にこの値を返します。
詳細については、Data Flow in the Filter Graph を参照してください。
SetSyncSource メソッドは、基準クロックを設定します。
| pClock | IReferenceClock* | inoptional | クロックの IReferenceClock インターフェースへのポインター、または NULL。このパラメーターが NULL の場合、フィルターグラフは基準クロックを使用せず、すべてのフィルターは可能な限り高速に実行されます。 |
戻り値
成功した場合は S_OK を返し、失敗した場合はエラーの原因を示す HRESULT 値を返します。
解説(Remarks)
フィルターグラフ内のすべてのフィルターは、同期を保つために同じ基準クロックを共有します。ストリーム時間は基準クロックから計算されます。レンダラーフィルターは、サンプルをいつレンダリングするかをスケジュールするために基準クロックを使用します。基準クロックがない場合、レンダラーフィルターはサンプルが到着するとすぐにすべてをレンダリングします。
このメソッドは、すべての DirectShow フィルター、および Filter Graph Manager によって実装されます。
フィルターの実装
グラフが実行されると、Filter Graph Manager はグラフの基準クロックを通知するために、グラフ内のすべてのフィルターに対してこのメソッドを呼び出します。このメソッドを使用して IReferenceClock ポインターを格納します。格納したポインターの参照カウントをインクリメントします。フィルターがグラフから削除される前に、Filter Graph Manager は値 NULL を指定して再び SetSyncSource を呼び出します。格納したポインターを解放し、NULL に設定します。CBaseFilter クラスはこのメソッドを実装します。CBaseFilter::SetSyncSource を参照してください。
フィルターはこのメソッドを使用してグラフクロックを選択できないことに注意してください。フィルターにおいて、このメソッドの唯一の機能は、グラフが使用しているクロックをフィルターに通知することです。フィルターは、IReferenceClock インターフェースを公開することで基準クロックを提供できます。詳細については、Time and Clocks in DirectShow を参照してください。
アプリケーションでの使用
アプリケーションは、Filter Graph Manager に対して SetSyncSource を呼び出すことで、既定のクロックをオーバーライドできます。別のクロックを優先する特別な理由がない限り、これを行わないでください。値 NULL を指定して SetSyncSource を呼び出すことで、グラフが基準クロックを使用しないように設定することもできます。サンプルを可能な限り高速に処理するために、これを行う場合があります。詳細については、Setting the Graph Clock を参照してください。アプリケーションは、フィルターに対してこのメソッドを決して呼び出さないでください。
GetSyncSource メソッドは、現在の基準クロックを取得します。
| pClock | IReferenceClock** | out | クロックの IReferenceClock インターフェースへのポインターを受け取ります。呼び出し元はこのインターフェースを解放する必要があります。 |
戻り値
解説(Remarks)
このメソッドは、IMediaFilter::SetSyncSource の最後の呼び出しと同じ基準クロックを返します。基準クロックがない場合、pClock は値 NULL を受け取ります。メソッドが戻ったときに *pClock が NULL でない場合、IReferenceClock インターフェースには未解放の参照カウントがあります。使用が終わったら必ず解放してください。
このメソッドを Filter Graph Manager に対して呼び出して、現在の基準クロックを判定することもできます。
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)
HSP用 COM定義
#usecom / #comfunc によるHSPのCOM呼び出し定義。数字は vtbl インデックス(0始まり)。クラスIDが無い場合 #usecom の末尾は "{}"、ある場合は "{CLSID}"。
#define global IID_IMediaFilter "{56A86899-0AD4-11CE-B03A-0020AF0BA770}" #usecom global IMediaFilter IID_IMediaFilter "{}" #comfunc global IMediaFilter_Stop 4 #comfunc global IMediaFilter_Pause 5 #comfunc global IMediaFilter_Run 6 int64 #comfunc global IMediaFilter_GetState 7 int,var #comfunc global IMediaFilter_SetSyncSource 8 sptr #comfunc global IMediaFilter_GetSyncSource 9 sptr ; ※数字は vtbl インデックス(0始まり)。0/1/2 は IUnknown(QueryInterface/AddRef/Release)。 ; ※このインターフェースは直接 CoCreateInstance するクラスIDが無いため "{}"(他メソッド/アクティベーションで取得)。 ; ※出力/バッファ引数は var(変数直渡し)。varptr 方式にも切替可。 ; ※ハンドル/void*等の不透明ポインタは IronHSP では intptr 指定が可能。#define global IID_IMediaFilter "{56A86899-0AD4-11CE-B03A-0020AF0BA770}" #usecom global IMediaFilter IID_IMediaFilter "{}" #comfunc global IMediaFilter_Stop 4 #comfunc global IMediaFilter_Pause 5 #comfunc global IMediaFilter_Run 6 int64 #comfunc global IMediaFilter_GetState 7 int,sptr #comfunc global IMediaFilter_SetSyncSource 8 sptr #comfunc global IMediaFilter_GetSyncSource 9 sptr ; ※数字は vtbl インデックス(0始まり)。0/1/2 は IUnknown(QueryInterface/AddRef/Release)。 ; ※このインターフェースは直接 CoCreateInstance するクラスIDが無いため "{}"(他メソッド/アクティベーションで取得)。 ; ※出力/バッファ引数はポインタ方式(token=sptr / 呼び出しは varptr(変数))。 ; ※ハンドル/void*等の不透明ポインタは IronHSP では intptr 指定が可能。