none
Construction of a simple graph RRS feed

  • Question

  • Hello,

    I use DirectShow in C# application to create a graph containing a camera (Camera-M) connected to SampleGrabber. I used GraphEdit to generate an example that I copied into my app.

    But this code does not run correctly and produces an error: "Building graph ...
    Camera-M can not connect and SampleGrabber", at the connection of the two filters.

    I send you the code used by GraphEdit product.

    using System;
    using System.Collections.Generic;
    using System.Runtime.InteropServices.ComTypes;
    using System.Runtime.InteropServices;
    using DirectShowLib;
    
    namespace PixiGraph
    {
        public class Graph
        {
    
            public Graph()
            {
                IGraphBuilder graph = (IGraphBuilder)new FilterGraph();
                Console.WriteLine("Building graph...");
                BuildGraph(graph);
            }
    
            static void BuildGraph(IGraphBuilder pGraph)
            {
                int hr = 0;
    
                //graph builder
                ICaptureGraphBuilder2 pBuilder = (ICaptureGraphBuilder2)new CaptureGraphBuilder2();
                hr = pBuilder.SetFiltergraph(pGraph);
                checkHR(hr, "Can't SetFiltergraph");
    
                Guid CLSID_VideoCaptureSources = new Guid("{860BB310-5D01-11D0-BD3B-00A0C911CE86}"); //
                Guid CLSID_SampleGrabber = new Guid("{C1F400A0-3F08-11D3-9F0B-006008039E37}"); //qedit.dll
    
                //add Camera-M
                IBaseFilter pCameraM = CreateFilterByName(@"Camera-M", CLSID_VideoCaptureSources);
                hr = pGraph.AddFilter(pCameraM, "Camera-M");
                checkHR(hr, "Can't add Camera-M 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");
                AMMediaType pSampleGrabber_pmt = new AMMediaType();
                pSampleGrabber_pmt.majorType = MediaType.Video;
                pSampleGrabber_pmt.subType = MediaSubType.I420;
                pSampleGrabber_pmt.formatType = FormatType.VideoInfo;
                pSampleGrabber_pmt.fixedSizeSamples = true;
                pSampleGrabber_pmt.formatSize = 88;
                pSampleGrabber_pmt.sampleSize = 460800;
                pSampleGrabber_pmt.temporalCompression = false;
                VideoInfoHeader pSampleGrabber_format = new VideoInfoHeader();
                pSampleGrabber_format.SrcRect = new DsRect();
                pSampleGrabber_format.TargetRect = new DsRect();
                pSampleGrabber_format.BitRate = 110592000;
                pSampleGrabber_format.AvgTimePerFrame = 333333;
                pSampleGrabber_format.BmiHeader = new BitmapInfoHeader();
                pSampleGrabber_format.BmiHeader.Size = 40;
                pSampleGrabber_format.BmiHeader.Width = 640;
                pSampleGrabber_format.BmiHeader.Height = 480;
                pSampleGrabber_format.BmiHeader.Planes = 1;
                pSampleGrabber_format.BmiHeader.BitCount = 12;
                pSampleGrabber_format.BmiHeader.Compression = 808596553;
                pSampleGrabber_format.BmiHeader.ImageSize = 460800;
                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");
    
    
                //connect Camera-M and SampleGrabber
                hr = pGraph.ConnectDirect(GetPin(pCameraM, "Capturer"), GetPin(pSampleGrabber, "Input"), null);
                checkHR(hr, "Can't connect Camera-M and SampleGrabber");
    
            }
    
            public static IBaseFilter CreateFilterByName(string filterName, Guid category)
            {
                int hr = 0;
                DsDevice[] devices = DsDevice.GetDevicesOfCat(category);
                foreach (DsDevice dev in devices)
                    if (dev.Name == filterName)
                    {
                        IBaseFilter filter = null;
                        IBindCtx bindCtx = null;
                        try
                        {
                            hr = CreateBindCtx(0, out bindCtx);
                            DsError.ThrowExceptionForHR(hr);
                            Guid guid = typeof(IBaseFilter).GUID;
                            object obj;
                            dev.Mon.BindToObject(bindCtx, null, ref guid, out obj);
                            filter = (IBaseFilter)obj;
                        }
                        finally
                        {
                            if (bindCtx != null) Marshal.ReleaseComObject(bindCtx);
                        }
                        return filter;
                    }
                return null;
            }
    
            [DllImport("ole32.dll")]
            public static extern int CreateBindCtx(int reserved, out IBindCtx ppbc);
    
            static IPin GetPin(IBaseFilter filter, string pinname)
            {
                IEnumPins epins;
                int hr = filter.EnumPins(out epins);
                checkHR(hr, "Can't enumerate pins");
                IntPtr fetched = Marshal.AllocCoTaskMem(4);
                IPin[] pins = new IPin[1];
                while (epins.Next(1, pins, fetched) == 0)
                {
                    PinInfo pinfo;
                    pins[0].QueryPinInfo(out pinfo);
                    bool found = (pinfo.name == pinname);
                    DsUtils.FreePinInfo(pinfo);
                    if (found)
                        return pins[0];
                }
                checkHR(-1, "Pin not found");
                return null;
            }
    
            static void checkHR(int hr, string msg)
            {
                if (hr < 0)
                {
                    Console.WriteLine(msg);
                    DsError.ThrowExceptionForHR(hr);
                }
            }
    
        }
    }
    

    Can you help me find the reason for this bug?

    Thank you for your help.

    Regards


    Alain

    • Type modifié Aurel Bera mardi 12 février 2013 08:21 Discussion
    • Type modifié Aurel Bera mardi 12 février 2013 13:41 Question
    lundi 11 février 2013 14:14

Réponses

  • Bonjour Aurel,

    Pardon à tous, je pensais être sur un forum anglais !

    J'ai obtenu la réponse à ma question sur le dysfonctionnement de ce code généré par GraphEdit :

    les paramètres de configuration du SampleGrabber ne sont pas tous gérés. Il suffit de les réduire au minimum, par exemple :

                AMMediaType pSampleGrabber_pmt = new AMMediaType();
                pSampleGrabber_pmt.majorType = MediaType.Video;
                pSampleGrabber_pmt.subType = MediaSubType.I420;
                pSampleGrabber_pmt.formatType = FormatType.VideoInfo;
    

    J'aurai d'autres questions sur DirectShow. Est-ce le bon endroit pour les poser ou existe-il un forum spécifique ?

    Merci


    Alain

    • Marqué comme réponse Aurel Bera mardi 12 février 2013 13:41
    mardi 12 février 2013 13:35

Toutes les réponses