locked
Creating Custom DirectShow filter graphs in C# RRS feed

  • Question

  • Hello everyone,

    I'd like to know how to create my own DirectShow filtergraph using a .net GUI in C# (C++ is ok, too).

    Until now I did it in C++ and rendered everything to an MFC GUI, but MFC is old, so I want to use .net. I think I can get the hang of the managed/unmanaged problems, but there are also different interfaces. In C++ I used IGraphBuilder, but I don't know how to connect the finished graph to a .net C++ panel. Does anyone know how to do this?

    In the example at
    http://www.codeproject.com/KB/directx/directshowmediaplayer.aspx
    the class "FilGraphManager" was used to automatically render a loaded media file and the result was displayed by giving the panel handle to the FilGraphManager-object: 

    // declaration
    
    private FilgraphManager m_objFilterGraph = null;
    
    private IVideoWindow m_objVideoWindow = null;
    
    
    
    // ...
    
    
    
    // function which opens and plays a media file
    
    m_objFilterGraph = new FilgraphManager();
    
    m_objFilterGraph.RenderFile("path to the file.avi");
    
    
    
    try
    
    {
    
     m_objVideoWindow = m_objFilterGraph as IVideoWindow;
    
     m_objVideoWindow.Owner = (int)panel1.Handle; // putting the video into the panel
    
    
    
     // window configuration...
    
    }
    
    catch (Exception)
    
    {
    
     m_objVideoWindow = null;
    
    }
    
    
    
    

    So now I'm wondering if I can somehow use a FilGraphManager-object to include my own DS-filters. Does anyone know this?

    Kind regards
    Squall83

    edit: It's odd, but this is the first forum where all my breaks get removed if I use Firefox and which doesn't use the [code]-tag. :-/
    Wednesday, May 25, 2011 12:03 PM

