Don't return from overlapped ReadFile on EAGAIN and other non-fatal
[wine/gsoc_dplay.git] / dlls / quartz / imfilter.c
blob5e802fa5391842b7545fa9e003035056e9cf3c71
1 /*
2 * Implementation of IMediaFilter for FilterGraph.
4 * FIXME - stub.
6 * hidenori@a2.ctktv.ne.jp
7 */
9 #include "config.h"
11 #include "windef.h"
12 #include "winbase.h"
13 #include "wingdi.h"
14 #include "winuser.h"
15 #include "winerror.h"
16 #include "strmif.h"
17 #include "control.h"
18 #include "uuids.h"
19 #include "vfwmsgs.h"
20 #include "evcode.h"
22 #include "debugtools.h"
23 DEFAULT_DEBUG_CHANNEL(quartz);
25 #include "quartz_private.h"
26 #include "fgraph.h"
29 #define WINE_QUARTZ_POLL_INTERVAL 10
31 /*****************************************************************************/
33 static
34 HRESULT CFilterGraph_PollGraphState(
35 CFilterGraph* This,
36 FILTER_STATE* pState)
38 HRESULT hr;
39 QUARTZ_CompListItem* pItem;
40 IBaseFilter* pFilter;
42 hr = S_OK;
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 );
54 if ( hr != S_OK )
55 break;
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",
64 hr, *pState );
66 return hr;
69 /*****************************************************************************/
71 static HRESULT WINAPI
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);
81 static ULONG WINAPI
82 IMediaFilter_fnAddRef(IMediaFilter* iface)
84 CFilterGraph_THIS(iface,mediafilter);
86 TRACE("(%p)->()\n",This);
88 return IUnknown_AddRef(This->unk.punkControl);
91 static ULONG WINAPI
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);
117 HRESULT hr;
118 HRESULT hrFilter;
119 QUARTZ_CompListItem* pItem;
120 IBaseFilter* pFilter;
122 TRACE("(%p)->()\n",This);
124 hr = S_OK;
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 )
142 if ( SUCCEEDED(hr) )
143 hr = hrFilter;
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 );
156 return hr;
159 static HRESULT WINAPI
160 IMediaFilter_fnPause(IMediaFilter* iface)
162 CFilterGraph_THIS(iface,mediafilter);
163 HRESULT hr;
164 HRESULT hrFilter;
165 QUARTZ_CompListItem* pItem;
166 IBaseFilter* pFilter;
168 TRACE("(%p)->()\n",This);
170 hr = S_OK;
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 )
188 if ( SUCCEEDED(hr) )
189 hr = hrFilter;
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 );
202 return hr;
205 static HRESULT WINAPI
206 IMediaFilter_fnRun(IMediaFilter* iface,REFERENCE_TIME rtStart)
208 CFilterGraph_THIS(iface,mediafilter);
209 HRESULT hr;
210 HRESULT hrFilter;
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);
222 if ( FAILED(hr) )
223 goto end;
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);
237 hr = NOERROR;
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 )
253 if ( SUCCEEDED(hr) )
254 hr = hrFilter;
257 pItem = QUARTZ_CompList_GetNext( This->m_pFilterList, pItem );
260 QUARTZ_CompList_Unlock( This->m_pFilterList );
262 This->m_stateGraph = State_Running;
265 end:
266 LeaveCriticalSection( &This->m_csGraphState );
268 return hr;
271 static HRESULT WINAPI
272 IMediaFilter_fnGetState(IMediaFilter* iface,DWORD dwTimeOut,FILTER_STATE* pState)
274 CFilterGraph_THIS(iface,mediafilter);
275 HRESULT hr;
276 DWORD dwTickStart;
277 DWORD dwTickUsed;
279 TRACE("(%p)->(%p)\n",This,pState);
280 if ( pState == NULL )
281 return E_POINTER;
283 dwTickStart = GetTickCount();
285 while ( 1 )
287 hr = CFilterGraph_PollGraphState( This, pState );
288 if ( hr != VFW_S_STATE_INTERMEDIATE )
289 break;
290 if ( dwTimeOut == 0 )
291 break;
293 Sleep( (dwTimeOut >= WINE_QUARTZ_POLL_INTERVAL) ?
294 WINE_QUARTZ_POLL_INTERVAL : dwTimeOut );
296 dwTickUsed = GetTickCount() - dwTickStart;
298 dwTickStart += dwTickUsed;
299 if ( dwTimeOut <= dwTickUsed )
300 dwTimeOut = 0;
301 else
302 dwTimeOut -= dwTickUsed;
305 EnterCriticalSection( &This->m_csGraphState );
306 *pState = This->m_stateGraph;
307 LeaveCriticalSection( &This->m_csGraphState );
309 return hr;
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;
319 HRESULT hrCur;
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);
343 if ( FAILED(hrCur) )
344 hr = hrCur;
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 );
357 return 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 )
369 return E_POINTER;
371 EnterCriticalSection( &This->m_csClock );
372 *ppobjClock = This->m_pClock;
373 if ( This->m_pClock != NULL )
375 hr = NOERROR;
376 IReferenceClock_AddRef( This->m_pClock );
378 LeaveCriticalSection( &This->m_csClock );
380 TRACE( "hr = %08lx\n", hr );
382 return 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 */
397 IMediaFilter_fnStop,
398 IMediaFilter_fnPause,
399 IMediaFilter_fnRun,
400 IMediaFilter_fnGetState,
401 IMediaFilter_fnSetSyncSource,
402 IMediaFilter_fnGetSyncSource,
405 HRESULT CFilterGraph_InitIMediaFilter( CFilterGraph* pfg )
407 TRACE("(%p)\n",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;
416 return NOERROR;
419 void CFilterGraph_UninitIMediaFilter( CFilterGraph* pfg )
421 TRACE("(%p)\n",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 );