Пример #1
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;
  }
}
Пример #2
0
static GstPad *
gst_gl_mixer_bin_request_new_pad (GstElement * element, GstPadTemplate * templ,
    const gchar * req_name, const GstCaps * caps)
{
  GstGLMixerBin *self = GST_GL_MIXER_BIN (element);
  GstPadTemplate *mixer_templ;
  struct input_chain *chain;
  GstPad *mixer_pad;

  chain = g_new0 (struct input_chain, 1);

  mixer_templ = _find_element_pad_template (self->mixer,
      GST_PAD_TEMPLATE_DIRECTION (templ), GST_PAD_TEMPLATE_PRESENCE (templ));
  g_return_val_if_fail (mixer_templ, NULL);

  mixer_pad =
      gst_element_request_pad (self->mixer, mixer_templ, req_name, NULL);
  g_return_val_if_fail (mixer_pad, NULL);

  if (!_create_input_chain (self, chain, mixer_pad)) {
    gst_element_release_request_pad (self->mixer, mixer_pad);
    _free_input_chain (chain);
    return NULL;
  }

  GST_OBJECT_LOCK (element);
  self->priv->input_chains = g_list_prepend (self->priv->input_chains, chain);
  GST_OBJECT_UNLOCK (element);

  gst_child_proxy_child_added (GST_CHILD_PROXY (self),
      G_OBJECT (chain->ghost_pad), GST_OBJECT_NAME (chain->ghost_pad));

  return GST_PAD (chain->ghost_pad);
}
Пример #3
0
/**
 * gst_ghost_pad_new_no_target_from_template:
 * @name: (allow-none): the name of the new pad, or NULL to assign a default name
 * @templ: (transfer none): the #GstPadTemplate to create the ghostpad from.
 *
 * Create a new ghostpad based on @templ, without setting a target. The
 * direction will be taken from the @templ.
 *
 * Returns: (transfer full): a new #GstPad, or NULL in case of an error.
 */
GstPad *
gst_ghost_pad_new_no_target_from_template (const gchar * name,
    GstPadTemplate * templ)
{
  GstPad *ret;

  g_return_val_if_fail (templ != NULL, NULL);

  ret =
      gst_ghost_pad_new_full (name, GST_PAD_TEMPLATE_DIRECTION (templ), templ);

  return ret;
}
Пример #4
0
static GValueArray *
gst_alsa_device_property_probe_get_values (GstPropertyProbe * probe,
    guint prop_id, const GParamSpec * pspec)
{
  GstElementClass *klass;
  const GList *templates;
  snd_pcm_stream_t mode = -1;
  GValueArray *array;
  GValue value = { 0, };
  GList *l, *list;

  if (!g_str_equal (pspec->name, "device")) {
    G_OBJECT_WARN_INVALID_PROPERTY_ID (probe, prop_id, pspec);
    return NULL;
  }

  klass = GST_ELEMENT_GET_CLASS (GST_ELEMENT (probe));

  /* I'm pretty sure ALSA has a good way to do this. However, their cool
   * auto-generated documentation is pretty much useless if you try to
   * do function-wise look-ups. */
  /* we assume one pad template at max [zero=mixer] */
  templates = gst_element_class_get_pad_template_list (klass);
  if (templates) {
    if (GST_PAD_TEMPLATE_DIRECTION (templates->data) == GST_PAD_SRC)
      mode = SND_PCM_STREAM_CAPTURE;
    else
      mode = SND_PCM_STREAM_PLAYBACK;
  }

  list = gst_alsa_get_device_list (mode);

  if (list == NULL) {
    GST_LOG_OBJECT (probe, "No devices found");
    return NULL;
  }

  array = g_value_array_new (g_list_length (list));
  g_value_init (&value, G_TYPE_STRING);
  for (l = list; l != NULL; l = l->next) {
    GST_LOG_OBJECT (probe, "Found device: %s", (gchar *) l->data);
    g_value_take_string (&value, (gchar *) l->data);
    l->data = NULL;
    g_value_array_append (array, &value);
  }
  g_value_unset (&value);
  g_list_free (list);

  return array;
}
Пример #5
0
static GstPad *
gst_switch_request_new_pad (GstElement * element,
    GstPadTemplate * templ, const gchar * name, const GstCaps * caps)
{
  GstSwitch *swit = GST_SWITCH (element);
  GstGhostPad *pad;

  INFO ("requesting: %s.%s (%d=%d+%d)", GST_ELEMENT_NAME (swit),
      name ? name : GST_PAD_TEMPLATE_NAME_TEMPLATE (templ),
      element->numpads, element->numsrcpads, element->numsinkpads);

  GST_SWITCH_LOCK (swit);

  switch (GST_PAD_TEMPLATE_DIRECTION (templ)) {
    case GST_PAD_SRC:
      pad = gst_switch_request_new_src_pad (swit, templ, name, caps);
      break;
    case GST_PAD_SINK:
      pad = gst_switch_request_new_sink_pad (swit, templ, name, caps);
      break;
    default:
      pad = NULL;
      break;
  }

  if (pad) {
    gst_pad_set_active (GST_PAD (pad), TRUE);

    if (gst_element_add_pad (GST_ELEMENT (swit), GST_PAD (pad))) {
      GstPad *basepad = gst_ghost_pad_get_target (pad);
      GstElement *swcase = GST_ELEMENT (GST_PAD_PARENT (basepad));

      GST_OBJECT_FLAG_SET (basepad, GST_SWITCH_PAD_FLAG_GHOSTED);

      GST_DEBUG_OBJECT (swit, "New %s:%s on %s:%s",
          GST_ELEMENT_NAME (swit), GST_PAD_NAME (pad),
          GST_ELEMENT_NAME (swcase), GST_PAD_NAME (basepad));

      INFO ("requested %s.%s on %s.%s",
          GST_ELEMENT_NAME (swit), GST_PAD_NAME (pad),
          GST_ELEMENT_NAME (swcase), GST_PAD_NAME (basepad));
    }
  }

  GST_SWITCH_UNLOCK (swit);

  return GST_PAD (pad);
}
Пример #6
0
static GstPadTemplate *
_find_element_pad_template (GstElement * element,
    GstPadDirection direction, GstPadPresence presence)
{
  GstElementClass *klass = GST_ELEMENT_GET_CLASS (element);
  GList *templ_list = gst_element_class_get_pad_template_list (klass);
  GstPadTemplate *templ;

  /* find suitable template */
  while (templ_list) {
    templ = (GstPadTemplate *) templ_list->data;

    if (GST_PAD_TEMPLATE_DIRECTION (templ) != direction
        || GST_PAD_TEMPLATE_PRESENCE (templ) != presence) {
      templ_list = templ_list->next;
      templ = NULL;
      continue;
    }

    break;
  }

  return templ;
}
static gboolean
connect_element (InsanityTest * test, GstElement * demux)
{
  GList *pads;
  gboolean res = TRUE;
  gboolean dynamic = FALSE;
  GList *to_connect = NULL;

  /* 1. Loop over pad templates, grabbing existing pads along the way */
  for (pads = GST_ELEMENT_GET_CLASS (demux)->padtemplates; pads;
      pads = g_list_next (pads)) {
    GstPadTemplate *templ = GST_PAD_TEMPLATE (pads->data);
    const gchar *templ_name;

    /* we are only interested in source pads */
    if (GST_PAD_TEMPLATE_DIRECTION (templ) != GST_PAD_SRC)
      continue;

    templ_name = GST_PAD_TEMPLATE_NAME_TEMPLATE (templ);

    /* figure out what kind of pad this is */
    switch (GST_PAD_TEMPLATE_PRESENCE (templ)) {
      case GST_PAD_ALWAYS:
      {
        GstPad *pad = gst_element_get_static_pad (demux, templ_name);

        /* We concider the demuxer is not broken, and thus always
         * pads are always here */
        to_connect = g_list_prepend (to_connect, pad);
        break;
      }
      case GST_PAD_SOMETIMES:
      {
        /* try to get the pad to see if it is already created or
         * not */
        GstPad *pad = gst_element_get_static_pad (demux, templ_name);

        if (pad) {
          /* the pad is created, we need to try to link to it */
          to_connect = g_list_prepend (to_connect, pad);
        } else {
          /* we have an element that will create dynamic pads */
          dynamic = TRUE;
        }
        break;
      }
      case GST_PAD_REQUEST:
        /* ignore request pads */
        break;
    }
  }

  /* 2. if there are more potential pads, connect to signal */
  if (dynamic) {
    g_signal_connect (glob_demuxer, "pad-added", G_CALLBACK (pad_added_cb),
        test);
  }

  /* 3. for every available pad, check if we can connect it */
  for (pads = to_connect; pads; pads = g_list_next (pads)) {
    GstPad *pad = GST_PAD_CAST (pads->data);

    pad_added_cb (demux, pad, test);
    gst_object_unref (pad);
  }
  g_list_free (to_connect);

  return res;
}