www.pudn.com > dllDSPlayer1.rar > DSPlayer.cpp


// DSPlayer.cpp: implementation of the CDSPlayer class. 
// 
////////////////////////////////////////////////////////////////////// 
 
#include "stdafx.h" 
#include "dllDSPlayer.h" 
#include  
#include "DSPlayer.h" 
 
#ifdef _DEBUG 
#undef THIS_FILE 
static char THIS_FILE[]=__FILE__; 
#define new DEBUG_NEW 
#endif 
 
#define SAFE_RELEASE(x) { if (x) x->Release(); x = NULL; } 
 
////////////////////////////////////////////////////////////////////// 
// Construction/Destruction 
////////////////////////////////////////////////////////////////////// 
CDSPlayer::CDSPlayer() 
{ 
	mGraph        = NULL; 
	mMediaControl = NULL; 
	mEvent        = NULL; 
	mBasicVideo   = NULL; 
	mBasicAudio   = NULL; 
	mVideoWindow  = NULL; 
	mSeeking      = NULL; 
	mAudioFilter  = NULL; 
	m_pSysDevEnum = NULL; 
	m_hWndNotify  = NULL; 
	m_hWndDisplay = NULL; 
 
	mObjectTableEntry = 0; 
} 
 
CDSPlayer::~CDSPlayer() 
{ 
	Release(); 
} 
 
BOOL CDSPlayer::Create(void) 
{ 
	if (!mGraph) 
	{ 
		if (SUCCEEDED(CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, 
			IID_IGraphBuilder, (void **)&mGraph))) 
		{ 
			AddToObjectTable(); 
 
			if ( !QueryInterfaces() ) 
				return FALSE; 
			return TRUE; 
		} 
		mGraph = 0; 
	} 
	return FALSE; 
} 
 
BOOL CDSPlayer::QueryInterfaces(void) 
{ 
	if (mGraph) 
	{ 
		HRESULT hr = NOERROR; 
		hr |= mGraph->QueryInterface(IID_IMediaControl, (void **)&mMediaControl); 
		hr |= mGraph->QueryInterface(IID_IMediaEventEx, (void **)&mEvent); 
		hr |= mGraph->QueryInterface(IID_IBasicVideo, (void **)&mBasicVideo); 
		hr |= mGraph->QueryInterface(IID_IBasicAudio, (void **)&mBasicAudio); 
		hr |= mGraph->QueryInterface(IID_IVideoWindow, (void **)&mVideoWindow); 
		hr |= mGraph->QueryInterface(IID_IMediaSeeking, (void **)&mSeeking); 
		if (mSeeking) 
		{ 
			mSeeking->SetTimeFormat(&TIME_FORMAT_MEDIA_TIME); 
		} 
		return SUCCEEDED(hr); 
	} 
	return FALSE; 
} 
 
void CDSPlayer::Release(void) 
{ 
	if (mSeeking) 
	{ 
		mSeeking->Release(); 
		mSeeking = NULL; 
	} 
	if (mMediaControl) 
	{ 
		mMediaControl->Release(); 
		mMediaControl = NULL; 
	} 
	if (mEvent) 
	{ 
		mEvent->Release(); 
		mEvent = NULL; 
	} 
	if (mBasicVideo) 
	{ 
		mBasicVideo->Release(); 
		mBasicVideo = NULL; 
	} 
	if (mBasicAudio) 
	{ 
		mBasicAudio->Release(); 
		mBasicAudio = NULL; 
	} 
	if (mVideoWindow) 
	{ 
		mVideoWindow->put_Visible(OAFALSE); 
		mVideoWindow->put_MessageDrain((OAHWND)NULL); 
		mVideoWindow->put_Owner(OAHWND(0)); 
		mVideoWindow->Release(); 
		mVideoWindow = NULL; 
	} 
	if ( mAudioFilter ) 
	{ 
		mAudioFilter->Release (); 
		mAudioFilter = NULL; 
	} 
	if ( m_pSysDevEnum ) 
	{ 
		m_pSysDevEnum->Release (); 
		m_pSysDevEnum = NULL; 
	} 
 
	for ( int i=0; iRelease();  
		mGraph = NULL; 
	} 
} 
 
BOOL CDSPlayer::Attach(IGraphBuilder * inGraphBuilder) 
{ 
	Release(); 
 
	if (inGraphBuilder) 
	{ 
		inGraphBuilder->AddRef(); 
		mGraph = inGraphBuilder; 
 
		AddToObjectTable(); 
		return QueryInterfaces(); 
	} 
	return TRUE; 
} 
 
IGraphBuilder * CDSPlayer::GetGraph(void) 
{ 
	return mGraph; 
} 
 
IMediaEventEx * CDSPlayer::GetEventHandle(void) 
{ 
	return mEvent; 
} 
 
// Connect filter from the upstream output pin to the downstream input pin 
BOOL CDSPlayer::ConnectFilters(IPin * inOutputPin, IPin * inInputPin,  
							  const AM_MEDIA_TYPE * inMediaType) 
{ 
	if (mGraph && inOutputPin && inInputPin) 
	{ 
		HRESULT hr = mGraph->ConnectDirect(inOutputPin, inInputPin, inMediaType); 
		return SUCCEEDED(hr) ? TRUE : FALSE; 
	} 
	return FALSE; 
} 
 
void CDSPlayer::DisconnectFilters(IPin * inOutputPin) 
{ 
	if (mGraph && inOutputPin) 
	{ 
		HRESULT hr = mGraph->Disconnect(inOutputPin); 
	} 
} 
 
BOOL CDSPlayer::SetDisplayWindow(HWND inWindow) 
{	 
	if (mVideoWindow) 
	{ 
	//	long lVisible; 
	//	mVideoWindow->get_Visible(&lVisible); 
		// Hide the video window first 
		mVideoWindow->put_Visible(OAFALSE); 
		mVideoWindow->put_Owner((OAHWND)inWindow); 
 
		RECT windowRect; 
		::GetClientRect(inWindow, &windowRect); 
		mVideoWindow->put_Left(0); 
		mVideoWindow->put_Top(0); 
		mVideoWindow->put_Width(windowRect.right - windowRect.left); 
		mVideoWindow->put_Height(windowRect.bottom - windowRect.top); 
		mVideoWindow->put_WindowStyle(WS_CHILD|WS_CLIPCHILDREN|WS_CLIPSIBLINGS); 
 
		mVideoWindow->put_MessageDrain((OAHWND) inWindow); 
		// Restore the video window 
		if (inWindow != NULL) 
		{ 
		//	mVideoWindow->put_Visible(lVisible); 
			mVideoWindow->put_Visible(OATRUE); 
		} 
		else 
		{ 
			mVideoWindow->put_Visible(OAFALSE); 
		} 
		return TRUE; 
	} 
	return FALSE; 
} 
 
BOOL CDSPlayer::ResizeVideoWindow(long inLeft, long inTop, long inWidth, long inHeight) 
{ 
	if (mVideoWindow) 
	{ 
		long lVisible = OATRUE; 
		mVideoWindow->get_Visible(&lVisible); 
		// Hide the video window first 
		mVideoWindow->put_Visible(OAFALSE); 
 
		mVideoWindow->put_Left(inLeft); 
		mVideoWindow->put_Top(inTop); 
		mVideoWindow->put_Width(inWidth); 
		mVideoWindow->put_Height(inHeight); 
	 
		// Restore the video window 
		mVideoWindow->put_Visible(lVisible); 
		return TRUE; 
	} 
	return FALSE; 
} 
 
BOOL CDSPlayer::SetNotifyWindow(HWND inWindow) 
{ 
	if (mEvent) 
	{ 
		mEvent->SetNotifyWindow((OAHWND)inWindow, WM_GRAPHNOTIFY, 0); 
		return TRUE; 
	} 
	return FALSE; 
} 
 
void CDSPlayer::HandleEvent(WPARAM inWParam, LPARAM inLParam) 
{ 
	if (mEvent) 
	{ 
		LONG eventCode = 0, eventParam1 = 0, eventParam2 = 0; 
		while (SUCCEEDED(mEvent->GetEvent(&eventCode, &eventParam1, &eventParam2, 0))) 
		{ 
			mEvent->FreeEventParams(eventCode, eventParam1, eventParam2); 
			switch (eventCode) 
			{ 
			case EC_COMPLETE: 
				break; 
 
			case EC_USERABORT: 
			case EC_ERRORABORT: 
				break; 
 
			default: 
				break; 
			} 
		} 
	} 
} 
 
BOOL CDSPlayer::Run(void) 
{ 
	if (mGraph && mMediaControl) 
	{ 
		if (!IsRunning()) 
		{ 
			if (SUCCEEDED(mMediaControl->Run())) 
			{ 
				return TRUE; 
			} 
		} 
		else 
		{ 
			return TRUE; 
		} 
	} 
	return FALSE; 
} 
 
BOOL CDSPlayer::Stop(void) 
{ 
	if (mGraph && mMediaControl) 
	{ 
		if (!IsStopped()) 
		{	 
			if (SUCCEEDED(mMediaControl->Stop())) 
			{ 
				if ( mAudioFilter ) 
				{ 
					mGraph->RemoveFilter ( mAudioFilter ); 
					mAudioFilter->Release (); 
					mAudioFilter = NULL; 
				} 
 
				return TRUE; 
			} 
		} 
		else 
		{ 
			return TRUE; 
		} 
	} 
	return FALSE; 
} 
 
BOOL CDSPlayer::Pause(void) 
{ 
	if (mGraph && mMediaControl) 
	{ 
		if (!IsPaused()) 
		{	 
			if (SUCCEEDED(mMediaControl->Pause())) 
			{ 
				return TRUE; 
			} 
		} 
		else 
		{ 
			return TRUE; 
		} 
	} 
	return FALSE; 
} 
 
BOOL CDSPlayer::IsRunning(void) 
{ 
	if (mGraph && mMediaControl) 
	{ 
		OAFilterState state = State_Stopped; 
		if (SUCCEEDED(mMediaControl->GetState(10, &state))) 
		{ 
			return state == State_Running; 
		} 
	} 
	return FALSE; 
} 
 
BOOL CDSPlayer::IsStopped(void) 
{ 
	if (mGraph && mMediaControl) 
	{ 
		OAFilterState state = State_Stopped; 
		if (SUCCEEDED(mMediaControl->GetState(10, &state))) 
		{ 
			return state == State_Stopped; 
		} 
	} 
	return FALSE; 
} 
 
BOOL CDSPlayer::IsPaused(void) 
{ 
	if (mGraph && mMediaControl) 
	{ 
		OAFilterState state = State_Stopped; 
		if (SUCCEEDED(mMediaControl->GetState(10, &state))) 
		{ 
			return state == State_Paused; 
		} 
	} 
	return FALSE; 
} 
 
BOOL CDSPlayer::SetFullScreen(BOOL inEnabled) 
{ 
	if (mVideoWindow) 
	{ 
		HRESULT hr = mVideoWindow->put_FullScreenMode(inEnabled ? OATRUE : OAFALSE); 
		return SUCCEEDED(hr); 
	} 
	return FALSE; 
} 
 
BOOL CDSPlayer::GetFullScreen(void) 
{ 
	if (mVideoWindow) 
	{ 
		long  fullScreenMode = OAFALSE; 
		mVideoWindow->get_FullScreenMode(&fullScreenMode); 
		return (fullScreenMode == OATRUE); 
	} 
	return FALSE; 
} 
 
// IMediaSeeking features 
BOOL CDSPlayer::GetCurrentPosition(double * outPosition) 
{ 
	if (mSeeking) 
	{ 
		__int64 position = 0; 
		if (SUCCEEDED(mSeeking->GetCurrentPosition(&position))) 
		{ 
			*outPosition = ((double)position) / 10000000.; 
			return TRUE; 
		} 
	} 
	return FALSE; 
} 
 
BOOL CDSPlayer::GetStopPosition(double * outPosition) 
{ 
	if (mSeeking) 
	{ 
		__int64 position = 0; 
		if (SUCCEEDED(mSeeking->GetStopPosition(&position))) 
		{ 
			*outPosition = ((double)position) / 10000000.; 
			return TRUE; 
		} 
	} 
	return FALSE; 
} 
 
BOOL CDSPlayer::SetCurrentPosition(double inPosition) 
{ 
	if (mSeeking) 
	{ 
		__int64 one = 10000000; 
		__int64 position = (__int64)(one * inPosition); 
		HRESULT hr = mSeeking->SetPositions(&position, AM_SEEKING_AbsolutePositioning | AM_SEEKING_SeekToKeyFrame,  
			0, AM_SEEKING_NoPositioning); 
		return SUCCEEDED(hr); 
	} 
	return FALSE; 
} 
 
