From: Rémi Bernon rbernon@codeweavers.com
--- dlls/mf/session.c | 102 ++++++++++++++++------------------------------ 1 file changed, 36 insertions(+), 66 deletions(-)
diff --git a/dlls/mf/session.c b/dlls/mf/session.c index 254fea6dfe4..23ac8917e80 100644 --- a/dlls/mf/session.c +++ b/dlls/mf/session.c @@ -196,7 +196,7 @@ struct topo_node } sink; struct { - struct transform_stream *inputs; + BOOL *inputs_eos; DWORD *input_map; unsigned int input_count;
@@ -699,11 +699,9 @@ static void release_topo_node(struct topo_node *node) IMFMediaSource_Release(node->u.source.source); break; case MF_TOPOLOGY_TRANSFORM_NODE: - for (i = 0; i < node->u.transform.input_count; ++i) - transform_stream_drop_samples(&node->u.transform.inputs[i]); for (i = 0; i < node->u.transform.output_count; ++i) transform_stream_drop_samples(&node->u.transform.outputs[i]); - free(node->u.transform.inputs); + free(node->u.transform.inputs_eos); free(node->u.transform.outputs); free(node->u.transform.input_map); free(node->u.transform.output_map); @@ -1513,11 +1511,7 @@ static HRESULT session_set_transform_stream_info(struct topo_node *node) { node->u.transform.input_map = input_map; node->u.transform.output_map = output_map; - - streams = calloc(input_count, sizeof(*streams)); - for (i = 0; i < input_count; ++i) - list_init(&streams[i].samples); - node->u.transform.inputs = streams; + node->u.transform.inputs_eos = calloc(input_count, sizeof(*node->u.transform.inputs_eos)); node->u.transform.input_count = input_count;
streams = calloc(output_count, sizeof(*streams)); @@ -3151,6 +3145,38 @@ static HRESULT transform_node_pull_samples(const struct media_session *session, return hr; }
+static BOOL transform_node_is_end_of_stream(struct topo_node *topo_node) +{ + UINT i; + + for (i = 0; i < topo_node->u.transform.input_count; i++) + if (!topo_node->u.transform.inputs_eos[i]) + return FALSE; + + return TRUE; +} + +static void transform_node_push_sample(const struct media_session *session, struct topo_node *topo_node, + UINT input, IMFSample *sample) +{ + HRESULT hr; + + if ((topo_node->u.transform.inputs_eos[input] = !sample)) + { + if (!transform_node_is_end_of_stream(topo_node)) + return; + + if (FAILED(hr = IMFTransform_ProcessMessage(topo_node->object.transform, MFT_MESSAGE_COMMAND_DRAIN, 0))) + WARN("Drain command failed for transform, hr %#lx.\n", hr); + } + else + { + UINT id = transform_node_get_stream_id(topo_node, FALSE, input); + if (FAILED(hr = IMFTransform_ProcessInput(topo_node->object.transform, id, sample, 0))) + WARN("Failed to process input for stream %u/%u, hr %#lx.\n", input, id, hr); + } +} + static void session_deliver_sample_to_node(struct media_session *session, IMFTopologyNode *node, unsigned int input, IMFSample *sample);
@@ -3190,13 +3216,9 @@ static void transform_node_deliver_samples(struct media_session *session, struct static void session_deliver_sample_to_node(struct media_session *session, IMFTopologyNode *node, unsigned int input, IMFSample *sample) { - struct sample *sample_entry, *sample_entry2; - DWORD stream_id; struct topo_node *topo_node; MF_TOPOLOGY_TYPE node_type; - BOOL drain = FALSE; TOPOID node_id; - unsigned int i; HRESULT hr;
if (session->quality_manager) @@ -3226,62 +3248,10 @@ static void session_deliver_sample_to_node(struct media_session *session, IMFTop } break; case MF_TOPOLOGY_TRANSFORM_NODE: - { - struct transform_stream *input_stream = &topo_node->u.transform.inputs[input]; - - transform_node_pull_samples(session, topo_node); - - sample_entry = transform_create_sample(sample); - list_add_tail(&input_stream->samples, &sample_entry->entry); - - for (i = 0; i < topo_node->u.transform.input_count; ++i) - { - struct transform_stream *stream = &topo_node->u.transform.inputs[i]; - - stream_id = transform_node_get_stream_id(topo_node, FALSE, i); - - LIST_FOR_EACH_ENTRY_SAFE(sample_entry, sample_entry2, &stream->samples, struct sample, entry) - { - if (sample_entry->sample) - { - if ((hr = IMFTransform_ProcessInput(topo_node->object.transform, stream_id, - sample_entry->sample, 0)) == MF_E_NOTACCEPTING) - break; - if (FAILED(hr)) - 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 (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_push_sample(session, topo_node, input, sample); 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; - } case MF_TOPOLOGY_TEE_NODE: FIXME("Unhandled downstream node type %d.\n", node_type); break;