static gboolean
gst_auto_video_convert_add_autoconvert (GstAutoVideoConvert * autovideoconvert)
{
  GstPad *pad;

  if (autovideoconvert->autoconvert)
    return TRUE;

  autovideoconvert->autoconvert =
      gst_element_factory_make ("autoconvert", "autoconvertchild");
  if (!autovideoconvert->autoconvert) {
    GST_ERROR_OBJECT (autovideoconvert,
        "Could not create autoconvert instance");
    return FALSE;
  }

  /* first add autoconvert in bin */
  gst_bin_add (GST_BIN (autovideoconvert),
      gst_object_ref (autovideoconvert->autoconvert));

  /* get sinkpad and link it to ghost sink pad */
  pad = gst_element_get_static_pad (autovideoconvert->autoconvert, "sink");
  gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (autovideoconvert->sinkpad),
      pad);
  gst_object_unref (pad);

  /* get srcpad and link it to ghost src pad */
  pad = gst_element_get_static_pad (autovideoconvert->autoconvert, "src");
  gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (autovideoconvert->srcpad), pad);
  gst_object_unref (pad);

  return TRUE;
}
static gboolean
gst_play_sink_convert_bin_sink_setcaps (GstPlaySinkConvertBin * self,
    GstCaps * caps)
{
  GstStructure *s;
  const gchar *name;
  gboolean reconfigure = FALSE;
  gboolean raw;

  GST_DEBUG_OBJECT (self, "setcaps");
  GST_PLAY_SINK_CONVERT_BIN_LOCK (self);
  s = gst_caps_get_structure (caps, 0);
  name = gst_structure_get_name (s);

  if (self->audio) {
    raw = g_str_equal (name, "audio/x-raw");
  } else {
    raw = g_str_equal (name, "video/x-raw");
  }

  GST_DEBUG_OBJECT (self, "raw %d, self->raw %d, blocked %d",
      raw, self->raw, gst_pad_is_blocked (self->sink_proxypad));

  if (raw) {
    if (!gst_pad_is_blocked (self->sink_proxypad)) {
      GstPad *target = gst_ghost_pad_get_target (GST_GHOST_PAD (self->sinkpad));

      if (!self->raw || (target && !gst_pad_query_accept_caps (target, caps))) {
        if (!self->raw)
          GST_DEBUG_OBJECT (self, "Changing caps from non-raw to raw");
        else
          GST_DEBUG_OBJECT (self, "Changing caps in an incompatible way");

        reconfigure = TRUE;
        block_proxypad (self);
      }

      if (target)
        gst_object_unref (target);
    }
  } else {
    if (self->raw && !gst_pad_is_blocked (self->sink_proxypad)) {
      GST_DEBUG_OBJECT (self, "Changing caps from raw to non-raw");
      reconfigure = TRUE;
      block_proxypad (self);
    }
  }

  /* Otherwise the setcaps below fails */
  if (reconfigure) {
    gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (self->sinkpad), NULL);
    gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (self->srcpad), NULL);
  }

  GST_PLAY_SINK_CONVERT_BIN_UNLOCK (self);

  GST_DEBUG_OBJECT (self, "Setting sink caps %" GST_PTR_FORMAT, caps);

  return TRUE;
}
static GstPadProbeReturn
pad_blocked_cb (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
{
  GstPlaySinkConvertBin *self = user_data;
  GstPad *peer;
  GstCaps *caps;
  gboolean raw;

  if (GST_IS_EVENT (info->data) && !GST_EVENT_IS_SERIALIZED (info->data)) {
    GST_DEBUG_OBJECT (self, "Letting non-serialized event %s pass",
        GST_EVENT_TYPE_NAME (info->data));
    return GST_PAD_PROBE_PASS;
  }

  GST_PLAY_SINK_CONVERT_BIN_LOCK (self);
  GST_DEBUG_OBJECT (self, "Pad blocked");

  /* There must be a peer at this point */
  peer = gst_pad_get_peer (self->sinkpad);
  caps = gst_pad_get_current_caps (peer);
  if (!caps)
    caps = gst_pad_query_caps (peer, NULL);
  gst_object_unref (peer);

  raw = is_raw_caps (caps, self->audio);
  GST_DEBUG_OBJECT (self, "Caps %" GST_PTR_FORMAT " are raw: %d", caps, raw);
  gst_caps_unref (caps);

  if (raw == self->raw)
    goto unblock;
  self->raw = raw;

  gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (self->sinkpad), NULL);
  gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (self->srcpad), NULL);

  if (raw) {
    GST_DEBUG_OBJECT (self, "Switching to raw conversion pipeline");

    if (self->conversion_elements)
      g_list_foreach (self->conversion_elements,
          (GFunc) gst_play_sink_convert_bin_on_element_added, self);
  } else {

    GST_DEBUG_OBJECT (self, "Switch to passthrough pipeline");

    gst_play_sink_convert_bin_on_element_added (self->identity, self);
  }

  gst_play_sink_convert_bin_set_targets (self, !raw);

