Microsoft DirectX 8.0

Visual Basic を使用したフィルタ グラフの作成方法

ここでは、Microsoft® Visual Basic® を使用してフィルタ グラフのコンポーネントを管理する方法について説明する。

この内容は、Microsoft® Windows® でのアプリケーション プログラミング、Windows ベースのマルチメディア プログラミング、および Visual Basic プログラミング システムの Automation 機能について既に理解している Visual Basic の開発者を対象にしている。

ここでは次の内容について説明する。

DirectShow Quartz.dll オブジェクトについて

Quartz.dll は、Visual Basic ベースのアプリケーションでフィルタおよびピンを管理するオブジェクトを提供する。それらのオブジェクト間には暗黙的な階層が存在する。つまり、多くの場合、オブジェクトを取得するには別のオブジェクトのプロパティにアクセスする必要がある。次の例で、オブジェクトの下に別のオブジェクトがインデントして示されている場合、その下位レベル オブジェクトは、上位レベル オブジェクトのプロパティまたはメソッドから取得する必要がある。

 
Filter graph object (IMediaControl) 
  Filter collection (RegFilterCollection, FilterCollection properties) 
    Filter Info object (IFilterInfo or IRegFilterInfo in filter collection) 
      Pin collection (Pins property) 
        Pin Info object (IPinInfo item in pins collection) 

階層の最上位レベル オブジェクトは、フィルタ グラフ オブジェクトつまり IMediaControl オブジェクトであり、フィルタ グラフ全体を表す。IMediaControl オブジェクトの 2 つのプロパティにアクセスすることによって、フィルタ オブジェクトのコレクションを取得できる。RegFilterCollection プロパティは、システムに登録されているフィルタを表す。FilterCollection プロパティは、フィルタ グラフの一部であるフィルタを表す。

Visual Basic でアクセス可能なほかのコレクションと同様に、Visual Basic の for each...next ステートメントを使ってコレクション内の個々の項目にアクセスできる。コレクション内の項目の数は、コレクションの Count プロパティによって示される。

フィルタ コレクションには、IFilterInfo オブジェクトが含まれている。各 IFilterInfo オブジェクトは、そのフィルタに対して定義されているピンのコレクションを表す Pins プロパティを持つ。

ピン コレクションには、IPinInfo オブジェクトが含まれている。各 IPinInfo オブジェクトは、メディア タイプや別のピンへの接続など、そのピンに関する詳細情報を含む。

フィルタ グラフ内のフィルタの特定のピンについて調べるには、次の手順を実行する。

  1. フィルタ グラフ オブジェクトを取得する。
  2. フィルタ グラフ オブジェクトの IMediaControl.FilterCollection プロパティを使用して、フィルタ グラフ内に存在するフィルタのコレクションを取得する。
  3. フィルタ コレクション内の特定のフィルタを検索する。
  4. フィルタ オブジェクトの IFilterInfo.Pins プロパティを使用して、そのフィルタに対して定義されているピンのコレクションを取得する。
  5. ピン コレクション内の特定のピンを検索する。
  6. ピン オブジェクトのプロパティを調べて、ピンの接続情報およびその他の情報を見つける。

フィルタ グラフの作成

Quartz.dll を使用してフィルタ グラフを作成するには、異なる 3 つの方法がある。それぞれの方法でフィルタ グラフに対する制御の度合いが異なり、フィルタ グラフ全体を自動生成することから、すべてのフィルタとピン接続を指定することまで可能である。3 つの方法を次に示す。

完全なフィルタ グラフの生成

次の例は、コードの一部分であり、マルチメディア ソースまたは保存されているフィルタ グラフに基づいて完全なフィルタ グラフを生成する方法を示している。アプリケーションでは、IMediaControl オブジェクト (最初は "空") を作成した後、IMediaControl.RenderFile メソッドを呼び出して完全なグラフを構築する。

' 最初に新しい空のフィルタ グラフを作成する
Dim g_objMC as IMediaControl       ' 汎用宣言セクションから
... 
Set g_objMC = New FilgraphManager  ' 新しいフィルタ グラフを作成する
... 
' 共通のファイルを開くダイアログ ボックスを使用してユーザーに入力ファイルを選択させる
CommonDialog1.ShowOpen             ' ユーザーがソースまたはフィルタ グラフを選択する
' IMediaControl.RenderFile を呼び出してすべてのフィルタを追加し、すべてのピンを接続する
g_objMC.RenderFile CommonDialog1.filename  ' 完全なグラフを生成する

新しいフィルタ グラフの作成とフィルタの追加

次の例は、コードの一部分であり、新しい (空の) フィルタ グラフ オブジェクトを作成する方法を示している。

Dim g_objMC as IMediaControl  ' 汎用宣言セクションから
    ... 
Set g_objMC = New FilgraphManager  ' 新しいフィルタ グラフを作成する

空のフィルタ グラフを作成して個々のフィルタを追加する場合は、フィルタ タイプがわかっている必要がある。通常、フィルタには 3 つのカテゴリがある。ソース フィルタ、変換フィルタ、およびレンダリング フィルタの 3 つである。ソース フィルタを追加する手順では、変換フィルタおよびレンダリング フィルタを追加する手順とは異なるメソッドを使用する。

フィルタ グラフにソース フィルタを追加する。そのためには、IMediaControl.AddSourceFilter メソッドを呼び出し、指定のソース タイプまたは保存されているフィルタ グラフのファイルの名前を指定する。

Dim objFilter As Object  ' 有効な構文用の一時オブジェクト; 使用しない
 
CommonDialog1.ShowOpen  ' ソースまたはフィルタ グラフ ファイルの名前を取得する
g_objMC.AddSourceFilter CommonDialog1.filename, objFilter 

IRegFilterInfo.Filter メソッドを呼び出して、フィルタ グラフに変換フィルタおよびレンダリング フィルタを追加する。IRegFilterInfo オブジェクトは、IMediaControl.RegFilterCollection プロパティから取得できる。このプロパティは、システムに登録されていて利用可能なフィルタ オブジェクトのコレクションを表す。

フィルタ グラフを作成して IMediaControl オブジェクトを取得した後、次の手順に従ってフィルタを追加する。

  1. 登録済みフィルタの一覧を取得するために、IMediaControl.RegFilterCollection プロパティを取得する。
  2. コレクションで目的のフィルタを検索する。コレクション内の各要素は IRegFilterInfo オブジェクトである。
  3. フィルタ グラフにフィルタを追加するために、IRegFilterInfo.Filter メソッドを呼び出す。

次の例は、コードの一部分で、この手順の 1 と 2 に対応する。

' 登録したフィルタ リスト ボックスにデータを挿入するコードの一部分
' グローバル変数 g_objRegFilters に IMediaControl.RegFilterCollection を設定する
' g_objRegFilters = g_objMC.RegFilterCollection と設定する
Dim filter As IRegFilterInfo 
    listRegFilters.Clear 
    If Not g_objRegFilters Is Nothing Then 
        For Each filter In g_objRegFilters  ' コレクション内のフィルタごとに
            listRegFilters.AddItem filter.Name ' 名前をリスト ボックスに追加する
Next filter 
End If 

次の例は、コードの一部分で、手順 3 に対応する。

Dim filter As IRegFilterInfo 
' 選択したフィルタを検索してグラフに追加する
' g_objRegFilters は IMediaControl オブジェクトの RegFilterCollection プロパティ
For Each filter In g_objRegFilters 
    If filter.Name = listRegFilters.Text Then  ' 選択したフィルタか? 
        Dim f As IFilterInfo  ' 答えが yes なら
        filter.filter f  ' フィルタ グラフに追加、IFilterInfo f を返す
        If f.IsFileSource Then 
            CommonDialog1.ShowOpen 
            f.filename = CommonDialog1.filename 
End If 
        Exit For 
End If 
Next filter 

フィルタ ピンの接続

フィルタ グラフに個々のフィルタを追加した後、各ピンを明示的に接続するか、特定のピンからダウンストリームに必要なすべての接続を自動的に生成して、フィルタ間の接続を確立できる。

いずれの場合も、Microsoft® DirectShow® オブジェクトの階層を走査して、フィルタ オブジェクトのピンを表す IPinInfo オブジェクトを取得する必要がある。そのためには、フィルタ グラフ オブジェクトのフィルタ コレクション内で目的のフィルタを見つけ、次にフィルタ オブジェクトのピン コレクション内で目的のピンを見つける。

ここでは次の内容について説明する。

フィルタ グラフのフィルタの一覧表示

フィルタ グラフ内のすべてのフィルタは、IMediaControl.FilterCollection プロパティを使用してアクセスできるコレクション内のフィルタとして利用可能である。

' グラフ内の現在のフィルタを含むリスト ボックスを最新の状態に更新する
listFilters.Clear 
For Each objFI In g_objMC.FilterCollection 
    listFilters.AddItem objFI.Name ' リスト ボックスに追加する
Next objFI 

フィルタに対して定義されているピンの一覧表示

フィルタ オブジェクトに対して定義されているピンは、IFilterInfo.Pins プロパティを使用してアクセスできる。Pins プロパティは、個々の IPinInfo オブジェクトのコレクションである。

コレクションから個々の IPinInfo オブジェクトを取得した後、オブジェクトのプロパティにアクセスし、オブジェクトのメソッドを呼び出すことができる。次の例は、これを示すコードの一部分である。

For Each objPin In g_objSelFilter.Pins 
If objPin.Name = listPins.Text Then  ' 選択したピンか?
    Set g_objSelPin = objPin ' 答えが yes なら、情報を更新する
    ' ... そのピンを使用して操作を実行する
