Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qplatformmediaintegration.cpp
Go to the documentation of this file.
1// Copyright (C) 2021 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
6#include <qatomic.h>
7#include <qmutex.h>
12#include <qmediadevices.h>
13#include <qcameradevice.h>
14#include <qloggingcategory.h>
15#include <QtCore/qcoreapplication.h>
16#include <QtCore/qapplicationstatic.h>
17
20#include <QtCore/private/qfactoryloader_p.h>
21#include <QtCore/private/qcoreapplication_p.h>
22#include <private/qplatformmediaformatinfo_p.h>
24
25namespace {
26
27class QFallbackIntegration : public QPlatformMediaIntegration
28{
29public:
30 QFallbackIntegration() : QPlatformMediaIntegration(QLatin1String("fallback"))
31 {
32 qWarning("No QtMultimedia backends found. Only QMediaDevices, QAudioDevice, QSoundEffect, QAudioSink, and QAudioSource are available.");
33 }
34};
35
36static Q_LOGGING_CATEGORY(qLcMediaPlugin, "qt.multimedia.plugin")
37
40 QLatin1String("/multimedia")))
41
42static const auto FFmpegBackend = QStringLiteral("ffmpeg");
43
44static QString defaultBackend(const QStringList &backends)
45{
46#ifdef QT_DEFAULT_MEDIA_BACKEND
47 auto backend = QString::fromUtf8(QT_DEFAULT_MEDIA_BACKEND);
48 if (backends.contains(backend))
49 return backend;
50#endif
51
52#if defined(Q_OS_DARWIN) || defined(Q_OS_LINUX) || defined(Q_OS_WINDOWS) || defined(Q_OS_ANDROID)
53 // Return ffmpeg backend by default.
54 // Platform backends for the OS list are optionally available but have limited support.
55 if (backends.contains(FFmpegBackend))
56 return FFmpegBackend;
57#else
58 // Return platform backend (non-ffmpeg) by default.
59 if (backends.size() > 1 && backends[0] == FFmpegBackend)
60 return backends[1];
61#endif
62
63 return backends[0];
64}
65
66struct InstanceHolder
67{
68 InstanceHolder()
69 {
71 qCCritical(qLcMediaPlugin()) << "Qt Multimedia requires a QCoreApplication instance";
72
74 QString backend = QString::fromUtf8(qgetenv("QT_MEDIA_BACKEND"));
75 if (backend.isEmpty() && !backends.isEmpty())
76 backend = defaultBackend(backends);
77
78 qCDebug(qLcMediaPlugin) << "Loading media backend" << backend;
79 instance.reset(
80 qLoadPlugin<QPlatformMediaIntegration, QPlatformMediaPlugin>(loader(), backend));
81
82 if (!instance) {
83 // No backends found. Use fallback to support basic functionality
84 instance = std::make_unique<QFallbackIntegration>();
85 }
86 }
87
88 ~InstanceHolder()
89 {
90 instance.reset();
91 qCDebug(qLcMediaPlugin) << "Released media backend";
92 }
93
94 std::unique_ptr<QPlatformMediaIntegration> instance;
95};
96
97Q_APPLICATION_STATIC(InstanceHolder, s_instanceHolder);
98
99} // namespace
100
102
104{
105 return s_instanceHolder->instance.get();
106}
107
109{
110 auto devices = videoDevices();
111 return devices ? devices->videoDevices() : QList<QCameraDevice>{};
112}
113
114QMaybe<std::unique_ptr<QPlatformAudioResampler>>
116{
117 return notAvailable;
118}
119
121{
122 return new QPlatformAudioInput(q);
123}
124
126{
127 return new QPlatformAudioOutput(q);
128}
129
131{
132 const auto capturableWindows = this->capturableWindows();
133 return capturableWindows ? capturableWindows->windows() : QList<QCapturableWindow>{};
134}
135
141
143{
144 std::call_once(m_formatInfoOnceFlg, [this]() {
145 m_formatInfo.reset(createFormatInfo());
146 Q_ASSERT(m_formatInfo);
147 });
148 return m_formatInfo.get();
149}
150
155
156std::unique_ptr<QPlatformMediaDevices> QPlatformMediaIntegration::createMediaDevices()
157{
159}
160
161// clang-format off
163{
164 std::call_once(m_videoDevicesOnceFlag,
165 [this]() {
166 m_videoDevices.reset(createVideoDevices());
167 });
168 return m_videoDevices.get();
169}
170
172{
173 std::call_once(m_capturableWindowsOnceFlag,
174 [this]() {
175 m_capturableWindows.reset(createCapturableWindows());
176 });
177 return m_capturableWindows.get();
178}
179
181{
182 std::call_once(m_mediaDevicesOnceFlag, [this] {
183 m_mediaDevices = createMediaDevices();
184 });
185 return m_mediaDevices.get();
186}
187
188// clang-format on
189
191{
193
194 if (QFactoryLoader *fl = loader()) {
195 const auto keyMap = fl->keyMap();
196 for (auto it = keyMap.constBegin(); it != keyMap.constEnd(); ++it)
197 if (!list.contains(it.value()))
198 list << it.value();
199 }
200
201 qCDebug(qLcMediaPlugin) << "Available backends" << list;
202 return list;
203}
204
206{
207 return m_backendName;
208}
209
215
217
219
221
222#include "moc_qplatformmediaintegration_p.cpp"
The QAudioFormat class stores audio stream parameter information.
\qmltype AudioInput \instantiates QAudioInput
Definition qaudioinput.h:19
\qmltype AudioOutput \instantiates QAudioOutput
static QCoreApplication * instance() noexcept
Returns a pointer to the application's QCoreApplication (or QGuiApplication/QApplication) instance.
virtual bool isWindowValid(const QCapturableWindowPrivate &) const
virtual QList< QCapturableWindow > windows() const
static std::unique_ptr< QPlatformMediaDevices > create()
virtual std::unique_ptr< QPlatformMediaDevices > createMediaDevices()
virtual QPlatformVideoDevices * createVideoDevices()
virtual QMaybe< QPlatformAudioOutput * > createAudioOutput(QAudioOutput *)
virtual QVideoFrame convertVideoFrame(QVideoFrame &, const QVideoFrameFormat &)
const QPlatformMediaFormatInfo * formatInfo()
QPlatformMediaDevices * mediaDevices()
virtual QMaybe< QPlatformAudioInput * > createAudioInput(QAudioInput *)
QList< QCapturableWindow > capturableWindowsList()
virtual QList< QCameraDevice > videoInputs()
virtual QPlatformMediaFormatInfo * createFormatInfo()
bool isCapturableWindowValid(const QCapturableWindowPrivate &)
virtual QMaybe< std::unique_ptr< QPlatformAudioResampler > > createAudioResampler(const QAudioFormat &, const QAudioFormat &)
virtual QPlatformCapturableWindows * createCapturableWindows()
static QPlatformMediaIntegration * instance()
virtual ~QPlatformMediaIntegration()
QPlatformCapturableWindows * capturableWindows()
QPlatformVideoDevices * videoDevices()
\inmodule QtCore
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
bool isEmpty() const noexcept
Returns true if the string has no characters; otherwise returns false.
Definition qstring.h:192
static QString fromUtf8(QByteArrayView utf8)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:6018
The QVideoFrameFormat class specifies the stream format of a video presentation surface.
The QVideoFrame class represents a frame of video data.
Definition qvideoframe.h:27
QSet< QString >::iterator it
Combined button and popup list for selecting options.
#define Q_APPLICATION_STATIC(TYPE, NAME,...)
EGLDeviceEXT * devices
#define qWarning
Definition qlogging.h:166
#define Q_LOGGING_CATEGORY(name,...)
#define qCCritical(category,...)
#define qCDebug(category,...)
GLuint name
GLdouble GLdouble GLdouble GLdouble q
Definition qopenglext.h:259
#define QPlatformMediaPlugin_iid
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
#define QStringLiteral(str)
Q_CORE_EXPORT QByteArray qgetenv(const char *varName)
static const struct @450 keyMap[]
QList< int > list
[14]
aWidget window() -> setWindowTitle("New Window Title")
[2]
bool contains(const AT &t) const noexcept
Definition qlist.h:45