Paul Chitescu : qedit: Add pins enumerator implementation to SampleGrabber.

Alexandre Julliard julliard at winehq.org
Mon Feb 15 10:06:11 CST 2010


Module: wine
Branch: master
Commit: 43fe5e35b861da79b973da41db479bf2140bad73
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=43fe5e35b861da79b973da41db479bf2140bad73

Author: Paul Chitescu <paulc at voip.null.ro>
Date:   Fri Feb 12 21:11:40 2010 +0200

qedit: Add pins enumerator implementation to SampleGrabber.

---

 dlls/qedit/samplegrabber.c |  162 +++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 160 insertions(+), 2 deletions(-)

diff --git a/dlls/qedit/samplegrabber.c b/dlls/qedit/samplegrabber.c
index eca259e..6b46a27 100644
--- a/dlls/qedit/samplegrabber.c
+++ b/dlls/qedit/samplegrabber.c
@@ -36,6 +36,160 @@ static WCHAR const vendor_name[] = { 'W', 'i', 'n', 'e', 0 };
 static WCHAR const pin_in_name[] = { 'I', 'n', 0 };
 static WCHAR const pin_out_name[] = { 'O', 'u', 't', 0 };
 
+IEnumPins *pinsenum_create(IBaseFilter *filter, IPin **pins, ULONG pinCount);
+
+/* Fixed pins enumerator, holds filter referenced */
+typedef struct _PE_Impl {
+    IEnumPins pe;
+    IBaseFilter *filter;
+    LONG refCount;
+    ULONG numPins;
+    ULONG index;
+    IPin *pins[0];
+} PE_Impl;
+
+
+/* IEnumPins interface implementation */
+
+/* IUnknown */
+static ULONG WINAPI
+Fixed_IEnumPins_AddRef(IEnumPins *iface)
+{
+    PE_Impl *This = (PE_Impl *)iface;
+    ULONG refCount = InterlockedIncrement(&This->refCount);
+    TRACE("(%p) new ref = %u\n", This, refCount);
+    return refCount;
+}
+
+/* IUnknown */
+static ULONG WINAPI
+Fixed_IEnumPins_Release(IEnumPins *iface)
+{
+    PE_Impl *This = (PE_Impl *)iface;
+    ULONG refCount = InterlockedDecrement(&This->refCount);
+    TRACE("(%p) new ref = %u\n", This, refCount);
+    if (refCount == 0)
+    {
+        IBaseFilter_Release(This->filter);
+        CoTaskMemFree(This);
+        return 0;
+    }
+    return refCount;
+}
+
+/* IUnknown */
+static HRESULT WINAPI
+Fixed_IEnumPins_QueryInterface(IEnumPins *iface, REFIID riid, void **ppvObject)
+{
+    PE_Impl *This = (PE_Impl *)iface;
+    TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppvObject);
+
+    if (IsEqualIID(riid, &IID_IUnknown) ||
+        IsEqualIID(riid, &IID_IEnumPins)) {
+	Fixed_IEnumPins_AddRef(iface);
+        *ppvObject = &(This->pins);
+        return S_OK;
+    }
+    *ppvObject = NULL;
+    WARN("(%p, %s,%p): not found\n", This, debugstr_guid(riid), ppvObject);
+    return E_NOINTERFACE;
+}
+
+/* IEnumPins */
+static HRESULT WINAPI
+Fixed_IEnumPins_Next(IEnumPins *iface, ULONG nPins, IPin **pins, ULONG *fetched)
+{
+    PE_Impl *This = (PE_Impl *)iface;
+    ULONG count = 0;
+    TRACE("(%p)->(%u, %p, %p) index = %u\n", This, nPins, pins, fetched, This->index);
+    if (!nPins)
+        return E_INVALIDARG;
+    if (!pins || ((nPins != 1) && !fetched))
+        return E_POINTER;
+    while ((count < nPins) && (This->index < This->numPins)) {
+        IPin *pin = This->pins[This->index++];
+        IPin_AddRef(pin);
+        pins[count++] = pin;
+    }
+    if (fetched)
+        *fetched = count;
+    return (count == nPins) ? S_OK : S_FALSE;
+}
+
+/* IEnumPins */
+static HRESULT WINAPI
+Fixed_IEnumPins_Skip(IEnumPins *iface, ULONG nPins)
+{
+    PE_Impl *This = (PE_Impl *)iface;
+    TRACE("(%p)->(%u) index = %u\n", This, nPins, This->index);
+    nPins += This->index;
+    if (nPins >= This->numPins) {
+        This->index = This->numPins;
+        return S_FALSE;
+    }
+    This->index = nPins;
+    return S_OK;
+}
+
+/* IEnumPins */
+static HRESULT WINAPI
+Fixed_IEnumPins_Reset(IEnumPins *iface)
+{
+    PE_Impl *This = (PE_Impl *)iface;
+    TRACE("(%p)->() index = %u\n", This, This->index);
+    This->index = 0;
+    return S_OK;
+}
+
+/* IEnumPins */
+static HRESULT WINAPI
+Fixed_IEnumPins_Clone(IEnumPins *iface, IEnumPins **pins)
+{
+    PE_Impl *This = (PE_Impl *)iface;
+    TRACE("(%p)->(%p) index = %u\n", This, pins, This->index);
+    if (!pins)
+        return E_POINTER;
+    *pins = pinsenum_create(This->filter, This->pins, This->numPins);
+    if (!*pins)
+        return E_OUTOFMEMORY;
+    ((PE_Impl *)*pins)->index = This->index;
+    return S_OK;
+}
+
+
+/* Virtual tables and constructor */
+
+static const IEnumPinsVtbl IEnumPins_VTable =
+{
+    Fixed_IEnumPins_QueryInterface,
+    Fixed_IEnumPins_AddRef,
+    Fixed_IEnumPins_Release,
+    Fixed_IEnumPins_Next,
+    Fixed_IEnumPins_Skip,
+    Fixed_IEnumPins_Reset,
+    Fixed_IEnumPins_Clone,
+};
+
+IEnumPins *pinsenum_create(IBaseFilter *filter, IPin **pins, ULONG pinCount)
+{
+    ULONG len = sizeof(PE_Impl) + (pinCount * sizeof(IPin *));
+    PE_Impl *obj = CoTaskMemAlloc(len);
+    if (obj) {
+        ULONG i;
+        ZeroMemory(obj, len);
+        obj->pe.lpVtbl = &IEnumPins_VTable;
+        obj->refCount = 1;
+        obj->filter = filter;
+        obj->numPins = pinCount;
+        obj->index = 0;
+        for (i=0; i<pinCount; i++)
+            obj->pins[i] = pins[i];
+        IBaseFilter_AddRef(filter);
+    }
+    return &obj->pe;
+}
+
+
 /* Sample Grabber pin implementation */
 typedef struct _SG_Pin {
     const IPinVtbl* lpVtbl;
@@ -314,10 +468,14 @@ static HRESULT WINAPI
 SampleGrabber_IBaseFilter_EnumPins(IBaseFilter *iface, IEnumPins **pins)
 {
     SG_Impl *This = impl_from_IBaseFilter(iface);
-    FIXME("(%p)->(%p): stub\n", This, pins);
+    IPin *pin[2];
+    TRACE("(%p)->(%p)\n", This, pins);
     if (!pins)
         return E_POINTER;
-    return E_OUTOFMEMORY;
+    pin[0] = (IPin*)&This->pin_in.lpVtbl;
+    pin[1] = (IPin*)&This->pin_out.lpVtbl;
+    *pins = pinsenum_create(iface, pin, 2);
+    return *pins ? S_OK : E_OUTOFMEMORY;
 }
 
 /* IBaseFilter */




More information about the wine-cvs mailing list