示例#1
0
文件: dsmixer.cpp 项目: harada3/krkrz
//----------------------------------------------------------------------------
//! @brief	  	フィルタグラフの構築
//! @param 		callbackwin : メッセージを送信するウィンドウ
//! @param 		stream : 読み込み元ストリーム
//! @param 		streamname : ストリームの名前
//! @param 		type : メディアタイプ(拡張子)
//! @param 		size : メディアサイズ
//----------------------------------------------------------------------------
void __stdcall tTVPDSMixerVideoOverlay::BuildGraph( HWND callbackwin, IStream *stream, const wchar_t * streamname, const wchar_t *type, unsigned __int64 size )
{
	HRESULT			hr;

	//CoInitialize(NULL);

	// detect CMediaType from stream's extension ('type')
	try {
		if( FAILED(hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED)) )
			ThrowDShowException(L"Failed to call CoInitializeEx.", hr);

		// create IFilterGraph instance
		if( FAILED(hr = m_GraphBuilder.CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC)) )
			ThrowDShowException(L"Failed to create FilterGraph.", hr);

		// Register to ROT
		if(GetShouldRegisterToROT())
		{
			AddToROT(m_dwROTReg);
		}

		{
			CAutoLock Lock(&m_VMRLock);
			OwnerWindow = callbackwin;	// copy window handle for D3D
			m_OwnerInst = GetModuleHandle(NULL);
		}
		m_AllocatorPresenter = new CVMRCustomAllocatorPresenter9(this,m_VMRLock);
		m_AllocatorPresenter->AddRef();
		m_AllocatorPresenter->Initialize();
		if( IsWindowsMediaFile(type) )
		{
			CComPtr<IBaseFilter>	pVMR9;
			AddVMR9Filer( pVMR9 );
			BuildWMVGraph( pVMR9, stream );

			if( FAILED(hr = pVMR9.QueryInterface( &m_VMR9MixerCtrl ) ) )
				ThrowDShowException(L"Failed to query IVMRMixerControl9.", hr);
			if( FAILED(hr = pVMR9.QueryInterface( &m_VMR9MixerBmp ) ) )
				ThrowDShowException(L"Failed to query IVMRMixerBitmap9.", hr);
		}
		else
		{
			CMediaType mt;
			mt.majortype = MEDIATYPE_Stream;
			ParseVideoType( mt, type ); // may throw an exception

			// create proxy filter
			m_Proxy = new CIStreamProxy( stream, size );
			hr = S_OK;
			m_Reader = new CIStreamReader( m_Proxy, &mt, &hr );
			if( FAILED(hr) || m_Reader == NULL )
				ThrowDShowException(L"Failed to create proxy filter object.", hr);
			m_Reader->AddRef();

			// add fliter
			if( FAILED(hr = GraphBuilder()->AddFilter( m_Reader, L"Stream Reader")) )
				ThrowDShowException(L"Failed to call IFilterGraph::AddFilter.", hr);
	
			// AddFilterしたのでRelease
			m_Reader->Release();

			if( mt.subtype == MEDIASUBTYPE_Avi || mt.subtype == MEDIASUBTYPE_QTMovie )
			{
				// render output pin
				if( FAILED(hr = GraphBuilder()->Render(m_Reader->GetPin(0))) )
					ThrowDShowException(L"Failed to call IGraphBuilder::Render.", hr);
	
				CComPtr<IBaseFilter>	pRender;
				if( FAILED(hr = FindVideoRenderer( &pRender ) ) )
					ThrowDShowException(L"Failed to call FindVideoRenderer( &pRender ).", hr);
	
				CComPtr<IPin>	pRenderPin;
				pRenderPin = GetInPin(pRender, 0);
	
				// get decoder output pin
				CComPtr<IPin>			pDecoderPinOut;
				if( FAILED(hr = pRenderPin->ConnectedTo( &pDecoderPinOut )) )
					ThrowDShowException(L"Failed to call pRenderPin->ConnectedTo( &pDecoderPinOut ).", hr);
	
				// dissconnect pins
				if( FAILED(hr = pDecoderPinOut->Disconnect()) )
					ThrowDShowException(L"Failed to call pDecoderPinOut->Disconnect().", hr);
				if( FAILED(hr = pRenderPin->Disconnect()) )
					ThrowDShowException(L"Failed to call pRenderPin->Disconnect().", hr);
	
				// remove default render
				if( FAILED(hr = GraphBuilder()->RemoveFilter( pRender ) ) )
					ThrowDShowException(L"Failed to call GraphBuilder->RemoveFilter(pRenderPin).", hr);

				CComPtr<IBaseFilter>	pVMR9;
				AddVMR9Filer( pVMR9 );
	
				CComPtr<IPin>	pRdrPinIn;
				pRdrPinIn = GetInPin(pVMR9, 0);
	
				if( FAILED(hr = GraphBuilder()->ConnectDirect( pDecoderPinOut, pRdrPinIn, NULL )) )
					ThrowDShowException(L"Failed to call GraphBuilder()->ConnectDirect( pDecoderPinOut, pRdrPinIn, NULL ).", hr);
	
				if( FAILED(hr = pVMR9.QueryInterface( &m_VMR9MixerCtrl ) ) )
					ThrowDShowException(L"Failed to query IVMRMixerControl9.", hr);
				if( FAILED(hr = pVMR9.QueryInterface( &m_VMR9MixerBmp ) ) )
					ThrowDShowException(L"Failed to query IVMRMixerBitmap9.", hr);
			}
			else
			{
				CComPtr<IBaseFilter>	pVMR9;
				AddVMR9Filer( pVMR9 );
				BuildMPEGGraph( pVMR9, m_Reader); // may throw an exception
	
				if( FAILED(hr = pVMR9.QueryInterface( &m_VMR9MixerCtrl ) ) )
					ThrowDShowException(L"Failed to query IVMRMixerControl9.", hr);
				if( FAILED(hr = pVMR9.QueryInterface( &m_VMR9MixerBmp ) ) )
					ThrowDShowException(L"Failed to query IVMRMixerBitmap9.", hr);
			}
		}
