SHOEISHA iD

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

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

特集記事

Enhanced Video Rendererを使ってみよう

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

  • X ポスト
  • このエントリーをはてなブックマークに追加

ダウンロード サンプルコード (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を呼び出します。MFVideoAlphaBitmapMFVideoAlphaBitmapParamを包含しています(表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

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

  • X ポスト
  • このエントリーをはてなブックマークに追加
特集記事連載記事一覧

もっと読む

この記事の著者

syu5()

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

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

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/3663 2009/06/12 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

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

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

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

メールバックナンバー

アクセスランキング

アクセスランキング