[QUARTZ] Improved AVIDec filter & transform template
Christian Costa
titan.costa at wanadoo.fr
Sat Feb 19 08:50:33 CST 2005
Hi,
Changelog:
Improved AVIDec.
Added 2 new callback functions to the transform template and moved all
of them into a funcs table.
Christian Costa titan.costa at wanadoo.fr
-------------- next part --------------
Index: dlls/quartz/avidec.c
===================================================================
RCS file: /home/wine/wine/dlls/quartz/avidec.c,v
retrieving revision 1.16
diff -u -r1.16 avidec.c
--- dlls/quartz/avidec.c 1 Feb 2005 14:22:00 -0000 1.16
+++ dlls/quartz/avidec.c 19 Feb 2005 13:32:21 -0000
@@ -46,6 +46,8 @@
WINE_DEFAULT_DEBUG_CHANNEL(quartz);
+static HRESULT AVIDec_Cleanup(TransformFilterImpl* pTransformFilter);
+
typedef struct AVIDecImpl
{
TransformFilterImpl tf;
@@ -54,7 +56,23 @@
BITMAPINFOHEADER* pBihOut;
} AVIDecImpl;
-static DWORD AVIDec_SendSampleData(TransformFilterImpl* pTransformFilter, LPBYTE data, DWORD size)
+static HRESULT AVIDec_ProcessBegin(TransformFilterImpl* pTransformFilter)
+{
+ AVIDecImpl* This = (AVIDecImpl*)pTransformFilter;
+ DWORD result;
+
+ TRACE("(%p)->()\n", This);
+
+ result = ICDecompressBegin(This->hvid, This->pBihIn, This->pBihOut);
+ if (result != ICERR_OK)
+ {
+ ERR("Cannot start processing (%ld)\n", result);
+ return E_FAIL;
+ }
+ return S_OK;
+}
+
+static HRESULT AVIDec_ProcessSampleData(TransformFilterImpl* pTransformFilter, LPBYTE data, DWORD size)
{
AVIDecImpl* This = (AVIDecImpl*)pTransformFilter;
VIDEOINFOHEADER* format;
@@ -115,25 +133,45 @@
return hr;
}
+static HRESULT AVIDec_ProcessEnd(TransformFilterImpl* pTransformFilter)
+{
+ AVIDecImpl* This = (AVIDecImpl*)pTransformFilter;
+ DWORD result;
+
+ TRACE("(%p)->()\n", This);
+
+ result = ICDecompressEnd(This->hvid);
+ if (result != ICERR_OK)
+ {
+ ERR("Cannot stop processing (%ld)\n", result);
+ return E_FAIL;
+ }
+ return S_OK;
+}
+
static HRESULT AVIDec_ConnectInput(TransformFilterImpl* pTransformFilter, const AM_MEDIA_TYPE * pmt)
{
AVIDecImpl* This = (AVIDecImpl*)pTransformFilter;
+ HRESULT hr = S_FALSE;
TRACE("(%p)->(%p)\n", This, pmt);
+ AVIDec_Cleanup(pTransformFilter);
+
if ((IsEqualIID(&pmt->majortype, &MEDIATYPE_Video)) &&
(!memcmp(((char*)&pmt->subtype)+4, ((char*)&MEDIATYPE_Video)+4, sizeof(GUID)-4)) && /* Check root (GUID w/o FOURCC) */
(IsEqualIID(&pmt->formattype, &FORMAT_VideoInfo)))
{
- HIC drv;
VIDEOINFOHEADER* format = (VIDEOINFOHEADER*)pmt->pbFormat;
- drv = ICLocate(pmt->majortype.Data1, pmt->subtype.Data1, &format->bmiHeader, NULL, ICMODE_DECOMPRESS);
- if (drv)
+ This->hvid = ICLocate(pmt->majortype.Data1, pmt->subtype.Data1, &format->bmiHeader, NULL, ICMODE_DECOMPRESS);
+ if (This->hvid)
{
AM_MEDIA_TYPE* outpmt = &((OutputPin*)This->tf.ppPins[1])->pin.mtCurrent;
const CLSID* outsubtype;
DWORD bih_size;
+ DWORD output_depth = format->bmiHeader.biBitCount;
+ DWORD result;
switch(format->bmiHeader.biBitCount)
{
@@ -142,41 +180,46 @@
case 16: outsubtype = &MEDIASUBTYPE_RGB565; break;
case 8: outsubtype = &MEDIASUBTYPE_RGB8; break;
default:
- FIXME("Depth %d not supported\n", format->bmiHeader.biBitCount);
- ICClose(drv);
- return S_FALSE;
+ TRACE("Non standard input depth %d, forced ouptut depth to 32\n", format->bmiHeader.biBitCount);
+ outsubtype = &MEDIASUBTYPE_RGB32;
+ output_depth = 32;
+ break;
}
- CopyMediaType(outpmt, pmt);
- outpmt->subtype = *outsubtype;
- This->hvid = drv;
/* Copy bitmap header from media type to 1 for input and 1 for output */
- if (This->pBihIn) {
- CoTaskMemFree(This->pBihIn);
- CoTaskMemFree(This->pBihOut);
- }
bih_size = format->bmiHeader.biSize + format->bmiHeader.biClrUsed * 4;
This->pBihIn = (BITMAPINFOHEADER*)CoTaskMemAlloc(bih_size);
if (!This->pBihIn)
{
- ICClose(drv);
- return E_OUTOFMEMORY;
+ hr = E_OUTOFMEMORY;
+ goto failed;
}
This->pBihOut = (BITMAPINFOHEADER*)CoTaskMemAlloc(bih_size);
if (!This->pBihOut)
{
- CoTaskMemFree(This->pBihIn);
- This->pBihIn = NULL;
- ICClose(drv);
- return E_OUTOFMEMORY;
+ hr = E_OUTOFMEMORY;
+ goto failed;
}
memcpy(This->pBihIn, &format->bmiHeader, bih_size);
memcpy(This->pBihOut, &format->bmiHeader, bih_size);
/* Update output format as non compressed bitmap */
This->pBihOut->biCompression = 0;
+ This->pBihOut->biBitCount = output_depth;
This->pBihOut->biSizeImage = This->pBihOut->biWidth * This->pBihOut->biHeight * This->pBihOut->biBitCount / 8;
+ result = ICDecompressQuery(This->hvid, This->pBihIn, This->pBihOut);
+ if (result != ICERR_OK)
+ {
+ TRACE("Unable to found a suitable output format (%ld)\n", result);
+ goto failed;
+ }
+
+ /* Update output media type */
+ CopyMediaType(outpmt, pmt);
+ outpmt->subtype = *outsubtype;
+ memcpy(&(((VIDEOINFOHEADER*)outpmt->pbFormat)->bmiHeader), This->pBihOut, This->pBihOut->biSize);
+
/* Update buffer size of media samples in output */
((OutputPin*)This->tf.ppPins[1])->allocProps.cbBuffer = This->pBihOut->biSizeImage;
@@ -186,8 +229,11 @@
TRACE("Unable to find a suitable VFW decompressor\n");
}
+failed:
+ AVIDec_Cleanup(pTransformFilter);
+
TRACE("Connection refused\n");
- return S_FALSE;
+ return hr;
}
static HRESULT AVIDec_Cleanup(TransformFilterImpl* pTransformFilter)
@@ -198,18 +244,26 @@
if (This->hvid)
ICClose(This->hvid);
-
- if (This->pBihIn) {
+ if (This->pBihIn)
CoTaskMemFree(This->pBihIn);
+ if (This->pBihOut)
CoTaskMemFree(This->pBihOut);
- }
This->hvid = NULL;
This->pBihIn = NULL;
+ This->pBihOut = NULL;
return S_OK;
}
+TransformFuncsTable AVIDec_FuncsTable = {
+ AVIDec_ProcessBegin,
+ AVIDec_ProcessSampleData,
+ AVIDec_ProcessEnd,
+ AVIDec_ConnectInput,
+ AVIDec_Cleanup
+};
+
HRESULT AVIDec_create(IUnknown * pUnkOuter, LPVOID * ppv)
{
HRESULT hr;
@@ -227,8 +281,9 @@
This->hvid = NULL;
This->pBihIn = NULL;
+ This->pBihOut = NULL;
- hr = TransformFilter_Create(&(This->tf), &CLSID_AVIDec, AVIDec_SendSampleData, AVIDec_ConnectInput, AVIDec_Cleanup);
+ hr = TransformFilter_Create(&(This->tf), &CLSID_AVIDec, &AVIDec_FuncsTable);
if (FAILED(hr))
return hr;
Index: dlls/quartz/acmwrapper.c
===================================================================
RCS file: /home/wine/wine/dlls/quartz/acmwrapper.c,v
retrieving revision 1.2
diff -u -r1.2 acmwrapper.c
--- dlls/quartz/acmwrapper.c 10 Feb 2005 19:19:35 -0000 1.2
+++ dlls/quartz/acmwrapper.c 19 Feb 2005 13:32:23 -0000
@@ -59,7 +59,7 @@
BOOL reinit_codec; /* FIXME: Should use sync points instead */
} ACMWrapperImpl;
-static DWORD ACMWrapper_SendSampleData(TransformFilterImpl* pTransformFilter, LPBYTE data, DWORD size)
+static HRESULT ACMWrapper_ProcessSampleData(TransformFilterImpl* pTransformFilter, LPBYTE data, DWORD size)
{
ACMWrapperImpl* This = (ACMWrapperImpl*)pTransformFilter;
AM_MEDIA_TYPE amt;
@@ -230,6 +230,14 @@
return S_OK;
}
+TransformFuncsTable ACMWrapper_FuncsTable = {
+ NULL,
+ ACMWrapper_ProcessSampleData,
+ NULL,
+ ACMWrapper_ConnectInput,
+ ACMWrapper_Cleanup
+};
+
HRESULT ACMWrapper_create(IUnknown * pUnkOuter, LPVOID * ppv)
{
HRESULT hr;
@@ -248,7 +256,7 @@
This->has = 0;
This->reinit_codec = TRUE;
- hr = TransformFilter_Create(&(This->tf), &CLSID_ACMWrapper, ACMWrapper_SendSampleData, ACMWrapper_ConnectInput, ACMWrapper_Cleanup);
+ hr = TransformFilter_Create(&(This->tf), &CLSID_ACMWrapper, &ACMWrapper_FuncsTable);
if (FAILED(hr))
return hr;
Index: dlls/quartz/transform.h
===================================================================
RCS file: /home/wine/wine/dlls/quartz/transform.h,v
retrieving revision 1.1
diff -u -r1.1 transform.h
--- dlls/quartz/transform.h 31 Jan 2005 16:24:00 -0000 1.1
+++ dlls/quartz/transform.h 19 Feb 2005 13:32:25 -0000
@@ -20,9 +20,13 @@
typedef struct TransformFilterImpl TransformFilterImpl;
-typedef DWORD (*PFN_PROCESS_SAMPLE) (TransformFilterImpl* This, LPBYTE data, DWORD size);
-typedef HRESULT (*PFN_CONNECT_INPUT) (TransformFilterImpl* This, const AM_MEDIA_TYPE * pmt);
-typedef HRESULT (*PFN_CLEANUP) (TransformFilterImpl* This);
+typedef struct TransformFuncsTable {
+ HRESULT (*pfnProcessBegin) (TransformFilterImpl* This);
+ HRESULT (*pfnProcessSampleData) (TransformFilterImpl* This, LPBYTE data, DWORD size);
+ HRESULT (*pfnProcessEnd) (TransformFilterImpl* This);
+ HRESULT (*pfnConnectInput) (TransformFilterImpl* This, const AM_MEDIA_TYPE * pmt);
+ HRESULT (*pfnCleanup) (TransformFilterImpl* This);
+} TransformFuncsTable;
struct TransformFilterImpl
{
@@ -38,9 +42,7 @@
IPin ** ppPins;
- PFN_PROCESS_SAMPLE pfnProcessSample;
- PFN_CONNECT_INPUT pfnConnectInput;
- PFN_CLEANUP pfnCleanup;
+ TransformFuncsTable * pFuncsTable;
};
-HRESULT TransformFilter_Create(TransformFilterImpl*, const CLSID*, PFN_PROCESS_SAMPLE, PFN_CONNECT_INPUT, PFN_CLEANUP);
+HRESULT TransformFilter_Create(TransformFilterImpl*, const CLSID*, TransformFuncsTable* pFuncsTable);
Index: dlls/quartz/transform.c
===================================================================
RCS file: /home/wine/wine/dlls/quartz/transform.c,v
retrieving revision 1.1
diff -u -r1.1 transform.c
--- dlls/quartz/transform.c 31 Jan 2005 16:24:00 -0000 1.1
+++ dlls/quartz/transform.c 19 Feb 2005 13:32:27 -0000
@@ -92,7 +92,7 @@
}
#endif
- This->pfnProcessSample(This, pbSrcStream, cbSrcStream);
+ This->pFuncsTable->pfnProcessSampleData(This, pbSrcStream, cbSrcStream);
return S_OK;
}
@@ -103,7 +103,7 @@
TRACE("%p\n", iface);
dump_AM_MEDIA_TYPE(pmt);
- return This->pfnConnectInput(This, pmt);
+ return This->pFuncsTable->pfnConnectInput(This, pmt);
}
@@ -173,7 +173,7 @@
return E_FAIL;
}
-HRESULT TransformFilter_Create(TransformFilterImpl* pTransformFilter, const CLSID* pClsid, PFN_PROCESS_SAMPLE pps, PFN_CONNECT_INPUT pci, PFN_CLEANUP pcu)
+HRESULT TransformFilter_Create(TransformFilterImpl* pTransformFilter, const CLSID* pClsid, TransformFuncsTable* pFuncsTable)
{
HRESULT hr;
PIN_INFO piInput;
@@ -181,9 +181,7 @@
/* pTransformFilter is already allocated */
pTransformFilter->clsid = *pClsid;
- pTransformFilter->pfnProcessSample = pps;
- pTransformFilter->pfnConnectInput = pci;
- pTransformFilter->pfnCleanup = pcu;
+ pTransformFilter->pFuncsTable = pFuncsTable;
pTransformFilter->lpVtbl = &TransformFilter_Vtbl;
@@ -285,7 +283,7 @@
HeapFree(GetProcessHeap(), 0, This->ppPins);
This->lpVtbl = NULL;
- This->pfnCleanup(This);
+ This->pFuncsTable->pfnCleanup(This);
TRACE("Destroying transform filter\n");
CoTaskMemFree(This);
@@ -320,6 +318,8 @@
EnterCriticalSection(&This->csFilter);
{
This->state = State_Stopped;
+ if (This->pFuncsTable->pfnProcessEnd)
+ This->pFuncsTable->pfnProcessEnd(This);
}
LeaveCriticalSection(&This->csFilter);
@@ -353,6 +353,8 @@
This->rtStreamStart = tStart;
This->state = State_Running;
OutputPin_CommitAllocator((OutputPin *)This->ppPins[1]);
+ if (This->pFuncsTable->pfnProcessBegin)
+ This->pFuncsTable->pfnProcessBegin(This);
}
LeaveCriticalSection(&This->csFilter);
@@ -540,7 +542,7 @@
if (hr == S_OK)
{
- pTransformFilter->pfnCleanup(pTransformFilter);
+ pTransformFilter->pFuncsTable->pfnCleanup(pTransformFilter);
}
return hr;
More information about the wine-patches
mailing list