Example #1
0
void
MediaSink::unlinkUnchecked (GstPad *sink)
{
  GstPad *peer;
  GstPad *sinkPad;

  if (sink == NULL)
    sinkPad = gst_element_get_static_pad (getElement(), getPadName().c_str() );
  else
    sinkPad = sink;

  if (sinkPad == NULL)
    return;

  peer = gst_pad_get_peer (sinkPad);

  if (peer != NULL) {
    gst_pad_unlink (peer, sinkPad);

    g_object_unref (peer);
  }

  if (sink == NULL) {
    GstElement *elem;

    elem = gst_pad_get_parent_element (sinkPad);
    gst_element_release_request_pad (elem, sinkPad);
    g_object_unref (elem);
    g_object_unref (sinkPad);
  }
}
void
MediaSinkImpl::unlinkUnchecked (GstPad *sink)
{
  GstPad *peer;
  GstPad *sinkPad;

  if (sink == NULL) {
    sinkPad = gst_element_get_static_pad (getGstreamerElement(),
                                          getPadName().c_str() );
  } else {
    sinkPad = sink;
  }

  if (sinkPad == NULL) {
    return;
  }

  peer = gst_pad_get_peer (sinkPad);

  if (peer != NULL) {
    Glib::Threads::Cond cond;
    Glib::Threads::Mutex cmutex;
    bool blocked = FALSE;
    std::function <void (GstPad *, GstPadProbeInfo *) >
    blockedLambda = [&] (GstPad * pad, GstPadProbeInfo * info) {
      Glib::Threads::Mutex::Lock lock (cmutex);

      GST_DEBUG ("Peer pad blocked %" GST_PTR_FORMAT, pad);

      if (blocked) {
        return;
      }

      gst_pad_unlink (pad, sinkPad);
      blocked = TRUE;

      cond.signal();
    };

    gst_pad_add_probe (peer, (GstPadProbeType) (GST_PAD_PROBE_TYPE_BLOCKING),
                       pad_blocked_adaptor, &blockedLambda, NULL);

    cmutex.lock ();

    while (!blocked) {
      cond.wait (cmutex);
    }

    cmutex.unlock ();

    g_object_unref (peer);
  }

  if (sink == NULL) {
    gst_element_release_request_pad (getGstreamerElement(), sinkPad);
    g_object_unref (sinkPad);
  }
}
Example #3
0
bool
MediaSink::linkPad (std::shared_ptr<MediaSrc> mediaSrc, GstPad *src)
{
  std::shared_ptr<MediaSrc> connectedSrcLocked;
  GstPad *sink;
  bool ret = false;

  mutex.lock();

  try {
    connectedSrcLocked = connectedSrc.lock();
  } catch (const std::bad_weak_ptr &e) {
  }

  if ( (sink = gst_element_get_static_pad (getElement(), getPadName().c_str() ) ) == NULL)
    sink = gst_element_get_request_pad (getElement(), getPadName().c_str() );

  if (gst_pad_is_linked (sink) ) {
    unlink (connectedSrcLocked, sink);
  }

  if (mediaSrc->parent == parent) {
    GstBin *container;
    GstElement *filter, *parent;
    GstPad *aux_sink, *aux_src;

    GST_DEBUG ("Connecting loopback, adding a capsfilter to allow connection");
    parent = GST_ELEMENT (GST_OBJECT_PARENT (sink) );

    if (parent == NULL)
      goto end;

    container = GST_BIN (GST_OBJECT_PARENT (parent) );

    if (container == NULL)
      goto end;

    filter = gst_element_factory_make ("capsfilter", NULL);

    aux_sink = gst_element_get_static_pad (filter, "sink");
    aux_src = gst_element_get_static_pad (filter, "src");

    g_signal_connect (G_OBJECT (aux_sink), "unlinked", G_CALLBACK (sink_unlinked), filter );
    g_signal_connect (G_OBJECT (aux_src), "unlinked", G_CALLBACK (src_unlinked), filter );

    gst_bin_add (container, filter);
    gst_element_sync_state_with_parent (filter);

    if (gst_pad_link (aux_src, sink) == GST_PAD_LINK_OK) {
      if (gst_pad_link (src, aux_sink) == GST_PAD_LINK_OK)
        ret = true;
      else
        gst_pad_unlink (aux_src, sink);

    }

    g_object_unref (aux_sink);
    g_object_unref (aux_src);

    gst_debug_bin_to_dot_file_with_ts (GST_BIN (container), GST_DEBUG_GRAPH_SHOW_ALL, "loopback");

  } else {
    if (gst_pad_link (src, sink) == GST_PAD_LINK_OK)
      ret = true;
  }

  if (ret == true) {
    connectedSrc = std::weak_ptr<MediaSrc> (mediaSrc);
  } else {
    gst_element_release_request_pad (getElement(), sink);
  }

end:

  g_object_unref (sink);

  mutex.unlock();

  return ret;
}
bool
MediaSinkImpl::linkPad (std::shared_ptr<MediaSourceImpl> mediaSrc, GstPad *src)
{
  RecMutex::Lock lock (mutex);
  std::shared_ptr<MediaSourceImpl> connectedSrcLocked;
  GstPad *sink;
  bool ret = false;

  try {
    connectedSrcLocked = connectedSrc.lock();
  } catch (const std::bad_weak_ptr &e) {
  }

  if ( (sink = gst_element_get_static_pad (getGstreamerElement(),
               getPadName().c_str() ) ) == NULL) {
    sink = gst_element_get_request_pad (getGstreamerElement(),
                                        getPadName().c_str() );
  }

  if (gst_pad_is_linked (sink) ) {
    unlink (connectedSrcLocked, sink);
  }

  if (std::dynamic_pointer_cast<MediaObjectImpl> (mediaSrc)->getParent() ==
      getParent() ) {
    GstBin *container;
    GstElement *filter, *parent;
    GstPad *aux_sink, *aux_src;

    GST_DEBUG ("Connecting loopback, adding a capsfilter to allow connection");
    parent = GST_ELEMENT (GST_OBJECT_PARENT (sink) );

    if (parent == NULL) {
      goto end;
    }

    container = GST_BIN (GST_OBJECT_PARENT (parent) );

    if (container == NULL) {
      goto end;
    }

    filter = gst_element_factory_make ("capsfilter", NULL);

    aux_sink = gst_element_get_static_pad (filter, "sink");
    aux_src = gst_element_get_static_pad (filter, "src");

    g_signal_connect (G_OBJECT (aux_sink), "unlinked", G_CALLBACK (sink_unlinked),
                      filter );
    g_signal_connect (G_OBJECT (aux_src), "unlinked", G_CALLBACK (src_unlinked),
                      filter );

    gst_bin_add (container, filter);
    gst_element_sync_state_with_parent (filter);

    if (gst_pad_link_full (aux_src, sink,
                           GST_PAD_LINK_CHECK_NOTHING) == GST_PAD_LINK_OK) {
      if (gst_pad_link_full (src, aux_sink,
                             GST_PAD_LINK_CHECK_NOTHING) == GST_PAD_LINK_OK) {
        ret = true;
      } else {
        gst_pad_unlink (aux_src, sink);
      }

    }

    g_object_unref (aux_sink);
    g_object_unref (aux_src);

    gst_debug_bin_to_dot_file_with_ts (GST_BIN (container),
                                       GST_DEBUG_GRAPH_SHOW_ALL, "loopback");

  } else {
    if (gst_pad_link_full (src, sink,
                           GST_PAD_LINK_CHECK_NOTHING) == GST_PAD_LINK_OK) {
      ret = true;
    }
  }

  if (ret == true) {
    connectedSrc = std::weak_ptr<MediaSourceImpl> (mediaSrc);
  } else {
    gst_element_release_request_pad (getGstreamerElement(), sink);
  }

end:

  g_object_unref (sink);

  return ret;
}