unblock:
  self->sink_proxypad_block_id = 0;
  GST_PLAY_SINK_CONVERT_BIN_UNLOCK (self);

  return GST_PAD_PROBE_REMOVE;
}
static void
gst_insert_bin_dispose (GObject * object)
{
  GstInsertBin *self = GST_INSERT_BIN (object);
  struct ChangeData *data;

  while ((data = g_queue_pop_head (&self->priv->change_queue)))
    gst_insert_bin_change_data_complete (self, data, FALSE);

  gst_ghost_pad_set_target (GST_GHOST_PAD (self->priv->srcpad), NULL);
  gst_ghost_pad_set_target (GST_GHOST_PAD (self->priv->sinkpad), NULL);

  G_OBJECT_CLASS (gst_insert_bin_parent_class)->dispose (object);
}
static gboolean
gst_play_sink_video_convert_sink_setcaps (GstPad * pad, GstCaps * caps)
{
    GstPlaySinkVideoConvert *self =
        GST_PLAY_SINK_VIDEO_CONVERT (gst_pad_get_parent (pad));
    gboolean ret;
    GstStructure *s;
    const gchar *name;
    gboolean reconfigure = FALSE;

    GST_PLAY_SINK_VIDEO_CONVERT_LOCK (self);
    s = gst_caps_get_structure (caps, 0);
    name = gst_structure_get_name (s);

    if (g_str_has_prefix (name, "video/x-raw-")) {
        if (!self->raw && !gst_pad_is_blocked (self->sink_proxypad)) {
            GST_DEBUG_OBJECT (self, "Changing caps from non-raw to raw");
            reconfigure = TRUE;
            gst_pad_set_blocked_async_full (self->sink_proxypad, TRUE,
                                            (GstPadBlockCallback) pad_blocked_cb, gst_object_ref (self),
                                            (GDestroyNotify) gst_object_unref);
        }
    } else {
        if (self->raw && !gst_pad_is_blocked (self->sink_proxypad)) {
            GST_DEBUG_OBJECT (self, "Changing caps from raw to non-raw");
            reconfigure = TRUE;
            gst_pad_set_blocked_async_full (self->sink_proxypad, TRUE,
                                            (GstPadBlockCallback) pad_blocked_cb, gst_object_ref (self),
                                            (GDestroyNotify) gst_object_unref);
        }
    }

    /* Otherwise the setcaps below fails */
    if (reconfigure) {
        gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (self->sinkpad), NULL);
        gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (self->srcpad), NULL);
    }
    GST_PLAY_SINK_VIDEO_CONVERT_UNLOCK (self);

    ret = gst_ghost_pad_setcaps_default (pad, caps);

    GST_DEBUG_OBJECT (self, "Setting sink caps %" GST_PTR_FORMAT ": %d", caps,
                      ret);

    gst_object_unref (self);

    return ret;
}
예제 #6
0
static gboolean
gst_auto_video_sink_detect (GstAutoVideoSink * sink)
{
  GstElement *esink;
  GstPad *targetpad;

  gst_auto_video_sink_clear_kid (sink);

  /* find element */
  GST_DEBUG_OBJECT (sink, "Creating new kid");
  if (!(esink = gst_auto_video_sink_find_best (sink)))
    goto no_sink;

  sink->kid = esink;
  gst_bin_add (GST_BIN (sink), esink);

  /* attach ghost pad */
  GST_DEBUG_OBJECT (sink, "Re-assigning ghostpad");
  targetpad = gst_element_get_pad (sink->kid, "sink");
  gst_ghost_pad_set_target (GST_GHOST_PAD (sink->pad), targetpad);
  gst_object_unref (targetpad);
  GST_DEBUG_OBJECT (sink, "done changing auto video sink");

  return TRUE;

  /* ERRORS */
no_sink:
  {
    GST_ELEMENT_ERROR (sink, LIBRARY, INIT, (NULL),
        ("Failed to find a supported video sink"));
    return FALSE;
  }
}
예제 #7
0
GstPad *
gst_ghost_pad_new_from_template (const gchar * name, GstPad * target,
    GstPadTemplate * templ)
{
  GstPad *ret;

  g_return_val_if_fail (GST_IS_PAD (target), NULL);
  g_return_val_if_fail (!gst_pad_is_linked (target), NULL);
  g_return_val_if_fail (templ != NULL, NULL);
  g_return_val_if_fail (GST_PAD_TEMPLATE_DIRECTION (templ) ==
      GST_PAD_DIRECTION (target), NULL);

  GST_LOG ("name:%s, target:%s:%s, templ:%p", GST_STR_NULL (name),
      GST_DEBUG_PAD_NAME (target), templ);

  if ((ret = gst_ghost_pad_new_full (name, GST_PAD_DIRECTION (target), templ)))
    if (!gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (ret), target))
      goto set_target_failed;

  return ret;

  /* ERRORS */
