Calling MFScheduleWorkItemEx() schedules the operation in the timer queue, but unless GetParameters() returns the timer queue, callback invocation will occur in the standard queue.
-- v2: mf: Specify a user queue for sample grabber timer callbacks. mf: Specify a user queue for presentation clock callbacks.
From: Conor McCarthy cmccarthy@codeweavers.com
Calling MFScheduleWorkItemEx() schedules the operation in the timer queue, but callback invocation occurs in the standard queue. Execution of app callbacks in a dedicated thread prevents possible slow execution from competing with demuxing and decoding. This matches native Windows behaviour. --- dlls/mf/clock.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-)
diff --git a/dlls/mf/clock.c b/dlls/mf/clock.c index e6be05d2794..1fd6b3028a0 100644 --- a/dlls/mf/clock.c +++ b/dlls/mf/clock.c @@ -1054,9 +1054,24 @@ static ULONG WINAPI present_clock_sink_callback_Release(IMFAsyncCallback *iface) return IMFPresentationClock_Release(&clock->IMFPresentationClock_iface); }
+static DWORD mf_get_sink_queue_id(void) +{ + static SRWLOCK mf_sink_queue_srw = SRWLOCK_INIT; + static DWORD mf_sink_queue_id; + + AcquireSRWLockExclusive(&mf_sink_queue_srw); + if (!mf_sink_queue_id) + MFAllocateWorkQueue(&mf_sink_queue_id); + ReleaseSRWLockExclusive(&mf_sink_queue_srw); + + return mf_sink_queue_id ? mf_sink_queue_id : MFASYNC_CALLBACK_QUEUE_STANDARD; +} + static HRESULT WINAPI present_clock_callback_GetParameters(IMFAsyncCallback *iface, DWORD *flags, DWORD *queue) { - return E_NOTIMPL; + *flags = 0; + *queue = mf_get_sink_queue_id(); + return S_OK; }
static HRESULT WINAPI present_clock_sink_callback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result)
From: Conor McCarthy cmccarthy@codeweavers.com
--- dlls/mf/clock.c | 2 +- dlls/mf/mf_private.h | 1 + dlls/mf/samplegrabber.c | 4 +++- 3 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/dlls/mf/clock.c b/dlls/mf/clock.c index 1fd6b3028a0..e8b04b0d90b 100644 --- a/dlls/mf/clock.c +++ b/dlls/mf/clock.c @@ -1054,7 +1054,7 @@ static ULONG WINAPI present_clock_sink_callback_Release(IMFAsyncCallback *iface) return IMFPresentationClock_Release(&clock->IMFPresentationClock_iface); }
-static DWORD mf_get_sink_queue_id(void) +DWORD mf_get_sink_queue_id(void) { static SRWLOCK mf_sink_queue_srw = SRWLOCK_INIT; static DWORD mf_sink_queue_id; diff --git a/dlls/mf/mf_private.h b/dlls/mf/mf_private.h index 1f2ef17a8c9..875c0cb4c66 100644 --- a/dlls/mf/mf_private.h +++ b/dlls/mf/mf_private.h @@ -118,6 +118,7 @@ extern HRESULT urlmon_scheme_handler_construct(REFIID riid, void **obj);
extern BOOL mf_is_sample_copier_transform(IMFTransform *transform); extern BOOL mf_is_sar_sink(IMFMediaSink *sink); +extern DWORD mf_get_sink_queue_id(void); extern HRESULT create_topology(TOPOID id, IMFTopology **topology); extern HRESULT topology_node_get_object(IMFTopologyNode *node, REFIID riid, void **obj); extern HRESULT topology_node_get_type_handler(IMFTopologyNode *node, DWORD stream, BOOL output, IMFMediaTypeHandler **handler); diff --git a/dlls/mf/samplegrabber.c b/dlls/mf/samplegrabber.c index de599139736..468dd47fe39 100644 --- a/dlls/mf/samplegrabber.c +++ b/dlls/mf/samplegrabber.c @@ -744,7 +744,9 @@ static ULONG WINAPI sample_grabber_stream_timer_callback_Release(IMFAsyncCallbac static HRESULT WINAPI sample_grabber_stream_timer_callback_GetParameters(IMFAsyncCallback *iface, DWORD *flags, DWORD *queue) { - return E_NOTIMPL; + *flags = 0; + *queue = mf_get_sink_queue_id(); + return S_OK; }
static HRESULT WINAPI sample_grabber_stream_timer_callback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result)