Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/quartz/Makefile.in | 2 - dlls/quartz/acmwrapper.c | 1 - dlls/quartz/avidec.c | 1 - dlls/quartz/dsoundrender.c | 1 - dlls/quartz/filesource.c | 1 - dlls/quartz/parser.c | 709 ------------------------------ dlls/quartz/parser.h | 77 ---- dlls/quartz/pin.c | 818 ----------------------------------- dlls/quartz/pin.h | 133 ------ dlls/quartz/quartz_private.h | 12 +- dlls/quartz/videorenderer.c | 1 - dlls/quartz/vmr9.c | 1 - 12 files changed, 1 insertion(+), 1756 deletions(-) delete mode 100644 dlls/quartz/parser.c delete mode 100644 dlls/quartz/parser.h delete mode 100644 dlls/quartz/pin.c delete mode 100644 dlls/quartz/pin.h
diff --git a/dlls/quartz/Makefile.in b/dlls/quartz/Makefile.in index e33c4e58b99..fd2397668d0 100644 --- a/dlls/quartz/Makefile.in +++ b/dlls/quartz/Makefile.in @@ -16,8 +16,6 @@ C_SRCS = \ filtermapper.c \ main.c \ memallocator.c \ - parser.c \ - pin.c \ regsvr.c \ systemclock.c \ videorenderer.c \ diff --git a/dlls/quartz/acmwrapper.c b/dlls/quartz/acmwrapper.c index c6ff1d7c113..d1e4803fac7 100644 --- a/dlls/quartz/acmwrapper.c +++ b/dlls/quartz/acmwrapper.c @@ -19,7 +19,6 @@ */
#include "quartz_private.h" -#include "pin.h"
#include "uuids.h" #include "mmreg.h" diff --git a/dlls/quartz/avidec.c b/dlls/quartz/avidec.c index cd92b646977..ce38b6963ce 100644 --- a/dlls/quartz/avidec.c +++ b/dlls/quartz/avidec.c @@ -19,7 +19,6 @@ */
#include "quartz_private.h" -#include "pin.h"
#include "uuids.h" #include "amvideo.h" diff --git a/dlls/quartz/dsoundrender.c b/dlls/quartz/dsoundrender.c index 29b6492adb9..dbb5b523fa8 100644 --- a/dlls/quartz/dsoundrender.c +++ b/dlls/quartz/dsoundrender.c @@ -19,7 +19,6 @@ */
#include "quartz_private.h" -#include "pin.h"
#include "uuids.h" #include "vfwmsgs.h" diff --git a/dlls/quartz/filesource.c b/dlls/quartz/filesource.c index cbd54b60ccb..21f93ff7d7f 100644 --- a/dlls/quartz/filesource.c +++ b/dlls/quartz/filesource.c @@ -24,7 +24,6 @@ #include "quartz_private.h"
#include "wine/debug.h" -#include "pin.h" #include "uuids.h" #include "vfwmsgs.h" #include "winbase.h" diff --git a/dlls/quartz/parser.c b/dlls/quartz/parser.c deleted file mode 100644 index e4e6036aff7..00000000000 --- a/dlls/quartz/parser.c +++ /dev/null @@ -1,709 +0,0 @@ -/* - * Parser (Base for parsers and splitters) - * - * Copyright 2003 Robert Shearman - * Copyright 2004-2005 Christian Costa - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include "quartz_private.h" -#include "pin.h" - -#include "vfwmsgs.h" -#include "amvideo.h" - -#include "wine/debug.h" - -#include <math.h> -#include <assert.h> - -#include "parser.h" - -WINE_DEFAULT_DEBUG_CHANNEL(quartz); - -static const IMediaSeekingVtbl Parser_Seeking_Vtbl; -static const IPinVtbl Parser_OutputPin_Vtbl; -static const IPinVtbl Parser_InputPin_Vtbl; - -static HRESULT WINAPI Parser_ChangeStart(IMediaSeeking *iface); -static HRESULT WINAPI Parser_ChangeStop(IMediaSeeking *iface); -static HRESULT WINAPI Parser_ChangeRate(IMediaSeeking *iface); -static HRESULT WINAPI Parser_OutputPin_DecideBufferSize(struct strmbase_source *iface, - IMemAllocator *allocator, ALLOCATOR_PROPERTIES *props); -static HRESULT WINAPI Parser_OutputPin_CheckMediaType(BasePin *pin, const AM_MEDIA_TYPE *pmt); -static HRESULT WINAPI Parser_OutputPin_GetMediaType(BasePin *iface, int iPosition, AM_MEDIA_TYPE *pmt); -static HRESULT WINAPI Parser_OutputPin_DecideAllocator(struct strmbase_source *iface, - IMemInputPin *peer, IMemAllocator **allocator); - -static inline ParserImpl *impl_from_IMediaSeeking( IMediaSeeking *iface ) -{ - return CONTAINING_RECORD(iface, ParserImpl, sourceSeeking.IMediaSeeking_iface); -} - -static inline ParserImpl *impl_from_IBaseFilter( IBaseFilter *iface ) -{ - return CONTAINING_RECORD(iface, ParserImpl, filter.IBaseFilter_iface); -} - -static inline ParserImpl *impl_from_strmbase_filter(struct strmbase_filter *iface) -{ - return CONTAINING_RECORD(iface, ParserImpl, filter); -} - -IPin *parser_get_pin(struct strmbase_filter *iface, unsigned int index) -{ - ParserImpl *filter = impl_from_strmbase_filter(iface); - - if (!index) - return &filter->pInputPin->pin.IPin_iface; - else if (index <= filter->cStreams) - return &filter->sources[index - 1]->pin.pin.IPin_iface; - return NULL; -} - -HRESULT Parser_Create(ParserImpl *pParser, const IBaseFilterVtbl *vtbl, IUnknown *outer, - const CLSID *clsid, const struct strmbase_filter_ops *func_table, const WCHAR *sink_name, - PFN_PROCESS_SAMPLE fnProcessSample, PFN_QUERY_ACCEPT fnQueryAccept, PFN_PRE_CONNECT fnPreConnect, - PFN_CLEANUP fnCleanup, PFN_DISCONNECT fnDisconnect, REQUESTPROC fnRequest, - STOPPROCESSPROC fnDone, SourceSeeking_ChangeStop stop, - SourceSeeking_ChangeStart start, SourceSeeking_ChangeRate rate) -{ - HRESULT hr; - - strmbase_filter_init(&pParser->filter, vtbl, outer, clsid, func_table); - - pParser->fnDisconnect = fnDisconnect; - - pParser->cStreams = 0; - pParser->sources = CoTaskMemAlloc(0 * sizeof(IPin *)); - - if (!start) - start = Parser_ChangeStart; - - if (!stop) - stop = Parser_ChangeStop; - - if (!rate) - rate = Parser_ChangeRate; - - SourceSeeking_Init(&pParser->sourceSeeking, &Parser_Seeking_Vtbl, stop, start, rate, &pParser->filter.csFilter); - - hr = PullPin_Construct(&Parser_InputPin_Vtbl, &pParser->filter, sink_name, - fnProcessSample, (void *)pParser, fnQueryAccept, fnCleanup, fnRequest, - fnDone, (IPin **)&pParser->pInputPin); - - if (SUCCEEDED(hr)) - { - pParser->pInputPin->fnPreConnect = fnPreConnect; - } - else - { - CoTaskMemFree(pParser->sources); - strmbase_filter_cleanup(&pParser->filter); - CoTaskMemFree(pParser); - } - - return hr; -} - -HRESULT WINAPI Parser_QueryInterface(IBaseFilter * iface, REFIID riid, LPVOID * ppv) -{ - ParserImpl *This = impl_from_IBaseFilter(iface); - TRACE("(%s, %p)\n", qzdebugstr_guid(riid), ppv); - - *ppv = NULL; - - if ( IsEqualIID(riid, &IID_IUnknown) - || IsEqualIID(riid, &IID_IPersist) - || IsEqualIID(riid, &IID_IMediaFilter) - || IsEqualIID(riid, &IID_IBaseFilter) ) - *ppv = &This->filter.IBaseFilter_iface; - - if (*ppv) - { - IUnknown_AddRef((IUnknown *)*ppv); - return S_OK; - } - - if (!IsEqualIID(riid, &IID_IPin) && !IsEqualIID(riid, &IID_IVideoWindow)) - FIXME("No interface for %s!\n", qzdebugstr_guid(riid)); - - return E_NOINTERFACE; -} - -ULONG WINAPI Parser_AddRef(IBaseFilter * iface) -{ - return BaseFilterImpl_AddRef(iface); -} - -void Parser_Destroy(ParserImpl *This) -{ - IPin *connected = NULL; - HRESULT hr; - - PullPin_WaitForStateChange(This->pInputPin, INFINITE); - - /* Don't need to clean up output pins, freeing input pin will do that */ - IPin_ConnectedTo(&This->pInputPin->pin.IPin_iface, &connected); - if (connected) - { - hr = IPin_Disconnect(connected); - assert(hr == S_OK); - IPin_Release(connected); - hr = IPin_Disconnect(&This->pInputPin->pin.IPin_iface); - assert(hr == S_OK); - } - - PullPin_destroy(This->pInputPin); - - CoTaskMemFree(This->sources); - strmbase_filter_cleanup(&This->filter); - - TRACE("Destroying parser\n"); - CoTaskMemFree(This); -} - -/** IMediaFilter methods **/ - -HRESULT WINAPI Parser_Stop(IBaseFilter * iface) -{ - ParserImpl *This = impl_from_IBaseFilter(iface); - PullPin *pin = This->pInputPin; - ULONG i; - - TRACE("%p->()\n", This); - - EnterCriticalSection(&pin->thread_lock); - - IAsyncReader_BeginFlush(This->pInputPin->pReader); - EnterCriticalSection(&This->filter.csFilter); - - if (This->filter.state == State_Stopped) - { - LeaveCriticalSection(&This->filter.csFilter); - IAsyncReader_EndFlush(This->pInputPin->pReader); - LeaveCriticalSection(&pin->thread_lock); - return S_OK; - } - - This->filter.state = State_Stopped; - - for (i = 0; i < This->cStreams; ++i) - { - BaseOutputPinImpl_Inactive(&This->sources[i]->pin); - } - - LeaveCriticalSection(&This->filter.csFilter); - - PullPin_PauseProcessing(This->pInputPin); - PullPin_WaitForStateChange(This->pInputPin, INFINITE); - IAsyncReader_EndFlush(This->pInputPin->pReader); - - LeaveCriticalSection(&pin->thread_lock); - return S_OK; -} - -HRESULT WINAPI Parser_Pause(IBaseFilter * iface) -{ - HRESULT hr = S_OK; - ParserImpl *This = impl_from_IBaseFilter(iface); - PullPin *pin = This->pInputPin; - - TRACE("%p->()\n", This); - - EnterCriticalSection(&pin->thread_lock); - EnterCriticalSection(&This->filter.csFilter); - - if (This->filter.state == State_Paused) - { - LeaveCriticalSection(&This->filter.csFilter); - LeaveCriticalSection(&pin->thread_lock); - return S_OK; - } - - if (This->filter.state == State_Stopped) - { - LeaveCriticalSection(&This->filter.csFilter); - hr = IBaseFilter_Run(iface, -1); - EnterCriticalSection(&This->filter.csFilter); - } - - if (SUCCEEDED(hr)) - This->filter.state = State_Paused; - - LeaveCriticalSection(&This->filter.csFilter); - LeaveCriticalSection(&pin->thread_lock); - - return hr; -} - -HRESULT WINAPI Parser_Run(IBaseFilter * iface, REFERENCE_TIME tStart) -{ - HRESULT hr = S_OK; - ParserImpl *This = impl_from_IBaseFilter(iface); - PullPin *pin = This->pInputPin; - - ULONG i; - - TRACE("%p->(%s)\n", This, wine_dbgstr_longlong(tStart)); - - EnterCriticalSection(&pin->thread_lock); - EnterCriticalSection(&This->filter.csFilter); - { - HRESULT hr_any = VFW_E_NOT_CONNECTED; - - This->filter.rtStreamStart = tStart; - if (This->filter.state == State_Running || This->filter.state == State_Paused) - { - This->filter.state = State_Running; - LeaveCriticalSection(&This->filter.csFilter); - LeaveCriticalSection(&pin->thread_lock); - return S_OK; - } - - for (i = 0; i < This->cStreams; ++i) - { - hr = BaseOutputPinImpl_Active(&This->sources[i]->pin); - if (SUCCEEDED(hr)) - hr_any = hr; - } - - hr = hr_any; - if (SUCCEEDED(hr)) - { - LeaveCriticalSection(&This->filter.csFilter); - hr = PullPin_StartProcessing(This->pInputPin); - EnterCriticalSection(&This->filter.csFilter); - } - - if (SUCCEEDED(hr)) - This->filter.state = State_Running; - } - LeaveCriticalSection(&This->filter.csFilter); - LeaveCriticalSection(&pin->thread_lock); - - return hr; -} - -HRESULT WINAPI Parser_GetState(IBaseFilter * iface, DWORD dwMilliSecsTimeout, FILTER_STATE *pState) -{ - ParserImpl *This = impl_from_IBaseFilter(iface); - PullPin *pin = This->pInputPin; - HRESULT hr = S_OK; - - TRACE("%p->(%d, %p)\n", This, dwMilliSecsTimeout, pState); - - EnterCriticalSection(&pin->thread_lock); - EnterCriticalSection(&This->filter.csFilter); - { - *pState = This->filter.state; - } - LeaveCriticalSection(&This->filter.csFilter); - - if (This->pInputPin && (PullPin_WaitForStateChange(This->pInputPin, dwMilliSecsTimeout) == S_FALSE)) - hr = VFW_S_STATE_INTERMEDIATE; - LeaveCriticalSection(&pin->thread_lock); - - return hr; -} - -HRESULT WINAPI Parser_SetSyncSource(IBaseFilter * iface, IReferenceClock *pClock) -{ - ParserImpl *This = impl_from_IBaseFilter(iface); - PullPin *pin = This->pInputPin; - - TRACE("%p->(%p)\n", This, pClock); - - EnterCriticalSection(&pin->thread_lock); - BaseFilterImpl_SetSyncSource(iface,pClock); - LeaveCriticalSection(&pin->thread_lock); - - return S_OK; -} - -static const struct strmbase_source_ops source_ops = -{ - { - Parser_OutputPin_CheckMediaType, - Parser_OutputPin_GetMediaType - }, - BaseOutputPinImpl_AttemptConnection, - Parser_OutputPin_DecideBufferSize, - Parser_OutputPin_DecideAllocator, -}; - -HRESULT Parser_AddPin(ParserImpl *filter, const WCHAR *name, - ALLOCATOR_PROPERTIES *props, const AM_MEDIA_TYPE *mt) -{ - Parser_OutputPin **old_sources; - Parser_OutputPin *object; - - if (!(object = CoTaskMemAlloc(sizeof(*object)))) - return E_OUTOFMEMORY; - - old_sources = filter->sources; - - filter->sources = CoTaskMemAlloc((filter->cStreams + 1) * sizeof(filter->sources[0])); - memcpy(filter->sources, old_sources, filter->cStreams * sizeof(filter->sources[0])); - filter->sources[filter->cStreams] = object; - - strmbase_source_init(&object->pin, &Parser_OutputPin_Vtbl, &filter->filter, - name, &source_ops); - - object->pmt = CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE)); - CopyMediaType(object->pmt, mt); - object->dwSamplesProcessed = 0; - object->allocProps = *props; - filter->cStreams++; - BaseFilterImpl_IncrementPinVersion(&filter->filter); - CoTaskMemFree(old_sources); - - return S_OK; -} - -static void free_source_pin(Parser_OutputPin *pin) -{ - if (pin->pin.pin.pConnectedTo) - { - IPin_Disconnect(pin->pin.pin.pConnectedTo); - IPin_Disconnect(&pin->pin.pin.IPin_iface); - } - - FreeMediaType(pin->pmt); - CoTaskMemFree(pin->pmt); - strmbase_source_cleanup(&pin->pin); - CoTaskMemFree(pin); -} - -static HRESULT Parser_RemoveOutputPins(ParserImpl * This) -{ - /* NOTE: should be in critical section when calling this function */ - ULONG i; - Parser_OutputPin **old_sources = This->sources; - - TRACE("(%p)\n", This); - - This->sources = CoTaskMemAlloc(0); - - for (i = 0; i < This->cStreams; i++) - free_source_pin(old_sources[i]); - - BaseFilterImpl_IncrementPinVersion(&This->filter); - This->cStreams = 0; - CoTaskMemFree(old_sources); - - return S_OK; -} - -static HRESULT WINAPI Parser_ChangeStart(IMediaSeeking *iface) -{ - FIXME("(%p) filter hasn't implemented start position change!\n", iface); - return S_OK; -} - -static HRESULT WINAPI Parser_ChangeStop(IMediaSeeking *iface) -{ - FIXME("(%p) filter hasn't implemented stop position change!\n", iface); - return S_OK; -} - -static HRESULT WINAPI Parser_ChangeRate(IMediaSeeking *iface) -{ - FIXME("(%p) filter hasn't implemented rate change!\n", iface); - return S_OK; -} - - -static HRESULT WINAPI Parser_Seeking_QueryInterface(IMediaSeeking * iface, REFIID riid, LPVOID * ppv) -{ - ParserImpl *This = impl_from_IMediaSeeking(iface); - - return IBaseFilter_QueryInterface(&This->filter.IBaseFilter_iface, riid, ppv); -} - -static ULONG WINAPI Parser_Seeking_AddRef(IMediaSeeking * iface) -{ - ParserImpl *This = impl_from_IMediaSeeking(iface); - - return IBaseFilter_AddRef(&This->filter.IBaseFilter_iface); -} - -static ULONG WINAPI Parser_Seeking_Release(IMediaSeeking * iface) -{ - ParserImpl *This = impl_from_IMediaSeeking(iface); - - return IBaseFilter_Release(&This->filter.IBaseFilter_iface); -} - -static const IMediaSeekingVtbl Parser_Seeking_Vtbl = -{ - Parser_Seeking_QueryInterface, - Parser_Seeking_AddRef, - Parser_Seeking_Release, - SourceSeekingImpl_GetCapabilities, - SourceSeekingImpl_CheckCapabilities, - SourceSeekingImpl_IsFormatSupported, - SourceSeekingImpl_QueryPreferredFormat, - SourceSeekingImpl_GetTimeFormat, - SourceSeekingImpl_IsUsingTimeFormat, - SourceSeekingImpl_SetTimeFormat, - SourceSeekingImpl_GetDuration, - SourceSeekingImpl_GetStopPosition, - SourceSeekingImpl_GetCurrentPosition, - SourceSeekingImpl_ConvertTimeFormat, - SourceSeekingImpl_SetPositions, - SourceSeekingImpl_GetPositions, - SourceSeekingImpl_GetAvailable, - SourceSeekingImpl_SetRate, - SourceSeekingImpl_GetRate, - SourceSeekingImpl_GetPreroll -}; - -static HRESULT WINAPI Parser_OutputPin_DecideBufferSize(struct strmbase_source *iface, - IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES *ppropInputRequest) -{ - Parser_OutputPin *This = (Parser_OutputPin*)iface; - ALLOCATOR_PROPERTIES actual; - - if (ppropInputRequest->cbAlign && ppropInputRequest->cbAlign != This->allocProps.cbAlign) - FIXME("Requested Buffer cbAlign mismatch %i,%i\n",This->allocProps.cbAlign, ppropInputRequest->cbAlign); - if (ppropInputRequest->cbPrefix) - FIXME("Requested Buffer cbPrefix mismatch %i,%i\n",This->allocProps.cbPrefix, ppropInputRequest->cbPrefix); - if (ppropInputRequest->cbBuffer) - FIXME("Requested Buffer cbBuffer mismatch %i,%i\n",This->allocProps.cbBuffer, ppropInputRequest->cbBuffer); - if (ppropInputRequest->cBuffers) - FIXME("Requested Buffer cBuffers mismatch %i,%i\n",This->allocProps.cBuffers, ppropInputRequest->cBuffers); - - return IMemAllocator_SetProperties(pAlloc, &This->allocProps, &actual); -} - -static HRESULT WINAPI Parser_OutputPin_GetMediaType(BasePin *iface, int iPosition, AM_MEDIA_TYPE *pmt) -{ - Parser_OutputPin *This = (Parser_OutputPin*)iface; - if (iPosition < 0) - return E_INVALIDARG; - if (iPosition > 0) - return VFW_S_NO_MORE_ITEMS; - CopyMediaType(pmt, This->pmt); - return S_OK; -} - -static HRESULT WINAPI Parser_OutputPin_DecideAllocator(struct strmbase_source *iface, - IMemInputPin *pPin, IMemAllocator **pAlloc) -{ - Parser_OutputPin *This = (Parser_OutputPin*)iface; - HRESULT hr; - - *pAlloc = NULL; - - if (This->alloc) - { - hr = IMemInputPin_NotifyAllocator(pPin, This->alloc, This->readonly); - if (SUCCEEDED(hr)) - { - *pAlloc = This->alloc; - IMemAllocator_AddRef(*pAlloc); - } - } - else - hr = VFW_E_NO_ALLOCATOR; - - return hr; -} - -static HRESULT WINAPI Parser_OutputPin_QueryInterface(IPin * iface, REFIID riid, LPVOID * ppv) -{ - Parser_OutputPin *This = unsafe_impl_Parser_OutputPin_from_IPin(iface); - - TRACE("(%s, %p)\n", qzdebugstr_guid(riid), ppv); - - *ppv = NULL; - - if (IsEqualIID(riid, &IID_IUnknown)) - *ppv = iface; - else if (IsEqualIID(riid, &IID_IPin)) - *ppv = iface; - /* The Parser filter does not support querying IMediaSeeking, return it directly */ - else if (IsEqualIID(riid, &IID_IMediaSeeking)) - *ppv = &impl_from_IBaseFilter(&This->pin.pin.filter->IBaseFilter_iface)->sourceSeeking; - - if (*ppv) - { - IUnknown_AddRef((IUnknown *)(*ppv)); - return S_OK; - } - - FIXME("No interface for %s!\n", qzdebugstr_guid(riid)); - - return E_NOINTERFACE; -} - -static HRESULT WINAPI Parser_OutputPin_Connect(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt) -{ - Parser_OutputPin *This = unsafe_impl_Parser_OutputPin_from_IPin(iface); - ParserImpl *parser = impl_from_IBaseFilter(&This->pin.pin.filter->IBaseFilter_iface); - - /* Set the allocator to our input pin's */ - EnterCriticalSection(&parser->filter.csFilter); - This->alloc = parser->pInputPin->pAlloc; - LeaveCriticalSection(&parser->filter.csFilter); - - return BaseOutputPinImpl_Connect(iface, pReceivePin, pmt); -} - -static HRESULT WINAPI Parser_OutputPin_CheckMediaType(BasePin *pin, const AM_MEDIA_TYPE *pmt) -{ - Parser_OutputPin *This = (Parser_OutputPin *)pin; - - dump_AM_MEDIA_TYPE(pmt); - - return (memcmp(This->pmt, pmt, sizeof(AM_MEDIA_TYPE)) == 0); -} - -static const IPinVtbl Parser_OutputPin_Vtbl = -{ - Parser_OutputPin_QueryInterface, - BasePinImpl_AddRef, - BasePinImpl_Release, - Parser_OutputPin_Connect, - BaseOutputPinImpl_ReceiveConnection, - BaseOutputPinImpl_Disconnect, - BasePinImpl_ConnectedTo, - BasePinImpl_ConnectionMediaType, - BasePinImpl_QueryPinInfo, - BasePinImpl_QueryDirection, - BasePinImpl_QueryId, - BasePinImpl_QueryAccept, - BasePinImpl_EnumMediaTypes, - BasePinImpl_QueryInternalConnections, - BaseOutputPinImpl_EndOfStream, - BaseOutputPinImpl_BeginFlush, - BaseOutputPinImpl_EndFlush, - BasePinImpl_NewSegment -}; - -static HRESULT WINAPI Parser_PullPin_QueryInterface(IPin * iface, REFIID riid, LPVOID * ppv) -{ - PullPin *This = impl_PullPin_from_IPin(iface); - - TRACE("(%p/%p)->(%s, %p)\n", This, iface, qzdebugstr_guid(riid), ppv); - - *ppv = NULL; - - /* - * It is important to capture the request for the IMediaSeeking interface before it is passed - * on to PullPin_QueryInterface, this is necessary since the Parser filter does not support - * querying IMediaSeeking - */ - if (IsEqualIID(riid, &IID_IMediaSeeking)) - *ppv = &impl_from_IBaseFilter(&This->pin.filter->IBaseFilter_iface)->sourceSeeking; - - if (*ppv) - { - IUnknown_AddRef((IUnknown *)(*ppv)); - return S_OK; - } - - return PullPin_QueryInterface(iface, riid, ppv); -} - -static HRESULT WINAPI Parser_PullPin_Disconnect(IPin * iface) -{ - HRESULT hr; - PullPin *This = impl_PullPin_from_IPin(iface); - - TRACE("()\n"); - - EnterCriticalSection(&This->thread_lock); - EnterCriticalSection(&This->pin.filter->csFilter); - { - if (This->pin.pConnectedTo) - { - FILTER_STATE state; - ParserImpl *Parser = impl_from_IBaseFilter(&This->pin.filter->IBaseFilter_iface); - - LeaveCriticalSection(&This->pin.filter->csFilter); - hr = IBaseFilter_GetState(&This->pin.filter->IBaseFilter_iface, INFINITE, &state); - EnterCriticalSection(&This->pin.filter->csFilter); - - if (SUCCEEDED(hr) && (state == State_Stopped) && SUCCEEDED(Parser->fnDisconnect(Parser))) - { - LeaveCriticalSection(&This->pin.filter->csFilter); - PullPin_Disconnect(iface); - EnterCriticalSection(&This->pin.filter->csFilter); - hr = Parser_RemoveOutputPins(impl_from_IBaseFilter(&This->pin.filter->IBaseFilter_iface)); - } - else - hr = VFW_E_NOT_STOPPED; - } - else - hr = S_FALSE; - } - LeaveCriticalSection(&This->pin.filter->csFilter); - LeaveCriticalSection(&This->thread_lock); - - return hr; -} - -static HRESULT WINAPI Parser_PullPin_ReceiveConnection(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt) -{ - HRESULT hr; - - TRACE("()\n"); - - hr = PullPin_ReceiveConnection(iface, pReceivePin, pmt); - if (FAILED(hr)) - { - BasePin *This = (BasePin *)iface; - - EnterCriticalSection(&This->filter->csFilter); - Parser_RemoveOutputPins(impl_from_IBaseFilter(&This->filter->IBaseFilter_iface)); - LeaveCriticalSection(&This->filter->csFilter); - } - - return hr; -} - -static HRESULT WINAPI Parser_PullPin_EnumMediaTypes(IPin *iface, IEnumMediaTypes **ppEnum) -{ - BasePin *This = (BasePin *)iface; - - TRACE("(%p/%p)->(%p)\n", This, iface, ppEnum); - - return EnumMediaTypes_Construct(This, BasePinImpl_GetMediaType, BasePinImpl_GetMediaTypeVersion, ppEnum); -} - -static const IPinVtbl Parser_InputPin_Vtbl = -{ - Parser_PullPin_QueryInterface, - BasePinImpl_AddRef, - BasePinImpl_Release, - BaseInputPinImpl_Connect, - Parser_PullPin_ReceiveConnection, - Parser_PullPin_Disconnect, - BasePinImpl_ConnectedTo, - BasePinImpl_ConnectionMediaType, - BasePinImpl_QueryPinInfo, - BasePinImpl_QueryDirection, - BasePinImpl_QueryId, - PullPin_QueryAccept, - Parser_PullPin_EnumMediaTypes, - BasePinImpl_QueryInternalConnections, - PullPin_EndOfStream, - PullPin_BeginFlush, - PullPin_EndFlush, - PullPin_NewSegment -}; diff --git a/dlls/quartz/parser.h b/dlls/quartz/parser.h deleted file mode 100644 index 748b7131926..00000000000 --- a/dlls/quartz/parser.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Parser declarations - * - * Copyright 2005 Christian Costa - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -typedef struct ParserImpl ParserImpl; - -typedef HRESULT (*PFN_PROCESS_SAMPLE) (LPVOID iface, IMediaSample * pSample, DWORD_PTR cookie); -typedef HRESULT (*PFN_QUERY_ACCEPT) (LPVOID iface, const AM_MEDIA_TYPE * pmt); -typedef HRESULT (*PFN_PRE_CONNECT) (IPin * iface, IPin * pConnectPin, ALLOCATOR_PROPERTIES *prop); -typedef HRESULT (*PFN_CLEANUP) (LPVOID iface); -typedef HRESULT (*PFN_DISCONNECT) (LPVOID iface); - -typedef struct Parser_OutputPin -{ - struct strmbase_source pin; - - AM_MEDIA_TYPE * pmt; - LONGLONG dwSamplesProcessed; - ALLOCATOR_PROPERTIES allocProps; - - IMemAllocator *alloc; - BOOL readonly; -} Parser_OutputPin; - -struct ParserImpl -{ - struct strmbase_filter filter; - - PFN_DISCONNECT fnDisconnect; - - PullPin *pInputPin; - Parser_OutputPin **sources; - ULONG cStreams; - SourceSeeking sourceSeeking; -}; - -extern HRESULT Parser_AddPin(ParserImpl *filter, const WCHAR *name, - ALLOCATOR_PROPERTIES *props, const AM_MEDIA_TYPE *mt); - -HRESULT Parser_Create(ParserImpl *parser, const IBaseFilterVtbl *vtbl, IUnknown *outer, - const CLSID *clsid, const struct strmbase_filter_ops *func_table, const WCHAR *sink_name, - PFN_PROCESS_SAMPLE, PFN_QUERY_ACCEPT, PFN_PRE_CONNECT, PFN_CLEANUP, PFN_DISCONNECT, - REQUESTPROC, STOPPROCESSPROC, SourceSeeking_ChangeStop, - SourceSeeking_ChangeStart, SourceSeeking_ChangeRate) DECLSPEC_HIDDEN; - -/* Override the _Release function and call this when releasing */ -extern void Parser_Destroy(ParserImpl *This); - -extern HRESULT WINAPI Parser_Stop(IBaseFilter * iface); -extern HRESULT WINAPI Parser_Pause(IBaseFilter * iface); -extern HRESULT WINAPI Parser_Run(IBaseFilter * iface, REFERENCE_TIME tStart); -extern HRESULT WINAPI Parser_GetState(IBaseFilter * iface, DWORD dwMilliSecsTimeout, FILTER_STATE *pState); -extern HRESULT WINAPI Parser_SetSyncSource(IBaseFilter * iface, IReferenceClock *pClock); - -IPin *parser_get_pin(struct strmbase_filter *iface, unsigned int index) DECLSPEC_HIDDEN; - -/* COM helpers */ -static inline Parser_OutputPin *unsafe_impl_Parser_OutputPin_from_IPin( IPin *iface ) -{ - return CONTAINING_RECORD(iface, Parser_OutputPin, pin.pin.IPin_iface); -} diff --git a/dlls/quartz/pin.c b/dlls/quartz/pin.c deleted file mode 100644 index bf31799641d..00000000000 --- a/dlls/quartz/pin.c +++ /dev/null @@ -1,818 +0,0 @@ -/* - * Generic Implementation of IPin Interface - * - * Copyright 2003 Robert Shearman - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include "quartz_private.h" -#include "pin.h" - -#include "wine/debug.h" -#include "uuids.h" -#include "vfwmsgs.h" -#include <assert.h> - -WINE_DEFAULT_DEBUG_CHANNEL(quartz); - -#define ALIGNDOWN(value,boundary) ((value)/(boundary)*(boundary)) -#define ALIGNUP(value,boundary) (ALIGNDOWN((value)+(boundary)-1, (boundary))) - -typedef HRESULT (*SendPinFunc)( IPin *to, LPVOID arg ); - -/** Helper function, there are a lot of places where the error code is inherited - * The following rules apply: - * - * Return the first received error code (E_NOTIMPL is ignored) - * If no errors occur: return the first received non-error-code that isn't S_OK - */ -static HRESULT updatehres( HRESULT original, HRESULT new ) -{ - if (FAILED( original ) || new == E_NOTIMPL) - return original; - - if (FAILED( new ) || original == S_OK) - return new; - - return original; -} - -/** Sends a message from a pin further to other, similar pins - * fnMiddle is called on each pin found further on the stream. - * fnEnd (can be NULL) is called when the message can't be sent any further (this is a renderer or source) - * - * If the pin given is an input pin, the message will be sent downstream to other input pins - * If the pin given is an output pin, the message will be sent upstream to other output pins - */ -static HRESULT SendFurther( IPin *from, SendPinFunc fnMiddle, LPVOID arg, SendPinFunc fnEnd ) -{ - PIN_INFO pin_info; - ULONG amount = 0; - HRESULT hr = S_OK; - HRESULT hr_return = S_OK; - IEnumPins *enumpins = NULL; - BOOL foundend = TRUE; - PIN_DIRECTION from_dir; - - IPin_QueryDirection( from, &from_dir ); - - hr = IPin_QueryInternalConnections( from, NULL, &amount ); - if (hr != E_NOTIMPL && amount) - FIXME("Use QueryInternalConnections!\n"); - - pin_info.pFilter = NULL; - hr = IPin_QueryPinInfo( from, &pin_info ); - if (FAILED(hr)) - goto out; - - hr = IBaseFilter_EnumPins( pin_info.pFilter, &enumpins ); - if (FAILED(hr)) - goto out; - - hr = IEnumPins_Reset( enumpins ); - while (hr == S_OK) { - IPin *pin = NULL; - hr = IEnumPins_Next( enumpins, 1, &pin, NULL ); - if (hr == VFW_E_ENUM_OUT_OF_SYNC) - { - hr = IEnumPins_Reset( enumpins ); - continue; - } - if (pin) - { - PIN_DIRECTION dir; - - IPin_QueryDirection( pin, &dir ); - if (dir != from_dir) - { - IPin *connected = NULL; - - foundend = FALSE; - IPin_ConnectedTo( pin, &connected ); - if (connected) - { - HRESULT hr_local; - - hr_local = fnMiddle( connected, arg ); - hr_return = updatehres( hr_return, hr_local ); - IPin_Release(connected); - } - } - IPin_Release( pin ); - } - else - { - hr = S_OK; - break; - } - } - - if (!foundend) - hr = hr_return; - else if (fnEnd) { - HRESULT hr_local; - - hr_local = fnEnd( from, arg ); - hr_return = updatehres( hr_return, hr_local ); - } - -out: - if (enumpins) - IEnumPins_Release( enumpins ); - if (pin_info.pFilter) - IBaseFilter_Release( pin_info.pFilter ); - return hr; -} - -static HRESULT deliver_endofstream(IPin* pin, LPVOID unused) -{ - return IPin_EndOfStream( pin ); -} - -static HRESULT deliver_beginflush(IPin* pin, LPVOID unused) -{ - return IPin_BeginFlush( pin ); -} - -static HRESULT deliver_endflush(IPin* pin, LPVOID unused) -{ - return IPin_EndFlush( pin ); -} - -typedef struct newsegmentargs -{ - REFERENCE_TIME tStart, tStop; - double rate; -} newsegmentargs; - -static HRESULT deliver_newsegment(IPin *pin, LPVOID data) -{ - newsegmentargs *args = data; - return IPin_NewSegment(pin, args->tStart, args->tStop, args->rate); -} - -/*** PullPin implementation ***/ - -static HRESULT PullPin_Init(const IPinVtbl *PullPin_Vtbl, struct strmbase_filter *filter, - const WCHAR *name, SAMPLEPROC_PULL pSampleProc, void *pUserData, - QUERYACCEPTPROC pQueryAccept, CLEANUPPROC pCleanUp, REQUESTPROC pCustomRequest, - STOPPROCESSPROC pDone, PullPin *pPinImpl) -{ - /* Common attributes */ - pPinImpl->pin.IPin_iface.lpVtbl = PullPin_Vtbl; - pPinImpl->pin.pConnectedTo = NULL; - wcscpy(pPinImpl->pin.name, name); - pPinImpl->pin.dir = PINDIR_INPUT; - pPinImpl->pin.filter = filter; - ZeroMemory(&pPinImpl->pin.mtCurrent, sizeof(AM_MEDIA_TYPE)); - - /* Input pin attributes */ - pPinImpl->pUserData = pUserData; - pPinImpl->fnQueryAccept = pQueryAccept; - pPinImpl->fnSampleProc = pSampleProc; - pPinImpl->fnCleanProc = pCleanUp; - pPinImpl->fnDone = pDone; - pPinImpl->fnPreConnect = NULL; - pPinImpl->pAlloc = NULL; - pPinImpl->prefAlloc = NULL; - pPinImpl->pReader = NULL; - pPinImpl->hThread = NULL; - pPinImpl->hEventStateChanged = CreateEventW(NULL, TRUE, TRUE, NULL); - pPinImpl->thread_sleepy = CreateEventW(NULL, FALSE, FALSE, NULL); - - pPinImpl->rtStart = 0; - pPinImpl->rtCurrent = 0; - pPinImpl->rtStop = ((LONGLONG)0x7fffffff << 32) | 0xffffffff; - pPinImpl->dRate = 1.0; - pPinImpl->state = Req_Die; - pPinImpl->fnCustomRequest = pCustomRequest; - pPinImpl->stop_playback = TRUE; - - InitializeCriticalSection(&pPinImpl->thread_lock); - pPinImpl->thread_lock.DebugInfo->Spare[0] = (DWORD_PTR)( __FILE__ ": PullPin.thread_lock"); - - return S_OK; -} - -HRESULT PullPin_Construct(const IPinVtbl *PullPin_Vtbl, struct strmbase_filter *filter, const WCHAR *name, - SAMPLEPROC_PULL pSampleProc, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, - CLEANUPPROC pCleanUp, REQUESTPROC pCustomRequest, STOPPROCESSPROC pDone, - IPin ** ppPin) -{ - PullPin * pPinImpl; - - *ppPin = NULL; - - pPinImpl = CoTaskMemAlloc(sizeof(*pPinImpl)); - - if (!pPinImpl) - return E_OUTOFMEMORY; - - if (SUCCEEDED(PullPin_Init(PullPin_Vtbl, filter, name, pSampleProc, pUserData, - pQueryAccept, pCleanUp, pCustomRequest, pDone, pPinImpl))) - { - *ppPin = &pPinImpl->pin.IPin_iface; - return S_OK; - } - - CoTaskMemFree(pPinImpl); - return E_FAIL; -} - -static HRESULT PullPin_InitProcessing(PullPin * This); - -HRESULT WINAPI PullPin_ReceiveConnection(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt) -{ - PIN_DIRECTION pindirReceive; - HRESULT hr = S_OK; - PullPin *This = impl_PullPin_from_IPin(iface); - - TRACE("(%p/%p)->(%p, %p)\n", This, iface, pReceivePin, pmt); - dump_AM_MEDIA_TYPE(pmt); - - EnterCriticalSection(&This->pin.filter->csFilter); - if (!This->pin.pConnectedTo) - { - ALLOCATOR_PROPERTIES props; - - props.cBuffers = 3; - props.cbBuffer = 64 * 1024; /* 64 KB */ - props.cbAlign = 1; - props.cbPrefix = 0; - - if (This->fnQueryAccept(This->pUserData, pmt) != S_OK) - hr = VFW_E_TYPE_NOT_ACCEPTED; /* FIXME: shouldn't we just map common errors onto - * VFW_E_TYPE_NOT_ACCEPTED and pass the value on otherwise? */ - - if (SUCCEEDED(hr)) - { - IPin_QueryDirection(pReceivePin, &pindirReceive); - - if (pindirReceive != PINDIR_OUTPUT) - { - ERR("Can't connect from non-output pin\n"); - hr = VFW_E_INVALID_DIRECTION; - } - } - - This->pReader = NULL; - This->pAlloc = NULL; - This->prefAlloc = NULL; - if (SUCCEEDED(hr)) - { - hr = IPin_QueryInterface(pReceivePin, &IID_IAsyncReader, (LPVOID *)&This->pReader); - } - - if (SUCCEEDED(hr) && This->fnPreConnect) - { - hr = This->fnPreConnect(iface, pReceivePin, &props); - } - - /* - * Some custom filters (such as the one used by Fallout 3 - * and Fallout: New Vegas) expect to be passed a non-NULL - * preferred allocator. - */ - if (SUCCEEDED(hr)) - { - hr = StdMemAllocator_create(NULL, (LPVOID *) &This->prefAlloc); - } - - if (SUCCEEDED(hr)) - { - hr = IAsyncReader_RequestAllocator(This->pReader, This->prefAlloc, &props, &This->pAlloc); - } - - if (SUCCEEDED(hr)) - { - CopyMediaType(&This->pin.mtCurrent, pmt); - This->pin.pConnectedTo = pReceivePin; - IPin_AddRef(pReceivePin); - hr = IMemAllocator_Commit(This->pAlloc); - } - - if (SUCCEEDED(hr)) - hr = PullPin_InitProcessing(This); - - if (FAILED(hr)) - { - if (This->pReader) - IAsyncReader_Release(This->pReader); - This->pReader = NULL; - if (This->prefAlloc) - IMemAllocator_Release(This->prefAlloc); - This->prefAlloc = NULL; - if (This->pAlloc) - IMemAllocator_Release(This->pAlloc); - This->pAlloc = NULL; - } - } - else - hr = VFW_E_ALREADY_CONNECTED; - LeaveCriticalSection(&This->pin.filter->csFilter); - return hr; -} - -HRESULT WINAPI PullPin_QueryInterface(IPin * iface, REFIID riid, LPVOID * ppv) -{ - PullPin *This = impl_PullPin_from_IPin(iface); - - TRACE("(%p/%p)->(%s, %p)\n", This, iface, qzdebugstr_guid(riid), ppv); - - *ppv = NULL; - - if (IsEqualIID(riid, &IID_IUnknown)) - *ppv = iface; - else if (IsEqualIID(riid, &IID_IPin)) - *ppv = iface; - else if (IsEqualIID(riid, &IID_IMediaSeeking) || - IsEqualIID(riid, &IID_IQualityControl)) - { - return IBaseFilter_QueryInterface(&This->pin.filter->IBaseFilter_iface, riid, ppv); - } - - if (*ppv) - { - IUnknown_AddRef((IUnknown *)(*ppv)); - return S_OK; - } - - FIXME("No interface for %s!\n", qzdebugstr_guid(riid)); - - return E_NOINTERFACE; -} - -void PullPin_destroy(PullPin *pin) -{ - WaitForSingleObject(pin->hEventStateChanged, INFINITE); - assert(!pin->hThread); - - if (pin->prefAlloc) - IMemAllocator_Release(pin->prefAlloc); - if (pin->pAlloc) - IMemAllocator_Release(pin->pAlloc); - if (pin->pReader) - IAsyncReader_Release(pin->pReader); - CloseHandle(pin->thread_sleepy); - CloseHandle(pin->hEventStateChanged); - pin->thread_lock.DebugInfo->Spare[0] = 0; - DeleteCriticalSection(&pin->thread_lock); - CoTaskMemFree(pin); -} - -static void PullPin_Flush(PullPin *This) -{ - IMediaSample *pSample; - TRACE("Flushing!\n"); - - if (This->pReader) - { - /* Do not allow state to change while flushing */ - EnterCriticalSection(&This->pin.filter->csFilter); - - /* Flush outstanding samples */ - IAsyncReader_BeginFlush(This->pReader); - - for (;;) - { - DWORD_PTR dwUser; - - pSample = NULL; - IAsyncReader_WaitForNext(This->pReader, 0, &pSample, &dwUser); - - if (!pSample) - break; - - assert(!IMediaSample_GetActualDataLength(pSample)); - - IMediaSample_Release(pSample); - } - - IAsyncReader_EndFlush(This->pReader); - - LeaveCriticalSection(&This->pin.filter->csFilter); - } -} - -static void PullPin_Thread_Process(PullPin *This) -{ - HRESULT hr; - IMediaSample * pSample = NULL; - ALLOCATOR_PROPERTIES allocProps; - - hr = IMemAllocator_GetProperties(This->pAlloc, &allocProps); - - This->cbAlign = allocProps.cbAlign; - - if (This->rtCurrent < This->rtStart) - This->rtCurrent = MEDIATIME_FROM_BYTES(ALIGNDOWN(BYTES_FROM_MEDIATIME(This->rtStart), This->cbAlign)); - - TRACE("Start\n"); - - if (This->rtCurrent >= This->rtStop) - { - IPin_EndOfStream(&This->pin.IPin_iface); - return; - } - - /* There is no sample in our buffer */ - hr = This->fnCustomRequest(This->pUserData); - - if (FAILED(hr)) - ERR("Request error: %x\n", hr); - - EnterCriticalSection(&This->pin.filter->csFilter); - SetEvent(This->hEventStateChanged); - LeaveCriticalSection(&This->pin.filter->csFilter); - - if (SUCCEEDED(hr)) - do - { - DWORD_PTR dwUser; - - TRACE("Process sample\n"); - - pSample = NULL; - hr = IAsyncReader_WaitForNext(This->pReader, 10000, &pSample, &dwUser); - - /* Return an empty sample on error to the implementation in case it does custom parsing, so it knows it's gone */ - if (SUCCEEDED(hr)) - { - hr = This->fnSampleProc(This->pUserData, pSample, dwUser); - } - else - { - if (hr == VFW_E_TIMEOUT) - { - if (pSample != NULL) - WARN("Non-NULL sample returned with VFW_E_TIMEOUT.\n"); - hr = S_OK; - } - /* FIXME: Errors are not well handled yet! */ - else - ERR("Processing error: %x\n", hr); - } - - if (pSample) - { - IMediaSample_Release(pSample); - pSample = NULL; - } - } while (This->rtCurrent < This->rtStop && hr == S_OK && !This->stop_playback); - - /* - * Sample was rejected, and we are asked to terminate. When there is more than one buffer - * it is possible for a filter to have several queued samples, making it necessary to - * release all of these pending samples. - */ - if (This->stop_playback || FAILED(hr)) - { - DWORD_PTR dwUser; - - do - { - if (pSample) - IMediaSample_Release(pSample); - pSample = NULL; - IAsyncReader_WaitForNext(This->pReader, 0, &pSample, &dwUser); - } while(pSample); - } - - /* Can't reset state to Sleepy here because that might race, instead PauseProcessing will do that for us - * Flush remaining samples - */ - if (This->fnDone) - This->fnDone(This->pUserData); - - TRACE("End: %08x, %d\n", hr, This->stop_playback); -} - -static void PullPin_Thread_Pause(PullPin *This) -{ - PullPin_Flush(This); - - EnterCriticalSection(&This->pin.filter->csFilter); - This->state = Req_Sleepy; - SetEvent(This->hEventStateChanged); - LeaveCriticalSection(&This->pin.filter->csFilter); -} - -static void PullPin_Thread_Stop(PullPin *This) -{ - TRACE("(%p)->()\n", This); - - EnterCriticalSection(&This->pin.filter->csFilter); - SetEvent(This->hEventStateChanged); - LeaveCriticalSection(&This->pin.filter->csFilter); - - IPin_Release(&This->pin.IPin_iface); - - CoUninitialize(); - ExitThread(0); -} - -static DWORD WINAPI PullPin_Thread_Main(LPVOID pv) -{ - PullPin *This = pv; - CoInitializeEx(NULL, COINIT_MULTITHREADED); - - PullPin_Flush(This); - - for (;;) - { - WaitForSingleObject(This->thread_sleepy, INFINITE); - - TRACE("State: %d\n", This->state); - - switch (This->state) - { - case Req_Die: PullPin_Thread_Stop(This); break; - case Req_Run: PullPin_Thread_Process(This); break; - case Req_Pause: PullPin_Thread_Pause(This); break; - case Req_Sleepy: ERR("Should not be signalled with SLEEPY!\n"); break; - default: ERR("Unknown state request: %d\n", This->state); break; - } - } - return 0; -} - -static HRESULT PullPin_InitProcessing(PullPin * This) -{ - HRESULT hr = S_OK; - - TRACE("(%p)->()\n", This); - - /* if we are connected */ - if (This->pAlloc) - { - DWORD dwThreadId; - - WaitForSingleObject(This->hEventStateChanged, INFINITE); - EnterCriticalSection(&This->pin.filter->csFilter); - - assert(!This->hThread); - assert(This->state == Req_Die); - assert(This->stop_playback); - assert(WaitForSingleObject(This->thread_sleepy, 0) == WAIT_TIMEOUT); - This->state = Req_Sleepy; - - IPin_AddRef(&This->pin.IPin_iface); - - This->hThread = CreateThread(NULL, 0, PullPin_Thread_Main, This, 0, &dwThreadId); - if (!This->hThread) - { - hr = HRESULT_FROM_WIN32(GetLastError()); - IPin_Release(&This->pin.IPin_iface); - } - - if (SUCCEEDED(hr)) - { - SetEvent(This->hEventStateChanged); - /* If assert fails, that means a command was not processed before the thread previously terminated */ - } - LeaveCriticalSection(&This->pin.filter->csFilter); - } - - TRACE(" -- %x\n", hr); - - return hr; -} - -HRESULT PullPin_StartProcessing(PullPin * This) -{ - /* if we are connected */ - TRACE("(%p)->()\n", This); - if(This->pAlloc) - { - assert(This->hThread); - - PullPin_WaitForStateChange(This, INFINITE); - - assert(This->state == Req_Sleepy); - - /* Wake up! */ - assert(WaitForSingleObject(This->thread_sleepy, 0) == WAIT_TIMEOUT); - This->state = Req_Run; - This->stop_playback = FALSE; - ResetEvent(This->hEventStateChanged); - SetEvent(This->thread_sleepy); - } - - return S_OK; -} - -HRESULT PullPin_PauseProcessing(PullPin * This) -{ - /* if we are connected */ - TRACE("(%p)->()\n", This); - if(This->pAlloc) - { - assert(This->hThread); - - PullPin_WaitForStateChange(This, INFINITE); - - EnterCriticalSection(&This->pin.filter->csFilter); - - assert(!This->stop_playback); - assert(This->state == Req_Run|| This->state == Req_Sleepy); - - assert(WaitForSingleObject(This->thread_sleepy, 0) == WAIT_TIMEOUT); - - This->state = Req_Pause; - This->stop_playback = TRUE; - ResetEvent(This->hEventStateChanged); - SetEvent(This->thread_sleepy); - - /* Release any outstanding samples */ - if (This->pReader) - { - IMediaSample *pSample; - DWORD_PTR dwUser; - - do - { - pSample = NULL; - IAsyncReader_WaitForNext(This->pReader, 0, &pSample, &dwUser); - if (pSample) - IMediaSample_Release(pSample); - } while(pSample); - } - - LeaveCriticalSection(&This->pin.filter->csFilter); - } - - return S_OK; -} - -static HRESULT PullPin_StopProcessing(PullPin * This) -{ - TRACE("(%p)->()\n", This); - - /* if we are alive */ - assert(This->hThread); - - PullPin_WaitForStateChange(This, INFINITE); - - assert(This->state == Req_Pause || This->state == Req_Sleepy); - - This->stop_playback = TRUE; - This->state = Req_Die; - assert(WaitForSingleObject(This->thread_sleepy, 0) == WAIT_TIMEOUT); - ResetEvent(This->hEventStateChanged); - SetEvent(This->thread_sleepy); - return S_OK; -} - -HRESULT PullPin_WaitForStateChange(PullPin * This, DWORD dwMilliseconds) -{ - if (WaitForSingleObject(This->hEventStateChanged, dwMilliseconds) == WAIT_TIMEOUT) - return S_FALSE; - return S_OK; -} - -HRESULT WINAPI PullPin_QueryAccept(IPin * iface, const AM_MEDIA_TYPE * pmt) -{ - PullPin *This = impl_PullPin_from_IPin(iface); - - TRACE("(%p/%p)->(%p)\n", This, iface, pmt); - - return (This->fnQueryAccept(This->pUserData, pmt) == S_OK ? S_OK : S_FALSE); -} - -HRESULT WINAPI PullPin_EndOfStream(IPin * iface) -{ - PullPin *This = impl_PullPin_from_IPin(iface); - HRESULT hr = S_FALSE; - - TRACE("(%p)->()\n", iface); - - EnterCriticalSection(&This->pin.filter->csFilter); - hr = SendFurther( iface, deliver_endofstream, NULL, NULL ); - SetEvent(This->hEventStateChanged); - LeaveCriticalSection(&This->pin.filter->csFilter); - - return hr; -} - -HRESULT WINAPI PullPin_BeginFlush(IPin * iface) -{ - PullPin *This = impl_PullPin_from_IPin(iface); - TRACE("(%p)->()\n", This); - - EnterCriticalSection(&This->pin.filter->csFilter); - { - SendFurther( iface, deliver_beginflush, NULL, NULL ); - } - LeaveCriticalSection(&This->pin.filter->csFilter); - - EnterCriticalSection(&This->thread_lock); - { - if (This->pReader) - IAsyncReader_BeginFlush(This->pReader); - PullPin_WaitForStateChange(This, INFINITE); - - if (This->hThread && This->state == Req_Run) - { - PullPin_PauseProcessing(This); - PullPin_WaitForStateChange(This, INFINITE); - } - } - LeaveCriticalSection(&This->thread_lock); - - EnterCriticalSection(&This->pin.filter->csFilter); - { - This->fnCleanProc(This->pUserData); - } - LeaveCriticalSection(&This->pin.filter->csFilter); - - return S_OK; -} - -HRESULT WINAPI PullPin_EndFlush(IPin * iface) -{ - PullPin *This = impl_PullPin_from_IPin(iface); - - TRACE("(%p)->()\n", iface); - - /* Send further first: Else a race condition might terminate processing early */ - EnterCriticalSection(&This->pin.filter->csFilter); - SendFurther( iface, deliver_endflush, NULL, NULL ); - LeaveCriticalSection(&This->pin.filter->csFilter); - - EnterCriticalSection(&This->thread_lock); - { - FILTER_STATE state; - - if (This->pReader) - IAsyncReader_EndFlush(This->pReader); - - IBaseFilter_GetState(&This->pin.filter->IBaseFilter_iface, INFINITE, &state); - - if (state != State_Stopped) - PullPin_StartProcessing(This); - - PullPin_WaitForStateChange(This, INFINITE); - } - LeaveCriticalSection(&This->thread_lock); - - return S_OK; -} - -HRESULT WINAPI PullPin_Disconnect(IPin *iface) -{ - HRESULT hr; - PullPin *This = impl_PullPin_from_IPin(iface); - - TRACE("()\n"); - - EnterCriticalSection(&This->pin.filter->csFilter); - { - if (FAILED(hr = IMemAllocator_Decommit(This->pAlloc))) - ERR("Allocator decommit failed with error %x. Possible memory leak\n", hr); - - if (This->pin.pConnectedTo) - { - IPin_Release(This->pin.pConnectedTo); - This->pin.pConnectedTo = NULL; - PullPin_StopProcessing(This); - - FreeMediaType(&This->pin.mtCurrent); - ZeroMemory(&This->pin.mtCurrent, sizeof(This->pin.mtCurrent)); - hr = S_OK; - } - else - hr = S_FALSE; - } - LeaveCriticalSection(&This->pin.filter->csFilter); - - WaitForSingleObject(This->hThread, INFINITE); - CloseHandle(This->hThread); - This->hThread = NULL; - - return hr; -} - -HRESULT WINAPI PullPin_NewSegment(IPin * iface, REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate) -{ - newsegmentargs args; - FIXME("(%p)->(%s, %s, %g) stub\n", iface, wine_dbgstr_longlong(tStart), wine_dbgstr_longlong(tStop), dRate); - - args.tStart = tStart; - args.tStop = tStop; - args.rate = dRate; - - return SendFurther( iface, deliver_newsegment, &args, NULL ); -} diff --git a/dlls/quartz/pin.h b/dlls/quartz/pin.h deleted file mode 100644 index fb39d3a7e39..00000000000 --- a/dlls/quartz/pin.h +++ /dev/null @@ -1,133 +0,0 @@ -/* - * IPin function declarations to allow inheritance - * - * Copyright 2003 Robert Shearman - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -/* This function will process incoming samples to the pin. - * Any return value valid in IMemInputPin::Receive is allowed here - * - * Cookie is the cookie that was set when requesting the buffer, if you don't - * implement custom requesting, you can safely ignore this - */ -typedef HRESULT (* SAMPLEPROC_PULL)(LPVOID userdata, IMediaSample * pSample, DWORD_PTR cookie); - -/* This function will determine whether a type is supported or not. - * It is allowed to return any error value (within reason), as opposed - * to IPin::QueryAccept which is only allowed to return S_OK or S_FALSE. - */ -typedef HRESULT (* QUERYACCEPTPROC)(LPVOID userdata, const AM_MEDIA_TYPE * pmt); - -/* This function is called prior to finalizing a connection with - * another pin and can be used to get things from the other pin - * like IMemInput interfaces. - * - * props contains some defaults, but you can safely override them to your liking - */ -typedef HRESULT (* PRECONNECTPROC)(IPin * iface, IPin * pConnectPin, ALLOCATOR_PROPERTIES *props); - -/* 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); - -/* This function is called whenever a request for a new sample is made, - * If you implement it (it can be NULL for default behavior), you have to - * call IMemAllocator_GetBuffer and IMemAllocator_RequestBuffer - * This is useful if you want to request more than 1 buffer at simultaneously - * - * This will also cause the Sample Proc to be called with empty buffers to indicate - * failure in retrieving the sample. - */ -typedef HRESULT (* REQUESTPROC) (LPVOID userdata); - -/* This function is called after processing is done (for whatever reason that is caused) - * This is useful if you create processing threads that need to die - */ -typedef HRESULT (* STOPPROCESSPROC) (LPVOID userdata); - -#define ALIGNDOWN(value,boundary) ((value)/(boundary)*(boundary)) -#define ALIGNUP(value,boundary) (ALIGNDOWN((value)+(boundary)-1, (boundary))) - -typedef struct PullPin -{ - /* inheritance C style! */ - BasePin pin; - LPVOID pUserData; - - REFERENCE_TIME rtStart, rtCurrent, rtNext, rtStop; - IAsyncReader * pReader; - IMemAllocator * prefAlloc; - IMemAllocator * pAlloc; - QUERYACCEPTPROC fnQueryAccept; - SAMPLEPROC_PULL fnSampleProc; - PRECONNECTPROC fnPreConnect; - REQUESTPROC fnCustomRequest; - CLEANUPPROC fnCleanProc; - STOPPROCESSPROC fnDone; - double dRate; - BOOL stop_playback; - DWORD cbAlign; - - /* Any code that touches the thread must hold the thread lock, - * lock order: thread_lock and then the filter critical section - * also signal thread_sleepy so the thread knows to wake up - */ - CRITICAL_SECTION thread_lock; - HANDLE hThread; - DWORD requested_state; - HANDLE hEventStateChanged, thread_sleepy; - DWORD state; -} PullPin; - -#define Req_Sleepy 0 -#define Req_Die 1 -#define Req_Run 2 -#define Req_Pause 3 - -/*** Constructors ***/ -HRESULT PullPin_Construct(const IPinVtbl *PullPin_Vtbl, struct strmbase_filter *filter, const WCHAR *name, - SAMPLEPROC_PULL pSampleProc, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, - CLEANUPPROC pCleanUp, REQUESTPROC pCustomRequest, STOPPROCESSPROC pDone, - IPin **ppPin); -void PullPin_destroy(PullPin *pin) DECLSPEC_HIDDEN; - -/**************************/ -/*** Pin Implementation ***/ - -/* Pull Pin */ -HRESULT WINAPI PullPin_ReceiveConnection(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt); -HRESULT WINAPI PullPin_Disconnect(IPin * iface); -HRESULT WINAPI PullPin_QueryInterface(IPin * iface, REFIID riid, LPVOID * ppv); -HRESULT WINAPI PullPin_EndOfStream(IPin * iface); -HRESULT WINAPI PullPin_QueryAccept(IPin * iface, const AM_MEDIA_TYPE * pmt); -HRESULT WINAPI PullPin_BeginFlush(IPin * iface); -HRESULT WINAPI PullPin_EndFlush(IPin * iface); -HRESULT WINAPI PullPin_NewSegment(IPin * iface, REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate); - -/* Thread interaction functions: Hold the thread_lock before calling them */ -HRESULT PullPin_StartProcessing(PullPin * This); -HRESULT PullPin_PauseProcessing(PullPin * This); -HRESULT PullPin_WaitForStateChange(PullPin * This, DWORD dwMilliseconds); - -/* COM helpers */ -static inline PullPin *impl_PullPin_from_IPin( IPin *iface ) -{ - return CONTAINING_RECORD(iface, PullPin, pin.IPin_iface); -} diff --git a/dlls/quartz/quartz_private.h b/dlls/quartz/quartz_private.h index e475cd01477..353d1e5a577 100644 --- a/dlls/quartz/quartz_private.h +++ b/dlls/quartz/quartz_private.h @@ -36,18 +36,9 @@ #include "wine/strmbase.h" #include "wine/list.h"
-static inline const char *debugstr_fourcc(DWORD fourcc) -{ - if (!fourcc) return "''"; - return wine_dbg_sprintf("'%c%c%c%c'", (char)(fourcc), (char)(fourcc >> 8), - (char)(fourcc >> 16), (char)(fourcc >> 24)); -} - /* see IAsyncReader::Request on MSDN for the explanation of this */ #define MEDIATIME_FROM_BYTES(x) ((LONGLONG)(x) * 10000000) -#define SEC_FROM_MEDIATIME(time) ((time) / 10000000) -#define BYTES_FROM_MEDIATIME(time) SEC_FROM_MEDIATIME(time) -#define MSEC_FROM_MEDIATIME(time) ((time) / 10000) +#define BYTES_FROM_MEDIATIME(time) ((time) / 10000000)
HRESULT FilterGraph_create(IUnknown *pUnkOuter, LPVOID *ppObj) DECLSPEC_HIDDEN; HRESULT FilterGraphNoThread_create(IUnknown *pUnkOuter, LPVOID *ppObj) DECLSPEC_HIDDEN; @@ -71,7 +62,6 @@ HRESULT IEnumRegFiltersImpl_Construct(REGFILTER * pInRegFilters, const ULONG siz extern const char * qzdebugstr_guid(const GUID * id) DECLSPEC_HIDDEN; extern void video_unregister_windowclass(void) DECLSPEC_HIDDEN;
-BOOL CompareMediaTypes(const AM_MEDIA_TYPE * pmt1, const AM_MEDIA_TYPE * pmt2, BOOL bWildcards); void dump_AM_MEDIA_TYPE(const AM_MEDIA_TYPE * pmt) DECLSPEC_HIDDEN;
BOOL get_media_type(const WCHAR *filename, GUID *majortype, GUID *subtype, GUID *source_clsid) DECLSPEC_HIDDEN; diff --git a/dlls/quartz/videorenderer.c b/dlls/quartz/videorenderer.c index 26bb05f8d92..aee362c7ef2 100644 --- a/dlls/quartz/videorenderer.c +++ b/dlls/quartz/videorenderer.c @@ -19,7 +19,6 @@ */
#include "quartz_private.h" -#include "pin.h"
#include "uuids.h" #include "vfwmsgs.h" diff --git a/dlls/quartz/vmr9.c b/dlls/quartz/vmr9.c index 184937b0385..d81c3252b05 100644 --- a/dlls/quartz/vmr9.c +++ b/dlls/quartz/vmr9.c @@ -34,7 +34,6 @@ #include "dvdmedia.h" #include "d3d9.h" #include "vmr9.h" -#include "pin.h"
#include "wine/debug.h"