typedef enum
{
+ GST_WASAPI2_CLIENT_ACTIVATE_NOT_FOUND = -2,
GST_WASAPI2_CLIENT_ACTIVATE_FAILED = -1,
GST_WASAPI2_CLIENT_ACTIVATE_INIT = 0,
GST_WASAPI2_CLIENT_ACTIVATE_WAIT,
}
/* *INDENT-ON* */
-static gboolean
+static void
gst_wasapi2_client_activate_async (GstWasapi2Client * self,
GstWasapiDeviceActivator * activator)
{
memset (&activation_params, 0, sizeof (GST_AUDIOCLIENT_ACTIVATION_PARAMS));
activation_params.ActivationType = GST_AUDIOCLIENT_ACTIVATION_TYPE_DEFAULT;
+ self->activate_state = GST_WASAPI2_CLIENT_ACTIVATE_NOT_FOUND;
+
if (self->device_class ==
GST_WASAPI2_CLIENT_DEVICE_CLASS_INCLUDE_PROCESS_LOOPBACK_CAPTURE ||
self->device_class ==
GST_WASAPI2_CLIENT_DEVICE_CLASS_EXCLUDE_PROCESS_LOOPBACK_CAPTURE) {
if (self->target_pid == 0) {
GST_ERROR_OBJECT (self, "Process loopback mode without PID");
- goto failed;
+ return;
}
if (!gst_wasapi2_can_process_loopback ()) {
GST_ERROR_OBJECT (self, "Process loopback is not supported");
- goto failed;
+ return;
}
process_loopback = TRUE;
default_device_id_wstring = gst_wasapi2_client_get_default_device_id (self);
if (default_device_id_wstring.empty ()) {
GST_WARNING_OBJECT (self, "Couldn't get default device id");
- goto failed;
+ return;
}
default_device_id = convert_wstring_to_string (default_device_id_wstring);
hr = GetActivationFactory (hstr_device_info.Get (), &device_info_static);
if (!gst_wasapi2_result (hr))
- goto failed;
+ return;
hr = device_info_static->FindAllAsyncDeviceClass (device_class, &async_op);
device_info_static.Reset ();
if (!gst_wasapi2_result (hr))
- goto failed;
+ return;
/* *INDENT-OFF* */
hr = SyncWait<DeviceInformationCollection*>(async_op.Get ());
/* *INDENT-ON* */
if (!gst_wasapi2_result (hr))
- goto failed;
+ return;
hr = async_op->GetResults (&device_list);
async_op.Reset ();
if (!gst_wasapi2_result (hr))
- goto failed;
+ return;
hr = device_list->get_Size (&count);
if (!gst_wasapi2_result (hr))
- goto failed;
+ return;
if (count == 0) {
GST_WARNING_OBJECT (self, "No available device");
- goto failed;
+ return;
}
/* device_index 0 will be assigned for default device
if (self->device_index >= 0 && self->device_index > (gint) count) {
GST_WARNING_OBJECT (self, "Device index %d is unavailable",
self->device_index);
- goto failed;
+ return;
}
GST_DEBUG_OBJECT (self, "Available device count: %d", count);
if (target_device_id_wstring.empty ()) {
GST_WARNING_OBJECT (self, "Couldn't find target device");
- goto failed;
+ return;
}
activate:
/* default device supports automatic stream routing */
self->can_auto_routing = use_default_device;
+ self->activate_state = GST_WASAPI2_CLIENT_ACTIVATE_INIT;
+
if (process_loopback) {
hr = activator->ActivateDeviceAsync (target_device_id_wstring,
&activation_params);
if (!gst_wasapi2_result (hr)) {
GST_WARNING_OBJECT (self, "Failed to activate device");
- goto failed;
+ self->activate_state = GST_WASAPI2_CLIENT_ACTIVATE_FAILED;
+ return;
}
g_mutex_lock (&self->lock);
if (self->activate_state == GST_WASAPI2_CLIENT_ACTIVATE_INIT)
self->activate_state = GST_WASAPI2_CLIENT_ACTIVATE_WAIT;
g_mutex_unlock (&self->lock);
-
- return TRUE;
-
-failed:
- self->activate_state = GST_WASAPI2_CLIENT_ACTIVATE_FAILED;
-
- return FALSE;
}
static const gchar *
activate_state_to_string (GstWasapi2ClientActivateState state)
{
switch (state) {
+ case GST_WASAPI2_CLIENT_ACTIVATE_NOT_FOUND:
+ return "NOT-FOUND";
case GST_WASAPI2_CLIENT_ACTIVATE_FAILED:
return "FAILED";
case GST_WASAPI2_CLIENT_ACTIVATE_INIT:
if (!gst_wasapi2_result (hr)) {
GST_ERROR_OBJECT (self, "Could not create activator object");
- self->activate_state = GST_WASAPI2_CLIENT_ACTIVATE_FAILED;
+ self->activate_state = GST_WASAPI2_CLIENT_ACTIVATE_NOT_FOUND;
goto run_loop;
}
* RoInitializeWrapper dtor is called */
core_dispatcher.Reset ();
- if (self->activate_state == GST_WASAPI2_CLIENT_ACTIVATE_FAILED) {
+ if (self->activate_state == GST_WASAPI2_CLIENT_ACTIVATE_FAILED ||
+ self->activate_state == GST_WASAPI2_CLIENT_ACTIVATE_NOT_FOUND) {
gst_object_unref (self);
return nullptr;
}
return self;
}
+GstWasapi2Result
+gst_wasapi2_client_enumerate (GstWasapi2ClientDeviceClass device_class,
+ gint device_index, GstWasapi2Client ** client)
+{
+ GstWasapi2Client *self;
+ /* *INDENT-OFF* */
+ ComPtr<ICoreDispatcher> core_dispatcher;
+ /* *INDENT-ON* */
+ /* Multiple COM init is allowed */
+ RoInitializeWrapper init_wrapper (RO_INIT_MULTITHREADED);
+
+ *client = nullptr;
+
+ find_dispatcher (&core_dispatcher);
+
+ self = (GstWasapi2Client *) g_object_new (GST_TYPE_WASAPI2_CLIENT,
+ "device-class", device_class, "device-index", device_index,
+ "dispatcher", core_dispatcher.Get (), nullptr);
+
+ /* Reset explicitly to ensure that it happens before
+ * RoInitializeWrapper dtor is called */
+ core_dispatcher.Reset ();
+
+ if (self->activate_state == GST_WASAPI2_CLIENT_ACTIVATE_NOT_FOUND) {
+ gst_object_unref (self);
+ return GST_WASAPI2_DEVICE_NOT_FOUND;
+ } else if (self->activate_state == GST_WASAPI2_CLIENT_ACTIVATE_FAILED) {
+ gst_object_unref (self);
+ return GST_WASAPI2_ACTIVATION_FAILED;
+ }
+
+ gst_object_ref_sink (self);
+
+ *client = self;
+ return GST_WASAPI2_OK;
+}
+
IAudioClient *
gst_wasapi2_client_get_handle (GstWasapi2Client * client)
{