[PATCH 05/14] quartz: Add quality control to avi decoder
Maarten Lankhorst
m.b.lankhorst at gmail.com
Tue Nov 9 16:42:42 CST 2010
---
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)
--
1.7.1
More information about the wine-patches
mailing list