set_target_failed:
  {
    GST_WARNING_OBJECT (ret, "failed to set target %s:%s",
        GST_DEBUG_PAD_NAME (target));
    gst_object_unref (ret);
    return NULL;
  }
}
예제 #8
0
static gboolean
set_target (GstPad * gp, GstPad * target)
{
  GstPad *old_target;
  GstPad *peer;

  old_target = gst_ghost_pad_get_target (GST_GHOST_PAD (gp));
  if (old_target == NULL) {
    goto end;
  }
  peer = gst_pad_get_peer (old_target);

  if (peer != NULL) {
    if (peer->direction == GST_PAD_SINK) {
      gst_pad_unlink (old_target, peer);
    } else {
      gst_pad_unlink (peer, old_target);
    }
    g_object_unref (peer);
  }
  g_object_unref (old_target);

end:
  return gst_ghost_pad_set_target (GST_GHOST_PAD (gp), target);
}
예제 #9
0
static gboolean
gst_gconf_video_sink_reset (GstGConfVideoSink * sink)
{
  GstPad *targetpad;

  /* fakesink */
  if (sink->kid) {
    gst_element_set_state (sink->kid, GST_STATE_NULL);
    gst_bin_remove (GST_BIN (sink), sink->kid);
  }
  sink->kid = gst_element_factory_make ("fakesink", "testsink");
  if (!sink->kid) {
    GST_ERROR_OBJECT (sink, "Failed to create fakesink");
    return FALSE;
  }
  gst_bin_add (GST_BIN (sink), sink->kid);

  targetpad = gst_element_get_static_pad (sink->kid, "sink");
  gst_ghost_pad_set_target (GST_GHOST_PAD (sink->pad), targetpad);
  gst_object_unref (targetpad);

  g_free (sink->gconf_str);
  sink->gconf_str = NULL;

  return TRUE;
}
예제 #10
0
static gboolean
do_toggle_element (GstHalAudioSink * sink)
{
  GstPad *targetpad;

  /* kill old element */
  if (sink->kid) {
    GST_DEBUG_OBJECT (sink, "Removing old kid");
    gst_element_set_state (sink->kid, GST_STATE_NULL);
    gst_bin_remove (GST_BIN (sink), sink->kid);
    sink->kid = NULL;
  }

  GST_DEBUG_OBJECT (sink, "Creating new kid");
  if (!sink->udi)
    GST_INFO_OBJECT (sink, "No UDI set for device, using default one");

  if (!(sink->kid = gst_hal_get_audio_sink (sink->udi))) {
    GST_ELEMENT_ERROR (sink, LIBRARY, SETTINGS, (NULL),
        ("Failed to render audio sink from Hal"));
    return FALSE;
  }
  gst_element_set_state (sink->kid, GST_STATE (sink));
  gst_bin_add (GST_BIN (sink), sink->kid);

  /* re-attach ghostpad */
  GST_DEBUG_OBJECT (sink, "Creating new ghostpad");
  targetpad = gst_element_get_static_pad (sink->kid, "sink");
  gst_ghost_pad_set_target (GST_GHOST_PAD (sink->pad), targetpad);
  gst_object_unref (targetpad);
  GST_DEBUG_OBJECT (sink, "done changing hal audio sink");

  return TRUE;
}
예제 #11
0
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);
}
예제 #12
0
EXPORT_C
#endif

GstPad *
gst_ghost_pad_new (const gchar * name, GstPad * target)
{
  GstPad *ret;

  g_return_val_if_fail (GST_IS_PAD (target), NULL);
  g_return_val_if_fail (!gst_pad_is_linked (target), NULL);

  GST_LOG ("name:%s, target:%s:%s", GST_STR_NULL (name),
      GST_DEBUG_PAD_NAME (target));

  if ((ret = gst_ghost_pad_new_no_target (name, GST_PAD_DIRECTION (target))))
    if (!gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (ret), target))
      goto set_target_failed;

  return ret;

  /* ERRORS */
