[PATCH 3/7] mf: Attempt to create mmdevapi device on SAR creation.

Nikolay Sivov nsivov at codeweavers.com
Wed Apr 8 09:21:24 CDT 2020


Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
 dlls/mf/sar.c      | 53 ++++++++++++++++++++++++++++++++++++++++++++++
 dlls/mf/tests/mf.c | 27 +++++++++++++++++++++++
 2 files changed, 80 insertions(+)

diff --git a/dlls/mf/sar.c b/dlls/mf/sar.c
index 2ef767b787..5d74238a91 100644
--- a/dlls/mf/sar.c
+++ b/dlls/mf/sar.c
@@ -22,6 +22,8 @@
 #include "mfidl.h"
 #include "mferror.h"
 #include "mf_private.h"
+#include "initguid.h"
+#include "mmdeviceapi.h"
 
 #include "wine/debug.h"
 #include "wine/heap.h"
@@ -447,9 +449,55 @@ static const IMFClockStateSinkVtbl audio_renderer_clock_sink_vtbl =
     audio_renderer_clock_sink_OnClockSetRate,
 };
 
+static HRESULT sar_create_mmdevice(IMFAttributes *attributes, IMMDevice **device)
+{
+    WCHAR *endpoint;
+    unsigned int length, role = eMultimedia;
+    IMMDeviceEnumerator *devenum;
+    HRESULT hr;
+
+    if (attributes)
+    {
+        /* Mutually exclusive attributes. */
+        if (SUCCEEDED(IMFAttributes_GetItem(attributes, &MF_AUDIO_RENDERER_ATTRIBUTE_ENDPOINT_ROLE, NULL)) &&
+                SUCCEEDED(IMFAttributes_GetItem(attributes, &MF_AUDIO_RENDERER_ATTRIBUTE_ENDPOINT_ID, NULL)))
+        {
+            return E_INVALIDARG;
+        }
+    }
+
+    if (FAILED(hr = CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL, CLSCTX_INPROC_SERVER, &IID_IMMDeviceEnumerator,
+            (void **)&devenum)))
+    {
+        return hr;
+    }
+
+    role = eMultimedia;
+    if (attributes && SUCCEEDED(IMFAttributes_GetUINT32(attributes, &MF_AUDIO_RENDERER_ATTRIBUTE_ENDPOINT_ROLE, &role)))
+        TRACE("Specified role %d.\n", role);
+
+    if (attributes && SUCCEEDED(IMFAttributes_GetAllocatedString(attributes, &MF_AUDIO_RENDERER_ATTRIBUTE_ENDPOINT_ID,
+            &endpoint, &length)))
+    {
+        TRACE("Specified end point %s.\n", debugstr_w(endpoint));
+        hr = IMMDeviceEnumerator_GetDevice(devenum, endpoint, device);
+        CoTaskMemFree(endpoint);
+    }
+    else
+        hr = IMMDeviceEnumerator_GetDefaultAudioEndpoint(devenum, eRender, role, device);
+
+    if (FAILED(hr))
+        hr = MF_E_NO_AUDIO_PLAYBACK_DEVICE;
+
+    IMMDeviceEnumerator_Release(devenum);
+
+    return hr;
+}
+
 static HRESULT sar_create_object(IMFAttributes *attributes, void *user_context, IUnknown **obj)
 {
     struct audio_renderer *renderer;
+    IMMDevice *device;
     HRESULT hr;
 
     TRACE("%p, %p, %p.\n", attributes, user_context, obj);
@@ -467,6 +515,11 @@ static HRESULT sar_create_object(IMFAttributes *attributes, void *user_context,
     if (FAILED(hr = MFCreateEventQueue(&renderer->event_queue)))
         goto failed;
 
+    if (FAILED(hr = sar_create_mmdevice(attributes, &device)))
+        goto failed;
+
+    IMMDevice_Release(device);
+
     *obj = (IUnknown *)&renderer->IMFMediaSink_iface;
 
     return S_OK;
diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c
index 98e180e453..4f29362102 100644
--- a/dlls/mf/tests/mf.c
+++ b/dlls/mf/tests/mf.c
@@ -38,6 +38,7 @@ DEFINE_GUID(MFVideoFormat_ABGR32, 0x00000020, 0x0000, 0x0010, 0x80, 0x00, 0x00,
 #include "mfapi.h"
 #include "mferror.h"
 #include "mfidl.h"
+#include "mmdeviceapi.h"
 
 #include "wine/test.h"
 
@@ -2636,6 +2637,7 @@ static void test_sar(void)
     IMFClockStateSink *state_sink;
     IMFMediaSink *sink, *sink2;
     IMFStreamSink *stream_sink;
+    IMFAttributes *attributes;
     IMFActivate *activate;
     MFCLOCK_STATE state;
     DWORD flags, count;
@@ -2823,6 +2825,31 @@ todo_wine
     hr = MFShutdown();
     ok(hr == S_OK, "Shutdown failure, hr %#x.\n", hr);
 
+    /* SAR attributes */
+    hr = MFCreateAttributes(&attributes, 0);
+    ok(hr == S_OK, "Failed to create attributes, hr %#x.\n", hr);
+
+    /* Specify role. */
+    hr = IMFAttributes_SetUINT32(attributes, &MF_AUDIO_RENDERER_ATTRIBUTE_ENDPOINT_ROLE, eMultimedia);
+    ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
+
+    hr = MFCreateAudioRenderer(attributes, &sink);
+    ok(hr == S_OK, "Failed to create a sink, hr %#x.\n", hr);
+    IMFMediaSink_Release(sink);
+
+    /* Invalid endpoint. */
+    hr = IMFAttributes_SetString(attributes, &MF_AUDIO_RENDERER_ATTRIBUTE_ENDPOINT_ID, L"endpoint");
+    ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
+
+    hr = MFCreateAudioRenderer(attributes, &sink);
+    ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
+
+    hr = IMFAttributes_DeleteItem(attributes, &MF_AUDIO_RENDERER_ATTRIBUTE_ENDPOINT_ROLE);
+    ok(hr == S_OK, "Failed to remove attribute, hr %#x.\n", hr);
+
+    hr = MFCreateAudioRenderer(attributes, &sink);
+    ok(hr == MF_E_NO_AUDIO_PLAYBACK_DEVICE, "Failed to create a sink, hr %#x.\n", hr);
+
     CoUninitialize();
 }
 
-- 
2.25.1




More information about the wine-devel mailing list