SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

特集記事

Enhanced Video Rendererを使ってみよう

DirectShowからEVRを使って動画再生を行うアプリケーションの制作

ダウンロード サンプルコード (17.9 KB)

標準プレゼンタのカスタマイズ

 EVRをアプリケーションで作成したウィンドウに表示するようにします。そのために、EVRの標準プレゼンタのインターフェイスを取得し、ウィンドウハンドルを設定します。

 まず、EVRからIMFGetServiceインターフェイスを取得します。そして、IMFGetService::GetServiceを使って標準プレゼンタのIMFVideoDisplayControlインターフェイスを取得します。IMFVideoDisplayControl::SetVideoWindowでウィンドウハンドルを指定します。

 次に、IMFVideoDisplayControl::SetVideoPositionを使って転送元矩形と転送先矩形を指定します。転送元矩形はMFVideoNormalizedRect構造体で指定するのですが、ピクセル単位ではなく、左上が(0,0)、右下が(1,1)となることに注意して下さい。

CComPtr<IMFVideoDisplayControl> m_Vdc;
CComQIPtr<IMFGetService> service(m_Evr);
hr=service->GetService(MR_VIDEO_RENDER_SERVICE,
	IID_IMFVideoDisplayControl, (void**)&m_Vdc);
hr=m_Vdc->SetVideoWindow(m_hWnd);
MFVideoNormalizedRect mvnr={0, 0, 1, 1};
RECT rect;
GetClientRect(&rect);
hr=m_Vdc->SetVideoPosition(&mvnr, &rect);

ウォーターマークの作成と適用

 動画をウィンドウに表示できるようになったので、続いてウォーターマークを作成し、適用しましょう。

 ウォーターマークはGDIのビットマップまたはDirect3D9サーフェイスを用意しておき、それをビデオフレームに合成することによって実現します。今回はGDIのビットマップを用意し、TextOut Win32 APIで「Use EVR with WaterMark」という文字列を描画したウォーターマークをEVRに割り当てます。

 まず、IMFGetService::GetServiceを使ってIMFVideoMixerBitmapインターフェイスを取得します。

hr=service->GetService(MR_VIDEO_MIXER_SERVICE,
	IID_IMFVideoMixerBitmap, (void**)&m_MixerBitmap);

 次に、用意したビットマップをEVRに割り当てます。そのためにMFVideoAlphaBitmap構造体でどのように合成するか指定し、IMFVideoMixerBitmap::SetAlphaBitmapを呼び出します。MFVideoAlphaBitmapはMFVideoAlphaBitmapParamを包含しています(表1、表2)。

表1. MFVideoAlphaBitmap 構造体
型 メンバ変数名 内容
BOOL GetBitmapFromDC TRUEであればhdcメンバが有効。FALSEであればpDDsメンバが有効。つまりウォーターマークとしてGDIビットマップを使うかDirect3D9サーフェイスを使うか。
HDC hdc ウォーターマークとなるGDIビットマップのデバイスコンテキスト。
IDirect3DSurface9 pDDs ウォーターマークとなるDirect3D9サーフェイス。
MFVideoAlphaBitmapParams params MFVideoAlphaBitmapParams構造体。
表2. MFVideoAlphaBitmapParam 構造体
型 メンバ変数名 内容
DWORD dwFlags MFVideoAlphaBitmapFlagsの組み合わせで、どの構造体メンバが有効かを示す。
COLORREF clrSrcKey ソースカラーキー。
RECT rcSrc 転送元矩形。
MFVideoNormalizedRect nrcDest 転送先矩形。
FLOAT fAlpha 透明度。0で完全に透明。1.0で不透明。
DWORD dwFilterMode Direct3Dのフィルタリングモード。D3DTEXTUREFILTERTYPEで指定する。
// HDC hdcBmp ウォーターマークを描くためのデバイスコンテキスト
// HBITMAP m_WaterMarkBmp ウォーターマークが描かれるビットマップハンドル
MFVideoAlphaBitmap bmpInfo={0};
ZeroMemory(&bmpInfo, sizeof(bmpInfo));
bmpInfo.GetBitmapFromDC=TRUE;
bmpInfo.bitmap.hdc=hdcBmp;
bmpInfo.params.clrSrcKey=0;
bmpInfo.params.dwFlags=
    MFVideoAlphaBitmap_Alpha | MFVideoAlphaBitmap_DestRect |
    MFVideoAlphaBitmap_SrcColorKey;
bmpInfo.params.fAlpha=0.8f;
MFVideoNormalizedRect dst={0, 0, 1.0f, 0.25f};
bmpInfo.params.nrcDest=dst;
BITMAP bm;
GetObject(m_WaterMarkBmp, sizeof(BITMAP), &bm);
SetRect(&bmpInfo.params.rcSrc, 0, 0, bm.bmWidth, bm.bmHeight);
hr=m_MixerBitmap->SetAlphaBitmap(&bmpInfo);

再描画とリサイズの処理

 ウィンドウが再描画されたり、リサイズされたりしたときは、それをEVRのプレゼンタに伝える必要があります。再描画のときはRepaintVideo、リサイズのときはSetVideoPositionを呼び出します。

LRESULT CMyWindow::OnPaint(UINT, WPARAM, LPARAM, BOOL&) {
	m_Vdc->RepaintVideo();
	return DefWindowProc();
}

LRESULT CMyWindow::OnSize(UINT, WPARAM, LPARAM, BOOL&) {
	MFVideoNormalizedRect mvnr={0, 0, 1, 1};
	RECT rect;
	GetClientRect(&rect);
	m_Vdc->SetVideoPosition(&mvnr, &rect);
	return 0;
}

動作確認

 それでは動作を確認してみましょう。適当な動画ファイルを用意して再生してみます。サンプルコードでは、USE_EVR1.cppに直接ファイル名を指定しているので適当に書き換えてください。

 アプリケーションを実行すると、ウィンドウが表示され、半透明のウォーターマークとともに動画が表示されます(図2)。

図2. 動作結果
図2

まとめ

 本稿では、EVRの概要について説明し、動画を再生するアプリケーションを作成しました。また、GDIビットマップを用意し、ウォーターマークとして合成しました。

 「EVRの概要」でも述べたように、EVRはMedia FoundationとDirectShow両方で使うことができます。Media FoundationはWindows 7で機能強化され、DirectShowに代わるマルチメディアプラットフォームとなっていくと思われますが、ゼロからMedia Foundationを始めると覚えることが多くて大変です。まずはEVRを使ってみるところから始めてみてはいかがでしょうか。

参考資料

  1. Enhanced Video Renderer

この記事は参考になりましたか?

連載通知を行うには会員登録(無料)が必要です。
既に会員の方はを行ってください。
特集記事連載記事一覧

もっと読む

この記事の著者

syu5()

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/3663 2009/06/12 14:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー