我使用的GMFBridge.DLL预览/正确捕获流? [英] Am I using the GMFBridge.DLL to preview/capture a stream correctly?

查看:632
本文介绍了我使用的GMFBridge.DLL预览/正确捕获流?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图用GMFBuilder,这样我可以预览一个摄像头流并定期保存它,无需重新启动整个图。但林不知道这是否正确与否,我试图遵循的例子,但这些代码被更新,一切都变了。



我尝试创建:

 网络摄像头 - >智能T恤(预览) -  GT; AVI解压缩 - >视频渲染器
智能T恤(捕获) - GT; BridgeSinkFilter

和也:

  BridgeSourceFilter  - > ffdshow的视频编码器 - > Haali的mastroska复用器



(只是导致其易于使用)



关于获取代码正常运行将不胜感激输入。

 私人无效button2_Click(对象发件人,EventArgs E)
{
IGraphBuilder firstGraph =(IGraphBuilder)FilterGraph动态新();
IGraphBuilder secondGraph =(IGraphBuilder)FilterGraph动态新();

IBaseFilter BridgeSinkFilter;
IBaseFilter BridgeSourceFilter;

IBaseFilter来源;
IBaseFilter复用;
IBaseFilter FileWriter的;

IGMFBridgeController桥=(IGMFBridgeController)新GMFBridgeController();

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

BridgeSinkFilter =(IBaseFilter)bridge.InsertSinkFilter(firstGraph);

来源= FindFilter(FilterCategory.VideoInputDevice,SG330);
firstGraph.AddFilter(资料来源,源);

IBaseFilter SmartTee = FindFilter(FilterCategory.LegacyAmFilterCategory,智能T恤);
firstGraph.AddFilter(SmartTee,智能T恤);

宜宾PININ,引出线;

引脚= FindPinByDirection(资料来源,PinDirection.Output);
PININ = FindPinByDirection(SmartTee,PinDirection.Input);

firstGraph.Connect(引脚,PININ);
引脚= FindPinByDirection(SmartTee,PinDirection.Output);
PININ = FindPinByDirection(BridgeSinkFilter,PinDirection.Input);

firstGraph.Connect(引脚,PININ);

IBaseFilter分解所= FindFilter(FilterCategory.LegacyAmFilterCategory,AVI解压缩);
firstGraph.AddFilter(分解,阿维解压缩);

引脚= FindPinByDirection(SmartTee,PinDirection.Output);
PININ = FindPinByDirection(分解,PinDirection.Input);

firstGraph.Connect(引脚,PININ);

IBaseFilter渲染= FindFilter(FilterCategory.LegacyAmFilterCategory,视频渲染器);
firstGraph.AddFilter(渲染器,视频渲染器);

引脚= FindPinByDirection(分解,PinDirection.Output);
PININ = FindPinByDirection(渲染,PinDirection.Input);

firstGraph.Connect(引脚,PININ);

DsROTEntry G =新DsROTEntry(firstGraph);

BridgeSourceFilter =(IBaseFilter)bridge.InsertSourceFilter(BridgeSinkFilter,secondGraph);
DsROTEntry H =新DsROTEntry(secondGraph);

IBaseFilter Muxe = FindFilter(FilterCategory.VideoCompressorCategory,ffdshow的视频编码器);
secondGraph.AddFilter(Muxe复用器);

引脚= FindPinByDirection(BridgeSourceFilter,PinDirection.Output);
PININ = FindPinByDirection(Muxe,PinDirection.Input);

secondGraph.Connect(引脚,PININ);

IBaseFilter MKV = FindFilter(FilterCategory.LegacyAmFilterCategory,Haali的Matroska的MUXER);
IFileSinkFilter FS =(IFileSinkFilter)MKV;
fs.SetFileName(C:\\cool.mkv,NULL);

secondGraph.AddFilter(MKV,MUX);

引脚= FindPinByDirection(Muxe,PinDirection.Output);
PININ = FindPinByDirection(MKV,PinDirection.Input);
secondGraph.Connect(引脚,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/
抓住DirectShowLib DLL:的 https://sourceforge.net/projects/directshownet/files/DirectShowNET/



在包括他们两个你项目。



创建2个图表。 1是预览第二是捕获

  IGraphBuilder firstgraph =(IGraphBuilder)FilterGraph动态新(); 
IGraphBuilder secondgraph =(IGraphBuilder)FilterGraph动态新();



创建一个桥,从GMFBridge DLL,将连接两个图

  IGMFBridgeController桥=(IGMFBridgeController)新GMFBridgeController(); 



从这里,你设置的桥梁,允许多工输入

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



从这里可以添加源视频滤镜,它并不需要连接的桥梁,添加智能T恤,并连接源智能T恤。



然后创建一个过滤器,以容纳第一桥过滤器,将做的工作。

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

这过滤器会不断地从智能T恤的捕捉引脚接受视频。如果第二图表桥滤波器连接并运行它会从BridgeSInkFilter视频传递到第2个曲线图。否则,它只是抛出它,但它一直在运行。



BridgeSinkFilter连接到智能T恤的捕捉引脚。
我发现连接销的最好方式是通过的 https://splicer.svn.codeplex.com/svn/src/Splicer/Utilities/FilterGraphTools.cs 然后就叫

  firstgraph.connect(pinoutput,pininput)

从这里,预览视频中,从FilterCategory.LegacyAmFilterCategory的AVI解压缩过滤器应addedd并连接到智能T恤的预览引脚。然后,视频渲染器添加并连接到AVI解压缩。



这应该照顾的第一个图形。



第二图表需要开始与桥。它会创建第一个图bridgesinkfilter的桥梁,它拉来的第二图表中,我们可以做任何事情,我们希望把它。要做到这一点,我们需要在桥的另一端。

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

这集源从firstgraph的sinkfilter而是假借把它放在我们的第二个图BridgeSourceFilter。



现在连接一个编码器,ffdshow的视频编码器等。
将它连接到BridgeSourceFilter。



添加一个复用器,AVI多路复用器和文件作家。连接它们。那是一切为了第二个图形。



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

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

现在我们可以称之为

  MediaControl_FirstGraph.Run()开始预览视频。 

和然后以捕获视频,我们需要连接在第一和第二图形之间的桥梁,然后。运行第二个图

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



在任何时候,你可以停止通过打破捕捉桥。连接,然后停止第二幅图

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



我认为,大约涵盖了什么香港专业教育学院发现了关于GMF桥控制:)



但愿这是达杰兰特戴维斯的标准



如果有第二图随时随地哪怕是一丁点的错误,当您运行第二图,它将停止第一张图。它很好地说明什么是错的。如果你给它一个无效的名称,如使阿维多路转换器 - >文件写入尝试在心不是真正的保存位置,ITLL停止图



此代码将创建一个新的窗口并坚持视频在新窗口。要流视频到一个窗体的面板中,您真的很需要添加4行代码。

  IVideoWindow VAR = firstgraph为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);


