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;
44 EnterCriticalSection( &This->m_csGraphState );
45 QUARTZ_CompList_Lock( This->m_pFilterList );
47 pItem = QUARTZ_CompList_GetFirst( This->m_pFilterList );
49 while ( pItem != NULL )
51 pFilter = (IBaseFilter*)QUARTZ_CompList_GetItemPtr( pItem );
52 hr = IBaseFilter_GetState( pFilter, (DWORD)0, pState );
56 pItem = QUARTZ_CompList_GetNext( This->m_pFilterList, pItem );
59 QUARTZ_CompList_Unlock( This->m_pFilterList );
60 LeaveCriticalSection( &This->m_csGraphState );
62 TRACE( "returns %08lx, state %d\n",
68 /*****************************************************************************/
71 IMediaFilter_fnQueryInterface(IMediaFilter* iface,REFIID riid,void** ppobj)
73 CFilterGraph_THIS(iface,mediafilter);
75 TRACE("(%p)->()\n",This);
77 return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
81 IMediaFilter_fnAddRef(IMediaFilter* iface)
83 CFilterGraph_THIS(iface,mediafilter);
85 TRACE("(%p)->()\n",This);
87 return IUnknown_AddRef(This->unk.punkControl);
91 IMediaFilter_fnRelease(IMediaFilter* iface)
93 CFilterGraph_THIS(iface,mediafilter);
95 TRACE("(%p)->()\n",This);
97 return IUnknown_Release(This->unk.punkControl);
101 static HRESULT WINAPI
102 IMediaFilter_fnGetClassID(IMediaFilter* iface,CLSID* pclsid)
104 CFilterGraph_THIS(iface,mediafilter);
106 TRACE("(%p)->()\n",This);
108 return IPersist_GetClassID(
109 CFilterGraph_IPersist(This),pclsid);
112 static HRESULT WINAPI
113 IMediaFilter_fnStop(IMediaFilter* iface)
115 CFilterGraph_THIS(iface,mediafilter);
118 QUARTZ_CompListItem* pItem;
119 IBaseFilter* pFilter;
121 TRACE("(%p)->()\n",This);
125 EnterCriticalSection( &This->m_csGraphState );
127 if ( This->m_stateGraph != State_Stopped )
129 /* IDistributorNotify_Stop() */
131 QUARTZ_CompList_Lock( This->m_pFilterList );
133 pItem = QUARTZ_CompList_GetFirst( This->m_pFilterList );
135 while ( pItem != NULL )
137 pFilter = (IBaseFilter*)QUARTZ_CompList_GetItemPtr( pItem );
138 hrFilter = IBaseFilter_Stop( pFilter );
139 if ( hrFilter != S_OK )
145 pItem = QUARTZ_CompList_GetNext( This->m_pFilterList, pItem );
148 QUARTZ_CompList_Unlock( This->m_pFilterList );
150 This->m_stateGraph = State_Stopped;
153 LeaveCriticalSection( &This->m_csGraphState );
158 static HRESULT WINAPI
159 IMediaFilter_fnPause(IMediaFilter* iface)
161 CFilterGraph_THIS(iface,mediafilter);
164 QUARTZ_CompListItem* pItem;
165 IBaseFilter* pFilter;
167 TRACE("(%p)->()\n",This);
171 EnterCriticalSection( &This->m_csGraphState );
173 if ( This->m_stateGraph != State_Paused )
175 /* IDistributorNotify_Pause() */
177 QUARTZ_CompList_Lock( This->m_pFilterList );
179 pItem = QUARTZ_CompList_GetFirst( This->m_pFilterList );
181 while ( pItem != NULL )
183 pFilter = (IBaseFilter*)QUARTZ_CompList_GetItemPtr( pItem );
184 hrFilter = IBaseFilter_Pause( pFilter );
185 if ( hrFilter != S_OK )
191 pItem = QUARTZ_CompList_GetNext( This->m_pFilterList, pItem );
194 QUARTZ_CompList_Unlock( This->m_pFilterList );
196 This->m_stateGraph = State_Paused;
199 LeaveCriticalSection( &This->m_csGraphState );
204 static HRESULT WINAPI
205 IMediaFilter_fnRun(IMediaFilter* iface,REFERENCE_TIME rtStart)
207 CFilterGraph_THIS(iface,mediafilter);
210 QUARTZ_CompListItem* pItem;
211 IBaseFilter* pFilter;
212 IReferenceClock* pClock;
214 TRACE("(%p)->()\n",This);
216 EnterCriticalSection( &This->m_csGraphState );
218 if ( This->m_stateGraph == State_Stopped )
220 hr = IMediaFilter_Pause(iface);
225 /* handle the special time. */
226 if ( rtStart == (REFERENCE_TIME)0 )
228 hr = IMediaFilter_GetSyncSource(iface,&pClock);
229 if ( hr == S_OK && pClock != NULL )
231 IReferenceClock_GetTime(pClock,&rtStart);
232 IReferenceClock_Release(pClock);
238 if ( This->m_stateGraph != State_Running )
240 /* IDistributorNotify_Run() */
242 QUARTZ_CompList_Lock( This->m_pFilterList );
244 pItem = QUARTZ_CompList_GetFirst( This->m_pFilterList );
246 while ( pItem != NULL )
248 pFilter = (IBaseFilter*)QUARTZ_CompList_GetItemPtr( pItem );
249 hrFilter = IBaseFilter_Run( pFilter, rtStart );
250 if ( hrFilter != S_OK )
256 pItem = QUARTZ_CompList_GetNext( This->m_pFilterList, pItem );
259 QUARTZ_CompList_Unlock( This->m_pFilterList );
261 This->m_stateGraph = State_Running;
265 LeaveCriticalSection( &This->m_csGraphState );
270 static HRESULT WINAPI
271 IMediaFilter_fnGetState(IMediaFilter* iface,DWORD dwTimeOut,FILTER_STATE* pState)
273 CFilterGraph_THIS(iface,mediafilter);
278 TRACE("(%p)->(%p)\n",This,pState);
279 if ( pState == NULL )
282 dwTickStart = GetTickCount();
286 hr = CFilterGraph_PollGraphState( This, pState );
287 if ( hr != VFW_S_STATE_INTERMEDIATE )
289 if ( dwTimeOut == 0 )
292 Sleep( (dwTimeOut >= WINE_QUARTZ_POLL_INTERVAL) ?
293 WINE_QUARTZ_POLL_INTERVAL : dwTimeOut );
295 dwTickUsed = GetTickCount() - dwTickStart;
297 dwTickStart += dwTickUsed;
298 if ( dwTimeOut <= dwTickUsed )
301 dwTimeOut -= dwTickUsed;
304 EnterCriticalSection( &This->m_csGraphState );
305 *pState = This->m_stateGraph;
306 LeaveCriticalSection( &This->m_csGraphState );
311 static HRESULT WINAPI
312 IMediaFilter_fnSetSyncSource(IMediaFilter* iface,IReferenceClock* pobjClock)
314 CFilterGraph_THIS(iface,mediafilter);
315 QUARTZ_CompListItem* pItem;
316 IBaseFilter* pFilter;
317 HRESULT hr = NOERROR;
320 TRACE("(%p)->(%p)\n",This,pobjClock);
322 /* IDistributorNotify_SetSyncSource() */
324 EnterCriticalSection( &This->m_csClock );
325 QUARTZ_CompList_Lock( This->m_pFilterList );
327 if ( This->m_pClock != NULL )
329 IReferenceClock_Release(This->m_pClock);
330 This->m_pClock = NULL;
333 This->m_pClock = pobjClock;
334 if ( pobjClock != NULL )
335 IReferenceClock_AddRef( pobjClock );
337 pItem = QUARTZ_CompList_GetFirst( This->m_pFilterList );
338 while ( pItem != NULL )
340 pFilter = (IBaseFilter*)QUARTZ_CompList_GetItemPtr( pItem );
341 hrCur = IBaseFilter_SetSyncSource(pFilter,pobjClock);
344 pItem = QUARTZ_CompList_GetNext( This->m_pFilterList, pItem );
347 QUARTZ_CompList_Unlock( This->m_pFilterList );
349 IMediaEventSink_Notify(CFilterGraph_IMediaEventSink(This),
350 EC_CLOCK_CHANGED, 0, 0);
352 LeaveCriticalSection( &This->m_csClock );
354 TRACE( "hr = %08lx\n", hr );
359 static HRESULT WINAPI
360 IMediaFilter_fnGetSyncSource(IMediaFilter* iface,IReferenceClock** ppobjClock)
362 CFilterGraph_THIS(iface,mediafilter);
363 HRESULT hr = VFW_E_NO_CLOCK;
365 TRACE("(%p)->(%p)\n",This,ppobjClock);
367 if ( ppobjClock == NULL )
370 EnterCriticalSection( &This->m_csClock );
371 *ppobjClock = This->m_pClock;
372 if ( This->m_pClock != NULL )
375 IReferenceClock_AddRef( This->m_pClock );
377 LeaveCriticalSection( &This->m_csClock );
379 TRACE( "hr = %08lx\n", hr );
386 static ICOM_VTABLE(IMediaFilter) imediafilter =
388 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
389 /* IUnknown fields */
390 IMediaFilter_fnQueryInterface,
391 IMediaFilter_fnAddRef,
392 IMediaFilter_fnRelease,
393 /* IPersist fields */
394 IMediaFilter_fnGetClassID,
395 /* IMediaFilter fields */
397 IMediaFilter_fnPause,
399 IMediaFilter_fnGetState,
400 IMediaFilter_fnSetSyncSource,
401 IMediaFilter_fnGetSyncSource,
404 HRESULT CFilterGraph_InitIMediaFilter( CFilterGraph* pfg )
408 ICOM_VTBL(&pfg->mediafilter) = &imediafilter;
410 InitializeCriticalSection( &pfg->m_csGraphState );
411 InitializeCriticalSection( &pfg->m_csClock );
412 pfg->m_stateGraph = State_Stopped;
413 pfg->m_pClock = NULL;
418 void CFilterGraph_UninitIMediaFilter( CFilterGraph* pfg )
422 if ( pfg->m_pClock != NULL )
424 IReferenceClock_Release( pfg->m_pClock );
425 pfg->m_pClock = NULL;
428 DeleteCriticalSection( &pfg->m_csGraphState );
429 DeleteCriticalSection( &pfg->m_csClock );