[PATCH 0/1] MR8933: mf: Update the stream sink input type when a transform output type changes.
From: Conor McCarthy <cmccarthy(a)codeweavers.com> --- dlls/mf/session.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/dlls/mf/session.c b/dlls/mf/session.c index 87af5b95eab..cfb28ca3646 100644 --- a/dlls/mf/session.c +++ b/dlls/mf/session.c @@ -3450,6 +3450,41 @@ static HRESULT transform_get_external_output_sample(const struct media_session * return hr; } +/* For H.264, the sink's input media type must be set to the aligned frame size before + * the sink receives the first sample. The decoder sends MF_E_TRANSFORM_STREAM_CHANGE + * to trigger a refresh of its output type once the aligned frame size is known. This + * occurs before any call to ProcessOutput() can succeed on the transform. + * Satisfactory is known to use the sink frame size. */ +static void transform_node_update_sink_input(struct topo_node *node, IMFMediaType *output_type) +{ + struct media_session *session = node->session; + IMFMediaTypeHandler *handler; + struct topo_node *down_node; + DWORD i, input; + HRESULT hr; + + for (i = 0; i < node->u.transform.output_count; ++i) + { + if (!(down_node = session_get_topo_node_output(session, node, i, &input))) + { + WARN("Failed to get node %p/%lu output.\n", node, i); + continue; + } + + if (down_node->type == MF_TOPOLOGY_OUTPUT_NODE) + { + if (FAILED(hr = IMFStreamSink_GetMediaTypeHandler(down_node->object.sink_stream, &handler))) + { + WARN("Failed to get type handler, hr %#lx.\n", hr); + continue; + } + if (FAILED(hr = IMFMediaTypeHandler_SetCurrentMediaType(handler, output_type))) + WARN("Failed to set type, hr %#lx.\n", hr); + IMFMediaTypeHandler_Release(handler); + } + } +} + /* update the transform output type while keeping subtype which matches the old output type */ static HRESULT transform_stream_update_output_type(struct topo_node *node, struct transform_stream *stream, UINT id, IMFMediaType *old_output_type, IMFMediaType **new_output_type) @@ -3475,6 +3510,7 @@ static HRESULT transform_stream_update_output_type(struct topo_node *node, struc IMFMediaType_Release(*new_output_type); break; } + transform_node_update_sink_input(node, *new_output_type); return S_OK; } IMFMediaType_Release(*new_output_type); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/8933
This won't fix test failure in !8887 until the media source is changed to emit compressed samples. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/8933#note_115396
The way it works now, if I'm reading this part correctly: MF_E_TRANSFORM_STREAM_CHANGE (happens due to decoder internal logic) -> transform_node_format_changed -> transform_stream_update_output_type + transform_stream_push_format_change -> MEStreamFormatChanged -> session_handle_format_change. Now, session_handle_format_change() then branches depending on destination node type. For output nodes it only cares about re-initializing sample allocator. My point is, shouldn't we amend session_handle_format_change() instead and keep existing flow, instead of fixing up sink types that early? -- https://gitlab.winehq.org/wine/wine/-/merge_requests/8933#note_118524
participants (3)
-
Conor McCarthy -
Conor McCarthy (@cmccarthy) -
Nikolay Sivov (@nsivov)