none
Some advices about custom filters

    Question

  • Hello,

    I´m a bit stuck since a few days. I´ve to decide if I make a custom filter (which means learn how to do one) or if I search another way to create my application.
    That´s why I need some information about filters:

    If I create a custom transform filter, for example, which have to pass only a designated number of horizontal pixellines from video frames; can I command the number of pixellines from outside (like the User Interface)? And am I obligated to stop the graph and restart it after the change?

    Flo
    Friday, October 10, 2008 2:15 PM

All replies

  • Yes, you can define and implement your own interface to control the filter operation from the host application.
    I have my own transform filters which also alter the media type in one way or another. I simply stop the graph and render the filters' output again after a change has been made. I've read that some filters can handle a dynamic change of the media type, but I haven't attempted it myself.
    You just need to make sure that any function that you expose through your own interface will properly synchronize access to any shared variables.
    As an example, let's say you have a boolean that toggles greyscale transform in your filter.
    The transform function does something like this:

    transform(IMediaSample * in, IMediaSample * out)
    {
        // Get the buffers, error checking and so on
        for(int y=0; y<height; ++y)
        {
            if(bGreyscale)    transformGreyscale(rowIn, rowOut);

            else
            transform(rowIn, rowOut);
        }
    }

    And you have a function that toggles the bGreyscale variable:

    setGreyscale(bool enable)
    {
        bGreyscale    = enable;
    }

    Since there's no synchronization between these functions, parts of the sample can be grey when the variable is changed. In short, just make sure to synchronize access to shared variables and you should do just fine.

    Friday, October 10, 2008 2:38 PM
  • Here are some pointers.

    //-------------------------------------------
    // YourTransformFilter.h
    //-------------------------------------------

    // The GUID that identifies your interface
    static const GUID IIDTransformFilterControl =    // {13F23FD9-A90C-480d-A597-F46BA20070AC}
    {
        0x13f23fd9, 0xa90c, 0x480d, { 0xa5, 0x97, 0xf4, 0x6b, 0xa2, 0x0, 0x70, 0xac }
    };

    DECLARE_INTERFACE_(ITransformFilterControl, IUnknown)
    {
        STDMETHOD(setGreyscale)(bool enable) = 0;
    };

    class YourTransformFilter : public CTransformFilter, public ITransformFilterControl
    {
        public:
        STDMETHODIMP    NonDelegatingQueryInterface(REFIID riid, void **ppv);
        STDMETHODIMP    setGreyscale(bool enable);
    };


    //-------------------------------------------
    // YourTransformFilter.cpp
    //-------------------------------------------

    STDMETHODIMP    YourTransformFilter::NonDelegatingQueryInterface(REFIID riid, void **ppv)
    {
        CheckPointer(ppv, E_POINTER);

        if(riid==IIDTransformFilterControl)    return GetInterface((ITransformFilterControl*) this, ppv);

        return CTransformFilter::NonDelegatingQueryInterface(riid, ppv);
    }

    STDMETHODIMP    YourTransformFilter:: setGreyscale(bool enable)
    {
        bGreyscale    = enable;
        return S_OK;
    }


    // In your C# host application
        [ComImport, System.Security.SuppressUnmanagedCodeSecurity, Guid("
    13F23FD9-A90C-480d-A597-F46BA20070AC"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        public interface ITransformControl
        {
            [PreserveSig]
            int setGreyscale(bool enable);
        }

    ITransformFilterControl transformControl = yourFilterInstance as ITransformFilterControl;
    if(transformControl!=null)
    {
        transformControl->setGreyscale(true);
    }
    Friday, October 10, 2008 2:52 PM
  • Thanks for the sample! I´m happy to know that what I want to do is possible.

    I´m just reading some lecture notes about creating custom filter; it looks like big work. But your sample seams easy. Anyway I´ve to get through these lecture note to get an overview about what I need and not.

    What´s about the
    GUID that identifies the interface? Should I really know that? For what is it?
    Friday, October 10, 2008 3:55 PM
  • Btw which filter in the "..Sample\Multimedia\Directshow\filter" folder is a transform filter (but not a iTransformInPlaceFilter)?
    Friday, October 10, 2008 4:56 PM