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 );
89 if ( This->fstate == State_Running )
91 if ( This->pHandlers->pOnInactive != NULL )
92 hr = This->pHandlers->pOnInactive( This );
94 This->fstate = State_Paused;
96 if ( This->fstate == State_Paused )
98 if ( This->pHandlers->pOnStop != NULL )
99 hr = This->pHandlers->pOnStop( This );
101 This->fstate = State_Stopped;
104 LeaveCriticalSection( &This->csFilter );
109 static HRESULT WINAPI
110 CBaseFilterImpl_fnPause(IBaseFilter* iface)
112 ICOM_THIS(CBaseFilterImpl,iface);
115 TRACE("(%p)->()\n",This);
119 EnterCriticalSection( &This->csFilter );
120 if ( This->fstate != State_Paused )
122 if ( This->pHandlers->pOnInactive != NULL )
123 hr = This->pHandlers->pOnInactive( This );
125 This->fstate = State_Paused;
127 LeaveCriticalSection( &This->csFilter );
129 TRACE("hr = %08lx\n",hr);
134 static HRESULT WINAPI
135 CBaseFilterImpl_fnRun(IBaseFilter* iface,REFERENCE_TIME rtStart)
137 ICOM_THIS(CBaseFilterImpl,iface);
140 TRACE("(%p)->()\n",This);
144 EnterCriticalSection( &This->csFilter );
146 This->rtStart = rtStart;
148 if ( This->fstate == State_Stopped )
150 if ( This->pHandlers->pOnInactive != NULL )
151 hr = This->pHandlers->pOnInactive( This );
153 This->fstate = State_Paused;
155 if ( This->fstate == State_Paused )
157 if ( This->pHandlers->pOnActive != NULL )
158 hr = This->pHandlers->pOnActive( This );
160 This->fstate = State_Running;
163 LeaveCriticalSection( &This->csFilter );
168 static HRESULT WINAPI
169 CBaseFilterImpl_fnGetState(IBaseFilter* iface,DWORD dw,FILTER_STATE* pState)
171 ICOM_THIS(CBaseFilterImpl,iface);
173 TRACE("(%p)->(%p)\n",This,pState);
175 if ( pState == NULL )
178 /* FIXME - ignore 'intermediate state' now */
180 EnterCriticalSection( &This->csFilter );
181 TRACE("state %d\n",This->fstate);
182 *pState = This->fstate;
183 LeaveCriticalSection( &This->csFilter );
188 static HRESULT WINAPI
189 CBaseFilterImpl_fnSetSyncSource(IBaseFilter* iface,IReferenceClock* pobjClock)
191 ICOM_THIS(CBaseFilterImpl,iface);
193 TRACE("(%p)->(%p)\n",This,pobjClock);
195 EnterCriticalSection( &This->csFilter );
197 if ( This->pClock != NULL )
199 IReferenceClock_Release( This->pClock );
203 This->pClock = pobjClock;
204 if ( pobjClock != NULL )
205 IReferenceClock_AddRef( pobjClock );
207 LeaveCriticalSection( &This->csFilter );
212 static HRESULT WINAPI
213 CBaseFilterImpl_fnGetSyncSource(IBaseFilter* iface,IReferenceClock** ppobjClock)
215 ICOM_THIS(CBaseFilterImpl,iface);
216 HRESULT hr = VFW_E_NO_CLOCK;
218 TRACE("(%p)->(%p)\n",This,ppobjClock);
220 if ( ppobjClock == NULL )
223 EnterCriticalSection( &This->csFilter );
225 *ppobjClock = This->pClock;
226 if ( This->pClock != NULL )
229 IReferenceClock_AddRef( This->pClock );
232 LeaveCriticalSection( &This->csFilter );
238 static HRESULT WINAPI
239 CBaseFilterImpl_fnEnumPins(IBaseFilter* iface,IEnumPins** ppenum)
241 ICOM_THIS(CBaseFilterImpl,iface);
243 QUARTZ_CompList* pListPins;
244 QUARTZ_CompListItem* pItem;
247 TRACE("(%p)->(%p)\n",This,ppenum);
249 if ( ppenum == NULL )
253 pListPins = QUARTZ_CompList_Alloc();
254 if ( pListPins == NULL )
255 return E_OUTOFMEMORY;
257 QUARTZ_CompList_Lock( This->pInPins );
258 QUARTZ_CompList_Lock( This->pOutPins );
260 pItem = QUARTZ_CompList_GetFirst( This->pInPins );
261 while ( pItem != NULL )
263 punkPin = QUARTZ_CompList_GetItemPtr( pItem );
264 hr = QUARTZ_CompList_AddComp( pListPins, punkPin, NULL, 0 );
267 pItem = QUARTZ_CompList_GetNext( This->pInPins, pItem );
270 pItem = QUARTZ_CompList_GetFirst( This->pOutPins );
271 while ( pItem != NULL )
273 punkPin = QUARTZ_CompList_GetItemPtr( pItem );
274 hr = QUARTZ_CompList_AddComp( pListPins, punkPin, NULL, 0 );
277 pItem = QUARTZ_CompList_GetNext( This->pOutPins, pItem );
280 hr = QUARTZ_CreateEnumUnknown(
281 &IID_IEnumPins, (void**)ppenum, pListPins );
283 QUARTZ_CompList_Unlock( This->pInPins );
284 QUARTZ_CompList_Unlock( This->pOutPins );
286 QUARTZ_CompList_Free( pListPins );
291 static HRESULT WINAPI
292 CBaseFilterImpl_fnFindPin(IBaseFilter* iface,LPCWSTR lpwszId,IPin** ppobj)
294 ICOM_THIS(CBaseFilterImpl,iface);
296 FIXME("(%p)->(%s,%p) stub!\n",This,debugstr_w(lpwszId),ppobj);
306 static HRESULT WINAPI
307 CBaseFilterImpl_fnQueryFilterInfo(IBaseFilter* iface,FILTER_INFO* pfi)
309 ICOM_THIS(CBaseFilterImpl,iface);
311 TRACE("(%p)->(%p)\n",This,pfi);
316 EnterCriticalSection( &This->csFilter );
318 if ( This->cbNameGraph <= sizeof(WCHAR)*MAX_FILTER_NAME )
320 memcpy( pfi->achName, This->pwszNameGraph, This->cbNameGraph );
324 memcpy( pfi->achName, This->pwszNameGraph,
325 sizeof(WCHAR)*MAX_FILTER_NAME );
326 pfi->achName[MAX_FILTER_NAME-1] = (WCHAR)0;
329 pfi->pGraph = This->pfg;
330 if ( pfi->pGraph != NULL )
331 IFilterGraph_AddRef(pfi->pGraph);
333 LeaveCriticalSection( &This->csFilter );
338 static HRESULT WINAPI
339 CBaseFilterImpl_fnJoinFilterGraph(IBaseFilter* iface,IFilterGraph* pfg,LPCWSTR lpwszName)
341 ICOM_THIS(CBaseFilterImpl,iface);
344 TRACE("(%p)->(%p,%s)\n",This,pfg,debugstr_w(lpwszName));
346 EnterCriticalSection( &This->csFilter );
348 if ( This->pwszNameGraph != NULL )
350 QUARTZ_FreeMem( This->pwszNameGraph );
351 This->pwszNameGraph = NULL;
352 This->cbNameGraph = 0;
356 This->cbNameGraph = sizeof(WCHAR) * (lstrlenW(lpwszName)+1);
357 This->pwszNameGraph = (WCHAR*)QUARTZ_AllocMem( This->cbNameGraph );
358 if ( This->pwszNameGraph == NULL )
363 memcpy( This->pwszNameGraph, lpwszName, This->cbNameGraph );
367 LeaveCriticalSection( &This->csFilter );
372 static HRESULT WINAPI
373 CBaseFilterImpl_fnQueryVendorInfo(IBaseFilter* iface,LPWSTR* lpwszVendor)
375 ICOM_THIS(CBaseFilterImpl,iface);
377 TRACE("(%p)->(%p)\n",This,lpwszVendor);
379 /* E_NOTIMPL means 'no vender information'. */
384 /***************************************************************************
386 * construct/destruct CBaseFilterImpl
390 static ICOM_VTABLE(IBaseFilter) ibasefilter =
392 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
393 /* IUnknown fields */
394 CBaseFilterImpl_fnQueryInterface,
395 CBaseFilterImpl_fnAddRef,
396 CBaseFilterImpl_fnRelease,
397 /* IPersist fields */
398 CBaseFilterImpl_fnGetClassID,
399 /* IMediaFilter fields */
400 CBaseFilterImpl_fnStop,
401 CBaseFilterImpl_fnPause,
402 CBaseFilterImpl_fnRun,
403 CBaseFilterImpl_fnGetState,
404 CBaseFilterImpl_fnSetSyncSource,
405 CBaseFilterImpl_fnGetSyncSource,
406 /* IBaseFilter fields */
407 CBaseFilterImpl_fnEnumPins,
408 CBaseFilterImpl_fnFindPin,
409 CBaseFilterImpl_fnQueryFilterInfo,
410 CBaseFilterImpl_fnJoinFilterGraph,
411 CBaseFilterImpl_fnQueryVendorInfo,
415 HRESULT CBaseFilterImpl_InitIBaseFilter(
416 CBaseFilterImpl* This, IUnknown* punkControl,
417 const CLSID* pclsidFilter, LPCWSTR lpwszNameGraph,
418 const CBaseFilterHandlers* pHandlers )
420 TRACE("(%p,%p)\n",This,punkControl);
422 if ( punkControl == NULL )
424 ERR( "punkControl must not be NULL\n" );
428 ICOM_VTBL(This) = &ibasefilter;
429 This->punkControl = punkControl;
430 This->pHandlers = pHandlers;
431 This->pclsidFilter = pclsidFilter;
432 This->pInPins = NULL;
433 This->pOutPins = NULL;
435 This->cbNameGraph = 0;
436 This->pwszNameGraph = NULL;
439 This->fstate = State_Stopped;
441 This->cbNameGraph = sizeof(WCHAR) * (lstrlenW(lpwszNameGraph)+1);
442 This->pwszNameGraph = (WCHAR*)QUARTZ_AllocMem( This->cbNameGraph );
443 if ( This->pwszNameGraph == NULL )
444 return E_OUTOFMEMORY;
445 memcpy( This->pwszNameGraph, lpwszNameGraph, This->cbNameGraph );
447 This->pInPins = QUARTZ_CompList_Alloc();
448 This->pOutPins = QUARTZ_CompList_Alloc();
449 if ( This->pInPins == NULL || This->pOutPins == NULL )
451 if ( This->pInPins != NULL )
452 QUARTZ_CompList_Free(This->pInPins);
453 if ( This->pOutPins != NULL )
454 QUARTZ_CompList_Free(This->pOutPins);
455 QUARTZ_FreeMem(This->pwszNameGraph);
456 return E_OUTOFMEMORY;
459 InitializeCriticalSection( &This->csFilter );
464 void CBaseFilterImpl_UninitIBaseFilter( CBaseFilterImpl* This )
466 QUARTZ_CompListItem* pListItem;
469 TRACE("(%p)\n",This);
471 if ( This->pInPins != NULL )
475 pListItem = QUARTZ_CompList_GetFirst( This->pInPins );
476 if ( pListItem == NULL )
478 pPin = (IPin*)QUARTZ_CompList_GetItemPtr( pListItem );
479 QUARTZ_CompList_RemoveComp( This->pInPins, (IUnknown*)pPin );
482 QUARTZ_CompList_Free( This->pInPins );
483 This->pInPins = NULL;
485 if ( This->pOutPins != NULL )
489 pListItem = QUARTZ_CompList_GetFirst( This->pOutPins );
490 if ( pListItem == NULL )
492 pPin = (IPin*)QUARTZ_CompList_GetItemPtr( pListItem );
493 QUARTZ_CompList_RemoveComp( This->pOutPins, (IUnknown*)pPin );
496 QUARTZ_CompList_Free( This->pOutPins );
497 This->pOutPins = NULL;
500 if ( This->pwszNameGraph != NULL )
502 QUARTZ_FreeMem( This->pwszNameGraph );
503 This->pwszNameGraph = NULL;
506 if ( This->pClock != NULL )
508 IReferenceClock_Release( This->pClock );
512 DeleteCriticalSection( &This->csFilter );
515 /***************************************************************************
517 * CBaseFilterImpl methods
521 HRESULT CBaseFilterImpl_MediaEventNotify(
522 CBaseFilterImpl* This, long lEvent,LONG_PTR lParam1,LONG_PTR lParam2)
524 IMediaEventSink* pSink = NULL;
525 HRESULT hr = E_NOTIMPL;
527 EnterCriticalSection( &This->csFilter );
529 if ( This->pfg == NULL )
535 hr = IFilterGraph_QueryInterface( This->pfg, &IID_IMediaEventSink, (void**)&pSink );
544 hr = IMediaEventSink_Notify(pSink,lEvent,lParam1,lParam2);
545 IMediaEventSink_Release(pSink);
547 LeaveCriticalSection( &This->csFilter );