1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#include <QtCore/qdebug.h>
41#include <QtCore/qmap.h>
42
43#include "qmediaservice.h"
44#include "qmediaserviceprovider_p.h"
45#include "qmediaserviceproviderplugin.h"
46#include "qmediapluginloader_p.h"
47#include "qmediaplayer.h"
48
49QT_BEGIN_NAMESPACE
50
51QMediaServiceProviderFactoryInterface::~QMediaServiceProviderFactoryInterface()
52{
53}
54
55class QMediaServiceProviderHintPrivate : public QSharedData
56{
57public:
58 QMediaServiceProviderHintPrivate(QMediaServiceProviderHint::Type type)
59 :type(type), cameraPosition(QCamera::UnspecifiedPosition), features(nullptr)
60 {
61 }
62
63 QMediaServiceProviderHintPrivate(const QMediaServiceProviderHintPrivate &other)
64 :QSharedData(other),
65 type(other.type),
66 device(other.device),
67 cameraPosition(other.cameraPosition),
68 mimeType(other.mimeType),
69 codecs(other.codecs),
70 features(other.features)
71 {
72 }
73
74 ~QMediaServiceProviderHintPrivate()
75 {
76 }
77
78 QMediaServiceProviderHint::Type type;
79 QByteArray device;
80 QCamera::Position cameraPosition;
81 QString mimeType;
82 QStringList codecs;
83 QMediaServiceProviderHint::Features features;
84};
85
86/*!
87 \class QMediaServiceProviderHint
88
89 \brief The QMediaServiceProviderHint class describes what is required of a QMediaService.
90
91 \inmodule QtMultimedia
92
93 \ingroup multimedia
94 \ingroup multimedia_control
95 \ingroup multimedia_core
96
97 \internal
98
99 The QMediaServiceProvider class uses hints to select an appropriate media service.
100*/
101
102/*!
103 \enum QMediaServiceProviderHint::Feature
104
105 Enumerates features a media service may provide.
106
107 \value LowLatencyPlayback
108 The service is expected to play simple audio formats,
109 but playback should start without significant delay.
110 Such playback service can be used for beeps, ringtones, etc.
111
112 \value RecordingSupport
113 The service provides audio or video recording functions.
114
115 \value StreamPlayback
116 The service is capable of playing QIODevice based streams.
117
118 \value VideoSurface
119 The service is capable of renderering to a QAbstractVideoSurface
120 output.
121*/
122
123/*!
124 \enum QMediaServiceProviderHint::Type
125
126 Enumerates the possible types of media service provider hint.
127
128 \value Null En empty hint, use the default service.
129 \value ContentType Select media service most suitable for certain content type.
130 \value Device Select media service which supports certain device.
131 \value SupportedFeatures Select media service supporting the set of optional features.
132 \value CameraPosition Select media service having a camera at a specified position.
133*/
134
135
136/*!
137 Constructs an empty media service provider hint.
138*/
139QMediaServiceProviderHint::QMediaServiceProviderHint()
140 :d(new QMediaServiceProviderHintPrivate(Null))
141{
142}
143
144/*!
145 Constructs a ContentType media service provider hint.
146
147 This type of hint describes a service that is able to play content of a specific MIME \a type
148 encoded with one or more of the listed \a codecs.
149*/
150QMediaServiceProviderHint::QMediaServiceProviderHint(const QString &type, const QStringList& codecs)
151 :d(new QMediaServiceProviderHintPrivate(ContentType))
152{
153 d->mimeType = type;
154 d->codecs = codecs;
155}
156
157/*!
158 Constructs a Device media service provider hint.
159
160 This type of hint describes a media service that utilizes a specific \a device.
161*/
162QMediaServiceProviderHint::QMediaServiceProviderHint(const QByteArray &device)
163 :d(new QMediaServiceProviderHintPrivate(Device))
164{
165 d->device = device;
166}
167
168/*!
169 \since 5.3
170
171 Constructs a CameraPosition media service provider hint.
172
173 This type of hint describes a media service that has a camera in the specific \a position.
174*/
175QMediaServiceProviderHint::QMediaServiceProviderHint(QCamera::Position position)
176 :d(new QMediaServiceProviderHintPrivate(CameraPosition))
177{
178 d->cameraPosition = position;
179}
180
181/*!
182 Constructs a SupportedFeatures media service provider hint.
183
184 This type of hint describes a service which supports a specific set of \a features.
185*/
186QMediaServiceProviderHint::QMediaServiceProviderHint(QMediaServiceProviderHint::Features features)
187 :d(new QMediaServiceProviderHintPrivate(SupportedFeatures))
188{
189 d->features = features;
190}
191
192/*!
193 Constructs a copy of the media service provider hint \a other.
194*/
195QMediaServiceProviderHint::QMediaServiceProviderHint(const QMediaServiceProviderHint &other)
196 :d(other.d)
197{
198}
199
200/*!
201 Destroys a media service provider hint.
202*/
203QMediaServiceProviderHint::~QMediaServiceProviderHint()
204{
205}
206
207/*!
208 Assigns the value \a other to a media service provider hint.
209*/
210QMediaServiceProviderHint& QMediaServiceProviderHint::operator=(const QMediaServiceProviderHint &other)
211{
212 d = other.d;
213 return *this;
214}
215
216/*!
217 Identifies if \a other is of equal value to a media service provider hint.
218
219 Returns true if the hints are equal, and false if they are not.
220*/
221bool QMediaServiceProviderHint::operator == (const QMediaServiceProviderHint &other) const
222{
223 return (d == other.d) ||
224 (d->type == other.d->type &&
225 d->device == other.d->device &&
226 d->cameraPosition == other.d->cameraPosition &&
227 d->mimeType == other.d->mimeType &&
228 d->codecs == other.d->codecs &&
229 d->features == other.d->features);
230}
231
232/*!
233 Identifies if \a other is not of equal value to a media service provider hint.
234
235 Returns true if the hints are not equal, and false if they are.
236*/
237bool QMediaServiceProviderHint::operator != (const QMediaServiceProviderHint &other) const
238{
239 return !(*this == other);
240}
241
242/*!
243 Returns true if a media service provider is null.
244*/
245bool QMediaServiceProviderHint::isNull() const
246{
247 return d->type == Null;
248}
249
250/*!
251 Returns the type of a media service provider hint.
252*/
253QMediaServiceProviderHint::Type QMediaServiceProviderHint::type() const
254{
255 return d->type;
256}
257
258/*!
259 Returns the mime type of the media a service is expected to be able play.
260*/
261QString QMediaServiceProviderHint::mimeType() const
262{
263 return d->mimeType;
264}
265
266/*!
267 Returns a list of codes a media service is expected to be able to decode.
268*/
269QStringList QMediaServiceProviderHint::codecs() const
270{
271 return d->codecs;
272}
273
274/*!
275 Returns the name of a device a media service is expected to utilize.
276*/
277QByteArray QMediaServiceProviderHint::device() const
278{
279 return d->device;
280}
281
282/*!
283 \since 5.3
284
285 Returns the camera's position a media service is expected to utilize.
286*/
287QCamera::Position QMediaServiceProviderHint::cameraPosition() const
288{
289 return d->cameraPosition;
290}
291
292
293/*!
294 Returns a set of features a media service is expected to provide.
295*/
296QMediaServiceProviderHint::Features QMediaServiceProviderHint::features() const
297{
298 return d->features;
299}
300
301
302Q_GLOBAL_STATIC_WITH_ARGS(QMediaPluginLoader, loader,
303 (QMediaServiceProviderFactoryInterface_iid, QLatin1String("mediaservice"), Qt::CaseInsensitive))
304
305
306class QPluginServiceProvider : public QMediaServiceProvider
307{
308 struct MediaServiceData {
309 QByteArray type;
310 QMediaServiceProviderPlugin *plugin;
311
312 MediaServiceData() : plugin(nullptr) { }
313 };
314
315 QMap<const QMediaService*, MediaServiceData> mediaServiceData;
316
317public:
318 QMediaService* requestService(const QByteArray &type, const QMediaServiceProviderHint &hint) override
319 {
320 QString key(QLatin1String(type.constData()));
321
322 QList<QMediaServiceProviderPlugin *>plugins;
323 const auto instances = loader()->instances(key);
324 for (QObject *obj : instances) {
325 QMediaServiceProviderPlugin *plugin =
326 qobject_cast<QMediaServiceProviderPlugin*>(obj);
327 if (plugin)
328 plugins << plugin;
329 }
330
331 if (!plugins.isEmpty()) {
332 QMediaServiceProviderPlugin *plugin = nullptr;
333
334 switch (hint.type()) {
335 case QMediaServiceProviderHint::Null:
336 plugin = plugins[0];
337 //special case for media player, if low latency was not asked,
338 //prefer services not offering it, since they are likely to support
339 //more formats
340 if (type == QByteArray(Q_MEDIASERVICE_MEDIAPLAYER)) {
341 for (QMediaServiceProviderPlugin *currentPlugin : qAsConst(plugins)) {
342 QMediaServiceFeaturesInterface *iface =
343 qobject_cast<QMediaServiceFeaturesInterface*>(currentPlugin);
344
345 if (!iface || !(iface->supportedFeatures(type) &
346 QMediaServiceProviderHint::LowLatencyPlayback)) {
347 plugin = currentPlugin;
348 break;
349 }
350
351 }
352 }
353 break;
354 case QMediaServiceProviderHint::SupportedFeatures:
355 plugin = plugins[0];
356 for (QMediaServiceProviderPlugin *currentPlugin : qAsConst(plugins)) {
357 QMediaServiceFeaturesInterface *iface =
358 qobject_cast<QMediaServiceFeaturesInterface*>(currentPlugin);
359
360 if (iface) {
361 if ((iface->supportedFeatures(type) & hint.features()) == hint.features()) {
362 plugin = currentPlugin;
363 break;
364 }
365 }
366 }
367 break;
368 case QMediaServiceProviderHint::Device: {
369 plugin = plugins[0];
370 for (QMediaServiceProviderPlugin *currentPlugin : qAsConst(plugins)) {
371 QMediaServiceSupportedDevicesInterface *iface =
372 qobject_cast<QMediaServiceSupportedDevicesInterface*>(currentPlugin);
373
374 if (iface && iface->devices(type).contains(hint.device())) {
375 plugin = currentPlugin;
376 break;
377 }
378 }
379 }
380 break;
381 case QMediaServiceProviderHint::CameraPosition: {
382 plugin = plugins[0];
383 if (type == QByteArray(Q_MEDIASERVICE_CAMERA)
384 && hint.cameraPosition() != QCamera::UnspecifiedPosition) {
385 for (QMediaServiceProviderPlugin *currentPlugin : qAsConst(plugins)) {
386 const QMediaServiceSupportedDevicesInterface *deviceIface =
387 qobject_cast<QMediaServiceSupportedDevicesInterface*>(currentPlugin);
388 const QMediaServiceCameraInfoInterface *cameraIface =
389 qobject_cast<QMediaServiceCameraInfoInterface*>(currentPlugin);
390
391 if (deviceIface && cameraIface) {
392 const QList<QByteArray> cameras = deviceIface->devices(type);
393 for (const QByteArray &camera : cameras) {
394 if (cameraIface->cameraPosition(camera) == hint.cameraPosition()) {
395 plugin = currentPlugin;
396 break;
397 }
398 }
399 }
400 }
401 }
402 }
403 break;
404 case QMediaServiceProviderHint::ContentType: {
405 QMultimedia::SupportEstimate estimate = QMultimedia::NotSupported;
406 for (QMediaServiceProviderPlugin *currentPlugin : qAsConst(plugins)) {
407 QMultimedia::SupportEstimate currentEstimate = QMultimedia::MaybeSupported;
408 QMediaServiceSupportedFormatsInterface *iface =
409 qobject_cast<QMediaServiceSupportedFormatsInterface*>(currentPlugin);
410
411 if (iface)
412 currentEstimate = iface->hasSupport(hint.mimeType(), hint.codecs());
413
414 if (currentEstimate > estimate) {
415 estimate = currentEstimate;
416 plugin = currentPlugin;
417
418 if (currentEstimate == QMultimedia::PreferredService)
419 break;
420 }
421 }
422 }
423 break;
424 }
425
426 if (plugin != nullptr) {
427 QMediaService *service = plugin->create(key);
428 if (service != nullptr) {
429 MediaServiceData d;
430 d.type = type;
431 d.plugin = plugin;
432 mediaServiceData.insert(service, d);
433 }
434
435 return service;
436 }
437 }
438
439 qWarning() << "defaultServiceProvider::requestService(): no service found for -" << key;
440 return nullptr;
441 }
442
443 void releaseService(QMediaService *service) override
444 {
445 if (service != nullptr) {
446 MediaServiceData d = mediaServiceData.take(service);
447
448 if (d.plugin != nullptr)
449 d.plugin->release(service);
450 }
451 }
452
453 QMediaServiceProviderHint::Features supportedFeatures(const QMediaService *service) const override
454 {
455 if (service) {
456 MediaServiceData d = mediaServiceData.value(service);
457
458 if (d.plugin) {
459 QMediaServiceFeaturesInterface *iface =
460 qobject_cast<QMediaServiceFeaturesInterface*>(d.plugin);
461
462 if (iface)
463 return iface->supportedFeatures(d.type);
464 }
465 }
466
467 return QMediaServiceProviderHint::Features();
468 }
469
470 QMultimedia::SupportEstimate hasSupport(const QByteArray &serviceType,
471 const QString &mimeType,
472 const QStringList& codecs,
473 int flags) const override
474 {
475 const QList<QObject*> instances = loader()->instances(QLatin1String(serviceType));
476
477 if (instances.isEmpty())
478 return QMultimedia::NotSupported;
479
480 bool allServicesProvideInterface = true;
481 QMultimedia::SupportEstimate supportEstimate = QMultimedia::NotSupported;
482
483 for (QObject *obj : instances) {
484 QMediaServiceSupportedFormatsInterface *iface =
485 qobject_cast<QMediaServiceSupportedFormatsInterface*>(obj);
486
487
488 if (flags) {
489 QMediaServiceFeaturesInterface *iface =
490 qobject_cast<QMediaServiceFeaturesInterface*>(obj);
491
492 if (iface) {
493 QMediaServiceProviderHint::Features features = iface->supportedFeatures(serviceType);
494
495 //if low latency playback was asked, skip services known
496 //not to provide low latency playback
497 if ((flags & QMediaPlayer::LowLatency) &&
498 !(features & QMediaServiceProviderHint::LowLatencyPlayback))
499 continue;
500
501 //the same for QIODevice based streams support
502 if ((flags & QMediaPlayer::StreamPlayback) &&
503 !(features & QMediaServiceProviderHint::StreamPlayback))
504 continue;
505 }
506 }
507
508 if (iface)
509 supportEstimate = qMax(supportEstimate, iface->hasSupport(mimeType, codecs));
510 else
511 allServicesProvideInterface = false;
512 }
513
514 //don't return PreferredService
515 supportEstimate = qMin(supportEstimate, QMultimedia::ProbablySupported);
516
517 //Return NotSupported only if no services are available of serviceType
518 //or all the services returned NotSupported, otherwise return at least MaybeSupported
519 if (!allServicesProvideInterface)
520 supportEstimate = qMax(QMultimedia::MaybeSupported, supportEstimate);
521
522 return supportEstimate;
523 }
524
525 QStringList supportedMimeTypes(const QByteArray &serviceType, int flags) const override
526 {
527 const QList<QObject*> instances = loader()->instances(QLatin1String(serviceType));
528
529 QStringList supportedTypes;
530
531 for (QObject *obj : instances) {
532 QMediaServiceSupportedFormatsInterface *iface =
533 qobject_cast<QMediaServiceSupportedFormatsInterface*>(obj);
534
535
536 if (flags) {
537 QMediaServiceFeaturesInterface *iface =
538 qobject_cast<QMediaServiceFeaturesInterface*>(obj);
539
540 if (iface) {
541 QMediaServiceProviderHint::Features features = iface->supportedFeatures(serviceType);
542
543 // If low latency playback was asked for, skip MIME types from services known
544 // not to provide low latency playback
545 if ((flags & QMediaPlayer::LowLatency) &&
546 !(features & QMediaServiceProviderHint::LowLatencyPlayback))
547 continue;
548
549 //the same for QIODevice based streams support
550 if ((flags & QMediaPlayer::StreamPlayback) &&
551 !(features & QMediaServiceProviderHint::StreamPlayback))
552 continue;
553
554 //the same for QAbstractVideoSurface support
555 if ((flags & QMediaPlayer::VideoSurface) &&
556 !(features & QMediaServiceProviderHint::VideoSurface))
557 continue;
558 }
559 }
560
561 if (iface) {
562 supportedTypes << iface->supportedMimeTypes();
563 }
564 }
565
566 // Multiple services may support the same MIME type
567 supportedTypes.removeDuplicates();
568
569 return supportedTypes;
570 }
571
572 QByteArray defaultDevice(const QByteArray &serviceType) const override
573 {
574 const auto instances = loader()->instances(QLatin1String(serviceType));
575 for (QObject *obj : instances) {
576 const QMediaServiceDefaultDeviceInterface *iface =
577 qobject_cast<QMediaServiceDefaultDeviceInterface*>(obj);
578
579 if (iface) {
580 QByteArray name = iface->defaultDevice(serviceType);
581 if (!name.isEmpty())
582 return name;
583 }
584 }
585
586 // if QMediaServiceDefaultDeviceInterface is not implemented, return the
587 // first available device.
588 QList<QByteArray> devs = devices(serviceType);
589 if (!devs.isEmpty())
590 return devs.first();
591
592 return QByteArray();
593 }
594
595 QList<QByteArray> devices(const QByteArray &serviceType) const override
596 {
597 QList<QByteArray> res;
598
599 const auto instances = loader()->instances(QLatin1String(serviceType));
600 for (QObject *obj : instances) {
601 QMediaServiceSupportedDevicesInterface *iface =
602 qobject_cast<QMediaServiceSupportedDevicesInterface*>(obj);
603
604 if (iface) {
605 res.append(iface->devices(serviceType));
606 }
607 }
608
609 return res;
610 }
611
612 QString deviceDescription(const QByteArray &serviceType, const QByteArray &device) override
613 {
614 const auto instances = loader()->instances(QLatin1String(serviceType));
615 for (QObject *obj : instances) {
616 QMediaServiceSupportedDevicesInterface *iface =
617 qobject_cast<QMediaServiceSupportedDevicesInterface*>(obj);
618
619 if (iface) {
620 if (iface->devices(serviceType).contains(device))
621 return iface->deviceDescription(serviceType, device);
622 }
623 }
624
625 return QString();
626 }
627
628 QCamera::Position cameraPosition(const QByteArray &device) const override
629 {
630 const QByteArray serviceType(Q_MEDIASERVICE_CAMERA);
631 const auto instances = loader()->instances(QString::fromLatin1(serviceType));
632 for (QObject *obj : instances) {
633 const QMediaServiceSupportedDevicesInterface *deviceIface =
634 qobject_cast<QMediaServiceSupportedDevicesInterface*>(obj);
635 const QMediaServiceCameraInfoInterface *cameraIface =
636 qobject_cast<QMediaServiceCameraInfoInterface*>(obj);
637
638 if (cameraIface) {
639 if (deviceIface && !deviceIface->devices(serviceType).contains(device))
640 continue;
641 return cameraIface->cameraPosition(device);
642 }
643 }
644
645 return QCamera::UnspecifiedPosition;
646 }
647
648 int cameraOrientation(const QByteArray &device) const override
649 {
650 const QByteArray serviceType(Q_MEDIASERVICE_CAMERA);
651 const auto instances = loader()->instances(QString::fromLatin1(serviceType));
652 for (QObject *obj : instances) {
653 const QMediaServiceSupportedDevicesInterface *deviceIface =
654 qobject_cast<QMediaServiceSupportedDevicesInterface*>(obj);
655 const QMediaServiceCameraInfoInterface *cameraIface =
656 qobject_cast<QMediaServiceCameraInfoInterface*>(obj);
657
658 if (cameraIface) {
659 if (deviceIface && !deviceIface->devices(serviceType).contains(device))
660 continue;
661 return cameraIface->cameraOrientation(device);
662 }
663 }
664
665 return 0;
666 }
667};
668
669Q_GLOBAL_STATIC(QPluginServiceProvider, pluginProvider);
670
671/*!
672 \class QMediaServiceProvider
673 \ingroup multimedia
674 \ingroup multimedia_control
675 \ingroup multimedia_core
676
677 \internal
678
679 \brief The QMediaServiceProvider class provides an abstract allocator for media services.
680*/
681
682/*!
683 \fn QMediaServiceProvider::requestService(const QByteArray &type, const QMediaServiceProviderHint &hint)
684
685 Requests an instance of a \a type service which best matches the given \a
686 hint.
687
688 Returns a pointer to the requested service, or a null pointer if there is
689 no suitable service.
690
691 The returned service must be released with releaseService when it is
692 finished with.
693*/
694
695/*!
696 \fn QMediaServiceProvider::releaseService(QMediaService *service)
697
698 Releases a media \a service requested with requestService().
699*/
700
701/*!
702 \fn QMediaServiceProvider::supportedFeatures(const QMediaService *service) const
703
704 Returns the features supported by a given \a service.
705*/
706QMediaServiceProviderHint::Features QMediaServiceProvider::supportedFeatures(const QMediaService *service) const
707{
708 Q_UNUSED(service);
709
710 return QMediaServiceProviderHint::Features(nullptr);
711}
712
713/*!
714 Returns how confident a media service provider is that is can provide a \a
715 serviceType service that is able to play media of a specific \a mimeType
716 that is encoded using the listed \a codecs while adhering to constraints
717 identified in \a flags.
718*/
719QMultimedia::SupportEstimate QMediaServiceProvider::hasSupport(const QByteArray &serviceType,
720 const QString &mimeType,
721 const QStringList& codecs,
722 int flags) const
723{
724 Q_UNUSED(serviceType);
725 Q_UNUSED(mimeType);
726 Q_UNUSED(codecs);
727 Q_UNUSED(flags);
728
729 return QMultimedia::MaybeSupported;
730}
731
732/*!
733 \fn QStringList QMediaServiceProvider::supportedMimeTypes(const QByteArray &serviceType, int flags) const
734
735 Returns a list of MIME types supported by the service provider for the
736 specified \a serviceType.
737
738 The resultant list is restricted to MIME types which can be supported given
739 the constraints in \a flags.
740*/
741QStringList QMediaServiceProvider::supportedMimeTypes(const QByteArray &serviceType, int flags) const
742{
743 Q_UNUSED(serviceType);
744 Q_UNUSED(flags);
745
746 return QStringList();
747}
748
749/*!
750 \since 5.3
751
752 Returns the default device for a \a service type.
753*/
754QByteArray QMediaServiceProvider::defaultDevice(const QByteArray &serviceType) const
755{
756 Q_UNUSED(serviceType);
757 return QByteArray();
758}
759
760/*!
761 Returns the list of devices related to \a service type.
762*/
763QList<QByteArray> QMediaServiceProvider::devices(const QByteArray &service) const
764{
765 Q_UNUSED(service);
766 return QList<QByteArray>();
767}
768
769/*!
770 Returns the description of \a device related to \a serviceType, suitable for use by
771 an application for display.
772*/
773QString QMediaServiceProvider::deviceDescription(const QByteArray &serviceType, const QByteArray &device)
774{
775 Q_UNUSED(serviceType);
776 Q_UNUSED(device);
777 return QString();
778}
779
780/*!
781 \since 5.3
782
783 Returns the physical position of a camera \a device on the system hardware.
784*/
785QCamera::Position QMediaServiceProvider::cameraPosition(const QByteArray &device) const
786{
787 Q_UNUSED(device);
788 return QCamera::UnspecifiedPosition;
789}
790
791/*!
792 \since 5.3
793
794 Returns the physical orientation of the camera \a device. The value is the angle by which the
795 camera image should be rotated anti-clockwise (in steps of 90 degrees) so it shows correctly on
796 the display in its natural orientation.
797*/
798int QMediaServiceProvider::cameraOrientation(const QByteArray &device) const
799{
800 Q_UNUSED(device);
801 return 0;
802}
803
804static QMediaServiceProvider *qt_defaultMediaServiceProvider = nullptr;
805
806/*!
807 Sets a media service \a provider as the default.
808 It's useful for unit tests to provide mock service.
809
810 \internal
811*/
812void QMediaServiceProvider::setDefaultServiceProvider(QMediaServiceProvider *provider)
813{
814 qt_defaultMediaServiceProvider = provider;
815}
816
817
818/*!
819 Returns a default provider of media services.
820*/
821QMediaServiceProvider *QMediaServiceProvider::defaultServiceProvider()
822{
823 return qt_defaultMediaServiceProvider != nullptr
824 ? qt_defaultMediaServiceProvider
825 : static_cast<QMediaServiceProvider *>(pluginProvider());
826}
827
828/*!
829 \class QMediaServiceProviderPlugin
830 \inmodule QtMultimedia
831 \brief The QMediaServiceProviderPlugin class interface provides an interface for QMediaService
832 plug-ins.
833
834 A media service provider plug-in may implement one or more of
835 QMediaServiceSupportedFormatsInterface,
836 QMediaServiceSupportedDevicesInterface, and QMediaServiceFeaturesInterface
837 to identify the features it supports.
838*/
839
840/*!
841 \fn QMediaServiceProviderPlugin::create(const QString &key)
842
843 Constructs a new instance of the QMediaService identified by \a key.
844
845 The QMediaService returned must be destroyed with release().
846*/
847
848/*!
849 \fn QMediaServiceProviderPlugin::release(QMediaService *service)
850
851 Destroys a media \a service constructed with create().
852*/
853
854
855/*!
856 \class QMediaServiceSupportedFormatsInterface
857 \inmodule QtMultimedia
858 \brief The QMediaServiceSupportedFormatsInterface class interface
859 identifies if a media service plug-in supports a media format.
860
861 A QMediaServiceProviderPlugin may implement this interface.
862*/
863
864/*!
865 \fn QMediaServiceSupportedFormatsInterface::~QMediaServiceSupportedFormatsInterface()
866
867 Destroys a media service supported formats interface.
868*/
869
870/*!
871 \fn QMediaServiceSupportedFormatsInterface::hasSupport(const QString &mimeType, const QStringList& codecs) const
872
873 Returns the level of support a media service plug-in has for a \a mimeType
874 and set of \a codecs.
875*/
876
877/*!
878 \fn QMediaServiceSupportedFormatsInterface::supportedMimeTypes() const
879
880 Returns a list of MIME types supported by the media service plug-in.
881*/
882
883/*!
884 \class QMediaServiceSupportedDevicesInterface
885 \inmodule QtMultimedia
886 \brief The QMediaServiceSupportedDevicesInterface class interface
887 identifies the devices supported by a media service plug-in.
888
889 A QMediaServiceProviderPlugin may implement this interface.
890*/
891
892/*!
893 \fn QMediaServiceSupportedDevicesInterface::~QMediaServiceSupportedDevicesInterface()
894
895 Destroys a media service supported devices interface.
896*/
897
898/*!
899 \fn QList<QByteArray> QMediaServiceSupportedDevicesInterface::devices(const QByteArray &service) const
900
901 Returns a list of devices available for a \a service type.
902*/
903
904/*!
905 \fn QString QMediaServiceSupportedDevicesInterface::deviceDescription(const QByteArray &service, const QByteArray &device)
906
907 Returns the description of a \a device available for a \a service type.
908*/
909
910/*!
911 \class QMediaServiceDefaultDeviceInterface
912 \inmodule QtMultimedia
913 \brief The QMediaServiceDefaultDeviceInterface class interface
914 identifies the default device used by a media service plug-in.
915
916 A QMediaServiceProviderPlugin may implement this interface.
917
918 \since 5.3
919*/
920
921/*!
922 \fn QMediaServiceDefaultDeviceInterface::~QMediaServiceDefaultDeviceInterface()
923
924 Destroys a media service default device interface.
925*/
926
927/*!
928 \fn QByteArray QMediaServiceDefaultDeviceInterface::defaultDevice(const QByteArray &service) const
929
930 Returns the default device for a \a service type.
931*/
932
933/*!
934 \class QMediaServiceCameraInfoInterface
935 \inmodule QtMultimedia
936 \since 5.3
937 \brief The QMediaServiceCameraInfoInterface class interface
938 provides camera-specific information about devices supported by a camera service plug-in.
939
940 A QMediaServiceProviderPlugin may implement this interface, in that case it also needs to
941 implement the QMediaServiceSupportedDevicesInterface.
942*/
943
944/*!
945 \fn QMediaServiceCameraInfoInterface::~QMediaServiceCameraInfoInterface()
946
947 Destroys a media service camera info interface.
948*/
949
950/*!
951 \fn QMediaServiceCameraInfoInterface::cameraPosition(const QByteArray &device) const
952
953 Returns the physical position of a camera \a device supported by a camera service plug-in.
954*/
955
956/*!
957 \fn QMediaServiceCameraInfoInterface::cameraOrientation(const QByteArray &device) const
958
959 Returns the physical orientation of a camera \a device supported by a camera service plug-in.
960*/
961
962/*!
963 \class QMediaServiceFeaturesInterface
964 \inmodule QtMultimedia
965 \brief The QMediaServiceFeaturesInterface class interface identifies
966 features supported by a media service plug-in.
967
968 A QMediaServiceProviderPlugin may implement this interface.
969*/
970
971/*!
972 \fn QMediaServiceFeaturesInterface::~QMediaServiceFeaturesInterface()
973
974 Destroys a media service features interface.
975*/
976/*!
977 \fn QMediaServiceFeaturesInterface::supportedFeatures(const QByteArray &service) const
978
979 Returns a set of features supported by a plug-in \a service.
980*/
981
982#include "moc_qmediaserviceprovider_p.cpp"
983#include "moc_qmediaserviceproviderplugin.cpp"
984QT_END_NAMESPACE
985
986