Esempio n. 1
0
/**
 * gst_ghost_pad_set_target:
 * @gpad: the #GstGhostPad
 * @newtarget: (transfer none) (allow-none): the new pad target
 *
 * Set the new target of the ghostpad @gpad. Any existing target
 * is unlinked and links to the new target are established. if @newtarget is
 * %NULL the target will be cleared.
 *
 * Returns: (transfer full): %TRUE if the new target could be set. This function
 *     can return %FALSE when the internal pads could not be linked.
 */
gboolean
gst_ghost_pad_set_target (GstGhostPad * gpad, GstPad * newtarget)
{
    GstPad *internal;
    GstPad *oldtarget;
    GstPadLinkReturn lret;

    g_return_val_if_fail (GST_IS_GHOST_PAD (gpad), FALSE);
    g_return_val_if_fail (GST_PAD_CAST (gpad) != newtarget, FALSE);
    g_return_val_if_fail (newtarget != GST_PROXY_PAD_INTERNAL (gpad), FALSE);

    GST_OBJECT_LOCK (gpad);
    internal = GST_PROXY_PAD_INTERNAL (gpad);

    if (newtarget)
        GST_DEBUG_OBJECT (gpad, "set target %s:%s", GST_DEBUG_PAD_NAME (newtarget));
    else
        GST_DEBUG_OBJECT (gpad, "clearing target");

    /* clear old target */
    if ((oldtarget = gst_pad_get_peer (internal))) {
        GST_OBJECT_UNLOCK (gpad);

        /* unlink internal pad */
        if (GST_PAD_IS_SRC (internal))
            gst_pad_unlink (internal, oldtarget);
        else
            gst_pad_unlink (oldtarget, internal);

        gst_object_unref (oldtarget);
    } else {
        GST_OBJECT_UNLOCK (gpad);
    }

    if (newtarget) {
        /* and link to internal pad without any checks */
        GST_DEBUG_OBJECT (gpad, "connecting internal pad to target %"
                          GST_PTR_FORMAT, newtarget);

        if (GST_PAD_IS_SRC (internal))
            lret =
                gst_pad_link_full (internal, newtarget, GST_PAD_LINK_CHECK_NOTHING);
        else
            lret =
                gst_pad_link_full (newtarget, internal, GST_PAD_LINK_CHECK_NOTHING);

        if (lret != GST_PAD_LINK_OK)
            goto link_failed;
    }

    return TRUE;

    /* ERRORS */
link_failed:
    {
        GST_WARNING_OBJECT (gpad, "could not link internal and target, reason:%s",
                            gst_pad_link_get_name (lret));
        return FALSE;
    }
}
Esempio n. 2
0
EXPORT_C
#endif

