2016-09-20 101 views
3

我使用DirectShow.NET创建WPF Web摄像头的控制。我已经成功创建了一个图表,并可以从相机获取视频以显示在我的屏幕上。但是,视频输出完全独立于其正在创建的WPF控件。附加的DirectShow视频窗口WPF控件

我通过调用videoWindow.put_owner(hWnd)来设置视频窗口的所有者,其中hWnd是当前WPF窗口的窗口句柄。我使用WindowInteropHelper获得该窗口句柄。

这里是主程序:

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'是零/空这将解释行为。 –

+0

@RomanR。啊,是的,我只是在尝试一些东西,似乎我复制了错误的代码。我编辑它以反映我用来产生上述结果的实际代码。是否有可能hWnd是零/空,因为我使用的是WPF?这是我似乎在网上找到的唯一答案。 –

+0

那么,你能调试并确保'hWnd'不是零?对于零行为是相当期待的(但不是你想要的)。也许你在把柄存在(分配)之前设置得太早。 –

回答

2

专门以窗口模式操作的视频渲染器(同样适用于无窗口)需要您提供有效的HWND窗口句柄,以便视频可以与标准UI精确集成。您的SetupVideoWindow代码片段正在对视频进行初始化“作为子控件”。

WPF是那种不需要创建一个窗口句柄每个UI控制的新UI的概念,并没有明确和直接的财产,请求处理,以便传递给VMR初始化。因此,WindowInteropHelper正确使用,除非有效的句柄在实际分配后立即可用,而不是形式构造函数。

使用零手柄指示视频渲染器视频发送到桌面窗口和行为,你看到的是预期和理解的。

您需要调试器来检查句柄值,如果它是零,那么移动配置代码形式建设的一些后期阶段。在设置时非零有效的窗口句柄应该使视频就位。

0

至于我记得,DirectShow使用直接视频内存访问来呈现屏幕上的内容以获得最佳性能,所以最有可能的是this.videoWindow.SetWindowPosition(0, 0, (int)this.Width, (int)this.Height);需要在屏幕坐标。

I.e.你需要在屏幕上获得托管WPF窗口的位置和它的大小(使用WinApi),并传递给SetWindowPosition方法。每当你的窗口移动/调整大小时都要这样做。

对不起,不完整的答案(没有提供确切的代码来解决问题),因为我已经是很多年前做过C++与WINAPI。