IMediaControl
COMIDispatch (デュアル)comobj 経由でメソッド名による遅延バインド呼び出しができます(vtableインデックス不要)。公式ドキュメント
IMediaControl インターフェイスは、フィルターグラフを通過するデータの流れを制御するためのメソッドを提供します。
メソッド 9
vtbl = vtable インデックス(0始まり)。IDispatch 実装のため HSP ではメソッド名でも呼べます(上記)。低レベルの index 呼び出し用に vtbl も掲載。0〜2 は IUnknown。
Run メソッドは、フィルターグラフ内のすべてのフィルターを実行します。グラフの実行中、データはグラフを通過して移動し、レンダリングされます。
戻り値
HRESULT 値を返します。取り得る値には次のものがあります。
| Return code | Description |
|---|---|
| グラフは実行の準備をしていますが、一部のフィルターは実行状態への遷移を完了していません。 | |
| グラフ内のすべてのフィルターが実行状態への遷移を完了しました。 |
解説(Remarks)
フィルターグラフが停止している場合、このメソッドは実行前にグラフを一時停止します。グラフがすでに実行中の場合、このメソッドは S_OK を返しますが、効果はありません。
グラフは、アプリケーションが IMediaControl::Pause メソッドまたは IMediaControl::Stop メソッドを呼び出すまで実行されます。再生がストリームの終端に達すると、グラフは実行を続けますが、フィルターはそれ以上データをストリーミングしません。その時点で、アプリケーションはグラフを一時停止または停止できます。ストリーム終端イベントについては、IMediaControl::Pause および EC_COMPLETE を参照してください。
このメソッドはストリームの先頭にシークしません。そのため、グラフを実行し、一時停止し、再度実行すると、再生は一時停止した位置から再開されます。ストリームの終端に達した後にグラフを実行しても、何もレンダリングされません。グラフをシークするには、IMediaSeeking インターフェイスを使用してください。
メソッドが S_FALSE を返した場合、それはすべてのフィルターが実行状態に切り替わる前にメソッドが戻ったことを意味します。フィルターはメソッドが戻った後に遷移を完了します。必要に応じて、タイムアウト値を指定して IMediaControl::GetState メソッドを呼び出すことで、遷移の完了を待つことができます。ただし、これは必須ではありません。
Run メソッドがエラーコードを返した場合、それは 1 つ以上のフィルターが実行に失敗したことを意味します。ただし、一部のフィルターは実行状態にある可能性があります。マルチストリームグラフでは、ストリーム全体が正常に再生されている場合があります。通常、この場合、アプリケーションはグラフを破棄してエラーを報告します。
Pause メソッドは、フィルターグラフ内のすべてのフィルターを一時停止します。
戻り値
HRESULT 値を返します。取り得る値には次のものがあります。
| Return code | Description |
|---|---|
| グラフは正常に一時停止しましたが、一部のフィルターは状態遷移を完了していません。 | |
| グラフ内のすべてのフィルターが一時停止状態への遷移を完了しました。 |
解説(Remarks)
フィルターグラフを一時停止すると、次にグラフを実行したときに即座にレンダリングできるようグラフが準備されます。グラフが一時停止している間、フィルターはデータを処理しますがレンダリングは行いません。データはグラフを通過して送られ、バッファリングが許す限り変換フィルターによって処理されますが、レンダラーフィルターはデータをレンダリングしません。ただし、ビデオレンダラーは最初のサンプルの静止したポスターフレームを表示します。
メソッドが S_FALSE を返した場合は、IMediaControl::GetState メソッドを呼び出して、状態遷移の完了を待つか、遷移が完了したかどうかを確認してください。ビデオファイルの最初のフレームを表示するために Pause を呼び出す場合は、状態遷移が完了したことを確認するため、必ず直後に GetState の呼び出しを続けてください。これを行わないと、ビデオの矩形が黒く塗りつぶされる可能性があります。
メソッドが失敗した場合は、戻る前にグラフを停止します。
Stop メソッドは、グラフ内のすべてのフィルターを停止します。
戻り値
成功した場合は S_OK を返し、失敗した場合はエラーの原因を示す HRESULT 値を返します。
解説(Remarks)
グラフが実行中の場合、このメソッドは停止する前にグラフを一時停止します。一時停止中、ビデオレンダラーは現在のフレームをコピーしてポスターフレームとして表示できます。
このメソッドはストリームの先頭にシークしません。このメソッドを呼び出した後に IMediaControl::Run メソッドを呼び出すと、再生は停止した位置から再開されます。シークするには、IMediaSeeking インターフェイスを使用してください。
フィルターグラフマネージャーは、グラフ内のすべてのフィルターを一時停止し、その後、一時停止操作の完了を待たずにすべてのフィルターに対して IMediaFilter::Stop メソッドを呼び出します。そのため、一部のフィルターは一時停止操作を完了する前に Stop メソッドが呼び出される場合があります。カスタムレンダリングフィルターを開発する場合は、実行状態のときに停止コマンドを受け取ったときにフィルターを一時停止することで、このケースに対処する必要があるかもしれません。ただし、ほとんどのフィルターはこの点に関して特別な対応をする必要はありません。
GetState メソッドは、フィルターグラフの状態(一時停止、実行中、または停止)を取得します。
| msTimeout | INT | in | タイムアウトの期間(ミリ秒単位)。無限のタイムアウトを指定するには INFINITE を指定します。 |
| pfs | INT* | out | FILTER_STATE 列挙体のメンバーを受け取ります。 |
戻り値
HRESULT 値を返します。取り得る値には次のものがあります。
| Return code | Description |
|---|---|
| 成功しました。 | |
| フィルターグラフはまだ指定された状態へ遷移中です。 | |
| フィルターグラフは一時停止していますが、データをキューできません。 | |
| 失敗しました。 |
解説(Remarks)
アプリケーションはこのメソッドを使用して、IMediaControl::Run の呼び出し後に再生が開始されたかどうかを判断できます。一般に、アプリケーションはフィルターグラフをどの状態にしたかを追跡する独自の仕組みを持つべきです。アプリケーションは通常、現在の状態を使用して、どのユーザーインターフェイスコントロールを有効または無効にするかを決定します。たとえば、グラフが実行状態になると、アプリケーションは「再生」ボタンを無効にし、「停止」および「一時停止」ボタンを有効にする場合があります。
フィルターグラフが新しい状態へ遷移中の場合、返される状態は前の状態ではなく、新しい状態です。
このメソッドがブロックされている間に、別のスレッドで状態を変更する呼び出しがあった場合、このメソッドはエラーを返します。
GetState で待機している間、スレッドはメッセージを処理できないため、INFINITE のタイムアウトを指定するのは避けてください。Windows メッセージを処理するスレッドから GetState を呼び出す場合は、ユーザー入力に対する応答性を維持するため、呼び出しに短い待機時間を指定してください。これは、ソースがネットワークやインターネット経由でストリーミングされている場合に特に重要です。これらの環境では状態遷移の完了に大幅に長い時間がかかることがあるためです。
FILTER_STATE 列挙体。変数は次のようにキャストできます。
FILTER_STATE fs;
hr = pControl->GetState(msTimeOut, (OAFilterState*)&fs);
フィルターグラフの状態の詳細については、Filter States を参照してください。
RenderFile メソッドは、指定されたファイルをレンダリングするフィルターグラフを構築します。(IMediaControl.RenderFile)
| strFilename | LPWSTR | in | 読み込むファイルの名前を指定します。 |
戻り値
このメソッドが成功すると S_OK を返します。それ以外の場合は HRESULT エラーコードを返します。
AddSourceFilter メソッドは、フィルターグラフにソースフィルターを追加します。
| strFilename | LPWSTR | in | 読み込むファイルの名前を指定します。 |
| ppUnk | IDispatch** | out | IDispatch インターフェイスへのポインターを受け取ります。呼び出し元はこのインターフェイスを解放する必要があります。返されたポインターに対して IFilterInfo インターフェイスをクエリできます。 |
戻り値
このメソッドが成功すると S_OK を返します。それ以外の場合は HRESULT エラーコードを返します。
get_FilterCollection メソッドは、フィルターグラフ内のフィルターのコレクションを取得します。
| ppUnk | IDispatch** | out | IDispatch インターフェイスへのポインターを受け取ります。呼び出し元はこのインターフェイスを解放する必要があります。返されたポインターに対して IAMCollection インターフェイスをクエリできます。このコレクションには IFilterInfo ポインターのリストが含まれます。 |
戻り値
このメソッドが成功すると S_OK を返します。それ以外の場合は HRESULT エラーコードを返します。
get_RegFilterCollection メソッドは、レジストリに登録されているすべてのフィルターのコレクションを取得します。
| ppUnk | IDispatch** | out | IDispatch インターフェイスへのポインターを受け取ります。呼び出し元はこのインターフェイスを解放する必要があります。返されたポインターに対して IAMCollection インターフェイスをクエリできます。このコレクションには IRegFilterInfo ポインターのリストが含まれます。 |
戻り値
このメソッドが成功すると S_OK を返します。それ以外の場合は HRESULT エラーコードを返します。
StopWhenReady メソッドは、フィルターがデータをキューに入れられるようフィルターグラフを一時停止し、その後フィルターグラフを停止します。
戻り値
HRESULT 値を返します。取り得る値には次のものがあります。
| Return code | Description |
|---|---|
| 成功しました。 | |
| メソッドが戻ったとき、グラフはまだ一時停止状態へ遷移中でした。 |
解説(Remarks)
このメソッドは、グラフが停止している間にフィルターグラフをシークしたい場合に便利です。フィルターグラフが停止している間は、現在位置を変更してもビデオウィンドウが新しいフレームで再描画されません。そのため、IMediaSeeking::SetPositions を呼び出してもビデオウィンドウは更新されません。シーク操作後にウィンドウを更新するには、StopWhenReady を呼び出してください。このメソッドはグラフを一時停止状態へ遷移させ、一時停止操作の完了を待ってから、グラフを停止状態へ戻します。一時停止操作によってグラフ内にデータがキューされるため、ビデオレンダラーは新しいフレームを受け取って表示します。
このメソッドは非同期です。別のスレッドで一時停止の完了を待ちます。呼び出し元のスレッドはブロックされないため、アプリケーションはユーザー入力に応答できます。メソッドが戻ると、一時停止操作が完了する前であっても、グラフの論理状態は停止になります。この時点で IMediaControl::GetState メソッドを呼び出すと、State_Stopped を返します。
一時停止操作が完了する前にアプリケーションが別の状態変更コマンド(一時停止、実行、シークなど)を発行すると、新しいコマンドが保留中の停止コマンドをキャンセルします。一時停止操作は完了しますが、グラフは停止しません。
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)
HSP用 COM定義
#usecom / #comfunc によるHSPのCOM呼び出し定義。数字は vtbl インデックス(0始まり)。クラスIDが無い場合 #usecom の末尾は "{}"、ある場合は "{CLSID}"。
#define global IID_IMediaControl "{56A868B1-0AD4-11CE-B03A-0020AF0BA770}" #usecom global IMediaControl IID_IMediaControl "{}" #comfunc global IMediaControl_Run 7 #comfunc global IMediaControl_Pause 8 #comfunc global IMediaControl_Stop 9 #comfunc global IMediaControl_GetState 10 int,var #comfunc global IMediaControl_RenderFile 11 wstr #comfunc global IMediaControl_AddSourceFilter 12 wstr,sptr #comfunc global IMediaControl_get_FilterCollection 13 sptr #comfunc global IMediaControl_get_RegFilterCollection 14 sptr #comfunc global IMediaControl_StopWhenReady 15 ; ※数字は vtbl インデックス(0始まり)。0/1/2 は IUnknown(QueryInterface/AddRef/Release)。 ; ※このインターフェースは直接 CoCreateInstance するクラスIDが無いため "{}"(他メソッド/アクティベーションで取得)。 ; ※出力/バッファ引数は var(変数直渡し)。varptr 方式にも切替可。 ; ※ハンドル/void*等の不透明ポインタは IronHSP では intptr 指定が可能。 ; ※IDispatch 実装。HSP では comobj 経由でメソッド名による呼び出しも可能(vtbl 不要)。#define global IID_IMediaControl "{56A868B1-0AD4-11CE-B03A-0020AF0BA770}" #usecom global IMediaControl IID_IMediaControl "{}" #comfunc global IMediaControl_Run 7 #comfunc global IMediaControl_Pause 8 #comfunc global IMediaControl_Stop 9 #comfunc global IMediaControl_GetState 10 int,sptr #comfunc global IMediaControl_RenderFile 11 wstr #comfunc global IMediaControl_AddSourceFilter 12 wstr,sptr #comfunc global IMediaControl_get_FilterCollection 13 sptr #comfunc global IMediaControl_get_RegFilterCollection 14 sptr #comfunc global IMediaControl_StopWhenReady 15 ; ※数字は vtbl インデックス(0始まり)。0/1/2 は IUnknown(QueryInterface/AddRef/Release)。 ; ※このインターフェースは直接 CoCreateInstance するクラスIDが無いため "{}"(他メソッド/アクティベーションで取得)。 ; ※出力/バッファ引数はポインタ方式(token=sptr / 呼び出しは varptr(変数))。 ; ※ハンドル/void*等の不透明ポインタは IronHSP では intptr 指定が可能。 ; ※IDispatch 実装。HSP では comobj 経由でメソッド名による呼び出しも可能(vtbl 不要)。