quartz: Handle failures better in acmwrapper.

This commit is contained in:
Maarten Lankhorst 2008-04-28 16:32:57 -07:00 committed by Alexandre Julliard
parent 37847b0d9b
commit 1ba8ece76e
1 changed files with 82 additions and 16 deletions

View File

@ -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;
}
cbSrcStream = IMediaSample_GetActualDataLength(pSample);
preroll = (IMediaSample_IsPreroll(pSample) == S_OK);
IMediaSample_GetTime(pSample, &tStart, &tStop);
cbSrcStream = IMediaSample_GetActualDataLength(pSample);
/* 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;
}
else if (This->lasttime_real == tStart)
tStart = This->lasttime_sent;
else
WARN("Discontinuity\n");
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
{
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;
}