Module: wine Branch: master Commit: 2a1b03ccc35148ae09bb40438613c89f26bb6a56 URL: https://gitlab.winehq.org/wine/wine/-/commit/2a1b03ccc35148ae09bb40438613c89...
Author: Rémi Bernon rbernon@codeweavers.com Date: Wed Sep 6 08:29:37 2023 +0200
dmsynth: Implement latency IReferenceClock interface on the sink.
---
dlls/dmsynth/synthsink.c | 97 ++++++++++++++++++++++++++++++++++++++------ dlls/dmsynth/tests/dmsynth.c | 12 +++--- 2 files changed, 90 insertions(+), 19 deletions(-)
diff --git a/dlls/dmsynth/synthsink.c b/dlls/dmsynth/synthsink.c index 6a2a7269092..28cee0c3a28 100644 --- a/dlls/dmsynth/synthsink.c +++ b/dlls/dmsynth/synthsink.c @@ -29,15 +29,16 @@ struct synth_sink { IDirectMusicSynthSink IDirectMusicSynthSink_iface; IKsControl IKsControl_iface; + IReferenceClock IReferenceClock_iface; LONG ref;
- IReferenceClock *latency_clock; IReferenceClock *master_clock; IDirectMusicSynth *synth; /* No reference hold! */ IDirectSound *dsound;
BOOL active; REFERENCE_TIME activate_time; + REFERENCE_TIME latency_time; };
static inline struct synth_sink *impl_from_IDirectMusicSynthSink(IDirectMusicSynthSink *iface) @@ -74,6 +75,7 @@ static HRESULT synth_sink_activate(struct synth_sink *This) if (This->active) return DMUS_E_SYNTHACTIVE;
if (FAILED(hr = IReferenceClock_GetTime(This->master_clock, &This->activate_time))) return hr; + This->latency_time = This->activate_time;
This->active = TRUE; return S_OK; @@ -131,8 +133,6 @@ static ULONG WINAPI synth_sink_Release(IDirectMusicSynthSink *iface) TRACE("(%p): new ref = %lu\n", This, ref);
if (!ref) { - if (This->latency_clock) - IReferenceClock_Release(This->latency_clock); if (This->master_clock) IReferenceClock_Release(This->master_clock); free(This); @@ -182,8 +182,8 @@ static HRESULT WINAPI synth_sink_GetLatencyClock(IDirectMusicSynthSink *iface, if (!clock) return E_POINTER;
- *clock = This->latency_clock; - IReferenceClock_AddRef(This->latency_clock); + *clock = &This->IReferenceClock_iface; + IReferenceClock_AddRef(*clock);
return S_OK; } @@ -371,10 +371,87 @@ static const IKsControlVtbl synth_sink_control = synth_sink_control_KsEvent, };
+static inline struct synth_sink *impl_from_IReferenceClock(IReferenceClock *iface) +{ + return CONTAINING_RECORD(iface, struct synth_sink, IReferenceClock_iface); +} + +static HRESULT WINAPI latency_clock_QueryInterface(IReferenceClock *iface, REFIID iid, void **out) +{ + TRACE("(%p, %s, %p)\n", iface, debugstr_dmguid(iid), out); + + if (IsEqualIID(iid, &IID_IUnknown) + || IsEqualIID(iid, &IID_IReferenceClock)) + { + IUnknown_AddRef(iface); + *out = iface; + return S_OK; + } + + FIXME("no interface for %s\n", debugstr_dmguid(iid)); + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI latency_clock_AddRef(IReferenceClock *iface) +{ + struct synth_sink *This = impl_from_IReferenceClock(iface); + return IDirectMusicSynthSink_AddRef(&This->IDirectMusicSynthSink_iface); +} + +static ULONG WINAPI latency_clock_Release(IReferenceClock *iface) +{ + struct synth_sink *This = impl_from_IReferenceClock(iface); + return IDirectMusicSynthSink_Release(&This->IDirectMusicSynthSink_iface); +} + +static HRESULT WINAPI latency_clock_GetTime(IReferenceClock *iface, REFERENCE_TIME *time) +{ + struct synth_sink *This = impl_from_IReferenceClock(iface); + + TRACE("(%p, %p)\n", iface, time); + + if (!time) return E_INVALIDARG; + if (!This->active) return E_FAIL; + *time = This->latency_time; + + return S_OK; +} + +static HRESULT WINAPI latency_clock_AdviseTime(IReferenceClock *iface, REFERENCE_TIME base, + REFERENCE_TIME offset, HEVENT event, DWORD_PTR *cookie) +{ + FIXME("(%p, %I64d, %I64d, %#Ix, %p): stub\n", iface, base, offset, event, cookie); + return E_NOTIMPL; +} + +static HRESULT WINAPI latency_clock_AdvisePeriodic(IReferenceClock *iface, REFERENCE_TIME start, + REFERENCE_TIME period, HSEMAPHORE semaphore, DWORD_PTR *cookie) +{ + FIXME("(%p, %I64d, %I64d, %#Ix, %p): stub\n", iface, start, period, semaphore, cookie); + return E_NOTIMPL; +} + +static HRESULT WINAPI latency_clock_Unadvise(IReferenceClock *iface, DWORD_PTR cookie) +{ + FIXME("(%p, %#Ix): stub\n", iface, cookie); + return E_NOTIMPL; +} + +static const IReferenceClockVtbl latency_clock_vtbl = +{ + latency_clock_QueryInterface, + latency_clock_AddRef, + latency_clock_Release, + latency_clock_GetTime, + latency_clock_AdviseTime, + latency_clock_AdvisePeriodic, + latency_clock_Unadvise, +}; + HRESULT synth_sink_create(IUnknown **ret_iface) { struct synth_sink *obj; - HRESULT hr;
TRACE("(%p)\n", ret_iface);
@@ -382,15 +459,9 @@ HRESULT synth_sink_create(IUnknown **ret_iface) if (!(obj = calloc(1, sizeof(*obj)))) return E_OUTOFMEMORY; obj->IDirectMusicSynthSink_iface.lpVtbl = &synth_sink_vtbl; obj->IKsControl_iface.lpVtbl = &synth_sink_control; + obj->IReferenceClock_iface.lpVtbl = &latency_clock_vtbl; obj->ref = 1;
- hr = CoCreateInstance(&CLSID_SystemClock, NULL, CLSCTX_INPROC_SERVER, &IID_IReferenceClock, (void **)&obj->latency_clock); - if (FAILED(hr)) - { - free(obj); - return hr; - } - TRACE("Created DirectMusicSynthSink %p\n", obj); *ret_iface = (IUnknown *)&obj->IDirectMusicSynthSink_iface; return S_OK; diff --git a/dlls/dmsynth/tests/dmsynth.c b/dlls/dmsynth/tests/dmsynth.c index 3aec7dd8825..6f89b1580b5 100644 --- a/dlls/dmsynth/tests/dmsynth.c +++ b/dlls/dmsynth/tests/dmsynth.c @@ -1222,12 +1222,12 @@ static void test_IDirectMusicSynthSink(void) ok(hr == S_OK, "got %#lx\n", hr); ok(latency_clock != clock, "got same clock\n"); ref = get_refcount(sink); - todo_wine ok(ref == 2, "got %#lx\n", ref); + ok(ref == 2, "got %#lx\n", ref);
hr = IReferenceClock_GetTime(latency_clock, NULL); - todo_wine ok(hr == E_INVALIDARG, "got %#lx\n", hr); + ok(hr == E_INVALIDARG, "got %#lx\n", hr); hr = IReferenceClock_GetTime(latency_clock, &time); - todo_wine ok(hr == E_FAIL, "got %#lx\n", hr); + ok(hr == E_FAIL, "got %#lx\n", hr);
hr = IDirectMusicSynthSink_Init(sink, NULL); ok(hr == S_OK, "got %#lx\n", hr); @@ -1255,7 +1255,7 @@ static void test_IDirectMusicSynthSink(void) hr = IDirectMusicSynthSink_SetMasterClock(sink, clock); ok(hr == S_OK, "got %#lx\n", hr); hr = IReferenceClock_GetTime(latency_clock, &time); - todo_wine ok(hr == E_FAIL, "got %#lx\n", hr); + ok(hr == E_FAIL, "got %#lx\n", hr); hr = IDirectMusicSynthSink_Activate(sink, TRUE); ok(hr == S_OK, "got %#lx\n", hr); hr = IDirectMusicSynthSink_Activate(sink, TRUE); @@ -1283,8 +1283,8 @@ static void test_IDirectMusicSynthSink(void) /* latency clock now works fine */ tmp_time = time; hr = IReferenceClock_GetTime(latency_clock, &tmp_time); - todo_wine_if(hr == S_FALSE) ok(hr == S_OK, "got %#lx\n", hr); - todo_wine_if(tmp_time <= time) ok(tmp_time > time, "got %I64d\n", tmp_time - time); + ok(hr == S_OK, "got %#lx\n", hr); + todo_wine ok(tmp_time > time, "got %I64d\n", tmp_time - time); ok(tmp_time - time <= 2000000, "got %I64d\n", tmp_time - time);
/* setting the clock while active is fine */