繁体   English   中英

DirectShow.Net筛选器图形黑屏

[英]DirectShow.Net Filter Graph Black Screen

问题:为什么我的过滤器图在GraphEditPlus中起作用,但在我的程序中却不起作用?

嗨,大家好,我正在为Sony FCB-EV7500建立一个云台系统,但遇到了一些问题。 我刚刚购买了一个hauppauge巨像 ,将相机组件带到了我的电脑中。 经过数小时的尝试来弄清楚DirectShow的工作原理后,我终于得到了一个有效的过滤器图表。

筛选图1

C#代码如下所示:

 //graph builder
        ICaptureGraphBuilder2 pBuilder = (ICaptureGraphBuilder2)new CaptureGraphBuilder2();
        hr = pBuilder.SetFiltergraph(pGraph);
        checkHR(hr, "Can't SetFiltergraph");

        Guid CLSID_WDMStreamingCrossbars = new Guid("{A799A801-A46D-11D0-A18C-00A02401DCD4}");
        Guid CLSID_WDMStreamingCaptureDevices = new Guid("{65E8773D-8F56-11D0-A3B9-00A0C9223196}"); 
        Guid CLSID_WDMStreamingEncoderDevices = new Guid("{19689BF6-C384-48FD-AD51-90E58C79F70B}");
        Guid CLSID_ArcSoftMPEGDemux = new Guid("{D5F9370B-E232-464F-BE29-A885B1249190}"); //ArcDemux.ax
        Guid CLSID_ArcSoftVideoDecoder = new Guid("{B793E9A8-C53E-4845-9DE9-C32326EACCAD}"); //ASVid.ax
        Guid CLSID_VideoRenderer = new Guid("{6BC1CFFA-8FC1-4261-AC22-CFB4CC38DB50}"); //quartz.dll

        //add Hauppauge Colossus Crossbar 0
        IBaseFilter pHauppaugeColossusCrossbar0 = CreateFilterByName(@"Hauppauge Colossus Crossbar 0", CLSID_WDMStreamingCrossbars);
        hr = pGraph.AddFilter(pHauppaugeColossusCrossbar0, "Hauppauge Colossus Crossbar 0");
        checkHR(hr, "Can't add Hauppauge Colossus Crossbar 0 to graph");

        //add Hauppauge Colossus Capture 0
        IBaseFilter pHauppaugeColossusCapture0 = CreateFilterByName(@"Hauppauge Colossus Capture 0", CLSID_WDMStreamingCaptureDevices);
        hr = pGraph.AddFilter(pHauppaugeColossusCapture0, "Hauppauge Colossus Capture 0");
        checkHR(hr, "Can't add Hauppauge Colossus Capture 0 to graph");

        //add Hauppauge Colossus TS Encoder 0
        IBaseFilter pHauppaugeColossusTSEncoder0 = CreateFilterByName(@"Hauppauge Colossus TS Encoder 0", CLSID_WDMStreamingEncoderDevices);
        hr = pGraph.AddFilter(pHauppaugeColossusTSEncoder0, "Hauppauge Colossus TS Encoder 0");
        checkHR(hr, "Can't add Hauppauge Colossus TS Encoder 0 to graph");

        //add ArcSoft MPEG Demux
        IBaseFilter pArcSoftMPEGDemux = (IBaseFilter)Activator.CreateInstance(Type.GetTypeFromCLSID(CLSID_ArcSoftMPEGDemux));

        IPin outPutPin;
        AMMediaType PinType = new AMMediaType();
        PinType.majorType = MediaType.Video;
        PinType.subType = MediaSubType.H264;
        hr = (pArcSoftMPEGDemux as IMpeg2Demultiplexer).CreateOutputPin(PinType, "Video", out outPutPin);
        checkHR(hr, "Can't add Output Pin to ArcSoft MPEG Demux");

        hr = pGraph.AddFilter(pArcSoftMPEGDemux, "ArcSoft MPEG Demux");
        checkHR(hr, "Can't add ArcSoft MPEG Demux to graph");

        //add ArcSoft Video Decoder
        IBaseFilter pArcSoftVideoDecoder = (IBaseFilter)Activator.CreateInstance(Type.GetTypeFromCLSID(CLSID_ArcSoftVideoDecoder));
        hr = pGraph.AddFilter(pArcSoftVideoDecoder, "ArcSoft Video Decoder");
        checkHR(hr, "Can't add ArcSoft Video Decoder to graph");

        //add Video Renderer
        IBaseFilter pVideoRenderer = (IBaseFilter)Activator.CreateInstance(Type.GetTypeFromCLSID(CLSID_VideoRenderer));
        hr = pGraph.AddFilter(pVideoRenderer, "Video Renderer");
        checkHR(hr, "Can't add Video Renderer to graph");

        //connect Hauppauge Colossus Crossbar 0 and Hauppauge Colossus Capture 0
        hr = pGraph.ConnectDirect(GetPin(pHauppaugeColossusCrossbar0, "0: Video Decoder Out"), GetPin(pHauppaugeColossusCapture0, "Analog Video In"), null);
        checkHR(hr, "Can't connect Hauppauge Colossus Crossbar 0 and Hauppauge Colossus Capture 0");

        //connect Hauppauge Colossus Capture 0 and Hauppauge Colossus TS Encoder 0
        hr = pGraph.ConnectDirect(GetPin(pHauppaugeColossusCapture0, "Virtual Video Out"), GetPin(pHauppaugeColossusTSEncoder0, "Virtual Video Out"), null);
        checkHR(hr, "Can't connect Hauppauge Colossus Capture 0 and Hauppauge Colossus TS Encoder 0");

        //connect Hauppauge Colossus TS Encoder 0 and ArcSoft MPEG Demux
        hr = pGraph.ConnectDirect(GetPin(pHauppaugeColossusTSEncoder0, "AVC TS Out"), GetPin(pArcSoftMPEGDemux, "Input"), null);
        checkHR(hr, "Can't connect Hauppauge Colossus TS Encoder 0 and ArcSoft MPEG Demux");

        //map pinPID for ArcSoft MPEG Demux
        IMPEG2PIDMap pidmap2 = (IMPEG2PIDMap)outPutPin;
        hr = pidmap2.MapPID(1, new int[1] { 0x1011 }, MediaSampleContent.ElementaryStream);
        checkHR(hr, "Can't map video output pin pid to ArcSoft MPEG Demux");

        //connect ArcSoft MPEG Demux and ArcSoft Video Decoder
        hr = pGraph.ConnectDirect(GetPin(pArcSoftMPEGDemux, "Video"), GetPin(pArcSoftVideoDecoder, "Video In"), null);
        checkHR(hr, "Can't connect MPEG-2 Demultiplexer and ArcSoft Video Decoder");

        //connect ArcSoft Video Decoder and Video Renderer
        hr = pGraph.ConnectDirect(GetPin(pArcSoftVideoDecoder, "Video Out"), GetPin(pVideoRenderer, "VMR Input0"), null);
        checkHR(hr, "Can't connect ArcSoft Video Decoder and Video Renderer");

