summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTim Blechmann <tim@klingt.org>2024-04-05 18:37:02 +0800
committerTim Blechmann <tim@klingt.org>2024-05-09 07:50:54 +0800
commit200f6d9c0db2af9166cea44cb1cdc48a85d0150e (patch)
tree7507d2014cc8e7b26f56e15a0c24d916f763ad95
parent47b41ef5f1b9612f761bd7cfcfd60c60cc64b8f8 (diff)
GStreamer: add createFromPipelineDescription
Helper functions to run `gst_parse_launch` and friends. Pick-to: 6.5 6.7 Change-Id: Iaa45fe97778ebea82cde155f925b309fa8ec8561 Reviewed-by: Jøger Hansegård <joger.hansegard@qt.io> Reviewed-by: Artem Dyomin <artem.dyomin@qt.io>
-rw-r--r--src/plugins/multimedia/gstreamer/common/qgst.cpp54
-rw-r--r--src/plugins/multimedia/gstreamer/common/qgst_p.h9
-rw-r--r--tests/auto/unit/multimedia/gstreamer_backend/tst_gstreamer_backend.cpp47
-rw-r--r--tests/auto/unit/multimedia/gstreamer_backend/tst_gstreamer_backend.h4
4 files changed, 113 insertions, 1 deletions
diff --git a/src/plugins/multimedia/gstreamer/common/qgst.cpp b/src/plugins/multimedia/gstreamer/common/qgst.cpp
index 8a77533a6..6f1a291a1 100644
--- a/src/plugins/multimedia/gstreamer/common/qgst.cpp
+++ b/src/plugins/multimedia/gstreamer/common/qgst.cpp
@@ -656,6 +656,11 @@ GType QGstObject::type() const
return G_OBJECT_TYPE(get());
}
+const char *QGstObject::typeName() const
+{
+ return g_type_name(type());
+}
+
GstObject *QGstObject::object() const
{
return get();
@@ -858,6 +863,25 @@ QGstElement QGstElement::createFromDevice(GstDevice *device, const char *name)
};
}
+QGstElement QGstElement::createFromPipelineDescription(const char *str)
+{
+ QUniqueGErrorHandle error;
+ QGstElement element{
+ gst_parse_launch(str, &error),
+ QGstElement::NeedsRef,
+ };
+
+ if (error) // error does not mean that the element could not be constructed
+ qWarning() << "gst_parse_launch error:" << error;
+
+ return element;
+}
+
+QGstElement QGstElement::createFromPipelineDescription(const QByteArray &str)
+{
+ return createFromPipelineDescription(str.constData());
+}
+
QGstPad QGstElement::staticPad(const char *name) const
{
return QGstPad(gst_element_get_static_pad(element(), name), HasRef);
@@ -1016,6 +1040,36 @@ QGstBin QGstBin::createFromFactory(const char *factory, const char *name)
};
}
+QGstBin QGstBin::createFromPipelineDescription(const QByteArray &pipelineDescription,
+ const char *name, bool ghostUnlinkedPads)
+{
+ return createFromPipelineDescription(pipelineDescription.constData(), name, ghostUnlinkedPads);
+}
+
+QGstBin QGstBin::createFromPipelineDescription(const char *pipelineDescription, const char *name,
+ bool ghostUnlinkedPads)
+{
+ QUniqueGErrorHandle error;
+
+ GstElement *element =
+ gst_parse_bin_from_description_full(pipelineDescription, ghostUnlinkedPads,
+ /*context=*/nullptr, GST_PARSE_FLAG_NONE, &error);
+
+ if (!element) {
+ qWarning() << "Failed to make element from pipeline description" << pipelineDescription
+ << error;
+ return QGstBin{};
+ }
+
+ if (name)
+ gst_element_set_name(element, name);
+
+ return QGstBin{
+ element,
+ NeedsRef,
+ };
+}
+
QGstBin::QGstBin(GstBin *bin, RefMode mode)
: QGstElement{
qGstCheckedCast<GstElement>(bin),
diff --git a/src/plugins/multimedia/gstreamer/common/qgst_p.h b/src/plugins/multimedia/gstreamer/common/qgst_p.h
index ec41b508d..34b7e7e22 100644
--- a/src/plugins/multimedia/gstreamer/common/qgst_p.h
+++ b/src/plugins/multimedia/gstreamer/common/qgst_p.h
@@ -408,6 +408,7 @@ public:
void disconnect(gulong handlerId);
GType type() const;
+ const char *typeName() const;
GstObject *object() const;
const char *name() const;
};
@@ -558,6 +559,8 @@ public:
const char *name = nullptr);
static QGstElement createFromDevice(const QGstDeviceHandle &, const char *name = nullptr);
static QGstElement createFromDevice(GstDevice *, const char *name = nullptr);
+ static QGstElement createFromPipelineDescription(const char *);
+ static QGstElement createFromPipelineDescription(const QByteArray &);
QGstPad staticPad(const char *name) const;
QGstPad src() const;
@@ -669,6 +672,12 @@ public:
explicit QGstBin(GstBin *bin, RefMode mode = NeedsRef);
static QGstBin create(const char *name);
static QGstBin createFromFactory(const char *factory, const char *name);
+ static QGstBin createFromPipelineDescription(const QByteArray &pipelineDescription,
+ const char *name = nullptr,
+ bool ghostUnlinkedPads = false);
+ static QGstBin createFromPipelineDescription(const char *pipelineDescription,
+ const char *name = nullptr,
+ bool ghostUnlinkedPads = false);
template <typename... Ts>
std::enable_if_t<(std::is_base_of_v<QGstElement, Ts> && ...), void> add(const Ts &...ts)
diff --git a/tests/auto/unit/multimedia/gstreamer_backend/tst_gstreamer_backend.cpp b/tests/auto/unit/multimedia/gstreamer_backend/tst_gstreamer_backend.cpp
index b0d814dfd..763ff01bf 100644
--- a/tests/auto/unit/multimedia/gstreamer_backend/tst_gstreamer_backend.cpp
+++ b/tests/auto/unit/multimedia/gstreamer_backend/tst_gstreamer_backend.cpp
@@ -4,8 +4,10 @@
#include "tst_gstreamer_backend.h"
#include <QtTest/QtTest>
-#include <QtQGstreamerMediaPlugin/private/qgstreamermetadata_p.h>
+
#include <QtQGstreamerMediaPlugin/private/qgst_handle_types_p.h>
+#include <QtQGstreamerMediaPlugin/private/qgst_p.h>
+#include <QtQGstreamerMediaPlugin/private/qgstreamermetadata_p.h>
QT_USE_NAMESPACE
@@ -73,6 +75,49 @@ void tst_GStreamer::metadata_taglistToMetaData_extractsDuration()
QCOMPARE(parsed[QMediaMetaData::Duration].value<int>(), 400);
}
+void tst_GStreamer::QGstBin_createFromPipelineDescription()
+{
+ QGstBin bin = QGstBin::createFromPipelineDescription("identity name=foo ! identity name=bar");
+
+ QVERIFY(bin);
+ QVERIFY(bin.findByName("foo"));
+ QCOMPARE_EQ(bin.findByName("foo").getParent(), bin);
+ QVERIFY(bin.findByName("bar"));
+ QVERIFY(!bin.findByName("baz"));
+ bin.dumpGraph("QGstBin_createFromPipelineDescription");
+}
+
+void tst_GStreamer::QGstElement_createFromPipelineDescription()
+{
+ using namespace std::string_view_literals;
+ QGstElement element = QGstElement::createFromPipelineDescription("identity name=foo");
+ QCOMPARE_EQ(element.name(), "foo"sv);
+ QCOMPARE_EQ(element.typeName(), "GstIdentity"sv);
+}
+
+void tst_GStreamer::QGstElement_createFromPipelineDescription_multipleElementsCreatesBin()
+{
+ using namespace std::string_view_literals;
+ QGstElement element =
+ QGstElement::createFromPipelineDescription("identity name=foo ! identity name=bar");
+
+ QVERIFY(element);
+ QCOMPARE_EQ(element.typeName(), "GstPipeline"sv);
+
+ QGstBin bin{
+ qGstSafeCast<GstBin>(element.element()),
+ QGstBin::NeedsRef,
+ };
+
+ QVERIFY(bin);
+ QVERIFY(bin.findByName("foo"));
+ QCOMPARE_EQ(bin.findByName("foo").getParent(), bin);
+ QVERIFY(bin.findByName("bar"));
+ QVERIFY(!bin.findByName("baz"));
+
+ bin.dumpGraph("QGstElement_createFromPipelineDescription_multipleElements");
+}
+
QTEST_GUILESS_MAIN(tst_GStreamer)
#include "moc_tst_gstreamer_backend.cpp"
diff --git a/tests/auto/unit/multimedia/gstreamer_backend/tst_gstreamer_backend.h b/tests/auto/unit/multimedia/gstreamer_backend/tst_gstreamer_backend.h
index e84e3f7cd..0a1628031 100644
--- a/tests/auto/unit/multimedia/gstreamer_backend/tst_gstreamer_backend.h
+++ b/tests/auto/unit/multimedia/gstreamer_backend/tst_gstreamer_backend.h
@@ -24,6 +24,10 @@ private slots:
void metadata_taglistToMetaData_extractsOrientation_data();
void metadata_taglistToMetaData_extractsDuration();
+ void QGstBin_createFromPipelineDescription();
+ void QGstElement_createFromPipelineDescription();
+ void QGstElement_createFromPipelineDescription_multipleElementsCreatesBin();
+
private:
QGstreamerIntegration integration;
};