summaryrefslogtreecommitdiffstats
path: root/src/multimedia/recording
diff options
context:
space:
mode:
Diffstat (limited to 'src/multimedia/recording')
-rw-r--r--src/multimedia/recording/qaudiorecorder.cpp248
-rw-r--r--src/multimedia/recording/qaudiorecorder.h88
-rw-r--r--src/multimedia/recording/qcapturablewindow.cpp156
-rw-r--r--src/multimedia/recording/qcapturablewindow.h66
-rw-r--r--src/multimedia/recording/qcapturablewindow_p.h41
-rw-r--r--src/multimedia/recording/qmediacapturesession.cpp688
-rw-r--r--src/multimedia/recording/qmediacapturesession.h106
-rw-r--r--src/multimedia/recording/qmediacapturesession_p.h53
-rw-r--r--src/multimedia/recording/qmediaencodersettings.cpp952
-rw-r--r--src/multimedia/recording/qmediaencodersettings.h180
-rw-r--r--src/multimedia/recording/qmediarecorder.cpp1347
-rw-r--r--src/multimedia/recording/qmediarecorder.h249
-rw-r--r--src/multimedia/recording/qmediarecorder_p.h99
-rw-r--r--src/multimedia/recording/qscreencapture-limitations.qdocinc25
-rw-r--r--src/multimedia/recording/qscreencapture.cpp261
-rw-r--r--src/multimedia/recording/qscreencapture.h72
-rw-r--r--src/multimedia/recording/qvideoframeinput.cpp181
-rw-r--r--src/multimedia/recording/qvideoframeinput.h48
-rw-r--r--src/multimedia/recording/qwindowcapture.cpp268
-rw-r--r--src/multimedia/recording/qwindowcapture.h71
-rw-r--r--src/multimedia/recording/recording.pri14
21 files changed, 2776 insertions, 2437 deletions
diff --git a/src/multimedia/recording/qaudiorecorder.cpp b/src/multimedia/recording/qaudiorecorder.cpp
deleted file mode 100644
index 1db5c54a2..000000000
--- a/src/multimedia/recording/qaudiorecorder.cpp
+++ /dev/null
@@ -1,248 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qaudiorecorder.h"
-#include "qaudioinputselectorcontrol.h"
-#include "qmediaobject_p.h"
-#include "qmediarecorder_p.h"
-#include <qmediaservice.h>
-#include <qmediaserviceprovider_p.h>
-
-#include <QtCore/qdebug.h>
-#include <QtCore/qurl.h>
-#include <QtCore/qstringlist.h>
-#include <QtCore/qmetaobject.h>
-
-#include <qaudioformat.h>
-
-QT_BEGIN_NAMESPACE
-
-/*!
- \class QAudioRecorder
- \inmodule QtMultimedia
- \ingroup multimedia
- \ingroup multimedia_recording
-
- \brief The QAudioRecorder class is used for the recording of audio.
-
- The QAudioRecorder class is a high level media recording class and contains
- the same functionality as \l QMediaRecorder.
-
- \snippet multimedia-snippets/media.cpp Audio recorder
-
- In addition QAudioRecorder provides functionality for selecting the audio input.
-
- \snippet multimedia-snippets/media.cpp Audio recorder inputs
-
- The \l {Audio Recorder Example} shows how to use this class in more detail.
-
- \sa QMediaRecorder, QAudioInputSelectorControl
-*/
-
-class QAudioRecorderObject : public QMediaObject
-{
-public:
- QAudioRecorderObject(QObject *parent, QMediaService *service)
- :QMediaObject(parent, service)
- {
- }
-
- ~QAudioRecorderObject()
- {
- }
-};
-
-class QAudioRecorderPrivate : public QMediaRecorderPrivate
-{
- Q_DECLARE_NON_CONST_PUBLIC(QAudioRecorder)
-
-public:
- void initControls()
- {
- Q_Q(QAudioRecorder);
- audioInputSelector = nullptr;
-
- QMediaService *service = mediaObject ? mediaObject->service() : nullptr;
-
- if (service != nullptr)
- audioInputSelector = qobject_cast<QAudioInputSelectorControl*>(service->requestControl(QAudioInputSelectorControl_iid));
-
- if (audioInputSelector) {
- q->connect(audioInputSelector, SIGNAL(activeInputChanged(QString)),
- SIGNAL(audioInputChanged(QString)));
- q->connect(audioInputSelector, SIGNAL(availableInputsChanged()),
- SIGNAL(availableAudioInputsChanged()));
- }
- }
-
- QAudioRecorderPrivate():
- QMediaRecorderPrivate(),
- provider(nullptr),
- audioInputSelector(nullptr) {}
-
- QMediaServiceProvider *provider;
- QAudioInputSelectorControl *audioInputSelector;
-};
-
-
-
-/*!
- Constructs an audio recorder.
- The \a parent is passed to QMediaObject.
-*/
-
-QAudioRecorder::QAudioRecorder(QObject *parent):
- QMediaRecorder(*new QAudioRecorderPrivate, nullptr, parent)
-{
- Q_D(QAudioRecorder);
- d->provider = QMediaServiceProvider::defaultServiceProvider();
-
- QMediaService *service = d->provider->requestService(Q_MEDIASERVICE_AUDIOSOURCE);
- setMediaObject(new QAudioRecorderObject(this, service));
- d->initControls();
-}
-
-/*!
- Destroys an audio recorder object.
-*/
-
-QAudioRecorder::~QAudioRecorder()
-{
- Q_D(QAudioRecorder);
- QMediaService *service = d->mediaObject ? d->mediaObject->service() : nullptr;
- QMediaObject *mediaObject = d->mediaObject;
- setMediaObject(nullptr);
-
- if (service && d->audioInputSelector)
- service->releaseControl(d->audioInputSelector);
-
- if (d->provider && service)
- d->provider->releaseService(service);
-
- delete mediaObject;
-}
-
-/*!
- Returns a list of available audio inputs
-*/
-
-QStringList QAudioRecorder::audioInputs() const
-{
- Q_D(const QAudioRecorder);
- if (d->audioInputSelector)
- return d->audioInputSelector->availableInputs();
- else
- return QStringList();
-}
-
-/*!
- Returns the readable translated description of the audio input device with \a name.
-*/
-
-QString QAudioRecorder::audioInputDescription(const QString& name) const
-{
- Q_D(const QAudioRecorder);
-
- if (d->audioInputSelector)
- return d->audioInputSelector->inputDescription(name);
- else
- return QString();
-}
-
-/*!
- Returns the default audio input name.
-*/
-
-QString QAudioRecorder::defaultAudioInput() const
-{
- Q_D(const QAudioRecorder);
-
- if (d->audioInputSelector)
- return d->audioInputSelector->defaultInput();
- else
- return QString();
-}
-
-/*!
- \property QAudioRecorder::audioInput
- \brief the active audio input name.
-
-*/
-
-/*!
- Returns the active audio input name.
-*/
-
-QString QAudioRecorder::audioInput() const
-{
- Q_D(const QAudioRecorder);
-
- if (d->audioInputSelector)
- return d->audioInputSelector->activeInput();
- else
- return QString();
-}
-
-/*!
- Set the active audio input to \a name.
-*/
-
-void QAudioRecorder::setAudioInput(const QString& name)
-{
- Q_D(const QAudioRecorder);
-
- if (d->audioInputSelector)
- return d->audioInputSelector->setActiveInput(name);
-}
-
-/*!
- \fn QAudioRecorder::audioInputChanged(const QString& name)
-
- Signal emitted when active audio input changes to \a name.
-*/
-
-/*!
- \fn QAudioRecorder::availableAudioInputsChanged()
-
- Signal is emitted when the available audio inputs change.
-*/
-
-QT_END_NAMESPACE
-
-#include "moc_qaudiorecorder.cpp"
diff --git a/src/multimedia/recording/qaudiorecorder.h b/src/multimedia/recording/qaudiorecorder.h
deleted file mode 100644
index e57794b40..000000000
--- a/src/multimedia/recording/qaudiorecorder.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QAUDIORECORDER_H
-#define QAUDIORECORDER_H
-
-#include <QtMultimedia/qmediarecorder.h>
-#include <QtMultimedia/qmediaobject.h>
-#include <QtMultimedia/qmediaencodersettings.h>
-#include <QtMultimedia/qmediaenumdebug.h>
-
-#include <QtCore/qpair.h>
-
-QT_BEGIN_NAMESPACE
-
-class QString;
-class QSize;
-class QAudioFormat;
-QT_END_NAMESPACE
-
-QT_BEGIN_NAMESPACE
-
-class QAudioRecorderPrivate;
-class Q_MULTIMEDIA_EXPORT QAudioRecorder : public QMediaRecorder
-{
- Q_OBJECT
- Q_PROPERTY(QString audioInput READ audioInput WRITE setAudioInput NOTIFY audioInputChanged)
-public:
- explicit QAudioRecorder(QObject *parent = nullptr);
- ~QAudioRecorder();
-
- QStringList audioInputs() const;
- QString defaultAudioInput() const;
- QString audioInputDescription(const QString& name) const;
-
- QString audioInput() const;
-
-public Q_SLOTS:
- void setAudioInput(const QString& name);
-
-Q_SIGNALS:
- void audioInputChanged(const QString& name);
- void availableAudioInputsChanged();
-
-private:
- Q_DISABLE_COPY(QAudioRecorder)
- Q_DECLARE_PRIVATE(QAudioRecorder)
-};
-
-QT_END_NAMESPACE
-
-#endif // QAUDIORECORDER_H
diff --git a/src/multimedia/recording/qcapturablewindow.cpp b/src/multimedia/recording/qcapturablewindow.cpp
new file mode 100644
index 000000000..34b6a1f5d
--- /dev/null
+++ b/src/multimedia/recording/qcapturablewindow.cpp
@@ -0,0 +1,156 @@
+// Copyright (C) 2023 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 "qcapturablewindow.h"
+#include "qcapturablewindow_p.h"
+#include "qplatformmediaintegration_p.h"
+
+QT_BEGIN_NAMESPACE
+
+QT_DEFINE_QESDP_SPECIALIZATION_DTOR(QCapturableWindowPrivate)
+
+/*!
+ \class QCapturableWindow
+ \inmodule QtMultimedia
+ \ingroup multimedia
+ \ingroup multimedia_video
+ \since 6.6
+
+ \brief Used for getting the basic information of a capturable window.
+
+ The class contains a set of window information, except the method
+ QCapturableWindow::isValid which pulls the current state
+ whenever it's called.
+
+ \sa QWindowCapture
+*/
+/*!
+ \qmlvaluetype CapturableWindow
+ \instantiates QCapturableWindow
+ \brief The CapturableWindow type is used getting basic
+ of a window that is available for capturing via WindowCapture.
+
+ \inqmlmodule QtMultimedia
+ \ingroup multimedia_qml
+ \ingroup multimedia_video_qml
+ \since 6.6
+
+ The class contains a dump of window information, except the property
+ 'isValid' which pulls the actual window state every time.
+
+ \sa WindowCapture
+*/
+
+/*!
+ \fn QCapturableWindow::QCapturableWindow(QCapturableWindow &&other)
+
+ Constructs a QCapturableWindow by moving from \a other.
+*/
+
+/*!
+ \fn void QCapturableWindow::swap(QCapturableWindow &other) noexcept
+
+ Swaps the current window information with \a other.
+*/
+
+/*!
+ \fn QCapturableWindow &QCapturableWindow::operator=(QCapturableWindow &&other)
+
+ Moves \a other into this QCapturableWindow.
+*/
+
+/*!
+ Constructs a null capturable window information that doesn't refer to any window.
+*/
+QCapturableWindow::QCapturableWindow() = default;
+
+/*!
+ Destroys the window information.
+ */
+QCapturableWindow::~QCapturableWindow() = default;
+
+/*!
+ Construct a new window information using \a other QCapturableWindow.
+*/
+QCapturableWindow::QCapturableWindow(const QCapturableWindow &other) = default;
+
+/*!
+ Assigns the \a other window information to this QCapturableWindow.
+*/
+QCapturableWindow& QCapturableWindow::operator=(const QCapturableWindow &other) = default;
+
+/*!
+ \fn bool QCapturableWindow::operator==(const QCapturableWindow &lhs, const QCapturableWindow &rhs)
+
+ Returns \c true if window information \a lhs and \a rhs refer to the same window,
+ otherwise returns \c false.
+*/
+
+/*!
+ \fn bool QCapturableWindow::operator!=(const QCapturableWindow &lhs, const QCapturableWindow &rhs)
+
+ Returns \c true if window information \a lhs and \a rhs refer to different windows,
+ otherwise returns \c false.
+*/
+bool operator==(const QCapturableWindow &lhs, const QCapturableWindow &rhs) noexcept
+{
+ return lhs.d == rhs.d || (lhs.d && rhs.d && lhs.d->id == rhs.d->id);
+}
+
+/*!
+ \qmlproperty string QtMultimedia::CapturableWindow::isValid
+
+ This property identifies whether a window information is valid.
+
+ An invalid window information refers to non-existing window or doesn't refer to any one.
+*/
+
+/*!
+ Identifies whether a window information is valid.
+
+ An invalid window information refers to non-existing window or doesn't refer to any one.
+
+ Returns true if the window is valid, and false if it is not.
+*/
+bool QCapturableWindow::isValid() const
+{
+ return d && QPlatformMediaIntegration::instance()->isCapturableWindowValid(*d);
+}
+
+/*!
+ \qmlproperty string QtMultimedia::CapturableWindow::description
+
+ This property holds the description of the reffered window.
+*/
+
+/*!
+ Returns a description of the window. In most cases it represents the window title.
+*/
+QString QCapturableWindow::description() const
+{
+ if (!d)
+ return {};
+
+ if (d->description.isEmpty() && d->id)
+ return QLatin1String("Window 0x") + QString::number(d->id, 16);
+
+ return d->description;
+}
+
+QCapturableWindow::QCapturableWindow(QCapturableWindowPrivate *capturablePrivate)
+ : d(capturablePrivate)
+{
+}
+
+#ifndef QT_NO_DEBUG_STREAM
+QDebug operator<<(QDebug dbg, const QCapturableWindow &window)
+{
+ dbg << QStringLiteral("Capturable window '%1'").arg(window.description());
+ return dbg;
+}
+#endif
+
+
+QT_END_NAMESPACE
+
+#include "moc_qcapturablewindow.cpp"
diff --git a/src/multimedia/recording/qcapturablewindow.h b/src/multimedia/recording/qcapturablewindow.h
new file mode 100644
index 000000000..f18dbf72d
--- /dev/null
+++ b/src/multimedia/recording/qcapturablewindow.h
@@ -0,0 +1,66 @@
+// Copyright (C) 2023 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 QCAPTURABLEWINDOW_H
+#define QCAPTURABLEWINDOW_H
+
+#include <QtMultimedia/qtmultimediaglobal.h>
+#include <QtCore/qmetatype.h>
+#include <QtCore/qshareddata.h>
+
+QT_BEGIN_NAMESPACE
+
+class QCapturableWindowPrivate;
+QT_DECLARE_QESDP_SPECIALIZATION_DTOR_WITH_EXPORT(QCapturableWindowPrivate, Q_MULTIMEDIA_EXPORT)
+
+class QMediaCaptureSession;
+class QWindowCapturePrivate;
+
+class QCapturableWindow
+{
+ Q_GADGET_EXPORT(Q_MULTIMEDIA_EXPORT)
+ Q_PROPERTY(QString description READ description CONSTANT)
+ Q_PROPERTY(bool isValid READ isValid CONSTANT)
+public:
+ Q_MULTIMEDIA_EXPORT QCapturableWindow();
+
+ Q_MULTIMEDIA_EXPORT ~QCapturableWindow();
+
+ Q_MULTIMEDIA_EXPORT QCapturableWindow(const QCapturableWindow &other);
+
+ QCapturableWindow(QCapturableWindow &&other) noexcept = default;
+
+ Q_MULTIMEDIA_EXPORT QCapturableWindow& operator=(const QCapturableWindow &other);
+
+ QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_PURE_SWAP(QCapturableWindow);
+
+ void swap(QCapturableWindow &other) noexcept
+ { d.swap(other.d); }
+
+ Q_MULTIMEDIA_EXPORT friend bool operator==(const QCapturableWindow &lhs, const QCapturableWindow &rhs) noexcept;
+
+ friend bool operator!=(const QCapturableWindow &lhs, const QCapturableWindow &rhs) noexcept
+ { return !(lhs == rhs); }
+
+ Q_MULTIMEDIA_EXPORT bool isValid() const;
+
+ Q_MULTIMEDIA_EXPORT QString description() const;
+
+#ifndef QT_NO_DEBUG_STREAM
+ Q_MULTIMEDIA_EXPORT friend QDebug operator<<(QDebug, const QCapturableWindow &);
+#endif
+
+private:
+ Q_MULTIMEDIA_EXPORT QCapturableWindow(QCapturableWindowPrivate *capturablePrivate);
+ friend class QCapturableWindowPrivate;
+
+ QExplicitlySharedDataPointer<QCapturableWindowPrivate> d;
+};
+
+Q_DECLARE_SHARED(QCapturableWindow)
+
+QT_END_NAMESPACE
+
+Q_DECLARE_METATYPE(QCapturableWindow)
+
+#endif // QCAPTURABLEWINDOW_H
diff --git a/src/multimedia/recording/qcapturablewindow_p.h b/src/multimedia/recording/qcapturablewindow_p.h
new file mode 100644
index 000000000..9cb186a77
--- /dev/null
+++ b/src/multimedia/recording/qcapturablewindow_p.h
@@ -0,0 +1,41 @@
+// Copyright (C) 2023 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 QCAPTURABLEWINDOW_P_H
+#define QCAPTURABLEWINDOW_P_H
+
+#include <QtGui/qwindowdefs.h>
+#include <QtCore/QSharedData>
+#include <QtMultimedia/qcapturablewindow.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.
+//
+
+QT_BEGIN_NAMESPACE
+
+class QCapturableWindowPrivate : public QSharedData {
+public:
+ using Id = size_t;
+
+ QString description;
+ Id id = 0;
+
+ static const QCapturableWindowPrivate *handle(const QCapturableWindow &window)
+ {
+ return window.d.get();
+ }
+
+ QCapturableWindow create() { return QCapturableWindow(this); }
+};
+
+QT_END_NAMESPACE
+
+#endif // QCAPTURABLEWINDOW_P_H
diff --git a/src/multimedia/recording/qmediacapturesession.cpp b/src/multimedia/recording/qmediacapturesession.cpp
new file mode 100644
index 000000000..9df09acef
--- /dev/null
+++ b/src/multimedia/recording/qmediacapturesession.cpp
@@ -0,0 +1,688 @@
+// Copyright (C) 2022 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 "qmediacapturesession.h"
+#include "qmediacapturesession_p.h"
+#include "qaudiodevice.h"
+#include "qcamera.h"
+#include "qmediarecorder.h"
+#include "qimagecapture.h"
+#include "qvideosink.h"
+#include "qscreencapture.h"
+#include "qwindowcapture.h"
+#include "qvideoframeinput.h"
+
+#include "qplatformmediaintegration_p.h"
+#include "qplatformmediacapture_p.h"
+#include "qaudioinput.h"
+#include "qaudiobufferinput.h"
+#include "qaudiooutput.h"
+
+QT_BEGIN_NAMESPACE
+
+void QMediaCaptureSessionPrivate::setVideoSink(QVideoSink *sink)
+{
+ Q_Q(QMediaCaptureSession);
+
+ 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
+
+ \brief The QMediaCaptureSession class allows capturing of audio and video content.
+ \inmodule QtMultimedia
+ \ingroup multimedia
+ \ingroup multimedia_video
+ \ingroup multimedia_audio
+
+ The QMediaCaptureSession is the central class that manages capturing of media on the local
+ device.
+
+ You can connect a video input to QMediaCaptureSession using setCamera(),
+ setScreenCapture(), setWindowCapture() or setVideoFrameInput().
+ A preview of the captured media can be seen by setting a QVideoWidget or QGraphicsVideoItem
+ using setVideoOutput().
+
+ You can connect a microphone to QMediaCaptureSession using setAudioInput(), or set your
+ custom audio input using setAudioBufferInput().
+ The captured sound can be heard by routing the audio to an output device using setAudioOutput().
+
+ You can capture still images from a camera by setting a QImageCapture object on the capture
+ session, and record audio/video using a QMediaRecorder.
+
+ \sa QCamera, QAudioDevice, QMediaRecorder, QImageCapture, QScreenCapture, QWindowCapture,
+ QVideoFrameInput, QMediaRecorder, QGraphicsVideoItem
+*/
+
+/*!
+ \qmltype CaptureSession
+ \since 6.2
+ \instantiates QMediaCaptureSession
+ \brief Allows capturing of audio and video content.
+
+ \inqmlmodule QtMultimedia
+ \ingroup multimedia_qml
+ \ingroup multimedia_audio_qml
+ \ingroup multimedia_video_qml
+
+ This is the central type that manages capturing of media on the local device.
+
+ Connect a camera and a microphone to a CaptureSession by assigning Camera
+ and AudioInput objects to the relevant properties.
+
+ Capture a screen by connecting a ScreenCapture object to
+ the screenCapture property.
+
+ Capture a window by connecting a WindowCapture object to
+ the windowCapture property.
+
+ Enable a preview of the captured media by assigning a VideoOutput element to
+ the videoOutput property.
+
+ Route audio to an output device by assigning an AudioOutput object
+ to the audioOutput property.
+
+ Capture still images from a camera by assigning an ImageCapture to the
+ imageCapture property.
+
+ Record audio/video by assigning a MediaRecorder to the recorder property.
+
+\qml
+ CaptureSession {
+ id: captureSession
+ camera: Camera {
+ id: camera
+ }
+ imageCapture: ImageCapture {
+ id: imageCapture
+ }
+
+ recorder: MediaRecorder {
+ id: recorder
+ }
+ videoOutput: preview
+ }
+\endqml
+
+ \sa Camera, MediaDevices, MediaRecorder, ImageCapture, ScreenCapture, WindowCapture, AudioInput, VideoOutput
+*/
+
+/*!
+ Creates a session for media capture from the \a parent object.
+ */
+QMediaCaptureSession::QMediaCaptureSession(QObject *parent)
+ : QObject{ *new QMediaCaptureSessionPrivate, parent }
+{
+ QT6_ONLY(Q_UNUSED(unused))
+
+ Q_D(QMediaCaptureSession);
+
+ auto maybeCaptureSession = QPlatformMediaIntegration::instance()->createCaptureSession();
+ if (maybeCaptureSession) {
+ d->captureSession.reset(maybeCaptureSession.value());
+ d->captureSession->setCaptureSession(this);
+ } else {
+ qWarning() << "Failed to initialize QMediaCaptureSession" << maybeCaptureSession.error();
+ }
+}
+
+/*!
+ Destroys the session.
+ */
+QMediaCaptureSession::~QMediaCaptureSession()
+{
+ Q_D(QMediaCaptureSession);
+
+ setCamera(nullptr);
+ setRecorder(nullptr);
+ setImageCapture(nullptr);
+ setScreenCapture(nullptr);
+ setWindowCapture(nullptr);
+ setVideoFrameInput(nullptr);
+ setAudioBufferInput(nullptr);
+ setAudioInput(nullptr);
+ setAudioOutput(nullptr);
+ d->setVideoSink(nullptr);
+ d->captureSession.reset();
+}
+/*!
+ \qmlproperty AudioInput QtMultimedia::CaptureSession::audioInput
+
+ This property holds the audio input that is being used to capture audio.
+*/
+
+/*!
+ \property QMediaCaptureSession::audioInput
+
+ Returns the device that is being used to capture audio.
+*/
+QAudioInput *QMediaCaptureSession::audioInput() const
+{
+ Q_D(const QMediaCaptureSession);
+ return d->audioInput;
+}
+
+/*!
+ Sets the audio input device to \a input. If setting it to an empty
+ QAudioDevice the capture session will use the default input as
+ defined by the operating system.
+*/
+void QMediaCaptureSession::setAudioInput(QAudioInput *input)
+{
+ Q_D(QMediaCaptureSession);
+
+ QAudioInput *oldInput = d->audioInput;
+ if (oldInput == input)
+ return;
+
+ // To avoid double emit of audioInputChanged
+ // from recursive setAudioInput(nullptr) call.
+ d->audioInput = nullptr;
+
+ if (d->captureSession)
+ d->captureSession->setAudioInput(nullptr);
+ if (oldInput)
+ oldInput->setDisconnectFunction({});
+ if (input) {
+ input->setDisconnectFunction([this](){ setAudioInput(nullptr); });
+ if (d->captureSession)
+ d->captureSession->setAudioInput(input->handle());
+ }
+ d->audioInput = input;
+ emit audioInputChanged();
+}
+
+/*!
+ \property QMediaCaptureSession::audioBufferInput
+ \since 6.8
+
+ \brief The object used to send custom audio buffers to \l QMediaRecorder.
+*/
+QAudioBufferInput *QMediaCaptureSession::audioBufferInput() const
+{
+ Q_D(const QMediaCaptureSession);
+
+ return d->audioBufferInput;
+}
+
+void QMediaCaptureSession::setAudioBufferInput(QAudioBufferInput *input)
+{
+ Q_D(QMediaCaptureSession);
+
+ // TODO: come up with an unification of the captures setup
+ QAudioBufferInput *oldInput = d->audioBufferInput;
+ if (oldInput == input)
+ return;
+ d->audioBufferInput = input;
+ if (d->captureSession)
+ d->captureSession->setAudioBufferInput(nullptr);
+ if (oldInput) {
+ if (oldInput->captureSession() && oldInput->captureSession() != this)
+ oldInput->captureSession()->setAudioBufferInput(nullptr);
+ oldInput->setCaptureSession(nullptr);
+ }
+ if (input) {
+ if (input->captureSession())
+ input->captureSession()->setAudioBufferInput(nullptr);
+ if (d->captureSession)
+ d->captureSession->setAudioBufferInput(input->platformAudioBufferInput());
+ input->setCaptureSession(this);
+ }
+ emit audioBufferInputChanged();
+}
+
+/*!
+ \qmlproperty Camera QtMultimedia::CaptureSession::camera
+
+ \brief The camera used to capture video.
+
+ Record video or take images by adding a camera to the capture session using
+ this property.
+*/
+
+/*!
+ \property QMediaCaptureSession::camera
+
+ \brief The camera used to capture video.
+
+ Record video or take images by adding a camera to the capture session
+ using this property.
+*/
+QCamera *QMediaCaptureSession::camera() const
+{
+ Q_D(const QMediaCaptureSession);
+
+ return d->camera;
+}
+
+void QMediaCaptureSession::setCamera(QCamera *camera)
+{
+ Q_D(QMediaCaptureSession);
+
+ // TODO: come up with an unification of the captures setup
+ QCamera *oldCamera = d->camera;
+ if (oldCamera == camera)
+ return;
+ d->camera = camera;
+ if (d->captureSession)
+ d->captureSession->setCamera(nullptr);
+ if (oldCamera) {
+ if (oldCamera->captureSession() && oldCamera->captureSession() != this)
+ oldCamera->captureSession()->setCamera(nullptr);
+ oldCamera->setCaptureSession(nullptr);
+ }
+ if (camera) {
+ if (camera->captureSession())
+ camera->captureSession()->setCamera(nullptr);
+ if (d->captureSession)
+ d->captureSession->setCamera(camera->platformCamera());
+ camera->setCaptureSession(this);
+ }
+ emit cameraChanged();
+}
+
+/*!
+ \qmlproperty ScreenCapture QtMultimedia::CaptureSession::screenCapture
+ \since 6.5
+
+ \brief The object used to capture a screen.
+
+ Record a screen by adding a screen capture objet
+ to the capture session using this property.
+*/
+
+/*!
+ \property QMediaCaptureSession::screenCapture
+ \since 6.5
+
+ \brief The object used to capture a screen.
+
+ Record a screen by adding a screen capture object
+ to the capture session using this property.
+*/
+QScreenCapture *QMediaCaptureSession::screenCapture()
+{
+ Q_D(QMediaCaptureSession);
+
+ return d->screenCapture;
+}
+
+void QMediaCaptureSession::setScreenCapture(QScreenCapture *screenCapture)
+{
+ Q_D(QMediaCaptureSession);
+
+ // TODO: come up with an unification of the captures setup
+ QScreenCapture *oldScreenCapture = d->screenCapture;
+ if (oldScreenCapture == screenCapture)
+ return;
+ d->screenCapture = screenCapture;
+ if (d->captureSession)
+ d->captureSession->setScreenCapture(nullptr);
+ if (oldScreenCapture) {
+ if (oldScreenCapture->captureSession() && oldScreenCapture->captureSession() != this)
+ oldScreenCapture->captureSession()->setScreenCapture(nullptr);
+ oldScreenCapture->setCaptureSession(nullptr);
+ }
+ if (screenCapture) {
+ if (screenCapture->captureSession())
+ screenCapture->captureSession()->setScreenCapture(nullptr);
+ if (d->captureSession)
+ d->captureSession->setScreenCapture(screenCapture->platformScreenCapture());
+ screenCapture->setCaptureSession(this);
+ }
+ emit screenCaptureChanged();
+}
+
+/*!
+ \qmlproperty WindowCapture QtMultimedia::CaptureSession::windowCapture
+ \since 6.6
+
+ \brief The object used to capture a window.
+
+ Record a window by adding a window capture object
+ to the capture session using this property.
+*/
+
+/*!
+ \property QMediaCaptureSession::windowCapture
+ \since 6.6
+
+ \brief The object used to capture a window.
+
+ Record a window by adding a window capture objet
+ to the capture session using this property.
+*/
+QWindowCapture *QMediaCaptureSession::windowCapture()
+{
+ Q_D(QMediaCaptureSession);
+ return d->windowCapture;
+}
+
+void QMediaCaptureSession::setWindowCapture(QWindowCapture *windowCapture)
+{
+ Q_D(QMediaCaptureSession);
+
+ // TODO: come up with an unification of the captures setup
+ QWindowCapture *oldCapture = d->windowCapture;
+ if (oldCapture == windowCapture)
+ return;
+ d->windowCapture = windowCapture;
+ if (d->captureSession)
+ d->captureSession->setWindowCapture(nullptr);
+ if (oldCapture) {
+ if (oldCapture->captureSession() && oldCapture->captureSession() != this)
+ oldCapture->captureSession()->setWindowCapture(nullptr);
+ oldCapture->setCaptureSession(nullptr);
+ }
+ if (windowCapture) {
+ if (windowCapture->captureSession())
+ windowCapture->captureSession()->setWindowCapture(nullptr);
+ if (d->captureSession)
+ d->captureSession->setWindowCapture(windowCapture->platformWindowCapture());
+ windowCapture->setCaptureSession(this);
+ }
+ emit windowCaptureChanged();
+}
+
+/*!
+ \property QMediaCaptureSession::videoFrameInput
+ \since 6.8
+
+ \brief The object used to send custom video frames to
+ \l QMediaRecorder or a video output.
+*/
+QVideoFrameInput *QMediaCaptureSession::videoFrameInput() const
+{
+ Q_D(const QMediaCaptureSession);
+ return d->videoFrameInput;
+}
+
+void QMediaCaptureSession::setVideoFrameInput(QVideoFrameInput *input)
+{
+ Q_D(QMediaCaptureSession);
+ // TODO: come up with an unification of the captures setup
+ QVideoFrameInput *oldInput = d->videoFrameInput;
+ if (oldInput == input)
+ return;
+ d->videoFrameInput = input;
+ if (d->captureSession)
+ d->captureSession->setVideoFrameInput(nullptr);
+ if (oldInput) {
+ if (oldInput->captureSession() && oldInput->captureSession() != this)
+ oldInput->captureSession()->setVideoFrameInput(nullptr);
+ oldInput->setCaptureSession(nullptr);
+ }
+ if (input) {
+ if (input->captureSession())
+ input->captureSession()->setVideoFrameInput(nullptr);
+ if (d->captureSession)
+ d->captureSession->setVideoFrameInput(input->platformVideoFrameInput());
+ input->setCaptureSession(this);
+ }
+ emit videoFrameInputChanged();
+}
+
+/*!
+ \qmlproperty ImageCapture QtMultimedia::CaptureSession::imageCapture
+
+ \brief The object used to capture still images.
+
+ Add an ImageCapture interface to the capture session to enable
+ capturing of still images from the camera.
+*/
+/*!
+ \property QMediaCaptureSession::imageCapture
+
+ \brief the object used to capture still images.
+
+ Add a QImageCapture object to the capture session to enable
+ capturing of still images from the camera.
+*/
+QImageCapture *QMediaCaptureSession::imageCapture()
+{
+ Q_D(QMediaCaptureSession);
+
+ return d->imageCapture;
+}
+
+void QMediaCaptureSession::setImageCapture(QImageCapture *imageCapture)
+{
+ Q_D(QMediaCaptureSession);
+
+ // TODO: come up with an unification of the captures setup
+ QImageCapture *oldImageCapture = d->imageCapture;
+ if (oldImageCapture == imageCapture)
+ return;
+ d->imageCapture = imageCapture;
+ if (d->captureSession)
+ d->captureSession->setImageCapture(nullptr);
+ if (oldImageCapture) {
+ if (oldImageCapture->captureSession() && oldImageCapture->captureSession() != this)
+ oldImageCapture->captureSession()->setImageCapture(nullptr);
+ oldImageCapture->setCaptureSession(nullptr);
+ }
+ if (imageCapture) {
+ if (imageCapture->captureSession())
+ imageCapture->captureSession()->setImageCapture(nullptr);
+ if (d->captureSession)
+ d->captureSession->setImageCapture(imageCapture->platformImageCapture());
+ imageCapture->setCaptureSession(this);
+ }
+ emit imageCaptureChanged();
+}
+/*!
+ \qmlproperty MediaRecorder QtMultimedia::CaptureSession::recorder
+
+ \brief The recorder object used to capture audio/video.
+
+ Add a MediaRcorder object to the capture session to enable
+ recording of audio and/or video from the capture session.
+*/
+/*!
+ \property QMediaCaptureSession::recorder
+
+ \brief The recorder object used to capture audio/video.
+
+ Add a QMediaRecorder object to the capture session to enable
+ recording of audio and/or video from the capture session.
+*/
+
+QMediaRecorder *QMediaCaptureSession::recorder()
+{
+ Q_D(QMediaCaptureSession);
+ return d->recorder;
+}
+
+void QMediaCaptureSession::setRecorder(QMediaRecorder *recorder)
+{
+ Q_D(QMediaCaptureSession);
+ QMediaRecorder *oldRecorder = d->recorder;
+ if (oldRecorder == recorder)
+ return;
+ d->recorder = recorder;
+ if (d->captureSession)
+ d->captureSession->setMediaRecorder(nullptr);
+ if (oldRecorder) {
+ if (oldRecorder->captureSession() && oldRecorder->captureSession() != this)
+ oldRecorder->captureSession()->setRecorder(nullptr);
+ oldRecorder->setCaptureSession(nullptr);
+ }
+ if (recorder) {
+ if (recorder->captureSession())
+ recorder->captureSession()->setRecorder(nullptr);
+ if (d->captureSession)
+ d->captureSession->setMediaRecorder(recorder->platformRecoder());
+ recorder->setCaptureSession(this);
+ }
+ emit recorderChanged();
+}
+/*!
+ \qmlproperty VideoOutput QtMultimedia::CaptureSession::videoOutput
+
+ \brief The VideoOutput that is the video preview for the capture session.
+
+ A VideoOutput based preview is expected to have an invokable videoSink()
+ method that returns a QVideoSink.
+
+ The previously set preview is detached.
+
+*/
+/*!
+ \property QMediaCaptureSession::videoOutput
+
+ Returns the video output for the session.
+*/
+QObject *QMediaCaptureSession::videoOutput() const
+{
+ Q_D(const QMediaCaptureSession);
+ return d->videoOutput;
+}
+/*!
+ Sets a QObject, (\a output), to a video preview for the capture session.
+
+ A QObject based preview is expected to have an invokable videoSink()
+ method that returns a QVideoSink.
+
+ The previously set preview is detached.
+*/
+void QMediaCaptureSession::setVideoOutput(QObject *output)
+{
+ Q_D(QMediaCaptureSession);
+ if (d->videoOutput == output)
+ return;
+ QVideoSink *sink = qobject_cast<QVideoSink *>(output);
+ if (!sink && output) {
+ auto *mo = output->metaObject();
+ mo->invokeMethod(output, "videoSink", Q_RETURN_ARG(QVideoSink *, sink));
+ }
+ d->videoOutput = output;
+ d->setVideoSink(sink);
+}
+
+/*!
+ Sets a QVideoSink, (\a sink), to a video preview for the capture session.
+
+ A QObject based preview is expected to have an invokable videoSink()
+ method that returns a QVideoSink.
+
+ The previously set preview is detached.
+*/
+void QMediaCaptureSession::setVideoSink(QVideoSink *sink)
+{
+ Q_D(QMediaCaptureSession);
+ d->videoOutput = nullptr;
+ d->setVideoSink(sink);
+}
+
+/*!
+ Returns the QVideoSink for the session.
+*/
+QVideoSink *QMediaCaptureSession::videoSink() const
+{
+ Q_D(const QMediaCaptureSession);
+ return d->videoSink;
+}
+/*!
+ Sets the audio output device to \a{output}.
+
+ Setting an audio output device enables audio routing from an audio input device.
+*/
+void QMediaCaptureSession::setAudioOutput(QAudioOutput *output)
+{
+ Q_D(QMediaCaptureSession);
+
+ QAudioOutput *oldOutput = d->audioOutput;
+ if (oldOutput == output)
+ return;
+
+ // We don't want to end up with signal emitted
+ // twice (from recursive call setAudioInput(nullptr)
+ // from oldOutput->setDisconnectFunction():
+ d->audioOutput = nullptr;
+
+ if (d->captureSession)
+ d->captureSession->setAudioOutput(nullptr);
+ if (oldOutput)
+ oldOutput->setDisconnectFunction({});
+ if (output) {
+ output->setDisconnectFunction([this](){ setAudioOutput(nullptr); });
+ if (d->captureSession)
+ d->captureSession->setAudioOutput(output->handle());
+ }
+ d->audioOutput = output;
+ emit audioOutputChanged();
+}
+/*!
+ \qmlproperty AudioOutput QtMultimedia::CaptureSession::audioOutput
+ \brief The audio output device for the capture session.
+
+ Add an AudioOutput device to the capture session to enable
+ audio routing from an AudioInput device.
+*/
+/*!
+ \property QMediaCaptureSession::audioOutput
+
+ Returns the audio output for the session.
+*/
+QAudioOutput *QMediaCaptureSession::audioOutput() const
+{
+ Q_D(const QMediaCaptureSession);
+ return d->audioOutput;
+}
+
+/*!
+ \internal
+*/
+QPlatformMediaCaptureSession *QMediaCaptureSession::platformSession() const
+{
+ Q_D(const QMediaCaptureSession);
+ return d->captureSession.get();
+}
+/*!
+ \qmlsignal QtMultimedia::CaptureSession::audioInputChanged()
+ This signal is emitted when an audio input has changed.
+ \sa CaptureSession::audioInput
+*/
+
+/*!
+ \qmlsignal QtMultimedia::CaptureSession::cameraChanged()
+ This signal is emitted when the selected camera has changed.
+ \sa CaptureSession::camera
+*/
+
+/*!
+ \qmlsignal QtMultimedia::CaptureSession::imageCaptureChanged()
+ This signal is emitted when the selected interface has changed.
+ \sa CaptureSession::camera
+*/
+
+/*!
+ \qmlsignal QtMultimedia::CaptureSession::recorderChanged()
+ This signal is emitted when the selected recorder has changed.
+ \sa CaptureSession::recorder
+*/
+
+/*!
+ \qmlsignal QtMultimedia::CaptureSession::videoOutputChanged()
+ This signal is emitted when the selected video output has changed.
+ \sa CaptureSession::videoOutput
+*/
+
+/*!
+ \qmlsignal QtMultimedia::CaptureSession::audioOutputChanged()
+ This signal is emitted when the selected audio output has changed.
+ \sa CaptureSession::audioOutput
+*/
+QT_END_NAMESPACE
+
+#include "moc_qmediacapturesession.cpp"
diff --git a/src/multimedia/recording/qmediacapturesession.h b/src/multimedia/recording/qmediacapturesession.h
new file mode 100644
index 000000000..219c382d1
--- /dev/null
+++ b/src/multimedia/recording/qmediacapturesession.h
@@ -0,0 +1,106 @@
+// Copyright (C) 2016 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_H
+#define QMEDIACAPTURESESSION_H
+
+#include <QtCore/qobject.h>
+#include <QtMultimedia/qtmultimediaglobal.h>
+
+QT_BEGIN_NAMESPACE
+
+class QCamera;
+class QAudioInput;
+class QAudioBufferInput;
+class QAudioOutput;
+class QCameraDevice;
+class QImageCapture;
+class QMediaRecorder;
+class QPlatformMediaCaptureSession;
+class QVideoSink;
+class QScreenCapture;
+class QWindowCapture;
+class QVideoFrameInput;
+
+class QMediaCaptureSessionPrivate;
+class Q_MULTIMEDIA_EXPORT QMediaCaptureSession : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QAudioInput *audioInput READ audioInput WRITE setAudioInput NOTIFY audioInputChanged)
+ Q_PROPERTY(QAudioBufferInput *audioBufferInput READ audioBufferInput WRITE setAudioBufferInput
+ NOTIFY audioBufferInputChanged)
+ Q_PROPERTY(QAudioOutput *audioOutput READ audioOutput WRITE setAudioOutput NOTIFY audioOutputChanged)
+ Q_PROPERTY(QCamera *camera READ camera WRITE setCamera NOTIFY cameraChanged)
+ Q_PROPERTY(
+ QScreenCapture *screenCapture READ screenCapture WRITE setScreenCapture NOTIFY screenCaptureChanged)
+ Q_PROPERTY(
+ QWindowCapture *windowCapture READ windowCapture WRITE setWindowCapture NOTIFY windowCaptureChanged)
+ Q_PROPERTY(QVideoFrameInput *videoFrameInput READ videoFrameInput WRITE setVideoFrameInput
+ NOTIFY videoFrameInputChanged)
+ Q_PROPERTY(QImageCapture *imageCapture READ imageCapture WRITE setImageCapture NOTIFY imageCaptureChanged)
+ Q_PROPERTY(QMediaRecorder *recorder READ recorder WRITE setRecorder NOTIFY recorderChanged)
+ Q_PROPERTY(QObject *videoOutput READ videoOutput WRITE setVideoOutput NOTIFY videoOutputChanged)
+public:
+ explicit QMediaCaptureSession(QObject *parent = nullptr);
+ ~QMediaCaptureSession();
+
+ QAudioInput *audioInput() const;
+ void setAudioInput(QAudioInput *input);
+
+ QAudioBufferInput *audioBufferInput() const;
+ void setAudioBufferInput(QAudioBufferInput *input);
+
+ QCamera *camera() const;
+ void setCamera(QCamera *camera);
+
+ QImageCapture *imageCapture();
+ void setImageCapture(QImageCapture *imageCapture);
+
+ QScreenCapture *screenCapture();
+ void setScreenCapture(QScreenCapture *screenCapture);
+
+ QWindowCapture *windowCapture();
+ void setWindowCapture(QWindowCapture *windowCapture);
+
+ QVideoFrameInput *videoFrameInput() const;
+ void setVideoFrameInput(QVideoFrameInput *input);
+
+ QMediaRecorder *recorder();
+ void setRecorder(QMediaRecorder *recorder);
+
+ void setVideoOutput(QObject *output);
+ QObject *videoOutput() const;
+
+ void setVideoSink(QVideoSink *sink);
+ QVideoSink *videoSink() const;
+
+ void setAudioOutput(QAudioOutput *output);
+ QAudioOutput *audioOutput() const;
+
+ QPlatformMediaCaptureSession *platformSession() const;
+
+Q_SIGNALS:
+ void audioInputChanged();
+ void audioBufferInputChanged();
+ void cameraChanged();
+ void screenCaptureChanged();
+ void windowCaptureChanged();
+ void videoFrameInputChanged();
+ void imageCaptureChanged();
+ void recorderChanged();
+ void videoOutputChanged();
+ void audioOutputChanged();
+
+private:
+ friend class QPlatformMediaCaptureSession;
+
+ // ### Qt7: remove unused member
+ QT6_ONLY(void *unused = nullptr;) // for ABI compatibility
+
+ Q_DISABLE_COPY(QMediaCaptureSession)
+ Q_DECLARE_PRIVATE(QMediaCaptureSession)
+};
+
+QT_END_NAMESPACE
+
+#endif // QMEDIACAPTURESESSION_H
diff --git a/src/multimedia/recording/qmediacapturesession_p.h b/src/multimedia/recording/qmediacapturesession_p.h
new file mode 100644
index 000000000..cba222993
--- /dev/null
+++ b/src/multimedia/recording/qmediacapturesession_p.h
@@ -0,0 +1,53 @@
+// 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>
+#include <QtCore/private/qobject_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QMediaCaptureSessionPrivate : public QObjectPrivate
+{
+public:
+ static QMediaCaptureSessionPrivate *get(QMediaCaptureSession *session)
+ {
+ return reinterpret_cast<QMediaCaptureSessionPrivate *>(QObjectPrivate::get(session));
+ }
+
+ Q_DECLARE_PUBLIC(QMediaCaptureSession)
+
+ std::unique_ptr<QPlatformMediaCaptureSession> captureSession;
+ QAudioInput *audioInput = nullptr;
+ QPointer<QAudioBufferInput> audioBufferInput;
+ QAudioOutput *audioOutput = nullptr;
+ QPointer<QCamera> camera;
+ QPointer<QScreenCapture> screenCapture;
+ QPointer<QWindowCapture> windowCapture;
+ QPointer<QVideoFrameInput> videoFrameInput;
+ 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/multimedia/recording/qmediaencodersettings.cpp b/src/multimedia/recording/qmediaencodersettings.cpp
deleted file mode 100644
index 0e169c2b0..000000000
--- a/src/multimedia/recording/qmediaencodersettings.cpp
+++ /dev/null
@@ -1,952 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qmediaencodersettings.h"
-
-QT_BEGIN_NAMESPACE
-
-static void qRegisterEncoderSettingsMetaTypes()
-{
- qRegisterMetaType<QAudioEncoderSettings>();
- qRegisterMetaType<QVideoEncoderSettings>();
- qRegisterMetaType<QImageEncoderSettings>();
-}
-
-Q_CONSTRUCTOR_FUNCTION(qRegisterEncoderSettingsMetaTypes)
-
-
-class QAudioEncoderSettingsPrivate : public QSharedData
-{
-public:
- QAudioEncoderSettingsPrivate() :
- isNull(true),
- encodingMode(QMultimedia::ConstantQualityEncoding),
- bitrate(-1),
- sampleRate(-1),
- channels(-1),
- quality(QMultimedia::NormalQuality)
- {
- }
-
- QAudioEncoderSettingsPrivate(const QAudioEncoderSettingsPrivate &other):
- QSharedData(other),
- isNull(other.isNull),
- encodingMode(other.encodingMode),
- codec(other.codec),
- bitrate(other.bitrate),
- sampleRate(other.sampleRate),
- channels(other.channels),
- quality(other.quality),
- encodingOptions(other.encodingOptions)
- {
- }
-
- bool isNull;
- QMultimedia::EncodingMode encodingMode;
- QString codec;
- int bitrate;
- int sampleRate;
- int channels;
- QMultimedia::EncodingQuality quality;
- QVariantMap encodingOptions;
-
-private:
- QAudioEncoderSettingsPrivate& operator=(const QAudioEncoderSettingsPrivate &other);
-};
-
-/*!
- \class QAudioEncoderSettings
-
- \brief The QAudioEncoderSettings class provides a set of audio encoder settings.
-
- \inmodule QtMultimedia
- \ingroup multimedia
- \ingroup multimedia_recording
-
- A audio encoder settings object is used to specify the audio encoder
- settings used by QMediaRecorder. Audio encoder settings are selected by
- constructing a QAudioEncoderSettings object, setting the desired properties
- and then passing it to a QMediaRecorder instance using the
- QMediaRecorder::setEncodingSettings() function.
-
- \snippet multimedia-snippets/media.cpp Audio encoder settings
-
- \sa QMediaRecorder, QAudioEncoderSettingsControl
-*/
-
-/*!
- Construct a null audio encoder settings object.
-*/
-QAudioEncoderSettings::QAudioEncoderSettings()
- :d(new QAudioEncoderSettingsPrivate)
-{
-}
-
-/*!
- Constructs a copy of the audio encoder settings object \a other.
-*/
-
-QAudioEncoderSettings::QAudioEncoderSettings(const QAudioEncoderSettings& other)
- :d(other.d)
-{
-}
-
-/*!
- Destroys an audio encoder settings object.
-*/
-
-QAudioEncoderSettings::~QAudioEncoderSettings()
-{
-}
-
-/*!
- Assigns the value of \a other to an audio encoder settings object.
-*/
-
-QAudioEncoderSettings& QAudioEncoderSettings::operator=(const QAudioEncoderSettings &other)
-{
- d = other.d;
- return *this;
-}
-
-/*!
- Determines if \a other is of equal value to an audio encoder settings
- object.
-
- Returns true if the settings objects are of equal value, and false if they
- are not of equal value.
-*/
-
-bool QAudioEncoderSettings::operator==(const QAudioEncoderSettings &other) const
-{
- return (d == other.d) ||
- (d->isNull == other.d->isNull &&
- d->encodingMode == other.d->encodingMode &&
- d->bitrate == other.d->bitrate &&
- d->sampleRate == other.d->sampleRate &&
- d->channels == other.d->channels &&
- d->quality == other.d->quality &&
- d->codec == other.d->codec &&
- d->encodingOptions == other.d->encodingOptions);
-}
-
-/*!
- Determines if \a other is of equal value to an audio encoder settings
- object.
-
- Returns true if the settings objects are not of equal value, and true if
- they are of equal value.
-*/
-
-bool QAudioEncoderSettings::operator!=(const QAudioEncoderSettings &other) const
-{
- return !(*this == other);
-}
-
-/*!
- Identifies if an audio settings object is initialized.
-
- Returns true if the settings object is null, and false if it is not.
-*/
-
-bool QAudioEncoderSettings::isNull() const
-{
- return d->isNull;
-}
-
-/*!
- Returns the audio encoding mode.
-
- \sa QMultimedia::EncodingMode
-*/
-QMultimedia::EncodingMode QAudioEncoderSettings::encodingMode() const
-{
- return d->encodingMode;
-}
-
-/*!
- Sets the audio encoding \a mode setting.
-
- If QMultimedia::ConstantQualityEncoding is set, the quality
- encoding parameter is used and bit rate is ignored,
- otherwise the bitrate is used.
-
- The audio codec, channels count and sample rate settings are used in all
- the encoding modes.
-
- \sa encodingMode(), QMultimedia::EncodingMode
-*/
-void QAudioEncoderSettings::setEncodingMode(QMultimedia::EncodingMode mode)
-{
- d->encodingMode = mode;
-}
-
-/*!
- Returns the audio codec.
-*/
-QString QAudioEncoderSettings::codec() const
-{
- return d->codec;
-}
-
-/*!
- Sets the audio \a codec.
-*/
-void QAudioEncoderSettings::setCodec(const QString& codec)
-{
- d->isNull = false;
- d->codec = codec;
-}
-
-/*!
- Returns the bit rate of the compressed audio stream in bits per second.
-*/
-int QAudioEncoderSettings::bitRate() const
-{
- return d->bitrate;
-}
-
-/*!
- Returns the number of audio channels.
-*/
-int QAudioEncoderSettings::channelCount() const
-{
- return d->channels;
-}
-
-/*!
- Sets the number of audio \a channels.
-
- A value of -1 indicates the encoder should make an optimal choice based on
- what is available from the audio source and the limitations of the codec.
-*/
-void QAudioEncoderSettings::setChannelCount(int channels)
-{
- d->isNull = false;
- d->channels = channels;
-}
-
-/*!
- Sets the audio bit \a rate in bits per second.
-*/
-void QAudioEncoderSettings::setBitRate(int rate)
-{
- d->isNull = false;
- d->bitrate = rate;
-}
-
-/*!
- Returns the audio sample rate in Hz.
-*/
-int QAudioEncoderSettings::sampleRate() const
-{
- return d->sampleRate;
-}
-
-/*!
- Sets the audio sample \a rate in Hz.
-
- A value of -1 indicates the encoder should make an optimal choice based on what is avaialbe
- from the audio source and the limitations of the codec.
- */
-void QAudioEncoderSettings::setSampleRate(int rate)
-{
- d->isNull = false;
- d->sampleRate = rate;
-}
-
-/*!
- Returns the audio encoding quality.
-*/
-
-QMultimedia::EncodingQuality QAudioEncoderSettings::quality() const
-{
- return d->quality;
-}
-
-/*!
- Set the audio encoding \a quality.
-
- Setting the audio quality parameter allows backend to choose the balanced
- set of encoding parameters to achieve the desired quality level.
-
- The \a quality settings parameter is only used in the
- \l {QMultimedia::ConstantQualityEncoding}{constant quality} \l{encodingMode()}{encoding mode}.
-*/
-void QAudioEncoderSettings::setQuality(QMultimedia::EncodingQuality quality)
-{
- d->isNull = false;
- d->quality = quality;
-}
-
-/*!
- Returns the value of encoding \a option.
-
- \sa setEncodingOption(), encodingOptions()
-*/
-QVariant QAudioEncoderSettings::encodingOption(const QString &option) const
-{
- return d->encodingOptions.value(option);
-}
-
-/*!
- Returns the all the encoding options as QVariantMap.
-
- \sa encodingOption(), setEncodingOptions()
-*/
-QVariantMap QAudioEncoderSettings::encodingOptions() const
-{
- return d->encodingOptions;
-}
-
-/*!
- Set the encoding \a option to \a value.
-
- The supported set and meaning of encoding options are
- system and selected codec specific.
-
- \sa encodingOption(), setEncodingOptions()
-*/
-void QAudioEncoderSettings::setEncodingOption(const QString &option, const QVariant &value)
-{
- d->isNull = false;
- if (value.isNull())
- d->encodingOptions.remove(option);
- else
- d->encodingOptions.insert(option, value);
-}
-
-/*!
- Replace all the encoding options with \a options.
-
- The supported set and meaning of encoding options are
- system and selected codec specific.
-
- \sa encodingOption(), setEncodingOption()
-*/
-void QAudioEncoderSettings::setEncodingOptions(const QVariantMap &options)
-{
- d->isNull = false;
- d->encodingOptions = options;
-}
-
-class QVideoEncoderSettingsPrivate : public QSharedData
-{
-public:
- QVideoEncoderSettingsPrivate() :
- isNull(true),
- encodingMode(QMultimedia::ConstantQualityEncoding),
- bitrate(-1),
- frameRate(0),
- quality(QMultimedia::NormalQuality)
- {
- }
-
- QVideoEncoderSettingsPrivate(const QVideoEncoderSettingsPrivate &other):
- QSharedData(other),
- isNull(other.isNull),
- encodingMode(other.encodingMode),
- codec(other.codec),
- bitrate(other.bitrate),
- resolution(other.resolution),
- frameRate(other.frameRate),
- quality(other.quality),
- encodingOptions(other.encodingOptions)
- {
- }
-
- bool isNull;
- QMultimedia::EncodingMode encodingMode;
- QString codec;
- int bitrate;
- QSize resolution;
- qreal frameRate;
- QMultimedia::EncodingQuality quality;
- QVariantMap encodingOptions;
-
-private:
- QVideoEncoderSettingsPrivate& operator=(const QVideoEncoderSettingsPrivate &other);
-};
-
-/*!
- \class QVideoEncoderSettings
-
- \brief The QVideoEncoderSettings class provides a set of video encoder settings.
-
- \inmodule QtMultimedia
- \ingroup multimedia
- \ingroup multimedia_recording
-
- A video encoder settings object is used to specify the video encoder
- settings used by QMediaRecorder. Video encoder settings are selected by
- constructing a QVideoEncoderSettings object, setting the desired properties
- and then passing it to a QMediaRecorder instance using the
- QMediaRecorder::setEncodingSettings() function.
-
- \snippet multimedia-snippets/media.cpp Video encoder settings
-
- \sa QMediaRecorder, QVideoEncoderSettingsControl
-*/
-
-/*!
- Constructs a null video encoder settings object.
-*/
-
-QVideoEncoderSettings::QVideoEncoderSettings()
- :d(new QVideoEncoderSettingsPrivate)
-{
-}
-
-/*!
- Constructs a copy of the video encoder settings object \a other.
-*/
-
-QVideoEncoderSettings::QVideoEncoderSettings(const QVideoEncoderSettings& other)
- :d(other.d)
-{
-}
-
-/*!
- Destroys a video encoder settings object.
-*/
-
-QVideoEncoderSettings::~QVideoEncoderSettings()
-{
-}
-
-/*!
- Assigns the value of \a other to a video encoder settings object.
-*/
-QVideoEncoderSettings &QVideoEncoderSettings::operator=(const QVideoEncoderSettings &other)
-{
- d = other.d;
- return *this;
-}
-
-/*!
- Determines if \a other is of equal value to a video encoder settings object.
-
- Returns true if the settings objects are of equal value, and false if they
- are not of equal value.
-*/
-bool QVideoEncoderSettings::operator==(const QVideoEncoderSettings &other) const
-{
- return (d == other.d) ||
- (d->isNull == other.d->isNull &&
- d->encodingMode == other.d->encodingMode &&
- d->bitrate == other.d->bitrate &&
- d->quality == other.d->quality &&
- d->codec == other.d->codec &&
- d->resolution == other.d->resolution &&
- qFuzzyCompare(d->frameRate, other.d->frameRate) &&
- d->encodingOptions == other.d->encodingOptions);
-}
-
-/*!
- Determines if \a other is of equal value to a video encoder settings object.
-
- Returns true if the settings objects are not of equal value, and false if
- they are of equal value.
-*/
-bool QVideoEncoderSettings::operator!=(const QVideoEncoderSettings &other) const
-{
- return !(*this == other);
-}
-
-/*!
- Identifies if a video encoder settings object is uninitalized.
-
- Returns true if the settings are null, and false if they are not.
-*/
-bool QVideoEncoderSettings::isNull() const
-{
- return d->isNull;
-}
-
-/*!
- Returns the video encoding mode.
-
- \sa QMultimedia::EncodingMode
-*/
-QMultimedia::EncodingMode QVideoEncoderSettings::encodingMode() const
-{
- return d->encodingMode;
-}
-
-/*!
- Sets the video encoding \a mode.
-
- If QMultimedia::ConstantQualityEncoding is set,
- the quality encoding parameter is used and bit rate is ignored,
- otherwise the bitrate is used.
-
- The rest of encoding settings are respected regardless of encoding mode.
-
- \sa QMultimedia::EncodingMode
-*/
-void QVideoEncoderSettings::setEncodingMode(QMultimedia::EncodingMode mode)
-{
- d->isNull = false;
- d->encodingMode = mode;
-}
-
-/*!
- Returns the video codec.
-*/
-
-QString QVideoEncoderSettings::codec() const
-{
- return d->codec;
-}
-
-/*!
- Sets the video \a codec.
-*/
-void QVideoEncoderSettings::setCodec(const QString& codec)
-{
- d->isNull = false;
- d->codec = codec;
-}
-
-/*!
- Returns bit rate of the encoded video stream in bits per second.
-*/
-int QVideoEncoderSettings::bitRate() const
-{
- return d->bitrate;
-}
-
-/*!
- Sets the bit rate of the encoded video stream to \a value.
-*/
-
-void QVideoEncoderSettings::setBitRate(int value)
-{
- d->isNull = false;
- d->bitrate = value;
-}
-
-/*!
- Returns the video frame rate.
-*/
-qreal QVideoEncoderSettings::frameRate() const
-{
- return d->frameRate;
-}
-
-/*!
- \fn QVideoEncoderSettings::setFrameRate(qreal rate)
-
- Sets the video frame \a rate.
-
- A value of 0 indicates the encoder should make an optimal choice based on what is available
- from the video source and the limitations of the codec.
-*/
-
-void QVideoEncoderSettings::setFrameRate(qreal rate)
-{
- d->isNull = false;
- d->frameRate = rate;
-}
-
-/*!
- Returns the resolution of the encoded video.
-*/
-
-QSize QVideoEncoderSettings::resolution() const
-{
- return d->resolution;
-}
-
-/*!
- Sets the \a resolution of the encoded video.
-
- An empty QSize indicates the encoder should make an optimal choice based on
- what is available from the video source and the limitations of the codec.
-*/
-
-void QVideoEncoderSettings::setResolution(const QSize &resolution)
-{
- d->isNull = false;
- d->resolution = resolution;
-}
-
-/*!
- Sets the \a width and \a height of the resolution of the encoded video.
-
- \overload
-*/
-
-void QVideoEncoderSettings::setResolution(int width, int height)
-{
- d->isNull = false;
- d->resolution = QSize(width, height);
-}
-
-/*!
- Returns the video encoding quality.
-*/
-
-QMultimedia::EncodingQuality QVideoEncoderSettings::quality() const
-{
- return d->quality;
-}
-
-/*!
- Sets the video encoding \a quality.
-
- Setting the video quality parameter allows backend to choose the balanced
- set of encoding parameters to achieve the desired quality level.
-
- The \a quality settings parameter is only used in the
- \l {QMultimedia::ConstantQualityEncoding}{constant quality} \l{encodingMode()}{encoding mode}.
- The \a quality settings parameter is only used in the \l
- {QMultimedia::ConstantQualityEncoding}{constant quality}
- \l{encodingMode()}{encoding mode}.
-*/
-
-void QVideoEncoderSettings::setQuality(QMultimedia::EncodingQuality quality)
-{
- d->isNull = false;
- d->quality = quality;
-}
-
-/*!
- Returns the value of encoding \a option.
-
- \sa setEncodingOption(), encodingOptions()
-*/
-QVariant QVideoEncoderSettings::encodingOption(const QString &option) const
-{
- return d->encodingOptions.value(option);
-}
-
-/*!
- Returns the all the encoding options as QVariantMap.
-
- \sa encodingOption(), setEncodingOptions()
-*/
-QVariantMap QVideoEncoderSettings::encodingOptions() const
-{
- return d->encodingOptions;
-}
-
-/*!
- Set the encoding \a option \a value.
-
- The supported set and meaning of encoding options are
- system and selected codec specific.
-
- \sa encodingOption(), setEncodingOptions()
-*/
-void QVideoEncoderSettings::setEncodingOption(const QString &option, const QVariant &value)
-{
- d->isNull = false;
- if (value.isNull())
- d->encodingOptions.remove(option);
- else
- d->encodingOptions.insert(option, value);
-}
-
-/*!
- Replace all the encoding options with \a options.
-
- The supported set and meaning of encoding options are
- system and selected codec specific.
-
- \sa encodingOption(), setEncodingOption()
-*/
-void QVideoEncoderSettings::setEncodingOptions(const QVariantMap &options)
-{
- d->isNull = false;
- d->encodingOptions = options;
-}
-
-
-class QImageEncoderSettingsPrivate : public QSharedData
-{
-public:
- QImageEncoderSettingsPrivate() :
- isNull(true),
- quality(QMultimedia::NormalQuality)
- {
- }
-
- QImageEncoderSettingsPrivate(const QImageEncoderSettingsPrivate &other):
- QSharedData(other),
- isNull(other.isNull),
- codec(other.codec),
- resolution(other.resolution),
- quality(other.quality),
- encodingOptions(other.encodingOptions)
- {
- }
-
- bool isNull;
- QString codec;
- QSize resolution;
- QMultimedia::EncodingQuality quality;
- QVariantMap encodingOptions;
-
-private:
- QImageEncoderSettingsPrivate& operator=(const QImageEncoderSettingsPrivate &other);
-};
-
-/*!
- \class QImageEncoderSettings
-
-
- \brief The QImageEncoderSettings class provides a set of image encoder
- settings.
-
- \inmodule QtMultimedia
- \ingroup multimedia
- \ingroup multimedia_camera
-
- A image encoder settings object is used to specify the image encoder
- settings used by QCameraImageCapture. Image encoder settings are selected
- by constructing a QImageEncoderSettings object, setting the desired
- properties and then passing it to a QCameraImageCapture instance using the
- QCameraImageCapture::setImageSettings() function.
-
- \snippet multimedia-snippets/media.cpp Image encoder settings
-
- \sa QImageEncoderControl
-*/
-
-/*!
- Constructs a null image encoder settings object.
-*/
-
-QImageEncoderSettings::QImageEncoderSettings()
- :d(new QImageEncoderSettingsPrivate)
-{
-}
-
-/*!
- Constructs a copy of the image encoder settings object \a other.
-*/
-
-QImageEncoderSettings::QImageEncoderSettings(const QImageEncoderSettings& other)
- :d(other.d)
-{
-}
-
-/*!
- Destroys a image encoder settings object.
-*/
-
-QImageEncoderSettings::~QImageEncoderSettings()
-{
-}
-
-/*!
- Assigns the value of \a other to a image encoder settings object.
-*/
-QImageEncoderSettings &QImageEncoderSettings::operator=(const QImageEncoderSettings &other)
-{
- d = other.d;
- return *this;
-}
-
-/*!
- Determines if \a other is of equal value to a image encoder settings
- object.
-
- Returns true if the settings objects are of equal value, and false if they
- are not of equal value.
-*/
-bool QImageEncoderSettings::operator==(const QImageEncoderSettings &other) const
-{
- return (d == other.d) ||
- (d->isNull == other.d->isNull &&
- d->quality == other.d->quality &&
- d->codec == other.d->codec &&
- d->resolution == other.d->resolution &&
- d->encodingOptions == other.d->encodingOptions);
-
-}
-
-/*!
- Determines if \a other is of equal value to a image encoder settings
- object.
-
- Returns true if the settings objects are not of equal value, and false if
- they are of equal value.
-*/
-bool QImageEncoderSettings::operator!=(const QImageEncoderSettings &other) const
-{
- return !(*this == other);
-}
-
-/*!
- Identifies if a image encoder settings object is uninitalized.
-
- Returns true if the settings are null, and false if they are not.
-*/
-bool QImageEncoderSettings::isNull() const
-{
- return d->isNull;
-}
-
-/*!
- Returns the image codec.
-*/
-
-QString QImageEncoderSettings::codec() const
-{
- return d->codec;
-}
-
-/*!
- Sets the image \a codec.
-*/
-void QImageEncoderSettings::setCodec(const QString& codec)
-{
- d->isNull = false;
- d->codec = codec;
-}
-
-/*!
- Returns the resolution of the encoded image.
-*/
-
-QSize QImageEncoderSettings::resolution() const
-{
- return d->resolution;
-}
-
-/*!
- Sets the \a resolution of the encoded image.
-
- An empty QSize indicates the encoder should make an optimal choice based on
- what is available from the image source and the limitations of the codec.
-*/
-
-void QImageEncoderSettings::setResolution(const QSize &resolution)
-{
- d->isNull = false;
- d->resolution = resolution;
-}
-
-/*!
- Sets the \a width and \a height of the resolution of the encoded image.
-
- \overload
-*/
-
-void QImageEncoderSettings::setResolution(int width, int height)
-{
- d->isNull = false;
- d->resolution = QSize(width, height);
-}
-
-/*!
- Returns the image encoding quality.
-*/
-
-QMultimedia::EncodingQuality QImageEncoderSettings::quality() const
-{
- return d->quality;
-}
-
-/*!
- Sets the image encoding \a quality.
-*/
-
-void QImageEncoderSettings::setQuality(QMultimedia::EncodingQuality quality)
-{
- d->isNull = false;
- d->quality = quality;
-}
-
-/*!
- Returns the value of encoding \a option.
-
- \sa setEncodingOption(), encodingOptions()
-*/
-QVariant QImageEncoderSettings::encodingOption(const QString &option) const
-{
- return d->encodingOptions.value(option);
-}
-
-/*!
- Returns the all the encoding options as QVariantMap.
-
- \sa encodingOption(), setEncodingOptions()
-*/
-QVariantMap QImageEncoderSettings::encodingOptions() const
-{
- return d->encodingOptions;
-}
-
-/*!
- Set the encoding \a option \a value.
-
- The supported set and meaning of encoding options are
- system and selected codec specific.
-
- \sa encodingOption(), setEncodingOptions()
-*/
-void QImageEncoderSettings::setEncodingOption(const QString &option, const QVariant &value)
-{
- d->isNull = false;
- if (value.isNull())
- d->encodingOptions.remove(option);
- else
- d->encodingOptions.insert(option, value);
-}
-
-/*!
- Replace all the encoding options with \a options.
-
- The supported set and meaning of encoding options are
- system and selected codec specific.
-
- \sa encodingOption(), setEncodingOption()
-*/
-void QImageEncoderSettings::setEncodingOptions(const QVariantMap &options)
-{
- d->isNull = false;
- d->encodingOptions = options;
-}
-
-
-QT_END_NAMESPACE
-
diff --git a/src/multimedia/recording/qmediaencodersettings.h b/src/multimedia/recording/qmediaencodersettings.h
deleted file mode 100644
index 0d6a9eddf..000000000
--- a/src/multimedia/recording/qmediaencodersettings.h
+++ /dev/null
@@ -1,180 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QMEDIAENCODERSETTINGS_H
-#define QMEDIAENCODERSETTINGS_H
-
-#include <QtCore/qsharedpointer.h>
-#include <QtCore/qstring.h>
-#include <QtCore/qsize.h>
-#include <QtCore/qvariant.h>
-#include <QtMultimedia/qtmultimediaglobal.h>
-#include <QtMultimedia/qmultimedia.h>
-
-QT_BEGIN_NAMESPACE
-
-
-
-class QAudioEncoderSettingsPrivate;
-class Q_MULTIMEDIA_EXPORT QAudioEncoderSettings
-{
-public:
- QAudioEncoderSettings();
- QAudioEncoderSettings(const QAudioEncoderSettings& other);
-
- ~QAudioEncoderSettings();
-
- QAudioEncoderSettings& operator=(const QAudioEncoderSettings &other);
- bool operator==(const QAudioEncoderSettings &other) const;
- bool operator!=(const QAudioEncoderSettings &other) const;
-
- bool isNull() const;
-
- QMultimedia::EncodingMode encodingMode() const;
- void setEncodingMode(QMultimedia::EncodingMode);
-
- QString codec() const;
- void setCodec(const QString& codec);
-
- int bitRate() const;
- void setBitRate(int bitrate);
-
- int channelCount() const;
- void setChannelCount(int channels);
-
- int sampleRate() const;
- void setSampleRate(int rate);
-
- QMultimedia::EncodingQuality quality() const;
- void setQuality(QMultimedia::EncodingQuality quality);
-
- QVariant encodingOption(const QString &option) const;
- QVariantMap encodingOptions() const;
- void setEncodingOption(const QString &option, const QVariant &value);
- void setEncodingOptions(const QVariantMap &options);
-
-private:
- QSharedDataPointer<QAudioEncoderSettingsPrivate> d;
-};
-
-class QVideoEncoderSettingsPrivate;
-class Q_MULTIMEDIA_EXPORT QVideoEncoderSettings
-{
-public:
- QVideoEncoderSettings();
- QVideoEncoderSettings(const QVideoEncoderSettings& other);
-
- ~QVideoEncoderSettings();
-
- QVideoEncoderSettings& operator=(const QVideoEncoderSettings &other);
- bool operator==(const QVideoEncoderSettings &other) const;
- bool operator!=(const QVideoEncoderSettings &other) const;
-
- bool isNull() const;
-
- QMultimedia::EncodingMode encodingMode() const;
- void setEncodingMode(QMultimedia::EncodingMode);
-
- QString codec() const;
- void setCodec(const QString &);
-
- QSize resolution() const;
- void setResolution(const QSize &);
- void setResolution(int width, int height);
-
- qreal frameRate() const;
- void setFrameRate(qreal rate);
-
- int bitRate() const;
- void setBitRate(int bitrate);
-
- QMultimedia::EncodingQuality quality() const;
- void setQuality(QMultimedia::EncodingQuality quality);
-
- QVariant encodingOption(const QString &option) const;
- QVariantMap encodingOptions() const;
- void setEncodingOption(const QString &option, const QVariant &value);
- void setEncodingOptions(const QVariantMap &options);
-
-private:
- QSharedDataPointer<QVideoEncoderSettingsPrivate> d;
-};
-
-class QImageEncoderSettingsPrivate;
-class Q_MULTIMEDIA_EXPORT QImageEncoderSettings
-{
-public:
- QImageEncoderSettings();
- QImageEncoderSettings(const QImageEncoderSettings& other);
-
- ~QImageEncoderSettings();
-
- QImageEncoderSettings& operator=(const QImageEncoderSettings &other);
- bool operator==(const QImageEncoderSettings &other) const;
- bool operator!=(const QImageEncoderSettings &other) const;
-
- bool isNull() const;
-
- QString codec() const;
- void setCodec(const QString &);
-
- QSize resolution() const;
- void setResolution(const QSize &);
- void setResolution(int width, int height);
-
- QMultimedia::EncodingQuality quality() const;
- void setQuality(QMultimedia::EncodingQuality quality);
-
- QVariant encodingOption(const QString &option) const;
- QVariantMap encodingOptions() const;
- void setEncodingOption(const QString &option, const QVariant &value);
- void setEncodingOptions(const QVariantMap &options);
-
-private:
- QSharedDataPointer<QImageEncoderSettingsPrivate> d;
-};
-
-QT_END_NAMESPACE
-
-Q_DECLARE_METATYPE(QAudioEncoderSettings)
-Q_DECLARE_METATYPE(QVideoEncoderSettings)
-Q_DECLARE_METATYPE(QImageEncoderSettings)
-
-
-#endif
diff --git a/src/multimedia/recording/qmediarecorder.cpp b/src/multimedia/recording/qmediarecorder.cpp
index 617627985..ea38b231a 100644
--- a/src/multimedia/recording/qmediarecorder.cpp
+++ b/src/multimedia/recording/qmediarecorder.cpp
@@ -1,61 +1,24 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qmediarecorder.h"
+// Copyright (C) 2016 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 "qmediarecorder_p.h"
-#include <qmediarecordercontrol.h>
-#include "qmediaobject_p.h"
-#include <qmediaservice.h>
-#include <qmediaserviceprovider_p.h>
-#include <qmetadatawritercontrol.h>
-#include <qaudioencodersettingscontrol.h>
-#include <qvideoencodersettingscontrol.h>
-#include <qmediacontainercontrol.h>
-#include <qmediaavailabilitycontrol.h>
+#include <private/qplatformmediarecorder_p.h>
+#include <qaudiodevice.h>
#include <qcamera.h>
-#include <qcameracontrol.h>
+#include <qscreencapture.h>
+#include <qwindowcapture.h>
+#include <qmediacapturesession.h>
+#include <private/qplatformcamera_p.h>
+#include <private/qplatformsurfacecapture_p.h>
+#include <private/qplatformmediaintegration_p.h>
+#include <private/qplatformmediacapture_p.h>
#include <QtCore/qdebug.h>
#include <QtCore/qurl.h>
#include <QtCore/qstringlist.h>
#include <QtCore/qmetaobject.h>
+#include <QtCore/qtimer.h>
#include <qaudioformat.h>
@@ -66,179 +29,103 @@ QT_BEGIN_NAMESPACE
\inmodule QtMultimedia
\ingroup multimedia
\ingroup multimedia_recording
+ \ingroup multimedia_video
+ \ingroup multimedia_audio
- \brief The QMediaRecorder class is used for the recording of media content.
+ \brief The QMediaRecorder class is used for encoding and recording a capture session.
- The QMediaRecorder class is a high level media recording class. It's not
- intended to be used alone but for accessing the media recording functions
- of other media objects, like QCamera.
+ The QMediaRecorder class is a class for encoding and recording media generated in a
+ QMediaCaptureSession.
\snippet multimedia-snippets/media.cpp Media recorder
-
- \sa QAudioRecorder
*/
+/*!
+ \qmltype MediaRecorder
+ \instantiates QMediaRecorder
+ \brief For encoding and recording media generated in a CaptureSession.
-static void qRegisterMediaRecorderMetaTypes()
-{
- qRegisterMetaType<QMediaRecorder::State>("QMediaRecorder::State");
- qRegisterMetaType<QMediaRecorder::Status>("QMediaRecorder::Status");
- qRegisterMetaType<QMediaRecorder::Error>("QMediaRecorder::Error");
-}
-
-Q_CONSTRUCTOR_FUNCTION(qRegisterMediaRecorderMetaTypes)
-
-
-QMediaRecorderPrivate::QMediaRecorderPrivate():
- mediaObject(nullptr),
- control(nullptr),
- formatControl(nullptr),
- audioControl(nullptr),
- videoControl(nullptr),
- metaDataControl(nullptr),
- availabilityControl(nullptr),
- settingsChanged(false),
- notifyTimer(nullptr),
- state(QMediaRecorder::StoppedState),
- error(QMediaRecorder::NoError)
-{
-}
-
-#define ENUM_NAME(c,e,v) (c::staticMetaObject.enumerator(c::staticMetaObject.indexOfEnumerator(e)).valueToKey((v)))
-
-void QMediaRecorderPrivate::_q_stateChanged(QMediaRecorder::State ps)
-{
- Q_Q(QMediaRecorder);
-
- if (ps == QMediaRecorder::RecordingState)
- notifyTimer->start();
- else
- notifyTimer->stop();
-
-// qDebug() << "Recorder state changed:" << ENUM_NAME(QMediaRecorder,"State",ps);
- if (state != ps) {
- emit q->stateChanged(ps);
- }
-
- state = ps;
-}
-
-
-void QMediaRecorderPrivate::_q_error(int error, const QString &errorString)
-{
- Q_Q(QMediaRecorder);
-
- this->error = QMediaRecorder::Error(error);
- this->errorString = errorString;
+ \inqmlmodule QtMultimedia
+ \ingroup multimedia_qml
+ \ingroup multimedia_audio_qml
+ \ingroup multimedia_video_qml
- emit q->error(this->error);
-}
+ The MediaRecorder element can be used within a CaptureSession to record and encode audio and
+ video captured from a microphone and camera
-void QMediaRecorderPrivate::_q_serviceDestroyed()
-{
- mediaObject = nullptr;
- control = nullptr;
- formatControl = nullptr;
- audioControl = nullptr;
- videoControl = nullptr;
- metaDataControl = nullptr;
- availabilityControl = nullptr;
- settingsChanged = true;
-}
+ \since 6.2
+ The code below shows a simple capture session containing a MediaRecorder using the default
+ camera and default audio input.
-void QMediaRecorderPrivate::_q_updateActualLocation(const QUrl &location)
-{
- if (actualLocation != location) {
- actualLocation = location;
- emit q_func()->actualLocationChanged(actualLocation);
+\qml
+ CaptureSession {
+ id: captureSession
+ camera: Camera {
+ id: camera
+ active: true
+ }
+ audioInput: AudioInput {}
+ recorder: MediaRecorder {
+ id: recorder
+ }
}
-}
-
-void QMediaRecorderPrivate::_q_notify()
-{
- emit q_func()->durationChanged(q_func()->duration());
-}
-
-void QMediaRecorderPrivate::_q_updateNotifyInterval(int ms)
-{
- notifyTimer->setInterval(ms);
-}
-
-void QMediaRecorderPrivate::applySettingsLater()
-{
- if (control && !settingsChanged) {
- settingsChanged = true;
- QMetaObject::invokeMethod(q_func(), "_q_applySettings", Qt::QueuedConnection);
+\endqml
+
+ The code below shows how the recording can be started and stopped.
+\qml
+ CameraButton {
+ text: "Record"
+ visible: recorder.recorderState !== MediaRecorder.RecordingState
+ onClicked: recorder.record()
}
-}
-void QMediaRecorderPrivate::_q_applySettings()
-{
- if (control && settingsChanged) {
- settingsChanged = false;
- control->applySettings();
+ CameraButton {
+ id: stopButton
+ text: "Stop"
+ visible: recorder.recorderState === MediaRecorder.RecordingState
+ onClicked: recorder.stop()
}
-}
+\endqml
-void QMediaRecorderPrivate::_q_availabilityChanged(QMultimedia::AvailabilityStatus availability)
+ \sa CaptureSession, Camera, AudioInput, ImageCapture
+*/
+QMediaRecorderPrivate::QMediaRecorderPrivate()
{
- Q_Q(QMediaRecorder);
- Q_UNUSED(error);
- Q_UNUSED(availability);
-
- // Really this should not always emit, but
- // we can't really tell from here (isAvailable
- // may not have changed, or the mediaobject's overridden
- // availability() may not have changed).
- q->availabilityChanged(q->availability());
- q->availabilityChanged(q->isAvailable());
+ // Force an early initialization of the mime database
+ // to avoid a delay when recording for the first time.
+ encoderSettings.mimeType();
}
-void QMediaRecorderPrivate::restartCamera()
+QString QMediaRecorderPrivate::msgFailedStartRecording()
{
- //restart camera if it can't apply new settings in the Active state
- QCamera *camera = qobject_cast<QCamera*>(mediaObject);
- if (camera && camera->captureMode() == QCamera::CaptureVideo) {
- QMetaObject::invokeMethod(camera,
- "_q_preparePropertyChange",
- Qt::DirectConnection,
- Q_ARG(int, QCameraControl::VideoEncodingSettings));
- }
+ return QMediaRecorder::tr("Failed to start recording");
}
-
/*!
- Constructs a media recorder which records the media produced by \a mediaObject.
-
- The \a parent is passed to QMediaObject.
+ Constructs a media recorder which records the media produced by a microphone and camera.
+ The media recorder is a child of \a{parent}.
*/
-QMediaRecorder::QMediaRecorder(QMediaObject *mediaObject, QObject *parent):
- QObject(parent),
- d_ptr(new QMediaRecorderPrivate)
+QMediaRecorder::QMediaRecorder(QObject *parent)
+ : QObject(parent),
+ d_ptr(new QMediaRecorderPrivate)
{
Q_D(QMediaRecorder);
- d->q_ptr = this;
- d->notifyTimer = new QTimer(this);
- connect(d->notifyTimer, SIGNAL(timeout()), SLOT(_q_notify()));
+ auto &mediaIntegration = *QPlatformMediaIntegration::instance();
- setMediaObject(mediaObject);
-}
-
-/*!
- \internal
-*/
-QMediaRecorder::QMediaRecorder(QMediaRecorderPrivate &dd, QMediaObject *mediaObject, QObject *parent):
- QObject(parent),
- d_ptr(&dd)
-{
- Q_D(QMediaRecorder);
d->q_ptr = this;
-
- d->notifyTimer = new QTimer(this);
- connect(d->notifyTimer, SIGNAL(timeout()), SLOT(_q_notify()));
-
- setMediaObject(mediaObject);
+ auto maybeControl = mediaIntegration.createRecorder(this);
+ if (maybeControl) {
+ // The first format info initialization may take some time,
+ // for users it seems to be more suitable to have a delay on the object construction
+ // rather than on QMediaRecorder::record
+ mediaIntegration.formatInfo();
+
+ d->control = maybeControl.value();
+ } else {
+ d->initErrorMessage = maybeControl.error();
+ qWarning() << "Failed to initialize QMediaRecorder" << maybeControl.error();
+ }
}
/*!
@@ -247,219 +134,76 @@ QMediaRecorder::QMediaRecorder(QMediaRecorderPrivate &dd, QMediaObject *mediaObj
QMediaRecorder::~QMediaRecorder()
{
+ if (d_ptr->captureSession)
+ d_ptr->captureSession->setRecorder(nullptr);
+ delete d_ptr->control;
delete d_ptr;
}
/*!
- Returns the QMediaObject instance that this QMediaRecorder is bound too,
- or 0 otherwise.
+ \internal
*/
-QMediaObject *QMediaRecorder::mediaObject() const
+QPlatformMediaRecorder *QMediaRecorder::platformRecoder() const
{
- return d_func()->mediaObject;
+ return d_ptr->control;
}
/*!
\internal
*/
-bool QMediaRecorder::setMediaObject(QMediaObject *object)
+void QMediaRecorder::setCaptureSession(QMediaCaptureSession *session)
{
Q_D(QMediaRecorder);
+ d->captureSession = session;
+}
+/*!
+ \qmlproperty QUrl QtMultimedia::MediaRecorder::outputLocation
+ \brief The destination location of media content.
- if (object == d->mediaObject)
- return true;
-
- if (d->mediaObject) {
- if (d->control) {
- disconnect(d->control, SIGNAL(stateChanged(QMediaRecorder::State)),
- this, SLOT(_q_stateChanged(QMediaRecorder::State)));
-
- disconnect(d->control, SIGNAL(statusChanged(QMediaRecorder::Status)),
- this, SIGNAL(statusChanged(QMediaRecorder::Status)));
-
- disconnect(d->control, SIGNAL(mutedChanged(bool)),
- this, SIGNAL(mutedChanged(bool)));
-
- disconnect(d->control, SIGNAL(volumeChanged(qreal)),
- this, SIGNAL(volumeChanged(qreal)));
-
- disconnect(d->control, SIGNAL(durationChanged(qint64)),
- this, SIGNAL(durationChanged(qint64)));
-
- disconnect(d->control, SIGNAL(actualLocationChanged(QUrl)),
- this, SLOT(_q_updateActualLocation(QUrl)));
-
- disconnect(d->control, SIGNAL(error(int,QString)),
- this, SLOT(_q_error(int,QString)));
- }
-
- disconnect(d->mediaObject, SIGNAL(notifyIntervalChanged(int)), this, SLOT(_q_updateNotifyInterval(int)));
-
- QMediaService *service = d->mediaObject->service();
-
- if (service) {
- disconnect(service, SIGNAL(destroyed()), this, SLOT(_q_serviceDestroyed()));
-
- if (d->control)
- service->releaseControl(d->control);
- if (d->formatControl)
- service->releaseControl(d->formatControl);
- if (d->audioControl)
- service->releaseControl(d->audioControl);
- if (d->videoControl)
- service->releaseControl(d->videoControl);
- if (d->metaDataControl) {
- disconnect(d->metaDataControl, SIGNAL(metaDataChanged()),
- this, SIGNAL(metaDataChanged()));
- disconnect(d->metaDataControl, SIGNAL(metaDataChanged(QString,QVariant)),
- this, SIGNAL(metaDataChanged(QString,QVariant)));
- disconnect(d->metaDataControl, SIGNAL(metaDataAvailableChanged(bool)),
- this, SIGNAL(metaDataAvailableChanged(bool)));
- disconnect(d->metaDataControl, SIGNAL(writableChanged(bool)),
- this, SIGNAL(metaDataWritableChanged(bool)));
-
- service->releaseControl(d->metaDataControl);
- }
- if (d->availabilityControl) {
- disconnect(d->availabilityControl, SIGNAL(availabilityChanged(QMultimedia::AvailabilityStatus)),
- this, SLOT(_q_availabilityChanged(QMultimedia::AvailabilityStatus)));
- service->releaseControl(d->availabilityControl);
- }
- }
- }
-
- d->control = nullptr;
- d->formatControl = nullptr;
- d->audioControl = nullptr;
- d->videoControl = nullptr;
- d->metaDataControl = nullptr;
- d->availabilityControl = nullptr;
-
- d->mediaObject = object;
-
- if (d->mediaObject) {
- QMediaService *service = d->mediaObject->service();
-
- d->notifyTimer->setInterval(d->mediaObject->notifyInterval());
- connect(d->mediaObject, SIGNAL(notifyIntervalChanged(int)), SLOT(_q_updateNotifyInterval(int)));
-
- if (service) {
- d->control = qobject_cast<QMediaRecorderControl*>(service->requestControl(QMediaRecorderControl_iid));
-
- if (d->control) {
- d->formatControl = qobject_cast<QMediaContainerControl *>(service->requestControl(QMediaContainerControl_iid));
- d->audioControl = qobject_cast<QAudioEncoderSettingsControl *>(service->requestControl(QAudioEncoderSettingsControl_iid));
- d->videoControl = qobject_cast<QVideoEncoderSettingsControl *>(service->requestControl(QVideoEncoderSettingsControl_iid));
-
- QMediaControl *control = service->requestControl(QMetaDataWriterControl_iid);
- if (control) {
- d->metaDataControl = qobject_cast<QMetaDataWriterControl *>(control);
- if (!d->metaDataControl) {
- service->releaseControl(control);
- } else {
- connect(d->metaDataControl,
- SIGNAL(metaDataChanged()),
- SIGNAL(metaDataChanged()));
- connect(d->metaDataControl, SIGNAL(metaDataChanged(QString,QVariant)),
- this, SIGNAL(metaDataChanged(QString,QVariant)));
- connect(d->metaDataControl,
- SIGNAL(metaDataAvailableChanged(bool)),
- SIGNAL(metaDataAvailableChanged(bool)));
- connect(d->metaDataControl,
- SIGNAL(writableChanged(bool)),
- SIGNAL(metaDataWritableChanged(bool)));
- }
- }
-
- d->availabilityControl = service->requestControl<QMediaAvailabilityControl*>();
- if (d->availabilityControl) {
- connect(d->availabilityControl, SIGNAL(availabilityChanged(QMultimedia::AvailabilityStatus)),
- this, SLOT(_q_availabilityChanged(QMultimedia::AvailabilityStatus)));
- }
-
- connect(d->control, SIGNAL(stateChanged(QMediaRecorder::State)),
- this, SLOT(_q_stateChanged(QMediaRecorder::State)));
-
- connect(d->control, SIGNAL(statusChanged(QMediaRecorder::Status)),
- this, SIGNAL(statusChanged(QMediaRecorder::Status)));
-
- connect(d->control, SIGNAL(mutedChanged(bool)),
- this, SIGNAL(mutedChanged(bool)));
-
- connect(d->control, SIGNAL(volumeChanged(qreal)),
- this, SIGNAL(volumeChanged(qreal)));
-
- connect(d->control, SIGNAL(durationChanged(qint64)),
- this, SIGNAL(durationChanged(qint64)));
-
- connect(d->control, SIGNAL(actualLocationChanged(QUrl)),
- this, SLOT(_q_updateActualLocation(QUrl)));
-
- connect(d->control, SIGNAL(error(int,QString)),
- this, SLOT(_q_error(int,QString)));
-
- connect(service, SIGNAL(destroyed()), this, SLOT(_q_serviceDestroyed()));
-
-
- d->applySettingsLater();
-
- return true;
- }
- }
+ Setting the location can fail, for example when the service supports only
+ local file system locations but a network URL was passed. If the operation
+ fails an errorOccured() signal is emitted.
- d->mediaObject = nullptr;
- return false;
- }
+ The location can be relative or empty. If empty the recorder uses the
+ system specific place and file naming scheme.
- return true;
-}
+ \sa errorOccurred()
+*/
/*!
\property QMediaRecorder::outputLocation
\brief the destination location of media content.
Setting the location can fail, for example when the service supports only
- local file system locations but a network URL was passed. If the service
- does not support media recording this setting the output location will
- always fail.
+ local file system locations but a network URL was passed. If the operation
+ fails an errorOccured() signal is emitted.
- The \a location can be relative or empty;
- in this case the recorder uses the system specific place and file naming scheme.
- After recording has stated, QMediaRecorder::outputLocation() returns the actual output location.
+ The output location can be relative or empty; in the latter case the recorder
+ uses the system specific place and file naming scheme.
*/
/*!
- \property QMediaRecorder::actualLocation
- \brief the actual location of the last media content.
+ \qmlproperty QUrl QtMultimedia::MediaRecorder::actualLocation
+ \brief The actual location of the last media content.
The actual location is usually available after recording starts,
and reset when new location is set or new recording starts.
*/
/*!
- Returns true if media recorder service ready to use.
+ \property QMediaRecorder::actualLocation
+ \brief The actual location of the last media content.
- \sa availabilityChanged()
+ The actual location is usually available after recording starts,
+ and reset when new location is set or new recording starts.
*/
-bool QMediaRecorder::isAvailable() const
-{
- return availability() == QMultimedia::Available;
-}
/*!
- Returns the availability of this functionality.
-
- \sa availabilityChanged()
+ Returns \c true if media recorder service ready to use.
*/
-QMultimedia::AvailabilityStatus QMediaRecorder::availability() const
+bool QMediaRecorder::isAvailable() const
{
- if (d_func()->control == nullptr)
- return QMultimedia::ServiceMissing;
-
- if (d_func()->availabilityControl)
- return d_func()->availabilityControl->availability();
-
- return QMultimedia::Available;
+ return d_func()->control && d_func()->captureSession;
}
QUrl QMediaRecorder::outputLocation() const
@@ -467,41 +211,68 @@ QUrl QMediaRecorder::outputLocation() const
return d_func()->control ? d_func()->control->outputLocation() : QUrl();
}
-bool QMediaRecorder::setOutputLocation(const QUrl &location)
+void QMediaRecorder::setOutputLocation(const QUrl &location)
{
Q_D(QMediaRecorder);
- d->actualLocation.clear();
- return d->control ? d->control->setOutputLocation(location) : false;
+ if (!d->control) {
+ emit errorOccurred(QMediaRecorder::ResourceError, d->initErrorMessage);
+ return;
+ }
+ d->control->setOutputLocation(location);
+ d->control->clearActualLocation();
+ if (!location.isEmpty() && !d->control->isLocationWritable(location))
+ emit errorOccurred(QMediaRecorder::LocationNotWritable, tr("Output location not writable"));
}
-QUrl QMediaRecorder::actualLocation() const
+/*!
+ Set the output IO device for media content.
+
+ The \a device must have been opened in the \l{QIODevice::WriteOnly}{WriteOnly} or
+ \l{QIODevice::ReadWrite}{ReadWrite} modes before the recording starts.
+
+ The media recorder doesn't take ownership of the specified \a device.
+ If the recording has been started, the device must be kept alive and open until
+ the signal \c recorderStateChanged(StoppedState) is emitted.
+
+ \sa outputDevice()
+*/
+void QMediaRecorder::setOutputDevice(QIODevice *device)
{
- return d_func()->actualLocation;
+ Q_D(QMediaRecorder);
+ d->control->setOutputDevice(device);
}
/*!
- Returns the current media recorder state.
+ Returns the output IO device for media content.
- \sa QMediaRecorder::State
+ \sa setOutputDevice()
*/
+QIODevice *QMediaRecorder::outputDevice() const
+{
+ Q_D(const QMediaRecorder);
+ return d->control->outputDevice();
+}
-QMediaRecorder::State QMediaRecorder::state() const
+QUrl QMediaRecorder::actualLocation() const
{
- return d_func()->control ? QMediaRecorder::State(d_func()->control->state()) : StoppedState;
+ Q_D(const QMediaRecorder);
+ return d->control ? d->control->actualLocation() : QUrl();
}
/*!
- Returns the current media recorder status.
+ Returns the current media recorder state.
- \sa QMediaRecorder::Status
+ \sa QMediaRecorder::RecorderState
*/
-QMediaRecorder::Status QMediaRecorder::status() const
+QMediaRecorder::RecorderState QMediaRecorder::recorderState() const
{
- return d_func()->control ? QMediaRecorder::Status(d_func()->control->status()) : UnavailableStatus;
+ return d_func()->control ? QMediaRecorder::RecorderState(d_func()->control->state()) : StoppedState;
}
/*!
+ \property QMediaRecorder::error
+
Returns the current error state.
\sa errorString()
@@ -509,10 +280,19 @@ QMediaRecorder::Status QMediaRecorder::status() const
QMediaRecorder::Error QMediaRecorder::error() const
{
- return d_func()->error;
+ Q_D(const QMediaRecorder);
+
+ return d->control ? d->control->error() : QMediaRecorder::ResourceError;
}
+/*!
+ \qmlproperty string QtMultimedia::MediaRecorder::errorString
+ \brief This property holds a string describing the current error state.
+ \sa error
+*/
/*!
+ \property QMediaRecorder::errorString
+
Returns a string describing the current error state.
\sa error()
@@ -520,8 +300,15 @@ QMediaRecorder::Error QMediaRecorder::error() const
QString QMediaRecorder::errorString() const
{
- return d_func()->errorString;
+ Q_D(const QMediaRecorder);
+
+ return d->control ? d->control->errorString() : d->initErrorMessage;
}
+/*!
+ \qmlproperty qint64 QtMultimedia::MediaRecorder::duration
+
+ \brief This property holds the recorded media duration in milliseconds.
+*/
/*!
\property QMediaRecorder::duration
@@ -533,577 +320,671 @@ qint64 QMediaRecorder::duration() const
{
return d_func()->control ? d_func()->control->duration() : 0;
}
-
/*!
- \property QMediaRecorder::muted
+ \fn void QMediaRecorder::encoderSettingsChanged()
- \brief whether a recording audio stream is muted.
+ Signals when the encoder settings change.
*/
+/*!
+ \qmlmethod QtMultimedia::MediaRecorder::record()
+ \brief Starts recording.
-bool QMediaRecorder::isMuted() const
-{
- return d_func()->control ? d_func()->control->isMuted() : 0;
-}
+ While the recorder state is changed immediately to
+ \c MediaRecorder.RecordingState, recording may start asynchronously.
-void QMediaRecorder::setMuted(bool muted)
-{
- Q_D(QMediaRecorder);
-
- if (d->control)
- d->control->setMuted(muted);
-}
+ If recording fails, the error() signal is emitted with recorder state being
+ reset back to \c{QMediaRecorder.StoppedState}.
+ \note On mobile devices, recording will happen in the orientation the
+ device had when calling record and is locked for the duration of the recording.
+ To avoid artifacts on the user interface, we recommend to keep the user interface
+ locked to the same orientation as long as the recording is ongoing using
+ the contentOrientation property of the Window and unlock it again once the recording
+ is finished.
+*/
/*!
- \property QMediaRecorder::volume
-
- \brief the current recording audio volume.
+ Start recording.
- The volume is scaled linearly from \c 0.0 (silence) to \c 1.0 (full volume). Values outside this
- range will be clamped.
+ While the recorder state is changed immediately to
+ c\{QMediaRecorder::RecordingState}, recording may start asynchronously.
- The default volume is \c 1.0.
+ If recording fails error() signal is emitted with recorder state being
+ reset back to \c{QMediaRecorder::StoppedState}.
- UI volume controls should usually be scaled nonlinearly. For example, using a logarithmic scale
- will produce linear changes in perceived loudness, which is what a user would normally expect
- from a volume control. See QAudio::convertVolume() for more details.
+ \note On mobile devices, recording will happen in the orientation the
+ device had when calling record and is locked for the duration of the recording.
+ To avoid artifacts on the user interface, we recommend to keep the user interface
+ locked to the same orientation as long as the recording is ongoing using
+ the contentOrientation property of QWindow and unlock it again once the recording
+ is finished.
*/
-qreal QMediaRecorder::volume() const
+void QMediaRecorder::record()
{
- return d_func()->control ? d_func()->control->volume() : 1.0;
-}
+ Q_D(QMediaRecorder);
+ if (!d->control || !d->captureSession)
+ return;
-void QMediaRecorder::setVolume(qreal volume)
-{
- Q_D(QMediaRecorder);
+ if (d->control->state() == QMediaRecorder::PausedState) {
+ d->control->resume();
+ } else {
+ auto oldMediaFormat = d->encoderSettings.mediaFormat();
- if (d->control) {
- volume = qMax(qreal(0.0), volume);
- d->control->setVolume(volume);
+ auto platformSession = d->captureSession->platformSession();
+ const bool hasVideo = platformSession && !platformSession->activeVideoSources().empty();
+
+ d->encoderSettings.resolveFormat(hasVideo ? QMediaFormat::RequiresVideo : QMediaFormat::NoFlags);
+ d->control->clearActualLocation();
+ d->control->clearError();
+
+ auto settings = d->encoderSettings;
+ d->control->record(d->encoderSettings);
+
+ if (settings != d->encoderSettings)
+ emit encoderSettingsChanged();
+
+ if (oldMediaFormat != d->encoderSettings.mediaFormat())
+ emit mediaFormatChanged();
}
}
-
/*!
- Returns a list of supported container formats.
-*/
-QStringList QMediaRecorder::supportedContainers() const
-{
- return d_func()->formatControl ?
- d_func()->formatControl->supportedContainers() : QStringList();
-}
+ \qmlmethod QtMultimedia::MediaRecorder::pause()
+ \brief Pauses recording.
-/*!
- Returns a description of a container \a format.
-*/
-QString QMediaRecorder::containerDescription(const QString &format) const
-{
- return d_func()->formatControl ?
- d_func()->formatControl->containerDescription(format) : QString();
-}
+ The recorder state is changed to QMediaRecorder.PausedState.
+ Depending on the platform, pausing recording may be not supported.
+ In this case the recorder state is unchanged.
+*/
/*!
- Returns the selected container format.
+ Pauses recording.
+
+ The recorder state is changed to QMediaRecorder::PausedState.
+
+ Depending on the platform, pausing recording may be not supported.
+ In this case the recorder state is unchanged.
*/
-QString QMediaRecorder::containerFormat() const
+void QMediaRecorder::pause()
{
- return d_func()->formatControl ?
- d_func()->formatControl->containerFormat() : QString();
+ Q_D(QMediaRecorder);
+ if (d->control && d->captureSession)
+ d->control->pause();
}
-
/*!
- Returns a list of supported audio codecs.
+ \qmlmethod QtMultimedia::MediaRecorder::stop()
+ \brief Stops the recording.
+
+ The recorder will stop the recording. Processing pending video and audio data might
+ however still take some time. The recording is finished, once the state of the media
+ recorder changes to QMediaRecorder::StoppedState.
*/
-QStringList QMediaRecorder::supportedAudioCodecs() const
-{
- return d_func()->audioControl ?
- d_func()->audioControl->supportedAudioCodecs() : QStringList();
-}
/*!
- Returns a description of an audio \a codec.
+ The recorder will stop the recording. Processing pending video and audio data might
+ however still take some time. The recording is finished, once the state of the media
+ recorder changes to QMediaRecorder::StoppedState.
*/
-QString QMediaRecorder::audioCodecDescription(const QString &codec) const
+void QMediaRecorder::stop()
{
- return d_func()->audioControl ?
- d_func()->audioControl->codecDescription(codec) : QString();
+ Q_D(QMediaRecorder);
+ if (d->control && d->captureSession)
+ d->control->stop();
}
+/*!
+ \qmlproperty enumeration QtMultimedia::MediaRecorder::recorderState
+ \brief This property holds the current media recorder state.
+
+ The state property represents the user request and is changed synchronously
+ during record(), pause() or stop() calls.
+ RecorderSstate may also change asynchronously when recording fails.
+ \value MediaRecorder.StoppedState The recorder is not active.
+ \value MediaRecorder.RecordingState The recording is requested.
+ \value MediaRecorder.PausedState The recorder is pause.
+*/
/*!
- Returns a list of supported audio sample rates.
+ \enum QMediaRecorder::RecorderState
- If non null audio \a settings parameter is passed, the returned list is
- reduced to sample rates supported with partial settings applied.
+ \value StoppedState The recorder is not active.
+ \value RecordingState The recording is requested.
+ \value PausedState The recorder is paused.
+*/
+/*!
+ \qmlproperty enumeration QtMultimedia::MediaRecorder::error
+ \brief This property holds the current media recorder error state.
- This can be used to query the list of sample rates, supported by specific
- audio codec.
+ \value MediaRecorder.NoError Not in an error state.
+ \value MediaRecorder.ResourceError Not enough system resources
+ \value MediaRecorder.FormatError the current format is not supported.
+ \value MediaRecorder.OutOfSpaceError No space left on device.
+ \value MediaRecorder.LocationNotWriteable The output location is not writable.
+*/
+/*!
+ \enum QMediaRecorder::Error
- If the encoder supports arbitrary sample rates within the supported rates
- range, *\a continuous is set to true, otherwise *\a continuous is set to
- false.
+ \value NoError No Errors.
+ \value ResourceError Device is not ready or not available.
+ \value FormatError Current format is not supported.
+ \value OutOfSpaceError No space left on device.
+ \value LocationNotWritable The output location is not writable.
*/
-QList<int> QMediaRecorder::supportedAudioSampleRates(const QAudioEncoderSettings &settings, bool *continuous) const
-{
- if (continuous)
- *continuous = false;
+/*!
+ \property QMediaRecorder::recorderState
+ \brief The current state of the media recorder.
- return d_func()->audioControl ?
- d_func()->audioControl->supportedSampleRates(settings, continuous) : QList<int>();
-}
+ The state property represents the user request and is changed synchronously
+ during record(), pause() or stop() calls.
+ Recorder state may also change asynchronously when recording fails.
+*/
/*!
- Returns a list of resolutions video can be encoded at.
+ \qmlsignal QtMultimedia::MediaRecorder::recorderStateChanged(RecorderState state)
+ \brief Signals that a media recorder's \a state has changed.
+*/
- If non null video \a settings parameter is passed, the returned list is
- reduced to resolution supported with partial settings like video codec or
- framerate applied.
+/*!
+ \fn QMediaRecorder::recorderStateChanged(QMediaRecorder::RecorderState state)
- If the encoder supports arbitrary resolutions within the supported range,
- *\a continuous is set to true, otherwise *\a continuous is set to false.
+ Signals that a media recorder's \a state has changed.
+*/
- \sa QVideoEncoderSettings::resolution()
+/*!
+ \qmlsignal QtMultimedia::MediaRecorder::durationChanged(qint64 duration)
+ \brief Signals that the \a duration of the recorded media has changed.
*/
-QList<QSize> QMediaRecorder::supportedResolutions(const QVideoEncoderSettings &settings, bool *continuous) const
-{
- if (continuous)
- *continuous = false;
- return d_func()->videoControl ?
- d_func()->videoControl->supportedResolutions(settings, continuous) : QList<QSize>();
-}
+/*!
+ \fn QMediaRecorder::durationChanged(qint64 duration)
+ Signals that the \a duration of the recorded media has changed.
+*/
/*!
- Returns a list of frame rates video can be encoded at.
+ \qmlsignal QtMultimedia::MediaRecorder::actualLocationChanged(const QUrl &location)
+ \brief Signals that the actual \a location of the recorded media has changed.
- If non null video \a settings parameter is passed, the returned list is
- reduced to frame rates supported with partial settings like video codec or
- resolution applied.
+ This signal is usually emitted when recording starts.
+*/
+/*!
+ \fn QMediaRecorder::actualLocationChanged(const QUrl &location)
- If the encoder supports arbitrary frame rates within the supported range,
- *\a continuous is set to true, otherwise *\a continuous is set to false.
+ Signals that the actual \a location of the recorded media has changed.
+ This signal is usually emitted when recording starts.
+*/
+/*!
+ \qmlsignal QtMultimedia::MediaRecorder::errorOccurred(Error error, const QString &errorString)
+ \brief Signals that an \a error has occurred.
- \sa QVideoEncoderSettings::frameRate()
+ The \a errorString contains a description of the error.
*/
-QList<qreal> QMediaRecorder::supportedFrameRates(const QVideoEncoderSettings &settings, bool *continuous) const
-{
- if (continuous)
- *continuous = false;
+/*!
+ \fn QMediaRecorder::errorOccurred(QMediaRecorder::Error error, const QString &errorString)
- return d_func()->videoControl ?
- d_func()->videoControl->supportedFrameRates(settings, continuous) : QList<qreal>();
-}
+ Signals that an \a error has occurred, with \a errorString containing
+ a description of the error.
+*/
/*!
- Returns a list of supported video codecs.
+ \qmlproperty mediaMetaData QtMultimedia::MediaRecorder::metaData
+
+ \brief This property holds meta data associated with the recording.
+
+ When a recording is started, any meta-data assigned will be attached to that
+ recording.
+
+ \note Ensure that meta-data is assigned correctly by assigning it before
+ starting the recording.
+
+ \sa mediaMetaData
*/
-QStringList QMediaRecorder::supportedVideoCodecs() const
-{
- return d_func()->videoControl ?
- d_func()->videoControl->supportedVideoCodecs() : QStringList();
-}
/*!
- Returns a description of a video \a codec.
+ \property QMediaRecorder::metaData
- \sa setEncodingSettings()
+ Returns the metaData associated with the recording.
*/
-QString QMediaRecorder::videoCodecDescription(const QString &codec) const
+QMediaMetaData QMediaRecorder::metaData() const
{
- return d_func()->videoControl ?
- d_func()->videoControl->videoCodecDescription(codec) : QString();
+ Q_D(const QMediaRecorder);
+
+ return d->control ? d->control->metaData() : QMediaMetaData{};
}
/*!
- Returns the audio encoder settings being used.
+ Sets the meta data to \a metaData.
- \sa setEncodingSettings()
+ \note To ensure that meta-data is set correctly, it should be set before starting the recording.
+ Once the recording is started, any meta-data set will be attached to the next recording.
*/
-
-QAudioEncoderSettings QMediaRecorder::audioSettings() const
+void QMediaRecorder::setMetaData(const QMediaMetaData &metaData)
{
- return d_func()->audioControl ?
- d_func()->audioControl->audioSettings() : QAudioEncoderSettings();
+ Q_D(QMediaRecorder);
+
+ if (d->control && d->captureSession)
+ d->control->setMetaData(metaData);
}
/*!
- Returns the video encoder settings being used.
-
- \sa setEncodingSettings()
+ Adds \a metaData to the recorded media.
*/
-
-QVideoEncoderSettings QMediaRecorder::videoSettings() const
+void QMediaRecorder::addMetaData(const QMediaMetaData &metaData)
{
- return d_func()->videoControl ?
- d_func()->videoControl->videoSettings() : QVideoEncoderSettings();
+ auto data = this->metaData();
+ // merge data
+ for (auto &&[key, value] : metaData.asKeyValueRange())
+ data.insert(key, value);
+ setMetaData(data);
}
/*!
- Sets the audio encoder \a settings.
+ \property QMediaRecorder::autoStop
- If some parameters are not specified, or null settings are passed, the
- encoder will choose default encoding parameters, depending on media
- source properties.
+ This property controls whether the media recorder stops automatically when
+ all media inputs have reported the end of the stream or have been deactivated.
- It's only possible to change settings when the encoder is in the
- QMediaEncoder::StoppedState state.
+ The end of the stream is reported by sending an empty media frame,
+ which you can send explicitly via \l QVideoFrameInput or \l QAudioBufferInput.
- \sa audioSettings(), videoSettings(), containerFormat()
+ Video inputs, specificly, \l QCamera, \l QScreenCapture and \l QWindowCapture,
+ can be deactivated via the function \c setActive.
+
+ Defaults to \c false.
+
+ \sa QCamera, QScreenCapture, QWindowCapture
*/
-void QMediaRecorder::setAudioSettings(const QAudioEncoderSettings &settings)
+bool QMediaRecorder::autoStop() const
+{
+ Q_D(const QMediaRecorder);
+
+ return d->autoStop;
+}
+
+void QMediaRecorder::setAutoStop(bool autoStop)
{
Q_D(QMediaRecorder);
- //restart camera if it can't apply new settings in the Active state
- d->restartCamera();
+ if (d->autoStop == autoStop)
+ return;
- if (d->audioControl) {
- d->audioControl->setAudioSettings(settings);
- d->applySettingsLater();
- }
+ d->autoStop = autoStop;
+ d->control->updateAutoStop();
+ emit autoStopChanged();
}
/*!
- Sets the video encoder \a settings.
-
- If some parameters are not specified, or null settings are passed, the
- encoder will choose default encoding parameters, depending on media
- source properties.
+ \qmlsignal QtMultimedia::MediaRecorder::metaDataChanged()
- It's only possible to change settings when the encoder is in the
- QMediaEncoder::StoppedState state.
+ \brief Signals that a media object's meta-data has changed.
- \sa audioSettings(), videoSettings(), containerFormat()
+ If multiple meta-data elements are changed metaDataChanged() is emitted
+ once.
*/
+/*!
+ \fn QMediaRecorder::metaDataChanged()
-void QMediaRecorder::setVideoSettings(const QVideoEncoderSettings &settings)
-{
- Q_D(QMediaRecorder);
+ Signals that a media object's meta-data has changed.
- d->restartCamera();
+ If multiple meta-data elements are changed metaDataChanged() is emitted
+ once.
+*/
- if (d->videoControl) {
- d->videoControl->setVideoSettings(settings);
- d->applySettingsLater();
- }
+/*!
+ Returns the media capture session.
+*/
+QMediaCaptureSession *QMediaRecorder::captureSession() const
+{
+ Q_D(const QMediaRecorder);
+ return d->captureSession;
}
-
/*!
- Sets the media \a container format.
+ \qmlproperty enumeration QtMultimedia::MediaRecorder::quality
- If the container format is not specified, the
- encoder will choose format, depending on media source properties
- and encoding settings selected.
+ Enumerates quality encoding levels.
- It's only possible to change settings when the encoder is in the
- QMediaEncoder::StoppedState state.
+ \value MediaRecorder.VeryLowQuality
+ \value MediaRecorder.LowQuality
+ \value MediaRecorder.NormalQuality
+ \value MediaRecorder.HighQuality
+ \value MediaRecorder.VeryHighQuality
+*/
+/*!
+ \enum QMediaRecorder::Quality
- \sa audioSettings(), videoSettings(), containerFormat()
+ Enumerates quality encoding levels.
+
+ \value VeryLowQuality
+ \value LowQuality
+ \value NormalQuality
+ \value HighQuality
+ \value VeryHighQuality
*/
-void QMediaRecorder::setContainerFormat(const QString &container)
-{
- Q_D(QMediaRecorder);
+/*!
+ \enum QMediaRecorder::EncodingMode
- d->restartCamera();
+ Enumerates encoding modes.
- if (d->formatControl) {
- d->formatControl->setContainerFormat(container);
- d->applySettingsLater();
- }
-}
+ \value ConstantQualityEncoding Encoding will aim to have a constant quality, adjusting bitrate to fit.
+ \value ConstantBitRateEncoding Encoding will use a constant bit rate, adjust quality to fit.
+ \value AverageBitRateEncoding Encoding will try to keep an average bitrate setting, but will use
+ more or less as needed.
+ \value TwoPassEncoding The media will first be processed to determine the characteristics,
+ and then processed a second time allocating more bits to the areas
+ that need it.
+*/
/*!
- Sets the \a audio and \a video encoder settings and \a container format.
- If some parameters are not specified, or null settings are passed, the
- encoder will choose default encoding parameters, depending on media
- source properties.
+ \qmlproperty MediaFormat QtMultimedia::MediaRecorder::mediaFormat
- It's only possible to change settings when the encoder is in the
- QMediaEncoder::StoppedState state.
+ \brief This property holds the current MediaFormat of the recorder.
+*/
+/*!
+ \property QMediaRecorder::mediaFormat
- \sa audioSettings(), videoSettings(), containerFormat()
+ Returns the recording media format.
*/
+QMediaFormat QMediaRecorder::mediaFormat() const
+{
+ Q_D(const QMediaRecorder);
+ return d->encoderSettings.mediaFormat();
+}
-void QMediaRecorder::setEncodingSettings(const QAudioEncoderSettings &audio,
- const QVideoEncoderSettings &video,
- const QString &container)
+void QMediaRecorder::setMediaFormat(const QMediaFormat &format)
{
Q_D(QMediaRecorder);
+ if (d->encoderSettings.mediaFormat() == format)
+ return;
+ d->encoderSettings.setMediaFormat(format);
+ emit mediaFormatChanged();
+}
- d->restartCamera();
-
- if (d->audioControl)
- d->audioControl->setAudioSettings(audio);
+/*!
- if (d->videoControl)
- d->videoControl->setVideoSettings(video);
+ \qmlproperty enumeration QtMultimedia::MediaRecorder::encodingMode
+ \since 6.6
+ \brief This property holds the encoding mode.
+ \sa QMediaRecorder::EncodingMode
+*/
- if (d->formatControl)
- d->formatControl->setContainerFormat(container);
+/*!
+ Returns the encoding mode.
- d->applySettingsLater();
+ \sa EncodingMode
+*/
+QMediaRecorder::EncodingMode QMediaRecorder::encodingMode() const
+{
+ Q_D(const QMediaRecorder);
+ return d->encoderSettings.encodingMode();
}
/*!
- Start recording.
-
- While the recorder state is changed immediately to QMediaRecorder::RecordingState,
- recording may start asynchronously, with statusChanged(QMediaRecorder::RecordingStatus)
- signal emitted when recording starts.
+ \fn void QMediaRecorder::encodingModeChanged()
- If recording fails error() signal is emitted
- with recorder state being reset back to QMediaRecorder::StoppedState.
+ Signals when the encoding mode changes.
*/
+/*!
+ Sets the encoding \a mode setting.
-void QMediaRecorder::record()
+ If ConstantQualityEncoding is set, the quality
+ encoding parameter is used and bit rates are ignored,
+ otherwise the bitrates are used.
+
+ \sa encodingMode(), EncodingMode
+*/
+void QMediaRecorder::setEncodingMode(EncodingMode mode)
{
Q_D(QMediaRecorder);
-
- d->actualLocation.clear();
-
- if (d->settingsChanged)
- d->_q_applySettings();
-
- // reset error
- d->error = NoError;
- d->errorString = QString();
-
- if (d->control)
- d->control->setState(RecordingState);
+ if (d->encoderSettings.encodingMode() == mode)
+ return;
+ d->encoderSettings.setEncodingMode(mode);
+ emit encodingModeChanged();
}
/*!
- Pause recording.
-
- The recorder state is changed to QMediaRecorder::PausedState.
+ \property QMediaRecorder::quality
- Depending on platform recording pause may be not supported,
- in this case the recorder state stays unchanged.
+ Returns the recording quality.
*/
-
-void QMediaRecorder::pause()
+QMediaRecorder::Quality QMediaRecorder::quality() const
{
- Q_D(QMediaRecorder);
- if (d->control)
- d->control->setState(PausedState);
+ Q_D(const QMediaRecorder);
+ return d->encoderSettings.quality();
}
/*!
- Stop recording.
+ \fn void QMediaRecorder::qualityChanged()
- The recorder state is changed to QMediaRecorder::StoppedState.
+ Signals when the recording quality changes.
*/
-
-void QMediaRecorder::stop()
+void QMediaRecorder::setQuality(Quality quality)
{
Q_D(QMediaRecorder);
- if (d->control)
- d->control->setState(StoppedState);
+ if (d->encoderSettings.quality() == quality)
+ return;
+ d->encoderSettings.setQuality(quality);
+ emit qualityChanged();
}
/*!
- \enum QMediaRecorder::State
+ \qmlproperty Size QtMultimedia::MediaRecorder::videoResolution
+ \since 6.6
+ \brief This property holds the resolution of the encoded video.
- \value StoppedState The recorder is not active.
- If this is the state after recording then the actual created recording has
- finished being written to the final location and is ready on all platforms
- except on Android. On Android, due to platform limitations, there is no way
- to be certain that the recording has finished writing to the final location.
- \value RecordingState The recording is requested.
- \value PausedState The recorder is paused.
+ Set an empty Size to make the recorder choose an optimal resolution based
+ on what is available from the video source and the limitations of the codec.
*/
-/*!
- \enum QMediaRecorder::Status
- \value UnavailableStatus
- The recorder is not available or not supported by connected media object.
- \value UnloadedStatus
- The recorder is avilable but not loaded.
- \value LoadingStatus
- The recorder is initializing.
- \value LoadedStatus
- The recorder is initialized and ready to record media.
- \value StartingStatus
- Recording is requested but not active yet.
- \value RecordingStatus
- Recording is active.
- \value PausedStatus
- Recording is paused.
- \value FinalizingStatus
- Recording is stopped with media being finalized.
+/*!
+ Returns the resolution of the encoded video.
*/
+QSize QMediaRecorder::videoResolution() const
+{
+ Q_D(const QMediaRecorder);
+ return d->encoderSettings.videoResolution();
+}
/*!
- \enum QMediaRecorder::Error
+ \fn void QMediaRecorder::videoResolutionChanged()
- \value NoError No Errors.
- \value ResourceError Device is not ready or not available.
- \value FormatError Current format is not supported.
- \value OutOfSpaceError No space left on device.
+ Signals when the video recording resolution changes.
*/
-
/*!
- \property QMediaRecorder::state
- \brief The current state of the media recorder.
+ Sets the resolution of the encoded video to \a{size}.
- The state property represents the user request and is changed synchronously
- during record(), pause() or stop() calls.
- Recorder state may also change asynchronously when recording fails.
+ Pass an empty QSize to make the recorder choose an optimal resolution based
+ on what is available from the video source and the limitations of the codec.
*/
+void QMediaRecorder::setVideoResolution(const QSize &size)
+{
+ Q_D(QMediaRecorder);
+ if (d->encoderSettings.videoResolution() == size)
+ return;
+ d->encoderSettings.setVideoResolution(size);
+ emit videoResolutionChanged();
+}
-/*!
- \property QMediaRecorder::status
- \brief The current status of the media recorder.
+/*! \fn void QMediaRecorder::setVideoResolution(int width, int height)
- The status is changed asynchronously and represents the actual status
- of media recorder.
+ Sets the \a width and \a height of the resolution of the encoded video.
+
+ \overload
*/
/*!
- \fn QMediaRecorder::stateChanged(State state)
+ \qmlproperty real QtMultimedia::MediaRecorder::videoFrameRate
+ \since 6.6
+ \brief This property holds the video frame rate.
- Signals that a media recorder's \a state has changed.
+ A value of 0 indicates the recorder should make an optimal choice based on what is available
+ from the video source and the limitations of the codec.
*/
/*!
- \fn QMediaRecorder::durationChanged(qint64 duration)
-
- Signals that the \a duration of the recorded media has changed.
+ Returns the video frame rate.
*/
+qreal QMediaRecorder::videoFrameRate() const
+{
+ Q_D(const QMediaRecorder);
+ return d->encoderSettings.videoFrameRate();
+}
/*!
- \fn QMediaRecorder::actualLocationChanged(const QUrl &location)
+ \fn void QMediaRecorder::videoFrameRateChanged()
- Signals that the actual \a location of the recorded media has changed.
- This signal is usually emitted when recording starts.
+ Signals when the recording video frame rate changes.
*/
-
/*!
- \fn QMediaRecorder::error(QMediaRecorder::Error error)
+ Sets the video \a frameRate.
- Signals that an \a error has occurred.
+ A value of 0 indicates the recorder should make an optimal choice based on what is available
+ from the video source and the limitations of the codec.
*/
+void QMediaRecorder::setVideoFrameRate(qreal frameRate)
+{
+ Q_D(QMediaRecorder);
+ if (d->encoderSettings.videoFrameRate() == frameRate)
+ return;
+ d->encoderSettings.setVideoFrameRate(frameRate);
+ emit videoFrameRateChanged();
+}
/*!
- \fn QMediaRecorder::availabilityChanged(bool available)
-
- Signals that the media recorder is now available (if \a available is true), or not.
+ \qmlproperty int QtMultimedia::MediaRecorder::videoBitRate
+ \since 6.6
+ \brief This property holds the bit rate of the compressed video stream in bits per second.
*/
/*!
- \fn QMediaRecorder::availabilityChanged(QMultimedia::AvailabilityStatus availability)
-
- Signals that the service availability has changed to \a availability.
+ Returns the bit rate of the compressed video stream in bits per second.
*/
+int QMediaRecorder::videoBitRate() const
+{
+ Q_D(const QMediaRecorder);
+ return d->encoderSettings.videoBitRate();
+}
/*!
- \fn QMediaRecorder::mutedChanged(bool muted)
+ \fn void QMediaRecorder::videoBitRateChanged()
- Signals that the \a muted state has changed. If true the recording is being muted.
+ Signals when the recording video bit rate changes.
*/
-
/*!
- \property QMediaRecorder::metaDataAvailable
- \brief whether access to a media object's meta-data is available.
+ Sets the video \a bitRate in bits per second.
+*/
+void QMediaRecorder::setVideoBitRate(int bitRate)
+{
+ Q_D(QMediaRecorder);
+ if (d->encoderSettings.videoBitRate() == bitRate)
+ return;
+ d->encoderSettings.setVideoBitRate(bitRate);
+ emit videoBitRateChanged();
+}
- If this is true there is meta-data available, otherwise there is no meta-data available.
+/*!
+ \qmlproperty int QtMultimedia::MediaRecorder::audioBitRate
+ \since 6.6
+ \brief This property holds the bit rate of the compressed audio stream in bits per second.
*/
-bool QMediaRecorder::isMetaDataAvailable() const
+/*!
+ Returns the bit rate of the compressed audio stream in bits per second.
+*/
+int QMediaRecorder::audioBitRate() const
{
Q_D(const QMediaRecorder);
-
- return d->metaDataControl
- ? d->metaDataControl->isMetaDataAvailable()
- : false;
+ return d->encoderSettings.audioBitRate();
}
/*!
- \fn QMediaRecorder::metaDataAvailableChanged(bool available)
+ \fn void QMediaRecorder::audioBitRateChanged()
- Signals that the \a available state of a media object's meta-data has changed.
+ Signals when the recording audio bit rate changes.
*/
-
/*!
- \property QMediaRecorder::metaDataWritable
- \brief whether a media object's meta-data is writable.
-
- If this is true the meta-data is writable, otherwise the meta-data is read-only.
+ Sets the audio \a bitRate in bits per second.
*/
-
-bool QMediaRecorder::isMetaDataWritable() const
+void QMediaRecorder::setAudioBitRate(int bitRate)
{
- Q_D(const QMediaRecorder);
-
- return d->metaDataControl
- ? d->metaDataControl->isWritable()
- : false;
+ Q_D(QMediaRecorder);
+ if (d->encoderSettings.audioBitRate() == bitRate)
+ return;
+ d->encoderSettings.setAudioBitRate(bitRate);
+ emit audioBitRateChanged();
}
/*!
- \fn QMediaRecorder::metaDataWritableChanged(bool writable)
-
- Signals that the \a writable state of a media object's meta-data has changed.
+ \qmlproperty int QtMultimedia::MediaRecorder::audioChannelCount
+ \since 6.6
+ \brief This property holds the number of audio channels.
*/
/*!
- Returns the value associated with a meta-data \a key.
+ Returns the number of audio channels.
*/
-QVariant QMediaRecorder::metaData(const QString &key) const
+int QMediaRecorder::audioChannelCount() const
{
Q_D(const QMediaRecorder);
-
- return d->metaDataControl
- ? d->metaDataControl->metaData(key)
- : QVariant();
+ return d->encoderSettings.audioChannelCount();
}
/*!
- Sets a \a value for a meta-data \a key.
+ \fn void QMediaRecorder::audioChannelCountChanged()
- \note To ensure that meta data is set corretly, it should be set before starting the recording.
- Once the recording is stopped, any meta data set will be attached to the next recording.
+ Signals when the recording audio channel count changes.
*/
-void QMediaRecorder::setMetaData(const QString &key, const QVariant &value)
+/*!
+ Sets the number of audio \a channels.
+
+ A value of -1 indicates the recorder should make an optimal choice based on
+ what is available from the audio source and the limitations of the codec.
+*/
+void QMediaRecorder::setAudioChannelCount(int channels)
{
Q_D(QMediaRecorder);
-
- if (d->metaDataControl)
- d->metaDataControl->setMetaData(key, value);
+ if (d->encoderSettings.audioChannelCount() == channels)
+ return;
+ d->encoderSettings.setAudioChannelCount(channels);
+ emit audioChannelCountChanged();
}
/*!
- Returns a list of keys there is meta-data available for.
+ \qmlproperty int QtMultimedia::MediaRecorder::audioSampleRate
+ \since 6.6
+ \brief This property holds the audio sample rate in Hz.
+*/
+
+/*!
+ Returns the audio sample rate in Hz.
*/
-QStringList QMediaRecorder::availableMetaData() const
+int QMediaRecorder::audioSampleRate() const
{
Q_D(const QMediaRecorder);
-
- return d->metaDataControl
- ? d->metaDataControl->availableMetaData()
- : QStringList();
+ return d->encoderSettings.audioSampleRate();
}
-
/*!
- \fn QMediaRecorder::metaDataChanged()
+ \fn void QMediaRecorder::audioSampleRateChanged()
- Signals that a media object's meta-data has changed.
-
- If multiple meta-data elements are changed,
- metaDataChanged(const QString &key, const QVariant &value) signal is emitted
- for each of them with metaDataChanged() changed emitted once.
+ Signals when the recording audio sample rate changes.
*/
-
/*!
- \fn QMediaRecorder::metaDataChanged(const QString &key, const QVariant &value)
+ Sets the audio \a sampleRate in Hz.
- Signal the changes of one meta-data element \a value with the given \a key.
+ A value of \c -1 indicates the recorder should make an optimal choice based
+ on what is available from the audio source, and the limitations of the codec.
*/
+void QMediaRecorder::setAudioSampleRate(int sampleRate)
+{
+ Q_D(QMediaRecorder);
+ if (d->encoderSettings.audioSampleRate() == sampleRate)
+ return;
+ d->encoderSettings.setAudioSampleRate(sampleRate);
+ emit audioSampleRateChanged();
+}
QT_END_NAMESPACE
diff --git a/src/multimedia/recording/qmediarecorder.h b/src/multimedia/recording/qmediarecorder.h
index 0fdcf80e4..a73d9f8af 100644
--- a/src/multimedia/recording/qmediarecorder.h
+++ b/src/multimedia/recording/qmediarecorder.h
@@ -1,50 +1,14 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QMEDIARECORDER_H
-#define QMEDIARECORDER_H
-
-#include <QtMultimedia/qmultimedia.h>
-#include <QtMultimedia/qmediaobject.h>
-#include <QtMultimedia/qmediaencodersettings.h>
-#include <QtMultimedia/qmediabindableinterface.h>
+// Copyright (C) 2016 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 QMediaRecorder_H
+#define QMediaRecorder_H
+
+#include <QtCore/qobject.h>
+#include <QtCore/qsize.h>
+#include <QtMultimedia/qtmultimediaglobal.h>
#include <QtMultimedia/qmediaenumdebug.h>
+#include <QtMultimedia/qmediametadata.h>
#include <QtCore/qpair.h>
@@ -53,171 +17,168 @@ QT_BEGIN_NAMESPACE
class QUrl;
class QSize;
class QAudioFormat;
-QT_END_NAMESPACE
-
-QT_BEGIN_NAMESPACE
-
-class QMediaRecorderService;
-class QAudioEncoderSettings;
-class QVideoEncoderSettings;
+class QCamera;
+class QCameraDevice;
+class QMediaFormat;
+class QAudioDevice;
+class QMediaCaptureSession;
+class QPlatformMediaRecorder;
class QMediaRecorderPrivate;
-class Q_MULTIMEDIA_EXPORT QMediaRecorder : public QObject, public QMediaBindableInterface
+class Q_MULTIMEDIA_EXPORT QMediaRecorder : public QObject
{
Q_OBJECT
- Q_INTERFACES(QMediaBindableInterface)
- Q_ENUMS(State)
- Q_ENUMS(Status)
- Q_ENUMS(Error)
- Q_PROPERTY(QMediaRecorder::State state READ state NOTIFY stateChanged)
- Q_PROPERTY(QMediaRecorder::Status status READ status NOTIFY statusChanged)
+ Q_PROPERTY(QMediaRecorder::RecorderState recorderState READ recorderState NOTIFY recorderStateChanged)
Q_PROPERTY(qint64 duration READ duration NOTIFY durationChanged)
Q_PROPERTY(QUrl outputLocation READ outputLocation WRITE setOutputLocation)
Q_PROPERTY(QUrl actualLocation READ actualLocation NOTIFY actualLocationChanged)
- Q_PROPERTY(bool muted READ isMuted WRITE setMuted NOTIFY mutedChanged)
- Q_PROPERTY(qreal volume READ volume WRITE setVolume NOTIFY volumeChanged)
- Q_PROPERTY(bool metaDataAvailable READ isMetaDataAvailable NOTIFY metaDataAvailableChanged)
- Q_PROPERTY(bool metaDataWritable READ isMetaDataWritable NOTIFY metaDataWritableChanged)
+ Q_PROPERTY(QMediaMetaData metaData READ metaData WRITE setMetaData NOTIFY metaDataChanged)
+ Q_PROPERTY(QMediaRecorder::Error error READ error NOTIFY errorChanged)
+ Q_PROPERTY(QString errorString READ errorString NOTIFY errorChanged)
+ Q_PROPERTY(QMediaFormat mediaFormat READ mediaFormat WRITE setMediaFormat NOTIFY mediaFormatChanged)
+ Q_PROPERTY(Quality quality READ quality WRITE setQuality NOTIFY qualityChanged)
+ Q_PROPERTY(QMediaRecorder::EncodingMode encodingMode READ encodingMode WRITE setEncodingMode NOTIFY encodingModeChanged)
+ Q_PROPERTY(QSize videoResolution READ videoResolution WRITE setVideoResolution NOTIFY videoResolutionChanged)
+ Q_PROPERTY(qreal videoFrameRate READ videoFrameRate WRITE setVideoFrameRate NOTIFY videoFrameRateChanged)
+ Q_PROPERTY(int videoBitRate READ videoBitRate WRITE setVideoBitRate NOTIFY videoBitRateChanged)
+ Q_PROPERTY(int audioBitRate READ audioBitRate WRITE setAudioBitRate NOTIFY audioBitRateChanged)
+ Q_PROPERTY(int audioChannelCount READ audioChannelCount WRITE setAudioChannelCount NOTIFY audioChannelCountChanged)
+ Q_PROPERTY(int audioSampleRate READ audioSampleRate WRITE setAudioSampleRate NOTIFY audioSampleRateChanged)
+ Q_PROPERTY(bool autoStop READ autoStop WRITE setAutoStop NOTIFY autoStopChanged)
public:
+ enum Quality
+ {
+ VeryLowQuality,
+ LowQuality,
+ NormalQuality,
+ HighQuality,
+ VeryHighQuality
+ };
+ Q_ENUM(Quality)
- enum State
+ enum EncodingMode
+ {
+ ConstantQualityEncoding,
+ ConstantBitRateEncoding,
+ AverageBitRateEncoding,
+ TwoPassEncoding
+ };
+ Q_ENUM(EncodingMode)
+
+ enum RecorderState
{
StoppedState,
RecordingState,
PausedState
};
-
- enum Status {
- UnavailableStatus,
- UnloadedStatus,
- LoadingStatus,
- LoadedStatus,
- StartingStatus,
- RecordingStatus,
- PausedStatus,
- FinalizingStatus
- };
+ Q_ENUM(RecorderState)
enum Error
{
NoError,
ResourceError,
FormatError,
- OutOfSpaceError
+ OutOfSpaceError,
+ LocationNotWritable
};
+ Q_ENUM(Error)
- explicit QMediaRecorder(QMediaObject *mediaObject, QObject *parent = nullptr);
+ QMediaRecorder(QObject *parent = nullptr);
~QMediaRecorder();
- QMediaObject *mediaObject() const override;
-
bool isAvailable() const;
- QMultimedia::AvailabilityStatus availability() const;
QUrl outputLocation() const;
- bool setOutputLocation(const QUrl &location);
+ void setOutputLocation(const QUrl &location);
+
+ void setOutputDevice(QIODevice *device);
+ QIODevice *outputDevice() const;
QUrl actualLocation() const;
- State state() const;
- Status status() const;
+ RecorderState recorderState() const;
Error error() const;
QString errorString() const;
qint64 duration() const;
- bool isMuted() const;
- qreal volume() const;
+ QMediaFormat mediaFormat() const;
+ void setMediaFormat(const QMediaFormat &format);
- QStringList supportedContainers() const;
- QString containerDescription(const QString &format) const;
+ EncodingMode encodingMode() const;
+ void setEncodingMode(EncodingMode);
- QStringList supportedAudioCodecs() const;
- QString audioCodecDescription(const QString &codecName) const;
+ Quality quality() const;
+ void setQuality(Quality quality);
- QList<int> supportedAudioSampleRates(const QAudioEncoderSettings &settings = QAudioEncoderSettings(),
- bool *continuous = nullptr) const;
+ QSize videoResolution() const;
+ void setVideoResolution(const QSize &);
+ void setVideoResolution(int width, int height) { setVideoResolution(QSize(width, height)); }
- QStringList supportedVideoCodecs() const;
- QString videoCodecDescription(const QString &codecName) const;
+ qreal videoFrameRate() const;
+ void setVideoFrameRate(qreal frameRate);
- QList<QSize> supportedResolutions(const QVideoEncoderSettings &settings = QVideoEncoderSettings(),
- bool *continuous = nullptr) const;
+ int videoBitRate() const;
+ void setVideoBitRate(int bitRate);
- QList<qreal> supportedFrameRates(const QVideoEncoderSettings &settings = QVideoEncoderSettings(),
- bool *continuous = nullptr) const;
+ int audioBitRate() const;
+ void setAudioBitRate(int bitRate);
- QAudioEncoderSettings audioSettings() const;
- QVideoEncoderSettings videoSettings() const;
- QString containerFormat() const;
+ int audioChannelCount() const;
+ void setAudioChannelCount(int channels);
- void setAudioSettings(const QAudioEncoderSettings &audioSettings);
- void setVideoSettings(const QVideoEncoderSettings &videoSettings);
- void setContainerFormat(const QString &container);
+ int audioSampleRate() const;
+ void setAudioSampleRate(int sampleRate);
- void setEncodingSettings(const QAudioEncoderSettings &audioSettings,
- const QVideoEncoderSettings &videoSettings = QVideoEncoderSettings(),
- const QString &containerMimeType = QString());
+ QMediaMetaData metaData() const;
+ void setMetaData(const QMediaMetaData &metaData);
+ void addMetaData(const QMediaMetaData &metaData);
- bool isMetaDataAvailable() const;
- bool isMetaDataWritable() const;
+ bool autoStop() const;
+ void setAutoStop(bool autoStop);
- QVariant metaData(const QString &key) const;
- void setMetaData(const QString &key, const QVariant &value);
- QStringList availableMetaData() const;
+ QMediaCaptureSession *captureSession() const;
+ QPlatformMediaRecorder *platformRecoder() const;
public Q_SLOTS:
void record();
void pause();
void stop();
- void setMuted(bool muted);
- void setVolume(qreal volume);
Q_SIGNALS:
- void stateChanged(QMediaRecorder::State state);
- void statusChanged(QMediaRecorder::Status status);
+ void recorderStateChanged(RecorderState state);
void durationChanged(qint64 duration);
- void mutedChanged(bool muted);
- void volumeChanged(qreal volume);
void actualLocationChanged(const QUrl &location);
+ void encoderSettingsChanged();
- void error(QMediaRecorder::Error error);
+ void errorOccurred(Error error, const QString &errorString);
+ void errorChanged();
- void metaDataAvailableChanged(bool available);
- void metaDataWritableChanged(bool writable);
void metaDataChanged();
- void metaDataChanged(const QString &key, const QVariant &value);
- void availabilityChanged(bool available);
- void availabilityChanged(QMultimedia::AvailabilityStatus availability);
+ void mediaFormatChanged();
+ void encodingModeChanged();
+ void qualityChanged();
+ void videoResolutionChanged();
+ void videoFrameRateChanged();
+ void videoBitRateChanged();
+ void audioBitRateChanged();
+ void audioChannelCountChanged();
+ void audioSampleRateChanged();
+ void autoStopChanged();
-protected:
- QMediaRecorder(QMediaRecorderPrivate &dd, QMediaObject *mediaObject, QObject *parent = nullptr);
- bool setMediaObject(QMediaObject *object) override;
-
- QMediaRecorderPrivate *d_ptr;
private:
+ QMediaRecorderPrivate *d_ptr;
+ friend class QMediaCaptureSession;
+ void setCaptureSession(QMediaCaptureSession *session);
Q_DISABLE_COPY(QMediaRecorder)
Q_DECLARE_PRIVATE(QMediaRecorder)
- Q_PRIVATE_SLOT(d_func(), void _q_stateChanged(QMediaRecorder::State))
- Q_PRIVATE_SLOT(d_func(), void _q_error(int, const QString &))
- Q_PRIVATE_SLOT(d_func(), void _q_serviceDestroyed())
- Q_PRIVATE_SLOT(d_func(), void _q_notify())
- Q_PRIVATE_SLOT(d_func(), void _q_updateActualLocation(const QUrl &))
- Q_PRIVATE_SLOT(d_func(), void _q_updateNotifyInterval(int))
- Q_PRIVATE_SLOT(d_func(), void _q_applySettings())
- Q_PRIVATE_SLOT(d_func(), void _q_availabilityChanged(QMultimedia::AvailabilityStatus))
};
QT_END_NAMESPACE
-Q_DECLARE_METATYPE(QMediaRecorder::State)
-Q_DECLARE_METATYPE(QMediaRecorder::Status)
-Q_DECLARE_METATYPE(QMediaRecorder::Error)
-
-Q_MEDIA_ENUM_DEBUG(QMediaRecorder, State)
-Q_MEDIA_ENUM_DEBUG(QMediaRecorder, Status)
+Q_MEDIA_ENUM_DEBUG(QMediaRecorder, RecorderState)
Q_MEDIA_ENUM_DEBUG(QMediaRecorder, Error)
-#endif // QMEDIARECORDER_H
+#endif // QMediaRecorder_H
diff --git a/src/multimedia/recording/qmediarecorder_p.h b/src/multimedia/recording/qmediarecorder_p.h
index f634d016e..896f6c368 100644
--- a/src/multimedia/recording/qmediarecorder_p.h
+++ b/src/multimedia/recording/qmediarecorder_p.h
@@ -1,44 +1,8 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QMEDIARECORDER_P_H
-#define QMEDIARECORDER_P_H
+// Copyright (C) 2016 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 QMediaRecorder_P_H
+#define QMediaRecorder_P_H
//
// W A R N I N G
@@ -52,60 +16,39 @@
//
#include "qmediarecorder.h"
-#include "qmediaobject_p.h"
+#include "qcamera.h"
#include <QtCore/qurl.h>
+#include <QtCore/qpointer.h>
+#include "private/qplatformmediarecorder_p.h"
QT_BEGIN_NAMESPACE
-class QMediaRecorderControl;
-class QMediaContainerControl;
-class QAudioEncoderSettingsControl;
-class QVideoEncoderSettingsControl;
-class QMetaDataWriterControl;
-class QMediaAvailabilityControl;
+class QPlatformMediaRecorder;
class QTimer;
-class QMediaRecorderPrivate
+class Q_MULTIMEDIA_EXPORT QMediaRecorderPrivate
{
- Q_DECLARE_NON_CONST_PUBLIC(QMediaRecorder)
+ Q_DECLARE_PUBLIC(QMediaRecorder)
public:
QMediaRecorderPrivate();
- virtual ~QMediaRecorderPrivate() {}
-
- void applySettingsLater();
- void restartCamera();
-
- QMediaObject *mediaObject;
- QMediaRecorderControl *control;
- QMediaContainerControl *formatControl;
- QAudioEncoderSettingsControl *audioControl;
- QVideoEncoderSettingsControl *videoControl;
- QMetaDataWriterControl *metaDataControl;
- QMediaAvailabilityControl *availabilityControl;
+ static QString msgFailedStartRecording();
- bool settingsChanged;
+ QMediaCaptureSession *captureSession = nullptr;
+ QPlatformMediaRecorder *control = nullptr;
+ QString initErrorMessage;
+ bool autoStop = false;
- QTimer* notifyTimer;
+ bool settingsChanged = false;
- QMediaRecorder::State state;
- QMediaRecorder::Error error;
- QString errorString;
- QUrl actualLocation;
+ QMediaEncoderSettings encoderSettings;
- void _q_stateChanged(QMediaRecorder::State state);
- void _q_error(int error, const QString &errorString);
- void _q_serviceDestroyed();
- void _q_updateActualLocation(const QUrl &);
- void _q_notify();
- void _q_updateNotifyInterval(int ms);
- void _q_applySettings();
- void _q_availabilityChanged(QMultimedia::AvailabilityStatus availability);
-
- QMediaRecorder *q_ptr;
+ QMediaRecorder *q_ptr = nullptr;
};
+#undef Q_DECLARE_NON_CONST_PUBLIC
+
QT_END_NAMESPACE
#endif
diff --git a/src/multimedia/recording/qscreencapture-limitations.qdocinc b/src/multimedia/recording/qscreencapture-limitations.qdocinc
new file mode 100644
index 000000000..240a1a389
--- /dev/null
+++ b/src/multimedia/recording/qscreencapture-limitations.qdocinc
@@ -0,0 +1,25 @@
+// Copyright (C) 2024 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
+
+/*!
+ //! [content]
+ \section1 Screen Capture Limitations
+ On Qt 6.5.2 and above, the following limitations apply to using \1ScreenCapture:
+ \list
+ \li It is only supported with the FFmpeg backend.
+ \li It is unsupported on Linux with Wayland compositor, due to Wayland
+ protocol restrictions and limitations.
+ \li It is not supported on mobile operating systems, except on Android.
+ There, you might run into performance issues as the class is currently
+ implemented via QScreen::grabWindow, which is not optimal for the use case.
+ \li On embedded with EGLFS, it has limited functionality. For Qt Quick
+ applications, the class is currently implemented via
+ QQuickWindow::grabWindow, which can cause performance issues.
+ \li In most cases, we set a screen capture frame rate that equals the screen
+ refresh rate, except on Windows, where the rate might be flexible.
+ Such a frame rate (75/120 FPS) might cause performance issues on weak
+ CPUs if the captured screen is of 4K resolution. On EGLFS, the capture
+ frame rate is currently locked to 30 FPS.
+ \endlist
+ //! [content]
+*/
diff --git a/src/multimedia/recording/qscreencapture.cpp b/src/multimedia/recording/qscreencapture.cpp
new file mode 100644
index 000000000..c178af1c1
--- /dev/null
+++ b/src/multimedia/recording/qscreencapture.cpp
@@ -0,0 +1,261 @@
+// Copyright (C) 2022 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 "qscreencapture.h"
+#include "qmediacapturesession.h"
+#include <private/qplatformmediaintegration_p.h>
+#include <private/qplatformsurfacecapture_p.h>
+#include <private/qobject_p.h>
+
+QT_BEGIN_NAMESPACE
+
+static QScreenCapture::Error toScreenCaptureError(QPlatformSurfaceCapture::Error error)
+{
+ return static_cast<QScreenCapture::Error>(error);
+}
+
+class QScreenCapturePrivate : public QObjectPrivate
+{
+public:
+ QMediaCaptureSession *captureSession = nullptr;
+ std::unique_ptr<QPlatformSurfaceCapture> platformScreenCapture;
+};
+
+/*!
+ \class QScreenCapture
+ \inmodule QtMultimedia
+ \ingroup multimedia
+ \ingroup multimedia_video
+ \since 6.5
+
+ \brief This class is used for capturing a screen.
+
+ The class captures a screen. It is managed by
+ the QMediaCaptureSession class where the captured screen can be displayed
+ in a video preview object or recorded to a file.
+
+ \snippet multimedia-snippets/media.cpp Media recorder
+
+ \include qscreencapture-limitations.qdocinc {content} {Q}
+
+ \sa QWindowCapture, QMediaCaptureSession
+*/
+/*!
+ \qmltype ScreenCapture
+ \instantiates QScreenCapture
+ \brief This type is used for capturing a screen.
+
+ \inqmlmodule QtMultimedia
+ \ingroup multimedia_qml
+ \ingroup multimedia_video_qml
+
+ ScreenCapture captures a screen. It is managed by
+ MediaCaptureSession where the captured screen can be displayed
+ in a video preview object or recorded to a file.
+
+ \since 6.5
+ The code below shows a simple capture session with ScreenCapture playing
+ back the captured primary screen view in VideoOutput.
+
+\qml
+ CaptureSession {
+ id: captureSession
+ screenCapture: ScreenCapture {
+ id: screenCapture
+ active: true
+ }
+ videoOutput: VideoOutput {
+ id: videoOutput
+ }
+ }
+\endqml
+
+ \include qscreencapture-limitations.qdocinc {content} {}
+
+ \sa WindowCapture, CaptureSession
+*/
+
+QScreenCapture::QScreenCapture(QObject *parent)
+ : QObject(*new QScreenCapturePrivate, parent)
+{
+ Q_D(QScreenCapture);
+
+ auto platformCapture = QPlatformMediaIntegration::instance()->createScreenCapture(this);
+ if (platformCapture) {
+ connect(platformCapture, &QPlatformSurfaceCapture::activeChanged, this,
+ &QScreenCapture::activeChanged);
+ connect(platformCapture, &QPlatformSurfaceCapture::errorChanged, this,
+ &QScreenCapture::errorChanged);
+ connect(platformCapture, &QPlatformSurfaceCapture::errorOccurred, this,
+ [this](QPlatformSurfaceCapture::Error error, QString errorString) {
+ emit errorOccurred(toScreenCaptureError(error), errorString);
+ });
+
+ connect(platformCapture,
+ qOverload<QPlatformSurfaceCapture::ScreenSource>(
+ &QPlatformSurfaceCapture::sourceChanged),
+ this, &QScreenCapture::screenChanged);
+
+ d->platformScreenCapture.reset(platformCapture);
+ }
+}
+
+QScreenCapture::~QScreenCapture()
+{
+ Q_D(QScreenCapture);
+
+ // Reset platformScreenCapture in the destructor to avoid having broken ref in the object.
+ d->platformScreenCapture.reset();
+
+ if (d->captureSession)
+ d->captureSession->setScreenCapture(nullptr);
+}
+
+/*!
+ \enum QScreenCapture::Error
+
+ Enumerates error codes that can be signaled by the QScreenCapture class.
+ errorString() provides detailed information about the error cause.
+
+ \value NoError No error
+ \value InternalError Internal screen capturing driver error
+ \value CapturingNotSupported Capturing is not supported
+ \value CaptureFailed Capturing screen failed
+ \value NotFound Selected screen not found
+*/
+
+/*!
+ Returns the capture session this QScreenCapture is connected to.
+
+ Use QMediaCaptureSession::setScreenCapture() to connect the camera to
+ a session.
+*/
+QMediaCaptureSession *QScreenCapture::captureSession() const
+{
+ Q_D(const QScreenCapture);
+
+ return d->captureSession;
+}
+
+/*!
+ \qmlproperty bool QtMultimedia::ScreenCapture::active
+ Describes whether the capturing is currently active.
+*/
+
+/*!
+ \property QScreenCapture::active
+ \brief whether the capturing is currently active.
+*/
+void QScreenCapture::setActive(bool active)
+{
+ Q_D(QScreenCapture);
+
+ if (d->platformScreenCapture)
+ d->platformScreenCapture->setActive(active);
+}
+
+bool QScreenCapture::isActive() const
+{
+ Q_D(const QScreenCapture);
+
+ return d->platformScreenCapture && d->platformScreenCapture->isActive();
+}
+
+/*!
+ \qmlproperty Screen QtMultimedia::ScreenCapture::screen
+ Describes the screen for capturing.
+*/
+
+/*!
+ \property QScreenCapture::screen
+ \brief the screen for capturing.
+*/
+
+void QScreenCapture::setScreen(QScreen *screen)
+{
+ Q_D(QScreenCapture);
+
+ if (d->platformScreenCapture)
+ d->platformScreenCapture->setSource(QPlatformSurfaceCapture::ScreenSource(screen));
+}
+
+QScreen *QScreenCapture::screen() const
+{
+ Q_D(const QScreenCapture);
+
+ return d->platformScreenCapture
+ ? d->platformScreenCapture->source<QPlatformSurfaceCapture::ScreenSource>()
+ : nullptr;
+}
+
+/*!
+ \qmlproperty enumeration QtMultimedia::ScreenCapture::error
+ Returns a code of the last error.
+*/
+
+/*!
+ \property QScreenCapture::error
+ \brief the code of the last error.
+*/
+QScreenCapture::Error QScreenCapture::error() const
+{
+ Q_D(const QScreenCapture);
+
+ return d->platformScreenCapture ? toScreenCaptureError(d->platformScreenCapture->error())
+ : CapturingNotSupported;
+}
+
+/*!
+ \fn void QScreenCapture::errorOccurred(QScreenCapture::Error error, const QString &errorString)
+
+ Signals when an \a error occurs, along with the \a errorString.
+*/
+/*!
+ \qmlproperty string QtMultimedia::ScreenCapture::errorString
+ Returns a human readable string describing the cause of error.
+*/
+
+/*!
+ \property QScreenCapture::errorString
+ \brief a human readable string describing the cause of error.
+*/
+QString QScreenCapture::errorString() const
+{
+ Q_D(const QScreenCapture);
+
+ return d->platformScreenCapture ? d->platformScreenCapture->errorString()
+ : QLatin1StringView("Capturing is not support on this platform");
+}
+/*!
+ \fn void QScreenCapture::start()
+
+ Starts screen capture.
+*/
+/*!
+ \fn void QScreenCapture::stop()
+
+ Stops screen capture.
+*/
+/*!
+ \internal
+*/
+void QScreenCapture::setCaptureSession(QMediaCaptureSession *captureSession)
+{
+ Q_D(QScreenCapture);
+
+ d->captureSession = captureSession;
+}
+
+/*!
+ \internal
+*/
+class QPlatformSurfaceCapture *QScreenCapture::platformScreenCapture() const
+{
+ Q_D(const QScreenCapture);
+
+ return d->platformScreenCapture.get();
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qscreencapture.cpp"
diff --git a/src/multimedia/recording/qscreencapture.h b/src/multimedia/recording/qscreencapture.h
new file mode 100644
index 000000000..b46925bc0
--- /dev/null
+++ b/src/multimedia/recording/qscreencapture.h
@@ -0,0 +1,72 @@
+// Copyright (C) 2022 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 QSCREENCAPTURE_H
+#define QSCREENCAPTURE_H
+
+#include <QtCore/qobject.h>
+#include <QtCore/qnamespace.h>
+#include <QtGui/qscreen.h>
+#include <QtGui/qwindow.h>
+#include <QtGui/qwindowdefs.h>
+#include <QtMultimedia/qtmultimediaglobal.h>
+
+QT_BEGIN_NAMESPACE
+
+class QMediaCaptureSession;
+class QPlatformSurfaceCapture;
+class QScreenCapturePrivate;
+
+class Q_MULTIMEDIA_EXPORT QScreenCapture : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(bool active READ isActive WRITE setActive NOTIFY activeChanged)
+ Q_PROPERTY(QScreen *screen READ screen WRITE setScreen NOTIFY screenChanged)
+ Q_PROPERTY(Error error READ error NOTIFY errorChanged)
+ Q_PROPERTY(QString errorString READ errorString NOTIFY errorChanged)
+
+public:
+ enum Error {
+ NoError = 0,
+ InternalError = 1,
+ CapturingNotSupported = 2,
+ CaptureFailed = 4,
+ NotFound = 5,
+ };
+ Q_ENUM(Error)
+
+ explicit QScreenCapture(QObject *parent = nullptr);
+ ~QScreenCapture() override;
+
+ QMediaCaptureSession *captureSession() const;
+
+ void setScreen(QScreen *screen);
+ QScreen *screen() const;
+
+ bool isActive() const;
+
+ Error error() const;
+ QString errorString() const;
+
+public Q_SLOTS:
+ void setActive(bool active);
+ void start() { setActive(true); }
+ void stop() { setActive(false); }
+
+Q_SIGNALS:
+ void activeChanged(bool);
+ void errorChanged();
+ void screenChanged(QScreen *);
+ void errorOccurred(QScreenCapture::Error error, const QString &errorString);
+
+private:
+ void setCaptureSession(QMediaCaptureSession *captureSession);
+ QPlatformSurfaceCapture *platformScreenCapture() const;
+ friend class QMediaCaptureSession;
+ Q_DISABLE_COPY(QScreenCapture)
+ Q_DECLARE_PRIVATE(QScreenCapture)
+};
+
+QT_END_NAMESPACE
+
+#endif // QSCREENCAPTURE_H
diff --git a/src/multimedia/recording/qvideoframeinput.cpp b/src/multimedia/recording/qvideoframeinput.cpp
new file mode 100644
index 000000000..99500bb65
--- /dev/null
+++ b/src/multimedia/recording/qvideoframeinput.cpp
@@ -0,0 +1,181 @@
+// 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
+
+#include "qvideoframeinput.h"
+#include "qmediaframeinput_p.h"
+#include "qmediainputencoderinterface_p.h"
+#include "qplatformvideoframeinput_p.h"
+
+QT_BEGIN_NAMESPACE
+
+class QVideoFrameInputPrivate : public QMediaFrameInputPrivate
+{
+public:
+ QVideoFrameInputPrivate(QVideoFrameInput *q) : q(q) { }
+
+ bool sendVideoFrame(const QVideoFrame &frame)
+ {
+ return sendMediaFrame([&]() { emit m_platfromVideoFrameInput->newVideoFrame(frame); });
+ }
+
+ void initialize(QVideoFrameFormat format = {})
+ {
+ m_platfromVideoFrameInput = std::make_unique<QPlatformVideoFrameInput>(std::move(format));
+ addUpdateSignal(m_platfromVideoFrameInput.get(), &QPlatformVideoFrameInput::encoderUpdated);
+ }
+
+ void uninitialize()
+ {
+ m_platfromVideoFrameInput.reset();
+
+ if (captureSession())
+ captureSession()->setVideoFrameInput(nullptr);
+ }
+
+ QPlatformVideoFrameInput *platfromVideoFrameInput() const
+ {
+ return m_platfromVideoFrameInput.get();
+ }
+
+protected:
+ void updateCaptureSessionConnections(QMediaCaptureSession *prevSession,
+ QMediaCaptureSession *newSession) override
+ {
+ if (prevSession)
+ removeUpdateSignal(prevSession, &QMediaCaptureSession::videoOutputChanged);
+
+ if (newSession)
+ addUpdateSignal(newSession, &QMediaCaptureSession::videoOutputChanged);
+ }
+
+ bool checkIfCanSendMediaFrame() const override
+ {
+ if (auto encoderInterface = m_platfromVideoFrameInput->encoderInterface())
+ return encoderInterface->canPushFrame();
+
+ return captureSession()->videoOutput() || captureSession()->videoSink();
+ }
+
+ void emitReadyToSendMediaFrame() override { emit q->readyToSendVideoFrame(); }
+
+private:
+ QVideoFrameInput *q = nullptr;
+ std::unique_ptr<QPlatformVideoFrameInput> m_platfromVideoFrameInput;
+};
+
+/*!
+ \class QVideoFrameInput
+ \inmodule QtMultimedia
+ \ingroup multimedia
+ \ingroup multimedia_video
+ \since 6.8
+
+ \brief The QVideoFrameInput class is used for providing custom video frames
+ to \l QMediaRecorder or a video output through \l QMediaCaptureSession.
+
+ \sa QMediaRecorder, QMediaCaptureSession, QVideoSink
+*/
+
+/*!
+ Constructs a new QVideoFrameInput object with \a parent.
+*/
+QVideoFrameInput::QVideoFrameInput(QObject *parent) : QVideoFrameInput({}, parent) { }
+
+/*!
+ Constructs a new QVideoFrameInput object with video frame \a format and \a parent.
+
+ The specified \a format will work as a hint for the initialization of the matching
+ video encoder upon invoking \l QMediaRecorder::record().
+ If the format is not specified or not valid, the video encoder will be initialized
+ upon sending the first frame.
+ Sending of video frames with another pixel format and size after initialization
+ of the matching video encoder might cause a performance penalty during recording.
+
+ We recommend specifying the format if you know in advance what kind of frames you're
+ going to send.
+*/
+QVideoFrameInput::QVideoFrameInput(const QVideoFrameFormat &format, QObject *parent)
+ : QObject(*new QVideoFrameInputPrivate(this), parent)
+{
+ Q_D(QVideoFrameInput);
+ d->initialize(format);
+}
+
+/*!
+ Destroys the object.
+ */
+QVideoFrameInput::~QVideoFrameInput()
+{
+ Q_D(QVideoFrameInput);
+ d->uninitialize();
+}
+
+/*!
+ Sends \l QVideoFrame to \l QMediaRecorder or a video output
+ through \l QMediaCaptureSession.
+
+ Returns \c true if the specified \a frame has been sent successfully
+ to the destination. Returns \c false, if the frame hasn't been sent,
+ which can happen if the instance is not assigned to
+ \l QMediaCaptureSession, the session doesn't have video outputs or
+ a media recorder, the media recorder is not started or its queue is full.
+ The signal \l readyToSendVideoFrame will be sent as soon as
+ the destination is able to handle a new frame.
+
+ Sending of an empty video frame is treated by \l QMediaRecorder
+ as an end of the input stream. QMediaRecorder stops the recording
+ automatically if \l QMediaRecorder::autoStop is \c true and
+ all the inputs have reported the end of the stream.
+*/
+bool QVideoFrameInput::sendVideoFrame(const QVideoFrame &frame)
+{
+ Q_D(QVideoFrameInput);
+ return d->sendVideoFrame(frame);
+}
+
+/*!
+ Returns the video frame format that was specified
+ upon construction of the video frame input.
+*/
+QVideoFrameFormat QVideoFrameInput::format() const
+{
+ Q_D(const QVideoFrameInput);
+ return d->platfromVideoFrameInput()->frameFormat();
+}
+
+/*!
+ Returns the capture session this video frame input is connected to, or
+ a \c nullptr if the video frame input is not connected to a capture session.
+
+ Use QMediaCaptureSession::setVideoFrameInput() to connect
+ the video frame input to a session.
+*/
+QMediaCaptureSession *QVideoFrameInput::captureSession() const
+{
+ Q_D(const QVideoFrameInput);
+ return d->captureSession();
+}
+
+void QVideoFrameInput::setCaptureSession(QMediaCaptureSession *captureSession)
+{
+ Q_D(QVideoFrameInput);
+ d->setCaptureSession(captureSession);
+}
+
+QPlatformVideoFrameInput *QVideoFrameInput::platformVideoFrameInput() const
+{
+ Q_D(const QVideoFrameInput);
+ return d->platfromVideoFrameInput();
+}
+
+/*!
+ \fn void QVideoFrameInput::readyToSendVideoFrame()
+
+ Signals that a new frame can be sent to the video frame input.
+ After receiving the signal, if you have frames to be sent, invoke \l sendVideoFrame
+ once or in a loop until it returns \c false.
+
+ \sa sendVideoFrame()
+*/
+
+QT_END_NAMESPACE
diff --git a/src/multimedia/recording/qvideoframeinput.h b/src/multimedia/recording/qvideoframeinput.h
new file mode 100644
index 000000000..fbe56b7db
--- /dev/null
+++ b/src/multimedia/recording/qvideoframeinput.h
@@ -0,0 +1,48 @@
+// 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 QVIDEOFRAMEINPUT_H
+#define QVIDEOFRAMEINPUT_H
+
+#include <QtMultimedia/qtmultimediaexports.h>
+#include <QtMultimedia/qvideoframe.h>
+#include <QtCore/qobject.h>
+
+QT_BEGIN_NAMESPACE
+
+class QPlatformVideoFrameInput;
+class QVideoFrameInputPrivate;
+class QMediaCaptureSession;
+
+class Q_MULTIMEDIA_EXPORT QVideoFrameInput : public QObject
+{
+ Q_OBJECT
+public:
+ explicit QVideoFrameInput(QObject *parent = nullptr);
+
+ explicit QVideoFrameInput(const QVideoFrameFormat &format, QObject *parent = nullptr);
+
+ ~QVideoFrameInput() override;
+
+ bool sendVideoFrame(const QVideoFrame &frame);
+
+ QVideoFrameFormat format() const;
+
+ QMediaCaptureSession *captureSession() const;
+
+Q_SIGNALS:
+ void readyToSendVideoFrame();
+
+private:
+ void setCaptureSession(QMediaCaptureSession *captureSession);
+
+ QPlatformVideoFrameInput *platformVideoFrameInput() const;
+
+ friend class QMediaCaptureSession;
+ Q_DISABLE_COPY(QVideoFrameInput)
+ Q_DECLARE_PRIVATE(QVideoFrameInput)
+};
+
+QT_END_NAMESPACE
+
+#endif // QVIDEOFRAMEINPUT_H
diff --git a/src/multimedia/recording/qwindowcapture.cpp b/src/multimedia/recording/qwindowcapture.cpp
new file mode 100644
index 000000000..69ad60100
--- /dev/null
+++ b/src/multimedia/recording/qwindowcapture.cpp
@@ -0,0 +1,268 @@
+// Copyright (C) 2023 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 "qwindowcapture.h"
+#include "qplatformmediaintegration_p.h"
+#include "qmediacapturesession.h"
+#include "private/qobject_p.h"
+#include "private/qplatformsurfacecapture_p.h"
+
+QT_BEGIN_NAMESPACE
+
+static QWindowCapture::Error toWindowCaptureError(QPlatformSurfaceCapture::Error error)
+{
+ return static_cast<QWindowCapture::Error>(error);
+}
+
+class QWindowCapturePrivate : public QObjectPrivate
+{
+public:
+ QMediaCaptureSession *captureSession = nullptr;
+ std::unique_ptr<QPlatformSurfaceCapture> platformWindowCapture;
+};
+
+/*!
+ \class QWindowCapture
+ \inmodule QtMultimedia
+ \ingroup multimedia
+ \ingroup multimedia_video
+ \since 6.6
+
+ \brief This class is used for capturing a window.
+
+ The class captures a window. It is managed by
+ the QMediaCaptureSession class where the captured window can be displayed
+ in a video preview object or recorded to a file.
+
+ \sa QMediaCaptureSession, QCapturableWindow
+*/
+/*!
+ \qmltype WindowCapture
+ \instantiates QWindowCapture
+ \inqmlmodule QtMultimedia
+ \ingroup multimedia_qml
+ \ingroup multimedia_video_qml
+ \since 6.6
+
+ \brief This type is used for capturing a window.
+
+ WindowCapture captures a window. It is managed by
+ MediaCaptureSession where the captured window can be displayed
+ in a video preview object or recorded to a file.
+
+ \sa CaptureSession, CapturableWindow
+*/
+
+/*!
+ \enum QWindowCapture::Error
+
+ Enumerates error codes that can be signaled by the QWindowCapture class.
+ errorString() provides detailed information about the error cause.
+
+ \value NoError No error
+ \value InternalError Internal window capturing driver error
+ \value CapturingNotSupported Window capturing is not supported
+ \value CaptureFailed Capturing window failed
+ \value NotFound Selected window not found
+*/
+
+/*!
+ Constructs a new QWindowCapture object with \a parent.
+*/
+QWindowCapture::QWindowCapture(QObject *parent) : QObject(*new QWindowCapturePrivate, parent)
+{
+ Q_D(QWindowCapture);
+
+ qRegisterMetaType<QCapturableWindow>();
+
+ auto platformCapture = QPlatformMediaIntegration::instance()->createWindowCapture(this);
+
+ if (platformCapture) {
+ connect(platformCapture, &QPlatformSurfaceCapture::activeChanged, this,
+ &QWindowCapture::activeChanged);
+ connect(platformCapture, &QPlatformSurfaceCapture::errorChanged, this,
+ &QWindowCapture::errorChanged);
+ connect(platformCapture, &QPlatformSurfaceCapture::errorOccurred, this,
+ [this](QPlatformSurfaceCapture::Error error, QString errorString) {
+ emit errorOccurred(toWindowCaptureError(error), errorString);
+ });
+ connect(platformCapture,
+ qOverload<QCapturableWindow>(&QPlatformSurfaceCapture::sourceChanged), this,
+ &QWindowCapture::windowChanged);
+
+ d->platformWindowCapture.reset(platformCapture);
+ }
+}
+
+/*!
+ Destroys the object.
+ */
+QWindowCapture::~QWindowCapture()
+{
+ Q_D(QWindowCapture);
+
+ d->platformWindowCapture.reset();
+
+ if (d->captureSession)
+ d->captureSession->setWindowCapture(nullptr);
+}
+
+/*!
+ \qmlmethod list<CapturableWindow> QtMultimedia::WindowCapture::capturableWindows()
+
+ Returns a list of CapturableWindow objects that is available for capturing.
+*/
+/*!
+ \fn QList<QCapturableWindow> QWindowCapture::capturableWindows()
+
+ Returns a list of QCapturableWindow objects that is available for capturing.
+ */
+QList<QCapturableWindow> QWindowCapture::capturableWindows()
+{
+ return QPlatformMediaIntegration::instance()->capturableWindowsList();
+}
+
+QMediaCaptureSession *QWindowCapture::captureSession() const
+{
+ Q_D(const QWindowCapture);
+
+ return d->captureSession;
+}
+
+/*!
+ \qmlproperty Window QtMultimedia::WindowCapture::window
+ Describes the window for capturing.
+
+ \sa QtMultimedia::WindowCapture::capturableWindows
+*/
+
+/*!
+ \property QWindowCapture::window
+ \brief the window for capturing.
+
+ \sa QWindowCapture::capturableWindows
+*/
+QCapturableWindow QWindowCapture::window() const
+{
+ Q_D(const QWindowCapture);
+
+ return d->platformWindowCapture ? d->platformWindowCapture->source<QCapturableWindow>()
+ : QCapturableWindow();
+}
+
+void QWindowCapture::setWindow(QCapturableWindow window)
+{
+ Q_D(QWindowCapture);
+
+ if (d->platformWindowCapture)
+ d->platformWindowCapture->setSource(window);
+}
+
+/*!
+ \qmlproperty bool QtMultimedia::WindowCapture::active
+ Describes whether the capturing is currently active.
+*/
+
+/*!
+ \property QWindowCapture::active
+ \brief whether the capturing is currently active.
+
+ \sa start(), stop()
+*/
+bool QWindowCapture::isActive() const
+{
+ Q_D(const QWindowCapture);
+
+ return d->platformWindowCapture && d->platformWindowCapture->isActive();
+}
+
+void QWindowCapture::setActive(bool active)
+{
+ Q_D(QWindowCapture);
+
+ if (d->platformWindowCapture)
+ d->platformWindowCapture->setActive(active);
+}
+
+/*!
+ \qmlmethod QtMultimedia::WindowCapture::start
+*/
+
+/*!
+ \fn void QWindowCapture::start()
+
+ Starts capturing the \l window.
+
+ This is equivalent to setting the \l active property to true.
+*/
+
+/*!
+ \qmlmethod QtMultimedia::WindowCapture::stop
+*/
+
+/*!
+ \fn void QWindowCapture::stop()
+
+ Stops capturing.
+
+ This is equivalent to setting the \l active property to false.
+*/
+
+
+/*!
+ \qmlproperty enumeration QtMultimedia::WindowCapture::error
+ Returns a code of the last error.
+*/
+
+/*!
+ \property QWindowCapture::error
+ \brief the code of the last error.
+*/
+QWindowCapture::Error QWindowCapture::error() const
+{
+ Q_D(const QWindowCapture);
+
+ return d->platformWindowCapture ? toWindowCaptureError(d->platformWindowCapture->error())
+ : CapturingNotSupported;
+}
+
+/*!
+ \fn void QWindowCapture::errorOccurred(QWindowCapture::Error error, const QString &errorString)
+
+ Signals when an \a error occurs, along with the \a errorString.
+*/
+/*!
+ \qmlproperty string QtMultimedia::WindowCapture::errorString
+ Returns a human readable string describing the cause of error.
+*/
+
+/*!
+ \property QWindowCapture::errorString
+ \brief a human readable string describing the cause of error.
+*/
+QString QWindowCapture::errorString() const
+{
+ Q_D(const QWindowCapture);
+
+ return d->platformWindowCapture
+ ? d->platformWindowCapture->errorString()
+ : QLatin1StringView("Capturing is not support on this platform");
+}
+
+void QWindowCapture::setCaptureSession(QMediaCaptureSession *captureSession)
+{
+ Q_D(QWindowCapture);
+
+ d->captureSession = captureSession;
+}
+
+QPlatformSurfaceCapture *QWindowCapture::platformWindowCapture() const
+{
+ Q_D(const QWindowCapture);
+
+ return d->platformWindowCapture.get();
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qwindowcapture.cpp"
diff --git a/src/multimedia/recording/qwindowcapture.h b/src/multimedia/recording/qwindowcapture.h
new file mode 100644
index 000000000..4c8b2eac3
--- /dev/null
+++ b/src/multimedia/recording/qwindowcapture.h
@@ -0,0 +1,71 @@
+// Copyright (C) 2023 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 QWINDOWCAPTURE_H
+#define QWINDOWCAPTURE_H
+
+#include <QtMultimedia/qtmultimediaexports.h>
+#include <QtMultimedia/qcapturablewindow.h>
+#include <QtCore/qobject.h>
+#include <QtCore/qlist.h>
+
+QT_BEGIN_NAMESPACE
+
+class QPlatformSurfaceCapture;
+
+class Q_MULTIMEDIA_EXPORT QWindowCapture : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(bool active READ isActive WRITE setActive NOTIFY activeChanged)
+ Q_PROPERTY(QCapturableWindow window READ window WRITE setWindow NOTIFY windowChanged)
+ Q_PROPERTY(Error error READ error NOTIFY errorChanged)
+ Q_PROPERTY(QString errorString READ errorString NOTIFY errorChanged)
+public:
+ enum Error {
+ NoError = 0,
+ InternalError = 1,
+ CapturingNotSupported = 2,
+ CaptureFailed = 4,
+ NotFound = 5,
+ };
+ Q_ENUM(Error)
+
+ explicit QWindowCapture(QObject *parent = nullptr);
+ ~QWindowCapture() override;
+
+ Q_INVOKABLE static QList<QCapturableWindow> capturableWindows();
+
+ QMediaCaptureSession *captureSession() const;
+
+ void setWindow(QCapturableWindow window);
+
+ QCapturableWindow window() const;
+
+ bool isActive() const;
+
+ Error error() const;
+ QString errorString() const;
+
+public Q_SLOTS:
+ void setActive(bool active);
+ void start() { setActive(true); }
+ void stop() { setActive(false); }
+
+Q_SIGNALS:
+ void activeChanged(bool);
+ void windowChanged(QCapturableWindow window);
+ void errorChanged();
+ void errorOccurred(QWindowCapture::Error error, const QString &errorString);
+
+private:
+ void setCaptureSession(QMediaCaptureSession *captureSession);
+ QPlatformSurfaceCapture *platformWindowCapture() const;
+
+ friend class QMediaCaptureSession;
+ Q_DISABLE_COPY(QWindowCapture)
+ Q_DECLARE_PRIVATE(QWindowCapture)
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWCAPTURE_H
diff --git a/src/multimedia/recording/recording.pri b/src/multimedia/recording/recording.pri
deleted file mode 100644
index 20ed99e04..000000000
--- a/src/multimedia/recording/recording.pri
+++ /dev/null
@@ -1,14 +0,0 @@
-INCLUDEPATH += recording
-
-PUBLIC_HEADERS += \
- recording/qaudiorecorder.h \
- recording/qmediaencodersettings.h \
- recording/qmediarecorder.h \
-
-PRIVATE_HEADERS += \
- recording/qmediarecorder_p.h \
-
-SOURCES += \
- recording/qaudiorecorder.cpp \
- recording/qmediaencodersettings.cpp \
- recording/qmediarecorder.cpp