ウィンドウ モードの使用

[このページに関連付けられている機能 DirectShow は、従来の機能です。 MediaPlayer、IMFMediaEngine、Media Foundation のオーディオ/ビデオ キャプチャに置き換わりました。 これらの機能は、Windows 10とWindows 11用に最適化されています。 新しいコードでは、可能であれば、DirectShow ではなく Media Foundation で MediaPlayerIMFMediaEngineAudio/Video Capture を使用することを強くお勧めします。 Microsoft は、レガシ API を使用する既存のコードを、可能であれば新しい API を使用するように書き換えるよう提案しています。]

注意

従来の ビデオ レンダラー フィルター では、常にウィンドウ モードが使用されます。 VMR-7 および VMR-9 フィルターでは、既定ではウィンドウ モードが使用されますが、ウィンドウレス モードもサポートされています。

 

ウィンドウ モードでは、ビデオ レンダラーはビデオ フレームを描画する独自のウィンドウを作成します。 特に指定しない限り、このウィンドウは、独自の罫線とタイトル バーを持つ最上位ウィンドウです。 ただし、ほとんどの場合、ビデオ ウィンドウをアプリケーション ウィンドウにアタッチして、ビデオがアプリケーション UI に統合されるようにします。 この場合、次の手順が必要です。

  1. IVideoWindow のクエリ。
  2. 親ウィンドウを設定します。
  3. 新しいウィンドウ スタイルを設定します。
  4. 所有者ウィンドウ内にビデオ ウィンドウを配置します。
  5. ビデオ ウィンドウにWM_MOVEメッセージを通知します。

IVideoWindow のクエリ

再生を開始する前に、フィルター グラフ マネージャーに IVideoWindow インターフェイスのクエリを実行します。

IVideoWindow *pVidWin = NULL;
pGraph->QueryInterface(IID_IVideoWindow, (void **)&pVidWin);

親ウィンドウを設定する

親ウィンドウを設定するには、アプリケーション ウィンドウへのハンドルを使用 して IVideoWindow::p ut_Owner メソッドを呼び出します。 このメソッドは OAHWND 型の変数を受け取ります。そのため、ハンドルをこの型にキャストします。

pVidWin->put_Owner((OAHWND)hwnd);

新しいウィンドウ スタイルを設定する

IVideoWindow::p ut_WindowStyle メソッドを呼び出して、ビデオ ウィンドウのスタイルを変更します。

pVidWin->put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS);

WS_CHILD フラグは、ウィンドウを子ウィンドウに設定し、WS_CLIPSIBLINGS フラグを設定すると、別の子ウィンドウのクライアント領域内にウィンドウが描画されなくなります。

ビデオ ウィンドウを配置する

アプリケーション ウィンドウのクライアント領域を基準にしてビデオの位置を設定するには、 IVideoWindow::SetWindowPosition メソッドを呼び出します。 このメソッドは、ビデオ ウィンドウの左端、上端、幅、高さを指定する四角形を受け取ります。 たとえば、次のコードは、親ウィンドウのクライアント領域全体に合わせてビデオ ウィンドウを拡大します。

RECT rc;
GetClientRect(hwnd, &rc);
pVidWin->SetWindowPosition(0, 0, rc.right, rc.bottom);

ビデオのネイティブ サイズを取得するには、フィルター グラフ マネージャーで IBasicVideo::GetVideoSize メソッドを呼び出します。 その情報を使用して、ビデオをスケーリングし、正しい縦横比を維持できます。

WM_MOVE メッセージに応答する

最適なパフォーマンスを得る場合は、グラフが一時停止している間にウィンドウが移動するたびにビデオ レンダラーに通知する必要があります。 IVideoWindow::NotifyOwnerMessage メソッドを呼び出して、WM_MOVE メッセージを転送します。

// (Inside your WindowProc)
case WM_MOVE:
    pVidWin->NotifyOwnerMessage((OAHWND)hWnd, msg, wParam, lParam);
    break;

レンダラーがハードウェア オーバーレイを使用している場合、この通知により、レンダラーはオーバーレイ位置を更新します。 (VMR-9 はオーバーレイを使用しないため、VMR-9 を使用している場合は、このメソッドを呼び出す必要はありません)。

クリーンアップ

アプリケーションが終了する前に、グラフを停止し、ビデオ ウィンドウの所有者を NULL にリセット します。 そうしないと、ウィンドウ メッセージが間違ったウィンドウに送信され、エラーが発生する可能性があります。 また、ビデオ ウィンドウを非表示にするか、ビデオ 画像が一時的に画面にちらつく場合があります。

pControl->Stop(); 
pVidWin->put_Visible(OAFALSE);
pVidWin->put_Owner(NULL);  

注意

ビデオ ウィンドウの親がメイン アプリケーション ウィンドウの子である場合 (つまり、ビデオ ウィンドウが子の子である場合)、Filter Graph Manager で Intelligent Connect 中にビデオ レンダラーを追加するのではなく、CoCreateInstance を使用してビデオ ウィンドウを作成し、グラフに追加する必要があります。 これにより、ビデオ ウィンドウと子ウィンドウが同時に再描画されます。 そうしないと、子ウィンドウがビデオ ウィンドウの上に描画される場合があります。

 

ビデオのレンダリング