bool MediaNode::disconnectNode(QObject *obj) { MediaNode *sink = qobject_cast<MediaNode*>(obj); if (root()) { // Disconnecting elements while playing or paused seems to cause // potential deadlock. Hence we force the pipeline into ready state // before any nodes are disconnected. gst_element_set_state(root()->pipeline(), GST_STATE_READY); Q_ASSERT(sink->root()); //sink has to have a root since it is onnected if (sink->description() & (AudioSink)) { GstPad *sinkPad = gst_element_get_pad(sink->audioElement(), "sink"); // Release requested src pad from tee GstPad *requestedPad = gst_pad_get_peer(sinkPad); if (requestedPad) { gst_element_release_request_pad(m_audioTee, requestedPad); gst_object_unref(requestedPad); } if (GST_ELEMENT_PARENT(sink->audioElement())) gst_bin_remove(GST_BIN(root()->audioGraph()), sink->audioElement()); gst_object_unref(sinkPad); } if (sink->description() & (VideoSink)) { GstPad *sinkPad = gst_element_get_pad(sink->videoElement(), "sink"); // Release requested src pad from tee GstPad *requestedPad = gst_pad_get_peer(sinkPad); if (requestedPad) { gst_element_release_request_pad(m_videoTee, requestedPad); gst_object_unref(requestedPad); } if (GST_ELEMENT_PARENT(sink->videoElement())) gst_bin_remove(GST_BIN(root()->videoGraph()), sink->videoElement()); gst_object_unref(sinkPad); } sink->breakGraph(); sink->setRoot(0); } m_videoSinkList.removeAll(obj); m_audioSinkList.removeAll(obj); if (sink->m_description & AudioSink) { // Remove sink from graph MediaNodeEvent event(MediaNodeEvent::AudioSinkRemoved, sink); mediaNodeEvent(&event); return true; } if ((m_description & VideoSource) && (sink->m_description & VideoSink)) { // Remove sink from graph MediaNodeEvent event(MediaNodeEvent::VideoSinkRemoved, sink); mediaNodeEvent(&event); return true; } return false; }
/** * Disconnects children recursively */ bool MediaNode::breakGraph() { for (int i=0; i<m_audioSinkList.size(); ++i) { MediaNode *node = qobject_cast<MediaNode*>(m_audioSinkList[i]); if (!node || !node->breakGraph()) return false; node->setRoot(0); } for (int i=0; i <m_videoSinkList.size(); ++i) { MediaNode *node = qobject_cast<MediaNode*>(m_videoSinkList[i]); if (!node || !node->breakGraph()) return false; node->setRoot(0); } unlink(); return true; }