quartz: Get rid of code duplication and add a flush method.

oldstable
Maarten Lankhorst 2008-04-04 14:29:21 -07:00 committed by Alexandre Julliard
parent 7f7c1d0752
commit fab66ee7a0
8 changed files with 106 additions and 325 deletions

View File

@ -96,38 +96,6 @@ static HRESULT sound_mod_rate(IBaseFilter *iface)
return S_OK;
}
static HRESULT DSoundRender_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 = &DSoundRender_InputPin_Vtbl;
pPinImpl->lpVtblMemInput = &MemInputPin_Vtbl;
*ppPin = (IPin *)(&pPinImpl->pin.lpVtbl);
return S_OK;
}
CoTaskMemFree(pPinImpl);
return E_FAIL;
}
static inline HRESULT DSoundRender_GetPos(DSoundRenderImpl *This, DWORD *pPlayPos, DWORD *pWritePos, REFERENCE_TIME *pRefTime)
{
HRESULT hr;
@ -324,7 +292,7 @@ HRESULT DSoundRender_create(IUnknown * pUnkOuter, LPVOID * ppv)
piInput.dir = PINDIR_INPUT;
piInput.pFilter = (IBaseFilter *)pDSoundRender;
lstrcpynW(piInput.achName, wcsInputPinName, sizeof(piInput.achName) / sizeof(piInput.achName[0]));
hr = DSoundRender_InputPin_Construct(&piInput, DSoundRender_Sample, (LPVOID)pDSoundRender, DSoundRender_QueryAccept, &pDSoundRender->csFilter, (IPin **)&pDSoundRender->pInputPin);
hr = InputPin_Construct(&DSoundRender_InputPin_Vtbl, &piInput, DSoundRender_Sample, pDSoundRender, DSoundRender_QueryAccept, NULL, &pDSoundRender->csFilter, (IPin **)&pDSoundRender->pInputPin);
if (SUCCEEDED(hr))
{

View File

@ -893,23 +893,18 @@ static HRESULT FileAsyncReaderPin_ConnectSpecific(IPin * iface, IPin * pReceiveP
static HRESULT FileAsyncReader_Construct(HANDLE hFile, IBaseFilter * pBaseFilter, LPCRITICAL_SECTION pCritSec, IPin ** ppPin)
{
FileAsyncReader * pPinImpl;
PIN_INFO piOutput;
HRESULT hr;
*ppPin = NULL;
pPinImpl = CoTaskMemAlloc(sizeof(*pPinImpl));
if (!pPinImpl)
return E_OUTOFMEMORY;
piOutput.dir = PINDIR_OUTPUT;
piOutput.pFilter = pBaseFilter;
strcpyW(piOutput.achName, wszOutputPinName);
hr = OutputPin_Construct(&FileAsyncReaderPin_Vtbl, sizeof(FileAsyncReader), &piOutput, NULL, pBaseFilter, AcceptProcAFR, pCritSec, ppPin);
if (SUCCEEDED(OutputPin_Init(&piOutput, NULL, pBaseFilter, AcceptProcAFR, pCritSec, &pPinImpl->pin)))
if (SUCCEEDED(hr))
{
pPinImpl->pin.pin.lpVtbl = &FileAsyncReaderPin_Vtbl;
FileAsyncReader *pPinImpl = (FileAsyncReader *)*ppPin;
pPinImpl->lpVtblAR = &FileAsyncReader_Vtbl;
pPinImpl->hFile = hFile;
pPinImpl->hEvent = CreateEventW(NULL, 0, 0, NULL);
@ -918,13 +913,8 @@ static HRESULT FileAsyncReader_Construct(HANDLE hFile, IBaseFilter * pBaseFilter
pPinImpl->pin.pConnectSpecific = FileAsyncReaderPin_ConnectSpecific;
InitializeCriticalSection(&pPinImpl->csList);
pPinImpl->csList.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": FileAsyncReader.csList");
*ppPin = (IPin *)(&pPinImpl->pin.pin.lpVtbl);
return S_OK;
}
CoTaskMemFree(pPinImpl);
return E_FAIL;
return hr;
}
/* IAsyncReader */

View File

@ -60,7 +60,7 @@ typedef struct NullRendererImpl
IReferenceClock * pClock;
FILTER_INFO filterInfo;
InputPin * pInputPin;
InputPin *pInputPin;
IPin ** ppPins;
IUnknown * pUnkOuter;
BOOL bUnkOuterValid;
@ -81,38 +81,6 @@ static const IMemInputPinVtbl MemInputPin_Vtbl =
MemInputPin_ReceiveCanBlock
};
static HRESULT NullRenderer_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 = &NullRenderer_InputPin_Vtbl;
pPinImpl->lpVtblMemInput = &MemInputPin_Vtbl;
*ppPin = (IPin *)(&pPinImpl->pin.lpVtbl);
return S_OK;
}
CoTaskMemFree(pPinImpl);
return E_FAIL;
}
static HRESULT NullRenderer_Sample(LPVOID iface, IMediaSample * pSample)
{
LPBYTE pbSrcStream = NULL;
@ -233,7 +201,7 @@ HRESULT NullRenderer_create(IUnknown * pUnkOuter, LPVOID * ppv)
piInput.pFilter = (IBaseFilter *)pNullRenderer;
lstrcpynW(piInput.achName, wcsInputPinName, sizeof(piInput.achName) / sizeof(piInput.achName[0]));
hr = NullRenderer_InputPin_Construct(&piInput, NullRenderer_Sample, (LPVOID)pNullRenderer, NullRenderer_QueryAccept, &pNullRenderer->csFilter, (IPin **)&pNullRenderer->pInputPin);
hr = InputPin_Construct(&NullRenderer_InputPin_Vtbl, &piInput, NullRenderer_Sample, (LPVOID)pNullRenderer, NullRenderer_QueryAccept, NULL, &pNullRenderer->csFilter, (IPin **)&pNullRenderer->pInputPin);
if (SUCCEEDED(hr))
{
@ -594,6 +562,7 @@ static HRESULT WINAPI NullRenderer_InputPin_EndOfStream(IPin * iface)
TRACE("(%p/%p)->()\n", This, iface);
InputPin_EndOfStream(iface);
hr = IFilterGraph_QueryInterface(((NullRendererImpl*)This->pin.pinInfo.pFilter)->filterInfo.pGraph, &IID_IMediaEventSink, (LPVOID*)&pEventSink);
if (SUCCEEDED(hr))
{

View File

@ -47,8 +47,6 @@ static HRESULT Parser_ChangeCurrent(IBaseFilter *iface);
static HRESULT Parser_ChangeStop(IBaseFilter *iface);
static HRESULT Parser_ChangeRate(IBaseFilter *iface);
static HRESULT Parser_InputPin_Construct(const PIN_INFO * pPinInfo, SAMPLEPROC pSampleProc, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, LPCRITICAL_SECTION pCritSec, IPin ** ppPin);
static inline ParserImpl *impl_from_IMediaSeeking( IMediaSeeking *iface )
{
return (ParserImpl *)((char*)iface - FIELD_OFFSET(ParserImpl, mediaSeeking.lpVtbl));
@ -92,7 +90,7 @@ HRESULT Parser_Create(ParserImpl* pParser, const CLSID* pClsid, PFN_PROCESS_SAMP
MediaSeekingImpl_Init((IBaseFilter*)pParser, stop, current, rate, &pParser->mediaSeeking, &pParser->csFilter);
pParser->mediaSeeking.lpVtbl = &Parser_Seeking_Vtbl;
hr = Parser_InputPin_Construct(&piInput, fnProcessSample, (LPVOID)pParser, fnQueryAccept, &pParser->csFilter, (IPin **)&pParser->pInputPin);
hr = PullPin_Construct(&Parser_InputPin_Vtbl, &piInput, fnProcessSample, (LPVOID)pParser, fnQueryAccept, fnCleanup, &pParser->csFilter, (IPin **)&pParser->pInputPin);
if (SUCCEEDED(hr))
{
@ -110,40 +108,6 @@ HRESULT Parser_Create(ParserImpl* pParser, const CLSID* pClsid, PFN_PROCESS_SAMP
return hr;
}
static HRESULT Parser_OutputPin_Init(const PIN_INFO * pPinInfo, ALLOCATOR_PROPERTIES * props, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, const AM_MEDIA_TYPE * pmt, LPCRITICAL_SECTION pCritSec, Parser_OutputPin * pPinImpl)
{
pPinImpl->pmt = CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE));
CopyMediaType(pPinImpl->pmt, pmt);
pPinImpl->dwSamplesProcessed = 0;
return OutputPin_Init(pPinInfo, props, pUserData, pQueryAccept, pCritSec, &pPinImpl->pin);
}
static HRESULT Parser_OutputPin_Construct(const PIN_INFO * pPinInfo, ALLOCATOR_PROPERTIES * props, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, const AM_MEDIA_TYPE * pmt, LPCRITICAL_SECTION pCritSec, IPin ** ppPin)
{
Parser_OutputPin * pPinImpl;
*ppPin = NULL;
assert(pPinInfo->dir == PINDIR_OUTPUT);
pPinImpl = CoTaskMemAlloc(sizeof(Parser_OutputPin));
if (!pPinImpl)
return E_OUTOFMEMORY;
if (SUCCEEDED(Parser_OutputPin_Init(pPinInfo, props, pUserData, pQueryAccept, pmt, pCritSec, pPinImpl)))
{
pPinImpl->pin.pin.lpVtbl = &Parser_OutputPin_Vtbl;
*ppPin = (IPin *)pPinImpl;
return S_OK;
}
CoTaskMemFree(pPinImpl);
return E_FAIL;
}
static HRESULT WINAPI Parser_QueryInterface(IBaseFilter * iface, REFIID riid, LPVOID * ppv)
{
ParserImpl *This = (ParserImpl *)iface;
@ -521,11 +485,17 @@ HRESULT Parser_AddPin(ParserImpl * This, const PIN_INFO * piOutput, ALLOCATOR_PR
This->ppPins = CoTaskMemAlloc((This->cStreams + 2) * sizeof(IPin *));
memcpy(This->ppPins, ppOldPins, (This->cStreams + 1) * sizeof(IPin *));
hr = Parser_OutputPin_Construct(piOutput, props, NULL, Parser_OutputPin_QueryAccept, amt, &This->csFilter, This->ppPins + This->cStreams + 1);
hr = OutputPin_Construct(&Parser_OutputPin_Vtbl, sizeof(Parser_OutputPin), piOutput, props, NULL, Parser_OutputPin_QueryAccept, &This->csFilter, This->ppPins + This->cStreams + 1);
if (SUCCEEDED(hr))
{
((Parser_OutputPin *)(This->ppPins[This->cStreams + 1]))->pin.pin.pUserData = (LPVOID)This->ppPins[This->cStreams + 1];
IPin *pPin = This->ppPins[This->cStreams + 1];
Parser_OutputPin *pin = (Parser_OutputPin *)pPin;
pin->pmt = CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE));
CopyMediaType(pin->pmt, amt);
pin->dwSamplesProcessed = 0;
pin->pin.pin.pUserData = (LPVOID)This->ppPins[This->cStreams + 1];
This->cStreams++;
CoTaskMemFree(ppOldPins);
}
@ -718,35 +688,6 @@ static const IPinVtbl Parser_OutputPin_Vtbl =
OutputPin_NewSegment
};
static HRESULT Parser_InputPin_Construct(const PIN_INFO * pPinInfo, SAMPLEPROC pSampleProc, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, LPCRITICAL_SECTION pCritSec, IPin ** ppPin)
{
PullPin * 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(PullPin_Init(pPinInfo, pSampleProc, pUserData, pQueryAccept, pCritSec, pPinImpl)))
{
pPinImpl->pin.lpVtbl = &Parser_InputPin_Vtbl;
*ppPin = (IPin *)(&pPinImpl->pin.lpVtbl);
return S_OK;
}
CoTaskMemFree(pPinImpl);
return E_FAIL;
}
static HRESULT WINAPI Parser_InputPin_Disconnect(IPin * iface)
{
HRESULT hr;

View File

@ -225,38 +225,8 @@ static HRESULT OutputPin_ConnectSpecific(IPin * iface, IPin * pReceivePin, const
return hr;
}
HRESULT 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 = &InputPin_Vtbl;
pPinImpl->lpVtblMemInput = &MemInputPin_Vtbl;
*ppPin = (IPin *)(&pPinImpl->pin.lpVtbl);
return S_OK;
}
CoTaskMemFree(pPinImpl);
return E_FAIL;
}
/* Note that we don't init the vtables here (like C++ constructor) */
HRESULT InputPin_Init(const PIN_INFO * pPinInfo, SAMPLEPROC pSampleProc, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, LPCRITICAL_SECTION pCritSec, InputPin * pPinImpl)
static HRESULT InputPin_Init(const IPinVtbl *InputPin_Vtbl, const PIN_INFO * pPinInfo, SAMPLEPROC pSampleProc, LPVOID pUserData,
QUERYACCEPTPROC pQueryAccept, CLEANUPPROC pCleanUp, LPCRITICAL_SECTION pCritSec, InputPin * pPinImpl)
{
TRACE("\n");
@ -271,21 +241,24 @@ HRESULT InputPin_Init(const PIN_INFO * pPinInfo, SAMPLEPROC pSampleProc, LPVOID
/* Input pin attributes */
pPinImpl->fnSampleProc = pSampleProc;
pPinImpl->fnCleanProc = pCleanUp;
pPinImpl->pAllocator = NULL;
pPinImpl->tStart = 0;
pPinImpl->tStop = 0;
pPinImpl->dRate = 0;
pPinImpl->pin.lpVtbl = InputPin_Vtbl;
pPinImpl->lpVtblMemInput = &MemInputPin_Vtbl;
return S_OK;
}
HRESULT OutputPin_Init(const PIN_INFO * pPinInfo, const ALLOCATOR_PROPERTIES * props, LPVOID pUserData,
QUERYACCEPTPROC pQueryAccept, LPCRITICAL_SECTION pCritSec, OutputPin * pPinImpl)
static HRESULT OutputPin_Init(const IPinVtbl *OutputPin_Vtbl, const PIN_INFO * pPinInfo, const ALLOCATOR_PROPERTIES * props, LPVOID pUserData,
QUERYACCEPTPROC pQueryAccept, LPCRITICAL_SECTION pCritSec, OutputPin * pPinImpl)
{
TRACE("\n");
/* Common attributes */
pPinImpl->pin.lpVtbl = &OutputPin_Vtbl;
pPinImpl->pin.lpVtbl = OutputPin_Vtbl;
pPinImpl->pin.refCount = 1;
pPinImpl->pin.pConnectedTo = NULL;
pPinImpl->pin.fnQueryAccept = pQueryAccept;
@ -309,7 +282,34 @@ HRESULT OutputPin_Init(const PIN_INFO * pPinInfo, const ALLOCATOR_PROPERTIES * p
return S_OK;
}
HRESULT OutputPin_Construct(const PIN_INFO * pPinInfo, ALLOCATOR_PROPERTIES *props, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, LPCRITICAL_SECTION pCritSec, IPin ** ppPin)
HRESULT InputPin_Construct(const IPinVtbl *InputPin_Vtbl, const PIN_INFO * pPinInfo, SAMPLEPROC pSampleProc, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, CLEANUPPROC pCleanUp, 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(InputPin_Vtbl, pPinInfo, pSampleProc, pUserData, pQueryAccept, pCleanUp, pCritSec, pPinImpl)))
{
*ppPin = (IPin *)pPinImpl;
return S_OK;
}
CoTaskMemFree(pPinImpl);
return E_FAIL;
}
HRESULT OutputPin_Construct(const IPinVtbl *OutputPin_Vtbl, long outputpin_size, const PIN_INFO * pPinInfo, ALLOCATOR_PROPERTIES *props, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, LPCRITICAL_SECTION pCritSec, IPin ** ppPin)
{
OutputPin * pPinImpl;
@ -321,15 +321,15 @@ HRESULT OutputPin_Construct(const PIN_INFO * pPinInfo, ALLOCATOR_PROPERTIES *pro
return E_INVALIDARG;
}
pPinImpl = CoTaskMemAlloc(sizeof(*pPinImpl));
assert(outputpin_size >= sizeof(OutputPin));
pPinImpl = CoTaskMemAlloc(outputpin_size);
if (!pPinImpl)
return E_OUTOFMEMORY;
if (SUCCEEDED(OutputPin_Init(pPinInfo, props, pUserData, pQueryAccept, pCritSec, pPinImpl)))
if (SUCCEEDED(OutputPin_Init(OutputPin_Vtbl, pPinInfo, props, pUserData, pQueryAccept, pCritSec, pPinImpl)))
{
pPinImpl->pin.lpVtbl = &OutputPin_Vtbl;
*ppPin = (IPin *)(&pPinImpl->pin.lpVtbl);
return S_OK;
}
@ -1149,7 +1149,37 @@ HRESULT OutputPin_DeliverDisconnect(OutputPin * This)
}
HRESULT PullPin_Construct(const PIN_INFO * pPinInfo, SAMPLEPROC pSampleProc, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, LPCRITICAL_SECTION pCritSec, IPin ** ppPin)
static HRESULT PullPin_Init(const IPinVtbl *PullPin_Vtbl, const PIN_INFO * pPinInfo, SAMPLEPROC pSampleProc, LPVOID pUserData,
QUERYACCEPTPROC pQueryAccept, CLEANUPPROC pCleanUp, LPCRITICAL_SECTION pCritSec, PullPin * pPinImpl)
{
/* Common attributes */
pPinImpl->pin.lpVtbl = PullPin_Vtbl;
pPinImpl->pin.refCount = 1;
pPinImpl->pin.pConnectedTo = NULL;
pPinImpl->pin.fnQueryAccept = pQueryAccept;
pPinImpl->pin.pUserData = pUserData;
pPinImpl->pin.pCritSec = pCritSec;
Copy_PinInfo(&pPinImpl->pin.pinInfo, pPinInfo);
ZeroMemory(&pPinImpl->pin.mtCurrent, sizeof(AM_MEDIA_TYPE));
/* Input pin attributes */
pPinImpl->fnSampleProc = pSampleProc;
pPinImpl->fnCleanProc = pCleanUp;
pPinImpl->fnPreConnect = NULL;
pPinImpl->pAlloc = NULL;
pPinImpl->pReader = NULL;
pPinImpl->hThread = NULL;
pPinImpl->hEventStateChanged = CreateEventW(NULL, TRUE, TRUE, NULL);
pPinImpl->rtStart = 0;
pPinImpl->rtCurrent = 0;
pPinImpl->rtStop = ((LONGLONG)0x7fffffff << 32) | 0xffffffff;
pPinImpl->state = State_Stopped;
return S_OK;
}
HRESULT PullPin_Construct(const IPinVtbl *PullPin_Vtbl, const PIN_INFO * pPinInfo, SAMPLEPROC pSampleProc, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, CLEANUPPROC pCleanUp, LPCRITICAL_SECTION pCritSec, IPin ** ppPin)
{
PullPin * pPinImpl;
@ -1166,10 +1196,8 @@ HRESULT PullPin_Construct(const PIN_INFO * pPinInfo, SAMPLEPROC pSampleProc, LPV
if (!pPinImpl)
return E_OUTOFMEMORY;
if (SUCCEEDED(PullPin_Init(pPinInfo, pSampleProc, pUserData, pQueryAccept, pCritSec, pPinImpl)))
if (SUCCEEDED(PullPin_Init(PullPin_Vtbl, pPinInfo, pSampleProc, pUserData, pQueryAccept, pCleanUp, pCritSec, pPinImpl)))
{
pPinImpl->pin.lpVtbl = &PullPin_Vtbl;
*ppPin = (IPin *)(&pPinImpl->pin.lpVtbl);
return S_OK;
}
@ -1178,33 +1206,6 @@ HRESULT PullPin_Construct(const PIN_INFO * pPinInfo, SAMPLEPROC pSampleProc, LPV
return E_FAIL;
}
HRESULT PullPin_Init(const PIN_INFO * pPinInfo, SAMPLEPROC pSampleProc, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, LPCRITICAL_SECTION pCritSec, PullPin * pPinImpl)
{
/* Common attributes */
pPinImpl->pin.refCount = 1;
pPinImpl->pin.pConnectedTo = NULL;
pPinImpl->pin.fnQueryAccept = pQueryAccept;
pPinImpl->pin.pUserData = pUserData;
pPinImpl->pin.pCritSec = pCritSec;
Copy_PinInfo(&pPinImpl->pin.pinInfo, pPinInfo);
ZeroMemory(&pPinImpl->pin.mtCurrent, sizeof(AM_MEDIA_TYPE));
/* Input pin attributes */
pPinImpl->fnSampleProc = pSampleProc;
pPinImpl->fnPreConnect = NULL;
pPinImpl->pAlloc = NULL;
pPinImpl->pReader = NULL;
pPinImpl->hThread = NULL;
pPinImpl->hEventStateChanged = CreateEventW(NULL, TRUE, TRUE, NULL);
pPinImpl->rtStart = 0;
pPinImpl->rtCurrent = 0;
pPinImpl->rtStop = ((LONGLONG)0x7fffffff << 32) | 0xffffffff;
pPinImpl->state = State_Stopped;
return S_OK;
}
HRESULT WINAPI PullPin_ReceiveConnection(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt)
{
PIN_DIRECTION pindirReceive;

View File

@ -35,6 +35,13 @@ typedef HRESULT (* QUERYACCEPTPROC)(LPVOID userdata, const AM_MEDIA_TYPE * pmt);
*/
typedef HRESULT (* PRECONNECTPROC)(IPin * iface, IPin * pConnectPin);
/* This function is called whenever a cleanup operation has to occur,
* this is usually after a flush, seek, or end of stream notification.
* This code may even be repeated multiple times, so build your code to
* tolerate this behavior. Return value is ignored and should be S_OK.
*/
typedef HRESULT (* CLEANUPPROC) (LPVOID userdata);
typedef struct IPinImpl
{
const struct IPinVtbl * lpVtbl;
@ -56,6 +63,7 @@ typedef struct InputPin
const IMemInputPinVtbl * lpVtblMemInput;
IMemAllocator * pAllocator;
SAMPLEPROC fnSampleProc;
CLEANUPPROC fnCleanProc;
REFERENCE_TIME tStart;
REFERENCE_TIME tStop;
double dRate;
@ -82,24 +90,19 @@ typedef struct PullPin
PRECONNECTPROC fnPreConnect;
HANDLE hThread;
HANDLE hEventStateChanged;
CLEANUPPROC fnCleanProc;
REFERENCE_TIME rtStart;
REFERENCE_TIME rtStop;
REFERENCE_TIME rtCurrent;
double dRate;
FILTER_STATE state;
BOOL stop_playback;
double dRate;
} PullPin;
/*** Initializers ***/
HRESULT InputPin_Init(const PIN_INFO * pPinInfo, SAMPLEPROC pSampleProc, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, LPCRITICAL_SECTION pCritSec, InputPin * pPinImpl);
HRESULT OutputPin_Init(const PIN_INFO * pPinInfo, const ALLOCATOR_PROPERTIES *props, LPVOID pUserData,
QUERYACCEPTPROC pQueryAccept, LPCRITICAL_SECTION pCritSec, OutputPin * pPinImpl);
HRESULT PullPin_Init(const PIN_INFO * pPinInfo, SAMPLEPROC pSampleProc, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, LPCRITICAL_SECTION pCritSec, PullPin * pPinImpl);
/*** Constructors ***/
HRESULT InputPin_Construct(const PIN_INFO * pPinInfo, SAMPLEPROC pSampleProc, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, LPCRITICAL_SECTION pCritSec, IPin ** ppPin);
HRESULT OutputPin_Construct(const PIN_INFO * pPinInfo, ALLOCATOR_PROPERTIES *props, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, LPCRITICAL_SECTION pCritSec, IPin ** ppPin);
HRESULT PullPin_Construct(const PIN_INFO * pPinInfo, SAMPLEPROC pSampleProc, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, LPCRITICAL_SECTION pCritSec, IPin ** ppPin);
HRESULT InputPin_Construct(const IPinVtbl *InputPin_Vtbl, const PIN_INFO * pPinInfo, SAMPLEPROC pSampleProc, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, CLEANUPPROC pCleanUp, LPCRITICAL_SECTION pCritSec, IPin ** ppPin);
HRESULT OutputPin_Construct(const IPinVtbl *OutputPin_Vtbl, long outputpin_size, const PIN_INFO * pPinInfo, ALLOCATOR_PROPERTIES *props, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, LPCRITICAL_SECTION pCritSec, IPin ** ppPin);
HRESULT PullPin_Construct(const IPinVtbl *PullPin_Vtbl, const PIN_INFO * pPinInfo, SAMPLEPROC pSampleProc, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, CLEANUPPROC pCleanUp, LPCRITICAL_SECTION pCritSec, IPin ** ppPin);
/**************************/
/*** Pin Implementation ***/

View File

@ -82,67 +82,6 @@ static HRESULT TransformFilter_Output_QueryAccept(LPVOID iface, const AM_MEDIA_T
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;
}
CoTaskMemFree(pPinImpl);
return E_FAIL;
}
static HRESULT TransformFilter_OutputPin_Construct(const PIN_INFO * pPinInfo, const 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;
}
CoTaskMemFree(pPinImpl);
return E_FAIL;
}
static inline TransformFilterImpl *impl_from_IMediaSeeking( IMediaSeeking *iface )
{
@ -241,7 +180,7 @@ HRESULT TransformFilter_Create(TransformFilterImpl* pTransformFilter, const CLSI
piOutput.pFilter = (IBaseFilter *)pTransformFilter;
lstrcpynW(piOutput.achName, wcsOutputPinName, sizeof(piOutput.achName) / sizeof(piOutput.achName[0]));
hr = TransformFilter_InputPin_Construct(&piInput, TransformFilter_Sample, pTransformFilter, TransformFilter_Input_QueryAccept, &pTransformFilter->csFilter, &pTransformFilter->ppPins[0]);
hr = InputPin_Construct(&TransformFilter_InputPin_Vtbl, &piInput, TransformFilter_Sample, pTransformFilter, TransformFilter_Input_QueryAccept, NULL, &pTransformFilter->csFilter, &pTransformFilter->ppPins[0]);
if (SUCCEEDED(hr))
{
@ -251,7 +190,7 @@ HRESULT TransformFilter_Create(TransformFilterImpl* pTransformFilter, const CLSI
props.cbBuffer = 0; /* Will be updated at connection time */
props.cBuffers = 2;
hr = TransformFilter_OutputPin_Construct(&piOutput, &props, pTransformFilter, TransformFilter_Output_QueryAccept, &pTransformFilter->csFilter, &pTransformFilter->ppPins[1]);
hr = OutputPin_Construct(&TransformFilter_OutputPin_Vtbl, sizeof(OutputPin), &piOutput, &props, pTransformFilter, TransformFilter_Output_QueryAccept, &pTransformFilter->csFilter, &pTransformFilter->ppPins[1]);
if (FAILED(hr))
ERR("Cannot create output pin (%x)\n", hr);

View File

@ -261,36 +261,6 @@ static const IMemInputPinVtbl MemInputPin_Vtbl =
MemInputPin_ReceiveCanBlock
};
static HRESULT VideoRenderer_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 = &VideoRenderer_InputPin_Vtbl;
pPinImpl->lpVtblMemInput = &MemInputPin_Vtbl;
*ppPin = (IPin *)(&pPinImpl->pin.lpVtbl);
return S_OK;
}
CoTaskMemFree(pPinImpl);
return E_FAIL;
}
static DWORD VideoRenderer_SendSampleData(VideoRendererImpl* This, LPBYTE data, DWORD size)
{
VIDEOINFOHEADER* format;
@ -467,7 +437,7 @@ HRESULT VideoRenderer_create(IUnknown * pUnkOuter, LPVOID * ppv)
piInput.pFilter = (IBaseFilter *)pVideoRenderer;
lstrcpynW(piInput.achName, wcsInputPinName, sizeof(piInput.achName) / sizeof(piInput.achName[0]));
hr = VideoRenderer_InputPin_Construct(&piInput, VideoRenderer_Sample, (LPVOID)pVideoRenderer, VideoRenderer_QueryAccept, &pVideoRenderer->csFilter, (IPin **)&pVideoRenderer->pInputPin);
hr = InputPin_Construct(&VideoRenderer_InputPin_Vtbl, &piInput, VideoRenderer_Sample, (LPVOID)pVideoRenderer, VideoRenderer_QueryAccept, NULL, &pVideoRenderer->csFilter, (IPin **)&pVideoRenderer->pInputPin);
if (SUCCEEDED(hr))
{