gboolean
gst_ghost_pad_set_target (GstGhostPad * gpad, GstPad * newtarget)
{
  GstPad *internal;
  GstPad *oldtarget;
  gboolean result;
  GstPadLinkReturn lret;

  g_return_val_if_fail (GST_IS_GHOST_PAD (gpad), FALSE);

  GST_PROXY_LOCK (gpad);
  internal = GST_PROXY_PAD_INTERNAL (gpad);

  GST_DEBUG_OBJECT (gpad, "set target %s:%s", GST_DEBUG_PAD_NAME (newtarget));

  /* clear old target */
  if ((oldtarget = GST_PROXY_PAD_TARGET (gpad))) {
    /* if we have an internal pad, unlink */
    if (internal) {
      if (GST_PAD_IS_SRC (internal))
        gst_pad_unlink (internal, oldtarget);
      else
        gst_pad_unlink (oldtarget, internal);
    }
  }

  result = gst_proxy_pad_set_target_unlocked (GST_PAD_CAST (gpad), newtarget);

  if (result && newtarget) {
    /* and link to internal pad */
    GST_DEBUG_OBJECT (gpad, "connecting internal pad to target");

    if (GST_PAD_IS_SRC (internal))
      lret = gst_pad_link (internal, newtarget);
    else
      lret = gst_pad_link (newtarget, internal);

    if (lret != GST_PAD_LINK_OK)
      goto link_failed;
  }
  GST_PROXY_UNLOCK (gpad);

  return result;

  /* ERRORS */
link_failed:
  {
    GST_WARNING_OBJECT (gpad, "could not link internal and target, reason:%d",
        lret);
    /* and unset target again */
    gst_proxy_pad_set_target_unlocked (GST_PAD_CAST (gpad), NULL);
    GST_PROXY_UNLOCK (gpad);
    return FALSE;
  }
}
static GstPadProbeReturn
input_selector_pad_probe (GstPad * pad, GstPadProbeInfo * info,
    gpointer userdata)
{
  GstPad *sink_pad = NULL;

  if (info->type == GST_PAD_PROBE_TYPE_BUFFER) {
    BufferCountData *bcd =
        g_object_get_data (G_OBJECT (pad), "buffer-count-data");
    if (!bcd) {
      GST_ERROR_OBJECT (pad, "No buffer-count-data found");
      return GST_PAD_PROBE_OK;
    }

    ++bcd->counter;
    if (GST_PAD_IS_SRC (pad)) {
      g_object_get (GST_PAD_PARENT (pad), "active-pad", &sink_pad, NULL);
      if (sink_pad) {
        bcd = g_object_get_data (G_OBJECT (sink_pad), "buffer-count-data");
        if (!bcd) {
          gst_object_unref (sink_pad);
          GST_ERROR_OBJECT (pad, "No buffer-count-data found");
          return GST_PAD_PROBE_OK;
        }
        ++bcd->back_counter;
        gst_object_unref (sink_pad);
      }
    }
  }
  return GST_PAD_PROBE_OK;
}
Esempio n. 4
0
static void Gstreamer_transform_pad_added(GstElement *filter, GstPad *pad, GstTfImpl *This)
{
    int ret;
    if (!GST_PAD_IS_SRC(pad))
        return;

    ret = gst_pad_link(pad, This->my_sink);
    if (ret < 0)
        WARN("Failed to link with %i\n", ret);
    This->their_src = pad;

    gst_pad_set_active(pad, TRUE);
    gst_pad_set_active(This->my_sink, TRUE);
}
Esempio n. 5
0
void Gstreamer_transform_pad_added(GstElement *filter, GstPad *pad, gpointer user)
{
    GstTfImpl *This = (GstTfImpl*)user;
    int ret;

    TRACE("%p %p %p\n", This, filter, pad);

    if (!GST_PAD_IS_SRC(pad))
        return;

    ret = gst_pad_link(pad, This->my_sink);
    if (ret < 0)
        WARN("Failed to link with %i\n", ret);
    This->their_src = pad;
}
static void
gst_tee_dispose (GObject * object)
{
  GList *item;

restart:
  for (item = GST_ELEMENT_PADS (object); item; item = g_list_next (item)) {
    GstPad *pad = GST_PAD (item->data);
    if (GST_PAD_IS_SRC (pad)) {
      gst_element_release_request_pad (GST_ELEMENT (object), pad);
      goto restart;
    }
  }

  G_OBJECT_CLASS (parent_class)->dispose (object);
}
Esempio n. 7
0
static int
gst_ffmpegdata_open (URLContext * h, const char *filename, int flags)
{
    GstProtocolInfo *info;
    GstPad *pad;

    GST_LOG ("Opening %s", filename);

    info = g_new0 (GstProtocolInfo, 1);

    info->set_streamheader = flags & GST_FFMPEG_URL_STREAMHEADER;
    flags &= ~GST_FFMPEG_URL_STREAMHEADER;
    h->flags &= ~GST_FFMPEG_URL_STREAMHEADER;

    /* we don't support R/W together */
    if (flags != URL_RDONLY && flags != URL_WRONLY) {
        GST_WARNING ("Only read-only or write-only are supported");
        return -EINVAL;
    }

    if (sscanf (&filename[12], "%p", &pad) != 1) {
        GST_WARNING ("could not decode pad from %s", filename);
        return -EIO;
    }

    /* make sure we're a pad and that we're of the right type */
    g_return_val_if_fail (GST_IS_PAD (pad), -EINVAL);

    switch (flags) {
    case URL_RDONLY:
        g_return_val_if_fail (GST_PAD_IS_SINK (pad), -EINVAL);
        break;
    case URL_WRONLY:
        g_return_val_if_fail (GST_PAD_IS_SRC (pad), -EINVAL);
        break;
    }

    info->eos = FALSE;
    info->pad = pad;
    info->offset = 0;

    h->priv_data = (void *) info;
    h->is_streamed = FALSE;
    h->max_packet_size = 0;

    return 0;
}
Esempio n. 8
0
static const GstFormat *
gst_speex_enc_get_formats (GstPad * pad)
{
  static const GstFormat src_formats[] = {
    GST_FORMAT_BYTES,
    GST_FORMAT_TIME,
    0
  };
  static const GstFormat sink_formats[] = {
    GST_FORMAT_BYTES,
    GST_FORMAT_DEFAULT,
    GST_FORMAT_TIME,
    0
  };

  return (GST_PAD_IS_SRC (pad) ? src_formats : sink_formats);
}
Esempio n. 9
0
static const GstFormat *
theora_get_formats (GstPad * pad)
{
  static GstFormat src_formats[] = {
    GST_FORMAT_DEFAULT,         /* frames in this case */
    GST_FORMAT_TIME,
    GST_FORMAT_BYTES,
    0
  };
  static GstFormat sink_formats[] = {
    GST_FORMAT_DEFAULT,
    GST_FORMAT_TIME,
    0
  };

  return (GST_PAD_IS_SRC (pad) ? src_formats : sink_formats);
}
Esempio n. 10
0
static void
gst_ghost_pad_dispose (GObject * object)
{
  GstPad *pad;
  GstPad *internal;
  GstPad *peer;

  pad = GST_PAD (object);

  GST_DEBUG_OBJECT (pad, "dispose");

  gst_ghost_pad_set_target (GST_GHOST_PAD (pad), NULL);

  /* Unlink here so that gst_pad_dispose doesn't. That would lead to a call to
   * gst_ghost_pad_do_unlink when the ghost pad is in an inconsistent state */
  peer = gst_pad_get_peer (pad);
  if (peer) {
    if (GST_PAD_IS_SRC (pad))
      gst_pad_unlink (pad, peer);
    else
      gst_pad_unlink (peer, pad);

    gst_object_unref (peer);
  }

  GST_PROXY_LOCK (pad);
  internal = GST_PROXY_PAD_INTERNAL (pad);

  gst_pad_set_activatepull_function (internal, NULL);
  gst_pad_set_activatepush_function (internal, NULL);

  g_signal_handler_disconnect (internal,
      GST_GHOST_PAD_PRIVATE (pad)->notify_id);

  /* disposes of the internal pad, since the ghostpad is the only possible object
   * that has a refcount on the internal pad. */
  gst_object_unparent (GST_OBJECT_CAST (internal));
  GST_PROXY_PAD_INTERNAL (pad) = NULL;

  GST_PROXY_UNLOCK (pad);

  G_OBJECT_CLASS (gst_ghost_pad_parent_class)->dispose (object);
}
Esempio n. 11
0
/**
 * gst_proxy_pad_save_thyself:
 * @pad: a ghost #GstPad to save.
 * @parent: the parent #xmlNodePtr to save the description in.
 *
 * Saves the ghost pad into an xml representation.
 *
 * Returns: the #xmlNodePtr representation of the pad.
 */
