Render a suitable plugin

Allow to render and connect the first
found plugin.
Either anyway with ANY caps or fitting caps.
This commit is contained in:
Stéphane Cerveau 2017-05-20 12:40:50 +02:00
parent 3de6d7f74e
commit b8f3b20fa3
5 changed files with 184 additions and 95 deletions

View file

@ -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(; j<element->m_pads.size(); j++)
if(element->m_pads[j].m_id == padId) {
@ -73,7 +77,6 @@ void GraphDisplay::updateDisplayInfoIds()
}
}
void GraphDisplay::update(const std::vector <ElementInfo> &info)
{
bool needUpdate = false;
@ -122,7 +125,6 @@ void GraphDisplay::update(const std::vector <ElementInfo> &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<m_info.size(); i++)
{
for(std::size_t j=0; j<m_info[i].m_connections.size(); j++)
@ -594,8 +588,7 @@ void GraphDisplay::showContextMenu(QMouseEvent *event)
double distance = std::abs((int)(dy * x0 - dx * y0 + x2 * y1 - y2 * x1));
distance = distance / sqrt(dy * dy + dx * dx);
if(distance < 5)
{
if (distance < 5) {
elementId = m_info[i].m_id;
padId = m_info[i].m_pads[j].m_id;
@ -617,25 +610,29 @@ void GraphDisplay::showContextMenu(QMouseEvent *event)
if(!menu.isEmpty())
{
CustomMenuAction *pact = (CustomMenuAction*)menu.exec(event -> 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<m_info.size(); i++)
ElementInfo* element = getElement(id);
if(element)
{
if(m_info[i].m_id == id)
break;
}
if(i < m_info.size())
{
if(m_pGraph -> RemovePlugin(m_info[i].m_name.c_str()))
if(m_pGraph -> RemovePlugin(element->m_name.c_str()))
{
std::vector<ElementInfo> 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(; i<m_info.size(); i++)
{
if(m_info[i].m_id == id)
break;
}
if(i < m_info.size())
{
ElementProperties *pprops = new ElementProperties(m_pGraph, m_info[i].m_name.c_str());
ElementInfo* element = getElement(id);
if (element) {
ElementProperties *pprops = new ElementProperties(m_pGraph,element->m_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(; i<m_info.size(); i++)
{
if(m_info[i].m_id == elementId)
break;
ElementInfo* element = getElement(elementId);
PadInfo* pad = getPad(elementId, padId);
if (pad) {
PadProperties *pprops = new PadProperties(m_pGraph, element->m_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<m_info[i].m_pads.size(); j++)
if(m_info[i].m_pads[j].m_id == padId)
break;
void GraphDisplay::renderPad(std::size_t elementId, std::size_t padId, bool capsAny)
{
ElementInfo* element = getElement(elementId);
PadInfo* pad = getPad(elementId, padId);
if(j < m_info[i].m_pads.size())
{
PadProperties *pprops = new PadProperties(m_pGraph, m_info[i].m_name.c_str(), m_info[i].m_pads[j].m_name.c_str());
pprops -> 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_info.size(); i++)
{
if(m_info[i].m_id == elementId)
{
element = gst_bin_get_by_name(GST_BIN(m_pGraph -> 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;

View file

@ -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 <ElementInfo> m_info;
std::vector <ElementDisplayInfo> m_displayInfo;

View file

@ -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 <ElementInfo> GraphManager::GetInfo()
{
std::vector <ElementInfo> res;
@ -262,7 +276,6 @@ std::vector <ElementInfo> 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;
}

View file

@ -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 <ElementInfo> 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();

View file

@ -35,7 +35,7 @@ PluginsList::PluginsList()
PluginsList::~PluginsList()
{
g_list_free(m_pluginsList);
//g_list_free(m_pluginsList);
}
void PluginsList::init()