Esempio n. 1
0
GstElement *
kms_element_get_data_tee (KmsElement * self)
{
  GstElement *sink, *tee;

  GST_DEBUG_OBJECT (self, "Data tee requested");
  KMS_ELEMENT_LOCK (self);
  if (self->priv->data_tee != NULL) {
    KMS_ELEMENT_UNLOCK (self);
    return self->priv->data_tee;
  }

  tee = gst_element_factory_make ("tee", NULL);

  sink = gst_element_factory_make ("fakesink", NULL);
  g_object_set (sink, "sync", FALSE, "async", FALSE, NULL);

  gst_bin_add_many (GST_BIN (self), tee, sink, NULL);
  gst_element_link (tee, sink);

  self->priv->data_tee = tee;
  KMS_ELEMENT_UNLOCK (self);

  gst_element_sync_state_with_parent (sink);
  gst_element_sync_state_with_parent (tee);

  kms_element_create_pending_pads (self, KMS_ELEMENT_PAD_TYPE_DATA);

  return tee;
}
Esempio n. 2
0
static void
kms_element_get_property (GObject * object, guint property_id,
    GValue * value, GParamSpec * pspec)
{
  KmsElement *self = KMS_ELEMENT (object);

  switch (property_id) {
    case PROP_ACCEPT_EOS:
      KMS_ELEMENT_LOCK (self);
      g_value_set_boolean (value, self->priv->accept_eos);
      KMS_ELEMENT_UNLOCK (self);
      break;
    case PROP_AUDIO_CAPS:
      g_value_take_boxed (value, kms_element_endpoint_get_caps (self,
              self->priv->audio_caps));
      break;
    case PROP_VIDEO_CAPS:
      g_value_take_boxed (value, kms_element_endpoint_get_caps (self,
              self->priv->video_caps));
      break;
    case PROP_TARGET_BITRATE:
      KMS_ELEMENT_LOCK (self);
      g_value_set_int (value, self->priv->target_bitrate);
      KMS_ELEMENT_UNLOCK (self);
      break;
    case PROP_MEDIA_STATS:
      KMS_ELEMENT_LOCK (self);
      g_value_set_boolean (value, self->priv->stats_enabled);
      KMS_ELEMENT_UNLOCK (self);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
      break;
  }
}
static void
kms_recorder_endpoint_get_property (GObject * object, guint property_id,
    GValue * value, GParamSpec * pspec)
{
  KmsRecorderEndpoint *self = KMS_RECORDER_ENDPOINT (object);

  KMS_ELEMENT_LOCK (KMS_ELEMENT (self));
  switch (property_id) {
    case PROP_DVR:
      g_value_set_boolean (value, self->priv->use_dvr);
      break;
    case PROP_PROFILE:{
      KmsRecordingProfile profile;

      g_object_get (G_OBJECT (self->priv->controller), "profile", &profile,
          NULL);
      g_value_set_enum (value, profile);
      break;
    }
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
      break;
  }
  KMS_ELEMENT_UNLOCK (KMS_ELEMENT (self));
}
Esempio n. 4
0
static void
kms_recorder_endpoint_paused (KmsUriEndpoint * obj)
{
  KmsRecorderEndpoint *self = KMS_RECORDER_ENDPOINT (obj);
  GstClock *clk;

  kms_recorder_endpoint_change_state (self, KMS_URI_ENDPOINT_STATE_PAUSE);

  kms_recorder_endpoint_remove_pads (self);

  KMS_ELEMENT_UNLOCK (self);

  /* Set internal pipeline to GST_STATE_PAUSED */
  kms_base_media_muxer_set_state (self->priv->mux, GST_STATE_PAUSED);

  KMS_ELEMENT_LOCK (self);

  clk = kms_base_media_muxer_get_clock (self->priv->mux);

  if (clk) {
    self->priv->paused_start = gst_clock_get_time (clk);
  }

  kms_recorder_endpoint_state_changed (self, KMS_URI_ENDPOINT_STATE_PAUSE);
}
Esempio n. 5
0
static void
kms_recorder_endpoint_started (KmsUriEndpoint * obj)
{
  KmsRecorderEndpoint *self = KMS_RECORDER_ENDPOINT (obj);

  kms_recorder_endpoint_create_parent_directories (self);

  kms_recorder_endpoint_change_state (self, KMS_URI_ENDPOINT_STATE_START);

  KMS_ELEMENT_UNLOCK (self);
  /* Set internal pipeline to playing */
  kms_base_media_muxer_set_state (self->priv->mux, GST_STATE_PLAYING);
  KMS_ELEMENT_LOCK (self);

  BASE_TIME_LOCK (self);

  if (GST_CLOCK_TIME_IS_VALID (self->priv->paused_start)) {
    self->priv->paused_time +=
        gst_clock_get_time (kms_base_media_muxer_get_clock (self->priv->mux)) -
        self->priv->paused_start;
    self->priv->paused_start = GST_CLOCK_TIME_NONE;
  }

  BASE_TIME_UNLOCK (self);

  kms_recorder_generate_pads (self);
}
Esempio n. 6
0
static void
kms_recorder_endpoint_stopped (KmsUriEndpoint * obj)
{
  KmsRecorderEndpoint *self = KMS_RECORDER_ENDPOINT (obj);

  if (self->priv->stopping) {
    return;
  }

  kms_recorder_endpoint_change_state (self, KMS_URI_ENDPOINT_STATE_STOP);

  if (kms_base_media_muxer_get_state (self->priv->mux) >= GST_STATE_PAUSED) {
    self->priv->stopping = TRUE;
    kms_recorder_endpoint_send_eos_to_appsrcs (self);
  }

  kms_recorder_endpoint_remove_pads (self);

  // Reset base time data
  BASE_TIME_LOCK (self);

  g_object_set_qdata_full (G_OBJECT (self), base_time_key_quark (), NULL, NULL);

  self->priv->paused_time = G_GUINT64_CONSTANT (0);
  self->priv->paused_start = GST_CLOCK_TIME_NONE;

  BASE_TIME_UNLOCK (self);

  if (kms_base_media_muxer_get_state (self->priv->mux) < GST_STATE_PAUSED &&
      !self->priv->stopping) {
    KMS_ELEMENT_UNLOCK (self);
    kms_base_media_muxer_set_state (self->priv->mux, GST_STATE_NULL);
    KMS_ELEMENT_LOCK (self);
  }
}
static void
kms_recorder_end_point_started (KmsUriEndPoint * obj)
{
  KmsRecorderEndPoint *self = KMS_RECORDER_END_POINT (obj);

  kms_recorder_end_point_change_state (self);

  /* Set internal pipeline to playing */
  gst_element_set_state (self->priv->pipeline, GST_STATE_PLAYING);

  KMS_ELEMENT_LOCK (self);

  if (GST_CLOCK_TIME_IS_VALID (self->priv->paused_start)) {
    self->priv->paused_time +=
        gst_clock_get_time (GST_ELEMENT (self->priv->pipeline)->clock) -
        self->priv->paused_start;
    self->priv->paused_start = GST_CLOCK_TIME_NONE;
  }

  KMS_ELEMENT_UNLOCK (self);

  /* Open valves */
  kms_recorder_end_point_open_valves (self);

  kms_recorder_end_point_state_changed (self, KMS_URI_END_POINT_STATE_START);
}
Esempio n. 8
0
static void
kms_recorder_endpoint_dispose (GObject * object)
{
  KmsRecorderEndpoint *self = KMS_RECORDER_ENDPOINT (object);

  GST_DEBUG_OBJECT (self, "dispose");

  KMS_ELEMENT_LOCK (KMS_ELEMENT (self));

  if (self->priv->mux != NULL) {
    if (kms_base_media_muxer_get_state (self->priv->mux) != GST_STATE_NULL) {
      GST_ELEMENT_WARNING (self, RESOURCE, BUSY,
          ("Recorder may have buffers to save"),
          ("Disposing recorder when it isn't stopped."));
    }

    kms_base_media_muxer_set_state (self->priv->mux, GST_STATE_NULL);

    if (self->priv->stopping) {
      GST_WARNING_OBJECT (self, "Forcing pending stop operation to finish");
      kms_recorder_endpoint_state_changed (self, KMS_URI_ENDPOINT_STATE_STOP);
      self->priv->stopping = FALSE;
    }
  }

  KMS_ELEMENT_UNLOCK (KMS_ELEMENT (self));

  g_mutex_clear (&self->priv->base_time_lock);

  /* clean up as possible.  may be called multiple times */

  G_OBJECT_CLASS (kms_recorder_endpoint_parent_class)->dispose (object);
}
Esempio n. 9
0
void
kms_element_remove_sink (KmsElement * self, GstPad * pad)
{
  GSList *l;

  g_return_if_fail (self);
  g_return_if_fail (pad);

  KMS_ELEMENT_LOCK (self);

  l = g_slist_find_custom (self->priv->stats.probes, pad,
      (GCompareFunc) find_stat_probe);

  if (l != NULL) {
    KmsStatsProbe *probe = l->data;

    self->priv->stats.probes = g_slist_remove (self->priv->stats.probes,
        l->data);
    kms_stats_probe_destroy (probe);
  }

  KMS_ELEMENT_UNLOCK (self);

  // TODO: Unlink correctly pad before removing it
  gst_ghost_pad_set_target (GST_GHOST_PAD (pad), NULL);
  gst_element_remove_pad (GST_ELEMENT (self), pad);
}
Esempio n. 10
0
static void
kms_recorder_endpoint_send_eos_to_appsrcs (KmsRecorderEndpoint * self)
{
  if (g_hash_table_size (self->priv->srcs) == 0) {
    KMS_ELEMENT_UNLOCK (KMS_ELEMENT (self));
    kms_base_media_muxer_set_state (self->priv->mux, GST_STATE_NULL);
    KMS_ELEMENT_LOCK (KMS_ELEMENT (self));
    return;
  }

  KMS_ELEMENT_UNLOCK (KMS_ELEMENT (self));
  kms_base_media_muxer_set_state (self->priv->mux, GST_STATE_PLAYING);
  KMS_ELEMENT_LOCK (KMS_ELEMENT (self));

  g_hash_table_foreach (self->priv->srcs, (GHFunc) send_eos_cb, NULL);
}
Esempio n. 11
0
static gboolean
kms_dummy_sink_release_requested_sink_pad (KmsElement * obj, GstPad * pad)
{
  KmsDummySink *self = KMS_DUMMY_SINK (obj);
  KmsDummySinkElement *dummy;
  gchar *padname;

  padname = gst_pad_get_name (pad);

  KMS_ELEMENT_LOCK (KMS_ELEMENT (self));

  dummy = g_hash_table_lookup (self->priv->sinks, padname);

  if (dummy == NULL) {
    KMS_ELEMENT_UNLOCK (KMS_ELEMENT (self));

    return FALSE;
  }

  kms_element_remove_sink_by_type_full (obj, dummy->type, dummy->description);
  g_hash_table_remove (self->priv->sinks, padname);
  g_free (padname);

  return TRUE;
}
Esempio n. 12
0
static void
kms_recorder_endpoint_set_property (GObject * object, guint property_id,
    const GValue * value, GParamSpec * pspec)
{
  KmsRecorderEndpoint *self = KMS_RECORDER_ENDPOINT (object);

  KMS_ELEMENT_LOCK (KMS_ELEMENT (self));
  switch (property_id) {
    case PROP_DVR:
      self->priv->use_dvr = g_value_get_boolean (value);
      break;
    case PROP_PROFILE:{
      if (self->priv->profile == KMS_RECORDING_PROFILE_NONE) {
        self->priv->profile = g_value_get_enum (value);

        if (self->priv->profile != KMS_RECORDING_PROFILE_NONE) {
          kms_recorder_endpoint_new_media_muxer (self);
        }
      } else {
        GST_ERROR_OBJECT (self, "Profile can only be configured once");
      }

      break;
    }
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
      break;
  }
  KMS_ELEMENT_UNLOCK (KMS_ELEMENT (self));
}
Esempio n. 13
0
static void
kms_element_set_sink_input_stats (KmsElement * self, GstPad * pad,
    KmsElementPadType type)
{
  KmsStatsProbe *s_probe;
  KmsMediaType media_type;

  switch (type) {
    case KMS_ELEMENT_PAD_TYPE_AUDIO:
      media_type = KMS_MEDIA_TYPE_AUDIO;
    case KMS_ELEMENT_PAD_TYPE_VIDEO:
      media_type = KMS_MEDIA_TYPE_VIDEO;
      break;
    default:
      GST_DEBUG ("No stats collected for pad type %d", type);
      return;
  }

  s_probe = kms_stats_probe_new (pad, media_type);

  KMS_ELEMENT_LOCK (self);

  self->priv->stats.probes = g_slist_prepend (self->priv->stats.probes,
      s_probe);

  if (self->priv->stats_enabled) {
    kms_stats_probe_add_latency (s_probe, kms_element_calculate_stats, self,
        NULL);
  }

  KMS_ELEMENT_UNLOCK (self);
}
Esempio n. 14
0
static GstPadProbeReturn
accept_eos_probe (GstPad * pad, GstPadProbeInfo * info, gpointer data)
{
  GstEvent *event = gst_pad_probe_info_get_event (info);
  GstEventType type = GST_EVENT_TYPE (event);

  if (type == GST_EVENT_EOS || type == GST_EVENT_FLUSH_START
      || type == GST_EVENT_FLUSH_STOP) {
    KmsElement *self;
    gboolean accept;

    self = KMS_ELEMENT (data);
    KMS_ELEMENT_LOCK (self);
    accept = self->priv->accept_eos;
    KMS_ELEMENT_UNLOCK (self);

    if (!accept) {
      GST_DEBUG_OBJECT (pad, "Event %s dropped",
          gst_event_type_get_name (type));
    }

    return (accept) ? GST_PAD_PROBE_OK : GST_PAD_PROBE_DROP;
  }

  return GST_PAD_PROBE_OK;
}
Esempio n. 15
0
static void
unlink_sinkpad_cb (GstPad * pad, GstPad * peer, gpointer user_data)
{
  KmsRecorderEndpoint *self = KMS_RECORDER_ENDPOINT (user_data);
  gchar *id = NULL;

  KMS_ELEMENT_LOCK (KMS_ELEMENT (self));

  id = gst_pad_get_name (pad);

  if (self->priv->stopping) {
    GST_DEBUG_OBJECT (self, "Stop operation is pending");
    self->priv->pending_pads = g_slist_prepend (self->priv->pending_pads,
        g_strdup (id));
    goto end;
  }

  if (kms_base_media_muxer_remove_src (self->priv->mux, id)) {
    g_hash_table_remove (self->priv->srcs, id);
  }

end:
  KMS_ELEMENT_UNLOCK (KMS_ELEMENT (self));

  g_free (id);
}
Esempio n. 16
0
static gchar *
kms_element_request_new_srcpad_action (KmsElement * self,
    KmsElementPadType type, const gchar * desc)
{
  const gchar *templ_name;
  gchar *pad_name;
  GstElement *element;

  KMS_ELEMENT_LOCK (self);

  if (!kms_element_get_data_by_type (self, type, &templ_name, &element)) {
    KMS_ELEMENT_UNLOCK (self);
    return NULL;
  }

  switch (type) {
    case KMS_ELEMENT_PAD_TYPE_DATA:
      pad_name = g_strdup_printf (templ_name, self->priv->data_pad_count++);
      break;
    case KMS_ELEMENT_PAD_TYPE_AUDIO:
      pad_name = g_strdup_printf (templ_name, self->priv->audio_pad_count++);
      break;
    case KMS_ELEMENT_PAD_TYPE_VIDEO:
      pad_name = g_strdup_printf (templ_name, self->priv->video_pad_count++);
      break;
    default:
      GST_WARNING_OBJECT (self, "Unsupported pad type %u", type);
      KMS_ELEMENT_UNLOCK (self);
      return NULL;
  }

  if (element == NULL) {
    PendingSrcPad *data;

    data = create_pendingpad (type, desc);
    g_hash_table_insert (self->priv->pendingpads, g_strdup (pad_name), data);
    KMS_ELEMENT_UNLOCK (self);

    return pad_name;
  }

  KMS_ELEMENT_UNLOCK (self);

  kms_element_add_src_pad (self, element, pad_name, templ_name);

  return pad_name;
}
Esempio n. 17
0
static void
kms_element_set_property (GObject * object, guint property_id,
    const GValue * value, GParamSpec * pspec)
{
  KmsElement *self = KMS_ELEMENT (object);

  switch (property_id) {
    case PROP_ACCEPT_EOS:
      KMS_ELEMENT_LOCK (self);
      self->priv->accept_eos = g_value_get_boolean (value);
      KMS_ELEMENT_UNLOCK (self);
      break;
    case PROP_AUDIO_CAPS:
      kms_element_endpoint_set_caps (self, gst_value_get_caps (value),
          &self->priv->audio_caps);
      break;
    case PROP_VIDEO_CAPS:
      kms_element_endpoint_set_caps (self, gst_value_get_caps (value),
          &self->priv->video_caps);
      break;
    case PROP_TARGET_BITRATE:
      KMS_ELEMENT_LOCK (self);
      self->priv->target_bitrate = g_value_get_int (value);
      g_object_set (G_OBJECT (kms_element_get_video_agnosticbin (self)),
          DEFAULT_BITRATE_, self->priv->target_bitrate, NULL);
      KMS_ELEMENT_UNLOCK (self);
      break;
    case PROP_MEDIA_STATS:{
      gboolean enable = g_value_get_boolean (value);

      KMS_ELEMENT_LOCK (self);
      if (enable != self->priv->stats_enabled) {
        self->priv->stats_enabled = enable;
        KMS_ELEMENT_GET_CLASS (self)->collect_media_stats (self, enable);
      }
      KMS_ELEMENT_UNLOCK (self);
      break;
    }
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
      break;
  }
}
Esempio n. 18
0
static void
kms_dummy_sink_set_property (GObject * object, guint property_id,
    const GValue * value, GParamSpec * pspec)
{
  KmsDummySink *self = KMS_DUMMY_SINK (object);
  gboolean val;

  KMS_ELEMENT_LOCK (KMS_ELEMENT (self));
  switch (property_id) {
    case PROP_DATA:
      val = g_value_get_boolean (value);
      if (val && !self->priv->data) {
        kms_dummy_sink_add_sinkpad (self, KMS_ELEMENT_PAD_TYPE_DATA);
      } else if (!val && self->priv->data) {
        kms_element_remove_sink_by_type (KMS_ELEMENT (self),
            KMS_ELEMENT_PAD_TYPE_DATA);
      } else {
        GST_DEBUG_OBJECT (self, "Operation without effect");
      }

      self->priv->data = val;
      break;
    case PROP_AUDIO:
      val = g_value_get_boolean (value);
      if (val && !self->priv->audio) {
        kms_dummy_sink_add_sinkpad (self, KMS_ELEMENT_PAD_TYPE_AUDIO);
      } else if (!val && self->priv->audio) {
        kms_element_remove_sink_by_type (KMS_ELEMENT (self),
            KMS_ELEMENT_PAD_TYPE_AUDIO);
      } else {
        GST_DEBUG_OBJECT (self, "Operation without effect");
      }

      self->priv->audio = val;
      break;
    case PROP_VIDEO:
      val = g_value_get_boolean (value);
      if (val && !self->priv->video) {
        kms_dummy_sink_add_sinkpad (self, KMS_ELEMENT_PAD_TYPE_VIDEO);
      } else if (!val && self->priv->video) {
        kms_element_remove_sink_by_type (KMS_ELEMENT (self),
            KMS_ELEMENT_PAD_TYPE_VIDEO);
      } else {
        GST_DEBUG_OBJECT (self, "Operation without effect");
      }

      self->priv->video = val;
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
      break;
  }
  KMS_ELEMENT_UNLOCK (KMS_ELEMENT (self));
}
Esempio n. 19
0
static GstFlowReturn
kms_http_post_endpoint_end_of_stream_action (KmsHttpPostEndpoint * self)
{
  GstFlowReturn ret;

  KMS_ELEMENT_LOCK (self);

  if (KMS_HTTP_ENDPOINT (self)->pipeline == NULL) {
    KMS_ELEMENT_UNLOCK (self);
    GST_ELEMENT_ERROR (self, RESOURCE, FAILED,
        ("Pipeline is not initialized"), GST_ERROR_SYSTEM);
    return GST_FLOW_ERROR;
  }

  KMS_ELEMENT_UNLOCK (self);

  g_signal_emit_by_name (self->priv->appsrc, "end-of-stream", &ret);

  return ret;
}
Esempio n. 20
0
static void
kms_recorder_endpoint_state_changed (KmsRecorderEndpoint * self,
    KmsUriEndpointState state)
{
  KMS_ELEMENT_LOCK (KMS_ELEMENT (self));
  if (!self->priv->stopping || state == KMS_URI_ENDPOINT_STATE_STOP) {
    KMS_URI_ENDPOINT_GET_CLASS (self)->change_state (KMS_URI_ENDPOINT (self),
        state);
  }
  KMS_ELEMENT_UNLOCK (KMS_ELEMENT (self));
}
Esempio n. 21
0
static gboolean
kms_dummy_sink_request_new_sink_pad (KmsElement * obj, KmsElementPadType type,
    const gchar * description, const gchar * name)
{
  KmsDummySink *self = KMS_DUMMY_SINK (obj);
  KmsDummySinkElement *dummy;
  GstElement *sink;
  GstPad *sinkpad;

  KMS_ELEMENT_LOCK (KMS_ELEMENT (self));

  if (g_hash_table_contains (self->priv->sinks, name)) {
    KMS_ELEMENT_UNLOCK (KMS_ELEMENT (self));

    return TRUE;
  }

  sink = gst_element_factory_make ("fakesink", NULL);
  g_object_set (sink, "async", FALSE, "sync", FALSE, NULL);

  dummy = create_dummy_sink_element (type, description, sink);

  if (!gst_bin_add (GST_BIN (self), sink)) {
    KMS_ELEMENT_UNLOCK (KMS_ELEMENT (self));
    destroy_dummy_sink_element (dummy);

    return FALSE;
  }

  g_hash_table_insert (self->priv->sinks, g_strdup (name), dummy);
  KMS_ELEMENT_UNLOCK (KMS_ELEMENT (self));

  gst_element_sync_state_with_parent (sink);

  sinkpad = gst_element_get_static_pad (sink, "sink");
  kms_element_connect_sink_target_full (KMS_ELEMENT (self), sinkpad, type,
      description, NULL, NULL);
  g_object_unref (sinkpad);

  return TRUE;
}
Esempio n. 22
0
GstElement *
kms_element_get_video_agnosticbin (KmsElement * self)
{
  GST_DEBUG_OBJECT (self, "Video agnostic requested");
  KMS_ELEMENT_LOCK (self);
  if (self->priv->video_agnosticbin != NULL) {
    KMS_ELEMENT_UNLOCK (self);
    return self->priv->video_agnosticbin;
  }

  self->priv->video_agnosticbin =
      gst_element_factory_make ("agnosticbin", NULL);

  gst_bin_add (GST_BIN (self), self->priv->video_agnosticbin);
  gst_element_sync_state_with_parent (self->priv->video_agnosticbin);
  KMS_ELEMENT_UNLOCK (self);

  kms_element_create_pending_pads (self, KMS_ELEMENT_PAD_TYPE_VIDEO);

  return self->priv->video_agnosticbin;
}
static void
kms_recorder_endpoint_set_property (GObject * object, guint property_id,
    const GValue * value, GParamSpec * pspec)
{
  KmsRecorderEndpoint *self = KMS_RECORDER_ENDPOINT (object);

  KMS_ELEMENT_LOCK (KMS_ELEMENT (self));
  switch (property_id) {
    case PROP_DVR:
      self->priv->use_dvr = g_value_get_boolean (value);
      break;
    case PROP_PROFILE:{
      if (self->priv->profile == KMS_RECORDING_PROFILE_NONE) {
        self->priv->profile = g_value_get_enum (value);

        if (self->priv->profile != KMS_RECORDING_PROFILE_NONE) {
          GstElement *sink;
          GstBus *bus;

          sink = kms_recorder_endpoint_create_sink (self);
          self->priv->mux =
              kms_muxing_pipeline_new (KMS_MUXING_PIPELINE_PROFILE,
              self->priv->profile, KMS_MUXING_PIPELINE_SINK, sink, NULL);
          g_object_unref (sink);

          bus = kms_muxing_pipeline_get_bus (self->priv->mux);
          gst_bus_set_sync_handler (bus, bus_sync_signal_handler, self, NULL);
          g_object_unref (bus);

          if (kms_recording_profile_supports_type (self->priv->profile,
                  KMS_ELEMENT_PAD_TYPE_AUDIO)) {
            kms_recorder_endpoint_add_appsink (self,
                KMS_ELEMENT_PAD_TYPE_AUDIO);
          }

          if (kms_recording_profile_supports_type (self->priv->profile,
                  KMS_ELEMENT_PAD_TYPE_VIDEO)) {
            kms_recorder_endpoint_add_appsink (self,
                KMS_ELEMENT_PAD_TYPE_VIDEO);
          }
        }
      } else {
        GST_ERROR_OBJECT (self, "Profile can only be configured once");
      }

      break;
    }
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
      break;
  }
  KMS_ELEMENT_UNLOCK (KMS_ELEMENT (self));
}
Esempio n. 24
0
static gboolean
kms_element_release_requested_srcpad_action (KmsElement * self,
    const gchar * pad_name)
{
  GValue item = G_VALUE_INIT;
  gboolean done = FALSE;
  gboolean released;
  GstIterator *it;
  GstPad *pad;

  KMS_ELEMENT_LOCK (self);
  released = g_hash_table_remove (self->priv->pendingpads, pad_name);
  KMS_ELEMENT_UNLOCK (self);

  if (released) {
    /* Pad was not created yet */
    return TRUE;
  }

  /* Pad is not in the pending list so it may have been already created */
  it = gst_element_iterate_src_pads (GST_ELEMENT (self));

  while (!done) {
    switch (gst_iterator_next (it, &item)) {
      case GST_ITERATOR_OK:{
        gchar *name;

        pad = g_value_get_object (&item);
        name = gst_pad_get_name (pad);
        if ((released = g_strcmp0 (name, pad_name) == 0)) {
          kms_element_remove_target_pad (self, pad);
          kms_element_release_pad (GST_ELEMENT (self), pad);
          done = TRUE;
        }
        g_value_reset (&item);
        g_free (name);
        break;
      }
      case GST_ITERATOR_RESYNC:
        gst_iterator_resync (it);
        break;
      case GST_ITERATOR_ERROR:
      case GST_ITERATOR_DONE:
        done = TRUE;
        break;
    }
  }

  gst_iterator_free (it);

  return released;
}
Esempio n. 25
0
static void
kms_element_create_pending_pads (KmsElement * self, KmsElementPadType type)
{
  GHashTableIter iter;
  gpointer key, value;
  GstElement *element;
  const gchar *templ_name;
  GSList *keys = NULL, *l;

  KMS_ELEMENT_LOCK (self);

  if (!kms_element_get_data_by_type (self, type, &templ_name, &element)) {
    KMS_ELEMENT_UNLOCK (self);
    return;
  }

  g_hash_table_iter_init (&iter, self->priv->pendingpads);
  while (g_hash_table_iter_next (&iter, &key, &value)) {
    PendingSrcPad *pendingpad = value;

    /* TODO: Discriminate pads using their description */
    if (pendingpad->type != type) {
      continue;
    }

    keys = g_slist_prepend (keys, g_strdup (key));
    g_hash_table_iter_remove (&iter);
  }

  KMS_ELEMENT_UNLOCK (self);

  /* Create all pending pads */
  for (l = keys; l != NULL; l = l->next) {
    kms_element_add_src_pad (self, element, l->data, templ_name);
  }

  g_slist_free_full (keys, g_free);
}
static void
kms_player_end_point_stopped (KmsUriEndPoint * obj)
{
  KmsPlayerEndPoint *self = KMS_PLAYER_END_POINT (obj);

  /* Set internal pipeline to NULL */
  gst_element_set_state (self->priv->pipeline, GST_STATE_NULL);
  KMS_ELEMENT_LOCK (self);
  g_object_set_data (G_OBJECT (self), BASE_TIME_DATA, NULL);
  KMS_ELEMENT_UNLOCK (self);

  KMS_URI_END_POINT_GET_CLASS (self)->change_state (KMS_URI_END_POINT (self),
      KMS_URI_END_POINT_STATE_STOP);
}
Esempio n. 27
0
static GstStructure *
kms_element_get_e2e_latency_stats (KmsRecorderEndpoint * self, gchar * selector)
{
  gpointer key, value;
  GHashTableIter iter;
  GstStructure *stats;

  stats = gst_structure_new_empty ("e2e-latencies");

  KMS_ELEMENT_LOCK (self);

  g_hash_table_iter_init (&iter, self->priv->stats.avg_e2e);

  while (g_hash_table_iter_next (&iter, &key, &value)) {
    StreamE2EAvgStat *avg = value;
    GstStructure *pad_latency;
    gchar *padname, *id = key;

    if (selector != NULL && ((g_strcmp0 (selector, AUDIO_STREAM_NAME) == 0 &&
                avg->type != KMS_MEDIA_TYPE_AUDIO) ||
            (g_strcmp0 (selector, VIDEO_STREAM_NAME) == 0 &&
                avg->type != KMS_MEDIA_TYPE_VIDEO))) {
      continue;
    }

    padname = kms_element_get_padname_from_id (self, id);

    if (padname == NULL) {
      GST_WARNING_OBJECT (self, "No pad identified by %s", id);
      continue;
    }

    /* Video and audio latencies are measured in nano seconds. They */
    /* are such an small values so there is no harm in casting them */
    /* to uint64 even we might lose a bit of preccision.            */

    pad_latency = gst_structure_new (padname, "type", G_TYPE_STRING,
        (avg->type ==
            KMS_MEDIA_TYPE_AUDIO) ? AUDIO_STREAM_NAME : VIDEO_STREAM_NAME,
        "avg", G_TYPE_UINT64, (guint64) avg->avg, NULL);

    gst_structure_set (stats, padname, GST_TYPE_STRUCTURE, pad_latency, NULL);
    gst_structure_free (pad_latency);
    g_free (padname);
  }

  KMS_ELEMENT_UNLOCK (self);

  return stats;
}
Esempio n. 28
0
static void
kms_recorder_endpoint_collect_media_stats (KmsElement * obj, gboolean enable)
{
  KmsRecorderEndpoint *self = KMS_RECORDER_ENDPOINT (obj);

  KMS_ELEMENT_LOCK (self);

  self->priv->stats.enabled = enable;
  kms_recorder_endpoint_update_media_stats (self);

  KMS_ELEMENT_UNLOCK (self);

  KMS_ELEMENT_CLASS
      (kms_recorder_endpoint_parent_class)->collect_media_stats (obj, enable);
}
Esempio n. 29
0
static void
kms_recorder_endpoint_state_changed (KmsRecorderEndpoint * self,
    KmsUriEndpointState state)
{
  KMS_URI_ENDPOINT_GET_CLASS (self)->change_state (KMS_URI_ENDPOINT (self),
      state);
  KMS_ELEMENT_UNLOCK (KMS_ELEMENT (self));

  g_mutex_lock (&self->priv->state_manager.mutex);
  self->priv->state_manager.changing = FALSE;
  if (self->priv->state_manager.locked > 0)
    g_cond_broadcast (&self->priv->state_manager.cond);
  g_mutex_unlock (&self->priv->state_manager.mutex);

  KMS_ELEMENT_LOCK (KMS_ELEMENT (self));
}
static gboolean
set_to_null_state_on_EOS (gpointer data)
{
  KmsRecorderEndpoint *recorder = KMS_RECORDER_ENDPOINT (data);

  GST_DEBUG ("Received EOS in pipeline, setting NULL state");

  KMS_ELEMENT_LOCK (KMS_ELEMENT (recorder));

  kms_muxing_pipeline_set_state (recorder->priv->mux, GST_STATE_NULL);

  kms_recorder_endpoint_state_changed (recorder, KMS_URI_ENDPOINT_STATE_STOP);

  KMS_ELEMENT_UNLOCK (KMS_ELEMENT (recorder));

  return G_SOURCE_REMOVE;
}