4

I am working on an application at the moment that plays back video with a DirectShow filter. The application is written in WPF and is using MediaElements to play the video. As long as the DirectShow filter is registered the video will play. At the moment I just use regsvr32 to register the filter before playback.

What I was wondering is if it is possible to load the filter from an embedded resource when the application is run? I am trying to avoid needing administrator privileges to register the filter.

Edit:

Ok I'm trying to use this information and come up with a solution. You will have to excuse my lack of knowledge in the DirectShow area. I did not write the filter, I am just trying to come up with a solution using it. I am trying to do a little more research so I understand DirectShow and its components a little better.

I found a handy ComHelper class that I'm using to load the filter.

https://gist.github.com/jjeffery/1568627

I am using the code below to create an instance of the filter.

LibraryModule module = LibraryModule.LoadModule(@"filter.ax");
var comObject = ComHelper.CreateInstance(module, new Guid("c91aa7be-f627-46e3-b79f-2de55da46a8b"));

Is this correct? I'm trying to figure out where to go next. How would I use this to build the filter graph?

thecaptain0220
  • 2,098
  • 5
  • 30
  • 51
  • I use this, but access violation exception occurs when application exit. If I use the same registered filter, exception doesn't occur. Do you know how to fix this? – Ngo Phuong Le Apr 15 '15 at 12:23

1 Answers1

1

Building a filter graph using unregistered filters is possible, but you have to be aware of obstacles and then decide whether it is acceptable or not.

DirectShow filters are COM objects with relaxed requirements for threading. That is, adding filters to graphs does not require full COM registration. Graph's IGraphBuilder::AddFilter will accept an interface pointer of your filter without asking you how you obtained it. This means in particular that if you take care of filter instantiation and then you build the graph manually adding filter and connecting pins - this will definitely work out well.

Filters, that you don't want to be registered, can be otherwise instantiated by creating C++ object directly, or by loading DLL and using its DllGetClassObject exported function the way COM would do it with instantiation through registration.

Another note is that COM class can be registered "per-user" without need to have administrator privileges, and such registration enables standard CoCreateInstance instantiation (but not Intelligent Connect - see below).

The typical problem on the way is scenario when you expect a filter of your interest, such as video/audio decoder, to be added automatically via DirectShow Intelligent Connect. This only works with full COM registration, or the alternate option is API hooking which I omit here. To cut long story short: if you are not registering the filters, you have to instantiate and add them to the filter graph yourself, via code.

A final note on embedding. The filter will still be hosted by DLL, so you will have to load executable code into memory. This means that you cannot load it "from resource" directly. Although there are certain methods to build executable DLL image right in memory, the easiest would be to keep filter DLL with you and load it as regular DLL from external file using LoadLibrary. If you prefer to have single binary, you can embed the DLL as binary resource, then extract into temporary file on runtime and then continue with LoadLibrary from there.

See also:

Community
  • 1
  • 1
Roman R.
  • 68,205
  • 6
  • 94
  • 158