www.pudn.com > filterasfmuxer_2008_01_23.rar > CFilterASFMuxer.cpp


// 
// CFilterASFMuxer.cpp 
// 
/** 
 ** Copyright (C) 2005 EnjoyView Inc., all rights reserved. 
 **           Your View, Our Passion. Just Enjoy It! 
 ** 
 **            http://spaces.msn.com/members/jemylu 
 ** 
 **/ 
 
/*************************************************************************/ 
 
#include  
 
#include  
#include "asfmuxer_ids.h" 
 
#include "CFilterASFMuxer.h" 
#include "CAudioInputPin.h" 
#include "CVideoInputPin.h" 
 
const AMOVIESETUP_MEDIATYPE sudPinTypes = 
{ 
    &MEDIATYPE_NULL,         // Major CLSID 
    &MEDIASUBTYPE_NULL       // Minor type 
}; 
 
const AMOVIESETUP_PIN psudPins[] = 
{ 
    { L"Input",             // Pin's string name 
      FALSE,                // Is it rendered 
      FALSE,                // Is it an output 
      FALSE,                // Allowed none 
      FALSE,                // Allowed many 
      &CLSID_NULL,          // Connects to filter 
      L"Output",            // Connects to pin 
      1,                    // Number of types 
      &sudPinTypes },       // Pin information 
 
    { L"Input",             // Pin's string name 
      FALSE,                // Is it rendered 
      FALSE,                // Is it an output 
      FALSE,                // Allowed none 
      FALSE,                // Allowed many 
      &CLSID_NULL,          // Connects to filter 
      L"Output",            // Connects to pin 
      1,                    // Number of types 
      &sudPinTypes },       // Pin information 
}; 
   
const AMOVIESETUP_FILTER sudflt = 
{ 
    &CLSID_HQ_ASFMuxer,         // CLSID 
    L"HQ ASF Muxer",            // Filter's name 
    MERIT_DO_NOT_USE,           // Filter's merit 
	2, 
    psudPins                    // Pin information 
}; 
 
 
CFactoryTemplate g_Templates [] =  
{ 
    {  
		L"HQ ASF Muxer", 
		&CLSID_HQ_ASFMuxer, 
		CFilterASFMuxer::CreateInstance, 
		NULL, 
		&sudflt  
	} 
}; 
int g_cTemplates = sizeof(g_Templates) / sizeof(g_Templates[0]); 
 
 
//////////////////////////////////////////////////////////////////////////// 
CFilterASFMuxer::CFilterASFMuxer(LPUNKNOWN lpunk, HRESULT *phr) : 
CBaseFilter(NAME("ASF Muxer"), lpunk, &mSyncFilter, CLSID_HQ_ASFMuxer), 
mVideoPin(NULL), mAudioPin(NULL), mPosition(NULL)//, mMuxer(NULL) 
{ 
	mVideoPin = new CVideoInputPin(this , phr, L"Video In"); 
	mAudioPin = new CAudioInputPin(this , phr, L"Audio In"); 
	mMuxer    = new CASFMuxer(this); 
	*phr = (mVideoPin && mAudioPin && mMuxer) ? S_OK : E_OUTOFMEMORY; 
 
	// Test 
//	mMuxer->SetDestFile(L"C:\\asf_mux.asf"); 
} 
 
CFilterASFMuxer::~CFilterASFMuxer() 
{	 
	SAFE_DELETE(mPosition); 
	SAFE_DELETE(mVideoPin); 
	SAFE_DELETE(mAudioPin); 
	SAFE_DELETE(mMuxer); 
} 
 
CUnknown * WINAPI CFilterASFMuxer::CreateInstance(LPUNKNOWN pUnknown, HRESULT * phr) 
{ 
	CFilterASFMuxer *pSDFilter = new CFilterASFMuxer(pUnknown, phr); 
	if (pSDFilter == NULL) 
	{ 
		*phr = E_OUTOFMEMORY; 
	} 
	return pSDFilter; 
} 
 
STDMETHODIMP CFilterASFMuxer::NonDelegatingQueryInterface(REFIID riid, void ** ppv) 
{ 
	CheckPointer(ppv,E_POINTER); 
 
	if (riid == IID_IMediaPosition || riid == IID_IMediaSeeking)  
	{ 
		// Expose mediaseeking interface on our renderer 
		HRESULT hr = S_OK; 
		if (mPosition == NULL)  
		{ 
			mPosition  = new CPosPassThru(NAME("Pass Through"), 
										(IUnknown *) GetOwner(), 
										(HRESULT *) &hr, mVideoPin); 
			if (mPosition == NULL)  
			{ 
				return E_OUTOFMEMORY; 
			} 
		} 
		if (FAILED(hr))  
		{ 
			delete mPosition; 
			mPosition = NULL; 
			return hr; 
		} 
		return mPosition->NonDelegatingQueryInterface(riid, ppv); 
	} 
	else if (riid == IID_IFileSinkFilter) 
	{ 
		return GetInterface((IFileSinkFilter *) this, ppv); 
	} 
	else 
	{ 
		return CBaseFilter::NonDelegatingQueryInterface(riid , ppv); 
	} 
} 
 
STDMETHODIMP CFilterASFMuxer::Run(REFERENCE_TIME tStart) 
{ 
	CAutoLock lck(&mSyncFilter); 
 
	return CBaseFilter::Run(tStart); 
} 
 
STDMETHODIMP CFilterASFMuxer::Pause() 
{ 
	CAutoLock lck(&mSyncFilter); 
 
	// At least one input pin should be connected! 
	if (mAudioPin->IsConnected() == FALSE && 
		mVideoPin->IsConnected() == FALSE) 
	{ 
		return E_UNEXPECTED; 
	} 
 
	HRESULT hr = NOERROR; 
	// Initializing when state from stopped to paused 
	if (State_Stopped == m_State) 
	{ 
		hr = mMuxer->StartStreaming(); 
		if (FAILED(hr)) 
		{ 
			return hr; 
		} 
	} 
 
	return CBaseFilter::Pause(); 
} 
 
STDMETHODIMP CFilterASFMuxer::Stop() 
{ 
	CAutoLock lck(&mSyncFilter); 
 
	mMuxer->StopStreaming();  
 
	return CBaseFilter::Stop(); 
} 
 
CBasePin* CFilterASFMuxer::GetPin(int n) 
{ 
	if (n == 0) 
	{ 
		return mVideoPin; 
	}	 
	else if (n == 1) 
	{ 
		return mAudioPin; 
	} 
	else 
	{ 
		return NULL; 
	} 
} 
 
int CFilterASFMuxer::GetPinCount() 
{ 
	return 2; 
} 
 
HRESULT CFilterASFMuxer::XEndOfStream(void) 
{ 
	BOOL shouldHandleEOS = FALSE; 
	if ((mAudioPin->IsConnected() && mAudioPin->IsEOSReceived()) || 
		!mAudioPin->IsConnected()) 
	{ 
		if ((mVideoPin->IsConnected() && mVideoPin->IsEOSReceived()) || 
			!mVideoPin->IsConnected()) 
		{ 
			shouldHandleEOS = TRUE; 
		} 
	} 
	 
	if (shouldHandleEOS) 
	{ 
		if (!mAudioPin->m_bCompleteNotified && !mVideoPin->m_bCompleteNotified) 
		{ 
			NotifyEvent(EC_COMPLETE, S_OK, (LONG_PTR)(IBaseFilter *)this); 
			mAudioPin->AfterCompleteHandling(); 
			mVideoPin->AfterCompleteHandling(); 
		} 
	} 
 
	return S_OK; 
} 
 
HRESULT CFilterASFMuxer::XCompleteConnect(PIN_ID inPinID) 
{ 
	return S_OK; 
} 
 
HRESULT CFilterASFMuxer::ReceiveVideo(IMediaSample * pSample) 
{ 
	HRESULT hr = S_OK; 
	hr = mMuxer->ReceiveVideo(pSample); 
	return hr; 
} 
 
HRESULT CFilterASFMuxer::ReceiveAudio(IMediaSample * pSample) 
{ 
	HRESULT hr = S_OK; 
	hr = mMuxer->ReceiveAudio(pSample); 
	return hr; 
} 
 
BOOL CFilterASFMuxer::IsAudioPinConnected(void) 
{ 
	return mAudioPin->IsConnected(); 
} 
 
BOOL CFilterASFMuxer::IsVideoPinConnected(void) 
{ 
	return mVideoPin->IsConnected(); 
} 
 
CMediaType& CFilterASFMuxer::GetAudioMediaType(void) 
{ 
	return mAudioPin->CurrentMediaType(); 
} 
 
CMediaType& CFilterASFMuxer::GetVideoMediaType(void) 
{ 
	return mVideoPin->CurrentMediaType(); 
} 
 
 
 
// --- IFileSinkFilter methods --- 
STDMETHODIMP CFilterASFMuxer::SetFileName(LPCOLESTR pszFileName, const AM_MEDIA_TYPE *pmt) 
{ 
	// Is this a valid filename supplied 
	CheckPointer(pszFileName, E_POINTER); 
	if (wcslen(pszFileName) > MAX_PATH) 
	{ 
		return ERROR_FILENAME_EXCED_RANGE; 
	} 
	return mMuxer->SetDestFile(pszFileName); 
} 
 
STDMETHODIMP CFilterASFMuxer::GetCurFile(LPOLESTR * ppszFileName, AM_MEDIA_TYPE *pmt) 
{ 
	CheckPointer(ppszFileName, E_POINTER); 
	*ppszFileName = NULL; 
 
	if (pmt)  
	{ 
		ZeroMemory(pmt, sizeof(*pmt)); 
		pmt->majortype = MEDIATYPE_NULL; 
		pmt->subtype   = MEDIASUBTYPE_NULL; 
	} 
	return mMuxer->GetDestFile(ppszFileName); 
} 
 
 
 
 
 
 
 
// 
// DllEntryPoint 
// 
extern "C" BOOL WINAPI DllEntryPoint(HINSTANCE, ULONG, LPVOID); 
 
BOOL APIENTRY DllMain(HANDLE hModule,  
                      DWORD  dwReason,  
                      LPVOID lpReserved) 
{ 
	return DllEntryPoint((HINSTANCE)(hModule), dwReason, lpReserved); 
} 
 
// 
// DllRegisterServer 
// 
STDAPI DllRegisterServer() 
{ 
    return AMovieDllRegisterServer2( TRUE ); 
} 
 
// 
// DllUnregisterServer 
// 
STDAPI DllUnregisterServer() 
{ 
    return AMovieDllRegisterServer2( FALSE ); 
}