Nikolay Sivov : mf: Add shutdown state for the standard quality manager.

Alexandre Julliard julliard at winehq.org
Mon Feb 1 16:13:08 CST 2021


Module: wine
Branch: master
Commit: a30d43c60ba2b16302bed1c8d3a7980c7abd6def
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=a30d43c60ba2b16302bed1c8d3a7980c7abd6def

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Mon Feb  1 13:22:06 2021 +0300

mf: Add shutdown state for the standard quality manager.

Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/mf/session.c  | 48 ++++++++++++++++++++++++++++++++++++++----------
 dlls/mf/tests/mf.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 89 insertions(+), 10 deletions(-)

diff --git a/dlls/mf/session.c b/dlls/mf/session.c
index 5034255339c..af58a47ed7a 100644
--- a/dlls/mf/session.c
+++ b/dlls/mf/session.c
@@ -319,12 +319,19 @@ struct presentation_clock
     BOOL is_shut_down;
 };
 
+enum quality_manager_state
+{
+    QUALITY_MANAGER_READY = 0,
+    QUALITY_MANAGER_SHUT_DOWN,
+};
+
 struct quality_manager
 {
     IMFQualityManager IMFQualityManager_iface;
     LONG refcount;
 
     IMFPresentationClock *clock;
+    unsigned int state;
     CRITICAL_SECTION cs;
 };
 
@@ -4794,24 +4801,35 @@ static HRESULT WINAPI standard_quality_manager_NotifyTopology(IMFQualityManager
     return S_OK;
 }
 
+static void standard_quality_manager_release_clock(struct quality_manager *manager)
+{
+    if (manager->clock)
+        IMFPresentationClock_Release(manager->clock);
+    manager->clock = NULL;
+}
+
 static HRESULT WINAPI standard_quality_manager_NotifyPresentationClock(IMFQualityManager *iface,
         IMFPresentationClock *clock)
 {
     struct quality_manager *manager = impl_from_IMFQualityManager(iface);
+    HRESULT hr = S_OK;
 
     TRACE("%p, %p.\n", iface, clock);
 
-    if (!clock)
-        return E_POINTER;
-
     EnterCriticalSection(&manager->cs);
-    if (manager->clock)
-        IMFPresentationClock_Release(manager->clock);
-    manager->clock = clock;
-    IMFPresentationClock_AddRef(manager->clock);
+    if (manager->state == QUALITY_MANAGER_SHUT_DOWN)
+        hr = MF_E_SHUTDOWN;
+    else if (!clock)
+        hr = E_POINTER;
+    else
+    {
+        standard_quality_manager_release_clock(manager);
+        manager->clock = clock;
+        IMFPresentationClock_AddRef(manager->clock);
+    }
     LeaveCriticalSection(&manager->cs);
 
-    return S_OK;
+    return hr;
 }
 
 static HRESULT WINAPI standard_quality_manager_NotifyProcessInput(IMFQualityManager *iface, IMFTopologyNode *node,
@@ -4840,9 +4858,19 @@ static HRESULT WINAPI standard_quality_manager_NotifyQualityEvent(IMFQualityMana
 
 static HRESULT WINAPI standard_quality_manager_Shutdown(IMFQualityManager *iface)
 {
-    FIXME("%p stub.\n", iface);
+    struct quality_manager *manager = impl_from_IMFQualityManager(iface);
 
-    return E_NOTIMPL;
+    TRACE("%p.\n", iface);
+
+    EnterCriticalSection(&manager->cs);
+    if (manager->state != QUALITY_MANAGER_SHUT_DOWN)
+    {
+        standard_quality_manager_release_clock(manager);
+        manager->state = QUALITY_MANAGER_SHUT_DOWN;
+    }
+    LeaveCriticalSection(&manager->cs);
+
+    return S_OK;
 }
 
 static IMFQualityManagerVtbl standard_quality_manager_vtbl =
diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c
index 846d311c877..aad1564c3f0 100644
--- a/dlls/mf/tests/mf.c
+++ b/dlls/mf/tests/mf.c
@@ -3647,16 +3647,67 @@ failed:
 
 static void test_quality_manager(void)
 {
+    IMFPresentationClock *clock;
     IMFQualityManager *manager;
     HRESULT hr;
 
+    hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
+    ok(hr == S_OK, "Startup failure, hr %#x.\n", hr);
+
+    hr = MFCreatePresentationClock(&clock);
+    ok(hr == S_OK, "Failed to create presentation clock, hr %#x.\n", hr);
+
     hr = MFCreateStandardQualityManager(&manager);
     ok(hr == S_OK, "Failed to create quality manager, hr %#x.\n", hr);
 
+    check_interface(manager, &IID_IMFQualityManager, TRUE);
+todo_wine
+    check_interface(manager, &IID_IMFClockStateSink, TRUE);
+
     hr = IMFQualityManager_NotifyPresentationClock(manager, NULL);
     ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
 
+    /* Set clock, then shutdown. */
+    EXPECT_REF(clock, 1);
+    EXPECT_REF(manager, 1);
+    hr = IMFQualityManager_NotifyPresentationClock(manager, clock);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+    EXPECT_REF(clock, 2);
+todo_wine
+    EXPECT_REF(manager, 2);
+
+    hr = IMFQualityManager_Shutdown(manager);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+    EXPECT_REF(clock, 1);
+
+    hr = IMFQualityManager_NotifyPresentationClock(manager, clock);
+    ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
+
+    hr = IMFQualityManager_NotifyPresentationClock(manager, NULL);
+    ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
+
+    hr = IMFQualityManager_Shutdown(manager);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+    IMFQualityManager_Release(manager);
+
+    /* Set clock, then release without shutting down. */
+    hr = MFCreateStandardQualityManager(&manager);
+    ok(hr == S_OK, "Failed to create quality manager, hr %#x.\n", hr);
+
+    EXPECT_REF(clock, 1);
+    hr = IMFQualityManager_NotifyPresentationClock(manager, clock);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+    EXPECT_REF(clock, 2);
+
     IMFQualityManager_Release(manager);
+todo_wine
+    EXPECT_REF(clock, 2);
+
+    IMFPresentationClock_Release(clock);
+
+    hr = MFShutdown();
+    ok(hr == S_OK, "Shutdown failure, hr %#x.\n", hr);
 }
 
 static void test_sar(void)




More information about the wine-cvs mailing list