Пример #1
0
static GstElement *
gst_switch_select (GstSwitch * swit,
    GstPadTemplate * templ, const gchar * name, const GstCaps * caps)
{
  GList *item = GST_BIN_CHILDREN (GST_BIN (swit));
  GstElement *swcase = NULL;

  for (; item; item = g_list_next (item)) {
    GList *paditem = GST_ELEMENT_PADS (GST_ELEMENT (item->data));
    GstPad *basepad = NULL, *pad = NULL;
    for (; paditem; paditem = g_list_next (paditem)) {
      pad = GST_PAD (paditem->data);
      if (GST_PAD_IS_SINK (pad) && !gst_pad_is_linked (pad) &&
          !GST_OBJECT_FLAG_IS_SET (GST_OBJECT (pad),
              GST_SWITCH_PAD_FLAG_GHOSTED)) {
        basepad = pad;
        break;
      }
    }

    if (basepad) {
      swcase = GST_ELEMENT (item->data);
      break;
    }
  }

  if (!swcase) {
    swcase = gst_switch_request_new_case (swit, templ, caps);
  }

  return swcase;
}
Пример #2
0
/* generate queries to adaptive demux */
static gboolean
testQueryCheckDataReceived (GstAdaptiveDemuxTestEngine * engine,
    GstAdaptiveDemuxTestOutputStream * stream,
    GstBuffer * buffer, gpointer user_data)
{
  GList *pads;
  GstPad *pad;
  GstQuery *query;
  gboolean ret;
  gint64 duration;
  gboolean seekable;
  gint64 segment_start;
  gint64 segment_end;
  gchar *uri;
  gchar *redirect_uri;
  gboolean redirect_permanent;

  pads = GST_ELEMENT_PADS (stream->appsink);

  /* AppSink should have only 1 pad */
  fail_unless (pads != NULL);
  fail_unless (g_list_length (pads) == 1);
  pad = GST_PAD (pads->data);

  query = gst_query_new_duration (GST_FORMAT_TIME);
  ret = gst_pad_peer_query (pad, query);
  fail_unless (ret == TRUE);
  gst_query_parse_duration (query, NULL, &duration);
  fail_unless (duration == 135743 * GST_MSECOND);
  gst_query_unref (query);

  query = gst_query_new_seeking (GST_FORMAT_TIME);
  ret = gst_pad_peer_query (pad, query);
  fail_unless (ret == TRUE);
  gst_query_parse_seeking (query, NULL, &seekable, &segment_start,
      &segment_end);
  fail_unless (seekable == TRUE);
  fail_unless (segment_start == 0);
  fail_unless (segment_end == duration);
  gst_query_unref (query);

  query = gst_query_new_uri ();
  ret = gst_pad_peer_query (pad, query);
  fail_unless (ret == TRUE);
  gst_query_parse_uri (query, &uri);
  gst_query_parse_uri_redirection (query, &redirect_uri);
  gst_query_parse_uri_redirection_permanent (query, &redirect_permanent);
  fail_unless (strcmp (uri, "http://unit.test/test.mpd") == 0);
  /* adaptive demux does not reply with redirect information */
  fail_unless (redirect_uri == NULL);
  fail_unless (redirect_permanent == FALSE);
  g_free (uri);
  g_free (redirect_uri);
  gst_query_unref (query);

  return gst_adaptive_demux_test_check_received_data (engine,
      stream, buffer, user_data);
}
Пример #3
0
static GstPad *
gst_tcp_mix_src_request_new_pad (GstElement * element, GstPadTemplate * templ,
    const gchar * unused, const GstCaps * caps)
{
  GstTCPMixSrc *src = GST_TCP_MIX_SRC (element);
  GstPad *srcpad;
  gchar *name;
  gboolean res;
  int num;

  //g_print ("%s:%d: %s\n", __FILE__, __LINE__, __FUNCTION__);

  GST_INFO_OBJECT (src, "Requesting new pad %s.%s (caps: %s)",
      GST_ELEMENT_NAME (src), GST_PAD_TEMPLATE_NAME_TEMPLATE (templ),
      gst_caps_to_string (caps));

  GST_OBJECT_LOCK (src);
  num = g_list_length (GST_ELEMENT_PADS (src));
  name = g_strdup_printf ("src_%u", num);
  srcpad = GST_PAD_CAST (g_object_new (GST_TYPE_TCP_MIX_SRC_PAD,
          "name", name, "direction", templ->direction, "template", templ,
          NULL));
  g_free (name);
  GST_OBJECT_UNLOCK (src);


  // see: gst_tcp_mix_src_activate_push
  gst_pad_set_active (srcpad, TRUE);
  gst_pad_activate_mode (srcpad, GST_PAD_MODE_PUSH, TRUE);

  gst_pad_set_activatemode_function (srcpad,
      (GstPadActivateModeFunction) gst_tcp_mix_src_activate_mode);
  gst_pad_set_query_function (srcpad, gst_tcp_mix_src_query);
  gst_pad_set_event_function (srcpad, gst_tcp_mix_src_event);
  gst_pad_set_getrange_function (srcpad, gst_tcp_mix_src_getrange);

  //GST_OBJECT_FLAG_SET (srcpad, GST_PAD_FLAG_PROXY_CAPS);

  //INFO ("add-pad: %s.%s", GST_ELEMENT_NAME (src), GST_PAD_NAME (srcpad));
  res = gst_element_add_pad (GST_ELEMENT_CAST (src), srcpad);

  gst_tcp_mix_src_start (src, GST_TCP_MIX_SRC_PAD (srcpad));

  if (G_UNLIKELY (!res)) {
    GST_ERROR_OBJECT (src, "Failed to add new pad");
  }

  return srcpad;
}
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);
}
Пример #5
0
static gboolean
gst_base_adaptive_sink_request_first_fragments (GstBaseAdaptiveSink * sink)
{
  GList *tmp;
  gint i;

  tmp = g_list_first (GST_ELEMENT_PADS (GST_ELEMENT (sink)));

  do {
    for (i = 0; i < sink->min_cache; i++) {
      gst_base_adaptive_sink_request_new_fragment (sink, (GstPad *) tmp->data);
    }
    tmp = g_list_next (tmp);
  } while (tmp != NULL);

  return TRUE;
}
static void
gst_rtp_mux_dispose (GObject * object)
{
  GstRTPMux *rtp_mux = GST_RTP_MUX (object);
  GList *item;

  g_clear_object (&rtp_mux->last_pad);

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

  G_OBJECT_CLASS (gst_rtp_mux_parent_class)->dispose (object);
}
Пример #7
0
static void
gst_funnel_dispose (GObject * object)
{
  GstFunnel *funnel = GST_FUNNEL (object);
  GList *item;

  gst_object_replace ((GstObject **) & funnel->last_sinkpad, NULL);

restart:
  for (item = GST_ELEMENT_PADS (object); item; item = g_list_next (item)) {
    GstPad *pad = GST_PAD (item->data);

    if (GST_PAD_IS_SINK (pad)) {
      gst_element_release_request_pad (GST_ELEMENT (object), pad);
      goto restart;
    }
  }

  G_OBJECT_CLASS (parent_class)->dispose (object);
}
Пример #8
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;
}
Пример #9
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);
  }
}
Пример #10
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;
}