我使用GMFBridge.DLL正确预览/捕获流吗?

我正在尝试使用GMFBuilder,以便我可以预览来自网络摄像头的流并定期保存,而无需重新启动整个图形。 但是,我不确定这是否正确,我试图按照示例,但代码已更新,事情已发生变化。

我试着创造:

WEbcam -> Smart Tee (preview) -> AVI Decompressor -> Video Renderer Smart Tee (Capture) -> BridgeSinkFilter 

并且:

 BridgeSourceFilter -> ffdshow video encoder -> haali mastroska muxer 

(只是因为它易于使用)

关于让代码正常运行的输入将非常感激。

  private void button2_Click(object sender, EventArgs e) { IGraphBuilder firstGraph = (IGraphBuilder)new FilterGraph(); IGraphBuilder secondGraph = (IGraphBuilder)new FilterGraph(); IBaseFilter BridgeSinkFilter; IBaseFilter BridgeSourceFilter; IBaseFilter Source; IBaseFilter Mux; IBaseFilter FileWriter; IGMFBridgeController bridge = (IGMFBridgeController)new GMFBridgeController(); bridge.AddStream(1, eFormatType.eMuxInputs, 1); BridgeSinkFilter = (IBaseFilter)bridge.InsertSinkFilter(firstGraph); Source = FindFilter(FilterCategory.VideoInputDevice, "SG330"); firstGraph.AddFilter(Source, "source"); IBaseFilter SmartTee = FindFilter(FilterCategory.LegacyAmFilterCategory, "Smart Tee"); firstGraph.AddFilter(SmartTee, "Smart Tee"); IPin pinin, pinout; pinout = FindPinByDirection( Source, PinDirection.Output); pinin = FindPinByDirection( SmartTee, PinDirection.Input); firstGraph.Connect(pinout, pinin); pinout = FindPinByDirection(SmartTee, PinDirection.Output); pinin = FindPinByDirection(BridgeSinkFilter, PinDirection.Input); firstGraph.Connect(pinout, pinin); IBaseFilter Decomp = FindFilter(FilterCategory.LegacyAmFilterCategory, "AVI Decompressor"); firstGraph.AddFilter(Decomp, "Avi Decompressor"); pinout = FindPinByDirection(SmartTee, PinDirection.Output); pinin = FindPinByDirection(Decomp, PinDirection.Input); firstGraph.Connect(pinout, pinin); IBaseFilter Renderer = FindFilter(FilterCategory.LegacyAmFilterCategory, "Video Renderer"); firstGraph.AddFilter(Renderer, "Video Renderer"); pinout = FindPinByDirection(Decomp, PinDirection.Output); pinin = FindPinByDirection(Renderer, PinDirection.Input); firstGraph.Connect(pinout, pinin); DsROTEntry g = new DsROTEntry(firstGraph); BridgeSourceFilter = (IBaseFilter)bridge.InsertSourceFilter(BridgeSinkFilter, secondGraph); DsROTEntry h = new DsROTEntry(secondGraph); IBaseFilter Muxe = FindFilter(FilterCategory.VideoCompressorCategory, "ffdshow video encoder"); secondGraph.AddFilter(Muxe, "Mux"); pinout = FindPinByDirection(BridgeSourceFilter, PinDirection.Output); pinin = FindPinByDirection(Muxe, PinDirection.Input); secondGraph.Connect(pinout, pinin); IBaseFilter MKV = FindFilter(FilterCategory.LegacyAmFilterCategory, "Haali Matroska Muxer"); IFileSinkFilter fs = (IFileSinkFilter)MKV; fs.SetFileName("c:\\cool.mkv", null); secondGraph.AddFilter(MKV, "mux"); pinout = FindPinByDirection(Muxe, PinDirection.Output); pinin = FindPinByDirection(MKV, PinDirection.Input); secondGraph.Connect(pinout, pinin); bridge.BridgeGraphs(BridgeSinkFilter, BridgeSourceFilter); IMediaControl mediacontrolforpartone = (IMediaControl)firstGraph; mediacontrolforparttwo = (IMediaControl)secondGraph; mediacontrolforpartone.Run(); mediacontrolforparttwo.Run(); } 

根据我目前的知识正确使用GMFBridge:

