Skip to content

mfvideosrc,wasapi2: Fix for UWP UI thread access issue

In case of UWP application, documentation from MS is saying that device activation should be called from UI thread.

(but activating device from non-UI thread seems to be working though...)

From a library point of view, there seems to be no robust way for accessing UI thread object. So this MR is introducing dispatcher property for wasapi2 elements and mfvideosrc. By the property, application can pass ICoreDispatcher object to wasapi2 elements and mfvideosrc. But if an application doesn't provide ICoreDispatcher for wasapi2/mfvideosrc elements, then elements will try to access ICoreDispatcher by themselves.

An example code

// Must be called from UI thread
this->dispatcher= CoreWindow::GetForCurrentThread()->Dispatcher;
...
// From worker thread (non-UI thread)
GstElement *source = gst_element_factory_make ("wasapi2src", nullptr);
g_object_set (source, "dispatcher", this->dispatcher, nullptr);
wasapi2device: Allow empty caps for UWP use case

If the device has not been activated yet, caps might not be available.
wasapi2: Activate device asynchronously if required

In case of UWP, documentation from MS is saying that
ActivateAudioInterfaceAsync() method should be called from UI thread.
And the resulting callback might not happen until user interaction
has been made.
So we cannot wait the activation result on constructed() method.
and therefore we should return gst_wasapi2_client_new()
immediately without waiting the result if wasapi2 elements are
running on UWP application.
In addition to async operation fix, this commit includes COM object
reference counting issue around ActivateAudioInterfaceAsync() call.
wasapi2: Add a new property for ICoreDispatcher setting

... so that ensure device activation on UI thread.
mfvideosrc: Only device activation needs to be running on UI thread

... and the other operations does not have the thread constraint.
mfvideosrc: Add a new property for ICoreDispatcher setting

Since the commit c29c71ae9d46cc70e29e0cca2313917f319ef6f2,
device activation method will be called from an internal thread.

A problem is that, CoreApplication::GetCurrentView()
method will return nullptr if it was called from non-UI thread,
and as a result, currently implemented method for accessing ICoreDispatcher
will not work in any case. There seems to be no robust way for
accessing ICoreDispatcher other then setting it by user.

cc: @nirbheek

Merge request reports