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 ); }