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