summaryrefslogtreecommitdiffstats
path: root/src/plugins
diff options
context:
space:
mode:
authorTim Blechmann <tim@klingt.org>2024-04-05 12:45:41 +0800
committerTim Blechmann <tim@klingt.org>2024-04-10 19:14:19 +0800
commitb3aa31cf3fdb266251f2ae10db28205563482a29 (patch)
treeb1f7b3c3949e572d69c24fb2b9c7ead0eb786ae0 /src/plugins
parent602fa9a5cf63d06245be99d271f7d18d5a1d0a01 (diff)
GStreamer: introduce `QGstAppSrc` wrapper object
Pick-to: 6.5 6.6 6.7 Change-Id: Ic37390d74d0d6faac34d55c6dbe257ff30b437a0 Reviewed-by: Jøger Hansegård <joger.hansegard@qt.io> Reviewed-by: Artem Dyomin <artem.dyomin@qt.io>
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/multimedia/gstreamer/audio/qgstreameraudiodecoder.cpp13
-rw-r--r--src/plugins/multimedia/gstreamer/common/qgst.cpp50
-rw-r--r--src/plugins/multimedia/gstreamer/common/qgst_p.h37
-rw-r--r--src/plugins/multimedia/gstreamer/common/qgstappsource.cpp24
-rw-r--r--src/plugins/multimedia/gstreamer/common/qgstappsource_p.h6
5 files changed, 109 insertions, 21 deletions
diff --git a/src/plugins/multimedia/gstreamer/audio/qgstreameraudiodecoder.cpp b/src/plugins/multimedia/gstreamer/audio/qgstreameraudiodecoder.cpp
index 6777bc2bc..240c69b5b 100644
--- a/src/plugins/multimedia/gstreamer/audio/qgstreameraudiodecoder.cpp
+++ b/src/plugins/multimedia/gstreamer/audio/qgstreameraudiodecoder.cpp
@@ -93,11 +93,10 @@ QGstreamerAudioDecoder::~QGstreamerAudioDecoder()
}
#if QT_CONFIG(gstreamer_app)
-void QGstreamerAudioDecoder::configureAppSrcElement(GObject* object, GObject *orig, GParamSpec *pspec, QGstreamerAudioDecoder *self)
+void QGstreamerAudioDecoder::configureAppSrcElement([[maybe_unused]] GObject *object, GObject *orig,
+ [[maybe_unused]] GParamSpec *pspec,
+ QGstreamerAudioDecoder *self)
{
- Q_UNUSED(object);
- Q_UNUSED(pspec);
-
// In case we switch from appsrc to not
if (!self->m_appSrc)
return;
@@ -106,8 +105,10 @@ void QGstreamerAudioDecoder::configureAppSrcElement(GObject* object, GObject *or
g_object_get(orig, "source", &appsrc, NULL);
auto *qAppSrc = self->m_appSrc;
- qAppSrc->setExternalAppSrc(
- QGstElement(appsrc.get(), QGstElement::NeedsRef)); // CHECK: can we `release()`?
+ qAppSrc->setExternalAppSrc(QGstAppSrc{
+ qGstSafeCast<GstAppSrc>(appsrc.get()),
+ QGstAppSrc::NeedsRef, // CHECK: can we `release()`?
+ });
qAppSrc->setup(self->mDevice);
}
#endif
diff --git a/src/plugins/multimedia/gstreamer/common/qgst.cpp b/src/plugins/multimedia/gstreamer/common/qgst.cpp
index 2d7dd1bce..4f4f28d97 100644
--- a/src/plugins/multimedia/gstreamer/common/qgst.cpp
+++ b/src/plugins/multimedia/gstreamer/common/qgst.cpp
@@ -1056,6 +1056,21 @@ GstBaseSink *QGstBaseSink::baseSink() const
return qGstCheckedCast<GstBaseSink>(element());
}
+// QGstBaseSrc
+
+QGstBaseSrc::QGstBaseSrc(GstBaseSrc *element, RefMode mode)
+ : QGstElement{
+ qGstCheckedCast<GstElement>(element),
+ mode,
+ }
+{
+}
+
+GstBaseSrc *QGstBaseSrc::baseSrc() const
+{
+ return qGstCheckedCast<GstBaseSrc>(element());
+}
+
#if QT_CONFIG(gstreamer_app)
// QGstAppSink
@@ -1101,6 +1116,41 @@ QGstSampleHandle QGstAppSink::pullSample()
};
}
+// QGstAppSrc
+
+QGstAppSrc::QGstAppSrc(GstAppSrc *element, RefMode mode)
+ : QGstBaseSrc{
+ qGstCheckedCast<GstBaseSrc>(element),
+ mode,
+ }
+{
+}
+
+QGstAppSrc QGstAppSrc::create(const char *name)
+{
+ QGstElement created = QGstElement::createFromFactory("appsrc", name);
+ return QGstAppSrc{
+ qGstCheckedCast<GstAppSrc>(created.element()),
+ QGstAppSrc::NeedsRef,
+ };
+}
+
+GstAppSrc *QGstAppSrc::appSrc() const
+{
+ return qGstCheckedCast<GstAppSrc>(element());
+}
+
+void QGstAppSrc::setCallbacks(GstAppSrcCallbacks &callbacks, gpointer user_data,
+ GDestroyNotify notify)
+{
+ gst_app_src_set_callbacks(appSrc(), &callbacks, user_data, notify);
+}
+
+GstFlowReturn QGstAppSrc::pushBuffer(GstBuffer *buffer)
+{
+ return gst_app_src_push_buffer(appSrc(), buffer);
+}
+
#endif
QT_END_NAMESPACE
diff --git a/src/plugins/multimedia/gstreamer/common/qgst_p.h b/src/plugins/multimedia/gstreamer/common/qgst_p.h
index 51383fd3a..3c97ee604 100644
--- a/src/plugins/multimedia/gstreamer/common/qgst_p.h
+++ b/src/plugins/multimedia/gstreamer/common/qgst_p.h
@@ -695,6 +695,21 @@ public:
GstBaseSink *baseSink() const;
};
+class QGstBaseSrc : public QGstElement
+{
+public:
+ using QGstElement::QGstElement;
+
+ explicit QGstBaseSrc(GstBaseSrc *, RefMode);
+
+ QGstBaseSrc(const QGstBaseSrc &) = default;
+ QGstBaseSrc(QGstBaseSrc &&) noexcept = default;
+ QGstBaseSrc &operator=(const QGstBaseSrc &) = default;
+ QGstBaseSrc &operator=(QGstBaseSrc &&) noexcept = default;
+
+ GstBaseSrc *baseSrc() const;
+};
+
#if QT_CONFIG(gstreamer_app)
class QGstAppSink : public QGstBaseSink
{
@@ -717,6 +732,28 @@ public:
QGstSampleHandle pullSample();
};
+
+class QGstAppSrc : public QGstBaseSrc
+{
+public:
+ using QGstBaseSrc::QGstBaseSrc;
+
+ explicit QGstAppSrc(GstAppSrc *, RefMode);
+
+ QGstAppSrc(const QGstAppSrc &) = default;
+ QGstAppSrc(QGstAppSrc &&) noexcept = default;
+ QGstAppSrc &operator=(const QGstAppSrc &) = default;
+ QGstAppSrc &operator=(QGstAppSrc &&) noexcept = default;
+
+ static QGstAppSrc create(const char *name);
+
+ GstAppSrc *appSrc() const;
+
+ void setCallbacks(GstAppSrcCallbacks &callbacks, gpointer user_data, GDestroyNotify notify);
+
+ GstFlowReturn pushBuffer(GstBuffer *); // take ownership
+};
+
#endif
inline QString errorMessageCannotFindElement(std::string_view element)
diff --git a/src/plugins/multimedia/gstreamer/common/qgstappsource.cpp b/src/plugins/multimedia/gstreamer/common/qgstappsource.cpp
index 78443ac19..e27f32f1a 100644
--- a/src/plugins/multimedia/gstreamer/common/qgstappsource.cpp
+++ b/src/plugins/multimedia/gstreamer/common/qgstappsource.cpp
@@ -14,14 +14,14 @@ QT_BEGIN_NAMESPACE
QMaybe<QGstAppSource *> QGstAppSource::create(QObject *parent)
{
- QGstElement appsrc = QGstElement::createFromFactory("appsrc", "appsrc");
+ QGstAppSrc appsrc = QGstAppSrc::create("appsrc");
if (!appsrc)
return errorMessageCannotFindElement("appsrc");
return new QGstAppSource(appsrc, parent);
}
-QGstAppSource::QGstAppSource(QGstElement appsrc, QObject *parent)
+QGstAppSource::QGstAppSource(QGstAppSrc appsrc, QObject *parent)
: QObject(parent), m_appSrc(std::move(appsrc))
{
}
@@ -41,14 +41,14 @@ bool QGstAppSource::setup(QIODevice *stream, qint64 offset)
if (!setStream(stream, offset))
return false;
- auto *appSrc = GST_APP_SRC(m_appSrc.element());
- GstAppSrcCallbacks m_callbacks;
- memset(&m_callbacks, 0, sizeof(GstAppSrcCallbacks));
- m_callbacks.need_data = &QGstAppSource::on_need_data;
- m_callbacks.enough_data = &QGstAppSource::on_enough_data;
- m_callbacks.seek_data = &QGstAppSource::on_seek_data;
- gst_app_src_set_callbacks(appSrc, (GstAppSrcCallbacks*)&m_callbacks, this, nullptr);
+ GstAppSrcCallbacks callbacks{};
+ callbacks.need_data = QGstAppSource::on_need_data;
+ callbacks.enough_data = QGstAppSource::on_enough_data;
+ callbacks.seek_data = QGstAppSource::on_seek_data;
+ m_appSrc.setCallbacks(callbacks, this, nullptr);
+
+ GstAppSrc *appSrc = m_appSrc.appSrc();
m_maxBytes = gst_app_src_get_max_bytes(appSrc);
m_suspended = false;
@@ -76,9 +76,9 @@ void QGstAppSource::setAudioFormat(const QAudioFormat &f)
m_appSrc.set("format", GST_FORMAT_TIME);
}
-void QGstAppSource::setExternalAppSrc(const QGstElement &appsrc)
+void QGstAppSource::setExternalAppSrc(QGstAppSrc appsrc)
{
- m_appSrc = appsrc;
+ m_appSrc = std::move(appsrc);
}
bool QGstAppSource::setStream(QIODevice *stream, qint64 offset)
@@ -201,7 +201,7 @@ void QGstAppSource::pushData()
m_noMoreData = false;
emit bytesProcessed(bytesRead);
- GstFlowReturn ret = gst_app_src_push_buffer(GST_APP_SRC(m_appSrc.element()), buffer);
+ GstFlowReturn ret = m_appSrc.pushBuffer(buffer);
if (ret == GST_FLOW_ERROR) {
qWarning() << "QGstAppSrc: push buffer error";
} else if (ret == GST_FLOW_FLUSHING) {
diff --git a/src/plugins/multimedia/gstreamer/common/qgstappsource_p.h b/src/plugins/multimedia/gstreamer/common/qgstappsource_p.h
index e25398001..bcfb0b530 100644
--- a/src/plugins/multimedia/gstreamer/common/qgstappsource_p.h
+++ b/src/plugins/multimedia/gstreamer/common/qgstappsource_p.h
@@ -39,7 +39,7 @@ public:
bool setup(QIODevice *stream = nullptr, qint64 offset = 0);
void setAudioFormat(const QAudioFormat &f);
- void setExternalAppSrc(const QGstElement &appsrc);
+ void setExternalAppSrc(QGstAppSrc);
QGstElement element();
void write(const char *data, qsizetype size);
@@ -60,7 +60,7 @@ private Q_SLOTS:
void streamDestroyed();
private:
- QGstAppSource(QGstElement appsrc, QObject *parent);
+ QGstAppSource(QGstAppSrc appsrc, QObject *parent);
bool setStream(QIODevice *, qint64 offset);
bool isStreamValid() const
@@ -79,7 +79,7 @@ private:
QRingBuffer m_buffer;
QAudioFormat m_format;
- QGstElement m_appSrc;
+ QGstAppSrc m_appSrc;
bool m_sequential = true;
bool m_suspended = false;
bool m_noMoreData = false;