quartz: Add quality control to avi decoder.
This commit is contained in:
parent
a5798fc96c
commit
f38688b836
|
@ -48,6 +48,7 @@ typedef struct AVIDecImpl
|
|||
HIC hvid;
|
||||
BITMAPINFOHEADER* pBihIn;
|
||||
BITMAPINFOHEADER* pBihOut;
|
||||
REFERENCE_TIME late;
|
||||
} AVIDecImpl;
|
||||
|
||||
static const IBaseFilterVtbl AVIDec_Vtbl;
|
||||
|
@ -58,6 +59,7 @@ static HRESULT WINAPI AVIDec_StartStreaming(TransformFilter* pTransformFilter)
|
|||
DWORD result;
|
||||
|
||||
TRACE("(%p)->()\n", This);
|
||||
This->late = -1;
|
||||
|
||||
result = ICDecompressBegin(This->hvid, This->pBihIn, This->pBihOut);
|
||||
if (result != ICERR_OK)
|
||||
|
@ -68,6 +70,36 @@ static HRESULT WINAPI AVIDec_StartStreaming(TransformFilter* pTransformFilter)
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI AVIDec_EndFlush(TransformFilter *pTransformFilter) {
|
||||
AVIDecImpl* This = (AVIDecImpl*)pTransformFilter;
|
||||
This->late = -1;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI AVIDec_NotifyDrop(TransformFilter *pTransformFilter, IBaseFilter *sender, Quality qm) {
|
||||
AVIDecImpl *This = (AVIDecImpl*)pTransformFilter;
|
||||
|
||||
EnterCriticalSection(&This->tf.filter.csFilter);
|
||||
if (qm.Late > 0)
|
||||
This->late = qm.Late + qm.TimeStamp;
|
||||
else
|
||||
This->late = -1;
|
||||
LeaveCriticalSection(&This->tf.filter.csFilter);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static int AVIDec_DropSample(AVIDecImpl *This, REFERENCE_TIME tStart) {
|
||||
if (This->late < 0)
|
||||
return 0;
|
||||
|
||||
if (tStart < This->late) {
|
||||
TRACE("Dropping sample\n");
|
||||
return 1;
|
||||
}
|
||||
This->late = -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI AVIDec_Receive(TransformFilter *tf, IMediaSample *pSample)
|
||||
{
|
||||
AVIDecImpl* This = (AVIDecImpl *)tf;
|
||||
|
@ -80,6 +112,7 @@ static HRESULT WINAPI AVIDec_Receive(TransformFilter *tf, IMediaSample *pSample)
|
|||
DWORD cbSrcStream;
|
||||
LPBYTE pbSrcStream;
|
||||
LONGLONG tStart, tStop;
|
||||
DWORD flags = 0;
|
||||
|
||||
EnterCriticalSection(&This->tf.filter.csFilter);
|
||||
hr = IMediaSample_GetPointer(pSample, &pbSrcStream);
|
||||
|
@ -123,10 +156,22 @@ static HRESULT WINAPI AVIDec_Receive(TransformFilter *tf, IMediaSample *pSample)
|
|||
goto error;
|
||||
}
|
||||
|
||||
res = ICDecompress(This->hvid, 0, This->pBihIn, pbSrcStream, This->pBihOut, pbDstStream);
|
||||
if (IMediaSample_IsPreroll(pSample) == S_OK)
|
||||
flags |= ICDECOMPRESS_PREROLL;
|
||||
if (IMediaSample_IsSyncPoint(pSample) != S_OK)
|
||||
flags |= ICDECOMPRESS_NOTKEYFRAME;
|
||||
if (IMediaSample_GetTime(pSample, &tStart, NULL) == S_OK &&
|
||||
AVIDec_DropSample(This, tStart))
|
||||
flags |= ICDECOMPRESS_HURRYUP;
|
||||
|
||||
res = ICDecompress(This->hvid, flags, This->pBihIn, pbSrcStream, This->pBihOut, pbDstStream);
|
||||
if (res != ICERR_OK)
|
||||
ERR("Error occurred during the decompression (%x)\n", res);
|
||||
|
||||
/* Drop sample if its intended to be dropped */
|
||||
if (flags & ICDECOMPRESS_HURRYUP)
|
||||
goto error;
|
||||
|
||||
IMediaSample_SetActualDataLength(pOutSample, This->pBihOut->biSizeImage);
|
||||
|
||||
IMediaSample_SetPreroll(pOutSample, (IMediaSample_IsPreroll(pSample) == S_OK));
|
||||
|
@ -338,8 +383,9 @@ static const TransformFilterFuncTable AVIDec_FuncsTable = {
|
|||
AVIDec_BreakConnect,
|
||||
NULL,
|
||||
NULL,
|
||||
AVIDec_EndFlush,
|
||||
NULL,
|
||||
NULL
|
||||
AVIDec_NotifyDrop
|
||||
};
|
||||
|
||||
HRESULT AVIDec_create(IUnknown * pUnkOuter, LPVOID * ppv)
|
||||
|
|
Loading…
Reference in New Issue