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:
parent
f553c2b14f
commit
cb9b207284
|
@ -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;
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue