diff options
70 files changed, 864 insertions, 320 deletions
diff --git a/.qmake.conf b/.qmake.conf index 33a2710f6..aa9ded07b 100644 --- a/.qmake.conf +++ b/.qmake.conf @@ -1,4 +1,4 @@ load(qt_build_config) CONFIG += qt_example_installs -MODULE_VERSION = 5.7.0 +MODULE_VERSION = 5.8.0 diff --git a/config.tests/directshow/directshow.pro b/config.tests/directshow/directshow.pro index 6dfc54a01..6493e54ab 100644 --- a/config.tests/directshow/directshow.pro +++ b/config.tests/directshow/directshow.pro @@ -3,4 +3,4 @@ CONFIG += console SOURCES += main.cpp -!wince: LIBS += -lstrmiids -ldmoguids -luuid -lmsdmo -lole32 -loleaut32 +LIBS += -lstrmiids -ldmoguids -luuid -lmsdmo -lole32 -loleaut32 diff --git a/config.tests/directshow/main.cpp b/config.tests/directshow/main.cpp index bb9a304ec..25e36f966 100644 --- a/config.tests/directshow/main.cpp +++ b/config.tests/directshow/main.cpp @@ -27,10 +27,8 @@ ****************************************************************************/ #include <dshow.h> -#ifndef _WIN32_WCE #include <d3d9.h> #include <vmr9.h> -#endif int main(int, char**) { diff --git a/examples/multimedia/audioinput/audioinput.cpp b/examples/multimedia/audioinput/audioinput.cpp index fd73d4f16..da5966598 100644 --- a/examples/multimedia/audioinput/audioinput.cpp +++ b/examples/multimedia/audioinput/audioinput.cpp @@ -315,7 +315,10 @@ void InputTest::initializeAudio() void InputTest::createAudioInput() { m_audioInput = new QAudioInput(m_device, m_format, this); - m_volumeSlider->setValue(m_audioInput->volume() * 100); + qreal initialVolume = QAudio::convertVolume(m_audioInput->volume(), + QAudio::LinearVolumeScale, + QAudio::CubicVolumeScale); + m_volumeSlider->setValue(qRound(initialVolume * 100)); m_audioInfo->start(); m_audioInput->start(m_audioInfo); } @@ -386,6 +389,11 @@ void InputTest::deviceChanged(int index) void InputTest::sliderChanged(int value) { - if (m_audioInput) - m_audioInput->setVolume(qreal(value) / 100); + if (m_audioInput) { + qreal linearVolume = QAudio::convertVolume(value / qreal(100), + QAudio::CubicVolumeScale, + QAudio::LinearVolumeScale); + + m_audioInput->setVolume(linearVolume); + } } diff --git a/examples/multimedia/audiooutput/audiooutput.cpp b/examples/multimedia/audiooutput/audiooutput.cpp index a00ffbb00..79e70bdc2 100644 --- a/examples/multimedia/audiooutput/audiooutput.cpp +++ b/examples/multimedia/audiooutput/audiooutput.cpp @@ -250,7 +250,11 @@ void AudioTest::createAudioOutput() m_audioOutput = new QAudioOutput(m_device, m_format, this); m_generator->start(); m_audioOutput->start(m_generator); - m_volumeSlider->setValue(int(m_audioOutput->volume()*100.0f)); + + qreal initialVolume = QAudio::convertVolume(m_audioOutput->volume(), + QAudio::LinearVolumeScale, + QAudio::CubicVolumeScale); + m_volumeSlider->setValue(qRound(initialVolume * 100)); } AudioTest::~AudioTest() @@ -270,8 +274,13 @@ void AudioTest::deviceChanged(int index) void AudioTest::volumeChanged(int value) { - if (m_audioOutput) - m_audioOutput->setVolume(qreal(value/100.0f)); + if (m_audioOutput) { + qreal linearVolume = QAudio::convertVolume(value / qreal(100), + QAudio::CubicVolumeScale, + QAudio::LinearVolumeScale); + + m_audioOutput->setVolume(linearVolume); + } } void AudioTest::pushTimerExpired() diff --git a/examples/multimediawidgets/player/playercontrols.cpp b/examples/multimediawidgets/player/playercontrols.cpp index 07aa2e731..80abf59b6 100644 --- a/examples/multimediawidgets/player/playercontrols.cpp +++ b/examples/multimediawidgets/player/playercontrols.cpp @@ -45,6 +45,7 @@ #include <QStyle> #include <QToolButton> #include <QComboBox> +#include <QAudio> PlayerControls::PlayerControls(QWidget *parent) : QWidget(parent) @@ -87,7 +88,7 @@ PlayerControls::PlayerControls(QWidget *parent) volumeSlider = new QSlider(Qt::Horizontal, this); volumeSlider->setRange(0, 100); - connect(volumeSlider, SIGNAL(sliderMoved(int)), this, SIGNAL(changeVolume(int))); + connect(volumeSlider, SIGNAL(valueChanged(int)), this, SLOT(onVolumeSliderValueChanged())); rateBox = new QComboBox(this); rateBox->addItem("0.5x", QVariant(0.5)); @@ -138,13 +139,20 @@ void PlayerControls::setState(QMediaPlayer::State state) int PlayerControls::volume() const { - return volumeSlider ? volumeSlider->value() : 0; + qreal linearVolume = QAudio::convertVolume(volumeSlider->value() / qreal(100), + QAudio::CubicVolumeScale, + QAudio::LinearVolumeScale); + + return qRound(linearVolume * 100); } void PlayerControls::setVolume(int volume) { - if (volumeSlider) - volumeSlider->setValue(volume); + qreal cubicVolume = QAudio::convertVolume(volume / qreal(100), + QAudio::LinearVolumeScale, + QAudio::CubicVolumeScale); + + volumeSlider->setValue(qRound(cubicVolume * 100)); } bool PlayerControls::isMuted() const @@ -203,3 +211,8 @@ void PlayerControls::updateRate() { emit changeRate(playbackRate()); } + +void PlayerControls::onVolumeSliderValueChanged() +{ + emit changeVolume(volume()); +} diff --git a/examples/multimediawidgets/player/playercontrols.h b/examples/multimediawidgets/player/playercontrols.h index 0ab195faa..d29a06d6c 100644 --- a/examples/multimediawidgets/player/playercontrols.h +++ b/examples/multimediawidgets/player/playercontrols.h @@ -82,6 +82,7 @@ private slots: void playClicked(); void muteClicked(); void updateRate(); + void onVolumeSliderValueChanged(); private: QMediaPlayer::State playerState; diff --git a/src/imports/multimedia/qdeclarativemultimediaglobal.cpp b/src/imports/multimedia/qdeclarativemultimediaglobal.cpp index b2a1aed12..bb1b9c9d8 100644 --- a/src/imports/multimedia/qdeclarativemultimediaglobal.cpp +++ b/src/imports/multimedia/qdeclarativemultimediaglobal.cpp @@ -183,4 +183,55 @@ QJSValue QDeclarativeMultimediaGlobal::availableCameras() const return availableCameras; } +/*! + \qmlmethod real QtMultimedia::QtMultimedia::convertVolume(real volume, VolumeScale from, VolumeScale to) + + Converts an audio \a volume \a from a volume scale \a to another, and returns the result. + + Depending on the context, different scales are used to represent audio volume. All Qt Multimedia + classes that have an audio volume use a linear scale, the reason is that the loudness of a + speaker is controlled by modulating its voltage on a linear scale. The human ear on the other + hand, perceives loudness in a logarithmic way. That is why the decibel scale, being a logarithmic + scale, is typically used to define sound levels. UI volume controls in professional audio + applications usually use a decibel scale. The cubic scale is a computationally cheap + approximation of a logarithmic scale, most applications should use a cubic scale for their UI + volume controls. + + Valid values for \a from and \a to are: + \list + \li QtMultimedia.LinearVolumeScale - Linear scale. \c 0.0 (0%) is silence and \c 1.0 (100%) is + full volume. All Qt Multimedia types that have an audio volume use a linear scale. + \li QtMultimedia.CubicVolumeScale - Cubic scale. \c 0.0 (0%) is silence and \c 1.0 (100%) is full + volume. UI volume controls should usually use a cubic scale. + \li QtMultimedia.DecibelVolumeScale - Decibel (dB, amplitude) logarithmic scale. \c -200 is + silence and \c 0 is full volume. + \endlist + + The following example shows how the volume value from a UI volume control can be converted so + that the perceived increase in loudness is the same when increasing the volume control from 0.2 + to 0.3 as it is from 0.5 to 0.6: + + \code + Slider { + id: volumeSlider + + property real volume: QtMultimedia.convertVolume(volumeSlider.value, + QtMultimedia.CubicVolumeScale, + QtMultimedia.LinearVolumeScale) + } + + MediaPlayer { + volume: volumeSlider.volume + } + \endcode + + \since 5.8 +*/ +qreal QDeclarativeMultimediaGlobal::convertVolume(qreal volume, + QDeclarativeMultimediaGlobal::VolumeScale from, + QDeclarativeMultimediaGlobal::VolumeScale to) const +{ + return QAudio::convertVolume(volume, QAudio::VolumeScale(from), QAudio::VolumeScale(to)); +} + QT_END_NAMESPACE diff --git a/src/imports/multimedia/qdeclarativemultimediaglobal_p.h b/src/imports/multimedia/qdeclarativemultimediaglobal_p.h index 2374b560c..a8413cc09 100644 --- a/src/imports/multimedia/qdeclarativemultimediaglobal_p.h +++ b/src/imports/multimedia/qdeclarativemultimediaglobal_p.h @@ -53,6 +53,7 @@ #include <QtQml/qqml.h> #include <QtQml/qjsvalue.h> +#include <QtMultimedia/qaudio.h> QT_BEGIN_NAMESPACE @@ -63,12 +64,22 @@ class QDeclarativeMultimediaGlobal : public QObject Q_PROPERTY(QJSValue defaultCamera READ defaultCamera NOTIFY defaultCameraChanged) Q_PROPERTY(QJSValue availableCameras READ availableCameras NOTIFY availableCamerasChanged) + Q_ENUMS(VolumeScale) + public: + enum VolumeScale { + LinearVolumeScale = QAudio::LinearVolumeScale, + CubicVolumeScale = QAudio::CubicVolumeScale, + DecibelVolumeScale = QAudio::DecibelVolumeScale + }; + explicit QDeclarativeMultimediaGlobal(QJSEngine *engine, QObject *parent = 0); QJSValue defaultCamera() const; QJSValue availableCameras() const; + Q_INVOKABLE qreal convertVolume(qreal volume, VolumeScale from, VolumeScale to) const; + Q_SIGNALS: // Unused at the moment. QCameraInfo doesn't notify when cameras are added or removed, // but it might change in the future. diff --git a/src/multimedia/audio/audio.pri b/src/multimedia/audio/audio.pri index 96cfb1ce4..4706fd23e 100644 --- a/src/multimedia/audio/audio.pri +++ b/src/multimedia/audio/audio.pri @@ -19,7 +19,8 @@ PRIVATE_HEADERS += \ audio/qaudiodevicefactory_p.h \ audio/qwavedecoder_p.h \ audio/qsamplecache_p.h \ - audio/qaudiohelpers_p.h + audio/qaudiohelpers_p.h \ + audio/qaudiosystempluginext_p.h SOURCES += \ audio/qaudio.cpp \ diff --git a/src/multimedia/audio/qaudio.cpp b/src/multimedia/audio/qaudio.cpp index c708fa4f8..426c984df 100644 --- a/src/multimedia/audio/qaudio.cpp +++ b/src/multimedia/audio/qaudio.cpp @@ -39,6 +39,7 @@ #include <qaudio.h> +#include <qmath.h> #include <QDebug> QT_BEGIN_NAMESPACE @@ -49,6 +50,7 @@ static void qRegisterAudioMetaTypes() qRegisterMetaType<QAudio::State>(); qRegisterMetaType<QAudio::Mode>(); qRegisterMetaType<QAudio::Role>(); + qRegisterMetaType<QAudio::VolumeScale>(); } Q_CONSTRUCTOR_FUNCTION(qRegisterAudioMetaTypes) @@ -111,6 +113,98 @@ Q_CONSTRUCTOR_FUNCTION(qRegisterAudioMetaTypes) \sa QMediaPlayer::setAudioRole() */ +/*! + \enum QAudio::VolumeScale + + This enum defines the different audio volume scales. + + \value LinearVolumeScale Linear scale. \c 0.0 (0%) is silence and \c 1.0 (100%) is full + volume. All Qt Multimedia classes that have an audio volume use a + linear scale. + \value CubicVolumeScale Cubic scale. \c 0.0 (0%) is silence and \c 1.0 (100%) is full + volume. UI volume controls should usually use a cubic scale. + \value DecibelVolumeScale Decibel (dB, amplitude) logarithmic scale. \c -200 is silence and + \c 0 is full volume. + + \since 5.8 + \sa QAudio::convertVolume() +*/ + +namespace QAudio +{ + +/*! + \fn qreal QAudio::convertVolume(qreal volume, VolumeScale from, VolumeScale to) + + Converts an audio \a volume \a from a volume scale \a to another, and returns the result. + + Depending on the context, different scales are used to represent audio volume. All Qt Multimedia + classes that have an audio volume use a linear scale, the reason is that the loudness of a + speaker is controlled by modulating its voltage on a linear scale. The human ear on the other + hand, perceives loudness in a logarithmic way. That is why the decibel scale, being a logarithmic + scale, is typically used to define sound levels. UI volume controls in professional audio + applications usually use a decibel scale. The cubic scale is a computationally cheap + approximation of a logarithmic scale, most applications should use a cubic scale for their UI + volume controls. + + The following example shows how to convert the volume value from a slider control before passing + it to a QMediaPlayer. As a result, the perceived increase in volume is the same when increasing + the volume slider from 20 to 30 as it is from 50 to 60: + + \snippet multimedia-snippets/audio.cpp Volume conversion + + \since 5.8 + \sa VolumeScale, QMediaPlayer::setVolume(), QAudioOutput::setVolume(), + QAudioInput::setVolume(), QSoundEffect::setVolume(), QMediaRecorder::setVolume() +*/ +qreal convertVolume(qreal volume, VolumeScale from, VolumeScale to) +{ + switch (from) { + case LinearVolumeScale: + volume = qMax(qreal(0), volume); + switch (to) { + case LinearVolumeScale: + return volume; + case CubicVolumeScale: + return qPow(volume, qreal(1 / 3.0)); + case DecibelVolumeScale: + if (volume < 0.001) + return qreal(-200); + else + return qreal(20.0) * std::log10(volume); + } + break; + case CubicVolumeScale: + volume = qMax(qreal(0), volume); + switch (to) { + case LinearVolumeScale: + return volume * volume * volume; + case CubicVolumeScale: + return volume; + case DecibelVolumeScale: + if (volume < 0.001) + return qreal(-200); + else + return qreal(3.0 * 20.0) * std::log10(volume); + } + break; + case DecibelVolumeScale: + switch (to) { + case LinearVolumeScale: + return qPow(qreal(10.0), volume / qreal(20.0)); + case CubicVolumeScale: + return qPow(qreal(10.0), volume / qreal(3.0 * 20.0)); + case DecibelVolumeScale: + return volume; + } + break; + } + + return volume; +} + +} + #ifndef QT_NO_DEBUG_STREAM QDebug operator<<(QDebug dbg, QAudio::Error error) { @@ -210,6 +304,25 @@ QDebug operator<<(QDebug dbg, QAudio::Role role) } return dbg; } + +QDebug operator<<(QDebug dbg, QAudio::VolumeScale scale) +{ + QDebugStateSaver saver(dbg); + dbg.nospace(); + switch (scale) { + case QAudio::LinearVolumeScale: + dbg << "LinearVolumeScale"; + break; + case QAudio::CubicVolumeScale: + dbg << "CubicVolumeScale"; + break; + case QAudio::DecibelVolumeScale: + dbg << "DecibelVolumeScale"; + break; + } + return dbg; +} + #endif diff --git a/src/multimedia/audio/qaudio.h b/src/multimedia/audio/qaudio.h index 449ddefae..9bbc6cf22 100644 --- a/src/multimedia/audio/qaudio.h +++ b/src/multimedia/audio/qaudio.h @@ -70,6 +70,14 @@ namespace QAudio SonificationRole, GameRole }; + + enum VolumeScale { + LinearVolumeScale, + CubicVolumeScale, + DecibelVolumeScale + }; + + Q_MULTIMEDIA_EXPORT qreal convertVolume(qreal volume, VolumeScale from, VolumeScale to); } #ifndef QT_NO_DEBUG_STREAM @@ -77,6 +85,7 @@ Q_MULTIMEDIA_EXPORT QDebug operator<<(QDebug dbg, QAudio::Error error); Q_MULTIMEDIA_EXPORT QDebug operator<<(QDebug dbg, QAudio::State state); Q_MULTIMEDIA_EXPORT QDebug operator<<(QDebug dbg, QAudio::Mode mode); Q_MULTIMEDIA_EXPORT QDebug operator<<(QDebug dbg, QAudio::Role role); +Q_MULTIMEDIA_EXPORT QDebug operator<<(QDebug dbg, QAudio::VolumeScale role); #endif QT_END_NAMESPACE @@ -85,5 +94,6 @@ Q_DECLARE_METATYPE(QAudio::Error) Q_DECLARE_METATYPE(QAudio::State) Q_DECLARE_METATYPE(QAudio::Mode) Q_DECLARE_METATYPE(QAudio::Role) +Q_DECLARE_METATYPE(QAudio::VolumeScale) #endif // QAUDIO_H diff --git a/src/multimedia/audio/qaudiodevicefactory.cpp b/src/multimedia/audio/qaudiodevicefactory.cpp index 83e1a6c0b..c3e4929b3 100644 --- a/src/multimedia/audio/qaudiodevicefactory.cpp +++ b/src/multimedia/audio/qaudiodevicefactory.cpp @@ -41,6 +41,7 @@ #include "qaudiosystem.h" #include "qaudiosystemplugin.h" +#include "qaudiosystempluginext_p.h" #include "qmediapluginloader_p.h" #include "qaudiodevicefactory_p.h" @@ -139,41 +140,53 @@ QList<QAudioDeviceInfo> QAudioDeviceFactory::availableDevices(QAudio::Mode mode) return devices; } -QAudioDeviceInfo QAudioDeviceFactory::defaultInputDevice() +QAudioDeviceInfo QAudioDeviceFactory::defaultDevice(QAudio::Mode mode) { #if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS) - QAudioSystemFactoryInterface* plugin = qobject_cast<QAudioSystemFactoryInterface*>(audioLoader()->instance(defaultKey())); - if (plugin) { - QList<QByteArray> list = plugin->availableDevices(QAudio::AudioInput); - if (list.size() > 0) - return QAudioDeviceInfo(defaultKey(), list.at(0), QAudio::AudioInput); - } + QMediaPluginLoader* l = audioLoader(); - // if no plugin is marked as default or if the default plugin doesn't have any input device, - // return the first input available from other plugins. - QList<QAudioDeviceInfo> inputDevices = availableDevices(QAudio::AudioInput); - if (!inputDevices.isEmpty()) - return inputDevices.first(); -#endif + // Check if there is a default plugin. + QAudioSystemFactoryInterface *plugin = qobject_cast<QAudioSystemFactoryInterface *>(l->instance(defaultKey())); + if (plugin) { + // Check if the plugin has the extension interface. + QAudioSystemPluginExtension *pluginExt = qobject_cast<QAudioSystemPluginExtension *>(l->instance(defaultKey())); + // Ask for the default device. + if (pluginExt) { + const QByteArray &device = pluginExt->defaultDevice(mode); + if (!device.isEmpty()) + return QAudioDeviceInfo(defaultKey(), device, mode); + } - return QAudioDeviceInfo(); -} + // If there were no default devices, e.g., if the plugin did not implement the extent-ion interface, + // then just pick the first device that's available. + const auto &devices = plugin->availableDevices(mode); + if (!devices.isEmpty()) + return QAudioDeviceInfo(defaultKey(), devices.first(), mode); + } -QAudioDeviceInfo QAudioDeviceFactory::defaultOutputDevice() -{ -#if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS) - QAudioSystemFactoryInterface* plugin = qobject_cast<QAudioSystemFactoryInterface*>(audioLoader()->instance(defaultKey())); - if (plugin) { - QList<QByteArray> list = plugin->availableDevices(QAudio::AudioOutput); - if (list.size() > 0) - return QAudioDeviceInfo(defaultKey(), list.at(0), QAudio::AudioOutput); + // If no plugin is marked as default, check the other plugins. + // Note: We're going to prioritize plugins that report a default device. + const auto &keys = l->keys(); + QAudioDeviceInfo fallbackDevice; + for (const auto &key : keys) { + if (key == defaultKey()) + continue; + QAudioSystemFactoryInterface* plugin = qobject_cast<QAudioSystemFactoryInterface*>(l->instance(key)); + if (plugin) { + // Check if the plugin has the extent-ion interface. + QAudioSystemPluginExtension *pluginExt = qobject_cast<QAudioSystemPluginExtension *>(l->instance(key)); + if (pluginExt) { + const QByteArray &device = pluginExt->defaultDevice(mode); + if (!device.isEmpty()) + return QAudioDeviceInfo(key, device, mode); + } else if (fallbackDevice.isNull()) { + const auto &devices = plugin->availableDevices(mode); + if (!devices.isEmpty()) + fallbackDevice = QAudioDeviceInfo(key, devices.first(), mode); + } + } } - // if no plugin is marked as default or if the default plugin doesn't have any output device, - // return the first output available from other plugins. - QList<QAudioDeviceInfo> outputDevices = availableDevices(QAudio::AudioOutput); - if (!outputDevices.isEmpty()) - return outputDevices.first(); #endif return QAudioDeviceInfo(); @@ -196,12 +209,12 @@ QAbstractAudioDeviceInfo* QAudioDeviceFactory::audioDeviceInfo(const QString &re QAbstractAudioInput* QAudioDeviceFactory::createDefaultInputDevice(QAudioFormat const &format) { - return createInputDevice(defaultInputDevice(), format); + return createInputDevice(defaultDevice(QAudio::AudioInput), format); } QAbstractAudioOutput* QAudioDeviceFactory::createDefaultOutputDevice(QAudioFormat const &format) { - return createOutputDevice(defaultOutputDevice(), format); + return createOutputDevice(defaultDevice(QAudio::AudioOutput), format); } QAbstractAudioInput* QAudioDeviceFactory::createInputDevice(QAudioDeviceInfo const& deviceInfo, QAudioFormat const &format) diff --git a/src/multimedia/audio/qaudiodevicefactory_p.h b/src/multimedia/audio/qaudiodevicefactory_p.h index 833184075..7ad5e4e78 100644 --- a/src/multimedia/audio/qaudiodevicefactory_p.h +++ b/src/multimedia/audio/qaudiodevicefactory_p.h @@ -71,8 +71,7 @@ class QAudioDeviceFactory public: static QList<QAudioDeviceInfo> availableDevices(QAudio::Mode mode); - static QAudioDeviceInfo defaultInputDevice(); - static QAudioDeviceInfo defaultOutputDevice(); + static QAudioDeviceInfo defaultDevice(QAudio::Mode mode); static QAbstractAudioDeviceInfo* audioDeviceInfo(const QString &realm, const QByteArray &handle, QAudio::Mode mode); diff --git a/src/multimedia/audio/qaudiodeviceinfo.cpp b/src/multimedia/audio/qaudiodeviceinfo.cpp index 945b415e8..f4f548017 100644 --- a/src/multimedia/audio/qaudiodeviceinfo.cpp +++ b/src/multimedia/audio/qaudiodeviceinfo.cpp @@ -419,7 +419,7 @@ QList<QAudioFormat::SampleType> QAudioDeviceInfo::supportedSampleTypes() const */ QAudioDeviceInfo QAudioDeviceInfo::defaultInputDevice() { - return QAudioDeviceFactory::defaultInputDevice(); + return QAudioDeviceFactory::defaultDevice(QAudio::AudioInput); } /*! @@ -428,7 +428,7 @@ QAudioDeviceInfo QAudioDeviceInfo::defaultInputDevice() */ QAudioDeviceInfo QAudioDeviceInfo::defaultOutputDevice() { - return QAudioDeviceFactory::defaultOutputDevice(); + return QAudioDeviceFactory::defaultDevice(QAudio::AudioOutput); } /*! diff --git a/src/multimedia/audio/qaudiosystemplugin.cpp b/src/multimedia/audio/qaudiosystemplugin.cpp index b4fc0dbca..438b8b7bb 100644 --- a/src/multimedia/audio/qaudiosystemplugin.cpp +++ b/src/multimedia/audio/qaudiosystemplugin.cpp @@ -39,6 +39,7 @@ #include "qaudiosystemplugin.h" +#include "qaudiosystempluginext_p.h" QT_BEGIN_NAMESPACE @@ -46,6 +47,10 @@ QAudioSystemFactoryInterface::~QAudioSystemFactoryInterface() { } +QAudioSystemPluginExtension::~QAudioSystemPluginExtension() +{ +} + /*! \class QAudioSystemPlugin \brief The QAudioSystemPlugin class provides an abstract base for audio plugins. @@ -72,25 +77,15 @@ QAudioSystemFactoryInterface::~QAudioSystemFactoryInterface() \sa QAbstractAudioDeviceInfo, QAbstractAudioOutput, QAbstractAudioInput - Qt supports win32, linux(alsa) and OS X standard (builtin to the - QtMultimedia library at compile time). - - You can support other backends other than these predefined ones by - creating a plugin subclassing QAudioSystemPlugin, QAbstractAudioDeviceInfo, - QAbstractAudioOutput and QAbstractAudioInput. - - - -audio-backend configure option will force compiling in of the builtin backend - into the QtMultimedia library at compile time. This is automatic by default - and will only be compiled into the library if the dependencies are installed. - eg. alsa-devel package installed for linux. + Qt comes with plugins for Windows (WinMM and WASAPI), Linux (ALSA and PulseAudio), OS X / iOS + (CoreAudio), Android (OpenSL ES) and QNX. - If the builtin backend is not compiled into the QtMultimedia library and - no audio plugins are available a fallback dummy backend will be used. - This should print out warnings if this is the case when you try and use QAudioInput or QAudioOutput. To fix this problem - reconfigure Qt using -audio-backend or create your own plugin with a default - key to always override the dummy fallback. The easiest way to determine - if you have only a dummy backend is to get a list of available audio devices. + If no audio plugins are available, a fallback dummy backend will be used. + This should print out warnings if this is the case when you try and use QAudioInput + or QAudioOutput. To fix this problem, make sure the dependencies for the Qt plugins are + installed on the system and reconfigure Qt (e.g. alsa-devel package on Linux), or create your + own plugin with a default key to always override the dummy fallback. The easiest way to + determine if you have only a dummy backend is to get a list of available audio devices. QAudioDeviceInfo::availableDevices(QAudio::AudioOutput).size() = 0 (dummy backend) */ diff --git a/src/multimedia/audio/qaudiosystempluginext_p.h b/src/multimedia/audio/qaudiosystempluginext_p.h new file mode 100644 index 000000000..380bc5afa --- /dev/null +++ b/src/multimedia/audio/qaudiosystempluginext_p.h @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** 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 QAUDIOSYSTEMPLUGINEXT_P_H +#define QAUDIOSYSTEMPLUGINEXT_P_H + +#include <QtMultimedia/qtmultimediadefs.h> +#include <QtMultimedia/qaudio.h> +#include <QtCore/qplugin.h> + +QT_BEGIN_NAMESPACE + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +struct Q_MULTIMEDIA_EXPORT QAudioSystemPluginExtension +{ + virtual QByteArray defaultDevice(QAudio::Mode) const = 0; + virtual ~QAudioSystemPluginExtension(); +}; + +#define QAudioSystemPluginExtension_iid "org.qt-project.qt.audiosystempluginextension" +Q_DECLARE_INTERFACE(QAudioSystemPluginExtension, QAudioSystemPluginExtension_iid) + +QT_END_NAMESPACE + +#endif // QAUDIOSYSTEMPLUGINEXT_P_H diff --git a/src/multimedia/doc/snippets/multimedia-snippets/audio.cpp b/src/multimedia/doc/snippets/multimedia-snippets/audio.cpp index 310206405..736d1b306 100644 --- a/src/multimedia/doc/snippets/multimedia-snippets/audio.cpp +++ b/src/multimedia/doc/snippets/multimedia-snippets/audio.cpp @@ -47,6 +47,7 @@ #include "qaudiooutput.h" #include "qaudioprobe.h" #include "qaudiodecoder.h" +#include "qmediaplayer.h" class AudioInputExample : public QObject { Q_OBJECT @@ -247,3 +248,18 @@ void AudioDecodingExample::decode() // Now wait for bufferReady() signal and call decoder->read() //! [Local audio decoding] } + +QMediaPlayer player; + +//! [Volume conversion] +void applyVolume(int volumeSliderValue) +{ + // volumeSliderValue is in the range [0..100] + + qreal linearVolume = QAudio::convertVolume(volumeSliderValue / qreal(100.0), + QAudio::CubicVolumeScale, + QAudio::LinearVolumeScale); + + player.setVolume(qRound(linearVolume * 100)); +} +//! [Volume conversion] diff --git a/src/multimedia/playback/qmediaplayer.cpp b/src/multimedia/playback/qmediaplayer.cpp index afea8e147..f52041e5f 100644 --- a/src/multimedia/playback/qmediaplayer.cpp +++ b/src/multimedia/playback/qmediaplayer.cpp @@ -142,7 +142,7 @@ public: QMediaContent rootMedia; QMediaContent pendingPlaylist; QMediaPlaylist *parentPlaylist(QMediaPlaylist *pls); - bool isInChain(QUrl url); + bool isInChain(const QUrl &url); int nestedPlaylists; void setMedia(const QMediaContent &media, QIODevice *stream = 0); @@ -175,7 +175,7 @@ QMediaPlaylist *QMediaPlayerPrivate::parentPlaylist(QMediaPlaylist *pls) return 0; } -bool QMediaPlayerPrivate::isInChain(QUrl url) +bool QMediaPlayerPrivate::isInChain(const QUrl &url) { // Check whether a URL is already in the chain of playlists. // Also see a comment in parentPlaylist(). diff --git a/src/multimedia/qmediaopenglhelper_p.h b/src/multimedia/qmediaopenglhelper_p.h index 602116976..0a65b9f53 100644 --- a/src/multimedia/qmediaopenglhelper_p.h +++ b/src/multimedia/qmediaopenglhelper_p.h @@ -72,7 +72,7 @@ inline bool QMediaOpenGLHelper::isANGLE() #else bool isANGLE = false; -# if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && (defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC)) +# if defined(Q_OS_WIN) && (defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC)) if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGLES) { // Although unlikely, technically LibGLES could mean a non-ANGLE EGL/GLES2 implementation too. // Verify that it is indeed ANGLE. @@ -104,7 +104,7 @@ inline bool QMediaOpenGLHelper::isANGLE() # endif // QT_OPENGL_ES_2_ANGLE_STATIC } -# endif // Q_OS_WIN && !Q_OS_WINCE && (QT_OPENGL_ES_2 || QT_OPENGL_DYNAMIC) +# endif // Q_OS_WIN && (QT_OPENGL_ES_2 || QT_OPENGL_DYNAMIC) return isANGLE; #endif // Q_OS_WINRT diff --git a/src/multimedia/qmediastoragelocation.cpp b/src/multimedia/qmediastoragelocation.cpp index 04aa79758..7bd1e84f4 100644 --- a/src/multimedia/qmediastoragelocation.cpp +++ b/src/multimedia/qmediastoragelocation.cpp @@ -131,7 +131,7 @@ QString QMediaStorageLocation::generateFileName(const QString &prefix, .arg(extension); const QString path = dir.absoluteFilePath(name); - if (!QFileInfo(path).exists()) { + if (!QFileInfo::exists(path)) { m_lastUsedIndex[lastMediaKey] = lastMediaIndex + 1; return path; } diff --git a/src/multimedia/qmediatimerange.cpp b/src/multimedia/qmediatimerange.cpp index 7739c704f..700dcd087 100644 --- a/src/multimedia/qmediatimerange.cpp +++ b/src/multimedia/qmediatimerange.cpp @@ -665,16 +665,7 @@ bool QMediaTimeRange::contains(qint64 time) const */ bool operator==(const QMediaTimeRange &a, const QMediaTimeRange &b) { - if (a.intervals().count() != b.intervals().count()) - return false; - - for (int i = 0; i < a.intervals().count(); i++) - { - if(a.intervals()[i] != b.intervals()[i]) - return false; - } - - return true; + return a.intervals() == b.intervals(); } /*! diff --git a/src/plugins/alsa/qalsaaudiodeviceinfo.cpp b/src/plugins/alsa/qalsaaudiodeviceinfo.cpp index 0342ca546..d0f772d5e 100644 --- a/src/plugins/alsa/qalsaaudiodeviceinfo.cpp +++ b/src/plugins/alsa/qalsaaudiodeviceinfo.cpp @@ -140,6 +140,15 @@ QList<QAudioFormat::SampleType> QAlsaAudioDeviceInfo::supportedSampleTypes() return typez; } +QByteArray QAlsaAudioDeviceInfo::defaultDevice(QAudio::Mode mode) +{ + const auto &devices = availableDevices(mode); + if (devices.size() == 0) + return QByteArray(); + + return devices.first(); +} + bool QAlsaAudioDeviceInfo::open() { int err = 0; @@ -396,24 +405,6 @@ QList<QByteArray> QAlsaAudioDeviceInfo::availableDevices(QAudio::Mode mode) return devices; } -QByteArray QAlsaAudioDeviceInfo::defaultInputDevice() -{ - QList<QByteArray> devices = availableDevices(QAudio::AudioInput); - if(devices.size() == 0) - return QByteArray(); - - return devices.first(); -} - -QByteArray QAlsaAudioDeviceInfo::defaultOutputDevice() -{ - QList<QByteArray> devices = availableDevices(QAudio::AudioOutput); - if(devices.size() == 0) - return QByteArray(); - - return devices.first(); -} - void QAlsaAudioDeviceInfo::checkSurround() { surround40 = false; diff --git a/src/plugins/alsa/qalsaaudiodeviceinfo.h b/src/plugins/alsa/qalsaaudiodeviceinfo.h index 0147a2cf9..3b14bd489 100644 --- a/src/plugins/alsa/qalsaaudiodeviceinfo.h +++ b/src/plugins/alsa/qalsaaudiodeviceinfo.h @@ -88,8 +88,7 @@ public: QList<int> supportedSampleSizes(); QList<QAudioFormat::Endian> supportedByteOrders(); QList<QAudioFormat::SampleType> supportedSampleTypes(); - static QByteArray defaultInputDevice(); - static QByteArray defaultOutputDevice(); + static QByteArray defaultDevice(QAudio::Mode mode); static QList<QByteArray> availableDevices(QAudio::Mode); private: diff --git a/src/plugins/alsa/qalsaplugin.cpp b/src/plugins/alsa/qalsaplugin.cpp index 79adbae59..e52e9ee83 100644 --- a/src/plugins/alsa/qalsaplugin.cpp +++ b/src/plugins/alsa/qalsaplugin.cpp @@ -49,6 +49,11 @@ QAlsaPlugin::QAlsaPlugin(QObject *parent) { } +QByteArray QAlsaPlugin::defaultDevice(QAudio::Mode mode) const +{ + return QAlsaAudioDeviceInfo::defaultDevice(mode); +} + QList<QByteArray> QAlsaPlugin::availableDevices(QAudio::Mode mode) const { return QAlsaAudioDeviceInfo::availableDevices(mode); diff --git a/src/plugins/alsa/qalsaplugin.h b/src/plugins/alsa/qalsaplugin.h index 74e3475b7..b3c530f88 100644 --- a/src/plugins/alsa/qalsaplugin.h +++ b/src/plugins/alsa/qalsaplugin.h @@ -41,19 +41,22 @@ #define QALSAPLUGIN_H #include <QtMultimedia/qaudiosystemplugin.h> +#include <QtMultimedia/private/qaudiosystempluginext_p.h> QT_BEGIN_NAMESPACE -class QAlsaPlugin : public QAudioSystemPlugin +class QAlsaPlugin : public QAudioSystemPlugin, public QAudioSystemPluginExtension { Q_OBJECT Q_PLUGIN_METADATA(IID "org.qt-project.qt.audiosystemfactory/5.0" FILE "alsa.json") + Q_INTERFACES(QAudioSystemPluginExtension) public: QAlsaPlugin(QObject *parent = 0); ~QAlsaPlugin() {} + QByteArray defaultDevice(QAudio::Mode mode) const Q_DECL_OVERRIDE; QList<QByteArray> availableDevices(QAudio::Mode mode) const Q_DECL_OVERRIDE; QAbstractAudioInput *createInput(const QByteArray &device) Q_DECL_OVERRIDE; QAbstractAudioOutput *createOutput(const QByteArray &device) Q_DECL_OVERRIDE; diff --git a/src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtAndroidMediaPlayer.java b/src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtAndroidMediaPlayer.java index d0983d38a..6818b2909 100644 --- a/src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtAndroidMediaPlayer.java +++ b/src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtAndroidMediaPlayer.java @@ -449,17 +449,6 @@ public class QtAndroidMediaPlayer return duration; } - private float adjustVolume(final int volume) - { - if (volume < 1) - return 0.0f; - - if (volume > 98) - return 1.0f; - - return (float) (1-(Math.log(100-volume)/Math.log(100))); - } - public void setVolume(int volume) { if (volume < 0) @@ -487,7 +476,7 @@ public class QtAndroidMediaPlayer } try { - float newVolume = adjustVolume(volume); + float newVolume = (float)volume / 100; mMediaPlayer.setVolume(newVolume, newVolume); } catch (final IllegalStateException e) { Log.d(TAG, "" + e.getMessage()); diff --git a/src/plugins/avfoundation/camera/avfcameraviewfindersettingscontrol.mm b/src/plugins/avfoundation/camera/avfcameraviewfindersettingscontrol.mm index 924b0d76a..19bc8815c 100644 --- a/src/plugins/avfoundation/camera/avfcameraviewfindersettingscontrol.mm +++ b/src/plugins/avfoundation/camera/avfcameraviewfindersettingscontrol.mm @@ -419,6 +419,10 @@ QVideoFrame::PixelFormat AVFCameraViewfinderSettingsControl2::QtPixelFormatFromC case kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange: case kCVPixelFormatType_420YpCbCr8BiPlanarFullRange: return QVideoFrame::Format_NV12; + case kCVPixelFormatType_422YpCbCr8: + return QVideoFrame::Format_UYVY; + case kCVPixelFormatType_422YpCbCr8_yuvs: + return QVideoFrame::Format_YUYV; default: return QVideoFrame::Format_Invalid; } @@ -439,6 +443,12 @@ bool AVFCameraViewfinderSettingsControl2::CVPixelFormatFromQtFormat(QVideoFrame: case QVideoFrame::Format_NV12: conv = kCVPixelFormatType_420YpCbCr8BiPlanarFullRange; break; + case QVideoFrame::Format_UYVY: + conv = kCVPixelFormatType_422YpCbCr8; + break; + case QVideoFrame::Format_YUYV: + conv = kCVPixelFormatType_422YpCbCr8_yuvs; + break; // These two formats below are not supported // by QSGVideoNodeFactory_RGB, so for now I have to // disable them. diff --git a/src/plugins/coreaudio/coreaudiodeviceinfo.h b/src/plugins/coreaudio/coreaudiodeviceinfo.h index fc8999850..08c3961e6 100644 --- a/src/plugins/coreaudio/coreaudiodeviceinfo.h +++ b/src/plugins/coreaudio/coreaudiodeviceinfo.h @@ -65,9 +65,7 @@ public: QList<QAudioFormat::Endian> supportedByteOrders(); QList<QAudioFormat::SampleType> supportedSampleTypes(); - static QByteArray defaultInputDevice(); - static QByteArray defaultOutputDevice(); - + static QByteArray defaultDevice(QAudio::Mode mode); static QList<QByteArray> availableDevices(QAudio::Mode mode); private: diff --git a/src/plugins/coreaudio/coreaudiodeviceinfo.mm b/src/plugins/coreaudio/coreaudiodeviceinfo.mm index 66e8ed4d7..1a79438cb 100644 --- a/src/plugins/coreaudio/coreaudiodeviceinfo.mm +++ b/src/plugins/coreaudio/coreaudiodeviceinfo.mm @@ -280,47 +280,29 @@ static QByteArray get_device_info(AudioDeviceID audioDevice, QAudio::Mode mode) } #endif -QByteArray CoreAudioDeviceInfo::defaultInputDevice() +QByteArray CoreAudioDeviceInfo::defaultDevice(QAudio::Mode mode) { #if defined(Q_OS_OSX) AudioDeviceID audioDevice; UInt32 size = sizeof(audioDevice); - AudioObjectPropertyAddress defaultInputDevicePropertyAddress = { kAudioHardwarePropertyDefaultInputDevice, - kAudioObjectPropertyScopeGlobal, - kAudioObjectPropertyElementMaster }; - - if (AudioObjectGetPropertyData(kAudioObjectSystemObject, - &defaultInputDevicePropertyAddress, - 0, NULL, &size, &audioDevice) != noErr) { - qWarning() << "QAudioDeviceInfo: Unable to find default input device"; - return QByteArray(); - } - - return get_device_info(audioDevice, QAudio::AudioInput); -#else //iOS - return CoreAudioSessionManager::instance().inputDevices().first(); -#endif -} - -QByteArray CoreAudioDeviceInfo::defaultOutputDevice() -{ -#if defined(Q_OS_OSX) - AudioDeviceID audioDevice; - UInt32 size = sizeof(audioDevice); - AudioObjectPropertyAddress defaultOutputDevicePropertyAddress = { kAudioHardwarePropertyDefaultOutputDevice, - kAudioObjectPropertyScopeGlobal, - kAudioObjectPropertyElementMaster }; + const AudioObjectPropertySelector selector = (mode == QAudio::AudioOutput) ? kAudioHardwarePropertyDefaultOutputDevice + : kAudioHardwarePropertyDefaultInputDevice; + AudioObjectPropertyAddress defaultDevicePropertyAddress = { selector, + kAudioObjectPropertyScopeGlobal, + kAudioObjectPropertyElementMaster }; if (AudioObjectGetPropertyData(kAudioObjectSystemObject, - &defaultOutputDevicePropertyAddress, + &defaultDevicePropertyAddress, 0, NULL, &size, &audioDevice) != noErr) { - qWarning() << "QAudioDeviceInfo: Unable to find default output device"; + qWarning("QAudioDeviceInfo: Unable to find default %s device", (mode == QAudio::AudioOutput) ? "output" : "input"); return QByteArray(); } - return get_device_info(audioDevice, QAudio::AudioOutput); + return get_device_info(audioDevice, mode); #else //iOS - return CoreAudioSessionManager::instance().outputDevices().first(); + const auto &devices = (mode == QAudio::AudioOutput) ? CoreAudioSessionManager::instance().outputDevices() + : CoreAudioSessionManager::instance().inputDevices(); + return !devices.isEmpty() ? devices.first() : QByteArray(); #endif } @@ -343,15 +325,10 @@ QList<QByteArray> CoreAudioDeviceInfo::availableDevices(QAudio::Mode mode) AudioDeviceID* audioDevices = new AudioDeviceID[dc]; if (AudioObjectGetPropertyData(kAudioObjectSystemObject, &audioDevicesPropertyAddress, 0, NULL, &propSize, audioDevices) == noErr) { - QByteArray defaultDevice = (mode == QAudio::AudioOutput) ? defaultOutputDevice() : defaultInputDevice(); for (int i = 0; i < dc; ++i) { - QByteArray info = get_device_info(audioDevices[i], mode); - if (!info.isNull()) { - if (info == defaultDevice) - devices.prepend(info); - else - devices << info; - } + const QByteArray &info = get_device_info(audioDevices[i], mode); + if (!info.isNull()) + devices << info; } } diff --git a/src/plugins/coreaudio/coreaudioplugin.h b/src/plugins/coreaudio/coreaudioplugin.h index 5868508d2..da18d8cfe 100644 --- a/src/plugins/coreaudio/coreaudioplugin.h +++ b/src/plugins/coreaudio/coreaudioplugin.h @@ -39,19 +39,22 @@ #ifndef IOSAUDIOPLUGIN_H #define IOSAUDIOPLUGIN_H -#include <qaudiosystemplugin.h> +#include <QtMultimedia/qaudiosystemplugin.h> +#include <QtMultimedia/private/qaudiosystempluginext_p.h> QT_BEGIN_NAMESPACE -class CoreAudioPlugin : public QAudioSystemPlugin +class CoreAudioPlugin : public QAudioSystemPlugin, public QAudioSystemPluginExtension { Q_OBJECT Q_PLUGIN_METADATA(IID "org.qt-project.qt.audiosystemfactory/5.0" FILE "coreaudio.json") + Q_INTERFACES(QAudioSystemPluginExtension) public: explicit CoreAudioPlugin(QObject *parent = 0); ~CoreAudioPlugin() {} + QByteArray defaultDevice(QAudio::Mode mode) const Q_DECL_OVERRIDE; QList<QByteArray> availableDevices(QAudio::Mode mode) const Q_DECL_OVERRIDE; QAbstractAudioInput *createInput(const QByteArray &device) Q_DECL_OVERRIDE; QAbstractAudioOutput *createOutput(const QByteArray &device) Q_DECL_OVERRIDE; diff --git a/src/plugins/coreaudio/coreaudioplugin.mm b/src/plugins/coreaudio/coreaudioplugin.mm index 6d899fb67..ac51b9cd0 100644 --- a/src/plugins/coreaudio/coreaudioplugin.mm +++ b/src/plugins/coreaudio/coreaudioplugin.mm @@ -49,6 +49,10 @@ CoreAudioPlugin::CoreAudioPlugin(QObject *parent) { } +QByteArray CoreAudioPlugin::defaultDevice(QAudio::Mode mode) const +{ + return CoreAudioDeviceInfo::defaultDevice(mode); +} QList<QByteArray> CoreAudioPlugin::availableDevices(QAudio::Mode mode) const { diff --git a/src/plugins/directshow/directshow.pro b/src/plugins/directshow/directshow.pro index 117b02ade..280b52619 100644 --- a/src/plugins/directshow/directshow.pro +++ b/src/plugins/directshow/directshow.pro @@ -13,7 +13,7 @@ SOURCES += dsserviceplugin.cpp mingw: DEFINES += NO_DSHOW_STRSAFE !config_wmf: include(player/player.pri) -!wince: include(camera/camera.pri) +include(camera/camera.pri) OTHER_FILES += \ directshow.json \ diff --git a/src/plugins/directshow/player/directshowplayerservice.cpp b/src/plugins/directshow/player/directshowplayerservice.cpp index fa5ce3d55..d0c342ed4 100644 --- a/src/plugins/directshow/player/directshowplayerservice.cpp +++ b/src/plugins/directshow/player/directshowplayerservice.cpp @@ -47,11 +47,9 @@ #include "directshowplayerservice.h" -#ifndef Q_OS_WINCE #include "directshowaudioendpointcontrol.h" #include "directshowmetadatacontrol.h" #include "vmr9videowindowcontrol.h" -#endif #include "directshowiosource.h" #include "directshowplayercontrol.h" #include "directshowvideorenderercontrol.h" @@ -111,14 +109,10 @@ private: DirectShowPlayerService::DirectShowPlayerService(QObject *parent) : QMediaService(parent) , m_playerControl(0) -#ifndef Q_OS_WINCE , m_metaDataControl(0) -#endif , m_videoRendererControl(0) -#ifndef Q_OS_WINCE , m_videoWindowControl(0) , m_audioEndpointControl(0) -#endif , m_taskThread(0) , m_loop(qt_directShowEventLoop()) , m_pendingTasks(0) @@ -142,10 +136,8 @@ DirectShowPlayerService::DirectShowPlayerService(QObject *parent) , m_dontCacheNextSeekResult(false) { m_playerControl = new DirectShowPlayerControl(this); -#ifndef Q_OS_WINCE m_metaDataControl = new DirectShowMetaDataControl(this); m_audioEndpointControl = new DirectShowAudioEndpointControl(this); -#endif m_taskThread = new DirectShowPlayerServiceThread(this); m_taskThread->start(); @@ -176,14 +168,10 @@ DirectShowPlayerService::~DirectShowPlayerService() } delete m_playerControl; -#ifndef Q_OS_WINCE delete m_audioEndpointControl; delete m_metaDataControl; -#endif delete m_videoRendererControl; -#ifndef Q_OS_WINCE delete m_videoWindowControl; -#endif ::CloseHandle(m_taskHandle); } @@ -192,18 +180,12 @@ QMediaControl *DirectShowPlayerService::requestControl(const char *name) { if (qstrcmp(name, QMediaPlayerControl_iid) == 0) { return m_playerControl; -#ifndef Q_OS_WINCE } else if (qstrcmp(name, QAudioOutputSelectorControl_iid) == 0) { return m_audioEndpointControl; } else if (qstrcmp(name, QMetaDataReaderControl_iid) == 0) { return m_metaDataControl; -#endif } else if (qstrcmp(name, QVideoRendererControl_iid) == 0) { - if (!m_videoRendererControl -#ifndef Q_OS_WINCE - && !m_videoWindowControl -#endif - ){ + if (!m_videoRendererControl && !m_videoWindowControl) { m_videoRendererControl = new DirectShowVideoRendererControl(m_loop); connect(m_videoRendererControl, SIGNAL(filterChanged()), @@ -211,7 +193,6 @@ QMediaControl *DirectShowPlayerService::requestControl(const char *name) return m_videoRendererControl; } -#ifndef Q_OS_WINCE } else if (qstrcmp(name, QVideoWindowControl_iid) == 0) { if (!m_videoRendererControl && !m_videoWindowControl) { IBaseFilter *filter; @@ -234,7 +215,6 @@ QMediaControl *DirectShowPlayerService::requestControl(const char *name) return m_videoWindowControl; } -#endif } return 0; } @@ -250,14 +230,12 @@ void DirectShowPlayerService::releaseControl(QMediaControl *control) delete m_videoRendererControl; m_videoRendererControl = 0; -#ifndef Q_OS_WINCE } else if (control == m_videoWindowControl) { setVideoOutput(0); delete m_videoWindowControl; m_videoWindowControl = 0; -#endif } } @@ -283,9 +261,7 @@ void DirectShowPlayerService::load(const QMediaContent &media, QIODevice *stream m_seekable = false; m_atEnd = false; m_dontCacheNextSeekResult = false; -#ifndef Q_OS_WINCE m_metaDataControl->reset(); -#endif if (m_resources.isEmpty() && !stream) { m_pendingTasks = 0; @@ -1190,9 +1166,7 @@ void DirectShowPlayerService::customEvent(QEvent *event) QMutexLocker locker(&m_mutex); m_playerControl->updateMediaInfo(m_duration, m_streamTypes, m_seekable); -#ifndef Q_OS_WINCE m_metaDataControl->updateMetadata(m_graph, m_source, m_url.toString()); -#endif updateStatus(); } else if (event->type() == QEvent::Type(Error)) { diff --git a/src/plugins/directshow/player/directshowplayerservice.h b/src/plugins/directshow/player/directshowplayerservice.h index 9419a8a99..b8d30e79a 100644 --- a/src/plugins/directshow/player/directshowplayerservice.h +++ b/src/plugins/directshow/player/directshowplayerservice.h @@ -176,14 +176,10 @@ private: }; DirectShowPlayerControl *m_playerControl; -#ifndef Q_OS_WINCE DirectShowMetaDataControl *m_metaDataControl; -#endif DirectShowVideoRendererControl *m_videoRendererControl; -#ifndef Q_OS_WINCE QVideoWindowControl *m_videoWindowControl; DirectShowAudioEndpointControl *m_audioEndpointControl; -#endif QThread *m_taskThread; DirectShowEventLoop *m_loop; diff --git a/src/plugins/directshow/player/player.pri b/src/plugins/directshow/player/player.pri index c5fb8442a..0bc9c6d0a 100644 --- a/src/plugins/directshow/player/player.pri +++ b/src/plugins/directshow/player/player.pri @@ -1,7 +1,6 @@ INCLUDEPATH += $$PWD -LIBS += -lstrmiids -ldmoguids -luuid -lole32 -loleaut32 -!wince: LIBS += -lmsdmo -lgdi32 +LIBS += -lstrmiids -ldmoguids -luuid -lole32 -loleaut32 -lmsdmo -lgdi32 qtHaveModule(widgets): QT += widgets @@ -21,7 +20,10 @@ HEADERS += \ $$PWD/directshowsamplescheduler.h \ $$PWD/directshowvideorenderercontrol.h \ $$PWD/mediasamplevideobuffer.h \ - $$PWD/videosurfacefilter.h + $$PWD/videosurfacefilter.h \ + $$PWD/directshowaudioendpointcontrol.h \ + $$PWD/directshowmetadatacontrol.h \ + $$PWD/vmr9videowindowcontrol.h SOURCES += \ $$PWD/directshoweventloop.cpp \ @@ -35,19 +37,10 @@ SOURCES += \ $$PWD/directshowsamplescheduler.cpp \ $$PWD/directshowvideorenderercontrol.cpp \ $$PWD/mediasamplevideobuffer.cpp \ - $$PWD/videosurfacefilter.cpp - -!wince { -HEADERS += \ - $$PWD/directshowaudioendpointcontrol.h \ - $$PWD/directshowmetadatacontrol.h \ - $$PWD/vmr9videowindowcontrol.h - -SOURCES += \ + $$PWD/videosurfacefilter.cpp \ $$PWD/directshowaudioendpointcontrol.cpp \ $$PWD/directshowmetadatacontrol.cpp \ $$PWD/vmr9videowindowcontrol.cpp -} config_evr { DEFINES += HAVE_EVR diff --git a/src/plugins/opensles/qopenslesaudiooutput.cpp b/src/plugins/opensles/qopenslesaudiooutput.cpp index 8bf0b5602..26f2380b2 100644 --- a/src/plugins/opensles/qopenslesaudiooutput.cpp +++ b/src/plugins/opensles/qopenslesaudiooutput.cpp @@ -48,8 +48,6 @@ #endif // ANDROID #define BUFFER_COUNT 2 -#define EBASE 2.302585093 -#define LOG10(x) qLn(x)/qreal(EBASE) QT_BEGIN_NAMESPACE @@ -696,7 +694,7 @@ inline SLmillibel QOpenSLESAudioOutput::adjustVolume(qreal vol) if (qFuzzyCompare(vol, qreal(1.0))) return 0; - return 20 * LOG10(vol) * 100; // I.e., 20 * LOG10(SL_MILLIBEL_MAX * vol / SL_MILLIBEL_MAX) + return QAudio::convertVolume(vol, QAudio::LinearVolumeScale, QAudio::DecibelVolumeScale) * 100; } QT_END_NAMESPACE diff --git a/src/plugins/opensles/qopenslesengine.cpp b/src/plugins/opensles/qopenslesengine.cpp index 0cbd10887..1a16cc2a3 100644 --- a/src/plugins/opensles/qopenslesengine.cpp +++ b/src/plugins/opensles/qopenslesengine.cpp @@ -101,6 +101,12 @@ SLDataFormat_PCM QOpenSLESEngine::audioFormatToSLFormatPCM(const QAudioFormat &f } +QByteArray QOpenSLESEngine::defaultDevice(QAudio::Mode mode) const +{ + const auto &devices = availableDevices(mode); + return !devices.isEmpty() ? devices.first() : QByteArray(); +} + QList<QByteArray> QOpenSLESEngine::availableDevices(QAudio::Mode mode) const { QList<QByteArray> devices; diff --git a/src/plugins/opensles/qopenslesengine.h b/src/plugins/opensles/qopenslesengine.h index 364b3ef60..c36b21488 100644 --- a/src/plugins/opensles/qopenslesengine.h +++ b/src/plugins/opensles/qopenslesengine.h @@ -62,6 +62,7 @@ public: static SLDataFormat_PCM audioFormatToSLFormatPCM(const QAudioFormat &format); + QByteArray defaultDevice(QAudio::Mode mode) const; QList<QByteArray> availableDevices(QAudio::Mode mode) const; QList<int> supportedChannelCounts(QAudio::Mode mode) const; QList<int> supportedSampleRates(QAudio::Mode mode) const; diff --git a/src/plugins/opensles/qopenslesplugin.cpp b/src/plugins/opensles/qopenslesplugin.cpp index 8f89d044d..9a2fbbf79 100644 --- a/src/plugins/opensles/qopenslesplugin.cpp +++ b/src/plugins/opensles/qopenslesplugin.cpp @@ -52,6 +52,11 @@ QOpenSLESPlugin::QOpenSLESPlugin(QObject *parent) { } +QByteArray QOpenSLESPlugin::defaultDevice(QAudio::Mode mode) const +{ + return m_engine->defaultDevice(mode); +} + QList<QByteArray> QOpenSLESPlugin::availableDevices(QAudio::Mode mode) const { return m_engine->availableDevices(mode); diff --git a/src/plugins/opensles/qopenslesplugin.h b/src/plugins/opensles/qopenslesplugin.h index 2a967b27e..d45a47923 100644 --- a/src/plugins/opensles/qopenslesplugin.h +++ b/src/plugins/opensles/qopenslesplugin.h @@ -40,22 +40,25 @@ #ifndef QOPENSLESPLUGIN_H #define QOPENSLESPLUGIN_H -#include <qaudiosystemplugin.h> +#include <QtMultimedia/qaudiosystemplugin.h> +#include <QtMultimedia/private/qaudiosystempluginext_p.h> QT_BEGIN_NAMESPACE class QOpenSLESEngine; -class QOpenSLESPlugin : public QAudioSystemPlugin +class QOpenSLESPlugin : public QAudioSystemPlugin, public QAudioSystemPluginExtension { Q_OBJECT Q_PLUGIN_METADATA(IID "org.qt-project.qt.audiosystemfactory/5.0" FILE "opensles.json") + Q_INTERFACES(QAudioSystemPluginExtension) public: QOpenSLESPlugin(QObject *parent = 0); ~QOpenSLESPlugin() {} + QByteArray defaultDevice(QAudio::Mode mode) const; QList<QByteArray> availableDevices(QAudio::Mode mode) const; QAbstractAudioInput *createInput(const QByteArray &device); QAbstractAudioOutput *createOutput(const QByteArray &device); diff --git a/src/plugins/plugins.pro b/src/plugins/plugins.pro index 67b06a61b..8cc925bc2 100644 --- a/src/plugins/plugins.pro +++ b/src/plugins/plugins.pro @@ -25,7 +25,7 @@ qnx:!blackberry { SUBDIRS += qnx-audio } -win32:!winrt:!wince { +win32:!winrt { SUBDIRS += audiocapture \ windowsaudio diff --git a/src/plugins/pulseaudio/qpulseaudioengine.cpp b/src/plugins/pulseaudio/qpulseaudioengine.cpp index 19ba7472f..eb8e2bf9d 100644 --- a/src/plugins/pulseaudio/qpulseaudioengine.cpp +++ b/src/plugins/pulseaudio/qpulseaudioengine.cpp @@ -338,14 +338,6 @@ void QPulseAudioEngine::updateDevices() pa_operation_unref(operation); unlock(); - - // Swap the default output to index 0 - m_sinks.removeOne(m_defaultSink); - m_sinks.prepend(m_defaultSink); - - // Swap the default input to index 0 - m_sources.removeOne(m_defaultSource); - m_sources.prepend(m_defaultSource); } void QPulseAudioEngine::onContextFailed() @@ -369,4 +361,9 @@ QList<QByteArray> QPulseAudioEngine::availableDevices(QAudio::Mode mode) const return mode == QAudio::AudioOutput ? m_sinks : m_sources; } +QByteArray QPulseAudioEngine::defaultDevice(QAudio::Mode mode) const +{ + return (mode == QAudio::AudioOutput) ? m_defaultSink : m_defaultSource; +} + QT_END_NAMESPACE diff --git a/src/plugins/pulseaudio/qpulseaudioengine.h b/src/plugins/pulseaudio/qpulseaudioengine.h index 5eb96bf00..912df5242 100644 --- a/src/plugins/pulseaudio/qpulseaudioengine.h +++ b/src/plugins/pulseaudio/qpulseaudioengine.h @@ -53,7 +53,7 @@ #include <QtCore/qmap.h> #include <QtCore/qbytearray.h> -#include <qaudiosystemplugin.h> +#include <QtMultimedia/qaudiosystemplugin.h> #include <pulse/pulseaudio.h> #include "qpulsehelpers.h" #include <qaudioformat.h> @@ -91,6 +91,7 @@ public: } QList<QByteArray> availableDevices(QAudio::Mode mode) const; + QByteArray defaultDevice(QAudio::Mode mode) const; Q_SIGNALS: void contextFailed(); diff --git a/src/plugins/pulseaudio/qpulseaudioplugin.cpp b/src/plugins/pulseaudio/qpulseaudioplugin.cpp index 2b7b22089..6b3019279 100644 --- a/src/plugins/pulseaudio/qpulseaudioplugin.cpp +++ b/src/plugins/pulseaudio/qpulseaudioplugin.cpp @@ -53,6 +53,11 @@ QPulseAudioPlugin::QPulseAudioPlugin(QObject *parent) { } +QByteArray QPulseAudioPlugin::defaultDevice(QAudio::Mode mode) const +{ + return m_pulseEngine->defaultDevice(mode); +} + QList<QByteArray> QPulseAudioPlugin::availableDevices(QAudio::Mode mode) const { return m_pulseEngine->availableDevices(mode); diff --git a/src/plugins/pulseaudio/qpulseaudioplugin.h b/src/plugins/pulseaudio/qpulseaudioplugin.h index 4bad509e9..120d57df5 100644 --- a/src/plugins/pulseaudio/qpulseaudioplugin.h +++ b/src/plugins/pulseaudio/qpulseaudioplugin.h @@ -40,22 +40,25 @@ #ifndef QPULSEAUDIOPLUGIN_H #define QPULSEAUDIOPLUGIN_H -#include <qaudiosystemplugin.h> +#include <QtMultimedia/qaudiosystemplugin.h> +#include <QtMultimedia/private/qaudiosystempluginext_p.h> QT_BEGIN_NAMESPACE class QPulseAudioEngine; -class QPulseAudioPlugin : public QAudioSystemPlugin +class QPulseAudioPlugin : public QAudioSystemPlugin, public QAudioSystemPluginExtension { Q_OBJECT Q_PLUGIN_METADATA(IID "org.qt-project.qt.audiosystemfactory/5.0" FILE "pulseaudio.json") + Q_INTERFACES(QAudioSystemPluginExtension) public: QPulseAudioPlugin(QObject *parent = 0); ~QPulseAudioPlugin() {} + QByteArray defaultDevice(QAudio::Mode mode) const; QList<QByteArray> availableDevices(QAudio::Mode mode) const; QAbstractAudioInput *createInput(const QByteArray &device); QAbstractAudioOutput *createOutput(const QByteArray &device); diff --git a/src/plugins/qnx-audio/audio/qnxaudioplugin.cpp b/src/plugins/qnx-audio/audio/qnxaudioplugin.cpp index a3793fc3c..5d26c8954 100644 --- a/src/plugins/qnx-audio/audio/qnxaudioplugin.cpp +++ b/src/plugins/qnx-audio/audio/qnxaudioplugin.cpp @@ -55,6 +55,11 @@ QnxAudioPlugin::QnxAudioPlugin(QObject *parent) { } +QByteArray QnxAudioPlugin::defaultDevice(QAudio::Mode mode) const +{ + return (mode == QAudio::AudioOutput) ? OUTPUT_ID : INPUT_ID; +} + QList<QByteArray> QnxAudioPlugin::availableDevices(QAudio::Mode mode) const { if (mode == QAudio::AudioOutput) diff --git a/src/plugins/qnx-audio/audio/qnxaudioplugin.h b/src/plugins/qnx-audio/audio/qnxaudioplugin.h index 5e2410619..1d8b8a74b 100644 --- a/src/plugins/qnx-audio/audio/qnxaudioplugin.h +++ b/src/plugins/qnx-audio/audio/qnxaudioplugin.h @@ -40,19 +40,22 @@ #ifndef QNXAUDIOPLUGIN_H #define QNXAUDIOPLUGIN_H -#include <qaudiosystemplugin.h> +#include <QtMultimedia/qaudiosystemplugin.h> +#include <QtMultimedia/private/qaudiosystempluginext_p.h> QT_BEGIN_NAMESPACE -class QnxAudioPlugin : public QAudioSystemPlugin +class QnxAudioPlugin : public QAudioSystemPlugin, public QAudioSystemPluginExtension { Q_OBJECT Q_PLUGIN_METADATA(IID "org.qt-project.qt.audiosystemfactory/5.0" FILE "qnx_audio.json") + Q_INTERFACES(QAudioSystemPluginExtension) public: explicit QnxAudioPlugin(QObject *parent = 0); ~QnxAudioPlugin() {} + QByteArray defaultDevice(QAudio::Mode mode) const Q_DECL_OVERRIDE; QList<QByteArray> availableDevices(QAudio::Mode mode) const Q_DECL_OVERRIDE; QAbstractAudioInput *createInput(const QByteArray &device) Q_DECL_OVERRIDE; QAbstractAudioOutput *createOutput(const QByteArray &device) Q_DECL_OVERRIDE; diff --git a/src/plugins/wasapi/qwasapiplugin.cpp b/src/plugins/wasapi/qwasapiplugin.cpp index 7b64a101d..39660b9c1 100644 --- a/src/plugins/wasapi/qwasapiplugin.cpp +++ b/src/plugins/wasapi/qwasapiplugin.cpp @@ -50,6 +50,11 @@ QWasapiPlugin::QWasapiPlugin(QObject *parent) qCDebug(lcMmPlugin) << __FUNCTION__; } +QByteArray QWasapiPlugin::defaultDevice(QAudio::Mode mode) const +{ + return QWasapiUtils::defaultDevice(mode); +} + QList<QByteArray> QWasapiPlugin::availableDevices(QAudio::Mode mode) const { qCDebug(lcMmPlugin) << __FUNCTION__ << mode; diff --git a/src/plugins/wasapi/qwasapiplugin.h b/src/plugins/wasapi/qwasapiplugin.h index 18c2e9575..697e9bd78 100644 --- a/src/plugins/wasapi/qwasapiplugin.h +++ b/src/plugins/wasapi/qwasapiplugin.h @@ -39,22 +39,25 @@ #include <QtCore/QLoggingCategory> #include <QtCore/QList> -#include <QtMultimedia/QAudioSystemPlugin> +#include <QtMultimedia/qaudiosystemplugin.h> +#include <QtMultimedia/private/qaudiosystempluginext_p.h> QT_BEGIN_NAMESPACE Q_DECLARE_LOGGING_CATEGORY(lcMmPlugin) -class QWasapiPlugin : public QAudioSystemPlugin +class QWasapiPlugin : public QAudioSystemPlugin, public QAudioSystemPluginExtension { Q_OBJECT Q_PLUGIN_METADATA(IID "org.qt-project.qt.audiosystemfactory/5.0" FILE "wasapi.json") + Q_INTERFACES(QAudioSystemPluginExtension) public: explicit QWasapiPlugin(QObject *parent = 0); ~QWasapiPlugin() {} + QByteArray defaultDevice(QAudio::Mode mode) const Q_DECL_OVERRIDE; QList<QByteArray> availableDevices(QAudio::Mode mode) const Q_DECL_OVERRIDE; QAbstractAudioInput *createInput(const QByteArray &device) Q_DECL_OVERRIDE; QAbstractAudioOutput *createOutput(const QByteArray &device) Q_DECL_OVERRIDE; diff --git a/src/plugins/wasapi/qwasapiutils.cpp b/src/plugins/wasapi/qwasapiutils.cpp index 87daa4e45..0e39ee32b 100644 --- a/src/plugins/wasapi/qwasapiutils.cpp +++ b/src/plugins/wasapi/qwasapiutils.cpp @@ -175,6 +175,29 @@ bool QWasapiUtils::convertFromNativeFormat(const WAVEFORMATEX *native, QAudioFor return true; } +QByteArray QWasapiUtils::defaultDevice(QAudio::Mode mode) +{ + qCDebug(lcMmUtils) << __FUNCTION__ << mode; + + ComPtr<IMediaDeviceStatics> mediaDeviceStatics; + HRESULT hr; + + hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Media_Devices_MediaDevice).Get(), &mediaDeviceStatics); + Q_ASSERT_SUCCEEDED(hr); + + HString defaultAudioDevice; + quint32 dADSize = 0; + + if (mode == QAudio::AudioOutput) + hr = mediaDeviceStatics->GetDefaultAudioRenderId(AudioDeviceRole_Default, defaultAudioDevice.GetAddressOf()); + else + hr = mediaDeviceStatics->GetDefaultAudioCaptureId(AudioDeviceRole_Default, defaultAudioDevice.GetAddressOf()); + + const wchar_t *dadWStr = defaultAudioDevice.GetRawBuffer(&dADSize); + const QString defaultAudioDeviceId = QString::fromWCharArray(dadWStr, dADSize); + return defaultAudioDeviceId.toLocal8Bit(); +} + QList<QByteArray> QWasapiUtils::availableDevices(QAudio::Mode mode) { qCDebug(lcMmUtils) << __FUNCTION__ << mode; @@ -186,16 +209,6 @@ QList<QByteArray> QWasapiUtils::availableDevices(QAudio::Mode mode) &statics); Q_ASSERT_SUCCEEDED(hr); - ComPtr<IMediaDeviceStatics> mediaDeviceStatics; - hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Media_Devices_MediaDevice).Get(), &mediaDeviceStatics); - Q_ASSERT_SUCCEEDED(hr); - - HString defaultAudioRender; - quint32 dARSize = 0; - hr = mediaDeviceStatics->GetDefaultAudioRenderId(AudioDeviceRole_Default, defaultAudioRender.GetAddressOf()); - const wchar_t *darWStr = defaultAudioRender.GetRawBuffer(&dARSize); - const QString defaultAudioDeviceId = QString::fromWCharArray(darWStr, dARSize); - DeviceClass dc = mode == QAudio::AudioInput ? DeviceClass_AudioCapture : DeviceClass_AudioRender; QList<QByteArray> &deviceNames = mode == QAudio::AudioInput ? gMapping->inputDeviceNames : gMapping->outputDeviceNames; @@ -245,18 +258,6 @@ QList<QByteArray> QWasapiUtils::availableDevices(QAudio::Mode mode) const wchar_t *idWStr = hString.GetRawBuffer(&size); const QString deviceId = QString::fromWCharArray(idWStr, size); - boolean def; - hr = item->get_IsDefault(&def); - if (FAILED(hr)) { - qErrnoWarning(hr, "Could not access audio device default."); - continue; - } - - // At least on desktop no device is marked as default - // Hence use the default audio device string from above - if (!def && !defaultAudioDeviceId.isEmpty()) - def = defaultAudioDeviceId == deviceId; - boolean enabled; hr = item->get_IsEnabled(&enabled); if (FAILED(hr)) { @@ -265,14 +266,10 @@ QList<QByteArray> QWasapiUtils::availableDevices(QAudio::Mode mode) } qCDebug(lcMmUtils) << "Audio Device:" << deviceName << " ID:" << deviceId - << " Enabled:" << enabled << " Default:" << def; - if (def) { - deviceNames.prepend(deviceName.toLocal8Bit()); - deviceIds.prepend(deviceId); - } else { - deviceNames.append(deviceName.toLocal8Bit()); - deviceIds.append(deviceId); - } + << " Enabled:" << enabled; + + deviceNames.append(deviceName.toLocal8Bit()); + deviceIds.append(deviceId); } return deviceNames; } diff --git a/src/plugins/wasapi/qwasapiutils.h b/src/plugins/wasapi/qwasapiutils.h index 21eff3583..3dda0e1a5 100644 --- a/src/plugins/wasapi/qwasapiutils.h +++ b/src/plugins/wasapi/qwasapiutils.h @@ -134,6 +134,7 @@ namespace QWasapiUtils bool convertToNativeFormat(const QAudioFormat &qt, WAVEFORMATEX *native); bool convertFromNativeFormat(const WAVEFORMATEX *native, QAudioFormat *qt); + QByteArray defaultDevice(QAudio::Mode mode); QList<QByteArray> availableDevices(QAudio::Mode mode); Microsoft::WRL::ComPtr<AudioInterface> createOrGetInterface(const QByteArray &dev, QAudio::Mode mode); } diff --git a/src/plugins/windowsaudio/qwindowsaudiodeviceinfo.cpp b/src/plugins/windowsaudio/qwindowsaudiodeviceinfo.cpp index 9aa4487ab..83e9ccfc8 100644 --- a/src/plugins/windowsaudio/qwindowsaudiodeviceinfo.cpp +++ b/src/plugins/windowsaudio/qwindowsaudiodeviceinfo.cpp @@ -400,7 +400,6 @@ QList<QByteArray> QWindowsAudioDeviceInfo::availableDevices(QAudio::Mode mode) Q_UNUSED(mode) QList<QByteArray> devices; -#ifndef Q_OS_WINCE //enumerate device fullnames through directshow api CoInitialize(NULL); ICreateDevEnum *pDevEnum = NULL; @@ -454,55 +453,18 @@ QList<QByteArray> QWindowsAudioDeviceInfo::availableDevices(QAudio::Mode mode) pDevEnum->Release(); } CoUninitialize(); -#else // Q_OS_WINCE - if (mode == QAudio::AudioOutput) { - WAVEOUTCAPS woc; - unsigned long iNumDevs,i; - iNumDevs = waveOutGetNumDevs(); - for (i=0;i<iNumDevs;i++) { - if (waveOutGetDevCaps(i, &woc, sizeof(WAVEOUTCAPS)) - == MMSYSERR_NOERROR) { - QByteArray device; - QDataStream ds(&device, QIODevice::WriteOnly); - ds << quint32(i) << QString::fromWCharArray(woc.szPname); - devices.append(device); - } - } - } else { - WAVEINCAPS woc; - unsigned long iNumDevs,i; - iNumDevs = waveInGetNumDevs(); - for (i=0;i<iNumDevs;i++) { - if (waveInGetDevCaps(i, &woc, sizeof(WAVEINCAPS)) - == MMSYSERR_NOERROR) { - QByteArray device; - QDataStream ds(&device, QIODevice::WriteOnly); - ds << quint32(i) << QString::fromWCharArray(woc.szPname); - devices.append(device); - } - } - } -#endif // !Q_OS_WINCE return devices; } -QByteArray QWindowsAudioDeviceInfo::defaultOutputDevice() -{ - QByteArray defaultDevice; - QDataStream ds(&defaultDevice, QIODevice::WriteOnly); - ds << quint32(WAVE_MAPPER) // device ID for default device - << QStringLiteral("Default Output Device"); - - return defaultDevice; -} - -QByteArray QWindowsAudioDeviceInfo::defaultInputDevice() +QByteArray QWindowsAudioDeviceInfo::defaultDevice(QAudio::Mode mode) { + const QString &name = (mode == QAudio::AudioOutput) ? QStringLiteral("Default Output Device") + : QStringLiteral("Default Input Device"); QByteArray defaultDevice; QDataStream ds(&defaultDevice, QIODevice::WriteOnly); ds << quint32(WAVE_MAPPER) // device ID for default device - << QStringLiteral("Default Input Device"); + << name; return defaultDevice; } diff --git a/src/plugins/windowsaudio/qwindowsaudiodeviceinfo.h b/src/plugins/windowsaudio/qwindowsaudiodeviceinfo.h index d4833d3fc..d84eb8acf 100644 --- a/src/plugins/windowsaudio/qwindowsaudiodeviceinfo.h +++ b/src/plugins/windowsaudio/qwindowsaudiodeviceinfo.h @@ -88,8 +88,7 @@ public: QList<int> supportedSampleSizes(); QList<QAudioFormat::Endian> supportedByteOrders(); QList<QAudioFormat::SampleType> supportedSampleTypes(); - static QByteArray defaultInputDevice(); - static QByteArray defaultOutputDevice(); + static QByteArray defaultDevice(QAudio::Mode mode); static QList<QByteArray> availableDevices(QAudio::Mode); private: diff --git a/src/plugins/windowsaudio/qwindowsaudioplugin.cpp b/src/plugins/windowsaudio/qwindowsaudioplugin.cpp index ba1dba4c2..8f532fa70 100644 --- a/src/plugins/windowsaudio/qwindowsaudioplugin.cpp +++ b/src/plugins/windowsaudio/qwindowsaudioplugin.cpp @@ -49,6 +49,11 @@ QWindowsAudioPlugin::QWindowsAudioPlugin(QObject *parent) { } +QByteArray QWindowsAudioPlugin::defaultDevice(QAudio::Mode mode) const +{ + return QWindowsAudioDeviceInfo::defaultDevice(mode); +} + QList<QByteArray> QWindowsAudioPlugin::availableDevices(QAudio::Mode mode) const { return QWindowsAudioDeviceInfo::availableDevices(mode); diff --git a/src/plugins/windowsaudio/qwindowsaudioplugin.h b/src/plugins/windowsaudio/qwindowsaudioplugin.h index fb4749e0d..7b500a39c 100644 --- a/src/plugins/windowsaudio/qwindowsaudioplugin.h +++ b/src/plugins/windowsaudio/qwindowsaudioplugin.h @@ -41,19 +41,22 @@ #define QWINDOWSAUDIOPLUGIN_H #include <QtMultimedia/qaudiosystemplugin.h> +#include <QtMultimedia/private/qaudiosystempluginext_p.h> QT_BEGIN_NAMESPACE -class QWindowsAudioPlugin : public QAudioSystemPlugin +class QWindowsAudioPlugin : public QAudioSystemPlugin, public QAudioSystemPluginExtension { Q_OBJECT Q_PLUGIN_METADATA(IID "org.qt-project.qt.audiosystemfactory/5.0" FILE "windowsaudio.json") + Q_INTERFACES(QAudioSystemPluginExtension) public: QWindowsAudioPlugin(QObject *parent = 0); ~QWindowsAudioPlugin() {} + QByteArray defaultDevice(QAudio::Mode mode) const Q_DECL_OVERRIDE; QList<QByteArray> availableDevices(QAudio::Mode mode) const Q_DECL_OVERRIDE; QAbstractAudioInput *createInput(const QByteArray &device) Q_DECL_OVERRIDE; QAbstractAudioOutput *createOutput(const QByteArray &device) Q_DECL_OVERRIDE; diff --git a/src/plugins/windowsaudio/windowsaudio.pro b/src/plugins/windowsaudio/windowsaudio.pro index ce64847dc..6d5fe9495 100644 --- a/src/plugins/windowsaudio/windowsaudio.pro +++ b/src/plugins/windowsaudio/windowsaudio.pro @@ -1,8 +1,7 @@ TARGET = qtaudio_windows QT += multimedia-private -LIBS += -lstrmiids -lole32 -loleaut32 -!wince*:LIBS += -lwinmm +LIBS += -lstrmiids -lole32 -loleaut32 -lwinmm HEADERS += \ qwindowsaudioplugin.h \ diff --git a/src/plugins/winrt/qwinrtcameravideorenderercontrol.cpp b/src/plugins/winrt/qwinrtcameravideorenderercontrol.cpp index 796a36f55..a94e1c578 100644 --- a/src/plugins/winrt/qwinrtcameravideorenderercontrol.cpp +++ b/src/plugins/winrt/qwinrtcameravideorenderercontrol.cpp @@ -263,6 +263,9 @@ bool QWinRTCameraVideoRendererControlPrivate::getCameraSampleInfo(const ComPtr<I case DXGI_FORMAT_NV12: cameraSampleformat = QVideoFrame::Format_NV12; break; + case DXGI_FORMAT_YUY2: + cameraSampleformat = QVideoFrame::Format_YUYV; + break; default: cameraSampleformat = QVideoFrame::Format_Invalid; qErrnoWarning("Unsupported camera probe format."); diff --git a/src/qtmultimediaquicktools/qsgvideonode_texture.cpp b/src/qtmultimediaquicktools/qsgvideonode_texture.cpp index 599b70021..8080f3ec2 100644 --- a/src/qtmultimediaquicktools/qsgvideonode_texture.cpp +++ b/src/qtmultimediaquicktools/qsgvideonode_texture.cpp @@ -78,7 +78,7 @@ public: QSGVideoMaterialShader_Texture() : QSGMaterialShader() { - setShaderSourceFile(QOpenGLShader::Vertex, QStringLiteral(":/qtmultimediaquicktools/shaders/rgbvideo.vert")); + setShaderSourceFile(QOpenGLShader::Vertex, QStringLiteral(":/qtmultimediaquicktools/shaders/monoplanarvideo.vert")); setShaderSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/qtmultimediaquicktools/shaders/rgbvideo.frag")); } diff --git a/src/qtmultimediaquicktools/qsgvideonode_yuv.cpp b/src/qtmultimediaquicktools/qsgvideonode_yuv.cpp index 314a26264..68e6b456b 100644 --- a/src/qtmultimediaquicktools/qsgvideonode_yuv.cpp +++ b/src/qtmultimediaquicktools/qsgvideonode_yuv.cpp @@ -53,7 +53,8 @@ QList<QVideoFrame::PixelFormat> QSGVideoNodeFactory_YUV::supportedPixelFormats( if (handleType == QAbstractVideoBuffer::NoHandle) { formats << QVideoFrame::Format_YUV420P << QVideoFrame::Format_YV12 - << QVideoFrame::Format_NV12 << QVideoFrame::Format_NV21; + << QVideoFrame::Format_NV12 << QVideoFrame::Format_NV21 + << QVideoFrame::Format_UYVY << QVideoFrame::Format_YUYV; } return formats; @@ -109,6 +110,55 @@ protected: int m_id_opacity; }; +class QSGVideoMaterialShader_UYVY : public QSGMaterialShader +{ +public: + QSGVideoMaterialShader_UYVY() + : QSGMaterialShader() + { + setShaderSourceFile(QOpenGLShader::Vertex, QStringLiteral(":/qtmultimediaquicktools/shaders/monoplanarvideo.vert")); + setShaderSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/qtmultimediaquicktools/shaders/uyvyvideo.frag")); + } + + void updateState(const RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial) Q_DECL_OVERRIDE; + + char const *const *attributeNames() const Q_DECL_OVERRIDE { + static const char *names[] = { + "qt_VertexPosition", + "qt_VertexTexCoord", + 0 + }; + return names; + } + +protected: + void initialize() Q_DECL_OVERRIDE { + m_id_matrix = program()->uniformLocation("qt_Matrix"); + m_id_yuvtexture = program()->uniformLocation("yuvTexture"); + m_id_imageWidth = program()->uniformLocation("imageWidth"); + m_id_colorMatrix = program()->uniformLocation("colorMatrix"); + m_id_opacity = program()->uniformLocation("opacity"); + QSGMaterialShader::initialize(); + } + + int m_id_matrix; + int m_id_yuvtexture; + int m_id_imageWidth; + int m_id_colorMatrix; + int m_id_opacity; +}; + + +class QSGVideoMaterialShader_YUYV : public QSGVideoMaterialShader_UYVY +{ +public: + QSGVideoMaterialShader_YUYV() + : QSGVideoMaterialShader_UYVY() + { + setShaderSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/qtmultimediaquicktools/shaders/yuyvvideo.frag")); + } +}; + class QSGVideoMaterialShader_YUV_BiPlanar_swizzle : public QSGVideoMaterialShader_YUV_BiPlanar { @@ -152,13 +202,17 @@ public: ~QSGVideoMaterial_YUV(); virtual QSGMaterialType *type() const { - static QSGMaterialType biPlanarType, biPlanarSwizzleType, triPlanarType; + static QSGMaterialType biPlanarType, biPlanarSwizzleType, triPlanarType, uyvyType, yuyvType; switch (m_format.pixelFormat()) { case QVideoFrame::Format_NV12: return &biPlanarType; case QVideoFrame::Format_NV21: return &biPlanarSwizzleType; + case QVideoFrame::Format_UYVY: + return &uyvyType; + case QVideoFrame::Format_YUYV: + return &yuyvType; default: // Currently: YUV420P and YV12 return &triPlanarType; } @@ -170,6 +224,10 @@ public: return new QSGVideoMaterialShader_YUV_BiPlanar; case QVideoFrame::Format_NV21: return new QSGVideoMaterialShader_YUV_BiPlanar_swizzle; + case QVideoFrame::Format_UYVY: + return new QSGVideoMaterialShader_UYVY; + case QVideoFrame::Format_YUYV: + return new QSGVideoMaterialShader_YUYV; default: // Currently: YUV420P and YV12 return new QSGVideoMaterialShader_YUV_TriPlanar; } @@ -230,6 +288,8 @@ QSGVideoMaterial_YUV::QSGVideoMaterial_YUV(const QVideoSurfaceFormat &format) : case QVideoFrame::Format_YV12: m_planeCount = 3; break; + case QVideoFrame::Format_UYVY: + case QVideoFrame::Format_YUYV: default: m_planeCount = 1; break; @@ -293,7 +353,15 @@ void QSGVideoMaterial_YUV::bind() functions->glGetIntegerv(GL_UNPACK_ALIGNMENT, &previousAlignment); functions->glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - if (m_format.pixelFormat() == QVideoFrame::Format_NV12 + if (m_format.pixelFormat() == QVideoFrame::Format_UYVY + || m_format.pixelFormat() == QVideoFrame::Format_YUYV) { + int fw = m_frame.width() / 2; + m_planeWidth[0] = fw; + + functions->glActiveTexture(GL_TEXTURE0); + bindTexture(m_textureIds[0], fw, m_frame.height(), m_frame.bits(), GL_RGBA); + + } else if (m_format.pixelFormat() == QVideoFrame::Format_NV12 || m_format.pixelFormat() == QVideoFrame::Format_NV21) { const int y = 0; const int uv = 1; @@ -338,7 +406,6 @@ void QSGVideoMaterial_YUV::bind() void QSGVideoMaterial_YUV::bindTexture(int id, int w, int h, const uchar *bits, GLenum format) { QOpenGLFunctions *functions = QOpenGLContext::currentContext()->functions(); - functions->glBindTexture(GL_TEXTURE_2D, id); functions->glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0, format, GL_UNSIGNED_BYTE, bits); functions->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); @@ -399,4 +466,28 @@ void QSGVideoMaterialShader_YUV_TriPlanar::updateState(const RenderState &state, program()->setUniformValue(m_id_plane3Width, mat->m_planeWidth[2]); } +void QSGVideoMaterialShader_UYVY::updateState(const RenderState &state, + QSGMaterial *newMaterial, + QSGMaterial *oldMaterial) +{ + Q_UNUSED(oldMaterial); + + QSGVideoMaterial_YUV *mat = static_cast<QSGVideoMaterial_YUV *>(newMaterial); + + program()->setUniformValue(m_id_yuvtexture, 0); + + mat->bind(); + + program()->setUniformValue(m_id_colorMatrix, mat->m_colorMatrix); + program()->setUniformValue(m_id_imageWidth, mat->m_frame.width()); + + if (state.isOpacityDirty()) { + mat->m_opacity = state.opacity(); + program()->setUniformValue(m_id_opacity, GLfloat(mat->m_opacity)); + } + + if (state.isMatrixDirty()) + program()->setUniformValue(m_id_matrix, state.combinedMatrix()); +} + QT_END_NAMESPACE diff --git a/src/qtmultimediaquicktools/qtmultimediaquicktools.pro b/src/qtmultimediaquicktools/qtmultimediaquicktools.pro index e1425c3ec..e4e157a54 100644 --- a/src/qtmultimediaquicktools/qtmultimediaquicktools.pro +++ b/src/qtmultimediaquicktools/qtmultimediaquicktools.pro @@ -35,7 +35,7 @@ RESOURCES += \ qtmultimediaquicktools.qrc OTHER_FILES += \ - shaders/rgbvideo.vert \ + shaders/monoplanarvideo.vert \ shaders/rgbvideo_padded.vert \ shaders/rgbvideo.frag \ shaders/rgbvideo_swizzle.frag \ @@ -43,6 +43,8 @@ OTHER_FILES += \ shaders/biplanaryuvvideo.frag \ shaders/biplanaryuvvideo_swizzle.frag \ shaders/triplanaryuvvideo.vert \ - shaders/triplanaryuvvideo.frag + shaders/triplanaryuvvideo.frag \ + shaders/uyvyvideo.frag \ + shaders/yuyvvideo.frag load(qt_module) diff --git a/src/qtmultimediaquicktools/qtmultimediaquicktools.qrc b/src/qtmultimediaquicktools/qtmultimediaquicktools.qrc index b0a7f0789..d5efb1f3e 100644 --- a/src/qtmultimediaquicktools/qtmultimediaquicktools.qrc +++ b/src/qtmultimediaquicktools/qtmultimediaquicktools.qrc @@ -1,6 +1,6 @@ <RCC> <qresource prefix="/qtmultimediaquicktools"> - <file>shaders/rgbvideo.vert</file> + <file>shaders/monoplanarvideo.vert</file> <file>shaders/rgbvideo.frag</file> <file>shaders/rgbvideo_swizzle.frag</file> <file>shaders/rgbvideo_padded.vert</file> @@ -9,5 +9,7 @@ <file>shaders/biplanaryuvvideo_swizzle.frag</file> <file>shaders/triplanaryuvvideo.frag</file> <file>shaders/triplanaryuvvideo.vert</file> + <file>shaders/uyvyvideo.frag</file> + <file>shaders/yuyvvideo.frag</file> </qresource> </RCC> diff --git a/src/qtmultimediaquicktools/shaders/rgbvideo.vert b/src/qtmultimediaquicktools/shaders/monoplanarvideo.vert index 19915f2ff..19915f2ff 100644 --- a/src/qtmultimediaquicktools/shaders/rgbvideo.vert +++ b/src/qtmultimediaquicktools/shaders/monoplanarvideo.vert diff --git a/src/qtmultimediaquicktools/shaders/uyvyvideo.frag b/src/qtmultimediaquicktools/shaders/uyvyvideo.frag new file mode 100644 index 000000000..905035703 --- /dev/null +++ b/src/qtmultimediaquicktools/shaders/uyvyvideo.frag @@ -0,0 +1,22 @@ +uniform sampler2D yuvTexture; // UYVY macropixel texture passed as RGBA format +uniform mediump float imageWidth; // The UYVY texture appears to the shader with 1/2 the image width since we use the RGBA format to pass UYVY +uniform mediump mat4 colorMatrix; +uniform lowp float opacity; + +varying highp vec2 qt_TexCoord; + +void main() +{ + // For U0 Y0 V0 Y1 macropixel, lookup Y0 or Y1 based on whether + // the original texture x coord is even or odd. + mediump float Y; + if (fract(floor(qt_TexCoord.x * imageWidth + 0.5) / 2.0) > 0.0) + Y = texture2D(yuvTexture, qt_TexCoord).a; // odd so choose Y1 + else + Y = texture2D(yuvTexture, qt_TexCoord).g; // even so choose Y0 + mediump float Cb = texture2D(yuvTexture, qt_TexCoord).r; + mediump float Cr = texture2D(yuvTexture, qt_TexCoord).b; + + mediump vec4 color = vec4(Y, Cb, Cr, 1.0); + gl_FragColor = colorMatrix * color * opacity; +} diff --git a/src/qtmultimediaquicktools/shaders/yuyvvideo.frag b/src/qtmultimediaquicktools/shaders/yuyvvideo.frag new file mode 100644 index 000000000..72732cd66 --- /dev/null +++ b/src/qtmultimediaquicktools/shaders/yuyvvideo.frag @@ -0,0 +1,22 @@ +uniform sampler2D yuvTexture; // YUYV macropixel texture passed as RGBA format +uniform mediump float imageWidth; // The YUYV texture appears to the shader with 1/2 the image width since we use the RGBA format to pass YUYV +uniform mediump mat4 colorMatrix; +uniform lowp float opacity; + +varying highp vec2 qt_TexCoord; + +void main() +{ + // For Y0 U0 Y1 V0 macropixel, lookup Y0 or Y1 based on whether + // the original texture x coord is even or odd. + mediump float Y; + if (fract(floor(qt_TexCoord.x * imageWidth + 0.5) / 2.0) > 0.0) + Y = texture2D(yuvTexture, qt_TexCoord).b; // odd so choose Y1 + else + Y = texture2D(yuvTexture, qt_TexCoord).r; // even so choose Y0 + mediump float Cb = texture2D(yuvTexture, qt_TexCoord).g; + mediump float Cr = texture2D(yuvTexture, qt_TexCoord).a; + + mediump vec4 color = vec4(Y, Cb, Cr, 1.0); + gl_FragColor = colorMatrix * color * opacity; +} diff --git a/tests/auto/integration/qsoundeffect/BLACKLIST b/tests/auto/integration/qsoundeffect/BLACKLIST index 3a358789a..44f6c2751 100644 --- a/tests/auto/integration/qsoundeffect/BLACKLIST +++ b/tests/auto/integration/qsoundeffect/BLACKLIST @@ -6,3 +6,4 @@ redhatenterpriselinuxworkstation-6.6 rhel-7.1 opensuse-13.1 rhel-7.2 +opensuse-42.1 diff --git a/tests/auto/integration/qsoundeffect/qsoundeffect.pro b/tests/auto/integration/qsoundeffect/qsoundeffect.pro index 7a0f63e4b..c4d965121 100644 --- a/tests/auto/integration/qsoundeffect/qsoundeffect.pro +++ b/tests/auto/integration/qsoundeffect/qsoundeffect.pro @@ -14,6 +14,3 @@ unix:!mac { } TESTDATA += test.wav - - -config_pulseaudio: CONFIG += insignificant_testcase # Crashes in QSoundEffectPrivate::sampleReady with bufferAttr == 0 diff --git a/tests/auto/unit/qaudionamespace/tst_qaudionamespace.cpp b/tests/auto/unit/qaudionamespace/tst_qaudionamespace.cpp index ebc58b66b..7907cd290 100644 --- a/tests/auto/unit/qaudionamespace/tst_qaudionamespace.cpp +++ b/tests/auto/unit/qaudionamespace/tst_qaudionamespace.cpp @@ -30,7 +30,7 @@ #include <QtTest/QtTest> -#include "qaudio.h" +#include <QtMultimedia/qaudio.h> // Adds an enum, and the stringized version #define ADD_ENUM_TEST(x) \ @@ -49,6 +49,10 @@ private slots: void debugState_data(); void debugMode(); void debugMode_data(); + void debugVolumeScale(); + void debugVolumeScale_data(); + void convertVolume(); + void convertVolume_data(); }; void tst_QAudioNamespace::debugError_data() @@ -109,6 +113,103 @@ void tst_QAudioNamespace::debugMode() QTest::ignoreMessage(QtDebugMsg, stringized.toLatin1().constData()); qDebug() << mode; } + +void tst_QAudioNamespace::debugVolumeScale_data() +{ + QTest::addColumn<QAudio::VolumeScale>("volumeScale"); + QTest::addColumn<QString>("stringized"); + + ADD_ENUM_TEST(LinearVolumeScale); + ADD_ENUM_TEST(CubicVolumeScale); + ADD_ENUM_TEST(DecibelVolumeScale); +} + +void tst_QAudioNamespace::debugVolumeScale() +{ + QFETCH(QAudio::VolumeScale, volumeScale); + QFETCH(QString, stringized); + + QTest::ignoreMessage(QtDebugMsg, stringized.toLatin1().constData()); + qDebug() << volumeScale; +} + +void tst_QAudioNamespace::convertVolume_data() +{ + QTest::addColumn<qreal>("input"); + QTest::addColumn<QAudio::VolumeScale>("from"); + QTest::addColumn<QAudio::VolumeScale>("to"); + QTest::addColumn<qreal>("expectedOutput"); + + QTest::newRow("-1.0 from linear to linear") << qreal(-1.0) << QAudio::LinearVolumeScale << QAudio::LinearVolumeScale << qreal(0.0); + QTest::newRow("0.0 from linear to linear") << qreal(0.0) << QAudio::LinearVolumeScale << QAudio::LinearVolumeScale << qreal(0.0); + QTest::newRow("0.5 from linear to linear") << qreal(0.5) << QAudio::LinearVolumeScale << QAudio::LinearVolumeScale << qreal(0.5); + QTest::newRow("1.0 from linear to linear") << qreal(1.0) << QAudio::LinearVolumeScale << QAudio::LinearVolumeScale << qreal(1.0); + + QTest::newRow("-1.0 from linear to cubic") << qreal(-1.0) << QAudio::LinearVolumeScale << QAudio::CubicVolumeScale << qreal(0.0); + QTest::newRow("0.0 from linear to cubic") << qreal(0.0) << QAudio::LinearVolumeScale << QAudio::CubicVolumeScale << qreal(0.0); + QTest::newRow("0.33 from linear to cubic") << qreal(0.33) << QAudio::LinearVolumeScale << QAudio::CubicVolumeScale << qreal(0.69); + QTest::newRow("0.5 from linear to cubic") << qreal(0.5) << QAudio::LinearVolumeScale << QAudio::CubicVolumeScale << qreal(0.79); + QTest::newRow("0.72 from linear to cubic") << qreal(0.72) << QAudio::LinearVolumeScale << QAudio::CubicVolumeScale << qreal(0.89); + QTest::newRow("1.0 from linear to cubic") << qreal(1.0) << QAudio::LinearVolumeScale << QAudio::CubicVolumeScale << qreal(1.0); + + QTest::newRow("-1.0 from linear to decibel") << qreal(-1.0) << QAudio::LinearVolumeScale << QAudio::DecibelVolumeScale << qreal(-200); + QTest::newRow("0.0 from linear to decibel") << qreal(0.0) << QAudio::LinearVolumeScale << QAudio::DecibelVolumeScale << qreal(-200); + QTest::newRow("0.33 from linear to decibel") << qreal(0.33) << QAudio::LinearVolumeScale << QAudio::DecibelVolumeScale << qreal(-9.63); + QTest::newRow("0.5 from linear to decibel") << qreal(0.5) << QAudio::LinearVolumeScale << QAudio::DecibelVolumeScale << qreal(-6.02); + QTest::newRow("0.72 from linear to decibel") << qreal(0.72) << QAudio::LinearVolumeScale << QAudio::DecibelVolumeScale << qreal(-2.85); + QTest::newRow("1.0 from linear to decibel") << qreal(1.0) << QAudio::LinearVolumeScale << QAudio::DecibelVolumeScale << qreal(0); + + QTest::newRow("-1.0 from cubic to linear") << qreal(-1.0) << QAudio::CubicVolumeScale << QAudio::LinearVolumeScale << qreal(0.0); + QTest::newRow("0.0 from cubic to linear") << qreal(0.0) << QAudio::CubicVolumeScale << QAudio::LinearVolumeScale << qreal(0.0); + QTest::newRow("0.33 from cubic to linear") << qreal(0.33) << QAudio::CubicVolumeScale << QAudio::LinearVolumeScale << qreal(0.04); + QTest::newRow("0.5 from cubic to linear") << qreal(0.5) << QAudio::CubicVolumeScale << QAudio::LinearVolumeScale << qreal(0.13); + QTest::newRow("0.72 from cubic to linear") << qreal(0.72) << QAudio::CubicVolumeScale << QAudio::LinearVolumeScale << qreal(0.37); + QTest::newRow("1.0 from cubic to linear") << qreal(1.0) << QAudio::CubicVolumeScale << QAudio::LinearVolumeScale << qreal(1.0); + + QTest::newRow("-1.0 from cubic to cubic") << qreal(-1.0) << QAudio::CubicVolumeScale << QAudio::CubicVolumeScale << qreal(0.0); + QTest::newRow("0.0 from cubic to cubic") << qreal(0.0) << QAudio::CubicVolumeScale << QAudio::CubicVolumeScale << qreal(0.0); + QTest::newRow("0.5 from cubic to cubic") << qreal(0.5) << QAudio::CubicVolumeScale << QAudio::CubicVolumeScale << qreal(0.5); + QTest::newRow("1.0 from cubic to cubic") << qreal(1.0) << QAudio::CubicVolumeScale << QAudio::CubicVolumeScale << qreal(1.0); + + QTest::newRow("-1.0 from cubic to decibel") << qreal(-1.0) << QAudio::CubicVolumeScale << QAudio::DecibelVolumeScale << qreal(-200); + QTest::newRow("0.0 from cubic to decibel") << qreal(0.0) << QAudio::CubicVolumeScale << QAudio::DecibelVolumeScale << qreal(-200); + QTest::newRow("0.33 from cubic to decibel") << qreal(0.33) << QAudio::CubicVolumeScale << QAudio::DecibelVolumeScale << qreal(-28.89); + QTest::newRow("0.5 from cubic to decibel") << qreal(0.5) << QAudio::CubicVolumeScale << QAudio::DecibelVolumeScale << qreal(-18.06); + QTest::newRow("0.72 from cubic to decibel") << qreal(0.72) << QAudio::CubicVolumeScale << QAudio::DecibelVolumeScale << qreal(-8.56); + QTest::newRow("1.0 from cubic to decibel") << qreal(1.0) << QAudio::CubicVolumeScale << QAudio::DecibelVolumeScale << qreal(0); + + QTest::newRow("-1000 from decibel to linear") << qreal(-1000.0) << QAudio::DecibelVolumeScale << QAudio::LinearVolumeScale << qreal(0.0); + QTest::newRow("-200 from decibel to linear") << qreal(-200.0) << QAudio::DecibelVolumeScale << QAudio::LinearVolumeScale << qreal(0.0); + QTest::newRow("-40 from decibel to linear") << qreal(-40.0) << QAudio::DecibelVolumeScale << QAudio::LinearVolumeScale << qreal(0.01); + QTest::newRow("-10 from decibel to linear") << qreal(-10.0) << QAudio::DecibelVolumeScale << QAudio::LinearVolumeScale << qreal(0.32); + QTest::newRow("-5 from decibel to linear") << qreal(-5.0) << QAudio::DecibelVolumeScale << QAudio::LinearVolumeScale << qreal(0.56); + QTest::newRow("0 from decibel to linear") << qreal(0.0) << QAudio::DecibelVolumeScale << QAudio::LinearVolumeScale << qreal(1.0); + + QTest::newRow("-1000 from decibel to cubic") << qreal(-1000.0) << QAudio::DecibelVolumeScale << QAudio::CubicVolumeScale << qreal(0.0); + QTest::newRow("-200 from decibel to cubic") << qreal(-200.0) << QAudio::DecibelVolumeScale << QAudio::CubicVolumeScale << qreal(0.0); + QTest::newRow("-40 from decibel to cubic") << qreal(-40.0) << QAudio::DecibelVolumeScale << QAudio::CubicVolumeScale << qreal(0.22); + QTest::newRow("-10 from decibel to cubic") << qreal(-10.0) << QAudio::DecibelVolumeScale << QAudio::CubicVolumeScale << qreal(0.68); + QTest::newRow("-5 from decibel to cubic") << qreal(-5.0) << QAudio::DecibelVolumeScale << QAudio::CubicVolumeScale << qreal(0.83); + QTest::newRow("0 from decibel to cubic") << qreal(0.0) << QAudio::DecibelVolumeScale << QAudio::CubicVolumeScale << qreal(1.0); + + QTest::newRow("-1000 from decibel to decibel") << qreal(-1000.0) << QAudio::DecibelVolumeScale << QAudio::DecibelVolumeScale << qreal(-1000.0); + QTest::newRow("-200 from decibel to decibel") << qreal(-200.0) << QAudio::DecibelVolumeScale << QAudio::DecibelVolumeScale << qreal(-200.0); + QTest::newRow("-30 from decibel to decibel") << qreal(-30.0) << QAudio::DecibelVolumeScale << QAudio::DecibelVolumeScale << qreal(-30.0); + QTest::newRow("0 from decibel to decibel") << qreal(0.0) << QAudio::DecibelVolumeScale << QAudio::DecibelVolumeScale << qreal(0.0); +} + +void tst_QAudioNamespace::convertVolume() +{ + QFETCH(qreal, input); + QFETCH(QAudio::VolumeScale, from); + QFETCH(QAudio::VolumeScale, to); + QFETCH(qreal, expectedOutput); + + qreal actualOutput = QAudio::convertVolume(input, from, to); + QVERIFY2(qAbs(actualOutput - expectedOutput) < 0.01, + QString("actual: %1, expected: %2").arg(actualOutput).arg(expectedOutput).toLocal8Bit().constData()); +} + QTEST_MAIN(tst_QAudioNamespace) #include "tst_qaudionamespace.moc" diff --git a/tests/auto/unit/qdeclarativemultimediaglobal/tst_qdeclarativemultimediaglobal.qml b/tests/auto/unit/qdeclarativemultimediaglobal/tst_qdeclarativemultimediaglobal.qml index bce0ca791..22f4bf604 100644 --- a/tests/auto/unit/qdeclarativemultimediaglobal/tst_qdeclarativemultimediaglobal.qml +++ b/tests/auto/unit/qdeclarativemultimediaglobal/tst_qdeclarativemultimediaglobal.qml @@ -63,4 +63,71 @@ TestCase { compare(camera.orientation, 0, "orientation"); } + function test_convertVolume_data() { + return [ + { tag: "-1.0 from linear to linear", input: -1, from: QtMultimedia.LinearVolumeScale, to: QtMultimedia.LinearVolumeScale, expectedOutput: 0 }, + { tag: "0.0 from linear to linear", input: 0, from: QtMultimedia.LinearVolumeScale, to: QtMultimedia.LinearVolumeScale, expectedOutput: 0 }, + { tag: "0.5 from linear to linear", input: 0.5, from: QtMultimedia.LinearVolumeScale, to: QtMultimedia.LinearVolumeScale, expectedOutput: 0.5 }, + { tag: "1.0 from linear to linear", input: 1.0, from: QtMultimedia.LinearVolumeScale, to: QtMultimedia.LinearVolumeScale, expectedOutput: 1.0 }, + + { tag: "-1.0 from linear to cubic", input: -1, from: QtMultimedia.LinearVolumeScale, to: QtMultimedia.CubicVolumeScale, expectedOutput: 0 }, + { tag: "0.0 from linear to cubic", input: 0, from: QtMultimedia.LinearVolumeScale, to: QtMultimedia.CubicVolumeScale, expectedOutput: 0 }, + { tag: "0.33 from linear to cubic", input: 0.33, from: QtMultimedia.LinearVolumeScale, to: QtMultimedia.CubicVolumeScale, expectedOutput: 0.69 }, + { tag: "0.5 from linear to cubic", input: 0.5, from: QtMultimedia.LinearVolumeScale, to: QtMultimedia.CubicVolumeScale, expectedOutput: 0.79 }, + { tag: "0.72 from linear to cubic", input: 0.72, from: QtMultimedia.LinearVolumeScale, to: QtMultimedia.CubicVolumeScale, expectedOutput: 0.89 }, + { tag: "1.0 from linear to cubic", input: 1.0, from: QtMultimedia.LinearVolumeScale, to: QtMultimedia.CubicVolumeScale, expectedOutput: 1.0 }, + + { tag: "-1.0 from linear to decibel", input: -1, from: QtMultimedia.LinearVolumeScale, to: QtMultimedia.DecibelVolumeScale, expectedOutput: -200 }, + { tag: "0.0 from linear to decibel", input: 0, from: QtMultimedia.LinearVolumeScale, to: QtMultimedia.DecibelVolumeScale, expectedOutput: -200 }, + { tag: "0.33 from linear to decibel", input: 0.33, from: QtMultimedia.LinearVolumeScale, to: QtMultimedia.DecibelVolumeScale, expectedOutput: -9.63 }, + { tag: "0.5 from linear to decibel", input: 0.5, from: QtMultimedia.LinearVolumeScale, to: QtMultimedia.DecibelVolumeScale, expectedOutput: -6.02 }, + { tag: "0.72 from linear to decibel", input: 0.72, from: QtMultimedia.LinearVolumeScale, to: QtMultimedia.DecibelVolumeScale, expectedOutput: -2.85 }, + { tag: "1.0 from linear to decibel", input: 1.0, from: QtMultimedia.LinearVolumeScale, to: QtMultimedia.DecibelVolumeScale, expectedOutput: 0 }, + + { tag: "-1.0 from cubic to linear", input: -1, from: QtMultimedia.CubicVolumeScale, to: QtMultimedia.LinearVolumeScale, expectedOutput: 0 }, + { tag: "0.0 from cubic to linear", input: 0, from: QtMultimedia.CubicVolumeScale, to: QtMultimedia.LinearVolumeScale, expectedOutput: 0 }, + { tag: "0.33 from cubic to linear", input: 0.33, from: QtMultimedia.CubicVolumeScale, to: QtMultimedia.LinearVolumeScale, expectedOutput: 0.04 }, + { tag: "0.5 from cubic to linear", input: 0.5, from: QtMultimedia.CubicVolumeScale, to: QtMultimedia.LinearVolumeScale, expectedOutput: 0.13 }, + { tag: "0.72 from cubic to linear", input: 0.72, from: QtMultimedia.CubicVolumeScale, to: QtMultimedia.LinearVolumeScale, expectedOutput: 0.37 }, + { tag: "1.0 from cubic to linear", input: 1.0, from: QtMultimedia.CubicVolumeScale, to: QtMultimedia.LinearVolumeScale, expectedOutput: 1 }, + + { tag: "-1.0 from cubic to cubic", input: -1, from: QtMultimedia.CubicVolumeScale, to: QtMultimedia.CubicVolumeScale, expectedOutput: 0 }, + { tag: "0.0 from cubic to cubic", input: 0, from: QtMultimedia.CubicVolumeScale, to: QtMultimedia.CubicVolumeScale, expectedOutput: 0 }, + { tag: "0.5 from cubic to cubic", input: 0.5, from: QtMultimedia.CubicVolumeScale, to: QtMultimedia.CubicVolumeScale, expectedOutput: 0.5 }, + { tag: "1.0 from cubic to cubic", input: 1.0, from: QtMultimedia.CubicVolumeScale, to: QtMultimedia.CubicVolumeScale, expectedOutput: 1.0 }, + + { tag: "-1.0 from cubic to decibel", input: -1, from: QtMultimedia.CubicVolumeScale, to: QtMultimedia.DecibelVolumeScale, expectedOutput: -200 }, + { tag: "0.0 from cubic to decibel", input: 0, from: QtMultimedia.CubicVolumeScale, to: QtMultimedia.DecibelVolumeScale, expectedOutput: -200 }, + { tag: "0.33 from cubic to decibel", input: 0.33, from: QtMultimedia.CubicVolumeScale, to: QtMultimedia.DecibelVolumeScale, expectedOutput: -28.89 }, + { tag: "0.5 from cubic to decibel", input: 0.5, from: QtMultimedia.CubicVolumeScale, to: QtMultimedia.DecibelVolumeScale, expectedOutput: -18.06 }, + { tag: "0.72 from cubic to decibel", input: 0.72, from: QtMultimedia.CubicVolumeScale, to: QtMultimedia.DecibelVolumeScale, expectedOutput: -8.56 }, + { tag: "1.0 from cubic to decibel", input: 1.0, from: QtMultimedia.CubicVolumeScale, to: QtMultimedia.DecibelVolumeScale, expectedOutput: 0 }, + + { tag: "-1000 from decibel to linear", input: -1000, from: QtMultimedia.DecibelVolumeScale, to: QtMultimedia.LinearVolumeScale, expectedOutput: 0 }, + { tag: "-200 from decibel to linear", input: -200, from: QtMultimedia.DecibelVolumeScale, to: QtMultimedia.LinearVolumeScale, expectedOutput: 0 }, + { tag: "-40 from decibel to linear", input: -40, from: QtMultimedia.DecibelVolumeScale, to: QtMultimedia.LinearVolumeScale, expectedOutput: 0.01 }, + { tag: "-10 from decibel to linear", input: -10, from: QtMultimedia.DecibelVolumeScale, to: QtMultimedia.LinearVolumeScale, expectedOutput: 0.32 }, + { tag: "-5 from decibel to linear", input: -5, from: QtMultimedia.DecibelVolumeScale, to: QtMultimedia.LinearVolumeScale, expectedOutput: 0.56 }, + { tag: "0 from decibel to linear", input: 0, from: QtMultimedia.DecibelVolumeScale, to: QtMultimedia.LinearVolumeScale, expectedOutput: 1 }, + + { tag: "-1000 from decibel to cubic", input: -1000, from: QtMultimedia.DecibelVolumeScale, to: QtMultimedia.CubicVolumeScale, expectedOutput: 0 }, + { tag: "-200 from decibel to cubic", input: -200, from: QtMultimedia.DecibelVolumeScale, to: QtMultimedia.CubicVolumeScale, expectedOutput: 0 }, + { tag: "-40 from decibel to cubic", input: -40, from: QtMultimedia.DecibelVolumeScale, to: QtMultimedia.CubicVolumeScale, expectedOutput: 0.22 }, + { tag: "-10 from decibel to cubic", input: -10, from: QtMultimedia.DecibelVolumeScale, to: QtMultimedia.CubicVolumeScale, expectedOutput: 0.68 }, + { tag: "-5 from decibel to cubic", input: -5, from: QtMultimedia.DecibelVolumeScale, to: QtMultimedia.CubicVolumeScale, expectedOutput: 0.83 }, + { tag: "0 from decibel to cubic", input: 0, from: QtMultimedia.DecibelVolumeScale, to: QtMultimedia.CubicVolumeScale, expectedOutput: 1 }, + + { tag: "-1000 from decibel to decibel", input: -1000, from: QtMultimedia.DecibelVolumeScale, to: QtMultimedia.DecibelVolumeScale, expectedOutput: -1000 }, + { tag: "-200 from decibel to decibel", input: -200, from: QtMultimedia.DecibelVolumeScale, to: QtMultimedia.DecibelVolumeScale, expectedOutput: -200 }, + { tag: "-30 from decibel to decibel", input: -30, from: QtMultimedia.DecibelVolumeScale, to: QtMultimedia.DecibelVolumeScale, expectedOutput: -30 }, + { tag: "0 from decibel to decibel", input: 0, from: QtMultimedia.DecibelVolumeScale, to: QtMultimedia.DecibelVolumeScale, expectedOutput: 0 }, + ] + } + + function test_convertVolume(data) { + fuzzyCompare(QtMultimedia.convertVolume(data.input, data.from, data.to), + data.expectedOutput, + 0.01); + } + } diff --git a/tests/auto/unit/qmediapluginloader/qmediapluginloader.pro b/tests/auto/unit/qmediapluginloader/qmediapluginloader.pro index 26f232010..90b02ac59 100644 --- a/tests/auto/unit/qmediapluginloader/qmediapluginloader.pro +++ b/tests/auto/unit/qmediapluginloader/qmediapluginloader.pro @@ -4,10 +4,3 @@ TARGET = tst_qmediapluginloader QT += multimedia-private testlib SOURCES += tst_qmediapluginloader.cpp - -wince* { - PLUGIN_DEPLOY.sources = $$OUTPUT_DIR/plugins/mediaservice/*.dll - PLUGIN_DEPLOY.path = mediaservice - DEPLOYMENT += PLUGIN_DEPLOY -} - |