#if 1
		{	// 平均フレーム表示時間を取得する
			CComPtr<IBaseFilter>	pRender;
			if( FAILED(hr = FindVideoRenderer( &pRender ) ) )
				ThrowDShowException(L"Failed to call FindVideoRenderer( &pRender ).", hr);

			CComPtr<IPin>	pRenderPin;
			pRenderPin = GetInPin(pRender, 0);

			AM_MEDIA_TYPE mt;
			if( FAILED(hr = pRenderPin->ConnectionMediaType(&mt)) )
				ThrowDShowException(L"Failed to call IPin::ConnectionMediaType(pmt).", hr);
			if( mt.formattype == FORMAT_VideoInfo && mt.cbFormat != 0 )
			{
				VIDEOINFOHEADER	*vih = reinterpret_cast<VIDEOINFOHEADER*>(mt.pbFormat);
				m_AvgTimePerFrame = vih->AvgTimePerFrame;
				m_Width = vih->bmiHeader.biWidth;
				m_Height = vih->bmiHeader.biHeight;
			}
			else if( mt.formattype == FORMAT_VideoInfo2 && mt.cbFormat != 0 )
			{
				VIDEOINFOHEADER2 *vih = reinterpret_cast<VIDEOINFOHEADER2*>(mt.pbFormat);
				m_AvgTimePerFrame = vih->AvgTimePerFrame;
				m_Width = vih->bmiHeader.biWidth;
				m_Height = vih->bmiHeader.biHeight;
			}
			FreeMediaType(mt);
		}
