From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfsrcsnk/tests/mfsrcsnk.c | 43 ++++++++++++- dlls/mfsrcsnk/wave.c | 112 ++++++++++++++++++++++++++++++++- 2 files changed, 152 insertions(+), 3 deletions(-)
diff --git a/dlls/mfsrcsnk/tests/mfsrcsnk.c b/dlls/mfsrcsnk/tests/mfsrcsnk.c index e3d5b100b09..1aba4094c62 100644 --- a/dlls/mfsrcsnk/tests/mfsrcsnk.c +++ b/dlls/mfsrcsnk/tests/mfsrcsnk.c @@ -46,13 +46,15 @@ static void check_interface_(unsigned int line, void *iface_ptr, REFIID iid, BOO
static void test_wave_sink(void) { + IMFMediaType *media_type, *media_type2; + IMFMediaTypeHandler *type_handler; IMFPresentationClock *clock; IMFStreamSink *stream_sink; IMFMediaSink *sink, *sink2; IMFByteStream *bytestream; - IMFMediaType *media_type; DWORD id, count, flags; HRESULT hr; + GUID guid;
hr = MFCreateWAVEMediaSink(NULL, NULL, NULL); ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr); @@ -133,6 +135,39 @@ static void test_wave_sink(void) ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); IMFMediaSink_Release(sink2);
+ check_interface(stream_sink, &IID_IMFMediaEventGenerator, TRUE); + check_interface(stream_sink, &IID_IMFMediaTypeHandler, TRUE); + + hr = IMFStreamSink_GetMediaTypeHandler(stream_sink, &type_handler); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IMFMediaTypeHandler_GetMajorType(type_handler, NULL); + ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaTypeHandler_GetMajorType(type_handler, &guid); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(IsEqualGUID(&guid, &MFMediaType_Audio), "Unexpected major type.\n"); + + hr = IMFMediaTypeHandler_GetMediaTypeCount(type_handler, &count); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(count == 1, "Unexpected count %lu.\n", count); + + hr = IMFMediaTypeHandler_GetCurrentMediaType(type_handler, &media_type2); + todo_wine + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + if (SUCCEEDED(hr)) + { + hr = IMFMediaType_SetUINT32(media_type2, &MF_MT_AUDIO_NUM_CHANNELS, 1); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IMFMediaTypeHandler_SetCurrentMediaType(type_handler, NULL); + ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaTypeHandler_SetCurrentMediaType(type_handler, media_type2); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + IMFMediaType_Release(media_type2); + } + /* Shutdown state */ hr = IMFMediaSink_Shutdown(sink); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); @@ -146,6 +181,11 @@ static void test_wave_sink(void) hr = IMFStreamSink_GetIdentifier(stream_sink, &id); ok(hr == MF_E_STREAMSINK_REMOVED, "Unexpected hr %#lx.\n", hr);
+ hr = IMFMediaTypeHandler_GetMajorType(type_handler, NULL); + ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaTypeHandler_GetMajorType(type_handler, &guid); + ok(hr == MF_E_STREAMSINK_REMOVED, "Unexpected hr %#lx.\n", hr); + IMFStreamSink_Release(stream_sink);
hr = IMFMediaSink_AddStreamSink(sink, 123, media_type, &stream_sink); @@ -159,6 +199,7 @@ static void test_wave_sink(void)
IMFMediaSink_Release(sink);
+ IMFMediaTypeHandler_Release(type_handler); IMFMediaType_Release(media_type); IMFByteStream_Release(bytestream); } diff --git a/dlls/mfsrcsnk/wave.c b/dlls/mfsrcsnk/wave.c index cf74368d8f7..a1108de4bdc 100644 --- a/dlls/mfsrcsnk/wave.c +++ b/dlls/mfsrcsnk/wave.c @@ -62,6 +62,7 @@ struct wave_sink IMFFinalizableMediaSink IMFFinalizableMediaSink_iface; IMFMediaEventGenerator IMFMediaEventGenerator_iface; IMFClockStateSink IMFClockStateSink_iface; + IMFMediaTypeHandler IMFMediaTypeHandler_iface; IMFStreamSink IMFStreamSink_iface; LONG refcount;
@@ -100,6 +101,11 @@ static struct wave_sink *impl_from_IMFClockStateSink(IMFClockStateSink *iface) return CONTAINING_RECORD(iface, struct wave_sink, IMFClockStateSink_iface); }
+static struct wave_sink *impl_from_IMFMediaTypeHandler(IMFMediaTypeHandler *iface) +{ + return CONTAINING_RECORD(iface, struct wave_sink, IMFMediaTypeHandler_iface); +} + static HRESULT WINAPI wave_sink_QueryInterface(IMFFinalizableMediaSink *iface, REFIID riid, void **obj) { struct wave_sink *sink = impl_from_IMFFinalizableMediaSink(iface); @@ -574,6 +580,10 @@ static HRESULT WINAPI wave_stream_sink_QueryInterface(IMFStreamSink *iface, REFI { *obj = &sink->IMFStreamSink_iface; } + else if (IsEqualIID(riid, &IID_IMFMediaTypeHandler)) + { + *obj = &sink->IMFMediaTypeHandler_iface; + } else { WARN("Unsupported %s.\n", debugstr_guid(riid)); @@ -680,9 +690,17 @@ static HRESULT WINAPI wave_stream_sink_GetIdentifier(IMFStreamSink *iface, DWORD
static HRESULT WINAPI wave_stream_sink_GetMediaTypeHandler(IMFStreamSink *iface, IMFMediaTypeHandler **handler) { - FIXME("%p, %p.\n", iface, handler); + struct wave_sink *sink = impl_from_IMFStreamSink(iface);
- return E_NOTIMPL; + TRACE("%p, %p.\n", iface, handler); + + if (sink->flags & SINK_SHUT_DOWN) + return MF_E_STREAMSINK_REMOVED; + + *handler = &sink->IMFMediaTypeHandler_iface; + IMFMediaTypeHandler_AddRef(*handler); + + return S_OK; }
static HRESULT WINAPI wave_stream_sink_ProcessSample(IMFStreamSink *iface, IMFSample *sample) @@ -833,6 +851,95 @@ static const IMFClockStateSinkVtbl wave_sink_clock_sink_vtbl = wave_sink_clock_sink_OnClockSetRate, };
+static HRESULT WINAPI wave_sink_type_handler_QueryInterface(IMFMediaTypeHandler *iface, REFIID riid, + void **obj) +{ + struct wave_sink *sink = impl_from_IMFMediaTypeHandler(iface); + return IMFStreamSink_QueryInterface(&sink->IMFStreamSink_iface, riid, obj); +} + +static ULONG WINAPI wave_sink_type_handler_AddRef(IMFMediaTypeHandler *iface) +{ + struct wave_sink *sink = impl_from_IMFMediaTypeHandler(iface); + return IMFStreamSink_AddRef(&sink->IMFStreamSink_iface); +} + +static ULONG WINAPI wave_sink_type_handler_Release(IMFMediaTypeHandler *iface) +{ + struct wave_sink *sink = impl_from_IMFMediaTypeHandler(iface); + return IMFStreamSink_Release(&sink->IMFStreamSink_iface); +} + +static HRESULT WINAPI wave_sink_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 wave_sink_type_handler_GetMediaTypeCount(IMFMediaTypeHandler *iface, DWORD *count) +{ + TRACE("%p, %p.\n", iface, count); + + *count = 1; + + return S_OK; +} + +static HRESULT WINAPI wave_sink_type_handler_GetMediaTypeByIndex(IMFMediaTypeHandler *iface, DWORD index, + IMFMediaType **media_type) +{ + FIXME("%p, %lu, %p.\n", iface, index, media_type); + + return E_NOTIMPL; +} + +static HRESULT WINAPI wave_sink_type_handler_SetCurrentMediaType(IMFMediaTypeHandler *iface, + IMFMediaType *media_type) +{ + FIXME("%p, %p.\n", iface, media_type); + + return E_NOTIMPL; +} + +static HRESULT WINAPI wave_sink_type_handler_GetCurrentMediaType(IMFMediaTypeHandler *iface, + IMFMediaType **media_type) +{ + FIXME("%p, %p.\n", iface, media_type); + + return E_NOTIMPL; +} + +static HRESULT WINAPI wave_sink_type_handler_GetMajorType(IMFMediaTypeHandler *iface, GUID *type) +{ + struct wave_sink *sink = impl_from_IMFMediaTypeHandler(iface); + + TRACE("%p, %p.\n", iface, type); + + if (!type) + return E_POINTER; + + if (sink->flags & SINK_SHUT_DOWN) + return MF_E_STREAMSINK_REMOVED; + + memcpy(type, &MFMediaType_Audio, sizeof(*type)); + return S_OK; +} + +static const IMFMediaTypeHandlerVtbl wave_sink_type_handler_vtbl = +{ + wave_sink_type_handler_QueryInterface, + wave_sink_type_handler_AddRef, + wave_sink_type_handler_Release, + wave_sink_type_handler_IsMediaTypeSupported, + wave_sink_type_handler_GetMediaTypeCount, + wave_sink_type_handler_GetMediaTypeByIndex, + wave_sink_type_handler_SetCurrentMediaType, + wave_sink_type_handler_GetCurrentMediaType, + wave_sink_type_handler_GetMajorType, +}; + /*********************************************************************** * MFCreateWAVEMediaSink (mfsrcsnk.@) */ @@ -871,6 +978,7 @@ HRESULT WINAPI MFCreateWAVEMediaSink(IMFByteStream *bytestream, IMFMediaType *me object->IMFMediaEventGenerator_iface.lpVtbl = &wave_sink_events_vtbl; object->IMFStreamSink_iface.lpVtbl = &wave_stream_sink_vtbl; object->IMFClockStateSink_iface.lpVtbl = &wave_sink_clock_sink_vtbl; + object->IMFMediaTypeHandler_iface.lpVtbl = &wave_sink_type_handler_vtbl; object->refcount = 1; IMFByteStream_AddRef((object->bytestream = bytestream)); InitializeCriticalSection(&object->cs);