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:
parent
5351870ea1
commit
f423c6e707
@ -32,6 +32,7 @@
|
|||||||
#include "mmstream.h"
|
#include "mmstream.h"
|
||||||
#include "austream.h"
|
#include "austream.h"
|
||||||
#include "amstream.h"
|
#include "amstream.h"
|
||||||
|
#include "wine/heap.h"
|
||||||
|
|
||||||
HRESULT AM_create(IUnknown *pUnkOuter, LPVOID *ppObj) DECLSPEC_HIDDEN;
|
HRESULT AM_create(IUnknown *pUnkOuter, LPVOID *ppObj) DECLSPEC_HIDDEN;
|
||||||
HRESULT AMAudioData_create(IUnknown *pUnkOuter, LPVOID *ppObj) DECLSPEC_HIDDEN;
|
HRESULT AMAudioData_create(IUnknown *pUnkOuter, LPVOID *ppObj) DECLSPEC_HIDDEN;
|
||||||
|
@ -34,6 +34,142 @@
|
|||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(amstream);
|
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 {
|
typedef struct {
|
||||||
BaseFilter filter;
|
BaseFilter filter;
|
||||||
ULONG nb_streams;
|
ULONG nb_streams;
|
||||||
@ -153,8 +289,35 @@ static HRESULT WINAPI MediaStreamFilterImpl_GetSyncSource(IMediaStreamFilter *if
|
|||||||
|
|
||||||
static HRESULT WINAPI MediaStreamFilterImpl_EnumPins(IMediaStreamFilter *iface, IEnumPins **enum_pins)
|
static HRESULT WINAPI MediaStreamFilterImpl_EnumPins(IMediaStreamFilter *iface, IEnumPins **enum_pins)
|
||||||
{
|
{
|
||||||
IMediaStreamFilterImpl *This = impl_from_IMediaStreamFilter(iface);
|
IMediaStreamFilterImpl *filter = impl_from_IMediaStreamFilter(iface);
|
||||||
return BaseFilterImpl_EnumPins(&This->filter.IBaseFilter_iface, enum_pins);
|
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)
|
static HRESULT WINAPI MediaStreamFilterImpl_FindPin(IMediaStreamFilter *iface, LPCWSTR id, IPin **pin)
|
||||||
|
@ -652,7 +652,7 @@ static void test_enum_pins(void)
|
|||||||
hr = IMediaStreamFilter_EnumPins(filter, &enum1);
|
hr = IMediaStreamFilter_EnumPins(filter, &enum1);
|
||||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||||
ref = get_refcount(filter);
|
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);
|
ref = get_refcount(enum1);
|
||||||
ok(ref == 1, "Got unexpected refcount %d.\n", ref);
|
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);
|
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||||
|
|
||||||
hr = IEnumPins_Skip(enum1, 0);
|
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);
|
hr = IEnumPins_Skip(enum1, 1);
|
||||||
ok(hr == S_FALSE, "Got hr %#x.\n", hr);
|
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);
|
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||||
|
|
||||||
hr = IEnumPins_Next(enum1, 1, pins, NULL);
|
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);
|
IEnumPins_Release(enum1);
|
||||||
|
|
||||||
@ -690,7 +690,7 @@ static void test_enum_pins(void)
|
|||||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||||
|
|
||||||
ref = get_refcount(filter);
|
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);
|
ref = get_refcount(enum1);
|
||||||
ok(ref == 1, "Got unexpected refcount %d.\n", ref);
|
ok(ref == 1, "Got unexpected refcount %d.\n", ref);
|
||||||
ref = get_refcount(pin);
|
ref = get_refcount(pin);
|
||||||
@ -700,7 +700,7 @@ static void test_enum_pins(void)
|
|||||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||||
ok(pins[0] == pin, "Expected pin %p, got %p.\n", pin, pins[0]);
|
ok(pins[0] == pin, "Expected pin %p, got %p.\n", pin, pins[0]);
|
||||||
ref = get_refcount(filter);
|
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);
|
ref = get_refcount(enum1);
|
||||||
ok(ref == 1, "Got unexpected refcount %d.\n", ref);
|
ok(ref == 1, "Got unexpected refcount %d.\n", ref);
|
||||||
ref = get_refcount(pin);
|
ref = get_refcount(pin);
|
||||||
@ -723,7 +723,7 @@ static void test_enum_pins(void)
|
|||||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||||
|
|
||||||
hr = IEnumPins_Next(enum1, 2, pins, NULL);
|
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);
|
hr = IEnumPins_Next(enum1, 2, pins, &count);
|
||||||
ok(hr == S_FALSE, "Got hr %#x.\n", hr);
|
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);
|
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||||
|
|
||||||
hr = IEnumPins_Skip(enum1, 1);
|
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);
|
hr = IEnumPins_Next(enum1, 1, pins, NULL);
|
||||||
ok(hr == S_FALSE, "Got hr %#x.\n", hr);
|
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);
|
ok(!ref, "Got outstanding refcount %d.\n", ref);
|
||||||
IMediaStream_Release(stream);
|
IMediaStream_Release(stream);
|
||||||
ref = IPin_Release(pin);
|
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)
|
static void test_find_pin(void)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user