From 9b38ff960dc3c31eb154b54746c84b2aa2f854e7 Mon Sep 17 00:00:00 2001 From: Nikolay Sivov Date: Mon, 15 Aug 2022 13:10:15 +0300 Subject: [PATCH] mfsrcsnk: Add WAVE sink class factory. Signed-off-by: Nikolay Sivov --- dlls/mfsrcsnk/Makefile.in | 3 + dlls/mfsrcsnk/factory.c | 115 +++++++++++++++++++++++++++++++ dlls/mfsrcsnk/mfsrcsnk.idl | 26 +++++++ dlls/mfsrcsnk/mfsrcsnk.spec | 2 + dlls/mfsrcsnk/mfsrcsnk_private.h | 21 ++++++ dlls/mfsrcsnk/wave.c | 49 +++++++++++++ 6 files changed, 216 insertions(+) create mode 100644 dlls/mfsrcsnk/factory.c create mode 100644 dlls/mfsrcsnk/mfsrcsnk.idl create mode 100644 dlls/mfsrcsnk/mfsrcsnk_private.h diff --git a/dlls/mfsrcsnk/Makefile.in b/dlls/mfsrcsnk/Makefile.in index a63ebaf60eb..5f586dcc83f 100644 --- a/dlls/mfsrcsnk/Makefile.in +++ b/dlls/mfsrcsnk/Makefile.in @@ -5,4 +5,7 @@ IMPORTS = ole32 mfplat mfuuid uuid EXTRADLLFLAGS = -Wb,--prefer-native C_SRCS = \ + factory.c \ wave.c + +IDL_SRCS = mfsrcsnk.idl diff --git a/dlls/mfsrcsnk/factory.c b/dlls/mfsrcsnk/factory.c new file mode 100644 index 00000000000..2e03451a523 --- /dev/null +++ b/dlls/mfsrcsnk/factory.c @@ -0,0 +1,115 @@ +/* + * Copyright 2022 Nikolay Sivov for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#define COBJMACROS + +#include "mfidl.h" +#include "wine/mfinternal.h" + +#include "mfsrcsnk_private.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(mfplat); + +struct class_factory +{ + IClassFactory IClassFactory_iface; + HRESULT (*create_instance)(REFIID riid, void **out); +}; + +static inline struct class_factory *impl_from_IClassFactory(IClassFactory *iface) +{ + return CONTAINING_RECORD(iface, struct class_factory, IClassFactory_iface); +} + +static HRESULT WINAPI class_factory_QueryInterface(IClassFactory *iface, REFIID riid, void **out) +{ + if (IsEqualGUID(riid, &IID_IClassFactory) || + IsEqualGUID(riid, &IID_IUnknown)) + { + IClassFactory_AddRef(iface); + *out = iface; + return S_OK; + } + + *out = NULL; + WARN("Interface %s is not supported.\n", debugstr_guid(riid)); + return E_NOINTERFACE; +} + +static ULONG WINAPI class_factory_AddRef(IClassFactory *iface) +{ + return 2; +} + +static ULONG WINAPI class_factory_Release(IClassFactory *iface) +{ + return 1; +} + +static HRESULT WINAPI class_factory_CreateInstance(IClassFactory *iface, IUnknown *outer, + REFIID riid, void **out) +{ + struct class_factory *factory = impl_from_IClassFactory(iface); + + TRACE("%p, %s, %p.\n", outer, debugstr_guid(riid), out); + + *out = NULL; + + if (outer) + return CLASS_E_NOAGGREGATION; + + return factory->create_instance(riid, out); +} + +static HRESULT WINAPI class_factory_LockServer(IClassFactory *iface, BOOL dolock) +{ + FIXME("%p, %d.\n", iface, dolock); + + return S_OK; +} + +static const IClassFactoryVtbl class_factory_vtbl = +{ + class_factory_QueryInterface, + class_factory_AddRef, + class_factory_Release, + class_factory_CreateInstance, + class_factory_LockServer, +}; + +static struct class_factory wave_sink_factory = { { &class_factory_vtbl }, wave_sink_factory_create }; + +/*********************************************************************** + * DllGetClassObject (mfsrcsnk.@) + */ +HRESULT WINAPI DllGetClassObject(REFCLSID clsid, REFIID riid, void **out) +{ + *out = NULL; + + if (IsEqualGUID(clsid, &CLSID_MFWAVESinkClassFactory)) + { + return IClassFactory_QueryInterface(&wave_sink_factory.IClassFactory_iface, riid, out); + } + else + { + FIXME("Unknown clsid %s.\n", debugstr_guid(clsid)); + return CLASS_E_CLASSNOTAVAILABLE; + } +} diff --git a/dlls/mfsrcsnk/mfsrcsnk.idl b/dlls/mfsrcsnk/mfsrcsnk.idl new file mode 100644 index 00000000000..13bdac2977e --- /dev/null +++ b/dlls/mfsrcsnk/mfsrcsnk.idl @@ -0,0 +1,26 @@ +/* + * Copyright 2022 Nikolay Sivov for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#pragma makedep register + +[ + helpstring("MF WAVE Sink Factory"), + threading(both), + uuid(36f99745-23c9-4c9c-8dd5-cc31ce964390) +] +coclass MFWAVESinkClassFactory { } diff --git a/dlls/mfsrcsnk/mfsrcsnk.spec b/dlls/mfsrcsnk/mfsrcsnk.spec index 9acfef27ae2..ab9f2e4c207 100644 --- a/dlls/mfsrcsnk/mfsrcsnk.spec +++ b/dlls/mfsrcsnk/mfsrcsnk.spec @@ -1 +1,3 @@ +@ stdcall -private DllRegisterServer() +@ stdcall -private DllUnregisterServer() @ stdcall MFCreateWAVEMediaSink(ptr ptr ptr) diff --git a/dlls/mfsrcsnk/mfsrcsnk_private.h b/dlls/mfsrcsnk/mfsrcsnk_private.h new file mode 100644 index 00000000000..29249d640f8 --- /dev/null +++ b/dlls/mfsrcsnk/mfsrcsnk_private.h @@ -0,0 +1,21 @@ +/* + * Copyright 2022 Nikolay Sivov for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "wine/mfinternal.h" + +extern HRESULT wave_sink_factory_create(REFIID riid, void **out) DECLSPEC_HIDDEN; diff --git a/dlls/mfsrcsnk/wave.c b/dlls/mfsrcsnk/wave.c index ce57865d093..cf74368d8f7 100644 --- a/dlls/mfsrcsnk/wave.c +++ b/dlls/mfsrcsnk/wave.c @@ -22,6 +22,8 @@ #include "mfidl.h" #include "mferror.h" +#include "mfsrcsnk_private.h" + #include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(mfplat); @@ -889,3 +891,50 @@ failed: return hr; } + +static HRESULT WINAPI sink_class_factory_QueryInterface(IMFSinkClassFactory *iface, REFIID riid, void **out) +{ + if (IsEqualIID(riid, &IID_IMFSinkClassFactory) + || IsEqualIID(riid, &IID_IUnknown)) + { + *out = iface; + IMFSinkClassFactory_AddRef(iface); + return S_OK; + } + + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI sink_class_factory_AddRef(IMFSinkClassFactory *iface) +{ + return 2; +} + +static ULONG WINAPI sink_class_factory_Release(IMFSinkClassFactory *iface) +{ + return 1; +} + +static HRESULT WINAPI sink_class_factory_CreateMediaSink(IMFSinkClassFactory *iface, IMFByteStream *stream, + IMFMediaType *video_type, IMFMediaType *audio_type, IMFMediaSink **sink) +{ + TRACE("%p, %p, %p, %p.\n", stream, video_type, audio_type, sink); + + return MFCreateWAVEMediaSink(stream, audio_type, sink); +} + +static const IMFSinkClassFactoryVtbl wave_sink_factory_vtbl = +{ + sink_class_factory_QueryInterface, + sink_class_factory_AddRef, + sink_class_factory_Release, + sink_class_factory_CreateMediaSink, +}; + +static IMFSinkClassFactory wave_sink_factory = { &wave_sink_factory_vtbl }; + +HRESULT wave_sink_factory_create(REFIID riid, void **out) +{ + return IMFSinkClassFactory_QueryInterface(&wave_sink_factory, riid, out); +}