I am trying to use the GMFBuilder so that i can preview a stream from a webcam and save it periodically without restarting the whole graph. However Im not sure if this is correct or not, I was trying to follow examples but the codes been updated and things have changed.

I try and create:

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

and also:

BridgeSourceFilter -> ffdshow video encoder -> haali mastroska muxer 

(just cause its easy to use)

Input regarding getting the code to run properly would be greatly appreciated.

    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();

    }

解决方案

To use GMFBridge correctly to my current knowledge:

Grab the GMFBridge DLL from: http://www.gdcl.co.uk/gmfbridge/ Grab the DirectShowLib DLL from: https://sourceforge.net/projects/directshownet/files/DirectShowNET/

include them both in your project.

Create 2 graphs. 1 is for preview the 2nd is for capture.

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

Create a Bridge which from the GMFBridge dll, will connect the two graphs

IGMFBridgeController Bridge = (IGMFBridgeController) new GMFBridgeController();

From here you setup the bridge to allow for muxed inputs

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

from here you can add your source video filter, it doesnt need connected to the bridge, add Smart Tee, and connect source to Smart Tee.

then create a filter to house the first bridge filter that will do the work

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

This filter will continuously accept video from the capture pin of Smart Tee. If the 2nd graph bridge filter is connected and running it will pass the video from BridgeSInkFilter to the 2nd graph. otherwise, it just throws it out, but it is always running.

Connect the BridgeSinkFilter to the capture pin of Smart Tee. I found the best way to connect the pins is to use FindPinByDirection by https://splicer.svn.codeplex.com/svn/src/Splicer/Utilities/FilterGraphTools.cs and then just call

firstgraph.connect(pinoutput, pininput)

From here, to preview the video, the AVI Decompressor filter from FilterCategory.LegacyAmFilterCategory should be addedd and connected to the Preview pin of Smart Tee. Then Video Renderer added and connected to AVI Decompressor.

That should take care of the first graph.

The second graph needs to start with the bridge. it will create a bridge from the first graph bridgesinkfilter and pull it to a second graph in which we can do anything we want to it. to do this we need the other side of the bridge.

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

this sets the source as the sinkfilter from the firstgraph but puts it on our second graph under the guise of BridgeSourceFilter.

Now connect an encoder, ffdshow video encoder, etc.. connect it to the BridgeSourceFilter.

add in a muxer, AVI Mux, and file writer. Connect them. Thats everything for the second graph.

To finish the graphs off, we need to create 2 mediacontrollers that can start and stop the graphs.

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

now we can call

MediaControl_FirstGraph.Run() to start previewing the video.

and then to capture that video, we need to connect the bridge between the first and second graph, then run the second graph.

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

at any point, you can stop capturing by breaking the bridge connection, then stopping the second graph.

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

I think that about covers what ive found out about GMF bridge control :)

Hopefully this is up to Geraint Davies's standards

if there is even the slightest error anywhere in the second graph, when you run the second graph, it will stop the first graph. its a good indication something is wrong. If you give it an invalid name like making Avi mux -> file writer try to save in a location that isnt real, itll stop the graph

This code would create a new window and stick the video in that new window. To stream the video into a panel box of a form you just really need to add 4 lines of code.

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);    

这篇关于我使用的GMFBridge.DLL预览/正确捕获流?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