Maarten Lankhorst : quartz: Handle failures better in acmwrapper.

Alexandre Julliard julliard at winehq.org
Tue Apr 29 08:54:36 CDT 2008


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

Author: Maarten Lankhorst <m.b.lankhorst at gmail.com>
Date:   Mon Apr 28 16:32:57 2008 -0700

quartz: Handle failures better in acmwrapper.

---

 dlls/quartz/acmwrapper.c |   96 ++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 81 insertions(+), 15 deletions(-)

diff --git a/dlls/quartz/acmwrapper.c b/dlls/quartz/acmwrapper.c
index c7b1e42..92d0298 100644
--- a/dlls/quartz/acmwrapper.c
+++ b/dlls/quartz/acmwrapper.c
@@ -48,6 +48,9 @@ typedef struct ACMWrapperImpl
     LPWAVEFORMATEX pWfIn;
     LPWAVEFORMATEX pWfOut;
 
+    IMediaSample *recv, *xmit;
+    ULONG done;
+
     LONGLONG lasttime_real;
     LONGLONG lasttime_sent;
 } ACMWrapperImpl;
@@ -66,32 +69,61 @@ static HRESULT ACMWrapper_ProcessSampleData(TransformFilterImpl* pTransformFilte
     HRESULT hr;
     LONGLONG tStart = -1, tStop = -1, tMed;
 
+    assert(pSample);
+
+    if (This->xmit)
+    {
+        hr = OutputPin_SendSample((OutputPin*)This->tf.ppPins[1], This->xmit);
+        if (hr != S_OK)
+            return hr;
+        IMediaSample_Release(This->xmit);
+        This->xmit = NULL;
+    }
+
     hr = IMediaSample_GetPointer(pSample, &pbSrcStream);
     if (FAILED(hr))
     {
         ERR("Cannot get pointer to sample data (%x)\n", hr);
 	return hr;
     }
-
-    preroll = (IMediaSample_IsPreroll(pSample) == S_OK);
-
-    IMediaSample_GetTime(pSample, &tStart, &tStop);
     cbSrcStream = IMediaSample_GetActualDataLength(pSample);
+    preroll = (IMediaSample_IsPreroll(pSample) == S_OK);
 
-    /* Prevent discontinuities when codecs 'absorb' data but not give anything back in return */
-    if (IMediaSample_IsDiscontinuity(pSample) == S_OK)
+    if (pSample != This->recv)
     {
-        This->lasttime_real = tStart;
-        This->lasttime_sent = tStart;
+        if (This->recv)
+        {
+            /* Get rid of buffered sample first */
+            hr = ACMWrapper_ProcessSampleData(pTransformFilter, This->recv);
+            if (hr != S_OK)
+                return hr;
+            if (This->recv)
+                return S_FALSE;
+        }
+
+        IMediaSample_GetTime(pSample, &tStart, &tStop);
+
+        /* Prevent discontinuities when codecs 'absorb' data but not give anything back in return */
+        if (IMediaSample_IsDiscontinuity(pSample) == S_OK)
+        {
+            This->lasttime_real = tStart;
+            This->lasttime_sent = tStart;
+        }
+        else if (This->lasttime_real == tStart)
+            tStart = This->lasttime_sent;
+        else
+            WARN("Discontinuity\n");
     }
-    else if (This->lasttime_real == tStart)
-        tStart = This->lasttime_sent;
     else
-        WARN("Discontinuity\n");
-
+    {
+        tStart = This->lasttime_sent;
+        tStop = This->lasttime_real;
+        cbSrcStream -= This->done;
+        pbSrcStream += This->done;
+    }
     tMed = tStart;
 
-    TRACE("Sample data ptr = %p, size = %ld\n", pbSrcStream, (long)cbSrcStream);
+    TRACE("Sample data ptr = %p, size = %u\n", pbSrcStream, cbSrcStream);
 
     hr = IPin_ConnectionMediaType(This->tf.ppPins[0], &amt);
     if (FAILED(hr)) {
@@ -201,17 +233,44 @@ error:
         ash.pbSrc += ash.cbSrcLengthUsed;
         ash.cbSrcLength -= ash.cbSrcLengthUsed;
 
+        if (hr == S_FALSE)
+        {
+            This->xmit = pOutSample;
+            if (ash.cbSrcLength && !This->recv)
+            {
+                This->recv = pSample;
+                IMediaSample_AddRef(This->recv);
+            }
+            else if (This->recv)
+            {
+                IMediaSample_Release(This->recv);
+                This->recv = NULL;
+            }
+
+            This->done = IMediaSample_GetActualDataLength(pSample) - ash.cbSrcLength;
+            break;
+        }
+
         if (pOutSample)
             IMediaSample_Release(pOutSample);
         pOutSample = NULL;
-
     }
 
     This->lasttime_real = tStop;
     This->lasttime_sent = tMed;
 
+
     if (hr != S_OK)
         FIXME("FATALITY: %08x\n", hr);
+    else if (This->recv)
+    {
+        assert(This->recv == pSample);
+        IMediaSample_Release(This->recv);
+        This->recv = NULL;
+    }
+
+    if (hr == S_FALSE)
+        return S_OK;
 
     return hr;
 }
@@ -277,7 +336,13 @@ static HRESULT ACMWrapper_Cleanup(TransformFilterImpl* pTransformFilter)
 
     This->has = 0;
     This->lasttime_real = This->lasttime_sent = -1;
-    
+    if (This->recv)
+        IMediaSample_Release(This->recv);
+
+    if (This->xmit)
+        IMediaSample_Release(This->xmit);
+
+    This->recv = This->xmit = NULL;
     return S_OK;
 }
 
@@ -313,6 +378,7 @@ HRESULT ACMWrapper_create(IUnknown * pUnkOuter, LPVOID * ppv)
 
     *ppv = (LPVOID)This;
     This->lasttime_real = This->lasttime_sent = -1;
+    This->recv = This->xmit = NULL;
 
     return hr;
 }




More information about the wine-cvs mailing list