Module: wine Branch: master Commit: f38688b836497c3eca7fbdebe30d69261b19dfba URL: http://source.winehq.org/git/wine.git/?a=commit;h=f38688b836497c3eca7fbdebe3...
Author: Maarten Lankhorst m.b.lankhorst@gmail.com Date: Tue Nov 9 23:42:42 2010 +0100
quartz: Add quality control to avi decoder.
---
dlls/quartz/avidec.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 files changed, 48 insertions(+), 2 deletions(-)
diff --git a/dlls/quartz/avidec.c b/dlls/quartz/avidec.c index 39fa861..02f7674 100644 --- a/dlls/quartz/avidec.c +++ b/dlls/quartz/avidec.c @@ -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)