diff --git a/src/GraphDisplay.cpp b/src/GraphDisplay.cpp index e2a7398..1300c74 100644 --- a/src/GraphDisplay.cpp +++ b/src/GraphDisplay.cpp @@ -16,6 +16,7 @@ #include "ElementProperties.h" #include "PadProperties.h" #include "CustomMenuAction.h" +#include "PluginsList.h" #define PAD_SIZE 8 #define PAD_SIZE_ACTION 16 @@ -42,9 +43,12 @@ ElementInfo* GraphDisplay::getElement(std::size_t elementId) return element; } -PadInfo* GraphDisplay::getPad(ElementInfo* element, std::size_t padId) +PadInfo* GraphDisplay::getPad(std::size_t elementId, std::size_t padId) { PadInfo* pad = NULL; + ElementInfo* element = getElement(elementId); + if (!element) + return NULL; std::size_t j=0; for(; jm_pads.size(); j++) if(element->m_pads[j].m_id == padId) { @@ -73,7 +77,6 @@ void GraphDisplay::updateDisplayInfoIds() } } - void GraphDisplay::update(const std::vector &info) { bool needUpdate = false; @@ -122,7 +125,6 @@ void GraphDisplay::update(const std::vector &info) } } - void GraphDisplay::paintEvent(QPaintEvent *event) { QPainter painter(this); @@ -192,7 +194,6 @@ void GraphDisplay::paintEvent(QPaintEvent *event) } } - GraphDisplay::ElementDisplayInfo GraphDisplay::calculateOnePosition(const ElementInfo &info) { ElementDisplayInfo displayInfo; @@ -345,8 +346,6 @@ void GraphDisplay::mousePressEvent(QMouseEvent *event) m_displayInfo[i].m_isSelected = false; } - - void GraphDisplay::mouseReleaseEvent (QMouseEvent *event) { if(m_moveInfo.m_action == MakeConnect) @@ -411,7 +410,7 @@ void GraphDisplay::mouseReleaseEvent (QMouseEvent *event) msg += QString(infoDst.m_name.c_str()) + ":" + dstPad; msg += " was FAILED"; - QMessageBox::warning(this, "Coonection failed", msg); + QMessageBox::warning(this, "Connection failed", msg); } m_info = m_pGraph -> GetInfo(); @@ -467,7 +466,6 @@ exit: repaint(); } - void GraphDisplay::mouseMoveEvent(QMouseEvent *event) { if(m_moveInfo.m_action == MoveComponent) @@ -481,14 +479,11 @@ void GraphDisplay::mouseMoveEvent(QMouseEvent *event) { QRect newRect = m_displayInfo[i].m_rect; newRect.adjust(dx, dy, dx, dy); - if(contentsRect().contains(newRect)) m_displayInfo[i].m_rect = newRect; - break; } } - } if(m_moveInfo.m_action != None) @@ -499,19 +494,16 @@ void GraphDisplay::mouseMoveEvent(QMouseEvent *event) std::size_t elementId, padId; getIdByPosition(event -> pos(), elementId, padId); if (padId != ((size_t)-1)) { - ElementInfo* element = getElement(elementId); - PadInfo* pad = getPad(element, padId); - QString caps = m_pGraph->getPadCaps(element,pad,PAD_CAPS_ALL,true); - setToolTip(caps); + ElementInfo* element = getElement(elementId); + PadInfo* pad = getPad(elementId, padId); + QString caps = m_pGraph->getPadCaps(element,pad,PAD_CAPS_ALL,true); + setToolTip(caps); } else - setToolTip(""); - + setToolTip(""); } } - - void GraphDisplay::keyPressEvent(QKeyEvent* event) { if(event -> key() == Qt::Key_Delete) @@ -549,8 +541,11 @@ void GraphDisplay::showContextMenu(QMouseEvent *event) pact -> setDisabled(true); } - else if(padId != ((size_t)-1)) + else if(padId != ((size_t)-1)) { + menu.addAction(new CustomMenuAction("Render", &menu)); + menu.addAction(new CustomMenuAction("Render anyway", &menu)); menu.addAction(new CustomMenuAction("Pad properties", &menu)); + } else if(elementId != ((size_t)-1)) { menu.addAction(new CustomMenuAction("Element properties", &menu)); @@ -565,7 +560,6 @@ void GraphDisplay::showContextMenu(QMouseEvent *event) } else { - for(std::size_t i=0; i globalPos()); - if(pact) - { - if(pact -> getName() == "Remove") + if (pact) { + if (pact -> getName() == "Remove") removePlugin(elementId); - else if(pact -> getName() == "Element properties") + else if (pact -> getName() == "Element properties") showElementProperties(elementId); - else if(pact -> getName() == "Pad properties") + else if (pact -> getName() == "Pad properties") showPadProperties(elementId, padId); - else if(pact -> getName() == "Disconnect") + else if (pact -> getName() == "Render") + renderPad(elementId, padId, true); + else if (pact -> getName() == "Render anyway") + renderPad(elementId, padId, false); + else if (pact -> getName() == "Disconnect") disconnect(elementId, padId); - else if(pact -> getName() == "Request pad...") + else if (pact -> getName() == "Request pad...") requestPad(elementId); - else if(pact -> getName() == "Remove selected") + else if (pact -> getName() == "Remove selected") removeSelected(); + else if(pact->getName() == "ElementName") + addPlugin(pact->text()); } } } - void GraphDisplay::removeSelected() { GstState state; @@ -662,39 +659,29 @@ void GraphDisplay::removeSelected() void GraphDisplay::removePlugin(std::size_t id) { - std::size_t i=0; - for(; i RemovePlugin(m_info[i].m_name.c_str())) + if(m_pGraph -> RemovePlugin(element->m_name.c_str())) { std::vector info = m_pGraph -> GetInfo(); update(info); } else - QMessageBox::warning(this, "Element removing problem", "Element `" + QString(m_info[i].m_name.c_str()) + "` remowing was FAILED"); - + QMessageBox::warning(this, "Element removing problem", "Element `" + QString(element->m_name.c_str()) + "` remowing was FAILED"); } } +void GraphDisplay::addPlugin(const QString& name) +{ +} + void GraphDisplay::showElementProperties(std::size_t id) { - std::size_t i=0; - for(; im_name.c_str()); pprops -> setAttribute(Qt::WA_QuitOnClose, false); pprops -> show(); } @@ -702,27 +689,38 @@ void GraphDisplay::showElementProperties(std::size_t id) void GraphDisplay::showPadProperties(std::size_t elementId, std::size_t padId) { - std::size_t i=0; - for(; im_name.c_str(), pad->m_name.c_str()); + pprops -> setAttribute(Qt::WA_QuitOnClose, false); + pprops -> show(); } +} - if(i < m_info.size()) - { - std::size_t j=0; - for(; j setAttribute(Qt::WA_QuitOnClose, false); - pprops -> show(); - } - } + if(!element || !pad) + qDebug() << "element or pad is unreachable"; + + PluginsList* pluginList = new PluginsList(); + GList* plugins_list = pluginList->getSortedByRank(); + GList* l; + + for (l = plugins_list; l != NULL; l = l->next) { + Plugin* plugin = (Plugin*)(l->data); + if (m_pGraph->CanConnect(element->m_name.c_str(), pad->m_name.c_str() , plugin->getName().toStdString().c_str())) { + if (m_pGraph->CanConnect(element->m_name.c_str(), pad->m_name.c_str() , plugin->getName().toStdString().c_str(), capsAny)) { + gchar* pluginName = m_pGraph->AddPlugin(plugin->getName().toStdString().c_str(), NULL); + m_pGraph->Connect(element->m_name.c_str(), pluginName); + g_free(pluginName); + break; + } + } + delete pluginList; } void GraphDisplay::disconnect(size_t elementId, size_t padId) @@ -791,14 +789,13 @@ void GraphDisplay::disconnect(size_t elementId, size_t padId) return; - m_pGraph -> Disconnect(src.c_str(), srcPad.c_str(), dst.c_str(), dstPad.c_str()); + m_pGraph->Disconnect(src.c_str(), srcPad.c_str(), dst.c_str(), dstPad.c_str()); m_info = m_pGraph -> GetInfo(); updateDisplayInfoIds(); repaint(); } - void GraphDisplay::requestPad(std::size_t elementId) { QStringList labels; @@ -812,15 +809,10 @@ void GraphDisplay::requestPad(std::size_t elementId) ptwgt -> setSelectionBehavior(QAbstractItemView::SelectRows); ptwgt -> setEditTriggers(QAbstractItemView::NoEditTriggers); + ElementInfo* elementInfo = getElement(elementId); GstElement *element = NULL; - for(std::size_t i=0; i m_pGraph), m_info[i].m_name.c_str()); - break; - } - } + if(elementInfo) + element = gst_bin_get_by_name(GST_BIN(m_pGraph -> m_pGraph),elementInfo->m_name.c_str()); if(!element) { @@ -953,8 +945,6 @@ void GraphDisplay::getIdByPosition(const QPoint &pos, std::size_t &elementId, st } } - - QPoint GraphDisplay::getPadPosition(std::size_t elementId, std::size_t padId) { QPoint res; diff --git a/src/GraphDisplay.h b/src/GraphDisplay.h index db5cdc8..1c86978 100644 --- a/src/GraphDisplay.h +++ b/src/GraphDisplay.h @@ -72,15 +72,17 @@ private: void showContextMenu(QMouseEvent *event); void showElementProperties(std::size_t id); void showPadProperties(std::size_t elementId, std::size_t padId); + void renderPad(std::size_t elementId, std::size_t padId, bool capsAny); void removePlugin(std::size_t id); void removeSelected(); void getIdByPosition(const QPoint &pos, std::size_t &elementId, std::size_t &padId); QPoint getPadPosition(std::size_t elementId, std::size_t padId); void disconnect(std::size_t elementId, std::size_t padId); void requestPad(std::size_t elementId); + void addPlugin(const QString& name); ElementInfo* getElement(std::size_t elementId); - PadInfo* getPad(ElementInfo* element, std::size_t padId); + PadInfo* getPad(std::size_t elementId, std::size_t padId); std::vector m_info; std::vector m_displayInfo; diff --git a/src/GraphManager.cpp b/src/GraphManager.cpp index c89bdba..796886d 100644 --- a/src/GraphManager.cpp +++ b/src/GraphManager.cpp @@ -93,11 +93,11 @@ QString GraphManager::getPadCaps(ElementInfo* elementInfo, PadInfo* padInfo, ePa return padCaps; } -bool GraphManager::AddPlugin(const char *plugin, const char *name) +gchar* GraphManager::AddPlugin(const char *plugin, const char *name) { GstElement *pel = gst_element_factory_make(plugin, name); if(!pel) - return false; + return NULL; if(GST_IS_URI_HANDLER(pel)) { @@ -121,7 +121,7 @@ bool GraphManager::AddPlugin(const char *plugin, const char *name) QString dir = CustomSettings::lastIODirectory(); if(gst_uri_handler_get_uri_type(GST_URI_HANDLER(pel)) == GST_URI_SRC) - path = QFileDialog::getOpenFileName(NULL, "Open Source File...", dir); + path = QFileDialog::getOpenFileName(NULL, "Open Media Source File...", dir); else path = QFileDialog::getSaveFileName(NULL, "Open Sink File...", dir); @@ -156,15 +156,18 @@ bool GraphManager::AddPlugin(const char *plugin, const char *name) gst_uri_handler_set_uri(GST_URI_HANDLER(pel), uri.toStdString().c_str()); #endif } - } } bool res = gst_bin_add(GST_BIN(m_pGraph), pel); - if(res) + if (res) gst_element_sync_state_with_parent(pel); + else { + gst_object_unref(pel); + return NULL; + } - return res; + return gst_element_get_name(pel); } @@ -199,7 +202,6 @@ bool GraphManager::OpenUri(const char *uri, const char *name) return res; } - bool GraphManager::Connect(const char *srcElement, const char *srcPad, const char *dstElement, const char *dstPad) { @@ -216,7 +218,20 @@ bool GraphManager::Connect(const char *srcElement, const char *srcPad, return res; } +bool GraphManager::Connect(const char *srcElement, const char *dstElement) +{ + GstElement *src = gst_bin_get_by_name (GST_BIN(m_pGraph), srcElement); + GstElement *dst = gst_bin_get_by_name (GST_BIN(m_pGraph), dstElement); + bool res = gst_element_link(src, dst); + + gboolean seekRes = gst_element_seek_simple(m_pGraph, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH, 0); + + gst_object_unref(src); + gst_object_unref(dst); + + return res; +} bool GraphManager::Disconnect(const char *srcElement, const char *srcPad, const char *dstElement, const char *dstPad) @@ -233,7 +248,6 @@ bool GraphManager::Disconnect(const char *srcElement, const char *srcPad, return true; } - std::vector GraphManager::GetInfo() { std::vector res; @@ -262,7 +276,6 @@ std::vector GraphManager::GetInfo() elementInfo.m_id = id; id++; - gchar *name = gst_element_get_name(element); elementInfo.m_name = name; g_free(name); @@ -496,3 +509,84 @@ bool GraphManager::SetPosition(double pos) return seekRes; } + +bool GraphManager::CanConnect(const char *srcName, const char *srcPadName, const char *destName, bool noANY) +{ + bool ret = false; + bool added = false; + GstElement *dest = NULL; + GstElement *src = NULL; + GstPad* srcPad = NULL; + GstCaps* srcCaps = NULL; + GstElementFactory *destFactory = NULL; + + src = gst_bin_get_by_name (GST_BIN(m_pGraph), srcName); + if (!src) { + qDebug() << "Unable to get the src element: " << srcName; + goto done; + } + + srcPad = gst_element_get_static_pad(src, srcPadName); + if (!srcPad) { + qDebug() << "Unable to get the src pad"; + goto done; + } + + srcCaps = gst_pad_get_current_caps(srcPad); + if (!srcCaps) { + qDebug() << "Unable to get the current caps for pad:" << srcPadName; + srcCaps =gst_pad_get_pad_template_caps(srcPad); + if (!srcCaps) { + qDebug() << "Unable to get the template caps for pad:" << srcPadName; + goto done; + } + } + + dest = gst_element_factory_make(destName, NULL); + if (!dest) { + qDebug() << "Unable to get the dest element: " << destName; + goto done; + } + + destFactory = gst_element_get_factory(dest); + if (!destFactory) { + qDebug() << "Unable to get the dest factory"; + goto done; + } + if (noANY && gst_element_factory_can_sink_any_caps(destFactory, srcCaps)) { + qDebug() << "The dest element " << destName << " can sink any caps"; + goto done; + } + + if(!gst_element_factory_can_sink_all_caps(destFactory, srcCaps)) { + gchar* caps_string = gst_caps_to_string(srcCaps); + qDebug() << "The dest element " << destName << " can not sink this caps: " << caps_string; + g_free (caps_string); + goto done; + } + + added = gst_bin_add(GST_BIN(m_pGraph), dest); + if (!added) { + qDebug() << "Unable to add element to the bin"; + goto done; + } + + ret = gst_element_link(src,dest); + if (ret) { + qDebug() << "Can link elements src " << GST_OBJECT_NAME(src) << " with dest " << GST_OBJECT_NAME(dest); + gst_element_unlink(src,dest); + } + +done: + if (added) { + gst_bin_remove(GST_BIN(m_pGraph), dest); + dest = NULL; + } + if (src) + gst_object_unref(src); + if (srcPad) + gst_object_unref(srcPad); + if (dest) + gst_object_unref(dest); + return ret; +} diff --git a/src/GraphManager.h b/src/GraphManager.h index 82f63df..cf4c53b 100644 --- a/src/GraphManager.h +++ b/src/GraphManager.h @@ -85,10 +85,11 @@ public: GraphManager(); ~GraphManager(); - bool AddPlugin(const char *plugin, const char *name); + gchar* AddPlugin(const char *plugin, const char *name); bool RemovePlugin(const char *name); bool Connect(const char *srcElement, const char *srcPad, const char *dstElement, const char *dstPad); + bool Connect(const char *srcElement, const char *dstElement); bool Disconnect(const char *srcElement, const char *srcPad, const char *dstElement, const char *dstPad); std::vector GetInfo(); @@ -99,6 +100,8 @@ public: bool SetPosition(double); PluginsList* getPluginsList() { return m_pluginsList;} + bool CanConnect(const char *srcName,const char *srcPadName, const char *destName, bool noANY = true); + bool Play(); bool Pause(); diff --git a/src/PluginsList.cpp b/src/PluginsList.cpp index 5654498..8306870 100644 --- a/src/PluginsList.cpp +++ b/src/PluginsList.cpp @@ -35,7 +35,7 @@ PluginsList::PluginsList() PluginsList::~PluginsList() { - g_list_free(m_pluginsList); + //g_list_free(m_pluginsList); } void PluginsList::init()