## Frequently Asked Questions

This section answers many frequently asked questions about DirectShow. It is divided into three parts: answers to general questions, answers to questions asked by application developers, and answers to questions asked by filter developers.

Contents of this article:

- General Questions
- Redistribution Questions
- Application Development Questions
- Filter Development Questions

General Questions

Q. What are the differences between DirectShow™, DirectDraw®, DirectSound®, and DirectX®?

A. For an overview of these Microsoft® technologies as well as many others, see http://www.microsoft.com/directx/.

Q. What operating systems does DirectShow support?

A. DirectShow supports Windows® 95 or later and Windows NT® version 4.x or later.

Q. Is there an DirectShow Hardware Compatibility List (HCL)?

A. No. DirectShow uses all DirectDraw® and DirectSound hardware capabilities where they are available. Where no special hardware is available, DirectShow uses GDI to draw video and the waveOut* Multimedia APIs to play back audio.

Q. What multimedia file formats does DirectShow support?

A. DirectShow supports the following formats.

- MIDI (.mid)
- MPEG-1 (.mpg, .mpeg, .mpv, .mp2, .mpa, .mpe)
- Audio-video interleaved (.avi)
- Nonproprietary Apple® QuickTime® files (.mov, .qt)
- Wave (.wav)
- AU (.au, .snd)
- AIFF (.aif, .aifc, .aiff)

Q. Where can I obtain detailed file format specifications?

A. One source is Encyclopedia of Graphics File Formats, second edition, by James D. Murray and William vanRyper, published by O'Reilly & Associates, Inc. That book describes MPEG-1, AVI, and some QuickTime file formats. See AVI 2.0 File Format Extensions for more information about DirectShow's support of this format.

Q. Does DirectShow provide video capture services?

A. Yes, DirectShow provides video capture.

Q. What version of Internet Explorer do I need to use DirectShow for Web content?

A. DirectShow is designed for Internet Explorer 3.x and later.

Q. What HTML tags would I use with DirectShow?

A. For information on the HTML tags to use to play movies using DirectShow, see Using the ActiveMovie Control in HTML Pages.

Q. Is there any sample code showing how to program DirectShow?

A. The DirectShow SDK includes sample source code in C, C++, and Microsoft Visual Basic®. For more information, see DirectShow Samples.

Q. What compiler do I need for DirectShow development?

A. DirectShow was designed with Visual C++® 5.x in mind, but any compiler capable of generating Component Object Model (COM) objects should work once the compiler's environment has been configured correctly. The base class libraries might need to be rebuilt to work completely since compilers can vary between versions.

Q. Do I need a compiler to play back movies?

A. No. Once DirectShow is installed, double-click any media file to view it. If you want more specialized applications, you can program DirectShow by using either C/C++ (in which case a compiler is required) or any Automation-compatible language (such as Visual Basic).

Q. When will DirectShow be integrated with Microsoft's operating systems?

A. DirectShow will be included in the next and future versions of Windows.

Q. Is the source for the ActiveMovie Control (Amovie.ocx) available?

A. No, the source is not available.

Q. What DirectX technologies are available on Windows NT?

A. Windows NT 5.x supports DirectX Foundation 5.x, including DirectDraw, DirectPlay®, DirectSound, Direct3D®, and DirectInput®. Windows NT 4.x supports DirectDraw, DirectPlay, and DirectSound.

Q. Can you recommend any reference books for Windows programming or COM?

A. Several books from Microsoft Press, including Advanced Windows by Jeffrey Richter and Understanding ActiveX and OLE by David Chappell, make great references for DirectShow developers.

Q. What is a GUID?

A. A globally unique identifier (GUID) is a 128-bit (16-byte) integer that an algorithm creates. The algorithm uses several criteria, including the current date, time, and a machine identifier, to ensure that it will be unique. GUIDs are used extensively in the Component Object Model (COM) and have an important role in DirectShow.

Q. How do I get a GUID?

