2 #include "hwcfilter.h"
\r
6 static HMODULE g_hModule = NULL;
\r
7 static long g_cServerLocks = 0;
\r
8 static long g_cComponents = 0;
\r
10 CHWCPin::CHWCPin(CHWCFilter *pFilter) :
\r
11 m_pCFilter(pFilter), m_pConnectedPin(NULL),
\r
12 m_pCallback(NULL), m_bReadOnly(FALSE), m_cRef(1)
\r
14 InterlockedIncrement(&g_cComponents);
\r
17 CHWCPin::~CHWCPin(void)
\r
19 InterlockedDecrement(&g_cComponents);
\r
22 STDMETHODIMP CHWCPin::QueryInterface(REFIID riid, void **ppv)
\r
24 if (riid == IID_IUnknown) {
\r
25 *ppv = (IUnknown*)((IHWCPin*)this);
\r
26 } else if (riid == IID_IPin) {
\r
28 } else if (riid == IID_IMemInputPin) {
\r
29 *ppv = (IMemInputPin*)this;
\r
30 } else if (riid == IID_IHWCPin) {
\r
31 *ppv = (IHWCPin*)this;
\r
34 StringFromIID(riid, &str);
\r
36 return E_NOINTERFACE;
\r
38 reinterpret_cast<IHWCPin*>(this)->AddRef();
\r
42 STDMETHODIMP_(ULONG) CHWCPin::AddRef()
\r
44 return InterlockedIncrement(&m_cRef);
\r
47 STDMETHODIMP_(ULONG) CHWCPin::Release()
\r
49 if( InterlockedDecrement(&m_cRef) == 0)
\r
57 STDMETHODIMP CHWCPin::Connect(IPin *pReceivePin, const AM_MEDIA_TYPE *pmt)
\r
64 STDMETHODIMP CHWCPin::ReceiveConnection(IPin *pConnector, const AM_MEDIA_TYPE *pmt)
\r
66 if (pConnector == NULL || pmt == NULL)
\r
69 if (m_pConnectedPin) {
\r
70 return VFW_E_ALREADY_CONNECTED;
\r
73 m_pCFilter->GetState(0, &fs);
\r
74 if (fs != State_Stopped) {
\r
75 return VFW_E_NOT_STOPPED;
\r
78 pConnector->QueryDirection(&pd);
\r
79 if (pd == PINDIR_INPUT) {
\r
80 return VFW_E_INVALID_DIRECTION;
\r
83 m_pConnectedPin = pConnector;
\r
84 m_pConnectedPin->AddRef();
\r
88 STDMETHODIMP CHWCPin::Disconnect(void)
\r
91 if (m_pConnectedPin == NULL) {
\r
94 m_pConnectedPin->Release();
\r
95 m_pConnectedPin = NULL;
\r
101 STDMETHODIMP CHWCPin::ConnectedTo(IPin **pPin)
\r
107 if ( m_pConnectedPin == NULL ) {
\r
108 hr = VFW_E_NOT_CONNECTED;
\r
110 m_pConnectedPin->AddRef();
\r
111 *pPin = m_pConnectedPin;
\r
117 STDMETHODIMP CHWCPin::ConnectionMediaType(AM_MEDIA_TYPE *pmt)
\r
122 return VFW_E_NOT_CONNECTED;
\r
125 STDMETHODIMP CHWCPin::QueryPinInfo(PIN_INFO *pInfo)
\r
130 pInfo->pFilter = (IBaseFilter*)m_pCFilter;
\r
132 m_pCFilter->AddRef();
\r
133 memcpy((void*)pInfo->achName, (void*)HWCPinName, sizeof(HWCPinName));
\r
134 pInfo->dir = PINDIR_INPUT;
\r
138 STDMETHODIMP CHWCPin::QueryDirection(PIN_DIRECTION *pPinDir)
\r
140 if (pPinDir == NULL)
\r
142 *pPinDir = PINDIR_INPUT;
\r
146 STDMETHODIMP CHWCPin::QueryId(LPWSTR *Id)
\r
150 PVOID pId = CoTaskMemAlloc(sizeof(HWCPinName));
\r
151 memcpy((void*)pId, (void*)HWCPinName, sizeof(HWCPinName));
\r
156 STDMETHODIMP CHWCPin::QueryAccept(const AM_MEDIA_TYPE *pmt)
\r
163 STDMETHODIMP CHWCPin::EnumMediaTypes(IEnumMediaTypes **ppEnum)
\r
165 if (ppEnum == NULL)
\r
170 STDMETHODIMP CHWCPin::QueryInternalConnections(IPin **ppPin, ULONG *nPin)
\r
175 STDMETHODIMP CHWCPin::EndOfStream(void)
\r
180 STDMETHODIMP CHWCPin::BeginFlush(void)
\r
185 STDMETHODIMP CHWCPin::EndFlush(void)
\r
190 STDMETHODIMP CHWCPin::NewSegment(REFERENCE_TIME tStart,
\r
191 REFERENCE_TIME tStop,
\r
197 STDMETHODIMP CHWCPin::GetAllocator(IMemAllocator **ppAllocator)
\r
199 if (ppAllocator == NULL)
\r
201 return VFW_E_NO_ALLOCATOR;
\r
204 STDMETHODIMP CHWCPin::NotifyAllocator(IMemAllocator *pAllocator,
\r
207 if (pAllocator == NULL)
\r
213 STDMETHODIMP CHWCPin::GetAllocatorRequirements(ALLOCATOR_PROPERTIES *pProps)
\r
218 STDMETHODIMP CHWCPin::Receive(IMediaSample *pSample)
\r
220 if (pSample == NULL)
\r
222 if (m_pCallback != NULL) {
\r
224 BYTE* pBuffer = NULL;
\r
226 dwSize = pSample->GetSize();
\r
227 hr = pSample->GetPointer(&pBuffer);
\r
230 m_pCallback->CaptureCallback(dwSize, pBuffer);
\r
235 STDMETHODIMP CHWCPin::ReceiveMultiple(IMediaSample **pSamples,
\r
236 long nSamples, long *nSamplesProcessed)
\r
238 if (pSamples == NULL)
\r
241 nSamplesProcessed = 0;
\r
242 while (nSamples-- > 0)
\r
244 hr = Receive(pSamples[*nSamplesProcessed]);
\r
247 (*nSamplesProcessed)++;
\r
252 STDMETHODIMP CHWCPin::ReceiveCanBlock(void)
\r
257 STDMETHODIMP CHWCPin::SetCallback(ICaptureCallBack *pCaptureCB)
\r
259 if (pCaptureCB == NULL) {
\r
260 m_pCallback->Release();
\r
262 m_pCallback = pCaptureCB;
\r
263 m_pCallback->AddRef();
\r
268 CHWCEnumPins::CHWCEnumPins(CHWCFilter *pCHWCFilter, int pos) :
\r
269 m_pFilter(pCHWCFilter), m_pos(pos), m_cRef(1)
\r
271 m_pFilter->AddRef();
\r
272 InterlockedIncrement(&g_cComponents);
\r
275 CHWCEnumPins::~CHWCEnumPins(void)
\r
277 m_pFilter->Release();
\r
278 InterlockedDecrement(&g_cComponents);
\r
281 STDMETHODIMP CHWCEnumPins::QueryInterface(REFIID riid, void **ppv)
\r
286 if (riid == IID_IUnknown) {
\r
287 *ppv = (IUnknown*)this;
\r
288 } else if (riid == IID_IEnumPins) {
\r
289 *ppv = (IEnumPins*)this;
\r
292 return E_NOINTERFACE;
\r
294 reinterpret_cast<IUnknown*>(this)->AddRef();
\r
298 STDMETHODIMP_(ULONG) CHWCEnumPins::AddRef()
\r
300 return InterlockedIncrement(&m_cRef);
\r
303 STDMETHODIMP_(ULONG) CHWCEnumPins::Release()
\r
305 if (InterlockedDecrement(&m_cRef) == 0) {
\r
312 STDMETHODIMP CHWCEnumPins::Next(ULONG cPins, IPin **ppPins,
\r
315 if (ppPins == NULL)
\r
319 if (m_pos < 1 && cPins > 0) {
\r
321 m_pFilter->FindPin(HWCPinName, &pPin);
\r
329 if (pcFetched != NULL ) {
\r
330 *pcFetched = fetched;
\r
333 return ( fetched == cPins ) ? S_OK : S_FALSE;
\r
336 STDMETHODIMP CHWCEnumPins::Skip(ULONG cPins)
\r
339 return ( m_pos >= 1 ) ? S_FALSE : S_OK;
\r
342 STDMETHODIMP CHWCEnumPins::Reset(void)
\r
348 STDMETHODIMP CHWCEnumPins::Clone(IEnumPins **ppEnum)
\r
350 if (ppEnum == NULL)
\r
352 *ppEnum = new CHWCEnumPins(m_pFilter, m_pos);
\r
353 if (*ppEnum == NULL) {
\r
354 return E_OUTOFMEMORY;
\r
359 CHWCFilter::CHWCFilter() : m_pFilterGraph(NULL), m_state(State_Stopped), m_cRef(1)
\r
361 m_pPin = new CHWCPin(this);
\r
362 InterlockedIncrement(&g_cComponents);
\r
365 CHWCFilter::~CHWCFilter()
\r
367 InterlockedDecrement(&g_cComponents);
\r
373 if (m_pFilterGraph) {
\r
374 m_pFilterGraph->Release();
\r
375 m_pFilterGraph = NULL;
\r
379 STDMETHODIMP CHWCFilter::QueryInterface(REFIID riid, void **ppv)
\r
381 if( riid == IID_IUnknown ) {
\r
382 *ppv = (IUnknown*)this;
\r
383 } else if( riid == IID_IPersist ) {
\r
384 *ppv = (IPersist*)this;
\r
385 } else if( riid == IID_IMediaFilter ) {
\r
386 *ppv = (IMediaFilter*)this;
\r
387 } else if( riid == IID_IBaseFilter ) {
\r
388 *ppv = (IBaseFilter*)this;
\r
391 StringFromIID(riid, &str);
\r
393 return E_NOINTERFACE;
\r
395 reinterpret_cast<IUnknown*>(this)->AddRef();
\r
400 STDMETHODIMP_(ULONG) CHWCFilter::AddRef()
\r
402 return InterlockedIncrement(&m_cRef);
\r
405 STDMETHODIMP_(ULONG) CHWCFilter::Release()
\r
407 if( InterlockedDecrement(&m_cRef) == 0) {
\r
414 STDMETHODIMP CHWCFilter::GetClassID(CLSID *pClsID)
\r
416 if (pClsID == NULL)
\r
421 STDMETHODIMP CHWCFilter::GetState(DWORD dwMSecs, FILTER_STATE *State)
\r
427 STDMETHODIMP CHWCFilter::SetSyncSource(IReferenceClock *pClock)
\r
432 STDMETHODIMP CHWCFilter::GetSyncSource(IReferenceClock **pClock)
\r
438 STDMETHODIMP CHWCFilter::Stop()
\r
440 m_pPin->EndFlush();
\r
441 m_state = State_Stopped;
\r
445 STDMETHODIMP CHWCFilter::Pause()
\r
447 m_state = State_Paused;
\r
451 STDMETHODIMP CHWCFilter::Run(REFERENCE_TIME tStart)
\r
453 if (m_state == State_Stopped){
\r
454 HRESULT hr = Pause();
\r
459 m_state = State_Running;
\r
463 STDMETHODIMP CHWCFilter::EnumPins(IEnumPins **ppEnum)
\r
465 if (ppEnum == NULL)
\r
467 *ppEnum = (IEnumPins*)(new CHWCEnumPins(this, 0));
\r
468 return *ppEnum == NULL ? E_OUTOFMEMORY : S_OK;
\r
471 STDMETHODIMP CHWCFilter::FindPin(LPCWSTR Id, IPin **ppPin)
\r
476 if (memcmp((void*)Id, (void*)HWCPinName, sizeof(HWCPinName))) {
\r
477 return VFW_E_NOT_FOUND;
\r
481 m_pPin = new CHWCPin(this);
\r
483 *ppPin = (IPin*)m_pPin;
\r
488 STDMETHODIMP CHWCFilter::QueryFilterInfo(FILTER_INFO *pInfo)
\r
493 memcpy((void*)pInfo->achName, (void*)HWCFilterName, sizeof(HWCFilterName));
\r
494 pInfo->pGraph = m_pFilterGraph;
\r
495 if(m_pFilterGraph) {
\r
496 m_pFilterGraph->AddRef();
\r
501 STDMETHODIMP CHWCFilter::JoinFilterGraph(IFilterGraph *pGraph,
\r
504 m_pFilterGraph = pGraph;
\r
509 STDMETHODIMP CHWCFilter::QueryVendorInfo(LPWSTR* pVendorInfo)
\r
514 HWCClassFactory::HWCClassFactory(void) : m_cRef(1)
\r
518 HWCClassFactory::~HWCClassFactory(void)
\r
522 STDMETHODIMP HWCClassFactory::QueryInterface(REFIID riid, LPVOID* ppv)
\r
524 if (riid == IID_IUnknown || riid == IID_IClassFactory) {
\r
525 *ppv = (IClassFactory*)this;
\r
528 return E_NOINTERFACE;
\r
531 reinterpret_cast<IUnknown*>(*ppv)->AddRef();
\r
535 STDMETHODIMP_(ULONG) HWCClassFactory::AddRef(void)
\r
537 return InterlockedIncrement(&m_cRef);
\r
540 STDMETHODIMP_(ULONG) HWCClassFactory::Release(void)
\r
542 if (InterlockedDecrement(&m_cRef) == 0) {
\r
549 STDMETHODIMP HWCClassFactory::CreateInstance(LPUNKNOWN pUnkOuter, REFIID riid, LPVOID* ppv)
\r
552 CHWCFilter* pFilter = NULL;
\r
555 if (pUnkOuter != NULL) {
\r
556 hr = CLASS_E_NOAGGREGATION;
\r
558 pFilter = new CHWCFilter;
\r
559 if (pFilter != NULL) {
\r
560 hr = pFilter->QueryInterface(riid, ppv);
\r
561 pFilter->Release();
\r
563 return E_OUTOFMEMORY;
\r
570 STDMETHODIMP HWCClassFactory::LockServer(BOOL bLock)
\r
573 InterlockedIncrement(&g_cServerLocks);
\r
575 InterlockedDecrement(&g_cServerLocks);
\r
580 STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
\r
582 HRESULT hr = CLASS_E_CLASSNOTAVAILABLE;
\r
583 HWCClassFactory *pFactory = NULL;
\r
585 if (rclsid != CLSID_HWCFilterClass) {
\r
589 pFactory = new HWCClassFactory;
\r
590 if (pFactory == NULL) {
\r
591 hr = E_OUTOFMEMORY;
\r
593 hr = pFactory->QueryInterface(riid, ppv);
\r
594 pFactory->Release();
\r
600 STDAPI DllCanUnloadNow(void)
\r
602 if ((g_cComponents == 0) && (g_cServerLocks == 0)) {
\r
608 STDAPI DllRegisterServer(void)
\r
613 STDAPI DllUnregisterServer(void)
\r