トップページに戻る

DirectShowの概要

DirectShowはWindwows環境でマルチメディアの再生とキャプチャーを行うための技術で、具体的にはAVI MPEG、ASF、MP3などの動画や音声の再生、フォーマットの変換、キャプチャーを行うことが出来ます。Windowsパソコンのビデオやオーディオのハードウエアーには依存しないようになっております。つまりアクセラレーション機能が使用可能なら利用し、そうでないシステムもサポートします。DirectShowを理解するには「フィルター」というソフトウエアーコンポーネントを知る必要がある。以下にその仕組みについてと、ストリーミング再生用のプレーヤのプログラムについて述べます。

DirectShowの仕組み

DirectShowはいろいろな機能を持ったフィルターの集合体といえます。たとえば、MPEGの動画ファイルを読み込む「ソースフィルター」、ビデオとオーディオを分離する「パーサーフィルター」、データを伸長して無圧縮のデータに変換する「デコーダフィルター」、グラフィックカードやサウンドカードにデータを渡す「レンダラーフィルター」などで、これらを適切につないでやることでMPEGのファイルを再生することが出来ます。これを簡単な図で描くと下図のようになります。

このようなフィルターの構成を「フィルターグラフ」といい、フィルターをつなぐものを「ピン」といいます。グラフ内のデータを管理するのは「フィルターグラフマネージャー」という上位のコンポーネントです。アプリケーションはフィルターグラフマネージャーに対して、再生の開始や停止などの制御を行います。ある目的のために適切にフィルターを組み合わせ、ピンでつなぐのはかなり手間のかかる作業です。そのため、一般的なアプリケーションではフィルターグラフマネージャーを使ってフィルターグラフを自動生成します。DirectShowにはたくさんのフィルターが登録されていますから、一般的にAVIファイル、MPEGファイル(MPEG-2は除く)、ASFファイルなど単に再生したりハードディスクに書き込むだけなら、登録されたフィルターでプログラムすることが出来ます。自分で新たにフィルターを開発することも出来ます。そのためにはDirectXのSDKをここからダウンロードしてインストールしなくてはなりません。このHPの 「Com Player」はLANからMPEGのストリーミングデータを読み取りながら再生しなければいけませんから、新たに 「ソースフィルター」 を開発しました。
一般的な動画ファイル(MPEG)の再生方法を記述しておきます。SDKにもあります。

(1) DirectShowはCOMとして機能が実装されますから、COMライブラリーを初期化します。
CoInitialize(NULL);

(2)フィルターグラフマネージャーを用意する。

IGraphBuilder *g_pGraph;
CoCreateInstance(CLSID_FilterGraph,NULL,CLSCTX_INPROC_SERVER,
IID_IGraphBuilder,(void **)&g_pGraph);

(3)このインターフェースを使って必要な2つのインターフェースを取得します。QueryInterfaceメソッドを使います。

IMediaControl *g_pMediaControl;
IMediaEvent *g_pEvent;
g_pGraph->QueryInterface(IID_IMediaControl,(void**)&g_pMediaControl);
g_pGraph->QueryInterface(IID_IMediaEvent,(void**)&g_pEvent);
g_pMediaControl で 再生の開始(Run)や停止(Stop)を実行し、g_pEvent で再生の終了のイベントを受け取ります。

(4)フィルターグラフを作る。再生する動画(MPEG)ファイル名を取得して、ファイル名をワイド文字(Unicode)に変換します。

char Filename[MAX_PATH];
WCHAR w_FileName[MAX_PATH];

MultiByteToWideChar(CP_ACP,0,Filename,-1,w_FileName,MAX_CHAR);
g_pGraph->RenderFile(w_FileName);

これでフィルターグラフができあがりました。IGraphBuilder::RenderFile メソッドは指定された動画ファイルを再生するフィルターグラフを自動的に構築します。

(5)フィルターグラフが出来たから実行します。

g_pMediaControl->Run();

(6) 実行に成功したら再生が終了するまで待ちます。

long EventCode;
g_pEvent->WaitForCompletion(INFINITE,&EventCode);

これは再生が終了するまでブロックしてしまいますから、実際のプログラムではフィルターグラフからのイベントはアプリケーションのメッセージループで受け取るようにする。

(7) グラフの終了処理 (クリーンアップ)

g_pMediaControle->Release();
g_pEvent->Release();
g_pGraph->Release();

(8) COM の使用を終了する

CoUnInitialize();

上記のサンプルコードにはエラー処理が含まれておりません。DirectShowのフィルターは別のスレッドで実行されますから、各メソッドの実行ではエラーを確認しながら進めないとハングの原因となります。

ストリーミング プレーヤ (Com Player)の開発

これまでに動画ファイルの再生プログラムのことについて書きましたが、ライブ映像音声(Com Live)、TV(Com Schedulw)などの動画を再生するにはどうすればいいのでしょうか。実は上で書いたメソッド RenderFile()はDirectShowのフィルターグラフマネージャーが全てを自動的にやってくれます。プログラマーにとっては楽でよいのですが、データの流れは何も見えません。ライブ動画を再生するためには、少なくとも次の難題を解決しなくてはなりません。
(1) LANインターフェースから動画データを受信する。
(2)受信したデータをパーサーフィルターに渡す。
この項目を満足するソースフィルターはDirectShowのサンプル中にはありません。ソースフィルターにはプッシュモデルとプルモデルがあり、ファイルソースフィルター(IAsyncReader)はプルモデルです。ライブデータではプッシュモデルのソースフィルターを開発しなければなりません。新しいフィルターの開発には、
(1) 基底クラスのライブラリーをビルドする。SDK\Sample\MultiMedia\DirectShow\BaseClassesにあるVC++のワークスペース baseclasses.dsw をデバッグモードでビルドする。streambasd.libができます。
(2) CSource クラスから派生したソースフィルタークラスを作る。同時にCSourceStreamクラスから派生した出力ピンを作る。
(3) GetMediaType()、CheckMediaTyoe() をオーバーライドする。
メディアタイプの解決(ピンの接続)とメディアサンプルのダウンストリームへのプッシュには覚悟してかかることが重要です。サンプルプログラムが無いのでBaseClassのソースとSDKにある数少ないサンプル例から類推するしかありません。
ライブを再生するプログラム開発に注意する情報がここにありました。参考にして下さい。
DirectShowに含まれる パーサーフィルターである AVIスプリッター、MPEG-1スプリッター、はプルモデルソースフィルターにしか接続できませんから、パーサーフィルターも作る必要があります。 そこで Com Player ではMpeg1 Mpeg2についてはファイルフィルターにプッシュするソースフィルターを開発しDirectShowのスプリッターフィルターをそのまま使用できるようにしました。これでローカルファイルでもライブでも再生出来るわけです。
Mpeg4 MotionJpeg WindowsMedia ではそう簡単にはいきません。DirectShowのBaseClas CSource クラスから新たにソースフィルターを 開発する必要があります。
LANインターフェースは WindowsSocket 2.0です。マルチスレッド対応とオーバーラップドIOに対応しています。DirectShowのフィルターとは同期を取る必要があります。