2 * Implementation of IMediaFilter for FilterGraph.
6 * Copyright (C) Hidenori TAKESHIMA <hidenori@a2.ctktv.ne.jp>
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
36 #include "wine/debug.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(quartz);
39 #include "quartz_private.h"
43 #define WINE_QUARTZ_POLL_INTERVAL 10
45 /*****************************************************************************/
48 HRESULT CFilterGraph_PollGraphState(
53 QUARTZ_CompListItem* pItem;
57 *pState = State_Stopped;
59 EnterCriticalSection( &This->m_csGraphState );
60 QUARTZ_CompList_Lock( This->m_pFilterList );
62 pItem = QUARTZ_CompList_GetFirst( This->m_pFilterList );
64 while ( pItem != NULL )
66 pFilter = (IBaseFilter*)QUARTZ_CompList_GetItemPtr( pItem );
67 hr = IBaseFilter_GetState( pFilter, (DWORD)0, pState );
71 pItem = QUARTZ_CompList_GetNext( This->m_pFilterList, pItem );
74 QUARTZ_CompList_Unlock( This->m_pFilterList );
75 LeaveCriticalSection( &This->m_csGraphState );
77 TRACE( "returns %08lx, state %d\n",
83 /*****************************************************************************/
86 IMediaFilter_fnQueryInterface(IMediaFilter* iface,REFIID riid,void** ppobj)
88 CFilterGraph_THIS(iface,mediafilter);
90 TRACE("(%p)->()\n",This);
92 return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
96 IMediaFilter_fnAddRef(IMediaFilter* iface)
98 CFilterGraph_THIS(iface,mediafilter);
100 TRACE("(%p)->()\n",This);
102 return IUnknown_AddRef(This->unk.punkControl);
106 IMediaFilter_fnRelease(IMediaFilter* iface)
108 CFilterGraph_THIS(iface,mediafilter);
110 TRACE("(%p)->()\n",This);
112 return IUnknown_Release(This->unk.punkControl);
116 static HRESULT WINAPI
117 IMediaFilter_fnGetClassID(IMediaFilter* iface,CLSID* pclsid)
119 CFilterGraph_THIS(iface,mediafilter);
121 TRACE("(%p)->()\n",This);
123 return IPersist_GetClassID(
124 CFilterGraph_IPersist(This),pclsid);
127 static HRESULT WINAPI
128 IMediaFilter_fnStop(IMediaFilter* iface)
130 CFilterGraph_THIS(iface,mediafilter);
133 QUARTZ_CompListItem* pItem;
134 IBaseFilter* pFilter;
136 TRACE("(%p)->()\n",This);
140 EnterCriticalSection( &This->m_csGraphState );
142 if ( This->m_stateGraph != State_Stopped )
144 /* IDistributorNotify_Stop() */
146 QUARTZ_CompList_Lock( This->m_pFilterList );
148 pItem = QUARTZ_CompList_GetFirst( This->m_pFilterList );
150 while ( pItem != NULL )
152 pFilter = (IBaseFilter*)QUARTZ_CompList_GetItemPtr( pItem );
153 hrFilter = IBaseFilter_Stop( pFilter );
154 if ( hrFilter != S_OK )
160 pItem = QUARTZ_CompList_GetNext( This->m_pFilterList, pItem );
163 QUARTZ_CompList_Unlock( This->m_pFilterList );
165 This->m_stateGraph = State_Stopped;
168 LeaveCriticalSection( &This->m_csGraphState );
173 static HRESULT WINAPI
174 IMediaFilter_fnPause(IMediaFilter* iface)
176 CFilterGraph_THIS(iface,mediafilter);
179 QUARTZ_CompListItem* pItem;
180 IBaseFilter* pFilter;
182 TRACE("(%p)->()\n",This);
186 EnterCriticalSection( &This->m_csGraphState );
188 if ( This->m_stateGraph != State_Paused )
190 /* IDistributorNotify_Pause() */
192 QUARTZ_CompList_Lock( This->m_pFilterList );
194 pItem = QUARTZ_CompList_GetFirst( This->m_pFilterList );
196 while ( pItem != NULL )
198 pFilter = (IBaseFilter*)QUARTZ_CompList_GetItemPtr( pItem );
199 hrFilter = IBaseFilter_Pause( pFilter );
200 if ( hrFilter != S_OK )
206 pItem = QUARTZ_CompList_GetNext( This->m_pFilterList, pItem );
209 QUARTZ_CompList_Unlock( This->m_pFilterList );
211 This->m_stateGraph = State_Paused;
214 LeaveCriticalSection( &This->m_csGraphState );
219 static HRESULT WINAPI
220 IMediaFilter_fnRun(IMediaFilter* iface,REFERENCE_TIME rtStart)
222 CFilterGraph_THIS(iface,mediafilter);
225 QUARTZ_CompListItem* pItem;
226 IBaseFilter* pFilter;
227 IReferenceClock* pClock;
229 TRACE("(%p)->()\n",This);
231 EnterCriticalSection( &This->m_csGraphState );
233 if ( This->m_stateGraph == State_Stopped )
235 hr = IMediaFilter_Pause(iface);
240 /* handle the special time. */
241 if ( rtStart == (REFERENCE_TIME)0 )
243 hr = IMediaFilter_GetSyncSource(iface,&pClock);
244 if ( hr == S_OK && pClock != NULL )
246 IReferenceClock_GetTime(pClock,&rtStart);
247 IReferenceClock_Release(pClock);
253 if ( This->m_stateGraph != State_Running )
255 /* IDistributorNotify_Run() */
257 QUARTZ_CompList_Lock( This->m_pFilterList );
259 pItem = QUARTZ_CompList_GetFirst( This->m_pFilterList );
261 while ( pItem != NULL )
263 pFilter = (IBaseFilter*)QUARTZ_CompList_GetItemPtr( pItem );
264 hrFilter = IBaseFilter_Run( pFilter, rtStart );
265 if ( hrFilter != S_OK )
271 pItem = QUARTZ_CompList_GetNext( This->m_pFilterList, pItem );
274 QUARTZ_CompList_Unlock( This->m_pFilterList );
276 This->m_stateGraph = State_Running;
280 LeaveCriticalSection( &This->m_csGraphState );
285 static HRESULT WINAPI
286 IMediaFilter_fnGetState(IMediaFilter* iface,DWORD dwTimeOut,FILTER_STATE* pState)
288 CFilterGraph_THIS(iface,mediafilter);
293 TRACE("(%p)->(%p)\n",This,pState);
294 if ( pState == NULL )
297 dwTickStart = GetTickCount();
301 hr = CFilterGraph_PollGraphState( This, pState );
302 if ( hr != VFW_S_STATE_INTERMEDIATE )
304 if ( dwTimeOut == 0 )
307 Sleep( (dwTimeOut >= WINE_QUARTZ_POLL_INTERVAL) ?
308 WINE_QUARTZ_POLL_INTERVAL : dwTimeOut );
310 dwTickUsed = GetTickCount() - dwTickStart;
312 dwTickStart += dwTickUsed;
313 if ( dwTimeOut <= dwTickUsed )
316 dwTimeOut -= dwTickUsed;
319 EnterCriticalSection( &This->m_csGraphState );
320 *pState = This->m_stateGraph;
321 LeaveCriticalSection( &This->m_csGraphState );
326 static HRESULT WINAPI
327 IMediaFilter_fnSetSyncSource(IMediaFilter* iface,IReferenceClock* pobjClock)
329 CFilterGraph_THIS(iface,mediafilter);
330 QUARTZ_CompListItem* pItem;
331 IBaseFilter* pFilter;
332 HRESULT hr = NOERROR;
335 TRACE("(%p)->(%p)\n",This,pobjClock);
337 /* IDistributorNotify_SetSyncSource() */
339 EnterCriticalSection( &This->m_csClock );
340 QUARTZ_CompList_Lock( This->m_pFilterList );
342 if ( This->m_pClock != NULL )
344 IReferenceClock_Release(This->m_pClock);
345 This->m_pClock = NULL;
348 This->m_pClock = pobjClock;
349 if ( pobjClock != NULL )
350 IReferenceClock_AddRef( pobjClock );
352 pItem = QUARTZ_CompList_GetFirst( This->m_pFilterList );
353 while ( pItem != NULL )
355 pFilter = (IBaseFilter*)QUARTZ_CompList_GetItemPtr( pItem );
356 hrCur = IBaseFilter_SetSyncSource(pFilter,pobjClock);
359 pItem = QUARTZ_CompList_GetNext( This->m_pFilterList, pItem );
362 QUARTZ_CompList_Unlock( This->m_pFilterList );
364 IMediaEventSink_Notify(CFilterGraph_IMediaEventSink(This),
365 EC_CLOCK_CHANGED, 0, 0);
367 LeaveCriticalSection( &This->m_csClock );
369 TRACE( "hr = %08lx\n", hr );
374 static HRESULT WINAPI
375 IMediaFilter_fnGetSyncSource(IMediaFilter* iface,IReferenceClock** ppobjClock)
377 CFilterGraph_THIS(iface,mediafilter);
378 HRESULT hr = VFW_E_NO_CLOCK;
380 TRACE("(%p)->(%p)\n",This,ppobjClock);
382 if ( ppobjClock == NULL )
385 EnterCriticalSection( &This->m_csClock );
386 *ppobjClock = This->m_pClock;
387 if ( This->m_pClock != NULL )
390 IReferenceClock_AddRef( This->m_pClock );
392 LeaveCriticalSection( &This->m_csClock );
394 TRACE( "hr = %08lx\n", hr );
401 static ICOM_VTABLE(IMediaFilter) imediafilter =
403 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
404 /* IUnknown fields */
405 IMediaFilter_fnQueryInterface,
406 IMediaFilter_fnAddRef,
407 IMediaFilter_fnRelease,
408 /* IPersist fields */
409 IMediaFilter_fnGetClassID,
410 /* IMediaFilter fields */
412 IMediaFilter_fnPause,
414 IMediaFilter_fnGetState,
415 IMediaFilter_fnSetSyncSource,
416 IMediaFilter_fnGetSyncSource,
419 HRESULT CFilterGraph_InitIMediaFilter( CFilterGraph* pfg )
423 ICOM_VTBL(&pfg->mediafilter) = &imediafilter;
425 InitializeCriticalSection( &pfg->m_csGraphState );
426 InitializeCriticalSection( &pfg->m_csClock );
427 pfg->m_stateGraph = State_Stopped;
428 pfg->m_pClock = NULL;
433 void CFilterGraph_UninitIMediaFilter( CFilterGraph* pfg )
437 if ( pfg->m_pClock != NULL )
439 IReferenceClock_Release( pfg->m_pClock );
440 pfg->m_pClock = NULL;
443 DeleteCriticalSection( &pfg->m_csGraphState );
444 DeleteCriticalSection( &pfg->m_csClock );