Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mf/tests/mf.c | 4 ++++ dlls/mf/topology.c | 2 ++ 2 files changed, 6 insertions(+)
diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index df286db6385..458da0cb275 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -2109,9 +2109,13 @@ todo_wine {
IMFTopologyNode_Release(sink_node2);
+ hr = IMFTopology_SetUINT32(full_topology, &IID_IMFTopology, 123); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); hr = IMFTopoLoader_Load(loader, full_topology, &topology2, NULL); ok(hr == S_OK, "Failed to resolve topology, hr %#x.\n", hr); ok(full_topology != topology2, "Unexpected instance.\n"); + hr = IMFTopology_GetUINT32(topology2, &IID_IMFTopology, &value); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
IMFTopology_Release(topology2); IMFTopology_Release(full_topology); diff --git a/dlls/mf/topology.c b/dlls/mf/topology.c index 58639a67bdb..bbed2cba893 100644 --- a/dlls/mf/topology.c +++ b/dlls/mf/topology.c @@ -2567,6 +2567,8 @@ static HRESULT WINAPI topology_loader_Load(IMFTopoLoader *iface, IMFTopology *in if (FAILED(hr = MFCreateTopology(&output_topology))) return hr;
+ IMFTopology_CopyAllItems(input_topology, (IMFAttributes *)output_topology); + context.input_topology = input_topology; context.output_topology = output_topology; memset(&context.key, 0xff, sizeof(context.key));
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mf/tests/mf.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index 458da0cb275..20440499227 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -3878,7 +3878,10 @@ if (SUCCEEDED(hr)) check_interface(sink, &IID_IMFClockStateSink, TRUE); check_interface(sink, &IID_IMFGetService, TRUE); todo_wine check_interface(sink, &IID_IMFPresentationTimeSource, TRUE); + todo_wine check_service_interface(sink, &MF_RATE_CONTROL_SERVICE, &IID_IMFRateSupport, TRUE); + check_service_interface(sink, &MF_RATE_CONTROL_SERVICE, &IID_IMFRateControl, FALSE); check_service_interface(sink, &MR_POLICY_VOLUME_SERVICE, &IID_IMFSimpleAudioVolume, TRUE); + check_service_interface(sink, &MR_STREAM_VOLUME_SERVICE, &IID_IMFAudioStreamVolume, TRUE);
/* Clock */ hr = IMFMediaSink_QueryInterface(sink, &IID_IMFClockStateSink, (void **)&state_sink);
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mf/session.c | 110 +++++++++++++++++++++++++-------------------- dlls/mf/tests/mf.c | 11 +++++ 2 files changed, 73 insertions(+), 48 deletions(-)
diff --git a/dlls/mf/session.c b/dlls/mf/session.c index 20ccdd0535e..7a8c7e9f598 100644 --- a/dlls/mf/session.c +++ b/dlls/mf/session.c @@ -2020,15 +2020,66 @@ static ULONG WINAPI session_get_service_Release(IMFGetService *iface) return IMFMediaSession_Release(&session->IMFMediaSession_iface); }
+static HRESULT session_get_video_render_service(struct media_session *session, REFGUID service, + REFIID riid, void **obj) +{ + IMFStreamSink *stream_sink; + IMFTopologyNode *node; + IMFCollection *nodes; + IMFMediaSink *sink; + unsigned int i = 0; + IUnknown *vr; + HRESULT hr = E_FAIL; + + /* Use first sink to support IMFVideoRenderer. */ + if (session->presentation.current_topology) + { + if (SUCCEEDED(IMFTopology_GetOutputNodeCollection(session->presentation.current_topology, + &nodes))) + { + while (IMFCollection_GetElement(nodes, i++, (IUnknown **)&node) == S_OK) + { + if (SUCCEEDED(topology_node_get_object(node, &IID_IMFStreamSink, (void **)&stream_sink))) + { + if (SUCCEEDED(IMFStreamSink_GetMediaSink(stream_sink, &sink))) + { + if (SUCCEEDED(IMFMediaSink_QueryInterface(sink, &IID_IMFVideoRenderer, (void **)&vr))) + { + if (FAILED(hr = MFGetService(vr, service, riid, obj))) + WARN("Failed to get service from video renderer %#x.\n", hr); + IUnknown_Release(vr); + } + } + IMFStreamSink_Release(stream_sink); + } + + IMFTopologyNode_Release(node); + + if (*obj) + break; + } + + IMFCollection_Release(nodes); + } + } + + return hr; +} + static HRESULT WINAPI session_get_service_GetService(IMFGetService *iface, REFGUID service, REFIID riid, void **obj) { struct media_session *session = impl_from_IMFGetService(iface); + HRESULT hr = S_OK;
TRACE("%p, %s, %s, %p.\n", iface, debugstr_guid(service), debugstr_guid(riid), obj);
*obj = NULL;
- if (IsEqualGUID(service, &MF_RATE_CONTROL_SERVICE)) + EnterCriticalSection(&session->cs); + if (FAILED(hr = session_is_shut_down(session))) + { + } + else if (IsEqualGUID(service, &MF_RATE_CONTROL_SERVICE)) { if (IsEqualIID(riid, &IID_IMFRateSupport)) { @@ -2038,68 +2089,31 @@ static HRESULT WINAPI session_get_service_GetService(IMFGetService *iface, REFGU { *obj = &session->IMFRateControl_iface; } + else + hr = E_NOINTERFACE; + + if (*obj) + IUnknown_AddRef((IUnknown *)*obj); } else if (IsEqualGUID(service, &MF_LOCAL_MFT_REGISTRATION_SERVICE)) { - return IMFLocalMFTRegistration_QueryInterface(&local_mft_registration, riid, obj); + hr = IMFLocalMFTRegistration_QueryInterface(&local_mft_registration, riid, obj); } else if (IsEqualGUID(service, &MF_TOPONODE_ATTRIBUTE_EDITOR_SERVICE)) { *obj = &session->IMFTopologyNodeAttributeEditor_iface; + IUnknown_AddRef((IUnknown *)*obj); } else if (IsEqualGUID(service, &MR_VIDEO_RENDER_SERVICE)) { - IMFStreamSink *stream_sink; - IMFTopologyNode *node; - IMFCollection *nodes; - IMFMediaSink *sink; - unsigned int i = 0; - IUnknown *vr; - HRESULT hr; - - EnterCriticalSection(&session->cs); - - /* Use first sink to support IMFVideoRenderer. */ - if (session->presentation.current_topology) - { - if (SUCCEEDED(IMFTopology_GetOutputNodeCollection(session->presentation.current_topology, - &nodes))) - { - while (IMFCollection_GetElement(nodes, i++, (IUnknown **)&node) == S_OK) - { - if (SUCCEEDED(topology_node_get_object(node, &IID_IMFStreamSink, (void **)&stream_sink))) - { - if (SUCCEEDED(IMFStreamSink_GetMediaSink(stream_sink, &sink))) - { - if (SUCCEEDED(IMFMediaSink_QueryInterface(sink, &IID_IMFVideoRenderer, (void **)&vr))) - { - if (FAILED(hr = MFGetService(vr, service, riid, obj))) - WARN("Failed to get service from video renderer %#x.\n", hr); - IUnknown_Release(vr); - } - } - IMFStreamSink_Release(stream_sink); - } - - IMFTopologyNode_Release(node); - - if (*obj) - break; - } - - IMFCollection_Release(nodes); - } - } - - LeaveCriticalSection(&session->cs); + hr = session_get_video_render_service(session, service, riid, obj); } else FIXME("Unsupported service %s.\n", debugstr_guid(service));
- if (*obj) - IUnknown_AddRef((IUnknown *)*obj); + LeaveCriticalSection(&session->cs);
- return *obj ? S_OK : E_NOINTERFACE; + return hr; }
static const IMFGetServiceVtbl session_get_service_vtbl = diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index 20440499227..308c1fae529 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -1170,6 +1170,7 @@ static void test_media_session(void) IMFShutdown *shutdown; PROPVARIANT propvar; DWORD status, caps; + IMFGetService *gs; IMFClock *clock; IUnknown *unk; HRESULT hr; @@ -1271,6 +1272,16 @@ todo_wine hr = IMFMediaSession_Shutdown(session); ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
+ check_interface(session, &IID_IMFGetService, TRUE); + + hr = IMFMediaSession_QueryInterface(session, &IID_IMFGetService, (void **)&gs); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + hr = IMFGetService_GetService(gs, &MF_RATE_CONTROL_SERVICE, &IID_IMFRateSupport, (void **)&rate_support); + ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr); + + IMFGetService_Release(gs); + hr = IMFShutdown_GetShutdownStatus(shutdown, &status); ok(hr == S_OK, "Unexpected hr %#x.\n", hr); ok(status == MFSHUTDOWN_COMPLETED, "Unexpected shutdown status %u.\n", status);
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mf/session.c | 9 +++++++++ 1 file changed, 9 insertions(+)
diff --git a/dlls/mf/session.c b/dlls/mf/session.c index 7a8c7e9f598..6e0f65e6998 100644 --- a/dlls/mf/session.c +++ b/dlls/mf/session.c @@ -3233,6 +3233,15 @@ static HRESULT WINAPI session_events_callback_Invoke(IMFAsyncCallback *iface, IM LeaveCriticalSection(&session->cs); break;
+ case MEReconnectStart: + case MEReconnectEnd: + + EnterCriticalSection(&session->cs); + if (session_get_media_source(session, (IMFMediaSource *)event_source)) + IMFMediaEventQueue_QueueEvent(session->event_queue, event); + LeaveCriticalSection(&session->cs); + break; + case MENewStream: stream = (IMFMediaStream *)value.punkVal;
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mf/session.c | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/dlls/mf/session.c b/dlls/mf/session.c index 6e0f65e6998..925a8c93d20 100644 --- a/dlls/mf/session.c +++ b/dlls/mf/session.c @@ -3242,6 +3242,13 @@ static HRESULT WINAPI session_events_callback_Invoke(IMFAsyncCallback *iface, IM LeaveCriticalSection(&session->cs); break;
+ case MEExtendedType: + case MERendererEvent: + case MEStreamSinkFormatChanged: + + IMFMediaEventQueue_QueueEvent(session->event_queue, event); + break; + case MENewStream: stream = (IMFMediaStream *)value.punkVal;