[PATCH v2 0/1] MR10092: mf: Drop events and end draining on MFT flush.
I unfortunately couldn't come up with a great way to test this, so it comes without a test. But I found issues when one stream finished before another. If a seek took place prior to completion of the second stream, then it would usually result in the stream that did finish delivering all its queued END_OF_STREAM markers even after the seek. This MR looks to clear that queue when the MFT is flushed (as presumably, any pending input or output samples are no longer wanted on a flush). This MR also clears the draining flag on a flush. As I also ran in to an issue where this flag was set during a seek and remained set afterwards. But after a flush, there should be nothing left to drain. -- v2: mf: Drop events and end draining on MFT flush. https://gitlab.winehq.org/wine/wine/-/merge_requests/10092
From: Brendan McGrath <bmcgrath@codeweavers.com> --- dlls/mf/session.c | 41 ++++++++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/dlls/mf/session.c b/dlls/mf/session.c index 1f23bf51592..28195f914b0 100644 --- a/dlls/mf/session.c +++ b/dlls/mf/session.c @@ -1039,22 +1039,39 @@ static void session_subscribe_sinks(struct media_session *session) session->presentation.flags |= SESSION_FLAG_SINKS_SUBSCRIBED; } -static void session_flush_transforms(struct media_session *session) +static void session_flush_transform_node(struct topo_node *node) { - struct topo_node *node; + struct transform_stream *stream; UINT i; - LIST_FOR_EACH_ENTRY(node, &session->presentation.nodes, struct topo_node, entry) + if (node->type == MF_TOPOLOGY_TRANSFORM_NODE) { - if (node->type == MF_TOPOLOGY_TRANSFORM_NODE) + for (i = 0; i < node->u.transform.input_count; ++i) + { + stream = &node->u.transform.inputs[i]; + transform_stream_drop_events(stream); + stream->draining = FALSE; /* we're about to flush, so draining can halt */ + } + IMFTransform_ProcessMessage(node->object.transform, MFT_MESSAGE_COMMAND_FLUSH, 0); + for (i = 0; i < node->u.transform.output_count; i++) { - IMFTransform_ProcessMessage(node->object.transform, MFT_MESSAGE_COMMAND_FLUSH, 0); - for (i = 0; i < node->u.transform.output_count; i++) - node->u.transform.outputs[i].requests = 0; /* these requests might have been flushed */ + stream = &node->u.transform.outputs[i]; + transform_stream_drop_events(stream); + stream->requests = 0; /* these requests might have been flushed */ } } } +static void session_flush_transforms(struct media_session *session) +{ + struct topo_node *node; + + LIST_FOR_EACH_ENTRY(node, &session->presentation.nodes, struct topo_node, entry) + { + session_flush_transform_node(node); + } +} + static void session_request_sample(struct media_session *session, IMFStreamSink *sink_stream); static void session_flush_sinks(struct media_session *session) @@ -1078,19 +1095,13 @@ static void session_flush_sinks(struct media_session *session) static void session_flush_nodes(struct media_session *session) { struct topo_node *node; - UINT i; LIST_FOR_EACH_ENTRY(node, &session->presentation.nodes, struct topo_node, entry) { if (node->type == MF_TOPOLOGY_OUTPUT_NODE) IMFStreamSink_Flush(node->object.sink_stream); - else if (node->type == MF_TOPOLOGY_TRANSFORM_NODE) - { - for (i = 0; i < node->u.transform.output_count; ++i) - node->u.transform.outputs[i].requests = 0; - - IMFTransform_ProcessMessage(node->object.transform, MFT_MESSAGE_COMMAND_FLUSH, 0); - } + else + session_flush_transform_node(node); } } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10092
v2: - remove unused `UINT i` in `session_flush_nodes` -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10092#note_129569
I can't really tell how accurate this is, but I don't see a problem with dropping events (especially since we don't produce any, I think). -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10092#note_130244
This merge request was approved by Nikolay Sivov. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10092
participants (3)
-
Brendan McGrath -
Brendan McGrath (@redmcg) -
Nikolay Sivov (@nsivov)