Signed-off-by: Nikolay Sivov nsivov@codeweavers.com ---
v2: fixed calling convention for QueryInterface.
dlls/mf/sar.c | 145 ++++++++++++++++++++++++++++++++++++++++++++- dlls/mf/tests/mf.c | 19 +++--- 2 files changed, 152 insertions(+), 12 deletions(-)
diff --git a/dlls/mf/sar.c b/dlls/mf/sar.c index 4f20472748..7acbd5d4cd 100644 --- a/dlls/mf/sar.c +++ b/dlls/mf/sar.c @@ -26,13 +26,154 @@
WINE_DEFAULT_DEBUG_CHANNEL(mfplat);
-static HRESULT sar_create_object(IMFAttributes *attributes, void *user_context, IUnknown **obj) +struct audio_renderer +{ + IMFMediaSink IMFMediaSink_iface; + LONG refcount; +}; + +static struct audio_renderer *impl_from_IMFMediaSink(IMFMediaSink *iface) +{ + return CONTAINING_RECORD(iface, struct audio_renderer, IMFMediaSink_iface); +} + +static HRESULT WINAPI audio_renderer_sink_QueryInterface(IMFMediaSink *iface, REFIID riid, void **obj) +{ + TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), obj); + + if (IsEqualIID(riid, &IID_IMFMediaSink) || + IsEqualIID(riid, &IID_IUnknown)) + { + *obj = iface; + IMFMediaSink_AddRef(iface); + return S_OK; + } + + WARN("Unsupported %s.\n", debugstr_guid(riid)); + *obj = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI audio_renderer_sink_AddRef(IMFMediaSink *iface) +{ + struct audio_renderer *renderer = impl_from_IMFMediaSink(iface); + ULONG refcount = InterlockedIncrement(&renderer->refcount); + TRACE("%p, refcount %u.\n", iface, refcount); + return refcount; +} + +static ULONG WINAPI audio_renderer_sink_Release(IMFMediaSink *iface) +{ + struct audio_renderer *renderer = impl_from_IMFMediaSink(iface); + ULONG refcount = InterlockedDecrement(&renderer->refcount); + + TRACE("%p, refcount %u.\n", iface, refcount); + + if (!refcount) + heap_free(renderer); + + return refcount; +} + +static HRESULT WINAPI audio_renderer_sink_GetCharacteristics(IMFMediaSink *iface, DWORD *flags) +{ + FIXME("%p, %p.\n", iface, flags); + + return E_NOTIMPL; +} + +static HRESULT WINAPI audio_renderer_sink_AddStreamSink(IMFMediaSink *iface, DWORD stream_sink_id, + IMFMediaType *media_type, IMFStreamSink **stream_sink) +{ + FIXME("%p, %#x, %p, %p.\n", iface, stream_sink_id, media_type, stream_sink); + + return E_NOTIMPL; +} + +static HRESULT WINAPI audio_renderer_sink_RemoveStreamSink(IMFMediaSink *iface, DWORD stream_sink_id) +{ + FIXME("%p, %#x.\n", iface, stream_sink_id); + + return E_NOTIMPL; +} + +static HRESULT WINAPI audio_renderer_sink_GetStreamSinkCount(IMFMediaSink *iface, DWORD *count) { - FIXME("%p, %p, %p.\n", attributes, user_context, obj); + FIXME("%p, %p.\n", iface, count);
return E_NOTIMPL; }
+static HRESULT WINAPI audio_renderer_sink_GetStreamSinkByIndex(IMFMediaSink *iface, DWORD index, + IMFStreamSink **stream) +{ + FIXME("%p, %u, %p.\n", iface, index, stream); + + return E_NOTIMPL; +} + +static HRESULT WINAPI audio_renderer_sink_GetStreamSinkById(IMFMediaSink *iface, DWORD stream_sink_id, + IMFStreamSink **stream) +{ + FIXME("%p, %#x, %p.\n", iface, stream_sink_id, stream); + + return E_NOTIMPL; +} + +static HRESULT WINAPI audio_renderer_sink_SetPresentationClock(IMFMediaSink *iface, IMFPresentationClock *clock) +{ + FIXME("%p, %p.\n", iface, clock); + + return E_NOTIMPL; +} + +static HRESULT WINAPI audio_renderer_sink_GetPresentationClock(IMFMediaSink *iface, IMFPresentationClock **clock) +{ + FIXME("%p, %p.\n", iface, clock); + + return E_NOTIMPL; +} + +static HRESULT WINAPI audio_renderer_sink_Shutdown(IMFMediaSink *iface) +{ + FIXME("%p.\n", iface); + + return E_NOTIMPL; +} + +static const IMFMediaSinkVtbl audio_renderer_sink_vtbl = +{ + audio_renderer_sink_QueryInterface, + audio_renderer_sink_AddRef, + audio_renderer_sink_Release, + audio_renderer_sink_GetCharacteristics, + audio_renderer_sink_AddStreamSink, + audio_renderer_sink_RemoveStreamSink, + audio_renderer_sink_GetStreamSinkCount, + audio_renderer_sink_GetStreamSinkByIndex, + audio_renderer_sink_GetStreamSinkById, + audio_renderer_sink_SetPresentationClock, + audio_renderer_sink_GetPresentationClock, + audio_renderer_sink_Shutdown, +}; + +static HRESULT sar_create_object(IMFAttributes *attributes, void *user_context, IUnknown **obj) +{ + struct audio_renderer *renderer; + + TRACE("%p, %p, %p.\n", attributes, user_context, obj); + + if (!(renderer = heap_alloc_zero(sizeof(*renderer)))) + return E_OUTOFMEMORY; + + renderer->IMFMediaSink_iface.lpVtbl = &audio_renderer_sink_vtbl; + renderer->refcount = 1; + + *obj = (IUnknown *)&renderer->IMFMediaSink_iface; + + return S_OK; +} + static void sar_shutdown_object(void *user_context, IUnknown *obj) { /* FIXME: shut down sink */ diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index dfbd928f60..46024d3fba 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -2650,15 +2650,14 @@ static void test_sar(void) CoUninitialize(); return; } - -todo_wine ok(hr == S_OK, "Failed to create renderer, hr %#x.\n", hr);
-if (SUCCEEDED(hr)) -{ hr = IMFMediaSink_QueryInterface(sink, &IID_IMFPresentationTimeSource, (void **)&time_source); +todo_wine ok(hr == S_OK, "Failed to get time source interface, hr %#x.\n", hr);
+if (SUCCEEDED(hr)) +{ hr = IMFPresentationTimeSource_GetUnderlyingClock(time_source, &clock); ok(hr == MF_E_NO_CLOCK, "Unexpected hr %#x.\n", hr);
@@ -2679,31 +2678,30 @@ if (SUCCEEDED(hr)) IMFClockStateSink_Release(state_sink);
IMFPresentationTimeSource_Release(time_source); - - IMFMediaSink_Release(sink); } + IMFMediaSink_Release(sink); + /* Activation */ hr = MFCreateAudioRendererActivate(&activate); ok(hr == S_OK, "Failed to create activation object, hr %#x.\n", hr);
hr = IMFActivate_ActivateObject(activate, &IID_IMFMediaSink, (void **)&sink); -todo_wine ok(hr == S_OK, "Failed to activate, hr %#x.\n", hr);
-if (hr == S_OK) -{ hr = IMFActivate_ActivateObject(activate, &IID_IMFMediaSink, (void **)&sink2); ok(hr == S_OK, "Failed to activate, hr %#x.\n", hr); ok(sink == sink2, "Unexpected instance.\n"); IMFMediaSink_Release(sink2);
hr = IMFMediaSink_GetCharacteristics(sink, &flags); +todo_wine ok(hr == S_OK, "Failed to get sink flags, hr %#x.\n", hr);
hr = IMFActivate_ShutdownObject(activate); ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
hr = IMFMediaSink_GetCharacteristics(sink, &flags); +todo_wine ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
IMFMediaSink_Release(sink); @@ -2712,13 +2710,14 @@ if (hr == S_OK) ok(hr == S_OK, "Failed to activate, hr %#x.\n", hr);
hr = IMFMediaSink_GetCharacteristics(sink, &flags); +todo_wine ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
IMFMediaSink_Release(sink);
hr = IMFActivate_DetachObject(activate); ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr); -} + IMFActivate_Release(activate);
CoUninitialize();