从以下网站获取GMFBridge DLL: http ://www.gdcl.co.uk/gmfbridge/从以下url获取DirectShowLib DLL: https ://sourceforge.net/projects/directshownet/files/DirectShowNET/

将它们包含在您的项目中。

创建2个图表。 1用于预览,第2个用于捕获。

 IGraphBuilder firstgraph = (IGraphBuilder) new FilterGraph(); IGraphBuilder secondgraph = (IGraphBuilder) new FilterGraph(); 

创建一个来自GMFBridge DLL的桥,将连接两个图

 IGMFBridgeController Bridge = (IGMFBridgeController) new GMFBridgeController(); 

从这里开始设置桥接器以允许多路复用输入

 Bridge.AddStream(1, eFormatType.eMuxInputs, 1); 

从这里您可以添加源videofilter,它不需要连接到网桥,添加Smart Tee,并将源连接到Smart Tee。

然后创建一个filter来容纳将完成工作的第一个桥接filter

 BridgeSinkFilter = (IBaseFilter)Bridge.InsertSinkFilter(firstgraph); 

此滤波器将连续接受来自Smart Tee捕获引脚的video。 如果第二个图桥接filter已连接并正在运行,它会将video从BridgeSInkFilter传递到第二个图形。 否则,它只会抛出它,但它总是在运行。

将BridgeSinkFilter连接到Smart Tee的捕获引脚。 我发现连接引脚的最佳方法是通过https://splicer.svn.codeplex.com/svn/src/Splicer/Utilities/FilterGraphTools.cs使用FindPinByDirection,然后调用

 firstgraph.connect(pinoutput, pininput) 

从这里开始,要预览video,应添加FilterCategory.LegacyAmFilterCategory中的AVI Decompressorfilter,并将其连接到Smart Tee的预览引脚。 然后Video Renderer添加并连接到AVI Decompressor。

那应该照顾第一张图。

第二个图需要从桥开始。 它将从第一个图形bridgesinkfilter创建一个桥梁,并将其拉到第二个图形,我们可以在其中执行任何我们想要的任务。 要做到这一点,我们需要桥梁的另一面。

 IBaseFilter BridgeSourceFilter = (IBaseFilter)Bridge.InsertSourceFilter(BridgeSinkFilter,secondgraph); 

这将源设置为第一段中的sinkfilter,但是在BridgeSourceFilter的幌子下将其放在我们的第二个图上。

现在连接编码器,ffdshowvideo编码器等。将它连接到BridgeSourceFilter。

添加多路复用器,AVI Mux和文件编写器。 连接他们。 那是第二张图的一切。

要完成图形关闭,我们需要创建2个可以启动和停止图形的mediacontrollers。

 IMediaControl MediaControl_FirstGraph = (IMediaControl)firstgraph; IMediaControl MediaControl_SecondGraph = (IMediaControl)secondgraph; 

现在我们可以打电话

 MediaControl_FirstGraph.Run() to start previewing the video. 

然后要捕获该video,我们需要连接第一个和第二个图之间的桥,然后运行第二个图。

 Bridge.BridgeGraphs(BridgeSinkFilter,BridgeSourceFilter); MediaControl_SecondGraph.Run() 

在任何时候,您都可以通过断开桥接连接来停止捕获,然后停止第二个图形。

 Bridge.BridgeGraphs(null, null); MediaControl_SecondGraph.Stop(); 

我认为这涵盖了我发现的关于GMF桥梁控制:)

希望这取决于Geraint Davies的标准

如果第二个图形中的任何位置都有最轻微的错误,当您运行第二个图形时,它将停止第一个图形。 这是一个很好的迹象。 如果你给它一个无效的名称,比如制作Avi mux – >文件编写器尝试保存在一个不真实的位置,它会停止图形

此代码将创建一个新窗口并将video粘贴到新窗口中。 要将video流式传输到表单的面板框中,您只需要添加4行代码。

 IVideoWindow var = firstgraph as IVideoWindow(); var.put_Owner(panel1.handle); var.put_windowstyle( windowstyle.child | windowstyle.clipchildren ); var.SetWindowPosition( panel1.clientrectangle.left, panel1.clientrectangle.top, panel1.clientrectangle.width, panel1.clientrectangle.height);