From b7e20bfdd1bc9777e56cb3fe73976e38146c1741 Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Fri, 25 Apr 2008 14:15:42 -0700 Subject: [PATCH] quartz: Fix time discontinuities in the acm wrapper. --- dlls/quartz/acmwrapper.c | 42 ++++++++++++++++++++++++++++++++-------- 1 file changed, 34 insertions(+), 8 deletions(-) diff --git a/dlls/quartz/acmwrapper.c b/dlls/quartz/acmwrapper.c index 11b07f1a4ab..65f196a133e 100644 --- a/dlls/quartz/acmwrapper.c +++ b/dlls/quartz/acmwrapper.c @@ -47,6 +47,9 @@ typedef struct ACMWrapperImpl HACMSTREAM has; LPWAVEFORMATEX pWfIn; LPWAVEFORMATEX pWfOut; + + LONGLONG lasttime_real; + LONGLONG lasttime_sent; } ACMWrapperImpl; static HRESULT ACMWrapper_ProcessSampleData(TransformFilterImpl* pTransformFilter, IMediaSample *pSample) @@ -75,6 +78,19 @@ static HRESULT ACMWrapper_ProcessSampleData(TransformFilterImpl* pTransformFilte 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) + { + This->lasttime_real = tStart; + This->lasttime_sent = tStart; + } + else if (This->lasttime_real == tStart) + tStart = This->lasttime_sent; + else + WARN("Discontinuity\n"); + + tMed = tStart; + TRACE("Sample data ptr = %p, size = %ld\n", pbSrcStream, (long)cbSrcStream); hr = IPin_ConnectionMediaType(This->tf.ppPins[0], &amt); @@ -132,19 +148,20 @@ static HRESULT ACMWrapper_ProcessSampleData(TransformFilterImpl* pTransformFilte if (res) { - if(res != MMSYSERR_MOREDATA) - ERR("Cannot convert data header %d\n", res); - goto error; - } + if(res != MMSYSERR_MOREDATA) + ERR("Cannot convert data header %d\n", res); + goto error; + } - TRACE("used in %u/%u, used out %u/%u\n", ash.cbSrcLengthUsed, ash.cbSrcLength, ash.cbDstLengthUsed, ash.cbDstLength); + TRACE("used in %u/%u, used out %u/%u\n", ash.cbSrcLengthUsed, ash.cbSrcLength, ash.cbDstLengthUsed, ash.cbDstLength); - hr = IMediaSample_SetActualDataLength(pOutSample, ash.cbDstLengthUsed); - assert(hr == S_OK); + hr = IMediaSample_SetActualDataLength(pOutSample, ash.cbDstLengthUsed); + assert(hr == S_OK); + /* Bug in acm codecs? It apparantly uses the input, but doesn't necessarily output immediately kl*/ if (!ash.cbSrcLengthUsed) { - WARN("Sample was skipped\n"); + WARN("Sample was skipped? Outputted: %u\n", ash.cbDstLengthUsed); ash.cbSrcLength = 0; goto error; } @@ -187,8 +204,15 @@ error: if (pOutSample) IMediaSample_Release(pOutSample); pOutSample = NULL; + } + This->lasttime_real = tStop; + This->lasttime_sent = tMed; + + if (hr != S_OK) + FIXME("FATALITY: %08x\n", hr); + return hr; } @@ -252,6 +276,7 @@ static HRESULT ACMWrapper_Cleanup(TransformFilterImpl* pTransformFilter) acmStreamClose(This->has, 0); This->has = 0; + This->lasttime_real = This->lasttime_sent = -1; return S_OK; } @@ -287,6 +312,7 @@ HRESULT ACMWrapper_create(IUnknown * pUnkOuter, LPVOID * ppv) return hr; *ppv = (LPVOID)This; + This->lasttime_real = This->lasttime_sent = -1; return hr; }