BOOL CDSPlayer::SetStartStopPosition(double inStart, double inStop) 
{ 
	if (mSeeking) 
	{ 
		__int64 one = 10000000; 
		__int64 startPos = (__int64)(one * inStart); 
		__int64 stopPos  = (__int64)(one * inStop); 
		HRESULT hr = mSeeking->SetPositions(&startPos, AM_SEEKING_AbsolutePositioning | AM_SEEKING_SeekToKeyFrame,  
			&stopPos, AM_SEEKING_AbsolutePositioning | AM_SEEKING_SeekToKeyFrame); 
		return SUCCEEDED(hr); 
	} 
	return FALSE; 
} 
 
BOOL CDSPlayer::GetDuration(double * outDuration) 
{ 
	if (mSeeking) 
	{ 
		__int64 length = 0; 
		if (SUCCEEDED(mSeeking->GetDuration(&length))) 
		{ 
			*outDuration = ((double)length) / 10000000.; 
			return TRUE; 
		} 
	} 
	return FALSE; 
} 
 
BOOL CDSPlayer::SetPlaybackRate(double inRate) 
{ 
	if (mSeeking) 
	{ 
		if (SUCCEEDED(mSeeking->SetRate(inRate))) 
		{ 
			return TRUE; 
		} 
	} 
	return FALSE; 
} 
 
// Attention: range from -10000 to 0, and 0 is FULL_VOLUME. 
BOOL CDSPlayer::SetAudioVolume(long inVolume) 
{ 
	if (mBasicAudio) 
	{ 
		HRESULT hr = mBasicAudio->put_Volume(inVolume); 
		return SUCCEEDED(hr); 
	} 
	return FALSE; 
} 
 
long CDSPlayer::GetAudioVolume(void) 
{ 
	long volume = 0; 
	if (mBasicAudio) 
	{ 
		mBasicAudio->get_Volume(&volume); 
	} 
	return volume; 
} 
 
// Attention: range from -10000(left) to 10000(right), and 0 is both. 
BOOL CDSPlayer::SetAudioBalance(long inBalance) 
{ 
	if (mBasicAudio) 
	{ 
		HRESULT hr = mBasicAudio->put_Balance(inBalance); 
		return SUCCEEDED(hr); 
	} 
	return FALSE; 
} 
 
long CDSPlayer::GetAudioBalance(void) 
{ 
	long balance = 0; 
	if (mBasicAudio) 
	{ 
		mBasicAudio->get_Balance(&balance); 
	} 
	return balance; 
} 
 
BOOL CDSPlayer::RenderFile(const char * inFile) 
{ 
	if ( mGraph ) 
	{ 
		if ( !Stop () ) return FALSE; 
		if ( mAudioFilter ) 
		{ 
			mGraph->RemoveFilter ( mAudioFilter ); 
			mAudioFilter->Release (); 
			mAudioFilter = NULL; 
		} 
 
		WCHAR wsz[MAX_PATH]; 
		MultiByteToWideChar(CP_ACP, 0, inFile, -1, wsz, MAX_PATH); 
		if (SUCCEEDED(mGraph->RenderFile(wsz, NULL))) 
		{ 
			mAudioFilter = FindFilters ( inFile ); 
			m_csMediaFileName = inFile; 
			SetNotifyWindow ( m_hWndNotify ); 
			SetDisplayWindow ( m_hWndDisplay ); 
 
			return ( mAudioFilter != NULL ); 
		} 
	} 
	return FALSE; 
} 
 
IBaseFilter* CDSPlayer::FindFilters ( const char *szFilterName ) 
{ 
	if( !mGraph ) return NULL; 
	IEnumFilters *pFilters = NULL; 
	 
	 
    if ( FAILED(mGraph->EnumFilters(&pFilters))) 
		return NULL; 
	 
    IBaseFilter *pFilter = NULL, *pFilter_Find = NULL; 
    ULONG	n = 0; 
 
    while ( pFilters->Next(1, &pFilter, &n) == S_OK ) 
	{ 
		FILTER_INFO	info; 
		if ( FAILED(pFilter->QueryFilterInfo(&info)) ) 
		{ 
			TRACE ( "Filter [%x]  -- failed QueryFilterInfo\n", pFilter ); 
		} 
		else 
		{ 
			CString csAchName = info.achName; 
			TRACE ( "%s\n", csAchName ); 
			if ( csAchName.Find ( szFilterName, 0 ) >= 0 ) 
			{ 
				pFilter_Find = pFilter; 
			} 
			else 
			{ 
				pFilter->Release(); 
			} 
		} 
    } 
	 
    pFilters->Release(); 
 
	return pFilter_Find; 
} 
 
