diff options
11 files changed, 178 insertions, 37 deletions
diff --git a/src/multimedia/CMakeLists.txt b/src/multimedia/CMakeLists.txt index 183ef7343..8c58545b5 100644 --- a/src/multimedia/CMakeLists.txt +++ b/src/multimedia/CMakeLists.txt @@ -67,7 +67,7 @@ qt_internal_add_module(Multimedia qmaybe_p.h qtmultimediaglobal.h qtmultimediaglobal_p.h qerrorinfo_p.h - recording/qmediacapturesession.cpp recording/qmediacapturesession.h + recording/qmediacapturesession.cpp recording/qmediacapturesession.h recording/qmediacapturesession_p.h recording/qmediarecorder.cpp recording/qmediarecorder.h recording/qmediarecorder_p.h recording/qscreencapture.cpp recording/qscreencapture.h recording/qwindowcapture.cpp recording/qwindowcapture.h diff --git a/src/multimedia/platform/qplatformmediacapture.cpp b/src/multimedia/platform/qplatformmediacapture.cpp index 826228764..c8aded824 100644 --- a/src/multimedia/platform/qplatformmediacapture.cpp +++ b/src/multimedia/platform/qplatformmediacapture.cpp @@ -1,12 +1,14 @@ // Copyright (C) 2021 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only -#include <qtmultimediaglobal_p.h> -#include "qplatformmediacapture_p.h" -#include "qaudiodevice.h" -#include "qaudioinput.h" -#include "qplatformcamera_p.h" -#include "qplatformsurfacecapture_p.h" +#include <QtMultimedia/qaudiodevice.h> +#include <QtMultimedia/qaudioinput.h> +#include <QtMultimedia/qmediacapturesession.h> +#include <QtMultimedia/private/qplatformcamera_p.h> +#include <QtMultimedia/private/qplatformmediacapture_p.h> +#include <QtMultimedia/private/qmediacapturesession_p.h> +#include <QtMultimedia/private/qplatformsurfacecapture_p.h> +#include <QtMultimedia/private/qtmultimediaglobal_p.h> QT_BEGIN_NAMESPACE @@ -28,6 +30,15 @@ std::vector<QPlatformVideoSource *> QPlatformMediaCaptureSession::activeVideoSou return result; } +void *QPlatformMediaCaptureSession::nativePipeline(QMediaCaptureSession *session) +{ + auto sessionPrivate = session->d_func(); + if (!sessionPrivate || !sessionPrivate->captureSession) + return nullptr; + + return sessionPrivate->captureSession->nativePipeline(); +} + QT_END_NAMESPACE #include "moc_qplatformmediacapture_p.cpp" diff --git a/src/multimedia/platform/qplatformmediacapture_p.h b/src/multimedia/platform/qplatformmediacapture_p.h index 814fa160c..981cf199b 100644 --- a/src/multimedia/platform/qplatformmediacapture_p.h +++ b/src/multimedia/platform/qplatformmediacapture_p.h @@ -64,6 +64,11 @@ public: // TBD: implement ordering of the sources basing on the order of adding std::vector<QPlatformVideoSource *> activeVideoSources(); + virtual void *nativePipeline() { return nullptr; } + + // private API, the purpose is getting GstPipeline + static void *nativePipeline(QMediaCaptureSession *); + Q_SIGNALS: void cameraChanged(); void screenCaptureChanged(); diff --git a/src/multimedia/recording/qmediacapturesession.cpp b/src/multimedia/recording/qmediacapturesession.cpp index 0ff804bf4..f175cd98e 100644 --- a/src/multimedia/recording/qmediacapturesession.cpp +++ b/src/multimedia/recording/qmediacapturesession.cpp @@ -2,6 +2,7 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include "qmediacapturesession.h" +#include "qmediacapturesession_p.h" #include "qaudiodevice.h" #include "qcamera.h" #include "qmediarecorder.h" @@ -10,8 +11,6 @@ #include "qscreencapture.h" #include "qwindowcapture.h" -#include <qpointer.h> - #include "qplatformmediaintegration_p.h" #include "qplatformmediacapture_p.h" #include "qaudioinput.h" @@ -19,35 +18,19 @@ QT_BEGIN_NAMESPACE -class QMediaCaptureSessionPrivate +void QMediaCaptureSessionPrivate::setVideoSink(QVideoSink *sink) { -public: - QMediaCaptureSession *q = nullptr; - QPlatformMediaCaptureSession *captureSession = nullptr; - QAudioInput *audioInput = nullptr; - QAudioOutput *audioOutput = nullptr; - QPointer<QCamera> camera; - QPointer<QScreenCapture> screenCapture; - QPointer<QWindowCapture> windowCapture; - QPointer<QImageCapture> imageCapture; - QPointer<QMediaRecorder> recorder; - QPointer<QVideoSink> videoSink; - QPointer<QObject> videoOutput; - - void setVideoSink(QVideoSink *sink) - { - if (sink == videoSink) - return; - if (videoSink) - videoSink->setSource(nullptr); - videoSink = sink; - if (sink) - sink->setSource(q); - if (captureSession) - captureSession->setVideoPreview(sink); - emit q->videoOutputChanged(); - } -}; + if (sink == videoSink) + return; + if (videoSink) + videoSink->setSource(nullptr); + videoSink = sink; + if (sink) + sink->setSource(q); + if (captureSession) + captureSession->setVideoPreview(sink); + emit q->videoOutputChanged(); +} /*! \class QMediaCaptureSession diff --git a/src/multimedia/recording/qmediacapturesession.h b/src/multimedia/recording/qmediacapturesession.h index c613c3615..1333af7eb 100644 --- a/src/multimedia/recording/qmediacapturesession.h +++ b/src/multimedia/recording/qmediacapturesession.h @@ -78,6 +78,8 @@ Q_SIGNALS: void audioOutputChanged(); private: + friend class QPlatformMediaCaptureSession; + QMediaCaptureSessionPrivate *d_ptr; Q_DISABLE_COPY(QMediaCaptureSession) Q_DECLARE_PRIVATE(QMediaCaptureSession) diff --git a/src/multimedia/recording/qmediacapturesession_p.h b/src/multimedia/recording/qmediacapturesession_p.h new file mode 100644 index 000000000..8702c8d2b --- /dev/null +++ b/src/multimedia/recording/qmediacapturesession_p.h @@ -0,0 +1,44 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#ifndef QMEDIACAPTURESESSION_P_H +#define QMEDIACAPTURESESSION_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtMultimedia/qmediacapturesession.h> + +#include <QtCore/qpointer.h> + +QT_BEGIN_NAMESPACE + +class QMediaCaptureSessionPrivate +{ +public: + QMediaCaptureSession *q = nullptr; + QPlatformMediaCaptureSession *captureSession = nullptr; + QAudioInput *audioInput = nullptr; + QAudioOutput *audioOutput = nullptr; + QPointer<QCamera> camera; + QPointer<QScreenCapture> screenCapture; + QPointer<QWindowCapture> windowCapture; + QPointer<QImageCapture> imageCapture; + QPointer<QMediaRecorder> recorder; + QPointer<QVideoSink> videoSink; + QPointer<QObject> videoOutput; + + void setVideoSink(QVideoSink *sink); +}; + +QT_END_NAMESPACE + +#endif // QMEDIACAPTURESESSION_P_H diff --git a/src/plugins/multimedia/gstreamer/mediacapture/qgstreamermediacapture.cpp b/src/plugins/multimedia/gstreamer/mediacapture/qgstreamermediacapture.cpp index 0574a1f1a..720ff5603 100644 --- a/src/plugins/multimedia/gstreamer/mediacapture/qgstreamermediacapture.cpp +++ b/src/plugins/multimedia/gstreamer/mediacapture/qgstreamermediacapture.cpp @@ -322,6 +322,10 @@ QGstreamerVideoSink *QGstreamerMediaCapture::gstreamerVideoSink() const return gstVideoOutput ? gstVideoOutput->gstreamerVideoSink() : nullptr; } +void *QGstreamerMediaCapture::nativePipeline() +{ + return gstPipeline.pipeline(); +} QT_END_NAMESPACE diff --git a/src/plugins/multimedia/gstreamer/mediacapture/qgstreamermediacapture_p.h b/src/plugins/multimedia/gstreamer/mediacapture/qgstreamermediacapture_p.h index 6e93e8564..219773413 100644 --- a/src/plugins/multimedia/gstreamer/mediacapture/qgstreamermediacapture_p.h +++ b/src/plugins/multimedia/gstreamer/mediacapture/qgstreamermediacapture_p.h @@ -63,6 +63,8 @@ public: QGstreamerVideoSink *gstreamerVideoSink() const; + void *nativePipeline() override; + private: void setCameraActive(bool activate); diff --git a/tests/auto/unit/multimedia/CMakeLists.txt b/tests/auto/unit/multimedia/CMakeLists.txt index 20b86c251..598bad5ad 100644 --- a/tests/auto/unit/multimedia/CMakeLists.txt +++ b/tests/auto/unit/multimedia/CMakeLists.txt @@ -33,5 +33,6 @@ add_subdirectory(qwavedecoder) if(QT_FEATURE_gstreamer) add_subdirectory(gstreamer_backend) + add_subdirectory(qmediacapture_gstreamer) add_subdirectory(qmediaplayer_gstreamer) endif() diff --git a/tests/auto/unit/multimedia/qmediacapture_gstreamer/CMakeLists.txt b/tests/auto/unit/multimedia/qmediacapture_gstreamer/CMakeLists.txt new file mode 100644 index 000000000..8a4734434 --- /dev/null +++ b/tests/auto/unit/multimedia/qmediacapture_gstreamer/CMakeLists.txt @@ -0,0 +1,14 @@ +# Copyright (C) 2024 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +##################################################################### +## tst_qmediacapture_gstreamer Test: +##################################################################### + +qt_internal_add_test(tst_qmediacapture_gstreamer + SOURCES + tst_qmediacapture_gstreamer.cpp + LIBRARIES + Qt::MultimediaPrivate + Qt::QGstreamerMediaPluginPrivate +) diff --git a/tests/auto/unit/multimedia/qmediacapture_gstreamer/tst_qmediacapture_gstreamer.cpp b/tests/auto/unit/multimedia/qmediacapture_gstreamer/tst_qmediacapture_gstreamer.cpp new file mode 100644 index 000000000..21258005c --- /dev/null +++ b/tests/auto/unit/multimedia/qmediacapture_gstreamer/tst_qmediacapture_gstreamer.cpp @@ -0,0 +1,75 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include <QtTest/QtTest> +#include <QtMultimedia/QMediaCaptureSession> +#include <QtMultimedia/private/qplatformmediacapture_p.h> +#include <QtQGstreamerMediaPlugin/private/qgstpipeline_p.h> + +#include <memory> + +QT_USE_NAMESPACE + +class tst_QMediaCaptureGStreamer : public QObject +{ + Q_OBJECT + +public: + tst_QMediaCaptureGStreamer(); + +public slots: + void init(); + void cleanup(); + +private slots: + void constructor_preparesGstPipeline(); + +private: + std::unique_ptr<QMediaCaptureSession> session; + + GstPipeline *getGstPipeline() + { + return reinterpret_cast<GstPipeline *>( + QPlatformMediaCaptureSession::nativePipeline(session.get())); + } + + void dumpGraph(const char *fileNamePrefix) + { + GST_DEBUG_BIN_TO_DOT_FILE(GST_BIN(getGstPipeline()), + GstDebugGraphDetails(GST_DEBUG_GRAPH_SHOW_VERBOSE), + fileNamePrefix); + } +}; + +tst_QMediaCaptureGStreamer::tst_QMediaCaptureGStreamer() +{ + qputenv("QT_MEDIA_BACKEND", "gstreamer"); +} + +void tst_QMediaCaptureGStreamer::init() +{ + session = std::make_unique<QMediaCaptureSession>(); +} + +void tst_QMediaCaptureGStreamer::cleanup() +{ + session.reset(); +} + +void tst_QMediaCaptureGStreamer::constructor_preparesGstPipeline() +{ + auto *rawPipeline = getGstPipeline(); + QVERIFY(rawPipeline); + + QGstPipeline pipeline{ + rawPipeline, + QGstPipeline::NeedsRef, + }; + QVERIFY(pipeline); + + dumpGraph("constructor_preparesGstPipeline"); +} + +QTEST_GUILESS_MAIN(tst_QMediaCaptureGStreamer) + +#include "tst_qmediacapture_gstreamer.moc" |