Skip to main content.

Wednesday, March 21, 2007

DirectShow基礎

開発環境
DirectShowの開発環境に関しては、前回までを参照して下さい。それから、今回参考にしたMSDN Library(参考リンク)はMicrosoft DirectX 9.0 のドキュメントです。開発環境に関する部分等、最新では変更されている部分がありますので、御了承、御注意下さい。

COM(Component Object Model)
DirectShowはベースになる技術はCOMです。そういった意味ではCOMの知識も必要になります。COMに関しては以下のサイト等を参照して下さい。
MSDN COMの概要
ITmediaエンタープライズ Component Object Model COMとは

DirectShow構成
フィルタ:DirectShowを構成するモジュール化されたコンポーネント。フィルタは更に"ソースフィルタ"、"変換フィルタ"、"レンダリングフィルタ"等のいくつかのカテゴリに分類される。
ピン:フィルタの接続ポイント。フィルタは、ピンを使って、データをあるフィルタから次のフィルタに移動させる。
フィルタグラフ:接続されたフィルタの集合体。
フィルタグラフマネージャ:フィルタグラフ内のフィルタを制御する。
実際には、これらはCOMコンポーネントとして実装されているので、実装されたCOMコンポーネントを使ってプログラミングをすることになります。あるいは、フィルターを自作するということも出来ます。

GraphEdit
GraphEditは、フィルタグラフを作成するためのビジュアル ツールです。上記のDirectShowの構成を実感する、テストをするといった場合に大変役立つツールです。現在では、インストールしたMicrosoft Platform SDK配下のbinディレクトリ(私の場合は、C:\Program Files\Microsoft Platform SDK for Windows Server 2003 R2\Bin)に入っているようです。実行ファイル名はgraphedt.exeです。使い方の詳細等はこちらを参照して下さい。

今回は、前回のプログラムを意識して、ruby.aviという動画ファイルを再生する処理を考えます。単純にGraphEditツールにruby.aviというファイルをドラッグ、ドロップすると以下のようなグラフが生成されます。四角それぞれがフィルタでピンで接続されていて、フィルタグラフを構成しているというのが視覚的に見えると思います。これでplayボタンを押すとサンプルプログラムと同様にruby.aviファイルが再生されます。


DirectShowプログラミング
プログラミングとしては、実装されたCOMコンポーネントを利用してプログラミングをします。以下、前回のサンプルプログラムですが、これとGraphEditツールのグラフを見るとプログラミングが多少はイメージ出来るかと思います。プログラムの方にはDecompressorとかいうフィルタはありませんが、IGraphBuilder::RenderFile()の説明には「ファイル名を指定してレンダリングを行うためのフィルタグラフを構築するメソッドである」とあります。ということは、IGraphBuilder::RenderFile()で上のようなフィルタグラフが構築されているのかな?と思います。ちなみに、IMediaControl::RenderFile()はVB6用となっていました。実際のプログラミングでは、このDirectShowのCOMコンポーネントをどう使いこなすかという課題の他に、画面を制御する処理、メニューやそのメニューの処理、エラー処理等が当然必要になってきます。
//
// DirectShowテスト用プログラム
//

//VC++ 2005の場合でとりえあえずwarningを無効にする
//(warningがいろいろと出ると見にくいので)
#pragma warning( disable : 4819 )
#pragma warning( disable : 4996 )

//DirectShowのインクルード
#include <dshow.h>

//動画ファイルの場所を指定(短いパス名の方が無難かも)
#define	MOV_FILENAME L"C:\\temp\\ruby.avi"

int main(int argc, char** argv)
{
    IGraphBuilder *pGraphBuilder;
    IMediaControl *pMediaControl;

    //COM初期化
    CoInitialize(NULL);

    //FilterGraph生成
    CoCreateInstance(CLSID_FilterGraph,NULL,CLSCTX_INPROC,
        IID_IGraphBuilder,(LPVOID *)&pGraphBuilder);

    //MediaControlインターフェース取得
    pGraphBuilder->QueryInterface(IID_IMediaControl,
        (LPVOID *)&pMediaControl);

    //ファイルがない場合は、画面が出ないだけなので、要注意
    //pMediaControl->RenderFile((BSTR)MOV_FILENAME);
    //2007.03.20 IGraphBuilderの方を使用に変更
    pGraphBuilder->RenderFile((BSTR)MOV_FILENAME,NULL);

    //再生開始
    pMediaControl->Run();

    //再生終了前に終了しないように停止
    MessageBox(NULL,(LPCSTR)"stop",(LPCSTR)"stop",MB_OK);

    //解放
    pMediaControl->Release();
    pGraphBuilder->Release();

    //COM終了
    CoUninitialize();

    return 0;
}

参考リンク
DirectShow(※Microsoft DirectX 9.0のドキュメント)

Windowsプログラミング関連記事