static xmlNodePtr
gst_proxy_pad_save_thyself (GstObject * object, xmlNodePtr parent)
{
  xmlNodePtr self;
  GstProxyPad *proxypad;
  GstPad *pad;
  GstPad *peer;

  g_return_val_if_fail (GST_IS_PROXY_PAD (object), NULL);

  self = xmlNewChild (parent, NULL, (xmlChar *) "ghostpad", NULL);
  xmlNewChild (self, NULL, (xmlChar *) "name",
      (xmlChar *) GST_OBJECT_NAME (object));
  xmlNewChild (self, NULL, (xmlChar *) "parent",
      (xmlChar *) GST_OBJECT_NAME (GST_OBJECT_PARENT (object)));

  proxypad = GST_PROXY_PAD_CAST (object);
  pad = GST_PAD_CAST (proxypad);
  peer = GST_PAD_CAST (pad->peer);

  if (GST_IS_PAD (pad)) {
    if (GST_PAD_IS_SRC (pad))
      xmlNewChild (self, NULL, (xmlChar *) "direction", (xmlChar *) "source");
    else if (GST_PAD_IS_SINK (pad))
      xmlNewChild (self, NULL, (xmlChar *) "direction", (xmlChar *) "sink");
    else
      xmlNewChild (self, NULL, (xmlChar *) "direction", (xmlChar *) "unknown");
  } else {
    xmlNewChild (self, NULL, (xmlChar *) "direction", (xmlChar *) "unknown");
  }
  if (GST_IS_PAD (peer)) {
    gchar *content = g_strdup_printf ("%s.%s",
        GST_OBJECT_NAME (GST_PAD_PARENT (peer)), GST_PAD_NAME (peer));

    xmlNewChild (self, NULL, (xmlChar *) "peer", (xmlChar *) content);
    g_free (content);
  } else {
    xmlNewChild (self, NULL, (xmlChar *) "peer", NULL);
  }

  return self;
}
Esempio n. 12
0
static void
gst_ghost_pad_dispose (GObject * object)
{
  GstPad *pad;
  GstPad *internal;
  GstPad *intpeer;

  pad = GST_PAD (object);

  GST_DEBUG_OBJECT (pad, "dispose");

  GST_PROXY_LOCK (pad);
  internal = GST_PROXY_PAD_INTERNAL (pad);

  gst_pad_set_activatepull_function (internal, NULL);
  gst_pad_set_activatepush_function (internal, NULL);

  g_signal_handler_disconnect (internal, GST_GHOST_PAD_CAST (pad)->notify_id);

  intpeer = gst_pad_get_peer (internal);
  if (intpeer) {
    if (GST_PAD_IS_SRC (internal))
      gst_pad_unlink (internal, intpeer);
    else
      gst_pad_unlink (intpeer, internal);

    gst_object_unref (intpeer);
  }

  GST_PROXY_PAD_INTERNAL (internal) = NULL;

  /* disposes of the internal pad, since the ghostpad is the only possible object
   * that has a refcount on the internal pad. */
  gst_object_unparent (GST_OBJECT_CAST (internal));

  GST_PROXY_UNLOCK (pad);

  G_OBJECT_CLASS (gst_ghost_pad_parent_class)->dispose (object);
}
Esempio n. 13
0
static GstPadLinkReturn
gst_ghost_pad_do_link (GstPad * pad, GstPad * peer)
{
  GstPadLinkReturn ret;
  GstPad *internal;

  GST_DEBUG_OBJECT (pad, "linking ghostpad");

  internal = GST_PROXY_PAD_INTERNAL (pad);
  if (!gst_proxy_pad_set_target (internal, peer))
    goto target_failed;

  ret = GST_PAD_LINK_OK;
  /* if we are a source pad, we should call the peer link function
   * if the peer has one, see design docs. */
  if (GST_PAD_IS_SRC (pad)) {
    if (GST_PAD_LINKFUNC (peer)) {
      ret = GST_PAD_LINKFUNC (peer) (peer, pad);
      if (ret != GST_PAD_LINK_OK)
        goto link_failed;
    }
  }
  return ret;

  /* ERRORS */
target_failed:
  {
    GST_DEBUG_OBJECT (pad, "setting target failed");
    return GST_PAD_LINK_REFUSED;
  }
link_failed:
  {
    GST_DEBUG_OBJECT (pad, "linking failed");
    /* clear target again */
    gst_proxy_pad_set_target (internal, NULL);
    return ret;
  }
}
Esempio n. 14
0
static gboolean
gst_tcp_mix_src_stop (GstTCPMixSrc * src, GstTCPMixSrcPad * pad)
{
  GError *err = NULL;
  GList *item;

  GST_OBJECT_LOCK (src);
  GST_DEBUG_OBJECT (src, "Closing client sockets");
  for (item = GST_ELEMENT_PADS (src); item; item = g_list_next (item)) {
    GstPad *p = GST_PAD (item->data);
    if (GST_PAD_IS_SRC (p)) {
      gst_tcp_mix_src_pad_reset (GST_TCP_MIX_SRC_PAD (p));
    }
  }
  GST_OBJECT_UNLOCK (src);

  if (src->server_socket) {
    GST_DEBUG_OBJECT (src, "Closing server socket");

    if (!g_socket_close (src->server_socket, &err)) {
      GST_ERROR_OBJECT (src, "Failed to close socket: %s", err->message);
      g_clear_error (&err);
    }

    g_object_unref (src->server_socket);
    src->server_socket = NULL;

    gst_tcp_mix_src_stop_acceptor (src);

    g_atomic_int_set (&src->bound_port, 0);
    g_object_notify (G_OBJECT (src), "bound-port");
  }

  GST_OBJECT_FLAG_UNSET (src, GST_TCP_MIX_SRC_OPEN);

  return TRUE;
}
Esempio n. 15
0
static GstElement *
setup_multiqueue (GstElement * pipe, GstElement * inputs[],
    GstElement * outputs[], guint num)
{
  GstElement *mq;
  guint i;

  mq = gst_element_factory_make ("multiqueue", NULL);
  fail_unless (mq != NULL, "failed to create 'multiqueue' element");

  gst_bin_add (GST_BIN (pipe), mq);

  for (i = 0; i < num; ++i) {
    GstPad *sinkpad = NULL;
    GstPad *srcpad = NULL;

    /* create multiqueue sink (and source) pad */
    sinkpad = gst_element_get_request_pad (mq, "sink%d");
    fail_unless (sinkpad != NULL,
        "failed to create multiqueue request pad #%u", i);

    /* link input element N to the N-th multiqueue sink pad we just created */
    if (inputs != NULL && inputs[i] != NULL) {
      gst_bin_add (GST_BIN (pipe), inputs[i]);

      srcpad = gst_element_get_static_pad (inputs[i], "src");
      fail_unless (srcpad != NULL, "failed to find src pad for input #%u", i);

      fail_unless_equals_int (GST_PAD_LINK_OK, gst_pad_link (srcpad, sinkpad));

      gst_object_unref (srcpad);
      srcpad = NULL;
    }
    gst_object_unref (sinkpad);
    sinkpad = NULL;

    /* link output element N to the N-th multiqueue src pad */
    if (outputs != NULL && outputs[i] != NULL) {
      gchar padname[10];

      /* only the sink pads are by request, the source pads are sometimes pads,
       * so this should return NULL */
      srcpad = gst_element_get_request_pad (mq, "src%d");
      fail_unless (srcpad == NULL);

      g_snprintf (padname, sizeof (padname), "src%d", i);
      srcpad = gst_element_get_static_pad (mq, padname);
      fail_unless (srcpad != NULL, "failed to get multiqueue src pad #%u", i);
      fail_unless (GST_PAD_IS_SRC (srcpad),
          "%s:%s is not a source pad?!", GST_DEBUG_PAD_NAME (srcpad));

      gst_bin_add (GST_BIN (pipe), outputs[i]);

      sinkpad = gst_element_get_static_pad (outputs[i], "sink");
      fail_unless (sinkpad != NULL, "failed to find sink pad of output #%u", i);
      fail_unless (GST_PAD_IS_SINK (sinkpad));

      fail_unless_equals_int (GST_PAD_LINK_OK, gst_pad_link (srcpad, sinkpad));

      gst_object_unref (srcpad);
      gst_object_unref (sinkpad);
    }
  }

  return mq;
}
static void
gst_insert_bin_block_pad_unlock (GstInsertBin * self)
{
  struct ChangeData *data;
  GstPad *pad;
  GstPadProbeType probetype;

again:

  data = g_queue_peek_head (&self->priv->change_queue);
  if (!data) {
    GST_OBJECT_UNLOCK (self);
    return;
  }

  if (data->action == GST_INSERT_BIN_ACTION_ADD &&
      !validate_element (self, data->element))
    goto error;

  if (data->action == GST_INSERT_BIN_ACTION_ADD) {
    if (data->sibling) {
      if (data->direction == DIRECTION_BEFORE)
        pad = get_single_pad (data->sibling, GST_PAD_SINK);
      else
        pad = get_single_pad (data->sibling, GST_PAD_SRC);
    } else {
      if (data->direction == DIRECTION_BEFORE)
        pad = (GstPad *)
            gst_proxy_pad_get_internal (GST_PROXY_PAD (self->priv->srcpad));
      else
        pad = (GstPad *)
            gst_proxy_pad_get_internal (GST_PROXY_PAD (self->priv->sinkpad));
    }

    if (!pad) {
      GST_WARNING_OBJECT (self, "Can not obtain a sibling pad to block"
          " before adding");
      goto error;
    }

    if (!is_right_direction_for_block (pad)) {
      GstPad *peer = gst_pad_get_peer (pad);

      if (peer) {
        gst_object_unref (pad);
        pad = peer;
      }
    }
  } else {
    GstPad *element_pad;

    element_pad = get_single_pad (data->element, GST_PAD_SINK);
    if (!element_pad) {
      GST_WARNING_OBJECT (self, "Can not obtain the element's sink pad");
      goto error;
    }

    if (!is_right_direction_for_block (element_pad)) {
      pad = gst_pad_get_peer (element_pad);
    } else {
      gst_object_unref (element_pad);

      element_pad = get_single_pad (data->element, GST_PAD_SRC);
      if (!element_pad) {
        GST_WARNING_OBJECT (self, "Can not obtain the element's src pad");
        goto error;
      }

      pad = gst_pad_get_peer (element_pad);
    }
    gst_object_unref (element_pad);

    if (!pad) {
      GST_WARNING_OBJECT (self, "Can not obtain a sibling pad for removing");
      goto error;
    }
  }

  if (GST_PAD_IS_SRC (pad))
    probetype = GST_PAD_PROBE_TYPE_BLOCK_DOWNSTREAM;
  else
    probetype = GST_PAD_PROBE_TYPE_BLOCK_UPSTREAM;

  GST_OBJECT_UNLOCK (self);
  gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_IDLE | probetype, pad_blocked_cb,
      self, NULL);
  gst_object_unref (pad);
  return;

