diff --git a/dlls/quartz/Makefile.in b/dlls/quartz/Makefile.in index 90955e73cb4..0670ba95b48 100644 --- a/dlls/quartz/Makefile.in +++ b/dlls/quartz/Makefile.in @@ -19,6 +19,7 @@ SOURCES = \ systemclock.c \ videorenderer.c \ vmr7.c \ + vmr7_presenter.c \ vmr9.c \ window.c diff --git a/dlls/quartz/main.c b/dlls/quartz/main.c index fc6f39e3859..f52884afb34 100644 --- a/dlls/quartz/main.c +++ b/dlls/quartz/main.c @@ -59,6 +59,7 @@ struct object_creation_info static const struct object_creation_info object_creation[] = { { &CLSID_ACMWrapper, acm_wrapper_create }, + { &CLSID_AllocPresenter, vmr7_presenter_create }, { &CLSID_AsyncReader, async_reader_create }, { &CLSID_AudioRender, dsound_render_create }, { &CLSID_AVIDec, avi_dec_create }, diff --git a/dlls/quartz/quartz_private.h b/dlls/quartz/quartz_private.h index 58d8bb775a9..8a761e540b9 100644 --- a/dlls/quartz/quartz_private.h +++ b/dlls/quartz/quartz_private.h @@ -81,6 +81,7 @@ HRESULT system_clock_create(IUnknown *outer, IUnknown **out); HRESULT seeking_passthrough_create(IUnknown *outer, IUnknown **out); HRESULT video_renderer_create(IUnknown *outer, IUnknown **out); HRESULT video_renderer_default_create(IUnknown *outer, IUnknown **out); +HRESULT vmr7_presenter_create(IUnknown *outer, IUnknown **out); HRESULT vmr7_create(IUnknown *outer, IUnknown **out); HRESULT vmr9_create(IUnknown *outer, IUnknown **out); diff --git a/dlls/quartz/quartz_strmif.idl b/dlls/quartz/quartz_strmif.idl index b0b43ee2f33..8e2506c80a4 100644 --- a/dlls/quartz/quartz_strmif.idl +++ b/dlls/quartz/quartz_strmif.idl @@ -139,3 +139,9 @@ coclass VideoMixingRenderer { interface IBaseFilter; } uuid(51b4abf3-748f-4e3b-a276-c828330e926a) ] coclass VideoMixingRenderer9 { interface IBaseFilter; } + +[ + threading(both), + uuid(99d54f63-1a69-41ae-aa4d-c976eb3f0713) +] +coclass AllocPresenter {} diff --git a/dlls/quartz/vmr7_presenter.c b/dlls/quartz/vmr7_presenter.c new file mode 100644 index 00000000000..952cb879197 --- /dev/null +++ b/dlls/quartz/vmr7_presenter.c @@ -0,0 +1,123 @@ +/* + * Default allocator-presenter for the VMR7 + * + * Copyright 2023 Zebediah Figura 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 "quartz_private.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(quartz); + +struct vmr7_presenter +{ + IVMRImagePresenter IVMRImagePresenter_iface; + LONG refcount; +}; + +static struct vmr7_presenter *impl_from_IVMRImagePresenter(IVMRImagePresenter *iface) +{ + return CONTAINING_RECORD(iface, struct vmr7_presenter, IVMRImagePresenter_iface); +} + +static HRESULT WINAPI image_presenter_QueryInterface(IVMRImagePresenter *iface, REFIID iid, void **out) +{ + struct vmr7_presenter *presenter = impl_from_IVMRImagePresenter(iface); + + TRACE("presenter %p, iid %s, out %p.\n", presenter, debugstr_guid(iid), out); + + if (IsEqualGUID(iid, &IID_IUnknown) || IsEqualGUID(iid, &IID_IVMRImagePresenter)) + *out = iface; + else + { + *out = NULL; + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid)); + return E_NOINTERFACE; + } + + IUnknown_AddRef((IUnknown *)*out); + return S_OK; +} + +static ULONG WINAPI image_presenter_AddRef(IVMRImagePresenter *iface) +{ + struct vmr7_presenter *presenter = impl_from_IVMRImagePresenter(iface); + ULONG refcount = InterlockedIncrement(&presenter->refcount); + + TRACE("%p increasing refcount to %lu.\n", presenter, refcount); + return refcount; +} + +static ULONG WINAPI image_presenter_Release(IVMRImagePresenter *iface) +{ + struct vmr7_presenter *presenter = impl_from_IVMRImagePresenter(iface); + ULONG refcount = InterlockedDecrement(&presenter->refcount); + + TRACE("%p decreasing refcount to %lu.\n", presenter, refcount); + if (!refcount) + free(presenter); + return refcount; +} + +static HRESULT WINAPI image_presenter_StartPresenting(IVMRImagePresenter *iface, DWORD_PTR cookie) +{ + FIXME("iface %p, cookie %#Ix, stub!\n", iface, cookie); + return E_NOTIMPL; +} + +static HRESULT WINAPI image_presenter_StopPresenting(IVMRImagePresenter *iface, DWORD_PTR cookie) +{ + FIXME("iface %p, cookie %#Ix, stub!\n", iface, cookie); + return E_NOTIMPL; +} + +static HRESULT WINAPI image_presenter_PresentImage(IVMRImagePresenter *iface, + DWORD_PTR cookie, VMRPRESENTATIONINFO *info) +{ + FIXME("iface %p, cookie %#Ix, info %p, stub!\n", iface, cookie, info); + return E_NOTIMPL; +} + +static const IVMRImagePresenterVtbl image_presenter_vtbl = +{ + image_presenter_QueryInterface, + image_presenter_AddRef, + image_presenter_Release, + image_presenter_StartPresenting, + image_presenter_StopPresenting, + image_presenter_PresentImage, +}; + +HRESULT vmr7_presenter_create(IUnknown *outer, IUnknown **out) +{ + struct vmr7_presenter *object; + + TRACE("outer %p, out %p.\n", outer, out); + + if (outer) + FIXME("Ignoring outer %p.\n", outer); + + if (!(object = calloc(1, sizeof(*object)))) + return E_OUTOFMEMORY; + object->IVMRImagePresenter_iface.lpVtbl = &image_presenter_vtbl; + object->refcount = 1; + + TRACE("Created VMR7 default presenter %p.\n", object); + *out = (IUnknown *)&object->IVMRSurfaceAllocator_iface; + return S_OK; +}