End If 
Next objPin 

ピン オブジェクトを取得した後、もう 1 つのピンに明示的に接続するか、ピンをレンダリングするために必要な残りのピン接続すべてを自動的に生成できる。

2 つのピンの明示的な接続

IPinInfo オブジェクトは、ピンを接続する 3 つのメソッドを提供する。ConnectConnectDirect、および ConnectWithType である。Connect は、必要に応じてほかの変換フィルタを追加する。ConnectDirect は変換フィルタを追加しない。ConnectWithType は、指定されたピンが指定されたメディア タイプに一致する場合にのみ、接続を実行する。

frmSelectPin.OtherDir = g_objSelPin.Direction 
Set frmSelectPin.Graph = g_objMC             ' そのフォームにグラフのコピーと
Set frmSelectPin.SelFilter = g_objSelFilter  ' 現在のフィルタを渡す
frmSelectPin.RefreshFilters                  ' 接続できるフィルタを表示する
frmSelectPin.Show 1                          ' フォームを表示する
If frmSelectPin.bOK Then        ' ユーザーがフォームを選択--OK ボタンが使用された
    Dim objPI As IPinInfo 
    Set objPI = frmSelectPin.SelPin          ' フォームから新しいピンを取得する
    g_objSelPin.Connect objPI                ' 2 つのピンを接続する
    RefreshFilters                           ' ピンの最新情報を表示する
End If 

ピンの自動接続

ピンのダウンストリームに必要なフィルタ グラフのすべての部分を自動的に生成するには、IPinInfo.Render メソッドを呼び出す。

ダウンストリームという用語は、そのピンからレンダリング フィルタまでの完全なパスを構築するために必要なすべての接続を意味する。たとえば、GraphEdit ユーティリティによるフィルタ グラフの表現を考える。これは、左側のソース フィルタから右側のレンダリング フィルタまで移動する接続を示す。Render メソッドは、指定されたピンの右に必要なすべてのフィルタと接続を追加する。

' IPinInfo.Render を呼び出す
' このピンからダウンストリームにグラフを完成する
' g_objSelPin は 'Pins' とラベル付けされたリスト ボックスで選択されたピンを参照する
    g_objSelPin.Render 

ピン接続情報の表示

フィルタ オブジェクトの IFilterInfo.Pins プロパティからアクセス可能なコレクションのピン オブジェクトを取得した後、接続およびその他の情報を一覧表示できる。

  Dim strTemp As String 
  On Error Resume Next 
  Dim objPin As IPinInfo 
For Each objPin In g_objSelFilter.Pins 
    If objPin.Name = listPins.Text Then    ' リスト ボックスで選択されたか? 
      Set g_objSelPin = objPin             '答えが yes なら、すべての情報を取得する
      strTemp = ""               ' 既存の表示されているピンの情報を消去する
      Dim objPinOther As IPinInfo 
      Set objPinOther = objPin.ConnectedTo 
      If Err.Number = 0 Then               ' yes、接続がある
        strTemp = "Connected to pin: " + objPinOther.Name + " " 
        Dim objPeer As IFilterInfo 
        Set objPeer = objPinOther.FilterInfo 
        strTemp = strTemp + " on filter: " + objPeer.Name + " " 
        Dim objMTI As IMediaTypeInfo 
        Set objMTI = objPin.ConnectionMediaType 
        strTemp = strTemp + vbCrLf + "Media Type: " + objMTI.Type 
End If 
      If objPin.Direction = 0 Then 
strTemp = strTemp + " " + vbCrLf + "Direction: Input" 
      Else 
strTemp = strTemp + " " + vbCrLf + "Direction: Output" 
End If 
    txtPinInfo.Text = strTemp 
End If 
Next objPin 

まとめ

ここで説明した DirectShow オブジェクト、プロパティ、およびメソッドの使い方を次にまとめて示す。
タスク DirectShow のプロパティまたはメソッド
新しい空のフィルタ グラフを作成する。objMediaControl = New FilgraphManager を設定する。
特定のファイルの完全なフィルタ グラフを生成する。IMediaControl.RenderFile メソッドを呼び出す。
ソース フィルタを追加する。IMediaControl.AddSourceFilter メソッドを呼び出す。
レンダリング フィルタまたは変換フィルタを追加する。 IMediaControl.RegFilterCollection プロパティを使用して IRegFilterInfo オブジェクトを取得する。 IRegFilterInfo.Filter メソッドを呼び出す。
フィルタ オブジェクトのピンを一覧表示する。IFilterInfo.Pins プロパティを使用して IPinInfo オブジェクトを取得する。
2 つのピンを明示的に接続する。IPinInfo.Connect メソッドを呼び出す。
ピンからレンダリング フィルタまでのすべての接続を作成する。IPinInfo.Render メソッドを呼び出す。