Media Foundation ⑥ WebCam + WPF XAMLとC#の実装

それでは XAMLとC#を実装しましょう。次のようにビデオ画像と、スライダーで回転・スケールを行うので、XAMLではD3DImageと2つのスライダー(とラベル)を宣言します。一つのスライダーはD3DImageの回転角度に、もう一つはD3DImageのXScaleとYScaleにバインディングします。

D3DImageはSystem.Windows.Interop名前空間にあるので、名前空間の追加に注意してください。

image

C#の実装

D3DImage チュートリアルとの違いは、初期化時にビデオのサイズを取得していることと、Rendering イベントハンドラーとコールバックを宣言する代わりに、Windows メッセージを処理するためのコールバック(ここではBltVideo)を HWndSourceクラスのAddHookメソッドを使って宣言することです。そのあとで一回目の非同期サンプリング命令(Sample)を呼び出します。

 

 

 

 

private readonly D3DWrapper myD3DScene = new D3DWrapper();
private HwndSource source;
private const int WM_PAINT = 0x000F;
private int videoWidth = 0;
private int videoHeight = 0;

...

 

 

 

private void StartDXRendering()
{
 if (!myD3DImage.IsFrontBufferAvailable)
  return;
IntPtr scene = myD3DScene.Initialize(
  new WindowInteropHelper(this).Handle,
  ref videoWidth,
  ref videoHeight);
myD3DImage.Lock();
myD3DImage.SetBackBuffer(
D3DResourceType.IDirect3DSurface9, scene);
  myD3DImage.Unlock();
source = HwndSource.FromHwnd(
new WindowInteropHelper(this).Handle);

source.AddHook(new HwndSourceHook(BltVideo));
myD3DScene.Sample();

}

 

 

 

BltVideo では WM_PAINT メッセージかどうかを確認して、D3DImageの内容を更新します。そのあとで、メッセージの処理完了を示す handled を true にし、次の非同期サンプリング命令を呼び出します。

private IntPtr BltVideo( IntPtr hwnd, int msg, IntPtr wParam,
IntPtr lParam, ref bool handled)
{
  if (msg == WM_PAINT)
  {
    myD3DImage.Lock();
    myD3DImage.AddDirtyRect(
new Int32Rect(0, 0, videoWidth, videoHeight));
    myD3DImage.Unlock();
    handled = true;
    myD3DScene.Sample();
  }
  return IntPtr.Zero;
}

ソリューションを添付するので、WebCam のついた PC でビルド・実行してみてください。動作環境は以下の通りです。

  • Windows 7 (RC)
  • Windows 7 SDK (RC)
  • Visual Studio 2008 SP1
  • DirectX SDK (Mar 2009)

MFCaptureViewer.zip