Microsoft DirectX 8.0 |
このトピックでは、Microsoft® DirectShow® でメディア ファイルを再生する方法を説明し、メディア ファイルを再生する C++ のサンプル プログラムを示す。このプログラムは、古典的な "Hello World" プログラムの DirectShow 版である。
このトピックは、以下のセクションで構成される。
DirectShow を使ったファイルの再生は、以下の 4 段階の処理で行われる。
この処理には、以下の COM インターフェイスが必要である。
フィルタ グラフ マネージャはこれらのインターフェイスすべてを実装する。
COM ライブラリを初期化する CoInitialize 関数を呼び出すことによって開始する。次に CoCreateInstance 関数を呼び出し、フィルタグラフ マネージャを作成する :
IGraphBuilder *pGraph; CoInitialize(NULL); CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void **)&pGraph);
CoCreateInstance 関数はフィルタグラフ マネージャの IGraphBuilder インターフェイスを返す。このインターフェイス ポインタを使って、必要な 2 つのインターフェイス IMediaControl と IMediaEvent をクエリする :
IMediaControl *pMediaControl; IMediaEvent *pEvent; pGraph->QueryInterface(IID_IMediaControl, (void **)&pMediaControl); pGraph->QueryInterface(IID_IMediaEvent, (void **)&pEvent);
プログラムの中心部分にきた :
pGraph->RenderFile(L"C:\\Hello_World.avi", NULL); pMediaControl->Run(); pEvent->WaitForCompletion(INFINITE, &evCode);
IGraphBuilder::RenderFile メソッドは、指定されたファイルを再生するフィルタ グラフを構築する。最初のパラメータは、ワイド文字 (2 バイト) の Unicode 文字列で表されたファイル名である。簡単であるため、サンプル プログラムでは、ユーザーにファイル名を選択させるのではなく、リテラル文字列を指定している。プリフィックス "L" を付けると、ASCII 文字列がワイド文字列に変換される。2 つめのパラメータは予約済みで、NULL でなければならない。
フィルタ グラフを構築すると、フィルタ グラフ マネージャは再生を開始することができる。IMediaControl::Run メソッドが、グラフを実行モードに切り換える。アプリケーションがこのメソッドを呼び出すと、メディア データはフィルタ グラフを通り始め、ビデオ、オーディオ、または両方としてレンダリングされる。
IMediaEvent::WaitForCompletion メソッドはファイルが再生されるまでブロックする。再生は別のスレッドで続けられる。実際のアプリケーションでは待ち時間を INFINITE にセットすべきではない、これは無制限にブロックしてしまうからだ。また他のフィルタグラフ イベントに対応したい場合もある。イベント ハンドリングの詳細については、「イベントへの応答」を参照すること。
更に、実際のアプリケーションでは、RenderFile の戻り値をテストしフィルタグラフの作成が成功したことを確認すべきだ。たとえば、指定したファイルがない場合、RenderFile は失敗しエラーコード VFW_E_NOT_FOUND を返す。
最終的に、すべてのインターフェイス ポインタと COM ライブラリを解放することでクリーンアップする :
pMediaControl->Release(); pEvent->Release(); pGraph->Release(); CoUninitialize();
以下のサンプル コードはファイルを再生する :
#include <dshow.h> void main(void) { IGraphBuilder *pGraph; IMediaControl *pMediaControl; IMediaEvent *pEvent; CoInitialize(NULL); // フィルタグラフマネージャを作成し、インターフェイスをクエリする。 CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void **)&pGraph); pGraph->QueryInterface(IID_IMediaControl, (void **)&pMediaControl); pGraph->QueryInterface(IID_IMediaEvent, (void **)&pEvent); // グラフを作成。重要: 使用システムのファイル文字列に変更すること。 pGraph->RenderFile(L"C:\\Hello_World.avi", NULL); // グラフの実行。 pMediaControl->Run(); // 終了を待つ。 long evCode; pEvent->WaitForCompletion(INFINITE, &evCode); // クリーン アップ。 pMediaControl->Release(); pEvent->Release(); pGraph->Release(); CoUninitialize(); }