[PATCH 5/7] mf: Notify just added sinks with current clock state.
Nikolay Sivov
nsivov at codeweavers.com
Wed Mar 11 06:19:43 CDT 2020
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
dlls/mf/session.c | 176 +++++++++++++++++++++++++---------------------
1 file changed, 95 insertions(+), 81 deletions(-)
diff --git a/dlls/mf/session.c b/dlls/mf/session.c
index 91fcce57ca..933cdf5c93 100644
--- a/dlls/mf/session.c
+++ b/dlls/mf/session.c
@@ -234,6 +234,7 @@ struct presentation_clock
IMFPresentationTimeSource *time_source;
IMFClockStateSink *time_source_sink;
MFCLOCK_STATE state;
+ LONGLONG start_offset;
struct list sinks;
struct list timers;
float rate;
@@ -2504,6 +2505,81 @@ failed:
return hr;
}
+static HRESULT WINAPI sink_notification_QueryInterface(IUnknown *iface, REFIID riid, void **out)
+{
+ if (IsEqualIID(riid, &IID_IUnknown))
+ {
+ *out = iface;
+ IUnknown_AddRef(iface);
+ return S_OK;
+ }
+
+ WARN("Unsupported %s.\n", debugstr_guid(riid));
+ *out = NULL;
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI sink_notification_AddRef(IUnknown *iface)
+{
+ struct sink_notification *notification = impl_sink_notification_from_IUnknown(iface);
+ ULONG refcount = InterlockedIncrement(¬ification->refcount);
+
+ TRACE("%p, refcount %u.\n", iface, refcount);
+
+ return refcount;
+}
+
+static ULONG WINAPI sink_notification_Release(IUnknown *iface)
+{
+ struct sink_notification *notification = impl_sink_notification_from_IUnknown(iface);
+ ULONG refcount = InterlockedDecrement(¬ification->refcount);
+
+ TRACE("%p, refcount %u.\n", iface, refcount);
+
+ if (!refcount)
+ {
+ IMFClockStateSink_Release(notification->sink);
+ heap_free(notification);
+ }
+
+ return refcount;
+}
+
+static const IUnknownVtbl sinknotificationvtbl =
+{
+ sink_notification_QueryInterface,
+ sink_notification_AddRef,
+ sink_notification_Release,
+};
+
+static void clock_notify_async_sink(struct presentation_clock *clock, MFTIME system_time,
+ struct clock_state_change_param param, enum clock_notification notification, IMFClockStateSink *sink)
+{
+ struct sink_notification *object;
+ IMFAsyncResult *result;
+ HRESULT hr;
+
+ object = heap_alloc(sizeof(*object));
+ if (!object)
+ return;
+
+ object->IUnknown_iface.lpVtbl = &sinknotificationvtbl;
+ object->refcount = 1;
+ object->system_time = system_time;
+ object->param = param;
+ object->notification = notification;
+ object->sink = sink;
+ IMFClockStateSink_AddRef(object->sink);
+
+ hr = MFCreateAsyncResult(&object->IUnknown_iface, &clock->sink_callback, NULL, &result);
+ IUnknown_Release(&object->IUnknown_iface);
+ if (SUCCEEDED(hr))
+ {
+ MFPutWorkItemEx(MFASYNC_CALLBACK_QUEUE_STANDARD, result);
+ IMFAsyncResult_Release(result);
+ }
+}
+
static HRESULT WINAPI present_clock_QueryInterface(IMFPresentationClock *iface, REFIID riid, void **out)
{
struct presentation_clock *clock = impl_from_IMFPresentationClock(iface);
@@ -2762,7 +2838,24 @@ static HRESULT WINAPI present_clock_AddClockStateSink(IMFPresentationClock *ifac
}
}
if (SUCCEEDED(hr))
+ {
+ static const enum clock_notification notifications[MFCLOCK_STATE_PAUSED + 1] =
+ {
+ /* MFCLOCK_STATE_INVALID */ 0, /* Does not apply */
+ /* MFCLOCK_STATE_RUNNING */ CLOCK_NOTIFY_START,
+ /* MFCLOCK_STATE_STOPPED */ CLOCK_NOTIFY_STOP,
+ /* MFCLOCK_STATE_PAUSED */ CLOCK_NOTIFY_PAUSE,
+ };
+ struct clock_state_change_param param;
+
+ if (!clock->is_shut_down && clock->state != MFCLOCK_STATE_INVALID)
+ {
+ param.u.offset = clock->start_offset;
+ clock_notify_async_sink(clock, MFGetSystemTime(), param, notifications[clock->state], sink->state_sink);
+ }
+
list_add_tail(&clock->sinks, &sink->entry);
+ }
LeaveCriticalSection(&clock->cs);
if (FAILED(hr))
@@ -2801,75 +2894,6 @@ static HRESULT WINAPI present_clock_RemoveClockStateSink(IMFPresentationClock *i
return S_OK;
}
-static HRESULT WINAPI sink_notification_QueryInterface(IUnknown *iface, REFIID riid, void **out)
-{
- if (IsEqualIID(riid, &IID_IUnknown))
- {
- *out = iface;
- IUnknown_AddRef(iface);
- return S_OK;
- }
-
- WARN("Unsupported %s.\n", debugstr_guid(riid));
- *out = NULL;
- return E_NOINTERFACE;
-}
-
-static ULONG WINAPI sink_notification_AddRef(IUnknown *iface)
-{
- struct sink_notification *notification = impl_sink_notification_from_IUnknown(iface);
- ULONG refcount = InterlockedIncrement(¬ification->refcount);
-
- TRACE("%p, refcount %u.\n", iface, refcount);
-
- return refcount;
-}
-
-static ULONG WINAPI sink_notification_Release(IUnknown *iface)
-{
- struct sink_notification *notification = impl_sink_notification_from_IUnknown(iface);
- ULONG refcount = InterlockedDecrement(¬ification->refcount);
-
- TRACE("%p, refcount %u.\n", iface, refcount);
-
- if (!refcount)
- {
- IMFClockStateSink_Release(notification->sink);
- heap_free(notification);
- }
-
- return refcount;
-}
-
-static const IUnknownVtbl sinknotificationvtbl =
-{
- sink_notification_QueryInterface,
- sink_notification_AddRef,
- sink_notification_Release,
-};
-
-static HRESULT create_sink_notification(MFTIME system_time, struct clock_state_change_param param,
- enum clock_notification notification, IMFClockStateSink *sink, IUnknown **out)
-{
- struct sink_notification *object;
-
- object = heap_alloc(sizeof(*object));
- if (!object)
- return E_OUTOFMEMORY;
-
- object->IUnknown_iface.lpVtbl = &sinknotificationvtbl;
- object->refcount = 1;
- object->system_time = system_time;
- object->param = param;
- object->notification = notification;
- object->sink = sink;
- IMFClockStateSink_AddRef(object->sink);
-
- *out = &object->IUnknown_iface;
-
- return S_OK;
-}
-
static HRESULT clock_call_state_change(MFTIME system_time, struct clock_state_change_param param,
enum clock_notification notification, IMFClockStateSink *sink)
{
@@ -2926,7 +2950,6 @@ static HRESULT clock_change_state(struct presentation_clock *clock, enum clock_c
};
enum clock_notification notification;
struct clock_sink *sink;
- IUnknown *notify_object;
MFCLOCK_STATE old_state;
IMFAsyncResult *result;
MFTIME system_time;
@@ -2992,16 +3015,7 @@ static HRESULT clock_change_state(struct presentation_clock *clock, enum clock_c
LIST_FOR_EACH_ENTRY(sink, &clock->sinks, struct clock_sink, entry)
{
- if (SUCCEEDED(create_sink_notification(system_time, param, notification, sink->state_sink, ¬ify_object)))
- {
- hr = MFCreateAsyncResult(notify_object, &clock->sink_callback, NULL, &result);
- IUnknown_Release(notify_object);
- if (SUCCEEDED(hr))
- {
- MFPutWorkItemEx(MFASYNC_CALLBACK_QUEUE_STANDARD, result);
- IMFAsyncResult_Release(result);
- }
- }
+ clock_notify_async_sink(clock, system_time, param, notification, sink->state_sink);
}
return S_OK;
@@ -3016,7 +3030,7 @@ static HRESULT WINAPI present_clock_Start(IMFPresentationClock *iface, LONGLONG
TRACE("%p, %s.\n", iface, wine_dbgstr_longlong(start_offset));
EnterCriticalSection(&clock->cs);
- param.u.offset = start_offset;
+ clock->start_offset = param.u.offset = start_offset;
hr = clock_change_state(clock, CLOCK_CMD_START, param);
LeaveCriticalSection(&clock->cs);
--
2.25.1
More information about the wine-devel
mailing list