[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