[PATCH 1/7] mf: Add support to get/set presentation clock for SAR.

Nikolay Sivov nsivov at codeweavers.com
Wed Apr 8 09:21:22 CDT 2020


Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
 dlls/mf/sar.c      | 131 +++++++++++++++++++++++++++++++++++++++++++--
 dlls/mf/tests/mf.c |  54 +++++++++++++++++++
 2 files changed, 181 insertions(+), 4 deletions(-)

diff --git a/dlls/mf/sar.c b/dlls/mf/sar.c
index 71fd4ed850..2ef767b787 100644
--- a/dlls/mf/sar.c
+++ b/dlls/mf/sar.c
@@ -32,9 +32,11 @@ struct audio_renderer
 {
     IMFMediaSink IMFMediaSink_iface;
     IMFMediaSinkPreroll IMFMediaSinkPreroll_iface;
+    IMFClockStateSink IMFClockStateSink_iface;
     IMFMediaEventGenerator IMFMediaEventGenerator_iface;
     LONG refcount;
     IMFMediaEventQueue *event_queue;
+    IMFPresentationClock *clock;
     BOOL is_shut_down;
     CRITICAL_SECTION cs;
 };
@@ -49,6 +51,11 @@ static struct audio_renderer *impl_from_IMFMediaSinkPreroll(IMFMediaSinkPreroll
     return CONTAINING_RECORD(iface, struct audio_renderer, IMFMediaSinkPreroll_iface);
 }
 
