Maarten Lankhorst : quartz: Add quality control to avi decoder.
Alexandre Julliard
julliard at winehq.org
Wed Nov 10 11:09:38 CST 2010
Module: wine
Branch: master
Commit: f38688b836497c3eca7fbdebe30d69261b19dfba
URL: http://source.winehq.org/git/wine.git/?a=commit;h=f38688b836497c3eca7fbdebe30d69261b19dfba
Author: Maarten Lankhorst <m.b.lankhorst at 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)
More information about the wine-cvs
mailing list