mf: Attempt to create mmdevapi device on SAR creation.

Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Nikolay Sivov 2020-04-08 17:21:24 +03:00 committed by Alexandre Julliard
parent f553c2b14f
commit cb9b207284
2 changed files with 80 additions and 0 deletions

View File

@ -22,6 +22,8 @@
#include "mfidl.h" #include "mfidl.h"
#include "mferror.h" #include "mferror.h"
#include "mf_private.h" #include "mf_private.h"
#include "initguid.h"
#include "mmdeviceapi.h"
#include "wine/debug.h" #include "wine/debug.h"
#include "wine/heap.h" #include "wine/heap.h"
@ -447,9 +449,55 @@ static const IMFClockStateSinkVtbl audio_renderer_clock_sink_vtbl =
audio_renderer_clock_sink_OnClockSetRate, 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) static HRESULT sar_create_object(IMFAttributes *attributes, void *user_context, IUnknown **obj)
{ {
struct audio_renderer *renderer; struct audio_renderer *renderer;
IMMDevice *device;
HRESULT hr; HRESULT hr;
TRACE("%p, %p, %p.\n", attributes, user_context, obj); 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))) if (FAILED(hr = MFCreateEventQueue(&renderer->event_queue)))
goto failed; goto failed;
if (FAILED(hr = sar_create_mmdevice(attributes, &device)))
goto failed;
IMMDevice_Release(device);
*obj = (IUnknown *)&renderer->IMFMediaSink_iface; *obj = (IUnknown *)&renderer->IMFMediaSink_iface;
return S_OK; return S_OK;

View File

@ -38,6 +38,7 @@ DEFINE_GUID(MFVideoFormat_ABGR32, 0x00000020, 0x0000, 0x0010, 0x80, 0x00, 0x00,
#include "mfapi.h" #include "mfapi.h"
#include "mferror.h" #include "mferror.h"
#include "mfidl.h" #include "mfidl.h"
#include "mmdeviceapi.h"
#include "wine/test.h" #include "wine/test.h"
@ -2636,6 +2637,7 @@ static void test_sar(void)
IMFClockStateSink *state_sink; IMFClockStateSink *state_sink;
IMFMediaSink *sink, *sink2; IMFMediaSink *sink, *sink2;
IMFStreamSink *stream_sink; IMFStreamSink *stream_sink;
IMFAttributes *attributes;
IMFActivate *activate; IMFActivate *activate;
MFCLOCK_STATE state; MFCLOCK_STATE state;
DWORD flags, count; DWORD flags, count;
@ -2823,6 +2825,31 @@ todo_wine
hr = MFShutdown(); hr = MFShutdown();
ok(hr == S_OK, "Shutdown failure, hr %#x.\n", hr); 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(); CoUninitialize();
} }