コード例 #1
0
ファイル: kmshubport.c プロジェクト: Kurento/kms-core
static GstPad *
kms_hub_port_generate_sink_pad (GstElement * element,
    GstPadTemplate * templ, const gchar * name, const GstCaps * caps,
    GstElement * output)
{
  GstPad *output_pad, *pad;

  output_pad = gst_element_get_static_pad (output, "sink");
  pad = gst_ghost_pad_new_from_template (name, output_pad, templ);
  g_object_unref (output_pad);

  if (GST_STATE (element) >= GST_STATE_PAUSED
      || GST_STATE_PENDING (element) >= GST_STATE_PAUSED
      || GST_STATE_TARGET (element) >= GST_STATE_PAUSED) {
    gst_pad_set_active (pad, TRUE);
  }

  if (gst_element_add_pad (element, pad))
    return pad;

  GST_ERROR_OBJECT (element, "Cannot add pad %" GST_PTR_FORMAT, pad);
  g_object_unref (pad);

  return NULL;
}
コード例 #2
0
ファイル: base-reader.c プロジェクト: step21/shmdata
//FIXME this should be part of the library
void
shmdata_base_reader_clean_element (GstElement *element)
{
    if (element != NULL && GST_IS_ELEMENT(element)
            && GST_STATE_CHANGE_FAILURE != GST_STATE_RETURN(element)) {
        {   // unlinking pads
            GstIterator *pad_iter = gst_element_iterate_pads(element);
            gst_iterator_foreach(pad_iter, (GFunc) shmdata_base_reader_unlink_pad, NULL);
            gst_iterator_free(pad_iter);
        }
        {   // releasing request pads
            GstIterator *pad_iter = gst_element_iterate_pads(element);
            gst_iterator_foreach(pad_iter,
                                 (GFunc) shmdata_base_reader_release_request_pad,
                                 element);
            gst_iterator_free(pad_iter);
        }

        GstState state = GST_STATE_TARGET(element);
        if (state != GST_STATE_NULL) {
            if (GST_STATE_CHANGE_ASYNC ==
                    gst_element_set_state(element, GST_STATE_NULL)) {
                while (GST_STATE(element) != GST_STATE_NULL) {
                    // warning this may be blocking
                    gst_element_get_state(element, NULL, NULL,
                                          GST_CLOCK_TIME_NONE);
                }
            }
        }
        if (GST_IS_BIN(gst_element_get_parent(element)))
            gst_bin_remove(GST_BIN(gst_element_get_parent(element)), element);
        else
            gst_object_unref(element);
    }
}
コード例 #3
0
static gboolean
kms_base_hub_create_and_link_ghost_pad (KmsBaseHub * mixer,
    GstPad * src_pad, const gchar * gp_name, const gchar * gp_template_name,
    GstPad * target)
{
  GstPadTemplate *templ;
  GstPad *gp;
  gboolean ret;

  templ =
      gst_element_class_get_pad_template (GST_ELEMENT_CLASS
      (G_OBJECT_GET_CLASS (mixer)), gp_template_name);
  gp = gst_ghost_pad_new_from_template (gp_name, target, templ);

  if (GST_STATE (mixer) >= GST_STATE_PAUSED
      || GST_STATE_PENDING (mixer) >= GST_STATE_PAUSED
      || GST_STATE_TARGET (mixer) >= GST_STATE_PAUSED) {
    gst_pad_set_active (gp, TRUE);
  }

  ret = gst_element_add_pad (GST_ELEMENT (mixer), gp);

  if (ret) {
    gst_pad_link (src_pad, gp);
  } else {
    g_object_unref (gp);
  }

  return ret;
}
コード例 #4
0
ファイル: kmsaudiomixer.c プロジェクト: KennyDark/kms-core
static void
kms_audio_mixer_remove_sometimes_src_pad (KmsAudioMixer * self,
    GstElement * adder)
{
  GstProxyPad *internal;
  GstPad *srcpad, *peer;

  srcpad = gst_element_get_static_pad (adder, "src");
  peer = gst_pad_get_peer (srcpad);
  if (peer == NULL)
    goto end_phase_1;

  internal = gst_proxy_pad_get_internal ((GstProxyPad *) peer);
  if (internal == NULL)
    goto end_phase_2;

  gst_ghost_pad_set_target (GST_GHOST_PAD (internal), NULL);

  if (GST_STATE (self) < GST_STATE_PAUSED
      || GST_STATE_PENDING (self) < GST_STATE_PAUSED
      || GST_STATE_TARGET (self) < GST_STATE_PAUSED) {
    gst_pad_set_active (GST_PAD (internal), FALSE);
  }

  GST_DEBUG ("Removing source pad %" GST_PTR_FORMAT, internal);

  gst_element_remove_pad (GST_ELEMENT (self), GST_PAD (internal));
  gst_object_unref (internal);

end_phase_2:
  gst_object_unref (peer);

end_phase_1:
  gst_object_unref (srcpad);
}
コード例 #5
0
ファイル: kmshubport.c プロジェクト: Kurento/kms-core
static void
kms_hub_port_start_media_type (KmsElement * self, KmsElementPadType type,
    GstPadTemplate * templ, const gchar * pad_name)
{
  GstElement *capsfilter = gst_element_factory_make ("capsfilter", NULL);
  GstPad *src = gst_element_get_static_pad (capsfilter, "src");
  GstPad *internal_src;

  gst_bin_add (GST_BIN (self), capsfilter);
  gst_element_sync_state_with_parent (capsfilter);

  internal_src = gst_ghost_pad_new_from_template (pad_name, src, templ);

  g_object_set_qdata_full (G_OBJECT (internal_src), key_elem_data_quark (),
      g_object_ref (capsfilter), g_object_unref);
  g_object_set_qdata (G_OBJECT (internal_src), key_type_data_quark (),
      GINT_TO_POINTER (type));

  g_signal_connect (internal_src, "linked",
      G_CALLBACK (kms_hub_port_internal_src_pad_linked), NULL);

  if (GST_STATE (self) >= GST_STATE_PAUSED
      || GST_STATE_PENDING (self) >= GST_STATE_PAUSED
      || GST_STATE_TARGET (self) >= GST_STATE_PAUSED) {
    gst_pad_set_active (internal_src, TRUE);
  }

  gst_element_add_pad (GST_ELEMENT (self), internal_src);
  g_object_unref (src);
}
static void
type_found (GstElement * typefind, guint probability,
    GstCaps * caps, GstSplitMuxPartReader * reader)
{
  GstElement *demux;

  GST_INFO_OBJECT (reader, "Got type %" GST_PTR_FORMAT, caps);

  /* typefind found a type. Look for the demuxer to handle it */
  demux = reader->demux = find_demuxer (caps);
  if (reader->demux == NULL) {
    GST_ERROR_OBJECT (reader, "Failed to create demuxer element");
    return;
  }

  /* Connect to demux signals */
  g_signal_connect (demux,
      "pad-added", G_CALLBACK (new_decoded_pad_added_cb), reader);
  g_signal_connect (demux, "no-more-pads", G_CALLBACK (no_more_pads), reader);

  gst_element_set_locked_state (demux, TRUE);
  gst_bin_add (GST_BIN_CAST (reader), demux);
  gst_element_link_pads (reader->typefind, "src", demux, NULL);
  gst_element_set_state (reader->demux, GST_STATE_TARGET (reader));
  gst_element_set_locked_state (demux, FALSE);
}
コード例 #7
0
ファイル: gst-utils.cpp プロジェクト: dulton/switcher
void GstUtils::sync_state_with_parent(GstElement *element) {
  if (!GST_IS_ELEMENT(element)) {
    g_debug("GstUtils::sync_state_with_parent, arg is not an element");
    return;
  }

  GstElement *parent = GST_ELEMENT(GST_ELEMENT_PARENT(element));
  if (GST_IS_ELEMENT(parent)) {
    if (GST_STATE(parent) != GST_STATE_TARGET(parent))
      gst_element_set_state(element, GST_STATE_TARGET(parent));
    else
      gst_element_sync_state_with_parent(element);
  }
  else
    g_warning
        ("GstUtils::sync_state_with_parent, cannot sync an orphan element");
}
コード例 #8
0
static gboolean
kms_base_hub_link_src_pad (KmsBaseHub * mixer, const gchar * gp_name,
    const gchar * template_name, GstElement * internal_element,
    const gchar * pad_name, gboolean remove_on_unlink)
{
  GstPad *gp, *target;
  gboolean ret;

  if (GST_OBJECT_PARENT (internal_element) != GST_OBJECT (mixer)) {
    GST_ERROR_OBJECT (mixer, "Cannot link %" GST_PTR_FORMAT " wrong hierarchy",
        internal_element);
    return FALSE;
  }

  target = gst_element_get_static_pad (internal_element, pad_name);
  if (target == NULL) {
    target = gst_element_get_request_pad (internal_element, pad_name);

    if (target != NULL && remove_on_unlink) {
      g_signal_connect (G_OBJECT (target), "unlinked",
          G_CALLBACK (remove_unlinked_pad), NULL);
    }
  }

  if (target == NULL) {
    GST_ERROR_OBJECT (mixer, "Cannot get target pad");
    return FALSE;
  }

  gp = gst_element_get_static_pad (GST_ELEMENT (mixer), gp_name);

  if (gp == NULL) {
    GstPadTemplate *templ;

    templ =
        gst_element_class_get_pad_template (GST_ELEMENT_CLASS
        (G_OBJECT_GET_CLASS (mixer)), template_name);
    gp = gst_ghost_pad_new_from_template (gp_name, target, templ);

    if (GST_STATE (mixer) >= GST_STATE_PAUSED
        || GST_STATE_PENDING (mixer) >= GST_STATE_PAUSED
        || GST_STATE_TARGET (mixer) >= GST_STATE_PAUSED) {
      gst_pad_set_active (gp, TRUE);
    }

    ret = gst_element_add_pad (GST_ELEMENT (mixer), gp);
    if (!ret) {
      g_object_unref (gp);
    }
  } else {
    ret = set_target (gp, target);
    g_object_unref (gp);
  }

  g_object_unref (target);

  return ret;
}
コード例 #9
0
ファイル: gst-utils.cpp プロジェクト: dulton/switcher
void GstUtils::wait_state_changed(GstElement *bin) {
  if (!GST_IS_BIN(bin)) {
    g_warning("GstUtils::wait_state_changed not a bin");
    return;
  }
  GValue val = G_VALUE_INIT;
  g_value_init(&val, G_TYPE_BOOLEAN);

  g_object_get_property(G_OBJECT(bin), "async-handling", &val);

  if (g_value_get_boolean(&val) == FALSE)
    while (GST_STATE(bin) != GST_STATE_TARGET(bin)) {
      g_debug("GstUtils::wait_state_changed, from %s to %s",
              gst_element_state_get_name(GST_STATE(bin)),
              gst_element_state_get_name(GST_STATE_TARGET(bin)));
      // warning this may be blocking
      gst_element_get_state(bin, nullptr, nullptr, GST_CLOCK_TIME_NONE);
    }
  g_value_unset(&val);
  return;
}
コード例 #10
0
static void
gst_decklink_video_sink_state_changed (GstElement * element,
    GstState old_state, GstState new_state, GstState pending_state)
{
  GstDecklinkVideoSink *self = GST_DECKLINK_VIDEO_SINK_CAST (element);

  // Aka gst_element_lost_state()
  if (old_state == GST_STATE_PAUSED &&
      new_state == GST_STATE_PAUSED && pending_state == GST_STATE_PAUSED &&
      GST_STATE_TARGET (element) == GST_STATE_PLAYING) {
    gst_decklink_video_sink_stop_scheduled_playback (self);
  }
}
コード例 #11
0
ファイル: kmselement.c プロジェクト: shelsonjava/kms-core
GstPad *
kms_element_connect_sink_target_full (KmsElement * self, GstPad * target,
    KmsElementPadType type, const gchar * description)
{
  GstPad *pad;
  gchar *pad_name;
  GstPadTemplate *templ;

  templ = gst_static_pad_template_get (&sink_factory);

  pad_name = get_pad_name (type, description);

  pad = gst_ghost_pad_new_from_template (pad_name, target, templ);
  g_free (pad_name);
  g_object_unref (templ);

  if (type == KMS_ELEMENT_PAD_TYPE_VIDEO) {
    kms_utils_drop_until_keyframe (pad, TRUE);
    kms_utils_manage_gaps (pad);
  }

  gst_pad_set_query_function (pad, kms_element_pad_query);
  gst_pad_add_probe (pad,
      GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM | GST_PAD_PROBE_TYPE_EVENT_FLUSH,
      accept_eos_probe, self, NULL);
  g_signal_connect (G_OBJECT (pad), "unlinked",
      G_CALLBACK (send_flush_on_unlink), NULL);

  if (GST_STATE (self) >= GST_STATE_PAUSED
      || GST_STATE_PENDING (self) >= GST_STATE_PAUSED
      || GST_STATE_TARGET (self) >= GST_STATE_PAUSED) {
    gst_pad_set_active (pad, TRUE);
  }

  if (gst_element_add_pad (GST_ELEMENT (self), pad)) {
    kms_element_set_sink_input_stats (self, pad, type);
    return pad;
  }

  g_object_unref (pad);

  return NULL;
}
コード例 #12
0
ファイル: kmsutils.c プロジェクト: 2bees-rd/kms-core
gboolean
gst_element_sync_state_with_parent_target_state (GstElement * element)
{
  GstElement *parent;
  GstState target;
  GstStateChangeReturn ret;

  g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);

  parent = GST_ELEMENT_CAST (gst_element_get_parent (element));

  if (parent == NULL) {
    GST_DEBUG_OBJECT (element, "element has no parent");
    return FALSE;
  }

  GST_OBJECT_LOCK (parent);
  target = GST_STATE_TARGET (parent);
  GST_OBJECT_UNLOCK (parent);

  GST_DEBUG_OBJECT (element,
      "setting parent (%s) target state %s",
      GST_ELEMENT_NAME (parent), gst_element_state_get_name (target));

  gst_object_unref (parent);

  ret = gst_element_set_state (element, target);
  if (ret == GST_STATE_CHANGE_FAILURE) {
    GST_DEBUG_OBJECT (element,
        "setting target state failed (%s)",
        gst_element_state_change_return_get_name (ret));

    return FALSE;
  }

  return TRUE;
}
コード例 #13
0
ファイル: kmselement.c プロジェクト: shelsonjava/kms-core
static void
kms_element_add_src_pad (KmsElement * self, GstElement * element,
    const gchar * pad_name, const gchar * templ_name)
{
  GstPad *srcpad;

  srcpad =
      gst_ghost_pad_new_no_target_from_template (pad_name,
      gst_element_class_get_pad_template (GST_ELEMENT_CLASS
          (G_OBJECT_GET_CLASS (self)), templ_name));

  if (GST_STATE (self) >= GST_STATE_PAUSED
      || GST_STATE_PENDING (self) >= GST_STATE_PAUSED
      || GST_STATE_TARGET (self) >= GST_STATE_PAUSED)
    gst_pad_set_active (srcpad, TRUE);

  g_signal_connect (srcpad, "linked",
      G_CALLBACK (kms_element_set_target_on_linked), element);

  g_signal_connect (srcpad, "unlinked",
      G_CALLBACK (kms_element_remove_target_on_unlinked), element);

  gst_element_add_pad (GST_ELEMENT (self), srcpad);
}
コード例 #14
0
ファイル: base-reader.c プロジェクト: step21/shmdata
gboolean
shmdata_base_reader_attach (shmdata_base_reader_t *reader)
{
    g_mutex_lock (&reader->mutex_);
    if (reader->attached_)
    {
        g_mutex_unlock (&reader->mutex_);
        return FALSE;
    }
    reader->attached_ = TRUE;
    reader->source_ = gst_element_factory_make ("shmsrc", NULL);
    reader->deserializer_ = gst_element_factory_make ("gdpdepay", NULL);
    GstPad *pad = gst_element_get_static_pad(reader->deserializer_, "src");
    gst_pad_add_data_probe (pad,
                            G_CALLBACK (shmdata_base_reader_reset_time),
                            reader);
    gst_object_unref(pad);
    reader->typefind_ = gst_element_factory_make ("typefind", NULL);
    if (NULL == reader->typefind_) {
        g_warning ("no typefind !");
        g_mutex_unlock (&reader->mutex_);
        return FALSE;
    }
    reader->have_type_handler_id_ =
        g_signal_connect (reader->typefind_,
                          "have-type",
                          G_CALLBACK (shmdata_base_reader_on_type_found),
                          reader);
    if (reader->do_absolute_)
        reader->timereset_ = FALSE;
    if (!reader->source_)
    {
        g_critical ("Reader: \"shmsrc\" element could not be created");
        g_mutex_unlock (&reader->mutex_);
        return FALSE;
    }
    if (!reader->deserializer_)
    {
        g_critical ("Reader: \"gdpdepay\" element could not be created.");
        g_mutex_unlock (&reader->mutex_);
        return FALSE;
    }
    if (!reader->typefind_)
    {
        g_critical ("Reader: \"typefind\" element could not be created.");
        g_mutex_unlock (&reader->mutex_);
        return FALSE;
    }
    g_object_set_data (G_OBJECT (reader->source_),
                       "shmdata_base_reader",
                       (gpointer)reader);
    g_object_set_data (G_OBJECT (reader->deserializer_),
                       "shmdata_base_reader",
                       (gpointer)reader);
    g_object_set (G_OBJECT (reader->source_), "socket-path",
                  reader->socket_name_, NULL);
    gst_bin_add_many (GST_BIN (reader->bin_),
                      reader->source_, reader->deserializer_, reader->typefind_, NULL);
    GstPad *src_pad = gst_element_get_static_pad (reader->typefind_,
                      "src");
    GstPad *sink_pad = gst_element_get_compatible_pad (reader->sink_,
                       src_pad,
                       GST_PAD_CAPS(src_pad));
    gst_element_link_many (reader->source_,
                           reader->deserializer_,
                           reader->typefind_,
                           NULL);
    gst_pad_link (src_pad, sink_pad);
    gst_object_unref(sink_pad);
    gst_object_unref(src_pad);
    gst_element_set_state (reader->typefind_,GST_STATE_TARGET(reader->bin_));
    gst_element_set_state (reader->deserializer_,GST_STATE_TARGET(reader->bin_));
    gst_element_set_state (reader->source_,GST_STATE_TARGET(reader->bin_));
    g_mutex_unlock (&reader->mutex_);
    return FALSE; //for g_idle_add
}
コード例 #15
0
static GstPad *
kms_element_request_new_pad (GstElement * element,
    GstPadTemplate * templ, const gchar * name, const GstCaps * caps)
{
  GstPad *ret_pad = NULL;
  gchar *pad_name;
  gboolean added;

  KMS_ELEMENT_LOCK (element);
  if (templ ==
      gst_element_class_get_pad_template (GST_ELEMENT_CLASS (G_OBJECT_GET_CLASS
              (element)), "audio_src_%u")) {
    pad_name = g_strdup_printf ("audio_src_%d",
        KMS_ELEMENT (element)->priv->audio_pad_count++);

    ret_pad = kms_element_generate_src_pad (KMS_ELEMENT (element), pad_name,
        KMS_ELEMENT (element)->priv->audio_agnosticbin, templ);
    if (ret_pad == NULL)
      KMS_ELEMENT (element)->priv->audio_pad_count--;

    g_free (pad_name);

  } else if (templ ==
      gst_element_class_get_pad_template (GST_ELEMENT_CLASS (G_OBJECT_GET_CLASS
              (element)), "video_src_%u")) {
    pad_name = g_strdup_printf ("video_src_%d",
        KMS_ELEMENT (element)->priv->video_pad_count++);

    ret_pad = kms_element_generate_src_pad (KMS_ELEMENT (element), pad_name,
        KMS_ELEMENT (element)->priv->video_agnosticbin, templ);
    if (ret_pad == NULL)
      KMS_ELEMENT (element)->priv->video_pad_count--;

    g_free (pad_name);

  } else if (templ ==
      gst_element_class_get_pad_template (GST_ELEMENT_CLASS (G_OBJECT_GET_CLASS
              (element)), AUDIO_SINK_PAD)) {
    ret_pad =
        kms_element_generate_sink_pad (KMS_ELEMENT (element), AUDIO_SINK_PAD,
        &KMS_ELEMENT (element)->priv->audio_valve, templ);

    gst_pad_add_probe (ret_pad, GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM,
        accept_eos_probe, element, NULL);

    g_signal_connect (G_OBJECT (ret_pad), "unlinked",
        G_CALLBACK (send_flush_on_unlink), NULL);
  } else if (templ ==
      gst_element_class_get_pad_template (GST_ELEMENT_CLASS (G_OBJECT_GET_CLASS
              (element)), VIDEO_SINK_PAD)) {
    ret_pad =
        kms_element_generate_sink_pad (KMS_ELEMENT (element), VIDEO_SINK_PAD,
        &KMS_ELEMENT (element)->priv->video_valve, templ);

    gst_pad_add_probe (ret_pad, GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM,
        accept_eos_probe, element, NULL);

    g_signal_connect (G_OBJECT (ret_pad), "unlinked",
        G_CALLBACK (send_flush_on_unlink), NULL);
  }

  if (ret_pad == NULL) {
    KMS_ELEMENT_UNLOCK (element);
    GST_WARNING ("No pad created");
    return NULL;
  }

  if (GST_STATE (element) >= GST_STATE_PAUSED
      || GST_STATE_PENDING (element) >= GST_STATE_PAUSED
      || GST_STATE_TARGET (element) >= GST_STATE_PAUSED)
    gst_pad_set_active (ret_pad, TRUE);

  added = gst_element_add_pad (element, ret_pad);
  KMS_ELEMENT_UNLOCK (element);

  if (added)
    return ret_pad;

  if (gst_pad_get_direction (ret_pad) == GST_PAD_SRC) {
    GstPad *target = gst_ghost_pad_get_target (GST_GHOST_PAD (ret_pad));

    if (target != NULL) {
      GstElement *agnostic = gst_pad_get_parent_element (target);

      gst_element_release_request_pad (agnostic, target);
      g_object_unref (target);
      g_object_unref (agnostic);
    }
  }

  g_object_unref (ret_pad);
  return NULL;
}
コード例 #16
0
static GstPad *
gst_sctp_base_sink_request_new_pad (GstElement * element,
    GstPadTemplate * templ, const gchar * name, const GstCaps * caps)
{
  GstSCTPBaseSink *self = GST_SCTP_BASE_SINK (element);
  GstPad *sinkpad, *ghostpad;
  GstElement *sctpclientsink;
  gchar *padname;
  gchar *pad_id;
  gint64 val;
  guint16 id;

  GST_SCTP_BASE_SINK_LOCK (self);
  if (self->priv->num_ostreams < self->priv->streams) {
    GST_SCTP_BASE_SINK_UNLOCK (self);
    GST_WARNING ("No more available streams");
    return NULL;
  }

  pad_id = get_stream_id_from_padname (name);
  if (pad_id == NULL) {
    GST_SCTP_BASE_SINK_UNLOCK (self);
    GST_WARNING
        ("Link of elements without using pad names is not yet supported");
    return NULL;
  }

  val = g_ascii_strtoll (pad_id, NULL, 10);
  g_free (pad_id);

  if (val > G_MAXUINT32) {
    GST_SCTP_BASE_SINK_UNLOCK (self);
    GST_ERROR ("SCTP stream id %" G_GINT64_FORMAT " is not valid", val);
    return NULL;
  }

  id = val;

  sctpclientsink = gst_element_factory_make ("sctpclientsink", NULL);
  sinkpad = gst_element_get_static_pad (sctpclientsink, "sink");
  if (sinkpad == NULL) {
    GST_SCTP_BASE_SINK_UNLOCK (self);
    GST_ERROR_OBJECT (sctpclientsink, "Can not get sink pad");
    gst_object_unref (sctpclientsink);
    return NULL;
  }

  g_object_set (sctpclientsink, "stream-id", id, "socket", self->priv->socket,
      NULL);

  gst_bin_add (GST_BIN (element), sctpclientsink);
  gst_element_sync_state_with_parent (sctpclientsink);

  padname = g_strdup_printf ("sink_%u", id);
  ghostpad = gst_ghost_pad_new_from_template (padname, sinkpad, templ);

  g_object_unref (sinkpad);
  g_free (padname);

  if (GST_STATE (element) >= GST_STATE_PAUSED
      || GST_STATE_PENDING (element) >= GST_STATE_PAUSED
      || GST_STATE_TARGET (element) >= GST_STATE_PAUSED)
    gst_pad_set_active (ghostpad, TRUE);

  gst_element_add_pad (element, ghostpad);

  self->priv->streams++;
  GST_SCTP_BASE_SINK_UNLOCK (self);

  return ghostpad;
}
コード例 #17
0
/* GstElement vfuncs */
static GstPad *
gst_stream_synchronizer_request_new_pad (GstElement * element,
    GstPadTemplate * temp, const gchar * name, const GstCaps * caps)
{
  GstStreamSynchronizer *self = GST_STREAM_SYNCHRONIZER (element);
  GstStream *stream;
  gchar *tmp;

  GST_STREAM_SYNCHRONIZER_LOCK (self);
  GST_DEBUG_OBJECT (self, "Requesting new pad for stream %d",
      self->current_stream_number);

  stream = g_slice_new0 (GstStream);
  stream->transform = self;
  stream->stream_number = self->current_stream_number;
  g_cond_init (&stream->stream_finish_cond);
  stream->stream_start_seqnum = G_MAXUINT32;
  stream->segment_seqnum = G_MAXUINT32;

  tmp = g_strdup_printf ("sink_%u", self->current_stream_number);
  stream->sinkpad = gst_pad_new_from_static_template (&sinktemplate, tmp);
  g_free (tmp);
  gst_pad_set_element_private (stream->sinkpad, stream);
  gst_pad_set_iterate_internal_links_function (stream->sinkpad,
      GST_DEBUG_FUNCPTR (gst_stream_synchronizer_iterate_internal_links));
  gst_pad_set_query_function (stream->sinkpad,
      GST_DEBUG_FUNCPTR (gst_stream_synchronizer_query));
  gst_pad_set_event_function (stream->sinkpad,
      GST_DEBUG_FUNCPTR (gst_stream_synchronizer_sink_event));
  gst_pad_set_chain_function (stream->sinkpad,
      GST_DEBUG_FUNCPTR (gst_stream_synchronizer_sink_chain));

  tmp = g_strdup_printf ("src_%u", self->current_stream_number);
  stream->srcpad = gst_pad_new_from_static_template (&srctemplate, tmp);
  g_free (tmp);
  gst_pad_set_element_private (stream->srcpad, stream);
  gst_pad_set_iterate_internal_links_function (stream->srcpad,
      GST_DEBUG_FUNCPTR (gst_stream_synchronizer_iterate_internal_links));
  gst_pad_set_query_function (stream->srcpad,
      GST_DEBUG_FUNCPTR (gst_stream_synchronizer_query));
  gst_pad_set_event_function (stream->srcpad,
      GST_DEBUG_FUNCPTR (gst_stream_synchronizer_src_event));

  gst_segment_init (&stream->segment, GST_FORMAT_UNDEFINED);

  self->streams = g_list_prepend (self->streams, stream);
  self->current_stream_number++;
  GST_STREAM_SYNCHRONIZER_UNLOCK (self);

  /* Add pads and activate unless we're going to NULL */
  g_rec_mutex_lock (GST_STATE_GET_LOCK (self));
  if (GST_STATE_TARGET (self) != GST_STATE_NULL) {
    gst_pad_set_active (stream->srcpad, TRUE);
    gst_pad_set_active (stream->sinkpad, TRUE);
  }
  gst_element_add_pad (GST_ELEMENT_CAST (self), stream->srcpad);
  gst_element_add_pad (GST_ELEMENT_CAST (self), stream->sinkpad);
  g_rec_mutex_unlock (GST_STATE_GET_LOCK (self));

  return stream->sinkpad;
}