diff --git a/dlls/evr/Makefile.in b/dlls/evr/Makefile.in index 8f971dca06f..bf3048f62ee 100644 --- a/dlls/evr/Makefile.in +++ b/dlls/evr/Makefile.in @@ -1,6 +1,6 @@ MODULE = evr.dll IMPORTLIB = evr -IMPORTS = mfuuid strmiids strmbase uuid ole32 oleaut32 +IMPORTS = mfuuid strmiids strmbase uuid dxguid ole32 oleaut32 EXTRADLLFLAGS = -mno-cygwin diff --git a/dlls/evr/evr_classes.idl b/dlls/evr/evr_classes.idl index 20a346ac67a..31f0d34fe75 100644 --- a/dlls/evr/evr_classes.idl +++ b/dlls/evr/evr_classes.idl @@ -18,11 +18,16 @@ #pragma makedep register -#include "strmif.idl" - [ helpstring("Enhanced Video Renderer"), threading(both), uuid(fa10746c-9b63-4b6c-bc49-fc300ea5f256) ] coclass EnhancedVideoRenderer { interface IBaseFilter; } + +[ + helpstring("MF Video Mixer"), + threading(both), + uuid(e474e05a-ab65-4f6a-827c-218b1baaf31f) +] +coclass MFVideoMixer9 { interface IMFTransform; } diff --git a/dlls/evr/evr_private.h b/dlls/evr/evr_private.h index ad47bd28b78..5698eb0c21e 100644 --- a/dlls/evr/evr_private.h +++ b/dlls/evr/evr_private.h @@ -24,6 +24,6 @@ #include "wine/strmbase.h" HRESULT evr_filter_create(IUnknown *outer_unk, void **ppv) DECLSPEC_HIDDEN; - +HRESULT evr_mixer_create(IUnknown *outer_unk, void **ppv) DECLSPEC_HIDDEN; #endif /* __EVR_PRIVATE_INCLUDED__ */ diff --git a/dlls/evr/main.c b/dlls/evr/main.c index 921e63535f9..85c81f13604 100644 --- a/dlls/evr/main.c +++ b/dlls/evr/main.c @@ -71,6 +71,7 @@ struct object_creation_info static const struct object_creation_info object_creation[] = { { &CLSID_EnhancedVideoRenderer, evr_filter_create }, + { &CLSID_MFVideoMixer9, evr_mixer_create }, }; static HRESULT WINAPI classfactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppobj) diff --git a/dlls/evr/mixer.c b/dlls/evr/mixer.c index fe2f4bab1df..41d63c8aab5 100644 --- a/dlls/evr/mixer.c +++ b/dlls/evr/mixer.c @@ -16,13 +16,289 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#define COBJMACROS + #include "wine/debug.h" #include "evr.h" +#include "d3d9.h" + +#include "evr_classes.h" WINE_DEFAULT_DEBUG_CHANNEL(evr); -HRESULT WINAPI MFCreateVideoMixer(IUnknown *owner, REFIID riid_device, REFIID riid, void **obj) +struct video_mixer { - FIXME("%p, %s, %s, %p.\n", owner, debugstr_guid(riid_device), debugstr_guid(riid), obj); + IMFTransform IMFTransform_iface; + LONG refcount; +}; + +static struct video_mixer *impl_from_IMFTransform(IMFTransform *iface) +{ + return CONTAINING_RECORD(iface, struct video_mixer, IMFTransform_iface); +} + +static HRESULT WINAPI video_mixer_transform_QueryInterface(IMFTransform *iface, REFIID riid, void **obj) +{ + if (IsEqualIID(riid, &IID_IMFTransform) || + IsEqualIID(riid, &IID_IUnknown)) + { + *obj = iface; + IMFTransform_AddRef(iface); + return S_OK; + } + + WARN("Unsupported interface %s.\n", debugstr_guid(riid)); + *obj = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI video_mixer_transform_AddRef(IMFTransform *iface) +{ + struct video_mixer *mixer = impl_from_IMFTransform(iface); + ULONG refcount = InterlockedIncrement(&mixer->refcount); + + TRACE("%p, refcount %u.\n", iface, refcount); + + return refcount; +} + +static ULONG WINAPI video_mixer_transform_Release(IMFTransform *iface) +{ + struct video_mixer *mixer = impl_from_IMFTransform(iface); + ULONG refcount = InterlockedDecrement(&mixer->refcount); + + TRACE("%p, refcount %u.\n", iface, refcount); + + if (!refcount) + free(mixer); + + return refcount; +} + +static HRESULT WINAPI video_mixer_transform_GetStreamLimits(IMFTransform *iface, DWORD *input_minimum, + DWORD *input_maximum, DWORD *output_minimum, DWORD *output_maximum) +{ + FIXME("%p, %p, %p, %p, %p.\n", iface, input_minimum, input_maximum, output_minimum, output_maximum); + return E_NOTIMPL; } + +static HRESULT WINAPI video_mixer_transform_GetStreamCount(IMFTransform *iface, DWORD *inputs, DWORD *outputs) +{ + FIXME("%p, %p, %p.\n", iface, inputs, outputs); + + return E_NOTIMPL; +} + +static HRESULT WINAPI video_mixer_transform_GetStreamIDs(IMFTransform *iface, DWORD input_size, DWORD *inputs, + DWORD output_size, DWORD *outputs) +{ + FIXME("%p, %u, %p, %u, %p.\n", iface, input_size, inputs, output_size, outputs); + + return E_NOTIMPL; +} + +static HRESULT WINAPI video_mixer_transform_GetInputStreamInfo(IMFTransform *iface, DWORD id, MFT_INPUT_STREAM_INFO *info) +{ + FIXME("%p, %u, %p.\n", iface, id, info); + + return E_NOTIMPL; +} + +static HRESULT WINAPI video_mixer_transform_GetOutputStreamInfo(IMFTransform *iface, DWORD id, MFT_OUTPUT_STREAM_INFO *info) +{ + FIXME("%p, %u, %p.\n", iface, id, info); + + return E_NOTIMPL; +} + +static HRESULT WINAPI video_mixer_transform_GetAttributes(IMFTransform *iface, IMFAttributes **attributes) +{ + FIXME("%p, %p.\n", iface, attributes); + + return E_NOTIMPL; +} + +static HRESULT WINAPI video_mixer_transform_GetInputStreamAttributes(IMFTransform *iface, DWORD id, + IMFAttributes **attributes) +{ + FIXME("%p, %u, %p.\n", iface, id, attributes); + + return E_NOTIMPL; +} + +static HRESULT WINAPI video_mixer_transform_GetOutputStreamAttributes(IMFTransform *iface, DWORD id, + IMFAttributes **attributes) +{ + FIXME("%p, %u, %p.\n", iface, id, attributes); + + return E_NOTIMPL; +} + +static HRESULT WINAPI video_mixer_transform_DeleteInputStream(IMFTransform *iface, DWORD id) +{ + FIXME("%p, %u.\n", iface, id); + + return E_NOTIMPL; +} + +static HRESULT WINAPI video_mixer_transform_AddInputStreams(IMFTransform *iface, DWORD streams, DWORD *ids) +{ + FIXME("%p, %u, %p.\n", iface, streams, ids); + + return E_NOTIMPL; +} + +static HRESULT WINAPI video_mixer_transform_GetInputAvailableType(IMFTransform *iface, DWORD id, DWORD index, + IMFMediaType **type) +{ + FIXME("%p, %u, %u, %p.\n", iface, id, index, type); + + return E_NOTIMPL; +} + +static HRESULT WINAPI video_mixer_transform_GetOutputAvailableType(IMFTransform *iface, DWORD id, DWORD index, + IMFMediaType **type) +{ + FIXME("%p, %u, %u, %p.\n", iface, id, index, type); + + return E_NOTIMPL; +} + +static HRESULT WINAPI video_mixer_transform_SetInputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags) +{ + FIXME("%p, %u, %p, %#x.\n", iface, id, type, flags); + + return E_NOTIMPL; +} + +static HRESULT WINAPI video_mixer_transform_SetOutputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags) +{ + FIXME("%p, %u, %p, %#x.\n", iface, id, type, flags); + + return E_NOTIMPL; +} + +static HRESULT WINAPI video_mixer_transform_GetInputCurrentType(IMFTransform *iface, DWORD id, IMFMediaType **type) +{ + FIXME("%p, %u, %p.\n", iface, id, type); + + return E_NOTIMPL; +} + +static HRESULT WINAPI video_mixer_transform_GetOutputCurrentType(IMFTransform *iface, DWORD id, IMFMediaType **type) +{ + FIXME("%p, %u, %p.\n", iface, id, type); + + return E_NOTIMPL; +} + +static HRESULT WINAPI video_mixer_transform_GetInputStatus(IMFTransform *iface, DWORD id, DWORD *flags) +{ + FIXME("%p, %u, %p.\n", iface, id, flags); + + return E_NOTIMPL; +} + +static HRESULT WINAPI video_mixer_transform_GetOutputStatus(IMFTransform *iface, DWORD *flags) +{ + FIXME("%p, %p.\n", iface, flags); + + return E_NOTIMPL; +} + +static HRESULT WINAPI video_mixer_transform_SetOutputBounds(IMFTransform *iface, LONGLONG lower, LONGLONG upper) +{ + FIXME("%p, %s, %s.\n", iface, wine_dbgstr_longlong(lower), wine_dbgstr_longlong(upper)); + + return E_NOTIMPL; +} + +static HRESULT WINAPI video_mixer_transform_ProcessEvent(IMFTransform *iface, DWORD id, IMFMediaEvent *event) +{ + FIXME("%p, %u, %p.\n", iface, id, event); + + return E_NOTIMPL; +} + +static HRESULT WINAPI video_mixer_transform_ProcessMessage(IMFTransform *iface, MFT_MESSAGE_TYPE message, ULONG_PTR param) +{ + FIXME("%p, %u, %#lx.\n", iface, message, param); + + return E_NOTIMPL; +} + +static HRESULT WINAPI video_mixer_transform_ProcessInput(IMFTransform *iface, DWORD id, IMFSample *sample, DWORD flags) +{ + FIXME("%p, %u, %p, %#x.\n", iface, id, sample, flags); + + return E_NOTIMPL; +} + +static HRESULT WINAPI video_mixer_transform_ProcessOutput(IMFTransform *iface, DWORD flags, DWORD count, + MFT_OUTPUT_DATA_BUFFER *samples, DWORD *status) +{ + FIXME("%p, %#x, %u, %p, %p.\n", iface, flags, count, samples, status); + + return E_NOTIMPL; +} + +static const IMFTransformVtbl video_mixer_transform_vtbl = +{ + video_mixer_transform_QueryInterface, + video_mixer_transform_AddRef, + video_mixer_transform_Release, + video_mixer_transform_GetStreamLimits, + video_mixer_transform_GetStreamCount, + video_mixer_transform_GetStreamIDs, + video_mixer_transform_GetInputStreamInfo, + video_mixer_transform_GetOutputStreamInfo, + video_mixer_transform_GetAttributes, + video_mixer_transform_GetInputStreamAttributes, + video_mixer_transform_GetOutputStreamAttributes, + video_mixer_transform_DeleteInputStream, + video_mixer_transform_AddInputStreams, + video_mixer_transform_GetInputAvailableType, + video_mixer_transform_GetOutputAvailableType, + video_mixer_transform_SetInputType, + video_mixer_transform_SetOutputType, + video_mixer_transform_GetInputCurrentType, + video_mixer_transform_GetOutputCurrentType, + video_mixer_transform_GetInputStatus, + video_mixer_transform_GetOutputStatus, + video_mixer_transform_SetOutputBounds, + video_mixer_transform_ProcessEvent, + video_mixer_transform_ProcessMessage, + video_mixer_transform_ProcessInput, + video_mixer_transform_ProcessOutput, +}; + +HRESULT WINAPI MFCreateVideoMixer(IUnknown *owner, REFIID riid_device, REFIID riid, void **obj) +{ + TRACE("%p, %s, %s, %p.\n", owner, debugstr_guid(riid_device), debugstr_guid(riid), obj); + + *obj = NULL; + + if (!IsEqualIID(riid_device, &IID_IDirect3DDevice9)) + return E_INVALIDARG; + + return CoCreateInstance(&CLSID_MFVideoMixer9, owner, CLSCTX_INPROC_SERVER, riid, obj); +} + +HRESULT evr_mixer_create(IUnknown *outer, void **out) +{ + struct video_mixer *object; + + if (outer) + return E_NOINTERFACE; + + if (!(object = calloc(1, sizeof(*object)))) + return E_OUTOFMEMORY; + + object->IMFTransform_iface.lpVtbl = &video_mixer_transform_vtbl; + object->refcount = 1; + + *out = &object->IMFTransform_iface; + + return S_OK; +} diff --git a/dlls/evr/tests/evr.c b/dlls/evr/tests/evr.c index adb2b777a2e..c4b1a561576 100644 --- a/dlls/evr/tests/evr.c +++ b/dlls/evr/tests/evr.c @@ -345,18 +345,19 @@ static void test_default_mixer(void) HRESULT hr; hr = MFCreateVideoMixer(NULL, &IID_IDirect3DDevice9, &IID_IMFTransform, (void **)&transform); -todo_wine ok(hr == S_OK, "Failed to create default mixer, hr %#x.\n", hr); - if (FAILED(hr)) - return; hr = IMFTransform_QueryInterface(transform, &IID_IMFTopologyServiceLookupClient, (void **)&unk); +todo_wine ok(hr == S_OK, "Unexpected hr %#x.\n", hr); - IUnknown_Release(unk); + if (SUCCEEDED(hr)) + IUnknown_Release(unk); hr = IMFTransform_QueryInterface(transform, &IID_IMFVideoDeviceID, (void **)&unk); +todo_wine ok(hr == S_OK, "Unexpected hr %#x.\n", hr); - IUnknown_Release(unk); + if (SUCCEEDED(hr)) + IUnknown_Release(unk); IMFTransform_Release(transform);