[KSPROXY]
authorJohannes Anderwald <johannes.anderwald@reactos.org>
Thu, 4 Mar 2010 17:34:22 +0000 (17:34 +0000)
committerJohannes Anderwald <johannes.anderwald@reactos.org>
Thu, 4 Mar 2010 17:34:22 +0000 (17:34 +0000)
- Silence traces in IEnumPins interface
- Partly implement IKsObject interface for COutputPin
- Retrieve pin communication and pass it to constructor of CInputPin
- Implement IKsPinEx and IMemInputPin interface for CInputPin
- The DVBT network provider can now connect to the BDA Source Filter

svn path=/trunk/; revision=45836

reactos/dll/directx/ksproxy/enumpins.cpp
reactos/dll/directx/ksproxy/input_pin.cpp
reactos/dll/directx/ksproxy/ksproxy.rbuild
reactos/dll/directx/ksproxy/output_pin.cpp
reactos/dll/directx/ksproxy/precomp.h
reactos/dll/directx/ksproxy/proxy.cpp

index 5d71d53..5c0f0ec 100644 (file)
@@ -64,13 +64,6 @@ CEnumPins::QueryInterface(
         return NOERROR;
     }
 
         return NOERROR;
     }
 
-    WCHAR Buffer[MAX_PATH];
-    LPOLESTR lpstr;
-    StringFromCLSID(refiid, &lpstr);
-    swprintf(Buffer, L"CEnumPins::QueryInterface: NoInterface for %s\n", lpstr);
-    OutputDebugStringW(Buffer);
-    CoTaskMemFree(lpstr);
-
     return E_NOINTERFACE;
 }
 
     return E_NOINTERFACE;
 }
 
