示例#1
0
static gboolean
gst_ks_video_src_start_worker (GstKsVideoSrc * self)
{
  GstKsVideoSrcPrivate *priv = GST_KS_VIDEO_SRC_GET_PRIVATE (self);
  gboolean result;

  priv->worker_lock = g_mutex_new ();
  priv->worker_notify_cond = g_cond_new ();
  priv->worker_result_cond = g_cond_new ();

  priv->worker_pending_caps = NULL;
  priv->worker_pending_run = FALSE;

  priv->worker_state = KS_WORKER_STATE_STARTING;
  priv->worker_thread =
      g_thread_create (gst_ks_video_src_worker_func, self, TRUE, NULL);

  KS_WORKER_LOCK (priv);
  while (priv->worker_state < KS_WORKER_STATE_READY)
    KS_WORKER_WAIT_FOR_RESULT (priv);
  result = priv->worker_state == KS_WORKER_STATE_READY;
  KS_WORKER_UNLOCK (priv);

  return result;
}
示例#2
0
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;
}
示例#3
0
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;
  }
}
示例#4
0
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;
  }
}