error:
  g_queue_pop_head (&self->priv->change_queue);
  gst_insert_bin_change_data_complete (self, data, FALSE);
  goto again;
}
Esempio n. 17
0
static void
gst_tcp_mix_src_add_client (GstTCPMixSrc * src, GSocket * socket)
{
  GstTCPMixSrcPad *pad, *p;
  GList *item;
  GError *err;

  pad = NULL;

  GST_OBJECT_LOCK (src);
  for (item = GST_ELEMENT_PADS (src); item; item = g_list_next (item)) {
    p = pad = GST_TCP_MIX_SRC_PAD (item->data);
    if (GST_PAD_IS_SRC (p)) {
      GST_OBJECT_LOCK (p);
      if (pad->client) {
        pad = NULL;
      } else {
        GST_TCP_MIX_SRC_PAD_CLIENT_LOCK (pad);
        pad->client = socket;
        GST_TCP_MIX_SRC_PAD_CLIENT_NOTIFY (pad);
        GST_TCP_MIX_SRC_PAD_CLIENT_UNLOCK (pad);
      }
      GST_OBJECT_UNLOCK (p);
      if (pad)
        break;
    }
  }
  GST_OBJECT_UNLOCK (src);

  if (!pad) {
    pad =
        GST_TCP_MIX_SRC_PAD (gst_element_get_request_pad (GST_ELEMENT (src),
            srctemplate.name_template));
    GST_OBJECT_LOCK (pad);
    GST_TCP_MIX_SRC_PAD_CLIENT_LOCK (pad);
    pad->client = socket;
    GST_TCP_MIX_SRC_PAD_CLIENT_NOTIFY (pad);
    GST_TCP_MIX_SRC_PAD_CLIENT_UNLOCK (pad);
    GST_OBJECT_UNLOCK (pad);
  }

  if (pad) {
    GST_DEBUG_OBJECT (pad, "New client on %s.%s (%d srcpads)",
        GST_ELEMENT_NAME (src), GST_PAD_NAME (pad),
        GST_ELEMENT (src)->numsrcpads);

    gst_tcp_mix_src_request_link_pad (src, pad);

    if (!gst_pad_is_linked (GST_PAD (pad))) {
      GST_ERROR_OBJECT (src, "Pad %s.%s is not linked",
          GST_ELEMENT_NAME (src), GST_PAD_NAME (pad));
    }

    if (!gst_pad_is_active (GST_PAD (pad)))
      gst_pad_set_active (GST_PAD (pad), TRUE);

    g_signal_emit (src, gst_tcpmixsrc_signals[SIGNAL_NEW_CLIENT], 0, pad);
  } else {
    GST_WARNING_OBJECT (src, "No pad for new client, closing..");

    if (!g_socket_close (socket, &err)) {
      GST_ERROR_OBJECT (src, "Failed to close socket: %s", err->message);
      g_clear_error (&err);
    }

    g_object_unref (socket);
  }
}
Esempio n. 18
0
static void
gst_tcp_mix_src_request_link_pad (GstTCPMixSrc * src, GstTCPMixSrcPad * pad)
{
  GstTCPMixSrcPad *p;
  GstPad *pp;
  GList *item;
  gboolean linked = FALSE;
  GstBin *parent;
  GstElement *target;
  GstPadLinkReturn linkRet;

  if (gst_pad_is_linked (GST_PAD (pad))) {
#if 1
    pp = GST_PAD_PEER (pad);
    GST_WARNING_OBJECT (src, "Pad %s.%s already linked to %s.%s",
        GST_ELEMENT_NAME (src), GST_PAD_NAME (pad),
        GST_ELEMENT_NAME (GST_PAD_PARENT (pp)), GST_PAD_NAME (pp));
#endif
    return;
  }

  GST_LOG_OBJECT (src, "Linking pad '%s.%s'",
      GST_ELEMENT_NAME (src), GST_PAD_NAME (pad));

  INFO ("link");

  /**
   *  Don't do GST_OBJECT_LOCK() here, it causes DEADLOCK.
   */
  /* GST_OBJECT_LOCK (src); */

  if (!src->autosink)
    goto find_sink;

  parent = GST_BIN (GST_ELEMENT_PARENT (src));
  target = gst_bin_get_by_name (parent, src->autosink);

  INFO ("link");

  if (!target)
    goto find_sink;

  pp = gst_element_get_request_pad (target, "sink_%u");

  GST_DEBUG_OBJECT (src, "Link %s.%s-%s.%s",
      GST_ELEMENT_NAME (src), GST_PAD_NAME (pad),
      GST_ELEMENT_NAME (GST_PAD_PARENT (pp)), GST_PAD_NAME (pp));

  INFO ("link");

  linkRet = gst_pad_link (GST_PAD (pad), GST_PAD (pp));
  if (GST_PAD_LINK_FAILED (linkRet)) {
    GST_ERROR_OBJECT (src, "can't link");
  }

  return;

find_sink:
#if 1
  for (item = GST_ELEMENT_PADS (src); item; item = g_list_next (item)) {
    p = GST_TCP_MIX_SRC_PAD (item->data);
    if (GST_PAD_IS_SRC (p)) {
      GST_OBJECT_LOCK (p);
      if ((pp = GST_PAD_PEER (p))) {
        GstElement *ele = GST_ELEMENT (GST_PAD_PARENT (pp));

        // FIXME: pad name calculation
        pp = gst_element_get_request_pad (ele, "sink_%u");

        GST_DEBUG_OBJECT (src, "Link %s.%s-%s.%s",
            GST_ELEMENT_NAME (src), GST_PAD_NAME (pad),
            GST_ELEMENT_NAME (GST_PAD_PARENT (pp)), GST_PAD_NAME (pp));

        linkRet = gst_pad_link (GST_PAD (pad), GST_PAD (pp));
        if (GST_PAD_LINK_FAILED (linkRet)) {
          GST_ERROR_OBJECT (src, "can't link");
        } else {
          linked = TRUE;
        }
      }
      GST_OBJECT_UNLOCK (p);

      if (linked)
        break;
    }
  }
#endif

  /* GST_OBJECT_UNLOCK (src); */
  return;
}