@@ -89,10 +82,6 @@ CEnumPins::Next(
     if (cPins > 1 && !pcFetched)
         return E_INVALIDARG;
 
     if (cPins > 1 && !pcFetched)
         return E_INVALIDARG;
 
-    WCHAR Buffer[MAX_PATH];
-    swprintf(Buffer, L"CEnumPins::Next: this %p m_Index %lx cPins %u\n", this, m_Index, cPins);
-    OutputDebugStringW(Buffer);
-
     while(i < cPins)
     {
         if (m_Index + i >= m_Pins.size())
     while(i < cPins)
     {
         if (m_Index + i >= m_Pins.size())
@@ -110,7 +99,6 @@ CEnumPins::Next(
     }
 
     m_Index += i;
     }
 
     m_Index += i;
-    OutputDebugStringW(L"CEnumPins::Next: done\n");
     if (i < cPins)
         return S_FALSE;
     else
     if (i < cPins)
         return S_FALSE;
     else
@@ -157,14 +145,6 @@ CEnumPins_fnConstructor(
 {
     CEnumPins * handler = new CEnumPins(Pins);
 
 {
     CEnumPins * handler = new CEnumPins(Pins);
 
-#ifdef MSDVBNP_TRACE
-    WCHAR Buffer[MAX_PATH];
-    LPOLESTR lpstr;
-    StringFromCLSID(riid, &lpstr);
-    swprintf(Buffer, L"CEnumPins_fnConstructor riid %s pUnknown %p\n", lpstr, pUnknown);
-    OutputDebugStringW(Buffer);
-#endif
-
     if (!handler)
         return E_OUTOFMEMORY;
 
     if (!handler)
         return E_OUTOFMEMORY;
 
index 896335b..2b08b16 100644 (file)
@@ -8,13 +8,32 @@
  */
 #include "precomp.h"
 
  */
 #include "precomp.h"
 
+const GUID IID_IKsPinEx = {0x7bb38260L, 0xd19c, 0x11d2, {0xb3, 0x8a, 0x00, 0xa0, 0xc9, 0x5e, 0xc2, 0x2e}};
+const GUID KSPROPSETID_Connection = {0x1D58C920L, 0xAC9B, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
+
+KSPIN_INTERFACE StandardPinInterface = 
+{
+    {STATIC_KSINTERFACESETID_Standard},
+    KSINTERFACE_STANDARD_STREAMING,
+    0
+};
+
+KSPIN_MEDIUM StandardPinMedium =
+{
+    {STATIC_KSMEDIUMSETID_Standard},
+    KSMEDIUM_TYPE_ANYINSTANCE,
+    0
+};
+
+
 class CInputPin : public IPin,
                   public IKsPropertySet,
                   public IKsControl,
 class CInputPin : public IPin,
                   public IKsPropertySet,
                   public IKsControl,
-                  public IKsObject
+                  public IKsObject,
+                  public IKsPinEx,
+                  public IMemInputPin
 /*
                   public IQualityControl,
 /*
                   public IQualityControl,
-                  public IKsPinEx,
                   public IKsPinPipe,
                   public ISpecifyPropertyPages,
                   public IStreamBuilder,
                   public IKsPinPipe,
                   public ISpecifyPropertyPages,
                   public IStreamBuilder,
@@ -71,8 +90,36 @@ public:
     HRESULT STDMETHODCALLTYPE KsMethod(PKSMETHOD Method, ULONG MethodLength, LPVOID MethodData, ULONG DataLength, ULONG* BytesReturned);
     HRESULT STDMETHODCALLTYPE KsEvent(PKSEVENT Event, ULONG EventLength, LPVOID EventData, ULONG DataLength, ULONG* BytesReturned);
 
     HRESULT STDMETHODCALLTYPE KsMethod(PKSMETHOD Method, ULONG MethodLength, LPVOID MethodData, ULONG DataLength, ULONG* BytesReturned);
     HRESULT STDMETHODCALLTYPE KsEvent(PKSEVENT Event, ULONG EventLength, LPVOID EventData, ULONG DataLength, ULONG* BytesReturned);
 
+    //IKsPin
+    HRESULT STDMETHODCALLTYPE KsQueryMediums(PKSMULTIPLE_ITEM* MediumList);
+    HRESULT STDMETHODCALLTYPE KsQueryInterfaces(PKSMULTIPLE_ITEM* InterfaceList);
+    HRESULT STDMETHODCALLTYPE KsCreateSinkPinHandle(KSPIN_INTERFACE& Interface, KSPIN_MEDIUM& Medium);
+    HRESULT STDMETHODCALLTYPE KsGetCurrentCommunication(KSPIN_COMMUNICATION *Communication, KSPIN_INTERFACE *Interface, KSPIN_MEDIUM *Medium);
+    HRESULT STDMETHODCALLTYPE KsPropagateAcquire();
+    HRESULT STDMETHODCALLTYPE KsDeliver(IMediaSample* Sample, ULONG Flags);
+    HRESULT STDMETHODCALLTYPE KsMediaSamplesCompleted(PKSSTREAM_SEGMENT StreamSegment);
+    IMemAllocator * STDMETHODCALLTYPE KsPeekAllocator(KSPEEKOPERATION Operation);
+    HRESULT STDMETHODCALLTYPE KsReceiveAllocator(IMemAllocator *MemAllocator);
+    HRESULT STDMETHODCALLTYPE KsRenegotiateAllocator();
+    LONG STDMETHODCALLTYPE KsIncrementPendingIoCount();
+    LONG STDMETHODCALLTYPE KsDecrementPendingIoCount();
+    HRESULT STDMETHODCALLTYPE KsQualityNotify(ULONG Proportion, REFERENCE_TIME TimeDelta);
+    // IKsPinEx
+    VOID STDMETHODCALLTYPE KsNotifyError(IMediaSample* Sample, HRESULT hr);
+
+    //IMemInputPin
+    HRESULT STDMETHODCALLTYPE GetAllocator(IMemAllocator **ppAllocator);
+    HRESULT STDMETHODCALLTYPE NotifyAllocator(IMemAllocator *pAllocator, BOOL bReadOnly);
+    HRESULT STDMETHODCALLTYPE GetAllocatorRequirements(ALLOCATOR_PROPERTIES *pProps);
+    HRESULT STDMETHODCALLTYPE Receive(IMediaSample *pSample);
+    HRESULT STDMETHODCALLTYPE ReceiveMultiple(IMediaSample **pSamples, long nSamples, long *nSamplesProcessed);
+    HRESULT STDMETHODCALLTYPE ReceiveCanBlock( void);
+
+    //---------------------------------------------------------------
     HRESULT STDMETHODCALLTYPE CheckFormat(const AM_MEDIA_TYPE *pmt);
     HRESULT STDMETHODCALLTYPE CheckFormat(const AM_MEDIA_TYPE *pmt);
-    CInputPin(IBaseFilter * ParentFilter, LPCWSTR PinName, HANDLE hFilter, ULONG PinId) : m_Ref(0), m_ParentFilter(ParentFilter), m_PinName(PinName), m_hFilter(hFilter), m_hPin(0), m_PinId(PinId){};
+    HRESULT STDMETHODCALLTYPE CreatePin();
+    HRESULT STDMETHODCALLTYPE CreatePinHandle(PKSPIN_MEDIUM Medium, PKSPIN_INTERFACE Interface, PKSDATAFORMAT DataFormat);
+    CInputPin(IBaseFilter * ParentFilter, LPCWSTR PinName, HANDLE hFilter, ULONG PinId, KSPIN_COMMUNICATION Communication) : m_Ref(0), m_ParentFilter(ParentFilter), m_PinName(PinName), m_hFilter(hFilter), m_hPin(0), m_PinId(PinId), m_MemAllocator(0), m_IoCount(0), m_Communication(Communication), m_Pin(0){};
     virtual ~CInputPin(){};
 
 protected:
     virtual ~CInputPin(){};
 
 protected:
@@ -82,6 +129,12 @@ protected:
     HANDLE m_hFilter;
     HANDLE m_hPin;
     ULONG m_PinId;
     HANDLE m_hFilter;
     HANDLE m_hPin;
     ULONG m_PinId;
+    IMemAllocator * m_MemAllocator;
+    LONG m_IoCount;
+    KSPIN_COMMUNICATION m_Communication;
+    KSPIN_INTERFACE m_Interface;
+    KSPIN_MEDIUM m_Medium;
+    IPin * m_Pin;
 };
 
 HRESULT
 };
 
 HRESULT
@@ -99,12 +152,19 @@ CInputPin::QueryInterface(
         reinterpret_cast<IUnknown*>(*Output)->AddRef();
         return NOERROR;
     }
         reinterpret_cast<IUnknown*>(*Output)->AddRef();
         return NOERROR;
     }
+    else if (IsEqualGUID(refiid, IID_IMemInputPin))
+    {
+        *Output = (IMemInputPin*)(this);
+        reinterpret_cast<IMemInputPin*>(*Output)->AddRef();
+        return NOERROR;
+    }
     else if (IsEqualGUID(refiid, IID_IKsObject))
     {
         if (!m_hPin)
         {
     else if (IsEqualGUID(refiid, IID_IKsObject))
     {
         if (!m_hPin)
         {
-            OutputDebugStringW(L"CInputPin::QueryInterface IID_IKsObject Create PIN!!!\n");
-            DebugBreak();
+            HRESULT hr = CreatePin();
+            if (FAILED(hr))
+                return hr;
         }
 
         *Output = (IKsObject*)(this);
         }
 
         *Output = (IKsObject*)(this);
@@ -115,8 +175,9 @@ CInputPin::QueryInterface(
     {
         if (!m_hPin)
         {
     {
         if (!m_hPin)
         {
-            OutputDebugStringW(L"CInputPin::QueryInterface IID_IKsPropertySet Create PIN!!!\n");
-            DebugBreak();
+            HRESULT hr = CreatePin();
+            if (FAILED(hr))
+                return hr;
         }
 
         *Output = (IKsPropertySet*)(this);
         }
 
         *Output = (IKsPropertySet*)(this);
@@ -127,14 +188,30 @@ CInputPin::QueryInterface(
     {
         if (!m_hPin)
         {
     {
         if (!m_hPin)
         {
-            OutputDebugStringW(L"CInputPin::QueryInterface IID_IKsControl Create PIN!!!\n");
-            DebugBreak();
+            HRESULT hr = CreatePin();
+            if (FAILED(hr))
+                return hr;
         }
 
         *Output = (IKsControl*)(this);
         reinterpret_cast<IKsControl*>(*Output)->AddRef();
         return NOERROR;
     }
         }
 
         *Output = (IKsControl*)(this);
         reinterpret_cast<IKsControl*>(*Output)->AddRef();
         return NOERROR;
     }
+    else if (IsEqualGUID(refiid, IID_IKsPin) ||
+             IsEqualGUID(refiid, IID_IKsPinEx))
+    {
+        if (!m_hPin)
+        {
+            HRESULT hr = CreatePin();
+            if (FAILED(hr))
+                return hr;
+        }
+
+        *Output = (IKsPinEx*)(this);
+        reinterpret_cast<IKsPinEx*>(*Output)->AddRef();
+        return NOERROR;
+    }
+
 
     WCHAR Buffer[MAX_PATH];
     LPOLESTR lpstr;
 
     WCHAR Buffer[MAX_PATH];
     LPOLESTR lpstr;
@@ -146,6 +223,248 @@ CInputPin::QueryInterface(
     return E_NOINTERFACE;
 }
 
     return E_NOINTERFACE;
 }
 
+//-------------------------------------------------------------------
+// IMemInputPin
+//
+
+    //
+HRESULT
+STDMETHODCALLTYPE
+CInputPin::GetAllocator(IMemAllocator **ppAllocator)
+{
+    OutputDebugStringW(L"CInputPin::GetAllocator\n");
+    return VFW_E_NO_ALLOCATOR;
+}
+
+HRESULT
+STDMETHODCALLTYPE
+CInputPin::NotifyAllocator(IMemAllocator *pAllocator, BOOL bReadOnly)
+{
+    if (pAllocator)
+    {
+        pAllocator->AddRef();
+    }
+
+    if (m_MemAllocator)
+    {
+        m_MemAllocator->Release();
+    }
+
+    m_MemAllocator = pAllocator;
+    return NOERROR;
+}
+
+HRESULT
+STDMETHODCALLTYPE
+CInputPin::GetAllocatorRequirements(ALLOCATOR_PROPERTIES *pProps)
+{
+    KSALLOCATOR_FRAMING Framing;
+    KSPROPERTY Property;
+    HRESULT hr;
+    ULONG BytesReturned;
+
+    Property.Set = KSPROPSETID_Connection;
+    Property.Id = KSPROPERTY_CONNECTION_ALLOCATORFRAMING;
+    Property.Flags = KSPROPERTY_TYPE_SET;
+
+    hr = KsProperty(&Property, sizeof(KSPROPERTY), (PVOID)&Framing, sizeof(KSALLOCATOR_FRAMING), &BytesReturned);
+    if (SUCCEEDED(hr))
+    {
+        pProps->cBuffers = Framing.Frames;
+        pProps->cbBuffer = Framing.FrameSize;
+        pProps->cbAlign = Framing.FileAlignment;
+        pProps->cbPrefix = 0;
+        return hr;
+    }
+    else
+        return E_NOTIMPL;
+}
+
+HRESULT
+STDMETHODCALLTYPE
+CInputPin::Receive(IMediaSample *pSample)
+{
+    OutputDebugStringW(L"CInputPin::Receive NotImplemented\n");
+    return E_NOTIMPL;
+}
+
+HRESULT
+STDMETHODCALLTYPE
+CInputPin::ReceiveMultiple(IMediaSample **pSamples, long nSamples, long *nSamplesProcessed)
+{
+    OutputDebugStringW(L"CInputPin::ReceiveMultiple NotImplemented\n");
+    return E_NOTIMPL;
+}
+
+HRESULT
+STDMETHODCALLTYPE
+CInputPin::ReceiveCanBlock( void)
+{
+    OutputDebugStringW(L"CInputPin::ReceiveCanBlock NotImplemented\n");
+    return S_FALSE;
+}
+
+
+//-------------------------------------------------------------------
+// IKsPin
+//
+
+HRESULT
+STDMETHODCALLTYPE
+CInputPin::KsQueryMediums(
+    PKSMULTIPLE_ITEM* MediumList)
+{
+    return KsGetMultiplePinFactoryItems(m_hFilter, m_PinId, KSPROPERTY_PIN_MEDIUMS, (PVOID*)MediumList);
+}
+
+HRESULT
+STDMETHODCALLTYPE
+CInputPin::KsQueryInterfaces(
+    PKSMULTIPLE_ITEM* InterfaceList)
+{
+    return KsGetMultiplePinFactoryItems(m_hFilter, m_PinId, KSPROPERTY_PIN_INTERFACES, (PVOID*)InterfaceList);
+}
+
+HRESULT
+STDMETHODCALLTYPE
+CInputPin::KsCreateSinkPinHandle(
+    KSPIN_INTERFACE& Interface,
+    KSPIN_MEDIUM& Medium)
+{
+    OutputDebugStringW(L"CInputPin::KsCreateSinkPinHandle NotImplemented\n");
+    return E_NOTIMPL;
+}
+
+HRESULT
+STDMETHODCALLTYPE
+CInputPin::KsGetCurrentCommunication(
+    KSPIN_COMMUNICATION *Communication,
+    KSPIN_INTERFACE *Interface,
+    KSPIN_MEDIUM *Medium)
+{
+    if (Communication)
+    {
+        *Communication = m_Communication;
+    }
+
+    if (Interface)
+    {
+        if (!m_hPin)
+            return VFW_E_NOT_CONNECTED;
+
+        CopyMemory(Interface, &m_Interface, sizeof(KSPIN_INTERFACE));
+    }
+
+    if (Medium)
+    {
+        if (!m_hPin)
+            return VFW_E_NOT_CONNECTED;
+
+        CopyMemory(Medium, &m_Medium, sizeof(KSPIN_MEDIUM));
+    }
+    return NOERROR;
+}
+
+HRESULT
+STDMETHODCALLTYPE
+CInputPin::KsPropagateAcquire()
+{
+    OutputDebugStringW(L"CInputPin::KsPropagateAcquire NotImplemented\n");
+    return E_NOTIMPL;
+}
+
+HRESULT
+STDMETHODCALLTYPE
+CInputPin::KsDeliver(
+    IMediaSample* Sample,
+    ULONG Flags)
+{
+    return E_FAIL;
+}
+
+HRESULT
+STDMETHODCALLTYPE
+CInputPin::KsMediaSamplesCompleted(PKSSTREAM_SEGMENT StreamSegment)
+{
+    return NOERROR;
+}
+
+IMemAllocator * 
+STDMETHODCALLTYPE
+CInputPin::KsPeekAllocator(KSPEEKOPERATION Operation)
+{
+    if (Operation == KsPeekOperation_AddRef)
+    {
+        // add reference on allocator
+        m_MemAllocator->AddRef();
+    }
+
+    return m_MemAllocator;
+}
+
+HRESULT
+STDMETHODCALLTYPE
+CInputPin::KsReceiveAllocator(IMemAllocator *MemAllocator)
+{
+    if (MemAllocator)
+    {
+        MemAllocator->AddRef();
+    }
+
+    if (m_MemAllocator)
+    {
+        m_MemAllocator->Release();
+    }
+
+    m_MemAllocator = MemAllocator;
+    return NOERROR;
+}
+
+HRESULT
+STDMETHODCALLTYPE
+CInputPin::KsRenegotiateAllocator()
+{
+    return E_FAIL;
+}
+
+LONG
+STDMETHODCALLTYPE
+CInputPin::KsIncrementPendingIoCount()
+{
+    return InterlockedIncrement((volatile LONG*)&m_IoCount);
+}
+
+LONG
+STDMETHODCALLTYPE
+CInputPin::KsDecrementPendingIoCount()
+{
+    return InterlockedDecrement((volatile LONG*)&m_IoCount);
+}
+
+HRESULT
+STDMETHODCALLTYPE
+CInputPin::KsQualityNotify(
+    ULONG Proportion,
+    REFERENCE_TIME TimeDelta)
+{
+    OutputDebugStringW(L"CInputPin::KsQualityNotify NotImplemented\n");
+    return E_NOTIMPL;
+}
+
+//-------------------------------------------------------------------
+// IKsPinEx
+//
+
+VOID
+STDMETHODCALLTYPE
+CInputPin::KsNotifyError(
+    IMediaSample* Sample,
+    HRESULT hr)
+{
+    OutputDebugStringW(L"CInputPin::KsNotifyError NotImplemented\n");
+}
+
+
 //-------------------------------------------------------------------
 // IKsPropertySet
 //
 //-------------------------------------------------------------------
 // IKsPropertySet
 //
@@ -314,25 +633,36 @@ HRESULT
 STDMETHODCALLTYPE
 CInputPin::Connect(IPin *pReceivePin, const AM_MEDIA_TYPE *pmt)
 {
 STDMETHODCALLTYPE
 CInputPin::Connect(IPin *pReceivePin, const AM_MEDIA_TYPE *pmt)
 {
-    //MajorFormat: KSDATAFORMAT_TYPE_BDA_ANTENNA
-    //SubType: MEDIASUBTYPE_None
-    //FormatType: FORMAT_None
-    //bFixedSizeSamples 1 bTemporalCompression 0 lSampleSize 1 pUnk 00000000 cbFormat 0 pbFormat 00000000
-
-    //KSPROPSETID_Connection KSPROPERTY_CONNECTION_PROPOSEDATAFORMAT
-    //PriorityClass = KSPRIORITY_NORMAL PrioritySubClass = KSPRIORITY_NORMAL
-
-
     OutputDebugStringW(L"CInputPin::Connect NotImplemented\n");
     OutputDebugStringW(L"CInputPin::Connect NotImplemented\n");
-    return E_NOTIMPL;
+    return NOERROR;
 }
 
 HRESULT
 STDMETHODCALLTYPE
 CInputPin::ReceiveConnection(IPin *pConnector, const AM_MEDIA_TYPE *pmt)
 {
 }
 
 HRESULT
 STDMETHODCALLTYPE
 CInputPin::ReceiveConnection(IPin *pConnector, const AM_MEDIA_TYPE *pmt)
 {
+    HRESULT hr;
+
+    if (m_Pin)
+    {
+        OutputDebugStringW(L"CInputPin::ReceiveConnection already connected\n");
+        return VFW_E_ALREADY_CONNECTED;
+    }
+
+    // first check format
+    hr = CheckFormat(pmt);
+    if (FAILED(hr))
+        return hr;
+
+    if (FAILED(CheckFormat(pmt)))
+        return hr;
+
+    //FIXME create pin
+   m_Pin = pConnector;
+   m_Pin->AddRef();
+
     OutputDebugStringW(L"CInputPin::ReceiveConnection NotImplemented\n");
     OutputDebugStringW(L"CInputPin::ReceiveConnection NotImplemented\n");
-    return E_NOTIMPL;
+    return S_OK;
 }
 HRESULT
 STDMETHODCALLTYPE
 }
 HRESULT
 STDMETHODCALLTYPE
@@ -345,8 +675,18 @@ HRESULT
 STDMETHODCALLTYPE
 CInputPin::ConnectedTo(IPin **pPin)
 {
 STDMETHODCALLTYPE
 CInputPin::ConnectedTo(IPin **pPin)
 {
+    if (!pPin)
+        return E_POINTER;
+
+    if (m_Pin)
+    {
+        // increment reference count
+        m_Pin->AddRef();
+        *pPin = m_Pin;
+        return S_OK;
+    }
+
     *pPin = NULL;
     *pPin = NULL;
-    OutputDebugStringW(L"CInputPin::ConnectedTo NotImplemented\n");
     return VFW_E_NOT_CONNECTED;
 }
 HRESULT
     return VFW_E_NOT_CONNECTED;
 }
 HRESULT
@@ -391,6 +731,56 @@ CInputPin::QueryId(LPWSTR *Id)
     return S_OK;
 }
 
     return S_OK;
 }
 
+HRESULT
+STDMETHODCALLTYPE
+CInputPin::QueryAccept(
+    const AM_MEDIA_TYPE *pmt)
+{
+    return CheckFormat(pmt);
+}
+HRESULT
+STDMETHODCALLTYPE
+CInputPin::EnumMediaTypes(IEnumMediaTypes **ppEnum)
+{
+    return CEnumMediaTypes_fnConstructor(0, NULL, IID_IEnumMediaTypes, (void**)ppEnum);
+}
+HRESULT
+STDMETHODCALLTYPE
+CInputPin::QueryInternalConnections(IPin **apPin, ULONG *nPin)
+{
+    OutputDebugStringW(L"CInputPin::QueryInternalConnections NotImplemented\n");
+    return E_NOTIMPL;
+}
+HRESULT
+STDMETHODCALLTYPE
+CInputPin::EndOfStream( void)
+{
+    OutputDebugStringW(L"CInputPin::EndOfStream NotImplemented\n");
+    return E_NOTIMPL;
+}
+HRESULT
+STDMETHODCALLTYPE
+CInputPin::BeginFlush( void)
+{
+    OutputDebugStringW(L"CInputPin::BeginFlush NotImplemented\n");
+    return E_NOTIMPL;
+}
+HRESULT
+STDMETHODCALLTYPE
+CInputPin::EndFlush( void)
+{
+    OutputDebugStringW(L"CInputPin::EndFlush NotImplemented\n");
+    return E_NOTIMPL;
+}
+HRESULT
+STDMETHODCALLTYPE
+CInputPin::NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate)
+{
+    OutputDebugStringW(L"CInputPin::NewSegment NotImplemented\n");
+    return E_NOTIMPL;
+}
+
+//-------------------------------------------------------------------
 HRESULT
 STDMETHODCALLTYPE
 CInputPin::CheckFormat(
 HRESULT
 STDMETHODCALLTYPE
 CInputPin::CheckFormat(
@@ -452,51 +842,118 @@ CInputPin::CheckFormat(
 
 HRESULT
 STDMETHODCALLTYPE
 
 HRESULT
 STDMETHODCALLTYPE
-CInputPin::QueryAccept(
-    const AM_MEDIA_TYPE *pmt)
-{
-    return CheckFormat(pmt);
-}
-HRESULT
-STDMETHODCALLTYPE
-CInputPin::EnumMediaTypes(IEnumMediaTypes **ppEnum)
-{
-    return CEnumMediaTypes_fnConstructor(0, NULL, IID_IEnumMediaTypes, (void**)ppEnum);
-}
-HRESULT
-STDMETHODCALLTYPE
-CInputPin::QueryInternalConnections(IPin **apPin, ULONG *nPin)
-{
-    OutputDebugStringW(L"CInputPin::QueryInternalConnections NotImplemented\n");
-    return E_NOTIMPL;
-}
-HRESULT
-STDMETHODCALLTYPE
-CInputPin::EndOfStream( void)
-{
-    OutputDebugStringW(L"CInputPin::EndOfStream NotImplemented\n");
-    return E_NOTIMPL;
-}
-HRESULT
-STDMETHODCALLTYPE
-CInputPin::BeginFlush( void)
-{
-    OutputDebugStringW(L"CInputPin::BeginFlush NotImplemented\n");
-    return E_NOTIMPL;
-}
-HRESULT
-STDMETHODCALLTYPE
-CInputPin::EndFlush( void)
+CInputPin::CreatePin()
 {
 {
-    OutputDebugStringW(L"CInputPin::EndFlush NotImplemented\n");
-    return E_NOTIMPL;
+    PKSMULTIPLE_ITEM MediumList;
+    PKSMULTIPLE_ITEM InterfaceList;
+    PKSMULTIPLE_ITEM DataFormatList = NULL;
+    PKSPIN_MEDIUM Medium;
+    PKSDATAFORMAT DataFormat;
+    PKSPIN_INTERFACE Interface;
+    HRESULT hr;
+
+    // query for pin medium
+    hr = KsQueryMediums(&MediumList);
+    if (FAILED(hr))
+        return hr;
+
+    // query for pin interface
+    hr = KsQueryInterfaces(&InterfaceList);
+    if (FAILED(hr))
+    {
+        // failed
+        CoTaskMemFree(MediumList);
+        return hr;
+    }
+
+    // get data ranges
+    hr = KsGetMultiplePinFactoryItems(m_hFilter, m_PinId, KSPROPERTY_PIN_DATARANGES, (PVOID*)&DataFormatList);
+    if (FAILED(hr) || DataFormatList->Count == 0)
+    {
+        // failed
+        CoTaskMemFree(MediumList);
+        CoTaskMemFree(InterfaceList);
+        if (DataFormatList)
+            CoTaskMemFree(DataFormatList);
+
+        return hr;
+    }
+
+    if (MediumList->Count)
+    {
+        //use first available medium
+        Medium = (PKSPIN_MEDIUM)(MediumList + 1);
+    }
+    else
+    {
+        // default to standard medium
+        Medium = &StandardPinMedium;
+    }
+
+    if (InterfaceList->Count)
+    {
+        //use first available interface
+        Interface = (PKSPIN_INTERFACE)(InterfaceList + 1);
+    }
+    else
+    {
+        // default to standard interface
+        Interface = &StandardPinInterface;
+    }
+
+    //FIXME determine format
+    // use first available format
+    DataFormat = (PKSDATAFORMAT) (DataFormatList + 1);
+
+    // now create pin
+    hr = CreatePinHandle(Medium, Interface, DataFormat);
+
+    // free medium / interface / dataformat
+    CoTaskMemFree(DataFormatList);
+    CoTaskMemFree(MediumList);
+    CoTaskMemFree(InterfaceList);
+
+    return hr;
 }
 }
+
 HRESULT
 STDMETHODCALLTYPE
 HRESULT
 STDMETHODCALLTYPE
-CInputPin::NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate)
+CInputPin::CreatePinHandle(
+    PKSPIN_MEDIUM Medium,
+    PKSPIN_INTERFACE Interface,
+    PKSDATAFORMAT DataFormat)
 {
 {
-    OutputDebugStringW(L"CInputPin::NewSegment NotImplemented\n");
-    return E_NOTIMPL;
+    PKSPIN_CONNECT PinConnect;
+    ULONG Length;
+    HRESULT hr;
+
+    // calc format size
+    Length = sizeof(KSPIN_CONNECT) + DataFormat->FormatSize;
+
+    // allocate pin connect
+    PinConnect = (PKSPIN_CONNECT)CoTaskMemAlloc(Length);
+    if (!PinConnect)
+    {
+        // failed
+        return E_OUTOFMEMORY;
+    }
+
+    // setup request
+    CopyMemory(&PinConnect->Interface, Interface, sizeof(KSPIN_INTERFACE));
+    CopyMemory(&PinConnect->Medium, Medium, sizeof(KSPIN_MEDIUM));
+    PinConnect->PinId = m_PinId;
+    PinConnect->PinToHandle = NULL;
+    PinConnect->Priority.PriorityClass = KSPRIORITY_NORMAL;
+    PinConnect->Priority.PrioritySubClass = KSPRIORITY_NORMAL;
+    CopyMemory((PinConnect + 1), DataFormat, DataFormat->FormatSize);
+
+    // create pin
+    hr = KsCreatePin(m_hFilter, PinConnect, GENERIC_WRITE, &m_hPin);
+
+    // free pin connect
+     CoTaskMemFree(PinConnect);
+
+    return hr;
 }
 
 HRESULT
 }
 
 HRESULT
@@ -506,10 +963,11 @@ CInputPin_Constructor(
     LPCWSTR PinName,
     HANDLE hFilter,
     ULONG PinId,
     LPCWSTR PinName,
     HANDLE hFilter,
     ULONG PinId,
+    KSPIN_COMMUNICATION Communication,
     REFIID riid,
     LPVOID * ppv)
 {
     REFIID riid,
     LPVOID * ppv)
 {
-    CInputPin * handler = new CInputPin(ParentFilter, PinName, hFilter, PinId);
+    CInputPin * handler = new CInputPin(ParentFilter, PinName, hFilter, PinId, Communication);
 
     if (!handler)
         return E_OUTOFMEMORY;
 
     if (!handler)
         return E_OUTOFMEMORY;
index 2fa2bd3..440e279 100644 (file)
@@ -11,6 +11,7 @@
        <library>setupapi</library>
        <library>msvcrt</library>
        <library>strmiids</library>
        <library>setupapi</library>
        <library>msvcrt</library>
        <library>strmiids</library>
+       <library>ksuser</library>
        <group compilerset="gcc">
                <compilerflag compiler="cxx">-fno-exceptions</compilerflag>
                <compilerflag compiler="cxx">-fno-rtti</compilerflag>
        <group compilerset="gcc">
                <compilerflag compiler="cxx">-fno-exceptions</compilerflag>
                <compilerflag compiler="cxx">-fno-rtti</compilerflag>
index ba7b31b..b29d12a 100644 (file)
@@ -8,10 +8,10 @@
  */
 #include "precomp.h"
 
  */
 #include "precomp.h"
 
-class COutputPin : public IPin
+class COutputPin : public IPin,
+                  public IKsObject
 /*
                   public IQualityControl,
 /*
                   public IQualityControl,
-                  public IKsObject,
                   public IKsPinEx,
                   public IKsPinPipe,
                   public ISpecifyPropertyPages,
                   public IKsPinEx,
                   public IKsPinPipe,
                   public ISpecifyPropertyPages,
@@ -61,6 +61,10 @@ public:
     HRESULT STDMETHODCALLTYPE EndFlush();
     HRESULT STDMETHODCALLTYPE NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate);
 
     HRESULT STDMETHODCALLTYPE EndFlush();
     HRESULT STDMETHODCALLTYPE NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate);
 
+    //IKsObject methods
+    HANDLE STDMETHODCALLTYPE KsGetObjectHandle();
+
+
     COutputPin(IBaseFilter * ParentFilter, LPCWSTR PinName) : m_Ref(0), m_ParentFilter(ParentFilter), m_PinName(PinName){};
     virtual ~COutputPin(){};
 
     COutputPin(IBaseFilter * ParentFilter, LPCWSTR PinName) : m_Ref(0), m_ParentFilter(ParentFilter), m_PinName(PinName){};
     virtual ~COutputPin(){};
 
@@ -84,6 +88,12 @@ COutputPin::QueryInterface(
         reinterpret_cast<IUnknown*>(*Output)->AddRef();
         return NOERROR;
     }
         reinterpret_cast<IUnknown*>(*Output)->AddRef();
         return NOERROR;
     }
+    else if (IsEqualGUID(refiid, IID_IKsObject))
+    {
+        *Output = (IKsObject*)(this);
+        reinterpret_cast<IKsObject*>(*Output)->AddRef();
+        return NOERROR;
+    }
 
     WCHAR Buffer[MAX_PATH];
     LPOLESTR lpstr;
 
     WCHAR Buffer[MAX_PATH];
     LPOLESTR lpstr;
@@ -95,6 +105,20 @@ COutputPin::QueryInterface(
     return E_NOINTERFACE;
 }
 
     return E_NOINTERFACE;
 }
 
+//-------------------------------------------------------------------
+// IKsObject
+//
+HANDLE
+STDMETHODCALLTYPE
+COutputPin::KsGetObjectHandle()
+{
+    OutputDebugStringW(L"COutputPin::KsGetObjectHandle CALLED\n");
+
+    //FIXME
+    // return pin handle
+    return NULL;
+}
+
 //-------------------------------------------------------------------
 // IPin interface
 //
 //-------------------------------------------------------------------
 // IPin interface
 //
@@ -124,6 +148,7 @@ HRESULT
 STDMETHODCALLTYPE
 COutputPin::ConnectedTo(IPin **pPin)
 {
 STDMETHODCALLTYPE
 COutputPin::ConnectedTo(IPin **pPin)
 {
+    *pPin = NULL;
     OutputDebugStringW(L"COutputPin::ConnectedTo called\n");
     return VFW_E_NOT_CONNECTED;
 }
     OutputDebugStringW(L"COutputPin::ConnectedTo called\n");
     return VFW_E_NOT_CONNECTED;
 }
index 19b846a..32953e9 100644 (file)
@@ -107,6 +107,7 @@ CInputPin_Constructor(
     LPCWSTR PinName,
     HANDLE hFilter,
     ULONG PinId,
     LPCWSTR PinName,
     HANDLE hFilter,
     ULONG PinId,
+    KSPIN_COMMUNICATION Communication,
     REFIID riid,
     LPVOID * ppv);
 
     REFIID riid,
     LPVOID * ppv);
 
index 5e939eb..0ff397c 100644 (file)
@@ -95,6 +95,7 @@ public:
     HRESULT STDMETHODCALLTYPE GetPinInstanceCount(ULONG PinId, PKSPIN_CINSTANCES Instances);
     HRESULT STDMETHODCALLTYPE GetPinDataflow(ULONG PinId, KSPIN_DATAFLOW * DataFlow);
     HRESULT STDMETHODCALLTYPE GetPinName(ULONG PinId, KSPIN_DATAFLOW DataFlow, ULONG PinCount, LPWSTR * OutPinName);
     HRESULT STDMETHODCALLTYPE GetPinInstanceCount(ULONG PinId, PKSPIN_CINSTANCES Instances);
     HRESULT STDMETHODCALLTYPE GetPinDataflow(ULONG PinId, KSPIN_DATAFLOW * DataFlow);
     HRESULT STDMETHODCALLTYPE GetPinName(ULONG PinId, KSPIN_DATAFLOW DataFlow, ULONG PinCount, LPWSTR * OutPinName);
+    HRESULT STDMETHODCALLTYPE GetPinCommunication(ULONG PinId, KSPIN_COMMUNICATION * Communication);
     HRESULT STDMETHODCALLTYPE CreatePins();
 protected:
     LONG m_Ref;
     HRESULT STDMETHODCALLTYPE CreatePins();
 protected:
     LONG m_Ref;
@@ -350,6 +351,25 @@ CKsProxy::GetPinInstanceCount(
     return KsSynchronousDeviceControl(m_hDevice, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSP_PIN), (PVOID)Instances, sizeof(KSPIN_CINSTANCES), &BytesReturned);
 }
 
     return KsSynchronousDeviceControl(m_hDevice, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSP_PIN), (PVOID)Instances, sizeof(KSPIN_CINSTANCES), &BytesReturned);
 }
 
+HRESULT
+STDMETHODCALLTYPE
+CKsProxy::GetPinCommunication(
+    ULONG PinId,
+    KSPIN_COMMUNICATION * Communication)
+{
+    KSP_PIN Property;
+    ULONG BytesReturned;
+
+    // setup request
+    Property.Property.Set = KSPROPSETID_Pin;
+    Property.Property.Id = KSPROPERTY_PIN_COMMUNICATION;
+    Property.Property.Flags = KSPROPERTY_TYPE_GET;
+    Property.PinId = PinId;
+    Property.Reserved = 0;
+
+    return KsSynchronousDeviceControl(m_hDevice, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSP_PIN), (PVOID)Communication, sizeof(KSPIN_COMMUNICATION), &BytesReturned);
+}
+
 HRESULT
 STDMETHODCALLTYPE
 CKsProxy::GetPinDataflow(
 HRESULT
 STDMETHODCALLTYPE
 CKsProxy::GetPinDataflow(
@@ -446,6 +466,7 @@ CKsProxy::CreatePins()
     ULONG NumPins, Index;
     KSPIN_CINSTANCES Instances;
     KSPIN_DATAFLOW DataFlow;
     ULONG NumPins, Index;
     KSPIN_CINSTANCES Instances;
     KSPIN_DATAFLOW DataFlow;
+    KSPIN_COMMUNICATION Communication;
     HRESULT hr;
     WCHAR Buffer[100];
     LPWSTR PinName;
     HRESULT hr;
     WCHAR Buffer[100];
     LPWSTR PinName;
@@ -465,6 +486,11 @@ CKsProxy::CreatePins()
         if (FAILED(hr))
             continue;
 
         if (FAILED(hr))
             continue;
 
+        // query pin communication;
+        hr = GetPinCommunication(Index, &Communication);
+        if (FAILED(hr))
+            continue;
+
         if (Instances.CurrentCount == Instances.PossibleCount)
         {
             // already maximum reached for this pin
         if (Instances.CurrentCount == Instances.PossibleCount)
         {
             // already maximum reached for this pin
@@ -487,7 +513,7 @@ CKsProxy::CreatePins()
         // construct the pins
         if (DataFlow == KSPIN_DATAFLOW_IN)
         {
         // construct the pins
         if (DataFlow == KSPIN_DATAFLOW_IN)
         {
-            hr = CInputPin_Constructor((IBaseFilter*)this, PinName, m_hDevice, Index, IID_IPin, (void**)&pPin);
+            hr = CInputPin_Constructor((IBaseFilter*)this, PinName, m_hDevice, Index, Communication, IID_IPin, (void**)&pPin);
             if (FAILED(hr))
             {
                 CoTaskMemFree(PinName);
             if (FAILED(hr))
             {
                 CoTaskMemFree(PinName);