diff options
author | Tim Blechmann <tim@klingt.org> | 2024-04-05 12:45:41 +0800 |
---|---|---|
committer | Tim Blechmann <tim@klingt.org> | 2024-04-10 19:14:19 +0800 |
commit | b3aa31cf3fdb266251f2ae10db28205563482a29 (patch) | |
tree | b1f7b3c3949e572d69c24fb2b9c7ead0eb786ae0 /src/plugins | |
parent | 602fa9a5cf63d06245be99d271f7d18d5a1d0a01 (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')
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; |