Answers

  • I'd like to know how to create my own DirectShow filtergraph using a .net GUI in C# (C++ is ok, too).
    [...]
    So now I'm wondering if I can somehow use a FilGraphManager-object to include my own DS-filters. Does anyone know this?

    The InterOp lib you are using is simply a collection of managed definitions for the standard DirectShow COM classes created using COM InterOp. So you just use the interfaces like you would in C++ to perform the same tasks. The interface you need to manage the filters in a graph, that is IGraphBuilder, should already be there, since RenderFile() is one of its methods. If it's not, you can add the definition yourself or use a more complete wrapper, like DirectShow.NET on http://sf.net/.

    If you are instead asking how to write custom filter in C#, that's possibile through COM InterOp as well, but very difficult since in C# you would not have the C++ BaseClasses of the DirectShow SDK to help you. Most transform filters however can be implemented as DMOs instead of actual DS filters and DMOs only need to implement one simple COM interface, so it is doable to write a DMO in C# from scratch.

    edit: It's odd, but this is the first forum where all my breaks get removed if I use Firefox and which doesn't use the [code]-tag. :-/

    Because forum runs on MS's own <del style="color: black;">crap</del> platform and not a "standard" one.


    <http://www.riseoftheants.com/mmx/faq.htm>
    • Marked as answer by __Alexander__ Wednesday, May 25, 2011 4:37 PM
    Wednesday, May 25, 2011 1:56 PM
  • Thanks for the quick response. Now it works! ^_^

    I couldn't find IGraphBuilder in the Quartz.dll and the RenderFile()-method is included in the FilGraphManager, which has less functionality than IGraphBuilder.

    After I downloaded the DirectShow.NET lib, as soon as I replaced "using QuartzTypeLib;" by "using DirectShowLib;" the FilGraphManager-object was no longer known to the compiler, while all other interfaces were still known. Therefore I think that FilGraphManager was indeed the (bad) replacement for IGraphBuilder.

    Below is a portion of the code I used for anyone else who wants to know what I did. I basically took the example code I linked above, and then I
    - changed the Quartz namespace to the DirectShow.net namespace as explained above (don't forget to add the new lib to the Reference-folder of your project)
    - changed the FilGraphManager-object to IGraphBuilder
    - added a few class members (see below)
    - changed the function "private void file_open_Click(object sender, EventArgs e)" as shown below
    - changed a few function calls, because some members can't be accessed directly anymore, so getters and putters are the way to go.

    // declarations
    private IGraphBuilder m_objFilterGraph = null;
    private IBaseFilter m_myFilter= null;
    private Guid m_guid;
    private Type m_comtype;
    
    
    m_objFilterGraph = (IGraphBuilder) new FilterGraph(); // replacing the "new FilGraphManager()"-command
    
    // new stuff
    m_guid = new Guid("12345678-9ABC-DEF1-2345-6789ABCDEF01"); // not the real GUID, just an example
    m_comtype = Type.GetTypeFromCLSID(m_guid);
    m_myFilter = (IBaseFilter)Activator.CreateInstance(m_comtype);
    m_objFilterGraph.AddFilter(m_myFilter, "Filter name");
    
    m_objFilterGraph.RenderFile(openFileDialog.FileName, null); // this statement is the same again as in the example code, except for the added null)
    
    
    


    I know many people prefer complete working examples (me too), but I hope this explanation is clear enough to get any subsequent readers up to speed anyway. I really didn't change all that much. Note that I did not yet look after potential memory-leaks, but I'll look into that later. I know that some of those COM-objects wrapped into the DirectShow.NET-lib have to deleted manually, so use this code at your own discretion.

    Btw:
    I am not trying to build my own DS-filters in C#, only graphs. I only need C# because the .net GUI is so nice. DS-filters have to be fast and therefore I have to work without garbage collection, i.e. in C++.

    • Marked as answer by __Alexander__ Wednesday, May 25, 2011 4:39 PM
    Wednesday, May 25, 2011 4:34 PM

All replies

  • I'd like to know how to create my own DirectShow filtergraph using a .net GUI in C# (C++ is ok, too).
    [...]
    So now I'm wondering if I can somehow use a FilGraphManager-object to include my own DS-filters. Does anyone know this?

    The InterOp lib you are using is simply a collection of managed definitions for the standard DirectShow COM classes created using COM InterOp. So you just use the interfaces like you would in C++ to perform the same tasks. The interface you need to manage the filters in a graph, that is IGraphBuilder, should already be there, since RenderFile() is one of its methods. If it's not, you can add the definition yourself or use a more complete wrapper, like DirectShow.NET on http://sf.net/.

    If you are instead asking how to write custom filter in C#, that's possibile through COM InterOp as well, but very difficult since in C# you would not have the C++ BaseClasses of the DirectShow SDK to help you. Most transform filters however can be implemented as DMOs instead of actual DS filters and DMOs only need to implement one simple COM interface, so it is doable to write a DMO in C# from scratch.

    edit: It's odd, but this is the first forum where all my breaks get removed if I use Firefox and which doesn't use the [code]-tag. :-/

    Because forum runs on MS's own <del style="color: black;">crap</del> platform and not a "standard" one.


    <http://www.riseoftheants.com/mmx/faq.htm>
    • Marked as answer by __Alexander__ Wednesday, May 25, 2011 4:37 PM
    Wednesday, May 25, 2011 1:56 PM
  • Thanks for the quick response. Now it works! ^_^

    I couldn't find IGraphBuilder in the Quartz.dll and the RenderFile()-method is included in the FilGraphManager, which has less functionality than IGraphBuilder.

    After I downloaded the DirectShow.NET lib, as soon as I replaced "using QuartzTypeLib;" by "using DirectShowLib;" the FilGraphManager-object was no longer known to the compiler, while all other interfaces were still known. Therefore I think that FilGraphManager was indeed the (bad) replacement for IGraphBuilder.

    Below is a portion of the code I used for anyone else who wants to know what I did. I basically took the example code I linked above, and then I
    - changed the Quartz namespace to the DirectShow.net namespace as explained above (don't forget to add the new lib to the Reference-folder of your project)
    - changed the FilGraphManager-object to IGraphBuilder
    - added a few class members (see below)
    - changed the function "private void file_open_Click(object sender, EventArgs e)" as shown below
    - changed a few function calls, because some members can't be accessed directly anymore, so getters and putters are the way to go.

    // declarations
    private IGraphBuilder m_objFilterGraph = null;
    private IBaseFilter m_myFilter= null;
    private Guid m_guid;
    private Type m_comtype;
    
    
    m_objFilterGraph = (IGraphBuilder) new FilterGraph(); // replacing the "new FilGraphManager()"-command
    
    // new stuff
    m_guid = new Guid("12345678-9ABC-DEF1-2345-6789ABCDEF01"); // not the real GUID, just an example
    m_comtype = Type.GetTypeFromCLSID(m_guid);
    m_myFilter = (IBaseFilter)Activator.CreateInstance(m_comtype);
    m_objFilterGraph.AddFilter(m_myFilter, "Filter name");
    
    m_objFilterGraph.RenderFile(openFileDialog.FileName, null); // this statement is the same again as in the example code, except for the added null)
    
    
    


    I know many people prefer complete working examples (me too), but I hope this explanation is clear enough to get any subsequent readers up to speed anyway. I really didn't change all that much. Note that I did not yet look after potential memory-leaks, but I'll look into that later. I know that some of those COM-objects wrapped into the DirectShow.NET-lib have to deleted manually, so use this code at your own discretion.

    Btw:
    I am not trying to build my own DS-filters in C#, only graphs. I only need C# because the .net GUI is so nice. DS-filters have to be fast and therefore I have to work without garbage collection, i.e. in C++.

    • Marked as answer by __Alexander__ Wednesday, May 25, 2011 4:39 PM
    Wednesday, May 25, 2011 4:34 PM
  • Hello,I want to create custom DXShow filter graphs in C#.I do as you said,but there is something wrong with the code.The Message display below:About The GUID,I don‘t know why you use a certain value? 
    Wednesday, December 25, 2013 6:17 AM
  • GUID is the GUID of the DirectShow filter (which is a COM object) you wish to instantiate. Since, you're creating new GUID, there's no filter registered in the system with that GUID. That's what the error (COMException) is telling you about.

    You should read more about COM objects and DirectShow in general.

    Saturday, December 28, 2013 10:03 AM
  • yeah!I am fresh about DXshow and COM object.I use RenderFile() method to playback a video file,the video playback not that smoothly.I open the same file using MediaPlayer or GraphEdit,it playback well.I wonder if the PC system don't chose the right Filter?Here is the struct of a video file,I want to know if i can define LAV Splitter,Mpeg4s Decoder DMO and Video Renderer Filters and connect them?

    Wednesday, February 12, 2014 7:14 AM
  • now,I konw  why we need a certain GUID.I find the filters’ GUID in GraphEdit and it exact exist in registry,but when I use CreateInstance(),some GUID worked and others failed。(The LAV Spiltter's GUID and Video Renderer's GUID worked and Mpeg4s' GUID failed) The structure of the Video is as fallow:

    I want to know the way I define these Filters is right?

    Thursday, February 13, 2014 5:45 AM