quartz: Fix time discontinuities in the acm wrapper.

This commit is contained in:
Maarten Lankhorst 2008-04-25 14:15:42 -07:00 committed by Alexandre Julliard
parent 9e143cdb63
commit b7e20bfdd1
1 changed files with 34 additions and 8 deletions

View File

@ -47,6 +47,9 @@ typedef struct ACMWrapperImpl
HACMSTREAM has; HACMSTREAM has;
LPWAVEFORMATEX pWfIn; LPWAVEFORMATEX pWfIn;
LPWAVEFORMATEX pWfOut; LPWAVEFORMATEX pWfOut;
LONGLONG lasttime_real;
LONGLONG lasttime_sent;
} ACMWrapperImpl; } ACMWrapperImpl;
static HRESULT ACMWrapper_ProcessSampleData(TransformFilterImpl* pTransformFilter, IMediaSample *pSample) static HRESULT ACMWrapper_ProcessSampleData(TransformFilterImpl* pTransformFilter, IMediaSample *pSample)
@ -75,6 +78,19 @@ static HRESULT ACMWrapper_ProcessSampleData(TransformFilterImpl* pTransformFilte
IMediaSample_GetTime(pSample, &tStart, &tStop); IMediaSample_GetTime(pSample, &tStart, &tStop);
cbSrcStream = IMediaSample_GetActualDataLength(pSample); 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); TRACE("Sample data ptr = %p, size = %ld\n", pbSrcStream, (long)cbSrcStream);
hr = IPin_ConnectionMediaType(This->tf.ppPins[0], &amt); hr = IPin_ConnectionMediaType(This->tf.ppPins[0], &amt);
@ -132,19 +148,20 @@ static HRESULT ACMWrapper_ProcessSampleData(TransformFilterImpl* pTransformFilte
if (res) if (res)
{ {
if(res != MMSYSERR_MOREDATA) if(res != MMSYSERR_MOREDATA)
ERR("Cannot convert data header %d\n", res); ERR("Cannot convert data header %d\n", res);
goto error; 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); hr = IMediaSample_SetActualDataLength(pOutSample, ash.cbDstLengthUsed);
assert(hr == S_OK); assert(hr == S_OK);
/* Bug in acm codecs? It apparantly uses the input, but doesn't necessarily output immediately kl*/
if (!ash.cbSrcLengthUsed) if (!ash.cbSrcLengthUsed)
{ {
WARN("Sample was skipped\n"); WARN("Sample was skipped? Outputted: %u\n", ash.cbDstLengthUsed);
ash.cbSrcLength = 0; ash.cbSrcLength = 0;
goto error; goto error;
} }
@ -187,8 +204,15 @@ error:
if (pOutSample) if (pOutSample)
IMediaSample_Release(pOutSample); IMediaSample_Release(pOutSample);
pOutSample = NULL; pOutSample = NULL;
} }
This->lasttime_real = tStop;
This->lasttime_sent = tMed;
if (hr != S_OK)
FIXME("FATALITY: %08x\n", hr);
return hr; return hr;
} }
@ -252,6 +276,7 @@ static HRESULT ACMWrapper_Cleanup(TransformFilterImpl* pTransformFilter)
acmStreamClose(This->has, 0); acmStreamClose(This->has, 0);
This->has = 0; This->has = 0;
This->lasttime_real = This->lasttime_sent = -1;
return S_OK; return S_OK;
} }
@ -287,6 +312,7 @@ HRESULT ACMWrapper_create(IUnknown * pUnkOuter, LPVOID * ppv)
return hr; return hr;
*ppv = (LPVOID)This; *ppv = (LPVOID)This;
This->lasttime_real = This->lasttime_sent = -1;
return hr; return hr;
} }