A. GUIDs can be generated using Guidgen.exe. Guidgen, a Windows-native program, is included with Microsoft's Visual C++® products. Developers can also use Uuidgen.exe, a console application, in the Platform SDK.

Q. When do I need to call QueryInterface?

A. Whenever you need to obtain an interface for an object.

Q. What are some typical "getting started" problems with COM?

A. Some typical problems involving COM are:

- Forgetting to create a new GUID is a very common problem in filter development. For example, if you create a new filter based on one of the sample filters, you must create a new GUID for your filter. Otherwise, when you install your filter, it will overwrite the information that was already registered for the sample filter. Create a new GUID by using the Guidgen.exe tool.
- Omitting the address of (&)' operator in the last parameter of a call to QueryInterface or CoCreateInstance causes an exception when trying to use the object specified in that last parameter. The problem can be difficult to debug, because the void cast required prevents a compiler warning. The following example shows both the bad and the good syntax in a call to QueryInterface.

      IUnknown *pUnk;

      // bad -- you will hit an exception when you try to use pUnk
      // HRESULT hr = pObject->QueryInterface(IID_IPersist,
      //                                     (void **)pUnk); // <-- bad

      // good -- note the '&' is required for the last parameter
      HRESULT hr = pObject->QueryInterface(IID_IPersist,
                                           (void **)&pUnk); // <-- good

Redistribution Questions

Q. What parts of DirectShow can I redistribute?

A. The SDK includes a redistributable package under the Redist directory.

Q. Is the source to the Filter Graph Editor (Graphedt.exe) tool available? Can the Filter Graph Editor be redistributed?

A. No, the source is not available, and Graphedt.exe is not redistributable.

Q. How can I install the DirectX Media redistributables package from my application?

A. The DirectX Media redistributable package is called Dxmedia.exe. An application must register itself as a client of the redist package by running Dxmedia.exe with the -id switch and a unique identifier for the application, as shown in the following syntax:

    dxmedia.exe -id:identifier

The identifier should uniquely identify your application. It can be the GUID of your registered application, or a unique string. You should probably not use a string such as "game," but a more distinctive string. For example:

    dxmedia.exe -id:myrocketgame

— or —

    dxmedia.exe -id:my_GUID

The identifier is required. If you simply type "Dxmedia.exe" or simply double-click on the Dxmedia.exe icon, nothing will be installed.

The same syntax is used for all platforms, Windows 95, Windows NT x86, and Windows NT Alpha. Note that each processor has its own executable (either an Alpha or an x86 version).

If successful, the installation can return one of the following success codes:

- ERROR_SUCCESS — the installation completed successfully.
- ERROR_SUCCESS_REBOOT_REQUIRED — the installation was successful, but changes will not be effective until the system is rebooted.

If unsuccessful, the installation returns an HRESULT describing the error; for example, E_FAIL or E_INVALIDARG.

The installation is totally quiet, and no dialog boxes appear.

Q. Does the install/uninstall identifier need to be a GUID?

A. No, but it must be unique. GUIDs are essentially guaranteed to be unique.

Q. Does the install package handle different versions during install?

A. Yes, automatically. Files are only overwritten (after backup) if they use the same platform and are older than the files about to be installed.

Q. How does an application uninstall the DirectX Media package it installed during its own installation?

A. The redist package includes an uninstall executable called Purgedxm.exe. Uninstall by running Purgedxm.exe with the application's identifier that was used during install, as shown in the following syntax:

    purgedxm.exe identifier

Note: Do not use the -id switch when uninstalling.

Q. Does the redistributable DirectX Media run-time setup install DirectX?

A. It installs the DirectX Media run-time components. It also installs a minimum version of DirectX Foundation on x86 and Alpha platforms, as appropriate. The application can install DirectX Foundation separately if the full installation is needed, after the redistributable package has been installed.

Application Development Questions

Q. How can you detect whether DirectShow is installed on a given machine?

