2 * Implementation of IMediaFilter for FilterGraph.
6 * hidenori@a2.ctktv.ne.jp
22 #include "debugtools.h"
23 DEFAULT_DEBUG_CHANNEL(quartz
);
25 #include "quartz_private.h"
29 #define WINE_QUARTZ_POLL_INTERVAL 10
31 /*****************************************************************************/
34 HRESULT
CFilterGraph_PollGraphState(
39 QUARTZ_CompListItem
* pItem
;
43 *pState
= State_Stopped
;
45 EnterCriticalSection( &This
->m_csGraphState
);
46 QUARTZ_CompList_Lock( This
->m_pFilterList
);
48 pItem
= QUARTZ_CompList_GetFirst( This
->m_pFilterList
);
50 while ( pItem
!= NULL
)
52 pFilter
= (IBaseFilter
*)QUARTZ_CompList_GetItemPtr( pItem
);
53 hr
= IBaseFilter_GetState( pFilter
, (DWORD
)0, pState
);
57 pItem
= QUARTZ_CompList_GetNext( This
->m_pFilterList
, pItem
);
60 QUARTZ_CompList_Unlock( This
->m_pFilterList
);
61 LeaveCriticalSection( &This
->m_csGraphState
);
63 TRACE( "returns %08lx, state %d\n",
69 /*****************************************************************************/
72 IMediaFilter_fnQueryInterface(IMediaFilter
* iface
,REFIID riid
,void** ppobj
)
74 CFilterGraph_THIS(iface
,mediafilter
);
76 TRACE("(%p)->()\n",This
);
78 return IUnknown_QueryInterface(This
->unk
.punkControl
,riid
,ppobj
);
82 IMediaFilter_fnAddRef(IMediaFilter
* iface
)
84 CFilterGraph_THIS(iface
,mediafilter
);
86 TRACE("(%p)->()\n",This
);
88 return IUnknown_AddRef(This
->unk
.punkControl
);
92 IMediaFilter_fnRelease(IMediaFilter
* iface
)
94 CFilterGraph_THIS(iface
,mediafilter
);
96 TRACE("(%p)->()\n",This
);
98 return IUnknown_Release(This
->unk
.punkControl
);
102 static HRESULT WINAPI
103 IMediaFilter_fnGetClassID(IMediaFilter
* iface
,CLSID
* pclsid
)
105 CFilterGraph_THIS(iface
,mediafilter
);
107 TRACE("(%p)->()\n",This
);
109 return IPersist_GetClassID(
110 CFilterGraph_IPersist(This
),pclsid
);
113 static HRESULT WINAPI
114 IMediaFilter_fnStop(IMediaFilter
* iface
)
116 CFilterGraph_THIS(iface
,mediafilter
);
119 QUARTZ_CompListItem
* pItem
;
120 IBaseFilter
* pFilter
;
122 TRACE("(%p)->()\n",This
);
126 EnterCriticalSection( &This
->m_csGraphState
);
128 if ( This
->m_stateGraph
!= State_Stopped
)
130 /* IDistributorNotify_Stop() */
132 QUARTZ_CompList_Lock( This
->m_pFilterList
);
134 pItem
= QUARTZ_CompList_GetFirst( This
->m_pFilterList
);
136 while ( pItem
!= NULL
)
138 pFilter
= (IBaseFilter
*)QUARTZ_CompList_GetItemPtr( pItem
);
139 hrFilter
= IBaseFilter_Stop( pFilter
);
140 if ( hrFilter
!= S_OK
)
146 pItem
= QUARTZ_CompList_GetNext( This
->m_pFilterList
, pItem
);
149 QUARTZ_CompList_Unlock( This
->m_pFilterList
);
151 This
->m_stateGraph
= State_Stopped
;
154 LeaveCriticalSection( &This
->m_csGraphState
);
159 static HRESULT WINAPI
160 IMediaFilter_fnPause(IMediaFilter
* iface
)
162 CFilterGraph_THIS(iface
,mediafilter
);
165 QUARTZ_CompListItem
* pItem
;
166 IBaseFilter
* pFilter
;
168 TRACE("(%p)->()\n",This
);
172 EnterCriticalSection( &This
->m_csGraphState
);
174 if ( This
->m_stateGraph
!= State_Paused
)
176 /* IDistributorNotify_Pause() */
178 QUARTZ_CompList_Lock( This
->m_pFilterList
);
180 pItem
= QUARTZ_CompList_GetFirst( This
->m_pFilterList
);
182 while ( pItem
!= NULL
)
184 pFilter
= (IBaseFilter
*)QUARTZ_CompList_GetItemPtr( pItem
);
185 hrFilter
= IBaseFilter_Pause( pFilter
);
186 if ( hrFilter
!= S_OK
)
192 pItem
= QUARTZ_CompList_GetNext( This
->m_pFilterList
, pItem
);
195 QUARTZ_CompList_Unlock( This
->m_pFilterList
);
197 This
->m_stateGraph
= State_Paused
;
200 LeaveCriticalSection( &This
->m_csGraphState
);
205 static HRESULT WINAPI
206 IMediaFilter_fnRun(IMediaFilter
* iface
,REFERENCE_TIME rtStart
)
208 CFilterGraph_THIS(iface
,mediafilter
);
211 QUARTZ_CompListItem
* pItem
;
212 IBaseFilter
* pFilter
;
213 IReferenceClock
* pClock
;
215 TRACE("(%p)->()\n",This
);
217 EnterCriticalSection( &This
->m_csGraphState
);
219 if ( This
->m_stateGraph
== State_Stopped
)
221 hr
= IMediaFilter_Pause(iface
);
226 /* handle the special time. */
227 if ( rtStart
== (REFERENCE_TIME
)0 )
229 hr
= IMediaFilter_GetSyncSource(iface
,&pClock
);
230 if ( hr
== S_OK
&& pClock
!= NULL
)
232 IReferenceClock_GetTime(pClock
,&rtStart
);
233 IReferenceClock_Release(pClock
);
239 if ( This
->m_stateGraph
!= State_Running
)
241 /* IDistributorNotify_Run() */
243 QUARTZ_CompList_Lock( This
->m_pFilterList
);
245 pItem
= QUARTZ_CompList_GetFirst( This
->m_pFilterList
);
247 while ( pItem
!= NULL
)
249 pFilter
= (IBaseFilter
*)QUARTZ_CompList_GetItemPtr( pItem
);
250 hrFilter
= IBaseFilter_Run( pFilter
, rtStart
);
251 if ( hrFilter
!= S_OK
)
257 pItem
= QUARTZ_CompList_GetNext( This
->m_pFilterList
, pItem
);
260 QUARTZ_CompList_Unlock( This
->m_pFilterList
);
262 This
->m_stateGraph
= State_Running
;
266 LeaveCriticalSection( &This
->m_csGraphState
);
271 static HRESULT WINAPI
272 IMediaFilter_fnGetState(IMediaFilter
* iface
,DWORD dwTimeOut
,FILTER_STATE
* pState
)
274 CFilterGraph_THIS(iface
,mediafilter
);
279 TRACE("(%p)->(%p)\n",This
,pState
);
280 if ( pState
== NULL
)
283 dwTickStart
= GetTickCount();
287 hr
= CFilterGraph_PollGraphState( This
, pState
);
288 if ( hr
!= VFW_S_STATE_INTERMEDIATE
)
290 if ( dwTimeOut
== 0 )
293 Sleep( (dwTimeOut
>= WINE_QUARTZ_POLL_INTERVAL
) ?
294 WINE_QUARTZ_POLL_INTERVAL
: dwTimeOut
);
296 dwTickUsed
= GetTickCount() - dwTickStart
;
298 dwTickStart
+= dwTickUsed
;
299 if ( dwTimeOut
<= dwTickUsed
)
302 dwTimeOut
-= dwTickUsed
;
305 EnterCriticalSection( &This
->m_csGraphState
);
306 *pState
= This
->m_stateGraph
;
307 LeaveCriticalSection( &This
->m_csGraphState
);
312 static HRESULT WINAPI
313 IMediaFilter_fnSetSyncSource(IMediaFilter
* iface
,IReferenceClock
* pobjClock
)
315 CFilterGraph_THIS(iface
,mediafilter
);
316 QUARTZ_CompListItem
* pItem
;
317 IBaseFilter
* pFilter
;
318 HRESULT hr
= NOERROR
;
321 TRACE("(%p)->(%p)\n",This
,pobjClock
);
323 /* IDistributorNotify_SetSyncSource() */
325 EnterCriticalSection( &This
->m_csClock
);
326 QUARTZ_CompList_Lock( This
->m_pFilterList
);
328 if ( This
->m_pClock
!= NULL
)
330 IReferenceClock_Release(This
->m_pClock
);
331 This
->m_pClock
= NULL
;
334 This
->m_pClock
= pobjClock
;
335 if ( pobjClock
!= NULL
)
336 IReferenceClock_AddRef( pobjClock
);
338 pItem
= QUARTZ_CompList_GetFirst( This
->m_pFilterList
);
339 while ( pItem
!= NULL
)
341 pFilter
= (IBaseFilter
*)QUARTZ_CompList_GetItemPtr( pItem
);
342 hrCur
= IBaseFilter_SetSyncSource(pFilter
,pobjClock
);
345 pItem
= QUARTZ_CompList_GetNext( This
->m_pFilterList
, pItem
);
348 QUARTZ_CompList_Unlock( This
->m_pFilterList
);
350 IMediaEventSink_Notify(CFilterGraph_IMediaEventSink(This
),
351 EC_CLOCK_CHANGED
, 0, 0);
353 LeaveCriticalSection( &This
->m_csClock
);
355 TRACE( "hr = %08lx\n", hr
);
360 static HRESULT WINAPI
361 IMediaFilter_fnGetSyncSource(IMediaFilter
* iface
,IReferenceClock
** ppobjClock
)
363 CFilterGraph_THIS(iface
,mediafilter
);
364 HRESULT hr
= VFW_E_NO_CLOCK
;
366 TRACE("(%p)->(%p)\n",This
,ppobjClock
);
368 if ( ppobjClock
== NULL
)
371 EnterCriticalSection( &This
->m_csClock
);
372 *ppobjClock
= This
->m_pClock
;
373 if ( This
->m_pClock
!= NULL
)
376 IReferenceClock_AddRef( This
->m_pClock
);
378 LeaveCriticalSection( &This
->m_csClock
);
380 TRACE( "hr = %08lx\n", hr
);
387 static ICOM_VTABLE(IMediaFilter
) imediafilter
=
389 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
390 /* IUnknown fields */
391 IMediaFilter_fnQueryInterface
,
392 IMediaFilter_fnAddRef
,
393 IMediaFilter_fnRelease
,
394 /* IPersist fields */
395 IMediaFilter_fnGetClassID
,
396 /* IMediaFilter fields */
398 IMediaFilter_fnPause
,
400 IMediaFilter_fnGetState
,
401 IMediaFilter_fnSetSyncSource
,
402 IMediaFilter_fnGetSyncSource
,
405 HRESULT
CFilterGraph_InitIMediaFilter( CFilterGraph
* pfg
)
409 ICOM_VTBL(&pfg
->mediafilter
) = &imediafilter
;
411 InitializeCriticalSection( &pfg
->m_csGraphState
);
412 InitializeCriticalSection( &pfg
->m_csClock
);
413 pfg
->m_stateGraph
= State_Stopped
;
414 pfg
->m_pClock
= NULL
;
419 void CFilterGraph_UninitIMediaFilter( CFilterGraph
* pfg
)
423 if ( pfg
->m_pClock
!= NULL
)
425 IReferenceClock_Release( pfg
->m_pClock
);
426 pfg
->m_pClock
= NULL
;
429 DeleteCriticalSection( &pfg
->m_csGraphState
);
430 DeleteCriticalSection( &pfg
->m_csClock
);