示例#1
0
static void
make_dynamic_link (GstEditorLink * link)
{
  GstElement *srce, *sinke;
  GstPadTemplate *src = NULL, *sink = NULL;

  if (GST_IS_EDITOR_PAD_SOMETIMES (link->srcpad))
    src = GST_PAD_TEMPLATE (link->srcpad->object);

  if (GST_IS_EDITOR_PAD_SOMETIMES (link->sinkpad))
    sink = GST_PAD_TEMPLATE (link->sinkpad->object);
  srce =
      GST_ELEMENT (GST_EDITOR_ITEM (goo_canvas_item_get_parent (GOO_CANVAS_ITEM
              (link->srcpad)))->object);
  sinke =
      GST_ELEMENT (GST_EDITOR_ITEM (goo_canvas_item_get_parent (GOO_CANVAS_ITEM
              (link->sinkpad)))->object);

  g_return_if_fail (src || sink);

  if (src)
    g_signal_connect_after (srce, "pad-added", G_CALLBACK (on_new_pad), link);
  if (sink)
    g_signal_connect_after (sinke, "pad-added", G_CALLBACK (on_new_pad), link);

  g_print ("dynamic link\n");
}
示例#2
0
static int
add_templates (gpointer gclass, PyObject * templates)
{
  if (PyTuple_Check (templates)) {
    gint i, len;
    PyGObject *templ;

    len = PyTuple_Size (templates);
    if (len == 0)
      return 0;

    for (i = 0; i < len; i++) {
      templ = (PyGObject *) PyTuple_GetItem (templates, i);

      if (!pygobject_check (templ, &PyGObject_Type)) {
        PyObject *repr = PyObject_Repr ((PyObject *) templ);
#if PY_VERSION_HEX < 0x03000000
        PyErr_Format (PyExc_TypeError, "expected GObject but got %s",
            PyString_AsString (repr));
#else
        PyErr_Format (PyExc_TypeError, "expected GObject but got %s",
            _PyUnicode_AsString (repr));
#endif
        Py_DECREF (repr);

        return -1;
      } else if (!GST_IS_PAD_TEMPLATE (pygobject_get (templ))) {
        gchar *error =
            g_strdup_printf
            ("entries for __gsttemplates__ must be of type GstPadTemplate (%s)",
            G_OBJECT_TYPE_NAME (pygobject_get (templ)));
        PyErr_SetString (PyExc_TypeError, error);
        g_free (error);

        return -1;
      }
    }

    for (i = 0; i < len; i++) {
      templ = (PyGObject *) PyTuple_GetItem (templates, i);
      gst_element_class_add_pad_template (gclass,
          GST_PAD_TEMPLATE (templ->obj));
    }
    return 0;

  } else if (!pygobject_check (templates, &PyGObject_Type) ||
      GST_IS_PAD_TEMPLATE (pygobject_get (templates)) == FALSE) {
    PyErr_SetString (PyExc_TypeError,
        "entry for __gsttemplates__ must be of type GstPadTemplate");

    return -1;
  }

  gst_element_class_add_pad_template (gclass,
      GST_PAD_TEMPLATE (pygobject_get (templates)));

  return 0;
}
示例#3
0
static void
gst_pad_template_dispose (GObject * object)
{
  GstPadTemplate *templ = GST_PAD_TEMPLATE (object);

  g_free (GST_PAD_TEMPLATE_NAME_TEMPLATE (templ));
  if (GST_PAD_TEMPLATE_CAPS (templ)) {
    gst_caps_unref (GST_PAD_TEMPLATE_CAPS (templ));
  }

  G_OBJECT_CLASS (parent_class)->dispose (object);
}
示例#4
0
/* this function is only linked for dynamic links */
static void
on_new_pad (GstElement * element, GstPad * pad, GstEditorLink * link)
{
  GstPadTemplate *src = NULL, *sink = NULL;

  if (GST_IS_EDITOR_PAD_SOMETIMES (link->srcpad))
    src = GST_PAD_TEMPLATE (link->srcpad->object);

  if (GST_IS_EDITOR_PAD_SOMETIMES (link->sinkpad))
    sink = GST_PAD_TEMPLATE (link->sinkpad->object);

  g_message ("new pad");
  if (pad->padtemplate) {
    g_message ("from a template");

    /* can't do pointer comparison -- some templates appear to be from the
       elementfactories, some from template factories... have to compare
       names */
    if (src &&
        g_ascii_strcasecmp (
            pad->padtemplate->name_template, src->name_template) == 0)
      g_object_set (G_OBJECT (GOO_CANVAS_ITEM (link)), "src-pad",
          gst_editor_item_get (GST_OBJECT (pad)), NULL);
    else if (sink &&
             g_ascii_strcasecmp (
                 pad->padtemplate->name_template, sink->name_template) == 0)
      g_object_set (G_OBJECT (GOO_CANVAS_ITEM (link)), "sink-pad",
          gst_editor_item_get (GST_OBJECT (pad)), NULL);
    else
      return;

    g_message ("we made it, now let's link");

    /*gst_element_set_state ((GstElement *)
       gst_element_get_managing_bin (element), GST_STATE_PAUSED); */
    gst_editor_link_link (link);
    /*gst_element_set_state ((GstElement *)
       gst_element_get_managing_bin (element), GST_STATE_PLAYING); */
  }
}
示例#5
0
static int
add_templates (gpointer gclass, PyObject * templates)
{
  if (PyTuple_Check (templates)) {
    gint i, len;
    PyGObject *templ;

    len = PyTuple_Size (templates);
    if (len == 0)
      return 0;

    for (i = 0; i < len; i++) {
      templ = (PyGObject *) PyTuple_GetItem (templates, i);
      if (GST_IS_PAD_TEMPLATE (pygobject_get (templ)) == FALSE) {
        PyErr_SetString (PyExc_TypeError,
            "entries for __gsttemplates__ must be of type GstPadTemplate");
        return -1;
      }
    }

    for (i = 0; i < len; i++) {
      templ = (PyGObject *) PyTuple_GetItem (templates, i);
      gst_element_class_add_pad_template (gclass,
          GST_PAD_TEMPLATE (templ->obj));
    }
    return 0;

  }

  if (GST_IS_PAD_TEMPLATE (pygobject_get (templates)) == FALSE) {
    PyErr_SetString (PyExc_TypeError,
        "entry for __gsttemplates__ must be of type GstPadTemplate");
    return -1;
  }

  gst_element_class_add_pad_template (gclass,
      GST_PAD_TEMPLATE (pygobject_get (templates)));

  return 0;
}
示例#6
0
static gboolean
has_sometimes_template (GstElement * element)
{
  GstElementClass *klass = GST_ELEMENT_GET_CLASS (element);
  GList *l;

  for (l = klass->padtemplates; l != NULL; l = l->next) {
    if (GST_PAD_TEMPLATE (l->data)->presence == GST_PAD_SOMETIMES)
      return TRUE;
  }

  return FALSE;
}
示例#7
0
gboolean
gst_editor_link_link (GstEditorLink * link)
{
  GObject * src, *sink;
  GstPad * srcpad = NULL, * sinkpad = NULL;

  GooCanvasItem * item;
  GooCanvasLineDash * dash;

  g_return_val_if_fail (GST_IS_EDITOR_LINK (link), FALSE);

  if (!link->srcpad || !link->sinkpad)
    goto error;

  src = (GObject *)GST_EDITOR_ITEM (link->srcpad)->object;
  sink = (GObject *)GST_EDITOR_ITEM (link->sinkpad)->object;
  if (!GST_EDITOR_PAD (link->srcpad)->istemplate) {
    if (!GST_EDITOR_PAD (link->sinkpad)->istemplate) {
      if (GST_PAD_PEER (src) || GST_PAD_PEER (sink)) {
        /*if (GST_PAD_PEER (src) != (GstPad *) sink)
           {
           g_warning ("The src pad is linked, but not to the sink pad");
           goto error;
           }
           if (GST_PAD_PEER (sink) != (GstPad *) src)
           {
           g_warning ("The sink pad is linked, but not to the src pad");
           goto error;
           } */
        srcpad = GST_PAD (src);
        sinkpad = GST_PAD (sink);
        goto linked;
        /* yay goto */
      }
    }

    else if (GST_PAD_PEER (src)) {
      /* the to pad is a template */
      g_warning ("The src pad is linked, but not to the sink pad");
      goto error;
    }
  }

  else if (!GST_EDITOR_PAD (link->sinkpad)->istemplate && GST_PAD_PEER (sink)) {
    /* from pad is a template */
    g_warning ("The sink pad is linked, but not to the src pad");
    goto error;
  }

  if (link->ghost) {
    g_object_set (
        G_OBJECT (GOO_CANVAS_ITEM (link)), "fill-color", "grey70", NULL);
    goto linked;
  }

  else if (GST_IS_EDITOR_PAD_SOMETIMES (link->srcpad) ||
           GST_IS_EDITOR_PAD_SOMETIMES (link->sinkpad)) {
    make_dynamic_link (link);
    g_object_set (
        G_OBJECT (GOO_CANVAS_ITEM (link)), "fill-color", "grey50", NULL);
    goto linked;
  }

  else {
    if (!GST_EDITOR_PAD (link->srcpad)->istemplate) {
      srcpad = GST_PAD (src);
    }

    else if (GST_IS_EDITOR_PAD_REQUEST (link->srcpad)) {
      srcpad = gst_element_get_request_pad (
          (GstElement *)GST_EDITOR_ITEM (
              goo_canvas_item_get_parent (GOO_CANVAS_ITEM (link->srcpad)))
              ->object,
          GST_PAD_TEMPLATE (src)->name_template);
      /* the new_pad signal will cause a new pad to made automagically in the
         element */
      g_object_set (G_OBJECT (GOO_CANVAS_ITEM (link)), "src-pad",
          gst_editor_item_get ((GstObject *)srcpad), NULL);
    }

    else {
      goto error;
    }

    if (!srcpad)
      goto error;

    if (!GST_EDITOR_PAD (link->sinkpad)->istemplate) {
      sinkpad = GST_PAD (sink);
    } else if (GST_IS_EDITOR_PAD_REQUEST (link->sinkpad)) {
      sinkpad = gst_element_get_request_pad (
          (GstElement *)GST_EDITOR_ITEM (
              goo_canvas_item_get_parent (GOO_CANVAS_ITEM (link->sinkpad)))
              ->object,
          GST_PAD_TEMPLATE (sink)->name_template);
      g_object_set (G_OBJECT (GOO_CANVAS_ITEM (link)), "sink-pad",
          gst_editor_item_get ((GstObject *)sinkpad), NULL);
    } else {
      goto error;
    }

    if (!sinkpad)
      goto error;

    if (gst_pad_link (srcpad, sinkpad) == GST_PAD_LINK_OK) {
      GstEditorBin * srcbin, *sinkbin;

      g_object_set (
          G_OBJECT (GOO_CANVAS_ITEM (link)), "fill-color", "black", NULL);

    linked:

      srcbin = sinkbin = NULL;
      dash = goo_canvas_line_dash_new (0, NULL);
      g_object_set (G_OBJECT (GOO_CANVAS_ITEM (link)), "line-dash", dash, NULL);
      goo_canvas_line_dash_unref (dash);

      g_signal_connect (link->srcpad, "position-changed",
          G_CALLBACK (on_editor_pad_position_changed), G_OBJECT (link));
      g_signal_connect (link->sinkpad, "position-changed",
          G_CALLBACK (on_editor_pad_position_changed), G_OBJECT (link));

      /* don't connect a signal on a ghost or dynamic link */
      g_print (
          "adding unlinked signal for src: %p and sink %p", srcpad, sinkpad);
      if (srcpad && sinkpad) {
        GST_CAT_DEBUG (gste_debug_cat,
            "link pad signal (%s:%s from %s:%s) with link %p",
            GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad), link);
        g_signal_connect (srcpad, "unlinked", G_CALLBACK (on_pad_unlink), link);
        g_signal_connect (
            sinkpad, "unlinked", G_CALLBACK (on_pad_unlink), link);
      }
      item = goo_canvas_item_get_parent (
          goo_canvas_item_get_parent (GOO_CANVAS_ITEM (link->srcpad)));
      if (GST_IS_EDITOR_BIN (item))
        srcbin = GST_EDITOR_BIN (item);

      item = goo_canvas_item_get_parent (
          goo_canvas_item_get_parent (GOO_CANVAS_ITEM (link->sinkpad)));
      if (GST_IS_EDITOR_BIN (item))
        sinkbin = GST_EDITOR_BIN (item);
      if (sinkbin)
        sinkbin->links = g_list_prepend (sinkbin->links, link);
      if (srcbin && sinkbin != srcbin)
        srcbin->links = g_list_prepend (srcbin->links, link);

      return TRUE;
    }
  }

error:
  g_message ("could not link");

  if (link->srcpad)
    GST_EDITOR_PAD (link->srcpad)->link = NULL;
  if (link->sinkpad)
    GST_EDITOR_PAD (link->sinkpad)->link = NULL;
  return FALSE;
}
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;
}