A. Use the following code fragment to detect whether DirectShow is installed. It assumes that you have already included the Streams.h header file and initialized the COM subsystem by using the CoInitialize function with a null parameter. It also assumes that you will uninitialize COM by using the CoUninitialize function before closing your application.

    IGraphBuilder * lpAMovie;

    HRESULT hr = CoCreateInstance(
    	CLSID_FilterGraph,
    	0,
    	CLSCTX_INPROC_SERVER,
    	IID_IGraphBuilder,
    	(void **) &lpAMovie );

    if (SUCCEEDED(hr)) {
        lpAMovie->Release();
        // DirectShow is installed
    } else {
        // DirectShow is not installed
    }

Q. Which interfaces do applications typically use?

A. IGraphBuilder, IMediaEvent, IMediaControl, and IVideoWindow.

Q. How do I change the owner of the video window?

A. Use the IVideoWindow::put_Owner method.

Q. How do I play a movie in a specific window?

A. Use IVideoWindow::put_Owner to specify the window you want. Set the style of the video window to include WS_CHILD using the IVideoWindow::put_WindowStyle method, and then position the video window inside your window using the IVideoWindow::SetWindowPosition method. The following sample code demonstrates this process.

    #include <windows.h>
    #include <streams.h>

    #define FILENAME L"C:\\WIN95.AVI"

    void PlayVideoInWindow(HWND hTargetWindow)

    {   // PlayVideoInWindow //

        CoInitialize(NULL);

        HRESULT hr;
        IGraphBuilder *pigb;

        // Create an empty filter graph object
        hr = CoCreateInstance(CLSID_FilterGraph,
            NULL,
            CLSCTX_INPROC_SERVER,
            IID_IGraphBuilder,
            (void **)&pigb);

        if (FAILED(hr))
            return;

        hr = pigb->RenderFile(FILENAME, NULL);

        if (FAILED(hr)) {
            pigb->Release();
            return;
            }   // Bail out, file probably wasn't found! //

        RECT rc;
        IVideoWindow *pivw;

        hr = pigb->QueryInterface(IID_IVideoWindow, (void **)&pivw);
        pivw->put_Owner((OAHWND)hTargetWindow);

        // Here's the key: we must set the required flags,
        //   AND set the position
        pivw->put_WindowStyle(WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS);
        GetClientRect(hTargetWindow, &rc);
        pivw->SetWindowPosition(rc.left, rc.top, rc.right rc.bottom);

        IMediaControl *pimc;

        hr = pigb->QueryInterface(IID_IMediaControl, (void **)&pimc);

        long l;
        IMediaEvent *pime;

        hr = pigb->QueryInterface(IID_IMediaEvent, (void **)&pime);
        pimc->Run();

        pime->WaitForCompletion(INFINITE, &l);

        // The following MUST be called otherwise nasty things can happen!
        pivw->put_Owner(NULL);

        pime->Release();
        pimc->Release();
        pivw->Release();
        pigb->Release();

        CoUninitialize();

    }   // PlayVideoInWindow

Q. Why doesn't my video always repaint correctly after being covered by another window?

A. You need to specify the WS_CLIPCHILDREN style for the video window's owner.

Q. When I try to build an application using DirectShow I get the following link error:

    Error LNK2001: unresolved external symbol IID_IGraphBuilder

I have included the Strfim.h file provided with the DirectX Media SDK but within Strfim.h IDD_IGraphBuilder is defined as an external. Why?

A. The symbols are defined in Strmiids.lib, which is one of the libraries located in the \LIB directory. You need to link this library into your project. See Build a Filter or Application with Visual C++ 5.x for information on how to do this in Microsoft Developer Studio. The VC5KIT kit in the \TOOLS directory also describes how to configure Developer Studio to build DirectShow-based applications.

Q. Where are the DirectShow-specific return codes (HRESULTs) defined?

A. The error return codes specific to DirectShow are found in Vfwmsgs.h, located in the DirectShow SDK Include directory. More general errors, such as error codes returned by CoCreateInstance, can be found in \Msdev\Include\Winerror.h if you have Microsoft Developer Studio. Vfwmsgs.h and Winerror.h also provide information about the layout of HRESULT values. Before you search for a particular error in Winerror.h, you might need to convert the low portion to decimal, depending on the error.

