簡體   English   中英

將DirectShow視頻窗口附加到WPF控件

[英]Attach DirectShow video window to WPF Control

我正在使用DirectShow.NET為WPF創建一個Web攝像頭控件。 我已經成功創建了一個圖表,可以從相機中獲取視頻以顯示在我的屏幕上。 但是,視頻輸出完全獨立於正在創建的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視頻窗口和WPF MainWindow控件

特別是在窗口模式下運行的視頻渲染器(同樣適用於無窗口)要求您提供有效的HWND窗口句柄,以便視頻可以與標准UI准確集成。 您的SetupVideoWindow代碼片段正在完成視頻“作為子控件”的初始化。

WPF是一種新的UI概念,它不需要為每個UI控件創建窗口句柄,並且沒有明確和直接的屬性來請求句柄以傳遞給VMR初始化。 因此,除了有效句柄之外,正確使用的WindowInteropHelper一旦實際分配就可用,這不是表單構造函數。

使用零句柄指示視頻渲染器將視頻發送到桌面窗口,您所看到的行為是可預期且易於理解的。

您需要使用調試器檢查句柄值,如果它為零,則將配置代碼移動到表單構造的稍后階段。 設置時非零有效窗口句柄應將視頻放在適當的位置。

據我所知,DirectShow使用直接視頻內存訪問在屏幕上呈現內容以獲得最佳性能,因此很可能是this.videoWindow.SetWindowPosition(0, 0, (int)this.Width, (int)this.Height); 需要在屏幕坐標。

即你需要在屏幕上獲取托管WPF窗口的位置和它的大小(使用WinApi),並傳遞給SetWindowPosition方法。 當你的窗口移動/調整大小時,每次都這樣做。

很抱歉沒有完整的答案(沒有提供確切的代碼來解決問題),因為我多年前在C ++中使用WinApi完成了這項工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM