[DSHOW] Beginning of winestrmbase lib

Christian Costa titan.costa at wanadoo.fr
Thu Aug 4 08:29:39 CDT 2005


Hi,

This patch adds  the winestrmbase library that enables sharing code 
between all
Direct Show dlls (or other ones that implement filters).
This is similarly done in Windows by means of the strmbase (c++ classes).
Although the purpose is quite the same, we use our own APIs (that's why 
the name
is prefixed to avoid the confusion).

Changelog:
Add winestrmbase library and make quartz use it.

Christian Costa   titan.costa at wanadoo.fr

-------------- next part --------------
Index: configure.ac
===================================================================
RCS file: /home/wine/wine/configure.ac,v
retrieving revision 1.388
diff -u -r1.388 configure.ac
--- configure.ac	3 Aug 2005 19:36:51 -0000	1.388
+++ configure.ac	4 Aug 2005 12:19:19 -0000
@@ -1732,6 +1732,7 @@
 dlls/wined3d/Makefile
 dlls/winedos/Makefile
 dlls/wineps/Makefile
+dlls/winestrmbase/Makefile
 dlls/wininet/Makefile
 dlls/wininet/tests/Makefile
 dlls/winmm/Makefile
Index: dlls/quartz/Makefile.in
===================================================================
RCS file: /home/wine/wine/dlls/quartz/Makefile.in,v
retrieving revision 1.46
diff -u -r1.46 Makefile.in
--- dlls/quartz/Makefile.in	13 Jun 2005 11:37:55 -0000	1.46
+++ dlls/quartz/Makefile.in	4 Aug 2005 12:19:21 -0000
@@ -5,7 +5,7 @@
 MODULE    = quartz.dll
 IMPORTLIB = libquartz.$(IMPLIBEXT)
 IMPORTS   = dsound msacm32 msvfw32 ole32 oleaut32 user32 gdi32 advapi32 kernel32
-EXTRALIBS = -lstrmiids -luuid $(LIBUNICODE)
+EXTRALIBS = -lstrmiids -lwinestrmbase -luuid $(LIBUNICODE)
 
 C_SRCS = \
 	acmwrapper.c \
@@ -14,9 +14,7 @@
 	control.c \
 	dsoundrender.c \
 	enumfilters.c \
-	enummedia.c \
 	enummoniker.c \
-	enumpins.c \
 	enumregfilters.c \
 	filesource.c \
 	filtergraph.c \
@@ -24,7 +22,6 @@
 	main.c \
 	memallocator.c \
 	parser.c \
-	pin.c \
 	regsvr.c \
 	systemclock.c \
 	transform.c \
Index: dlls/quartz/quartz_private.h
===================================================================
RCS file: /home/wine/wine/dlls/quartz/quartz_private.h,v
retrieving revision 1.24
diff -u -r1.24 quartz_private.h
--- dlls/quartz/quartz_private.h	6 May 2005 14:34:02 -0000	1.24
+++ dlls/quartz/quartz_private.h	4 Aug 2005 12:19:22 -0000
@@ -33,11 +33,7 @@
 #include "wingdi.h"
 #include "winuser.h"
 #include "dshow.h"
-
-#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)
+#include "wine/winestreams.h"
 
 #define ICOM_THIS_MULTI(impl,field,iface) impl* const This=(impl*)((char*)(iface) - offsetof(impl,field))
 
@@ -55,31 +51,7 @@
 HRESULT WAVEParser_create(IUnknown * pUnkOuter, LPVOID * ppv);
 
 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);
-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);
-
-extern const char * qzdebugstr_guid(const GUID * id);
-extern const char * qzdebugstr_State(FILTER_STATE state);
-
-HRESULT CopyMediaType(AM_MEDIA_TYPE * pDest, const AM_MEDIA_TYPE *pSrc);
-void FreeMediaType(AM_MEDIA_TYPE * pmt);
-void DeleteMediaType(AM_MEDIA_TYPE * pmt);
-BOOL CompareMediaTypes(const AM_MEDIA_TYPE * pmt1, const AM_MEDIA_TYPE * pmt2, BOOL bWildcards);
-void dump_AM_MEDIA_TYPE(const AM_MEDIA_TYPE * pmt);
 
 #endif /* __QUARTZ_PRIVATE_INCLUDED__ */
Index: dlls/quartz/main.c
===================================================================
RCS file: /home/wine/wine/dlls/quartz/main.c,v
retrieving revision 1.48
diff -u -r1.48 main.c
--- dlls/quartz/main.c	12 Jul 2005 19:21:36 -0000	1.48
+++ dlls/quartz/main.c	4 Aug 2005 12:19:24 -0000
@@ -205,61 +205,18 @@
     return dll_ref != 0 ? S_FALSE : S_OK;
 }
 
-
-#define OUR_GUID_ENTRY(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
-    { { l, w1, w2, { b1, b2,  b3,  b4,  b5,  b6,  b7,  b8 } } , #name },
-
-static struct {
-	const GUID	riid;
-	const char 	*name;
-} InterfaceDesc[] =
-{
-#include "uuids.h"
-    { { 0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0} }, NULL }
-};
-
 /***********************************************************************
- *              qzdebugstr_guid (internal)
- *
- * Gives a text version of DirectShow GUIDs
+ *              AmpFactorToDB (QUARTZ.@)
  */
-const char * qzdebugstr_guid( const GUID * id )
-{
-    int i;
-    char * name = NULL;
-
-    for (i=0;InterfaceDesc[i].name && !name;i++) {
-        if (IsEqualGUID(&InterfaceDesc[i].riid, id)) return InterfaceDesc[i].name;
-    }
-    return debugstr_guid(id);
-}
-
-/***********************************************************************
- *              qzdebugstr_State (internal)
- *
- * Gives a text version of the FILTER_STATE enumeration
- */
-const char * qzdebugstr_State(FILTER_STATE state)
-{
-    switch (state)
-    {
-    case State_Stopped:
-        return "State_Stopped";
-    case State_Running:
-        return "State_Running";
-    case State_Paused:
-        return "State_Paused";
-    default:
-        return "State_Unknown";
-    }
-}
-
 LONG WINAPI AmpFactorToDB(LONG ampfactor)
 {
     FIXME("(%ld) Stub!\n", ampfactor);
     return 0;
 }
 
+/***********************************************************************
+ *              DBToAmpFactor (QUARTZ.@)
+ */
 LONG WINAPI DBToAmpFactor(LONG db)
 {
     FIXME("(%ld) Stub!\n", db);
Index: dlls/quartz/filesource.c
===================================================================
RCS file: /home/wine/wine/dlls/quartz/filesource.c,v
retrieving revision 1.18
diff -u -r1.18 filesource.c
--- dlls/quartz/filesource.c	27 Jul 2005 15:18:14 -0000	1.18
+++ dlls/quartz/filesource.c	4 Aug 2005 12:19:27 -0000
@@ -25,7 +25,6 @@
 
 #include "wine/debug.h"
 #include "wine/unicode.h"
-#include "pin.h"
 #include "uuids.h"
 #include "vfwmsgs.h"
 #include "winbase.h"
Index: dlls/quartz/avisplit.c
===================================================================
RCS file: /home/wine/wine/dlls/quartz/avisplit.c,v
retrieving revision 1.14
diff -u -r1.14 avisplit.c
--- dlls/quartz/avisplit.c	2 Mar 2005 10:12:12 -0000	1.14
+++ dlls/quartz/avisplit.c	4 Aug 2005 12:19:30 -0000
@@ -25,7 +25,6 @@
 
 #include "quartz_private.h"
 #include "control_private.h"
-#include "pin.h"
 
 #include "uuids.h"
 #include "aviriff.h"
Index: dlls/quartz/waveparser.c
===================================================================
RCS file: /home/wine/wine/dlls/quartz/waveparser.c,v
retrieving revision 1.3
diff -u -r1.3 waveparser.c
--- dlls/quartz/waveparser.c	28 Mar 2005 14:17:51 -0000	1.3
+++ dlls/quartz/waveparser.c	4 Aug 2005 12:19:32 -0000
@@ -20,7 +20,6 @@
 
 #include "quartz_private.h"
 #include "control_private.h"
-#include "pin.h"
 
 #include "uuids.h"
 #include "aviriff.h"
Index: dlls/quartz/avidec.c
===================================================================
RCS file: /home/wine/wine/dlls/quartz/avidec.c,v
retrieving revision 1.18
diff -u -r1.18 avidec.c
--- dlls/quartz/avidec.c	7 Jun 2005 20:29:23 -0000	1.18
+++ dlls/quartz/avidec.c	4 Aug 2005 12:19:34 -0000
@@ -22,7 +22,6 @@
 
 #include "quartz_private.h"
 #include "control_private.h"
-#include "pin.h"
 
 #include "uuids.h"
 #include "aviriff.h"
Index: dlls/quartz/acmwrapper.c
===================================================================
RCS file: /home/wine/wine/dlls/quartz/acmwrapper.c,v
retrieving revision 1.5
diff -u -r1.5 acmwrapper.c
--- dlls/quartz/acmwrapper.c	5 Jun 2005 19:18:34 -0000	1.5
+++ dlls/quartz/acmwrapper.c	4 Aug 2005 12:19:35 -0000
@@ -22,7 +22,6 @@
 
 #include "quartz_private.h"
 #include "control_private.h"
-#include "pin.h"
 
 #include "uuids.h"
 #include "mmreg.h"
Index: dlls/quartz/videorenderer.c
===================================================================
RCS file: /home/wine/wine/dlls/quartz/videorenderer.c,v
retrieving revision 1.14
diff -u -r1.14 videorenderer.c
--- dlls/quartz/videorenderer.c	12 Jul 2005 19:21:36 -0000	1.14
+++ dlls/quartz/videorenderer.c	4 Aug 2005 12:19:40 -0000
@@ -24,7 +24,6 @@
 #define NONAMELESSUNION
 #include "quartz_private.h"
 #include "control_private.h"
-#include "pin.h"
 
 #include "uuids.h"
 #include "mmreg.h"
Index: dlls/quartz/dsoundrender.c
===================================================================
RCS file: /home/wine/wine/dlls/quartz/dsoundrender.c,v
retrieving revision 1.10
diff -u -r1.10 dsoundrender.c
--- dlls/quartz/dsoundrender.c	12 Jul 2005 19:21:36 -0000	1.10
+++ dlls/quartz/dsoundrender.c	4 Aug 2005 12:19:42 -0000
@@ -22,7 +22,6 @@
 
 #include "quartz_private.h"
 #include "control_private.h"
-#include "pin.h"
 
 #include "uuids.h"
 #include "mmreg.h"
Index: dlls/quartz/parser.c
===================================================================
RCS file: /home/wine/wine/dlls/quartz/parser.c,v
retrieving revision 1.18
diff -u -r1.18 parser.c
--- dlls/quartz/parser.c	27 Jul 2005 15:18:14 -0000	1.18
+++ dlls/quartz/parser.c	4 Aug 2005 12:19:45 -0000
@@ -21,7 +21,6 @@
 
 #include "quartz_private.h"
 #include "control_private.h"
-#include "pin.h"
 
 #include "uuids.h"
 #include "aviriff.h"
Index: dlls/quartz/transform.c
===================================================================
RCS file: /home/wine/wine/dlls/quartz/transform.c,v
retrieving revision 1.6
diff -u -r1.6 transform.c
--- dlls/quartz/transform.c	20 Jun 2005 18:39:40 -0000	1.6
+++ dlls/quartz/transform.c	4 Aug 2005 12:19:47 -0000
@@ -22,7 +22,6 @@
 
 #include "quartz_private.h"
 #include "control_private.h"
-#include "pin.h"
 
 #include "uuids.h"
 #include "aviriff.h"
--- dlls/quartz/pin.c	2005-07-29 18:31:40.000000000 +0100
+++ /dev/null	1970-01-01 01:00:00.000000000 +0100
@@ -1,1369 +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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include "quartz_private.h"
-#include "pin.h"
-
-#include "wine/debug.h"
-#include "wine/unicode.h"
-#include "uuids.h"
-#include "vfwmsgs.h"
-#include <assert.h>
-
-WINE_DEFAULT_DEBUG_CHANNEL(quartz);
-
-static const IPinVtbl InputPin_Vtbl;
-static const IPinVtbl OutputPin_Vtbl;
-static const IMemInputPinVtbl MemInputPin_Vtbl;
-static const IPinVtbl PullPin_Vtbl;
-
-#define ALIGNDOWN(value,boundary) ((value) & ~(boundary-1))
-#define ALIGNUP(value,boundary) (ALIGNDOWN(value - 1, boundary) + boundary)
-
-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)
-{
-    /* Tempting to just do a memcpy, but the name field is
-       128 characters long! We will probably never exceed 10
-       most of the time, so we are better off copying 
-       each field manually */
-    strcpyW(pDest->achName, pSrc->achName);
-    pDest->dir = pSrc->dir;
-    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))
-    {
-        hr = IPin_QueryInterface(pReceivePin, &IID_IMemInputPin, (LPVOID)&This->pMemInputPin);
-
-        if (SUCCEEDED(hr))
-            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 = IMemInputPin_NotifyAllocator(This->pMemInputPin, pMemAlloc, FALSE);
-            }
-        }
-
-        if (SUCCEEDED(hr))
-            hr = IMemAllocator_SetProperties(pMemAlloc, &This->allocProps, &actual);
-
-        if (pMemAlloc)
-            IMemAllocator_Release(pMemAlloc);
-
-        /* break connection if we couldn't get the allocator */
-        if (FAILED(hr))
-            IPin_Disconnect(pReceivePin);
-    }
-
-    if (FAILED(hr))
-    {
-        IPin_Release(This->pin.pConnectedTo);
-        This->pin.pConnectedTo = NULL;
-        FreeMediaType(&This->pin.mtCurrent);
-    }
-
-    TRACE(" -- %lx\n", hr);
-    return hr;
-}
-
-HRESULT InputPin_Construct(const PIN_INFO * pPinInfo, SAMPLEPROC pSampleProc, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, LPCRITICAL_SECTION pCritSec, IPin ** ppPin)
-{
-    InputPin * pPinImpl;
-
-    *ppPin = NULL;
-
-    if (pPinInfo->dir != PINDIR_INPUT)
-    {
-        ERR("Pin direction(%x) != PINDIR_INPUT\n", pPinInfo->dir);
-        return E_INVALIDARG;
-    }
-
-    pPinImpl = CoTaskMemAlloc(sizeof(*pPinImpl));
-
-    if (!pPinImpl)
-        return E_OUTOFMEMORY;
-
-    if (SUCCEEDED(InputPin_Init(pPinInfo, pSampleProc, pUserData, pQueryAccept, pCritSec, pPinImpl)))
-    {
-        pPinImpl->pin.lpVtbl = &InputPin_Vtbl;
-        pPinImpl->lpVtblMemInput = &MemInputPin_Vtbl;
-        
-        *ppPin = (IPin *)(&pPinImpl->pin.lpVtbl);
-        return S_OK;
-    }
-    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");
-
-    /* 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->pAllocator = NULL;
-    pPinImpl->tStart = 0;
-    pPinImpl->tStop = 0;
-    pPinImpl->dRate = 0;
-
-    return S_OK;
-}
-
-HRESULT OutputPin_Init(const PIN_INFO * pPinInfo, 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 (props)
-    {
-        memcpy(&pPinImpl->allocProps, props, sizeof(pPinImpl->allocProps));
-        if (pPinImpl->allocProps.cbAlign == 0)
-            pPinImpl->allocProps.cbAlign = 1;
-    }
-    else
-        ZeroMemory(&pPinImpl->allocProps, sizeof(pPinImpl->allocProps));
-
-    return S_OK;
-}
-
-HRESULT OutputPin_Construct(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;
-    }
-
-    pPinImpl = CoTaskMemAlloc(sizeof(*pPinImpl));
-
-    if (!pPinImpl)
-        return E_OUTOFMEMORY;
-
-    if (SUCCEEDED(OutputPin_Init(pPinInfo, props, pUserData, pQueryAccept, pCritSec, pPinImpl)))
-    {
-        pPinImpl->pin.lpVtbl = &OutputPin_Vtbl;
-        
-        *ppPin = (IPin *)(&pPinImpl->pin.lpVtbl);
-        return S_OK;
-    }
-    return E_FAIL;
-}
-
-/*** Common pin functions ***/
-
-ULONG WINAPI IPinImpl_AddRef(IPin * iface)
-{
-    IPinImpl *This = (IPinImpl *)iface;
-    ULONG refCount = InterlockedIncrement(&This->refCount);
-    
-    TRACE("(%p)->() AddRef from %ld\n", iface, refCount - 1);
-    
-    return refCount;
-}
-
-HRESULT WINAPI IPinImpl_Disconnect(IPin * iface)
-{
-    HRESULT hr;
-    IPinImpl *This = (IPinImpl *)iface;
-
-    TRACE("()\n");
-
-    EnterCriticalSection(This->pCritSec);
-    {
-        if (This->pConnectedTo)
-        {
-            IPin_Release(This->pConnectedTo);
-            This->pConnectedTo = NULL;
-            hr = S_OK;
-        }
-        else
-            hr = S_FALSE;
-    }
-    LeaveCriticalSection(This->pCritSec);
-    
-    return hr;
-}
-
-HRESULT WINAPI IPinImpl_ConnectedTo(IPin * iface, IPin ** ppPin)
-{
-    HRESULT hr;
-    IPinImpl *This = (IPinImpl *)iface;
-
-/*  TRACE("(%p)\n", ppPin);*/
-
-    EnterCriticalSection(This->pCritSec);
-    {
-        if (This->pConnectedTo)
-        {
-            *ppPin = This->pConnectedTo;
-            IPin_AddRef(*ppPin);
-            hr = S_OK;
-        }
-        else
-            hr = VFW_E_NOT_CONNECTED;
-    }
-    LeaveCriticalSection(This->pCritSec);
-
-    return hr;
-}
-
-HRESULT WINAPI IPinImpl_ConnectionMediaType(IPin * iface, AM_MEDIA_TYPE * pmt)
-{
-    HRESULT hr;
-    IPinImpl *This = (IPinImpl *)iface;
-
-    TRACE("(%p/%p)->(%p)\n", This, iface, pmt);
-
-    EnterCriticalSection(This->pCritSec);
-    {
-        if (This->pConnectedTo)
-        {
-            CopyMediaType(pmt, &This->mtCurrent);
-            hr = S_OK;
-        }
-        else
-        {
-            ZeroMemory(pmt, sizeof(*pmt));
-            hr = VFW_E_NOT_CONNECTED;
-        }
-    }
-    LeaveCriticalSection(This->pCritSec);
-
-    return hr;
-}
-
-HRESULT WINAPI IPinImpl_QueryPinInfo(IPin * iface, PIN_INFO * pInfo)
-{
-    IPinImpl *This = (IPinImpl *)iface;
-
-    TRACE("(%p/%p)->(%p)\n", This, iface, pInfo);
-
-    Copy_PinInfo(pInfo, &This->pinInfo);
-    IBaseFilter_AddRef(pInfo->pFilter);
-
-    return S_OK;
-}
-
-HRESULT WINAPI IPinImpl_QueryDirection(IPin * iface, PIN_DIRECTION * pPinDir)
-{
-    IPinImpl *This = (IPinImpl *)iface;
-
-    TRACE("(%p/%p)->(%p)\n", This, iface, pPinDir);
-
-    *pPinDir = This->pinInfo.dir;
-
-    return S_OK;
-}
-
-HRESULT WINAPI IPinImpl_QueryId(IPin * iface, LPWSTR * Id)
-{
-    IPinImpl *This = (IPinImpl *)iface;
-
-    TRACE("(%p/%p)->(%p)\n", This, iface, Id);
-
-    *Id = CoTaskMemAlloc((strlenW(This->pinInfo.achName) + 1) * sizeof(WCHAR));
-    if (!Id)
-        return E_OUTOFMEMORY;
-
-    strcpyW(*Id, This->pinInfo.achName);
-
-    return S_OK;
-}
-
-HRESULT WINAPI IPinImpl_QueryAccept(IPin * iface, const AM_MEDIA_TYPE * pmt)
-{
-    IPinImpl *This = (IPinImpl *)iface;
-
-    TRACE("(%p/%p)->(%p)\n", This, iface, pmt);
-
-    return (This->fnQueryAccept(This->pUserData, pmt) == S_OK ? S_OK : S_FALSE);
-}
-
-HRESULT WINAPI IPinImpl_EnumMediaTypes(IPin * iface, IEnumMediaTypes ** ppEnum)
-{
-    IPinImpl *This = (IPinImpl *)iface;
-    ENUMMEDIADETAILS emd;
-
-    TRACE("(%p/%p)->(%p)\n", This, iface, ppEnum);
-
-    /* override this method to allow enumeration of your types */
-    emd.cMediaTypes = 0;
-    emd.pMediaTypes = NULL;
-
-    return IEnumMediaTypesImpl_Construct(&emd, ppEnum);
-}
-
-HRESULT WINAPI IPinImpl_QueryInternalConnections(IPin * iface, IPin ** apPin, ULONG * cPin)
-{
-    IPinImpl *This = (IPinImpl *)iface;
-
-    TRACE("(%p/%p)->(%p, %p)\n", This, iface, apPin, cPin);
-
-    return E_NOTIMPL; /* to tell caller that all input pins connected to all output pins */
-}
-
-/*** IPin implementation for an input pin ***/
-
-HRESULT WINAPI InputPin_QueryInterface(IPin * iface, REFIID riid, LPVOID * ppv)
-{
-    InputPin *This = (InputPin *)iface;
-
-    TRACE("(%p)->(%s, %p)\n", iface, qzdebugstr_guid(riid), ppv);
-
-    *ppv = NULL;
-
-    if (IsEqualIID(riid, &IID_IUnknown))
-        *ppv = (LPVOID)iface;
-    else if (IsEqualIID(riid, &IID_IPin))
-        *ppv = (LPVOID)iface;
-    else if (IsEqualIID(riid, &IID_IMemInputPin))
-        *ppv = (LPVOID)&This->lpVtblMemInput;
-
-    if (*ppv)
-    {
-        IUnknown_AddRef((IUnknown *)(*ppv));
-        return S_OK;
-    }
-
-    FIXME("No interface for %s!\n", qzdebugstr_guid(riid));
-
-    return E_NOINTERFACE;
-}
-
-ULONG WINAPI InputPin_Release(IPin * iface)
-{
-    InputPin *This = (InputPin *)iface;
-    ULONG refCount = InterlockedDecrement(&This->pin.refCount);
-    
-    TRACE("(%p)->() Release from %ld\n", iface, refCount + 1);
-    
-    if (!refCount)
-    {
-        FreeMediaType(&This->pin.mtCurrent);
-        if (This->pAllocator)
-            IMemAllocator_Release(This->pAllocator);
-        CoTaskMemFree(This);
-        return 0;
-    }
-    else
-        return refCount;
-}
-
-HRESULT WINAPI InputPin_Connect(IPin * iface, IPin * pConnector, const AM_MEDIA_TYPE * pmt)
-{
-    ERR("Outgoing connection on an input pin! (%p, %p)\n", pConnector, pmt);
-
-    return E_UNEXPECTED;
-}
-
-
-HRESULT WINAPI InputPin_ReceiveConnection(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt)
-{
-    InputPin *This = (InputPin *)iface;
-    PIN_DIRECTION pindirReceive;
-    HRESULT hr = S_OK;
-
-    TRACE("(%p, %p)\n", pReceivePin, pmt);
-    dump_AM_MEDIA_TYPE(pmt);
-
-    EnterCriticalSection(This->pin.pCritSec);
-    {
-        if (This->pin.pConnectedTo)
-            hr = VFW_E_ALREADY_CONNECTED;
-
-        if (SUCCEEDED(hr) && This->pin.fnQueryAccept(This->pin.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;
-            }
-        }
-
-        if (SUCCEEDED(hr))
-        {
-            CopyMediaType(&This->pin.mtCurrent, pmt);
-            This->pin.pConnectedTo = pReceivePin;
-            IPin_AddRef(pReceivePin);
-        }
-    }
-    LeaveCriticalSection(This->pin.pCritSec);
-
-    return hr;
-}
-
-HRESULT WINAPI InputPin_EndOfStream(IPin * iface)
-{
-    TRACE("()\n");
-
-    return S_OK;
-}
-
-HRESULT WINAPI InputPin_BeginFlush(IPin * iface)
-{
-    FIXME("()\n");
-    return E_NOTIMPL;
-}
-
-HRESULT WINAPI InputPin_EndFlush(IPin * iface)
-{
-    FIXME("()\n");
-    return E_NOTIMPL;
-}
-
-HRESULT WINAPI InputPin_NewSegment(IPin * iface, REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate)
-{
-    InputPin *This = (InputPin *)iface;
-
-    TRACE("(%lx%08lx, %lx%08lx, %e)\n", (ULONG)(tStart >> 32), (ULONG)tStart, (ULONG)(tStop >> 32), (ULONG)tStop, dRate);
-
-    This->tStart = tStart;
-    This->tStop = tStop;
-    This->dRate = dRate;
-
-    return S_OK;
-}
-
-static const IPinVtbl InputPin_Vtbl = 
-{
-    InputPin_QueryInterface,
-    IPinImpl_AddRef,
-    InputPin_Release,
-    InputPin_Connect,
-    InputPin_ReceiveConnection,
-    IPinImpl_Disconnect,
-    IPinImpl_ConnectedTo,
-    IPinImpl_ConnectionMediaType,
-    IPinImpl_QueryPinInfo,
-    IPinImpl_QueryDirection,
-    IPinImpl_QueryId,
-    IPinImpl_QueryAccept,
-    IPinImpl_EnumMediaTypes,
-    IPinImpl_QueryInternalConnections,
-    InputPin_EndOfStream,
-    InputPin_BeginFlush,
-    InputPin_EndFlush,
-    InputPin_NewSegment
-};
-
-/*** IMemInputPin implementation ***/
-
-HRESULT WINAPI MemInputPin_QueryInterface(IMemInputPin * iface, REFIID riid, LPVOID * ppv)
-{
-    InputPin *This = impl_from_IMemInputPin(iface);
-
-    return IPin_QueryInterface((IPin *)&This->pin, riid, ppv);
-}
-
-ULONG WINAPI MemInputPin_AddRef(IMemInputPin * iface)
-{
-    InputPin *This = impl_from_IMemInputPin(iface);
-
-    return IPin_AddRef((IPin *)&This->pin);
-}
-
-ULONG WINAPI MemInputPin_Release(IMemInputPin * iface)
-{
-    InputPin *This = impl_from_IMemInputPin(iface);
-
-    return IPin_Release((IPin *)&This->pin);
-}
-
-HRESULT WINAPI MemInputPin_GetAllocator(IMemInputPin * iface, IMemAllocator ** ppAllocator)
-{
-    InputPin *This = impl_from_IMemInputPin(iface);
-
-    TRACE("(%p/%p)->(%p)\n", This, iface, ppAllocator);
-
-    *ppAllocator = This->pAllocator;
-    if (*ppAllocator)
-        IMemAllocator_AddRef(*ppAllocator);
-    
-    return *ppAllocator ? S_OK : VFW_E_NO_ALLOCATOR;
-}
-
-HRESULT WINAPI MemInputPin_NotifyAllocator(IMemInputPin * iface, IMemAllocator * pAllocator, BOOL bReadOnly)
-{
-    InputPin *This = impl_from_IMemInputPin(iface);
-
-    TRACE("(%p/%p)->(%p, %d)\n", This, iface, pAllocator, bReadOnly);
-
-    if (This->pAllocator)
-        IMemAllocator_Release(This->pAllocator);
-    This->pAllocator = pAllocator;
-    if (This->pAllocator)
-        IMemAllocator_AddRef(This->pAllocator);
-
-    return S_OK;
-}
-
-HRESULT WINAPI MemInputPin_GetAllocatorRequirements(IMemInputPin * iface, ALLOCATOR_PROPERTIES * pProps)
-{
-    InputPin *This = impl_from_IMemInputPin(iface);
-
-    TRACE("(%p/%p)->(%p)\n", This, iface, pProps);
-
-    /* override this method if you have any specific requirements */
-
-    return E_NOTIMPL;
-}
-
-HRESULT WINAPI MemInputPin_Receive(IMemInputPin * iface, IMediaSample * pSample)
-{
-    InputPin *This = impl_from_IMemInputPin(iface);
-
-    /* this trace commented out for performance reasons */
-    /*TRACE("(%p/%p)->(%p)\n", This, iface, pSample);*/
-
-    return This->fnSampleProc(This->pin.pUserData, pSample);
-}
-
-HRESULT WINAPI MemInputPin_ReceiveMultiple(IMemInputPin * iface, IMediaSample ** pSamples, long nSamples, long *nSamplesProcessed)
-{
-    HRESULT hr = S_OK;
-    InputPin *This = impl_from_IMemInputPin(iface);
-
-    TRACE("(%p/%p)->(%p, %ld, %p)\n", This, iface, pSamples, nSamples, nSamplesProcessed);
-
-    for (*nSamplesProcessed = 0; *nSamplesProcessed < nSamples; (*nSamplesProcessed)++)
-    {
-        hr = IMemInputPin_Receive(iface, pSamples[*nSamplesProcessed]);
-        if (hr != S_OK)
-            break;
-    }
-
-    return hr;
-}
-
-HRESULT WINAPI MemInputPin_ReceiveCanBlock(IMemInputPin * iface)
-{
-    InputPin *This = impl_from_IMemInputPin(iface);
-
-    FIXME("(%p/%p)->()\n", This, iface);
-
-    /* FIXME: we should check whether any output pins will block */
-
-    return S_OK;
-}
-
-static const IMemInputPinVtbl MemInputPin_Vtbl = 
-{
-    MemInputPin_QueryInterface,
-    MemInputPin_AddRef,
-    MemInputPin_Release,
-    MemInputPin_GetAllocator,
-    MemInputPin_NotifyAllocator,
-    MemInputPin_GetAllocatorRequirements,
-    MemInputPin_Receive,
-    MemInputPin_ReceiveMultiple,
-    MemInputPin_ReceiveCanBlock
-};
-
-HRESULT WINAPI OutputPin_QueryInterface(IPin * iface, REFIID riid, LPVOID * ppv)
-{
-    OutputPin *This = (OutputPin *)iface;
-
-    TRACE("(%p/%p)->(%s, %p)\n", This, iface, qzdebugstr_guid(riid), ppv);
-
-    *ppv = NULL;
-
-    if (IsEqualIID(riid, &IID_IUnknown))
-        *ppv = (LPVOID)iface;
-    else if (IsEqualIID(riid, &IID_IPin))
-        *ppv = (LPVOID)iface;
-
-    if (*ppv)
-    {
-        IUnknown_AddRef((IUnknown *)(*ppv));
-        return S_OK;
-    }
-
-    FIXME("No interface for %s!\n", qzdebugstr_guid(riid));
-
-    return E_NOINTERFACE;
-}
-
-ULONG WINAPI OutputPin_Release(IPin * iface)
-{
-    OutputPin *This = (OutputPin *)iface;
-    ULONG refCount = InterlockedDecrement(&This->pin.refCount);
-    
-    TRACE("(%p)->() Release from %ld\n", iface, refCount + 1);
-    
-    if (!refCount)
-    {
-        FreeMediaType(&This->pin.mtCurrent);
-        CoTaskMemFree(This);
-        return 0;
-    }
-    return refCount;
-}
-
-HRESULT WINAPI OutputPin_Connect(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt)
-{
-    HRESULT hr;
-    OutputPin *This = (OutputPin *)iface;
-
-    TRACE("(%p/%p)->(%p, %p)\n", This, iface, pReceivePin, pmt);
-    dump_AM_MEDIA_TYPE(pmt);
-
-    /* If we try to connect to ourself, we will definitely deadlock.
-     * There are other cases where we could deadlock too, but this
-     * catches the obvious case */
-    assert(pReceivePin != iface);
-
-    EnterCriticalSection(This->pin.pCritSec);
-    {
-        /* if we have been a specific type to connect with, then we can either connect
-         * with that or fail. We cannot choose different AM_MEDIA_TYPE */
-        if (pmt && !IsEqualGUID(&pmt->majortype, &GUID_NULL) && !IsEqualGUID(&pmt->subtype, &GUID_NULL))
-            hr = This->pConnectSpecific(iface, pReceivePin, pmt);
-        else
-        {
-            /* negotiate media type */
-
-            IEnumMediaTypes * pEnumCandidates;
-            AM_MEDIA_TYPE * pmtCandidate; /* Candidate media type */
-
-            if (SUCCEEDED(hr = IPin_EnumMediaTypes(iface, &pEnumCandidates)))
-            {
-                hr = VFW_E_NO_ACCEPTABLE_TYPES; /* Assume the worst, but set to S_OK if connected successfully */
-
-                /* try this filter's media types first */
-                while (S_OK == IEnumMediaTypes_Next(pEnumCandidates, 1, &pmtCandidate, NULL))
-                {
-                    if (( !pmt || CompareMediaTypes(pmt, pmtCandidate, TRUE) ) && 
-                        (This->pConnectSpecific(iface, pReceivePin, pmtCandidate) == S_OK))
-                    {
-                        hr = S_OK;
-                        CoTaskMemFree(pmtCandidate);
-                        break;
-                    }
-                    CoTaskMemFree(pmtCandidate);
-                }
-                IEnumMediaTypes_Release(pEnumCandidates);
-            }
-
-            /* then try receiver filter's media types */
-            if (hr != S_OK && SUCCEEDED(hr = IPin_EnumMediaTypes(pReceivePin, &pEnumCandidates))) /* if we haven't already connected successfully */
-            {
-                hr = VFW_E_NO_ACCEPTABLE_TYPES; /* Assume the worst, but set to S_OK if connected successfully */
-
-                while (S_OK == IEnumMediaTypes_Next(pEnumCandidates, 1, &pmtCandidate, NULL))
-                {
-                    if (( !pmt || CompareMediaTypes(pmt, pmtCandidate, TRUE) ) && 
-                        (This->pConnectSpecific(iface, pReceivePin, pmtCandidate) == S_OK))
-                    {
-                        hr = S_OK;
-                        CoTaskMemFree(pmtCandidate);
-                        break;
-                    }
-                    CoTaskMemFree(pmtCandidate);
-                } /* while */
-                IEnumMediaTypes_Release(pEnumCandidates);
-            } /* if not found */
-        } /* if negotiate media type */
-    } /* if succeeded */
-    LeaveCriticalSection(This->pin.pCritSec);
-
-    TRACE(" -- %lx\n", hr);
-    return hr;
-}
-
-HRESULT WINAPI OutputPin_ReceiveConnection(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt)
-{
-    ERR("Incoming connection on an output pin! (%p, %p)\n", pReceivePin, pmt);
-
-    return E_UNEXPECTED;
-}
-
-HRESULT WINAPI OutputPin_Disconnect(IPin * iface)
-{
-    HRESULT hr;
-    OutputPin *This = (OutputPin *)iface;
-
-    TRACE("()\n");
-
-    EnterCriticalSection(This->pin.pCritSec);
-    {
-        if (This->pMemInputPin)
-        {
-            IMemInputPin_Release(This->pMemInputPin);
-            This->pMemInputPin = NULL;
-        }
-        if (This->pin.pConnectedTo)
-        {
-            IPin_Release(This->pin.pConnectedTo);
-            This->pin.pConnectedTo = NULL;
-            hr = S_OK;
-        }
-        else
-            hr = S_FALSE;
-    }
-    LeaveCriticalSection(This->pin.pCritSec);
-    
-    return hr;
-}
-
-HRESULT WINAPI OutputPin_EndOfStream(IPin * iface)
-{
-    TRACE("()\n");
-
-    /* not supposed to do anything in an output pin */
-
-    return E_UNEXPECTED;
-}
-
-HRESULT WINAPI OutputPin_BeginFlush(IPin * iface)
-{
-    TRACE("(%p)->()\n", iface);
-
-    /* not supposed to do anything in an output pin */
-
-    return E_UNEXPECTED;
-}
-
-HRESULT WINAPI OutputPin_EndFlush(IPin * iface)
-{
-    TRACE("(%p)->()\n", iface);
-
-    /* not supposed to do anything in an output pin */
-
-    return E_UNEXPECTED;
-}
-
-HRESULT WINAPI OutputPin_NewSegment(IPin * iface, REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate)
-{
-    TRACE("(%p)->(%lx%08lx, %lx%08lx, %e)\n", iface, (ULONG)(tStart >> 32), (ULONG)tStart, (ULONG)(tStop >> 32), (ULONG)tStop, dRate);
-
-    /* not supposed to do anything in an output pin */
-
-    return E_UNEXPECTED;
-}
-
-static const IPinVtbl OutputPin_Vtbl = 
-{
-    OutputPin_QueryInterface,
-    IPinImpl_AddRef,
-    OutputPin_Release,
-    OutputPin_Connect,
-    OutputPin_ReceiveConnection,
-    OutputPin_Disconnect,
-    IPinImpl_ConnectedTo,
-    IPinImpl_ConnectionMediaType,
-    IPinImpl_QueryPinInfo,
-    IPinImpl_QueryDirection,
-    IPinImpl_QueryId,
-    IPinImpl_QueryAccept,
-    IPinImpl_EnumMediaTypes,
-    IPinImpl_QueryInternalConnections,
-    OutputPin_EndOfStream,
-    OutputPin_BeginFlush,
-    OutputPin_EndFlush,
-    OutputPin_NewSegment
-};
-
-HRESULT OutputPin_GetDeliveryBuffer(OutputPin * This, IMediaSample ** ppSample, const REFERENCE_TIME * tStart, const REFERENCE_TIME * tStop, DWORD dwFlags)
-{
-    HRESULT hr;
-
-    TRACE("(%p, %p, %p, %lx)\n", ppSample, tStart, tStop, dwFlags);
-
-    EnterCriticalSection(This->pin.pCritSec);
-    {
-        if (!This->pin.pConnectedTo)
-            hr = VFW_E_NOT_CONNECTED;
-        else
-        {
-            IMemAllocator * pAlloc = NULL;
-            
-            hr = IMemInputPin_GetAllocator(This->pMemInputPin, &pAlloc);
-
-            if (SUCCEEDED(hr))
-                hr = IMemAllocator_GetBuffer(pAlloc, ppSample, (REFERENCE_TIME *)tStart, (REFERENCE_TIME *)tStop, dwFlags);
-
-            if (SUCCEEDED(hr))
-                hr = IMediaSample_SetTime(*ppSample, (REFERENCE_TIME *)tStart, (REFERENCE_TIME *)tStop);
-
-            if (pAlloc)
-                IMemAllocator_Release(pAlloc);
-        }
-    }
-    LeaveCriticalSection(This->pin.pCritSec);
-    
-    return hr;
-}
-
-HRESULT OutputPin_SendSample(OutputPin * This, IMediaSample * pSample)
-{
-    HRESULT hr = S_OK;
-    IMemInputPin * pMemConnected = NULL;
-
-    EnterCriticalSection(This->pin.pCritSec);
-    {
-        if (!This->pin.pConnectedTo || !This->pMemInputPin)
-            hr = VFW_E_NOT_CONNECTED;
-        else
-        {
-            /* we don't have the lock held when using This->pMemInputPin,
-             * so we need to AddRef it to stop it being deleted while we are
-             * using it. */
-            pMemConnected = This->pMemInputPin;
-            IMemInputPin_AddRef(pMemConnected);
-        }
-    }
-    LeaveCriticalSection(This->pin.pCritSec);
-
-    if (SUCCEEDED(hr))
-    {
-        /* NOTE: if we are in a critical section when Receive is called
-         * then it causes some problems (most notably with the native Video
-         * Renderer) if we are re-entered for whatever reason */
-        hr = IMemInputPin_Receive(pMemConnected, pSample);
-        IMemInputPin_Release(pMemConnected);
-    }
-    
-    return hr;
-}
-
-HRESULT OutputPin_DeliverNewSegment(OutputPin * This, REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate)
-{
-    HRESULT hr;
-
-    EnterCriticalSection(This->pin.pCritSec);
-    {
-        if (!This->pin.pConnectedTo)
-            hr = VFW_E_NOT_CONNECTED;
-        else
-            hr = IPin_NewSegment(This->pin.pConnectedTo, tStart, tStop, dRate);
-    }
-    LeaveCriticalSection(This->pin.pCritSec);
-    
-    return hr;
-}
-
-HRESULT OutputPin_CommitAllocator(OutputPin * This)
-{
-    HRESULT hr;
-
-    TRACE("(%p)->()\n", This);
-
-    EnterCriticalSection(This->pin.pCritSec);
-    {
-        if (!This->pin.pConnectedTo || !This->pMemInputPin)
-            hr = VFW_E_NOT_CONNECTED;
-        else
-        {
-            IMemAllocator * pAlloc = NULL;
-
-            hr = IMemInputPin_GetAllocator(This->pMemInputPin, &pAlloc);
-
-            if (SUCCEEDED(hr))
-                hr = IMemAllocator_Commit(pAlloc);
-
-            if (pAlloc)
-                IMemAllocator_Release(pAlloc);
-        }
-    }
-    LeaveCriticalSection(This->pin.pCritSec);
-    
-    return hr;
-}
-
-HRESULT OutputPin_DeliverDisconnect(OutputPin * This)
-{
-    HRESULT hr;
-
-    TRACE("(%p)->()\n", This);
-
-    EnterCriticalSection(This->pin.pCritSec);
-    {
-        if (!This->pin.pConnectedTo || !This->pMemInputPin)
-            hr = VFW_E_NOT_CONNECTED;
-        else
-        {
-            IMemAllocator * pAlloc = NULL;
-
-            hr = IMemInputPin_GetAllocator(This->pMemInputPin, &pAlloc);
-
-            if (SUCCEEDED(hr))
-                hr = IMemAllocator_Decommit(pAlloc);
-
-            if (pAlloc)
-                IMemAllocator_Release(pAlloc);
-
-            if (SUCCEEDED(hr))
-                hr = IPin_Disconnect(This->pin.pConnectedTo);
-        }
-    }
-    LeaveCriticalSection(This->pin.pCritSec);
-
-    return hr;
-}
-
-
-HRESULT PullPin_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 = &PullPin_Vtbl;
-        
-        *ppPin = (IPin *)(&pPinImpl->pin.lpVtbl);
-        return S_OK;
-    }
-    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, FALSE, TRUE, NULL);
-
-    pPinImpl->rtStart = 0;
-    pPinImpl->rtStop = ((LONGLONG)0x7fffffff << 32) | 0xffffffff;
-
-    return S_OK;
-}
-
-HRESULT WINAPI PullPin_ReceiveConnection(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt)
-{
-    PIN_DIRECTION pindirReceive;
-    HRESULT hr = S_OK;
-    PullPin *This = (PullPin *)iface;
-
-    TRACE("(%p/%p)->(%p, %p)\n", This, iface, pReceivePin, pmt);
-    dump_AM_MEDIA_TYPE(pmt);
-
-    EnterCriticalSection(This->pin.pCritSec);
-    {
-        if (This->pin.pConnectedTo)
-            hr = VFW_E_ALREADY_CONNECTED;
-
-        if (SUCCEEDED(hr) && (This->pin.fnQueryAccept(This->pin.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;
-            }
-        }
-
-        if (SUCCEEDED(hr))
-        {
-            hr = IPin_QueryInterface(pReceivePin, &IID_IAsyncReader, (LPVOID *)&This->pReader);
-        }
-
-        if (SUCCEEDED(hr))
-        {
-            ALLOCATOR_PROPERTIES props;
-            props.cBuffers = 3;
-            props.cbBuffer = 64 * 1024; /* 64k bytes */
-            props.cbAlign = 1;
-            props.cbPrefix = 0;
-            hr = IAsyncReader_RequestAllocator(This->pReader, NULL, &props, &This->pAlloc);
-        }
-
-        if (SUCCEEDED(hr) && This->fnPreConnect)
-        {
-            hr = This->fnPreConnect(iface, pReceivePin);
-        }
-
-        if (SUCCEEDED(hr))
-        {
-            CopyMediaType(&This->pin.mtCurrent, pmt);
-            This->pin.pConnectedTo = pReceivePin;
-            IPin_AddRef(pReceivePin);
-        }
-    }
-    LeaveCriticalSection(This->pin.pCritSec);
-    return hr;
-}
-
-HRESULT WINAPI PullPin_QueryInterface(IPin * iface, REFIID riid, LPVOID * ppv)
-{
-    PullPin *This = (PullPin *)iface;
-
-    TRACE("(%p/%p)->(%s, %p)\n", This, iface, qzdebugstr_guid(riid), ppv);
-
-    *ppv = NULL;
-
-    if (IsEqualIID(riid, &IID_IUnknown))
-        *ppv = (LPVOID)iface;
-    else if (IsEqualIID(riid, &IID_IPin))
-        *ppv = (LPVOID)iface;
-
-    if (*ppv)
-    {
-        IUnknown_AddRef((IUnknown *)(*ppv));
-        return S_OK;
-    }
-
-    FIXME("No interface for %s!\n", qzdebugstr_guid(riid));
-
-    return E_NOINTERFACE;
-}
-
-ULONG WINAPI PullPin_Release(IPin * iface)
-{
-    PullPin *This = (PullPin *)iface;
-    ULONG refCount = InterlockedDecrement(&This->pin.refCount);
-
-    TRACE("(%p/%p)->()\n", This, iface);
-
-    if (!refCount)
-    {
-        if (This->hThread)
-            PullPin_StopProcessing(This);
-        IMemAllocator_Release(This->pAlloc);
-        IAsyncReader_Release(This->pReader);
-        CloseHandle(This->hEventStateChanged);
-        CoTaskMemFree(This);
-        return 0;
-    }
-    return refCount;
-}
-
-static DWORD WINAPI PullPin_Thread_Main(LPVOID pv)
-{
-    for (;;)
-        SleepEx(INFINITE, TRUE);
-}
-
-static void CALLBACK PullPin_Thread_Process(ULONG_PTR iface)
-{
-    PullPin *This = (PullPin *)iface;
-    HRESULT hr;
-
-    REFERENCE_TIME rtCurrent;
-    ALLOCATOR_PROPERTIES allocProps;
-
-    CoInitializeEx(NULL, COINIT_MULTITHREADED);
-    
-    SetEvent(This->hEventStateChanged);
-
-    hr = IMemAllocator_GetProperties(This->pAlloc, &allocProps);
-
-    rtCurrent = MEDIATIME_FROM_BYTES(ALIGNDOWN(BYTES_FROM_MEDIATIME(This->rtStart), allocProps.cbAlign));
-
-    TRACE("Start\n");
-
-    while (rtCurrent < This->rtStop && hr == S_OK)
-    {
-        /* FIXME: to improve performance by quite a bit this should be changed
-         * so that one sample is processed while one sample is fetched. However,
-         * it is harder to debug so for the moment it will stay as it is */
-        IMediaSample * pSample = NULL;
-        REFERENCE_TIME rtSampleStop;
-        DWORD dwUser;
-
-        TRACE("Process sample\n");
-
-        hr = IMemAllocator_GetBuffer(This->pAlloc, &pSample, NULL, NULL, 0);
-
-        if (SUCCEEDED(hr))
-        {
-            rtSampleStop = rtCurrent + MEDIATIME_FROM_BYTES(IMediaSample_GetSize(pSample));
-            if (rtSampleStop > This->rtStop)
-                rtSampleStop = MEDIATIME_FROM_BYTES(ALIGNUP(BYTES_FROM_MEDIATIME(This->rtStop), allocProps.cbAlign));
-            hr = IMediaSample_SetTime(pSample, &rtCurrent, &rtSampleStop);
-            rtCurrent = rtSampleStop;
-        }
-
-        if (SUCCEEDED(hr))
-            hr = IAsyncReader_Request(This->pReader, pSample, (ULONG_PTR)0);
-
-        if (SUCCEEDED(hr))
-            hr = IAsyncReader_WaitForNext(This->pReader, 10000, &pSample, &dwUser);
-
-        if (SUCCEEDED(hr))
-            hr = This->fnSampleProc(This->pin.pUserData, pSample);
-        else
-            ERR("Processing error: %lx\n", hr);
-        
-        if (pSample)
-            IMediaSample_Release(pSample);
-    }
-
-    CoUninitialize();
-
-    TRACE("End\n");
-}
-
-static void CALLBACK PullPin_Thread_Stop(ULONG_PTR iface)
-{
-    PullPin *This = (PullPin *)iface;
-
-    TRACE("(%p/%p)->()\n", This, (LPVOID)iface);
-
-    EnterCriticalSection(This->pin.pCritSec);
-    {
-        HRESULT hr;
-
-        CloseHandle(This->hThread);
-        This->hThread = NULL;
-        if (FAILED(hr = IMemAllocator_Decommit(This->pAlloc)))
-            ERR("Allocator decommit failed with error %lx. Possible memory leak\n", hr);
-    }
-    LeaveCriticalSection(This->pin.pCritSec);
-
-    SetEvent(This->hEventStateChanged);
-
-    ExitThread(0);
-}
-
-HRESULT PullPin_InitProcessing(PullPin * This)
-{
-    HRESULT hr = S_OK;
-
-    TRACE("(%p)->()\n", This);
-
-    assert(!This->hThread);
-
-    /* if we are connected */
-    if (This->pAlloc)
-    {
-        EnterCriticalSection(This->pin.pCritSec);
-        {
-            DWORD dwThreadId;
-            assert(!This->hThread);
-        
-            This->hThread = CreateThread(NULL, 0, PullPin_Thread_Main, NULL, 0, &dwThreadId);
-            if (!This->hThread)
-                hr = HRESULT_FROM_WIN32(GetLastError());
-
-            if (SUCCEEDED(hr))
-                hr = IMemAllocator_Commit(This->pAlloc);
-        }
-        LeaveCriticalSection(This->pin.pCritSec);
-    }
-
-    TRACE(" -- %lx\n", hr);
-
-    return hr;
-}
-
-HRESULT PullPin_StartProcessing(PullPin * This)
-{
-    /* if we are connected */
-    TRACE("(%p)->()\n", This);
-    if(This->pAlloc)
-    {
-        assert(This->hThread);
-        
-        ResetEvent(This->hEventStateChanged);
-        
-        if (!QueueUserAPC(PullPin_Thread_Process, This->hThread, (ULONG_PTR)This))
-            return HRESULT_FROM_WIN32(GetLastError());
-    }
-
-    return S_OK;
-}
-
-HRESULT PullPin_PauseProcessing(PullPin * This)
-{
-    /* make the processing function exit its loop */
-    This->rtStop = 0;
-
-    return S_OK;
-}
-
-HRESULT PullPin_StopProcessing(PullPin * This)
-{
-    /* if we are connected */
-    if (This->pAlloc)
-    {
-        assert(This->hThread);
-
-        ResetEvent(This->hEventStateChanged);
-
-        PullPin_PauseProcessing(This);
-
-        if (!QueueUserAPC(PullPin_Thread_Stop, This->hThread, (ULONG_PTR)This))
-            return HRESULT_FROM_WIN32(GetLastError());
-    }
-
-    return S_OK;
-}
-
-HRESULT PullPin_WaitForStateChange(PullPin * This, DWORD dwMilliseconds)
-{
-    if (WaitForSingleObject(This->hEventStateChanged, dwMilliseconds) == WAIT_TIMEOUT)
-        return S_FALSE;
-    return S_OK;
-}
-
-HRESULT PullPin_Seek(PullPin * This, REFERENCE_TIME rtStart, REFERENCE_TIME rtStop)
-{
-    FIXME("(%p)->(%lx%08lx, %lx%08lx)\n", This, (LONG)(rtStart >> 32), (LONG)rtStart, (LONG)(rtStop >> 32), (LONG)rtStop);
-
-    PullPin_BeginFlush((IPin *)This);
-    /* FIXME: need critical section? */
-    This->rtStart = rtStart;
-    This->rtStop = rtStop;
-    PullPin_EndFlush((IPin *)This);
-
-    return S_OK;
-}
-
-HRESULT WINAPI PullPin_EndOfStream(IPin * iface)
-{
-    FIXME("(%p)->()\n", iface);
-    return E_NOTIMPL;
-}
-
-HRESULT WINAPI PullPin_BeginFlush(IPin * iface)
-{
-    FIXME("(%p)->()\n", iface);
-    return E_NOTIMPL;
-}
-
-HRESULT WINAPI PullPin_EndFlush(IPin * iface)
-{
-    FIXME("(%p)->()\n", iface);
-    return E_NOTIMPL;
-}
-
-HRESULT WINAPI PullPin_NewSegment(IPin * iface, REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate)
-{
-    FIXME("(%p)->(%s, %s, %g)\n", iface, wine_dbgstr_longlong(tStart), wine_dbgstr_longlong(tStop), dRate);
-    return E_NOTIMPL;
-}
-
-static const IPinVtbl PullPin_Vtbl = 
-{
-    PullPin_QueryInterface,
-    IPinImpl_AddRef,
-    PullPin_Release,
-    OutputPin_Connect,
-    PullPin_ReceiveConnection,
-    IPinImpl_Disconnect,
-    IPinImpl_ConnectedTo,
-    IPinImpl_ConnectionMediaType,
-    IPinImpl_QueryPinInfo,
-    IPinImpl_QueryDirection,
-    IPinImpl_QueryId,
-    IPinImpl_QueryAccept,
-    IPinImpl_EnumMediaTypes,
-    IPinImpl_QueryInternalConnections,
-    PullPin_EndOfStream,
-    PullPin_BeginFlush,
-    PullPin_EndFlush,
-    PullPin_NewSegment
-};
--- dlls/quartz/pin.h	2005-07-14 16:42:21.000000000 +0100
+++ /dev/null	1970-01-01 01:00:00.000000000 +0100
@@ -1,167 +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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-/* This function will process incoming samples to the pin.
- * Any return value valid in IMemInputPin::Receive is allowed here
- */
-typedef HRESULT (* SAMPLEPROC)(LPVOID userdata, IMediaSample * pSample);
-
-/* 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.
- */
-typedef HRESULT (* PRECONNECTPROC)(IPin * iface, IPin * pConnectPin);
-
-typedef struct IPinImpl
-{
-	const struct IPinVtbl * lpVtbl;
-	LONG refCount;
-	LPCRITICAL_SECTION pCritSec;
-	PIN_INFO pinInfo;
-	IPin * pConnectedTo;
-	AM_MEDIA_TYPE mtCurrent;
-	ENUMMEDIADETAILS enumMediaDetails;
-	QUERYACCEPTPROC fnQueryAccept;
-	LPVOID pUserData;
-} IPinImpl;
-
-typedef struct InputPin
-{
-	/* inheritance C style! */
-	IPinImpl pin;
-
-	const IMemInputPinVtbl * lpVtblMemInput;
-	IMemAllocator * pAllocator;
-	SAMPLEPROC fnSampleProc;
-	REFERENCE_TIME tStart;
-	REFERENCE_TIME tStop;
-	double dRate;
-} InputPin;
-
-typedef struct OutputPin
-{
-	/* inheritance C style! */
-	IPinImpl pin;
-
-	IMemInputPin * pMemInputPin;
-	HRESULT (* pConnectSpecific)(IPin * iface, IPin * pReceiver, const AM_MEDIA_TYPE * pmt);
-	ALLOCATOR_PROPERTIES allocProps;
-} OutputPin;
-
-typedef struct PullPin
-{
-	/* inheritance C style! */
-	IPinImpl pin;
-
-	IAsyncReader * pReader;
-	IMemAllocator * pAlloc;
-	SAMPLEPROC fnSampleProc;
-	PRECONNECTPROC fnPreConnect;
-	HANDLE hThread;
-	HANDLE hEventStateChanged;
-	REFERENCE_TIME rtStart;
-	REFERENCE_TIME rtStop;
-} 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, ALLOCATOR_PROPERTIES *props, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, LPCRITICAL_SECTION pCritSec, OutputPin * pPinImpl);
-HRESULT PullPin_Init(const PIN_INFO * pPinInfo, SAMPLEPROC pSampleProc, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, LPCRITICAL_SECTION pCritSec, PullPin * pPinImpl);
-
-/*** Constructors ***/
-HRESULT InputPin_Construct(const PIN_INFO * pPinInfo, SAMPLEPROC pSampleProc, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, LPCRITICAL_SECTION pCritSec, IPin ** ppPin);
-HRESULT OutputPin_Construct(const PIN_INFO * pPinInfo, ALLOCATOR_PROPERTIES *props, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, LPCRITICAL_SECTION pCritSec, IPin ** ppPin);
-HRESULT PullPin_Construct(const PIN_INFO * pPinInfo, SAMPLEPROC pSampleProc, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, LPCRITICAL_SECTION pCritSec, IPin ** ppPin);
-
-/**************************/
-/*** Pin Implementation ***/
-
-/* Common */
-ULONG   WINAPI IPinImpl_AddRef(IPin * iface);
-HRESULT WINAPI IPinImpl_Disconnect(IPin * iface);
-HRESULT WINAPI IPinImpl_ConnectedTo(IPin * iface, IPin ** ppPin);
-HRESULT WINAPI IPinImpl_ConnectionMediaType(IPin * iface, AM_MEDIA_TYPE * pmt);
-HRESULT WINAPI IPinImpl_QueryPinInfo(IPin * iface, PIN_INFO * pInfo);
-HRESULT WINAPI IPinImpl_QueryDirection(IPin * iface, PIN_DIRECTION * pPinDir);
-HRESULT WINAPI IPinImpl_QueryId(IPin * iface, LPWSTR * Id);
-HRESULT WINAPI IPinImpl_QueryAccept(IPin * iface, const AM_MEDIA_TYPE * pmt);
-HRESULT WINAPI IPinImpl_EnumMediaTypes(IPin * iface, IEnumMediaTypes ** ppEnum);
-HRESULT WINAPI IPinImpl_QueryInternalConnections(IPin * iface, IPin ** apPin, ULONG * cPin);
-
-/* Input Pin */
-HRESULT WINAPI InputPin_QueryInterface(IPin * iface, REFIID riid, LPVOID * ppv);
-ULONG   WINAPI InputPin_Release(IPin * iface);
-HRESULT WINAPI InputPin_Connect(IPin * iface, IPin * pConnector, const AM_MEDIA_TYPE * pmt);
-HRESULT WINAPI InputPin_ReceiveConnection(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt);
-HRESULT WINAPI InputPin_EndOfStream(IPin * iface);
-HRESULT WINAPI InputPin_BeginFlush(IPin * iface);
-HRESULT WINAPI InputPin_EndFlush(IPin * iface);
-HRESULT WINAPI InputPin_NewSegment(IPin * iface, REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate);
-
-/* Output Pin */
-HRESULT WINAPI OutputPin_QueryInterface(IPin * iface, REFIID riid, LPVOID * ppv);
-ULONG   WINAPI OutputPin_Release(IPin * iface);
-HRESULT WINAPI OutputPin_Connect(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt);
-HRESULT WINAPI OutputPin_Disconnect(IPin * iface);
-HRESULT WINAPI OutputPin_ReceiveConnection(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt);
-HRESULT WINAPI OutputPin_EndOfStream(IPin * iface);
-HRESULT WINAPI OutputPin_BeginFlush(IPin * iface);
-HRESULT WINAPI OutputPin_EndFlush(IPin * iface);
-HRESULT WINAPI OutputPin_NewSegment(IPin * iface, REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate);
-
-HRESULT OutputPin_CommitAllocator(OutputPin * This);
-HRESULT OutputPin_GetDeliveryBuffer(OutputPin * This, IMediaSample ** ppSample, const REFERENCE_TIME * tStart, const REFERENCE_TIME * tStop, DWORD dwFlags);
-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_QueryInterface(IPin * iface, REFIID riid, LPVOID * ppv);
-ULONG   WINAPI PullPin_Release(IPin * iface);
-HRESULT PullPin_InitProcessing(PullPin * This);
-HRESULT PullPin_StartProcessing(PullPin * This);
-HRESULT PullPin_StopProcessing(PullPin * This);
-HRESULT PullPin_PauseProcessing(PullPin * This);
-HRESULT PullPin_Seek(PullPin * This, REFERENCE_TIME rtStart, REFERENCE_TIME rtStop);
-HRESULT WINAPI PullPin_EndOfStream(IPin * iface);
-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);
-HRESULT PullPin_WaitForStateChange(PullPin * This, DWORD dwMilliseconds);
--- dlls/quartz/enumpins.c	2005-07-14 16:42:18.000000000 +0100
+++ /dev/null	1970-01-01 01:00:00.000000000 +0100
@@ -1,175 +0,0 @@
-/*
- * Implementation of IEnumPins 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include "quartz_private.h"
-
-#include "wine/debug.h"
-
-WINE_DEFAULT_DEBUG_CHANNEL(quartz);
-
-typedef struct IEnumPinsImpl
-{
-    const IEnumPinsVtbl * lpVtbl;
-    LONG refCount;
-    ENUMPINDETAILS enumPinDetails;
-    ULONG uIndex;
-} IEnumPinsImpl;
-
-static const struct IEnumPinsVtbl IEnumPinsImpl_Vtbl;
-
-HRESULT IEnumPinsImpl_Construct(const ENUMPINDETAILS * pDetails, IEnumPins ** ppEnum)
-{
-    IEnumPinsImpl * pEnumPins = CoTaskMemAlloc(sizeof(IEnumPinsImpl));
-    if (!pEnumPins)
-    {
-        *ppEnum = NULL;
-        return E_OUTOFMEMORY;
-    }
-    pEnumPins->lpVtbl = &IEnumPinsImpl_Vtbl;
-    pEnumPins->refCount = 1;
-    pEnumPins->uIndex = 0;
-    CopyMemory(&pEnumPins->enumPinDetails, pDetails, sizeof(ENUMPINDETAILS));
-    *ppEnum = (IEnumPins *)(&pEnumPins->lpVtbl);
-    return S_OK;
-}
-
-static HRESULT WINAPI IEnumPinsImpl_QueryInterface(IEnumPins * iface, REFIID riid, LPVOID * ppv)
-{
-    TRACE("(%s, %p)\n", qzdebugstr_guid(riid), ppv);
-
-    *ppv = NULL;
-
-    if (IsEqualIID(riid, &IID_IUnknown))
-        *ppv = (LPVOID)iface;
-    else if (IsEqualIID(riid, &IID_IEnumPins))
-        *ppv = (LPVOID)iface;
-
-    if (*ppv)
-    {
-        IUnknown_AddRef((IUnknown *)(*ppv));
-        return S_OK;
-    }
-
-    FIXME("No interface for %s!\n", qzdebugstr_guid(riid));
-
-    return E_NOINTERFACE;
-}
-
-static ULONG WINAPI IEnumPinsImpl_AddRef(IEnumPins * iface)
-{
-    IEnumPinsImpl *This = (IEnumPinsImpl *)iface;
-    ULONG refCount = InterlockedIncrement(&This->refCount);
-
-    TRACE("()\n");
-
-    return refCount;
-}
-
-static ULONG WINAPI IEnumPinsImpl_Release(IEnumPins * iface)
-{
-    IEnumPinsImpl *This = (IEnumPinsImpl *)iface;
-    ULONG refCount = InterlockedDecrement(&This->refCount);
-
-    TRACE("()\n");
-    
-    if (!refCount)
-    {
-        CoTaskMemFree(This);
-        return 0;
-    }
-    else
-        return refCount;
-}
-
-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;
-
-    TRACE("(%lu, %p, %p)\n", cPins, ppPins, pcFetched);
-
-    if (cFetched > 0)
-    {
-        ULONG i;
-        for (i = 0; i < cFetched; i++) {
-            IPin_AddRef(This->enumPinDetails.ppPins[This->uIndex + i]);
-            ppPins[i] = This->enumPinDetails.ppPins[This->uIndex + i];
-        }
-    }
-
-    if ((cPins != 1) || pcFetched)
-        *pcFetched = cFetched;
-
-    This->uIndex += cFetched;
-
-    if (cFetched != cPins)
-        return S_FALSE;
-    return S_OK;
-}
-
-static HRESULT WINAPI IEnumPinsImpl_Skip(IEnumPins * iface, ULONG cPins)
-{
-    IEnumPinsImpl *This = (IEnumPinsImpl *)iface;
-
-    TRACE("(%lu)\n", cPins);
-
-    if (This->uIndex + cPins < This->enumPinDetails.cPins)
-    {
-        This->uIndex += cPins;
-        return S_OK;
-    }
-    return S_FALSE;
-}
-
-static HRESULT WINAPI IEnumPinsImpl_Reset(IEnumPins * iface)
-{
-    IEnumPinsImpl *This = (IEnumPinsImpl *)iface;
-
-    TRACE("IEnumPinsImpl::Reset()\n");
-
-    This->uIndex = 0;
-    return S_OK;
-}
-
-static HRESULT WINAPI IEnumPinsImpl_Clone(IEnumPins * iface, IEnumPins ** ppEnum)
-{
-    HRESULT hr;
-    IEnumPinsImpl *This = (IEnumPinsImpl *)iface;
-
-    TRACE("(%p)\n", ppEnum);
-
-    hr = IEnumPinsImpl_Construct(&This->enumPinDetails, ppEnum);
-    if (FAILED(hr))
-        return hr;
-    return IEnumPins_Skip(*ppEnum, This->uIndex);
-}
-
-static const IEnumPinsVtbl IEnumPinsImpl_Vtbl =
-{
-    IEnumPinsImpl_QueryInterface,
-    IEnumPinsImpl_AddRef,
-    IEnumPinsImpl_Release,
-    IEnumPinsImpl_Next,
-    IEnumPinsImpl_Skip,
-    IEnumPinsImpl_Reset,
-    IEnumPinsImpl_Clone
-};
--- dlls/quartz/enummedia.c	2005-07-14 16:42:18.000000000 +0100
+++ /dev/null	1970-01-01 01:00:00.000000000 +0100
@@ -1,260 +0,0 @@
-/*
- * Implementation of IEnumMediaTypes 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include "quartz_private.h"
-
-#include "wine/debug.h"
-
-WINE_DEFAULT_DEBUG_CHANNEL(quartz);
-
-HRESULT CopyMediaType(AM_MEDIA_TYPE * pDest, const AM_MEDIA_TYPE *pSrc)
-{
-    memcpy(pDest, pSrc, sizeof(AM_MEDIA_TYPE));
-    if (!pSrc->pbFormat) return S_OK;
-    if (!(pDest->pbFormat = CoTaskMemAlloc(pSrc->cbFormat)))
-        return E_OUTOFMEMORY;
-    memcpy(pDest->pbFormat, pSrc->pbFormat, pSrc->cbFormat);
-    if (pDest->pUnk)
-        IUnknown_AddRef(pDest->pUnk);
-    return S_OK;
-}
-
-void FreeMediaType(AM_MEDIA_TYPE * pMediaType)
-{
-    if (pMediaType->pbFormat)
-    {
-        CoTaskMemFree(pMediaType->pbFormat);
-        pMediaType->pbFormat = NULL;
-    }
-    if (pMediaType->pUnk)
-    {
-        IUnknown_Release(pMediaType->pUnk);
-        pMediaType->pUnk = NULL;
-    }
-}
-
-static AM_MEDIA_TYPE * CreateMediaType(AM_MEDIA_TYPE const * pSrc)
-{
-    AM_MEDIA_TYPE * pDest;
-    
-    pDest = CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE));
-    if (!pDest)
-        return NULL;
-
-    if (FAILED(CopyMediaType(pDest, pSrc)))
-    {
-        CoTaskMemFree(pDest);
-	return NULL;
-    }
-
-    return pDest;
-}
-
-void DeleteMediaType(AM_MEDIA_TYPE * pMediaType)
-{
-    FreeMediaType(pMediaType);
-    CoTaskMemFree(pMediaType);
-}
-
-BOOL CompareMediaTypes(const AM_MEDIA_TYPE * pmt1, const AM_MEDIA_TYPE * pmt2, BOOL bWildcards)
-{
-    TRACE("pmt1: ");
-    dump_AM_MEDIA_TYPE(pmt1);
-    TRACE("pmt2: ");
-    dump_AM_MEDIA_TYPE(pmt2);
-    return (((bWildcards && (IsEqualGUID(&pmt1->majortype, &GUID_NULL) || IsEqualGUID(&pmt2->majortype, &GUID_NULL))) || IsEqualGUID(&pmt1->majortype, &pmt2->majortype)) &&
-            ((bWildcards && (IsEqualGUID(&pmt1->subtype, &GUID_NULL)   || IsEqualGUID(&pmt2->subtype, &GUID_NULL)))   || IsEqualGUID(&pmt1->subtype, &pmt2->subtype)));
-}
-
-void dump_AM_MEDIA_TYPE(const AM_MEDIA_TYPE * pmt)
-{
-    if (!pmt)
-        return;
-    TRACE("\t%s\n\t%s\n\t...\n\t%s\n", qzdebugstr_guid(&pmt->majortype), qzdebugstr_guid(&pmt->subtype), qzdebugstr_guid(&pmt->formattype));
-}
-
-typedef struct IEnumMediaTypesImpl
-{
-    const IEnumMediaTypesVtbl * lpVtbl;
-    LONG refCount;
-    ENUMMEDIADETAILS enumMediaDetails;
-    ULONG uIndex;
-} IEnumMediaTypesImpl;
-
-static const struct IEnumMediaTypesVtbl IEnumMediaTypesImpl_Vtbl;
-
-HRESULT IEnumMediaTypesImpl_Construct(const ENUMMEDIADETAILS * pDetails, IEnumMediaTypes ** ppEnum)
-{
-    ULONG i;
-    IEnumMediaTypesImpl * pEnumMediaTypes = CoTaskMemAlloc(sizeof(IEnumMediaTypesImpl));
-
-    if (!pEnumMediaTypes)
-    {
-        *ppEnum = NULL;
-        return E_OUTOFMEMORY;
-    }
-    pEnumMediaTypes->lpVtbl = &IEnumMediaTypesImpl_Vtbl;
-    pEnumMediaTypes->refCount = 1;
-    pEnumMediaTypes->uIndex = 0;
-    pEnumMediaTypes->enumMediaDetails.cMediaTypes = pDetails->cMediaTypes;
-    pEnumMediaTypes->enumMediaDetails.pMediaTypes = CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE) * pDetails->cMediaTypes);
-    for (i = 0; i < pDetails->cMediaTypes; i++)
-        if (FAILED(CopyMediaType(&pEnumMediaTypes->enumMediaDetails.pMediaTypes[i], &pDetails->pMediaTypes[i])))
-        {
-           while (i--)
-              CoTaskMemFree(pEnumMediaTypes->enumMediaDetails.pMediaTypes[i].pbFormat);
-           CoTaskMemFree(pEnumMediaTypes->enumMediaDetails.pMediaTypes);
-           return E_OUTOFMEMORY;
-        }
-    *ppEnum = (IEnumMediaTypes *)(&pEnumMediaTypes->lpVtbl);
-    return S_OK;
-}
-
-static HRESULT WINAPI IEnumMediaTypesImpl_QueryInterface(IEnumMediaTypes * iface, REFIID riid, LPVOID * ppv)
-{
-    TRACE("(%s, %p)\n", qzdebugstr_guid(riid), ppv);
-
-    *ppv = NULL;
-
-    if (IsEqualIID(riid, &IID_IUnknown))
-        *ppv = (LPVOID)iface;
-    else if (IsEqualIID(riid, &IID_IEnumMediaTypes))
-        *ppv = (LPVOID)iface;
-
-    if (*ppv)
-    {
-        IUnknown_AddRef((IUnknown *)(*ppv));
-        return S_OK;
-    }
-
-    FIXME("No interface for %s!\n", qzdebugstr_guid(riid));
-
-    return E_NOINTERFACE;
-}
-
-static ULONG WINAPI IEnumMediaTypesImpl_AddRef(IEnumMediaTypes * iface)
-{
-    IEnumMediaTypesImpl *This = (IEnumMediaTypesImpl *)iface;
-    ULONG refCount = InterlockedIncrement(&This->refCount);
-
-    TRACE("(%p)->() AddRef from %ld\n", iface, refCount - 1);
-
-    return refCount;
-}
-
-static ULONG WINAPI IEnumMediaTypesImpl_Release(IEnumMediaTypes * iface)
-{
-    IEnumMediaTypesImpl *This = (IEnumMediaTypesImpl *)iface;
-    ULONG refCount = InterlockedDecrement(&This->refCount);
-
-    TRACE("(%p)->() Release from %ld\n", iface, refCount + 1);
-
-    if (!refCount)
-    {
-        int i;
-        for (i = 0; i < This->enumMediaDetails.cMediaTypes; i++)
-            if (This->enumMediaDetails.pMediaTypes[i].pbFormat)
-                CoTaskMemFree(This->enumMediaDetails.pMediaTypes[i].pbFormat);
-        CoTaskMemFree(This->enumMediaDetails.pMediaTypes);
-        CoTaskMemFree(This);
-    }
-    return refCount;
-}
-
-static HRESULT WINAPI IEnumMediaTypesImpl_Next(IEnumMediaTypes * iface, ULONG cMediaTypes, AM_MEDIA_TYPE ** ppMediaTypes, ULONG * pcFetched)
-{
-    ULONG cFetched; 
-    IEnumMediaTypesImpl *This = (IEnumMediaTypesImpl *)iface;
-
-    cFetched = min(This->enumMediaDetails.cMediaTypes, This->uIndex + cMediaTypes) - This->uIndex;
-
-    TRACE("(%lu, %p, %p)\n", cMediaTypes, ppMediaTypes, pcFetched);
-    TRACE("Next uIndex: %lu, cFetched: %lu\n", This->uIndex, cFetched);
-
-    if (cFetched > 0)
-    {
-        ULONG i;
-        for (i = 0; i < cFetched; i++)
-            if (!(ppMediaTypes[i] = CreateMediaType(&This->enumMediaDetails.pMediaTypes[This->uIndex + i])))
-            {
-                while (i--)
-                    DeleteMediaType(ppMediaTypes[i]);
-                *pcFetched = 0;
-                return E_OUTOFMEMORY;
-            }
-    }
-
-    if ((cMediaTypes != 1) || pcFetched)
-        *pcFetched = cFetched;
-
-    This->uIndex += cFetched;
-
-    if (cFetched != cMediaTypes)
-        return S_FALSE;
-    return S_OK;
-}
-
-static HRESULT WINAPI IEnumMediaTypesImpl_Skip(IEnumMediaTypes * iface, ULONG cMediaTypes)
-{
-    IEnumMediaTypesImpl *This = (IEnumMediaTypesImpl *)iface;
-
-    TRACE("(%lu)\n", cMediaTypes);
-
-    if (This->uIndex + cMediaTypes < This->enumMediaDetails.cMediaTypes)
-    {
-        This->uIndex += cMediaTypes;
-        return S_OK;
-    }
-    return S_FALSE;
-}
-
-static HRESULT WINAPI IEnumMediaTypesImpl_Reset(IEnumMediaTypes * iface)
-{
-    IEnumMediaTypesImpl *This = (IEnumMediaTypesImpl *)iface;
-
-    TRACE("()\n");
-
-    This->uIndex = 0;
-    return S_OK;
-}
-
-static HRESULT WINAPI IEnumMediaTypesImpl_Clone(IEnumMediaTypes * iface, IEnumMediaTypes ** ppEnum)
-{
-    HRESULT hr;
-    IEnumMediaTypesImpl *This = (IEnumMediaTypesImpl *)iface;
-
-    TRACE("(%p)\n", ppEnum);
-
-    hr = IEnumMediaTypesImpl_Construct(&This->enumMediaDetails, ppEnum);
-    if (FAILED(hr))
-        return hr;
-    return IEnumMediaTypes_Skip(*ppEnum, This->uIndex);
-}
-
-static const IEnumMediaTypesVtbl IEnumMediaTypesImpl_Vtbl =
-{
-    IEnumMediaTypesImpl_QueryInterface,
-    IEnumMediaTypesImpl_AddRef,
-    IEnumMediaTypesImpl_Release,
-    IEnumMediaTypesImpl_Next,
-    IEnumMediaTypesImpl_Skip,
-    IEnumMediaTypesImpl_Reset,
-    IEnumMediaTypesImpl_Clone
-};
--- /dev/null	1970-01-01 01:00:00.000000000 +0100
+++ dlls/winestrmbase/Makefile.in	2005-08-03 18:58:10.000000000 +0100
@@ -0,0 +1,31 @@
+DLLDEFS   = @DLLDEFS@
+DLLFLAGS  = @DLLFLAGS@
+DEFS      = -D__WINESRC__ $(DLLDEFS)
+TOPSRCDIR = @top_srcdir@
+TOPOBJDIR = ../..
+SRCDIR    = @srcdir@
+VPATH     = @srcdir@
+MODULE    = libwinestrmbase.a
+
+C_SRCS = \
+	debug.c \
+	enummedia.c \
+	enumpins.c \
+	pin.c
+
+all: $(MODULE)
+
+ at MAKE_RULES@
+
+$(MODULE): $(OBJS) Makefile.in
+	$(RM) $@
+	$(AR) $@ $(OBJS)
+	$(RANLIB) $@
+
+man:
+
+doc-html:
+
+doc-sgml:
+
+### Dependencies:
--- /dev/null	1970-01-01 01:00:00.000000000 +0100
+++ dlls/winestrmbase/pin.c	2005-08-03 19:03:52.000000000 +0100
@@ -0,0 +1,1376 @@
+/*
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <stdarg.h>
+
+#define COBJMACROS
+
+#include <windef.h>
+#include <winbase.h>
+#include "dshow.h"
+#include "amvideo.h"
+#include "wine/winestreams.h"
+
+#include "wine/debug.h"
+#include "wine/unicode.h"
+#include "uuids.h"
+#include "vfwmsgs.h"
+#include <assert.h>
+
+WINE_DEFAULT_DEBUG_CHANNEL(quartz);
+
+static const IPinVtbl InputPin_Vtbl;
+static const IPinVtbl OutputPin_Vtbl;
+static const IMemInputPinVtbl MemInputPin_Vtbl;
+static const IPinVtbl PullPin_Vtbl;
+
+#define ALIGNDOWN(value,boundary) ((value) & ~(boundary-1))
+#define ALIGNUP(value,boundary) (ALIGNDOWN(value - 1, boundary) + boundary)
+
+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)
+{
+    /* Tempting to just do a memcpy, but the name field is
+       128 characters long! We will probably never exceed 10
+       most of the time, so we are better off copying 
+       each field manually */
+    strcpyW(pDest->achName, pSrc->achName);
+    pDest->dir = pSrc->dir;
+    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))
+    {
+        hr = IPin_QueryInterface(pReceivePin, &IID_IMemInputPin, (LPVOID)&This->pMemInputPin);
+
+        if (SUCCEEDED(hr))
+            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 = IMemInputPin_NotifyAllocator(This->pMemInputPin, pMemAlloc, FALSE);
+            }
+        }
+
+        if (SUCCEEDED(hr))
+            hr = IMemAllocator_SetProperties(pMemAlloc, &This->allocProps, &actual);
+
+        if (pMemAlloc)
+            IMemAllocator_Release(pMemAlloc);
+
+        /* break connection if we couldn't get the allocator */
+        if (FAILED(hr))
+            IPin_Disconnect(pReceivePin);
+    }
+
+    if (FAILED(hr))
+    {
+        IPin_Release(This->pin.pConnectedTo);
+        This->pin.pConnectedTo = NULL;
+        FreeMediaType(&This->pin.mtCurrent);
+    }
+
+    TRACE(" -- %lx\n", hr);
+    return hr;
+}
+
+HRESULT InputPin_Construct(const PIN_INFO * pPinInfo, SAMPLEPROC pSampleProc, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, LPCRITICAL_SECTION pCritSec, IPin ** ppPin)
+{
+    InputPin * pPinImpl;
+
+    *ppPin = NULL;
+
+    if (pPinInfo->dir != PINDIR_INPUT)
+    {
+        ERR("Pin direction(%x) != PINDIR_INPUT\n", pPinInfo->dir);
+        return E_INVALIDARG;
+    }
+
+    pPinImpl = CoTaskMemAlloc(sizeof(*pPinImpl));
+
+    if (!pPinImpl)
+        return E_OUTOFMEMORY;
+
+    if (SUCCEEDED(InputPin_Init(pPinInfo, pSampleProc, pUserData, pQueryAccept, pCritSec, pPinImpl)))
+    {
+        pPinImpl->pin.lpVtbl = &InputPin_Vtbl;
+        pPinImpl->lpVtblMemInput = &MemInputPin_Vtbl;
+        
+        *ppPin = (IPin *)(&pPinImpl->pin.lpVtbl);
+        return S_OK;
+    }
+    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");
+
+    /* 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->pAllocator = NULL;
+    pPinImpl->tStart = 0;
+    pPinImpl->tStop = 0;
+    pPinImpl->dRate = 0;
+
+    return S_OK;
+}
+
+HRESULT OutputPin_Init(const PIN_INFO * pPinInfo, 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 (props)
+    {
+        memcpy(&pPinImpl->allocProps, props, sizeof(pPinImpl->allocProps));
+        if (pPinImpl->allocProps.cbAlign == 0)
+            pPinImpl->allocProps.cbAlign = 1;
+    }
+    else
+        ZeroMemory(&pPinImpl->allocProps, sizeof(pPinImpl->allocProps));
+
+    return S_OK;
+}
+
+HRESULT OutputPin_Construct(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;
+    }
+
+    pPinImpl = CoTaskMemAlloc(sizeof(*pPinImpl));
+
+    if (!pPinImpl)
+        return E_OUTOFMEMORY;
+
+    if (SUCCEEDED(OutputPin_Init(pPinInfo, props, pUserData, pQueryAccept, pCritSec, pPinImpl)))
+    {
+        pPinImpl->pin.lpVtbl = &OutputPin_Vtbl;
+        
+        *ppPin = (IPin *)(&pPinImpl->pin.lpVtbl);
+        return S_OK;
+    }
+    return E_FAIL;
+}
+
+/*** Common pin functions ***/
+
+ULONG WINAPI IPinImpl_AddRef(IPin * iface)
+{
+    IPinImpl *This = (IPinImpl *)iface;
+    ULONG refCount = InterlockedIncrement(&This->refCount);
+    
+    TRACE("(%p)->() AddRef from %ld\n", iface, refCount - 1);
+    
+    return refCount;
+}
+
+HRESULT WINAPI IPinImpl_Disconnect(IPin * iface)
+{
+    HRESULT hr;
+    IPinImpl *This = (IPinImpl *)iface;
+
+    TRACE("()\n");
+
+    EnterCriticalSection(This->pCritSec);
+    {
+        if (This->pConnectedTo)
+        {
+            IPin_Release(This->pConnectedTo);
+            This->pConnectedTo = NULL;
+            hr = S_OK;
+        }
+        else
+            hr = S_FALSE;
+    }
+    LeaveCriticalSection(This->pCritSec);
+    
+    return hr;
+}
+
+HRESULT WINAPI IPinImpl_ConnectedTo(IPin * iface, IPin ** ppPin)
+{
+    HRESULT hr;
+    IPinImpl *This = (IPinImpl *)iface;
+
+/*  TRACE("(%p)\n", ppPin);*/
+
+    EnterCriticalSection(This->pCritSec);
+    {
+        if (This->pConnectedTo)
+        {
+            *ppPin = This->pConnectedTo;
+            IPin_AddRef(*ppPin);
+            hr = S_OK;
+        }
+        else
+            hr = VFW_E_NOT_CONNECTED;
+    }
+    LeaveCriticalSection(This->pCritSec);
+
+    return hr;
+}
+
+HRESULT WINAPI IPinImpl_ConnectionMediaType(IPin * iface, AM_MEDIA_TYPE * pmt)
+{
+    HRESULT hr;
+    IPinImpl *This = (IPinImpl *)iface;
+
+    TRACE("(%p/%p)->(%p)\n", This, iface, pmt);
+
+    EnterCriticalSection(This->pCritSec);
+    {
+        if (This->pConnectedTo)
+        {
+            CopyMediaType(pmt, &This->mtCurrent);
+            hr = S_OK;
+        }
+        else
+        {
+            ZeroMemory(pmt, sizeof(*pmt));
+            hr = VFW_E_NOT_CONNECTED;
+        }
+    }
+    LeaveCriticalSection(This->pCritSec);
+
+    return hr;
+}
+
+HRESULT WINAPI IPinImpl_QueryPinInfo(IPin * iface, PIN_INFO * pInfo)
+{
+    IPinImpl *This = (IPinImpl *)iface;
+
+    TRACE("(%p/%p)->(%p)\n", This, iface, pInfo);
+
+    Copy_PinInfo(pInfo, &This->pinInfo);
+    IBaseFilter_AddRef(pInfo->pFilter);
+
+    return S_OK;
+}
+
+HRESULT WINAPI IPinImpl_QueryDirection(IPin * iface, PIN_DIRECTION * pPinDir)
+{
+    IPinImpl *This = (IPinImpl *)iface;
+
+    TRACE("(%p/%p)->(%p)\n", This, iface, pPinDir);
+
+    *pPinDir = This->pinInfo.dir;
+
+    return S_OK;
+}
+
+HRESULT WINAPI IPinImpl_QueryId(IPin * iface, LPWSTR * Id)
+{
+    IPinImpl *This = (IPinImpl *)iface;
+
+    TRACE("(%p/%p)->(%p)\n", This, iface, Id);
+
+    *Id = CoTaskMemAlloc((strlenW(This->pinInfo.achName) + 1) * sizeof(WCHAR));
+    if (!Id)
+        return E_OUTOFMEMORY;
+
+    strcpyW(*Id, This->pinInfo.achName);
+
+    return S_OK;
+}
+
+HRESULT WINAPI IPinImpl_QueryAccept(IPin * iface, const AM_MEDIA_TYPE * pmt)
+{
+    IPinImpl *This = (IPinImpl *)iface;
+
+    TRACE("(%p/%p)->(%p)\n", This, iface, pmt);
+
+    return (This->fnQueryAccept(This->pUserData, pmt) == S_OK ? S_OK : S_FALSE);
+}
+
+HRESULT WINAPI IPinImpl_EnumMediaTypes(IPin * iface, IEnumMediaTypes ** ppEnum)
+{
+    IPinImpl *This = (IPinImpl *)iface;
+    ENUMMEDIADETAILS emd;
+
+    TRACE("(%p/%p)->(%p)\n", This, iface, ppEnum);
+
+    /* override this method to allow enumeration of your types */
+    emd.cMediaTypes = 0;
+    emd.pMediaTypes = NULL;
+
+    return IEnumMediaTypesImpl_Construct(&emd, ppEnum);
+}
+
+HRESULT WINAPI IPinImpl_QueryInternalConnections(IPin * iface, IPin ** apPin, ULONG * cPin)
+{
+    IPinImpl *This = (IPinImpl *)iface;
+
+    TRACE("(%p/%p)->(%p, %p)\n", This, iface, apPin, cPin);
+
+    return E_NOTIMPL; /* to tell caller that all input pins connected to all output pins */
+}
+
+/*** IPin implementation for an input pin ***/
+
+HRESULT WINAPI InputPin_QueryInterface(IPin * iface, REFIID riid, LPVOID * ppv)
+{
+    InputPin *This = (InputPin *)iface;
+
+    TRACE("(%p)->(%s, %p)\n", iface, qzdebugstr_guid(riid), ppv);
+
+    *ppv = NULL;
+
+    if (IsEqualIID(riid, &IID_IUnknown))
+        *ppv = (LPVOID)iface;
+    else if (IsEqualIID(riid, &IID_IPin))
+        *ppv = (LPVOID)iface;
+    else if (IsEqualIID(riid, &IID_IMemInputPin))
+        *ppv = (LPVOID)&This->lpVtblMemInput;
+
+    if (*ppv)
+    {
+        IUnknown_AddRef((IUnknown *)(*ppv));
+        return S_OK;
+    }
+
+    FIXME("No interface for %s!\n", qzdebugstr_guid(riid));
+
+    return E_NOINTERFACE;
+}
+
+ULONG WINAPI InputPin_Release(IPin * iface)
+{
+    InputPin *This = (InputPin *)iface;
+    ULONG refCount = InterlockedDecrement(&This->pin.refCount);
+    
+    TRACE("(%p)->() Release from %ld\n", iface, refCount + 1);
+    
+    if (!refCount)
+    {
+        FreeMediaType(&This->pin.mtCurrent);
+        if (This->pAllocator)
+            IMemAllocator_Release(This->pAllocator);
+        CoTaskMemFree(This);
+        return 0;
+    }
+    else
+        return refCount;
+}
+
+HRESULT WINAPI InputPin_Connect(IPin * iface, IPin * pConnector, const AM_MEDIA_TYPE * pmt)
+{
+    ERR("Outgoing connection on an input pin! (%p, %p)\n", pConnector, pmt);
+
+    return E_UNEXPECTED;
+}
+
+
+HRESULT WINAPI InputPin_ReceiveConnection(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt)
+{
+    InputPin *This = (InputPin *)iface;
+    PIN_DIRECTION pindirReceive;
+    HRESULT hr = S_OK;
+
+    TRACE("(%p, %p)\n", pReceivePin, pmt);
+    dump_AM_MEDIA_TYPE(pmt);
+
+    EnterCriticalSection(This->pin.pCritSec);
+    {
+        if (This->pin.pConnectedTo)
+            hr = VFW_E_ALREADY_CONNECTED;
+
+        if (SUCCEEDED(hr) && This->pin.fnQueryAccept(This->pin.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;
+            }
+        }
+
+        if (SUCCEEDED(hr))
+        {
+            CopyMediaType(&This->pin.mtCurrent, pmt);
+            This->pin.pConnectedTo = pReceivePin;
+            IPin_AddRef(pReceivePin);
+        }
+    }
+    LeaveCriticalSection(This->pin.pCritSec);
+
+    return hr;
+}
+
+HRESULT WINAPI InputPin_EndOfStream(IPin * iface)
+{
+    TRACE("()\n");
+
+    return S_OK;
+}
+
+HRESULT WINAPI InputPin_BeginFlush(IPin * iface)
+{
+    FIXME("()\n");
+    return E_NOTIMPL;
+}
+
+HRESULT WINAPI InputPin_EndFlush(IPin * iface)
+{
+    FIXME("()\n");
+    return E_NOTIMPL;
+}
+
+HRESULT WINAPI InputPin_NewSegment(IPin * iface, REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate)
+{
+    InputPin *This = (InputPin *)iface;
+
+    TRACE("(%lx%08lx, %lx%08lx, %e)\n", (ULONG)(tStart >> 32), (ULONG)tStart, (ULONG)(tStop >> 32), (ULONG)tStop, dRate);
+
+    This->tStart = tStart;
+    This->tStop = tStop;
+    This->dRate = dRate;
+
+    return S_OK;
+}
+
+static const IPinVtbl InputPin_Vtbl = 
+{
+    InputPin_QueryInterface,
+    IPinImpl_AddRef,
+    InputPin_Release,
+    InputPin_Connect,
+    InputPin_ReceiveConnection,
+    IPinImpl_Disconnect,
+    IPinImpl_ConnectedTo,
+    IPinImpl_ConnectionMediaType,
+    IPinImpl_QueryPinInfo,
+    IPinImpl_QueryDirection,
+    IPinImpl_QueryId,
+    IPinImpl_QueryAccept,
+    IPinImpl_EnumMediaTypes,
+    IPinImpl_QueryInternalConnections,
+    InputPin_EndOfStream,
+    InputPin_BeginFlush,
+    InputPin_EndFlush,
+    InputPin_NewSegment
+};
+
+/*** IMemInputPin implementation ***/
+
+HRESULT WINAPI MemInputPin_QueryInterface(IMemInputPin * iface, REFIID riid, LPVOID * ppv)
+{
+    InputPin *This = impl_from_IMemInputPin(iface);
+
+    return IPin_QueryInterface((IPin *)&This->pin, riid, ppv);
+}
+
+ULONG WINAPI MemInputPin_AddRef(IMemInputPin * iface)
+{
+    InputPin *This = impl_from_IMemInputPin(iface);
+
+    return IPin_AddRef((IPin *)&This->pin);
+}
+
+ULONG WINAPI MemInputPin_Release(IMemInputPin * iface)
+{
+    InputPin *This = impl_from_IMemInputPin(iface);
+
+    return IPin_Release((IPin *)&This->pin);
+}
+
+HRESULT WINAPI MemInputPin_GetAllocator(IMemInputPin * iface, IMemAllocator ** ppAllocator)
+{
+    InputPin *This = impl_from_IMemInputPin(iface);
+
+    TRACE("(%p/%p)->(%p)\n", This, iface, ppAllocator);
+
+    *ppAllocator = This->pAllocator;
+    if (*ppAllocator)
+        IMemAllocator_AddRef(*ppAllocator);
+    
+    return *ppAllocator ? S_OK : VFW_E_NO_ALLOCATOR;
+}
+
+HRESULT WINAPI MemInputPin_NotifyAllocator(IMemInputPin * iface, IMemAllocator * pAllocator, BOOL bReadOnly)
+{
+    InputPin *This = impl_from_IMemInputPin(iface);
+
+    TRACE("(%p/%p)->(%p, %d)\n", This, iface, pAllocator, bReadOnly);
+
+    if (This->pAllocator)
+        IMemAllocator_Release(This->pAllocator);
+    This->pAllocator = pAllocator;
+    if (This->pAllocator)
+        IMemAllocator_AddRef(This->pAllocator);
+
+    return S_OK;
+}
+
+HRESULT WINAPI MemInputPin_GetAllocatorRequirements(IMemInputPin * iface, ALLOCATOR_PROPERTIES * pProps)
+{
+    InputPin *This = impl_from_IMemInputPin(iface);
+
+    TRACE("(%p/%p)->(%p)\n", This, iface, pProps);
+
+    /* override this method if you have any specific requirements */
+
+    return E_NOTIMPL;
+}
+
+HRESULT WINAPI MemInputPin_Receive(IMemInputPin * iface, IMediaSample * pSample)
+{
+    InputPin *This = impl_from_IMemInputPin(iface);
+
+    /* this trace commented out for performance reasons */
+    /*TRACE("(%p/%p)->(%p)\n", This, iface, pSample);*/
+
+    return This->fnSampleProc(This->pin.pUserData, pSample);
+}
+
+HRESULT WINAPI MemInputPin_ReceiveMultiple(IMemInputPin * iface, IMediaSample ** pSamples, long nSamples, long *nSamplesProcessed)
+{
+    HRESULT hr = S_OK;
+    InputPin *This = impl_from_IMemInputPin(iface);
+
+    TRACE("(%p/%p)->(%p, %ld, %p)\n", This, iface, pSamples, nSamples, nSamplesProcessed);
+
+    for (*nSamplesProcessed = 0; *nSamplesProcessed < nSamples; (*nSamplesProcessed)++)
+    {
+        hr = IMemInputPin_Receive(iface, pSamples[*nSamplesProcessed]);
+        if (hr != S_OK)
+            break;
+    }
+
+    return hr;
+}
+
+HRESULT WINAPI MemInputPin_ReceiveCanBlock(IMemInputPin * iface)
+{
+    InputPin *This = impl_from_IMemInputPin(iface);
+
+    FIXME("(%p/%p)->()\n", This, iface);
+
+    /* FIXME: we should check whether any output pins will block */
+
+    return S_OK;
+}
+
+static const IMemInputPinVtbl MemInputPin_Vtbl = 
+{
+    MemInputPin_QueryInterface,
+    MemInputPin_AddRef,
+    MemInputPin_Release,
+    MemInputPin_GetAllocator,
+    MemInputPin_NotifyAllocator,
+    MemInputPin_GetAllocatorRequirements,
+    MemInputPin_Receive,
+    MemInputPin_ReceiveMultiple,
+    MemInputPin_ReceiveCanBlock
+};
+
+HRESULT WINAPI OutputPin_QueryInterface(IPin * iface, REFIID riid, LPVOID * ppv)
+{
+    OutputPin *This = (OutputPin *)iface;
+
+    TRACE("(%p/%p)->(%s, %p)\n", This, iface, qzdebugstr_guid(riid), ppv);
+
+    *ppv = NULL;
+
+    if (IsEqualIID(riid, &IID_IUnknown))
+        *ppv = (LPVOID)iface;
+    else if (IsEqualIID(riid, &IID_IPin))
+        *ppv = (LPVOID)iface;
+
+    if (*ppv)
+    {
+        IUnknown_AddRef((IUnknown *)(*ppv));
+        return S_OK;
+    }
+
+    FIXME("No interface for %s!\n", qzdebugstr_guid(riid));
+
+    return E_NOINTERFACE;
+}
+
+ULONG WINAPI OutputPin_Release(IPin * iface)
+{
+    OutputPin *This = (OutputPin *)iface;
+    ULONG refCount = InterlockedDecrement(&This->pin.refCount);
+    
+    TRACE("(%p)->() Release from %ld\n", iface, refCount + 1);
+    
+    if (!refCount)
+    {
+        FreeMediaType(&This->pin.mtCurrent);
+        CoTaskMemFree(This);
+        return 0;
+    }
+    return refCount;
+}
+
+HRESULT WINAPI OutputPin_Connect(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt)
+{
+    HRESULT hr;
+    OutputPin *This = (OutputPin *)iface;
+
+    TRACE("(%p/%p)->(%p, %p)\n", This, iface, pReceivePin, pmt);
+    dump_AM_MEDIA_TYPE(pmt);
+
+    /* If we try to connect to ourself, we will definitely deadlock.
+     * There are other cases where we could deadlock too, but this
+     * catches the obvious case */
+    assert(pReceivePin != iface);
+
+    EnterCriticalSection(This->pin.pCritSec);
+    {
+        /* if we have been a specific type to connect with, then we can either connect
+         * with that or fail. We cannot choose different AM_MEDIA_TYPE */
+        if (pmt && !IsEqualGUID(&pmt->majortype, &GUID_NULL) && !IsEqualGUID(&pmt->subtype, &GUID_NULL))
+            hr = This->pConnectSpecific(iface, pReceivePin, pmt);
+        else
+        {
+            /* negotiate media type */
+
+            IEnumMediaTypes * pEnumCandidates;
+            AM_MEDIA_TYPE * pmtCandidate; /* Candidate media type */
+
+            if (SUCCEEDED(hr = IPin_EnumMediaTypes(iface, &pEnumCandidates)))
+            {
+                hr = VFW_E_NO_ACCEPTABLE_TYPES; /* Assume the worst, but set to S_OK if connected successfully */
+
+                /* try this filter's media types first */
+                while (S_OK == IEnumMediaTypes_Next(pEnumCandidates, 1, &pmtCandidate, NULL))
+                {
+                    if (( !pmt || CompareMediaTypes(pmt, pmtCandidate, TRUE) ) && 
+                        (This->pConnectSpecific(iface, pReceivePin, pmtCandidate) == S_OK))
+                    {
+                        hr = S_OK;
+                        CoTaskMemFree(pmtCandidate);
+                        break;
+                    }
+                    CoTaskMemFree(pmtCandidate);
+                }
+                IEnumMediaTypes_Release(pEnumCandidates);
+            }
+
+            /* then try receiver filter's media types */
+            if (hr != S_OK && SUCCEEDED(hr = IPin_EnumMediaTypes(pReceivePin, &pEnumCandidates))) /* if we haven't already connected successfully */
+            {
+                hr = VFW_E_NO_ACCEPTABLE_TYPES; /* Assume the worst, but set to S_OK if connected successfully */
+
+                while (S_OK == IEnumMediaTypes_Next(pEnumCandidates, 1, &pmtCandidate, NULL))
+                {
+                    if (( !pmt || CompareMediaTypes(pmt, pmtCandidate, TRUE) ) && 
+                        (This->pConnectSpecific(iface, pReceivePin, pmtCandidate) == S_OK))
+                    {
+                        hr = S_OK;
+                        CoTaskMemFree(pmtCandidate);
+                        break;
+                    }
+                    CoTaskMemFree(pmtCandidate);
+                } /* while */
+                IEnumMediaTypes_Release(pEnumCandidates);
+            } /* if not found */
+        } /* if negotiate media type */
+    } /* if succeeded */
+    LeaveCriticalSection(This->pin.pCritSec);
+
+    TRACE(" -- %lx\n", hr);
+    return hr;
+}
+
+HRESULT WINAPI OutputPin_ReceiveConnection(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt)
+{
+    ERR("Incoming connection on an output pin! (%p, %p)\n", pReceivePin, pmt);
+
+    return E_UNEXPECTED;
+}
+
+HRESULT WINAPI OutputPin_Disconnect(IPin * iface)
+{
+    HRESULT hr;
+    OutputPin *This = (OutputPin *)iface;
+
+    TRACE("()\n");
+
+    EnterCriticalSection(This->pin.pCritSec);
+    {
+        if (This->pMemInputPin)
+        {
+            IMemInputPin_Release(This->pMemInputPin);
+            This->pMemInputPin = NULL;
+        }
+        if (This->pin.pConnectedTo)
+        {
+            IPin_Release(This->pin.pConnectedTo);
+            This->pin.pConnectedTo = NULL;
+            hr = S_OK;
+        }
+        else
+            hr = S_FALSE;
+    }
+    LeaveCriticalSection(This->pin.pCritSec);
+    
+    return hr;
+}
+
+HRESULT WINAPI OutputPin_EndOfStream(IPin * iface)
+{
+    TRACE("()\n");
+
+    /* not supposed to do anything in an output pin */
+
+    return E_UNEXPECTED;
+}
+
+HRESULT WINAPI OutputPin_BeginFlush(IPin * iface)
+{
+    TRACE("(%p)->()\n", iface);
+
+    /* not supposed to do anything in an output pin */
+
+    return E_UNEXPECTED;
+}
+
+HRESULT WINAPI OutputPin_EndFlush(IPin * iface)
+{
+    TRACE("(%p)->()\n", iface);
+
+    /* not supposed to do anything in an output pin */
+
+    return E_UNEXPECTED;
+}
+
+HRESULT WINAPI OutputPin_NewSegment(IPin * iface, REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate)
+{
+    TRACE("(%p)->(%lx%08lx, %lx%08lx, %e)\n", iface, (ULONG)(tStart >> 32), (ULONG)tStart, (ULONG)(tStop >> 32), (ULONG)tStop, dRate);
+
+    /* not supposed to do anything in an output pin */
+
+    return E_UNEXPECTED;
+}
+
+static const IPinVtbl OutputPin_Vtbl = 
+{
+    OutputPin_QueryInterface,
+    IPinImpl_AddRef,
+    OutputPin_Release,
+    OutputPin_Connect,
+    OutputPin_ReceiveConnection,
+    OutputPin_Disconnect,
+    IPinImpl_ConnectedTo,
+    IPinImpl_ConnectionMediaType,
+    IPinImpl_QueryPinInfo,
+    IPinImpl_QueryDirection,
+    IPinImpl_QueryId,
+    IPinImpl_QueryAccept,
+    IPinImpl_EnumMediaTypes,
+    IPinImpl_QueryInternalConnections,
+    OutputPin_EndOfStream,
+    OutputPin_BeginFlush,
+    OutputPin_EndFlush,
+    OutputPin_NewSegment
+};
+
+HRESULT OutputPin_GetDeliveryBuffer(OutputPin * This, IMediaSample ** ppSample, const REFERENCE_TIME * tStart, const REFERENCE_TIME * tStop, DWORD dwFlags)
+{
+    HRESULT hr;
+
+    TRACE("(%p, %p, %p, %lx)\n", ppSample, tStart, tStop, dwFlags);
+
+    EnterCriticalSection(This->pin.pCritSec);
+    {
+        if (!This->pin.pConnectedTo)
+            hr = VFW_E_NOT_CONNECTED;
+        else
+        {
+            IMemAllocator * pAlloc = NULL;
+            
+            hr = IMemInputPin_GetAllocator(This->pMemInputPin, &pAlloc);
+
+            if (SUCCEEDED(hr))
+                hr = IMemAllocator_GetBuffer(pAlloc, ppSample, (REFERENCE_TIME *)tStart, (REFERENCE_TIME *)tStop, dwFlags);
+
+            if (SUCCEEDED(hr))
+                hr = IMediaSample_SetTime(*ppSample, (REFERENCE_TIME *)tStart, (REFERENCE_TIME *)tStop);
+
+            if (pAlloc)
+                IMemAllocator_Release(pAlloc);
+        }
+    }
+    LeaveCriticalSection(This->pin.pCritSec);
+    
+    return hr;
+}
+
+HRESULT OutputPin_SendSample(OutputPin * This, IMediaSample * pSample)
+{
+    HRESULT hr = S_OK;
+    IMemInputPin * pMemConnected = NULL;
+
+    EnterCriticalSection(This->pin.pCritSec);
+    {
+        if (!This->pin.pConnectedTo || !This->pMemInputPin)
+            hr = VFW_E_NOT_CONNECTED;
+        else
+        {
+            /* we don't have the lock held when using This->pMemInputPin,
+             * so we need to AddRef it to stop it being deleted while we are
+             * using it. */
+            pMemConnected = This->pMemInputPin;
+            IMemInputPin_AddRef(pMemConnected);
+        }
+    }
+    LeaveCriticalSection(This->pin.pCritSec);
+
+    if (SUCCEEDED(hr))
+    {
+        /* NOTE: if we are in a critical section when Receive is called
+         * then it causes some problems (most notably with the native Video
+         * Renderer) if we are re-entered for whatever reason */
+        hr = IMemInputPin_Receive(pMemConnected, pSample);
+        IMemInputPin_Release(pMemConnected);
+    }
+    
+    return hr;
+}
+
+HRESULT OutputPin_DeliverNewSegment(OutputPin * This, REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate)
+{
+    HRESULT hr;
+
+    EnterCriticalSection(This->pin.pCritSec);
+    {
+        if (!This->pin.pConnectedTo)
+            hr = VFW_E_NOT_CONNECTED;
+        else
+            hr = IPin_NewSegment(This->pin.pConnectedTo, tStart, tStop, dRate);
+    }
+    LeaveCriticalSection(This->pin.pCritSec);
+    
+    return hr;
+}
+
+HRESULT OutputPin_CommitAllocator(OutputPin * This)
+{
+    HRESULT hr;
+
+    TRACE("(%p)->()\n", This);
+
+    EnterCriticalSection(This->pin.pCritSec);
+    {
+        if (!This->pin.pConnectedTo || !This->pMemInputPin)
+            hr = VFW_E_NOT_CONNECTED;
+        else
+        {
+            IMemAllocator * pAlloc = NULL;
+
+            hr = IMemInputPin_GetAllocator(This->pMemInputPin, &pAlloc);
+
+            if (SUCCEEDED(hr))
+                hr = IMemAllocator_Commit(pAlloc);
+
+            if (pAlloc)
+                IMemAllocator_Release(pAlloc);
+        }
+    }
+    LeaveCriticalSection(This->pin.pCritSec);
+    
+    return hr;
+}
+
+HRESULT OutputPin_DeliverDisconnect(OutputPin * This)
+{
+    HRESULT hr;
+
+    TRACE("(%p)->()\n", This);
+
+    EnterCriticalSection(This->pin.pCritSec);
+    {
+        if (!This->pin.pConnectedTo || !This->pMemInputPin)
+            hr = VFW_E_NOT_CONNECTED;
+        else
+        {
+            IMemAllocator * pAlloc = NULL;
+
+            hr = IMemInputPin_GetAllocator(This->pMemInputPin, &pAlloc);
+
+            if (SUCCEEDED(hr))
+                hr = IMemAllocator_Decommit(pAlloc);
+
+            if (pAlloc)
+                IMemAllocator_Release(pAlloc);
+
+            if (SUCCEEDED(hr))
+                hr = IPin_Disconnect(This->pin.pConnectedTo);
+        }
+    }
+    LeaveCriticalSection(This->pin.pCritSec);
+
+    return hr;
+}
+
+
+HRESULT PullPin_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 = &PullPin_Vtbl;
+        
+        *ppPin = (IPin *)(&pPinImpl->pin.lpVtbl);
+        return S_OK;
+    }
+    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, FALSE, TRUE, NULL);
+
+    pPinImpl->rtStart = 0;
+    pPinImpl->rtStop = ((LONGLONG)0x7fffffff << 32) | 0xffffffff;
+
+    return S_OK;
+}
+
+HRESULT WINAPI PullPin_ReceiveConnection(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt)
+{
+    PIN_DIRECTION pindirReceive;
+    HRESULT hr = S_OK;
+    PullPin *This = (PullPin *)iface;
+
+    TRACE("(%p/%p)->(%p, %p)\n", This, iface, pReceivePin, pmt);
+    dump_AM_MEDIA_TYPE(pmt);
+
+    EnterCriticalSection(This->pin.pCritSec);
+    {
+        if (This->pin.pConnectedTo)
+            hr = VFW_E_ALREADY_CONNECTED;
+
+        if (SUCCEEDED(hr) && (This->pin.fnQueryAccept(This->pin.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;
+            }
+        }
+
+        if (SUCCEEDED(hr))
+        {
+            hr = IPin_QueryInterface(pReceivePin, &IID_IAsyncReader, (LPVOID *)&This->pReader);
+        }
+
+        if (SUCCEEDED(hr))
+        {
+            ALLOCATOR_PROPERTIES props;
+            props.cBuffers = 3;
+            props.cbBuffer = 64 * 1024; /* 64k bytes */
+            props.cbAlign = 1;
+            props.cbPrefix = 0;
+            hr = IAsyncReader_RequestAllocator(This->pReader, NULL, &props, &This->pAlloc);
+        }
+
+        if (SUCCEEDED(hr) && This->fnPreConnect)
+        {
+            hr = This->fnPreConnect(iface, pReceivePin);
+        }
+
+        if (SUCCEEDED(hr))
+        {
+            CopyMediaType(&This->pin.mtCurrent, pmt);
+            This->pin.pConnectedTo = pReceivePin;
+            IPin_AddRef(pReceivePin);
+        }
+    }
+    LeaveCriticalSection(This->pin.pCritSec);
+    return hr;
+}
+
+HRESULT WINAPI PullPin_QueryInterface(IPin * iface, REFIID riid, LPVOID * ppv)
+{
+    PullPin *This = (PullPin *)iface;
+
+    TRACE("(%p/%p)->(%s, %p)\n", This, iface, qzdebugstr_guid(riid), ppv);
+
+    *ppv = NULL;
+
+    if (IsEqualIID(riid, &IID_IUnknown))
+        *ppv = (LPVOID)iface;
+    else if (IsEqualIID(riid, &IID_IPin))
+        *ppv = (LPVOID)iface;
+
+    if (*ppv)
+    {
+        IUnknown_AddRef((IUnknown *)(*ppv));
+        return S_OK;
+    }
+
+    FIXME("No interface for %s!\n", qzdebugstr_guid(riid));
+
+    return E_NOINTERFACE;
+}
+
+ULONG WINAPI PullPin_Release(IPin * iface)
+{
+    PullPin *This = (PullPin *)iface;
+    ULONG refCount = InterlockedDecrement(&This->pin.refCount);
+
+    TRACE("(%p/%p)->()\n", This, iface);
+
+    if (!refCount)
+    {
+        if (This->hThread)
+            PullPin_StopProcessing(This);
+        IMemAllocator_Release(This->pAlloc);
+        IAsyncReader_Release(This->pReader);
+        CloseHandle(This->hEventStateChanged);
+        CoTaskMemFree(This);
+        return 0;
+    }
+    return refCount;
+}
+
+static DWORD WINAPI PullPin_Thread_Main(LPVOID pv)
+{
+    for (;;)
+        SleepEx(INFINITE, TRUE);
+}
+
+static void CALLBACK PullPin_Thread_Process(ULONG_PTR iface)
+{
+    PullPin *This = (PullPin *)iface;
+    HRESULT hr;
+
+    REFERENCE_TIME rtCurrent;
+    ALLOCATOR_PROPERTIES allocProps;
+
+    CoInitializeEx(NULL, COINIT_MULTITHREADED);
+    
+    SetEvent(This->hEventStateChanged);
+
+    hr = IMemAllocator_GetProperties(This->pAlloc, &allocProps);
+
+    rtCurrent = MEDIATIME_FROM_BYTES(ALIGNDOWN(BYTES_FROM_MEDIATIME(This->rtStart), allocProps.cbAlign));
+
+    TRACE("Start\n");
+
+    while (rtCurrent < This->rtStop && hr == S_OK)
+    {
+        /* FIXME: to improve performance by quite a bit this should be changed
+         * so that one sample is processed while one sample is fetched. However,
+         * it is harder to debug so for the moment it will stay as it is */
+        IMediaSample * pSample = NULL;
+        REFERENCE_TIME rtSampleStop;
+        DWORD dwUser;
+
+        TRACE("Process sample\n");
+
+        hr = IMemAllocator_GetBuffer(This->pAlloc, &pSample, NULL, NULL, 0);
+
+        if (SUCCEEDED(hr))
+        {
+            rtSampleStop = rtCurrent + MEDIATIME_FROM_BYTES(IMediaSample_GetSize(pSample));
+            if (rtSampleStop > This->rtStop)
+                rtSampleStop = MEDIATIME_FROM_BYTES(ALIGNUP(BYTES_FROM_MEDIATIME(This->rtStop), allocProps.cbAlign));
+            hr = IMediaSample_SetTime(pSample, &rtCurrent, &rtSampleStop);
+            rtCurrent = rtSampleStop;
+        }
+
+        if (SUCCEEDED(hr))
+            hr = IAsyncReader_Request(This->pReader, pSample, (ULONG_PTR)0);
+
+        if (SUCCEEDED(hr))
+            hr = IAsyncReader_WaitForNext(This->pReader, 10000, &pSample, &dwUser);
+
+        if (SUCCEEDED(hr))
+            hr = This->fnSampleProc(This->pin.pUserData, pSample);
+        else
+            ERR("Processing error: %lx\n", hr);
+        
+        if (pSample)
+            IMediaSample_Release(pSample);
+    }
+
+    CoUninitialize();
+
+    TRACE("End\n");
+}
+
+static void CALLBACK PullPin_Thread_Stop(ULONG_PTR iface)
+{
+    PullPin *This = (PullPin *)iface;
+
+    TRACE("(%p/%p)->()\n", This, (LPVOID)iface);
+
+    EnterCriticalSection(This->pin.pCritSec);
+    {
+        HRESULT hr;
+
+        CloseHandle(This->hThread);
+        This->hThread = NULL;
+        if (FAILED(hr = IMemAllocator_Decommit(This->pAlloc)))
+            ERR("Allocator decommit failed with error %lx. Possible memory leak\n", hr);
+    }
+    LeaveCriticalSection(This->pin.pCritSec);
+
+    SetEvent(This->hEventStateChanged);
+
+    ExitThread(0);
+}
+
+HRESULT PullPin_InitProcessing(PullPin * This)
+{
+    HRESULT hr = S_OK;
+
+    TRACE("(%p)->()\n", This);
+
+    assert(!This->hThread);
+
+    /* if we are connected */
+    if (This->pAlloc)
+    {
+        EnterCriticalSection(This->pin.pCritSec);
+        {
+            DWORD dwThreadId;
+            assert(!This->hThread);
+        
+            This->hThread = CreateThread(NULL, 0, PullPin_Thread_Main, NULL, 0, &dwThreadId);
+            if (!This->hThread)
+                hr = HRESULT_FROM_WIN32(GetLastError());
+
+            if (SUCCEEDED(hr))
+                hr = IMemAllocator_Commit(This->pAlloc);
+        }
+        LeaveCriticalSection(This->pin.pCritSec);
+    }
+
+    TRACE(" -- %lx\n", hr);
+
+    return hr;
+}
+
+HRESULT PullPin_StartProcessing(PullPin * This)
+{
+    /* if we are connected */
+    TRACE("(%p)->()\n", This);
+    if(This->pAlloc)
+    {
+        assert(This->hThread);
+        
+        ResetEvent(This->hEventStateChanged);
+        
+        if (!QueueUserAPC(PullPin_Thread_Process, This->hThread, (ULONG_PTR)This))
+            return HRESULT_FROM_WIN32(GetLastError());
+    }
+
+    return S_OK;
+}
+
+HRESULT PullPin_PauseProcessing(PullPin * This)
+{
+    /* make the processing function exit its loop */
+    This->rtStop = 0;
+
+    return S_OK;
+}
+
+HRESULT PullPin_StopProcessing(PullPin * This)
+{
+    /* if we are connected */
+    if (This->pAlloc)
+    {
+        assert(This->hThread);
+
+        ResetEvent(This->hEventStateChanged);
+
+        PullPin_PauseProcessing(This);
+
+        if (!QueueUserAPC(PullPin_Thread_Stop, This->hThread, (ULONG_PTR)This))
+            return HRESULT_FROM_WIN32(GetLastError());
+    }
+
+    return S_OK;
+}
+
+HRESULT PullPin_WaitForStateChange(PullPin * This, DWORD dwMilliseconds)
+{
+    if (WaitForSingleObject(This->hEventStateChanged, dwMilliseconds) == WAIT_TIMEOUT)
+        return S_FALSE;
+    return S_OK;
+}
+
+HRESULT PullPin_Seek(PullPin * This, REFERENCE_TIME rtStart, REFERENCE_TIME rtStop)
+{
+    FIXME("(%p)->(%lx%08lx, %lx%08lx)\n", This, (LONG)(rtStart >> 32), (LONG)rtStart, (LONG)(rtStop >> 32), (LONG)rtStop);
+
+    PullPin_BeginFlush((IPin *)This);
+    /* FIXME: need critical section? */
+    This->rtStart = rtStart;
+    This->rtStop = rtStop;
+    PullPin_EndFlush((IPin *)This);
+
+    return S_OK;
+}
+
+HRESULT WINAPI PullPin_EndOfStream(IPin * iface)
+{
+    FIXME("(%p)->()\n", iface);
+    return E_NOTIMPL;
+}
+
+HRESULT WINAPI PullPin_BeginFlush(IPin * iface)
+{
+    FIXME("(%p)->()\n", iface);
+    return E_NOTIMPL;
+}
+
+HRESULT WINAPI PullPin_EndFlush(IPin * iface)
+{
+    FIXME("(%p)->()\n", iface);
+    return E_NOTIMPL;
+}
+
+HRESULT WINAPI PullPin_NewSegment(IPin * iface, REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate)
+{
+    FIXME("(%p)->(%s, %s, %g)\n", iface, wine_dbgstr_longlong(tStart), wine_dbgstr_longlong(tStop), dRate);
+    return E_NOTIMPL;
+}
+
+static const IPinVtbl PullPin_Vtbl = 
+{
+    PullPin_QueryInterface,
+    IPinImpl_AddRef,
+    PullPin_Release,
+    OutputPin_Connect,
+    PullPin_ReceiveConnection,
+    IPinImpl_Disconnect,
+    IPinImpl_ConnectedTo,
+    IPinImpl_ConnectionMediaType,
+    IPinImpl_QueryPinInfo,
+    IPinImpl_QueryDirection,
+    IPinImpl_QueryId,
+    IPinImpl_QueryAccept,
+    IPinImpl_EnumMediaTypes,
+    IPinImpl_QueryInternalConnections,
+    PullPin_EndOfStream,
+    PullPin_BeginFlush,
+    PullPin_EndFlush,
+    PullPin_NewSegment
+};
--- /dev/null	1970-01-01 01:00:00.000000000 +0100
+++ dlls/winestrmbase/enumpins.c	2005-08-03 19:04:18.000000000 +0100
@@ -0,0 +1,183 @@
+/*
+ * Implementation of IEnumPins 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <stdarg.h>
+
+#define COBJMACROS
+
+#include <windef.h>
+#include <winbase.h>
+#include "dshow.h"
+#include "amvideo.h"
+#include "wine/winestreams.h"
+
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(quartz);
+
+typedef struct IEnumPinsImpl
+{
+    const IEnumPinsVtbl * lpVtbl;
+    LONG refCount;
+    ENUMPINDETAILS enumPinDetails;
+    ULONG uIndex;
+} IEnumPinsImpl;
+
+static const struct IEnumPinsVtbl IEnumPinsImpl_Vtbl;
+
+HRESULT IEnumPinsImpl_Construct(const ENUMPINDETAILS * pDetails, IEnumPins ** ppEnum)
+{
+    IEnumPinsImpl * pEnumPins = CoTaskMemAlloc(sizeof(IEnumPinsImpl));
+    if (!pEnumPins)
+    {
+        *ppEnum = NULL;
+        return E_OUTOFMEMORY;
+    }
+    pEnumPins->lpVtbl = &IEnumPinsImpl_Vtbl;
+    pEnumPins->refCount = 1;
+    pEnumPins->uIndex = 0;
+    CopyMemory(&pEnumPins->enumPinDetails, pDetails, sizeof(ENUMPINDETAILS));
+    *ppEnum = (IEnumPins *)(&pEnumPins->lpVtbl);
+    return S_OK;
+}
+
+static HRESULT WINAPI IEnumPinsImpl_QueryInterface(IEnumPins * iface, REFIID riid, LPVOID * ppv)
+{
+    TRACE("(%s, %p)\n", qzdebugstr_guid(riid), ppv);
+
+    *ppv = NULL;
+
+    if (IsEqualIID(riid, &IID_IUnknown))
+        *ppv = (LPVOID)iface;
+    else if (IsEqualIID(riid, &IID_IEnumPins))
+        *ppv = (LPVOID)iface;
+
+    if (*ppv)
+    {
+        IUnknown_AddRef((IUnknown *)(*ppv));
+        return S_OK;
+    }
+
+    FIXME("No interface for %s!\n", qzdebugstr_guid(riid));
+
+    return E_NOINTERFACE;
+}
+
+static ULONG WINAPI IEnumPinsImpl_AddRef(IEnumPins * iface)
+{
+    IEnumPinsImpl *This = (IEnumPinsImpl *)iface;
+    ULONG refCount = InterlockedIncrement(&This->refCount);
+
+    TRACE("()\n");
+
+    return refCount;
+}
+
+static ULONG WINAPI IEnumPinsImpl_Release(IEnumPins * iface)
+{
+    IEnumPinsImpl *This = (IEnumPinsImpl *)iface;
+    ULONG refCount = InterlockedDecrement(&This->refCount);
+
+    TRACE("()\n");
+    
+    if (!refCount)
+    {
+        CoTaskMemFree(This);
+        return 0;
+    }
+    else
+        return refCount;
+}
+
+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;
+
+    TRACE("(%lu, %p, %p)\n", cPins, ppPins, pcFetched);
+
+    if (cFetched > 0)
+    {
+        ULONG i;
+        for (i = 0; i < cFetched; i++) {
+            IPin_AddRef(This->enumPinDetails.ppPins[This->uIndex + i]);
+            ppPins[i] = This->enumPinDetails.ppPins[This->uIndex + i];
+        }
+    }
+
+    if ((cPins != 1) || pcFetched)
+        *pcFetched = cFetched;
+
+    This->uIndex += cFetched;
+
+    if (cFetched != cPins)
+        return S_FALSE;
+    return S_OK;
+}
+
+static HRESULT WINAPI IEnumPinsImpl_Skip(IEnumPins * iface, ULONG cPins)
+{
+    IEnumPinsImpl *This = (IEnumPinsImpl *)iface;
+
+    TRACE("(%lu)\n", cPins);
+
+    if (This->uIndex + cPins < This->enumPinDetails.cPins)
+    {
+        This->uIndex += cPins;
+        return S_OK;
+    }
+    return S_FALSE;
+}
+
+static HRESULT WINAPI IEnumPinsImpl_Reset(IEnumPins * iface)
+{
+    IEnumPinsImpl *This = (IEnumPinsImpl *)iface;
+
+    TRACE("IEnumPinsImpl::Reset()\n");
+
+    This->uIndex = 0;
+    return S_OK;
+}
+
+static HRESULT WINAPI IEnumPinsImpl_Clone(IEnumPins * iface, IEnumPins ** ppEnum)
+{
+    HRESULT hr;
+    IEnumPinsImpl *This = (IEnumPinsImpl *)iface;
+
+    TRACE("(%p)\n", ppEnum);
+
+    hr = IEnumPinsImpl_Construct(&This->enumPinDetails, ppEnum);
+    if (FAILED(hr))
+        return hr;
+    return IEnumPins_Skip(*ppEnum, This->uIndex);
+}
+
+static const IEnumPinsVtbl IEnumPinsImpl_Vtbl =
+{
+    IEnumPinsImpl_QueryInterface,
+    IEnumPinsImpl_AddRef,
+    IEnumPinsImpl_Release,
+    IEnumPinsImpl_Next,
+    IEnumPinsImpl_Skip,
+    IEnumPinsImpl_Reset,
+    IEnumPinsImpl_Clone
+};
--- /dev/null	1970-01-01 01:00:00.000000000 +0100
+++ dlls/winestrmbase/enummedia.c	2005-08-03 19:04:05.000000000 +0100
@@ -0,0 +1,268 @@
+/*
+ * Implementation of IEnumMediaTypes 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <stdarg.h>
+
+#define COBJMACROS
+
+#include <windef.h>
+#include <winbase.h>
+#include "dshow.h"
+#include "amvideo.h"
+#include "wine/winestreams.h"
+
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(quartz);
+
+HRESULT CopyMediaType(AM_MEDIA_TYPE * pDest, const AM_MEDIA_TYPE *pSrc)
+{
+    memcpy(pDest, pSrc, sizeof(AM_MEDIA_TYPE));
+    if (!pSrc->pbFormat) return S_OK;
+    if (!(pDest->pbFormat = CoTaskMemAlloc(pSrc->cbFormat)))
+        return E_OUTOFMEMORY;
+    memcpy(pDest->pbFormat, pSrc->pbFormat, pSrc->cbFormat);
+    if (pDest->pUnk)
+        IUnknown_AddRef(pDest->pUnk);
+    return S_OK;
+}
+
+void FreeMediaType(AM_MEDIA_TYPE * pMediaType)
+{
+    if (pMediaType->pbFormat)
+    {
+        CoTaskMemFree(pMediaType->pbFormat);
+        pMediaType->pbFormat = NULL;
+    }
+    if (pMediaType->pUnk)
+    {
+        IUnknown_Release(pMediaType->pUnk);
+        pMediaType->pUnk = NULL;
+    }
+}
+
+static AM_MEDIA_TYPE * CreateMediaType(AM_MEDIA_TYPE const * pSrc)
+{
+    AM_MEDIA_TYPE * pDest;
+    
+    pDest = CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE));
+    if (!pDest)
+        return NULL;
+
+    if (FAILED(CopyMediaType(pDest, pSrc)))
+    {
+        CoTaskMemFree(pDest);
+	return NULL;
+    }
+
+    return pDest;
+}
+
+void DeleteMediaType(AM_MEDIA_TYPE * pMediaType)
+{
+    FreeMediaType(pMediaType);
+    CoTaskMemFree(pMediaType);
+}
+
+BOOL CompareMediaTypes(const AM_MEDIA_TYPE * pmt1, const AM_MEDIA_TYPE * pmt2, BOOL bWildcards)
+{
+    TRACE("pmt1: ");
+    dump_AM_MEDIA_TYPE(pmt1);
+    TRACE("pmt2: ");
+    dump_AM_MEDIA_TYPE(pmt2);
+    return (((bWildcards && (IsEqualGUID(&pmt1->majortype, &GUID_NULL) || IsEqualGUID(&pmt2->majortype, &GUID_NULL))) || IsEqualGUID(&pmt1->majortype, &pmt2->majortype)) &&
+            ((bWildcards && (IsEqualGUID(&pmt1->subtype, &GUID_NULL)   || IsEqualGUID(&pmt2->subtype, &GUID_NULL)))   || IsEqualGUID(&pmt1->subtype, &pmt2->subtype)));
+}
+
+void dump_AM_MEDIA_TYPE(const AM_MEDIA_TYPE * pmt)
+{
+    if (!pmt)
+        return;
+    TRACE("\t%s\n\t%s\n\t...\n\t%s\n", qzdebugstr_guid(&pmt->majortype), qzdebugstr_guid(&pmt->subtype), qzdebugstr_guid(&pmt->formattype));
+}
+
+typedef struct IEnumMediaTypesImpl
+{
+    const IEnumMediaTypesVtbl * lpVtbl;
+    LONG refCount;
+    ENUMMEDIADETAILS enumMediaDetails;
+    ULONG uIndex;
+} IEnumMediaTypesImpl;
+
+static const struct IEnumMediaTypesVtbl IEnumMediaTypesImpl_Vtbl;
+
+HRESULT IEnumMediaTypesImpl_Construct(const ENUMMEDIADETAILS * pDetails, IEnumMediaTypes ** ppEnum)
+{
+    ULONG i;
+    IEnumMediaTypesImpl * pEnumMediaTypes = CoTaskMemAlloc(sizeof(IEnumMediaTypesImpl));
+
+    if (!pEnumMediaTypes)
+    {
+        *ppEnum = NULL;
+        return E_OUTOFMEMORY;
+    }
+    pEnumMediaTypes->lpVtbl = &IEnumMediaTypesImpl_Vtbl;
+    pEnumMediaTypes->refCount = 1;
+    pEnumMediaTypes->uIndex = 0;
+    pEnumMediaTypes->enumMediaDetails.cMediaTypes = pDetails->cMediaTypes;
+    pEnumMediaTypes->enumMediaDetails.pMediaTypes = CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE) * pDetails->cMediaTypes);
+    for (i = 0; i < pDetails->cMediaTypes; i++)
+        if (FAILED(CopyMediaType(&pEnumMediaTypes->enumMediaDetails.pMediaTypes[i], &pDetails->pMediaTypes[i])))
+        {
+           while (i--)
+              CoTaskMemFree(pEnumMediaTypes->enumMediaDetails.pMediaTypes[i].pbFormat);
+           CoTaskMemFree(pEnumMediaTypes->enumMediaDetails.pMediaTypes);
+           return E_OUTOFMEMORY;
+        }
+    *ppEnum = (IEnumMediaTypes *)(&pEnumMediaTypes->lpVtbl);
+    return S_OK;
+}
+
+static HRESULT WINAPI IEnumMediaTypesImpl_QueryInterface(IEnumMediaTypes * iface, REFIID riid, LPVOID * ppv)
+{
+    TRACE("(%s, %p)\n", qzdebugstr_guid(riid), ppv);
+
+    *ppv = NULL;
+
+    if (IsEqualIID(riid, &IID_IUnknown))
+        *ppv = (LPVOID)iface;
+    else if (IsEqualIID(riid, &IID_IEnumMediaTypes))
+        *ppv = (LPVOID)iface;
+
+    if (*ppv)
+    {
+        IUnknown_AddRef((IUnknown *)(*ppv));
+        return S_OK;
+    }
+
+    FIXME("No interface for %s!\n", qzdebugstr_guid(riid));
+
+    return E_NOINTERFACE;
+}
+
+static ULONG WINAPI IEnumMediaTypesImpl_AddRef(IEnumMediaTypes * iface)
+{
+    IEnumMediaTypesImpl *This = (IEnumMediaTypesImpl *)iface;
+    ULONG refCount = InterlockedIncrement(&This->refCount);
+
+    TRACE("(%p)->() AddRef from %ld\n", iface, refCount - 1);
+
+    return refCount;
+}
+
+static ULONG WINAPI IEnumMediaTypesImpl_Release(IEnumMediaTypes * iface)
+{
+    IEnumMediaTypesImpl *This = (IEnumMediaTypesImpl *)iface;
+    ULONG refCount = InterlockedDecrement(&This->refCount);
+
+    TRACE("(%p)->() Release from %ld\n", iface, refCount + 1);
+
+    if (!refCount)
+    {
+        int i;
+        for (i = 0; i < This->enumMediaDetails.cMediaTypes; i++)
+            if (This->enumMediaDetails.pMediaTypes[i].pbFormat)
+                CoTaskMemFree(This->enumMediaDetails.pMediaTypes[i].pbFormat);
+        CoTaskMemFree(This->enumMediaDetails.pMediaTypes);
+        CoTaskMemFree(This);
+    }
+    return refCount;
+}
+
+static HRESULT WINAPI IEnumMediaTypesImpl_Next(IEnumMediaTypes * iface, ULONG cMediaTypes, AM_MEDIA_TYPE ** ppMediaTypes, ULONG * pcFetched)
+{
+    ULONG cFetched; 
+    IEnumMediaTypesImpl *This = (IEnumMediaTypesImpl *)iface;
+
+    cFetched = min(This->enumMediaDetails.cMediaTypes, This->uIndex + cMediaTypes) - This->uIndex;
+
+    TRACE("(%lu, %p, %p)\n", cMediaTypes, ppMediaTypes, pcFetched);
+    TRACE("Next uIndex: %lu, cFetched: %lu\n", This->uIndex, cFetched);
+
+    if (cFetched > 0)
+    {
+        ULONG i;
+        for (i = 0; i < cFetched; i++)
+            if (!(ppMediaTypes[i] = CreateMediaType(&This->enumMediaDetails.pMediaTypes[This->uIndex + i])))
+            {
+                while (i--)
+                    DeleteMediaType(ppMediaTypes[i]);
+                *pcFetched = 0;
+                return E_OUTOFMEMORY;
+            }
+    }
+
+    if ((cMediaTypes != 1) || pcFetched)
+        *pcFetched = cFetched;
+
+    This->uIndex += cFetched;
+
+    if (cFetched != cMediaTypes)
+        return S_FALSE;
+    return S_OK;
+}
+
+static HRESULT WINAPI IEnumMediaTypesImpl_Skip(IEnumMediaTypes * iface, ULONG cMediaTypes)
+{
+    IEnumMediaTypesImpl *This = (IEnumMediaTypesImpl *)iface;
+
+    TRACE("(%lu)\n", cMediaTypes);
+
+    if (This->uIndex + cMediaTypes < This->enumMediaDetails.cMediaTypes)
+    {
+        This->uIndex += cMediaTypes;
+        return S_OK;
+    }
+    return S_FALSE;
+}
+
+static HRESULT WINAPI IEnumMediaTypesImpl_Reset(IEnumMediaTypes * iface)
+{
+    IEnumMediaTypesImpl *This = (IEnumMediaTypesImpl *)iface;
+
+    TRACE("()\n");
+
+    This->uIndex = 0;
+    return S_OK;
+}
+
+static HRESULT WINAPI IEnumMediaTypesImpl_Clone(IEnumMediaTypes * iface, IEnumMediaTypes ** ppEnum)
+{
+    HRESULT hr;
+    IEnumMediaTypesImpl *This = (IEnumMediaTypesImpl *)iface;
+
+    TRACE("(%p)\n", ppEnum);
+
+    hr = IEnumMediaTypesImpl_Construct(&This->enumMediaDetails, ppEnum);
+    if (FAILED(hr))
+        return hr;
+    return IEnumMediaTypes_Skip(*ppEnum, This->uIndex);
+}
+
+static const IEnumMediaTypesVtbl IEnumMediaTypesImpl_Vtbl =
+{
+    IEnumMediaTypesImpl_QueryInterface,
+    IEnumMediaTypesImpl_AddRef,
+    IEnumMediaTypesImpl_Release,
+    IEnumMediaTypesImpl_Next,
+    IEnumMediaTypesImpl_Skip,
+    IEnumMediaTypesImpl_Reset,
+    IEnumMediaTypesImpl_Clone
+};
--- /dev/null	1970-01-01 01:00:00.000000000 +0100
+++ dlls/winestrmbase/debug.c	2005-08-03 19:06:03.000000000 +0100
@@ -0,0 +1,75 @@
+/*              DirectShow Debug Functions
+ *
+ * Copyright 2002 Lionel Ulmer
+ *
+ * This file contains the (internal) driver registration functions,
+ * driver enumeration APIs and DirectDraw creation functions.
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "config.h"
+#include "wine/debug.h"
+#include "dshow.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(quartz);
+
+#define OUR_GUID_ENTRY(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
+    { { l, w1, w2, { b1, b2,  b3,  b4,  b5,  b6,  b7,  b8 } } , #name },
+
+static struct {
+	const GUID	riid;
+	const char 	*name;
+} InterfaceDesc[] =
+{
+#include "uuids.h"
+    { { 0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0} }, NULL }
+};
+
+/***********************************************************************
+ *              qzdebugstr_guid (internal)
+ *
+ * Gives a text version of DirectShow GUIDs
+ */
+const char * qzdebugstr_guid( const GUID * id )
+{
+    int i;
+    char * name = NULL;
+
+    for (i=0;InterfaceDesc[i].name && !name;i++) {
+        if (IsEqualGUID(&InterfaceDesc[i].riid, id)) return InterfaceDesc[i].name;
+    }
+    return debugstr_guid(id);
+}
+
+/***********************************************************************
+ *              qzdebugstr_State (internal)
+ *
+ * Gives a text version of the FILTER_STATE enumeration
+ */
+const char * qzdebugstr_State(FILTER_STATE state)
+{
+    switch (state)
+    {
+    case State_Stopped:
+        return "State_Stopped";
+    case State_Running:
+        return "State_Running";
+    case State_Paused:
+        return "State_Paused";
+    default:
+        return "State_Unknown";
+    }
+}
--- /dev/null	1970-01-01 01:00:00.000000000 +0100
+++ include/wine/winestreams.h	2005-08-04 14:25:11.000000000 +0100
@@ -0,0 +1,213 @@
+/*
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __WINE_WINESTREAMS_H
+#define __WINE_WINESTREAMS_H
+
+/**************************************************************************************************/
+/***                                   Misc Defines and Function                                ***/
+/**************************************************************************************************/
+
+#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)
+
+const char * qzdebugstr_guid(const GUID * id);
+const char * qzdebugstr_State(FILTER_STATE state);
+
+/**************************************************************************************************/
+/***                                     Media Types Functions                                  ***/
+/**************************************************************************************************/
+
+typedef struct tagENUMEDIADETAILS
+{
+	ULONG cMediaTypes;
+	AM_MEDIA_TYPE * pMediaTypes;
+} ENUMMEDIADETAILS;
+
+HRESULT IEnumMediaTypesImpl_Construct(const ENUMMEDIADETAILS * pDetails, IEnumMediaTypes ** ppEnum);
+
+HRESULT CopyMediaType(AM_MEDIA_TYPE * pDest, const AM_MEDIA_TYPE *pSrc);
+void FreeMediaType(AM_MEDIA_TYPE * pmt);
+void DeleteMediaType(AM_MEDIA_TYPE * pmt);
+BOOL CompareMediaTypes(const AM_MEDIA_TYPE * pmt1, const AM_MEDIA_TYPE * pmt2, BOOL bWildcards);
+
+void dump_AM_MEDIA_TYPE(const AM_MEDIA_TYPE * pmt);
+
+/**************************************************************************************************/
+/***                                         Pins Functions                                     ***/
+/**************************************************************************************************/
+
+typedef struct tagENUMPINDETAILS
+{
+	ULONG cPins;
+	IPin ** ppPins;
+} ENUMPINDETAILS;
+
+HRESULT IEnumPinsImpl_Construct(const ENUMPINDETAILS * pDetails, IEnumPins ** ppEnum);
+
+/* This function will process incoming samples to the pin.
+ * Any return value valid in IMemInputPin::Receive is allowed here
+ */
+typedef HRESULT (* SAMPLEPROC)(LPVOID userdata, IMediaSample * pSample);
+
+/* 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.
+ */
+typedef HRESULT (* PRECONNECTPROC)(IPin * iface, IPin * pConnectPin);
+
+typedef struct IPinImpl
+{
+	const struct IPinVtbl * lpVtbl;
+	ULONG refCount;
+	LPCRITICAL_SECTION pCritSec;
+	PIN_INFO pinInfo;
+	IPin * pConnectedTo;
+	AM_MEDIA_TYPE mtCurrent;
+	ENUMMEDIADETAILS enumMediaDetails;
+	QUERYACCEPTPROC fnQueryAccept;
+	LPVOID pUserData;
+} IPinImpl;
+
+typedef struct InputPin
+{
+	/* inheritance C style! */
+	IPinImpl pin;
+
+	const IMemInputPinVtbl * lpVtblMemInput;
+	IMemAllocator * pAllocator;
+	SAMPLEPROC fnSampleProc;
+	REFERENCE_TIME tStart;
+	REFERENCE_TIME tStop;
+	double dRate;
+} InputPin;
+
+typedef struct OutputPin
+{
+	/* inheritance C style! */
+	IPinImpl pin;
+
+	IMemInputPin * pMemInputPin;
+	HRESULT (* pConnectSpecific)(IPin * iface, IPin * pReceiver, const AM_MEDIA_TYPE * pmt);
+	ALLOCATOR_PROPERTIES allocProps;
+} OutputPin;
+
+typedef struct PullPin
+{
+	/* inheritance C style! */
+	IPinImpl pin;
+
+	IAsyncReader * pReader;
+	IMemAllocator * pAlloc;
+	SAMPLEPROC fnSampleProc;
+	PRECONNECTPROC fnPreConnect;
+	HANDLE hThread;
+	HANDLE hEventStateChanged;
+	REFERENCE_TIME rtStart;
+	REFERENCE_TIME rtStop;
+} 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, ALLOCATOR_PROPERTIES *props, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, LPCRITICAL_SECTION pCritSec, OutputPin * pPinImpl);
+HRESULT PullPin_Init(const PIN_INFO * pPinInfo, SAMPLEPROC pSampleProc, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, LPCRITICAL_SECTION pCritSec, PullPin * pPinImpl);
+
+/*** Constructors ***/
+HRESULT InputPin_Construct(const PIN_INFO * pPinInfo, SAMPLEPROC pSampleProc, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, LPCRITICAL_SECTION pCritSec, IPin ** ppPin);
+HRESULT OutputPin_Construct(const PIN_INFO * pPinInfo, ALLOCATOR_PROPERTIES *props, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, LPCRITICAL_SECTION pCritSec, IPin ** ppPin);
+HRESULT PullPin_Construct(const PIN_INFO * pPinInfo, SAMPLEPROC pSampleProc, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, LPCRITICAL_SECTION pCritSec, IPin ** ppPin);
+
+/**************************/
+/*** Pin Implementation ***/
+
+/* Common */
+ULONG   WINAPI IPinImpl_AddRef(IPin * iface);
+HRESULT WINAPI IPinImpl_Disconnect(IPin * iface);
+HRESULT WINAPI IPinImpl_ConnectedTo(IPin * iface, IPin ** ppPin);
+HRESULT WINAPI IPinImpl_ConnectionMediaType(IPin * iface, AM_MEDIA_TYPE * pmt);
+HRESULT WINAPI IPinImpl_QueryPinInfo(IPin * iface, PIN_INFO * pInfo);
+HRESULT WINAPI IPinImpl_QueryDirection(IPin * iface, PIN_DIRECTION * pPinDir);
+HRESULT WINAPI IPinImpl_QueryId(IPin * iface, LPWSTR * Id);
+HRESULT WINAPI IPinImpl_QueryAccept(IPin * iface, const AM_MEDIA_TYPE * pmt);
+HRESULT WINAPI IPinImpl_EnumMediaTypes(IPin * iface, IEnumMediaTypes ** ppEnum);
+HRESULT WINAPI IPinImpl_QueryInternalConnections(IPin * iface, IPin ** apPin, ULONG * cPin);
+
+/* Input Pin */
+HRESULT WINAPI InputPin_QueryInterface(IPin * iface, REFIID riid, LPVOID * ppv);
+ULONG   WINAPI InputPin_Release(IPin * iface);
+HRESULT WINAPI InputPin_Connect(IPin * iface, IPin * pConnector, const AM_MEDIA_TYPE * pmt);
+HRESULT WINAPI InputPin_ReceiveConnection(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt);
+HRESULT WINAPI InputPin_EndOfStream(IPin * iface);
+HRESULT WINAPI InputPin_BeginFlush(IPin * iface);
+HRESULT WINAPI InputPin_EndFlush(IPin * iface);
+HRESULT WINAPI InputPin_NewSegment(IPin * iface, REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate);
+
+/* Output Pin */
+HRESULT WINAPI OutputPin_QueryInterface(IPin * iface, REFIID riid, LPVOID * ppv);
+ULONG   WINAPI OutputPin_Release(IPin * iface);
+HRESULT WINAPI OutputPin_Connect(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt);
+HRESULT WINAPI OutputPin_Disconnect(IPin * iface);
+HRESULT WINAPI OutputPin_ReceiveConnection(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt);
+HRESULT WINAPI OutputPin_EndOfStream(IPin * iface);
+HRESULT WINAPI OutputPin_BeginFlush(IPin * iface);
+HRESULT WINAPI OutputPin_EndFlush(IPin * iface);
+HRESULT WINAPI OutputPin_NewSegment(IPin * iface, REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate);
+
+HRESULT OutputPin_CommitAllocator(OutputPin * This);
+HRESULT OutputPin_GetDeliveryBuffer(OutputPin * This, IMediaSample ** ppSample, const REFERENCE_TIME * tStart, const REFERENCE_TIME * tStop, DWORD dwFlags);
+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);
+
+
+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_QueryInterface(IPin * iface, REFIID riid, LPVOID * ppv);
+ULONG   WINAPI PullPin_Release(IPin * iface);
+HRESULT PullPin_InitProcessing(PullPin * This);
+HRESULT PullPin_StartProcessing(PullPin * This);
+HRESULT PullPin_StopProcessing(PullPin * This);
+HRESULT PullPin_PauseProcessing(PullPin * This);
+HRESULT PullPin_Seek(PullPin * This, REFERENCE_TIME rtStart, REFERENCE_TIME rtStop);
+HRESULT WINAPI PullPin_EndOfStream(IPin * iface);
+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);
+HRESULT PullPin_WaitForStateChange(PullPin * This, DWORD dwMilliseconds);
+
+#endif /* __WINE_WINESTREAMS_H */


More information about the wine-patches mailing list