From fec653b6f4402e70ee6d11f8beba070ece0b3d8d Mon Sep 17 00:00:00 2001 From: James McDonnell Date: Mon, 27 Mar 2017 14:59:06 -0400 Subject: Add custom audio role API to QMediaPlayer Allows use of audio roles beyond those known to Qt. [ChangeLog][QMediaPlayer] Added customAudioRole string property to enable use of audio roles beyond those available via the audioRole enum property. Change-Id: Id7ed5d7bc1af0c15910e699f25c97cfed2d48243 Reviewed-by: Christian Stromme Reviewed-by: Rafael Roquetto --- src/multimedia/audio/qaudio.cpp | 4 + src/multimedia/audio/qaudio.h | 3 +- src/multimedia/controls/controls.pri | 7 +- .../controls/qcustomaudiorolecontrol.cpp | 117 +++++++++++++++++++++ src/multimedia/controls/qcustomaudiorolecontrol.h | 76 +++++++++++++ src/multimedia/playback/qmediaplayer.cpp | 90 +++++++++++++++- src/multimedia/playback/qmediaplayer.h | 7 +- src/plugins/qnx/mediaplayer/mmrendererutil.cpp | 8 +- 8 files changed, 305 insertions(+), 7 deletions(-) create mode 100644 src/multimedia/controls/qcustomaudiorolecontrol.cpp create mode 100644 src/multimedia/controls/qcustomaudiorolecontrol.h (limited to 'src') diff --git a/src/multimedia/audio/qaudio.cpp b/src/multimedia/audio/qaudio.cpp index dea9a05a5..82613270a 100644 --- a/src/multimedia/audio/qaudio.cpp +++ b/src/multimedia/audio/qaudio.cpp @@ -115,6 +115,7 @@ Q_CONSTRUCTOR_FUNCTION(qRegisterAudioMetaTypes) \value AccessibilityRole For accessibility, such as with a screen reader \value SonificationRole Sonification, such as with user interface sounds \value GameRole Game audio + \value CustomRole The role is specified by QMediaPlayer::customAudioRole() \since 5.6 \sa QMediaPlayer::setAudioRole() @@ -347,6 +348,9 @@ QDebug operator<<(QDebug dbg, QAudio::Role role) case QAudio::VoiceCommunicationRole: dbg << "VoiceCommunicationRole"; break; + case QAudio::CustomRole: + dbg << "CustomRole"; + break; } return dbg; } diff --git a/src/multimedia/audio/qaudio.h b/src/multimedia/audio/qaudio.h index 2603d71d1..90a8c236f 100644 --- a/src/multimedia/audio/qaudio.h +++ b/src/multimedia/audio/qaudio.h @@ -68,7 +68,8 @@ namespace QAudio RingtoneRole, AccessibilityRole, SonificationRole, - GameRole + GameRole, + CustomRole }; enum VolumeScale { diff --git a/src/multimedia/controls/controls.pri b/src/multimedia/controls/controls.pri index 7ab2e51c4..cfebe9777 100644 --- a/src/multimedia/controls/controls.pri +++ b/src/multimedia/controls/controls.pri @@ -37,7 +37,8 @@ PUBLIC_HEADERS += \ controls/qmediaaudioprobecontrol.h \ controls/qmediavideoprobecontrol.h \ controls/qmediaavailabilitycontrol.h \ - controls/qaudiorolecontrol.h + controls/qaudiorolecontrol.h \ + controls/qcustomaudiorolecontrol.h PRIVATE_HEADERS += \ controls/qmediaplaylistcontrol_p.h \ @@ -81,5 +82,5 @@ SOURCES += \ controls/qaudioinputselectorcontrol.cpp \ controls/qaudiooutputselectorcontrol.cpp \ controls/qvideodeviceselectorcontrol.cpp \ - controls/qaudiorolecontrol.cpp - + controls/qaudiorolecontrol.cpp \ + controls/qcustomaudiorolecontrol.cpp diff --git a/src/multimedia/controls/qcustomaudiorolecontrol.cpp b/src/multimedia/controls/qcustomaudiorolecontrol.cpp new file mode 100644 index 000000000..c01fc430c --- /dev/null +++ b/src/multimedia/controls/qcustomaudiorolecontrol.cpp @@ -0,0 +1,117 @@ +/**************************************************************************** +** +** Copyright (C) 2017 QNX Software Systems. All rights reserved. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qmediacontrol_p.h" +#include "qcustomaudiorolecontrol.h" + +QT_BEGIN_NAMESPACE + +/*! + \class QCustomAudioRoleControl + \inmodule QtMultimedia + \ingroup multimedia_control + \since 5.10 + + \brief The QCustomAudioRoleControl class provides control over the audio role of a media object. + + If a QMediaService supports audio roles it may implement QCustomAudioRoleControl in order to + provide access to roles unknown to Qt. + + The functionality provided by this control is exposed to application code through the + QMediaPlayer class. + + The interface name of QCustomAudioRoleControl is \c org.qt-project.qt.customaudiorolecontrol/5.10 as + defined in QCustomAudioRoleControl_iid. + + \sa QMediaService::requestControl(), QMediaPlayer +*/ + +/*! + \macro QCustomAudioRoleControl_iid + + \c org.qt-project.qt.customaudiorolecontrol/5.10 + + Defines the interface name of the QCustomAudioRoleControl class. + + \relates QCustomAudioRoleControl +*/ + +/*! + Construct a QCustomAudioRoleControl with the given \a parent. +*/ +QCustomAudioRoleControl::QCustomAudioRoleControl(QObject *parent) + : QMediaControl(*new QMediaControlPrivate, parent) +{ +} + +/*! + Destroys the audio role control. +*/ +QCustomAudioRoleControl::~QCustomAudioRoleControl() +{ +} + +/*! + \fn QAudio::Role QCustomAudioRoleControl::customAudioRole() const + + Returns the audio role of the media played by the media service. +*/ + +/*! + \fn void QCustomAudioRoleControl::setCustomAudioRole(const QString &role) + + Sets the audio \a role of the media played by the media service. +*/ + +/*! + \fn QStringList QCustomAudioRoleControl::supportedCustomAudioRoles() const + + Returns a list of custom audio roles that the media service supports. An + empty list may indicate that the supported custom audio roles aren't known. + The list may not be complete. +*/ + +/*! + \fn void QCustomAudioRoleControl::customAudioRoleChanged(const QString &role) + + Signal emitted when the audio \a role has changed. + */ + +#include "moc_qcustomaudiorolecontrol.cpp" +QT_END_NAMESPACE diff --git a/src/multimedia/controls/qcustomaudiorolecontrol.h b/src/multimedia/controls/qcustomaudiorolecontrol.h new file mode 100644 index 000000000..d699afe4e --- /dev/null +++ b/src/multimedia/controls/qcustomaudiorolecontrol.h @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2017 QNX Software Systems. All rights reserved. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QCUSTOMAUDIOROLECONTROL_H +#define QCUSTOMAUDIOROLECONTROL_H + +#include +#include + +QT_BEGIN_NAMESPACE + +// Class forward declaration required for QDoc bug +class QString; +class QStringList; + +class Q_MULTIMEDIA_EXPORT QCustomAudioRoleControl : public QMediaControl +{ + Q_OBJECT + +public: + virtual ~QCustomAudioRoleControl(); + + virtual QString customAudioRole() const = 0; + virtual void setCustomAudioRole(const QString &role) = 0; + + virtual QStringList supportedCustomAudioRoles() const = 0; + +Q_SIGNALS: + void customAudioRoleChanged(const QString &role); + +protected: + explicit QCustomAudioRoleControl(QObject *parent = nullptr); +}; + +#define QCustomAudioRoleControl_iid "org.qt-project.qt.customaudiorolecontrol/5.10" +Q_MEDIA_DECLARE_CONTROL(QCustomAudioRoleControl, QCustomAudioRoleControl_iid) + +QT_END_NAMESPACE + +#endif // QCUSTOMAUDIOROLECONTROL_H diff --git a/src/multimedia/playback/qmediaplayer.cpp b/src/multimedia/playback/qmediaplayer.cpp index 16fdec8ea..e1fa31451 100644 --- a/src/multimedia/playback/qmediaplayer.cpp +++ b/src/multimedia/playback/qmediaplayer.cpp @@ -49,6 +49,7 @@ #include #include #include +#include #include #include @@ -111,6 +112,7 @@ public: : provider(0) , control(0) , audioRoleControl(0) + , customAudioRoleControl(0) , playlist(0) , networkAccessControl(0) , state(QMediaPlayer::StoppedState) @@ -124,6 +126,7 @@ public: QMediaServiceProvider *provider; QMediaPlayerControl* control; QAudioRoleControl *audioRoleControl; + QCustomAudioRoleControl *customAudioRoleControl; QString errorString; QPointer videoOutput; @@ -616,6 +619,15 @@ QMediaPlayer::QMediaPlayer(QObject *parent, QMediaPlayer::Flags flags): if (d->audioRoleControl) { connect(d->audioRoleControl, &QAudioRoleControl::audioRoleChanged, this, &QMediaPlayer::audioRoleChanged); + + d->customAudioRoleControl = qobject_cast( + d->service->requestControl(QCustomAudioRoleControl_iid)); + if (d->customAudioRoleControl) { + connect(d->customAudioRoleControl, + &QCustomAudioRoleControl::customAudioRoleChanged, + this, + &QMediaPlayer::customAudioRoleChanged); + } } } if (d->networkAccessControl != 0) { @@ -641,6 +653,8 @@ QMediaPlayer::~QMediaPlayer() d->service->releaseControl(d->control); if (d->audioRoleControl) d->service->releaseControl(d->audioRoleControl); + if (d->customAudioRoleControl) + d->service->releaseControl(d->customAudioRoleControl); d->provider->releaseService(d->service); } @@ -1150,8 +1164,13 @@ void QMediaPlayer::setAudioRole(QAudio::Role audioRole) { Q_D(QMediaPlayer); - if (d->audioRoleControl) + if (d->audioRoleControl) { + if (d->customAudioRoleControl != nullptr && d->audioRoleControl->audioRole() != audioRole) { + d->customAudioRoleControl->setCustomAudioRole(QString()); + } + d->audioRoleControl->setAudioRole(audioRole); + } } /*! @@ -1172,6 +1191,48 @@ QList QMediaPlayer::supportedAudioRoles() const return QList(); } +QString QMediaPlayer::customAudioRole() const +{ + Q_D(const QMediaPlayer); + + if (audioRole() != QAudio::CustomRole) + return QString(); + + if (d->customAudioRoleControl != nullptr) + return d->customAudioRoleControl->customAudioRole(); + + return QString(); +} + +void QMediaPlayer::setCustomAudioRole(const QString &audioRole) +{ + Q_D(QMediaPlayer); + + if (d->customAudioRoleControl) { + Q_ASSERT(d->audioRoleControl); + setAudioRole(QAudio::CustomRole); + d->customAudioRoleControl->setCustomAudioRole(audioRole); + } +} + +/*! + Returns a list of supported custom audio roles. An empty list may + indicate that the supported custom audio roles aren't known. The + list may not be complete. + + \since 5.10 + \sa customAudioRole +*/ +QStringList QMediaPlayer::supportedCustomAudioRoles() const +{ + Q_D(const QMediaPlayer); + + if (d->customAudioRoleControl) + return d->customAudioRoleControl->supportedCustomAudioRoles(); + + return QStringList(); +} + // Enums /*! \enum QMediaPlayer::State @@ -1279,6 +1340,14 @@ QList QMediaPlayer::supportedAudioRoles() const \since 5.6 */ +/*! + \fn void QMediaPlayer::customAudioRoleChanged(const QString &role) + + Signals that the audio \a role of the media player has changed. + + \since 5.10 +*/ + // Properties /*! \property QMediaPlayer::state @@ -1461,10 +1530,29 @@ QList QMediaPlayer::supportedAudioRoles() const The audio role must be set before calling setMedia(). + customAudioRole is cleared when this property is set to anything other than + QAudio::CustomRole. + \since 5.6 \sa supportedAudioRoles() */ +/*! + \property QMediaPlayer::customAudioRole + \brief the role of the audio stream played by the media player. + + It can be set to specify the type of audio being played when the backend supports + audio roles unknown to Qt. Specifying a role allows the system to make appropriate + decisions when it comes to volume, routing or post-processing. + + The audio role must be set before calling setMedia(). + + audioRole is set to QAudio::CustomRole when this property is set. + + \since 5.10 + \sa supportedCustomAudioRoles() +*/ + /*! \fn void QMediaPlayer::durationChanged(qint64 duration) diff --git a/src/multimedia/playback/qmediaplayer.h b/src/multimedia/playback/qmediaplayer.h index f23a94104..4e676a2d8 100644 --- a/src/multimedia/playback/qmediaplayer.h +++ b/src/multimedia/playback/qmediaplayer.h @@ -73,7 +73,8 @@ class Q_MULTIMEDIA_EXPORT QMediaPlayer : public QMediaObject Q_PROPERTY(qreal playbackRate READ playbackRate WRITE setPlaybackRate NOTIFY playbackRateChanged) Q_PROPERTY(State state READ state NOTIFY stateChanged) Q_PROPERTY(MediaStatus mediaStatus READ mediaStatus NOTIFY mediaStatusChanged) - Q_PROPERTY(QAudio::Role audioRole READ audioRole WRITE setAudioRole) + Q_PROPERTY(QAudio::Role audioRole READ audioRole WRITE setAudioRole NOTIFY audioRoleChanged) + Q_PROPERTY(QString customAudioRole READ customAudioRole WRITE setCustomAudioRole NOTIFY customAudioRoleChanged) Q_PROPERTY(QString error READ errorString) Q_ENUMS(State) Q_ENUMS(MediaStatus) @@ -162,6 +163,9 @@ public: QAudio::Role audioRole() const; void setAudioRole(QAudio::Role audioRole); QList supportedAudioRoles() const; + QString customAudioRole() const; + void setCustomAudioRole(const QString &audioRole); + QStringList supportedCustomAudioRoles() const; public Q_SLOTS: void play(); @@ -200,6 +204,7 @@ Q_SIGNALS: void playbackRateChanged(qreal rate); void audioRoleChanged(QAudio::Role role); + void customAudioRoleChanged(const QString &role); void error(QMediaPlayer::Error error); diff --git a/src/plugins/qnx/mediaplayer/mmrendererutil.cpp b/src/plugins/qnx/mediaplayer/mmrendererutil.cpp index 7a9f6393b..d8af4a746 100644 --- a/src/plugins/qnx/mediaplayer/mmrendererutil.cpp +++ b/src/plugins/qnx/mediaplayer/mmrendererutil.cpp @@ -92,7 +92,7 @@ static const unsigned int numMmErrors = sizeof(mmErrors) / sizeof(MmError); static QBasicMutex roleMapMutex; static bool roleMapInitialized = false; -static QString roleMap[QAudio::GameRole + 1]; +static QString roleMap[QAudio::CustomRole + 1]; template constexpr size_t countof(T (&)[N]) @@ -166,9 +166,15 @@ static void loadRoleMap() loadRoleMapping(AccessibilityRole); loadRoleMapping(SonificationRole); loadRoleMapping(GameRole); + loadRoleMapping(CustomRole); } #undef loadRoleMapping #pragma GCC diagnostic pop + + if (!roleMap[QAudio::CustomRole].isEmpty()) { + qWarning("CustomRole mapping ignored"); + roleMap[QAudio::CustomRole].clear(); + } } roleMapInitialized = true; -- cgit v1.2.3