BOOL CDSPlayer::SnapshotBitmap(const char * outFile) 
{ 
	if (mBasicVideo) 
	{ 
		long bitmapSize = 0; 
		if (SUCCEEDED(mBasicVideo->GetCurrentImage(&bitmapSize, 0))) 
		{ 
			BOOL pass = FALSE; 
			unsigned char * buffer = new unsigned char[bitmapSize]; 
			if (SUCCEEDED(mBasicVideo->GetCurrentImage(&bitmapSize, (long *)buffer))) 
			{ 
				BITMAPFILEHEADER	hdr; 
				LPBITMAPINFOHEADER	lpbi; 
 
				lpbi = (LPBITMAPINFOHEADER)buffer; 
 
				int nColors = 1 << lpbi->biBitCount; 
				if (nColors > 256) 
					nColors = 0; 
 
				hdr.bfType		= ((WORD) ('M' << 8) | 'B');	//always is "BM" 
				hdr.bfSize		= bitmapSize + sizeof( hdr ); 
				hdr.bfReserved1 	= 0; 
				hdr.bfReserved2 	= 0; 
				hdr.bfOffBits		= (DWORD) (sizeof(BITMAPFILEHEADER) + lpbi->biSize + 
						nColors * sizeof(RGBQUAD)); 
 
				CFile bitmapFile(outFile, CFile::modeReadWrite | CFile::modeCreate | CFile::typeBinary); 
				bitmapFile.Write(&hdr, sizeof(BITMAPFILEHEADER)); 
				bitmapFile.Write(buffer, bitmapSize); 
				bitmapFile.Close(); 
				pass = TRUE; 
			} 
			delete [] buffer; 
			return pass; 
		} 
	} 
	return FALSE; 
} 
 
//////////////////////// For GraphEdit Dubug purpose ///////////////////////////// 
void CDSPlayer::AddToObjectTable(void) 
{ 
	IMoniker * pMoniker = 0; 
    IRunningObjectTable * objectTable = 0; 
    if (SUCCEEDED(GetRunningObjectTable(0, &objectTable)))  
	{ 
		CString csItem; 
		csItem.Format ( "FilterGraph %08p pid %08x", (DWORD_PTR)mGraph, GetCurrentProcessId() ); 
		WCHAR wsz[256] = {0}; 
		MultiByteToWideChar(CP_ACP, 0, csItem, csItem.GetLength(), wsz, 256); 
		HRESULT hr = CreateItemMoniker(L"!", wsz, &pMoniker); 
		if (SUCCEEDED(hr))  
		{ 
			hr = objectTable->Register(0, mGraph, pMoniker, &mObjectTableEntry); 
			pMoniker->Release(); 
		} 
		objectTable->Release(); 
	} 
} 
 
void CDSPlayer::RemoveFromObjectTable(void) 
{ 
	IRunningObjectTable * objectTable = 0; 
    if (SUCCEEDED(GetRunningObjectTable(0, &objectTable)))  
	{ 
        objectTable->Revoke(mObjectTableEntry); 
        objectTable->Release(); 
		mObjectTableEntry = 0; 
    } 
} 
 
BOOL CDSPlayer::IsInitedOK() 
{ 
	return ( mGraph != NULL ); 
} 
 
BOOL CDSPlayer::EnumAudioDevice() 
{ 
	HRESULT hr; 
    IEnumMoniker *pEnumCat = NULL; 
	if ( !m_pSysDevEnum ) 
	{ 
		hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL,  
			CLSCTX_INPROC, IID_ICreateDevEnum,  
			(void **)&m_pSysDevEnum ); 
	} 
	hr = m_pSysDevEnum->CreateClassEnumerator(CLSID_AudioRendererCategory, &pEnumCat, 0); 
	if ( FAILED(hr) ) return FALSE; 
	m_StrAry_AudioDevice.RemoveAll (); 
	 
	IMoniker *pMoniker; 
    ULONG cFetched; 
    VARIANT varName={0}; 
    int nFilters=0; 
	 
    // Enumerate all items associated with the moniker 
    while(pEnumCat->Next(1, &pMoniker, &cFetched) == S_OK) 
    { 
        IPropertyBag *pPropBag; 
        ASSERT(pMoniker); 
		 
        // Associate moniker with a file 
        hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag,  
			(void **)&pPropBag); 
        ASSERT(SUCCEEDED(hr)); 
        ASSERT(pPropBag); 
        if (FAILED(hr)) 
            continue; 
		 
        // Read filter name from property bag 
        varName.vt = VT_BSTR; 
        hr = pPropBag->Read(L"FriendlyName", &varName, 0); 
        if (FAILED(hr)) 
            continue; 
		 
        // Get filter name (converting BSTR name to a CString) 
        CString str(varName.bstrVal); 
        SysFreeString(varName.bstrVal); 
        nFilters++; 
		m_StrAry_AudioDevice.Add ( str ); 
		IBaseFilter *pFilter = NULL; 
		pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&pFilter); 
		m_PtrAry_Filter_AudioDevice.Add ( pFilter ); 
 
        // Cleanup interfaces 
        SAFE_RELEASE(pPropBag); 
        SAFE_RELEASE(pMoniker); 
    } 
	 
	SAFE_RELEASE ( pEnumCat ); 
 
	ASSERT ( m_StrAry_AudioDevice.GetSize() == m_PtrAry_Filter_AudioDevice.GetSize() ); 
	return TRUE; 
} 
 
