Esempio n. 1
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);
}
Esempio n. 2
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);
}
Esempio n. 3
0
static void
link_element_to_tee (GstElement * tee, GstElement * element)
{
  GstPad *tee_src = gst_element_get_request_pad (tee, "src_%u");
  GstPad *element_sink = gst_element_get_static_pad (element, "sink");
  GstPadLinkReturn ret;
  GstPadChainFunction old_func;

  /*
   * HACK Add a custom chain function that does not return error, this way
   * we avoid race conditions produced by reconnect events not using the stream
   * lock
   */
  old_func = GST_PAD_CHAINFUNC (element_sink);

  if (old_func != NULL) {
    if (old_func != no_fail_chain) {
      g_object_set_data (G_OBJECT (element_sink), OLD_CHAIN_KEY, old_func);
    }
    gst_pad_set_chain_function (element_sink, no_fail_chain);
  }

  remove_element_on_unlinked (element, "src", "sink");
  g_signal_connect (tee_src, "unlinked", G_CALLBACK (remove_tee_pad_on_unlink),
      NULL);

  gst_pad_add_probe (tee_src, GST_PAD_PROBE_TYPE_EVENT_UPSTREAM, tee_src_probe,
      NULL, NULL);

  ret = gst_pad_link_full (tee_src, element_sink, GST_PAD_LINK_CHECK_NOTHING);

  if (G_UNLIKELY (GST_PAD_LINK_FAILED (ret))) {
    GST_ERROR ("Linking %" GST_PTR_FORMAT " with %" GST_PTR_FORMAT " result %d",
        tee_src, element_sink, ret);
  }

  g_object_unref (element_sink);
  g_object_unref (tee_src);
}
Esempio n. 4
0
static void
link_element_to_tee (GstElement * tee, GstElement * element)
{
  GstPad *tee_src = gst_element_get_request_pad (tee, "src_%u");
  GstPad *element_sink = gst_element_get_static_pad (element, "sink");
  GstPadLinkReturn ret;

  remove_element_on_unlinked (element, "src", "sink");
  g_signal_connect (tee_src, "unlinked", G_CALLBACK (remove_tee_pad_on_unlink),
      NULL);

  gst_pad_add_probe (tee_src, GST_PAD_PROBE_TYPE_EVENT_UPSTREAM, tee_src_probe,
      NULL, NULL);

  ret = gst_pad_link_full (tee_src, element_sink, GST_PAD_LINK_CHECK_NOTHING);

  if (G_UNLIKELY (GST_PAD_LINK_FAILED (ret))) {
    GST_ERROR ("Linking %" GST_PTR_FORMAT " with %" GST_PTR_FORMAT " result %d",
        tee_src, element_sink, ret);
  }

  g_object_unref (element_sink);
  g_object_unref (tee_src);
}