summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorArtem Dyomin <artem.dyomin@qt.io>2023-05-12 17:49:13 +0200
committerArtem Dyomin <artem.dyomin@qt.io>2023-06-02 13:12:21 +0200
commit24c854fff9af00461b0920074b23d156e345a804 (patch)
tree6f71d2c9a8e1b76d12eaa2e25e7da839bad02d5c /src
parentdda06373eba84999a89e539035860fc45f2fa5f5 (diff)
Add QWindowCapure and QCapturableWindow for window capturing
The design of QMediaCaptureSession already uses different types and setters/gettes for each video source, like QCamera, QImageCapture, and QScreenCapture, so a new source type, QWindowCapure, has been added instead of extending QScreenCapture. For now we only cover the case of capturing windows enumerated though the capturing API itself, via a list of QCapturableWindow instances, as this is considered the primary use-case for such an API. An extension to this would be to add a QWindow overload to either QCapturableWindow's constructor or QWindowCapture::setWindow, to allow capturing of windows in the application itself, either created by Qt, or via QWindow::fromWinId(), but this has been left out for the initial API to keep things minimal. A WId overload has been intentionally left out of this API, as the path for capturing by WId should go via QWindow::fromWinId(). Finally, capture of windows from other applications without enumerating them via QWindowCapure is left out, as adding such an API would require us to build a more generic WId replacement that isn't tied to a single type for each OS, like WId is (it's a NSView* on macOS e.g., but windows can also be represented by CGWindowID). Task-number: QTBUG-103226 Change-Id: I99e3b8bde62250aba35abcedbc8680a299a3cbb2 Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/multimedia/CMakeLists.txt2
-rw-r--r--src/multimedia/platform/qplatformmediaintegration_p.h6
-rw-r--r--src/multimedia/platform/qplatformscreencapture.cpp4
-rw-r--r--src/multimedia/platform/qplatformscreencapture_p.h2
-rw-r--r--src/multimedia/recording/qcapturablewindow.cpp149
-rw-r--r--src/multimedia/recording/qcapturablewindow.h62
-rw-r--r--src/multimedia/recording/qcapturablewindow_p.h33
-rw-r--r--src/multimedia/recording/qmediacapturesession.cpp58
-rw-r--r--src/multimedia/recording/qmediacapturesession.h7
-rw-r--r--src/multimedia/recording/qscreencapture.cpp88
-rw-r--r--src/multimedia/recording/qscreencapture.h12
-rw-r--r--src/multimedia/recording/qwindowcapture.cpp161
-rw-r--r--src/multimedia/recording/qwindowcapture.h68
-rw-r--r--src/multimediaquick/qtmultimediaquicktypes_p.h21
-rw-r--r--src/plugins/multimedia/ffmpeg/qavfscreencapture.mm2
-rw-r--r--src/plugins/multimedia/ffmpeg/qffmpegscreencapturebase.cpp22
-rw-r--r--src/plugins/multimedia/ffmpeg/qffmpegscreencapturebase_p.h10
17 files changed, 571 insertions, 136 deletions
diff --git a/src/multimedia/CMakeLists.txt b/src/multimedia/CMakeLists.txt
index 1cdbd5927..cd70634f2 100644
--- a/src/multimedia/CMakeLists.txt
+++ b/src/multimedia/CMakeLists.txt
@@ -63,6 +63,8 @@ qt_internal_add_module(Multimedia
recording/qmediacapturesession.cpp recording/qmediacapturesession.h
recording/qmediarecorder.cpp recording/qmediarecorder.h recording/qmediarecorder_p.h
recording/qscreencapture.cpp recording/qscreencapture.h
+ recording/qwindowcapture.cpp recording/qwindowcapture.h
+ recording/qcapturablewindow.cpp recording/qcapturablewindow.h recording/qcapturablewindow_p.h
video/qabstractvideobuffer.cpp video/qabstractvideobuffer_p.h
video/qmemoryvideobuffer.cpp video/qmemoryvideobuffer_p.h
video/qvideoframe.cpp video/qvideoframe.h
diff --git a/src/multimedia/platform/qplatformmediaintegration_p.h b/src/multimedia/platform/qplatformmediaintegration_p.h
index 27f00cdc0..6f60208de 100644
--- a/src/multimedia/platform/qplatformmediaintegration_p.h
+++ b/src/multimedia/platform/qplatformmediaintegration_p.h
@@ -16,6 +16,7 @@
#include <private/qtmultimediaglobal_p.h>
#include <private/qmultimediautils_p.h>
+#include <qcapturablewindow.h>
#include <qmediarecorder.h>
#include <qstring.h>
@@ -47,6 +48,7 @@ class QAudioOutput;
class QPlatformAudioInput;
class QPlatformAudioOutput;
class QPlatformVideoDevices;
+class QCapturableWindow;
class Q_MULTIMEDIA_EXPORT QPlatformMediaIntegration
{
@@ -76,6 +78,10 @@ public:
virtual QMaybe<QPlatformVideoSink *> createVideoSink(QVideoSink *) { return notAvailable; }
+ virtual QList<QCapturableWindow> capturableWindows() { return {}; };
+
+ bool isCapturableWindowValid(const QCapturableWindowPrivate &) { return false; }
+
protected:
std::unique_ptr<QPlatformVideoDevices> m_videoDevices;
};
diff --git a/src/multimedia/platform/qplatformscreencapture.cpp b/src/multimedia/platform/qplatformscreencapture.cpp
index de7f74d9d..afb1a6c78 100644
--- a/src/multimedia/platform/qplatformscreencapture.cpp
+++ b/src/multimedia/platform/qplatformscreencapture.cpp
@@ -16,7 +16,7 @@ QPlatformScreenCapture::QPlatformScreenCapture(QScreenCapture *screenCapture)
void QPlatformScreenCapture::setWindow(QWindow *w)
{
if (w) {
- emit m_screenCapture->errorOccurred(QScreenCapture::WindowCapturingNotSupported,
+ emit m_screenCapture->errorOccurred(QScreenCapture::InternalError,
QLatin1String("Window capture is not supported"));
}
}
@@ -29,7 +29,7 @@ QWindow *QPlatformScreenCapture::window() const
void QPlatformScreenCapture::setWindowId(WId id)
{
if (id) {
- emit m_screenCapture->errorOccurred(QScreenCapture::WindowCapturingNotSupported,
+ emit m_screenCapture->errorOccurred(QScreenCapture::InternalError,
QLatin1String("Window capture is not supported"));
}
}
diff --git a/src/multimedia/platform/qplatformscreencapture_p.h b/src/multimedia/platform/qplatformscreencapture_p.h
index b5a865e22..a162fc7e6 100644
--- a/src/multimedia/platform/qplatformscreencapture_p.h
+++ b/src/multimedia/platform/qplatformscreencapture_p.h
@@ -32,9 +32,11 @@ public:
virtual void setScreen(QScreen *s) = 0;
virtual QScreen *screen() const = 0;
+ // TODO: move the methods and implementations to QPlatformWindowCapture
virtual void setWindow(QWindow *w);
virtual QWindow *window() const;
+ // to be removed
virtual void setWindowId(WId id);
virtual WId windowId() const;
diff --git a/src/multimedia/recording/qcapturablewindow.cpp b/src/multimedia/recording/qcapturablewindow.cpp
new file mode 100644
index 000000000..0be0208ff
--- /dev/null
+++ b/src/multimedia/recording/qcapturablewindow.cpp
@@ -0,0 +1,149 @@
+// 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
+
+ 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;
+
+/*!
+ Returns \c true if current window information and \a other refer to the same window,
+ otherwise returns \c false.
+*/
+bool QCapturableWindow::operator==(const QCapturableWindow &other) const
+{
+ return d == other.d || (d && other.d && d->id == other.d->id);
+}
+
+/*!
+ Returns \c true if current window information and \a other refer to different windows,
+ otherwise returns \c false.
+*/
+bool QCapturableWindow::operator!=(const QCapturableWindow &other) const
+{
+ return !(*this == other);
+}
+
+/*!
+ \qmlproperty string QtMultimedia::QCapturableWindow::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::QCapturableWindow::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
+{
+ return d ? d->description : QString{};
+}
+
+QCapturableWindow::QCapturableWindow(QCapturableWindowPrivate *capturablePrivate)
+ : d(capturablePrivate)
+{
+}
+
+#ifndef QT_NO_DEBUG_STREAM
+QDebug operator<<(QDebug dbg, const QCapturableWindow &window)
+{
+ dbg << QString::fromUtf8("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..56fc673a0
--- /dev/null
+++ b/src/multimedia/recording/qcapturablewindow.h
@@ -0,0 +1,62 @@
+// 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 Q_MULTIMEDIA_EXPORT QCapturableWindow
+{
+ Q_GADGET
+ Q_PROPERTY(QString description READ description CONSTANT)
+ Q_PROPERTY(bool isValid READ isValid CONSTANT)
+public:
+ QCapturableWindow();
+
+ ~QCapturableWindow();
+
+ QCapturableWindow(const QCapturableWindow &other);
+
+ QCapturableWindow(QCapturableWindow &&other) noexcept = default;
+
+ QCapturableWindow& operator=(const QCapturableWindow &other);
+
+ QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_PURE_SWAP(QCapturableWindow);
+
+ void swap(QCapturableWindow &other) noexcept
+ { d.swap(other.d); }
+
+ bool operator==(const QCapturableWindow &other) const;
+
+ bool operator!=(const QCapturableWindow &other) const;
+
+ bool isValid() const;
+
+ QString description() const;
+
+private:
+ QCapturableWindow(QCapturableWindowPrivate *capturablePrivate);
+
+ QExplicitlySharedDataPointer<QCapturableWindowPrivate> d;
+};
+
+#ifndef QT_NO_DEBUG_STREAM
+Q_MULTIMEDIA_EXPORT QDebug operator<<(QDebug, const QCapturableWindow &);
+#endif
+
+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..f4c370def
--- /dev/null
+++ b/src/multimedia/recording/qcapturablewindow_p.h
@@ -0,0 +1,33 @@
+// 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>
+
+//
+// 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;
+};
+
+QT_END_NAMESPACE
+
+#endif // QCAPTURABLEWINDOW_P_H
diff --git a/src/multimedia/recording/qmediacapturesession.cpp b/src/multimedia/recording/qmediacapturesession.cpp
index 97b62b38e..45e8bb98a 100644
--- a/src/multimedia/recording/qmediacapturesession.cpp
+++ b/src/multimedia/recording/qmediacapturesession.cpp
@@ -8,6 +8,7 @@
#include "qimagecapture.h"
#include "qvideosink.h"
#include "qscreencapture.h"
+#include "qwindowcapture.h"
#include <qpointer.h>
@@ -27,6 +28,7 @@ public:
QAudioOutput *audioOutput = nullptr;
QCamera *camera = nullptr;
QScreenCapture *screenCapture = nullptr;
+ QWindowCapture *windowCapture = nullptr;
QImageCapture *imageCapture = nullptr;
QMediaRecorder *recorder = nullptr;
QVideoSink *videoSink = nullptr;
@@ -45,7 +47,6 @@ public:
captureSession->setVideoPreview(sink);
emit q->videoOutputChanged();
}
-
};
/*!
@@ -59,14 +60,16 @@ public:
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
*/
/*!
@@ -85,9 +88,12 @@ public:
Connect a camera and a microphone to a CaptureSession by assigning Camera
and AudioInput objects to the relevant properties.
- Capture a screen or window view by connecting a ScreenCapture object to
+ 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.
@@ -116,7 +122,7 @@ public:
}
\endqml
- \sa Camera, MediaDevices, MediaRecorder, ImageCapture, AudioInput, VideoOutput
+ \sa Camera, MediaDevices, MediaRecorder, ImageCapture, ScreenCapture, WindowCapture, AudioInput, VideoOutput
*/
/*!
@@ -204,7 +210,7 @@ void QMediaCaptureSession::setAudioInput(QAudioInput *input)
\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
{
@@ -238,9 +244,9 @@ void QMediaCaptureSession::setCamera(QCamera *camera)
\qmlproperty ScreenCapture QtMultimedia::CaptureSession::screenCapture
\since 6.5
- \brief The object used to capture a window or screen view.
+ \brief The object used to capture a screen.
- Record a screen or window view by adding a screen capture objet
+ Record a screen by adding a screen capture objet
to the capture session using this property.
*/
@@ -248,9 +254,9 @@ void QMediaCaptureSession::setCamera(QCamera *camera)
\property QMediaCaptureSession::screenCapture
\since 6.5
- \brief The object used to capture a window or screen view.
+ \brief The object used to capture a screen.
- Record a screen or window view by adding a screen capture objet
+ Record a screen by adding a screen capture object
to the capture session using this property.
*/
QScreenCapture *QMediaCaptureSession::screenCapture()
@@ -280,6 +286,34 @@ void QMediaCaptureSession::setScreenCapture(QScreenCapture *screenCapture)
}
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 *) {
+ // TODO: implement
+}
+
/*!
\qmlproperty ImageCapture QtMultimedia::CaptureSession::imageCapture
diff --git a/src/multimedia/recording/qmediacapturesession.h b/src/multimedia/recording/qmediacapturesession.h
index daef2a3ab..c613c3615 100644
--- a/src/multimedia/recording/qmediacapturesession.h
+++ b/src/multimedia/recording/qmediacapturesession.h
@@ -18,6 +18,7 @@ class QMediaRecorder;
class QPlatformMediaCaptureSession;
class QVideoSink;
class QScreenCapture;
+class QWindowCapture;
class QMediaCaptureSessionPrivate;
class Q_MULTIMEDIA_EXPORT QMediaCaptureSession : public QObject
@@ -28,6 +29,8 @@ class Q_MULTIMEDIA_EXPORT QMediaCaptureSession : public QObject
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(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)
@@ -47,6 +50,9 @@ public:
QScreenCapture *screenCapture();
void setScreenCapture(QScreenCapture *screenCapture);
+ QWindowCapture *windowCapture();
+ void setWindowCapture(QWindowCapture *windowCapture);
+
QMediaRecorder *recorder();
void setRecorder(QMediaRecorder *recorder);
@@ -65,6 +71,7 @@ Q_SIGNALS:
void audioInputChanged();
void cameraChanged();
void screenCaptureChanged();
+ void windowCaptureChanged();
void imageCaptureChanged();
void recorderChanged();
void videoOutputChanged();
diff --git a/src/multimedia/recording/qscreencapture.cpp b/src/multimedia/recording/qscreencapture.cpp
index bd687b8eb..864fcf779 100644
--- a/src/multimedia/recording/qscreencapture.cpp
+++ b/src/multimedia/recording/qscreencapture.cpp
@@ -22,28 +22,26 @@ public:
\ingroup multimedia_video
\since 6.5
- \brief The QScreenCapture class is used for capturing a screen or
- a window.
+ \brief This class is used for capturing a screen.
- The class captures a screen or window. It is managed by
- the QMediaCaptureSession class where the captured view can be displayed
- in a window or recorded to a file.
+ 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
*/
/*!
\qmltype ScreenCapture
\instantiates QScreenCapture
- \brief The ScreenCapture type is used for capturing a screen or
- a window.
+ \brief This type is used for capturing a screen.
\inqmlmodule QtMultimedia
\ingroup multimedia_qml
\ingroup multimedia_video_qml
- ScreenCapture captures a screen or a window. It is managed by
- MediaCaptureSession where the captured view can be displayed in a window
- or recorded to a file.
+ 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
@@ -91,10 +89,8 @@ QScreenCapture::~QScreenCapture()
\value NoError No error
\value InternalError Internal screen capturing driver error
\value CapturingNotSupported Capturing is not supported
- \value WindowCapturingNotSupported Window capturing is not supported.
- This enum value was added in Qt 6.6.
- \value CaptureFailed Capturing screen or window view failed
- \value NotFound Selected screen or window not found
+ \value CaptureFailed Capturing screen failed
+ \value NotFound Selected screen not found
*/
/*!
@@ -111,68 +107,6 @@ QMediaCaptureSession *QScreenCapture::captureSession() const
}
/*!
- \qmlproperty Window QtMultimedia::ScreenCapture::window
- Describes the window for capturing.
-
- \since 6.6
-*/
-
-/*!
- \property QScreenCapture::window
- \brief the window for capturing.
-
- \since 6.6
-*/
-void QScreenCapture::setWindow(QWindow *window)
-{
- Q_D(QScreenCapture);
-
- if (d->platformScreenCapture) {
- d->platformScreenCapture->setScreen(nullptr);
- d->platformScreenCapture->setWindowId(0);
- d->platformScreenCapture->setWindow(window);
- }
-}
-
-QWindow *QScreenCapture::window() const
-{
- Q_D(const QScreenCapture);
-
- return d->platformScreenCapture ? d->platformScreenCapture->window()
- : nullptr;
-}
-
-/*!
- \qmlproperty Window QtMultimedia::ScreenCapture::windowId
- Describes the window ID for capturing.
-*/
-
-/*!
- \property QScreenCapture::windowId
- \brief the window ID for capturing.
-
- \since 6.6
-*/
-void QScreenCapture::setWindowId(WId id)
-{
- Q_D(QScreenCapture);
-
- if (d->platformScreenCapture) {
- d->platformScreenCapture->setScreen(nullptr);
- d->platformScreenCapture->setWindow(nullptr);
- d->platformScreenCapture->setWindowId(id);
- }
-}
-
-WId QScreenCapture::windowId() const
-{
- Q_D(const QScreenCapture);
-
- return d->platformScreenCapture ? d->platformScreenCapture->windowId()
- : 0;
-}
-
-/*!
\qmlproperty bool QtMultimedia::ScreenCapture::active
Describes whether the capturing is currently active.
*/
@@ -197,7 +131,7 @@ bool QScreenCapture::isActive() const
}
/*!
- \qmlproperty bool QtMultimedia::ScreenCapture::screen
+ \qmlproperty Screen QtMultimedia::ScreenCapture::screen
Describes the screen for capturing.
*/
diff --git a/src/multimedia/recording/qscreencapture.h b/src/multimedia/recording/qscreencapture.h
index 4dc2cc1d3..e99e71921 100644
--- a/src/multimedia/recording/qscreencapture.h
+++ b/src/multimedia/recording/qscreencapture.h
@@ -13,7 +13,6 @@
QT_BEGIN_NAMESPACE
-
class QMediaCaptureSession;
class QPlatformScreenCapture;
class QScreenCapturePrivate;
@@ -22,8 +21,6 @@ class Q_MULTIMEDIA_EXPORT QScreenCapture : public QObject
{
Q_OBJECT
Q_PROPERTY(bool active READ isActive WRITE setActive NOTIFY activeChanged)
- Q_PROPERTY(WId windowId READ windowId WRITE setWindowId NOTIFY windowIdChanged)
- Q_PROPERTY(QWindow *window READ window WRITE setWindow NOTIFY windowChanged)
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)
@@ -33,7 +30,6 @@ public:
NoError,
InternalError,
CapturingNotSupported,
- WindowCapturingNotSupported,
CaptureFailed,
NotFound,
};
@@ -44,12 +40,6 @@ public:
QMediaCaptureSession *captureSession() const;
- void setWindow(QWindow *window);
- QWindow *window() const;
-
- void setWindowId(WId id);
- WId windowId() const;
-
void setScreen(QScreen *screen);
QScreen *screen() const;
@@ -66,8 +56,6 @@ public Q_SLOTS:
Q_SIGNALS:
void activeChanged(bool);
void errorChanged();
- void windowIdChanged(WId);
- void windowChanged(QWindow *);
void screenChanged(QScreen *);
void errorOccurred(QScreenCapture::Error error, const QString &errorString);
diff --git a/src/multimedia/recording/qwindowcapture.cpp b/src/multimedia/recording/qwindowcapture.cpp
new file mode 100644
index 000000000..549468930
--- /dev/null
+++ b/src/multimedia/recording/qwindowcapture.cpp
@@ -0,0 +1,161 @@
+// 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"
+
+QT_BEGIN_NAMESPACE
+
+class QWindowCapturePrivate : public QObjectData
+{
+public:
+ // TODO add impl
+};
+
+/*!
+ \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(parent) { }
+
+/*!
+ Destroys the object.
+ */
+QWindowCapture::~QWindowCapture() = default;
+
+/*!
+ \qmlmethod list<CapturableWindow> QtMultimedia::CapturableWindow::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()->capturableWindows();
+}
+
+QMediaCaptureSession *QWindowCapture::captureSession() const
+{
+ return nullptr;
+}
+
+/*!
+ \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
+{
+ return {};
+}
+
+void QWindowCapture::setWindow(QCapturableWindow /*window*/) { }
+
+/*!
+ \qmlproperty bool QtMultimedia::WindowCapture::active
+ Describes whether the capturing is currently active.
+*/
+
+/*!
+ \property QWindowCapture::active
+ \brief whether the capturing is currently active.
+*/
+bool QWindowCapture::isActive() const
+{
+ return false;
+}
+
+void QWindowCapture::setActive(bool /*active*/) { }
+
+/*!
+ \qmlproperty string 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
+{
+ return NoError;
+}
+
+/*!
+ \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
+{
+ return {};
+}
+
+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..7f2f2d79b
--- /dev/null
+++ b/src/multimedia/recording/qwindowcapture.h
@@ -0,0 +1,68 @@
+// 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 <QtMultimedia/qtmultimediaexports.h>
+#include <QtMultimedia/qcapturablewindow.h>
+#include <QtCore/qobject.h>
+#include <QtCore/qlist.h>
+
+#ifndef QWINDOWCAPTURE_H
+#define QWINDOWCAPTURE_H
+
+QT_BEGIN_NAMESPACE
+
+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,
+ InternalError,
+ CapturingNotSupported,
+ CaptureFailed,
+ NotFound,
+ };
+ 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);
+
+ friend class QMediaCaptureSession;
+ Q_DISABLE_COPY(QWindowCapture)
+ Q_DECLARE_PRIVATE(QWindowCapture)
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWCAPTURE_H
diff --git a/src/multimediaquick/qtmultimediaquicktypes_p.h b/src/multimediaquick/qtmultimediaquicktypes_p.h
index e9dffe8be..93aed7193 100644
--- a/src/multimediaquick/qtmultimediaquicktypes_p.h
+++ b/src/multimediaquick/qtmultimediaquicktypes_p.h
@@ -147,6 +147,27 @@ struct QVideoSinkForeign
QML_NAMED_ELEMENT(VideoSink)
};
+struct QCapturableWindowForeign
+{
+ Q_GADGET
+ QML_FOREIGN(QCapturableWindow)
+ QML_NAMED_ELEMENT(capturableWindow)
+};
+
+namespace QCapturableWindowNamespaceForeign
+{
+ Q_NAMESPACE
+ QML_FOREIGN_NAMESPACE(QCapturableWindow)
+ QML_NAMED_ELEMENT(CapturableWindow)
+};
+
+struct QWindowCaptureForeign
+{
+ Q_GADGET
+ QML_FOREIGN(QWindowCapture)
+ QML_NAMED_ELEMENT(WindowCapture)
+};
+
QT_END_NAMESPACE
#endif
diff --git a/src/plugins/multimedia/ffmpeg/qavfscreencapture.mm b/src/plugins/multimedia/ffmpeg/qavfscreencapture.mm
index 7f46d40fe..3fe7b6f4c 100644
--- a/src/plugins/multimedia/ffmpeg/qavfscreencapture.mm
+++ b/src/plugins/multimedia/ffmpeg/qavfscreencapture.mm
@@ -224,7 +224,7 @@ protected:
<< CGImageGetAlphaInfo(imageRef)
<< "ByteOrderInfo:" << CGImageGetByteOrderInfo(imageRef);
- updateError(QScreenCapture::WindowCapturingNotSupported,
+ updateError(QScreenCapture::CapturingNotSupported,
QLatin1String("Not supported pixel format"));
return {};
}
diff --git a/src/plugins/multimedia/ffmpeg/qffmpegscreencapturebase.cpp b/src/plugins/multimedia/ffmpeg/qffmpegscreencapturebase.cpp
index 3d791d054..ce1b75158 100644
--- a/src/plugins/multimedia/ffmpeg/qffmpegscreencapturebase.cpp
+++ b/src/plugins/multimedia/ffmpeg/qffmpegscreencapturebase.cpp
@@ -36,26 +36,6 @@ QScreen *QFFmpegScreenCaptureBase::screen() const
return m_screen;
}
-void QFFmpegScreenCaptureBase::setWindow(QWindow *w)
-{
- setSource(m_window, w, &QScreenCapture::windowChanged);
-}
-
-QWindow *QFFmpegScreenCaptureBase::window() const
-{
- return m_window;
-}
-
-void QFFmpegScreenCaptureBase::setWindowId(WId id)
-{
- setSource(m_wid, id, &QScreenCapture::windowIdChanged);
-}
-
-WId QFFmpegScreenCaptureBase::windowId() const
-{
- return m_wid;
-}
-
template<typename Source, typename NewSource, typename Signal>
void QFFmpegScreenCaptureBase::setSource(Source &source, NewSource newSource, Signal sig)
{
@@ -70,8 +50,6 @@ void QFFmpegScreenCaptureBase::setSource(Source &source, NewSource newSource, Si
source = {};
Q_ASSERT(!m_screen);
- Q_ASSERT(!m_wid);
- Q_ASSERT(!m_window);
}
source = newSource;
diff --git a/src/plugins/multimedia/ffmpeg/qffmpegscreencapturebase_p.h b/src/plugins/multimedia/ffmpeg/qffmpegscreencapturebase_p.h
index e4466bb2a..1b89f76a8 100644
--- a/src/plugins/multimedia/ffmpeg/qffmpegscreencapturebase_p.h
+++ b/src/plugins/multimedia/ffmpeg/qffmpegscreencapturebase_p.h
@@ -34,14 +34,6 @@ public:
QScreen *screen() const final;
- void setWindow(QWindow *w) final;
-
- QWindow *window() const final;
-
- void setWindowId(WId id) final;
-
- WId windowId() const final;
-
protected:
virtual bool setActiveInternal(bool active) = 0;
@@ -52,8 +44,6 @@ private:
private:
bool m_active = false;
QPointer<QScreen> m_screen;
- QPointer<QWindow> m_window;
- WId m_wid = 0;
};
QT_END_NAMESPACE