static void gst_ks_video_src_stop_worker (GstKsVideoSrc * self) { GstKsVideoSrcPrivate *priv = GST_KS_VIDEO_SRC_GET_PRIVATE (self); KS_WORKER_LOCK (priv); priv->worker_state = KS_WORKER_STATE_STOPPING; KS_WORKER_NOTIFY (priv); KS_WORKER_UNLOCK (priv); g_thread_join (priv->worker_thread); priv->worker_thread = NULL; g_cond_clear (&priv->worker_result_cond); g_cond_clear (&priv->worker_notify_cond); g_mutex_clear (&priv->worker_lock); }
static gboolean gst_ks_video_src_set_caps (GstBaseSrc * basesrc, GstCaps * caps) { GstKsVideoSrc *self = GST_KS_VIDEO_SRC (basesrc); GstKsVideoSrcPrivate *priv = GST_KS_VIDEO_SRC_GET_PRIVATE (self); if (priv->device == NULL) return FALSE; KS_WORKER_LOCK (priv); priv->worker_pending_caps = caps; KS_WORKER_NOTIFY (priv); while (priv->worker_pending_caps == caps) KS_WORKER_WAIT_FOR_RESULT (priv); KS_WORKER_UNLOCK (priv); return priv->worker_setcaps_result; }
static GstFlowReturn gst_ks_video_src_create (GstPushSrc * pushsrc, GstBuffer ** buf) { GstKsVideoSrc *self = GST_KS_VIDEO_SRC (pushsrc); GstKsVideoSrcPrivate *priv = GST_KS_VIDEO_SRC_GET_PRIVATE (self); GstFlowReturn result; GstClockTime presentation_time; gulong error_code; gchar *error_str; g_assert (priv->device != NULL); if (!gst_ks_video_device_has_caps (priv->device)) goto error_no_caps; if (G_UNLIKELY (!priv->running)) { KS_WORKER_LOCK (priv); priv->worker_pending_run = TRUE; KS_WORKER_NOTIFY (priv); while (priv->worker_pending_run) KS_WORKER_WAIT_FOR_RESULT (priv); priv->running = priv->worker_run_result; error_code = priv->worker_error_code; KS_WORKER_UNLOCK (priv); if (!priv->running) goto error_start_capture; } do { if (*buf != NULL) { gst_buffer_unref (*buf); *buf = NULL; } result = gst_ks_video_device_read_frame (priv->device, buf, &presentation_time, &error_code, &error_str); if (G_UNLIKELY (result != GST_FLOW_OK)) goto error_read_frame; } while (!gst_ks_video_src_timestamp_buffer (self, *buf, presentation_time)); if (G_UNLIKELY (priv->do_stats)) gst_ks_video_src_update_statistics (self); gst_ks_video_device_postprocess_frame (priv->device, GST_BUFFER_DATA (*buf), GST_BUFFER_SIZE (*buf)); return GST_FLOW_OK; /* ERRORS */ error_no_caps: { GST_ELEMENT_ERROR (self, CORE, NEGOTIATION, ("not negotiated"), ("maybe setcaps failed?")); return GST_FLOW_ERROR; } error_start_capture: { const gchar *debug_str = "failed to change pin state to KSSTATE_RUN"; switch (error_code) { case ERROR_FILE_NOT_FOUND: GST_ELEMENT_ERROR (self, RESOURCE, NOT_FOUND, ("failed to start capture (device unplugged)"), (debug_str)); break; case ERROR_NO_SYSTEM_RESOURCES: GST_ELEMENT_ERROR (self, RESOURCE, BUSY, ("failed to start capture (device already in use)"), (debug_str)); break; default: GST_ELEMENT_ERROR (self, RESOURCE, FAILED, ("failed to start capture (0x%08x)", error_code), (debug_str)); break; } return GST_FLOW_ERROR; } error_read_frame: { if (result == GST_FLOW_ERROR) { if (error_str != NULL) { GST_ELEMENT_ERROR (self, RESOURCE, READ, ("read failed: %s [0x%08x]", error_str, error_code), ("gst_ks_video_device_read_frame failed")); } } else if (result == GST_FLOW_UNEXPECTED) { GST_ELEMENT_ERROR (self, RESOURCE, READ, ("read failed"), ("gst_ks_video_device_read_frame failed")); } g_free (error_str); return result; } }
static GstFlowReturn gst_ks_video_src_create (GstPushSrc * pushsrc, GstBuffer ** buffer) { GstKsVideoSrc *self = GST_KS_VIDEO_SRC (pushsrc); GstKsVideoSrcPrivate *priv = GST_KS_VIDEO_SRC_GET_PRIVATE (self); guint buf_size; GstCaps *caps; GstBuffer *buf = NULL; GstFlowReturn result; GstClockTime presentation_time; gulong error_code; gchar *error_str; g_assert (priv->device != NULL); if (!gst_ks_video_device_has_caps (priv->device)) goto error_no_caps; buf_size = gst_ks_video_device_get_frame_size (priv->device); g_assert (buf_size); caps = gst_pad_get_negotiated_caps (GST_BASE_SRC_PAD (self)); if (caps == NULL) goto error_no_caps; result = gst_pad_alloc_buffer (GST_BASE_SRC_PAD (self), priv->offset, buf_size, caps, &buf); gst_caps_unref (caps); if (G_UNLIKELY (result != GST_FLOW_OK)) goto error_alloc_buffer; if (G_UNLIKELY (!priv->running)) { KS_WORKER_LOCK (priv); priv->worker_pending_run = TRUE; KS_WORKER_NOTIFY (priv); while (priv->worker_pending_run) KS_WORKER_WAIT_FOR_RESULT (priv); priv->running = priv->worker_run_result; KS_WORKER_UNLOCK (priv); if (!priv->running) goto error_start_capture; } do { gulong bytes_read; result = gst_ks_video_device_read_frame (priv->device, GST_BUFFER_DATA (buf), buf_size, &bytes_read, &presentation_time, &error_code, &error_str); if (G_UNLIKELY (result != GST_FLOW_OK)) goto error_read_frame; GST_BUFFER_SIZE (buf) = bytes_read; } while (!gst_ks_video_src_timestamp_buffer (self, buf, presentation_time)); if (G_UNLIKELY (priv->do_stats)) gst_ks_video_src_update_statistics (self); gst_ks_video_device_postprocess_frame (priv->device, GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf)); *buffer = buf; return GST_FLOW_OK; /* ERRORS */ error_no_caps: { GST_ELEMENT_ERROR (self, CORE, NEGOTIATION, ("not negotiated"), ("maybe setcaps failed?")); return GST_FLOW_ERROR; } error_start_capture: { GST_ELEMENT_ERROR (self, RESOURCE, OPEN_READ, ("could not start capture"), ("failed to change pin state to KSSTATE_RUN")); return GST_FLOW_ERROR; } error_alloc_buffer: { GST_ELEMENT_ERROR (self, CORE, PAD, ("alloc_buffer failed"), (NULL)); return result; } error_read_frame: { if (result != GST_FLOW_WRONG_STATE && result != GST_FLOW_UNEXPECTED) { GST_ELEMENT_ERROR (self, RESOURCE, READ, ("read failed: %s [0x%08x]", error_str, error_code), ("gst_ks_video_device_read_frame failed")); } g_free (error_str); gst_buffer_unref (buf); return result; } }