forked from Mirrors/wine-wine
quartz: Get rid of code duplication and add a flush method.
parent
7f7c1d0752
commit
fab66ee7a0
|
@ -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))
|
||||
{
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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))
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 ***/
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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))
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue