forked from Mirrors/wine-wine
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
parent
1bd7dbfbc4
commit
98a28d1493
|
@ -45,7 +45,7 @@
|
||||||
@ stub MFCreatePMPHost
|
@ stub MFCreatePMPHost
|
||||||
@ stub MFCreatePMPMediaSession
|
@ stub MFCreatePMPMediaSession
|
||||||
@ stub MFCreatePMPServer
|
@ stub MFCreatePMPServer
|
||||||
@ stub MFCreatePresentationClock
|
@ stdcall MFCreatePresentationClock(ptr)
|
||||||
@ stub MFCreatePresentationDescriptorFromASFProfile
|
@ stub MFCreatePresentationDescriptorFromASFProfile
|
||||||
@ stub MFCreateProxyLocator
|
@ stub MFCreateProxyLocator
|
||||||
@ stub MFCreateRemoteDesktopPlugin
|
@ stub MFCreateRemoteDesktopPlugin
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include "winbase.h"
|
#include "winbase.h"
|
||||||
#include "mfidl.h"
|
#include "mfidl.h"
|
||||||
#include "mfapi.h"
|
#include "mfapi.h"
|
||||||
|
#include "mferror.h"
|
||||||
|
|
||||||
#include "wine/debug.h"
|
#include "wine/debug.h"
|
||||||
#include "wine/heap.h"
|
#include "wine/heap.h"
|
||||||
|
@ -38,11 +39,43 @@ struct media_session
|
||||||
IMFMediaEventQueue *event_queue;
|
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)
|
static inline struct media_session *impl_from_IMFMediaSession(IMFMediaSession *iface)
|
||||||
{
|
{
|
||||||
return CONTAINING_RECORD(iface, struct media_session, 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)
|
static HRESULT WINAPI mfsession_QueryInterface(IMFMediaSession *iface, REFIID riid, void **out)
|
||||||
{
|
{
|
||||||
struct media_session *session = impl_from_IMFMediaSession(iface);
|
struct media_session *session = impl_from_IMFMediaSession(iface);
|
||||||
|
@ -251,3 +284,351 @@ HRESULT WINAPI MFCreateMediaSession(IMFAttributes *config, IMFMediaSession **ses
|
||||||
|
|
||||||
return S_OK;
|
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;
|
||||||
|
}
|
||||||
|
|
|
@ -735,6 +735,68 @@ static void test_MFShutdownObject(void)
|
||||||
ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
|
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)
|
START_TEST(mf)
|
||||||
{
|
{
|
||||||
test_topology();
|
test_topology();
|
||||||
|
@ -743,4 +805,5 @@ START_TEST(mf)
|
||||||
test_MFCreateSequencerSource();
|
test_MFCreateSequencerSource();
|
||||||
test_media_session();
|
test_media_session();
|
||||||
test_MFShutdownObject();
|
test_MFShutdownObject();
|
||||||
|
test_presentation_clock();
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,4 +82,6 @@
|
||||||
#define MF_E_TOPO_MISSING_SOURCE _HRESULT_TYPEDEF_(0xc00d521a)
|
#define MF_E_TOPO_MISSING_SOURCE _HRESULT_TYPEDEF_(0xc00d521a)
|
||||||
#define MF_E_TOPO_SINK_ACTIVATES_UNSUPPORTED _HRESULT_TYPEDEF_(0xc00d521b)
|
#define MF_E_TOPO_SINK_ACTIVATES_UNSUPPORTED _HRESULT_TYPEDEF_(0xc00d521b)
|
||||||
|
|
||||||
|
#define MF_E_CLOCK_NO_TIME_SOURCE _HRESULT_TYPEDEF_(0xc00d9c41)
|
||||||
|
|
||||||
#endif /* __WINE_MFERROR_H */
|
#endif /* __WINE_MFERROR_H */
|
||||||
|
|
|
@ -70,6 +70,37 @@ interface IMFClock : IUnknown
|
||||||
HRESULT GetProperties([out] MFCLOCK_PROPERTIES *props);
|
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,
|
object,
|
||||||
uuid(83cf873a-f6da-4bc8-823f-bacfd55dc430),
|
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 MFCreateMediaSession(IMFAttributes *config, IMFMediaSession **session);")
|
||||||
cpp_quote("HRESULT WINAPI MFCreateMFByteStreamOnStream(IStream *stream, IMFByteStream **bytestream);" )
|
cpp_quote("HRESULT WINAPI MFCreateMFByteStreamOnStream(IStream *stream, IMFByteStream **bytestream);" )
|
||||||
cpp_quote("HRESULT WINAPI MFCreateMFByteStreamOnStreamEx(IUnknown *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 MFCreateSequencerSource(IUnknown *reserved, IMFSequencerSource **seq_source);" )
|
||||||
cpp_quote("HRESULT WINAPI MFCreateSourceResolver(IMFSourceResolver **resolver);")
|
cpp_quote("HRESULT WINAPI MFCreateSourceResolver(IMFSourceResolver **resolver);")
|
||||||
cpp_quote("HRESULT WINAPI MFCreateStreamDescriptor(DWORD identifier, DWORD cMediaTypes,")
|
cpp_quote("HRESULT WINAPI MFCreateStreamDescriptor(DWORD identifier, DWORD cMediaTypes,")
|
||||||
|
@ -360,7 +392,31 @@ interface IMFMediaSource : IMFMediaEventGenerator
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IMFStreamSink;
|
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,
|
object,
|
||||||
|
|
Loading…
Reference in New Issue