set_target_failed:
  {
    GST_WARNING_OBJECT (ret, "failed to set target %s:%s",
        GST_DEBUG_PAD_NAME (target));
    gst_object_unref (ret);
    return NULL;
  }
}
예제 #13
0
static void
kms_agnostic_bin2_link_to_tee (KmsAgnosticBin2 * self, GstPad * pad,
    GstElement * tee, GstCaps * caps)
{
  GstElement *queue = gst_element_factory_make ("queue", NULL);
  GstPad *target;

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

  if (!gst_caps_is_any (caps) && is_raw_caps (caps)) {
    GstElement *convert = kms_utils_create_convert_for_caps (caps);
    GstElement *rate = kms_utils_create_rate_for_caps (caps);
    GstElement *mediator = kms_utils_create_mediator_element (caps);

    remove_element_on_unlinked (convert, "src", "sink");
    remove_element_on_unlinked (rate, "src", "sink");
    remove_element_on_unlinked (mediator, "src", "sink");

    gst_bin_add_many (GST_BIN (self), convert, rate, mediator, NULL);

    gst_element_sync_state_with_parent (mediator);
    gst_element_sync_state_with_parent (convert);
    gst_element_sync_state_with_parent (rate);

    gst_element_link_many (queue, rate, convert, mediator, NULL);
    target = gst_element_get_static_pad (mediator, "src");
  } else {
    target = gst_element_get_static_pad (queue, "src");
  }

  gst_ghost_pad_set_target (GST_GHOST_PAD (pad), target);
  g_object_unref (target);
  link_element_to_tee (tee, queue);
}
예제 #14
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);
}
예제 #15
0
static void
gst_auto_video_convert_remove_autoconvert (GstAutoVideoConvert *
    autovideoconvert)
{
  if (!autovideoconvert->autoconvert)
    return;

  gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (autovideoconvert->srcpad),
      NULL);
  gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (autovideoconvert->sinkpad),
      NULL);

  gst_bin_remove (GST_BIN (autovideoconvert), autovideoconvert->autoconvert);
  gst_object_unref (autovideoconvert->autoconvert);
  autovideoconvert->autoconvert = NULL;
}
예제 #16
0
/*
 * gst_camerabin_image_link_first_element:
 * @img: a pointer to #GstCameraBinImage object
 * @elem: first element to be linked on imagebin
 *
 * Adds given element to imagebin and links it to imagebin's ghost sink pad.
 *
 * Returns: %TRUE if adding and linking succeeded, %FALSE otherwise
 */
static gboolean
gst_camerabin_image_link_first_element (GstCameraBinImage * imagebin,
    GstElement * elem)
{
  GstPad *first_sinkpad = NULL;
  gboolean ret = FALSE;

  g_return_val_if_fail (imagebin != NULL, FALSE);
  /* Link given element to imagebin ghost sink pad */
  if (gst_bin_add (GST_BIN (imagebin), elem)) {
    first_sinkpad = gst_element_get_static_pad (elem, "sink");
    if (first_sinkpad) {
      if (gst_ghost_pad_set_target (GST_GHOST_PAD (imagebin->sinkpad),
              first_sinkpad)) {
        ret = TRUE;
      } else {
        GST_WARNING ("linking first element failed");
      }
      gst_object_unref (first_sinkpad);
    } else {
      GST_WARNING ("no sink pad in first element");
    }
  } else {
    GST_WARNING ("adding element failed");
  }
  return ret;
}
static void
gst_play_sink_video_convert_init (GstPlaySinkVideoConvert * self)
{
    GstPadTemplate *templ;

    self->lock = g_mutex_new ();
    gst_segment_init (&self->segment, GST_FORMAT_UNDEFINED);

    templ = gst_static_pad_template_get (&sinktemplate);
    self->sinkpad = gst_ghost_pad_new_no_target_from_template ("sink", templ);
    gst_pad_set_event_function (self->sinkpad,
                                GST_DEBUG_FUNCPTR (gst_play_sink_video_convert_sink_event));
    gst_pad_set_setcaps_function (self->sinkpad,
                                  GST_DEBUG_FUNCPTR (gst_play_sink_video_convert_sink_setcaps));
    gst_pad_set_getcaps_function (self->sinkpad,
                                  GST_DEBUG_FUNCPTR (gst_play_sink_video_convert_getcaps));

    self->sink_proxypad =
        GST_PAD_CAST (gst_proxy_pad_get_internal (GST_PROXY_PAD (self->sinkpad)));

    gst_element_add_pad (GST_ELEMENT_CAST (self), self->sinkpad);
    gst_object_unref (templ);

    templ = gst_static_pad_template_get (&srctemplate);
    self->srcpad = gst_ghost_pad_new_no_target_from_template ("src", templ);
    gst_pad_set_getcaps_function (self->srcpad,
                                  GST_DEBUG_FUNCPTR (gst_play_sink_video_convert_getcaps));
    gst_element_add_pad (GST_ELEMENT_CAST (self), self->srcpad);
    gst_object_unref (templ);

    gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (self->srcpad),
                              self->sink_proxypad);
}
예제 #18
0
static gboolean
do_toggle_element (GstGConfVideoSrc * src)
{
  GstPad *targetpad;
  gchar *new_gconf_str;
  GstState cur, next;

  new_gconf_str = gst_gconf_get_string (GST_GCONF_AUDIOSRC_KEY);
  if (new_gconf_str != NULL && src->gconf_str != NULL &&
      (strlen (new_gconf_str) == 0 ||
          strcmp (src->gconf_str, new_gconf_str) == 0)) {
    g_free (new_gconf_str);
    GST_DEBUG_OBJECT (src, "GConf key was updated, but it didn't change");
    return TRUE;
  }

  GST_OBJECT_LOCK (src);
  cur = GST_STATE (src);
  next = GST_STATE_PENDING (src);
  GST_OBJECT_UNLOCK (src);

  if (cur >= GST_STATE_READY || next == GST_STATE_PAUSED) {
    GST_DEBUG_OBJECT (src, "already running, ignoring GConf change");
    g_free (new_gconf_str);
    return TRUE;
  }

  g_free (src->gconf_str);
  src->gconf_str = new_gconf_str;

  /* kill old element */
  if (src->kid) {
    GST_DEBUG_OBJECT (src, "Removing old kid");
    gst_element_set_state (src->kid, GST_STATE_NULL);
    gst_bin_remove (GST_BIN (src), src->kid);
    src->kid = NULL;
  }

  GST_DEBUG_OBJECT (src, "Creating new kid");
  if (!(src->kid = gst_gconf_get_default_video_src ())) {
    GST_ELEMENT_ERROR (src, LIBRARY, SETTINGS, (NULL),
        ("Failed to render video source from GConf"));
    g_free (src->gconf_str);
    src->gconf_str = NULL;
    return FALSE;
  }
  gst_element_set_state (src->kid, GST_STATE (src));
  gst_bin_add (GST_BIN (src), src->kid);

  /* re-attach ghostpad */
  GST_DEBUG_OBJECT (src, "Creating new ghostpad");
  targetpad = gst_element_get_static_pad (src->kid, "src");
  gst_ghost_pad_set_target (GST_GHOST_PAD (src->pad), targetpad);
  gst_object_unref (targetpad);
  GST_DEBUG_OBJECT (src, "done changing gconf video source");

  return TRUE;
}
예제 #19
0
static gboolean
_create_input_chain (GstGLMixerBin * self, struct input_chain *chain,
    GstPad * mixer_pad)
{
  GstGLMixerBinClass *klass = GST_GL_MIXER_BIN_GET_CLASS (self);
  GstPad *pad;
  gboolean res = TRUE;
  gchar *name;

  chain->self = self;
  chain->mixer_pad = mixer_pad;

  chain->upload = gst_element_factory_make ("glupload", NULL);
  chain->in_convert = gst_element_factory_make ("glcolorconvert", NULL);

  res &= gst_bin_add (GST_BIN (self), chain->in_convert);
  res &= gst_bin_add (GST_BIN (self), chain->upload);

  pad = gst_element_get_static_pad (chain->in_convert, "src");
  if (gst_pad_link (pad, mixer_pad) != GST_PAD_LINK_OK) {
    gst_object_unref (pad);
    return FALSE;
  }
  gst_object_unref (pad);
  res &=
      gst_element_link_pads (chain->upload, "src", chain->in_convert, "sink");

  pad = gst_element_get_static_pad (chain->upload, "sink");
  if (!pad) {
    return FALSE;
  } else {
    GST_DEBUG_OBJECT (self, "setting target sink pad %" GST_PTR_FORMAT, pad);
    name = gst_object_get_name (GST_OBJECT (mixer_pad));
    if (klass->create_input_pad) {
      chain->ghost_pad = klass->create_input_pad (self, chain->mixer_pad);
      gst_object_set_name (GST_OBJECT (chain->ghost_pad), name);
      gst_ghost_pad_set_target (chain->ghost_pad, pad);
    } else {
      chain->ghost_pad =
          GST_GHOST_PAD (gst_ghost_pad_new (GST_PAD_NAME (chain->mixer_pad),
              pad));
    }
    g_free (name);

    GST_OBJECT_LOCK (self);
    if (self->priv->running)
      gst_pad_set_active (GST_PAD (chain->ghost_pad), TRUE);
    GST_OBJECT_UNLOCK (self);

    gst_element_add_pad (GST_ELEMENT_CAST (self), GST_PAD (chain->ghost_pad));
    gst_object_unref (pad);
  }

  gst_element_sync_state_with_parent (chain->upload);
  gst_element_sync_state_with_parent (chain->in_convert);

  return TRUE;
}
예제 #20
0
static void
kms_agnostic_bin2_link_to_tee (KmsAgnosticBin2 * self, GstPad * pad,
    GstElement * tee, GstCaps * caps)
{
  GstElement *queue = gst_element_factory_make ("queue", NULL);
  GstPad *target;
  GstProxyPad *proxy;

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

  if (!(gst_caps_is_any (caps) || gst_caps_is_empty (caps))
      && kms_utils_caps_are_raw (caps)) {
    GstElement *convert = kms_utils_create_convert_for_caps (caps);
    GstElement *rate = kms_utils_create_rate_for_caps (caps);
    GstElement *mediator = kms_utils_create_mediator_element (caps);

    remove_element_on_unlinked (convert, "src", "sink");
    if (rate) {
      remove_element_on_unlinked (rate, "src", "sink");
    }
    remove_element_on_unlinked (mediator, "src", "sink");

    if (rate) {
      gst_bin_add (GST_BIN (self), rate);
    }

    gst_bin_add_many (GST_BIN (self), convert, mediator, NULL);

    gst_element_sync_state_with_parent (mediator);
    gst_element_sync_state_with_parent (convert);
    if (rate) {
      gst_element_sync_state_with_parent (rate);
    }

    if (rate) {
      gst_element_link_many (queue, rate, mediator, NULL);
    } else {
      gst_element_link (queue, mediator);
    }

    gst_element_link_many (mediator, convert, NULL);
    target = gst_element_get_static_pad (convert, "src");
  } else {
    target = gst_element_get_static_pad (queue, "src");
  }

  gst_ghost_pad_set_target (GST_GHOST_PAD (pad), target);

  proxy = gst_proxy_pad_get_internal (GST_PROXY_PAD (pad));
  gst_pad_set_query_function (GST_PAD_CAST (proxy),
      proxy_src_pad_query_function);
  g_object_unref (proxy);

  g_object_unref (target);
  link_element_to_tee (tee, queue);
}
예제 #21
0
/*
 * gst_camerabin_image_destroy_elements:
 * @img: a pointer to #GstCameraBinImage object
 *
 * This function releases resources allocated in
 * gst_camerabin_image_create_elements.
 *
 */
static void
gst_camerabin_image_destroy_elements (GstCameraBinImage * img)
{
  GST_LOG ("destroying image elements");

  gst_ghost_pad_set_target (GST_GHOST_PAD (img->sinkpad), NULL);

  gst_camerabin_remove_elements_from_bin (GST_BIN (img));
}
static GstStateChangeReturn
gst_play_sink_video_convert_change_state (GstElement * element,
        GstStateChange transition)
{
    GstStateChangeReturn ret;
    GstPlaySinkVideoConvert *self = GST_PLAY_SINK_VIDEO_CONVERT_CAST (element);

    switch (transition) {
    case GST_STATE_CHANGE_PAUSED_TO_READY:
        GST_PLAY_SINK_VIDEO_CONVERT_LOCK (self);
        if (gst_pad_is_blocked (self->sink_proxypad))
            gst_pad_set_blocked_async_full (self->sink_proxypad, FALSE,
                                            (GstPadBlockCallback) pad_blocked_cb, gst_object_ref (self),
                                            (GDestroyNotify) gst_object_unref);
        GST_PLAY_SINK_VIDEO_CONVERT_UNLOCK (self);
        break;
    default:
        break;
    }

    ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
    if (ret == GST_STATE_CHANGE_FAILURE)
        return ret;

    switch (transition) {
    case GST_STATE_CHANGE_PAUSED_TO_READY:
        GST_PLAY_SINK_VIDEO_CONVERT_LOCK (self);
        gst_segment_init (&self->segment, GST_FORMAT_UNDEFINED);
        if (self->conv) {
            gst_element_set_state (self->conv, GST_STATE_NULL);
            gst_bin_remove (GST_BIN_CAST (self), self->conv);
            self->conv = NULL;
        }
        if (self->scale) {
            gst_element_set_state (self->scale, GST_STATE_NULL);
            gst_bin_remove (GST_BIN_CAST (self), self->scale);
            self->scale = NULL;
        }
        gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (self->srcpad),
                                  self->sink_proxypad);
        self->raw = FALSE;
        GST_PLAY_SINK_VIDEO_CONVERT_UNLOCK (self);
        break;
    case GST_STATE_CHANGE_READY_TO_PAUSED:
        GST_PLAY_SINK_VIDEO_CONVERT_LOCK (self);
        if (!gst_pad_is_blocked (self->sink_proxypad))
            gst_pad_set_blocked_async_full (self->sink_proxypad, TRUE,
                                            (GstPadBlockCallback) pad_blocked_cb, gst_object_ref (self),
                                            (GDestroyNotify) gst_object_unref);
        GST_PLAY_SINK_VIDEO_CONVERT_UNLOCK (self);
    default:
        break;
    }

    return ret;
}
예제 #23
0
static gboolean
rsn_dec_set_child (RsnDec * self, GstElement * new_child)
{
  GstPad *child_pad;
  if (self->current_decoder) {
    gst_ghost_pad_set_target (self->srcpad, NULL);
    gst_ghost_pad_set_target (self->sinkpad, NULL);
    gst_bin_remove ((GstBin *) self, self->current_decoder);
    self->current_decoder = NULL;
  }

  if (new_child == NULL)
    return TRUE;

  if (!gst_bin_add ((GstBin *) self, new_child))
    return FALSE;

  child_pad = gst_element_get_static_pad (new_child, "sink");
  if (child_pad == NULL) {
    return FALSE;
  }
  gst_ghost_pad_set_target (self->sinkpad, child_pad);
  gst_object_unref (child_pad);

  child_pad = gst_element_get_static_pad (new_child, "src");
  if (child_pad == NULL) {
    return FALSE;
  }
  gst_ghost_pad_set_target (self->srcpad, child_pad);
  gst_object_unref (child_pad);

  GST_DEBUG_OBJECT (self, "Add child %" GST_PTR_FORMAT, new_child);
  self->current_decoder = new_child;

  gst_element_sync_state_with_parent (new_child);

  return TRUE;
}
예제 #24
0
static void
fps_display_sink_start (GstFPSDisplaySink * self)
{
  GstPad *target_pad = NULL;

  /* Init counters */
  self->next_ts = GST_CLOCK_TIME_NONE;
  self->last_ts = GST_CLOCK_TIME_NONE;
  self->frames_rendered = G_GUINT64_CONSTANT (0);
  self->frames_dropped = G_GUINT64_CONSTANT (0);

  GST_DEBUG_OBJECT (self, "Use text-overlay? %d", self->use_text_overlay);

  if (self->use_text_overlay) {
    if (!self->text_overlay) {
      self->text_overlay =
          gst_element_factory_make ("textoverlay", "fps-display-text-overlay");
      if (!self->text_overlay) {
        GST_WARNING_OBJECT (self, "text-overlay element could not be created");
        self->use_text_overlay = FALSE;
        goto no_text_overlay;
      }
      gst_object_ref (self->text_overlay);
      g_object_set (self->text_overlay,
          "font-desc", DEFAULT_FONT, "silent", FALSE, NULL);
      gst_bin_add (GST_BIN (self), self->text_overlay);

      if (!gst_element_link (self->text_overlay, self->video_sink)) {
        GST_ERROR_OBJECT (self, "Could not link elements");
      }
    }
    target_pad = gst_element_get_static_pad (self->text_overlay, "video_sink");
  }
no_text_overlay:
  if (!self->use_text_overlay) {
    if (self->text_overlay) {
      gst_element_unlink (self->text_overlay, self->video_sink);
      gst_bin_remove (GST_BIN (self), self->text_overlay);
      self->text_overlay = NULL;
    }
    target_pad = gst_element_get_static_pad (self->video_sink, "sink");
  }
  gst_ghost_pad_set_target (GST_GHOST_PAD (self->ghost_pad), target_pad);
  gst_object_unref (target_pad);

  /* Set a timeout for the fps display */
  self->timeout_id =
      g_timeout_add (FPS_DISPLAY_INTERVAL_MS,
      display_current_fps, (gpointer) self);
}
예제 #25
0
static gboolean
gst_auto_audio_sink_detect (GstAutoAudioSink * sink)
{
  GstElement *esink;
  GstPad *targetpad;

  gst_auto_audio_sink_clear_kid (sink);

  /* find element */
  GST_DEBUG_OBJECT (sink, "Creating new kid");
  if (!(esink = gst_auto_audio_sink_find_best (sink)))
    goto no_sink;

  g_object_set (G_OBJECT (esink), "ts-offset", sink->ts_offset, NULL);

  sink->kid = esink;
  /* Ensure the child is brought up to the right state to match the parent
   * although it's currently always in READY and 
   * we're always doing NULL->READY. */
  if (GST_STATE (sink->kid) < GST_STATE (sink))
    gst_element_set_state (sink->kid, GST_STATE (sink));

  gst_bin_add (GST_BIN (sink), esink);

  /* attach ghost pad */
  GST_DEBUG_OBJECT (sink, "Re-assigning ghostpad");
  targetpad = gst_element_get_static_pad (sink->kid, "sink");
  if (!gst_ghost_pad_set_target (GST_GHOST_PAD (sink->pad), targetpad))
    goto target_failed;

  gst_object_unref (targetpad);
  GST_DEBUG_OBJECT (sink, "done changing auto audio sink");

  return TRUE;

  /* ERRORS */
no_sink:
  {
    GST_ELEMENT_ERROR (sink, LIBRARY, INIT, (NULL),
        ("Failed to find a supported audio sink"));
    return FALSE;
  }
target_failed:
  {
    GST_ELEMENT_ERROR (sink, LIBRARY, INIT, (NULL),
        ("Failed to set target pad"));
    gst_object_unref (targetpad);
    return FALSE;
  }
}
static void
gst_play_sink_convert_bin_set_targets (GstPlaySinkConvertBin * self,
    gboolean passthrough)
{
  GstPad *pad;
  GstElement *head, *tail;

  GST_DEBUG_OBJECT (self, "Setting pad targets with passthrough %d",
      passthrough);
  if (self->conversion_elements == NULL || passthrough) {
    GST_DEBUG_OBJECT (self, "no conversion elements, using identity (%p) as "
        "head/tail", self->identity);
    if (!passthrough) {
      GST_WARNING_OBJECT (self,
          "Doing passthrough as no converter elements were added");
    }
    head = tail = self->identity;
  } else {
    head = GST_ELEMENT (g_list_first (self->conversion_elements)->data);
    tail = GST_ELEMENT (g_list_last (self->conversion_elements)->data);
    GST_DEBUG_OBJECT (self, "conversion elements in use, picking "
        "head:%s and tail:%s", GST_OBJECT_NAME (head), GST_OBJECT_NAME (tail));
  }

  g_return_if_fail (head != NULL);
  g_return_if_fail (tail != NULL);

  pad = gst_element_get_static_pad (head, "sink");
  GST_DEBUG_OBJECT (self, "Ghosting bin sink pad to %" GST_PTR_FORMAT, pad);
  gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (self->sinkpad), pad);
  gst_object_unref (pad);

  pad = gst_element_get_static_pad (tail, "src");
  GST_DEBUG_OBJECT (self, "Ghosting bin src pad to %" GST_PTR_FORMAT, pad);
  gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (self->srcpad), pad);
  gst_object_unref (pad);
}
예제 #27
0
static gboolean
make_encodebin (GstTranscodeBin * self)
{
  GstPad *pad;
  GST_INFO_OBJECT (self, "making new encodebin");

  if (!self->profile)
    goto no_profile;

  self->encodebin = gst_element_factory_make ("encodebin", NULL);
  if (!self->encodebin)
    goto no_decodebin;

  g_object_set (self->encodebin, "profile", self->profile, NULL);

  gst_bin_add (GST_BIN (self), self->encodebin);

  pad = gst_element_get_static_pad (self->encodebin, "src");
  if (!gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (self->srcpad), pad)) {

    gst_object_unref (pad);
    GST_ERROR_OBJECT (self, "Could not ghost %" GST_PTR_FORMAT " srcpad",
        self->encodebin);

    return FALSE;
  }
  gst_object_unref (pad);

  return gst_element_sync_state_with_parent (self->encodebin);

  /* ERRORS */