Q. How do I interpret errors from Visual Basic?

A. Calls to DirectShow object methods and properties can return error codes; these codes are stored in (and can be retrieved from) the Number property of the Err object. Error numbers can be returned in one of two forms: an DirectShow error or a Visual Basic run-time error code. DirectShow errors are referred to by number, starting at 0x80040200 (2147746304 in decimal). You can look up the error number by its hexadecimal value in the Include\Vfwmsgs.h header file. When Visual Basic can interpret the external object error, it generates a Visual Basic run-time error. For example, the E_INVALIDARG return code from an interface generates Visual Basic run-time error 5, "remote procedure call failed". In cases when Visual Basic cannot interpret a system error (such as E_ABORT), error 287 is returned in the Err object.

Q. Why does the filter graph manager return E_NOTIMPL when I call IVideoWindow methods?

A. The E_NOTIMPL return value indicates that no filter is in the graph that supports IVideoWindow. In other words, your graph does not contain a video renderer. One solution is to call the IGraphBuilder::Render method and allow the filter graph manager to automatically insert any necessary filters and complete the filter graph.

Q. Why does the filter graph manager return VFW_E_NOT_CONNECTED when I call IVideoWindow methods?

A. The VFW_E_NOT_CONNECTED return value indicates that the video renderer's input pin is not connected.

Q. I want to use the ActiveMovie Control to play a video, but I only want the image to show and not the toolbar or controls. How do I do this?

A. You can turn off the controls and display through the property pages. Or, you can change the options programmatically by setting the ShowControls and ShowDisplay properties to FALSE (0).

Q. How do enumerators work?

A. Enumerators are COM objects created to traverse an ordered set. The application or filter can call a method such as IEnumPins::Next to obtain an item from the set. Enumerators are usually matched to the data type they retrieve. In DirectShow, there are different enumerators to retrieve items such as filters, pins, and media types.

Q. How do I change a filter's settings without displaying the property page?

A. If the filter exposes a custom interface for this purpose, then you can access the filter properties. The DirectShow SDK includes a sample called Contrast, which exposes methods such as get_ContrastLevel and put_ContrastLevel to enable you to change its properties programmatically. For more details, see the implementation of Contrast's property page. You can find a description of the Contrast filter in About Effect Filters and Contrast Sample (Video Contrast Filter).

Q. Can I change the properties of the MPEG audio decoder without displaying its property page?

A. Currently the MPEG audio codec does not allow you to set its properties programmatically.

Q. Can DirectShow notify me of its current position on a regular basis?

A. There is no callback notification of position. Use a timer and poll for the current position by using the IMediaSeeking::GetCurrentPosition method.

Q. My application monitors the frame rate and sets a new frame rate every time a certain event takes place. However, playback stutters as the rate adjusts. How do I switch the rate smoothly?

A. Alter the time stamps instead of changing the frame rate.

Filter Development Questions

Q. What programming languages can filters be developed in?

A. You can write DirectShow filters in any language that can generate objects adhering to Microsoft's Component Object Model (COM). The base classes for DirectShow are written in C++.

Q. Can I develop my filter using the Microsoft Foundation Classes (MFC)?

A.The DirectShow class library is totally independent of MFC and contains most of the base classes you might need for filter development. See Build a Filter or Application with Visual C++ 5.x for information on how to build DirectShow applications with Visual C++. You can use the VC5Kit located in the Tools directory for assistance in building these applications.

Q. What are the differences between source, rendering, and transform filters?

A. Source filters form the point of origin for data, while rendering filters present the data in a final format on various devices such as a video card, audio card, disk file, and so on. Transform filters manipulate, modify, or alter the data in some way.

Q. How do I install my filter?

A. For information about how to install (self-register) a filter, see Register DirectShow Objects and the IAMovieSetup interface.

Q. Where do I install my filter on an end-user system?

A. You can install the filter anywhere you want, because the filter registration process records the filter's full path and file name at the time of registration. There is no need to put your filter in the Windows System or System32 directory.

Q. What causes the Filter Graph Editor to report that "The filter could not be created. Resources used by this filter might already be in use." when I try to insert a filter?

A. The Filter Graph Editor (Graphedt.exe) displays this message when it can't find the filter's .ax file. The filter has probably been moved, renamed, deleted, or was not properly set up. It needs to be properly registered. For information about how to self-register a filter, see Register DirectShow Objects and the IAMovieSetup interface.

Q. What is the resolution of time stamps in DirectShow?

A. The minimum resolution is 100 nanoseconds.

Q. Can a filter graph have only one filter that performs the work of source, transform, and renderer?

A. Yes, but to take advantage of DirectShow's "plug-in" nature, it is best to use different combinations of filters chained together. This also provides easier code reuse and flexibility in design, and is strongly recommended.

Q. Can I have a filter with many input and output pins (with some fixed one-to-one correspondence between them)?

A. Yes. Ensure that you implement the IPin::QueryInternalConnections method on every pin. Without this, the graph builder will assume that each input pin streams through to every output pin. While you can have a filter with many input and output pins, it's often more desirable to have several filters. Otherwise, you might find yourself writing more code (overriding more and more functions from the base classes) than if you just use an individual filter for each stream.

Q. Why does the graph builder stream each of my input pins through to every output pin?

A. This is the default behavior. Implement the IPin::QueryInternalConnections method on every pin to avoid this.

Q. Can I use a filter outside an DirectShow filter graph?

A. No, filters are integrated with the DirectShow architecture and require a filter graph.

Q. How do I determine the number of pins on a filter?

A. Call the IBaseFilter::EnumPins method, and then keep calling the IEnumPins::Next method until you don't get any more pins.

Q. At what privilege ring do filters run?

A. Filters in DirectShow run at user-privilege level three (ring three on x86 processors).

Q. How do filters communicate with one another?

A. Filters typically communicate with one another through their pins. Pins negotiate a common format and transport for exchanging data.

Q. Can I test my filter with the Filter Graph Editor (Graphedt.exe)?

A. Graphedt was designed to help filter developers visualize the connections and interaction between filters during filter development. It is not meant as a robust test platform.

Q. Can pin direction change dynamically?

A. DirectShow pins are not designed to have their direction changed. You could create two pins, one for each direction, and use a single piece of code to drive both pins.

Q. Why is the MPEG audio codec filter sometimes missing from an auto-rendered graph? How can the MPEG stream splitter audio output pin connect directly to an audio renderer?

A. Codec filters are only required by the renderer if the audio driver does not support a given audio format. Renderers often query the audio driver inside CheckMediaType to determine if the proposed format is supported, and if supported, pass the media samples directly to the audio subsystem when the graph is run. If the driver incorrectly indicates a format is supported, the most obvious symptom is garbled audio. You then need to get corrected drivers from your audio board manufacturer.

Q. My source/capture filter feeds streaming data from a network card into a filter graph. How do I get the DirectShow ActiveMovie Control to automatically use my source filter?

A1. If you want your source filter to be recognized like the DirectShow file and URL source filters, then use one of the methods below.

Method 1: Refer to your object using some protocol name you make up (for example, ABC). Add an entry in the registry under HKEY_CLASSES_ROOT\ABC, specifying the CLSID of your source filter. Your source filter will be used for your fictional ABC protocol, much like HTTP is used for internet addresses.

Method 2: Use a special file to start up your filter with a known set of bytes (for example a UUID you define yourself). Add the necessary check bytes to the registry under HKEY_CLASSES_ROOT\Media Type, making up your own major type, or stick with MEDIATYPE_Stream as other filters do and specify the proper subtype. Put your filter's CLSID in the Source Filter value. Check bytes are (decimal start, decimal length, mask (default all FF), hex value) so for a CLSID at the start you want (0, 36, , your CLSID). See Registering a Custom File Type for more information.

A2.If you want your capture filter to show up in the list of devices in a video capture application, see Write a Video Capture Filter.

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