Sign in to follow this  
Frankie68

DirectShow: how to play MPEG2 files

Recommended Posts

Hi guys, Short question: when I use GraphEdit, I can render an MPEG2 file very simple: with File->Render Media File..., but when I do the same programatically, IGraphBuilder::RenderFile(...) fails. The used filters in graphedit are: "MPEG2 demultiplexer", "Intervideo noncss audio decoder for hauppauge" and "intervideo video decoder". I don't know what can be the problem, especially because calling RenderFile(...) with an AVI file works great. Also MPEG1 files can be rendered. I have spend a lot of time searching with google, also searching on this and other sites, all fruitless. So I am afraid that this is something that happens only on my computer. Has anyone experience with MPEG2 playback with DirectShow? And how did you do it? Thanks up front...

Share this post


Link to post
Share on other sites
Thanks for replying and sorry for the late reaction, but it returns 0x80040111.

I was unable to find this error code in the directx docs and VC.NET thinks it means "0x80040111: ClassFactory cannot supply requested class", this seems highly unlikely, to say the least.

Any help is strongly appreciated. :)

Share this post


Link to post
Share on other sites
Usually you would get that message if you have no decoder on the machine, but if it works in GraphEdit then that can't be it. Maybe post some code.

Share this post


Link to post
Share on other sites
Alright, because I know what the policy is on posting code (don't post 27 pages of it), I have stepped through the execution of my code and written down every DS related line.

Important note: even though it doesn't show in this code, every line returns an HRESULT and as soon it doesn't pass SUCCEEDED(...), I end the function and return FALSE. Because of that, I know for sure the first call that fails is RenderFile(bstrFileName, NULL), I just removed all the error checing code to please your eyes. :)


/*
* Defined in class interface (in .h file):
*
* - IGraphBuilder * m_pRenderGraph;
* - IMediaControl * m_pRenderControl;
* - IMediaEvent * m_pRenderEvent;
* - IMediaSeeking * m_pRenderSeeking;
* - IBaseFilter * m_pVideoRenderer;
* - IBaseFilter * m_pAudioRenderer;
* - IBasicAudio * m_pAudioControl;
*
*/


// In .cpp file:
CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void **)&m_pRenderGraph);
m_pRenderGraph->QueryInterface(IID_IMediaControl, (void **)&m_pRenderControl);
m_pRenderGraph->QueryInterface(IID_IMediaEvent, (void **)&m_pRenderEvent);
m_pRenderGraph->QueryInterface(IID_IMediaSeeking, (void **)&m_pRenderSeeking);
CoCreateInstance(CLSID_VideoMixingRenderer9, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **)&m_pVideoRenderer);
CoCreateInstance(CLSID_DSoundRender, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **)&m_pAudioRenderer);
m_pAudioRenderer->QueryInterface(IID_IBasicAudio, (void **)&m_pAudioControl);
m_pRenderGraph->AddFilter(m_pVideoRenderer, L"Video Renderer");
m_pRenderGraph->AddFilter(m_pAudioRenderer, L"Audio Renderer");
// ^^ Those all pass SUCCEEDED(...)

// sFileName is a CString (remember: this works with .avi files)
CComBSTR bstrFileName((LPCSTR)sFileName);
m_pRenderGraph->RenderFile(bstrFileName, NULL); // this one fails



Share this post


Link to post
Share on other sites
When you tried it on graphedit, did you also use the same filters you're adding on the code (VMR9 and DSound renderer)?

If not then I'd suspect the problem comes from your mpeg2 decoder filters not being compatible with VMR9 for some reason...

Share this post


Link to post
Share on other sites
I agree with Kamikaze, the graph must not be quite the same as when you prototyped in GraphEdit. This happens sometimes. What you need to do is add your graph to the Running Object Table and then look at it in GraphEdit while your app is running. See here for code and instructions. This will let you look "under the hood" and see exactly the graph that is being built for you.

Share this post


Link to post
Share on other sites
OK, that was a long day... thank you both for helping me.

I have tried a lot of things, even writing code that would build the graph the same way as graphedit does. Registering the graph with ROT was maybe the best idea, not even because it gave me new information (I already had copied the SaveGraph function from the DS sdk docs, so I could already see that only the source filter, and the two rendering filters were added).

But for some reason I also tried it outside of the debugger. When testing if my code works, I always run it inside the debugger, because pressing F5 is simpler than opening the .exe via windows explorer.

When I tried it now outside the debugger (I wanted to see if connecting to a graph then also works), it worked. So... some codecs don't work when used in the debugger. NeVideo.ax (mpeg encoder for Nero, Ahead Software) shows a message box ("Debugger detected"), but this particular codec just doesn't work.

Lesson learned today: when it doesn't seem work: also try it outside of the debugger. Even thought it may cost you some more time, it can help you excluding the influence of your debugger.

Thank you guys for helping me, I hope I can do the same for you one day. :)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this