amstream: Reimplement IMediaStreamFilter::EnumPins().

Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Zebediah Figura 2019-05-17 00:31:05 -05:00 committed by Alexandre Julliard
parent 5351870ea1
commit f423c6e707
3 changed files with 174 additions and 10 deletions

View file

@ -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;

View file

@ -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)

View file

@ -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)