Maarten Lankhorst : quartz: Implement MediaControl_GetState.

Alexandre Julliard julliard at winehq.org
Sat Jun 21 05:39:10 CDT 2008


Module: wine
Branch: master
Commit: 29b6dbab8097108d6c20348afe889f9309d4a799
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=29b6dbab8097108d6c20348afe889f9309d4a799

Author: Maarten Lankhorst <m.b.lankhorst at gmail.com>
Date:   Tue Jun 10 18:20:33 2008 +0200

quartz: Implement MediaControl_GetState.

This allows applications to wait for state transitions to be really
complete. Fixes some xvid crashes.

---

 dlls/quartz/filtergraph.c |   70 +++++++++++++++++++++++++++++++++++---------
 1 files changed, 55 insertions(+), 15 deletions(-)

diff --git a/dlls/quartz/filtergraph.c b/dlls/quartz/filtergraph.c
index 7031c72..c63663d 100644
--- a/dlls/quartz/filtergraph.c
+++ b/dlls/quartz/filtergraph.c
@@ -1555,9 +1555,9 @@ static HRESULT WINAPI MediaControl_Invoke(IMediaControl *iface,
     return S_OK;
 }
 
-typedef HRESULT(WINAPI *fnFoundFilter)(IBaseFilter *);
+typedef HRESULT(WINAPI *fnFoundFilter)(IBaseFilter *, DWORD_PTR data);
 
-static HRESULT ExploreGraph(IFilterGraphImpl* pGraph, IPin* pOutputPin, fnFoundFilter FoundFilter)
+static HRESULT ExploreGraph(IFilterGraphImpl* pGraph, IPin* pOutputPin, fnFoundFilter FoundFilter, DWORD_PTR data)
 {
     HRESULT hr;
     IPin* pInputPin;
@@ -1594,7 +1594,7 @@ static HRESULT ExploreGraph(IFilterGraphImpl* pGraph, IPin* pOutputPin, fnFoundF
                 /* Explore the graph downstream from this pin
 		 * FIXME: We should prevent exploring from a pin more than once. This can happens when
 		 * several input pins are connected to the same output (a MUX for instance). */
-                ExploreGraph(pGraph, ppPins[i], FoundFilter);
+                ExploreGraph(pGraph, ppPins[i], FoundFilter, data);
                 IPin_Release(ppPins[i]);
             }
 
@@ -1602,14 +1602,15 @@ static HRESULT ExploreGraph(IFilterGraphImpl* pGraph, IPin* pOutputPin, fnFoundF
         }
         TRACE("Doing stuff with filter %p\n", PinInfo.pFilter);
 
-        FoundFilter(PinInfo.pFilter);
+        FoundFilter(PinInfo.pFilter, data);
     }
 
     if (PinInfo.pFilter) IBaseFilter_Release(PinInfo.pFilter);
     return hr;
 }
 
