2 * Implements IBaseFilter. (internal)
4 * hidenori@a2.ctktv.ne.jp
17 #include "debugtools.h"
18 DEFAULT_DEBUG_CHANNEL(quartz);
20 #include "quartz_private.h"
25 /***************************************************************************
27 * CBaseFilterImpl::IBaseFilter
32 CBaseFilterImpl_fnQueryInterface(IBaseFilter* iface,REFIID riid,void** ppobj)
34 ICOM_THIS(CBaseFilterImpl,iface);
36 TRACE("(%p)->()\n",This);
38 return IUnknown_QueryInterface(This->punkControl,riid,ppobj);
42 CBaseFilterImpl_fnAddRef(IBaseFilter* iface)
44 ICOM_THIS(CBaseFilterImpl,iface);
46 TRACE("(%p)->()\n",This);
48 return IUnknown_AddRef(This->punkControl);
52 CBaseFilterImpl_fnRelease(IBaseFilter* iface)
54 ICOM_THIS(CBaseFilterImpl,iface);
56 TRACE("(%p)->()\n",This);
58 return IUnknown_Release(This->punkControl);
63 CBaseFilterImpl_fnGetClassID(IBaseFilter* iface,CLSID* pclsid)
65 ICOM_THIS(CBaseFilterImpl,iface);
67 TRACE("(%p)->()\n",This);
72 memcpy( pclsid, This->pclsidFilter, sizeof(CLSID) );
78 CBaseFilterImpl_fnStop(IBaseFilter* iface)
80 ICOM_THIS(CBaseFilterImpl,iface);
83 TRACE("(%p)->()\n",This);
87 EnterCriticalSection( &This->csFilter );
88 TRACE("(%p) state = %d\n",This,This->fstate);
90 if ( This->fstate == State_Running )
92 if ( This->pHandlers->pOnInactive != NULL )
93 hr = This->pHandlers->pOnInactive( This );
95 This->fstate = State_Paused;
97 if ( This->fstate == State_Paused )
99 if ( This->pHandlers->pOnStop != NULL )
100 hr = This->pHandlers->pOnStop( This );
102 This->fstate = State_Stopped;
105 LeaveCriticalSection( &This->csFilter );
110 static HRESULT WINAPI
111 CBaseFilterImpl_fnPause(IBaseFilter* iface)
113 ICOM_THIS(CBaseFilterImpl,iface);
116 TRACE("(%p)->()\n",This);
120 EnterCriticalSection( &This->csFilter );
121 TRACE("(%p) state = %d\n",This,This->fstate);
123 if ( This->fstate != State_Paused )
125 if ( This->pHandlers->pOnInactive != NULL )
126 hr = This->pHandlers->pOnInactive( This );
128 This->fstate = State_Paused;
130 LeaveCriticalSection( &This->csFilter );
132 TRACE("hr = %08lx\n",hr);
137 static HRESULT WINAPI
138 CBaseFilterImpl_fnRun(IBaseFilter* iface,REFERENCE_TIME rtStart)
140 ICOM_THIS(CBaseFilterImpl,iface);
143 TRACE("(%p)->()\n",This);
147 EnterCriticalSection( &This->csFilter );
148 TRACE("(%p) state = %d\n",This,This->fstate);
150 This->rtStart = rtStart;
152 if ( This->fstate == State_Stopped )
154 if ( This->pHandlers->pOnInactive != NULL )
155 hr = This->pHandlers->pOnInactive( This );
157 This->fstate = State_Paused;
159 if ( This->fstate == State_Paused )
161 if ( This->pHandlers->pOnActive != NULL )
162 hr = This->pHandlers->pOnActive( This );
164 This->fstate = State_Running;
167 LeaveCriticalSection( &This->csFilter );
172 static HRESULT WINAPI
173 CBaseFilterImpl_fnGetState(IBaseFilter* iface,DWORD dw,FILTER_STATE* pState)
175 ICOM_THIS(CBaseFilterImpl,iface);
177 TRACE("(%p)->(%p)\n",This,pState);
179 if ( pState == NULL )
182 /* FIXME - ignore 'intermediate state' now */
184 EnterCriticalSection( &This->csFilter );
185 TRACE("(%p) state = %d\n",This,This->fstate);
186 *pState = This->fstate;
187 LeaveCriticalSection( &This->csFilter );
192 static HRESULT WINAPI
193 CBaseFilterImpl_fnSetSyncSource(IBaseFilter* iface,IReferenceClock* pobjClock)
195 ICOM_THIS(CBaseFilterImpl,iface);
197 TRACE("(%p)->(%p)\n",This,pobjClock);
199 EnterCriticalSection( &This->csFilter );
201 if ( This->pClock != NULL )
203 IReferenceClock_Release( This->pClock );
207 This->pClock = pobjClock;
208 if ( pobjClock != NULL )
209 IReferenceClock_AddRef( pobjClock );
211 LeaveCriticalSection( &This->csFilter );
216 static HRESULT WINAPI
217 CBaseFilterImpl_fnGetSyncSource(IBaseFilter* iface,IReferenceClock** ppobjClock)
219 ICOM_THIS(CBaseFilterImpl,iface);
220 HRESULT hr = VFW_E_NO_CLOCK;
222 TRACE("(%p)->(%p)\n",This,ppobjClock);
224 if ( ppobjClock == NULL )
227 EnterCriticalSection( &This->csFilter );
229 *ppobjClock = This->pClock;
230 if ( This->pClock != NULL )
233 IReferenceClock_AddRef( This->pClock );
236 LeaveCriticalSection( &This->csFilter );
242 static HRESULT WINAPI
243 CBaseFilterImpl_fnEnumPins(IBaseFilter* iface,IEnumPins** ppenum)
245 ICOM_THIS(CBaseFilterImpl,iface);
247 QUARTZ_CompList* pListPins;
248 QUARTZ_CompListItem* pItem;
251 TRACE("(%p)->(%p)\n",This,ppenum);
253 if ( ppenum == NULL )
257 pListPins = QUARTZ_CompList_Alloc();
258 if ( pListPins == NULL )
259 return E_OUTOFMEMORY;
261 QUARTZ_CompList_Lock( This->pInPins );
262 QUARTZ_CompList_Lock( This->pOutPins );
264 pItem = QUARTZ_CompList_GetFirst( This->pInPins );
265 while ( pItem != NULL )
267 punkPin = QUARTZ_CompList_GetItemPtr( pItem );
268 hr = QUARTZ_CompList_AddComp( pListPins, punkPin, NULL, 0 );
271 pItem = QUARTZ_CompList_GetNext( This->pInPins, pItem );
274 pItem = QUARTZ_CompList_GetFirst( This->pOutPins );
275 while ( pItem != NULL )
277 punkPin = QUARTZ_CompList_GetItemPtr( pItem );
278 hr = QUARTZ_CompList_AddComp( pListPins, punkPin, NULL, 0 );
281 pItem = QUARTZ_CompList_GetNext( This->pOutPins, pItem );
284 hr = QUARTZ_CreateEnumUnknown(
285 &IID_IEnumPins, (void**)ppenum, pListPins );
287 QUARTZ_CompList_Unlock( This->pInPins );
288 QUARTZ_CompList_Unlock( This->pOutPins );
290 QUARTZ_CompList_Free( pListPins );
295 static HRESULT WINAPI
296 CBaseFilterImpl_fnFindPin(IBaseFilter* iface,LPCWSTR lpwszId,IPin** ppobj)
298 ICOM_THIS(CBaseFilterImpl,iface);
300 FIXME("(%p)->(%s,%p) stub!\n",This,debugstr_w(lpwszId),ppobj);
310 static HRESULT WINAPI
311 CBaseFilterImpl_fnQueryFilterInfo(IBaseFilter* iface,FILTER_INFO* pfi)
313 ICOM_THIS(CBaseFilterImpl,iface);
315 TRACE("(%p)->(%p)\n",This,pfi);
320 EnterCriticalSection( &This->csFilter );
322 if ( This->cbNameGraph <= sizeof(WCHAR)*MAX_FILTER_NAME )
324 memcpy( pfi->achName, This->pwszNameGraph, This->cbNameGraph );
328 memcpy( pfi->achName, This->pwszNameGraph,
329 sizeof(WCHAR)*MAX_FILTER_NAME );
330 pfi->achName[MAX_FILTER_NAME-1] = (WCHAR)0;
333 pfi->pGraph = This->pfg;
334 if ( pfi->pGraph != NULL )
335 IFilterGraph_AddRef(pfi->pGraph);
337 LeaveCriticalSection( &This->csFilter );
342 static HRESULT WINAPI
343 CBaseFilterImpl_fnJoinFilterGraph(IBaseFilter* iface,IFilterGraph* pfg,LPCWSTR lpwszName)
345 ICOM_THIS(CBaseFilterImpl,iface);
348 TRACE("(%p)->(%p,%s)\n",This,pfg,debugstr_w(lpwszName));
350 EnterCriticalSection( &This->csFilter );
352 if ( This->pwszNameGraph != NULL )
354 QUARTZ_FreeMem( This->pwszNameGraph );
355 This->pwszNameGraph = NULL;
356 This->cbNameGraph = 0;
360 This->cbNameGraph = sizeof(WCHAR) * (lstrlenW(lpwszName)+1);
361 This->pwszNameGraph = (WCHAR*)QUARTZ_AllocMem( This->cbNameGraph );
362 if ( This->pwszNameGraph == NULL )
367 memcpy( This->pwszNameGraph, lpwszName, This->cbNameGraph );
371 LeaveCriticalSection( &This->csFilter );
376 static HRESULT WINAPI
377 CBaseFilterImpl_fnQueryVendorInfo(IBaseFilter* iface,LPWSTR* lpwszVendor)
379 ICOM_THIS(CBaseFilterImpl,iface);
381 TRACE("(%p)->(%p)\n",This,lpwszVendor);
383 /* E_NOTIMPL means 'no vender information'. */
388 /***************************************************************************
390 * construct/destruct CBaseFilterImpl
394 static ICOM_VTABLE(IBaseFilter) ibasefilter =
396 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
397 /* IUnknown fields */
398 CBaseFilterImpl_fnQueryInterface,
399 CBaseFilterImpl_fnAddRef,
400 CBaseFilterImpl_fnRelease,
401 /* IPersist fields */
402 CBaseFilterImpl_fnGetClassID,
403 /* IMediaFilter fields */
404 CBaseFilterImpl_fnStop,
405 CBaseFilterImpl_fnPause,
406 CBaseFilterImpl_fnRun,
407 CBaseFilterImpl_fnGetState,
408 CBaseFilterImpl_fnSetSyncSource,
409 CBaseFilterImpl_fnGetSyncSource,
410 /* IBaseFilter fields */
411 CBaseFilterImpl_fnEnumPins,
412 CBaseFilterImpl_fnFindPin,
413 CBaseFilterImpl_fnQueryFilterInfo,
414 CBaseFilterImpl_fnJoinFilterGraph,
415 CBaseFilterImpl_fnQueryVendorInfo,
419 HRESULT CBaseFilterImpl_InitIBaseFilter(
420 CBaseFilterImpl* This, IUnknown* punkControl,
421 const CLSID* pclsidFilter, LPCWSTR lpwszNameGraph,
422 const CBaseFilterHandlers* pHandlers )
424 TRACE("(%p,%p)\n",This,punkControl);
426 if ( punkControl == NULL )
428 ERR( "punkControl must not be NULL\n" );
432 ICOM_VTBL(This) = &ibasefilter;
433 This->punkControl = punkControl;
434 This->pHandlers = pHandlers;
435 This->pclsidFilter = pclsidFilter;
436 This->pInPins = NULL;
437 This->pOutPins = NULL;
439 This->cbNameGraph = 0;
440 This->pwszNameGraph = NULL;
443 This->fstate = State_Stopped;
445 This->cbNameGraph = sizeof(WCHAR) * (lstrlenW(lpwszNameGraph)+1);
446 This->pwszNameGraph = (WCHAR*)QUARTZ_AllocMem( This->cbNameGraph );
447 if ( This->pwszNameGraph == NULL )
448 return E_OUTOFMEMORY;
449 memcpy( This->pwszNameGraph, lpwszNameGraph, This->cbNameGraph );
451 This->pInPins = QUARTZ_CompList_Alloc();
452 This->pOutPins = QUARTZ_CompList_Alloc();
453 if ( This->pInPins == NULL || This->pOutPins == NULL )
455 if ( This->pInPins != NULL )
456 QUARTZ_CompList_Free(This->pInPins);
457 if ( This->pOutPins != NULL )
458 QUARTZ_CompList_Free(This->pOutPins);
459 QUARTZ_FreeMem(This->pwszNameGraph);
460 return E_OUTOFMEMORY;
463 InitializeCriticalSection( &This->csFilter );
468 void CBaseFilterImpl_UninitIBaseFilter( CBaseFilterImpl* This )
470 QUARTZ_CompListItem* pListItem;
473 TRACE("(%p)\n",This);
475 if ( This->pInPins != NULL )
479 pListItem = QUARTZ_CompList_GetFirst( This->pInPins );
480 if ( pListItem == NULL )
482 pPin = (IPin*)QUARTZ_CompList_GetItemPtr( pListItem );
483 QUARTZ_CompList_RemoveComp( This->pInPins, (IUnknown*)pPin );
486 QUARTZ_CompList_Free( This->pInPins );
487 This->pInPins = NULL;
489 if ( This->pOutPins != NULL )
493 pListItem = QUARTZ_CompList_GetFirst( This->pOutPins );
494 if ( pListItem == NULL )
496 pPin = (IPin*)QUARTZ_CompList_GetItemPtr( pListItem );
497 QUARTZ_CompList_RemoveComp( This->pOutPins, (IUnknown*)pPin );
500 QUARTZ_CompList_Free( This->pOutPins );
501 This->pOutPins = NULL;
504 if ( This->pwszNameGraph != NULL )
506 QUARTZ_FreeMem( This->pwszNameGraph );
507 This->pwszNameGraph = NULL;
510 if ( This->pClock != NULL )
512 IReferenceClock_Release( This->pClock );
516 DeleteCriticalSection( &This->csFilter );
519 /***************************************************************************
521 * CBaseFilterImpl methods
525 HRESULT CBaseFilterImpl_MediaEventNotify(
526 CBaseFilterImpl* This, long lEvent,LONG_PTR lParam1,LONG_PTR lParam2)
528 IMediaEventSink* pSink = NULL;
529 HRESULT hr = E_NOTIMPL;
531 EnterCriticalSection( &This->csFilter );
533 if ( This->pfg == NULL )
539 hr = IFilterGraph_QueryInterface( This->pfg, &IID_IMediaEventSink, (void**)&pSink );
548 hr = IMediaEventSink_Notify(pSink,lEvent,lParam1,lParam2);
549 IMediaEventSink_Release(pSink);
551 LeaveCriticalSection( &This->csFilter );