VMR ウィンドウレス モード
[このページに関連付けられている機能 DirectShow は、従来の機能です。 MediaPlayer、IMFMediaEngine、および Media Foundation のオーディオ/ビデオ キャプチャに置き換わりました。 これらの機能は、Windows 10とWindows 11用に最適化されています。 新しいコードでは、可能であれば、DirectShow ではなく Media Foundation で MediaPlayer、IMFMediaEngine、Audio/Video Capture を使用することを強くお勧めします。 Microsoft は、従来の API を使用する既存のコードを、可能であれば新しい API を使用するように書き直すよう提案しています。]
ウィンドウレス モードは、アプリケーションがアプリケーション ウィンドウ内でビデオをレンダリングする場合に推奨される方法です。 ウィンドウレス モードでは、Video Mixing Renderer は Window Manager コンポーネントを読み込まず、 IBasicVideo または IVideoWindow インターフェイスをサポートしていません。 代わりに、アプリケーションは再生ウィンドウを提供し、VMR がビデオを描画するためのターゲット四角形をクライアント領域に設定します。 VMR は DirectDraw クリッパー オブジェクトを使用して、ビデオがアプリケーションのウィンドウにクリップされ、他のウィンドウには表示されないようにします。 VMR は、アプリケーションのウィンドウをサブクラス化したり、システム/プロセス フックをインストールしたりすることはありません。
ウィンドウレス モードでは、接続中のイベントのシーケンスと実行状態への移行は次のとおりです。
- アップストリーム フィルターは、VMR が受け入れるか拒否するメディアの種類を提案します。
- メディアの種類が受け入れられる場合、VMR はアロケーター発表者を呼び出して DirectDraw サーフェスを取得します。 サーフェスが正常に作成されると、ピンが接続され、VMR が実行状態に移行する準備が整います。
- フィルター グラフが実行されると、デコーダーは GetBuffer を 呼び出して、アロケーターからメディア サンプルを取得します。 VMR はアロケーター 発表者に対してクエリを実行して、DirectDraw サーフェス上のピクセル深度、四角形のサイズ、およびその他のパラメーターが受信ビデオと互換性があることを確認します。 互換性がある場合、VMR は DirectDraw サーフェスをデコーダーに返します。 デコーダーがサーフェスにデコードされると、VMR のコア同期ユニットによってタイム スタンプが検証されます。 このユニットは、プレゼンテーション時間が到着するまで Receive 呼び出しをブロックします。 その時点で、VMR は allocator-presenter で PresentImage を呼び出します。これにより、サーフェスがグラフィックス カードに表示されます。
次の図は、複数の入力ストリームを含むウィンドウレス モードの VMR を示しています。
ウィンドウレス モード用の VMR-7 の構成
ウィンドウレス モード用に VMR-7 を構成するには、VMR の入力ピンのいずれかを接続する前に、次のすべての手順を実行します。
フィルターを作成し、グラフに追加します。
VMRMode_Windowless フラグを指定して IVMRFilterConfig::SetRenderingMode メソッドを呼び出します。
必要に応じて、 IVMRFilterConfig::SetNumberOfStreams を呼び出して、複数の入力ストリームの VMR を構成します。 VMR は、ストリームごとに入力ピンを作成します。 ストリームの Z オーダーやその他のパラメーターを設定するには、 IVMRMixerControl インターフェイスを使用します。 詳細については、「 複数ストリームを含む VMR (混合モード)」を参照してください。
SetNumberOfStreams を呼び出さない場合、VMR-7 は既定で 1 つの入力ピンになります。 入力ピンを接続した後は、ピンの数を変更できません。
IVMRWindowlessControl::SetVideoClippingWindow を呼び出して、レンダリングされたビデオが表示されるウィンドウを指定します。
これらの手順が完了したら、VMR フィルターの入力ピンを接続できます。 ピンを直接接続したり、 IGraphBuilder::RenderFile などの Intelligent Connect メソッドを使用したり、Capture Graph Builder の ICaptureGraphBuilder2::RenderStream メソッドを使用したりするなど、さまざまな方法でグラフを作成できます。 詳細については、「 一般的なGraph-Building手法」を参照してください。
アプリケーション ウィンドウ内のビデオの位置を設定するには、 IVMRWindowlessControl::SetVideoPosition メソッドを呼び出します。 IVMRWindowlessControl::GetNativeVideoSize メソッドは、ネイティブ ビデオ サイズを返します。 再生中に、アプリケーションは次の Windows メッセージを VMR に通知する必要があります。
- WM_PAINT: IVMRWindowlessControl::RepaintVideo を呼び出してイメージを再描画します。
- WM_DISPLAYCHANGE: IVMRWindowlessControl::D isplayModeChanged を呼び出します。 VMR は、新しい解像度または色深度でビデオを表示するために必要なアクションを実行します。
- WM_SIZE: ビデオの位置を再計算し、必要に応じて SetVideoPosition をもう一度呼び出します。
注意
MFC アプリケーションでは、空のWM_ERASEBKGND メッセージ ハンドラーを定義する必要があります。または、ビデオ表示領域が正しく再描画されません。
ウィンドウレス モード用の VMR-9 の構成
ウィンドウレス モード用に VMR-9 を構成するには、ウィンドウレス モードの VMR-7 で説明されている手順を使用しますが、 IVMRFilterConfig9 インターフェイスと IVMRWindowlessControl9 インターフェイスを使用します。 唯一の大きな違いは、VMR-9 は 1 つの入力ピンではなく、既定で 4 つの入力ピンを作成することです。 したがって、 SetNumberOfStreams を呼び出す必要があるのは、4 つ以上のビデオ ストリームを混在させる場合のみです。
コード例
次のコードは、VMR-7 フィルターを作成し、DirectShow フィルター グラフに追加し、VMR をウィンドウレス モードにする方法を示しています。 VMR-9 の場合は、 CoCreateInstance と対応する VMR-9 インターフェイスでCLSID_VideoMixingRenderer9を使用します。
HRESULT InitializeWindowlessVMR(
HWND hwndApp, // Application window.
IFilterGraph* pFG, // Pointer to the Filter Graph Manager.
IVMRWindowlessControl** ppWc, // Receives the interface.
DWORD dwNumStreams, // Number of streams to use.
BOOL fBlendAppImage // Are we alpha-blending a bitmap?
)
{
IBaseFilter* pVmr = NULL;
IVMRWindowlessControl* pWc = NULL;
*ppWc = NULL;
// Create the VMR and add it to the filter graph.
HRESULT hr = CoCreateInstance(CLSID_VideoMixingRenderer, NULL,
CLSCTX_INPROC, IID_IBaseFilter, (void**)&pVmr);
if (FAILED(hr))
{
return hr;
}
hr = pFG->AddFilter(pVmr, L"Video Mixing Renderer");
if (FAILED(hr))
{
pVmr->Release();
return hr;
}
// Set the rendering mode and number of streams.
IVMRFilterConfig* pConfig;
hr = pVmr->QueryInterface(IID_IVMRFilterConfig, (void**)&pConfig);
if (SUCCEEDED(hr))
{
pConfig->SetRenderingMode(VMRMode_Windowless);
// Set the VMR-7 to mixing mode if you want more than one video
// stream, or you want to mix a static bitmap over the video.
// (The VMR-9 defaults to mixing mode with four inputs.)
if (dwNumStreams > 1 || fBlendAppImage)
{
pConfig->SetNumberOfStreams(dwNumStreams);
}
pConfig->Release();
hr = pVmr->QueryInterface(IID_IVMRWindowlessControl, (void**)&pWc);
if (SUCCEEDED(hr))
{
pWc->SetVideoClippingWindow(hwndApp);
*ppWc = pWc; // The caller must release this interface.
}
}
pVmr->Release();
// Now the VMR can be connected to other filters.
return hr;
}
関連トピック