The Artima Developer Community
Sponsored Link

.NET Buzz Forum
DirectShow and C#

0 replies on 1 page.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 0 replies on 1 page
Eric Gunnerson

Posts: 1006
Nickname: ericgu
Registered: Aug, 2003

Eric Gunnerson is a program manager on the Visual C# team
DirectShow and C# Posted: Sep 20, 2004 6:06 PM
Reply to this message Reply

This post originated from an RSS feed registered with .NET Buzz by Eric Gunnerson.
Original Post: DirectShow and C#
Feed Title: Eric Gunnerson's C# Compendium
Feed URL: /msdnerror.htm?aspxerrorpath=/ericgu/Rss.aspx
Feed Description: Eric comments on C#, programming and dotnet in general, and the aerodynamic characteristics of the red-nosed flying squirrel of the Lesser Antilles
Latest .NET Buzz Posts
Latest .NET Buzz Posts by Eric Gunnerson
Latest Posts From Eric Gunnerson's C# Compendium

Advertisement

I'm currently in the "ramping up" phase of my job, and last week I spent a fair amount of time playing around with DirectShow from C#.

DirectShow is an interesting technology that provides a sort of "building block" approach to multimedia. You create a DirectShow graph, populate it with different filters, hook them together, and start the whole process in motion. DirectShow handles the mechanics of getting the different parts talking to each other so data can flow through the system.

If, for example, you wanted to capture some audio and save it to the disk in WMA format. You'd start with an audio input filter, which has an output pin. You'd wire that output pin to the input pin of a WMA encoder, and then wire the output pin of the encoder to the input pin of the FileStream filter, and that would give you the basic graph. Select which input you want, tell the graph to play, and your app is up and savin' data.

Want to add a little reverb? Hook in the reverb filter.

Video is similar - you hook things up together, and DShow handles passing things around. There's a cool workbench app named GraphEdit (graphedt.exe) that lets you graphically play around, and is a great way to find out what works before you write code.

All of this is explained quite well in "Programming Microsoft DirectShow for Digital Video and Television"

There are some managed DirectX wrappers in the DX9 SDK, but there aren't any available for DirectShow. I think I know why, but I'll save that for later...

I set out to try to use C# from DirectShow, to emulate some of the C++ samples. The first problem is defining the COM interfaces. I've spent some time trying to define interfaces by hand in the past, but that hasn't been very successful. I searched for a typelib, but didn't find one.

I did, however, find something that is a little better - the .IDL files. IDL files provide the definition of COM interfaces, and in this case are used to generate the C++ header files. They can also be used as input to MIDL, which produces a type library, which can be consumed by tlbimp to produce managed wrappers, which allows us all to go home early.

They can if they've been set up to do that. But this IDL wasn't authored to produce a typelib, so it doesn't generate one by default. To do that, you need a library statement, which tells MIDL what to put in the typelib. Here's what I put in an IDL file:

import "devenum.idl";
import "axcore.idl";
import "axextend.idl";

[
uuid(22995cc9-e37e-4b96-9326-b418935ac4be),
helpstring("DirectShow interfaces")
]
library DirectShow
{
    interface IFilterGraph;
    interface ICreateDevEnum;
    interface IGraphBuilder;
    interface ICaptureGraphBuilder2;
    interface IFileSinkFilter;
    interface IFileSinkFilter2;
    interface IAMAudioInputMixer;
};

You have to have a GUID there for it to work.

When run through MIDL, this gave me the typelib, which gave me a wrapper with some of the types I needed. You'll also need to add quartz.dll from windows\system32, which does have type information, so that you can get some of the other types.

Once you've got that set up, you can start writing code. The C++ COM code in the samples is like most C++ COM code - ugly and hard to understand. But it's not that bad in C#.

To create a COM object, you need to write:

Type t = Type.GetTypeFromCLSID(guid);

IGraphBuilder graphBuilder = (IGraphBuilder) Activator.CreateInstance(t);

The guid is a Guid instance, and you get the Guid to use by looking in the include files or copying it from GraphEdit. That's a bit ugly, so I wrote this little helper function:

private T CreateComObject<T>(Guid guid) where T: class|
{
    Type comType = Type.GetTypeFromCLSID(guid);
    object o = Activator.CreateInstance(comType);
    if (o == null)
        return null;

    else
        return (T) o;
}

Which then allows me just to write:

IGraphBuilder graphBuilder =
       CreateComObject<IGraphBuilder>(CLSID_FilterGraph);

That's a nice little use of a generic method.

Sometimes, you want an interface off an object rather than a new object. You can do that through a simple cast.

Up to this point, things are fairly easy, and it makes you wonder why there's no managed interface to this stuff. Some of the real power comes when you want to write a filter, which could do something convert a picture to grayscale. While one could write a filter in C#, one would have to be pretty daft to try it, given that there are lots of helper classes in C++ that you'd have to rewrite in C++ (ok, perhaps MC++ could help...). My guess is that that's why there are no managed wrappers.

 

Read: DirectShow and C#

Topic: Irish developers Previous Topic   Next Topic Topic: MVPBLOGs at Microsoft India Community Home

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use