void CDSPlayer::GetAudioDeviceList(CStringArray &StrAry_AudioDevice) 
{ 
	if ( m_StrAry_AudioDevice.GetSize() <= 0 ) 
		EnumAudioDevice (); 
	StrAry_AudioDevice.Append ( m_StrAry_AudioDevice ); 
} 
 
int CDSPlayer::FindAudioDeivceIDByName(CString strContainText, BOOL bInclude, CString *pcsAudioDeviceFullName/*=NULL*/) 
{ 
	for ( int i=0; i= 0 
				) 
				|| 
				( 
					!bInclude && 
					csWaveoutCard.Find(strContainText,0) < 0 
				) 
			) 
		{ 
			if ( pcsAudioDeviceFullName ) 
				*pcsAudioDeviceFullName = csWaveoutCard; 
			return i; 
		} 
	} 
	return -1; 
} 
 
BOOL CDSPlayer::SetAudioDevice(CString strContainText, BOOL bInclude/*=TRUE*/, CString *pcsAudioDeviceFullName/*=NULL*/) 
{ 
	m_csAudioDeviceName = strContainText; 
	if ( !mGraph ) return FALSE; 
 
	// 该声音设备滤镜已经有了	 
	BOOL bMustReplay = FALSE; 
	double pos = 0.0; 
	if ( IsInitedOK() && !m_csMediaFileName.IsEmpty() ) 
	{ 
		bMustReplay = TRUE; 
		GetCurrentPosition ( &pos ); 
		Stop (); 
		Release (); 
		if ( !Create () ) return FALSE; 
	} 
 
	if ( m_StrAry_AudioDevice.GetSize() <= 0 ) 
		EnumAudioDevice (); 
 
	int nDeviceID = FindAudioDeivceIDByName ( strContainText, bInclude, &m_csAudioDeviceName ); 
	if ( pcsAudioDeviceFullName ) *pcsAudioDeviceFullName = m_csAudioDeviceName; 
	if ( nDeviceID < 0 || nDeviceID >= m_PtrAry_Filter_AudioDevice.GetSize() ) 
		return FALSE; 
	IBaseFilter *pFilter = (IBaseFilter*)m_PtrAry_Filter_AudioDevice.GetAt(nDeviceID); 
	if ( !pFilter ) return FALSE; 
 
	WCHAR wsz[256] = {0}; 
	CString csFilterName = m_StrAry_AudioDevice.GetAt (nDeviceID); 
	MultiByteToWideChar(CP_ACP, 0, csFilterName, -1, wsz, 256); 
	HRESULT hr = mGraph->AddFilter ( pFilter, wsz ); 
 
	if ( bMustReplay ) 
	{ 
		if ( !RenderFile ( m_csMediaFileName ) ) 
			return FALSE; 
		Run (); 
		SetCurrentPosition ( pos ); 
	} 
 
	return SUCCEEDED(hr); 
} 
 
BOOL CDSPlayer::Delete_DefaultDirectSoundDevice() 
{ 
	if ( !mGraph ) return FALSE; 
	IBaseFilter* pFilter_Find = FindFilters ( "Default DirectSound Device" ); 
	if ( pFilter_Find ) 
	{ 
		mGraph->RemoveFilter ( pFilter_Find ); 
		SAFE_RELEASE ( pFilter_Find ); 
		SetAudioDevice ( m_csAudioDeviceName ); 
	} 
 
	return TRUE; 
}