no_decodebin:
  {
    post_missing_plugin_error (GST_ELEMENT_CAST (self), "encodebin");

    GST_ELEMENT_ERROR (self, CORE, MISSING_PLUGIN, (NULL),
        ("No encodebin element, check your installation"));

    return FALSE;
  }
  /* ERRORS */
no_profile:
  {
    GST_ELEMENT_ERROR (self, CORE, MISSING_PLUGIN, (NULL),
        ("No GstEncodingProfile set, can not run."));

    return FALSE;
  }
}
예제 #28
0
/*
 * Hack to make initial linking work; ideally, this'd work even when
 * no target has been assigned to the ghostpad yet.
 */
static void
gst_auto_audio_src_reset (GstAutoAudioSrc * src)
{
  GstPad *targetpad;

  gst_auto_audio_src_clear_kid (src);

  /* fakesink placeholder */
  src->kid = gst_element_factory_make ("fakesrc", "tempsrc");
  gst_bin_add (GST_BIN (src), src->kid);

  /* pad */
  targetpad = gst_element_get_static_pad (src->kid, "src");
  gst_ghost_pad_set_target (GST_GHOST_PAD (src->pad), targetpad);
  gst_object_unref (targetpad);
}
예제 #29
0
static void
gst_auto_video_sink_reset (GstAutoVideoSink * sink)
{
  GstPad *targetpad;

  /* Remove any existing element */
  gst_auto_video_sink_clear_kid (sink);

  /* fakesink placeholder */
  sink->kid = gst_element_factory_make ("fakesink", "tempsink");
  gst_bin_add (GST_BIN (sink), sink->kid);

  /* pad */
  targetpad = gst_element_get_pad (sink->kid, "sink");
  gst_ghost_pad_set_target (GST_GHOST_PAD (sink->pad), targetpad);
  gst_object_unref (targetpad);
}
예제 #30
0
static void
gst_hal_audio_sink_reset (GstHalAudioSink * sink)
{
  GstPad *targetpad;

  /* fakesink */
  if (sink->kid) {
    gst_element_set_state (sink->kid, GST_STATE_NULL);
    gst_bin_remove (GST_BIN (sink), sink->kid);
  }
  sink->kid = gst_element_factory_make ("fakesink", "testsink");
  gst_bin_add (GST_BIN (sink), sink->kid);

  targetpad = gst_element_get_static_pad (sink->kid, "sink");
  gst_ghost_pad_set_target (GST_GHOST_PAD (sink->pad), targetpad);
  gst_object_unref (targetpad);
}