 
            From: Conor McCarthy cmccarthy@codeweavers.com
--- dlls/mf/session.c | 35 ++++++++++++++++++++++++++++++----- 1 file changed, 30 insertions(+), 5 deletions(-)
diff --git a/dlls/mf/session.c b/dlls/mf/session.c index abc77d9f143..a06f106f4dc 100644 --- a/dlls/mf/session.c +++ b/dlls/mf/session.c @@ -3765,18 +3765,43 @@ static HRESULT transform_node_handle_format_change(struct media_session *session return transform_stream_update_input_type(topo_node, input, media_type); }
+/* For H.264, the sink's input media type must be set to the aligned frame size + * before MESessionStarted is sent. 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 HRESULT sink_node_update_input_type(struct topo_node *topo_node, IMFMediaType *media_type) +{ + IMFMediaTypeHandler *handler; + HRESULT hr; + + if (FAILED(hr = IMFStreamSink_GetMediaTypeHandler(topo_node->object.sink_stream, &handler))) + { + WARN("Failed to get type handler, hr %#lx.\n", hr); + return hr; + } + if (FAILED(hr = IMFMediaTypeHandler_SetCurrentMediaType(handler, media_type))) + WARN("Failed to set type, hr %#lx.\n", hr); + IMFMediaTypeHandler_Release(handler); + + return hr; +} + static HRESULT session_handle_format_change(struct media_session *session, struct topo_node *topo_node, UINT input, IMFMediaType *media_type) { - HRESULT hr; + HRESULT hr = S_OK;
switch (topo_node->type) { case MF_TOPOLOGY_OUTPUT_NODE: - if (!topo_node->u.sink.allocator) - return S_OK; - if (SUCCEEDED(hr = IMFVideoSampleAllocator_UninitializeSampleAllocator(topo_node->u.sink.allocator))) - hr = IMFVideoSampleAllocator_InitializeSampleAllocator(topo_node->u.sink.allocator, 4, media_type); + if (topo_node->u.sink.allocator) + { + if (SUCCEEDED(hr = IMFVideoSampleAllocator_UninitializeSampleAllocator(topo_node->u.sink.allocator))) + hr = IMFVideoSampleAllocator_InitializeSampleAllocator(topo_node->u.sink.allocator, 4, media_type); + } + if (SUCCEEDED(hr)) + hr = sink_node_update_input_type(topo_node, media_type); return hr;
case MF_TOPOLOGY_TRANSFORM_NODE: