Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mf/sar.c | 117 +++++++++++++++++++++++++++++++++++++++++++-- dlls/mf/tests/mf.c | 17 +++++-- 2 files changed, 126 insertions(+), 8 deletions(-)
diff --git a/dlls/mf/sar.c b/dlls/mf/sar.c index 0b498b73a7..4ebd64facf 100644 --- a/dlls/mf/sar.c +++ b/dlls/mf/sar.c @@ -35,6 +35,7 @@ struct audio_renderer; struct audio_renderer_stream { IMFStreamSink IMFStreamSink_iface; + IMFMediaTypeHandler IMFMediaTypeHandler_iface; LONG refcount; struct audio_renderer *sink; IMFMediaEventQueue *event_queue; @@ -80,6 +81,11 @@ static struct audio_renderer_stream *impl_from_IMFStreamSink(IMFStreamSink *ifac return CONTAINING_RECORD(iface, struct audio_renderer_stream, IMFStreamSink_iface); }
+static struct audio_renderer_stream *impl_from_IMFMediaTypeHandler(IMFMediaTypeHandler *iface) +{ + return CONTAINING_RECORD(iface, struct audio_renderer_stream, IMFMediaTypeHandler_iface); +} + static HRESULT WINAPI audio_renderer_sink_QueryInterface(IMFMediaSink *iface, REFIID riid, void **obj) { struct audio_renderer *renderer = impl_from_IMFMediaSink(iface); @@ -562,12 +568,18 @@ static HRESULT sar_create_mmdevice(IMFAttributes *attributes, IMMDevice **device
static HRESULT WINAPI audio_renderer_stream_QueryInterface(IMFStreamSink *iface, REFIID riid, void **obj) { + struct audio_renderer_stream *stream = impl_from_IMFStreamSink(iface); + TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), obj);
if (IsEqualIID(riid, &IID_IMFStreamSink) || IsEqualIID(riid, &IID_IUnknown)) { - *obj = iface; + *obj = &stream->IMFStreamSink_iface; + } + else if (IsEqualIID(riid, &IID_IMFMediaTypeHandler)) + { + *obj = &stream->IMFMediaTypeHandler_iface; } else { @@ -696,9 +708,20 @@ static HRESULT WINAPI audio_renderer_stream_GetIdentifier(IMFStreamSink *iface,
static HRESULT WINAPI audio_renderer_stream_GetMediaTypeHandler(IMFStreamSink *iface, IMFMediaTypeHandler **handler) { - FIXME("%p, %p.\n", iface, handler); + struct audio_renderer_stream *stream = impl_from_IMFStreamSink(iface);
- return E_NOTIMPL; + TRACE("%p, %p.\n", iface, handler); + + if (!handler) + return E_POINTER; + + if (!stream->sink) + return MF_E_STREAMSINK_REMOVED; + + *handler = &stream->IMFMediaTypeHandler_iface; + IMFMediaTypeHandler_AddRef(*handler); + + return S_OK; }
static HRESULT WINAPI audio_renderer_stream_ProcessSample(IMFStreamSink *iface, IMFSample *sample) @@ -740,6 +763,93 @@ static const IMFStreamSinkVtbl audio_renderer_stream_vtbl = audio_renderer_stream_Flush, };
+static HRESULT WINAPI audio_renderer_stream_type_handler_QueryInterface(IMFMediaTypeHandler *iface, REFIID riid, + void **obj) +{ + struct audio_renderer_stream *stream = impl_from_IMFMediaTypeHandler(iface); + return IMFStreamSink_QueryInterface(&stream->IMFStreamSink_iface, riid, obj); +} + +static ULONG WINAPI audio_renderer_stream_type_handler_AddRef(IMFMediaTypeHandler *iface) +{ + struct audio_renderer_stream *stream = impl_from_IMFMediaTypeHandler(iface); + return IMFStreamSink_AddRef(&stream->IMFStreamSink_iface); +} + +static ULONG WINAPI audio_renderer_stream_type_handler_Release(IMFMediaTypeHandler *iface) +{ + struct audio_renderer_stream *stream = impl_from_IMFMediaTypeHandler(iface); + return IMFStreamSink_Release(&stream->IMFStreamSink_iface); +} + +static HRESULT WINAPI audio_renderer_stream_type_handler_IsMediaTypeSupported(IMFMediaTypeHandler *iface, + IMFMediaType *in_type, IMFMediaType **out_type) +{ + FIXME("%p, %p, %p.\n", iface, in_type, out_type); + + return E_NOTIMPL; +} + +static HRESULT WINAPI audio_renderer_stream_type_handler_GetMediaTypeCount(IMFMediaTypeHandler *iface, DWORD *count) +{ + FIXME("%p, %p.\n", iface, count); + + return E_NOTIMPL; +} + +static HRESULT WINAPI audio_renderer_stream_type_handler_GetMediaTypeByIndex(IMFMediaTypeHandler *iface, DWORD index, + IMFMediaType **media_type) +{ + FIXME("%p, %u, %p.\n", iface, index, media_type); + + return E_NOTIMPL; +} + +static HRESULT WINAPI audio_renderer_stream_type_handler_SetCurrentMediaType(IMFMediaTypeHandler *iface, + IMFMediaType *media_type) +{ + FIXME("%p, %p.\n", iface, media_type); + + return E_NOTIMPL; +} + +static HRESULT WINAPI audio_renderer_stream_type_handler_GetCurrentMediaType(IMFMediaTypeHandler *iface, + IMFMediaType **media_type) +{ + FIXME("%p, %p.\n", iface, media_type); + + return E_NOTIMPL; +} + +static HRESULT WINAPI audio_renderer_stream_type_handler_GetMajorType(IMFMediaTypeHandler *iface, GUID *type) +{ + struct audio_renderer_stream *stream = impl_from_IMFMediaTypeHandler(iface); + + TRACE("%p, %p.\n", iface, type); + + if (!type) + return E_POINTER; + + if (!stream->sink) + return MF_E_STREAMSINK_REMOVED; + + memcpy(type, &MFMediaType_Audio, sizeof(*type)); + return S_OK; +} + +static const IMFMediaTypeHandlerVtbl audio_renderer_stream_type_handler_vtbl = +{ + audio_renderer_stream_type_handler_QueryInterface, + audio_renderer_stream_type_handler_AddRef, + audio_renderer_stream_type_handler_Release, + audio_renderer_stream_type_handler_IsMediaTypeSupported, + audio_renderer_stream_type_handler_GetMediaTypeCount, + audio_renderer_stream_type_handler_GetMediaTypeByIndex, + audio_renderer_stream_type_handler_SetCurrentMediaType, + audio_renderer_stream_type_handler_GetCurrentMediaType, + audio_renderer_stream_type_handler_GetMajorType, +}; + static HRESULT audio_renderer_create_stream(struct audio_renderer *sink, struct audio_renderer_stream **stream) { struct audio_renderer_stream *object; @@ -750,6 +860,7 @@ static HRESULT audio_renderer_create_stream(struct audio_renderer *sink, struct return E_OUTOFMEMORY;
object->IMFStreamSink_iface.lpVtbl = &audio_renderer_stream_vtbl; + object->IMFMediaTypeHandler_iface.lpVtbl = &audio_renderer_stream_type_handler_vtbl; object->refcount = 1; object->sink = sink; IMFMediaSink_AddRef(&object->sink->IMFMediaSink_iface); diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index 3b919d536a..72c70fcafe 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -2635,10 +2635,10 @@ static void test_quality_manager(void) static void test_sar(void) { IMFPresentationClock *present_clock, *present_clock2; + IMFMediaTypeHandler *handler, *handler2; IMFPresentationTimeSource *time_source; IMFMediaType *mediatype, *mediatype2; IMFClockStateSink *state_sink; - IMFMediaTypeHandler *handler; IMFMediaSink *sink, *sink2; IMFStreamSink *stream_sink; IMFAttributes *attributes; @@ -2765,19 +2765,26 @@ todo_wine IMFMediaSink_Release(sink2);
hr = IMFStreamSink_GetMediaTypeHandler(stream_sink, &handler); -todo_wine ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
-if (SUCCEEDED(hr)) -{ + hr = IMFStreamSink_QueryInterface(stream_sink, &IID_IMFMediaTypeHandler, (void **)&handler2); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(handler2 == handler, "Unexpected instance.\n"); + IMFMediaTypeHandler_Release(handler2); + hr = IMFMediaTypeHandler_GetMajorType(handler, &guid); ok(hr == S_OK, "Failed to get major type, hr %#x.\n", hr); ok(IsEqualGUID(&guid, &MFMediaType_Audio), "Unexpected type %s.\n", wine_dbgstr_guid(&guid));
+ count = 0; hr = IMFMediaTypeHandler_GetMediaTypeCount(handler, &count); +todo_wine { ok(hr == S_OK, "Failed to get type count, hr %#x.\n", hr); - ok(count > 0, "Unexpected type count %u.\n", count); + ok(!!count, "Unexpected type count %u.\n", count); +}
+if (SUCCEEDED(hr)) +{ hr = IMFMediaTypeHandler_GetCurrentMediaType(handler, &mediatype); ok(hr == MF_E_NOT_INITIALIZED, "Unexpected hr %#x.\n", hr);