mf: Subscribe standard quality manager to clock state change events.

Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Nikolay Sivov 2021-02-01 13:22:07 +03:00 committed by Alexandre Julliard
parent a30d43c60b
commit 144dcc1a26
2 changed files with 87 additions and 8 deletions

View File

@ -328,6 +328,7 @@ enum quality_manager_state
struct quality_manager
{
IMFQualityManager IMFQualityManager_iface;
IMFClockStateSink IMFClockStateSink_iface;
LONG refcount;
IMFPresentationClock *clock;
@ -425,6 +426,11 @@ static struct quality_manager *impl_from_IMFQualityManager(IMFQualityManager *if
return CONTAINING_RECORD(iface, struct quality_manager, IMFQualityManager_iface);
}
static struct quality_manager *impl_from_qm_IMFClockStateSink(IMFClockStateSink *iface)
{
return CONTAINING_RECORD(iface, struct quality_manager, IMFClockStateSink_iface);
}
static struct topo_node *impl_node_from_IMFVideoSampleAllocatorNotify(IMFVideoSampleAllocatorNotify *iface)
{
return CONTAINING_RECORD(iface, struct topo_node, u.sink.notify_cb);
@ -4751,19 +4757,28 @@ HRESULT WINAPI MFCreatePresentationClock(IMFPresentationClock **clock)
static HRESULT WINAPI standard_quality_manager_QueryInterface(IMFQualityManager *iface, REFIID riid, void **out)
{
struct quality_manager *manager = impl_from_IMFQualityManager(iface);
TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), out);
if (IsEqualIID(riid, &IID_IMFQualityManager) ||
IsEqualIID(riid, &IID_IUnknown))
{
*out = iface;
IMFQualityManager_AddRef(iface);
return S_OK;
}
else if (IsEqualIID(riid, &IID_IMFClockStateSink))
{
*out = &manager->IMFClockStateSink_iface;
}
else
{
WARN("Unsupported %s.\n", debugstr_guid(riid));
*out = NULL;
return E_NOINTERFACE;
}
WARN("Unsupported %s.\n", debugstr_guid(riid));
*out = NULL;
return E_NOINTERFACE;
IUnknown_AddRef((IUnknown *)*out);
return S_OK;
}
static ULONG WINAPI standard_quality_manager_AddRef(IMFQualityManager *iface)
@ -4804,7 +4819,10 @@ static HRESULT WINAPI standard_quality_manager_NotifyTopology(IMFQualityManager
static void standard_quality_manager_release_clock(struct quality_manager *manager)
{
if (manager->clock)
{
IMFPresentationClock_RemoveClockStateSink(manager->clock, &manager->IMFClockStateSink_iface);
IMFPresentationClock_Release(manager->clock);
}
manager->clock = NULL;
}
@ -4826,6 +4844,8 @@ static HRESULT WINAPI standard_quality_manager_NotifyPresentationClock(IMFQualit
standard_quality_manager_release_clock(manager);
manager->clock = clock;
IMFPresentationClock_AddRef(manager->clock);
if (FAILED(IMFPresentationClock_AddClockStateSink(manager->clock, &manager->IMFClockStateSink_iface)))
WARN("Failed to set state sink.\n");
}
LeaveCriticalSection(&manager->cs);
@ -4886,6 +4906,67 @@ static IMFQualityManagerVtbl standard_quality_manager_vtbl =
standard_quality_manager_Shutdown,
};
static HRESULT WINAPI standard_quality_manager_sink_QueryInterface(IMFClockStateSink *iface,
REFIID riid, void **obj)
{
struct quality_manager *manager = impl_from_qm_IMFClockStateSink(iface);
return IMFQualityManager_QueryInterface(&manager->IMFQualityManager_iface, riid, obj);
}
static ULONG WINAPI standard_quality_manager_sink_AddRef(IMFClockStateSink *iface)
{
struct quality_manager *manager = impl_from_qm_IMFClockStateSink(iface);
return IMFQualityManager_AddRef(&manager->IMFQualityManager_iface);
}
static ULONG WINAPI standard_quality_manager_sink_Release(IMFClockStateSink *iface)
{
struct quality_manager *manager = impl_from_qm_IMFClockStateSink(iface);
return IMFQualityManager_Release(&manager->IMFQualityManager_iface);
}
static HRESULT WINAPI standard_quality_manager_sink_OnClockStart(IMFClockStateSink *iface,
MFTIME systime, LONGLONG offset)
{
return S_OK;
}
static HRESULT WINAPI standard_quality_manager_sink_OnClockStop(IMFClockStateSink *iface,
MFTIME systime)
{
return S_OK;
}
static HRESULT WINAPI standard_quality_manager_sink_OnClockPause(IMFClockStateSink *iface,
MFTIME systime)
{
return S_OK;
}
static HRESULT WINAPI standard_quality_manager_sink_OnClockRestart(IMFClockStateSink *iface,
MFTIME systime)
{
return S_OK;
}
static HRESULT WINAPI standard_quality_manager_sink_OnClockSetRate(IMFClockStateSink *iface,
MFTIME systime, float rate)
{
return S_OK;
}
static const IMFClockStateSinkVtbl standard_quality_manager_sink_vtbl =
{
standard_quality_manager_sink_QueryInterface,
standard_quality_manager_sink_AddRef,
standard_quality_manager_sink_Release,
standard_quality_manager_sink_OnClockStart,
standard_quality_manager_sink_OnClockStop,
standard_quality_manager_sink_OnClockPause,
standard_quality_manager_sink_OnClockRestart,
standard_quality_manager_sink_OnClockSetRate,
};
HRESULT WINAPI MFCreateStandardQualityManager(IMFQualityManager **manager)
{
struct quality_manager *object;
@ -4897,6 +4978,7 @@ HRESULT WINAPI MFCreateStandardQualityManager(IMFQualityManager **manager)
return E_OUTOFMEMORY;
object->IMFQualityManager_iface.lpVtbl = &standard_quality_manager_vtbl;
object->IMFClockStateSink_iface.lpVtbl = &standard_quality_manager_sink_vtbl;
object->refcount = 1;
InitializeCriticalSection(&object->cs);

View File

@ -3661,7 +3661,6 @@ static void test_quality_manager(void)
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);
@ -3673,7 +3672,6 @@ todo_wine
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);
@ -3701,7 +3699,6 @@ todo_wine
EXPECT_REF(clock, 2);
IMFQualityManager_Release(manager);
todo_wine
EXPECT_REF(clock, 2);
IMFPresentationClock_Release(clock);