From: Rémi Bernon rbernon@codeweavers.com
--- dlls/mf/session.c | 44 +++++++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 21 deletions(-)
diff --git a/dlls/mf/session.c b/dlls/mf/session.c index 254fea6dfe4..81198349f66 100644 --- a/dlls/mf/session.c +++ b/dlls/mf/session.c @@ -155,6 +155,7 @@ struct transform_stream struct list samples; unsigned int requests; unsigned int min_buffer_size; + BOOL stream_ended; };
enum topo_node_flags @@ -3151,11 +3152,23 @@ static HRESULT transform_node_pull_samples(const struct media_session *session, return hr; }
+static BOOL transform_node_all_streams_ended(struct topo_node *topo_node) +{ + UINT i; + + for (i = 0; i < topo_node->u.transform.input_count; i++) + if (!topo_node->u.transform.inputs[i].stream_ended) + return FALSE; + + return TRUE; +} + static void session_deliver_sample_to_node(struct media_session *session, IMFTopologyNode *node, unsigned int input, IMFSample *sample);
static void transform_node_deliver_samples(struct media_session *session, struct topo_node *topo_node) { + BOOL draining = transform_node_all_streams_ended(topo_node); IMFTopologyNode *up_node = topo_node->node, *down_node; struct sample *sample, *next; DWORD output, input; @@ -3183,6 +3196,12 @@ static void transform_node_deliver_samples(struct media_session *session, struct transform_release_sample(sample); }
+ while (stream->requests && draining) + { + session_deliver_sample_to_node(session, down_node, input, NULL); + stream->requests--; + } + IMFTopologyNode_Release(down_node); } } @@ -3194,7 +3213,6 @@ static void session_deliver_sample_to_node(struct media_session *session, IMFTop DWORD stream_id; struct topo_node *topo_node; MF_TOPOLOGY_TYPE node_type; - BOOL drain = FALSE; TOPOID node_id; unsigned int i; HRESULT hr; @@ -3242,7 +3260,9 @@ static void session_deliver_sample_to_node(struct media_session *session, IMFTop
LIST_FOR_EACH_ENTRY_SAFE(sample_entry, sample_entry2, &stream->samples, struct sample, entry) { - if (sample_entry->sample) + if ((stream->stream_ended = !sample_entry->sample)) + transform_stream_drop_samples(stream); + else { if ((hr = IMFTransform_ProcessInput(topo_node->object.transform, stream_id, sample_entry->sample, 0)) == MF_E_NOTACCEPTING) @@ -3251,34 +3271,16 @@ static void session_deliver_sample_to_node(struct media_session *session, IMFTop WARN("Failed to process input for stream %u/%lu, hr %#lx.\n", i, stream_id, hr); transform_release_sample(sample_entry); } - else - { - transform_stream_drop_samples(stream); - drain = TRUE; - } } }
- if (drain) + if (transform_node_all_streams_ended(topo_node)) { if (FAILED(hr = IMFTransform_ProcessMessage(topo_node->object.transform, MFT_MESSAGE_COMMAND_DRAIN, 0))) WARN("Drain command failed for transform, hr %#lx.\n", hr); }
transform_node_pull_samples(session, topo_node); - - /* Remaining unprocessed input has been discarded, now queue markers for every output. */ - if (drain) - { - for (i = 0; i < topo_node->u.transform.output_count; ++i) - { - struct transform_stream *stream = &topo_node->u.transform.outputs[i]; - - if ((sample_entry = transform_create_sample(NULL))) - list_add_tail(&stream->samples, &sample_entry->entry); - } - } - transform_node_deliver_samples(session, topo_node); break; }