2 * Implements IBaseFilter. (internal)
4 * Copyright (C) Hidenori TAKESHIMA <hidenori@a2.ctktv.ne.jp>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
31 #include "wine/debug.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(quartz);
34 #include "quartz_private.h"
39 /***************************************************************************
41 * CBaseFilterImpl::IBaseFilter
46 CBaseFilterImpl_fnQueryInterface(IBaseFilter* iface,REFIID riid,void** ppobj)
48 ICOM_THIS(CBaseFilterImpl,iface);
50 TRACE("(%p)->()\n",This);
52 return IUnknown_QueryInterface(This->punkControl,riid,ppobj);
56 CBaseFilterImpl_fnAddRef(IBaseFilter* iface)
58 ICOM_THIS(CBaseFilterImpl,iface);
60 TRACE("(%p)->()\n",This);
62 return IUnknown_AddRef(This->punkControl);
66 CBaseFilterImpl_fnRelease(IBaseFilter* iface)
68 ICOM_THIS(CBaseFilterImpl,iface);
70 TRACE("(%p)->()\n",This);
72 return IUnknown_Release(This->punkControl);
77 CBaseFilterImpl_fnGetClassID(IBaseFilter* iface,CLSID* pclsid)
79 ICOM_THIS(CBaseFilterImpl,iface);
81 TRACE("(%p)->()\n",This);
86 memcpy( pclsid, This->pclsidFilter, sizeof(CLSID) );
92 CBaseFilterImpl_fnStop(IBaseFilter* iface)
94 ICOM_THIS(CBaseFilterImpl,iface);
97 TRACE("(%p)->()\n",This);
101 EnterCriticalSection( &This->csFilter );
102 TRACE("(%p) state = %d\n",This,This->fstate);
104 if ( This->fstate == State_Running )
106 if ( This->pHandlers->pOnInactive != NULL )
107 hr = This->pHandlers->pOnInactive( This );
109 This->fstate = State_Paused;
111 if ( This->fstate == State_Paused )
113 if ( This->pHandlers->pOnStop != NULL )
114 hr = This->pHandlers->pOnStop( This );
116 This->fstate = State_Stopped;
119 LeaveCriticalSection( &This->csFilter );
124 static HRESULT WINAPI
125 CBaseFilterImpl_fnPause(IBaseFilter* iface)
127 ICOM_THIS(CBaseFilterImpl,iface);
130 TRACE("(%p)->()\n",This);
134 EnterCriticalSection( &This->csFilter );
135 TRACE("(%p) state = %d\n",This,This->fstate);
137 if ( This->fstate != State_Paused )
139 if ( This->pHandlers->pOnInactive != NULL )
140 hr = This->pHandlers->pOnInactive( This );
142 This->fstate = State_Paused;
144 LeaveCriticalSection( &This->csFilter );
146 TRACE("hr = %08lx\n",hr);
151 static HRESULT WINAPI
152 CBaseFilterImpl_fnRun(IBaseFilter* iface,REFERENCE_TIME rtStart)
154 ICOM_THIS(CBaseFilterImpl,iface);
157 TRACE("(%p)->()\n",This);
161 EnterCriticalSection( &This->csFilter );
162 TRACE("(%p) state = %d\n",This,This->fstate);
164 This->rtStart = rtStart;
166 if ( This->fstate == State_Stopped )
168 if ( This->pHandlers->pOnInactive != NULL )
169 hr = This->pHandlers->pOnInactive( This );
171 This->fstate = State_Paused;
173 if ( This->fstate == State_Paused )
175 if ( This->pHandlers->pOnActive != NULL )
176 hr = This->pHandlers->pOnActive( This );
178 This->fstate = State_Running;
181 LeaveCriticalSection( &This->csFilter );
186 static HRESULT WINAPI
187 CBaseFilterImpl_fnGetState(IBaseFilter* iface,DWORD dw,FILTER_STATE* pState)
189 ICOM_THIS(CBaseFilterImpl,iface);
191 TRACE("(%p)->(%p)\n",This,pState);
193 if ( pState == NULL )
196 /* FIXME - ignore 'intermediate state' now */
198 EnterCriticalSection( &This->csFilter );
199 TRACE("(%p) state = %d\n",This,This->fstate);
200 *pState = This->fstate;
201 LeaveCriticalSection( &This->csFilter );
206 static HRESULT WINAPI
207 CBaseFilterImpl_fnSetSyncSource(IBaseFilter* iface,IReferenceClock* pobjClock)
209 ICOM_THIS(CBaseFilterImpl,iface);
211 TRACE("(%p)->(%p)\n",This,pobjClock);
213 EnterCriticalSection( &This->csFilter );
215 if ( This->pClock != NULL )
217 IReferenceClock_Release( This->pClock );
221 This->pClock = pobjClock;
222 if ( pobjClock != NULL )
223 IReferenceClock_AddRef( pobjClock );
225 LeaveCriticalSection( &This->csFilter );
230 static HRESULT WINAPI
231 CBaseFilterImpl_fnGetSyncSource(IBaseFilter* iface,IReferenceClock** ppobjClock)
233 ICOM_THIS(CBaseFilterImpl,iface);
234 HRESULT hr = VFW_E_NO_CLOCK;
236 TRACE("(%p)->(%p)\n",This,ppobjClock);
238 if ( ppobjClock == NULL )
241 EnterCriticalSection( &This->csFilter );
243 *ppobjClock = This->pClock;
244 if ( This->pClock != NULL )
247 IReferenceClock_AddRef( This->pClock );
250 LeaveCriticalSection( &This->csFilter );
256 static HRESULT WINAPI
257 CBaseFilterImpl_fnEnumPins(IBaseFilter* iface,IEnumPins** ppenum)
259 ICOM_THIS(CBaseFilterImpl,iface);
261 QUARTZ_CompList* pListPins;
262 QUARTZ_CompListItem* pItem;
265 TRACE("(%p)->(%p)\n",This,ppenum);
267 if ( ppenum == NULL )
271 pListPins = QUARTZ_CompList_Alloc();
272 if ( pListPins == NULL )
273 return E_OUTOFMEMORY;
275 QUARTZ_CompList_Lock( This->pInPins );
276 QUARTZ_CompList_Lock( This->pOutPins );
278 pItem = QUARTZ_CompList_GetFirst( This->pInPins );
279 while ( pItem != NULL )
281 punkPin = QUARTZ_CompList_GetItemPtr( pItem );
282 hr = QUARTZ_CompList_AddComp( pListPins, punkPin, NULL, 0 );
285 pItem = QUARTZ_CompList_GetNext( This->pInPins, pItem );
288 pItem = QUARTZ_CompList_GetFirst( This->pOutPins );
289 while ( pItem != NULL )
291 punkPin = QUARTZ_CompList_GetItemPtr( pItem );
292 hr = QUARTZ_CompList_AddComp( pListPins, punkPin, NULL, 0 );
295 pItem = QUARTZ_CompList_GetNext( This->pOutPins, pItem );
298 hr = QUARTZ_CreateEnumUnknown(
299 &IID_IEnumPins, (void**)ppenum, pListPins );
301 QUARTZ_CompList_Unlock( This->pInPins );
302 QUARTZ_CompList_Unlock( This->pOutPins );
304 QUARTZ_CompList_Free( pListPins );
309 static HRESULT WINAPI
310 CBaseFilterImpl_fnFindPin(IBaseFilter* iface,LPCWSTR lpwszId,IPin** ppobj)
312 ICOM_THIS(CBaseFilterImpl,iface);
314 FIXME("(%p)->(%s,%p) stub!\n",This,debugstr_w(lpwszId),ppobj);
324 static HRESULT WINAPI
325 CBaseFilterImpl_fnQueryFilterInfo(IBaseFilter* iface,FILTER_INFO* pfi)
327 ICOM_THIS(CBaseFilterImpl,iface);
329 TRACE("(%p)->(%p)\n",This,pfi);
334 EnterCriticalSection( &This->csFilter );
336 if ( This->cbNameGraph <= sizeof(WCHAR)*MAX_FILTER_NAME )
338 memcpy( pfi->achName, This->pwszNameGraph, This->cbNameGraph );
342 memcpy( pfi->achName, This->pwszNameGraph,
343 sizeof(WCHAR)*MAX_FILTER_NAME );
344 pfi->achName[MAX_FILTER_NAME-1] = (WCHAR)0;
347 pfi->pGraph = This->pfg;
348 if ( pfi->pGraph != NULL )
349 IFilterGraph_AddRef(pfi->pGraph);
351 LeaveCriticalSection( &This->csFilter );
356 static HRESULT WINAPI
357 CBaseFilterImpl_fnJoinFilterGraph(IBaseFilter* iface,IFilterGraph* pfg,LPCWSTR lpwszName)
359 ICOM_THIS(CBaseFilterImpl,iface);
362 TRACE("(%p)->(%p,%s)\n",This,pfg,debugstr_w(lpwszName));
364 EnterCriticalSection( &This->csFilter );
366 if ( This->pwszNameGraph != NULL )
368 QUARTZ_FreeMem( This->pwszNameGraph );
369 This->pwszNameGraph = NULL;
370 This->cbNameGraph = 0;
374 This->cbNameGraph = sizeof(WCHAR) * (lstrlenW(lpwszName)+1);
375 This->pwszNameGraph = (WCHAR*)QUARTZ_AllocMem( This->cbNameGraph );
376 if ( This->pwszNameGraph == NULL )
381 memcpy( This->pwszNameGraph, lpwszName, This->cbNameGraph );
385 LeaveCriticalSection( &This->csFilter );
390 static HRESULT WINAPI
391 CBaseFilterImpl_fnQueryVendorInfo(IBaseFilter* iface,LPWSTR* lpwszVendor)
393 ICOM_THIS(CBaseFilterImpl,iface);
395 TRACE("(%p)->(%p)\n",This,lpwszVendor);
397 /* E_NOTIMPL means 'no vender information'. */
402 /***************************************************************************
404 * construct/destruct CBaseFilterImpl
408 static ICOM_VTABLE(IBaseFilter) ibasefilter =
410 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
411 /* IUnknown fields */
412 CBaseFilterImpl_fnQueryInterface,
413 CBaseFilterImpl_fnAddRef,
414 CBaseFilterImpl_fnRelease,
415 /* IPersist fields */
416 CBaseFilterImpl_fnGetClassID,
417 /* IMediaFilter fields */
418 CBaseFilterImpl_fnStop,
419 CBaseFilterImpl_fnPause,
420 CBaseFilterImpl_fnRun,
421 CBaseFilterImpl_fnGetState,
422 CBaseFilterImpl_fnSetSyncSource,
423 CBaseFilterImpl_fnGetSyncSource,
424 /* IBaseFilter fields */
425 CBaseFilterImpl_fnEnumPins,
426 CBaseFilterImpl_fnFindPin,
427 CBaseFilterImpl_fnQueryFilterInfo,
428 CBaseFilterImpl_fnJoinFilterGraph,
429 CBaseFilterImpl_fnQueryVendorInfo,
433 HRESULT CBaseFilterImpl_InitIBaseFilter(
434 CBaseFilterImpl* This, IUnknown* punkControl,
435 const CLSID* pclsidFilter, LPCWSTR lpwszNameGraph,
436 const CBaseFilterHandlers* pHandlers )
438 TRACE("(%p,%p)\n",This,punkControl);
440 if ( punkControl == NULL )
442 ERR( "punkControl must not be NULL\n" );
446 ICOM_VTBL(This) = &ibasefilter;
447 This->punkControl = punkControl;
448 This->pHandlers = pHandlers;
449 This->pclsidFilter = pclsidFilter;
450 This->pInPins = NULL;
451 This->pOutPins = NULL;
453 This->cbNameGraph = 0;
454 This->pwszNameGraph = NULL;
457 This->fstate = State_Stopped;
459 This->cbNameGraph = sizeof(WCHAR) * (lstrlenW(lpwszNameGraph)+1);
460 This->pwszNameGraph = (WCHAR*)QUARTZ_AllocMem( This->cbNameGraph );
461 if ( This->pwszNameGraph == NULL )
462 return E_OUTOFMEMORY;
463 memcpy( This->pwszNameGraph, lpwszNameGraph, This->cbNameGraph );
465 This->pInPins = QUARTZ_CompList_Alloc();
466 This->pOutPins = QUARTZ_CompList_Alloc();
467 if ( This->pInPins == NULL || This->pOutPins == NULL )
469 if ( This->pInPins != NULL )
470 QUARTZ_CompList_Free(This->pInPins);
471 if ( This->pOutPins != NULL )
472 QUARTZ_CompList_Free(This->pOutPins);
473 QUARTZ_FreeMem(This->pwszNameGraph);
474 return E_OUTOFMEMORY;
477 InitializeCriticalSection( &This->csFilter );
482 void CBaseFilterImpl_UninitIBaseFilter( CBaseFilterImpl* This )
484 QUARTZ_CompListItem* pListItem;
487 TRACE("(%p)\n",This);
489 if ( This->pInPins != NULL )
493 pListItem = QUARTZ_CompList_GetFirst( This->pInPins );
494 if ( pListItem == NULL )
496 pPin = (IPin*)QUARTZ_CompList_GetItemPtr( pListItem );
497 QUARTZ_CompList_RemoveComp( This->pInPins, (IUnknown*)pPin );
500 QUARTZ_CompList_Free( This->pInPins );
501 This->pInPins = NULL;
503 if ( This->pOutPins != NULL )
507 pListItem = QUARTZ_CompList_GetFirst( This->pOutPins );
508 if ( pListItem == NULL )
510 pPin = (IPin*)QUARTZ_CompList_GetItemPtr( pListItem );
511 QUARTZ_CompList_RemoveComp( This->pOutPins, (IUnknown*)pPin );
514 QUARTZ_CompList_Free( This->pOutPins );
515 This->pOutPins = NULL;
518 if ( This->pwszNameGraph != NULL )
520 QUARTZ_FreeMem( This->pwszNameGraph );
521 This->pwszNameGraph = NULL;
524 if ( This->pClock != NULL )
526 IReferenceClock_Release( This->pClock );
530 DeleteCriticalSection( &This->csFilter );
533 /***************************************************************************
535 * CBaseFilterImpl methods
539 HRESULT CBaseFilterImpl_MediaEventNotify(
540 CBaseFilterImpl* This, long lEvent,LONG_PTR lParam1,LONG_PTR lParam2)
542 IMediaEventSink* pSink = NULL;
543 HRESULT hr = E_NOTIMPL;
545 EnterCriticalSection( &This->csFilter );
547 if ( This->pfg == NULL )
553 hr = IFilterGraph_QueryInterface( This->pfg, &IID_IMediaEventSink, (void**)&pSink );
562 hr = IMediaEventSink_Notify(pSink,lEvent,lParam1,lParam2);
563 IMediaEventSink_Release(pSink);
565 LeaveCriticalSection( &This->csFilter );