Microsoft DirectX 8.0 |
ここでは、Microsoft® DirectShow® のダイナミック リンク ライブラリである Quartz.dll によって公開されているメソッド、イベント、およびプロパティを使用して、Microsoft® Visual Basic® ベースのアプリケーションでタイム スタンプ付きのビデオ データのストリームをレンダリングする方法を説明する。この内容は、Microsoft® Windows® ベースのアプリケーション プログラミング、Windows ベースのマルチメディア プログラミング、および Visual Basic プログラミング システム バージョン 5.x の Automation 機能について既に理解している開発者が対象である。
ここでは次の内容について説明する。
アプリケーションで Quartz.dll を使用してマルチメディアを表示するには、フィルタと呼ばれるオブジェクトのコレクションを使用する。このコレクションはフィルタ グラフとも呼ばれる。次の図は、AVI (Audio-Video Interleaved) ファイルをレンダリングするフィルタ グラフを示している。
この図では、AVI ソース フィルタがディスクからファイルを読み取る。AVI デコンプレッサ フィルタ (CODEC) は、ソース フィルタから渡されたビデオ データを圧縮解除する。次に、CODEC フィルタはこのデータをビデオ レンダラに渡す。その次に、ビデオ レンダラはデバイスが認識できるフォーマットのデータをデバイスに渡す。AVI ソース フィルタはオーディオ レンダラに直接オーディオ データを渡し、オーディオ レンダラはオーディオ デバイスにデータを渡す。
DirectShow は、フィルタのほかにも、フィルタ グラフ マネージャと呼ばれる Automation オブジェクトをサポートしている。このオブジェクトは、利用可能なフィルタについて知っている。また、どのファイル フォーマットをレンダリングするためにどのフィルタ タイプが必要かを認識している。フィルタ グラフ マネージャは、特定のグラフ内のフィルタがサポートしているメソッド、イベント、およびプロパティを公開する。さらに、独自のメソッド、イベント、およびプロパティのセットを、インターフェイスを使用して公開する。インターフェイスは、関連したメソッド、イベント、およびプロパティのコレクションである。
次の表では、Visual Basic ベースのアプリケーションで使用する、Quartz.dll に提供されている DirectShow のインターフェイスを示し、各インターフェイスの目的を説明する。
インターフェイス | 説明 |
---|---|
IAMCollection | ピン コレクションおよびフィルタ コレクションにアクセスする。 |
IBasicAudio | 現在のボリューム設定を制御し、取得する。 |
IBasicVideo | 汎用ビデオ レンダラを制御する。 |
IFilterInfo | フィルタに関する情報、およびフィルタ内のピン オブジェクトに関する情報を取得する。 |
IMediaControl | フィルタ グラフをインスタンス化し、メディア フロー (実行、ポーズ、停止) を制御する。 |
IMediaEvent | 再ペイント、ユーザー終了、完了などのイベントに対するカスタマイズしたイベント処理を可能にする。 |
IMediaPosition | 開始タイム、終了タイム、レート、および現在位置を制御し、取得する。 |
IMediaTypeInfo | メディア タイプとサブタイプを取得する。 |
IPinInfo | ピンの方向やメディア タイプなどのピン情報にアクセスし、ピンの接続、切断、およびレンダリングを制御する。 |
IRegFilterInfo | 登録済みの (変換およびレンダリング) フィルタに関する情報を含む。 |
IVideoWindow | ビデオ レンダラのウィンドウ アスペクトを制御する。 |
Microsoft Visual Basic ベースのアプリケーションで DirectShow のインターフェイスを使用するには、Visual Basic プロジェクトで Microsoft® ActiveMovie® コントロール タイプ ライブラリを登録する必要がある。そのためには、[プロジェクト] メニューの [参照設定] をクリックし、次に [ActiveMovie control type library] の左のチェック ボックスをオンにする。
Visual Basic の [参照設定] ダイアログ ボックスを使用して ActiveMovie コントロール タイプ ライブラリを登録することによって、Visual Basic に必要な Automation 情報を含むタイプ ライブラリを特定する。次の図に [参照設定] ダイアログ ボックスを示す。
タイプ ライブラリを登録した後、[オブジェクト ブラウザ] ダイアログ ボックスを使用して、特定のインターフェイスに関連したメソッド、イベント、およびプロパティの一覧を表示できる。[表示] メニューの [オブジェクト ブラウザ] をクリックし、次に、[オブジェクト ブラウザ] ダイアログ ボックスの左上にあるライブラリのドロップダウン リストから [QuartzTypeLib] を選択する。
注 : QuartzTypeLib 内のタイプ情報は、オブジェクト別ではなくインターフェイス別に編成されている。
ここでは次の内容について説明する。
Visual Basic ベースのアプリケーションで DirectShow オブジェクトを使用するには、Windows\System ディレクトリに Quartz.dll をインストールし、システムのレジストリ データベースに適切な項目が作成されたことを確認する必要がある。現在、このプロセスは Microsoft® DirectX® Software Development Kit (SDK) セットアップ プログラムによって自動化されている。インストールするには、Setup.exe を起動し、Runtime オプションを選択する。ダイナミック リンク ライブラリ (DLL) が正しい場所にコピーされ、レジストリが自動的に更新される。
ファイルが正しくインストールされたことを確認するには、Visual Basic アプリケーションを開き、[表示] メニューの [参照設定] コマンドをクリックする。起動時に Visual Basic によってレジストリ データベースの登録済み Automation コントロールが確認され、このダイアログ ボックスに表示される一覧にコントロールの名前が追加される。フィルタ グラフ マネージャを使用するには、[ActiveMovie control type library] をクリックする。
Visual Basic にタイプ情報が登録されると、アプリケーションでフィルタ グラフ マネージャおよび関連するインターフェイスを使用できる。
Visual Basic は、FilgraphManager オブジェクトを使用してすべてのオブジェクトを初期化する。FilgraphManager オブジェクトは次のインターフェイスを実装する。
各インターフェイスには、そのインターフェイス タイプとして定義した Visual Basic のプログラム可能なオブジェクトからアクセスする。オブジェクトは、次の例に示すように、汎用宣言セクションでグローバル変数として定義できる。
Dim g_objVideoWindow As IVideoWindow ' VideoWindow オブジェクト Dim g_objMediaControl As IMediaControl ' MediaControl オブジェクト Dim g_objMediaPosition As IMediaPosition ' MediaPosition オブジェクト Dim g_objBasicAudio As IBasicAudio ' Basic Audio オブジェクト Dim g_objBasicVideo As IBasicVideo ' Basic Video オブジェクト
次の例に示すように、FilgraphManager を使用してすべてのプログラム可能なオブジェクトを初期化する。
Set g_objMediaControl = New FilgraphManager g_objMediaControl.RenderFile (g_strFileName) ' 入力ファイルの名前 ... Set g_objBasicAudio = g_objMediaControl Set g_objVideoWindow = g_objMediaControl Set g_objMediaEvent = g_objMediaControl Set g_objMediaPosition = g_objMediaControl
目的のインターフェイスを明示的に返すメソッドを呼び出すことによって、ほかのインターフェイスを取得する。次の表は、これらのインターフェイスの取得方法を示している。
これらのフィルタ インターフェイスおよびピン インターフェイスの操作方法を示す例については、「Visual Basic を使用したフィルタ グラフの作成」を参照すること。
フィルタ グラフ マネージャを使用して、次のタイプの既存ファイルをレンダリングできる。
さらに、フィルタ グラフ マネージャを使用して既存のフィルタ グラフをレンダリングできる。そのためには、そのグラフを含むファイルを RenderFile メソッドのパラメータとして指定する。
フィルタ グラフ内のフィルタはレンダリングするファイルのタイプに依存するため、ユーザーがファイルを選択してからフィルタ グラフをインスタンス化すること。フィルタ グラフ マネージャは、Visual Basic のキーワード New を使用して AUTOMATION オブジェクトを作成するときにインスタンス化される。フィルタ グラフ オブジェクトは、次の例に示すように、IMediaControl::RenderFile メソッドを呼び出したときに作成される。
'要求されたファイル フォーマットのフィルタ グラフを 'インスタンス化する Set g_objMediaControl = New FileGraphManager g_objMediaControl.RenderFile (g_strFileName)
IMediaControl インターフェイスは 3 つのメソッドをサポートしている (Run、Pause、および Stop)。アプリケーションでは、これらのメソッドを呼び出してビデオ ストリームをレンダリング、ポーズ、または停止することができる。フィルタ グラフ オブジェクトがインスタンス化された後、アプリケーションでこれらのメソッドを呼び出すことができる。
次のコード例は、ユーザーがボタンをクリックしたとき、それに応答して Run、Pause、および Stop メソッドを起動する。
Private Sub Toolbar1_ButtonClick(ByVal Button As Button) ' ツール バーのボタンを処理する ' オブジェクトが定義されていない場合はエラーを回避する If g_objMediaControl Is Nothing Then Exit Sub End If If Button.Index = 1 Then 'PLAY 'MediaControl Run() メソッドを呼び出して 'ビデオを再生する (あらかじめ定義された 'フィルタ グラフを使用) g_objMediaControl.Run g_fVideoRun = True ElseIf Button.Index = 2 Then 'PAUSE 'MediaControl Pause() メソッドを呼び出して '表示中のビデオをポーズする (ビデオの表示には 'あらかじめ定義されたフィルタ グラフを使用) g_objMediaControl.Pause g_fVideoRun = False ElseIf Button.Index = 3 Then 'STOP 'MediaControl Stop() メソッドを呼び出して '表示中のビデオを停止する (ビデオの表示には 'あらかじめ定義されたフィルタ グラフを使用) g_objMediaControl.Stop g_fVideoRun = False ' ビデオの先頭にリセットする g_objMediaPosition.CurrentPosition = 0 txtElapsed.Text = "0.0"
IBasicAudio インターフェイスは、Volume プロパティと Balance プロパティという 2 つのプロパティをサポートしている。Volume プロパティはボリュームを取得または設定する。サンプル アプリケーションでは、このプロパティはスライダ コントロール slVolume にバインドされている。Balance プロパティはステレオのバランスを取得または設定する。サンプル アプリケーションでは、このプロパティはスライダ コントロール slBalance にバインドされている。
注 : ボリュームはリニア ボリューム スケールであるため、有用なのはスライダの右端だけである。
次の例では、g_objBasicAudio.Volume プロパティを設定してボリュームを調整している。
Private Sub slVolume_Change() 'スライダのボリュームを設定する If Not g_objMediaControl Is Nothing Then 'g_objMediaControl が割り当てられている場合 g_objBasicAudio.Volume = slVolume.Value End If End Sub
IVideoWindow インターフェイスは、転送先ウィンドウのサイズ、状態、所有者、パレット、可視性などを変更するメソッドとプロパティをサポートしている。転送先ウィンドウの位置または外観を考慮する必要がない場合は、これらのメソッドとプロパティを呼び出さず、デフォルトのウィンドウ (デスクトップの左上に表示される) に出力をレンダリングすることができる。
キャプション、境界、およびダイアログ ボックスの枠を移動してウィンドウのスタイルを変更することもできる。そのためには、g_objVideoWindow.WindowStyle プロパティを 0x06000000 に設定する。これは、値 WS_DLGFRAME (0x04000000) と WS_VSCROLL (0x02000000) の 論理 OR に相当する。ウィンドウのスタイルおよび対応する値すべての一覧については、Microsoft® Platform SDK の Winuser.h ファイルを参照すること。
転送先ウィンドウをフォームの上に移動する場合、新しい位置を指定するには、g_objVideoWindow の Top および Left プロパティを設定する。Top および Left プロパティは、矩形をした空のコントロールの左上隅に対応するように設定する。これはフォームに表示されるある種のプレースホルダである。フォームの ScaleMode プロパティは 3 に設定されている。これはピクセルの単位を指定する。これでフォームのプロパティと DirectShow オブジェクトのプロパティを変換することなく使用できる。DirectShow オブジェクトのプロパティもピクセルで表される。Visual Basic フォームのデフォルトの単位は twip である。
ソース ビデオの幅と高さを取得して必要な矩形のサイズを決定する。これらの値は、IBasicVideo オブジェクトの VideoWidth および VideoHeight プロパティに対応する。
Top および Left プロパティを設定することに加えて、アプリケーションのフォームを新しい親ウィンドウとして識別する必要がある。そのためには、フォームのウィンドウ ハンドルである hWnd をオブジェクトの Owner プロパティに渡す。ハンドルを渡さない場合、転送先ウィンドウはフォームではなくデスクトップに対して相対的な位置に表示される。
次に例は、これらのタスクを示している。
Set g_objVideoWindow = g_objMediaControl g_objVideoWindow.WindowStyle = CLng(&H6000000) ' WS_DLGFRAME | WS_VSCROLL g_objVideoWindow.Left = CLng(Shape1.Left) ' shape はフォームのプレースホルダ g_objVideoWindow.Top = CLng(Shape1.Top) Shape1.Width = g_objVideoWindow.Width ' 入力ビデオに応じて shape をサイズ変更する Shape1.Height = g_objVideoWindow.Height g_objVideoWindow.Owner = frmMain.hWnd ' フォームを親として設定する
次の例は、ScaleMode プロパティを初期化する方法を示している。
' ... frmMain.ScaleMode = 3 ' ピクセル ' ...
パフォーマンスに大きく影響するため、IVideoWindow オブジェクトの Width および Height プロパティを設定して転送先ウィンドウのスケールを変更しないこと。
IMediaPosition オブジェクトによって公開されている多数のプロパテイを使用して、現在位置、停止位置、時間幅、およびレートを取得または設定できる。次のコード例は、その方法を示している。
Set g_objMediaPosition = g_objMediaControl g_dblRunLength = g_objMediaPosition.Duration txtDuration.Text = CStr(g_dblRunLength) ' 時間幅を表示する g_dblStartPosition = 0.0 txtStart.Text = CDbl(g_dblStartPosition) ' 開始タイムを表示する g_dblRate = g_objMediaPosition.Rate txtRate.Text = CStr(g_dblRate)
IMediaPosition.CurrentPosition プロパティを使用すると、ユーザーがビデオのレンダリング開始位置を調整できる。次のコード例では、ユーザーがキーを押すと、それに応じて現在の位置を変更する。
Private Sub txtStart_KeyDown(KeyCode As Integer, Shift As Integer) ' ユーザー入力を処理して開始位置を変更する If KeyCode = vbKeyReturn Then If g_objMediaPosition Is Nothing Then Exit Sub ElseIf CDbl(txtStart.Text) > g_dblRunLength Then MsgBox "Specified position invalid:re-enter new position." ElseIf CDbl(txtStart.Text) < 0 Then MsgBox "Specified position invalid:re-enter new position." ElseIf CDbl(txtStart.Text) <> "" Then g_dblStartPosition = CDbl(txtStart.Text) g_objMediaPosition.CurrentPosition = g_dblStartPosition End If End If End Sub
IMediaPosition.Rate プロパティを使用すると、ユーザーがビデオのレンダリング レートを調整できる。このレートは、標準再生速度を基準にしている。たとえば、レートが 0.5 の場合、ビデオは標準速度の 2 分の 1 の速度でレンダリングされ、レートが 2.0 の場合は標準レートの 2 倍の速度でレンダリングされる。
CurrentPosition プロパティはビデオのレンダリング中に設定できるが、Rate プロパティはレンダリングの前にあらかじめ設定しておく必要がある。
注 : レートが 1.0 未満のときはサウンド トラックを無効にできるビデオもある。
次のコード例では、ユーザーがキーを押すと、それに応じてレートを変更する。
Private Sub txtRate_KeyDown(KeyCode As Integer, Shift As Integer) ' DirectShow VB サンプル ' Rate 値に対するユーザーによる更新を処理する If KeyCode = vbKeyReturn Then If g_objMediaPosition Is Nothing Then Exit Sub ElseIf CDbl(txtRate.Text) < 0# Then MsgBox "Negative values invalid: re-enter value between 0 and 2.0" ElseIf CStr(txtRate.Text) <> "" Then g_dblRate = CDbl(txtRate.Text) g_objMediaPosition.Rate = g_dblRate End If End If End Sub
アプリケーションでは、Visual Basic の Set ステートメントを使用して新しい DirectShow オブジェクトのインスタンスを作成するたびに、次のコード例に示すように、対応する Set ステートメントでそのオブジェクト (および関連するリソース) をメモリから削除してからシャットダウンする必要がある。
Set g_objBasicAudio = Nothing