-static HRESULT WINAPI SendRun(IBaseFilter *pFilter) {
+static HRESULT WINAPI SendRun(IBaseFilter *pFilter, DWORD_PTR data)
+{
     LONGLONG time = 0;
     IReferenceClock *clock = NULL;
 
@@ -1628,15 +1629,39 @@ static HRESULT WINAPI SendRun(IBaseFilter *pFilter) {
     return IBaseFilter_Run(pFilter, time);
 }
 
-static HRESULT WINAPI SendPause(IBaseFilter *pFilter) {
+static HRESULT WINAPI SendPause(IBaseFilter *pFilter, DWORD_PTR data)
+{
     return IBaseFilter_Pause(pFilter);
 }
 
-static HRESULT WINAPI SendStop(IBaseFilter *pFilter) {
+static HRESULT WINAPI SendStop(IBaseFilter *pFilter, DWORD_PTR data)
+{
     return IBaseFilter_Stop(pFilter);
 }
 
-static HRESULT SendFilterMessage(IMediaControl *iface, fnFoundFilter FoundFilter) {
+static HRESULT WINAPI SendGetState(IBaseFilter *pFilter, DWORD_PTR data)
+{
+    FILTER_STATE state;
+    DWORD time_end = data;
+    DWORD time_now = GetTickCount();
+    LONG wait;
+
+    if (time_end == INFINITE)
+    {
+        wait = INFINITE;
+    }
+    else if (time_end > time_now)
+    {
+        wait = time_end - time_now;
+    }
+    else
+        wait = 0;
+
+    return IBaseFilter_GetState(pFilter, wait, &state);
+}
+
+
+static HRESULT SendFilterMessage(IMediaControl *iface, fnFoundFilter FoundFilter, DWORD_PTR data) {
     ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
     int i;
     IBaseFilter* pfilter;
@@ -1680,10 +1705,10 @@ static HRESULT SendFilterMessage(IMediaControl *iface, fnFoundFilter FoundFilter
             while(IEnumPins_Next(pEnum, 1, &pPin, &dummy) == S_OK)
             {
                 /* Explore the graph downstream from this pin */
-                ExploreGraph(This, pPin, FoundFilter);
+                ExploreGraph(This, pPin, FoundFilter, data);
                 IPin_Release(pPin);
             }
-            FoundFilter(pfilter);
+            FoundFilter(pfilter, data);
         }
         IEnumPins_Release(pEnum);
     }
@@ -1709,7 +1734,7 @@ static HRESULT WINAPI MediaControl_Run(IMediaControl *iface) {
     }
     else This->position = This->start_time = 0;
 
-    SendFilterMessage(iface, SendRun);
+    SendFilterMessage(iface, SendRun, 0);
     This->state = State_Running;
     LeaveCriticalSection(&This->cs);
     return S_FALSE;
@@ -1732,7 +1757,7 @@ static HRESULT WINAPI MediaControl_Pause(IMediaControl *iface) {
         This->position += time - This->start_time;
     }
 
-    SendFilterMessage(iface, SendPause);
+    SendFilterMessage(iface, SendPause, 0);
     This->state = State_Paused;
     LeaveCriticalSection(&This->cs);
     return S_FALSE;
@@ -1752,8 +1777,8 @@ static HRESULT WINAPI MediaControl_Stop(IMediaControl *iface) {
         This->position += time - This->start_time;
     }
 
-    if (This->state == State_Running) SendFilterMessage(iface, SendPause);
-    SendFilterMessage(iface, SendStop);
+    if (This->state == State_Running) SendFilterMessage(iface, SendPause, 0);
+    SendFilterMessage(iface, SendStop, 0);
     This->state = State_Stopped;
     LeaveCriticalSection(&This->cs);
     return S_OK;
@@ -1763,8 +1788,9 @@ static HRESULT WINAPI MediaControl_GetState(IMediaControl *iface,
 					    LONG msTimeout,
 					    OAFilterState *pfs) {
     ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
+    DWORD end;
 
-    TRACE("(%p/%p)->(%d, %p): semi-stub !!!\n", This, iface, msTimeout, pfs);
+    TRACE("(%p/%p)->(%d, %p)\n", This, iface, msTimeout, pfs);
 
     if (!pfs)
         return E_POINTER;
@@ -1772,6 +1798,20 @@ static HRESULT WINAPI MediaControl_GetState(IMediaControl *iface,
     EnterCriticalSection(&This->cs);
 
     *pfs = This->state;
+    if (msTimeout > 0)
+    {
+        end = GetTickCount() + msTimeout;
+    }
+    else if (msTimeout < 0)
+    {
+        end = INFINITE;
+    }
+    else
+    {
+        end = 0;
+    }
+    if (end)
+        SendFilterMessage(iface, SendGetState, end);
 
     LeaveCriticalSection(&This->cs);
 




More information about the wine-cvs mailing list