#endif
		// query each interfaces
		if( FAILED(hr = m_GraphBuilder.QueryInterface( &m_MediaControl )) )
			ThrowDShowException(L"Failed to query IMediaControl", hr);
		if( FAILED(hr = m_GraphBuilder.QueryInterface( &m_MediaPosition )) )
			ThrowDShowException(L"Failed to query IMediaPosition", hr);
		if( FAILED(hr = m_GraphBuilder.QueryInterface( &m_MediaSeeking )) )
			ThrowDShowException(L"Failed to query IMediaSeeking", hr);
		if( FAILED(hr = m_GraphBuilder.QueryInterface( &m_MediaEventEx )) )
			ThrowDShowException(L"Failed to query IMediaEventEx", hr);

		if( FAILED(hr = m_GraphBuilder.QueryInterface( &m_BasicAudio )) )
			ThrowDShowException(L"Failed to query IBasicAudio", hr);

		// set notify event
		if(callbackwin)
		{
			if(FAILED(hr = Event()->SetNotifyWindow((OAHWND)callbackwin, WM_GRAPHNOTIFY, (long)(this))))
				ThrowDShowException(L"Failed to set IMediaEventEx::SetNotifyWindow.", hr);
		}
	}
	catch(const wchar_t *msg)
	{
		MakeAPause(true);
		ReleaseAll();
		CoUninitialize();
		TVPThrowExceptionMessage(msg);
	}
	catch(...)
	{
		MakeAPause(true);
		ReleaseAll();
		CoUninitialize();
		throw;
	}

	MakeAPause(false);
	CoUninitialize();
}
示例#2
0
//-----------------------------------------------------------------------------
// InitDShowTextureRenderer : Create DirectShow filter graph and run the graph
//-----------------------------------------------------------------------------
HRESULT CDShowManager::InitDShowTextureRenderer()
{
	HRESULT hr = S_OK;
	IBaseFilter*    pFSrc;          // Source Filter
	IPin*           pFSrcPinOut;    // Source Filter Output Pin
	CTextureRenderer        *pCTR=0;        // DirectShow Texture renderer

	// Create the filter graph
	//if (FAILED(g_pGB->CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC)))
	//	return E_FAIL;

	hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC, IID_IGraphBuilder, (void **)&m_pGB);
	if (FAILED(hr))
	{
		return E_FAIL;
	}

#ifdef REGISTER_FILTERGRAPH
	// Register the graph in the Running Object Table (for debug purposes)
	AddToROT(m_pGB);
#endif

	// Create the Texture Renderer object
	pCTR = new CTextureRenderer(NULL, &hr);
	if (FAILED(hr) || !pCTR)
	{
		delete pCTR;
		Msg(TEXT("Could not create texture renderer object!  hr=0x%x"), hr);
		return E_FAIL;
	}

	// Get a pointer to the IBaseFilter on the TextureRenderer, add it to graph
	m_pRenderer = pCTR;
	pCTR->AddRef();
	if (FAILED(hr = m_pGB->AddFilter(m_pRenderer, L"TEXTURERENDERER")))
	{
		Msg(TEXT("Could not add renderer filter to graph!  hr=0x%x"), hr);
		return hr;
	}

	// Determine the file to load based on windows directory
	// Use the standard win32 API to do this.
	TCHAR strFileName[MAX_PATH] = {0};
	WCHAR wFileName[MAX_PATH];

	if (! GetClipFileName(strFileName))
	{
		DWORD dwDlgErr = CommDlgExtendedError();

		// Don't show output if user cancelled the selection (no dlg error)
		if (dwDlgErr)
		{
			Msg(TEXT("GetClipFileName Failed! Error=0x%x\r\n"), GetLastError());
		}
		return E_FAIL;
	}

	strFileName[MAX_PATH-1] = 0;  // NULL-terminate
	wFileName[MAX_PATH-1] = 0;    // NULL-terminate

	//USES_CONVERSION;
	(void)StringCchCopyW(wFileName, NUMELMS(wFileName), T2W(strFileName));

	// Add the source filter to the graph.
	hr = m_pGB->AddSourceFilter (wFileName, L"SOURCE", &pFSrc);

	// If the media file was not found, inform the user.
	if (hr == VFW_E_NOT_FOUND)
	{
		Msg(TEXT("Could not add source filter to graph!  (hr==VFW_E_NOT_FOUND)\r\n\r\n")
			TEXT("This sample reads a media file from your windows directory.\r\n")
			TEXT("This file is missing from this machine."));
		return hr;
	}
	else if(FAILED(hr))
	{
		Msg(TEXT("Could not add source filter to graph!  hr=0x%x"), hr);
		return hr;
	}

	if (FAILED(hr = pFSrc->FindPin(L"Output", &pFSrcPinOut)))
	{
		Msg(TEXT("Could not find output pin!  hr=0x%x"), hr);
		return hr;
	}

