quartz: Get rid of code duplication and add a flush method.
This commit is contained in:
parent
7f7c1d0752
commit
fab66ee7a0
|
@ -96,38 +96,6 @@ static HRESULT sound_mod_rate(IBaseFilter *iface)
|
||||||
return S_OK;
|
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)
|
static inline HRESULT DSoundRender_GetPos(DSoundRenderImpl *This, DWORD *pPlayPos, DWORD *pWritePos, REFERENCE_TIME *pRefTime)
|
||||||
{
|
{
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
@ -324,7 +292,7 @@ HRESULT DSoundRender_create(IUnknown * pUnkOuter, LPVOID * ppv)
|
||||||
piInput.dir = PINDIR_INPUT;
|
piInput.dir = PINDIR_INPUT;
|
||||||
piInput.pFilter = (IBaseFilter *)pDSoundRender;
|
piInput.pFilter = (IBaseFilter *)pDSoundRender;
|
||||||
lstrcpynW(piInput.achName, wcsInputPinName, sizeof(piInput.achName) / sizeof(piInput.achName[0]));
|
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))
|
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)
|
static HRESULT FileAsyncReader_Construct(HANDLE hFile, IBaseFilter * pBaseFilter, LPCRITICAL_SECTION pCritSec, IPin ** ppPin)
|
||||||
{
|
{
|
||||||
FileAsyncReader * pPinImpl;
|
|
||||||
PIN_INFO piOutput;
|
PIN_INFO piOutput;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
*ppPin = NULL;
|
*ppPin = NULL;
|
||||||
|
|
||||||
pPinImpl = CoTaskMemAlloc(sizeof(*pPinImpl));
|
|
||||||
|
|
||||||
if (!pPinImpl)
|
|
||||||
return E_OUTOFMEMORY;
|
|
||||||
|
|
||||||
piOutput.dir = PINDIR_OUTPUT;
|
piOutput.dir = PINDIR_OUTPUT;
|
||||||
piOutput.pFilter = pBaseFilter;
|
piOutput.pFilter = pBaseFilter;
|
||||||
strcpyW(piOutput.achName, wszOutputPinName);
|
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->lpVtblAR = &FileAsyncReader_Vtbl;
|
||||||
pPinImpl->hFile = hFile;
|
pPinImpl->hFile = hFile;
|
||||||
pPinImpl->hEvent = CreateEventW(NULL, 0, 0, NULL);
|
pPinImpl->hEvent = CreateEventW(NULL, 0, 0, NULL);
|
||||||
|
@ -918,13 +913,8 @@ static HRESULT FileAsyncReader_Construct(HANDLE hFile, IBaseFilter * pBaseFilter
|
||||||
pPinImpl->pin.pConnectSpecific = FileAsyncReaderPin_ConnectSpecific;
|
pPinImpl->pin.pConnectSpecific = FileAsyncReaderPin_ConnectSpecific;
|
||||||
InitializeCriticalSection(&pPinImpl->csList);
|
InitializeCriticalSection(&pPinImpl->csList);
|
||||||
pPinImpl->csList.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": FileAsyncReader.csList");
|
pPinImpl->csList.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": FileAsyncReader.csList");
|
||||||
|
|
||||||
*ppPin = (IPin *)(&pPinImpl->pin.pin.lpVtbl);
|
|
||||||
return S_OK;
|
|
||||||
}
|
}
|
||||||
|
return hr;
|
||||||
CoTaskMemFree(pPinImpl);
|
|
||||||
return E_FAIL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* IAsyncReader */
|
/* IAsyncReader */
|
||||||
|
|
|
@ -60,7 +60,7 @@ typedef struct NullRendererImpl
|
||||||
IReferenceClock * pClock;
|
IReferenceClock * pClock;
|
||||||
FILTER_INFO filterInfo;
|
FILTER_INFO filterInfo;
|
||||||
|
|
||||||
InputPin * pInputPin;
|
InputPin *pInputPin;
|
||||||
IPin ** ppPins;
|
IPin ** ppPins;
|
||||||
IUnknown * pUnkOuter;
|
IUnknown * pUnkOuter;
|
||||||
BOOL bUnkOuterValid;
|
BOOL bUnkOuterValid;
|
||||||
|
@ -81,38 +81,6 @@ static const IMemInputPinVtbl MemInputPin_Vtbl =
|
||||||
MemInputPin_ReceiveCanBlock
|
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)
|
static HRESULT NullRenderer_Sample(LPVOID iface, IMediaSample * pSample)
|
||||||
{
|
{
|
||||||
LPBYTE pbSrcStream = NULL;
|
LPBYTE pbSrcStream = NULL;
|
||||||
|
@ -233,7 +201,7 @@ HRESULT NullRenderer_create(IUnknown * pUnkOuter, LPVOID * ppv)
|
||||||
piInput.pFilter = (IBaseFilter *)pNullRenderer;
|
piInput.pFilter = (IBaseFilter *)pNullRenderer;
|
||||||
lstrcpynW(piInput.achName, wcsInputPinName, sizeof(piInput.achName) / sizeof(piInput.achName[0]));
|
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))
|
if (SUCCEEDED(hr))
|
||||||
{
|
{
|
||||||
|
@ -594,6 +562,7 @@ static HRESULT WINAPI NullRenderer_InputPin_EndOfStream(IPin * iface)
|
||||||
|
|
||||||
TRACE("(%p/%p)->()\n", This, iface);
|
TRACE("(%p/%p)->()\n", This, iface);
|
||||||
|
|
||||||
|
InputPin_EndOfStream(iface);
|
||||||
hr = IFilterGraph_QueryInterface(((NullRendererImpl*)This->pin.pinInfo.pFilter)->filterInfo.pGraph, &IID_IMediaEventSink, (LPVOID*)&pEventSink);
|
hr = IFilterGraph_QueryInterface(((NullRendererImpl*)This->pin.pinInfo.pFilter)->filterInfo.pGraph, &IID_IMediaEventSink, (LPVOID*)&pEventSink);
|
||||||
if (SUCCEEDED(hr))
|
if (SUCCEEDED(hr))
|
||||||
{
|
{
|
||||||
|
|
|
@ -47,8 +47,6 @@ static HRESULT Parser_ChangeCurrent(IBaseFilter *iface);
|
||||||
static HRESULT Parser_ChangeStop(IBaseFilter *iface);
|
static HRESULT Parser_ChangeStop(IBaseFilter *iface);
|
||||||
static HRESULT Parser_ChangeRate(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 )
|
static inline ParserImpl *impl_from_IMediaSeeking( IMediaSeeking *iface )
|
||||||
{
|
{
|
||||||
return (ParserImpl *)((char*)iface - FIELD_OFFSET(ParserImpl, mediaSeeking.lpVtbl));
|
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);
|
MediaSeekingImpl_Init((IBaseFilter*)pParser, stop, current, rate, &pParser->mediaSeeking, &pParser->csFilter);
|
||||||
pParser->mediaSeeking.lpVtbl = &Parser_Seeking_Vtbl;
|
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))
|
if (SUCCEEDED(hr))
|
||||||
{
|
{
|
||||||
|
@ -110,40 +108,6 @@ HRESULT Parser_Create(ParserImpl* pParser, const CLSID* pClsid, PFN_PROCESS_SAMP
|
||||||
return hr;
|
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)
|
static HRESULT WINAPI Parser_QueryInterface(IBaseFilter * iface, REFIID riid, LPVOID * ppv)
|
||||||
{
|
{
|
||||||
ParserImpl *This = (ParserImpl *)iface;
|
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 *));
|
This->ppPins = CoTaskMemAlloc((This->cStreams + 2) * sizeof(IPin *));
|
||||||
memcpy(This->ppPins, ppOldPins, (This->cStreams + 1) * 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))
|
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++;
|
This->cStreams++;
|
||||||
CoTaskMemFree(ppOldPins);
|
CoTaskMemFree(ppOldPins);
|
||||||
}
|
}
|
||||||
|
@ -718,35 +688,6 @@ static const IPinVtbl Parser_OutputPin_Vtbl =
|
||||||
OutputPin_NewSegment
|
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)
|
static HRESULT WINAPI Parser_InputPin_Disconnect(IPin * iface)
|
||||||
{
|
{
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
|
@ -225,38 +225,8 @@ static HRESULT OutputPin_ConnectSpecific(IPin * iface, IPin * pReceivePin, const
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT InputPin_Construct(const PIN_INFO * pPinInfo, SAMPLEPROC pSampleProc, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, LPCRITICAL_SECTION pCritSec, IPin ** ppPin)
|
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)
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
TRACE("\n");
|
TRACE("\n");
|
||||||
|
|
||||||
|
@ -271,21 +241,24 @@ HRESULT InputPin_Init(const PIN_INFO * pPinInfo, SAMPLEPROC pSampleProc, LPVOID
|
||||||
|
|
||||||
/* Input pin attributes */
|
/* Input pin attributes */
|
||||||
pPinImpl->fnSampleProc = pSampleProc;
|
pPinImpl->fnSampleProc = pSampleProc;
|
||||||
|
pPinImpl->fnCleanProc = pCleanUp;
|
||||||
pPinImpl->pAllocator = NULL;
|
pPinImpl->pAllocator = NULL;
|
||||||
pPinImpl->tStart = 0;
|
pPinImpl->tStart = 0;
|
||||||
pPinImpl->tStop = 0;
|
pPinImpl->tStop = 0;
|
||||||
pPinImpl->dRate = 0;
|
pPinImpl->dRate = 0;
|
||||||
|
pPinImpl->pin.lpVtbl = InputPin_Vtbl;
|
||||||
|
pPinImpl->lpVtblMemInput = &MemInputPin_Vtbl;
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT OutputPin_Init(const PIN_INFO * pPinInfo, const ALLOCATOR_PROPERTIES * props, LPVOID pUserData,
|
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)
|
QUERYACCEPTPROC pQueryAccept, LPCRITICAL_SECTION pCritSec, OutputPin * pPinImpl)
|
||||||
{
|
{
|
||||||
TRACE("\n");
|
TRACE("\n");
|
||||||
|
|
||||||
/* Common attributes */
|
/* Common attributes */
|
||||||
pPinImpl->pin.lpVtbl = &OutputPin_Vtbl;
|
pPinImpl->pin.lpVtbl = OutputPin_Vtbl;
|
||||||
pPinImpl->pin.refCount = 1;
|
pPinImpl->pin.refCount = 1;
|
||||||
pPinImpl->pin.pConnectedTo = NULL;
|
pPinImpl->pin.pConnectedTo = NULL;
|
||||||
pPinImpl->pin.fnQueryAccept = pQueryAccept;
|
pPinImpl->pin.fnQueryAccept = pQueryAccept;
|
||||||
|
@ -309,7 +282,34 @@ HRESULT OutputPin_Init(const PIN_INFO * pPinInfo, const ALLOCATOR_PROPERTIES * p
|
||||||
return S_OK;
|
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;
|
OutputPin * pPinImpl;
|
||||||
|
|
||||||
|
@ -321,15 +321,15 @@ HRESULT OutputPin_Construct(const PIN_INFO * pPinInfo, ALLOCATOR_PROPERTIES *pro
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
pPinImpl = CoTaskMemAlloc(sizeof(*pPinImpl));
|
assert(outputpin_size >= sizeof(OutputPin));
|
||||||
|
|
||||||
|
pPinImpl = CoTaskMemAlloc(outputpin_size);
|
||||||
|
|
||||||
if (!pPinImpl)
|
if (!pPinImpl)
|
||||||
return E_OUTOFMEMORY;
|
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);
|
*ppPin = (IPin *)(&pPinImpl->pin.lpVtbl);
|
||||||
return S_OK;
|
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;
|
PullPin * pPinImpl;
|
||||||
|
|
||||||
|
@ -1166,10 +1196,8 @@ HRESULT PullPin_Construct(const PIN_INFO * pPinInfo, SAMPLEPROC pSampleProc, LPV
|
||||||
if (!pPinImpl)
|
if (!pPinImpl)
|
||||||
return E_OUTOFMEMORY;
|
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);
|
*ppPin = (IPin *)(&pPinImpl->pin.lpVtbl);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
@ -1178,33 +1206,6 @@ HRESULT PullPin_Construct(const PIN_INFO * pPinInfo, SAMPLEPROC pSampleProc, LPV
|
||||||
return E_FAIL;
|
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)
|
HRESULT WINAPI PullPin_ReceiveConnection(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt)
|
||||||
{
|
{
|
||||||
PIN_DIRECTION pindirReceive;
|
PIN_DIRECTION pindirReceive;
|
||||||
|
|
|
@ -35,6 +35,13 @@ typedef HRESULT (* QUERYACCEPTPROC)(LPVOID userdata, const AM_MEDIA_TYPE * pmt);
|
||||||
*/
|
*/
|
||||||
typedef HRESULT (* PRECONNECTPROC)(IPin * iface, IPin * pConnectPin);
|
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
|
typedef struct IPinImpl
|
||||||
{
|
{
|
||||||
const struct IPinVtbl * lpVtbl;
|
const struct IPinVtbl * lpVtbl;
|
||||||
|
@ -56,6 +63,7 @@ typedef struct InputPin
|
||||||
const IMemInputPinVtbl * lpVtblMemInput;
|
const IMemInputPinVtbl * lpVtblMemInput;
|
||||||
IMemAllocator * pAllocator;
|
IMemAllocator * pAllocator;
|
||||||
SAMPLEPROC fnSampleProc;
|
SAMPLEPROC fnSampleProc;
|
||||||
|
CLEANUPPROC fnCleanProc;
|
||||||
REFERENCE_TIME tStart;
|
REFERENCE_TIME tStart;
|
||||||
REFERENCE_TIME tStop;
|
REFERENCE_TIME tStop;
|
||||||
double dRate;
|
double dRate;
|
||||||
|
@ -82,24 +90,19 @@ typedef struct PullPin
|
||||||
PRECONNECTPROC fnPreConnect;
|
PRECONNECTPROC fnPreConnect;
|
||||||
HANDLE hThread;
|
HANDLE hThread;
|
||||||
HANDLE hEventStateChanged;
|
HANDLE hEventStateChanged;
|
||||||
|
CLEANUPPROC fnCleanProc;
|
||||||
REFERENCE_TIME rtStart;
|
REFERENCE_TIME rtStart;
|
||||||
REFERENCE_TIME rtStop;
|
REFERENCE_TIME rtStop;
|
||||||
REFERENCE_TIME rtCurrent;
|
REFERENCE_TIME rtCurrent;
|
||||||
|
double dRate;
|
||||||
FILTER_STATE state;
|
FILTER_STATE state;
|
||||||
BOOL stop_playback;
|
BOOL stop_playback;
|
||||||
double dRate;
|
|
||||||
} PullPin;
|
} 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 ***/
|
/*** Constructors ***/
|
||||||
HRESULT InputPin_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 PIN_INFO * pPinInfo, ALLOCATOR_PROPERTIES *props, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, 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 PIN_INFO * pPinInfo, SAMPLEPROC pSampleProc, 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 ***/
|
/*** Pin Implementation ***/
|
||||||
|
|
|
@ -82,67 +82,6 @@ static HRESULT TransformFilter_Output_QueryAccept(LPVOID iface, const AM_MEDIA_T
|
||||||
return S_FALSE;
|
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 )
|
static inline TransformFilterImpl *impl_from_IMediaSeeking( IMediaSeeking *iface )
|
||||||
{
|
{
|
||||||
|
@ -241,7 +180,7 @@ HRESULT TransformFilter_Create(TransformFilterImpl* pTransformFilter, const CLSI
|
||||||
piOutput.pFilter = (IBaseFilter *)pTransformFilter;
|
piOutput.pFilter = (IBaseFilter *)pTransformFilter;
|
||||||
lstrcpynW(piOutput.achName, wcsOutputPinName, sizeof(piOutput.achName) / sizeof(piOutput.achName[0]));
|
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))
|
if (SUCCEEDED(hr))
|
||||||
{
|
{
|
||||||
|
@ -251,7 +190,7 @@ HRESULT TransformFilter_Create(TransformFilterImpl* pTransformFilter, const CLSI
|
||||||
props.cbBuffer = 0; /* Will be updated at connection time */
|
props.cbBuffer = 0; /* Will be updated at connection time */
|
||||||
props.cBuffers = 2;
|
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))
|
if (FAILED(hr))
|
||||||
ERR("Cannot create output pin (%x)\n", hr);
|
ERR("Cannot create output pin (%x)\n", hr);
|
||||||
|
|
|
@ -261,36 +261,6 @@ static const IMemInputPinVtbl MemInputPin_Vtbl =
|
||||||
MemInputPin_ReceiveCanBlock
|
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)
|
static DWORD VideoRenderer_SendSampleData(VideoRendererImpl* This, LPBYTE data, DWORD size)
|
||||||
{
|
{
|
||||||
VIDEOINFOHEADER* format;
|
VIDEOINFOHEADER* format;
|
||||||
|
@ -467,7 +437,7 @@ HRESULT VideoRenderer_create(IUnknown * pUnkOuter, LPVOID * ppv)
|
||||||
piInput.pFilter = (IBaseFilter *)pVideoRenderer;
|
piInput.pFilter = (IBaseFilter *)pVideoRenderer;
|
||||||
lstrcpynW(piInput.achName, wcsInputPinName, sizeof(piInput.achName) / sizeof(piInput.achName[0]));
|
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))
|
if (SUCCEEDED(hr))
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue