C# IVMRWindowlessControl9未呈现到父WPF窗口中

C# IVMRWindowlessControl9未呈现到父WPF窗口中,c#,wpf,video,directshow,directshow.net,C#,Wpf,Video,Directshow,Directshow.net,我正在使用DirectShow.NET创建网络摄像头控件。我想将相机的视频渲染到WPF窗口中。当前发生的情况是,IVMRWindowlessControl9似乎没有进入无窗口模式,并且没有成为我指定的窗口的父窗口,即使我正在调用适当的方法 为什么不调用这些方法?还有什么我没有做的吗 以下是相关代码的片段: IGraphBuilder graphBuilder = (IGraphBuilder) new FilterGraph(); ICaptureGraphBuilder2 captureGra

我正在使用DirectShow.NET创建网络摄像头控件。我想将相机的视频渲染到WPF窗口中。当前发生的情况是,
IVMRWindowlessControl9
似乎没有进入无窗口模式,并且没有成为我指定的窗口的父窗口,即使我正在调用适当的方法

为什么不调用这些方法?还有什么我没有做的吗

以下是相关代码的片段:

IGraphBuilder graphBuilder = (IGraphBuilder) new FilterGraph();
ICaptureGraphBuilder2 captureGraphBuilder = (ICaptureGraphBuilder2)new CaptureGraphBuilder2();            
IMediaControl mediaControl = (IMediaControl) this.graphBuilder;
IBaseFilter renderFilter = (IBaseFilter) new VideoMixingRenderer9();

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

IBaseFilter sourceFilter = FindCaptureDevice();

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

SetCaptureResolution();

IVMRFilterConfig9 filterConfig = (IVMRFilterConfig9)renderFilter;

hr = filterConfig.SetNumberOfStreams(1);
DsError.ThrowExceptionForHR(hr);

hr = filterConfig.SetRenderingMode(VMR9Mode.Windowless);
DsError.ThrowExceptionForHR(hr);

windowlessControl = (IVMRWindowlessControl9)renderFilter;

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

Window window = Window.GetWindow(this);
var wih = new WindowInteropHelper(window);
IntPtr hWnd = wih.Handle;
hr = windowlessControl.SetVideoClippingWindow(hWnd);
DsError.ThrowExceptionForHR(hr);

hr = windowlessControl.SetAspectRatioMode(VMR9AspectRatioMode.LetterBox);
DsError.ThrowExceptionForHR(hr);

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

Marshal.ReleaseComObject(sourceFilter);

hr = this.mediaControl.Run();
DsError.ThrowExceptionForHR(hr);
下面是正在发生的事情的图像(我将背景设置为绿色以便于查看):

这是过滤器图的示意图:

要回答一个潜在的问题(因为我以前遇到过这个问题),是的,
hWnd
正在设置/有一个值-因此windowlessControl确实有一个指向窗口的指针

运行过滤器图形时创建的弹出窗口“ActiveMovie Window”是视频渲染器过滤器插入管道并以默认模式运行的症状,而未配置为其他UI的一部分:嵌入为子窗口等

将图表反转可以清楚地了解正在发生的事情:

插入并设置一个视频渲染器过滤器,然后API添加另一个并连接到输入。当第一个嵌入到用户界面时,它保持空闲,另一个将视频渲染到弹出窗口中

给出问题的代码行是:

hr = this.captureGraphBuilder.RenderStream(PinCategory.Capture,
    MediaType.Video, sourceFilter, null, null);
问题是对于那些通过插入视频渲染器并期望它们被拾取和连接来构建图形的人来说,尤其是它有时可以工作,并且这样的代码片段可以在线找到的人

MSDN说:

如果pSink参数为NULL,则该方法将尝试使用默认渲染器对于视频,它使用视频渲染器,对于音频,它使用DirectSound渲染器

该调用添加了另一个实例,您希望连接现有实例。虽然
RenderStream
是一个功能强大的调用,它可以通过过滤魔法将事情连接起来,但很容易以错误的方式结束

如果您已经有了视频渲染器,则可以在此调用中将其用作sink参数。或者,您可以避免使用
RenderStream
,并逐步添加所需的过滤器,以确保所有内容都按照您的期望构建。或者,另一个选项是调用
AM\u RENDEREX\u rendertoexistingrenders
标志:

…该方法尝试使用过滤器图中已有的渲染器它不会向图形中添加新的渲染器。(如果需要,它将添加中间变换过滤器。)要使方法成功,图形必须包含适当的渲染器,并且它们必须具有未连接的输入端号


SetNumberOfStreams
可能太早,
SetRenderingMode
应该。ActiveMovie窗口表示未设置视频渲染器。您的有效过滤器图可能不是您所期望的。看见具体来说,您的有效图可能有两个渲染器。@RomanR.-下面是我在应用程序运行时捕获的过滤器图图像的链接。这看起来正常吗?我使用了渲染过滤器作为sink参数。它似乎已经创建了预期的图形,但是,我没有在窗口中显示视频。不再有
ActiveMovie窗口
,但网络摄像头视频不会出现在窗口中。这就是我添加渲染过滤器的方式:
hr=This.captureGraphBuilder.RenderStream(PinCategory.Capture,MediaType.Video,sourceFilter,null,renderFilter)这是窗口外观的图像:。这是新捕获图的图像:。是否使用来定位渲染器?我在上面的代码中没有看到这一点。此外,您还可以更新您的问题(特别是插入图像)。出于某种原因,我认为
IVMRWindowlessControl9
不需要SetVideoPosition()。但这确实奏效了。最后,我的过滤图设置不正确,需要设置视频位置。