summaryrefslogtreecommitdiffstats
path: root/src/multimedia/recording/qmediacapturesession.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/multimedia/recording/qmediacapturesession.cpp')
-rw-r--r--src/multimedia/recording/qmediacapturesession.cpp359
1 files changed, 251 insertions, 108 deletions
diff --git a/src/multimedia/recording/qmediacapturesession.cpp b/src/multimedia/recording/qmediacapturesession.cpp
index 10324313e..f175cd98e 100644
--- a/src/multimedia/recording/qmediacapturesession.cpp
+++ b/src/multimedia/recording/qmediacapturesession.cpp
@@ -1,50 +1,15 @@
-/****************************************************************************
-**
-** 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$
-**
-****************************************************************************/
+// 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 <qpointer.h>
+#include "qscreencapture.h"
+#include "qwindowcapture.h"
#include "qplatformmediaintegration_p.h"
#include "qplatformmediacapture_p.h"
@@ -53,33 +18,19 @@
QT_BEGIN_NAMESPACE
-class QMediaCaptureSessionPrivate
+void QMediaCaptureSessionPrivate::setVideoSink(QVideoSink *sink)
{
-public:
- QMediaCaptureSession *q = nullptr;
- QPlatformMediaCaptureSession *captureSession;
- QAudioInput *audioInput = nullptr;
- QAudioOutput *audioOutput = nullptr;
- QCamera *camera = nullptr;
- QImageCapture *imageCapture = nullptr;
- QMediaRecorder *recorder = nullptr;
- QVideoSink *videoSink = nullptr;
- QPointer<QObject> videoOutput;
-
- void setVideoSink(QVideoSink *sink)
- {
- if (sink == videoSink)
- return;
- if (videoSink)
- videoSink->setSource(nullptr);
- videoSink = sink;
- if (sink)
- sink->setSource(q);
+ if (sink == videoSink)
+ return;
+ if (videoSink)
+ videoSink->setSource(nullptr);
+ videoSink = sink;
+ if (sink)
+ sink->setSource(q);
+ if (captureSession)
captureSession->setVideoPreview(sink);
- emit q->videoOutputChanged();
- }
-
-};
+ emit q->videoOutputChanged();
+}
/*!
\class QMediaCaptureSession
@@ -87,17 +38,21 @@ public:
\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 camera and a microphone to QMediaCaptureSession using setCamera() and setAudioInput().
- A preview of the captured media can be seen by setting a QVideoSink of QVideoWidget using setVideoOutput()
- and heard by routing the audio to an output device using setAudioOutput().
+ You can connect a video input to QMediaCaptureSession using setCamera(), setScreenCapture() or setWindowCapture().
+ 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().
+ 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, QMediaRecorder
+ \sa QCamera, QAudioDevice, QMediaRecorder, QImageCapture, QScreenCapture, QWindowCapture, QMediaRecorder, QGraphicsVideoItem
*/
/*!
@@ -116,6 +71,12 @@ public:
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.
@@ -144,7 +105,7 @@ public:
}
\endqml
- \sa Camera, MediaDevice, MediaRecorder, ImageCapture, AudioInput, VideoOutput
+ \sa Camera, MediaDevices, MediaRecorder, ImageCapture, ScreenCapture, WindowCapture, AudioInput, VideoOutput
*/
/*!
@@ -155,8 +116,13 @@ QMediaCaptureSession::QMediaCaptureSession(QObject *parent)
d_ptr(new QMediaCaptureSessionPrivate)
{
d_ptr->q = this;
- d_ptr->captureSession = QPlatformMediaIntegration::instance()->createCaptureSession();
- Q_ASSERT(d_ptr->captureSession);
+ auto maybeCaptureSession = QPlatformMediaIntegration::instance()->createCaptureSession();
+ if (maybeCaptureSession) {
+ d_ptr->captureSession = maybeCaptureSession.value();
+ d_ptr->captureSession->setCaptureSession(this);
+ } else {
+ qWarning() << "Failed to initialize QMediaCaptureSession" << maybeCaptureSession.error();
+ }
}
/*!
@@ -164,12 +130,13 @@ QMediaCaptureSession::QMediaCaptureSession(QObject *parent)
*/
QMediaCaptureSession::~QMediaCaptureSession()
{
- if (d_ptr->camera)
- d_ptr->camera->setCaptureSession(nullptr);
- if (d_ptr->recorder)
- d_ptr->recorder->setCaptureSession(nullptr);
- if (d_ptr->imageCapture)
- d_ptr->imageCapture->setCaptureSession(nullptr);
+ setCamera(nullptr);
+ setRecorder(nullptr);
+ setImageCapture(nullptr);
+ setScreenCapture(nullptr);
+ setWindowCapture(nullptr);
+ setAudioInput(nullptr);
+ setAudioOutput(nullptr);
d_ptr->setVideoSink(nullptr);
delete d_ptr->captureSession;
delete d_ptr;
@@ -177,11 +144,12 @@ QMediaCaptureSession::~QMediaCaptureSession()
/*!
\qmlproperty AudioInput QtMultimedia::CaptureSession::audioInput
- This property holds the audio input that is being used to capture audio..
- \sa setAudioInput()
+ 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
@@ -190,16 +158,30 @@ QAudioInput *QMediaCaptureSession::audioInput() const
}
/*!
- Sets the audio input device to \a device. If setting it to an empty
+ 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 *device)
+void QMediaCaptureSession::setAudioInput(QAudioInput *input)
{
- if (d_ptr->audioInput == device)
+ QAudioInput *oldInput = d_ptr->audioInput;
+ if (oldInput == input)
return;
- d_ptr->audioInput = device;
- d_ptr->captureSession->setAudioInput(device ? device->handle() : nullptr);
+
+ // To avoid double emit of audioInputChanged
+ // from recursive setAudioInput(nullptr) call.
+ d_ptr->audioInput = nullptr;
+
+ if (d_ptr->captureSession)
+ d_ptr->captureSession->setAudioInput(nullptr);
+ if (oldInput)
+ oldInput->setDisconnectFunction({});
+ if (input) {
+ input->setDisconnectFunction([this](){ setAudioInput(nullptr); });
+ if (d_ptr->captureSession)
+ d_ptr->captureSession->setAudioInput(input->handle());
+ }
+ d_ptr->audioInput = input;
emit audioInputChanged();
}
@@ -218,7 +200,7 @@ void QMediaCaptureSession::setAudioInput(QAudioInput *device)
\brief The camera used to capture video.
Record video or take images by adding a camera to the capture session
- using this property,
+ using this property.
*/
QCamera *QMediaCaptureSession::camera() const
{
@@ -227,16 +209,123 @@ QCamera *QMediaCaptureSession::camera() const
void QMediaCaptureSession::setCamera(QCamera *camera)
{
- if (d_ptr->camera == camera)
+ // TODO: come up with an unification of the captures setup
+ QCamera *oldCamera = d_ptr->camera;
+ if (oldCamera == camera)
return;
- if (d_ptr->camera)
- d_ptr->camera->setCaptureSession(nullptr);
-
d_ptr->camera = camera;
- if (d_ptr->camera)
- d_ptr->camera->setCaptureSession(this);
+ if (d_ptr->captureSession)
+ d_ptr->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_ptr->captureSession)
+ d_ptr->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()
+{
+ return d_ptr ? d_ptr->screenCapture : nullptr;
+}
+
+void QMediaCaptureSession::setScreenCapture(QScreenCapture *screenCapture)
+{
+ // TODO: come up with an unification of the captures setup
+ QScreenCapture *oldScreenCapture = d_ptr->screenCapture;
+ if (oldScreenCapture == screenCapture)
+ return;
+ d_ptr->screenCapture = screenCapture;
+ if (d_ptr->captureSession)
+ d_ptr->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_ptr->captureSession)
+ d_ptr->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() {
+ return d_ptr ? d_ptr->windowCapture : nullptr;
+}
+
+void QMediaCaptureSession::setWindowCapture(QWindowCapture *windowCapture)
+{
+ // TODO: come up with an unification of the captures setup
+ QWindowCapture *oldCapture = d_ptr->windowCapture;
+ if (oldCapture == windowCapture)
+ return;
+ d_ptr->windowCapture = windowCapture;
+ if (d_ptr->captureSession)
+ d_ptr->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_ptr->captureSession)
+ d_ptr->captureSession->setWindowCapture(windowCapture->platformWindowCapture());
+ windowCapture->setCaptureSession(this);
+ }
+ emit windowCaptureChanged();
+}
+
/*!
\qmlproperty ImageCapture QtMultimedia::CaptureSession::imageCapture
@@ -260,14 +349,25 @@ QImageCapture *QMediaCaptureSession::imageCapture()
void QMediaCaptureSession::setImageCapture(QImageCapture *imageCapture)
{
- if (d_ptr->imageCapture == imageCapture)
+ // TODO: come up with an unification of the captures setup
+ QImageCapture *oldImageCapture = d_ptr->imageCapture;
+ if (oldImageCapture == imageCapture)
return;
- if (d_ptr->imageCapture)
- d_ptr->imageCapture->setCaptureSession(nullptr);
-
d_ptr->imageCapture = imageCapture;
- if (d_ptr->imageCapture)
- d_ptr->imageCapture->setCaptureSession(this);
+ if (d_ptr->captureSession)
+ d_ptr->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_ptr->captureSession)
+ d_ptr->captureSession->setImageCapture(imageCapture->platformImageCapture());
+ imageCapture->setCaptureSession(this);
+ }
emit imageCaptureChanged();
}
/*!
@@ -294,14 +394,24 @@ QMediaRecorder *QMediaCaptureSession::recorder()
void QMediaCaptureSession::setRecorder(QMediaRecorder *recorder)
{
- if (d_ptr->recorder == recorder)
+ QMediaRecorder *oldRecorder = d_ptr->recorder;
+ if (oldRecorder == recorder)
return;
- if (d_ptr->recorder)
- d_ptr->recorder->setCaptureSession(nullptr);
-
d_ptr->recorder = recorder;
- if (d_ptr->recorder)
- d_ptr->recorder->setCaptureSession(this);
+ if (d_ptr->captureSession)
+ d_ptr->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_ptr->captureSession)
+ d_ptr->captureSession->setMediaRecorder(recorder->platformRecoder());
+ recorder->setCaptureSession(this);
+ }
emit recorderChanged();
}
/*!
@@ -315,6 +425,11 @@ void QMediaCaptureSession::setRecorder(QMediaRecorder *recorder)
The previously set preview is detached.
*/
+/*!
+ \property QMediaCaptureSession::videoOutput
+
+ Returns the video output for the session.
+*/
QObject *QMediaCaptureSession::videoOutput() const
{
Q_D(const QMediaCaptureSession);
@@ -356,6 +471,10 @@ void QMediaCaptureSession::setVideoSink(QVideoSink *sink)
d->videoOutput = nullptr;
d->setVideoSink(sink);
}
+
+/*!
+ Returns the QVideoSink for the session.
+*/
QVideoSink *QMediaCaptureSession::videoSink() const
{
Q_D(const QMediaCaptureSession);
@@ -363,19 +482,43 @@ QVideoSink *QMediaCaptureSession::videoSink() const
}
/*!
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);
- if (d->audioOutput == output)
+ QAudioOutput *oldOutput = d_ptr->audioOutput;
+ if (oldOutput == output)
return;
- d->audioOutput = output;
- d->captureSession->setAudioOutput(output ? output->handle() : nullptr);
+
+ // We don't want to end up with signal emitted
+ // twice (from recursive call setAudioInput(nullptr)
+ // from oldOutput->setDisconnectFunction():
+ d_ptr->audioOutput = nullptr;
+
+ if (d_ptr->captureSession)
+ d_ptr->captureSession->setAudioOutput(nullptr);
+ if (oldOutput)
+ oldOutput->setDisconnectFunction({});
+ if (output) {
+ output->setDisconnectFunction([this](){ setAudioOutput(nullptr); });
+ if (d_ptr->captureSession)
+ d_ptr->captureSession->setAudioOutput(output->handle());
+ }
+ d_ptr->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
{