GNU tools and the DirectShow API

Directory
Code fixes
Base classes
Linking
Download
Author's home page
This page provides some information and source code on using the DirectShow API with the free gcc compiler. During my testing, I've mostly used the mingw port of gcc, but Cygwin should work as well. There are a few tricks to getting it all working, so you might find this introduction (and maybe some of the code) useful.

Note (2003/08/18): the code presented hear seems to be broken with the latest version of the w32api package, so if you have a new version of w32api (e.g. v2.3) and get lots of compile errors on things like DWORD or HINSTANCE with this code, you have a problem. I might get to fix this in the next couple of weeks, but better yet, why not fix it yourself and email me the changes.

Note also that I've only used the DirectX 8.1 SDK, so other versions may have different issues to those described here. You can (used to be able to) download the SDK, which includes DirectShow, from Microsoft if you have access to enough bandwidth. In my case, the people at Microsoft actually sent me a CD in the post! Why not ask them, maybe they'll oblige.

Code fixes

Unfortunately, there are some parts of the Microsoft supplied base classes (and even the DirectShow headers) that are not standard C++ compliant. The GNU compiler can handle some of these problems, like for-loop variable scope, but not others. Here's a list of the necessary changes to the Microsoft code (remember, this applies specifically to the DirectX 8.1 SDK):

In the DXSDK/include directory:

In the DXSDK/samples/Multimedia/DirectShow/BaseClasses directory:

  • ctlutil.h, at line 278, in the definition of class COARefTime, the (unimplemented) assignment from long must have a return type. e.g.:

    COARefTime &operator=(LONG);

    At line 358, g++ doesn't like the declaration of the function GetSeekingLongLong in class CPosPassThru. You can fix it by removing the __stdcall attribute, e.g.:

    HRESULT GetSeekingLongLong
      ( HRESULT ( IMediaSeeking::*pMethod)( LONGLONG * ),
      LONGLONG * pll );

  • ctlutil.cpp at line 665 make the corresponding change to the definition of the GetSeekingLongLong member function by removing the __stdcall attribute:

    HRESULT
    CPosPassThru::GetSeekingLongLong
    ( HRESULT(IMediaSeeking::*pMethod)( LONGLONG * )
    , LONGLONG * pll
    ) {

  • ddmm.cpp at line 21 has the same name-reuse problem as the strmif.h header. It should look like this:

    typedef struct {
     LPSTR szDevice;
     ::GUID* lpGUID;
     ::GUID GUID;
     BOOL fFound;
    } FindDeviceData;

  • wxdebug.cpp at line 530, the variable g_dwLastRefresh must be defined with a type (which should presumably be DWORD).

    At line 1081, the code seems to rely on a Microsoft extension to allow one constructor to call another from within the constructor body. What I did was cut and paste the other constructor's body in place of the explicit call. The exact details are included in a patch script contained in the download.

Actually, things could have been a lot worse, considering the differences between the Microsoft compiler and g++. The make script included in the download performs all of the given patches to the microsoft files if you run make fix in the BaseClasses directory.

1the relevant section of the 1998 C++ standard is section 3.3.6, paragraph 1, item 2 in the list.

DirectShow Base Class library

After fixing the code problems described above, it should be possible to compile the DirectShow base classes. This isn't always necessary, depending on what kind of code you want to develop, but it's a good test of your compilation environment anyway.

Here's the sort of command line I ended up with:

f:/mingw/bin/gcc \
    -g -O2 -w -fno-for-scope -mthreads \
    -DRELEASE \
    -I d:/DXSDK/include \
    -I d:/DXSDK/samples/Multimedia/DirectShow/BaseClasses \
    -include mingw_dshow_port.h \
    -c -o cprop.o \
    d:/DXSDK/samples/Multimedia/DirectShow/BaseClasses/cprop.cpp
Details of the relevant compiler options are as follows:

-w -fno-for-scope Disable warnings and use the old (Microsoft-compiler-compatible) for-loop scoping.
-mthreads Enable thread support. For video capture at least, DirectShow is inherently multi-threaded.
-DRELEASE Define the RELEASE macro to compile in release mode.
-I d:/DXSDK/include The location of the DirectX API headers (including DirectShow). This will likely be different on other installations.
-I d:/DXSDK/samples/ Multimedia/DirectShow/ BaseClasses Location of the base class headers.
-include mingw_dshow_port.h Include this header automatically at the start of each module. More details below.

If I remember rightly, there were some compilation problems using -DDEBUG which I didn't really investigate, so I suggest using release mode as shown (post me some news if you have more information on this).

Generally, any code of yours that directly or indirectly includes dshow.h will also need the same kind of command line options, including turning off the warnings. This is a good reason to encapsulate any DirectShow code behind a compilation firewall, so that you can compile more of your modules with warnings enabled.

The mingw_dshow_port.h header contains the following:

#include <wtypes.h>
#include <unknwn.h>
#include <ole2.h>
#include <limits.h>

#define _WINGDI_ 1
#define AM_NOVTABLE
#define _OBJBASE_H_
#undef _X86_
#define _I64_MAX LONG_LONG_MAX

The need for these includes probably indicates some incompatibilities between the Windows API headers that gcc uses and the real Microsoft ones. I stopped asking questions once I got it working :-)

Linking

Linker commands wind up looking something like this on my system:
f:/mingw/bin/gcc \
    -L d:/DXSDK/lib \
    vidutils.o ... \
    BaseClasses/strmbase.a \
    -lstrmiids -lole32 -loleaut32 \
    -lwinmm -luuid \
    -lstdc++ -o vidutils

I also include the boost thread library and a few other things not shown here, but I think that gives you the basis of it. Of course, you can't actually do very much with the API without some general knowledge about COM and the Windows Platform SDK. Without the MFC or ATL, you generally have to do things the hard way, but some of my sample code could be useful.

Download

The code available for download was not originally intended for general consumption, so not all of it is well commented. I wrote parts of it when I first started using DirectX, other parts are relatively new and correspondingly better written. Please send me an email if you notice any problems using this code.

The contents of this file are licensed for non-commercial uses only - please respect this and don't use it if you intend to write applications for profit. The download file is dshow.tar.gz (43kB).

Installation involves unpacking the archive and fixing up some pathnames in cxx/Makefile.inc to suit your system. You should then be able to go the the cxx/DShow/BaseClasses sub-directory and run

make fix
make all

This will first patch some Microsoft sources (as described above) and then build the strmbase.a library. I wrote the patches for the DirectX 8.1 SDK, so don't run make fix if you have a different version installed.

If you've got the boost libraries installed, you should also be able to build some of my sample code by running make.sh in the installation root directory. There are two sample applications included:

hwinfo Dumps textual information about the installed video capture hardware, attempts to capture a still image from each device and dumps them out as ASCII art. Alright!
vidutils This will only work if you install libpng and libz and fix the relevant macro defs in Makefile.inc. It can capture real-time video to a raw binary file which you can later reprocess into black and white .png graphics files (using various command-line options).

OK, the applications are pretty lame, but they were only intended as test beds and utilities for my video modem development work. vidutils only works in black and white (it ignores the colour components in the YVU9 video format) because that's how the video modem code works. It wouldn't be hard to modify this, though.

Contact information

This page is copyright (c) 2003 by Raoul Gough. Please send any comments or requests to RaoulGough@yahoo.co.uk.