+static struct audio_renderer *impl_from_IMFClockStateSink(IMFClockStateSink *iface)
+{
+    return CONTAINING_RECORD(iface, struct audio_renderer, IMFClockStateSink_iface);
+}
+
 static struct audio_renderer *impl_from_IMFMediaEventGenerator(IMFMediaEventGenerator *iface)
 {
     return CONTAINING_RECORD(iface, struct audio_renderer, IMFMediaEventGenerator_iface);
@@ -69,6 +76,10 @@ static HRESULT WINAPI audio_renderer_sink_QueryInterface(IMFMediaSink *iface, RE
     {
         *obj = &renderer->IMFMediaSinkPreroll_iface;
     }
+    else if (IsEqualIID(riid, &IID_IMFClockStateSink))
+    {
+        *obj = &renderer->IMFClockStateSink_iface;
+    }
     else if (IsEqualIID(riid, &IID_IMFMediaEventGenerator))
     {
         *obj = &renderer->IMFMediaEventGenerator_iface;
@@ -104,6 +115,8 @@ static ULONG WINAPI audio_renderer_sink_Release(IMFMediaSink *iface)
     {
         if (renderer->event_queue)
             IMFMediaEventQueue_Release(renderer->event_queue);
+        if (renderer->clock)
+            IMFPresentationClock_Release(renderer->clock);
         DeleteCriticalSection(&renderer->cs);
         heap_free(renderer);
     }
@@ -179,16 +192,60 @@ static HRESULT WINAPI audio_renderer_sink_GetStreamSinkById(IMFMediaSink *iface,
 
 static HRESULT WINAPI audio_renderer_sink_SetPresentationClock(IMFMediaSink *iface, IMFPresentationClock *clock)
 {
-    FIXME("%p, %p.\n", iface, clock);
+    struct audio_renderer *renderer = impl_from_IMFMediaSink(iface);
+    HRESULT hr = S_OK;
 
-    return E_NOTIMPL;
+    TRACE("%p, %p.\n", iface, clock);
+
+    EnterCriticalSection(&renderer->cs);
+
+    if (renderer->is_shut_down)
+        hr = MF_E_SHUTDOWN;
+    else
+    {
+        if (renderer->clock)
+        {
+            IMFPresentationClock_RemoveClockStateSink(renderer->clock, &renderer->IMFClockStateSink_iface);
+            IMFPresentationClock_Release(renderer->clock);
+        }
+        renderer->clock = clock;
+        if (renderer->clock)
+        {
+            IMFPresentationClock_AddRef(renderer->clock);
+            IMFPresentationClock_AddClockStateSink(renderer->clock, &renderer->IMFClockStateSink_iface);
+        }
+    }
+
+    LeaveCriticalSection(&renderer->cs);
+
+    return hr;
 }
 
 static HRESULT WINAPI audio_renderer_sink_GetPresentationClock(IMFMediaSink *iface, IMFPresentationClock **clock)
 {
-    FIXME("%p, %p.\n", iface, clock);
+    struct audio_renderer *renderer = impl_from_IMFMediaSink(iface);
+    HRESULT hr = S_OK;
 
-    return E_NOTIMPL;
+    TRACE("%p, %p.\n", iface, clock);
+
+    if (!clock)
+        return E_POINTER;
+
+    EnterCriticalSection(&renderer->cs);
+
+    if (renderer->is_shut_down)
+        hr = MF_E_SHUTDOWN;
+    else if (renderer->clock)
+    {
+        *clock = renderer->clock;
+        IMFPresentationClock_AddRef(*clock);
+    }
+    else
+        hr = MF_E_NO_CLOCK;
+
+    LeaveCriticalSection(&renderer->cs);
+
+    return hr;
 }
 
 static HRESULT WINAPI audio_renderer_sink_Shutdown(IMFMediaSink *iface)
@@ -325,6 +382,71 @@ static const IMFMediaEventGeneratorVtbl audio_renderer_events_vtbl =
     audio_renderer_events_QueueEvent,
 };
 
+static HRESULT WINAPI audio_renderer_clock_sink_QueryInterface(IMFClockStateSink *iface, REFIID riid, void **obj)
+{
+    struct audio_renderer *renderer = impl_from_IMFClockStateSink(iface);
+    return IMFMediaSink_QueryInterface(&renderer->IMFMediaSink_iface, riid, obj);
+}
+
+static ULONG WINAPI audio_renderer_clock_sink_AddRef(IMFClockStateSink *iface)
+{
+    struct audio_renderer *renderer = impl_from_IMFClockStateSink(iface);
+    return IMFMediaSink_AddRef(&renderer->IMFMediaSink_iface);
+}
+
+static ULONG WINAPI audio_renderer_clock_sink_Release(IMFClockStateSink *iface)
+{
+    struct audio_renderer *renderer = impl_from_IMFClockStateSink(iface);
+    return IMFMediaSink_Release(&renderer->IMFMediaSink_iface);
+}
+
+static HRESULT WINAPI audio_renderer_clock_sink_OnClockStart(IMFClockStateSink *iface, MFTIME systime, LONGLONG offset)
+{
+    FIXME("%p, %s, %s.\n", iface, debugstr_time(systime), debugstr_time(offset));
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI audio_renderer_clock_sink_OnClockStop(IMFClockStateSink *iface, MFTIME systime)
+{
+    FIXME("%p, %s.\n", iface, debugstr_time(systime));
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI audio_renderer_clock_sink_OnClockPause(IMFClockStateSink *iface, MFTIME systime)
+{
+    FIXME("%p, %s.\n", iface, debugstr_time(systime));
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI audio_renderer_clock_sink_OnClockRestart(IMFClockStateSink *iface, MFTIME systime)
+{
+    FIXME("%p, %s.\n", iface, debugstr_time(systime));
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI audio_renderer_clock_sink_OnClockSetRate(IMFClockStateSink *iface, MFTIME systime, float rate)
+{
+    FIXME("%p, %s, %f.\n", iface, debugstr_time(systime), rate);
+
+    return E_NOTIMPL;
+}
+
+static const IMFClockStateSinkVtbl audio_renderer_clock_sink_vtbl =
+{
+    audio_renderer_clock_sink_QueryInterface,
+    audio_renderer_clock_sink_AddRef,
+    audio_renderer_clock_sink_Release,
+    audio_renderer_clock_sink_OnClockStart,
+    audio_renderer_clock_sink_OnClockStop,
+    audio_renderer_clock_sink_OnClockPause,
+    audio_renderer_clock_sink_OnClockRestart,
+    audio_renderer_clock_sink_OnClockSetRate,
+};
+
 static HRESULT sar_create_object(IMFAttributes *attributes, void *user_context, IUnknown **obj)
 {
     struct audio_renderer *renderer;
@@ -337,6 +459,7 @@ static HRESULT sar_create_object(IMFAttributes *attributes, void *user_context,
 
     renderer->IMFMediaSink_iface.lpVtbl = &audio_renderer_sink_vtbl;
     renderer->IMFMediaSinkPreroll_iface.lpVtbl = &audio_renderer_preroll_vtbl;
+    renderer->IMFClockStateSink_iface.lpVtbl = &audio_renderer_clock_sink_vtbl;
     renderer->IMFMediaEventGenerator_iface.lpVtbl = &audio_renderer_events_vtbl;
     renderer->refcount = 1;
     InitializeCriticalSection(&renderer->cs);
diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c
index fcbbde36fb..98e180e453 100644
--- a/dlls/mf/tests/mf.c
+++ b/dlls/mf/tests/mf.c
@@ -2631,6 +2631,7 @@ static void test_quality_manager(void)
 
 static void test_sar(void)
 {
+    IMFPresentationClock *present_clock, *present_clock2;
     IMFPresentationTimeSource *time_source;
     IMFClockStateSink *state_sink;
     IMFMediaSink *sink, *sink2;
@@ -2654,6 +2655,12 @@ static void test_sar(void)
     }
     ok(hr == S_OK, "Failed to create renderer, hr %#x.\n", hr);
 
+    hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
+    ok(hr == S_OK, "Startup failure, hr %#x.\n", hr);
+
+    hr = MFCreatePresentationClock(&present_clock);
+    ok(hr == S_OK, "Failed to create presentation clock, hr %#x.\n", hr);
+
     hr = IMFMediaSink_QueryInterface(sink, &IID_IMFPresentationTimeSource, (void **)&time_source);
 todo_wine
     ok(hr == S_OK, "Failed to get time source interface, hr %#x.\n", hr);
@@ -2707,6 +2714,36 @@ if (SUCCEEDED(hr))
     ok(hr == S_OK, "Failed to get interface, hr %#x.\n", hr);
     IUnknown_Release(unk);
 
+    /* Clock */
+    hr = IMFMediaSink_QueryInterface(sink, &IID_IMFClockStateSink, (void **)&unk);
+    ok(hr == S_OK, "Failed to get interface, hr %#x.\n", hr);
+    IUnknown_Release(unk);
+
+    hr = IMFMediaSink_SetPresentationClock(sink, NULL);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+    hr = IMFMediaSink_SetPresentationClock(sink, present_clock);
+todo_wine
+    ok(hr == MF_E_CLOCK_NO_TIME_SOURCE, "Unexpected hr %#x.\n", hr);
+
+    hr = MFCreateSystemTimeSource(&time_source);
+    ok(hr == S_OK, "Failed to create time source, hr %#x.\n", hr);
+
+    hr = IMFPresentationClock_SetTimeSource(present_clock, time_source);
+    ok(hr == S_OK, "Failed to set time source, hr %#x.\n", hr);
+    IMFPresentationTimeSource_Release(time_source);
+
+    hr = IMFMediaSink_SetPresentationClock(sink, present_clock);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+    hr = IMFMediaSink_GetPresentationClock(sink, NULL);
+    ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
+
+    hr = IMFMediaSink_GetPresentationClock(sink, &present_clock2);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+    ok(present_clock == present_clock2, "Unexpected instance.\n");
+    IMFPresentationClock_Release(present_clock2);
+
     /* Shutdown */
     hr = IMFMediaSink_Shutdown(sink);
     ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
@@ -2729,6 +2766,18 @@ if (SUCCEEDED(hr))
     hr = IMFMediaSink_GetCharacteristics(sink, &flags);
     ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
 
+    hr = IMFMediaSink_SetPresentationClock(sink, NULL);
+    ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
+
+    hr = IMFMediaSink_SetPresentationClock(sink, present_clock);
+    ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
+
+    hr = IMFMediaSink_GetPresentationClock(sink, NULL);
+    ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
+
+    hr = IMFMediaSink_GetPresentationClock(sink, &present_clock2);
+    ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
+
     IMFMediaSink_Release(sink);
 
     /* Activation */
@@ -2769,6 +2818,11 @@ todo_wine
 
     IMFActivate_Release(activate);
 
+    IMFPresentationClock_Release(present_clock);
+
+    hr = MFShutdown();
+    ok(hr == S_OK, "Shutdown failure, hr %#x.\n", hr);
+
     CoUninitialize();
 }
 
-- 
2.25.1




More information about the wine-devel mailing list