Zebediah Figura : amstream: Reimplement IMediaStreamFilter::EnumPins().
Alexandre Julliard
julliard at winehq.org
Fri May 17 16:10:14 CDT 2019
Module: wine
Branch: master
Commit: f423c6e7079f797f81fe2f32db089eed5320b4d4
URL: https://source.winehq.org/git/wine.git/?a=commit;h=f423c6e7079f797f81fe2f32db089eed5320b4d4
Author: Zebediah Figura <z.figura12 at gmail.com>
Date: Fri May 17 00:31:05 2019 -0500
amstream: Reimplement IMediaStreamFilter::EnumPins().
Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/amstream/amstream_private.h | 1 +
dlls/amstream/mediastreamfilter.c | 167 +++++++++++++++++++++++++++++++++++++-
dlls/amstream/tests/amstream.c | 16 ++--
3 files changed, 174 insertions(+), 10 deletions(-)
diff --git a/dlls/amstream/amstream_private.h b/dlls/amstream/amstream_private.h
index 8f25b8e..3cbc5c8 100644
--- a/dlls/amstream/amstream_private.h
+++ b/dlls/amstream/amstream_private.h
@@ -32,6 +32,7 @@
#include "mmstream.h"
#include "austream.h"
#include "amstream.h"
+#include "wine/heap.h"
HRESULT AM_create(IUnknown *pUnkOuter, LPVOID *ppObj) DECLSPEC_HIDDEN;
HRESULT AMAudioData_create(IUnknown *pUnkOuter, LPVOID *ppObj) DECLSPEC_HIDDEN;
diff --git a/dlls/amstream/mediastreamfilter.c b/dlls/amstream/mediastreamfilter.c
index a61d1e7..e9f98b6 100644
--- a/dlls/amstream/mediastreamfilter.c
+++ b/dlls/amstream/mediastreamfilter.c
@@ -34,6 +34,142 @@
WINE_DEFAULT_DEBUG_CHANNEL(amstream);
+struct enum_pins
+{
+ IEnumPins IEnumPins_iface;
+ LONG refcount;
+
+ IPin **pins;
+ unsigned int count, index;
+};
+
+static const IEnumPinsVtbl enum_pins_vtbl;
+
+static struct enum_pins *impl_from_IEnumPins(IEnumPins *iface)
+{
+ return CONTAINING_RECORD(iface, struct enum_pins, IEnumPins_iface);
+}
+
+static HRESULT WINAPI enum_pins_QueryInterface(IEnumPins *iface, REFIID iid, void **out)
+{
+ TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out);
+
+ if (IsEqualGUID(iid, &IID_IUnknown) || IsEqualGUID(iid, &IID_IEnumPins))
+ {
+ IEnumPins_AddRef(iface);
+ *out = iface;
+ return S_OK;
+ }
+
+ WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid));
+ *out = NULL;
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI enum_pins_AddRef(IEnumPins *iface)
+{
+ struct enum_pins *enum_pins = impl_from_IEnumPins(iface);
+ ULONG refcount = InterlockedIncrement(&enum_pins->refcount);
+ TRACE("%p increasing refcount to %u.\n", enum_pins, refcount);
+ return refcount;
+}
+
+static ULONG WINAPI enum_pins_Release(IEnumPins *iface)
+{
+ struct enum_pins *enum_pins = impl_from_IEnumPins(iface);
+ ULONG refcount = InterlockedDecrement(&enum_pins->refcount);
+ unsigned int i;
+
+ TRACE("%p decreasing refcount to %u.\n", enum_pins, refcount);
+ if (!refcount)
+ {
+ for (i = 0; i < enum_pins->count; ++i)
+ IPin_Release(enum_pins->pins[i]);
+ heap_free(enum_pins->pins);
+ heap_free(enum_pins);
+ }
+ return refcount;
+}
+
+static HRESULT WINAPI enum_pins_Next(IEnumPins *iface, ULONG count, IPin **pins, ULONG *ret_count)
+{
+ struct enum_pins *enum_pins = impl_from_IEnumPins(iface);
+ unsigned int i;
+
+ TRACE("iface %p, count %u, pins %p, ret_count %p.\n", iface, count, pins, ret_count);
+
+ if (!pins || (count > 1 && !ret_count))
+ return E_POINTER;
+
+ for (i = 0; i < count && enum_pins->index < enum_pins->count; ++i)
+ {
+ IPin_AddRef(pins[i] = enum_pins->pins[i]);
+ enum_pins->index++;
+ }
+
+ if (ret_count) *ret_count = i;
+ return i == count ? S_OK : S_FALSE;
+}
+
+static HRESULT WINAPI enum_pins_Skip(IEnumPins *iface, ULONG count)
+{
+ struct enum_pins *enum_pins = impl_from_IEnumPins(iface);
+
+ TRACE("iface %p, count %u.\n", iface, count);
+
+ enum_pins->index += count;
+
+ return enum_pins->index >= enum_pins->count ? S_FALSE : S_OK;
+}
+
+static HRESULT WINAPI enum_pins_Reset(IEnumPins *iface)
+{
+ struct enum_pins *enum_pins = impl_from_IEnumPins(iface);
+
+ TRACE("iface %p.\n", iface);
+
+ enum_pins->index = 0;
+ return S_OK;
+}
+
+static HRESULT WINAPI enum_pins_Clone(IEnumPins *iface, IEnumPins **out)
+{
+ struct enum_pins *enum_pins = impl_from_IEnumPins(iface);
+ struct enum_pins *object;
+ unsigned int i;
+
+ TRACE("iface %p, out %p.\n", iface, out);
+
+ if (!(object = heap_alloc(sizeof(*object))))
+ return E_OUTOFMEMORY;
+
+ object->IEnumPins_iface.lpVtbl = &enum_pins_vtbl;
+ object->refcount = 1;
+ object->count = enum_pins->count;
+ object->index = enum_pins->index;
+ if (!(object->pins = heap_alloc(enum_pins->count * sizeof(*object->pins))))
+ {
+ heap_free(object);
+ return E_OUTOFMEMORY;
+ }
+ for (i = 0; i < enum_pins->count; ++i)
+ IPin_AddRef(object->pins[i] = enum_pins->pins[i]);
+
+ *out = &object->IEnumPins_iface;
+ return S_OK;
+}
+
+static const IEnumPinsVtbl enum_pins_vtbl =
+{
+ enum_pins_QueryInterface,
+ enum_pins_AddRef,
+ enum_pins_Release,
+ enum_pins_Next,
+ enum_pins_Skip,
+ enum_pins_Reset,
+ enum_pins_Clone,
+};
+
typedef struct {
BaseFilter filter;
ULONG nb_streams;
@@ -153,8 +289,35 @@ static HRESULT WINAPI MediaStreamFilterImpl_GetSyncSource(IMediaStreamFilter *if
static HRESULT WINAPI MediaStreamFilterImpl_EnumPins(IMediaStreamFilter *iface, IEnumPins **enum_pins)
{
- IMediaStreamFilterImpl *This = impl_from_IMediaStreamFilter(iface);
- return BaseFilterImpl_EnumPins(&This->filter.IBaseFilter_iface, enum_pins);
+ IMediaStreamFilterImpl *filter = impl_from_IMediaStreamFilter(iface);
+ struct enum_pins *object;
+ unsigned int i;
+
+ TRACE("iface %p, enum_pins %p.\n", iface, enum_pins);
+
+ if (!enum_pins)
+ return E_POINTER;
+
+ if (!(object = heap_alloc(sizeof(*object))))
+ return E_OUTOFMEMORY;
+
+ object->IEnumPins_iface.lpVtbl = &enum_pins_vtbl;
+ object->refcount = 1;
+ object->count = filter->nb_streams;
+ object->index = 0;
+ if (!(object->pins = heap_alloc(filter->nb_streams * sizeof(*object->pins))))
+ {
+ heap_free(object);
+ return E_OUTOFMEMORY;
+ }
+ for (i = 0; i < filter->nb_streams; ++i)
+ {
+ if (FAILED(IAMMediaStream_QueryInterface(filter->streams[i], &IID_IPin, (void **)&object->pins[i])))
+ WARN("Stream %p does not support IPin.\n", filter->streams[i]);
+ }
+
+ *enum_pins = &object->IEnumPins_iface;
+ return S_OK;
}
static HRESULT WINAPI MediaStreamFilterImpl_FindPin(IMediaStreamFilter *iface, LPCWSTR id, IPin **pin)
diff --git a/dlls/amstream/tests/amstream.c b/dlls/amstream/tests/amstream.c
index 148e6bd..7215775 100644
--- a/dlls/amstream/tests/amstream.c
+++ b/dlls/amstream/tests/amstream.c
@@ -652,7 +652,7 @@ static void test_enum_pins(void)
hr = IMediaStreamFilter_EnumPins(filter, &enum1);
ok(hr == S_OK, "Got hr %#x.\n", hr);
ref = get_refcount(filter);
- todo_wine ok(ref == 3, "Got unexpected refcount %d.\n", ref);
+ ok(ref == 3, "Got unexpected refcount %d.\n", ref);
ref = get_refcount(enum1);
ok(ref == 1, "Got unexpected refcount %d.\n", ref);
@@ -666,7 +666,7 @@ static void test_enum_pins(void)
ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IEnumPins_Skip(enum1, 0);
- todo_wine ok(hr == S_FALSE, "Got hr %#x.\n", hr);
+ ok(hr == S_FALSE, "Got hr %#x.\n", hr);
hr = IEnumPins_Skip(enum1, 1);
ok(hr == S_FALSE, "Got hr %#x.\n", hr);
@@ -682,7 +682,7 @@ static void test_enum_pins(void)
ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IEnumPins_Next(enum1, 1, pins, NULL);
- todo_wine ok(hr == S_FALSE, "Got hr %#x.\n", hr);
+ ok(hr == S_FALSE, "Got hr %#x.\n", hr);
IEnumPins_Release(enum1);
@@ -690,7 +690,7 @@ static void test_enum_pins(void)
ok(hr == S_OK, "Got hr %#x.\n", hr);
ref = get_refcount(filter);
- ok(ref == 4, "Got unexpected refcount %d.\n", ref);
+ todo_wine ok(ref == 4, "Got unexpected refcount %d.\n", ref);
ref = get_refcount(enum1);
ok(ref == 1, "Got unexpected refcount %d.\n", ref);
ref = get_refcount(pin);
@@ -700,7 +700,7 @@ static void test_enum_pins(void)
ok(hr == S_OK, "Got hr %#x.\n", hr);
ok(pins[0] == pin, "Expected pin %p, got %p.\n", pin, pins[0]);
ref = get_refcount(filter);
- ok(ref == 4, "Got unexpected refcount %d.\n", ref);
+ todo_wine ok(ref == 4, "Got unexpected refcount %d.\n", ref);
ref = get_refcount(enum1);
ok(ref == 1, "Got unexpected refcount %d.\n", ref);
ref = get_refcount(pin);
@@ -723,7 +723,7 @@ static void test_enum_pins(void)
ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IEnumPins_Next(enum1, 2, pins, NULL);
- todo_wine ok(hr == E_POINTER, "Got hr %#x.\n", hr);
+ ok(hr == E_POINTER, "Got hr %#x.\n", hr);
hr = IEnumPins_Next(enum1, 2, pins, &count);
ok(hr == S_FALSE, "Got hr %#x.\n", hr);
@@ -741,7 +741,7 @@ static void test_enum_pins(void)
ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IEnumPins_Skip(enum1, 1);
- todo_wine ok(hr == S_FALSE, "Got hr %#x.\n", hr);
+ ok(hr == S_FALSE, "Got hr %#x.\n", hr);
hr = IEnumPins_Next(enum1, 1, pins, NULL);
ok(hr == S_FALSE, "Got hr %#x.\n", hr);
@@ -759,7 +759,7 @@ static void test_enum_pins(void)
ok(!ref, "Got outstanding refcount %d.\n", ref);
IMediaStream_Release(stream);
ref = IPin_Release(pin);
- todo_wine ok(!ref, "Got outstanding refcount %d.\n", ref);
+ ok(!ref, "Got outstanding refcount %d.\n", ref);
}
static void test_find_pin(void)
More information about the wine-cvs
mailing list