diff --git a/dlls/quartz/pin.c b/dlls/quartz/pin.c index 2d63064860..00165e535c 100644 --- a/dlls/quartz/pin.c +++ b/dlls/quartz/pin.c @@ -142,11 +142,6 @@ out: return hr; } -static inline InputPin *impl_from_IMemInputPin( IMemInputPin *iface ) -{ - return (InputPin *)((char*)iface - FIELD_OFFSET(InputPin, lpVtblMemInput)); -} - static void Copy_PinInfo(PIN_INFO * pDest, const PIN_INFO * pSrc) { @@ -159,205 +154,6 @@ static void Copy_PinInfo(PIN_INFO * pDest, const PIN_INFO * pSrc) pDest->pFilter = pSrc->pFilter; } -/* Function called as a helper to IPin_Connect */ -/* specific AM_MEDIA_TYPE - it cannot be NULL */ -/* NOTE: not part of standard interface */ -static HRESULT OutputPin_ConnectSpecific(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt) -{ - OutputPin *This = (OutputPin *)iface; - HRESULT hr; - IMemAllocator * pMemAlloc = NULL; - ALLOCATOR_PROPERTIES actual; /* FIXME: should we put the actual props back in to This? */ - - TRACE("(%p, %p)\n", pReceivePin, pmt); - dump_AM_MEDIA_TYPE(pmt); - - /* FIXME: call queryacceptproc */ - - This->pin.pConnectedTo = pReceivePin; - IPin_AddRef(pReceivePin); - CopyMediaType(&This->pin.mtCurrent, pmt); - - hr = IPin_ReceiveConnection(pReceivePin, iface, pmt); - - /* get the IMemInputPin interface we will use to deliver samples to the - * connected pin */ - if (SUCCEEDED(hr)) - { - This->pMemInputPin = NULL; - hr = IPin_QueryInterface(pReceivePin, &IID_IMemInputPin, (LPVOID)&This->pMemInputPin); - - if (SUCCEEDED(hr) && !This->custom_allocator) - { - hr = IMemInputPin_GetAllocator(This->pMemInputPin, &pMemAlloc); - - if (hr == VFW_E_NO_ALLOCATOR) - /* Input pin provides no allocator, use standard memory allocator */ - hr = CoCreateInstance(&CLSID_MemoryAllocator, NULL, CLSCTX_INPROC_SERVER, &IID_IMemAllocator, (LPVOID*)&pMemAlloc); - - if (SUCCEEDED(hr)) - hr = IMemAllocator_SetProperties(pMemAlloc, &This->allocProps, &actual); - - if (SUCCEEDED(hr)) - hr = IMemInputPin_NotifyAllocator(This->pMemInputPin, pMemAlloc, This->readonly); - - if (pMemAlloc) - IMemAllocator_Release(pMemAlloc); - } - else if (SUCCEEDED(hr)) - { - if (This->alloc) - { - hr = IMemInputPin_NotifyAllocator(This->pMemInputPin, This->alloc, This->readonly); - } - else - hr = VFW_E_NO_ALLOCATOR; - } - - /* break connection if we couldn't get the allocator */ - if (FAILED(hr)) - { - if (This->pMemInputPin) - IMemInputPin_Release(This->pMemInputPin); - This->pMemInputPin = NULL; - - IPin_Disconnect(pReceivePin); - } - } - - if (FAILED(hr)) - { - IPin_Release(This->pin.pConnectedTo); - This->pin.pConnectedTo = NULL; - FreeMediaType(&This->pin.mtCurrent); - } - - TRACE(" -- %x\n", hr); - return hr; -} - -static HRESULT InputPin_Init(const IPinVtbl *InputPin_Vtbl, const PIN_INFO * pPinInfo, SAMPLEPROC_PUSH pSampleProc, LPVOID pUserData, - QUERYACCEPTPROC pQueryAccept, CLEANUPPROC pCleanUp, LPCRITICAL_SECTION pCritSec, IMemAllocator *allocator, InputPin * pPinImpl) -{ - TRACE("\n"); - - /* 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->fnCleanProc = pCleanUp; - pPinImpl->pAllocator = pPinImpl->preferred_allocator = allocator; - if (pPinImpl->preferred_allocator) - IMemAllocator_AddRef(pPinImpl->preferred_allocator); - pPinImpl->tStart = 0; - pPinImpl->tStop = 0; - pPinImpl->dRate = 1.0; - pPinImpl->pin.lpVtbl = InputPin_Vtbl; - pPinImpl->lpVtblMemInput = &MemInputPin_Vtbl; - pPinImpl->flushing = pPinImpl->end_of_stream = 0; - - return S_OK; -} - -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.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)); - - /* Output pin attributes */ - pPinImpl->pMemInputPin = NULL; - pPinImpl->pConnectSpecific = OutputPin_ConnectSpecific; - /* If custom_allocator is set, you will need to specify an allocator - * in the alloc member of the struct before an output pin can connect - */ - pPinImpl->custom_allocator = 0; - pPinImpl->alloc = NULL; - pPinImpl->readonly = FALSE; - if (props) - { - pPinImpl->allocProps = *props; - if (pPinImpl->allocProps.cbAlign == 0) - pPinImpl->allocProps.cbAlign = 1; - } - else - ZeroMemory(&pPinImpl->allocProps, sizeof(pPinImpl->allocProps)); - - return S_OK; -} - -HRESULT InputPin_Construct(const IPinVtbl *InputPin_Vtbl, const PIN_INFO * pPinInfo, SAMPLEPROC_PUSH pSampleProc, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, CLEANUPPROC pCleanUp, LPCRITICAL_SECTION pCritSec, IMemAllocator *allocator, 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, allocator, 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; - - *ppPin = NULL; - - if (pPinInfo->dir != PINDIR_OUTPUT) - { - ERR("Pin direction(%x) != PINDIR_OUTPUT\n", pPinInfo->dir); - return E_INVALIDARG; - } - - assert(outputpin_size >= sizeof(OutputPin)); - - pPinImpl = CoTaskMemAlloc(outputpin_size); - - if (!pPinImpl) - return E_OUTOFMEMORY; - - if (SUCCEEDED(OutputPin_Init(OutputPin_Vtbl, pPinInfo, props, pUserData, pQueryAccept, pCritSec, pPinImpl))) - { - *ppPin = (IPin *)(&pPinImpl->pin.lpVtbl); - return S_OK; - } - - CoTaskMemFree(pPinImpl); - return E_FAIL; -} - /*** Common pin functions ***/ ULONG WINAPI IPinImpl_AddRef(IPin * iface) @@ -735,6 +531,11 @@ static const IPinVtbl InputPin_Vtbl = /*** IMemInputPin implementation ***/ +static inline InputPin *impl_from_IMemInputPin( IMemInputPin *iface ) +{ + return (InputPin *)((char*)iface - FIELD_OFFSET(InputPin, lpVtblMemInput)); +} + HRESULT WINAPI MemInputPin_QueryInterface(IMemInputPin * iface, REFIID riid, LPVOID * ppv) { InputPin *This = impl_from_IMemInputPin(iface); @@ -858,6 +659,8 @@ static const IMemInputPinVtbl MemInputPin_Vtbl = MemInputPin_ReceiveCanBlock }; +/*** OutputPin implementation ***/ + HRESULT WINAPI OutputPin_QueryInterface(IPin * iface, REFIID riid, LPVOID * ppv) { OutputPin *This = (OutputPin *)iface; @@ -1260,6 +1063,7 @@ HRESULT OutputPin_DeliverDisconnect(OutputPin * This) return hr; } +/*** PullPin implementation ***/ static HRESULT PullPin_Init(const IPinVtbl *PullPin_Vtbl, const PIN_INFO * pPinInfo, SAMPLEPROC_PULL pSampleProc, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, CLEANUPPROC pCleanUp, REQUESTPROC pCustomRequest, STOPPROCESSPROC pDone, LPCRITICAL_SECTION pCritSec, PullPin * pPinImpl) @@ -1876,3 +1680,204 @@ static const IPinVtbl PullPin_Vtbl = PullPin_EndFlush, PullPin_NewSegment }; + +/*** The Construct functions ***/ + +/* Function called as a helper to IPin_Connect */ +/* specific AM_MEDIA_TYPE - it cannot be NULL */ +/* NOTE: not part of standard interface */ +static HRESULT OutputPin_ConnectSpecific(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt) +{ + OutputPin *This = (OutputPin *)iface; + HRESULT hr; + IMemAllocator * pMemAlloc = NULL; + ALLOCATOR_PROPERTIES actual; /* FIXME: should we put the actual props back in to This? */ + + TRACE("(%p, %p)\n", pReceivePin, pmt); + dump_AM_MEDIA_TYPE(pmt); + + /* FIXME: call queryacceptproc */ + + This->pin.pConnectedTo = pReceivePin; + IPin_AddRef(pReceivePin); + CopyMediaType(&This->pin.mtCurrent, pmt); + + hr = IPin_ReceiveConnection(pReceivePin, iface, pmt); + + /* get the IMemInputPin interface we will use to deliver samples to the + * connected pin */ + if (SUCCEEDED(hr)) + { + This->pMemInputPin = NULL; + hr = IPin_QueryInterface(pReceivePin, &IID_IMemInputPin, (LPVOID)&This->pMemInputPin); + + if (SUCCEEDED(hr) && !This->custom_allocator) + { + hr = IMemInputPin_GetAllocator(This->pMemInputPin, &pMemAlloc); + + if (hr == VFW_E_NO_ALLOCATOR) + /* Input pin provides no allocator, use standard memory allocator */ + hr = CoCreateInstance(&CLSID_MemoryAllocator, NULL, CLSCTX_INPROC_SERVER, &IID_IMemAllocator, (LPVOID*)&pMemAlloc); + + if (SUCCEEDED(hr)) + hr = IMemAllocator_SetProperties(pMemAlloc, &This->allocProps, &actual); + + if (SUCCEEDED(hr)) + hr = IMemInputPin_NotifyAllocator(This->pMemInputPin, pMemAlloc, This->readonly); + + if (pMemAlloc) + IMemAllocator_Release(pMemAlloc); + } + else if (SUCCEEDED(hr)) + { + if (This->alloc) + { + hr = IMemInputPin_NotifyAllocator(This->pMemInputPin, This->alloc, This->readonly); + } + else + hr = VFW_E_NO_ALLOCATOR; + } + + /* break connection if we couldn't get the allocator */ + if (FAILED(hr)) + { + if (This->pMemInputPin) + IMemInputPin_Release(This->pMemInputPin); + This->pMemInputPin = NULL; + + IPin_Disconnect(pReceivePin); + } + } + + if (FAILED(hr)) + { + IPin_Release(This->pin.pConnectedTo); + This->pin.pConnectedTo = NULL; + FreeMediaType(&This->pin.mtCurrent); + } + + TRACE(" -- %x\n", hr); + return hr; +} + +static HRESULT InputPin_Init(const IPinVtbl *InputPin_Vtbl, const PIN_INFO * pPinInfo, SAMPLEPROC_PUSH pSampleProc, LPVOID pUserData, + QUERYACCEPTPROC pQueryAccept, CLEANUPPROC pCleanUp, LPCRITICAL_SECTION pCritSec, IMemAllocator *allocator, InputPin * pPinImpl) +{ + TRACE("\n"); + + /* 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->fnCleanProc = pCleanUp; + pPinImpl->pAllocator = pPinImpl->preferred_allocator = allocator; + if (pPinImpl->preferred_allocator) + IMemAllocator_AddRef(pPinImpl->preferred_allocator); + pPinImpl->tStart = 0; + pPinImpl->tStop = 0; + pPinImpl->dRate = 1.0; + pPinImpl->pin.lpVtbl = InputPin_Vtbl; + pPinImpl->lpVtblMemInput = &MemInputPin_Vtbl; + pPinImpl->flushing = pPinImpl->end_of_stream = 0; + + return S_OK; +} + +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.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)); + + /* Output pin attributes */ + pPinImpl->pMemInputPin = NULL; + pPinImpl->pConnectSpecific = OutputPin_ConnectSpecific; + /* If custom_allocator is set, you will need to specify an allocator + * in the alloc member of the struct before an output pin can connect + */ + pPinImpl->custom_allocator = 0; + pPinImpl->alloc = NULL; + pPinImpl->readonly = FALSE; + if (props) + { + pPinImpl->allocProps = *props; + if (pPinImpl->allocProps.cbAlign == 0) + pPinImpl->allocProps.cbAlign = 1; + } + else + ZeroMemory(&pPinImpl->allocProps, sizeof(pPinImpl->allocProps)); + + return S_OK; +} + +HRESULT InputPin_Construct(const IPinVtbl *InputPin_Vtbl, const PIN_INFO * pPinInfo, SAMPLEPROC_PUSH pSampleProc, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, CLEANUPPROC pCleanUp, LPCRITICAL_SECTION pCritSec, IMemAllocator *allocator, 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, allocator, 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; + + *ppPin = NULL; + + if (pPinInfo->dir != PINDIR_OUTPUT) + { + ERR("Pin direction(%x) != PINDIR_OUTPUT\n", pPinInfo->dir); + return E_INVALIDARG; + } + + assert(outputpin_size >= sizeof(OutputPin)); + + pPinImpl = CoTaskMemAlloc(outputpin_size); + + if (!pPinImpl) + return E_OUTOFMEMORY; + + if (SUCCEEDED(OutputPin_Init(OutputPin_Vtbl, pPinInfo, props, pUserData, pQueryAccept, pCritSec, pPinImpl))) + { + *ppPin = (IPin *)(&pPinImpl->pin.lpVtbl); + return S_OK; + } + + CoTaskMemFree(pPinImpl); + return E_FAIL; +} diff --git a/dlls/quartz/pin.h b/dlls/quartz/pin.h index 3a9719cd22..df0f4fdd5b 100644 --- a/dlls/quartz/pin.h +++ b/dlls/quartz/pin.h @@ -189,19 +189,6 @@ HRESULT OutputPin_SendSample(OutputPin * This, IMediaSample * pSample); HRESULT OutputPin_DeliverDisconnect(OutputPin * This); HRESULT OutputPin_DeliverNewSegment(OutputPin * This, REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate); -/**********************************/ -/*** MemInputPin Implementation ***/ - -HRESULT WINAPI MemInputPin_QueryInterface(IMemInputPin * iface, REFIID riid, LPVOID * ppv); -ULONG WINAPI MemInputPin_AddRef(IMemInputPin * iface); -ULONG WINAPI MemInputPin_Release(IMemInputPin * iface); -HRESULT WINAPI MemInputPin_GetAllocator(IMemInputPin * iface, IMemAllocator ** ppAllocator); -HRESULT WINAPI MemInputPin_NotifyAllocator(IMemInputPin * iface, IMemAllocator * pAllocator, BOOL bReadOnly); -HRESULT WINAPI MemInputPin_GetAllocatorRequirements(IMemInputPin * iface, ALLOCATOR_PROPERTIES * pProps); -HRESULT WINAPI MemInputPin_Receive(IMemInputPin * iface, IMediaSample * pSample); -HRESULT WINAPI MemInputPin_ReceiveMultiple(IMemInputPin * iface, IMediaSample ** pSamples, long nSamples, long *nSamplesProcessed); -HRESULT WINAPI MemInputPin_ReceiveCanBlock(IMemInputPin * iface); - /* Pull Pin */ HRESULT WINAPI PullPin_ReceiveConnection(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt); HRESULT WINAPI PullPin_Disconnect(IPin * iface);