HRESULT ConfigureVMR9(HWND window)
{
    assert(g_graph != NULL);

    HRESULT hr = S_OK;
    RECT rect;

    SmartPtr<IVMRFilterConfig9> filterConfig;

    // Create the VMR-9.
    FAIL_RET( CoCreateInstance(CLSID_VideoMixingRenderer9, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&g_filter) );

    // Configure the VMR-9.
    // Set the maximum number of video streams, and set windowless mode. 
    FAIL_RET( g_filter->QueryInterface(IID_IVMRFilterConfig9, reinterpret_cast<void**>(&filterConfig)) );

    FAIL_RET( filterConfig->SetNumberOfStreams( MAX_VIDEO_STREAMS ) );
    FAIL_RET( filterConfig->SetRenderingMode( VMR9Mode_Windowless ) );

    FAIL_RET( g_filter->QueryInterface(IID_IVMRWindowlessControl9, reinterpret_cast<void**>(&g_windowlessControl)) );
    FAIL_RET( g_windowlessControl->SetVideoClippingWindow( window ) );

    GetClientRect( window, & rect );
    FAIL_RET( g_windowlessControl->SetVideoPosition(NULL, & rect) );

    // Set the custom compositor on the VMR-9.

    g_compositor.Attach( new CMyCompositor9() );
    FAIL_RET( filterConfig->SetImageCompositor( g_compositor ));

    // Add the VMR-9 to the filter graph.
    FAIL_RET( g_graph->AddFilter(g_filter, L"Video Mixing Renderer 9") );

    return hr;
}
HRESULT SetAllocatorPresenter( IBaseFilter *filter, HWND window )
{
    if( filter == NULL )
    {
        return E_FAIL;
    }

    HRESULT hr;

    SmartPtr<IVMRSurfaceAllocatorNotify9> lpIVMRSurfAllocNotify;
    FAIL_RET( filter->QueryInterface(IID_IVMRSurfaceAllocatorNotify9, reinterpret_cast<void**>(&lpIVMRSurfAllocNotify)) );

    // create our surface allocator
    g_allocator.Attach(new CAllocator( hr, window ));
    if( FAILED( hr ) )
    {
        g_allocator = NULL;
        return hr;
    }

    // let the allocator and the notify know about each other
    FAIL_RET( lpIVMRSurfAllocNotify->AdviseSurfaceAllocator( g_userId, g_allocator ) );
    FAIL_RET( g_allocator->AdviseNotify(lpIVMRSurfAllocNotify) );
    
    return hr;
}