使用此图,一切正常。 我可以在一个表单上显示摄像机的视频,然后在该表单上创建一个透明表单,然后使用GDI +构建我的屏幕显示。 我仍然要添加到OSD中的两件事是当前的FPS计数,当我在操纵杆上扳动扳机时,我想捕获屏幕并将其保存到磁盘。

因此,为了做到这一点,我相信我需要添加一个样本采集器过滤器来手动计时FPS并拉出单个帧。 我将一个样本采集器和一个AVI Decompressor一起添加到了图形中,并试图运行它。

筛选图2

面对直接展示我遇到的所有麻烦,我没想到它会起作用,但令人惊讶的是它确实起作用了。 在GraphEditPlus中,显示了视频,我可以看到捕获帧的样本采集器。 所以我将其导出到C#,然后尝试再次运行它。

int hr = 0;

        //graph builder
        ICaptureGraphBuilder2 pBuilder = (ICaptureGraphBuilder2)new CaptureGraphBuilder2();
        hr = pBuilder.SetFiltergraph(pGraph);
        checkHR(hr, "Can't Set Filtergraph");

        Guid CLSID_WDMStreamingCrossbars = new Guid("{A799A801-A46D-11D0-A18C-00A02401DCD4}");
        Guid CLSID_WDMStreamingCaptureDevices = new Guid("{65E8773D-8F56-11D0-A3B9-00A0C9223196}"); 
        Guid CLSID_WDMStreamingEncoderDevices = new Guid("{19689BF6-C384-48FD-AD51-90E58C79F70B}");
        Guid CLSID_ArcSoftMPEGDemux = new Guid("{D5F9370B-E232-464F-BE29-A885B1249190}"); //ArcDemux.ax
        Guid CLSID_ArcSoftVideoDecoder = new Guid("{B793E9A8-C53E-4845-9DE9-C32326EACCAD}"); //ASVid.ax
        Guid CLSID_SampleGrabber = new Guid("{C1F400A0-3F08-11D3-9F0B-006008039E37}"); //qedit.d11

        //add Hauppauge Colossus Crossbar 0
        IBaseFilter pHauppaugeColossusCrossbar0 = CreateFilterByName(@"Hauppauge Colossus Crossbar 0", CLSID_WDMStreamingCrossbars);
        hr = pGraph.AddFilter(pHauppaugeColossusCrossbar0, "Hauppauge Colossus Crossbar 0");
        checkHR(hr, "Can't add Hauppauge Colossus Crossbar 0 to graph");

        //add Hauppauge Colossus Capture 0
        IBaseFilter pHauppaugeColossusCapture0 = CreateFilterByName(@"Hauppauge Colossus Capture 0", CLSID_WDMStreamingCaptureDevices);
        hr = pGraph.AddFilter(pHauppaugeColossusCapture0, "Hauppauge Colossus Capture 0");
        checkHR(hr, "Can't add Hauppauge Colossus Capture 0 to graph");

        //add Hauppauge Colossus TS Encoder 0
        IBaseFilter pHauppaugeColossusTSEncoder0 = CreateFilterByName(@"Hauppauge Colossus TS Encoder 0", CLSID_WDMStreamingEncoderDevices);
        hr = pGraph.AddFilter(pHauppaugeColossusTSEncoder0, "Hauppauge Colossus TS Encoder 0");
        checkHR(hr, "Can't add Hauppauge Colossus TS Encoder 0 to graph");

        //add ArcSoft MPEG Demux
        IBaseFilter pArcSoftMPEGDemux = (IBaseFilter)Activator.CreateInstance(Type.GetTypeFromCLSID(CLSID_ArcSoftMPEGDemux));
        //add Video output map
        IPin outPutPin;
        AMMediaType PinType = new AMMediaType();
        PinType.majorType = MediaType.Video;
        PinType.subType = MediaSubType.H264;
        hr = (pArcSoftMPEGDemux as IMpeg2Demultiplexer).CreateOutputPin(PinType, "Video", out outPutPin);
        checkHR(hr, "Can't add Output Pin to ArcSoft MPEG Demux");
        hr = pGraph.AddFilter(pArcSoftMPEGDemux, "ArcSoft MPEG Demux");
        checkHR(hr, "Can't add ArcSoft MPEG Demux to graph");

        //add ArcSoft Video Decoder
        IBaseFilter pArcSoftVideoDecoder = (IBaseFilter)Activator.CreateInstance(Type.GetTypeFromCLSID(CLSID_ArcSoftVideoDecoder));
        hr = pGraph.AddFilter(pArcSoftVideoDecoder, "ArcSoft Video Decoder");
        checkHR(hr, "Can't add ArcSoft Video Decoder to graph");

        //add SampleGrabber
        IBaseFilter pSampleGrabber = (IBaseFilter)Activator.CreateInstance(Type.GetTypeFromCLSID(CLSID_SampleGrabber));
        hr = pGraph.AddFilter(pSampleGrabber, "SampleGrabber");
        checkHR(hr, "Can't add SampleGrabber to graph");
        (pSampleGrabber as ISampleGrabber).SetCallback(this, 0);

        /*
        AMMediaType pSampleGrabber_pmt = new AMMediaType();
        pSampleGrabber_pmt.majorType = MediaType.Video;
        pSampleGrabber_pmt.subType = MediaSubType.YUY2;
        pSampleGrabber_pmt.formatType = FormatType.VideoInfo;
        pSampleGrabber_pmt.fixedSizeSamples = true;
        pSampleGrabber_pmt.formatSize = 88;
        pSampleGrabber_pmt.sampleSize = 4147200;
        pSampleGrabber_pmt.temporalCompression = false;
        VideoInfoHeader pSampleGrabber_format = new VideoInfoHeader();
        pSampleGrabber_format.SrcRect = new DsRect();
        pSampleGrabber_format.SrcRect.right = 1920;
        pSampleGrabber_format.SrcRect.bottom = 1080;
        pSampleGrabber_format.TargetRect = new DsRect();
        pSampleGrabber_format.TargetRect.right = 1920;
        pSampleGrabber_format.TargetRect.bottom = 1080;
        pSampleGrabber_format.BitRate = 4000000;
        pSampleGrabber_format.AvgTimePerFrame = 333667;
        pSampleGrabber_format.BmiHeader = new BitmapInfoHeader();
        pSampleGrabber_format.BmiHeader.Size = 40;
        pSampleGrabber_format.BmiHeader.Width = 1920;
        pSampleGrabber_format.BmiHeader.Height = 1080;
        pSampleGrabber_format.BmiHeader.Planes = 1;
        pSampleGrabber_format.BmiHeader.BitCount = 16;
        pSampleGrabber_format.BmiHeader.Compression = 844715353;
        pSampleGrabber_format.BmiHeader.ImageSize = 4147200;
        pSampleGrabber_pmt.formatPtr = Marshal.AllocCoTaskMem(Marshal.SizeOf(pSampleGrabber_format));
        Marshal.StructureToPtr(pSampleGrabber_format, pSampleGrabber_pmt.formatPtr, false);
        hr = ((ISampleGrabber)pSampleGrabber).SetMediaType(pSampleGrabber_pmt);
        DsUtils.FreeAMMediaType(pSampleGrabber_pmt);
        checkHR(hr, "Can't set media type to sample grabber");
        */

        //add AVI Decompressor
        IBaseFilter pAVIDecompressor2 = (IBaseFilter)new AVIDec();
        hr = pGraph.AddFilter(pAVIDecompressor2, "AVI Decompressor");
        checkHR(hr, "Can't add AVI Decompressor to graph");

        //connect Hauppauge Colossus Crossbar 0 and Hauppauge Colossus Capture 0
        hr = pGraph.ConnectDirect(GetPin(pHauppaugeColossusCrossbar0, "0: Video Decoder Out"), GetPin(pHauppaugeColossusCapture0, "Analog Video In"), null);
        checkHR(hr, "Can't connect Hauppauge Colossus Crossbar 0 and Hauppauge Colossus Capture 0");

        //connect Hauppauge Colossus Capture 0 and Hauppauge Colossus TS Encoder 0
        hr = pGraph.ConnectDirect(GetPin(pHauppaugeColossusCapture0, "Virtual Video Out"), GetPin(pHauppaugeColossusTSEncoder0, "Virtual Video Out"), null);
        checkHR(hr, "Can't connect Hauppauge Colossus Capture 0 and Hauppauge Colossus TS Encoder 0");

        //connect Hauppauge Colossus TS Encoder 0 and ArcSoft MPEG Demux
        hr = pGraph.ConnectDirect(GetPin(pHauppaugeColossusTSEncoder0, "AVC TS Out"), GetPin(pArcSoftMPEGDemux, "Input"), null);
        checkHR(hr, "Can't connect Hauppauge Colossus TS Encoder 0 and ArcSoft MPEG Demux");

        //map pinPID for ArcSoft MPEG Demux
        IMPEG2PIDMap pidmap2 = (IMPEG2PIDMap)outPutPin;
        hr = pidmap2.MapPID(1, new int[1] { 0x1011 }, MediaSampleContent.ElementaryStream);
        checkHR(hr, "Can't map video output pin pid to ArcSoft MPEG Demux");

        //connect ArcSoft MPEG Demux and ArcSoft Video Decoder
        hr = pGraph.ConnectDirect(GetPin(pArcSoftMPEGDemux, "Video"), GetPin(pArcSoftVideoDecoder, "Video In"), null);
        checkHR(hr, "Can't connect MPEG-2 Demultiplexer and ArcSoft Video Decoder");

        //connect ArcSoft Video Decoder and SampleGrabber
        hr = pGraph.ConnectDirect(GetPin(pArcSoftVideoDecoder, "Video Out"), GetPin(pSampleGrabber, "Input"), null);
        checkHR(hr, "Can't connect ArcSoft Video Decoder and SampleGrabber");

        //connect SampleGrabber and AVI Decompressor
        hr = pGraph.ConnectDirect(GetPin(pSampleGrabber, "Output"), GetPin(pAVIDecompressor2, "XForm In"), null);
        checkHR(hr, "Can't connect SampleGrabber and AVI Decompressor");

        //add Video Renderer
        IBaseFilter pVideoRenderer = (IBaseFilter)new VideoRenderer();
        hr = pGraph.AddFilter(pVideoRenderer, "Video Renderer");
        checkHR(hr, "Can't add Video Renderer to graph");

        //connect AVI Decompressor and Video Renderer
        hr = pGraph.ConnectDirect(GetPin(pAVIDecompressor2, "XForm Out"), GetPin(pVideoRenderer, "Input"), null);
        checkHR(hr, "Can't connect AVI Decompressor and Video Renderer");

现在我得到的只是一个黑屏,我不知道为什么。 我试图确保样本采集卡的媒体类型正确,但是老实说我不确定我在做什么。(这是我第一次使用直接放映),感谢您提供任何帮助来解决此问题。 谢谢您的帮助!

更新我通过彼得·科斯托夫(Peter Kostov)的指令成功地远程连接了我的图形,我想我知道了为什么它不起作用。

图片3

似乎解码器未连接到样品采集卡。 我逐步完成了该方法,但没有出错。

  //connect ArcSoft Video Decoder and SampleGrabber
  hr = pGraph.ConnectDirect(GetPin(pArcSoftVideoDecoder, "Video Out"),     GetPin(pSampleGrabber, "Input"), null);
  checkHR(hr, "Can't connect ArcSoft Video Decoder and SampleGrabber");

它似乎运行正常,但输出仍未连接。

好吧,我最终通过在样本采集器的输出中添加一个空渲染器解决了它。 然后,我将样品采集卡的媒体类型从YUY2更改为RGB24,并使用了来自样品采集卡的回叫,将数据转换为位图,然后我要做的就是将其显示在图片框上。 感谢您的帮助!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM