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.

I have implemented the DVDPlayerNET example in my freeware open source program, SubtitleCreator, which allows users to create new subtitles for DVDs, or manipulate existing ones. However, I don't know how to show a new subtitle on top of the DVD output - as this is only a hobby project of mine, I would rather not study the complete DirectX SDK, and I was wondering if someone could show me how I can overlay a (mostly transparent) bitmap on top of the DVDPlayerNET output surface.

I've got two samples that show how to superimpose on a video stream on my website. However, one reads from a file, and the other works from a capture device.

Whether these samples will be useful to you depends on whether the Sample Grabber can be added to the DVD graph. Frankly, I haven't ever tried. How familiar are you with capture graphs? Do you have GraphEdit (from the DirectX SDK)?

I've seen your updates on LimeGreenSocks, and I am using your new DShowNET version, but unfortunately they don't use the DVD player. Futhermore, as I am not familiar with DirectX, it wasn't obvious to me how to add them. GraphEdit is something I have seen in the SDK, but no idea how to put an existing program in there. DVDPlayerNET also uses a dvdGraph variable, so probably the final solution will be very simple (add a final filter to the dvdGraph, which overlays a transparent bitmap), but I have no clue of how to do it... My 2 cents is that it should be added to the function below, although the other possibility is bool FirstPlayDvd(). Any suggestions?

I've just tried your code, and it fixed the obsoleteness problem - thanks for that! I will see if I can use the GraphEdit program, but it didn't seem to be the easiest tool in the shed...

BTW, does the DShowNET library have any limitation? More specifically, when running DVDShrink, the DVDPlayerNET cannot open a DVD anymore, and it responds with the following error "Could not get interfaces! No such interface supported".

First of all, you can forget about using the Sample Grabber. The only place you can hook in the sample grabber is *before* the MPEG decoder. And trying to overlay a bitmap on the encoded stream is a losing proposition, so forget that.

On the plus side, I've got a bitmap overlaying on the dvd output (Yea!). However, there are limitations. How big a problems these limitations are depends on your requirements.

The overlay mixer (which is already being used to display the dvd image) is happy to mix in another stream. This is the widget that mixes the regular dvd video with the closed captions and dvd subpicture. Unfortunately, it doesn't provide any blending. Or, to quote the docs:

The value of the dwBlendingParameter parameter must be between 0 and 255, where 0 makes the secondary stream invisible and 255 makes the primary stream invisible in the area that the secondary stream occupies. If no value is set the default is 255.

Note Current DirectShow implementation of this interface allows only values of 0 or 255 for the dwBlendingParameter parameter. Any other values are invalid.

That's limitation #1. The docs seem to imply that if your video card supports it, you may be using the VMR instead of the overlay mixer. That may give you more options, but my card is using the overlay mixer, so I can't say.

Limitation #2 is where the "stream" containing the bitmap comes from. I'm using one of the samples from the Microsoft DirectX SDK: PushSourceBitmap. While this file has an .AX extension, it is really a DLL, and will need to be distributed and regsvr32'ed.

Limitation #3: As written, the location of the bitmap file PushSourceBitmap uses is hardcoded to a specific location. However, the source code is included, so modifications are possible. This file is pretty short (~400 lines) and contains copious comments and whitespace.

Damn, you are good - not in a 100 years would I have found that!!! When I get it working, I will add you to SubtitleCreator's About box as an important contributor. We (actually, you, as you are contributing the knowledge) could even add a new sample to this DShowNET toolbox, a DVDplayer which can overlay text subtitles...

But just to confirm that I understand you:
- WRT the blending of bitmaps: if the bitmap (second stream) itself is a full screen 32bpp (transparency+RGB), only opaque where the subtitles are, setting the dwBlendingParameter to 255 should be OK: it will only show the bitmap (i.e. subtitles) in the locations where they are.
- PushSourceBitmap: another complication I didn't think about. Instead of having to deal with static bitmaps I can turn on and off at certain times, as subtitles normally do, I have to create a stream of bitmaps. I will download the code and play with it.

BTW, you say you've got it working on a DVD - I would really appreciate it if you could send me a copy of the project, so I can directly change it from there. It's complicated enough that I want to try it on a separate project first before I integrate it into my program...

The DirectShow samples have migrated into the Platform SDK (but only the very latest version). You will find them in: Microsoft Platform SDK\Samples\Multimedia\DirectShow\Filters\PushSource. Note that you will need to build the "BaseClasses" project first.

I have been playing with this for a while now, and it is great stuff. The question that I have is that in all the players, including the one that I am building, if the graph is paused, I can't seem to move the position of the window.

I am using a class similar to the capture class with minimal calls, and have a playerwindow.Resize event handler, but it doesn't seem to want to move the position with it? that event only seems to be fired if the graph is playing, and I don't understand why...any insight?

But its abit different from DirectShow.Net. the version i got from this codeproject web page.

its actually promping errors when i use this DirectShowLib. is there any other way to fix the clean close? Coz my team is urgentlt needing this directshow component. so not much time to reaseach on the totally new one. Thanks vr much again lgs.lsg.

Hi, I'm trying to implement IVMRMixerBitmap from the idl but I'm stuck in the surface LPDIRECTDRAWSURFACE7 of the structure VMRALPHABITMAP .
Someone has do this? Or want to complete the remains intefaces of VmRender.idl

Hi,
A couple of days ago I knew nothing about DirectShow etc. Now I need to modify some C# code to mask-out part of a video (the top left-hand quarter, say). I've been trawling the web to find examples, but so far, nothing. I did find an example using the VMR to show one video on top of the other, which might do the trick but it was all in C++ and total gibberish to me.

Can anyone point me to any examples of C# code which will do what I want. i.e. mask-out a section of the picture, either using VMR9 or any other method.