|What can be done with DirectShow and C#|
We would like to start by asking why there is no managed wrapper for DirectShow.
The DirectShow SDK documentation contains a FAQ with this answer: "There are no current plans to implement a "Managed DirectShow" platform. You can use COM interop to create DirectShow client applications in managed code, but creating filters that depend on the Common Language Runtime (CLR) is not recommended for performance reasons."
Should we buy this answer like it would be "words from the Gospels"? I like the motto "trust but verify". One thing is sure, when we create a GraphBuilder object and run a stream through it, we end up creating a lot of threads and mixing native COM and managed code might not be an ideal mix for people who don't want to work more than what they have to get the job done.
So, we're not going to write filters in C#. But DirectShow client applications are an interesting possibility. The SDK already contains samples written in VB and there is no reason why we couldn't write similar applications in C#. So how do we go about it. There are a few samples at www.codeproject.com that use C# and DirectShow.
The easiest way to write a DirectShow client application is simply to wrap the library "quartz.dll" (with the tool tlbimp from the .Net SDK or by adding a reference to in a VS project). That's the easiest way but the methods we'd like might not be exposed this way. So we have a couple of alternatives. There a library called "FSFWrap.dll" that adds some of the missing APIs or we can look at DShowNet (available on the CodeProject web site).
Playing a file using DirectShow in C++ is illustrated in the SDK documentation as:
Here's is the equivalent code in C# using interop and quartz.dll:
We declare the namespace QuartzTypeLib and we reference it on the command line (the command line to compile this program is: csc /r:Interop.QuartzTypeLib.dll PlayFile.cs). We passed the file name to play on the command line instead of hardcoding the name in the source as the example from the SDK. Also the first argument to WaitForCompletion is -1 because INFINITE is defined as 0xfffffff.
The interop version uses the FilgraphManagerClass to do all the work.
.Net Master (at CodeProject) decided that the COM interfaces for DirectShow are sufficiantly simple to write wrappers for them using the IDL provided with the SDK. The advantage of this approach is that you have more control on which members of the interfaces that you can access. The disadvantages are the code can be rather ugly and you have to think in term of native COM and managed code at the same time. Here is a C# version using DShowNet from .Net Master at CodeProject:
The call to GetTypeFromCLSID of the Type class, the call to CreateInstance of the Activator
class and ReleaseComOjbect of the Marshall class are examples of what I meant by having
to keep track of native COM and managed code. If the DShowNet implementation give you
access to what you need but not the plain Quartz interop. Then DShowNet is the way
At the moment, there is a Beta version of an open source extension to the DShowNet library. When the final version will be released, we'll look at the possibility to update our code using this new library.
We'll stop here for our first look at DirectShow and C#.