Commit 1caf8ade authored by Nikolay Sivov's avatar Nikolay Sivov Committed by Alexandre Julliard

evr: Add aggregation support for default mixer object.

parent 17e7de4b
...@@ -60,6 +60,8 @@ struct video_mixer ...@@ -60,6 +60,8 @@ struct video_mixer
IMFVideoMixerBitmap IMFVideoMixerBitmap_iface; IMFVideoMixerBitmap IMFVideoMixerBitmap_iface;
IMFVideoPositionMapper IMFVideoPositionMapper_iface; IMFVideoPositionMapper IMFVideoPositionMapper_iface;
IMFVideoProcessor IMFVideoProcessor_iface; IMFVideoProcessor IMFVideoProcessor_iface;
IUnknown IUnknown_inner;
IUnknown *outer_unk;
LONG refcount; LONG refcount;
struct input_stream inputs[MAX_MIXER_INPUT_STREAMS]; struct input_stream inputs[MAX_MIXER_INPUT_STREAMS];
...@@ -74,6 +76,11 @@ struct video_mixer ...@@ -74,6 +76,11 @@ struct video_mixer
CRITICAL_SECTION cs; CRITICAL_SECTION cs;
}; };
static struct video_mixer *impl_from_IUnknown(IUnknown *iface)
{
return CONTAINING_RECORD(iface, struct video_mixer, IUnknown_inner);
}
static struct video_mixer *impl_from_IMFTransform(IMFTransform *iface) static struct video_mixer *impl_from_IMFTransform(IMFTransform *iface)
{ {
return CONTAINING_RECORD(iface, struct video_mixer, IMFTransform_iface); return CONTAINING_RECORD(iface, struct video_mixer, IMFTransform_iface);
...@@ -155,17 +162,20 @@ static void video_mixer_clear_types(struct video_mixer *mixer) ...@@ -155,17 +162,20 @@ static void video_mixer_clear_types(struct video_mixer *mixer)
mixer->output.media_type = NULL; mixer->output.media_type = NULL;
} }
static HRESULT WINAPI video_mixer_transform_QueryInterface(IMFTransform *iface, REFIID riid, void **obj) static HRESULT WINAPI video_mixer_inner_QueryInterface(IUnknown *iface, REFIID riid, void **obj)
{ {
struct video_mixer *mixer = impl_from_IMFTransform(iface); struct video_mixer *mixer = impl_from_IUnknown(iface);
TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), obj); TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), obj);
if (IsEqualIID(riid, &IID_IMFTransform) || if (IsEqualIID(riid, &IID_IUnknown))
IsEqualIID(riid, &IID_IUnknown))
{ {
*obj = iface; *obj = iface;
} }
else if (IsEqualIID(riid, &IID_IMFTransform))
{
*obj = &mixer->IMFTransform_iface;
}
else if (IsEqualIID(riid, &IID_IMFVideoDeviceID)) else if (IsEqualIID(riid, &IID_IMFVideoDeviceID))
{ {
*obj = &mixer->IMFVideoDeviceID_iface; *obj = &mixer->IMFVideoDeviceID_iface;
...@@ -206,9 +216,9 @@ static HRESULT WINAPI video_mixer_transform_QueryInterface(IMFTransform *iface, ...@@ -206,9 +216,9 @@ static HRESULT WINAPI video_mixer_transform_QueryInterface(IMFTransform *iface,
return S_OK; return S_OK;
} }
static ULONG WINAPI video_mixer_transform_AddRef(IMFTransform *iface) static ULONG WINAPI video_mixer_inner_AddRef(IUnknown *iface)
{ {
struct video_mixer *mixer = impl_from_IMFTransform(iface); struct video_mixer *mixer = impl_from_IUnknown(iface);
ULONG refcount = InterlockedIncrement(&mixer->refcount); ULONG refcount = InterlockedIncrement(&mixer->refcount);
TRACE("%p, refcount %u.\n", iface, refcount); TRACE("%p, refcount %u.\n", iface, refcount);
...@@ -216,9 +226,9 @@ static ULONG WINAPI video_mixer_transform_AddRef(IMFTransform *iface) ...@@ -216,9 +226,9 @@ static ULONG WINAPI video_mixer_transform_AddRef(IMFTransform *iface)
return refcount; return refcount;
} }
static ULONG WINAPI video_mixer_transform_Release(IMFTransform *iface) static ULONG WINAPI video_mixer_inner_Release(IUnknown *iface)
{ {
struct video_mixer *mixer = impl_from_IMFTransform(iface); struct video_mixer *mixer = impl_from_IUnknown(iface);
ULONG refcount = InterlockedDecrement(&mixer->refcount); ULONG refcount = InterlockedDecrement(&mixer->refcount);
unsigned int i; unsigned int i;
...@@ -241,6 +251,31 @@ static ULONG WINAPI video_mixer_transform_Release(IMFTransform *iface) ...@@ -241,6 +251,31 @@ static ULONG WINAPI video_mixer_transform_Release(IMFTransform *iface)
return refcount; return refcount;
} }
static const IUnknownVtbl video_mixer_inner_vtbl =
{
video_mixer_inner_QueryInterface,
video_mixer_inner_AddRef,
video_mixer_inner_Release,
};
static HRESULT WINAPI video_mixer_transform_QueryInterface(IMFTransform *iface, REFIID riid, void **obj)
{
struct video_mixer *mixer = impl_from_IMFTransform(iface);
return IUnknown_QueryInterface(mixer->outer_unk, riid, obj);
}
static ULONG WINAPI video_mixer_transform_AddRef(IMFTransform *iface)
{
struct video_mixer *mixer = impl_from_IMFTransform(iface);
return IUnknown_AddRef(mixer->outer_unk);
}
static ULONG WINAPI video_mixer_transform_Release(IMFTransform *iface)
{
struct video_mixer *mixer = impl_from_IMFTransform(iface);
return IUnknown_Release(mixer->outer_unk);
}
static HRESULT WINAPI video_mixer_transform_GetStreamLimits(IMFTransform *iface, DWORD *input_minimum, static HRESULT WINAPI video_mixer_transform_GetStreamLimits(IMFTransform *iface, DWORD *input_minimum,
DWORD *input_maximum, DWORD *output_minimum, DWORD *output_maximum) DWORD *input_maximum, DWORD *output_minimum, DWORD *output_maximum)
{ {
...@@ -1251,9 +1286,6 @@ HRESULT evr_mixer_create(IUnknown *outer, void **out) ...@@ -1251,9 +1286,6 @@ HRESULT evr_mixer_create(IUnknown *outer, void **out)
{ {
struct video_mixer *object; struct video_mixer *object;
if (outer)
return E_NOINTERFACE;
if (!(object = calloc(1, sizeof(*object)))) if (!(object = calloc(1, sizeof(*object))))
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
...@@ -1265,12 +1297,14 @@ HRESULT evr_mixer_create(IUnknown *outer, void **out) ...@@ -1265,12 +1297,14 @@ HRESULT evr_mixer_create(IUnknown *outer, void **out)
object->IMFVideoMixerBitmap_iface.lpVtbl = &video_mixer_bitmap_vtbl; object->IMFVideoMixerBitmap_iface.lpVtbl = &video_mixer_bitmap_vtbl;
object->IMFVideoPositionMapper_iface.lpVtbl = &video_mixer_position_mapper_vtbl; object->IMFVideoPositionMapper_iface.lpVtbl = &video_mixer_position_mapper_vtbl;
object->IMFVideoProcessor_iface.lpVtbl = &video_mixer_processor_vtbl; object->IMFVideoProcessor_iface.lpVtbl = &video_mixer_processor_vtbl;
object->IUnknown_inner.lpVtbl = &video_mixer_inner_vtbl;
object->outer_unk = outer ? outer : &object->IUnknown_inner;
object->refcount = 1; object->refcount = 1;
object->input_count = 1; object->input_count = 1;
video_mixer_init_input(&object->inputs[0]); video_mixer_init_input(&object->inputs[0]);
InitializeCriticalSection(&object->cs); InitializeCriticalSection(&object->cs);
*out = &object->IMFTransform_iface; *out = &object->IUnknown_inner;
return S_OK; return S_OK;
} }
......
...@@ -119,6 +119,7 @@ static void test_aggregation(void) ...@@ -119,6 +119,7 @@ static void test_aggregation(void)
IBaseFilter *filter, *filter2; IBaseFilter *filter, *filter2;
IMFVideoPresenter *presenter; IMFVideoPresenter *presenter;
IUnknown *unk, *unk2; IUnknown *unk, *unk2;
IMFTransform *mixer;
HRESULT hr; HRESULT hr;
ULONG ref; ULONG ref;
...@@ -191,6 +192,22 @@ static void test_aggregation(void) ...@@ -191,6 +192,22 @@ static void test_aggregation(void)
IUnknown_Release(unk); IUnknown_Release(unk);
} }
/* Default mixer. */
presenter = (void *)0xdeadbeef;
hr = CoCreateInstance(&CLSID_MFVideoMixer9, &test_outer, CLSCTX_INPROC_SERVER, &IID_IMFTransform,
(void **)&mixer);
ok(hr == E_NOINTERFACE, "Unexpected hr %#x.\n", hr);
ok(!mixer, "Got interface %p.\n", mixer);
hr = CoCreateInstance(&CLSID_MFVideoMixer9, &test_outer, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void **)&unk);
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
ok(outer_ref == 1, "Got unexpected refcount %d.\n", outer_ref);
ok(unk != &test_outer, "Returned IUnknown should not be outer IUnknown.\n");
ref = get_refcount(unk);
ok(ref == 1, "Got unexpected refcount %d.\n", ref);
IUnknown_Release(unk);
} }
#define check_interface(a, b, c) check_interface_(__LINE__, a, b, c) #define check_interface(a, b, c) check_interface_(__LINE__, a, b, c)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment