mf: Add a stub for default presentation clock.

Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
stable
Nikolay Sivov 2019-03-05 10:49:38 +03:00 committed by Alexandre Julliard
parent 1bd7dbfbc4
commit 98a28d1493
5 changed files with 504 additions and 2 deletions

View File

@ -45,7 +45,7 @@
@ stub MFCreatePMPHost
@ stub MFCreatePMPMediaSession
@ stub MFCreatePMPServer
@ stub MFCreatePresentationClock
@ stdcall MFCreatePresentationClock(ptr)
@ stub MFCreatePresentationDescriptorFromASFProfile
@ stub MFCreateProxyLocator
@ stub MFCreateRemoteDesktopPlugin

View File

@ -25,6 +25,7 @@
#include "winbase.h"
#include "mfidl.h"
#include "mfapi.h"
#include "mferror.h"
#include "wine/debug.h"
#include "wine/heap.h"
@ -38,11 +39,43 @@ struct media_session
IMFMediaEventQueue *event_queue;
};
struct presentation_clock
{
IMFPresentationClock IMFPresentationClock_iface;
IMFRateControl IMFRateControl_iface;
IMFTimer IMFTimer_iface;
IMFShutdown IMFShutdown_iface;
LONG refcount;
IMFPresentationTimeSource *time_source;
MFCLOCK_STATE state;
CRITICAL_SECTION cs;
};
static inline struct media_session *impl_from_IMFMediaSession(IMFMediaSession *iface)
{
return CONTAINING_RECORD(iface, struct media_session, IMFMediaSession_iface);
}
static struct presentation_clock *impl_from_IMFPresentationClock(IMFPresentationClock *iface)
{
return CONTAINING_RECORD(iface, struct presentation_clock, IMFPresentationClock_iface);
}
static struct presentation_clock *impl_from_IMFRateControl(IMFRateControl *iface)
{
return CONTAINING_RECORD(iface, struct presentation_clock, IMFRateControl_iface);
}
static struct presentation_clock *impl_from_IMFTimer(IMFTimer *iface)
{
return CONTAINING_RECORD(iface, struct presentation_clock, IMFTimer_iface);
}
static struct presentation_clock *impl_from_IMFShutdown(IMFShutdown *iface)
{
return CONTAINING_RECORD(iface, struct presentation_clock, IMFShutdown_iface);
}
static HRESULT WINAPI mfsession_QueryInterface(IMFMediaSession *iface, REFIID riid, void **out)
{
struct media_session *session = impl_from_IMFMediaSession(iface);
@ -251,3 +284,351 @@ HRESULT WINAPI MFCreateMediaSession(IMFAttributes *config, IMFMediaSession **ses
return S_OK;
}
static HRESULT WINAPI present_clock_QueryInterface(IMFPresentationClock *iface, REFIID riid, void **out)
{
struct presentation_clock *clock = impl_from_IMFPresentationClock(iface);
TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), out);
if (IsEqualIID(riid, &IID_IMFPresentationClock) ||
IsEqualIID(riid, &IID_IMFClock) ||
IsEqualIID(riid, &IID_IUnknown))
{
*out = &clock->IMFPresentationClock_iface;
}
else if (IsEqualIID(riid, &IID_IMFRateControl))
{
*out = &clock->IMFRateControl_iface;
}
else if (IsEqualIID(riid, &IID_IMFTimer))
{
*out = &clock->IMFTimer_iface;
}
else if (IsEqualIID(riid, &IID_IMFShutdown))
{
*out = &clock->IMFShutdown_iface;
}
else
{
WARN("Unsupported %s.\n", debugstr_guid(riid));
*out = NULL;
return E_NOINTERFACE;
}
IUnknown_AddRef((IUnknown *)*out);
return S_OK;
}
static ULONG WINAPI present_clock_AddRef(IMFPresentationClock *iface)
{
struct presentation_clock *clock = impl_from_IMFPresentationClock(iface);
ULONG refcount = InterlockedIncrement(&clock->refcount);
TRACE("%p, refcount %u.\n", iface, refcount);
return refcount;
}
static ULONG WINAPI present_clock_Release(IMFPresentationClock *iface)
{
struct presentation_clock *clock = impl_from_IMFPresentationClock(iface);
ULONG refcount = InterlockedDecrement(&clock->refcount);
TRACE("%p, refcount %u.\n", iface, refcount);
if (!refcount)
{
if (clock->time_source)
IMFPresentationTimeSource_Release(clock->time_source);
DeleteCriticalSection(&clock->cs);
heap_free(clock);
}
return refcount;
}
static HRESULT WINAPI present_clock_GetClockCharacteristics(IMFPresentationClock *iface, DWORD *flags)
{
FIXME("%p, %p.\n", iface, flags);
return E_NOTIMPL;
}
static HRESULT WINAPI present_clock_GetCorrelatedTime(IMFPresentationClock *iface, DWORD reserved,
LONGLONG *clock_time, MFTIME *system_time)
{
FIXME("%p, %#x, %p, %p.\n", iface, reserved, clock_time, system_time);
return E_NOTIMPL;
}
static HRESULT WINAPI present_clock_GetContinuityKey(IMFPresentationClock *iface, DWORD *key)
{
TRACE("%p, %p.\n", iface, key);
*key = 0;
return S_OK;
}
static HRESULT WINAPI present_clock_GetState(IMFPresentationClock *iface, DWORD reserved, MFCLOCK_STATE *state)
{
struct presentation_clock *clock = impl_from_IMFPresentationClock(iface);
TRACE("%p, %#x, %p.\n", iface, reserved, state);
EnterCriticalSection(&clock->cs);
*state = clock->state;
LeaveCriticalSection(&clock->cs);
return S_OK;
}
static HRESULT WINAPI present_clock_GetProperties(IMFPresentationClock *iface, MFCLOCK_PROPERTIES *props)
{
FIXME("%p, %p.\n", iface, props);
return E_NOTIMPL;
}
static HRESULT WINAPI present_clock_SetTimeSource(IMFPresentationClock *iface,
IMFPresentationTimeSource *time_source)
{
FIXME("%p, %p.\n", iface, time_source);
return E_NOTIMPL;
}
static HRESULT WINAPI present_clock_GetTimeSource(IMFPresentationClock *iface,
IMFPresentationTimeSource **time_source)
{
struct presentation_clock *clock = impl_from_IMFPresentationClock(iface);
HRESULT hr = S_OK;
TRACE("%p, %p.\n", iface, time_source);
EnterCriticalSection(&clock->cs);
if (clock->time_source)
{
*time_source = clock->time_source;
IMFPresentationTimeSource_AddRef(*time_source);
}
else
hr = MF_E_CLOCK_NO_TIME_SOURCE;
LeaveCriticalSection(&clock->cs);
return hr;
}
static HRESULT WINAPI present_clock_GetTime(IMFPresentationClock *iface, MFTIME *time)
{
FIXME("%p, %p.\n", iface, time);
return E_NOTIMPL;
}
static HRESULT WINAPI present_clock_AddClockStateSink(IMFPresentationClock *iface, IMFClockStateSink *state_sink)
{
FIXME("%p, %p.\n", iface, state_sink);
return E_NOTIMPL;
}
static HRESULT WINAPI present_clock_RemoveClockStateSink(IMFPresentationClock *iface,
IMFClockStateSink *state_sink)
{
FIXME("%p, %p.\n", iface, state_sink);
return E_NOTIMPL;
}
static HRESULT WINAPI present_clock_Start(IMFPresentationClock *iface, LONGLONG start_offset)
{
FIXME("%p, %s.\n", iface, wine_dbgstr_longlong(start_offset));
return E_NOTIMPL;
}
static HRESULT WINAPI present_clock_Stop(IMFPresentationClock *iface)
{
FIXME("%p.\n", iface);
return E_NOTIMPL;
}
static HRESULT WINAPI present_clock_Pause(IMFPresentationClock *iface)
{
FIXME("%p.\n", iface);
return E_NOTIMPL;
}
static const IMFPresentationClockVtbl presentationclockvtbl =
{
present_clock_QueryInterface,
present_clock_AddRef,
present_clock_Release,
present_clock_GetClockCharacteristics,
present_clock_GetCorrelatedTime,
present_clock_GetContinuityKey,
present_clock_GetState,
present_clock_GetProperties,
present_clock_SetTimeSource,
present_clock_GetTimeSource,
present_clock_GetTime,
present_clock_AddClockStateSink,
present_clock_RemoveClockStateSink,
present_clock_Start,
present_clock_Stop,
present_clock_Pause,
};
static HRESULT WINAPI present_clock_rate_control_QueryInterface(IMFRateControl *iface, REFIID riid, void **out)
{
struct presentation_clock *clock = impl_from_IMFRateControl(iface);
return IMFPresentationClock_QueryInterface(&clock->IMFPresentationClock_iface, riid, out);
}
static ULONG WINAPI present_clock_rate_control_AddRef(IMFRateControl *iface)
{
struct presentation_clock *clock = impl_from_IMFRateControl(iface);
return IMFPresentationClock_AddRef(&clock->IMFPresentationClock_iface);
}
static ULONG WINAPI present_clock_rate_control_Release(IMFRateControl *iface)
{
struct presentation_clock *clock = impl_from_IMFRateControl(iface);
return IMFPresentationClock_Release(&clock->IMFPresentationClock_iface);
}
static HRESULT WINAPI present_clock_rate_SetRate(IMFRateControl *iface, BOOL thin, float rate)
{
FIXME("%p, %d, %f.\n", iface, thin, rate);
return E_NOTIMPL;
}
static HRESULT WINAPI present_clock_rate_GetRate(IMFRateControl *iface, BOOL *thin, float *rate)
{
FIXME("%p, %p, %p.\n", iface, thin, rate);
return E_NOTIMPL;
}
static const IMFRateControlVtbl presentclockratecontrolvtbl =
{
present_clock_rate_control_QueryInterface,
present_clock_rate_control_AddRef,
present_clock_rate_control_Release,
present_clock_rate_SetRate,
present_clock_rate_GetRate,
};
static HRESULT WINAPI present_clock_timer_QueryInterface(IMFTimer *iface, REFIID riid, void **out)
{
struct presentation_clock *clock = impl_from_IMFTimer(iface);
return IMFPresentationClock_QueryInterface(&clock->IMFPresentationClock_iface, riid, out);
}
static ULONG WINAPI present_clock_timer_AddRef(IMFTimer *iface)
{
struct presentation_clock *clock = impl_from_IMFTimer(iface);
return IMFPresentationClock_AddRef(&clock->IMFPresentationClock_iface);
}
static ULONG WINAPI present_clock_timer_Release(IMFTimer *iface)
{
struct presentation_clock *clock = impl_from_IMFTimer(iface);
return IMFPresentationClock_Release(&clock->IMFPresentationClock_iface);
}
static HRESULT WINAPI present_clock_timer_SetTimer(IMFTimer *iface, DWORD flags, LONGLONG time,
IMFAsyncCallback *callback, IUnknown *state, IUnknown **cancel_key)
{
FIXME("%p, %#x, %s, %p, %p, %p.\n", iface, flags, wine_dbgstr_longlong(time), callback, state, cancel_key);
return E_NOTIMPL;
}
static HRESULT WINAPI present_clock_timer_CancelTimer(IMFTimer *iface, IUnknown *cancel_key)
{
FIXME("%p, %p.\n", iface, cancel_key);
return E_NOTIMPL;
}
static const IMFTimerVtbl presentclocktimervtbl =
{
present_clock_timer_QueryInterface,
present_clock_timer_AddRef,
present_clock_timer_Release,
present_clock_timer_SetTimer,
present_clock_timer_CancelTimer,
};
static HRESULT WINAPI present_clock_shutdown_QueryInterface(IMFShutdown *iface, REFIID riid, void **out)
{
struct presentation_clock *clock = impl_from_IMFShutdown(iface);
return IMFPresentationClock_QueryInterface(&clock->IMFPresentationClock_iface, riid, out);
}
static ULONG WINAPI present_clock_shutdown_AddRef(IMFShutdown *iface)
{
struct presentation_clock *clock = impl_from_IMFShutdown(iface);
return IMFPresentationClock_AddRef(&clock->IMFPresentationClock_iface);
}
static ULONG WINAPI present_clock_shutdown_Release(IMFShutdown *iface)
{
struct presentation_clock *clock = impl_from_IMFShutdown(iface);
return IMFPresentationClock_Release(&clock->IMFPresentationClock_iface);
}
static HRESULT WINAPI present_clock_shutdown_Shutdown(IMFShutdown *iface)
{
FIXME("%p.\n", iface);
return E_NOTIMPL;
}
static HRESULT WINAPI present_clock_shutdown_GetShutdownStatus(IMFShutdown *iface, MFSHUTDOWN_STATUS *status)
{
FIXME("%p, %p.\n", iface, status);
return E_NOTIMPL;
}
static const IMFShutdownVtbl presentclockshutdownvtbl =
{
present_clock_shutdown_QueryInterface,
present_clock_shutdown_AddRef,
present_clock_shutdown_Release,
present_clock_shutdown_Shutdown,
present_clock_shutdown_GetShutdownStatus,
};
/***********************************************************************
* MFCreatePresentationClock (mf.@)
*/
HRESULT WINAPI MFCreatePresentationClock(IMFPresentationClock **clock)
{
struct presentation_clock *object;
TRACE("%p.\n", clock);
object = heap_alloc_zero(sizeof(*object));
if (!object)
return E_OUTOFMEMORY;
object->IMFPresentationClock_iface.lpVtbl = &presentationclockvtbl;
object->IMFRateControl_iface.lpVtbl = &presentclockratecontrolvtbl;
object->IMFTimer_iface.lpVtbl = &presentclocktimervtbl;
object->IMFShutdown_iface.lpVtbl = &presentclockshutdownvtbl;
object->refcount = 1;
InitializeCriticalSection(&object->cs);
*clock = &object->IMFPresentationClock_iface;
return S_OK;
}

View File

@ -735,6 +735,68 @@ static void test_MFShutdownObject(void)
ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
}
static void test_presentation_clock(void)
{
IMFPresentationTimeSource *time_source;
IMFRateControl *rate_control;
IMFPresentationClock *clock;
MFCLOCK_PROPERTIES props;
IMFShutdown *shutdown;
LONGLONG clock_time;
MFCLOCK_STATE state;
IMFTimer *timer;
MFTIME systime;
DWORD value;
HRESULT hr;
hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
ok(hr == S_OK, "Failed to start up, hr %#x.\n", hr);
hr = MFCreatePresentationClock(&clock);
ok(hr == S_OK, "Failed to create presentation clock, hr %#x.\n", hr);
hr = IMFPresentationClock_GetTimeSource(clock, &time_source);
ok(hr == MF_E_CLOCK_NO_TIME_SOURCE, "Unexpected hr %#x.\n", hr);
hr = IMFPresentationClock_GetClockCharacteristics(clock, &value);
todo_wine
ok(hr == MF_E_CLOCK_NO_TIME_SOURCE, "Unexpected hr %#x.\n", hr);
value = 1;
hr = IMFPresentationClock_GetContinuityKey(clock, &value);
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
ok(value == 0, "Unexpected value %u.\n", value);
hr = IMFPresentationClock_GetProperties(clock, &props);
todo_wine
ok(hr == MF_E_CLOCK_NO_TIME_SOURCE, "Unexpected hr %#x.\n", hr);
hr = IMFPresentationClock_GetState(clock, 0, &state);
ok(hr == S_OK, "Failed to get state, hr %#x.\n", hr);
ok(state == MFCLOCK_STATE_INVALID, "Unexpected state %d.\n", state);
hr = IMFPresentationClock_GetCorrelatedTime(clock, 0, &clock_time, &systime);
todo_wine
ok(hr == MF_E_CLOCK_NO_TIME_SOURCE, "Unexpected hr %#x.\n", hr);
hr = IMFPresentationClock_QueryInterface(clock, &IID_IMFRateControl, (void **)&rate_control);
ok(hr == S_OK, "Failed to get rate control interface, hr %#x.\n", hr);
IMFRateControl_Release(rate_control);
hr = IMFPresentationClock_QueryInterface(clock, &IID_IMFTimer, (void **)&timer);
ok(hr == S_OK, "Failed to get timer interface, hr %#x.\n", hr);
IMFTimer_Release(timer);
hr = IMFPresentationClock_QueryInterface(clock, &IID_IMFShutdown, (void **)&shutdown);
ok(hr == S_OK, "Failed to get shutdown interface, hr %#x.\n", hr);
IMFShutdown_Release(shutdown);
IMFPresentationClock_Release(clock);
hr = MFShutdown();
ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
}
START_TEST(mf)
{
test_topology();
@ -743,4 +805,5 @@ START_TEST(mf)
test_MFCreateSequencerSource();
test_media_session();
test_MFShutdownObject();
test_presentation_clock();
}

View File

@ -82,4 +82,6 @@
#define MF_E_TOPO_MISSING_SOURCE _HRESULT_TYPEDEF_(0xc00d521a)
#define MF_E_TOPO_SINK_ACTIVATES_UNSUPPORTED _HRESULT_TYPEDEF_(0xc00d521b)
#define MF_E_CLOCK_NO_TIME_SOURCE _HRESULT_TYPEDEF_(0xc00d9c41)
#endif /* __WINE_MFERROR_H */

View File

@ -70,6 +70,37 @@ interface IMFClock : IUnknown
HRESULT GetProperties([out] MFCLOCK_PROPERTIES *props);
}
[
object,
uuid(88ddcd21-03c3-4275-91ed-55ee3929328f)
]
interface IMFRateControl : IUnknown
{
HRESULT SetRate(
[in] BOOL thin,
[in] float rate);
HRESULT GetRate(
[in, out, unique] BOOL *thin,
[in, out, unique] float *rate);
}
[
object,
uuid(e56e4cbd-8f70-49d8-a0f8-edb3d6ab9bf2),
local
]
interface IMFTimer : IUnknown
{
HRESULT SetTimer(
[in] DWORD flags,
[in] LONGLONG time,
[in] IMFAsyncCallback *callback,
[in] IUnknown *state,
[out] IUnknown **key);
HRESULT CancelTimer(
[in] IUnknown *key);
}
[
object,
uuid(83cf873a-f6da-4bc8-823f-bacfd55dc430),
@ -319,6 +350,7 @@ interface IMFSequencerSource : IUnknown
cpp_quote("HRESULT WINAPI MFCreateMediaSession(IMFAttributes *config, IMFMediaSession **session);")
cpp_quote("HRESULT WINAPI MFCreateMFByteStreamOnStream(IStream *stream, IMFByteStream **bytestream);" )
cpp_quote("HRESULT WINAPI MFCreateMFByteStreamOnStreamEx(IUnknown *stream, IMFByteStream **bytestream);")
cpp_quote("HRESULT WINAPI MFCreatePresentationClock(IMFPresentationClock **clock);")
cpp_quote("HRESULT WINAPI MFCreateSequencerSource(IUnknown *reserved, IMFSequencerSource **seq_source);" )
cpp_quote("HRESULT WINAPI MFCreateSourceResolver(IMFSourceResolver **resolver);")
cpp_quote("HRESULT WINAPI MFCreateStreamDescriptor(DWORD identifier, DWORD cMediaTypes,")
@ -360,7 +392,31 @@ interface IMFMediaSource : IMFMediaEventGenerator
}
interface IMFStreamSink;
interface IMFPresentationClock;
[
object,
uuid(7ff12cce-f76f-41c2-863b-1666c8e5e139)
]
interface IMFPresentationTimeSource : IMFClock
{
HRESULT GetUnderlyingClock([out] IMFClock **clock);
}
[
object,
uuid(868ce85c-8ea9-4f55-ab82-b009a910a805)
]
interface IMFPresentationClock : IMFClock
{
HRESULT SetTimeSource([in] IMFPresentationTimeSource *time_source);
HRESULT GetTimeSource([out] IMFPresentationTimeSource **time_source);
HRESULT GetTime([out] MFTIME *time);
HRESULT AddClockStateSink([in] IMFClockStateSink *state_sink);
HRESULT RemoveClockStateSink([in] IMFClockStateSink *state_sink);
HRESULT Start([in] LONGLONG start_offset);
HRESULT Stop();
HRESULT Pause();
}
[
object,