quartz: Make the EnumPins interface dynamic.
Take a reference to the ibasefilter and request it for the pins and a
cookie. This seems to be the easiest way to ensure correctness.
diff --git a/dlls/quartz/dsoundrender.c b/dlls/quartz/dsoundrender.c
index af98c52..3e465a0 100644
--- a/dlls/quartz/dsoundrender.c
+++ b/dlls/quartz/dsoundrender.c
@@ -61,7 +61,6 @@
FILTER_INFO filterInfo;
InputPin * pInputPin;
- IPin ** ppPins;
LPDIRECTSOUND dsound;
LPDIRECTSOUNDBUFFER dsbuffer;
@@ -334,15 +333,6 @@
pDSoundRender->csFilter.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": DSoundRenderImpl.csFilter");
pDSoundRender->state = State_Stopped;
- pDSoundRender->ppPins = CoTaskMemAlloc(1 * sizeof(IPin *));
- if (!pDSoundRender->ppPins)
- {
- pDSoundRender->csFilter.DebugInfo->Spare[0] = 0;
- DeleteCriticalSection(&pDSoundRender->csFilter);
- CoTaskMemFree(pDSoundRender);
- return E_OUTOFMEMORY;
- }
-
/* construct input pin */
piInput.dir = PINDIR_INPUT;
piInput.pFilter = (IBaseFilter *)pDSoundRender;
@@ -361,14 +351,12 @@
MediaSeekingImpl_Init((IBaseFilter*)pDSoundRender, sound_mod_stop, sound_mod_start, sound_mod_rate, &pDSoundRender->mediaSeeking, &pDSoundRender->csFilter);
pDSoundRender->mediaSeeking.lpVtbl = &IMediaSeeking_Vtbl;
- pDSoundRender->ppPins[0] = (IPin *)pDSoundRender->pInputPin;
*ppv = (LPVOID)pDSoundRender;
}
else
{
if (pDSoundRender->pInputPin)
IPin_Release((IPin*)pDSoundRender->pInputPin);
- CoTaskMemFree(pDSoundRender->ppPins);
pDSoundRender->csFilter.DebugInfo->Spare[0] = 0;
DeleteCriticalSection(&pDSoundRender->csFilter);
CoTaskMemFree(pDSoundRender);
@@ -442,16 +430,15 @@
IDirectSound_Release(This->dsound);
This->dsound = NULL;
- if (SUCCEEDED(IPin_ConnectedTo(This->ppPins[0], &pConnectedTo)))
+ if (SUCCEEDED(IPin_ConnectedTo((IPin *)This->pInputPin, &pConnectedTo)))
{
IPin_Disconnect(pConnectedTo);
IPin_Release(pConnectedTo);
}
- IPin_Disconnect(This->ppPins[0]);
+ IPin_Disconnect((IPin *)This->pInputPin);
- IPin_Release(This->ppPins[0]);
-
- CoTaskMemFree(This->ppPins);
+ IPin_Release((IPin *)This->pInputPin);
+
This->lpVtbl = NULL;
This->IBasicAudio_vtbl = NULL;
@@ -609,16 +596,28 @@
/** IBaseFilter implementation **/
+static HRESULT DSoundRender_GetPin(IBaseFilter *iface, ULONG pos, IPin **pin, DWORD *lastsynctick)
+{
+ DSoundRenderImpl *This = (DSoundRenderImpl *)iface;
+
+ /* Our pins are static, not changing so setting static tick count is ok */
+ *lastsynctick = 0;
+
+ if (pos >= 1)
+ return S_FALSE;
+
+ *pin = (IPin *)This->pInputPin;
+ IPin_AddRef(*pin);
+ return S_OK;
+}
+
static HRESULT WINAPI DSoundRender_EnumPins(IBaseFilter * iface, IEnumPins **ppEnum)
{
- ENUMPINDETAILS epd;
DSoundRenderImpl *This = (DSoundRenderImpl *)iface;
TRACE("(%p/%p)->(%p)\n", This, iface, ppEnum);
- epd.cPins = 1; /* input pin */
- epd.ppPins = This->ppPins;
- return IEnumPinsImpl_Construct(&epd, ppEnum);
+ return IEnumPinsImpl_Construct(ppEnum, DSoundRender_GetPin, iface);
}
static HRESULT WINAPI DSoundRender_FindPin(IBaseFilter * iface, LPCWSTR Id, IPin **ppPin)
diff --git a/dlls/quartz/enumpins.c b/dlls/quartz/enumpins.c
index 675ef5c..82dac9d 100644
--- a/dlls/quartz/enumpins.c
+++ b/dlls/quartz/enumpins.c
@@ -28,13 +28,15 @@
{
const IEnumPinsVtbl * lpVtbl;
LONG refCount;
- ENUMPINDETAILS enumPinDetails;
ULONG uIndex;
+ IBaseFilter *base;
+ FNOBTAINPIN receive_pin;
+ DWORD synctime;
} IEnumPinsImpl;
static const struct IEnumPinsVtbl IEnumPinsImpl_Vtbl;
-HRESULT IEnumPinsImpl_Construct(const ENUMPINDETAILS * pDetails, IEnumPins ** ppEnum)
+HRESULT IEnumPinsImpl_Construct(IEnumPins ** ppEnum, FNOBTAINPIN receive_pin, IBaseFilter *base)
{
IEnumPinsImpl * pEnumPins;
@@ -50,9 +52,13 @@
pEnumPins->lpVtbl = &IEnumPinsImpl_Vtbl;
pEnumPins->refCount = 1;
pEnumPins->uIndex = 0;
- pEnumPins->enumPinDetails = *pDetails;
+ pEnumPins->receive_pin = receive_pin;
+ pEnumPins->base = base;
+ IBaseFilter_AddRef(base);
*ppEnum = (IEnumPins *)(&pEnumPins->lpVtbl);
+ receive_pin(base, ~0, NULL, &pEnumPins->synctime);
+
TRACE("Created new enumerator (%p)\n", *ppEnum);
return S_OK;
}
@@ -95,9 +101,10 @@
ULONG refCount = InterlockedDecrement(&This->refCount);
TRACE("(%p)->() Release from %d\n", This, refCount + 1);
-
+
if (!refCount)
{
+ IBaseFilter_Release(This->base);
CoTaskMemFree(This);
return 0;
}
@@ -107,10 +114,10 @@
static HRESULT WINAPI IEnumPinsImpl_Next(IEnumPins * iface, ULONG cPins, IPin ** ppPins, ULONG * pcFetched)
{
- ULONG cFetched;
IEnumPinsImpl *This = (IEnumPinsImpl *)iface;
-
- cFetched = min(This->enumPinDetails.cPins, This->uIndex + cPins) - This->uIndex;
+ DWORD synctime = This->synctime;
+ HRESULT hr = S_OK;
+ ULONG i = 0;
TRACE("(%u, %p, %p)\n", cPins, ppPins, pcFetched);
@@ -120,21 +127,28 @@
if (cPins > 1 && !pcFetched)
return E_INVALIDARG;
- if (cFetched > 0)
+ if (pcFetched)
+ *pcFetched = 0;
+
+ while (i < cPins && hr == S_OK)
{
- ULONG i;
- for (i = 0; i < cFetched; i++) {
- IPin_AddRef(This->enumPinDetails.ppPins[This->uIndex + i]);
- ppPins[i] = This->enumPinDetails.ppPins[This->uIndex + i];
- }
+ hr = This->receive_pin(This->base, This->uIndex + i, &ppPins[i], &synctime);
+
+ if (hr == S_OK)
+ ++i;
+
+ if (synctime != This->synctime)
+ break;
}
- if ((cPins != 1) || pcFetched)
- *pcFetched = cFetched;
+ if (!i && synctime != This->synctime)
+ return VFW_E_ENUM_OUT_OF_SYNC;
- This->uIndex += cFetched;
+ if (pcFetched)
+ *pcFetched = i;
+ This->uIndex += i;
- if (cFetched != cPins)
+ if (i < cPins)
return S_FALSE;
return S_OK;
}
@@ -142,15 +156,23 @@
static HRESULT WINAPI IEnumPinsImpl_Skip(IEnumPins * iface, ULONG cPins)
{
IEnumPinsImpl *This = (IEnumPinsImpl *)iface;
+ DWORD synctime = This->synctime;
+ HRESULT hr;
+ IPin *pin = NULL;
TRACE("(%u)\n", cPins);
- if (This->uIndex + cPins < This->enumPinDetails.cPins)
- {
+ hr = This->receive_pin(This->base, This->uIndex + cPins, &pin, &synctime);
+ if (pin)
+ IPin_Release(pin);
+
+ if (synctime != This->synctime)
+ return VFW_E_ENUM_OUT_OF_SYNC;
+
+ if (hr == S_OK)
This->uIndex += cPins;
- return S_OK;
- }
- return S_FALSE;
+
+ return hr;
}
static HRESULT WINAPI IEnumPinsImpl_Reset(IEnumPins * iface)
@@ -158,6 +180,7 @@
IEnumPinsImpl *This = (IEnumPinsImpl *)iface;
TRACE("IEnumPinsImpl::Reset()\n");
+ This->receive_pin(This->base, ~0, NULL, &This->synctime);
This->uIndex = 0;
return S_OK;
@@ -170,7 +193,7 @@
TRACE("(%p)\n", ppEnum);
- hr = IEnumPinsImpl_Construct(&This->enumPinDetails, ppEnum);
+ hr = IEnumPinsImpl_Construct(ppEnum, This->receive_pin, This->base);
if (FAILED(hr))
return hr;
return IEnumPins_Skip(*ppEnum, This->uIndex);
diff --git a/dlls/quartz/filesource.c b/dlls/quartz/filesource.c
index 4519fdf..a44de7a 100644
--- a/dlls/quartz/filesource.c
+++ b/dlls/quartz/filesource.c
@@ -46,6 +46,7 @@
FILTER_INFO filterInfo;
FILTER_STATE state;
CRITICAL_SECTION csFilter;
+ DWORD lastpinchange;
IPin * pOutputPin;
LPOLESTR pszFileName;
@@ -353,6 +354,7 @@
pAsyncRead->filterInfo.achName[0] = '\0';
pAsyncRead->filterInfo.pGraph = NULL;
pAsyncRead->pOutputPin = NULL;
+ pAsyncRead->lastpinchange = GetTickCount();
InitializeCriticalSection(&pAsyncRead->csFilter);
pAsyncRead->csFilter.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": AsyncReader.csFilter");
@@ -520,16 +522,28 @@
/** IBaseFilter methods **/
-static HRESULT WINAPI AsyncReader_EnumPins(IBaseFilter * iface, IEnumPins **ppEnum)
+static HRESULT AsyncReader_GetPin(IBaseFilter *iface, ULONG pos, IPin **pin, DWORD *lastsynctick)
{
- ENUMPINDETAILS epd;
AsyncReader *This = (AsyncReader *)iface;
- TRACE("(%p)\n", ppEnum);
+ /* Our pins are almost static, not changing so setting static tick count is ok */
+ *lastsynctick = This->lastpinchange;
- epd.cPins = This->pOutputPin ? 1 : 0;
- epd.ppPins = &This->pOutputPin;
- return IEnumPinsImpl_Construct(&epd, ppEnum);
+ if (pos >= 1)
+ return S_FALSE;
+
+ *pin = (IPin *)This->pOutputPin;
+ IPin_AddRef(*pin);
+ return S_OK;
+}
+
+static HRESULT WINAPI AsyncReader_EnumPins(IBaseFilter * iface, IEnumPins **ppEnum)
+{
+ AsyncReader *This = (AsyncReader *)iface;
+
+ TRACE("(%p/%p)->(%p)\n", This, iface, ppEnum);
+
+ return IEnumPinsImpl_Construct(ppEnum, AsyncReader_GetPin, iface);
}
static HRESULT WINAPI AsyncReader_FindPin(IBaseFilter * iface, LPCWSTR Id, IPin **ppPin)
@@ -636,6 +650,7 @@
/* create pin */
hr = FileAsyncReader_Construct(hFile, (IBaseFilter *)&This->lpVtbl, &This->csFilter, &This->pOutputPin);
+ This->lastpinchange = GetTickCount();
if (SUCCEEDED(hr))
hr = IPin_QueryInterface(This->pOutputPin, &IID_IAsyncReader, (LPVOID *)&pReader);
diff --git a/dlls/quartz/nullrenderer.c b/dlls/quartz/nullrenderer.c
index f511a7b..4bf2c84 100644
--- a/dlls/quartz/nullrenderer.c
+++ b/dlls/quartz/nullrenderer.c
@@ -61,7 +61,6 @@
FILTER_INFO filterInfo;
InputPin *pInputPin;
- IPin ** ppPins;
IUnknown * pUnkOuter;
BOOL bUnkOuterValid;
BOOL bAggregatable;
@@ -194,8 +193,6 @@
pNullRenderer->pClock = NULL;
ZeroMemory(&pNullRenderer->filterInfo, sizeof(FILTER_INFO));
- pNullRenderer->ppPins = CoTaskMemAlloc(1 * sizeof(IPin *));
-
/* construct input pin */
piInput.dir = PINDIR_INPUT;
piInput.pFilter = (IBaseFilter *)pNullRenderer;
@@ -205,7 +202,6 @@
if (SUCCEEDED(hr))
{
- pNullRenderer->ppPins[0] = (IPin *)pNullRenderer->pInputPin;
MediaSeekingImpl_Init((IBaseFilter*)pNullRenderer, NullRendererImpl_Change, NullRendererImpl_Change, NullRendererImpl_Change, &pNullRenderer->mediaSeeking, &pNullRenderer->csFilter);
pNullRenderer->mediaSeeking.lpVtbl = &TransformFilter_Seeking_Vtbl;
@@ -213,7 +209,6 @@
}
else
{
- CoTaskMemFree(pNullRenderer->ppPins);
pNullRenderer->csFilter.DebugInfo->Spare[0] = 0;
DeleteCriticalSection(&pNullRenderer->csFilter);
CoTaskMemFree(pNullRenderer);
@@ -279,15 +274,15 @@
if (This->pClock)
IReferenceClock_Release(This->pClock);
- if (SUCCEEDED(IPin_ConnectedTo(This->ppPins[0], &pConnectedTo)))
+ if (SUCCEEDED(IPin_ConnectedTo((IPin *)This->pInputPin, &pConnectedTo)))
{
IPin_Disconnect(pConnectedTo);
IPin_Release(pConnectedTo);
}
- IPin_Disconnect(This->ppPins[0]);
- IPin_Release(This->ppPins[0]);
+ IPin_Disconnect((IPin *)This->pInputPin);
+ IPin_Release((IPin *)This->pInputPin);
- CoTaskMemFree(This->ppPins);
+ CoTaskMemFree((IPin *)This->pInputPin);
This->lpVtbl = NULL;
This->csFilter.DebugInfo->Spare[0] = 0;
@@ -473,16 +468,28 @@
/** IBaseFilter implementation **/
+static HRESULT NullRenderer_GetPin(IBaseFilter *iface, ULONG pos, IPin **pin, DWORD *lastsynctick)
+{
+ NullRendererImpl *This = (NullRendererImpl *)iface;
+
+ /* Our pins are static, not changing so setting static tick count is ok */
+ *lastsynctick = 0;
+
+ if (pos >= 1)
+ return S_FALSE;
+
+ *pin = (IPin *)This->pInputPin;
+ IPin_AddRef(*pin);
+ return S_OK;
+}
+
static HRESULT WINAPI NullRenderer_EnumPins(IBaseFilter * iface, IEnumPins **ppEnum)
{
- ENUMPINDETAILS epd;
NullRendererImpl *This = (NullRendererImpl *)iface;
TRACE("(%p/%p)->(%p)\n", This, iface, ppEnum);
- epd.cPins = 1; /* input pin */
- epd.ppPins = This->ppPins;
- return IEnumPinsImpl_Construct(&epd, ppEnum);
+ return IEnumPinsImpl_Construct(ppEnum, NullRenderer_GetPin, iface);
}
static HRESULT WINAPI NullRenderer_FindPin(IBaseFilter * iface, LPCWSTR Id, IPin **ppPin)
diff --git a/dlls/quartz/parser.c b/dlls/quartz/parser.c
index 23eb9f2..7a7f9ba 100644
--- a/dlls/quartz/parser.c
+++ b/dlls/quartz/parser.c
@@ -68,6 +68,7 @@
pParser->fnDisconnect = fnDisconnect;
ZeroMemory(&pParser->filterInfo, sizeof(FILTER_INFO));
+ pParser->lastpinchange = GetTickCount();
pParser->cStreams = 0;
pParser->ppPins = CoTaskMemAlloc(1 * sizeof(IPin *));
@@ -377,16 +378,30 @@
/** IBaseFilter implementation **/
-HRESULT WINAPI Parser_EnumPins(IBaseFilter * iface, IEnumPins **ppEnum)
+static HRESULT Parser_GetPin(IBaseFilter *iface, ULONG pos, IPin **pin, DWORD *lastsynctick)
{
- ENUMPINDETAILS epd;
ParserImpl *This = (ParserImpl *)iface;
- TRACE("(%p)\n", ppEnum);
+ *lastsynctick = This->lastpinchange;
- epd.cPins = This->cStreams + 1; /* +1 for input pin */
- epd.ppPins = This->ppPins;
- return IEnumPinsImpl_Construct(&epd, ppEnum);
+ TRACE("Asking for pos %x\n", pos);
+
+ /* Input pin also has a pin, hence the > and not >= */
+ if (pos > This->cStreams)
+ return S_FALSE;
+
+ *pin = This->ppPins[pos];
+ IPin_AddRef(*pin);
+ return S_OK;
+}
+
+HRESULT WINAPI Parser_EnumPins(IBaseFilter * iface, IEnumPins **ppEnum)
+{
+ ParserImpl *This = (ParserImpl *)iface;
+
+ TRACE("(%p/%p)->(%p)\n", This, iface, ppEnum);
+
+ return IEnumPinsImpl_Construct(ppEnum, Parser_GetPin, iface);
}
HRESULT WINAPI Parser_FindPin(IBaseFilter * iface, LPCWSTR Id, IPin **ppPin)
@@ -463,6 +478,7 @@
pin->pin.pin.pinInfo.pFilter = (LPVOID)This;
pin->pin.custom_allocator = 1;
This->cStreams++;
+ This->lastpinchange = GetTickCount();
CoTaskMemFree(ppOldPins);
}
else
@@ -493,6 +509,7 @@
}
This->cStreams = 0;
+ This->lastpinchange = GetTickCount();
CoTaskMemFree(ppOldPins);
return S_OK;
diff --git a/dlls/quartz/parser.h b/dlls/quartz/parser.h
index 5e056d5..6fda5e3 100644
--- a/dlls/quartz/parser.h
+++ b/dlls/quartz/parser.h
@@ -43,6 +43,7 @@
PullPin * pInputPin;
IPin ** ppPins;
ULONG cStreams;
+ DWORD lastpinchange;
MediaSeekingImpl mediaSeeking;
};
diff --git a/dlls/quartz/quartz_private.h b/dlls/quartz/quartz_private.h
index 9f92ad6..9eb1630 100644
--- a/dlls/quartz/quartz_private.h
+++ b/dlls/quartz/quartz_private.h
@@ -61,19 +61,15 @@
HRESULT EnumMonikerImpl_Create(IMoniker ** ppMoniker, ULONG nMonikerCount, IEnumMoniker ** ppEnum);
-typedef struct tagENUMPINDETAILS
-{
- ULONG cPins;
- IPin ** ppPins;
-} ENUMPINDETAILS;
-
typedef struct tagENUMEDIADETAILS
{
ULONG cMediaTypes;
AM_MEDIA_TYPE * pMediaTypes;
} ENUMMEDIADETAILS;
-HRESULT IEnumPinsImpl_Construct(const ENUMPINDETAILS * pDetails, IEnumPins ** ppEnum);
+typedef HRESULT (* FNOBTAINPIN)(IBaseFilter *iface, ULONG pos, IPin **pin, DWORD *lastsynctick);
+
+HRESULT IEnumPinsImpl_Construct(IEnumPins ** ppEnum, FNOBTAINPIN receive_pin, IBaseFilter *base);
HRESULT IEnumMediaTypesImpl_Construct(const ENUMMEDIADETAILS * pDetails, IEnumMediaTypes ** ppEnum);
HRESULT IEnumRegFiltersImpl_Construct(REGFILTER * pInRegFilters, const ULONG size, IEnumRegFilters ** ppEnum);
HRESULT IEnumFiltersImpl_Construct(IBaseFilter ** ppFilters, ULONG nFilters, IEnumFilters ** ppEnum);
diff --git a/dlls/quartz/transform.c b/dlls/quartz/transform.c
index 2596f63..7f50268 100644
--- a/dlls/quartz/transform.c
+++ b/dlls/quartz/transform.c
@@ -434,16 +434,28 @@
/** IBaseFilter implementation **/
+static HRESULT TransformFilter_GetPin(IBaseFilter *iface, ULONG pos, IPin **pin, DWORD *lastsynctick)
+{
+ TransformFilterImpl *This = (TransformFilterImpl *)iface;
+
+ /* Our pins are static, not changing so setting static tick count is ok */
+ *lastsynctick = 0;
+
+ if (pos >= 2)
+ return S_FALSE;
+
+ *pin = This->ppPins[pos];
+ IPin_AddRef(*pin);
+ return S_OK;
+}
+
static HRESULT WINAPI TransformFilter_EnumPins(IBaseFilter * iface, IEnumPins **ppEnum)
{
- ENUMPINDETAILS epd;
TransformFilterImpl *This = (TransformFilterImpl *)iface;
TRACE("(%p/%p)->(%p)\n", This, iface, ppEnum);
- epd.cPins = 2; /* input and output pins */
- epd.ppPins = This->ppPins;
- return IEnumPinsImpl_Construct(&epd, ppEnum);
+ return IEnumPinsImpl_Construct(ppEnum, TransformFilter_GetPin, iface);
}
static HRESULT WINAPI TransformFilter_FindPin(IBaseFilter * iface, LPCWSTR Id, IPin **ppPin)
diff --git a/dlls/quartz/videorenderer.c b/dlls/quartz/videorenderer.c
index 97bb825..f009eda 100644
--- a/dlls/quartz/videorenderer.c
+++ b/dlls/quartz/videorenderer.c
@@ -67,8 +67,7 @@
IReferenceClock * pClock;
FILTER_INFO filterInfo;
- InputPin * pInputPin;
- IPin ** ppPins;
+ InputPin *pInputPin;
BOOL init;
HANDLE hThread;
@@ -267,12 +266,17 @@
{
AM_MEDIA_TYPE amt;
HRESULT hr = S_OK;
+ DDSURFACEDESC sdesc;
+ int width;
+ int height;
+ LPBYTE palette = NULL;
HDC hDC;
BITMAPINFOHEADER *bmiHeader;
TRACE("%p %p %d\n", This, data, size);
- hr = IPin_ConnectionMediaType(This->ppPins[0], &amt);
+ sdesc.dwSize = sizeof(sdesc);
+ hr = IPin_ConnectionMediaType((IPin *)This->pInputPin, &amt);
if (FAILED(hr)) {
ERR("Unable to retrieve media type\n");
return hr;
@@ -301,6 +305,10 @@
TRACE("biCompression = %s\n", debugstr_an((LPSTR)&(bmiHeader->biCompression), 4));
TRACE("biSizeImage = %d\n", bmiHeader->biSizeImage);
+ width = bmiHeader->biWidth;
+ height = bmiHeader->biHeight;
+ palette = ((LPBYTE)bmiHeader) + bmiHeader->biSize;
+
if (!This->init)
{
if (!This->WindowPos.right || !This->WindowPos.bottom)
@@ -384,7 +392,7 @@
TRACE("\n");
}
#endif
-
+
VideoRenderer_SendSampleData(This, pbSrcStream, cbSrcStream);
return S_OK;
@@ -458,8 +466,6 @@
pVideoRenderer->AutoShow = 1;
ZeroMemory(&pVideoRenderer->filterInfo, sizeof(FILTER_INFO));
- pVideoRenderer->ppPins = CoTaskMemAlloc(1 * sizeof(IPin *));
-
/* construct input pin */
piInput.dir = PINDIR_INPUT;
piInput.pFilter = (IBaseFilter *)pVideoRenderer;
@@ -469,12 +475,10 @@
if (SUCCEEDED(hr))
{
- pVideoRenderer->ppPins[0] = (IPin *)pVideoRenderer->pInputPin;
*ppv = (LPVOID)pVideoRenderer;
}
else
{
- CoTaskMemFree(pVideoRenderer->ppPins);
pVideoRenderer->csFilter.DebugInfo->Spare[0] = 0;
DeleteCriticalSection(&pVideoRenderer->csFilter);
CoTaskMemFree(pVideoRenderer);
@@ -556,16 +560,15 @@
if (This->pClock)
IReferenceClock_Release(This->pClock);
- if (SUCCEEDED(IPin_ConnectedTo(This->ppPins[0], &pConnectedTo)))
+ if (SUCCEEDED(IPin_ConnectedTo((IPin *)This->pInputPin, &pConnectedTo)))
{
IPin_Disconnect(pConnectedTo);
IPin_Release(pConnectedTo);
}
- IPin_Disconnect(This->ppPins[0]);
+ IPin_Disconnect((IPin *)This->pInputPin);
- IPin_Release(This->ppPins[0]);
-
- CoTaskMemFree(This->ppPins);
+ IPin_Release((IPin *)This->pInputPin);
+
This->lpVtbl = NULL;
This->csFilter.DebugInfo->Spare[0] = 0;
@@ -690,6 +693,7 @@
TRACE("(%p/%p)->(%s)\n", This, iface, wine_dbgstr_longlong(tStart));
EnterCriticalSection(&This->csFilter);
+ if (This->state != State_Running)
{
if (This->state == State_Stopped)
This->pInputPin->end_of_stream = 0;
@@ -755,16 +759,28 @@
/** IBaseFilter implementation **/
+static HRESULT VideoRenderer_GetPin(IBaseFilter *iface, ULONG pos, IPin **pin, DWORD *lastsynctick)
+{
+ VideoRendererImpl *This = (VideoRendererImpl *)iface;
+
+ /* Our pins are static, not changing so setting static tick count is ok */
+ *lastsynctick = 0;
+
+ if (pos >= 1)
+ return S_FALSE;
+
+ *pin = (IPin *)This->pInputPin;
+ IPin_AddRef(*pin);
+ return S_OK;
+}
+
static HRESULT WINAPI VideoRenderer_EnumPins(IBaseFilter * iface, IEnumPins **ppEnum)
{
- ENUMPINDETAILS epd;
VideoRendererImpl *This = (VideoRendererImpl *)iface;
TRACE("(%p/%p)->(%p)\n", This, iface, ppEnum);
- epd.cPins = 1; /* input pin */
- epd.ppPins = This->ppPins;
- return IEnumPinsImpl_Construct(&epd, ppEnum);
+ return IEnumPinsImpl_Construct(ppEnum, VideoRenderer_GetPin, iface);
}
static HRESULT WINAPI VideoRenderer_FindPin(IBaseFilter * iface, LPCWSTR Id, IPin **ppPin)
@@ -1804,7 +1820,7 @@
if ((Focus != FALSE) && (Focus != TRUE))
return E_INVALIDARG;
- hr = IPin_ConnectedTo(This->ppPins[0], &pPin);
+ hr = IPin_ConnectedTo((IPin *)This->pInputPin, &pPin);
if ((hr != S_OK) || !pPin)
return VFW_E_NOT_CONNECTED;