evr: Add aggregation support for default mixer object.
Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
17e7de4bdf
commit
1caf8ade07
|
@ -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
|
||||||
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)
|
||||||
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,
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
{
|
{
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
|
|
||||||
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)
|
||||||
|
|
Loading…
Reference in New Issue