## About Effect Filters

In DirectShow, effect filters are defined as filters that apply an effect to media data, but don't change the media type. DirectShow provides several effect filters, including Contrast, Gargle, and EzRGB24. Effect filters can apply a wide range of useful video and audio effects to media data.

Contents of this article:

- Creating Effect Filters
- List of DirectShow Effect Filters and Samples

Creating Effect Filters

Because the input and output media formats are the same, and the applied effect can't change the format, effect filters often contain a code that checks the media formatting. If the filter derives from one of the transform filter base classes, CTransformFilter or CTransInPlaceFilter, the filter typically checks the format with the CheckMediaType, CheckInputType, and CheckTransform methods. If the filter doesn't derive from one of the transform filter base classes, its pins typically check the format by calling the CBasePin::CheckMediaType member function. See Negotiating Media Types with CBasePin::AgreeMediaType for more information.

You should choose a base class for your effect filter class that provides the greatest amount of the functionality you need. Often, the base class will be one of the transform filter base classes. If none of the higher-level base classes support your required functionality, you can choose CBaseFilter or CBasePin as your base class.

Your effect filter must implement the IPersistStream interface if you want to save the state of your effects in the Filter Graph Editor. To access this interface, derive your effect filter class from CPersistStream and query for the IPersistStream interface. Saving the filter's state can be helpful during design, but it is often useful to have the effect filter return to a default state when the Filter Graph Editor closes it, in which case you don't need to implement IPersistStream.

If you want the user to be able to manipulate the effect, you must create and display your effect filter's property page and provide a mechanism for returning the user's input to the filter. To do this, implement a property page class, the ISpecifyPropertyPages interface (which exposes property pages), and a custom interface that changes property page values. Typically, property pages use controls such as a slider, button, or check box to receive user input. You also must provide the resource file that displays the controls on the property page.

To implement the property page class, create a class that derives from CBasePropertyPage and implement the OnReceiveMessage method, the CPersistStream::SetDirty method, and a data member for each effect parameter. To access the two interfaces, derive your effect filter class from ISpecifyPropertyPages and the custom interface, and then query for the interfaces. You can query for all the interfaces you need by overriding the NonDelegatingQueryInterface method as shown in the following code from the Gargle sample (IGargle is the custom interface):

    STDMETHODIMP CGargle::NonDelegatingQueryInterface(REFIID riid, void **ppv)
    {
        CheckPointer(ppv,E_POINTER);
        if (riid == IID_IGargle) {
            return GetInterface((IGargle *) this, ppv);
        } else if (riid == IID_ISpecifyPropertyPages) {
            return GetInterface((ISpecifyPropertyPages *) this, ppv);
        } else if (riid == IID_IPersistStream) {
            return GetInterface((IPersistStream *) this, ppv);
        } else {
            return CTransInPlaceFilter::NonDelegatingQueryInterface(riid, ppv);
        }
    }

The effect filter's custom interface typically supplies a put and a get method for each effect parameter. For example, the IGargle custom interface supplies put_GargleRate and get_GargleRate methods. The IContrast custom interface in the Contrast sample supplies put_ContrastLevel and get_ContrastLevel methods. When the user accesses one of the controls on the property page, the page generates a windows message. The property page class's OnReceiveMessage member function handles this message. The following code fragment from the Contrast sample demonstrates this message generation and handling. IDB_DEFAULT is the resource ID of the Default button. The user clicks this button to set the video contrast to its default state. The CContrastProperties class implements the property page and the IContrast::put_DefaultContrastLevel method sets the contrast level to its default value.

    BOOL CContrastProperties::OnReceiveMessage(HWND hwnd, UINT uMsg,
                                    WPARAM wParam, LPARAM lParam)
    {
        switch (uMsg)
        {
           case WM_COMMAND:
            {
              if (LOWORD(wParam) == IDB_DEFAULT)
                {
    	        pIContrast()->put_DefaultContrastLevel();
    	        SendMessage(m_hwndSlider, TBM_SETPOS, TRUE, 0L);
                  SetDirty();
    	    }
                return (LRESULT) 1;
            }
    ...

Effect filters use critical sections internally to protect the global filter state. Effect filters can lock a critical section to ensure that data flow through the filter graph is serialized and that the global filter state doesn't change while an effect is occurring. DirectShow locks a critical section by declaring a CAutoLock class object. Typically, effect filters lock the critical section as soon as they enter the function that applies the effect. For example, in the following code fragment from the Gargle sample, the function that applies the effect is MessItAbout:

    CCritSec   m_GargleLock; // Declare the critical section data member in the effect filter class definition

    void CGargle::MessItAbout(PBYTE pb, int cb)
    {
        CAutoLock foo(&m_GargleLock);

The put and get methods of the effect properties (for example, put_GargleRate) typically lock the critical section so effect values can't change in the middle of an update.

List of DirectShow Effect Filters and Samples

The DirectShow SDK ships with the following effect filters. You can find these filters in the Samples directory. All the source code is included.

Contrast: This effect filter adjusts the contrast of the video images sent through it. The filter adjusts the contrast by using palettes, because an image's color palette effectively determines how the image is interpreted by the display device; that is, how the value 23 (for example) maps into an RGB triplet for display. By changing the palette, you can reduce and increase contrast without doing anything to the image pixels themselves. The Filter Graph Editor lists this filter as Video Contrast.

EzRGB24: This effect filter modifies decompressed video images sent through it. It creates color and image filtering effects through simple techniques such as adjusting the red, green, or blue levels (to change the playback color) and by averaging neighboring pixels (to achieve blur and embossed (raised) effects). The Filter Graph Editor lists this filter as Image Effects.

Gargle: This effect filter modifies audio data sent through it. A synthesized wave function modulates the audio data's amplitude. The secondary wave can be a triangular or square wave, and can have different frequencies. At low modulation frequencies it sounds like a tremolo. At high modulation frequencies it sounds like a distortion. The Filter Graph Editor lists this filter as Gargle.

© 1997 Microsoft Corporation. All rights reserved. Terms of Use.