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 if ( This->bIntermediateState )
104 LeaveCriticalSection( &This->csFilter );
105 return VFW_S_STATE_INTERMEDIATE; /* FIXME? */
107 TRACE("(%p) state = %d\n",This,This->fstate);
109 if ( This->fstate == State_Running )
111 if ( This->pHandlers->pOnInactive != NULL )
112 hr = This->pHandlers->pOnInactive( This );
114 This->fstate = State_Paused;
116 if ( This->fstate == State_Paused )
118 if ( This->pHandlers->pOnStop != NULL )
119 hr = This->pHandlers->pOnStop( This );
121 This->fstate = State_Stopped;
124 LeaveCriticalSection( &This->csFilter );
129 static HRESULT WINAPI
130 CBaseFilterImpl_fnPause(IBaseFilter* iface)
132 ICOM_THIS(CBaseFilterImpl,iface);
135 TRACE("(%p)->()\n",This);
139 EnterCriticalSection( &This->csFilter );
140 if ( This->bIntermediateState )
142 LeaveCriticalSection( &This->csFilter );
143 return VFW_E_WRONG_STATE; /* FIXME? */
145 TRACE("(%p) state = %d\n",This,This->fstate);
147 if ( This->fstate != State_Paused )
149 if ( This->pHandlers->pOnInactive != NULL )
150 hr = This->pHandlers->pOnInactive( This );
152 This->fstate = State_Paused;
154 LeaveCriticalSection( &This->csFilter );
156 TRACE("hr = %08lx\n",hr);
161 static HRESULT WINAPI
162 CBaseFilterImpl_fnRun(IBaseFilter* iface,REFERENCE_TIME rtStart)
164 ICOM_THIS(CBaseFilterImpl,iface);
167 TRACE("(%p)->()\n",This);
171 EnterCriticalSection( &This->csFilter );
172 if ( This->bIntermediateState )
174 LeaveCriticalSection( &This->csFilter );
175 return VFW_E_WRONG_STATE; /* FIXME? */
177 TRACE("(%p) state = %d\n",This,This->fstate);
179 This->rtStart = rtStart;
181 if ( This->fstate == State_Stopped )
183 if ( This->pHandlers->pOnInactive != NULL )
184 hr = This->pHandlers->pOnInactive( This );
186 This->fstate = State_Paused;
188 if ( This->fstate == State_Paused )
190 if ( This->pHandlers->pOnActive != NULL )
191 hr = This->pHandlers->pOnActive( This );
193 This->fstate = State_Running;
196 LeaveCriticalSection( &This->csFilter );
201 static HRESULT WINAPI
202 CBaseFilterImpl_fnGetState(IBaseFilter* iface,DWORD dw,FILTER_STATE* pState)
204 ICOM_THIS(CBaseFilterImpl,iface);
207 TRACE("(%p)->(%p)\n",This,pState);
209 if ( pState == NULL )
212 EnterCriticalSection( &This->csFilter );
213 TRACE("(%p) state = %d\n",This,This->fstate);
214 *pState = This->fstate;
215 if ( This->bIntermediateState )
216 hr = VFW_S_STATE_INTERMEDIATE;
217 LeaveCriticalSection( &This->csFilter );
222 static HRESULT WINAPI
223 CBaseFilterImpl_fnSetSyncSource(IBaseFilter* iface,IReferenceClock* pobjClock)
225 ICOM_THIS(CBaseFilterImpl,iface);
227 TRACE("(%p)->(%p)\n",This,pobjClock);
229 EnterCriticalSection( &This->csFilter );
231 if ( This->pClock != NULL )
233 IReferenceClock_Release( This->pClock );
237 This->pClock = pobjClock;
238 if ( pobjClock != NULL )
239 IReferenceClock_AddRef( pobjClock );
241 LeaveCriticalSection( &This->csFilter );
246 static HRESULT WINAPI
247 CBaseFilterImpl_fnGetSyncSource(IBaseFilter* iface,IReferenceClock** ppobjClock)
249 ICOM_THIS(CBaseFilterImpl,iface);
250 HRESULT hr = VFW_E_NO_CLOCK;
252 TRACE("(%p)->(%p)\n",This,ppobjClock);
254 if ( ppobjClock == NULL )
257 EnterCriticalSection( &This->csFilter );
259 *ppobjClock = This->pClock;
260 if ( This->pClock != NULL )
263 IReferenceClock_AddRef( This->pClock );
266 LeaveCriticalSection( &This->csFilter );
272 static HRESULT WINAPI
273 CBaseFilterImpl_fnEnumPins(IBaseFilter* iface,IEnumPins** ppenum)
275 ICOM_THIS(CBaseFilterImpl,iface);
277 QUARTZ_CompList* pListPins;
278 QUARTZ_CompListItem* pItem;
281 TRACE("(%p)->(%p)\n",This,ppenum);
283 if ( ppenum == NULL )
287 pListPins = QUARTZ_CompList_Alloc();
288 if ( pListPins == NULL )
289 return E_OUTOFMEMORY;
291 QUARTZ_CompList_Lock( This->pInPins );
292 QUARTZ_CompList_Lock( This->pOutPins );
294 pItem = QUARTZ_CompList_GetFirst( This->pInPins );
295 while ( pItem != NULL )
297 punkPin = QUARTZ_CompList_GetItemPtr( pItem );
298 hr = QUARTZ_CompList_AddComp( pListPins, punkPin, NULL, 0 );
301 pItem = QUARTZ_CompList_GetNext( This->pInPins, pItem );
304 pItem = QUARTZ_CompList_GetFirst( This->pOutPins );
305 while ( pItem != NULL )
307 punkPin = QUARTZ_CompList_GetItemPtr( pItem );
308 hr = QUARTZ_CompList_AddComp( pListPins, punkPin, NULL, 0 );
311 pItem = QUARTZ_CompList_GetNext( This->pOutPins, pItem );
314 hr = QUARTZ_CreateEnumUnknown(
315 &IID_IEnumPins, (void**)ppenum, pListPins );
317 QUARTZ_CompList_Unlock( This->pInPins );
318 QUARTZ_CompList_Unlock( This->pOutPins );
320 QUARTZ_CompList_Free( pListPins );
325 static HRESULT WINAPI
326 CBaseFilterImpl_fnFindPin(IBaseFilter* iface,LPCWSTR lpwszId,IPin** ppobj)
328 ICOM_THIS(CBaseFilterImpl,iface);
330 FIXME("(%p)->(%s,%p) stub!\n",This,debugstr_w(lpwszId),ppobj);
340 static HRESULT WINAPI
341 CBaseFilterImpl_fnQueryFilterInfo(IBaseFilter* iface,FILTER_INFO* pfi)
343 ICOM_THIS(CBaseFilterImpl,iface);
345 TRACE("(%p)->(%p)\n",This,pfi);
350 EnterCriticalSection( &This->csFilter );
352 if ( This->cbNameGraph <= sizeof(WCHAR)*MAX_FILTER_NAME )
354 memcpy( pfi->achName, This->pwszNameGraph, This->cbNameGraph );
358 memcpy( pfi->achName, This->pwszNameGraph,
359 sizeof(WCHAR)*MAX_FILTER_NAME );
360 pfi->achName[MAX_FILTER_NAME-1] = (WCHAR)0;
363 pfi->pGraph = This->pfg;
364 if ( pfi->pGraph != NULL )
365 IFilterGraph_AddRef(pfi->pGraph);
367 LeaveCriticalSection( &This->csFilter );
372 static HRESULT WINAPI
373 CBaseFilterImpl_fnJoinFilterGraph(IBaseFilter* iface,IFilterGraph* pfg,LPCWSTR lpwszName)
375 ICOM_THIS(CBaseFilterImpl,iface);
378 TRACE("(%p)->(%p,%s)\n",This,pfg,debugstr_w(lpwszName));
380 EnterCriticalSection( &This->csFilter );
382 if ( This->pwszNameGraph != NULL )
384 QUARTZ_FreeMem( This->pwszNameGraph );
385 This->pwszNameGraph = NULL;
386 This->cbNameGraph = 0;
390 This->cbNameGraph = sizeof(WCHAR) * (lstrlenW(lpwszName)+1);
391 This->pwszNameGraph = (WCHAR*)QUARTZ_AllocMem( This->cbNameGraph );
392 if ( This->pwszNameGraph == NULL )
397 memcpy( This->pwszNameGraph, lpwszName, This->cbNameGraph );
401 LeaveCriticalSection( &This->csFilter );
406 static HRESULT WINAPI
407 CBaseFilterImpl_fnQueryVendorInfo(IBaseFilter* iface,LPWSTR* lpwszVendor)
409 ICOM_THIS(CBaseFilterImpl,iface);
411 TRACE("(%p)->(%p)\n",This,lpwszVendor);
413 /* E_NOTIMPL means 'no vender information'. */
418 /***************************************************************************
420 * construct/destruct CBaseFilterImpl
424 static ICOM_VTABLE(IBaseFilter) ibasefilter =
426 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
427 /* IUnknown fields */
428 CBaseFilterImpl_fnQueryInterface,
429 CBaseFilterImpl_fnAddRef,
430 CBaseFilterImpl_fnRelease,
431 /* IPersist fields */
432 CBaseFilterImpl_fnGetClassID,
433 /* IMediaFilter fields */
434 CBaseFilterImpl_fnStop,
435 CBaseFilterImpl_fnPause,
436 CBaseFilterImpl_fnRun,
437 CBaseFilterImpl_fnGetState,
438 CBaseFilterImpl_fnSetSyncSource,
439 CBaseFilterImpl_fnGetSyncSource,
440 /* IBaseFilter fields */
441 CBaseFilterImpl_fnEnumPins,
442 CBaseFilterImpl_fnFindPin,
443 CBaseFilterImpl_fnQueryFilterInfo,
444 CBaseFilterImpl_fnJoinFilterGraph,
445 CBaseFilterImpl_fnQueryVendorInfo,
449 HRESULT CBaseFilterImpl_InitIBaseFilter(
450 CBaseFilterImpl* This, IUnknown* punkControl,
451 const CLSID* pclsidFilter, LPCWSTR lpwszNameGraph,
452 const CBaseFilterHandlers* pHandlers )
454 TRACE("(%p,%p)\n",This,punkControl);
456 if ( punkControl == NULL )
458 ERR( "punkControl must not be NULL\n" );
462 ICOM_VTBL(This) = &ibasefilter;
463 This->punkControl = punkControl;
464 This->pHandlers = pHandlers;
465 This->pclsidFilter = pclsidFilter;
466 This->pInPins = NULL;
467 This->pOutPins = NULL;
469 This->cbNameGraph = 0;
470 This->pwszNameGraph = NULL;
473 This->fstate = State_Stopped;
474 This->bIntermediateState = FALSE;
476 This->cbNameGraph = sizeof(WCHAR) * (lstrlenW(lpwszNameGraph)+1);
477 This->pwszNameGraph = (WCHAR*)QUARTZ_AllocMem( This->cbNameGraph );
478 if ( This->pwszNameGraph == NULL )
479 return E_OUTOFMEMORY;
480 memcpy( This->pwszNameGraph, lpwszNameGraph, This->cbNameGraph );
482 This->pInPins = QUARTZ_CompList_Alloc();
483 This->pOutPins = QUARTZ_CompList_Alloc();
484 if ( This->pInPins == NULL || This->pOutPins == NULL )
486 if ( This->pInPins != NULL )
487 QUARTZ_CompList_Free(This->pInPins);
488 if ( This->pOutPins != NULL )
489 QUARTZ_CompList_Free(This->pOutPins);
490 QUARTZ_FreeMem(This->pwszNameGraph);
491 return E_OUTOFMEMORY;
494 InitializeCriticalSection( &This->csFilter );
499 void CBaseFilterImpl_UninitIBaseFilter( CBaseFilterImpl* This )
501 QUARTZ_CompListItem* pListItem;
504 TRACE("(%p)\n",This);
506 if ( This->pInPins != NULL )
510 pListItem = QUARTZ_CompList_GetFirst( This->pInPins );
511 if ( pListItem == NULL )
513 pPin = (IPin*)QUARTZ_CompList_GetItemPtr( pListItem );
514 QUARTZ_CompList_RemoveComp( This->pInPins, (IUnknown*)pPin );
517 QUARTZ_CompList_Free( This->pInPins );
518 This->pInPins = NULL;
520 if ( This->pOutPins != NULL )
524 pListItem = QUARTZ_CompList_GetFirst( This->pOutPins );
525 if ( pListItem == NULL )
527 pPin = (IPin*)QUARTZ_CompList_GetItemPtr( pListItem );
528 QUARTZ_CompList_RemoveComp( This->pOutPins, (IUnknown*)pPin );
531 QUARTZ_CompList_Free( This->pOutPins );
532 This->pOutPins = NULL;
535 if ( This->pwszNameGraph != NULL )
537 QUARTZ_FreeMem( This->pwszNameGraph );
538 This->pwszNameGraph = NULL;
541 if ( This->pClock != NULL )
543 IReferenceClock_Release( This->pClock );
547 DeleteCriticalSection( &This->csFilter );
550 /***************************************************************************
552 * CBaseFilterImpl methods
556 HRESULT CBaseFilterImpl_MediaEventNotify(
557 CBaseFilterImpl* This, long lEvent,LONG_PTR lParam1,LONG_PTR lParam2)
559 IMediaEventSink* pSink = NULL;
560 HRESULT hr = E_NOTIMPL;
562 EnterCriticalSection( &This->csFilter );
564 if ( This->pfg == NULL )
570 hr = IFilterGraph_QueryInterface( This->pfg, &IID_IMediaEventSink, (void**)&pSink );
579 hr = IMediaEventSink_Notify(pSink,lEvent,lParam1,lParam2);
580 IMediaEventSink_Release(pSink);
582 LeaveCriticalSection( &This->csFilter );