Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- 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)