2016-09-20 4 views
3

私はDirectShow.NETを使用してWPF用のWebカメラコントロールを作成しています。私は正常にグラフを作成し、私の画面に表示するためにカメラからビデオを得ることができます。ただし、ビデオ出力は、作成中のWPFコントロールとは完全に独立しています。videoWindow.put_owner(hWnd)を呼び出すことによってビデオウィンドウのオーナーを設定しています。現在のWPFウィンドウのウィンドウハンドルはhWndです。 WindowInteropHelperを使用してそのウィンドウハンドルを取得します。ここでDirectShowビデオウィンドウをWPFコントロールに接続する

は、メインルーチンである:

public void CaptureVideo() 
     { 
      int hr = 0; 
      IBaseFilter sourceFilter = null; 

      try 
      { 
       hr = this.captureGraphBuilder.SetFiltergraph(this.graphBuilder); 
       DsError.ThrowExceptionForHR(hr); 

       sourceFilter = FindCaptureDevice(); 

       hr = this.graphBuilder.AddFilter(sourceFilter, "Video Capture"); 
       DsError.ThrowExceptionForHR(hr); 

       hr = this.captureGraphBuilder.RenderStream(PinCategory.Preview, MediaType.Video, sourceFilter, null, null); 
       DsError.ThrowExceptionForHR(hr); 

       Marshal.ReleaseComObject(sourceFilter); 

       SetupVideoWindow(); 

       hr = this.mediaControl.Run(); 
       DsError.ThrowExceptionForHR(hr); 
      } 
      catch 
      { 
       Console.WriteLine("An unrecoverable DirectShow error has occurred."); 
      } 
     } 

そしてSetupVideoWindowのコード():ここで

public void SetupVideoWindow() 
     { 
      int hr = 0; 

      Window window = Window.GetWindow(this); 
      var wih = new WindowInteropHelper(window); 
      IntPtr hWnd = wih.Handle; 

      hr = this.videoWindow.put_Owner(hWnd); 
      DsError.ThrowExceptionForHR(hr); 

      hr = this.videoWindow.put_WindowStyle(DirectShowLib.WindowStyle.Child | DirectShowLib.WindowStyle.ClipChildren); 
      DsError.ThrowExceptionForHR(hr); 

      this.videoWindow.SetWindowPosition(0, 0, (int)this.Width, (int)this.Height); 

      hr = this.videoWindow.put_Visible(OABool.True); 
      DsError.ThrowExceptionForHR(hr); 
     } 

は何が起こっているかの画像です: DirectShow.NET Video Window and WPF MainWindow Control

+0

最後の 'RenderStream'呼び出し引数は意味をなさない。また、あなたの 'hWnd'がゼロ/ヌルで、動作を説明するようになるかもしれません。 @RomanR。 –

+0

ああ、私はちょうどいくつかのことを試していたし、間違ったコードをコピーしたようだ。私は上記の結果を生成するために使用している実際のコードを反映するように編集した。私はWPFを使用しているので、hWndがゼロ/ヌルである可能性はありますか?それは、私がオンラインで探している唯一の答えです。 –

+0

デバッグして、 'hWnd'が非ゼロであることを確認できますか? 0の場合、動作はかなり期待されます(ただし、あなたが望むものではありません)。おそらく、ハンドルが存在する(割り当てられた)前に、あなたは早すぎてそれを設定しているでしょう。 @RomanR。 –

答えて

2

ウィンドウレンダリングモードで特に動作するビデオレンダラ(ウィンドウレスの場合と同じ)は、有効なHWNDウィンドウハンドルを用意して、ビデオを標準UIと正確に統合できるようにする必要があります。 SetupVideoWindowコードスニペットでは、動画の初期化が「子コントロールとして」行われています。

WPFは、UIコントロールごとにウィンドウハンドルを作成する必要はなく、VMRの初期化に渡すためのハンドルを要求する明確で直接的なプロパティはありません。したがって、有効なハンドルが、実際に割り当てられるとすぐに使用可能であることを除いて、正しく使用するWindowInteropHelperがフォームコンストラクタではありません。

ゼロ・ハンドルを使用すると、ビデオ・レンダラはデスクトップ・ウィンドウにビデオを送信し、表示されている動作は予期され理解できるものです。

デバッガでハンドル値をチェックする必要があります。ゼロの場合は、設定コードをフォーム構築の後の段階に移動します。セットアップ時に有効でない有効なウィンドウハンドルは、ビデオを配置する必要があります。

0

限りDirectShowは直接ビデオメモリアクセスを使用して、最高のパフォーマンスを得るために画面上にコンテンツを表示することを覚えています。したがって、おそらくthis.videoWindow.SetWindowPosition(0, 0, (int)this.Width, (int)this.Height);は画面座標にする必要があります。

I.e.あなたはWPFウインドウの位置をスクリーン上に取得する必要があり、そのサイズはWinApiを使用してSetWindowPositionメソッドに渡されます。ウィンドウを移動/サイズ変更するたびに毎回行います。

申し訳ありませんが、私はWinApiを使用してC++で長年行ってきたため、問題を解決するためのコードはありません。

関連する問題