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); } }
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; }