diff options
author | Lars Knoll <lars.knoll@qt.io> | 2020-12-21 19:45:49 +0100 |
---|---|---|
committer | Lars Knoll <lars.knoll@qt.io> | 2021-01-21 06:47:26 +0000 |
commit | adb83ac39baa9b7e3faba076d3fd6541e71f6f79 (patch) | |
tree | 069195af1417eacb9ce0ca08da84b4964cb77536 /src | |
parent | 1a16281dc71004479679f025adf58f2c77272c99 (diff) | |
download | qtmultimedia-adb83ac39baa9b7e3faba076d3fd6541e71f6f79.tar.gz |
Cleanup the QMediaPluginLoader
We expect only one plugin per service type, later on this
will get reduced to one plugin per platform.
Change-Id: I01383427efa7021f4c33299c551108982a8bc67a
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/gsttools/qgstvideorendererplugin_p.h | 2 | ||||
-rw-r--r-- | src/gsttools/qgstvideorenderersink.cpp | 9 | ||||
-rw-r--r-- | src/multimedia/audio/qaudiodevicefactory.cpp | 1 | ||||
-rw-r--r-- | src/multimedia/playback/qmediaplaylist.cpp | 1 | ||||
-rw-r--r-- | src/multimedia/qmediapluginloader.cpp | 83 | ||||
-rw-r--r-- | src/multimedia/qmediapluginloader_p.h | 3 | ||||
-rw-r--r-- | src/multimedia/qmediaserviceprovider.cpp | 191 | ||||
-rw-r--r-- | src/qtmultimediaquicktools/qdeclarativevideooutput.cpp | 8 |
8 files changed, 85 insertions, 213 deletions
diff --git a/src/gsttools/qgstvideorendererplugin_p.h b/src/gsttools/qgstvideorendererplugin_p.h index df36dbe09..3635fea35 100644 --- a/src/gsttools/qgstvideorendererplugin_p.h +++ b/src/gsttools/qgstvideorendererplugin_p.h @@ -63,8 +63,6 @@ QT_BEGIN_NAMESPACE class QAbstractVideoSurface; -const QLatin1String QGstVideoRendererPluginKey("gstvideorenderer"); - class Q_GSTTOOLS_EXPORT QGstVideoRenderer { public: diff --git a/src/gsttools/qgstvideorenderersink.cpp b/src/gsttools/qgstvideorenderersink.cpp index 5257a1849..f282fd751 100644 --- a/src/gsttools/qgstvideorenderersink.cpp +++ b/src/gsttools/qgstvideorenderersink.cpp @@ -45,7 +45,7 @@ #include <QEvent> #include <QCoreApplication> -#include <private/qmediapluginloader_p.h> +#include <private/qfactoryloader_p.h> #include "qgstvideobuffer_p.h" #include "qgstvideorenderersink_p.h" @@ -175,17 +175,18 @@ bool QGstDefaultVideoRenderer::proposeAllocation(GstQuery *) return true; } -Q_GLOBAL_STATIC_WITH_ARGS(QMediaPluginLoader, rendererLoader, +Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, rendererLoader, (QGstVideoRendererInterface_iid, QLatin1String("video/gstvideorenderer"), Qt::CaseInsensitive)) QVideoSurfaceGstDelegate::QVideoSurfaceGstDelegate(QAbstractVideoSurface *surface) : m_surface(surface) { - const auto instances = rendererLoader()->instances(QGstVideoRendererPluginKey); - for (QObject *instance : instances) { + int i = 0; + while (QObject *instance = rendererLoader->instance(i)) { auto plugin = qobject_cast<QGstVideoRendererInterface*>(instance); if (QGstVideoRenderer *renderer = plugin ? plugin->createRenderer() : nullptr) m_renderers.append(renderer); + ++i; } m_renderers.append(new QGstDefaultVideoRenderer); diff --git a/src/multimedia/audio/qaudiodevicefactory.cpp b/src/multimedia/audio/qaudiodevicefactory.cpp index e4a794ce3..f7fe82a36 100644 --- a/src/multimedia/audio/qaudiodevicefactory.cpp +++ b/src/multimedia/audio/qaudiodevicefactory.cpp @@ -41,7 +41,6 @@ #include "qaudiosystem_p.h" -#include "qmediapluginloader_p.h" #include "qaudiodevicefactory_p.h" QT_BEGIN_NAMESPACE diff --git a/src/multimedia/playback/qmediaplaylist.cpp b/src/multimedia/playback/qmediaplaylist.cpp index 84293d338..e1427ccf7 100644 --- a/src/multimedia/playback/qmediaplaylist.cpp +++ b/src/multimedia/playback/qmediaplaylist.cpp @@ -49,7 +49,6 @@ #include <QtCore/qcoreevent.h> #include <QtCore/qcoreapplication.h> #include <QRandomGenerator> -#include "qmediapluginloader_p.h" QT_BEGIN_NAMESPACE diff --git a/src/multimedia/qmediapluginloader.cpp b/src/multimedia/qmediapluginloader.cpp index 3e9e6cc21..9d145d789 100644 --- a/src/multimedia/qmediapluginloader.cpp +++ b/src/multimedia/qmediapluginloader.cpp @@ -66,72 +66,21 @@ QMediaPluginLoader::~QMediaPluginLoader() QStringList QMediaPluginLoader::keys() const { - return m_metadata.keys(); + return m_map.keys(); } -QObject* QMediaPluginLoader::instance(QString const &key) +QObject *QMediaPluginLoader::instance(QString const &key) { - if (!m_metadata.contains(key)) + if (!m_map.contains(key)) return nullptr; - int idx = m_metadata.value(key).first().value(QStringLiteral("index")).toDouble(); + int idx = m_map.value(key); if (idx < 0) return nullptr; return m_factoryLoader->instance(idx); } -QList<QObject*> QMediaPluginLoader::instances(QString const &key) -{ - if (!m_metadata.contains(key)) - return QList<QObject*>(); - - QList<QString> keys; - QList<QObject *> objects; - const auto list = m_metadata.value(key); - for (const QJsonObject &jsonobj : list) { - int idx = jsonobj.value(QStringLiteral("index")).toDouble(); - if (idx < 0) - continue; - - QObject *object = m_factoryLoader->instance(idx); - if (!objects.contains(object)) { - QJsonArray arr = jsonobj.value(QStringLiteral("Keys")).toArray(); - keys.append(!arr.isEmpty() ? arr.at(0).toString() : QStringLiteral("")); - objects.append(object); - } - } - - static const bool showDebug = qEnvironmentVariableIntValue("QT_DEBUG_PLUGINS"); - static const QStringList preferredPlugins = - qEnvironmentVariable("QT_MULTIMEDIA_PREFERRED_PLUGINS").split(QLatin1Char(','), Qt::SkipEmptyParts); - for (int i = preferredPlugins.size() - 1; i >= 0; --i) { - auto name = preferredPlugins[i]; - bool found = false; - for (int j = 0; j < keys.size(); ++j) { - if (!keys[j].startsWith(name)) - continue; - - auto obj = objects[j]; - objects.removeAt(j); - objects.prepend(obj); - auto k = keys[j]; - keys.removeAt(j); - keys.prepend(k); - found = true; - break; - } - - if (showDebug && !found) - qWarning() << "QMediaPluginLoader: pattern" << name << "did not match any loaded plugin"; - } - - if (showDebug) - qDebug() << "QMediaPluginLoader: loaded plugins for key" << key << ":" << keys; - - return objects; -} - void QMediaPluginLoader::loadMetadata() { #if !defined QT_NO_DEBUG @@ -143,7 +92,7 @@ void QMediaPluginLoader::loadMetadata() qDebug() << "QMediaPluginLoader: loading metadata for iid " << m_iid << " at location " << m_location; #endif - if (!m_metadata.isEmpty()) { + if (!m_map.isEmpty()) { #if !defined QT_NO_DEBUG if (showDebug) qDebug() << "QMediaPluginLoader: already loaded metadata, returning"; @@ -154,30 +103,24 @@ void QMediaPluginLoader::loadMetadata() QList<QJsonObject> meta = m_factoryLoader->metaData(); for (int i = 0; i < meta.size(); i++) { QJsonObject jsonobj = meta.at(i).value(QStringLiteral("MetaData")).toObject(); - jsonobj.insert(QStringLiteral("index"), i); -#if !defined QT_NO_DEBUG - if (showDebug) - qDebug() << "QMediaPluginLoader: Inserted index " << i << " into metadata: " << jsonobj; -#endif - QJsonArray arr = jsonobj.value(QStringLiteral("Services")).toArray(); - // Preserve compatibility with older plugins (made before 5.1) in which - // services were declared in the 'Keys' property - if (arr.isEmpty()) - arr = jsonobj.value(QStringLiteral("Keys")).toArray(); for (const QJsonValue &value : qAsConst(arr)) { QString key = value.toString(); - if (!m_metadata.contains(key)) { + if (m_map.contains(key)) { #if !defined QT_NO_DEBUG if (showDebug) - qDebug() << "QMediaPluginLoader: Inserting new list for key: " << key; + qDebug() << "QMediaPluginLoader: Two plugins provide service " << key; #endif - m_metadata.insert(key, QList<QJsonObject>()); + continue; } - m_metadata[key].append(jsonobj); +#if !defined QT_NO_DEBUG + if (showDebug) + qDebug() << "QMediaPluginLoader: Inserting new list for key: " << key; +#endif + m_map.insert(key, i); } } } diff --git a/src/multimedia/qmediapluginloader_p.h b/src/multimedia/qmediapluginloader_p.h index a4e726544..8d43d2045 100644 --- a/src/multimedia/qmediapluginloader_p.h +++ b/src/multimedia/qmediapluginloader_p.h @@ -74,14 +74,13 @@ public: QStringList keys() const; QObject* instance(QString const &key); - QList<QObject*> instances(QString const &key); private: void loadMetadata(); QByteArray m_iid; QString m_location; - QMap<QString, QList<QJsonObject> > m_metadata; + QMap<QString, int> m_map; QFactoryLoader *m_factoryLoader; }; diff --git a/src/multimedia/qmediaserviceprovider.cpp b/src/multimedia/qmediaserviceprovider.cpp index dda8ad24f..67bd5d240 100644 --- a/src/multimedia/qmediaserviceprovider.cpp +++ b/src/multimedia/qmediaserviceprovider.cpp @@ -74,27 +74,19 @@ public: QString key(QLatin1String(type.constData())); QList<QMediaServiceProviderPlugin *>plugins; - const auto instances = loader()->instances(key); - for (QObject *obj : instances) { - QMediaServiceProviderPlugin *plugin = qobject_cast<QMediaServiceProviderPlugin*>(obj); - if (plugin) - plugins << plugin; - } - - if (!plugins.isEmpty()) { - QMediaServiceProviderPlugin *plugin = plugins[0]; - - if (plugin != nullptr) { - QMediaService *service = plugin->create(key); - if (service != nullptr) { - MediaServiceData d; - d.type = type; - d.plugin = plugin; - mediaServiceData.insert(service, d); - } - - return service; + QObject *instance = loader()->instance(key); + QMediaServiceProviderPlugin *plugin = qobject_cast<QMediaServiceProviderPlugin*>(instance); + + if (plugin != nullptr) { + QMediaService *service = plugin->create(key); + if (service != nullptr) { + MediaServiceData d; + d.type = type; + d.plugin = plugin; + mediaServiceData.insert(service, d); } + + return service; } qWarning() << "defaultServiceProvider::requestService(): no service found for -" << key; @@ -133,148 +125,89 @@ public: const QStringList& codecs, int flags) const override { - const QList<QObject*> instances = loader()->instances(QLatin1String(serviceType)); + QObject *instance = loader()->instance(QLatin1String(serviceType)); - if (instances.isEmpty()) + if (!instance) return QMultimedia::NotSupported; - bool allServicesProvideInterface = true; - QMultimedia::SupportEstimate supportEstimate = QMultimedia::NotSupported; - - for (QObject *obj : instances) { - QMediaServiceSupportedFormatsInterface *iface = - qobject_cast<QMediaServiceSupportedFormatsInterface*>(obj); + QMultimedia::SupportEstimate supportEstimate = QMultimedia::MaybeSupported; + QMediaServiceSupportedFormatsInterface *iface = qobject_cast<QMediaServiceSupportedFormatsInterface*>(instance); + if (iface) + supportEstimate = qMax(supportEstimate, iface->hasSupport(mimeType, codecs)); + if (flags && supportEstimate == QMultimedia::ProbablySupported) { + QMediaServiceFeaturesInterface *iface = qobject_cast<QMediaServiceFeaturesInterface*>(instance); - if (flags) { - QMediaServiceFeaturesInterface *iface = - qobject_cast<QMediaServiceFeaturesInterface*>(obj); - - if (iface) { - QMediaServiceFeaturesInterface::Features features = iface->supportedFeatures(serviceType); - - //if low latency playback was asked, skip services known - //not to provide low latency playback - if ((flags & QMediaPlayer::LowLatency) && - !(features & QMediaServiceFeaturesInterface::LowLatencyPlayback)) - continue; - - //the same for QIODevice based streams support - if ((flags & QMediaPlayer::StreamPlayback) && - !(features & QMediaServiceFeaturesInterface::StreamPlayback)) - continue; - } + if (iface) { + QMediaServiceFeaturesInterface::Features features = iface->supportedFeatures(serviceType); + + //if low latency playback was asked, skip services known + //not to provide low latency playback + if ((flags & QMediaPlayer::LowLatency) && + !(features & QMediaServiceFeaturesInterface::LowLatencyPlayback)) + supportEstimate = QMultimedia::MaybeSupported; + + //the same for QIODevice based streams support + if ((flags & QMediaPlayer::StreamPlayback) && + !(features & QMediaServiceFeaturesInterface::StreamPlayback)) + supportEstimate = QMultimedia::MaybeSupported; } - - if (iface) - supportEstimate = qMax(supportEstimate, iface->hasSupport(mimeType, codecs)); - else - allServicesProvideInterface = false; } - //don't return PreferredService - supportEstimate = qMin(supportEstimate, QMultimedia::ProbablySupported); - - //Return NotSupported only if no services are available of serviceType - //or all the services returned NotSupported, otherwise return at least MaybeSupported - if (!allServicesProvideInterface) - supportEstimate = qMax(QMultimedia::MaybeSupported, supportEstimate); - return supportEstimate; } QStringList supportedMimeTypes(const QByteArray &serviceType, int flags) const override { - const QList<QObject*> instances = loader()->instances(QLatin1String(serviceType)); - - QStringList supportedTypes; - - for (QObject *obj : instances) { - QMediaServiceSupportedFormatsInterface *iface = - qobject_cast<QMediaServiceSupportedFormatsInterface*>(obj); - - - if (flags) { - QMediaServiceFeaturesInterface *iface = - qobject_cast<QMediaServiceFeaturesInterface*>(obj); - - if (iface) { - QMediaServiceFeaturesInterface::Features features = iface->supportedFeatures(serviceType); - - // If low latency playback was asked for, skip MIME types from services known - // not to provide low latency playback - if ((flags & QMediaPlayer::LowLatency) && - !(features & QMediaServiceFeaturesInterface::LowLatencyPlayback)) - continue; - - //the same for QIODevice based streams support - if ((flags & QMediaPlayer::StreamPlayback) && - !(features & QMediaServiceFeaturesInterface::StreamPlayback)) - continue; - - //the same for QAbstractVideoSurface support - if ((flags & QMediaPlayer::VideoSurface) && - !(features & QMediaServiceFeaturesInterface::VideoSurface)) - continue; - } - } + Q_UNUSED(flags); + QObject *instance = loader()->instance(QLatin1String(serviceType)); + if (!instance) + return {}; - if (iface) { - supportedTypes << iface->supportedMimeTypes(); - } - } + QMediaServiceSupportedFormatsInterface *iface = qobject_cast<QMediaServiceSupportedFormatsInterface*>(instance); - // Multiple services may support the same MIME type - supportedTypes.removeDuplicates(); + if (iface) + return iface->supportedMimeTypes(); - return supportedTypes; + return {}; } QByteArray defaultDevice(const QByteArray &serviceType) const override { - const auto instances = loader()->instances(QLatin1String(serviceType)); - for (QObject *obj : instances) { - const QMediaServiceSupportedDevicesInterface *iface = - qobject_cast<QMediaServiceSupportedDevicesInterface *>(obj); + QObject *instance = loader()->instance(QLatin1String(serviceType)); + if (!instance) + return QByteArray(); - if (iface) { - QByteArray name = iface->defaultDevice(serviceType); - if (!name.isEmpty()) - return name; - } - } + const QMediaServiceSupportedDevicesInterface *iface = qobject_cast<QMediaServiceSupportedDevicesInterface *>(instance); + if (iface) + return iface->defaultDevice(serviceType); return QByteArray(); } QList<QByteArray> devices(const QByteArray &serviceType) const override { - QList<QByteArray> res; + QObject *instance = loader()->instance(QLatin1String(serviceType)); + if (!instance) + return {}; - const auto instances = loader()->instances(QLatin1String(serviceType)); - for (QObject *obj : instances) { - QMediaServiceSupportedDevicesInterface *iface = - qobject_cast<QMediaServiceSupportedDevicesInterface*>(obj); + QMediaServiceSupportedDevicesInterface *iface = qobject_cast<QMediaServiceSupportedDevicesInterface*>(instance); + if (iface) + return iface->devices(serviceType); - if (iface) { - res.append(iface->devices(serviceType)); - } - } - - return res; + return {}; } QString deviceDescription(const QByteArray &serviceType, const QByteArray &device) override { - const auto instances = loader()->instances(QLatin1String(serviceType)); - for (QObject *obj : instances) { - QMediaServiceSupportedDevicesInterface *iface = - qobject_cast<QMediaServiceSupportedDevicesInterface*>(obj); - - if (iface) { - if (iface->devices(serviceType).contains(device)) - return iface->deviceDescription(serviceType, device); - } + QObject *instance = loader()->instance(QLatin1String(serviceType)); + if (!instance) + return {}; + + QMediaServiceSupportedDevicesInterface *iface = qobject_cast<QMediaServiceSupportedDevicesInterface*>(instance); + if (iface) { + if (iface->devices(serviceType).contains(device)) + return iface->deviceDescription(serviceType, device); } return QString(); diff --git a/src/qtmultimediaquicktools/qdeclarativevideooutput.cpp b/src/qtmultimediaquicktools/qdeclarativevideooutput.cpp index 966f3d587..2051f7c73 100644 --- a/src/qtmultimediaquicktools/qdeclarativevideooutput.cpp +++ b/src/qtmultimediaquicktools/qdeclarativevideooutput.cpp @@ -44,7 +44,7 @@ #include <private/qvideooutputorientationhandler_p.h> #include <QtMultimedia/qmediaobject.h> #include <QtMultimedia/qmediaservice.h> -#include <private/qmediapluginloader_p.h> +#include <private/qfactoryloader_p.h> #include <QtCore/qloggingcategory.h> static void initResource() { @@ -239,15 +239,15 @@ void QDeclarativeVideoOutput::setSource(QObject *source) emit sourceChanged(); } -Q_GLOBAL_STATIC_WITH_ARGS(QMediaPluginLoader, videoBackendFactoryLoader, +Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, videoBackendFactoryLoader, (QDeclarativeVideoBackendFactoryInterface_iid, QLatin1String("video/declarativevideobackend"), Qt::CaseInsensitive)) bool QDeclarativeVideoOutput::createBackend(QMediaService *service) { bool backendAvailable = false; - const auto instances = videoBackendFactoryLoader()->instances(QLatin1String("declarativevideobackend")); - for (QObject *instance : instances) { + int i = 0; + while (const auto instance = videoBackendFactoryLoader()->instance(i)) { if (QDeclarativeVideoBackendFactoryInterface *plugin = qobject_cast<QDeclarativeVideoBackendFactoryInterface*>(instance)) { if (!m_backend) m_backend.reset(plugin->create(this)); |