[QUARTZ] Added transform filter template and made AVIDec use it.
Christian Costa
titan.costa at wanadoo.fr
Sun Jan 30 06:53:38 CST 2005
Hi,
Changelog:
Added transform filter template and made AVIDec use it.
Fixed memory leak in register_filters function.
Christian Costa titan.costa at wanadoo.fr
-------------- next part --------------
Index: dlls/quartz/Makefile.in
===================================================================
RCS file: /home/wine/wine/dlls/quartz/Makefile.in,v
retrieving revision 1.40
diff -u -r1.40 Makefile.in
--- dlls/quartz/Makefile.in 24 Aug 2004 02:28:35 -0000 1.40
+++ dlls/quartz/Makefile.in 30 Jan 2005 11:35:55 -0000
@@ -24,6 +24,7 @@
pin.c \
regsvr.c \
systemclock.c \
+ transform.c \
videorenderer.c
RC_SRCS = version.rc
Index: dlls/quartz/regsvr.c
===================================================================
RCS file: /home/wine/wine/dlls/quartz/regsvr.c,v
retrieving revision 1.16
diff -u -r1.16 regsvr.c
--- dlls/quartz/regsvr.c 21 Jan 2005 10:14:45 -0000 1.16
+++ dlls/quartz/regsvr.c 30 Jan 2005 11:35:58 -0000
@@ -630,6 +630,7 @@
if (FAILED(hr)) {
ERR("failed to register with hresult 0x%lx\n", hr);
+ CoTaskMemFree(prfp2);
break;
}
Index: dlls/quartz/avidec.c
===================================================================
RCS file: /home/wine/wine/dlls/quartz/avidec.c,v
retrieving revision 1.14
diff -u -r1.14 avidec.c
--- dlls/quartz/avidec.c 6 Jan 2005 19:36:47 -0000 1.14
+++ dlls/quartz/avidec.c 30 Jan 2005 11:36:00 -0000
@@ -1,7 +1,7 @@
/*
* AVI Decompressor (VFW decompressors wrapper)
*
- * Copyright 2004 Christian Costa
+ * Copyright 2004-2005 Christian Costa
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -36,45 +36,27 @@
#include "vfwmsgs.h"
#include "evcode.h"
#include "vfw.h"
-/* #include "fourcc.h" */
-/* #include "avcodec.h" */
#include <assert.h>
#include "wine/unicode.h"
#include "wine/debug.h"
-WINE_DEFAULT_DEBUG_CHANNEL(quartz);
-
-static const WCHAR wcsInputPinName[] = {'i','n','p','u','t',' ','p','i','n',0};
-static const WCHAR wcsOutputPinName[] = {'o','u','t','p','u','t',' ','p','i','n',0};
+#include "transform.h"
-static const IBaseFilterVtbl AVIDec_Vtbl;
-static const IPinVtbl AVIDec_InputPin_Vtbl;
-static const IMemInputPinVtbl MemInputPin_Vtbl;
-static const IPinVtbl AVIDec_OutputPin_Vtbl;
+WINE_DEFAULT_DEBUG_CHANNEL(quartz);
typedef struct AVIDecImpl
{
- const IBaseFilterVtbl * lpVtbl;
-
- ULONG refCount;
- CRITICAL_SECTION csFilter;
- FILTER_STATE state;
- REFERENCE_TIME rtStreamStart;
- IReferenceClock * pClock;
- FILTER_INFO filterInfo;
-
- IPin ** ppPins;
-
+ TransformFilterImpl tf;
HIC hvid;
BITMAPINFOHEADER* pBihIn;
BITMAPINFOHEADER* pBihOut;
- int init;
} AVIDecImpl;
-static DWORD AVIDec_SendSampleData(AVIDecImpl* This, LPBYTE data, DWORD size)
+static DWORD AVIDec_SendSampleData(TransformFilterImpl* sub, LPBYTE data, DWORD size)
{
+ AVIDecImpl* This = (AVIDecImpl*)sub;
VIDEOINFOHEADER* format;
AM_MEDIA_TYPE amt;
HRESULT hr;
@@ -83,7 +65,9 @@
DWORD cbDstStream;
LPBYTE pbDstStream;
- hr = IPin_ConnectionMediaType(This->ppPins[0], &amt);
+ TRACE("%p %p %ld\n", sub, data, size);
+
+ hr = IPin_ConnectionMediaType(This->tf.ppPins[0], &amt);
if (FAILED(hr)) {
ERR("Unable to retrieve media type\n");
goto error;
@@ -93,12 +77,12 @@
/* Update input size to match sample size */
This->pBihIn->biSizeImage = size;
- hr = OutputPin_GetDeliveryBuffer((OutputPin*)This->ppPins[1], &pSample, NULL, NULL, 0);
+ hr = OutputPin_GetDeliveryBuffer((OutputPin*)This->tf.ppPins[1], &pSample, NULL, NULL, 0);
if (FAILED(hr)) {
ERR("Unable to get delivery buffer (%lx)\n", hr);
goto error;
}
-
+
hr = IMediaSample_SetActualDataLength(pSample, 0);
assert(hr == S_OK);
@@ -118,7 +102,7 @@
if (res != ICERR_OK)
ERR("Error occurred during the decompression (%lx)\n", res);
- hr = OutputPin_SendSample((OutputPin*)This->ppPins[1], pSample);
+ hr = OutputPin_SendSample((OutputPin*)This->tf.ppPins[1], pSample);
if (hr != S_OK && hr != VFW_E_NOT_CONNECTED) {
ERR("Error sending sample (%lx)\n", hr);
goto error;
@@ -131,50 +115,7 @@
return hr;
}
-static HRESULT AVIDec_Sample(LPVOID iface, IMediaSample * pSample)
-{
- AVIDecImpl *This = (AVIDecImpl *)iface;
- LPBYTE pbSrcStream = NULL;
- long cbSrcStream = 0;
- REFERENCE_TIME tStart, tStop;
- HRESULT hr;
-
- TRACE("%p %p\n", iface, pSample);
-
- hr = IMediaSample_GetPointer(pSample, &pbSrcStream);
- if (FAILED(hr))
- {
- ERR("Cannot get pointer to sample data (%lx)\n", hr);
- return hr;
- }
-
- hr = IMediaSample_GetTime(pSample, &tStart, &tStop);
- if (FAILED(hr))
- ERR("Cannot get sample time (%lx)\n", hr);
-
- cbSrcStream = IMediaSample_GetActualDataLength(pSample);
-
- TRACE("Sample data ptr = %p, size = %ld\n", pbSrcStream, cbSrcStream);
-
-#if 0 /* For debugging purpose */
- {
- int i;
- for(i = 0; i < cbSrcStream; i++)
- {
- if ((i!=0) && !(i%16))
- DPRINTF("\n");
- DPRINTF("%02x ", pbSrcStream[i]);
- }
- DPRINTF("\n");
- }
-#endif
-
- AVIDec_SendSampleData(This, pbSrcStream, cbSrcStream);
-
- return S_OK;
-}
-
-static HRESULT AVIDec_Input_QueryAccept(LPVOID iface, const AM_MEDIA_TYPE * pmt)
+static HRESULT AVIDec_ConnectInput(TransformFilterImpl* iface, const AM_MEDIA_TYPE * pmt)
{
AVIDecImpl* pAVIDec = (AVIDecImpl*)iface;
TRACE("%p\n", iface);
@@ -186,10 +127,11 @@
{
HIC drv;
VIDEOINFOHEADER* format = (VIDEOINFOHEADER*)pmt->pbFormat;
+
drv = ICLocate(pmt->majortype.Data1, pmt->subtype.Data1, &format->bmiHeader, NULL, ICMODE_DECOMPRESS);
if (drv)
{
- AM_MEDIA_TYPE* outpmt = &((OutputPin*)pAVIDec->ppPins[1])->pin.mtCurrent;
+ AM_MEDIA_TYPE* outpmt = &((OutputPin*)pAVIDec->tf.ppPins[1])->pin.mtCurrent;
const CLSID* outsubtype;
DWORD bih_size;
@@ -204,7 +146,7 @@
ICClose(drv);
return S_FALSE;
}
- CopyMediaType( outpmt, pmt);
+ CopyMediaType(outpmt, pmt);
outpmt->subtype = *outsubtype;
pAVIDec->hvid = drv;
@@ -236,91 +178,39 @@
pAVIDec->pBihOut->biSizeImage = pAVIDec->pBihOut->biWidth * pAVIDec->pBihOut->biHeight * pAVIDec->pBihOut->biBitCount / 8;
/* Update buffer size of media samples in output */
- ((OutputPin*)pAVIDec->ppPins[1])->allocProps.cbBuffer = pAVIDec->pBihOut->biSizeImage;
-
- pAVIDec->init = 1;
+ ((OutputPin*)pAVIDec->tf.ppPins[1])->allocProps.cbBuffer = pAVIDec->pBihOut->biSizeImage;
+
TRACE("Connection accepted\n");
return S_OK;
}
TRACE("Unable to find a suitable VFW decompressor\n");
}
-
- TRACE("Connection refused\n");
- return S_FALSE;
-}
-
-static HRESULT AVIDec_Output_QueryAccept(LPVOID iface, const AM_MEDIA_TYPE * pmt)
-{
- AVIDecImpl* pAVIDec = (AVIDecImpl*)iface;
- AM_MEDIA_TYPE* outpmt = &((OutputPin*)pAVIDec->ppPins[1])->pin.mtCurrent;
- TRACE("%p\n", iface);
-
- if (IsEqualIID(&pmt->majortype, &outpmt->majortype) && IsEqualIID(&pmt->subtype, &outpmt->subtype))
- return S_OK;
+ TRACE("Connection refused\n");
return S_FALSE;
}
-static HRESULT AVIDec_InputPin_Construct(const PIN_INFO * pPinInfo, SAMPLEPROC pSampleProc, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, LPCRITICAL_SECTION pCritSec, IPin ** ppPin)
+static HRESULT AVIDec_Cleanup(TransformFilterImpl* This)
{
- InputPin * pPinImpl;
-
- *ppPin = NULL;
-
- if (pPinInfo->dir != PINDIR_INPUT)
- {
- ERR("Pin direction(%x) != PINDIR_INPUT\n", pPinInfo->dir);
- return E_INVALIDARG;
- }
-
- pPinImpl = CoTaskMemAlloc(sizeof(*pPinImpl));
+ AVIDecImpl* pAVIDec = (AVIDecImpl*)This;
+
+ if (pAVIDec->hvid)
+ ICClose(pAVIDec->hvid);
- if (!pPinImpl)
- return E_OUTOFMEMORY;
- TRACE("QA : %p %p\n", pQueryAccept, AVIDec_Input_QueryAccept);
- if (SUCCEEDED(InputPin_Init(pPinInfo, pSampleProc, pUserData, pQueryAccept, pCritSec, pPinImpl)))
- {
- pPinImpl->pin.lpVtbl = &AVIDec_InputPin_Vtbl;
- pPinImpl->lpVtblMemInput = &MemInputPin_Vtbl;
-
- *ppPin = (IPin *)(&pPinImpl->pin.lpVtbl);
- return S_OK;
+ if (pAVIDec->pBihIn) {
+ CoTaskMemFree(pAVIDec->pBihIn);
+ CoTaskMemFree(pAVIDec->pBihOut);
}
- return E_FAIL;
-}
-
-HRESULT AVIDec_OutputPin_Construct(const PIN_INFO * pPinInfo, ALLOCATOR_PROPERTIES *props, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, LPCRITICAL_SECTION pCritSec, IPin ** ppPin)
-{
- OutputPin * pPinImpl;
- *ppPin = NULL;
-
- if (pPinInfo->dir != PINDIR_OUTPUT)
- {
- ERR("Pin direction(%x) != PINDIR_OUTPUT\n", pPinInfo->dir);
- return E_INVALIDARG;
- }
-
- pPinImpl = CoTaskMemAlloc(sizeof(*pPinImpl));
-
- if (!pPinImpl)
- return E_OUTOFMEMORY;
+ pAVIDec->hvid = NULL;
+ pAVIDec->pBihIn = NULL;
- if (SUCCEEDED(OutputPin_Init(pPinInfo, props, pUserData, pQueryAccept, pCritSec, pPinImpl)))
- {
- pPinImpl->pin.lpVtbl = &AVIDec_OutputPin_Vtbl;
-
- *ppPin = (IPin *)(&pPinImpl->pin.lpVtbl);
- return S_OK;
- }
- return E_FAIL;
+ return S_OK;
}
HRESULT AVIDec_create(IUnknown * pUnkOuter, LPVOID * ppv)
{
HRESULT hr;
- PIN_INFO piInput;
- PIN_INFO piOutput;
AVIDecImpl * pAVIDec;
TRACE("(%p, %p)\n", pUnkOuter, ppv);
@@ -329,417 +219,19 @@
if (pUnkOuter)
return CLASS_E_NOAGGREGATION;
-
+
+ /* Note: This memory is managed by the transform filter once created */
pAVIDec = CoTaskMemAlloc(sizeof(AVIDecImpl));
- pAVIDec->lpVtbl = &AVIDec_Vtbl;
-
- pAVIDec->refCount = 1;
- InitializeCriticalSection(&pAVIDec->csFilter);
- pAVIDec->state = State_Stopped;
- pAVIDec->pClock = NULL;
+ pAVIDec->hvid = NULL;
pAVIDec->pBihIn = NULL;
- pAVIDec->pBihOut = NULL;
- pAVIDec->init = 0;
- ZeroMemory(&pAVIDec->filterInfo, sizeof(FILTER_INFO));
-
- pAVIDec->ppPins = CoTaskMemAlloc(2 * sizeof(IPin *));
-
- /* construct input pin */
- piInput.dir = PINDIR_INPUT;
- piInput.pFilter = (IBaseFilter *)pAVIDec;
- strncpyW(piInput.achName, wcsInputPinName, sizeof(piInput.achName) / sizeof(piInput.achName[0]));
- piOutput.dir = PINDIR_OUTPUT;
- piOutput.pFilter = (IBaseFilter *)pAVIDec;
- strncpyW(piOutput.achName, wcsOutputPinName, sizeof(piOutput.achName) / sizeof(piOutput.achName[0]));
-
- hr = AVIDec_InputPin_Construct(&piInput, AVIDec_Sample, (LPVOID)pAVIDec, AVIDec_Input_QueryAccept, &pAVIDec->csFilter, &pAVIDec->ppPins[0]);
-
- if (SUCCEEDED(hr))
- {
- ALLOCATOR_PROPERTIES props;
- props.cbAlign = 1;
- props.cbPrefix = 0;
- props.cbBuffer = 0; /* Will be updated at connection time */
- props.cBuffers = 2;
-
- hr = AVIDec_OutputPin_Construct(&piOutput, &props, NULL, AVIDec_Output_QueryAccept, &pAVIDec->csFilter, &pAVIDec->ppPins[1]);
-
- if (FAILED(hr))
- ERR("Cannot create output pin (%lx)\n", hr);
-
- *ppv = (LPVOID)pAVIDec;
- }
- else
- {
- CoTaskMemFree(pAVIDec->ppPins);
- DeleteCriticalSection(&pAVIDec->csFilter);
- CoTaskMemFree(pAVIDec);
- }
-
- return hr;
-}
-static HRESULT WINAPI AVIDec_QueryInterface(IBaseFilter * iface, REFIID riid, LPVOID * ppv)
-{
- AVIDecImpl *This = (AVIDecImpl *)iface;
- TRACE("(%p/%p)->(%s, %p)\n", This, iface, qzdebugstr_guid(riid), ppv);
-
- *ppv = NULL;
-
- if (IsEqualIID(riid, &IID_IUnknown))
- *ppv = (LPVOID)This;
- else if (IsEqualIID(riid, &IID_IPersist))
- *ppv = (LPVOID)This;
- else if (IsEqualIID(riid, &IID_IMediaFilter))
- *ppv = (LPVOID)This;
- else if (IsEqualIID(riid, &IID_IBaseFilter))
- *ppv = (LPVOID)This;
-
- if (*ppv)
- {
- IUnknown_AddRef((IUnknown *)(*ppv));
- return S_OK;
- }
-
- FIXME("No interface for %s!\n", qzdebugstr_guid(riid));
-
- return E_NOINTERFACE;
-}
-
-static ULONG WINAPI AVIDec_AddRef(IBaseFilter * iface)
-{
- AVIDecImpl *This = (AVIDecImpl *)iface;
- ULONG refCount = InterlockedIncrement(&This->refCount);
-
- TRACE("(%p/%p)->() AddRef from %ld\n", This, iface, refCount - 1);
-
- return refCount;
-}
-
-static ULONG WINAPI AVIDec_Release(IBaseFilter * iface)
-{
- AVIDecImpl *This = (AVIDecImpl *)iface;
- ULONG refCount = InterlockedDecrement(&This->refCount);
-
- TRACE("(%p/%p)->() Release from %ld\n", This, iface, refCount + 1);
-
- if (!refCount)
- {
- ULONG i;
-
- DeleteCriticalSection(&This->csFilter);
- IReferenceClock_Release(This->pClock);
-
- for (i = 0; i < 2; i++)
- IPin_Release(This->ppPins[i]);
-
- HeapFree(GetProcessHeap(), 0, This->ppPins);
- This->lpVtbl = NULL;
-
- if (This->hvid)
- ICClose(This->hvid);
-
- if (This->pBihIn) {
- CoTaskMemFree(This->pBihIn);
- CoTaskMemFree(This->pBihOut);
- }
-
- TRACE("Destroying AVI Decompressor\n");
- CoTaskMemFree(This);
-
- return 0;
- }
- else
- return refCount;
-}
-
-/** IPersist methods **/
-
-static HRESULT WINAPI AVIDec_GetClassID(IBaseFilter * iface, CLSID * pClsid)
-{
- AVIDecImpl *This = (AVIDecImpl *)iface;
-
- TRACE("(%p/%p)->(%p)\n", This, iface, pClsid);
-
- *pClsid = CLSID_AVIDec;
-
- return S_OK;
-}
+ hr = TransformFilter_Create(&(pAVIDec->tf), &CLSID_AVIDec, AVIDec_SendSampleData, AVIDec_ConnectInput, AVIDec_Cleanup);
-/** IMediaFilter methods **/
-
-static HRESULT WINAPI AVIDec_Stop(IBaseFilter * iface)
-{
- AVIDecImpl *This = (AVIDecImpl *)iface;
-
- TRACE("(%p/%p)\n", This, iface);
-
- EnterCriticalSection(&This->csFilter);
- {
- This->state = State_Stopped;
- }
- LeaveCriticalSection(&This->csFilter);
-
- return S_OK;
-}
-
-static HRESULT WINAPI AVIDec_Pause(IBaseFilter * iface)
-{
- AVIDecImpl *This = (AVIDecImpl *)iface;
-
- TRACE("(%p/%p)->()\n", This, iface);
-
- EnterCriticalSection(&This->csFilter);
- {
- This->state = State_Paused;
- }
- LeaveCriticalSection(&This->csFilter);
-
- return S_OK;
-}
-
-static HRESULT WINAPI AVIDec_Run(IBaseFilter * iface, REFERENCE_TIME tStart)
-{
- HRESULT hr = S_OK;
- AVIDecImpl *This = (AVIDecImpl *)iface;
-
- TRACE("(%p/%p)->(%s)\n", This, iface, wine_dbgstr_longlong(tStart));
-
- EnterCriticalSection(&This->csFilter);
- {
- This->rtStreamStart = tStart;
- This->state = State_Running;
- OutputPin_CommitAllocator((OutputPin *)This->ppPins[1]);
- }
- LeaveCriticalSection(&This->csFilter);
-
- return hr;
-}
-
-static HRESULT WINAPI AVIDec_GetState(IBaseFilter * iface, DWORD dwMilliSecsTimeout, FILTER_STATE *pState)
-{
- AVIDecImpl *This = (AVIDecImpl *)iface;
-
- TRACE("(%p/%p)->(%ld, %p)\n", This, iface, dwMilliSecsTimeout, pState);
-
- EnterCriticalSection(&This->csFilter);
- {
- *pState = This->state;
- }
- LeaveCriticalSection(&This->csFilter);
-
- return S_OK;
-}
-
-static HRESULT WINAPI AVIDec_SetSyncSource(IBaseFilter * iface, IReferenceClock *pClock)
-{
- AVIDecImpl *This = (AVIDecImpl *)iface;
-
- TRACE("(%p/%p)->(%p)\n", This, iface, pClock);
-
- EnterCriticalSection(&This->csFilter);
- {
- if (This->pClock)
- IReferenceClock_Release(This->pClock);
- This->pClock = pClock;
- if (This->pClock)
- IReferenceClock_AddRef(This->pClock);
- }
- LeaveCriticalSection(&This->csFilter);
-
- return S_OK;
-}
-
-static HRESULT WINAPI AVIDec_GetSyncSource(IBaseFilter * iface, IReferenceClock **ppClock)
-{
- AVIDecImpl *This = (AVIDecImpl *)iface;
-
- TRACE("(%p/%p)->(%p)\n", This, iface, ppClock);
-
- EnterCriticalSection(&This->csFilter);
- {
- *ppClock = This->pClock;
- IReferenceClock_AddRef(This->pClock);
- }
- LeaveCriticalSection(&This->csFilter);
-
- return S_OK;
-}
-
-/** IBaseFilter implementation **/
-
-static HRESULT WINAPI AVIDec_EnumPins(IBaseFilter * iface, IEnumPins **ppEnum)
-{
- ENUMPINDETAILS epd;
- AVIDecImpl *This = (AVIDecImpl *)iface;
-
- TRACE("(%p/%p)->(%p)\n", This, iface, ppEnum);
-
- epd.cPins = 2; /* input and output pins */
- epd.ppPins = This->ppPins;
- return IEnumPinsImpl_Construct(&epd, ppEnum);
-}
-
-static HRESULT WINAPI AVIDec_FindPin(IBaseFilter * iface, LPCWSTR Id, IPin **ppPin)
-{
- AVIDecImpl *This = (AVIDecImpl *)iface;
-
- TRACE("(%p/%p)->(%p,%p)\n", This, iface, debugstr_w(Id), ppPin);
-
- FIXME("AVISplitter::FindPin(...)\n");
-
- /* FIXME: critical section */
-
- return E_NOTIMPL;
-}
-
-static HRESULT WINAPI AVIDec_QueryFilterInfo(IBaseFilter * iface, FILTER_INFO *pInfo)
-{
- AVIDecImpl *This = (AVIDecImpl *)iface;
-
- TRACE("(%p/%p)->(%p)\n", This, iface, pInfo);
-
- strcpyW(pInfo->achName, This->filterInfo.achName);
- pInfo->pGraph = This->filterInfo.pGraph;
-
- if (pInfo->pGraph)
- IFilterGraph_AddRef(pInfo->pGraph);
-
- return S_OK;
-}
-
-static HRESULT WINAPI AVIDec_JoinFilterGraph(IBaseFilter * iface, IFilterGraph *pGraph, LPCWSTR pName)
-{
- HRESULT hr = S_OK;
- AVIDecImpl *This = (AVIDecImpl *)iface;
-
- TRACE("(%p/%p)->(%p, %s)\n", This, iface, pGraph, debugstr_w(pName));
-
- EnterCriticalSection(&This->csFilter);
- {
- if (pName)
- strcpyW(This->filterInfo.achName, pName);
- else
- *This->filterInfo.achName = '\0';
- This->filterInfo.pGraph = pGraph; /* NOTE: do NOT increase ref. count */
- }
- LeaveCriticalSection(&This->csFilter);
-
- return hr;
-}
-
-static HRESULT WINAPI AVIDec_QueryVendorInfo(IBaseFilter * iface, LPWSTR *pVendorInfo)
-{
- AVIDecImpl *This = (AVIDecImpl *)iface;
- TRACE("(%p/%p)->(%p)\n", This, iface, pVendorInfo);
- return E_NOTIMPL;
-}
-
-static const IBaseFilterVtbl AVIDec_Vtbl =
-{
- AVIDec_QueryInterface,
- AVIDec_AddRef,
- AVIDec_Release,
- AVIDec_GetClassID,
- AVIDec_Stop,
- AVIDec_Pause,
- AVIDec_Run,
- AVIDec_GetState,
- AVIDec_SetSyncSource,
- AVIDec_GetSyncSource,
- AVIDec_EnumPins,
- AVIDec_FindPin,
- AVIDec_QueryFilterInfo,
- AVIDec_JoinFilterGraph,
- AVIDec_QueryVendorInfo
-};
-
-static const IPinVtbl AVIDec_InputPin_Vtbl =
-{
- InputPin_QueryInterface,
- IPinImpl_AddRef,
- InputPin_Release,
- InputPin_Connect,
- InputPin_ReceiveConnection,
- IPinImpl_Disconnect,
- IPinImpl_ConnectedTo,
- IPinImpl_ConnectionMediaType,
- IPinImpl_QueryPinInfo,
- IPinImpl_QueryDirection,
- IPinImpl_QueryId,
- IPinImpl_QueryAccept,
- IPinImpl_EnumMediaTypes,
- IPinImpl_QueryInternalConnections,
- InputPin_EndOfStream,
- InputPin_BeginFlush,
- InputPin_EndFlush,
- InputPin_NewSegment
-};
-
-HRESULT WINAPI AVIDec_Output_EnumMediaTypes(IPin * iface, IEnumMediaTypes ** ppEnum)
-{
- IPinImpl *This = (IPinImpl *)iface;
- ENUMMEDIADETAILS emd;
-
- TRACE("(%p/%p)->(%p)\n", This, iface, ppEnum);
-
- emd.cMediaTypes = 1;
- emd.pMediaTypes = &This->mtCurrent;
-
- return IEnumMediaTypesImpl_Construct(&emd, ppEnum);
-}
+ if (FAILED(hr))
+ return hr;
-HRESULT WINAPI AVIDec_Output_Disconnect(IPin * iface)
-{
- OutputPin* This = (OutputPin*)iface;
- HRESULT hr;
- AVIDecImpl* pAVIDec = (AVIDecImpl*)This->pin.pinInfo.pFilter;
+ *ppv = (LPVOID)pAVIDec;
- TRACE("(%p/%p)->()\n", This, iface);
-
- hr = OutputPin_Disconnect(iface);
-
- if (hr == S_OK)
- {
- ICClose(pAVIDec->hvid);
- pAVIDec->hvid = 0;
- }
-
return hr;
}
-
-static const IPinVtbl AVIDec_OutputPin_Vtbl =
-{
- OutputPin_QueryInterface,
- IPinImpl_AddRef,
- OutputPin_Release,
- OutputPin_Connect,
- OutputPin_ReceiveConnection,
- AVIDec_Output_Disconnect,
- IPinImpl_ConnectedTo,
- IPinImpl_ConnectionMediaType,
- IPinImpl_QueryPinInfo,
- IPinImpl_QueryDirection,
- IPinImpl_QueryId,
- IPinImpl_QueryAccept,
- AVIDec_Output_EnumMediaTypes,
- IPinImpl_QueryInternalConnections,
- OutputPin_EndOfStream,
- OutputPin_BeginFlush,
- OutputPin_EndFlush,
- OutputPin_NewSegment
-};
-
-static const IMemInputPinVtbl MemInputPin_Vtbl =
-{
- MemInputPin_QueryInterface,
- MemInputPin_AddRef,
- MemInputPin_Release,
- MemInputPin_GetAllocator,
- MemInputPin_NotifyAllocator,
- MemInputPin_GetAllocatorRequirements,
- MemInputPin_Receive,
- MemInputPin_ReceiveMultiple,
- MemInputPin_ReceiveCanBlock
-};
--- /dev/null 1970-01-01 01:00:00.000000000 +0100
+++ dlls/quartz/transform.c 2005-01-30 12:30:28.000000000 +0000
@@ -0,0 +1,582 @@
+/*
+ * Transform Filter (Base for decoders, etc...)
+ *
+ * Copyright 2005 Christian Costa
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "config.h"
+
+#include "quartz_private.h"
+#include "control_private.h"
+#include "pin.h"
+
+#include "uuids.h"
+#include "aviriff.h"
+#include "mmreg.h"
+#include "vfwmsgs.h"
+#include "amvideo.h"
+#include "windef.h"
+#include "winbase.h"
+#include "dshow.h"
+#include "strmif.h"
+#include "vfwmsgs.h"
+#include "evcode.h"
+#include "vfw.h"
+
+#include <assert.h>
+
+#include "wine/unicode.h"
+#include "wine/debug.h"
+
+#include "transform.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(quartz);
+
+static const WCHAR wcsInputPinName[] = {'i','n','p','u','t',' ','p','i','n',0};
+static const WCHAR wcsOutputPinName[] = {'o','u','t','p','u','t',' ','p','i','n',0};
+
+static const IBaseFilterVtbl TransformFilter_Vtbl;
+static const IPinVtbl TransformFilter_InputPin_Vtbl;
+static const IMemInputPinVtbl MemInputPin_Vtbl;
+static const IPinVtbl TransformFilter_OutputPin_Vtbl;
+
+static HRESULT TransformFilter_Sample(LPVOID iface, IMediaSample * pSample)
+{
+ TransformFilterImpl *This = (TransformFilterImpl *)iface;
+ LPBYTE pbSrcStream = NULL;
+ long cbSrcStream = 0;
+ REFERENCE_TIME tStart, tStop;
+ HRESULT hr;
+
+ TRACE("%p %p\n", iface, pSample);
+
+ hr = IMediaSample_GetPointer(pSample, &pbSrcStream);
+ if (FAILED(hr))
+ {
+ ERR("Cannot get pointer to sample data (%lx)\n", hr);
+ return hr;
+ }
+
+ hr = IMediaSample_GetTime(pSample, &tStart, &tStop);
+ if (FAILED(hr))
+ ERR("Cannot get sample time (%lx)\n", hr);
+
+ cbSrcStream = IMediaSample_GetActualDataLength(pSample);
+
+ TRACE("Sample data ptr = %p, size = %ld\n", pbSrcStream, cbSrcStream);
+
+#if 0 /* For debugging purpose */
+ {
+ int i;
+ for(i = 0; i < cbSrcStream; i++)
+ {
+ if ((i!=0) && !(i%16))
+ DPRINTF("\n");
+ DPRINTF("%02x ", pbSrcStream[i]);
+ }
+ DPRINTF("\n");
+ }
+#endif
+
+ This->pfnProcessSample(This, pbSrcStream, cbSrcStream);
+
+ return S_OK;
+}
+
+static HRESULT TransformFilter_Input_QueryAccept(LPVOID iface, const AM_MEDIA_TYPE * pmt)
+{
+ TransformFilterImpl* This = (TransformFilterImpl*)iface;
+ TRACE("%p\n", iface);
+ dump_AM_MEDIA_TYPE(pmt);
+
+ return This->pfnConnectInput(This, pmt);
+}
+
+
+static HRESULT TransformFilter_Output_QueryAccept(LPVOID iface, const AM_MEDIA_TYPE * pmt)
+{
+ TransformFilterImpl* pTransformFilter = (TransformFilterImpl*)iface;
+ AM_MEDIA_TYPE* outpmt = &((OutputPin*)pTransformFilter->ppPins[1])->pin.mtCurrent;
+ TRACE("%p\n", iface);
+
+ if (IsEqualIID(&pmt->majortype, &outpmt->majortype) && IsEqualIID(&pmt->subtype, &outpmt->subtype))
+ return S_OK;
+ return S_FALSE;
+}
+
+static HRESULT TransformFilter_InputPin_Construct(const PIN_INFO * pPinInfo, SAMPLEPROC pSampleProc, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, LPCRITICAL_SECTION pCritSec, IPin ** ppPin)
+{
+ InputPin * pPinImpl;
+
+ *ppPin = NULL;
+
+ if (pPinInfo->dir != PINDIR_INPUT)
+ {
+ ERR("Pin direction(%x) != PINDIR_INPUT\n", pPinInfo->dir);
+ return E_INVALIDARG;
+ }
+
+ pPinImpl = CoTaskMemAlloc(sizeof(*pPinImpl));
+
+ if (!pPinImpl)
+ return E_OUTOFMEMORY;
+
+ if (SUCCEEDED(InputPin_Init(pPinInfo, pSampleProc, pUserData, pQueryAccept, pCritSec, pPinImpl)))
+ {
+ pPinImpl->pin.lpVtbl = &TransformFilter_InputPin_Vtbl;
+ pPinImpl->lpVtblMemInput = &MemInputPin_Vtbl;
+
+ *ppPin = (IPin *)(&pPinImpl->pin.lpVtbl);
+ return S_OK;
+ }
+ return E_FAIL;
+}
+
+HRESULT TransformFilter_OutputPin_Construct(const PIN_INFO * pPinInfo, ALLOCATOR_PROPERTIES *props, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, LPCRITICAL_SECTION pCritSec, IPin ** ppPin)
+{
+ OutputPin * pPinImpl;
+
+ *ppPin = NULL;
+
+ if (pPinInfo->dir != PINDIR_OUTPUT)
+ {
+ ERR("Pin direction(%x) != PINDIR_OUTPUT\n", pPinInfo->dir);
+ return E_INVALIDARG;
+ }
+
+ pPinImpl = CoTaskMemAlloc(sizeof(*pPinImpl));
+
+ if (!pPinImpl)
+ return E_OUTOFMEMORY;
+
+ if (SUCCEEDED(OutputPin_Init(pPinInfo, props, pUserData, pQueryAccept, pCritSec, pPinImpl)))
+ {
+ pPinImpl->pin.lpVtbl = &TransformFilter_OutputPin_Vtbl;
+
+ *ppPin = (IPin *)(&pPinImpl->pin.lpVtbl);
+ return S_OK;
+ }
+ return E_FAIL;
+}
+
+HRESULT TransformFilter_Create(TransformFilterImpl* pTransformFilter, const CLSID* pClsid, PFN_PROCESS_SAMPLE pps, PFN_CONNECT_INPUT pci, PFN_CLEANUP pcu)
+{
+ HRESULT hr;
+ PIN_INFO piInput;
+ PIN_INFO piOutput;
+
+ /* pTransformFilter is already allocated */
+ pTransformFilter->clsid = *pClsid;
+ pTransformFilter->pfnProcessSample = pps;
+ pTransformFilter->pfnConnectInput = pci;
+ pTransformFilter->pfnCleanup = pcu;
+
+ pTransformFilter->lpVtbl = &TransformFilter_Vtbl;
+
+ pTransformFilter->refCount = 1;
+ InitializeCriticalSection(&pTransformFilter->csFilter);
+ pTransformFilter->state = State_Stopped;
+ pTransformFilter->pClock = NULL;
+ ZeroMemory(&pTransformFilter->filterInfo, sizeof(FILTER_INFO));
+
+ pTransformFilter->ppPins = CoTaskMemAlloc(2 * sizeof(IPin *));
+
+ /* construct input pin */
+ piInput.dir = PINDIR_INPUT;
+ piInput.pFilter = (IBaseFilter *)pTransformFilter;
+ strncpyW(piInput.achName, wcsInputPinName, sizeof(piInput.achName) / sizeof(piInput.achName[0]));
+ piOutput.dir = PINDIR_OUTPUT;
+ piOutput.pFilter = (IBaseFilter *)pTransformFilter;
+ strncpyW(piOutput.achName, wcsOutputPinName, sizeof(piOutput.achName) / sizeof(piOutput.achName[0]));
+
+ hr = TransformFilter_InputPin_Construct(&piInput, TransformFilter_Sample, (LPVOID)pTransformFilter, TransformFilter_Input_QueryAccept, &pTransformFilter->csFilter, &pTransformFilter->ppPins[0]);
+
+ if (SUCCEEDED(hr))
+ {
+ ALLOCATOR_PROPERTIES props;
+ props.cbAlign = 1;
+ props.cbPrefix = 0;
+ props.cbBuffer = 0; /* Will be updated at connection time */
+ props.cBuffers = 2;
+
+ hr = TransformFilter_OutputPin_Construct(&piOutput, &props, NULL, TransformFilter_Output_QueryAccept, &pTransformFilter->csFilter, &pTransformFilter->ppPins[1]);
+
+ if (FAILED(hr))
+ ERR("Cannot create output pin (%lx)\n", hr);
+ }
+ else
+ {
+ CoTaskMemFree(pTransformFilter->ppPins);
+ DeleteCriticalSection(&pTransformFilter->csFilter);
+ CoTaskMemFree(pTransformFilter);
+ }
+
+ return hr;
+}
+
+static HRESULT WINAPI TransformFilter_QueryInterface(IBaseFilter * iface, REFIID riid, LPVOID * ppv)
+{
+ TransformFilterImpl *This = (TransformFilterImpl *)iface;
+ TRACE("(%p/%p)->(%s, %p)\n", This, iface, qzdebugstr_guid(riid), ppv);
+
+ *ppv = NULL;
+
+ if (IsEqualIID(riid, &IID_IUnknown))
+ *ppv = (LPVOID)This;
+ else if (IsEqualIID(riid, &IID_IPersist))
+ *ppv = (LPVOID)This;
+ else if (IsEqualIID(riid, &IID_IMediaFilter))
+ *ppv = (LPVOID)This;
+ else if (IsEqualIID(riid, &IID_IBaseFilter))
+ *ppv = (LPVOID)This;
+
+ if (*ppv)
+ {
+ IUnknown_AddRef((IUnknown *)(*ppv));
+ return S_OK;
+ }
+
+ FIXME("No interface for %s!\n", qzdebugstr_guid(riid));
+
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI TransformFilter_AddRef(IBaseFilter * iface)
+{
+ TransformFilterImpl *This = (TransformFilterImpl *)iface;
+ ULONG refCount = InterlockedIncrement(&This->refCount);
+
+ TRACE("(%p/%p)->() AddRef from %ld\n", This, iface, refCount - 1);
+
+ return refCount;
+}
+
+static ULONG WINAPI TransformFilter_Release(IBaseFilter * iface)
+{
+ TransformFilterImpl *This = (TransformFilterImpl *)iface;
+ ULONG refCount = InterlockedDecrement(&This->refCount);
+
+ TRACE("(%p/%p)->() Release from %ld\n", This, iface, refCount + 1);
+
+ if (!refCount)
+ {
+ ULONG i;
+
+ DeleteCriticalSection(&This->csFilter);
+ IReferenceClock_Release(This->pClock);
+
+ for (i = 0; i < 2; i++)
+ IPin_Release(This->ppPins[i]);
+
+ HeapFree(GetProcessHeap(), 0, This->ppPins);
+ This->lpVtbl = NULL;
+
+ This->pfnCleanup(This);
+
+ TRACE("Destroying transform filter\n");
+ CoTaskMemFree(This);
+
+ return 0;
+ }
+ else
+ return refCount;
+}
+
+/** IPersist methods **/
+
+static HRESULT WINAPI TransformFilter_GetClassID(IBaseFilter * iface, CLSID * pClsid)
+{
+ TransformFilterImpl *This = (TransformFilterImpl *)iface;
+
+ TRACE("(%p/%p)->(%p)\n", This, iface, pClsid);
+
+ *pClsid = This->clsid;
+
+ return S_OK;
+}
+
+/** IMediaFilter methods **/
+
+static HRESULT WINAPI TransformFilter_Stop(IBaseFilter * iface)
+{
+ TransformFilterImpl *This = (TransformFilterImpl *)iface;
+
+ TRACE("(%p/%p)\n", This, iface);
+
+ EnterCriticalSection(&This->csFilter);
+ {
+ This->state = State_Stopped;
+ }
+ LeaveCriticalSection(&This->csFilter);
+
+ return S_OK;
+}
+
+static HRESULT WINAPI TransformFilter_Pause(IBaseFilter * iface)
+{
+ TransformFilterImpl *This = (TransformFilterImpl *)iface;
+
+ TRACE("(%p/%p)->()\n", This, iface);
+
+ EnterCriticalSection(&This->csFilter);
+ {
+ This->state = State_Paused;
+ }
+ LeaveCriticalSection(&This->csFilter);
+
+ return S_OK;
+}
+
+static HRESULT WINAPI TransformFilter_Run(IBaseFilter * iface, REFERENCE_TIME tStart)
+{
+ HRESULT hr = S_OK;
+ TransformFilterImpl *This = (TransformFilterImpl *)iface;
+
+ TRACE("(%p/%p)->(%s)\n", This, iface, wine_dbgstr_longlong(tStart));
+
+ EnterCriticalSection(&This->csFilter);
+ {
+ This->rtStreamStart = tStart;
+ This->state = State_Running;
+ OutputPin_CommitAllocator((OutputPin *)This->ppPins[1]);
+ }
+ LeaveCriticalSection(&This->csFilter);
+
+ return hr;
+}
+
+static HRESULT WINAPI TransformFilter_GetState(IBaseFilter * iface, DWORD dwMilliSecsTimeout, FILTER_STATE *pState)
+{
+ TransformFilterImpl *This = (TransformFilterImpl *)iface;
+
+ TRACE("(%p/%p)->(%ld, %p)\n", This, iface, dwMilliSecsTimeout, pState);
+
+ EnterCriticalSection(&This->csFilter);
+ {
+ *pState = This->state;
+ }
+ LeaveCriticalSection(&This->csFilter);
+
+ return S_OK;
+}
+
+static HRESULT WINAPI TransformFilter_SetSyncSource(IBaseFilter * iface, IReferenceClock *pClock)
+{
+ TransformFilterImpl *This = (TransformFilterImpl *)iface;
+
+ TRACE("(%p/%p)->(%p)\n", This, iface, pClock);
+
+ EnterCriticalSection(&This->csFilter);
+ {
+ if (This->pClock)
+ IReferenceClock_Release(This->pClock);
+ This->pClock = pClock;
+ if (This->pClock)
+ IReferenceClock_AddRef(This->pClock);
+ }
+ LeaveCriticalSection(&This->csFilter);
+
+ return S_OK;
+}
+
+static HRESULT WINAPI TransformFilter_GetSyncSource(IBaseFilter * iface, IReferenceClock **ppClock)
+{
+ TransformFilterImpl *This = (TransformFilterImpl *)iface;
+
+ TRACE("(%p/%p)->(%p)\n", This, iface, ppClock);
+
+ EnterCriticalSection(&This->csFilter);
+ {
+ *ppClock = This->pClock;
+ IReferenceClock_AddRef(This->pClock);
+ }
+ LeaveCriticalSection(&This->csFilter);
+
+ return S_OK;
+}
+
+/** IBaseFilter implementation **/
+
+static HRESULT WINAPI TransformFilter_EnumPins(IBaseFilter * iface, IEnumPins **ppEnum)
+{
+ ENUMPINDETAILS epd;
+ TransformFilterImpl *This = (TransformFilterImpl *)iface;
+
+ TRACE("(%p/%p)->(%p)\n", This, iface, ppEnum);
+
+ epd.cPins = 2; /* input and output pins */
+ epd.ppPins = This->ppPins;
+ return IEnumPinsImpl_Construct(&epd, ppEnum);
+}
+
+static HRESULT WINAPI TransformFilter_FindPin(IBaseFilter * iface, LPCWSTR Id, IPin **ppPin)
+{
+ TransformFilterImpl *This = (TransformFilterImpl *)iface;
+
+ TRACE("(%p/%p)->(%p,%p)\n", This, iface, debugstr_w(Id), ppPin);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI TransformFilter_QueryFilterInfo(IBaseFilter * iface, FILTER_INFO *pInfo)
+{
+ TransformFilterImpl *This = (TransformFilterImpl *)iface;
+
+ TRACE("(%p/%p)->(%p)\n", This, iface, pInfo);
+
+ strcpyW(pInfo->achName, This->filterInfo.achName);
+ pInfo->pGraph = This->filterInfo.pGraph;
+
+ if (pInfo->pGraph)
+ IFilterGraph_AddRef(pInfo->pGraph);
+
+ return S_OK;
+}
+
+static HRESULT WINAPI TransformFilter_JoinFilterGraph(IBaseFilter * iface, IFilterGraph *pGraph, LPCWSTR pName)
+{
+ HRESULT hr = S_OK;
+ TransformFilterImpl *This = (TransformFilterImpl *)iface;
+
+ TRACE("(%p/%p)->(%p, %s)\n", This, iface, pGraph, debugstr_w(pName));
+
+ EnterCriticalSection(&This->csFilter);
+ {
+ if (pName)
+ strcpyW(This->filterInfo.achName, pName);
+ else
+ *This->filterInfo.achName = '\0';
+ This->filterInfo.pGraph = pGraph; /* NOTE: do NOT increase ref. count */
+ }
+ LeaveCriticalSection(&This->csFilter);
+
+ return hr;
+}
+
+static HRESULT WINAPI TransformFilter_QueryVendorInfo(IBaseFilter * iface, LPWSTR *pVendorInfo)
+{
+ TransformFilterImpl *This = (TransformFilterImpl *)iface;
+ TRACE("(%p/%p)->(%p)\n", This, iface, pVendorInfo);
+ return E_NOTIMPL;
+}
+
+static const IBaseFilterVtbl TransformFilter_Vtbl =
+{
+ TransformFilter_QueryInterface,
+ TransformFilter_AddRef,
+ TransformFilter_Release,
+ TransformFilter_GetClassID,
+ TransformFilter_Stop,
+ TransformFilter_Pause,
+ TransformFilter_Run,
+ TransformFilter_GetState,
+ TransformFilter_SetSyncSource,
+ TransformFilter_GetSyncSource,
+ TransformFilter_EnumPins,
+ TransformFilter_FindPin,
+ TransformFilter_QueryFilterInfo,
+ TransformFilter_JoinFilterGraph,
+ TransformFilter_QueryVendorInfo
+};
+
+static const IPinVtbl TransformFilter_InputPin_Vtbl =
+{
+ InputPin_QueryInterface,
+ IPinImpl_AddRef,
+ InputPin_Release,
+ InputPin_Connect,
+ InputPin_ReceiveConnection,
+ IPinImpl_Disconnect,
+ IPinImpl_ConnectedTo,
+ IPinImpl_ConnectionMediaType,
+ IPinImpl_QueryPinInfo,
+ IPinImpl_QueryDirection,
+ IPinImpl_QueryId,
+ IPinImpl_QueryAccept,
+ IPinImpl_EnumMediaTypes,
+ IPinImpl_QueryInternalConnections,
+ InputPin_EndOfStream,
+ InputPin_BeginFlush,
+ InputPin_EndFlush,
+ InputPin_NewSegment
+};
+
+HRESULT WINAPI TransformFilter_Output_EnumMediaTypes(IPin * iface, IEnumMediaTypes ** ppEnum)
+{
+ IPinImpl *This = (IPinImpl *)iface;
+ ENUMMEDIADETAILS emd;
+
+ TRACE("(%p/%p)->(%p)\n", This, iface, ppEnum);
+
+ emd.cMediaTypes = 1;
+ emd.pMediaTypes = &This->mtCurrent;
+
+ return IEnumMediaTypesImpl_Construct(&emd, ppEnum);
+}
+
+HRESULT WINAPI TransformFilter_Output_Disconnect(IPin * iface)
+{
+ OutputPin* This = (OutputPin*)iface;
+ HRESULT hr;
+ TransformFilterImpl* pTransformFilter = (TransformFilterImpl*)This->pin.pinInfo.pFilter;
+
+ TRACE("(%p/%p)->()\n", This, iface);
+
+ hr = OutputPin_Disconnect(iface);
+
+ if (hr == S_OK)
+ {
+ pTransformFilter->pfnCleanup(pTransformFilter);
+ }
+
+ return hr;
+}
+
+static const IPinVtbl TransformFilter_OutputPin_Vtbl =
+{
+ OutputPin_QueryInterface,
+ IPinImpl_AddRef,
+ OutputPin_Release,
+ OutputPin_Connect,
+ OutputPin_ReceiveConnection,
+ TransformFilter_Output_Disconnect,
+ IPinImpl_ConnectedTo,
+ IPinImpl_ConnectionMediaType,
+ IPinImpl_QueryPinInfo,
+ IPinImpl_QueryDirection,
+ IPinImpl_QueryId,
+ IPinImpl_QueryAccept,
+ TransformFilter_Output_EnumMediaTypes,
+ IPinImpl_QueryInternalConnections,
+ OutputPin_EndOfStream,
+ OutputPin_BeginFlush,
+ OutputPin_EndFlush,
+ OutputPin_NewSegment
+};
+
+static const IMemInputPinVtbl MemInputPin_Vtbl =
+{
+ MemInputPin_QueryInterface,
+ MemInputPin_AddRef,
+ MemInputPin_Release,
+ MemInputPin_GetAllocator,
+ MemInputPin_NotifyAllocator,
+ MemInputPin_GetAllocatorRequirements,
+ MemInputPin_Receive,
+ MemInputPin_ReceiveMultiple,
+ MemInputPin_ReceiveCanBlock
+};
--- /dev/null 1970-01-01 01:00:00.000000000 +0100
+++ dlls/quartz/transform.h 2005-01-30 12:26:02.000000000 +0000
@@ -0,0 +1,46 @@
+/*
+ * Transform Filter declarations
+ *
+ * Copyright 2005 Christian Costa
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+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);
+
+struct TransformFilterImpl
+{
+ const IBaseFilterVtbl * lpVtbl;
+
+ ULONG refCount;
+ CRITICAL_SECTION csFilter;
+ FILTER_STATE state;
+ REFERENCE_TIME rtStreamStart;
+ IReferenceClock * pClock;
+ FILTER_INFO filterInfo;
+ CLSID clsid;
+
+ IPin ** ppPins;
+
+ PFN_PROCESS_SAMPLE pfnProcessSample;
+ PFN_CONNECT_INPUT pfnConnectInput;
+ PFN_CLEANUP pfnCleanup;
+};
+
+HRESULT TransformFilter_Create(TransformFilterImpl*, const CLSID*, PFN_PROCESS_SAMPLE, PFN_CONNECT_INPUT, PFN_CLEANUP);
More information about the wine-patches
mailing list