Nikolay Sivov : evr: Partially implement InitServicePointers() for the presenter.
Alexandre Julliard
julliard at winehq.org
Wed Jul 1 15:22:49 CDT 2020
Module: wine
Branch: master
Commit: 17e7de4bdfc5b5bb7aac42a2a7da109677167c35
URL: https://source.winehq.org/git/wine.git/?a=commit;h=17e7de4bdfc5b5bb7aac42a2a7da109677167c35
Author: Nikolay Sivov <nsivov at codeweavers.com>
Date: Wed Jul 1 15:55:44 2020 +0300
evr: Partially implement InitServicePointers() for the presenter.
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/evr/presenter.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 68 insertions(+), 3 deletions(-)
diff --git a/dlls/evr/presenter.c b/dlls/evr/presenter.c
index c70b83d072..a7da070492 100644
--- a/dlls/evr/presenter.c
+++ b/dlls/evr/presenter.c
@@ -50,6 +50,10 @@ struct video_presenter
IUnknown *outer_unk;
LONG refcount;
+ IMFTransform *mixer;
+ IMFClock *clock;
+ IMediaEventSink *event_sink;
+
unsigned int state;
CRITICAL_SECTION cs;
};
@@ -136,6 +140,19 @@ static ULONG WINAPI video_presenter_inner_AddRef(IUnknown *iface)
return refcount;
}
+static void video_presenter_clear_container(struct video_presenter *presenter)
+{
+ if (presenter->clock)
+ IMFClock_Release(presenter->clock);
+ if (presenter->mixer)
+ IMFTransform_Release(presenter->mixer);
+ if (presenter->event_sink)
+ IMediaEventSink_Release(presenter->event_sink);
+ presenter->clock = NULL;
+ presenter->mixer = NULL;
+ presenter->event_sink = NULL;
+}
+
static ULONG WINAPI video_presenter_inner_Release(IUnknown *iface)
{
struct video_presenter *presenter = impl_from_IUnknown(iface);
@@ -145,6 +162,7 @@ static ULONG WINAPI video_presenter_inner_Release(IUnknown *iface)
if (!refcount)
{
+ video_presenter_clear_container(presenter);
DeleteCriticalSection(&presenter->cs);
heap_free(presenter);
}
@@ -324,9 +342,53 @@ static ULONG WINAPI video_presenter_service_client_Release(IMFTopologyServiceLoo
static HRESULT WINAPI video_presenter_service_client_InitServicePointers(IMFTopologyServiceLookupClient *iface,
IMFTopologyServiceLookup *service_lookup)
{
- FIXME("%p, %p.\n", iface, service_lookup);
+ struct video_presenter *presenter = impl_from_IMFTopologyServiceLookupClient(iface);
+ unsigned int count;
+ HRESULT hr = S_OK;
- return E_NOTIMPL;
+ TRACE("%p, %p.\n", iface, service_lookup);
+
+ if (!service_lookup)
+ return E_POINTER;
+
+ EnterCriticalSection(&presenter->cs);
+
+ if (presenter->state == PRESENTER_STATE_STARTED ||
+ presenter->state == PRESENTER_STATE_PAUSED)
+ {
+ hr = MF_E_INVALIDREQUEST;
+ }
+ else
+ {
+ video_presenter_clear_container(presenter);
+
+ count = 1;
+ IMFTopologyServiceLookup_LookupService(service_lookup, MF_SERVICE_LOOKUP_GLOBAL, 0,
+ &MR_VIDEO_RENDER_SERVICE, &IID_IMFClock, (void **)&presenter->clock, &count);
+
+ count = 1;
+ if (SUCCEEDED(hr = IMFTopologyServiceLookup_LookupService(service_lookup, MF_SERVICE_LOOKUP_GLOBAL, 0,
+ &MR_VIDEO_MIXER_SERVICE, &IID_IMFTransform, (void **)&presenter->mixer, &count)))
+ {
+ /* FIXME: presumably should validate mixer's device id. */
+ }
+ else
+ WARN("Failed to get mixer interface, hr %#x.\n", hr);
+
+ count = 1;
+ if (FAILED(hr = IMFTopologyServiceLookup_LookupService(service_lookup, MF_SERVICE_LOOKUP_GLOBAL, 0,
+ &MR_VIDEO_RENDER_SERVICE, &IID_IMediaEventSink, (void **)&presenter->event_sink, &count)))
+ {
+ WARN("Failed to get renderer event sink, hr %#x.\n", hr);
+ }
+
+ if (SUCCEEDED(hr))
+ presenter->state = PRESENTER_STATE_STOPPED;
+ }
+
+ LeaveCriticalSection(&presenter->cs);
+
+ return hr;
}
static HRESULT WINAPI video_presenter_service_client_ReleaseServicePointers(IMFTopologyServiceLookupClient *iface)
@@ -336,7 +398,10 @@ static HRESULT WINAPI video_presenter_service_client_ReleaseServicePointers(IMFT
TRACE("%p.\n", iface);
EnterCriticalSection(&presenter->cs);
+
presenter->state = PRESENTER_STATE_SHUT_DOWN;
+ video_presenter_clear_container(presenter);
+
LeaveCriticalSection(&presenter->cs);
return S_OK;
@@ -527,7 +592,7 @@ HRESULT evr_presenter_create(IUnknown *outer, void **out)
{
struct video_presenter *object;
- if (!(object = heap_alloc(sizeof(*object))))
+ if (!(object = heap_alloc_zero(sizeof(*object))))
return E_OUTOFMEMORY;
object->IMFVideoPresenter_iface.lpVtbl = &video_presenter_vtbl;
More information about the wine-cvs
mailing list