Started implementing AVI splitter.
[wine.git] / dlls / quartz / basefilt.c
blob4bec553ad489b765b37d4eed16a35bfffc0a2a7d
1 /*
2 * Implements IBaseFilter. (internal)
4 * hidenori@a2.ctktv.ne.jp
5 */
7 #include "config.h"
9 #include "windef.h"
10 #include "winbase.h"
11 #include "wingdi.h"
12 #include "winuser.h"
13 #include "winerror.h"
14 #include "strmif.h"
15 #include "vfwmsgs.h"
17 #include "debugtools.h"
18 DEFAULT_DEBUG_CHANNEL(quartz);
20 #include "quartz_private.h"
21 #include "basefilt.h"
22 #include "enumunk.h"
25 /***************************************************************************
27 * CBaseFilterImpl::IBaseFilter
31 static HRESULT WINAPI
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);
41 static ULONG WINAPI
42 CBaseFilterImpl_fnAddRef(IBaseFilter* iface)
44 ICOM_THIS(CBaseFilterImpl,iface);
46 TRACE("(%p)->()\n",This);
48 return IUnknown_AddRef(This->punkControl);
51 static ULONG WINAPI
52 CBaseFilterImpl_fnRelease(IBaseFilter* iface)
54 ICOM_THIS(CBaseFilterImpl,iface);
56 TRACE("(%p)->()\n",This);
58 return IUnknown_Release(This->punkControl);
62 static HRESULT WINAPI
63 CBaseFilterImpl_fnGetClassID(IBaseFilter* iface,CLSID* pclsid)
65 ICOM_THIS(CBaseFilterImpl,iface);
67 TRACE("(%p)->()\n",This);
69 if ( pclsid == NULL )
70 return E_POINTER;
72 memcpy( pclsid, This->pclsidFilter, sizeof(CLSID) );
74 return NOERROR;
77 static HRESULT WINAPI
78 CBaseFilterImpl_fnStop(IBaseFilter* iface)
80 ICOM_THIS(CBaseFilterImpl,iface);
81 HRESULT hr;
83 TRACE("(%p)->()\n",This);
85 hr = NOERROR;
87 EnterCriticalSection( &This->csFilter );
89 if ( This->fstate == State_Running )
91 if ( This->pHandlers->pOnInactive != NULL )
92 hr = This->pHandlers->pOnInactive( This );
93 if ( SUCCEEDED(hr) )
94 This->fstate = State_Paused;
96 if ( This->fstate == State_Paused )
98 if ( This->pHandlers->pOnStop != NULL )
99 hr = This->pHandlers->pOnStop( This );
100 if ( SUCCEEDED(hr) )
101 This->fstate = State_Stopped;
104 LeaveCriticalSection( &This->csFilter );
106 return hr;
109 static HRESULT WINAPI
110 CBaseFilterImpl_fnPause(IBaseFilter* iface)
112 ICOM_THIS(CBaseFilterImpl,iface);
113 HRESULT hr;
115 TRACE("(%p)->()\n",This);
117 hr = NOERROR;
119 EnterCriticalSection( &This->csFilter );
120 if ( This->fstate != State_Paused )
122 if ( This->pHandlers->pOnInactive != NULL )
123 hr = This->pHandlers->pOnInactive( This );
124 if ( SUCCEEDED(hr) )
125 This->fstate = State_Paused;
127 LeaveCriticalSection( &This->csFilter );
129 TRACE("hr = %08lx\n",hr);
131 return hr;
134 static HRESULT WINAPI
135 CBaseFilterImpl_fnRun(IBaseFilter* iface,REFERENCE_TIME rtStart)
137 ICOM_THIS(CBaseFilterImpl,iface);
138 HRESULT hr;
140 TRACE("(%p)->()\n",This);
142 hr = NOERROR;
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 );
152 if ( SUCCEEDED(hr) )
153 This->fstate = State_Paused;
155 if ( This->fstate == State_Paused )
157 if ( This->pHandlers->pOnActive != NULL )
158 hr = This->pHandlers->pOnActive( This );
159 if ( SUCCEEDED(hr) )
160 This->fstate = State_Running;
163 LeaveCriticalSection( &This->csFilter );
165 return hr;
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 )
176 return E_POINTER;
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 );
185 return NOERROR;
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 );
200 This->pClock = NULL;
203 This->pClock = pobjClock;
204 if ( pobjClock != NULL )
205 IReferenceClock_AddRef( pobjClock );
207 LeaveCriticalSection( &This->csFilter );
209 return NOERROR;
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 )
221 return E_POINTER;
223 EnterCriticalSection( &This->csFilter );
225 *ppobjClock = This->pClock;
226 if ( This->pClock != NULL )
228 hr = NOERROR;
229 IReferenceClock_AddRef( This->pClock );
232 LeaveCriticalSection( &This->csFilter );
234 return hr;
238 static HRESULT WINAPI
239 CBaseFilterImpl_fnEnumPins(IBaseFilter* iface,IEnumPins** ppenum)
241 ICOM_THIS(CBaseFilterImpl,iface);
242 HRESULT hr = E_FAIL;
243 QUARTZ_CompList* pListPins;
244 QUARTZ_CompListItem* pItem;
245 IUnknown* punkPin;
247 TRACE("(%p)->(%p)\n",This,ppenum);
249 if ( ppenum == NULL )
250 return E_POINTER;
251 *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 );
265 if ( FAILED(hr) )
266 goto err;
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 );
275 if ( FAILED(hr) )
276 goto err;
277 pItem = QUARTZ_CompList_GetNext( This->pOutPins, pItem );
280 hr = QUARTZ_CreateEnumUnknown(
281 &IID_IEnumPins, (void**)ppenum, pListPins );
282 err:
283 QUARTZ_CompList_Unlock( This->pInPins );
284 QUARTZ_CompList_Unlock( This->pOutPins );
286 QUARTZ_CompList_Free( pListPins );
288 return hr;
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);
298 if ( ppobj == NULL )
299 return E_POINTER;
303 return E_NOTIMPL;
306 static HRESULT WINAPI
307 CBaseFilterImpl_fnQueryFilterInfo(IBaseFilter* iface,FILTER_INFO* pfi)
309 ICOM_THIS(CBaseFilterImpl,iface);
311 TRACE("(%p)->(%p)\n",This,pfi);
313 if ( pfi == NULL )
314 return E_POINTER;
316 EnterCriticalSection( &This->csFilter );
318 if ( This->cbNameGraph <= sizeof(WCHAR)*MAX_FILTER_NAME )
320 memcpy( pfi->achName, This->pwszNameGraph, This->cbNameGraph );
322 else
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 );
335 return NOERROR;
338 static HRESULT WINAPI
339 CBaseFilterImpl_fnJoinFilterGraph(IBaseFilter* iface,IFilterGraph* pfg,LPCWSTR lpwszName)
341 ICOM_THIS(CBaseFilterImpl,iface);
342 HRESULT hr;
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;
355 This->pfg = pfg;
356 This->cbNameGraph = sizeof(WCHAR) * (lstrlenW(lpwszName)+1);
357 This->pwszNameGraph = (WCHAR*)QUARTZ_AllocMem( This->cbNameGraph );
358 if ( This->pwszNameGraph == NULL )
360 hr = E_OUTOFMEMORY;
361 goto err;
363 memcpy( This->pwszNameGraph, lpwszName, This->cbNameGraph );
365 hr = NOERROR;
366 err:
367 LeaveCriticalSection( &This->csFilter );
369 return hr;
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'. */
380 return E_NOTIMPL;
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" );
425 return E_INVALIDARG;
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;
434 This->pfg = NULL;
435 This->cbNameGraph = 0;
436 This->pwszNameGraph = NULL;
437 This->pClock = NULL;
438 This->rtStart = 0;
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 );
461 return NOERROR;
464 void CBaseFilterImpl_UninitIBaseFilter( CBaseFilterImpl* This )
466 QUARTZ_CompListItem* pListItem;
467 IPin* pPin;
469 TRACE("(%p)\n",This);
471 if ( This->pInPins != NULL )
473 while ( 1 )
475 pListItem = QUARTZ_CompList_GetFirst( This->pInPins );
476 if ( pListItem == NULL )
477 break;
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 )
487 while ( 1 )
489 pListItem = QUARTZ_CompList_GetFirst( This->pOutPins );
490 if ( pListItem == NULL )
491 break;
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 );
509 This->pClock = NULL;
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 )
531 hr = E_UNEXPECTED;
532 goto err;
535 hr = IFilterGraph_QueryInterface( This->pfg, &IID_IMediaEventSink, (void**)&pSink );
536 if ( FAILED(hr) )
537 goto err;
538 if ( pSink == NULL )
540 hr = E_FAIL;
541 goto err;
544 hr = IMediaEventSink_Notify(pSink,lEvent,lParam1,lParam2);
545 IMediaEventSink_Release(pSink);
546 err:
547 LeaveCriticalSection( &This->csFilter );
549 return hr;