mfplat: Create system clock instance per system time source.
Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
ac2038ef30
commit
5904eb8419
|
@ -44,12 +44,19 @@ WINE_DEFAULT_DEBUG_CHANNEL(mfplat);
|
|||
|
||||
static LONG platform_lock;
|
||||
|
||||
struct system_clock
|
||||
{
|
||||
IMFClock IMFClock_iface;
|
||||
LONG refcount;
|
||||
};
|
||||
|
||||
struct system_time_source
|
||||
{
|
||||
IMFPresentationTimeSource IMFPresentationTimeSource_iface;
|
||||
IMFClockStateSink IMFClockStateSink_iface;
|
||||
LONG refcount;
|
||||
MFCLOCK_STATE state;
|
||||
IMFClock *clock;
|
||||
CRITICAL_SECTION cs;
|
||||
};
|
||||
|
||||
|
@ -63,6 +70,11 @@ static struct system_time_source *impl_from_IMFClockStateSink(IMFClockStateSink
|
|||
return CONTAINING_RECORD(iface, struct system_time_source, IMFClockStateSink_iface);
|
||||
}
|
||||
|
||||
static struct system_clock *impl_from_IMFClock(IMFClock *iface)
|
||||
{
|
||||
return CONTAINING_RECORD(iface, struct system_clock, IMFClock_iface);
|
||||
}
|
||||
|
||||
static const WCHAR transform_keyW[] = {'M','e','d','i','a','F','o','u','n','d','a','t','i','o','n','\\',
|
||||
'T','r','a','n','s','f','o','r','m','s',0};
|
||||
static const WCHAR categories_keyW[] = {'M','e','d','i','a','F','o','u','n','d','a','t','i','o','n','\\',
|
||||
|
@ -6538,6 +6550,126 @@ HRESULT WINAPI MFCreateMFByteStreamOnStreamEx(IUnknown *stream, IMFByteStream **
|
|||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI system_clock_QueryInterface(IMFClock *iface, REFIID riid, void **obj)
|
||||
{
|
||||
TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), obj);
|
||||
|
||||
if (IsEqualIID(riid, &IID_IMFClock) ||
|
||||
IsEqualIID(riid, &IID_IUnknown))
|
||||
{
|
||||
*obj = iface;
|
||||
IMFClock_AddRef(iface);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
WARN("Unsupported %s.\n", debugstr_guid(riid));
|
||||
*obj = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG WINAPI system_clock_AddRef(IMFClock *iface)
|
||||
{
|
||||
struct system_clock *clock = impl_from_IMFClock(iface);
|
||||
ULONG refcount = InterlockedIncrement(&clock->refcount);
|
||||
|
||||
TRACE("%p, refcount %u.\n", iface, refcount);
|
||||
|
||||
return refcount;
|
||||
}
|
||||
|
||||
static ULONG WINAPI system_clock_Release(IMFClock *iface)
|
||||
{
|
||||
struct system_clock *clock = impl_from_IMFClock(iface);
|
||||
ULONG refcount = InterlockedDecrement(&clock->refcount);
|
||||
|
||||
TRACE("%p, refcount %u.\n", iface, refcount);
|
||||
|
||||
if (!refcount)
|
||||
heap_free(clock);
|
||||
|
||||
return refcount;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI system_clock_GetClockCharacteristics(IMFClock *iface, DWORD *flags)
|
||||
{
|
||||
TRACE("%p, %p.\n", iface, flags);
|
||||
|
||||
*flags = MFCLOCK_CHARACTERISTICS_FLAG_FREQUENCY_10MHZ | MFCLOCK_CHARACTERISTICS_FLAG_ALWAYS_RUNNING |
|
||||
MFCLOCK_CHARACTERISTICS_FLAG_IS_SYSTEM_CLOCK;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI system_clock_GetCorrelatedTime(IMFClock *iface, DWORD reserved, LONGLONG *clock_time,
|
||||
MFTIME *system_time)
|
||||
{
|
||||
TRACE("%p, %#x, %p, %p.\n", iface, reserved, clock_time, system_time);
|
||||
|
||||
*clock_time = *system_time = MFGetSystemTime();
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI system_clock_GetContinuityKey(IMFClock *iface, DWORD *key)
|
||||
{
|
||||
TRACE("%p, %p.\n", iface, key);
|
||||
|
||||
*key = 0;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI system_clock_GetState(IMFClock *iface, DWORD reserved, MFCLOCK_STATE *state)
|
||||
{
|
||||
TRACE("%p, %#x, %p.\n", iface, reserved, state);
|
||||
|
||||
*state = MFCLOCK_STATE_RUNNING;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI system_clock_GetProperties(IMFClock *iface, MFCLOCK_PROPERTIES *props)
|
||||
{
|
||||
TRACE("%p, %p.\n", iface, props);
|
||||
|
||||
if (!props)
|
||||
return E_POINTER;
|
||||
|
||||
memset(props, 0, sizeof(*props));
|
||||
props->qwClockFrequency = MFCLOCK_FREQUENCY_HNS;
|
||||
props->dwClockTolerance = MFCLOCK_TOLERANCE_UNKNOWN;
|
||||
props->dwClockJitter = 1;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static const IMFClockVtbl system_clock_vtbl =
|
||||
{
|
||||
system_clock_QueryInterface,
|
||||
system_clock_AddRef,
|
||||
system_clock_Release,
|
||||
system_clock_GetClockCharacteristics,
|
||||
system_clock_GetCorrelatedTime,
|
||||
system_clock_GetContinuityKey,
|
||||
system_clock_GetState,
|
||||
system_clock_GetProperties,
|
||||
};
|
||||
|
||||
static HRESULT create_system_clock(IMFClock **clock)
|
||||
{
|
||||
struct system_clock *object;
|
||||
|
||||
if (!(object = heap_alloc(sizeof(*object))))
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
object->IMFClock_iface.lpVtbl = &system_clock_vtbl;
|
||||
object->refcount = 1;
|
||||
|
||||
*clock = &object->IMFClock_iface;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI system_time_source_QueryInterface(IMFPresentationTimeSource *iface, REFIID riid, void **obj)
|
||||
{
|
||||
struct system_time_source *source = impl_from_IMFPresentationTimeSource(iface);
|
||||
|
@ -6583,6 +6715,8 @@ static ULONG WINAPI system_time_source_Release(IMFPresentationTimeSource *iface)
|
|||
|
||||
if (!refcount)
|
||||
{
|
||||
if (source->clock)
|
||||
IMFClock_Release(source->clock);
|
||||
DeleteCriticalSection(&source->cs);
|
||||
heap_free(source);
|
||||
}
|
||||
|
@ -6648,9 +6782,14 @@ static HRESULT WINAPI system_time_source_GetProperties(IMFPresentationTimeSource
|
|||
|
||||
static HRESULT WINAPI system_time_source_GetUnderlyingClock(IMFPresentationTimeSource *iface, IMFClock **clock)
|
||||
{
|
||||
FIXME("%p, %p.\n", iface, clock);
|
||||
struct system_time_source *source = impl_from_IMFPresentationTimeSource(iface);
|
||||
|
||||
return E_NOTIMPL;
|
||||
TRACE("%p, %p.\n", iface, clock);
|
||||
|
||||
*clock = source->clock;
|
||||
IMFClock_AddRef(*clock);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static const IMFPresentationTimeSourceVtbl systemtimesourcevtbl =
|
||||
|
@ -6812,6 +6951,7 @@ static const IMFClockStateSinkVtbl systemtimesourcesinkvtbl =
|
|||
HRESULT WINAPI MFCreateSystemTimeSource(IMFPresentationTimeSource **time_source)
|
||||
{
|
||||
struct system_time_source *object;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("%p.\n", time_source);
|
||||
|
||||
|
@ -6824,6 +6964,12 @@ HRESULT WINAPI MFCreateSystemTimeSource(IMFPresentationTimeSource **time_source)
|
|||
object->refcount = 1;
|
||||
InitializeCriticalSection(&object->cs);
|
||||
|
||||
if (FAILED(hr = create_system_clock(&object->clock)))
|
||||
{
|
||||
IMFPresentationTimeSource_Release(&object->IMFPresentationTimeSource_iface);
|
||||
return hr;
|
||||
}
|
||||
|
||||
*time_source = &object->IMFPresentationTimeSource_iface;
|
||||
|
||||
return S_OK;
|
||||
|
|
|
@ -52,6 +52,15 @@ DEFINE_GUID(CLSID_FileSchemeHandler, 0x477ec299, 0x1421, 0x4bdd, 0x97, 0x1f, 0x7
|
|||
|
||||
static BOOL is_win8_plus;
|
||||
|
||||
#define EXPECT_REF(obj,ref) _expect_ref((IUnknown*)obj, ref, __LINE__)
|
||||
static void _expect_ref(IUnknown *obj, ULONG ref, int line)
|
||||
{
|
||||
ULONG rc;
|
||||
IUnknown_AddRef(obj);
|
||||
rc = IUnknown_Release(obj);
|
||||
ok_(__FILE__,line)(rc == ref, "Unexpected refcount %d, expected %d.\n", rc, ref);
|
||||
}
|
||||
|
||||
static HRESULT (WINAPI *pMFCopyImage)(BYTE *dest, LONG deststride, const BYTE *src, LONG srcstride,
|
||||
DWORD width, DWORD lines);
|
||||
static HRESULT (WINAPI *pMFCreateSourceResolver)(IMFSourceResolver **resolver);
|
||||
|
@ -2540,11 +2549,14 @@ static void test_system_time_source(void)
|
|||
{ CLOCK_STOP, MFCLOCK_STATE_STOPPED },
|
||||
{ CLOCK_PAUSE, MFCLOCK_STATE_STOPPED, TRUE },
|
||||
};
|
||||
IMFPresentationTimeSource *time_source;
|
||||
IMFPresentationTimeSource *time_source, *time_source2;
|
||||
IMFClockStateSink *statesink;
|
||||
IMFClock *clock, *clock2;
|
||||
MFCLOCK_PROPERTIES props;
|
||||
MFCLOCK_STATE state;
|
||||
unsigned int i;
|
||||
MFTIME systime;
|
||||
LONGLONG time;
|
||||
DWORD value;
|
||||
HRESULT hr;
|
||||
|
||||
|
@ -2612,6 +2624,57 @@ static void test_system_time_source(void)
|
|||
ok(props.dwClockTolerance == MFCLOCK_TOLERANCE_UNKNOWN, "Unexpected tolerance %u.\n", props.dwClockTolerance);
|
||||
ok(props.dwClockJitter == 1, "Unexpected jitter %u.\n", props.dwClockJitter);
|
||||
|
||||
/* Underlying clock. */
|
||||
hr = MFCreateSystemTimeSource(&time_source2);
|
||||
ok(hr == S_OK, "Failed to create time source, hr %#x.\n", hr);
|
||||
EXPECT_REF(time_source2, 1);
|
||||
hr = IMFPresentationTimeSource_GetUnderlyingClock(time_source2, &clock2);
|
||||
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
|
||||
EXPECT_REF(time_source2, 1);
|
||||
EXPECT_REF(clock2, 2);
|
||||
|
||||
EXPECT_REF(time_source, 1);
|
||||
hr = IMFPresentationTimeSource_GetUnderlyingClock(time_source, &clock);
|
||||
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
|
||||
EXPECT_REF(time_source, 1);
|
||||
EXPECT_REF(clock, 2);
|
||||
|
||||
ok(clock != clock2, "Unexpected clock instance.\n");
|
||||
|
||||
IMFPresentationTimeSource_Release(time_source2);
|
||||
IMFClock_Release(clock2);
|
||||
|
||||
hr = IMFClock_GetClockCharacteristics(clock, &value);
|
||||
ok(hr == S_OK, "Failed to get clock flags, hr %#x.\n", hr);
|
||||
ok(value == (MFCLOCK_CHARACTERISTICS_FLAG_FREQUENCY_10MHZ | MFCLOCK_CHARACTERISTICS_FLAG_ALWAYS_RUNNING |
|
||||
MFCLOCK_CHARACTERISTICS_FLAG_IS_SYSTEM_CLOCK), "Unexpected flags %#x.\n", value);
|
||||
|
||||
hr = IMFClock_GetContinuityKey(clock, &value);
|
||||
ok(hr == S_OK, "Failed to get clock key, hr %#x.\n", hr);
|
||||
ok(value == 0, "Unexpected key value %u.\n", value);
|
||||
|
||||
hr = IMFClock_GetState(clock, 0, &state);
|
||||
ok(hr == S_OK, "Failed to get clock state, hr %#x.\n", hr);
|
||||
ok(state == MFCLOCK_STATE_RUNNING, "Unexpected state %d.\n", state);
|
||||
|
||||
hr = IMFClock_GetProperties(clock, &props);
|
||||
ok(hr == S_OK, "Failed to get clock properties, hr %#x.\n", hr);
|
||||
|
||||
ok(props.qwCorrelationRate == 0, "Unexpected correlation rate %s.\n",
|
||||
wine_dbgstr_longlong(props.qwCorrelationRate));
|
||||
ok(IsEqualGUID(&props.guidClockId, &GUID_NULL), "Unexpected clock id %s.\n", wine_dbgstr_guid(&props.guidClockId));
|
||||
ok(props.dwClockFlags == 0, "Unexpected flags %#x.\n", props.dwClockFlags);
|
||||
ok(props.qwClockFrequency == MFCLOCK_FREQUENCY_HNS, "Unexpected frequency %s.\n",
|
||||
wine_dbgstr_longlong(props.qwClockFrequency));
|
||||
ok(props.dwClockTolerance == MFCLOCK_TOLERANCE_UNKNOWN, "Unexpected tolerance %u.\n", props.dwClockTolerance);
|
||||
ok(props.dwClockJitter == 1, "Unexpected jitter %u.\n", props.dwClockJitter);
|
||||
|
||||
hr = IMFClock_GetCorrelatedTime(clock, 0, &time, &systime);
|
||||
ok(hr == S_OK, "Failed to get clock time, hr %#x.\n", hr);
|
||||
ok(time == systime, "Unexpected time %s, %s.\n", wine_dbgstr_longlong(time), wine_dbgstr_longlong(systime));
|
||||
|
||||
IMFClock_Release(clock);
|
||||
|
||||
IMFPresentationTimeSource_Release(time_source);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue