6#include <QtCore/qapplicationstatic.h>
7#include <QtCore/qatomic.h>
8#include <QtCore/qcoreapplication.h>
9#include <QtCore/qloggingcategory.h>
10#include <QtCore/qmutex.h>
11#include <QtCore/private/qcoreapplication_p.h>
12#include <QtCore/private/qfactoryloader_p.h>
14#include <QtGui/qwindow.h>
16#include <QtMultimedia/qcameradevice.h>
17#include <QtMultimedia/qmediadevices.h>
18#include <QtMultimedia/private/qplatformaudiodevices_p.h>
19#include <QtMultimedia/private/qplatformaudioinput_p.h>
20#include <QtMultimedia/private/qplatformaudiooutput_p.h>
21#include <QtMultimedia/private/qplatformaudioresampler_p.h>
22#include <QtMultimedia/private/qplatformcapturablewindows_p.h>
23#include <QtMultimedia/private/qplatformmediaformatinfo_p.h>
24#include <QtMultimedia/private/qplatformmediaplugin_p.h>
25#include <QtMultimedia/private/qplatformvideodevices_p.h>
26#include <QtMultimedia/private/qtmultimediaglobal_p.h>
30class QFallbackIntegration :
public QPlatformMediaIntegration
33 QFallbackIntegration() : QPlatformMediaIntegration(QLatin1String(
"fallback"))
35 qWarning(
"No QtMultimedia backends found. Only QMediaDevices, QAudioDevice, QSoundEffect, QAudioSink, and QAudioSource are available.");
39Q_STATIC_LOGGING_CATEGORY(qLcMediaPlugin,
"qt.multimedia.plugin")
41Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader,
42 (QPlatformMediaPlugin_iid,
43 QLatin1String(
"/multimedia")))
45static const auto FFmpegBackend = QStringLiteral(
"ffmpeg");
47static QString defaultBackend(
const QStringList &backends)
49#ifdef QT_DEFAULT_MEDIA_BACKEND
50 auto backend = QString::fromUtf8(QT_DEFAULT_MEDIA_BACKEND);
51 if (backends.contains(backend))
55#if defined(Q_OS_DARWIN) || defined(Q_OS_LINUX) || defined(Q_OS_WINDOWS) || defined(Q_OS_ANDROID)
58 if (backends.contains(FFmpegBackend))
62 if (backends.size() > 1 && backends[0] == FFmpegBackend)
78 if (!QCoreApplication::instance())
79 qCCritical(qLcMediaPlugin()) <<
"Qt Multimedia requires a QCoreApplication instance";
81 const QStringList backends = QPlatformMediaIntegration::availableBackends();
82 QString backend = QString::fromUtf8(qgetenv(
"QT_MEDIA_BACKEND")).toLower();
83 if (backend.isEmpty() && !backends.isEmpty())
84 backend = defaultBackend(backends);
86 qCDebug(qLcMediaPlugin) <<
"Loading media backend" << backend;
88 qLoadPlugin<QPlatformMediaIntegration, QPlatformMediaPlugin>(loader(), backend));
92 instance = std::make_unique<QFallbackIntegration>();
99 qCDebug(qLcMediaPlugin) <<
"Released media backend";
102 std::unique_ptr<QPlatformMediaIntegration> instance;
105Q_APPLICATION_STATIC(InstanceHolder, s_instanceHolder);
113 return s_instanceHolder->instance.get();
116void QPlatformMediaIntegration::resetInstance()
118 s_instanceHolder->init();
121q23::expected<std::unique_ptr<QPlatformAudioResampler>, QString>
122QPlatformMediaIntegration::createAudioResampler(
const QAudioFormat &,
const QAudioFormat &)
124 return q23::unexpected(notAvailable);
127q23::expected<QPlatformAudioInput *, QString> QPlatformMediaIntegration::createAudioInput(QAudioInput *q)
129 return new QPlatformAudioInput(q);
132q23::expected<QPlatformAudioOutput *, QString> QPlatformMediaIntegration::createAudioOutput(QAudioOutput *q)
134 return new QPlatformAudioOutput(q);
137QList<QCapturableWindow> QPlatformMediaIntegration::capturableWindowsList()
139 const auto capturableWindows =
this->capturableWindows();
140 return capturableWindows ? capturableWindows->windows() : QList<QCapturableWindow>{};
143bool QPlatformMediaIntegration::isCapturableWindowValid(
const QCapturableWindowPrivate &window)
145 const auto capturableWindows =
this->capturableWindows();
146 return capturableWindows && capturableWindows->isWindowValid(window);
149q23::expected<QCapturableWindow, QString> QPlatformMediaIntegration::capturableWindowFromQWindow(QWindow *window)
151 const auto capturableWindows =
this->capturableWindows();
152 if (!capturableWindows)
153 return q23::unexpected{ QStringLiteral(
"No windowcapture platform implementation") };
154 if (window ==
nullptr)
155 return q23::unexpected{ QStringLiteral(
"QWindow is nullptr") };
156 if (!window->isTopLevel())
157 return q23::unexpected{ QStringLiteral(
"QWindow is not top-level.") };
158 return capturableWindows->fromQWindow(window);
161const QPlatformMediaFormatInfo *QPlatformMediaIntegration::formatInfo()
163 std::call_once(m_formatInfoOnceFlg, [
this]() {
164 m_formatInfo.reset(createFormatInfo());
165 Q_ASSERT(m_formatInfo);
167 return m_formatInfo.get();
170QPlatformMediaFormatInfo *QPlatformMediaIntegration::createFormatInfo()
172 return new QPlatformMediaFormatInfo;
175std::unique_ptr<QPlatformAudioDevices> QPlatformMediaIntegration::createAudioDevices()
177 return QPlatformAudioDevices::create();
181QPlatformVideoDevices *QPlatformMediaIntegration::videoDevices()
183 std::call_once(m_videoDevicesOnceFlag,
185 m_videoDevices.reset(createVideoDevices());
187 return m_videoDevices.get();
190QPlatformCapturableWindows *QPlatformMediaIntegration::capturableWindows()
192 std::call_once(m_capturableWindowsOnceFlag,
194 m_capturableWindows.reset(createCapturableWindows());
196 return m_capturableWindows.get();
199QPlatformAudioDevices *QPlatformMediaIntegration::audioDevices()
201 std::call_once(m_audioDevicesOnceFlag, [
this] {
202 m_audioDevices = createAudioDevices();
204 return m_audioDevices.get();
209QStringList QPlatformMediaIntegration::availableBackends()
213 if (QFactoryLoader *fl = loader()) {
214 const auto keyMap = fl->keyMap();
215 for (
auto it = keyMap.constBegin(); it != keyMap.constEnd(); ++it)
216 if (!list.contains(it.value()))
220 qCDebug(qLcMediaPlugin) <<
"Available backends" << list;
224QLatin1String QPlatformMediaIntegration::name()
226 return m_backendName;
229QVideoFrame QPlatformMediaIntegration::convertVideoFrame(QVideoFrame &,
230 const QVideoFrameFormat &)
235QLatin1String QPlatformMediaIntegration::audioBackendName()
237 return QPlatformMediaIntegration::instance()->audioDevices()->backendName();
240QPlatformMediaIntegration::QPlatformMediaIntegration(QLatin1String name) : m_backendName(name) { }
242QPlatformMediaIntegration::~QPlatformMediaIntegration() =
default;
246#include "moc_qplatformmediaintegration_p.cpp"