Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/winegstreamer/media_source.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c index 85ec31d2498..9a77cf72c07 100644 --- a/dlls/winegstreamer/media_source.c +++ b/dlls/winegstreamer/media_source.c @@ -1109,6 +1109,8 @@ static ULONG WINAPI media_source_rate_control_Release(IMFRateControl *iface)
static HRESULT WINAPI media_source_rate_control_SetRate(IMFRateControl *iface, BOOL thin, float rate) { + struct media_source *source = impl_from_IMFRateControl(iface); + FIXME("%p, %d, %f.\n", iface, thin, rate);
if (rate < 0.0f) @@ -1120,7 +1122,7 @@ static HRESULT WINAPI media_source_rate_control_SetRate(IMFRateControl *iface, B if (rate != 1.0f) return MF_E_UNSUPPORTED_RATE;
- return S_OK; + return IMFMediaEventQueue_QueueEventParamVar(source->event_queue, MESourceRateChanged, &GUID_NULL, S_OK, NULL); }
static HRESULT WINAPI media_source_rate_control_GetRate(IMFRateControl *iface, BOOL *thin, float *rate)
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mf/session.c | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-)
diff --git a/dlls/mf/session.c b/dlls/mf/session.c index c2a626e654b..9503f72ac51 100644 --- a/dlls/mf/session.c +++ b/dlls/mf/session.c @@ -77,7 +77,7 @@ struct session_op { TOPOID node_id; } sa_ready; - } u; + }; struct list entry; };
@@ -397,15 +397,15 @@ static ULONG WINAPI session_op_Release(IUnknown *iface) switch (op->command) { case SESSION_CMD_SET_TOPOLOGY: - if (op->u.set_topology.topology) - IMFTopology_Release(op->u.set_topology.topology); + if (op->set_topology.topology) + IMFTopology_Release(op->set_topology.topology); break; case SESSION_CMD_START: - PropVariantClear(&op->u.start.start_position); + PropVariantClear(&op->start.start_position); break; case SESSION_CMD_QM_NOTIFY_TOPOLOGY: - if (op->u.notify_topology.topology) - IMFTopology_Release(op->u.notify_topology.topology); + if (op->notify_topology.topology) + IMFTopology_Release(op->notify_topology.topology); break; default: ; @@ -1295,7 +1295,7 @@ static HRESULT WINAPI node_sample_allocator_cb_NotifyRelease(IMFVideoSampleAlloc
if (SUCCEEDED(create_session_op(SESSION_CMD_SA_READY, &op))) { - op->u.sa_ready.node_id = topo_node->node_id; + op->sa_ready.node_id = topo_node->node_id; MFPutWorkItem(MFASYNC_CALLBACK_QUEUE_STANDARD, &topo_node->session->commands_callback, &op->IUnknown_iface); IUnknown_Release(&op->IUnknown_iface); } @@ -1460,8 +1460,8 @@ static HRESULT session_set_current_topology(struct media_session *session, IMFTo { if (SUCCEEDED(create_session_op(SESSION_CMD_QM_NOTIFY_TOPOLOGY, &op))) { - op->u.notify_topology.topology = topology; - IMFTopology_AddRef(op->u.notify_topology.topology); + op->notify_topology.topology = topology; + IMFTopology_AddRef(op->notify_topology.topology); session_submit_command(session, op); IUnknown_Release(&op->IUnknown_iface); } @@ -1742,10 +1742,10 @@ static HRESULT WINAPI mfsession_SetTopology(IMFMediaSession *iface, DWORD flags, if (FAILED(hr = create_session_op(SESSION_CMD_SET_TOPOLOGY, &op))) return hr;
- op->u.set_topology.flags = flags; - op->u.set_topology.topology = topology; - if (op->u.set_topology.topology) - IMFTopology_AddRef(op->u.set_topology.topology); + op->set_topology.flags = flags; + op->set_topology.topology = topology; + if (op->set_topology.topology) + IMFTopology_AddRef(op->set_topology.topology);
hr = session_submit_command(session, op); IUnknown_Release(&op->IUnknown_iface); @@ -1776,8 +1776,8 @@ static HRESULT WINAPI mfsession_Start(IMFMediaSession *iface, const GUID *format if (FAILED(hr = create_session_op(SESSION_CMD_START, &op))) return hr;
- op->u.start.time_format = format ? *format : GUID_NULL; - hr = PropVariantCopy(&op->u.start.start_position, start_position); + op->start.time_format = format ? *format : GUID_NULL; + hr = PropVariantCopy(&op->start.start_position, start_position);
if (SUCCEEDED(hr)) hr = session_submit_command(session, op); @@ -2144,11 +2144,11 @@ static HRESULT WINAPI session_commands_callback_Invoke(IMFAsyncCallback *iface, session_clear_topologies(session); break; case SESSION_CMD_SET_TOPOLOGY: - session_set_topology(session, op->u.set_topology.flags, op->u.set_topology.topology); + session_set_topology(session, op->set_topology.flags, op->set_topology.topology); session_command_complete(session); break; case SESSION_CMD_START: - session_start(session, &op->u.start.time_format, &op->u.start.start_position); + session_start(session, &op->start.time_format, &op->start.start_position); break; case SESSION_CMD_PAUSE: session_pause(session); @@ -2160,11 +2160,11 @@ static HRESULT WINAPI session_commands_callback_Invoke(IMFAsyncCallback *iface, session_close(session); break; case SESSION_CMD_QM_NOTIFY_TOPOLOGY: - IMFQualityManager_NotifyTopology(session->quality_manager, op->u.notify_topology.topology); + IMFQualityManager_NotifyTopology(session->quality_manager, op->notify_topology.topology); session_command_complete(session); break; case SESSION_CMD_SA_READY: - topo_node = session_get_node_by_id(session, op->u.sa_ready.node_id); + topo_node = session_get_node_by_id(session, op->sa_ready.node_id);
if (topo_node->u.sink.requests) {
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mf/session.c | 458 ++++++++++++++++++++++++++++----------------- dlls/mf/tests/mf.c | 2 - 2 files changed, 283 insertions(+), 177 deletions(-)
diff --git a/dlls/mf/session.c b/dlls/mf/session.c index 9503f72ac51..e4a54b1c6de 100644 --- a/dlls/mf/session.c +++ b/dlls/mf/session.c @@ -46,6 +46,7 @@ enum session_command SESSION_CMD_START, SESSION_CMD_PAUSE, SESSION_CMD_STOP, + SESSION_CMD_SET_RATE, /* Internally used commands. */ SESSION_CMD_END, SESSION_CMD_QM_NOTIFY_TOPOLOGY, @@ -70,6 +71,11 @@ struct session_op PROPVARIANT start_position; } start; struct + { + BOOL thin; + float rate; + } set_rate; + struct { IMFTopology *topology; } notify_topology; @@ -214,6 +220,7 @@ enum presentation_flags SESSION_FLAG_FINALIZE_SINKS = 0x4, SESSION_FLAG_NEEDS_PREROLL = 0x8, SESSION_FLAG_END_OF_PRESENTATION = 0x10, + SESSION_FLAG_PENDING_RATE_CHANGE = 0x20, };
struct media_session @@ -246,6 +253,9 @@ struct media_session /* Latest Start() arguments. */ GUID time_format; PROPVARIANT start_position; + /* Latest SetRate() arguments. */ + BOOL thin; + float rate; } presentation; struct list topologies; struct list commands; @@ -813,6 +823,26 @@ static void session_command_complete_with_event(struct media_session *session, M session_command_complete(session); }
+static void session_subscribe_sources(struct media_session *session) +{ + struct media_source *source; + HRESULT hr; + + if (session->presentation.flags & SESSION_FLAG_SOURCES_SUBSCRIBED) + return; + + LIST_FOR_EACH_ENTRY(source, &session->presentation.sources, struct media_source, entry) + { + if (FAILED(hr = IMFMediaSource_BeginGetEvent(source->source, &session->events_callback, + source->object))) + { + WARN("Failed to subscribe to source events, hr %#lx.\n", hr); + } + } + + session->presentation.flags |= SESSION_FLAG_SOURCES_SUBSCRIBED; +} + static void session_start(struct media_session *session, const GUID *time_format, const PROPVARIANT *start_position) { struct media_source *source; @@ -836,22 +866,14 @@ static void session_start(struct media_session *session, const GUID *time_format session->presentation.start_position.vt = VT_EMPTY; PropVariantCopy(&session->presentation.start_position, start_position);
+ session_subscribe_sources(session); + LIST_FOR_EACH_ENTRY(source, &session->presentation.sources, struct media_source, entry) { - if (!(session->presentation.flags & SESSION_FLAG_SOURCES_SUBSCRIBED)) - { - if (FAILED(hr = IMFMediaSource_BeginGetEvent(source->source, &session->events_callback, - source->object))) - { - WARN("Failed to subscribe to source events, hr %#lx.\n", hr); - } - } - if (FAILED(hr = IMFMediaSource_Start(source->source, source->pd, &GUID_NULL, start_position))) WARN("Failed to start media source %p, hr %#lx.\n", source->source, hr); }
- session->presentation.flags |= SESSION_FLAG_SOURCES_SUBSCRIBED; session->state = SESSION_STATE_STARTING_SOURCES; break; case SESSION_STATE_STARTED: @@ -1072,6 +1094,227 @@ static void session_clear_topologies(struct media_session *session) session_command_complete_with_event(session, MESessionTopologiesCleared, hr, NULL); }
+static HRESULT session_is_presentation_rate_supported(struct media_session *session, BOOL thin, float rate, + float *nearest_rate) +{ + IMFRateSupport *rate_support; + struct media_source *source; + struct media_sink *sink; + float value = 0.0f, tmp; + HRESULT hr = S_OK; + DWORD flags; + + if (!nearest_rate) nearest_rate = &tmp; + + if (rate == 0.0f) + { + *nearest_rate = 1.0f; + return S_OK; + } + + if (session->presentation.topo_status != MF_TOPOSTATUS_INVALID) + { + LIST_FOR_EACH_ENTRY(source, &session->presentation.sources, struct media_source, entry) + { + if (FAILED(hr = MFGetService(source->object, &MF_RATE_CONTROL_SERVICE, &IID_IMFRateSupport, + (void **)&rate_support))) + { + value = 1.0f; + break; + } + + value = rate; + if (FAILED(hr = IMFRateSupport_IsRateSupported(rate_support, thin, rate, &value))) + WARN("Source does not support rate %f, hr %#lx.\n", rate, hr); + IMFRateSupport_Release(rate_support); + + /* Only "first" source is considered. */ + break; + } + + if (SUCCEEDED(hr)) + { + /* For sinks only check if rate is supported, ignoring nearest values. */ + LIST_FOR_EACH_ENTRY(sink, &session->presentation.sinks, struct media_sink, entry) + { + flags = 0; + if (FAILED(hr = IMFMediaSink_GetCharacteristics(sink->sink, &flags))) + break; + + if (flags & MEDIASINK_RATELESS) + continue; + + if (FAILED(MFGetService(sink->object, &MF_RATE_CONTROL_SERVICE, &IID_IMFRateSupport, + (void **)&rate_support))) + continue; + + hr = IMFRateSupport_IsRateSupported(rate_support, thin, rate, NULL); + IMFRateSupport_Release(rate_support); + if (FAILED(hr)) + { + WARN("Sink %p does not support rate %f, hr %#lx.\n", sink->sink, rate, hr); + break; + } + } + } + } + + *nearest_rate = value; + + return hr; +} + +static void session_set_consumed_clock(IUnknown *object, IMFPresentationClock *clock) +{ + IMFClockConsumer *consumer; + + if (SUCCEEDED(IUnknown_QueryInterface(object, &IID_IMFClockConsumer, (void **)&consumer))) + { + IMFClockConsumer_SetPresentationClock(consumer, clock); + IMFClockConsumer_Release(consumer); + } +} + +static void session_set_presentation_clock(struct media_session *session) +{ + IMFPresentationTimeSource *time_source = NULL; + struct media_source *source; + struct media_sink *sink; + struct topo_node *node; + HRESULT hr; + + LIST_FOR_EACH_ENTRY(node, &session->presentation.nodes, struct topo_node, entry) + { + if (node->type == MF_TOPOLOGY_TRANSFORM_NODE) + IMFTransform_ProcessMessage(node->object.transform, MFT_MESSAGE_NOTIFY_START_OF_STREAM, 0); + } + + if (!(session->presentation.flags & SESSION_FLAG_PRESENTATION_CLOCK_SET)) + { + /* Attempt to get time source from the sinks. */ + LIST_FOR_EACH_ENTRY(sink, &session->presentation.sinks, struct media_sink, entry) + { + if (SUCCEEDED(IMFMediaSink_QueryInterface(sink->sink, &IID_IMFPresentationTimeSource, + (void **)&time_source))) + break; + } + + if (time_source) + { + hr = IMFPresentationClock_SetTimeSource(session->clock, time_source); + IMFPresentationTimeSource_Release(time_source); + } + else + hr = IMFPresentationClock_SetTimeSource(session->clock, session->system_time_source); + + if (FAILED(hr)) + WARN("Failed to set time source, hr %#lx.\n", hr); + + LIST_FOR_EACH_ENTRY(node, &session->presentation.nodes, struct topo_node, entry) + { + if (node->type != MF_TOPOLOGY_OUTPUT_NODE) + continue; + + if (FAILED(hr = IMFStreamSink_BeginGetEvent(node->object.sink_stream, &session->events_callback, + node->object.object))) + { + WARN("Failed to subscribe to stream sink events, hr %#lx.\n", hr); + } + } + + /* Set clock for all topology nodes. */ + LIST_FOR_EACH_ENTRY(source, &session->presentation.sources, struct media_source, entry) + { + session_set_consumed_clock(source->object, session->clock); + } + + LIST_FOR_EACH_ENTRY(sink, &session->presentation.sinks, struct media_sink, entry) + { + if (sink->event_generator && FAILED(hr = IMFMediaEventGenerator_BeginGetEvent(sink->event_generator, + &session->events_callback, (IUnknown *)sink->event_generator))) + { + WARN("Failed to subscribe to sink events, hr %#lx.\n", hr); + } + + if (FAILED(hr = IMFMediaSink_SetPresentationClock(sink->sink, session->clock))) + WARN("Failed to set presentation clock for the sink, hr %#lx.\n", hr); + } + + LIST_FOR_EACH_ENTRY(node, &session->presentation.nodes, struct topo_node, entry) + { + if (node->type != MF_TOPOLOGY_TRANSFORM_NODE) + continue; + + session_set_consumed_clock(node->object.object, session->clock); + } + + session->presentation.flags |= SESSION_FLAG_PRESENTATION_CLOCK_SET; + } +} + +static void session_set_rate(struct media_session *session, BOOL thin, float rate) +{ + IMFRateControl *rate_control; + struct media_source *source; + float clock_rate = 0.0f; + PROPVARIANT param; + HRESULT hr; + + hr = session_is_presentation_rate_supported(session, thin, rate, NULL); + + if (SUCCEEDED(hr)) + hr = IMFRateControl_GetRate(session->clock_rate_control, NULL, &clock_rate); + + if (SUCCEEDED(hr) && (rate != clock_rate)) + { + session_subscribe_sources(session); + + LIST_FOR_EACH_ENTRY(source, &session->presentation.sources, struct media_source, entry) + { + if (SUCCEEDED(hr = MFGetService(source->object, &MF_RATE_CONTROL_SERVICE, &IID_IMFRateControl, + (void **)&rate_control))) + { + hr = IMFRateControl_SetRate(rate_control, thin, rate); + IMFRateControl_Release(rate_control); + if (SUCCEEDED(hr)) + { + session->presentation.flags |= SESSION_FLAG_PENDING_RATE_CHANGE; + session->presentation.rate = rate; + return; + } + } + + break; + } + } + + param.vt = VT_R4; + param.fltVal = rate; + session_command_complete_with_event(session, MESessionRateChanged, hr, SUCCEEDED(hr) ? ¶m : NULL); +} + +static void session_complete_rate_change(struct media_session *session) +{ + PROPVARIANT param; + HRESULT hr; + + if (!(session->presentation.flags & SESSION_FLAG_PENDING_RATE_CHANGE)) + return; + + session->presentation.flags &= ~SESSION_FLAG_PENDING_RATE_CHANGE; + session_set_presentation_clock(session); + + hr = IMFRateControl_SetRate(session->clock_rate_control, session->presentation.thin, + session->presentation.rate); + + param.vt = VT_R4; + param.fltVal = session->presentation.rate; + + IMFMediaEventQueue_QueueEventParamVar(session->event_queue, MESessionRateChanged, &GUID_NULL, hr, + SUCCEEDED(hr) ? ¶m : NULL); + session_command_complete(session); +} + static struct media_source *session_get_media_source(struct media_session *session, IMFMediaSource *source) { struct media_source *cur; @@ -2175,6 +2418,9 @@ static HRESULT WINAPI session_commands_callback_Invoke(IMFAsyncCallback *iface, } } break; + case SESSION_CMD_SET_RATE: + session_set_rate(session, op->set_rate.thin, op->set_rate.rate); + break; default: ; } @@ -2318,94 +2564,6 @@ static enum object_state session_get_object_state_for_event(MediaEventType event } }
-static void session_set_consumed_clock(IUnknown *object, IMFPresentationClock *clock) -{ - IMFClockConsumer *consumer; - - if (SUCCEEDED(IUnknown_QueryInterface(object, &IID_IMFClockConsumer, (void **)&consumer))) - { - IMFClockConsumer_SetPresentationClock(consumer, clock); - IMFClockConsumer_Release(consumer); - } -} - -static void session_set_presentation_clock(struct media_session *session) -{ - IMFPresentationTimeSource *time_source = NULL; - struct media_source *source; - struct media_sink *sink; - struct topo_node *node; - HRESULT hr; - - LIST_FOR_EACH_ENTRY(node, &session->presentation.nodes, struct topo_node, entry) - { - if (node->type == MF_TOPOLOGY_TRANSFORM_NODE) - IMFTransform_ProcessMessage(node->object.transform, MFT_MESSAGE_NOTIFY_START_OF_STREAM, 0); - } - - if (!(session->presentation.flags & SESSION_FLAG_PRESENTATION_CLOCK_SET)) - { - /* Attempt to get time source from the sinks. */ - LIST_FOR_EACH_ENTRY(sink, &session->presentation.sinks, struct media_sink, entry) - { - if (SUCCEEDED(IMFMediaSink_QueryInterface(sink->sink, &IID_IMFPresentationTimeSource, - (void **)&time_source))) - break; - } - - if (time_source) - { - hr = IMFPresentationClock_SetTimeSource(session->clock, time_source); - IMFPresentationTimeSource_Release(time_source); - } - else - hr = IMFPresentationClock_SetTimeSource(session->clock, session->system_time_source); - - if (FAILED(hr)) - WARN("Failed to set time source, hr %#lx.\n", hr); - - LIST_FOR_EACH_ENTRY(node, &session->presentation.nodes, struct topo_node, entry) - { - if (node->type != MF_TOPOLOGY_OUTPUT_NODE) - continue; - - if (FAILED(hr = IMFStreamSink_BeginGetEvent(node->object.sink_stream, &session->events_callback, - node->object.object))) - { - WARN("Failed to subscribe to stream sink events, hr %#lx.\n", hr); - } - } - - /* Set clock for all topology nodes. */ - LIST_FOR_EACH_ENTRY(source, &session->presentation.sources, struct media_source, entry) - { - session_set_consumed_clock(source->object, session->clock); - } - - LIST_FOR_EACH_ENTRY(sink, &session->presentation.sinks, struct media_sink, entry) - { - if (sink->event_generator && FAILED(hr = IMFMediaEventGenerator_BeginGetEvent(sink->event_generator, - &session->events_callback, (IUnknown *)sink->event_generator))) - { - WARN("Failed to subscribe to sink events, hr %#lx.\n", hr); - } - - if (FAILED(hr = IMFMediaSink_SetPresentationClock(sink->sink, session->clock))) - WARN("Failed to set presentation clock for the sink, hr %#lx.\n", hr); - } - - LIST_FOR_EACH_ENTRY(node, &session->presentation.nodes, struct topo_node, entry) - { - if (node->type != MF_TOPOLOGY_TRANSFORM_NODE) - continue; - - session_set_consumed_clock(node->object.object, session->clock); - } - - session->presentation.flags |= SESSION_FLAG_PRESENTATION_CLOCK_SET; - } -} - static HRESULT session_start_clock(struct media_session *session) { LONGLONG start_offset = 0; @@ -3195,6 +3353,14 @@ static HRESULT WINAPI session_events_callback_Invoke(IMFAsyncCallback *iface, IM
break;
+ case MESourceRateChanged: + + EnterCriticalSection(&session->cs); + session_complete_rate_change(session); + LeaveCriticalSection(&session->cs); + + break; + case MEBufferingStarted: case MEBufferingStopped:
@@ -3541,80 +3707,6 @@ static HRESULT session_get_presentation_rate(struct media_session *session, MFRA return hr; }
-static HRESULT session_is_presentation_rate_supported(struct media_session *session, BOOL thin, float rate, - float *nearest_rate) -{ - IMFRateSupport *rate_support; - struct media_source *source; - struct media_sink *sink; - float value = 0.0f, tmp; - HRESULT hr = S_OK; - DWORD flags; - - if (!nearest_rate) nearest_rate = &tmp; - - if (rate == 0.0f) - { - *nearest_rate = 1.0f; - return S_OK; - } - - EnterCriticalSection(&session->cs); - - if (session->presentation.topo_status != MF_TOPOSTATUS_INVALID) - { - LIST_FOR_EACH_ENTRY(source, &session->presentation.sources, struct media_source, entry) - { - if (FAILED(hr = MFGetService(source->object, &MF_RATE_CONTROL_SERVICE, &IID_IMFRateSupport, - (void **)&rate_support))) - { - value = 1.0f; - break; - } - - value = rate; - if (FAILED(hr = IMFRateSupport_IsRateSupported(rate_support, thin, rate, &value))) - WARN("Source does not support rate %f, hr %#lx.\n", rate, hr); - IMFRateSupport_Release(rate_support); - - /* Only "first" source is considered. */ - break; - } - - if (SUCCEEDED(hr)) - { - /* For sinks only check if rate is supported, ignoring nearest values. */ - LIST_FOR_EACH_ENTRY(sink, &session->presentation.sinks, struct media_sink, entry) - { - flags = 0; - if (FAILED(hr = IMFMediaSink_GetCharacteristics(sink->sink, &flags))) - break; - - if (flags & MEDIASINK_RATELESS) - continue; - - if (FAILED(MFGetService(sink->object, &MF_RATE_CONTROL_SERVICE, &IID_IMFRateSupport, - (void **)&rate_support))) - continue; - - hr = IMFRateSupport_IsRateSupported(rate_support, thin, rate, NULL); - IMFRateSupport_Release(rate_support); - if (FAILED(hr)) - { - WARN("Sink %p does not support rate %f, hr %#lx.\n", sink->sink, rate, hr); - break; - } - } - } - } - - LeaveCriticalSection(&session->cs); - - *nearest_rate = value; - - return hr; -} - static HRESULT WINAPI session_rate_support_GetSlowestRate(IMFRateSupport *iface, MFRATE_DIRECTION direction, BOOL thin, float *rate) { @@ -3639,10 +3731,15 @@ static HRESULT WINAPI session_rate_support_IsRateSupported(IMFRateSupport *iface float *nearest_supported_rate) { struct media_session *session = impl_session_from_IMFRateSupport(iface); + HRESULT hr;
TRACE("%p, %d, %f, %p.\n", iface, thin, rate, nearest_supported_rate);
- return session_is_presentation_rate_supported(session, thin, rate, nearest_supported_rate); + EnterCriticalSection(&session->cs); + hr = session_is_presentation_rate_supported(session, thin, rate, nearest_supported_rate); + LeaveCriticalSection(&session->cs); + + return hr; }
static const IMFRateSupportVtbl session_rate_support_vtbl = @@ -3675,9 +3772,20 @@ static ULONG WINAPI session_rate_control_Release(IMFRateControl *iface)
static HRESULT WINAPI session_rate_control_SetRate(IMFRateControl *iface, BOOL thin, float rate) { - FIXME("%p, %d, %f.\n", iface, thin, rate); + struct media_session *session = impl_session_from_IMFRateControl(iface); + struct session_op *op; + HRESULT hr;
- return E_NOTIMPL; + TRACE("%p, %d, %f.\n", iface, thin, rate); + + if (FAILED(hr = create_session_op(SESSION_CMD_SET_RATE, &op))) + return hr; + + op->set_rate.thin = thin; + op->set_rate.rate = rate; + hr = session_submit_command(session, op); + IUnknown_Release(&op->IUnknown_iface); + return hr; }
static HRESULT WINAPI session_rate_control_GetRate(IMFRateControl *iface, BOOL *thin, float *rate) diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index b9e2a3b940f..6bde7568202 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -1401,7 +1401,6 @@ static void test_media_session_rate_control(void) ok(hr == MF_E_CLOCK_NO_TIME_SOURCE, "Unexpected hr %#x.\n", hr);
hr = IMFRateControl_SetRate(rate_control, FALSE, 1.5f); - todo_wine ok(hr == S_OK, "Failed to set rate, hr %#x.\n", hr);
hr = IMFClock_GetProperties(clock, &clock_props); @@ -1414,7 +1413,6 @@ static void test_media_session_rate_control(void) ok(hr == S_OK, "Failed to set time source, hr %#x.\n", hr);
hr = IMFRateControl_SetRate(rate_control, FALSE, 1.5f); - todo_wine ok(hr == S_OK, "Failed to set rate, hr %#x.\n", hr);
rate = 0.0f;
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=108055
Your paranoid android.
=== w8adm (32 bit report) ===
mf: mf.c:4291: Test failed: Unexpected hr 0x800401f0.