#ifdef NO_AUDIO_RENDERER

	// If no audio component is desired, directly connect the two video pins
	// instead of allowing the Filter Graph Manager to render all pins.

	CComPtr<IPin> pFTRPinIn;      // Texture Renderer Input Pin

	// Find the source's output pin and the renderer's input pin
	if (FAILED(hr = pFTR->FindPin(L"In", &pFTRPinIn)))
	{
		Msg(TEXT("Could not find input pin!  hr=0x%x"), hr);
		return hr;
	}

	// Connect these two filters
	if (FAILED(hr = m_pGB->Connect(pFSrcPinOut, pFTRPinIn)))
	{
		Msg(TEXT("Could not connect pins!  hr=0x%x"), hr);
		return hr;
	}

#else

	// Render the source filter's output pin.  The Filter Graph Manager
	// will connect the video stream to the loaded CTextureRenderer
	// and will load and connect an audio renderer (if needed).

	if (FAILED(hr = m_pGB->Render(pFSrcPinOut)))
	{
		Msg(TEXT("Could not render source output pin!  hr=0x%x"), hr);
		return hr;
	}

#endif

	// Get the graph's media control, event & position interfaces
	m_pGB->QueryInterface(&m_pMC);
	m_pGB->QueryInterface(&m_pMP);
	m_pGB->QueryInterface(&m_pME);

	// Start the graph running;
	if (FAILED(hr = m_pMC->Run()))
	{
		Msg(TEXT("Could not run the DirectShow graph!  hr=0x%x"), hr);
		return hr;
	}


	return S_OK;
}
示例#3
0
//----------------------------------------------------------------------------
//! @brief	  	フィルタグラフの構築
//! @param 		callbackwin : メッセージを送信するウィンドウ
//! @param 		stream : 読み込み元ストリーム
//! @param 		streamname : ストリームの名前
//! @param 		type : メディアタイプ(拡張子)
//! @param 		size : メディアサイズ
//----------------------------------------------------------------------------
void __stdcall tTVPDSVideoOverlay::BuildGraph( HWND callbackwin, IStream *stream,
	const wchar_t * streamname, const wchar_t *type, unsigned __int64 size )
{
	HRESULT			hr;

//	CoInitialize(NULL);

	// detect CMediaType from stream's extension ('type')
	try {
		if( FAILED(hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED)) )
			ThrowDShowException(L"Failed to call CoInitializeEx.", hr);

		// create IFilterGraph instance
		if( FAILED(hr = m_GraphBuilder.CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC)) )
			ThrowDShowException(L"Failed to create FilterGraph.", hr);

		// Register to ROT
		if(GetShouldRegisterToROT())
		{
			AddToROT(m_dwROTReg);
		}

		if( IsWindowsMediaFile(type) )
		{
			CComPtr<IBaseFilter>	pVRender;	// for video renderer filter
			if( FAILED(hr = pVRender.CoCreateInstance(CLSID_VideoRenderer, NULL, CLSCTX_INPROC_SERVER)) )
				ThrowDShowException(L"Failed to create video renderer filter object.", hr);
			if( FAILED(hr = GraphBuilder()->AddFilter(pVRender, L"Video Renderer")) )
				ThrowDShowException(L"Failed to call IFilterGraph::AddFilter.", hr);

			BuildWMVGraph( pVRender, stream );
		}
		else
		{
			CMediaType mt;
			mt.majortype = MEDIATYPE_Stream;
			ParseVideoType( mt, type ); // may throw an exception

			// create proxy filter
			m_Proxy = new CIStreamProxy( stream, size );
			hr = S_OK;
			m_Reader = new CIStreamReader( m_Proxy, &mt, &hr );

			if( FAILED(hr) || m_Reader == NULL )
				ThrowDShowException(L"Failed to create proxy filter object.", hr);

			m_Reader->AddRef();
			// add fliter
			if( FAILED(hr = GraphBuilder()->AddFilter( m_Reader, NULL)) )
				ThrowDShowException(L"Failed to call IFilterGraph::AddFilter.", hr);

			// AddFilterしたのでRelease
			m_Reader->Release();

			if( mt.subtype == MEDIASUBTYPE_Avi || mt.subtype == MEDIASUBTYPE_QTMovie )
			{
				// render output pin
				if( FAILED(hr = GraphBuilder()->Render(m_Reader->GetPin(0))) )
					ThrowDShowException(L"Failed to call IGraphBuilder::Render.", hr);
			}
			else
			{
				CComPtr<IBaseFilter>	pVRender;	// for video renderer filter
				if( FAILED(hr = pVRender.CoCreateInstance(CLSID_VideoRenderer, NULL, CLSCTX_INPROC_SERVER)) )
					ThrowDShowException(L"Failed to create video renderer filter object.", hr);
				if( FAILED(hr = GraphBuilder()->AddFilter(pVRender, L"Video Renderer")) )
					ThrowDShowException(L"Failed to call IFilterGraph::AddFilter.", hr);

				BuildMPEGGraph( pVRender, m_Reader); // may throw an exception
			}
		}

		// query each interfaces
		if( FAILED(hr = m_GraphBuilder.QueryInterface( &m_MediaControl )) )
			ThrowDShowException(L"Failed to query IMediaControl", hr);
		if( FAILED(hr = m_GraphBuilder.QueryInterface( &m_MediaPosition )) )
			ThrowDShowException(L"Failed to query IMediaPosition", hr);
		if( FAILED(hr = m_GraphBuilder.QueryInterface( &m_MediaSeeking )) )
			ThrowDShowException(L"Failed to query IMediaSeeking", hr);
		if( FAILED(hr = m_GraphBuilder.QueryInterface( &m_MediaEventEx )) )
			ThrowDShowException(L"Failed to query IMediaEventEx", hr);

		if( FAILED(hr = m_GraphBuilder.QueryInterface( &m_BasicVideo )) )
			ThrowDShowException(L"Failed to query IBasicVideo", hr);

		if( FAILED(hr = m_GraphBuilder.QueryInterface( &m_VideoWindow )) )
			ThrowDShowException(L"Failed to query IVideoWindow", hr);
		if( FAILED(hr = m_GraphBuilder.QueryInterface( &m_BasicAudio )) )
			ThrowDShowException(L"Failed to query IBasicAudio", hr);

		// check whether the stream has video 
		if(!m_VideoWindow || !m_BasicVideo )
			TVPThrowExceptionMessage(L"The stream has no video components.");

		{
			long visible;
			if(FAILED(hr = VideoWindow()->get_Visible(&visible)))
				ThrowDShowException(L"The stream has no video components or has unsupported video format.", hr);
		}
	
		// disable AutoShow
		VideoWindow()->put_AutoShow(OAFALSE);

		// set notify event
		if(callbackwin)
		{
			if(FAILED(hr = Event()->SetNotifyWindow((OAHWND)callbackwin, WM_GRAPHNOTIFY, (long)(this))))
				ThrowDShowException(L"Failed to set IMediaEventEx::SetNotifyWindow.", hr);
		}
	}
	catch(const wchar_t *msg)
	{
		MakeAPause(true);
		ReleaseAll();
		CoUninitialize();
		TVPThrowExceptionMessage(msg);
	}
	catch(...)
	{
		MakeAPause(true);
		ReleaseAll();
		CoUninitialize();
		throw;
	}

	MakeAPause(false);
	CoUninitialize();	// ここでこれを呼ぶとまずそうな気がするけど、大丈夫なのかなぁ
}
示例#4
0
bool CVideoRenderer::Initialize ( const char * szFile )
{
    IBaseFilter * pDSound, * pXVID, * pVorbis;
    IBaseFilter * pSource;
    IFileSourceFilter * pFileSource;
    HRESULT hr;

    // Get the codecs
    CVideoManager *pManager = CVideoManager::GetSingletonPtr ();
    if ( pManager->CreateCodecSource ( &pSource ) != S_OK ) return false;
    if ( pManager->CreateCodecVorbis ( &pVorbis ) != S_OK ) return false;
    if ( pManager->CreateCodecXVID ( &pXVID ) != S_OK ) return false;

    // Check for a valid device
    if ( !m_pDevice ) return false;

    // Lock so we don't f**k up
    Lock ();

    CCore::GetSingleton ().GetConsole ()->Printf ( "Creating DirectShow graph instance" );

    // Initialize the graph builder
    CoCreateInstance ( CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, reinterpret_cast < void** > ( &m_pGraph ) );
    if ( m_pGraph == NULL ) return false;

    CCore::GetSingleton ().GetConsole ()->Printf ( "Creating DirectSound renderer instance" );

    // Initialize the DirectSound filter
    CoCreateInstance ( CLSID_DSoundRender, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, reinterpret_cast < void** > ( &pDSound ) );
    if ( pDSound == NULL ) return false;

#ifdef MTA_DEBUG
    CCore::GetSingleton ().GetConsole ()->Printf ( "Adding ROT for debug stuff" );

    // Enable GraphView debugging
    AddToROT(m_pGraph);
#endif

    CCore::GetSingleton ().GetConsole ()->Printf ( "Creating video renderer instance" );

    // Create an instance of the texture renderer and add it to the graph
    m_pFilter = CreateTextureRenderer ( &hr, m_pDevice, this );
    if ( hr != S_OK ) return false;

    // Add the source file filter to the grap h
    int iBufferSize = MultiByteToWideChar ( CP_ACP, 0, szFile, -1, NULL, 0 );
    wchar_t *wszFile = new wchar_t[iBufferSize];
    MultiByteToWideChar ( CP_ACP, 0, szFile, -1, wszFile, iBufferSize );

    CCore::GetSingleton ().GetConsole ()->Printf ( "Registering filter (Matroska)" );

    // Add the filters to the graph
    m_pGraph->AddFilter         ( pSource,      L"[MTA] MKV source" );
    
    CCore::GetSingleton ().GetConsole ()->Printf ( "Loading video file" );

    pSource->QueryInterface ( IID_IFileSourceFilter, reinterpret_cast < void** > ( &pFileSource ) );
    if ( pFileSource->Load ( wszFile, NULL ) != S_OK ) return false;

    CCore::GetSingleton ().GetConsole ()->Printf ( "Registering filter (Output)" );

    m_pGraph->AddFilter         ( m_pFilter,    L"[MTA] Texture renderer" );
    CCore::GetSingleton ().GetConsole ()->Printf ( "Registering filter (Vorbis)" );
    m_pGraph->AddFilter         ( pVorbis,      L"[MTA] Vorbis decoder" );
    CCore::GetSingleton ().GetConsole ()->Printf ( "Registering filter (XVID)" );
    m_pGraph->AddFilter         ( pXVID,        L"[MTA] XVID codec" );
    CCore::GetSingleton ().GetConsole ()->Printf ( "Registering filter (DirectSound)" );
    m_pGraph->AddFilter         ( pDSound,      L"[MTA] DirectSound renderer" );

    CCore::GetSingleton ().GetConsole ()->Printf ( "Connecting video renderer" );

    // Connect the video pins
    IPin *pOut, *pSourceOut;
    hr = ConnectFilters ( m_pGraph, pSource, pXVID, &pSourceOut );      // MKV Source       -> XVID
    assert ( hr == S_OK );
    hr = ConnectFilters ( m_pGraph, pXVID, m_pFilter, &pOut );          // XVID             -> Texture Renderer
    assert ( hr == S_OK );

    // Connect the audio pins (not necessary)
    hr = ConnectFilters ( m_pGraph, pSource, pVorbis, &pOut );          // MKV Source       -> Vorbis Decoder
    hr = ConnectFilters ( m_pGraph, pVorbis, pDSound, &pOut );          // Vorbis Decoder   -> DirectSound renderer

    m_pGraph->QueryInterface ( IID_IMediaSeeking, reinterpret_cast < void** > ( &m_pMediaSeeking ) );
    assert ( m_pMediaSeeking != NULL );
    m_pGraph->QueryInterface ( IID_IMediaControl, reinterpret_cast < void** > ( &m_pMediaControl ) );
    if ( m_pMediaControl == NULL || m_pMediaSeeking == NULL ) return false;

    m_pGraph->QueryInterface ( IID_IBasicAudio, reinterpret_cast < void** > ( &m_pBasicAudio ) );
    if ( m_pBasicAudio == NULL ) return false;

    CCore::GetSingleton ().GetConsole ()->Printf ( "Successfully loaded video renderer" );

    m_pBasicAudio->get_Volume ( &lDefaultVolume );

    // Clean up
    delete [] wszFile;
//  m_pGraph->Release ();

    // Unlock the mutex
    Unlock ();

    return true;
}