views:

140

answers:

2

I am having problems writing a good C++/DirectX9/DirectShow video player.

I have tried using the DirectShow samples and modifying them. I've tried VMR9 and TextureRenderer.

In all my attempts the video playback is choppy and jerky. In one case I got it nearly smooth, but the audio was out of sync!

Windows Media Player always manages to play back the files smoothly. How can I harness that magic?

Or is there something I should have done in my app? Setting up threading or similar?

I am using MSVC2008, Win7, trying to play back AVI and WMV files.

Thanks

Si

EDIT

bool VMR::RenderVideo(LPSTR fileName)
{
    if(!fileName && file == "")
        return false;
    file = fileName;
    CloseGraph();

    SmartPtr<IVMRFilterConfig9> pFilterConfig = NULL;
    if(FAILED(CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void**)&pGraph)))
    return false;
    if(FAILED(CoCreateInstance(CLSID_VideoMixingRenderer9, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&pVMR)))
    return false;
    if(FAILED(pVMR->QueryInterface(IID_IVMRFilterConfig9, reinterpret_cast<void**>(&pFilterConfig))))
        return false;
    //if(FAILED(pFilterConfig->SetNumberOfStreams(1)))
    //  return false;
    if(FAILED(pFilterConfig->SetRenderingMode( VMR9Mode_Renderless )))
    return false;
    if(FAILED(SetupAllocPresenter()))
        return false;
    if(FAILED(pGraph->AddFilter(pVMR, L"Video Mixing Renderer 9")))
        return false;
    if(FAILED(pGraph->QueryInterface(IID_IMediaControl, reinterpret_cast<void**>(&pControl))))
        return false;
    if(FAILED(pGraph->QueryInterface(IID_IMediaSeeking, reinterpret_cast<void**>(&pSeek))))
        return false;

    WCHAR wcTemp[256] = L"";
    ::MultiByteToWideChar(CP_UTF8, 0, file.c_str(), -1, wcTemp, 256);
    if(FAILED(pGraph->RenderFile( wcTemp, NULL )))
        return false;
    return true;
}
A: 

The performance difference is probably due to something you're not doing quite right, but I can't help you there, as I have zilch experience with DShow. You could look at

One difference between WMP12 (Windows 7) and WMP11 (Vista) and regular DShow is that the first two use the WMF (Windows Media Foundation) by default to decode/show supported formats. They are both able to use DShow filters as a fallback when the internal WMF "transforms" can't handle the input. But like I said, the lack of performance is probably not due to this difference. It might also be better to use the WMF for better future compatibility (if you leave Windows XP out of the question of course... WMF is not available there).

rubenvb
Thanks, for the links.I notice my output includes both ffdshow and WMF codecs. How so?ac3DX.ax'ffdshow.ax'WMADMOD.DLL'WMVDECOD.DLL'DShowRdpFilter.dll'
sipickles
I believe those are all DShow. WMP 11/12 will probably still include the DShow codecs, but uses WMF by default (or so I gather). When using DShow, you won't notice the WMF, for backwards compatibility (Windows XP). It might even be that the DLL's are used by both the DShow codecs and WMF, I have absolutely no development knowledge about these things, just know about DShow and WMF ;) and where they are used
rubenvb
A: 

Try doing a RenderFile and then QueryInterface'ing the IVMRFilterConfig9. Let the IGraphBuilder do the hard work. Its probably worth trying without getting the FilterConfig the first time to see what happens. Does it render properly? If so then you are getting somewhere. Next try getting the FilterConfig and setting the Windowless mode.

Goz