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);
192 TRACE("(%p)->(%p)\n",This,pState);
194 if ( pState == NULL )
197 EnterCriticalSection( &This->csFilter );
198 TRACE("(%p) state = %d\n",This,This->fstate);
199 *pState = This->fstate;
200 if ( This->bIntermediateState )
201 hr = VFW_S_STATE_INTERMEDIATE;
202 LeaveCriticalSection( &This->csFilter );
207 static HRESULT WINAPI
208 CBaseFilterImpl_fnSetSyncSource(IBaseFilter* iface,IReferenceClock* pobjClock)
210 ICOM_THIS(CBaseFilterImpl,iface);
212 TRACE("(%p)->(%p)\n",This,pobjClock);
214 EnterCriticalSection( &This->csFilter );
216 if ( This->pClock != NULL )
218 IReferenceClock_Release( This->pClock );
222 This->pClock = pobjClock;
223 if ( pobjClock != NULL )
224 IReferenceClock_AddRef( pobjClock );
226 LeaveCriticalSection( &This->csFilter );
231 static HRESULT WINAPI
232 CBaseFilterImpl_fnGetSyncSource(IBaseFilter* iface,IReferenceClock** ppobjClock)
234 ICOM_THIS(CBaseFilterImpl,iface);
235 HRESULT hr = VFW_E_NO_CLOCK;
237 TRACE("(%p)->(%p)\n",This,ppobjClock);
239 if ( ppobjClock == NULL )
242 EnterCriticalSection( &This->csFilter );
244 *ppobjClock = This->pClock;
245 if ( This->pClock != NULL )
248 IReferenceClock_AddRef( This->pClock );
251 LeaveCriticalSection( &This->csFilter );
257 static HRESULT WINAPI
258 CBaseFilterImpl_fnEnumPins(IBaseFilter* iface,IEnumPins** ppenum)
260 ICOM_THIS(CBaseFilterImpl,iface);
262 QUARTZ_CompList* pListPins;
263 QUARTZ_CompListItem* pItem;
266 TRACE("(%p)->(%p)\n",This,ppenum);
268 if ( ppenum == NULL )
272 pListPins = QUARTZ_CompList_Alloc();
273 if ( pListPins == NULL )
274 return E_OUTOFMEMORY;
276 QUARTZ_CompList_Lock( This->pInPins );
277 QUARTZ_CompList_Lock( This->pOutPins );
279 pItem = QUARTZ_CompList_GetFirst( This->pInPins );
280 while ( pItem != NULL )
282 punkPin = QUARTZ_CompList_GetItemPtr( pItem );
283 hr = QUARTZ_CompList_AddComp( pListPins, punkPin, NULL, 0 );
286 pItem = QUARTZ_CompList_GetNext( This->pInPins, pItem );
289 pItem = QUARTZ_CompList_GetFirst( This->pOutPins );
290 while ( pItem != NULL )
292 punkPin = QUARTZ_CompList_GetItemPtr( pItem );
293 hr = QUARTZ_CompList_AddComp( pListPins, punkPin, NULL, 0 );
296 pItem = QUARTZ_CompList_GetNext( This->pOutPins, pItem );
299 hr = QUARTZ_CreateEnumUnknown(
300 &IID_IEnumPins, (void**)ppenum, pListPins );
302 QUARTZ_CompList_Unlock( This->pInPins );
303 QUARTZ_CompList_Unlock( This->pOutPins );
305 QUARTZ_CompList_Free( pListPins );
310 static HRESULT WINAPI
311 CBaseFilterImpl_fnFindPin(IBaseFilter* iface,LPCWSTR lpwszId,IPin** ppobj)
313 ICOM_THIS(CBaseFilterImpl,iface);
315 FIXME("(%p)->(%s,%p) stub!\n",This,debugstr_w(lpwszId),ppobj);
325 static HRESULT WINAPI
326 CBaseFilterImpl_fnQueryFilterInfo(IBaseFilter* iface,FILTER_INFO* pfi)
328 ICOM_THIS(CBaseFilterImpl,iface);
330 TRACE("(%p)->(%p)\n",This,pfi);
335 EnterCriticalSection( &This->csFilter );
337 if ( This->cbNameGraph <= sizeof(WCHAR)*MAX_FILTER_NAME )
339 memcpy( pfi->achName, This->pwszNameGraph, This->cbNameGraph );
343 memcpy( pfi->achName, This->pwszNameGraph,
344 sizeof(WCHAR)*MAX_FILTER_NAME );
345 pfi->achName[MAX_FILTER_NAME-1] = (WCHAR)0;
348 pfi->pGraph = This->pfg;
349 if ( pfi->pGraph != NULL )
350 IFilterGraph_AddRef(pfi->pGraph);
352 LeaveCriticalSection( &This->csFilter );
357 static HRESULT WINAPI
358 CBaseFilterImpl_fnJoinFilterGraph(IBaseFilter* iface,IFilterGraph* pfg,LPCWSTR lpwszName)
360 ICOM_THIS(CBaseFilterImpl,iface);
363 TRACE("(%p)->(%p,%s)\n",This,pfg,debugstr_w(lpwszName));
365 EnterCriticalSection( &This->csFilter );
367 if ( This->pwszNameGraph != NULL )
369 QUARTZ_FreeMem( This->pwszNameGraph );
370 This->pwszNameGraph = NULL;
371 This->cbNameGraph = 0;
375 This->cbNameGraph = sizeof(WCHAR) * (lstrlenW(lpwszName)+1);
376 This->pwszNameGraph = (WCHAR*)QUARTZ_AllocMem( This->cbNameGraph );
377 if ( This->pwszNameGraph == NULL )
382 memcpy( This->pwszNameGraph, lpwszName, This->cbNameGraph );
386 LeaveCriticalSection( &This->csFilter );
391 static HRESULT WINAPI
392 CBaseFilterImpl_fnQueryVendorInfo(IBaseFilter* iface,LPWSTR* lpwszVendor)
394 ICOM_THIS(CBaseFilterImpl,iface);
396 TRACE("(%p)->(%p)\n",This,lpwszVendor);
398 /* E_NOTIMPL means 'no vender information'. */
403 /***************************************************************************
405 * construct/destruct CBaseFilterImpl
409 static ICOM_VTABLE(IBaseFilter) ibasefilter =
411 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
412 /* IUnknown fields */
413 CBaseFilterImpl_fnQueryInterface,
414 CBaseFilterImpl_fnAddRef,
415 CBaseFilterImpl_fnRelease,
416 /* IPersist fields */
417 CBaseFilterImpl_fnGetClassID,
418 /* IMediaFilter fields */
419 CBaseFilterImpl_fnStop,
420 CBaseFilterImpl_fnPause,
421 CBaseFilterImpl_fnRun,
422 CBaseFilterImpl_fnGetState,
423 CBaseFilterImpl_fnSetSyncSource,
424 CBaseFilterImpl_fnGetSyncSource,
425 /* IBaseFilter fields */
426 CBaseFilterImpl_fnEnumPins,
427 CBaseFilterImpl_fnFindPin,
428 CBaseFilterImpl_fnQueryFilterInfo,
429 CBaseFilterImpl_fnJoinFilterGraph,
430 CBaseFilterImpl_fnQueryVendorInfo,
434 HRESULT CBaseFilterImpl_InitIBaseFilter(
435 CBaseFilterImpl* This, IUnknown* punkControl,
436 const CLSID* pclsidFilter, LPCWSTR lpwszNameGraph,
437 const CBaseFilterHandlers* pHandlers )
439 TRACE("(%p,%p)\n",This,punkControl);
441 if ( punkControl == NULL )
443 ERR( "punkControl must not be NULL\n" );
447 ICOM_VTBL(This) = &ibasefilter;
448 This->punkControl = punkControl;
449 This->pHandlers = pHandlers;
450 This->pclsidFilter = pclsidFilter;
451 This->pInPins = NULL;
452 This->pOutPins = NULL;
454 This->cbNameGraph = 0;
455 This->pwszNameGraph = NULL;
458 This->fstate = State_Stopped;
459 This->bIntermediateState = FALSE;
461 This->cbNameGraph = sizeof(WCHAR) * (lstrlenW(lpwszNameGraph)+1);
462 This->pwszNameGraph = (WCHAR*)QUARTZ_AllocMem( This->cbNameGraph );
463 if ( This->pwszNameGraph == NULL )
464 return E_OUTOFMEMORY;
465 memcpy( This->pwszNameGraph, lpwszNameGraph, This->cbNameGraph );
467 This->pInPins = QUARTZ_CompList_Alloc();
468 This->pOutPins = QUARTZ_CompList_Alloc();
469 if ( This->pInPins == NULL || This->pOutPins == NULL )
471 if ( This->pInPins != NULL )
472 QUARTZ_CompList_Free(This->pInPins);
473 if ( This->pOutPins != NULL )
474 QUARTZ_CompList_Free(This->pOutPins);
475 QUARTZ_FreeMem(This->pwszNameGraph);
476 return E_OUTOFMEMORY;
479 InitializeCriticalSection( &This->csFilter );
484 void CBaseFilterImpl_UninitIBaseFilter( CBaseFilterImpl* This )
486 QUARTZ_CompListItem* pListItem;
489 TRACE("(%p)\n",This);
491 if ( This->pInPins != NULL )
495 pListItem = QUARTZ_CompList_GetFirst( This->pInPins );
496 if ( pListItem == NULL )
498 pPin = (IPin*)QUARTZ_CompList_GetItemPtr( pListItem );
499 QUARTZ_CompList_RemoveComp( This->pInPins, (IUnknown*)pPin );
502 QUARTZ_CompList_Free( This->pInPins );
503 This->pInPins = NULL;
505 if ( This->pOutPins != NULL )
509 pListItem = QUARTZ_CompList_GetFirst( This->pOutPins );
510 if ( pListItem == NULL )
512 pPin = (IPin*)QUARTZ_CompList_GetItemPtr( pListItem );
513 QUARTZ_CompList_RemoveComp( This->pOutPins, (IUnknown*)pPin );
516 QUARTZ_CompList_Free( This->pOutPins );
517 This->pOutPins = NULL;
520 if ( This->pwszNameGraph != NULL )
522 QUARTZ_FreeMem( This->pwszNameGraph );
523 This->pwszNameGraph = NULL;
526 if ( This->pClock != NULL )
528 IReferenceClock_Release( This->pClock );
532 DeleteCriticalSection( &This->csFilter );
535 /***************************************************************************
537 * CBaseFilterImpl methods
541 HRESULT CBaseFilterImpl_MediaEventNotify(
542 CBaseFilterImpl* This, long lEvent,LONG_PTR lParam1,LONG_PTR lParam2)
544 IMediaEventSink* pSink = NULL;
545 HRESULT hr = E_NOTIMPL;
547 EnterCriticalSection( &This->csFilter );
549 if ( This->pfg == NULL )
555 hr = IFilterGraph_QueryInterface( This->pfg, &IID_IMediaEventSink, (void**)&pSink );
564 hr = IMediaEventSink_Notify(pSink,lEvent,lParam1,lParam2);
565 IMediaEventSink_Release(pSink);
567 LeaveCriticalSection( &This->csFilter );