Working with Multiple Video Streams

Oct 4, 2010 at 6:22 AM

Hi All,

Hoping someone might be able to point me in the right direction on how I would go about using MediaKit to render multiple video streams in WPF from a DirectShow graph.

We have a DirectShow application (using DirectShowLib) that renders multiple video streams from either a MPEG2 or Matroska container. Essentially, we build the graph, adding n (n = num of streams) windowless renderers and pass them the handle to the GDI windows we want the streams to render too. (pretty standard stuff).

So, what would be the steps (pseudo code welcome) for hooking up the same directshow graph to WPF "renderer" elements? 

TIA!

-Steve

PS. Is there somewhere that explains the architecture of MediaKit, just trying to get a good understanding on how it actually works?

Jan 10, 2011 at 4:42 AM
Edited Jan 10, 2011 at 5:52 AM

Ok, so I decided to revisit this and have made some progress, but still have one remaining issue. I've got rendering working, but I had to comment the TestCooperativeLevel() call in Vmr9Allocator.TestRestoreLostDevice() (called from PresentImage) because it was throwing an exception for every frame.

I created two classes that extend MediaPlayerBase and MediaElementBase, they look like this:

 

    public class MyMediaPlayerBase : MediaPlayerBase
    {
        public IBaseFilter GetVideoRenderer(IGraphBuilder graph)
        {
            IBaseFilter renderer = CreateVideoRenderer(VideoRendererType.VideoMixingRenderer9, graph);
            return renderer;
        }
    }

 

and

 

    public class MyMediaElementBase : MediaElementBase
    {
        public IBaseFilter GetVideoRenderer(IGraphBuilder graph)
        {
            return ((MyMediaPlayerBase)MediaPlayerBase).GetVideoRenderer(graph);
        }

        protected override MediaPlayerBase OnRequestMediaPlayer()
        {
            var mmpb = new MyMediaPlayerBase();

            return mmpb;
        }

    }

 

then, in my application, I do:

                ... // Build DirectShow graph
                MyMediaElementBase mmeb = new MyMediaElementBase();
                previewWindow.AddVideo(mmeb);

                IBaseFilter wpfrenderer = mmeb.GetVideoRenderer(m_graph); // the returned renderer is added to the graph
                ... // Connect up the renderer

 

finally, make the following change to TestRestoreLostDevice() in Vmr9Allocator.cs (in the WPFMediaKit library code)

-            int hr = m_device.TestCooperativeLevel();
+            int hr = 0; // m_device.TestCooperativeLevel();

 

This then renderers video to my WPF app.

However, if I don't make the above change to Vmr9Allocator.cs, the following exception is thrown (continuously, for every frame):

Unable to cast COM object of type 'System.__ComObject' to interface type 'WPFMediaKit.DirectX.IDirect3DDevice9'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{D0223B96-BF7A-43FD-92BD-A43B0D82B9EB}' failed due to the following error: No such interface supported (Exception from HRESULT: 0x80004002 (E_NOINTERFACE)).

which makes absolutely no sense to me (I know what the exception means, but no idea why it would be occurring).

What is even more confusing is the WFPMediaKit sample application works absoulely fine without needing to comment out TestCooperativeLevel(). 

 

Has anyone got any ideas? Is there some additional setup I need to do with IDirect3DDevice9 (m_device) or something?

TIA

-Steve

 

Jan 12, 2011 at 1:49 PM

Hi Steve,

I would be very interested in a sample project of the work you have done.... (would it be possible to get it?? or maybe a more complete code than in your post)

I'm a newbie in context of DirectShow. So complete source code base of WPfMediakit would really beneficial.

My approach up to now was to use DirectShowLib and to build a VideoRenderer based on the VMRPlayer (from Windows SDK examples).

But the quality of video rendering is really bad. So I have to try another approach.

Could anybody give me a hint which direction is the best (in terms of quality of video output and ease of development)

TIA

Martin

 

 

 

 

Jan 14, 2011 at 12:55 AM

Hi Martin,

Unfortunately i'm not in a position to give out source code, but I can certainly give you some pointers.

If you're familiar with DirectShowLib and can build a basic graph in code, then you're most of the way there. When it comes to adding a renderer to the graph, instead connect up the one you get from MyMediaElementBase.GetVideoRenderer().

The quality of your video is most likely a result of the compression you are using, not the renderer. Experiment with different compressor filters and/or increase the compression bit-rate and resolution.

For combining multiple streams in sync, look at the Matroska or MPEG2 container formats. 

HTH

-Steve

Jan 14, 2011 at 5:55 AM

Hi Steve,

thank you very much for your hints...

I'll try it.

Regards,

Martin

 

 

 

Apr 10, 2012 at 2:14 PM
Edited Apr 16, 2012 at 4:00 PM

Hello 

I am trying to setup the "MyMediaElementBase" and "MyMediaPlayerBase", which all goes fine.  But in the end, what is the "previewWindow" to which you add the myMediaElementBase to?

Greetings

Steven

EDIT: didn't know it was the mediaelementbase which has to be added to the wpf window ...