static void gst_ks_video_device_close_current_pin (GstKsVideoDevice * self) { GstKsVideoDevicePrivate *priv = GST_KS_VIDEO_DEVICE_GET_PRIVATE (self); if (!ks_is_valid_handle (priv->pin_handle)) return; gst_ks_video_device_set_state (self, KSSTATE_STOP); CloseHandle (priv->pin_handle); priv->pin_handle = INVALID_HANDLE_VALUE; }
/* * Worker thread that takes care of starting, configuring and stopping things. * * This is needed because Logitech's driver software injects a DLL that * intercepts API functions like NtCreateFile, NtClose, NtDeviceIoControlFile * and NtDuplicateObject so that they can provide in-place video effects to * existing applications. Their assumption is that at least one thread tainted * by their code stays around for the lifetime of the capture. */ static gpointer gst_ks_video_src_worker_func (gpointer data) { GstKsVideoSrc *self = data; GstKsVideoSrcPrivate *priv = GST_KS_VIDEO_SRC_GET_PRIVATE (self); if (!gst_ks_video_src_open_device (self)) goto open_failed; KS_WORKER_LOCK (priv); priv->worker_state = KS_WORKER_STATE_READY; KS_WORKER_NOTIFY_RESULT (priv); while (priv->worker_state != KS_WORKER_STATE_STOPPING) { KS_WORKER_WAIT (priv); if (priv->worker_pending_caps != NULL) { priv->worker_setcaps_result = gst_ks_video_device_set_caps (priv->device, priv->worker_pending_caps); priv->worker_pending_caps = NULL; KS_WORKER_NOTIFY_RESULT (priv); } else if (priv->worker_pending_run) { if (priv->ksclock != NULL) gst_ks_clock_start (priv->ksclock); priv->worker_run_result = gst_ks_video_device_set_state (priv->device, KSSTATE_RUN, &priv->worker_error_code); priv->worker_pending_run = FALSE; KS_WORKER_NOTIFY_RESULT (priv); } } KS_WORKER_UNLOCK (priv); gst_ks_video_src_close_device (self); return NULL; /* ERRORS */ open_failed: { KS_WORKER_LOCK (priv); priv->worker_state = KS_WORKER_STATE_ERROR; KS_WORKER_NOTIFY_RESULT (priv); KS_WORKER_UNLOCK (priv); return NULL; } }