Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mf/session.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-)
diff --git a/dlls/mf/session.c b/dlls/mf/session.c index 169ba7403b..6b993b1d60 100644 --- a/dlls/mf/session.c +++ b/dlls/mf/session.c @@ -38,6 +38,7 @@ enum session_command SESSION_CMD_CLOSE, SESSION_CMD_SET_TOPOLOGY, SESSION_CMD_START, + SESSION_CMD_PAUSE, };
struct session_op @@ -718,9 +719,19 @@ static HRESULT WINAPI mfsession_Start(IMFMediaSession *iface, const GUID *format
static HRESULT WINAPI mfsession_Pause(IMFMediaSession *iface) { - FIXME("(%p)\n", iface); + struct media_session *session = impl_from_IMFMediaSession(iface); + struct session_op *op; + HRESULT hr;
- return E_NOTIMPL; + TRACE("%p.\n", iface); + + if (FAILED(hr = create_session_op(SESSION_CMD_PAUSE, &op))) + return hr; + + hr = session_submit_command(session, op); + IUnknown_Release(&op->IUnknown_iface); + + return hr; }
static HRESULT WINAPI mfsession_Stop(IMFMediaSession *iface) @@ -1010,6 +1021,8 @@ static HRESULT WINAPI session_commands_callback_Invoke(IMFAsyncCallback *iface, session_start(session, &op->u.start.time_format, &op->u.start.start_position); break; } + case SESSION_CMD_PAUSE: + break; case SESSION_CMD_CLOSE: EnterCriticalSection(&session->cs); if (session->state != SESSION_STATE_CLOSED)
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mf/session.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/dlls/mf/session.c b/dlls/mf/session.c index 6b993b1d60..5ac8bd97ae 100644 --- a/dlls/mf/session.c +++ b/dlls/mf/session.c @@ -39,6 +39,7 @@ enum session_command SESSION_CMD_SET_TOPOLOGY, SESSION_CMD_START, SESSION_CMD_PAUSE, + SESSION_CMD_STOP, };
struct session_op @@ -736,9 +737,19 @@ static HRESULT WINAPI mfsession_Pause(IMFMediaSession *iface)
static HRESULT WINAPI mfsession_Stop(IMFMediaSession *iface) { - FIXME("(%p)\n", iface); + struct media_session *session = impl_from_IMFMediaSession(iface); + struct session_op *op; + HRESULT hr;
- return E_NOTIMPL; + TRACE("%p.\n", iface); + + if (FAILED(hr = create_session_op(SESSION_CMD_STOP, &op))) + return hr; + + hr = session_submit_command(session, op); + IUnknown_Release(&op->IUnknown_iface); + + return hr; }
static HRESULT WINAPI mfsession_Close(IMFMediaSession *iface)
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mf/session.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-)
diff --git a/dlls/mf/session.c b/dlls/mf/session.c index 5ac8bd97ae..9c0b80e340 100644 --- a/dlls/mf/session.c +++ b/dlls/mf/session.c @@ -550,7 +550,7 @@ static HRESULT WINAPI mfsession_QueryInterface(IMFMediaSession *iface, REFIID ri { struct media_session *session = impl_from_IMFMediaSession(iface);
- TRACE("(%p)->(%s %p)\n", iface, debugstr_guid(riid), out); + TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), out);
if (IsEqualIID(riid, &IID_IMFMediaSession) || IsEqualIID(riid, &IID_IMFMediaEventGenerator) || @@ -577,7 +577,7 @@ static ULONG WINAPI mfsession_AddRef(IMFMediaSession *iface) struct media_session *session = impl_from_IMFMediaSession(iface); ULONG refcount = InterlockedIncrement(&session->refcount);
- TRACE("(%p) refcount=%u\n", iface, refcount); + TRACE("%p, refcount %u.\n", iface, refcount);
return refcount; } @@ -587,7 +587,7 @@ static ULONG WINAPI mfsession_Release(IMFMediaSession *iface) struct media_session *session = impl_from_IMFMediaSession(iface); ULONG refcount = InterlockedDecrement(&session->refcount);
- TRACE("(%p) refcount=%u\n", iface, refcount); + TRACE("%p, refcount %u.\n", iface, refcount);
if (!refcount) { @@ -614,7 +614,7 @@ static HRESULT WINAPI mfsession_GetEvent(IMFMediaSession *iface, DWORD flags, IM { struct media_session *session = impl_from_IMFMediaSession(iface);
- TRACE("(%p)->(%#x, %p)\n", iface, flags, event); + TRACE("%p, %#x, %p.\n", iface, flags, event);
return IMFMediaEventQueue_GetEvent(session->event_queue, flags, event); } @@ -623,7 +623,7 @@ static HRESULT WINAPI mfsession_BeginGetEvent(IMFMediaSession *iface, IMFAsyncCa { struct media_session *session = impl_from_IMFMediaSession(iface);
- TRACE("(%p)->(%p, %p)\n", iface, callback, state); + TRACE("%p, %p, %p.\n", iface, callback, state);
return IMFMediaEventQueue_BeginGetEvent(session->event_queue, callback, state); } @@ -632,7 +632,7 @@ static HRESULT WINAPI mfsession_EndGetEvent(IMFMediaSession *iface, IMFAsyncResu { struct media_session *session = impl_from_IMFMediaSession(iface);
- TRACE("(%p)->(%p, %p)\n", iface, result, event); + TRACE("%p, %p, %p.\n", iface, result, event);
return IMFMediaEventQueue_EndGetEvent(session->event_queue, result, event); } @@ -642,7 +642,7 @@ static HRESULT WINAPI mfsession_QueueEvent(IMFMediaSession *iface, MediaEventTyp { struct media_session *session = impl_from_IMFMediaSession(iface);
- TRACE("(%p)->(%d, %s, %#x, %p)\n", iface, event_type, debugstr_guid(ext_type), hr, value); + TRACE("%p, %d, %s, %#x, %p.\n", iface, event_type, debugstr_guid(ext_type), hr, value);
return IMFMediaEventQueue_QueueEventParamVar(session->event_queue, event_type, ext_type, hr, value); } @@ -758,7 +758,7 @@ static HRESULT WINAPI mfsession_Close(IMFMediaSession *iface) struct session_op *op; HRESULT hr;
- TRACE("(%p)\n", iface); + TRACE("%p.\n", iface);
if (FAILED(hr = create_session_op(SESSION_CMD_CLOSE, &op))) return hr; @@ -774,7 +774,7 @@ static HRESULT WINAPI mfsession_Shutdown(IMFMediaSession *iface) struct media_session *session = impl_from_IMFMediaSession(iface); HRESULT hr = S_OK;
- FIXME("(%p)\n", iface); + FIXME("%p.\n", iface);
EnterCriticalSection(&session->cs); if (session->state == SESSION_STATE_SHUT_DOWN) @@ -803,14 +803,14 @@ static HRESULT WINAPI mfsession_GetClock(IMFMediaSession *iface, IMFClock **cloc
static HRESULT WINAPI mfsession_GetSessionCapabilities(IMFMediaSession *iface, DWORD *caps) { - FIXME("(%p)->(%p)\n", iface, caps); + FIXME("%p, %p.\n", iface, caps);
return E_NOTIMPL; }
static HRESULT WINAPI mfsession_GetFullTopology(IMFMediaSession *iface, DWORD flags, TOPOID id, IMFTopology **topology) { - FIXME("(%p)->(%#x, %s, %p)\n", iface, flags, wine_dbgstr_longlong(id), topology); + FIXME("%p, %#x, %s, %p.\n", iface, flags, wine_dbgstr_longlong(id), topology);
return E_NOTIMPL; }
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mf/session.c | 128 +++++++++++++++++++++++++++------------------- 1 file changed, 74 insertions(+), 54 deletions(-)
diff --git a/dlls/mf/session.c b/dlls/mf/session.c index 9c0b80e340..e23481d5c9 100644 --- a/dlls/mf/session.c +++ b/dlls/mf/session.c @@ -66,6 +66,7 @@ struct queued_topology { struct list entry; IMFTopology *topology; + MF_TOPOSTATUS status; };
enum session_state @@ -114,7 +115,7 @@ struct media_session IMFQualityManager *quality_manager; struct { - IMFTopology *current_topology; + struct queued_topology current_topology; struct list sources; } presentation; struct list topologies; @@ -356,6 +357,31 @@ static void session_clear_topologies(struct media_session *session) } }
+static void session_set_topo_status(struct media_session *session, struct queued_topology *topology, HRESULT status, + MF_TOPOSTATUS topo_status) +{ + IMFMediaEvent *event; + PROPVARIANT param; + + if (topo_status == MF_TOPOSTATUS_INVALID) + return; + + if (topo_status > topology->status) + { + param.vt = topology ? VT_UNKNOWN : VT_EMPTY; + param.punkVal = topology ? (IUnknown *)topology->topology : NULL; + + if (FAILED(MFCreateMediaEvent(MESessionTopologyStatus, &GUID_NULL, status, ¶m, &event))) + return; + + IMFMediaEvent_SetUINT32(event, &MF_EVENT_TOPOLOGY_STATUS, topo_status); + topology->status = topo_status; + IMFMediaEventQueue_QueueEvent(session->event_queue, event); + } + + IMFMediaEvent_Release(event); +} + static HRESULT session_bind_output_nodes(IMFTopology *topology) { MF_TOPOLOGY_TYPE node_type; @@ -422,19 +448,19 @@ static IMFTopology *session_get_next_topology(struct media_session *session) { struct queued_topology *queued;
- if (!session->presentation.current_topology) + if (!session->presentation.current_topology.topology) { struct list *head = list_head(&session->topologies); if (!head) return NULL;
queued = LIST_ENTRY(head, struct queued_topology, entry); - session->presentation.current_topology = queued->topology; + session->presentation.current_topology = *queued; list_remove(&queued->entry); heap_free(queued); }
- return session->presentation.current_topology; + return session->presentation.current_topology.topology; }
static void session_clear_presentation(struct media_session *session) @@ -442,10 +468,10 @@ static void session_clear_presentation(struct media_session *session) struct media_source *source, *source2; struct media_stream *stream, *stream2;
- if (session->presentation.current_topology) + if (session->presentation.current_topology.topology) { - IMFTopology_Release(session->presentation.current_topology); - session->presentation.current_topology = NULL; + IMFTopology_Release(session->presentation.current_topology.topology); + session->presentation.current_topology.topology = NULL; }
LIST_FOR_EACH_ENTRY_SAFE(source, source2, &session->presentation.sources, struct media_source, entry) @@ -924,6 +950,16 @@ static HRESULT WINAPI session_commands_callback_GetParameters(IMFAsyncCallback * return E_NOTIMPL; }
+static void session_raise_topology_set(struct media_session *session, IMFTopology *topology, HRESULT status) +{ + PROPVARIANT param; + + param.vt = topology ? VT_UNKNOWN : VT_EMPTY; + param.punkVal = (IUnknown *)topology; + + IMFMediaEventQueue_QueueEventParamVar(session->event_queue, MESessionTopologySet, &GUID_NULL, status, ¶m); +} + static HRESULT WINAPI session_commands_callback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result) { struct session_op *op = impl_op_from_IUnknown(IMFAsyncResult_GetStateNoAddRef(result)); @@ -944,26 +980,12 @@ static HRESULT WINAPI session_commands_callback_Invoke(IMFAsyncCallback *iface, { IMFTopology *topology = op->u.set_topology.topology; MF_TOPOSTATUS topo_status = MF_TOPOSTATUS_INVALID; - struct queued_topology *queued_topology; + struct queued_topology *queued_topology = NULL; DWORD flags = op->u.set_topology.flags; - PROPVARIANT param;
- if (flags & MFSESSION_SETTOPOLOGY_CLEAR_CURRENT) - { - EnterCriticalSection(&session->cs); - if ((topology && topology == session->presentation.current_topology) || !topology) - { - /* FIXME: stop current topology, queue next one. */ - session_clear_presentation(session); - } - else - status = S_FALSE; - topo_status = MF_TOPOSTATUS_READY; - LeaveCriticalSection(&session->cs); - } - else if (topology) + /* Resolve unless claimed to be full. */ + if (!(flags & MFSESSION_SETTOPOLOGY_CLEAR_CURRENT) && topology) { - /* Resolve unless claimed to be full. */ if (!(flags & MFSESSION_SETTOPOLOGY_NORESOLUTION)) { IMFTopology *resolved_topology = NULL; @@ -984,47 +1006,45 @@ static HRESULT WINAPI session_commands_callback_Invoke(IMFAsyncCallback *iface, { if (!(queued_topology = heap_alloc_zero(sizeof(*queued_topology)))) status = E_OUTOFMEMORY; - else - { - EnterCriticalSection(&session->cs); - - if (flags & MFSESSION_SETTOPOLOGY_IMMEDIATE) - { - session_clear_topologies(session); - session_clear_presentation(session); - } - - queued_topology->topology = topology; - IMFTopology_AddRef(queued_topology->topology); - list_add_tail(&session->topologies, &queued_topology->entry); + }
- LeaveCriticalSection(&session->cs); - } + if (SUCCEEDED(status)) + { + queued_topology->topology = topology; + IMFTopology_AddRef(queued_topology->topology); } }
- if (topology) + EnterCriticalSection(&session->cs); + + if (flags & MFSESSION_SETTOPOLOGY_CLEAR_CURRENT) { - param.vt = VT_UNKNOWN; - param.punkVal = (IUnknown *)topology; + if ((topology && topology == session->presentation.current_topology.topology) || !topology) + { + /* FIXME: stop current topology, queue next one. */ + session_clear_presentation(session); + } + else + status = S_FALSE; + topo_status = MF_TOPOSTATUS_READY; + queued_topology = &session->presentation.current_topology; } - else - param.vt = VT_EMPTY; - - IMFMediaEventQueue_QueueEventParamVar(session->event_queue, MESessionTopologySet, &GUID_NULL, - status, ¶m); - if (topo_status != MF_TOPOSTATUS_INVALID) + else if (queued_topology) { - IMFMediaEvent *event; - - if (SUCCEEDED(MFCreateMediaEvent(MESessionTopologyStatus, &GUID_NULL, status, ¶m, &event))) + if (flags & MFSESSION_SETTOPOLOGY_IMMEDIATE) { - IMFMediaEvent_SetUINT32(event, &MF_EVENT_TOPOLOGY_STATUS, topo_status); - IMFMediaEventQueue_QueueEvent(session->event_queue, event); - IMFMediaEvent_Release(event); + session_clear_topologies(session); + session_clear_presentation(session); } + + list_add_tail(&session->topologies, &queued_topology->entry); }
+ session_raise_topology_set(session, topology, status); + session_set_topo_status(session, queued_topology, status, topo_status); + + LeaveCriticalSection(&session->cs); + break; } case SESSION_CMD_START:
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mf/session.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-)
diff --git a/dlls/mf/session.c b/dlls/mf/session.c index e23481d5c9..fa8d58ad9d 100644 --- a/dlls/mf/session.c +++ b/dlls/mf/session.c @@ -1127,18 +1127,19 @@ static HRESULT session_add_media_stream(struct media_source *source, IMFMediaStr return S_OK; }
-static void session_set_source_state(struct media_session *session, IMFMediaSource *source, enum source_state state) +static BOOL session_set_source_state(struct media_session *session, IMFMediaSource *source, enum source_state state) { struct media_source *cur; + BOOL ret = TRUE;
LIST_FOR_EACH_ENTRY(cur, &session->presentation.sources, struct media_source, entry) { if (source == cur->source) - { cur->state = state; - break; - } + ret &= cur->state == state; } + + return ret; }
static HRESULT WINAPI session_events_callback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result) @@ -1153,6 +1154,7 @@ static HRESULT WINAPI session_events_callback_Invoke(IMFAsyncCallback *iface, IM IMFMediaStream *stream; PROPVARIANT value; HRESULT hr; + BOOL ret;
if (FAILED(hr = IMFAsyncResult_GetState(result, (IUnknown **)&event_source))) return hr; @@ -1189,7 +1191,12 @@ static HRESULT WINAPI session_events_callback_Invoke(IMFAsyncCallback *iface, IM source_state = SOURCE_STATE_STOPPED;
EnterCriticalSection(&session->cs); - session_set_source_state(session, (IMFMediaSource *)event_source, source_state); + + ret = session_set_source_state(session, (IMFMediaSource *)event_source, source_state); + if (ret && event_type == MESourceStarted) + session_set_topo_status(session, &session->presentation.current_topology, S_OK, + MF_TOPOSTATUS_STARTED_SOURCE); + LeaveCriticalSection(&session->cs); break; case MENewStream:
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mf/session.c | 93 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+)
diff --git a/dlls/mf/session.c b/dlls/mf/session.c index fa8d58ad9d..bf1e48aaf7 100644 --- a/dlls/mf/session.c +++ b/dlls/mf/session.c @@ -99,6 +99,12 @@ struct media_source struct list streams; };
+struct media_sink +{ + struct list entry; + IMFMediaSink *sink; +}; + struct media_session { IMFMediaSession IMFMediaSession_iface; @@ -117,6 +123,7 @@ struct media_session { struct queued_topology current_topology; struct list sources; + struct list sinks; } presentation; struct list topologies; enum session_state state; @@ -467,6 +474,7 @@ static void session_clear_presentation(struct media_session *session) { struct media_source *source, *source2; struct media_stream *stream, *stream2; + struct media_sink *sink, *sink2;
if (session->presentation.current_topology.topology) { @@ -490,6 +498,15 @@ static void session_clear_presentation(struct media_session *session) IMFMediaSource_Release(source->source); heap_free(source); } + + LIST_FOR_EACH_ENTRY_SAFE(sink, sink2, &session->presentation.sinks, struct media_sink, entry) + { + list_remove(&sink->entry); + + if (sink->sink) + IMFMediaSink_Release(sink->sink); + heap_free(sink); + } }
static void session_start(struct media_session *session, const GUID *time_format, const PROPVARIANT *start_position) @@ -1142,6 +1159,71 @@ static BOOL session_set_source_state(struct media_session *session, IMFMediaSour return ret; }
+static HRESULT session_set_sinks_clock(struct media_session *session) +{ + IMFTopology *topology = session->presentation.current_topology.topology; + IMFTopologyNode *node; + IMFCollection *nodes; + DWORD count, i; + HRESULT hr; + + if (!list_empty(&session->presentation.sinks)) + return S_OK; + + if (FAILED(hr = IMFTopology_GetOutputNodeCollection(topology, &nodes))) + return hr; + + if (FAILED(hr = IMFCollection_GetElementCount(nodes, &count))) + { + IMFCollection_Release(nodes); + return hr; + } + + for (i = 0; i < count; ++i) + { + IMFStreamSink *stream_sink = NULL; + struct media_sink *sink; + + if (FAILED(hr = IMFCollection_GetElement(nodes, i, (IUnknown **)&node))) + break; + + if (!(sink = heap_alloc_zero(sizeof(*sink)))) + hr = E_OUTOFMEMORY; + + if (SUCCEEDED(hr)) + hr = IMFTopologyNode_GetObject(node, (IUnknown **)&stream_sink); + + if (SUCCEEDED(hr)) + hr = IMFStreamSink_GetMediaSink(stream_sink, &sink->sink); + + if (SUCCEEDED(hr)) + hr = IMFMediaSink_SetPresentationClock(sink->sink, session->clock); + + if (SUCCEEDED(hr)) + hr = IMFStreamSink_BeginGetEvent(stream_sink, &session->events_callback, (IUnknown *)stream_sink); + + if (stream_sink) + IMFStreamSink_Release(stream_sink); + + if (SUCCEEDED(hr)) + { + list_add_tail(&session->presentation.sinks, &sink->entry); + } + else if (sink) + { + if (sink->sink) + IMFMediaSink_Release(sink->sink); + heap_free(sink); + } + + IMFTopologyNode_Release(node); + } + + IMFCollection_Release(nodes); + + return hr; +} + static HRESULT WINAPI session_events_callback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result) { struct media_session *session = impl_from_events_callback_IMFAsyncCallback(iface); @@ -1194,9 +1276,19 @@ static HRESULT WINAPI session_events_callback_Invoke(IMFAsyncCallback *iface, IM
ret = session_set_source_state(session, (IMFMediaSource *)event_source, source_state); if (ret && event_type == MESourceStarted) + { session_set_topo_status(session, &session->presentation.current_topology, S_OK, MF_TOPOSTATUS_STARTED_SOURCE);
+ if (session->state == SESSION_STATE_STARTING) + { + if (SUCCEEDED(session_set_sinks_clock(session))) + { + session->state = SESSION_STATE_RUNNING; + } + } + } + LeaveCriticalSection(&session->cs); break; case MENewStream: @@ -1371,6 +1463,7 @@ HRESULT WINAPI MFCreateMediaSession(IMFAttributes *config, IMFMediaSession **ses object->refcount = 1; list_init(&object->topologies); list_init(&object->presentation.sources); + list_init(&object->presentation.sinks); InitializeCriticalSection(&object->cs);
if (FAILED(hr = MFCreateEventQueue(&object->event_queue)))
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mf/session.c | 3 +++ dlls/mf/tests/mf.c | 21 +++++++++++++++++---- 2 files changed, 20 insertions(+), 4 deletions(-)
diff --git a/dlls/mf/session.c b/dlls/mf/session.c index bf1e48aaf7..a3c0ee717f 100644 --- a/dlls/mf/session.c +++ b/dlls/mf/session.c @@ -1923,6 +1923,9 @@ static HRESULT clock_change_state(struct presentation_clock *clock, enum clock_c MFTIME system_time; HRESULT hr;
+ if (!clock->time_source) + return MF_E_CLOCK_NO_TIME_SOURCE; + if (command != CLOCK_CMD_SET_RATE && clock->state == states[command] && clock->state != MFCLOCK_STATE_RUNNING) return MF_E_CLOCK_STATE_ALREADY_SET;
diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index b221398a71..e118c36ec7 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -1501,6 +1501,9 @@ static void test_presentation_clock(void) hr = MFCreatePresentationClock(&clock); ok(hr == S_OK, "Failed to create presentation clock, 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); + hr = IMFPresentationClock_GetTimeSource(clock, &time_source); ok(hr == MF_E_CLOCK_NO_TIME_SOURCE, "Unexpected hr %#x.\n", hr);
@@ -1521,7 +1524,7 @@ static void test_presentation_clock(void)
value = 1; hr = IMFPresentationClock_GetContinuityKey(clock, &value); - ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(hr == S_OK, "Failed to get continuity key, hr %#x.\n", hr); ok(value == 0, "Unexpected value %u.\n", value);
hr = IMFPresentationClock_GetProperties(clock, &props); @@ -1559,6 +1562,19 @@ static void test_presentation_clock(void) hr = IMFPresentationClock_RemoveClockStateSink(clock, &test_sink); ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+ /* State change commands, time source is not set yet. */ + hr = IMFPresentationClock_Start(clock, 0); + ok(hr == MF_E_CLOCK_NO_TIME_SOURCE, "Unexpected hr %#x.\n", hr); + + hr = IMFPresentationClock_Pause(clock); + ok(hr == MF_E_CLOCK_NO_TIME_SOURCE, "Unexpected hr %#x.\n", hr); + + hr = IMFPresentationClock_Stop(clock); + ok(hr == MF_E_CLOCK_NO_TIME_SOURCE, "Unexpected hr %#x.\n", hr); + + hr = IMFRateControl_SetRate(rate_control, FALSE, 0.0f); + ok(hr == MF_E_CLOCK_NO_TIME_SOURCE, "Unexpected hr %#x.\n", hr); + /* Set default time source. */ hr = MFCreateSystemTimeSource(&time_source); ok(hr == S_OK, "Failed to create time source, hr %#x.\n", hr); @@ -1631,9 +1647,6 @@ static void test_presentation_clock(void)
IMFPresentationTimeSource_Release(time_source);
- hr = IMFPresentationClock_QueryInterface(clock, &IID_IMFRateControl, (void **)&rate_control); - ok(hr == S_OK, "Failed to get rate control interface, hr %#x.\n", hr); - hr = IMFRateControl_GetRate(rate_control, NULL, &rate); ok(hr == S_OK, "Failed to get clock rate, hr %#x.\n", hr);
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=57429
Your paranoid android.
=== wvistau64_zh_CN (32 bit report) ===
mf: mf.c:917: Test failed: Unexpected hr 0xc00d36da. mf.c:921: Test failed: Unexpected hr 0. mf.c:937: Test failed: Unexpected return value 0x102.
=== wvistau64_he (32 bit report) ===
mf: mf.c:917: Test failed: Unexpected hr 0xc00d36da. mf.c:921: Test failed: Unexpected hr 0. mf.c:937: Test failed: Unexpected return value 0x102.
=== w7u (32 bit report) ===
mf: mf.c:917: Test failed: Unexpected hr 0xc00d36da.
=== w8 (32 bit report) ===
mf: mf.c:921: Test failed: Unexpected hr 0. mf.c:937: Test failed: Unexpected return value 0x102.
=== w1064v1507 (32 bit report) ===
mf: mf.c:917: Test failed: Unexpected hr 0xc00d36da. mf.c:937: Test failed: Unexpected return value 0x102.
These are existing failures.