[PATCH 5/5] mfmediaengine: Set up audio output branch.

Nikolay Sivov nsivov at codeweavers.com
Thu Jun 4 05:41:49 CDT 2020


Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
 dlls/mfmediaengine/main.c | 77 ++++++++++++++++++++++++++++++++++++++-
 1 file changed, 75 insertions(+), 2 deletions(-)

diff --git a/dlls/mfmediaengine/main.c b/dlls/mfmediaengine/main.c
index fee5f6338d5..d93e2b2f38c 100644
--- a/dlls/mfmediaengine/main.c
+++ b/dlls/mfmediaengine/main.c
@@ -329,11 +329,55 @@ static ULONG WINAPI media_engine_load_handler_Release(IMFAsyncCallback *iface)
     return IMFMediaEngine_Release(&engine->IMFMediaEngine_iface);
 }
 
+static HRESULT media_engine_create_source_node(IMFMediaSource *source, IMFPresentationDescriptor *pd, IMFStreamDescriptor *sd,
+        IMFTopologyNode **node)
+{
+    HRESULT hr;
+
+    if (FAILED(hr = MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE, node)))
+        return hr;
+
+    IMFTopologyNode_SetUnknown(*node, &MF_TOPONODE_SOURCE, (IUnknown *)source);
+    IMFTopologyNode_SetUnknown(*node, &MF_TOPONODE_PRESENTATION_DESCRIPTOR, (IUnknown *)pd);
+    IMFTopologyNode_SetUnknown(*node, &MF_TOPONODE_STREAM_DESCRIPTOR, (IUnknown *)sd);
+
+    return S_OK;
+}
+
+static HRESULT media_engine_create_audio_renderer(struct media_engine *engine, IMFTopologyNode **node)
+{
+    unsigned int category, role;
+    IMFActivate *sar_activate;
+    HRESULT hr;
+
+    *node = NULL;
+
+    if (FAILED(hr = MFCreateAudioRendererActivate(&sar_activate)))
+        return hr;
+
+    /* Configuration attributes keys differ between Engine and SAR. */
+    if (SUCCEEDED(IMFAttributes_GetUINT32(engine->attributes, &MF_MEDIA_ENGINE_AUDIO_CATEGORY, &category)))
+        IMFActivate_SetUINT32(sar_activate, &MF_AUDIO_RENDERER_ATTRIBUTE_STREAM_CATEGORY, category);
+    if (SUCCEEDED(IMFAttributes_GetUINT32(engine->attributes, &MF_MEDIA_ENGINE_AUDIO_ENDPOINT_ROLE, &role)))
+        IMFActivate_SetUINT32(sar_activate, &MF_AUDIO_RENDERER_ATTRIBUTE_ENDPOINT_ROLE, role);
+
+    if (SUCCEEDED(hr = MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, node)))
+    {
+        IMFTopologyNode_SetObject(*node, (IUnknown *)sar_activate);
+        IMFTopologyNode_SetUINT32(*node, &MF_TOPONODE_NOSHUTDOWN_ON_REMOVE, FALSE);
+    }
+
+    IMFActivate_Release(sar_activate);
+
+    return hr;
+}
+
 static HRESULT media_engine_create_topology(struct media_engine *engine, IMFMediaSource *source)
 {
     IMFStreamDescriptor *sd_audio = NULL, *sd_video = NULL;
     unsigned int stream_count = 0, i;
     IMFPresentationDescriptor *pd;
+    IMFTopology *topology;
     UINT64 duration;
     HRESULT hr;
 
@@ -410,7 +454,36 @@ static HRESULT media_engine_create_topology(struct media_engine *engine, IMFMedi
 
     IMFMediaEngineNotify_EventNotify(engine->callback, MF_MEDIA_ENGINE_EVENT_LOADEDDATA, 0, 0);
 
-    /* TODO: set up topology nodes */
+    /* TODO: set up video stream nodes */
+
+    if (SUCCEEDED(hr = MFCreateTopology(&topology)))
+    {
+        IMFTopologyNode *sar_node = NULL, *audio_src = NULL;
+
+        if (sd_audio)
+        {
+            if (FAILED(hr = media_engine_create_source_node(source, pd, sd_audio, &audio_src)))
+                WARN("Failed to create audio source node, hr %#x.\n", hr);
+
+            if (FAILED(hr = media_engine_create_audio_renderer(engine, &sar_node)))
+                WARN("Failed to create audio renderer node, hr %#x.\n", hr);
+
+            if (sar_node && audio_src)
+            {
+                IMFTopology_AddNode(topology, audio_src);
+                IMFTopology_AddNode(topology, sar_node);
+                IMFTopologyNode_ConnectOutput(audio_src, 0, sar_node, 0);
+            }
+
+            if (sar_node)
+                IMFTopologyNode_Release(sar_node);
+            if (audio_src)
+                IMFTopologyNode_Release(audio_src);
+        }
+    }
+
+    if (topology)
+        IMFTopology_Release(topology);
 
     if (sd_video)
         IMFStreamDescriptor_Release(sd_video);
@@ -419,7 +492,7 @@ static HRESULT media_engine_create_topology(struct media_engine *engine, IMFMedi
 
     IMFPresentationDescriptor_Release(pd);
 
-    return S_OK;
+    return hr;
 }
 
 static HRESULT WINAPI media_engine_load_handler_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result)
-- 
2.26.2




More information about the wine-devel mailing list