[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