From: Ziqing Hui zhui@codeweavers.com
--- dlls/winegstreamer/media_sink.c | 92 +++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+)
diff --git a/dlls/winegstreamer/media_sink.c b/dlls/winegstreamer/media_sink.c index 57f38729bbb..c9560a7ecb0 100644 --- a/dlls/winegstreamer/media_sink.c +++ b/dlls/winegstreamer/media_sink.c @@ -39,11 +39,13 @@ struct stream_sink struct media_sink { IMFFinalizableMediaSink IMFFinalizableMediaSink_iface; + IMFMediaEventGenerator IMFMediaEventGenerator_iface; LONG refcount; CRITICAL_SECTION cs; bool shutdown;
IMFByteStream *bytestream; + IMFMediaEventQueue *event_queue;
struct stream_sink **stream_sinks; size_t stream_sink_count; @@ -60,6 +62,11 @@ static struct media_sink *impl_from_IMFFinalizableMediaSink(IMFFinalizableMediaS return CONTAINING_RECORD(iface, struct media_sink, IMFFinalizableMediaSink_iface); }
+static struct media_sink *impl_from_IMFMediaEventGenerator(IMFMediaEventGenerator *iface) +{ + return CONTAINING_RECORD(iface, struct media_sink, IMFMediaEventGenerator_iface); +} + static HRESULT WINAPI stream_sink_QueryInterface(IMFStreamSink *iface, REFIID riid, void **obj) { struct stream_sink *stream_sink = impl_from_IMFStreamSink(iface); @@ -265,6 +272,8 @@ static struct stream_sink *media_sink_get_stream_sink_by_id(struct media_sink *m
static HRESULT WINAPI media_sink_QueryInterface(IMFFinalizableMediaSink *iface, REFIID riid, void **obj) { + struct media_sink *media_sink = impl_from_IMFFinalizableMediaSink(iface); + TRACE("iface %p, riid %s, obj %p.\n", iface, debugstr_guid(riid), obj);
if (IsEqualIID(riid, &IID_IMFFinalizableMediaSink) || @@ -273,6 +282,10 @@ static HRESULT WINAPI media_sink_QueryInterface(IMFFinalizableMediaSink *iface, { *obj = iface; } + else if (IsEqualGUID(riid, &IID_IMFMediaEventGenerator)) + { + *obj = &media_sink->IMFMediaEventGenerator_iface; + } else { WARN("Unsupported interface %s.\n", debugstr_guid(riid)); @@ -303,6 +316,7 @@ static ULONG WINAPI media_sink_Release(IMFFinalizableMediaSink *iface) if (!refcount) { IMFFinalizableMediaSink_Shutdown(iface); + IMFMediaEventQueue_Release(media_sink->event_queue); IMFByteStream_Release(media_sink->bytestream); free(media_sink); } @@ -424,6 +438,7 @@ static HRESULT WINAPI media_sink_Shutdown(IMFFinalizableMediaSink *iface) } free(media_sink->stream_sinks);
+ IMFMediaEventQueue_Shutdown(media_sink->event_queue); IMFByteStream_Close(media_sink->bytestream);
media_sink->shutdown = TRUE; @@ -465,9 +480,79 @@ static const IMFFinalizableMediaSinkVtbl media_sink_vtbl = media_sink_EndFinalize, };
+static HRESULT WINAPI media_sink_event_QueryInterface(IMFMediaEventGenerator *iface, REFIID riid, void **obj) +{ + struct media_sink *media_sink = impl_from_IMFMediaEventGenerator(iface); + return IMFFinalizableMediaSink_QueryInterface(&media_sink->IMFFinalizableMediaSink_iface, riid, obj); +} + +static ULONG WINAPI media_sink_event_AddRef(IMFMediaEventGenerator *iface) +{ + struct media_sink *media_sink = impl_from_IMFMediaEventGenerator(iface); + return IMFFinalizableMediaSink_AddRef(&media_sink->IMFFinalizableMediaSink_iface); +} + +static ULONG WINAPI media_sink_event_Release(IMFMediaEventGenerator *iface) +{ + struct media_sink *media_sink = impl_from_IMFMediaEventGenerator(iface); + return IMFFinalizableMediaSink_Release(&media_sink->IMFFinalizableMediaSink_iface); +} + +static HRESULT WINAPI media_sink_event_GetEvent(IMFMediaEventGenerator *iface, DWORD flags, IMFMediaEvent **event) +{ + struct media_sink *media_sink = impl_from_IMFMediaEventGenerator(iface); + + TRACE("iface %p, flags %#lx, event %p.\n", iface, flags, event); + + return IMFMediaEventQueue_GetEvent(media_sink->event_queue, flags, event); +} + +static HRESULT WINAPI media_sink_event_BeginGetEvent(IMFMediaEventGenerator *iface, IMFAsyncCallback *callback, + IUnknown *state) +{ + struct media_sink *media_sink = impl_from_IMFMediaEventGenerator(iface); + + TRACE("iface %p, callback %p, state %p.\n", iface, callback, state); + + return IMFMediaEventQueue_BeginGetEvent(media_sink->event_queue, callback, state); +} + +static HRESULT WINAPI media_sink_event_EndGetEvent(IMFMediaEventGenerator *iface, IMFAsyncResult *result, + IMFMediaEvent **event) +{ + struct media_sink *media_sink = impl_from_IMFMediaEventGenerator(iface); + + TRACE("iface %p, result %p, event %p.\n", iface, result, event); + + return IMFMediaEventQueue_EndGetEvent(media_sink->event_queue, result, event); +} + +static HRESULT WINAPI media_sink_event_QueueEvent(IMFMediaEventGenerator *iface, MediaEventType event_type, + REFGUID ext_type, HRESULT hr, const PROPVARIANT *value) +{ + struct media_sink *media_sink = impl_from_IMFMediaEventGenerator(iface); + + TRACE("iface %p, event_type %lu, ext_type %s, hr %#lx, value %p.\n", + iface, event_type, debugstr_guid(ext_type), hr, value); + + return IMFMediaEventQueue_QueueEventParamVar(media_sink->event_queue, event_type, ext_type, hr, value); +} + +static const IMFMediaEventGeneratorVtbl media_sink_event_vtbl = +{ + media_sink_event_QueryInterface, + media_sink_event_AddRef, + media_sink_event_Release, + media_sink_event_GetEvent, + media_sink_event_BeginGetEvent, + media_sink_event_EndGetEvent, + media_sink_event_QueueEvent, +}; + static HRESULT media_sink_create(IMFByteStream *bytestream, struct media_sink **out) { struct media_sink *media_sink; + HRESULT hr;
TRACE("bytestream %p, out %p.\n", bytestream, out);
@@ -477,7 +562,14 @@ static HRESULT media_sink_create(IMFByteStream *bytestream, struct media_sink ** if (!(media_sink = calloc(1, sizeof(*media_sink)))) return E_OUTOFMEMORY;
+ if (FAILED(hr = MFCreateEventQueue(&media_sink->event_queue))) + { + free(media_sink); + return hr; + } + media_sink->IMFFinalizableMediaSink_iface.lpVtbl = &media_sink_vtbl; + media_sink->IMFMediaEventGenerator_iface.lpVtbl = &media_sink_event_vtbl; media_sink->refcount = 1; InitializeCriticalSection(&media_sink->cs); media_sink->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": cs");