Disclaimer: Experimental code using DirectShow with the .NET Framework 1.0

Abstract

This experimental code shows how to use DirectShow with .NET and C#. This includes simple media playback, playing DVD discs, capturing video streams to disk and a sample picture grabber.

Note, this article doesn't save you from reading the detailed DirectShow SDK documentation! I will not explain DirectShow, only some of the used .NET Interop technologies!

DirectShow

DirectShow is a standardized Microsoft Win32 API to use any compliant movie or video device from your application. DirectShow is available with the current DirectX version 8.1(b) for Windows 98/ME/2000 and included in XP. Please install the latest version, this article doesn't support anything except 8.1 :

Playback

The first sample included in the download is PlayWndNET. It plays the known video and audio file formats of DirectShow like avi, mpg, wav, mid etc.

DVD Player

For the next sample, DVDPlayerNET you must have a third-party DVD codec installed, like WinDVD or PowerDVD. Then, the C# sample uses the DirectShow DVD interfaces to watch the movie. It also supports menu navigation.

Grab Picture

The most complex sample provided is SampleGrabberNET. It shows a live video stream from a capture device like DV cam, web cam or TV card in a preview window. By pressing the 'Grab' toolbar-button, you can capture a still picture to a 24-Bit RGB bitmap file!

The sample also supports the IAMTVTuner interface of a TV card, so you can switch the TV tuner channel.

Capturing

The last sample, CaptureNET can be used to capture a live video stream to disk. Note, the few settings can only be done once at startup, and writing to the AVI file starts immediately.

Limitations

EXPERIMENTAL! don't use it in production quality code.

The samples only provide partial and very basic functionality.

I did most tests on Windows XP and few on Windows ME.

Tested only on a very limited set of devices with only few media formats. I used a Logitech QuickCam, Sony DV camcorder, Hauppauge WinTV PCI and WinDVD.

Get the latest driver (WDM) from manufacturer.

Some devices fail if you select unsupported settings in the dialogs.

This code will NOT help to solve any DirectShow/WDM configuration problems.

Share

About the Author

Comments and Discussions

Hello, thanks for your article, i'm using your library for display a preview from de tvtuner (full screen) and when is schedule show an avi file (if someone has done something similar plese let me know), i was reading a lot, but i found a problem that i can't solve, i need (at startup) to set programmatically the preview resolution to the max resolution accepted, I can read from videoSpecs, but i can't set it up...
I can do it from pin specs preview dialog..
please if know someting about it, let me know.
(my next challenge will be accept the remote control calls, have you ever done it?)
Thank you!!
(excuse my english)

Anyway, the answer to your question is that you will need to write a filter. "Filter" is a generic term used by DirectShow which encompasses a number of things: Compressors, Decompressors, video/audio capture devices, etc.

There are a number of sample filters included in the DirectShow sdk (now part of the platform sdk). Hopefully there is one there you can use as a starting point. Reading the docs makes it sound pretty complex, and I suppose it can be. However, the one time I had to create a filter, it didn't turn out to be too difficult.

Of course my needs were pretty simple, but there are a number of Base classes already written that make things pretty easy.

If you get stuck, you might have better luck posting your questions in one of these news groups:

There is a capture library at http://www.LimeGreenSocks.com/DShow[^]. It is based on Brian Low's work (another project here at CodeProject). In particular, look at VideoWindowResize() in CaptureTest.cs. This works in combination with onPreviewWindowResize() (from Capture.cs).

1. User select video device 1
2. The above piece of code run perfectly
3. While application is still running, user decided to view video from device 2
4. The above piece of code still run perfectly
5. Now, when user decided to switch back to device 1, I always hit "Parameter is in correct" error at ReaderStream() function above.

What could be the problem here? I did release all object before I re-attempt to render the stream? Is it because of memory leaking?

It sounds like the memory leak I ran into ages ago. My first suggestion would be to use the library at http://DirectShowNet.SourceForge.net[^]. Unlike the work the netmaster did which hasn't been updated in three years, the sourceforge stuff is actively being worked on.

However, if you wish to continue using the old stuff, the problem was in DsBugWO.cs. You need to add:

Hi,
I created a source filter and registered it properly.
I can even create an IBaseFilter object out of it.
I can also add it to the graph using
hr = graphBuilder.AddFilter( sourceFilter, "My source filter" );

The problem is that I can not cast it to any one of its other interfaces and therefore can not use it in the graph.
when I try to start the graph:
hr = capGraph.RenderStream( ref cat, ref med, sourceFilter, null, mux );
I get an error HRESULT.

In c++ everything works well... i can query on the intrface and use it.
any ideas ????

.Net use QueryInterface to cast COM Object so the problem probably come from your custom filter. Are you sure of its implementation ?

0x80070057 is the code of E_INVALIDARG (One or more arguments are invalid) and ICaptureGraphBuilder2.RenderStream is documented to return this code when an argument is invalid. Again, the troubles can come from your filter...

You might also want to take a look at the DirectShow library at DirectShowNet.SourceForge.Net[^]. Unlike the library here which hasn't been updated in ~3 years, we are actively doing work on that project.