From 241444eab724ba0cb4fa142c5ccb02243b6f2dc2 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Mon, 15 Feb 2016 12:19:24 +0100 Subject: [Win] Compile fix, the mmdeviceapi.h header can only be included once Change-Id: Idb9a995c90e6e0e8be392022e2a76b4d8fea853a Reviewed-by: Yoann Lopes --- src/plugins/wmf/player/mfaudioendpointcontrol.cpp | 2 ++ src/plugins/wmf/player/mfaudioendpointcontrol.h | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/plugins/wmf/player/mfaudioendpointcontrol.cpp b/src/plugins/wmf/player/mfaudioendpointcontrol.cpp index 7178a75c1..939b98f0d 100644 --- a/src/plugins/wmf/player/mfaudioendpointcontrol.cpp +++ b/src/plugins/wmf/player/mfaudioendpointcontrol.cpp @@ -34,6 +34,8 @@ #include "QtCore/qdebug.h" #include "mfaudioendpointcontrol.h" +#include + MFAudioEndpointControl::MFAudioEndpointControl(QObject *parent) : QAudioOutputSelectorControl(parent) , m_currentActivate(0) diff --git a/src/plugins/wmf/player/mfaudioendpointcontrol.h b/src/plugins/wmf/player/mfaudioendpointcontrol.h index d0186a4ac..18791e1c3 100644 --- a/src/plugins/wmf/player/mfaudioendpointcontrol.h +++ b/src/plugins/wmf/player/mfaudioendpointcontrol.h @@ -36,7 +36,6 @@ #include #include -#include #include "qaudiooutputselectorcontrol.h" -- cgit v1.2.1 From 857996876e769bbdd1ab5058b8c3c9c9f3406190 Mon Sep 17 00:00:00 2001 From: Yoann Lopes Date: Thu, 25 Feb 2016 15:33:27 +0100 Subject: Add 5.6.0 changelog. Change-Id: I1e7ad9b663db94d2986277c92abf574f6380e44d Reviewed-by: Christian Stromme --- dist/changes-5.6.0 | 138 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 138 insertions(+) create mode 100644 dist/changes-5.6.0 diff --git a/dist/changes-5.6.0 b/dist/changes-5.6.0 new file mode 100644 index 000000000..5051431f8 --- /dev/null +++ b/dist/changes-5.6.0 @@ -0,0 +1,138 @@ +Qt 5.6 introduces many new features and improvements as well as bugfixes +over the 5.5.x series. For more details, refer to the online documentation +included in this distribution. The documentation is also available online: + + http://doc.qt.io/qt-5.6 + +The Qt version 5.6 series is binary compatible with the 5.5.x series. +Applications compiled for 5.5 will continue to run with 5.6. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + + http://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* Important Behavior Changes * +**************************************************************************** + + - QAudioOutput now transitions to IdleState instead of ActiveState when + calling resume() in push mode. This was already the documented behavior + but in practice, it was not respected on any platform. See QTBUG-50390. + + - DirectShow is now the default backend on all desktop versions of Windows, + regardless of the compiler used. The Windows Media Foundation backend + (WMF) can be re-enabled by configuring Qt with the -wmf-backend option. + See QTBUG-45597. + +**************************************************************************** +* Library * +**************************************************************************** + +QtMultimedia +------------ + + - Added new Playlist QML type. + + - Audio Engine QML types + * All types can now be created dynamically and added to the engine + using new 'add' functions. + + - MediaPlayer, Audio and Video (QML): + * Added new audio role API. + * Added playlist support. + + - QMediaPlayer: + * Added new audio role API. + + - [QTBUG-49838] Fixed crash when playing very short WAV files with + QSoundEffect. + +**************************************************************************** +* Platform Specific Changes * +**************************************************************************** + +Android +------- + + - QAudioOutput: improved detection of the default buffer size and sample + rate. + - [QTBUG-35416] Camera QVideoFrames can now me mapped when retrieved using + QAbstractVideoSurface or QVideoProbe. + - [QTBUG-37837] Fixed crash when recording the camera on specific devices. + - [QTBUG-46491] Fixed media player blocking the UI when loading a media. + - [QTBUG-49134] Fixed crash when starting the camera on specific devices. + - [QTBUG-50282] Fixed QAudioRecorder crashing when trying to start it + with invalid settings. + +iOS / OS X +---------- + + - Greatly improved performance of displaying camera frames using the QML + VideoOutput type on iOS. + - Camera capture previews from the imageCaptured() signal are now in higher + resolutions. + - QMediaPlayer::isSeekable() (and QML counterpart) now correctly reports + the seekable status. + - QAudioRecorder::setVolume() is now functional. + - [QTBUG-45570] Fixed media player playback rate not working when set + before calling play(). + - [QTBUG-48057] Media player now correctly seeks as soon as playback starts + when the position is changed before calling play(). + - [QTBUG-48154] Fixed media player volume not working when set before + loading a media. + - [QTBUG-49170] It is not necessary anymore to set a viewfinder on a + QCamera to be able to query the supported viewfinder settings. + - [QTBUG-49170] Fixed QCamera ignoring the resolution set in + QCameraViewfinderSettings. + +Linux +----- + + - QCameraImageProcessing is now functional. + - [QTBUG-49531] Fixed QMediaPlayer not being able to play the same resource + file more than once. + +QNX +--- + + - QAudioRecorder::setVolume() is now functional. + - [QTBUG-49668] Fixed 'loops' property not working for Audio, Video and + MediaPlayer QML types. + +Windows +------- + + - [QTBUG-45593] The DirectShow backend now supports HW-accelerated video + decoding. + - The QML MediaPlayer and Video types previously supported HW-accelerated + video decoding only when using the ANGLE OpenGL implementation. It now + works with desktop OpenGL as well. + - QAudioRecorder::setVolume() is now functional. + - QCameraImageProcessing is now functional. + - Fixed media player volume not working when set before a media is loaded. + - Fixed QVideoFrame::startTime() not returning any value. + - Fixed seek requests never being processed when QMediaPlayer::setPosition() + is called while the media is not playing. + +WinRT +----- + + - Improved camera support: focus, focus lock and video probe APIs are now + functional. + - [QTBUG-47465] Fixed camera viewfinder aspect ratio. + - [QTBUG-47809] Fixed camera frames being upside down after switching + between front and back cameras. + - [QTBUG-48331][QTBUG-49660] Fixed camera viewfinder frames not being + displayed on the Lumia 930 and 1520. + - [QTBUG-48534] Fixed QCamera::searchAndLock() blocking the UI. + - [QTBUG-48569] Fixed crash when resuming an application that uses the + camera. + - [QTBUG-48672] Fixed crash when mapping camera frames after the camera + has stopped. + - [QTBUG-49236] Fixed playback of local files. + - [QTBUG-49347] Fixed crash when the application is suspended while + a camera focus lock is in progress. -- cgit v1.2.1 From 9985224a89b830dc182b428f491b6187d6f0e1ba Mon Sep 17 00:00:00 2001 From: Yoann Lopes Date: Wed, 24 Feb 2016 14:25:33 +0100 Subject: Update version number in QML plugins. Also removes unnecessary references of that import version in the documentation and snippets. The import version is always displayed at the top of every doc page anyway. Change-Id: Ifbf4666e0bc333c51f51104a5720b988e8c04d0b Reviewed-by: Christian Stromme --- src/imports/audioengine/audioengine.pro | 2 +- src/imports/audioengine/plugins.qmltypes | 4 ++-- src/imports/audioengine/qdeclarative_attenuationmodel_p.cpp | 12 ------------ src/imports/audioengine/qdeclarative_audiocategory_p.cpp | 5 ----- src/imports/audioengine/qdeclarative_audioengine_p.cpp | 5 ----- src/imports/audioengine/qdeclarative_audiolistener_p.cpp | 8 -------- src/imports/audioengine/qdeclarative_audiosample_p.cpp | 5 ----- src/imports/audioengine/qdeclarative_playvariation_p.cpp | 5 ----- src/imports/audioengine/qdeclarative_sound_p.cpp | 4 ---- src/imports/audioengine/qdeclarative_soundinstance_p.cpp | 8 -------- src/multimedia/doc/src/multimedia.qdoc | 4 ++-- src/multimedia/doc/src/qtaudioengine.qdoc | 4 ++-- src/multimedia/doc/src/qtmultimedia-index.qdoc | 2 +- src/multimedia/doc/src/qtmultimedia5.qdoc | 4 ++-- 14 files changed, 10 insertions(+), 62 deletions(-) diff --git a/src/imports/audioengine/audioengine.pro b/src/imports/audioengine/audioengine.pro index 6c4b17c1d..c00a6ec6b 100644 --- a/src/imports/audioengine/audioengine.pro +++ b/src/imports/audioengine/audioengine.pro @@ -1,7 +1,7 @@ CXX_MODULE = multimedia TARGET = declarative_audioengine TARGETPATH = QtAudioEngine -IMPORT_VERSION = 1.0 +IMPORT_VERSION = 1.1 QT += quick qml multimedia-private diff --git a/src/imports/audioengine/plugins.qmltypes b/src/imports/audioengine/plugins.qmltypes index 22fad073a..0468d839a 100644 --- a/src/imports/audioengine/plugins.qmltypes +++ b/src/imports/audioengine/plugins.qmltypes @@ -4,10 +4,10 @@ import QtQuick.tooling 1.2 // It is used for QML tooling purposes only. // // This file was auto-generated by: -// 'qmlplugindump -nonrelocatable QtAudioEngine 1.0' +// 'qmlplugindump -nonrelocatable QtAudioEngine 1.1' Module { - dependencies: [] + dependencies: ["QtQuick 2.0"] Component { name: "QDeclarativeAttenuationModel" prototype: "QObject" diff --git a/src/imports/audioengine/qdeclarative_attenuationmodel_p.cpp b/src/imports/audioengine/qdeclarative_attenuationmodel_p.cpp index 7ecdb41ae..c15c77767 100644 --- a/src/imports/audioengine/qdeclarative_attenuationmodel_p.cpp +++ b/src/imports/audioengine/qdeclarative_attenuationmodel_p.cpp @@ -79,17 +79,11 @@ void QDeclarativeAttenuationModel::setName(const QString& name) \inherits Item \preliminary - This type is part of the \b{QtAudioEngine 1.0} module. - AttenuationModelLinear must be defined inside \l AudioEngine or be added to it using \l{QtAudioEngine::AudioEngine::addAttenuationModel()}{AudioEngine.addAttenuationModel()} if AttenuationModelLinear is created dynamically. \qml - import QtQuick 2.0 - import QtAudioEngine 1.0 - - Rectangle { color:"white" width: 300 @@ -214,17 +208,11 @@ qreal QDeclarativeAttenuationModelLinear::calculateGain(const QVector3D &listene \inherits Item \preliminary - This type is part of the \b{QtAudioEngine 1.0} module. - AttenuationModelInverse must be defined inside \l AudioEngine or be added to it using \l{QtAudioEngine::AudioEngine::addAttenuationModel()}{AudioEngine.addAttenuationModel()} if AttenuationModelInverse is created dynamically. \qml - import QtQuick 2.0 - import QtAudioEngine 1.0 - - Rectangle { color:"white" width: 300 diff --git a/src/imports/audioengine/qdeclarative_audiocategory_p.cpp b/src/imports/audioengine/qdeclarative_audiocategory_p.cpp index 847941ca9..4931cce7f 100644 --- a/src/imports/audioengine/qdeclarative_audiocategory_p.cpp +++ b/src/imports/audioengine/qdeclarative_audiocategory_p.cpp @@ -48,17 +48,12 @@ QT_USE_NAMESPACE \inherits Item \preliminary - This type is part of the \b{QtAudioEngine 1.0} module. - An instance of AudioCategory can be accessed through \l {QtAudioEngine::AudioEngine::categories} {AudioEngine.categories} with its unique name and must be defined inside AudioEngine or be added to it using \l{QtAudioEngine::AudioEngine::addAudioCategory()}{AudioEngine.addAudioCategory()} if AudioCategory is created dynamically. \qml - import QtQuick 2.0 - import QtAudioEngine 1.0 - Rectangle { color:"white" width: 300 diff --git a/src/imports/audioengine/qdeclarative_audioengine_p.cpp b/src/imports/audioengine/qdeclarative_audioengine_p.cpp index dd80c698d..bb53cbb34 100644 --- a/src/imports/audioengine/qdeclarative_audioengine_p.cpp +++ b/src/imports/audioengine/qdeclarative_audioengine_p.cpp @@ -57,12 +57,7 @@ QT_BEGIN_NAMESPACE \inherits Item \preliminary - \c AudioEngine is part of the \b{QtAudioEngine 1.0} module. - \qml - import QtQuick 2.0 - import QtAudioEngine 1.0 - Rectangle { color:"white" width: 300 diff --git a/src/imports/audioengine/qdeclarative_audiolistener_p.cpp b/src/imports/audioengine/qdeclarative_audiolistener_p.cpp index 0403fc1c7..645a0446b 100644 --- a/src/imports/audioengine/qdeclarative_audiolistener_p.cpp +++ b/src/imports/audioengine/qdeclarative_audiolistener_p.cpp @@ -49,15 +49,10 @@ QT_USE_NAMESPACE \inherits Item \preliminary - This type is part of the \b{QtAudioEngine 1.0} module. - AudioListener will have only one global instance and you can either access it through the listener property of AudioEngine: \qml - import QtQuick 2.0 - import QtAudioEngine 1.0 - Rectangle { color:"white" width: 300 @@ -92,9 +87,6 @@ QT_USE_NAMESPACE or alternatively, by defining an AudioListener outside AudioEngine: \qml - import QtQuick 2.0 - import QtAudioEngine 1.0 - Rectangle { color:"white" width: 300 diff --git a/src/imports/audioengine/qdeclarative_audiosample_p.cpp b/src/imports/audioengine/qdeclarative_audiosample_p.cpp index 297af3b31..09f708702 100644 --- a/src/imports/audioengine/qdeclarative_audiosample_p.cpp +++ b/src/imports/audioengine/qdeclarative_audiosample_p.cpp @@ -51,17 +51,12 @@ QT_USE_NAMESPACE \inherits Item \preliminary - \c AudioSample is part of the \b{QtAudioEngine 1.0} module. - It can be accessed through QtAudioEngine::AudioEngine::samples with its unique name and must be defined inside AudioEngine or be added to it using \l{QtAudioEngine::AudioEngine::addAudioSample()}{AudioEngine.addAudioSample()} if AudioSample is created dynamically. \qml - import QtQuick 2.0 - import QtAudioEngine 1.0 - Rectangle { color:"white" width: 300 diff --git a/src/imports/audioengine/qdeclarative_playvariation_p.cpp b/src/imports/audioengine/qdeclarative_playvariation_p.cpp index 156f83f68..ac2bd67ad 100644 --- a/src/imports/audioengine/qdeclarative_playvariation_p.cpp +++ b/src/imports/audioengine/qdeclarative_playvariation_p.cpp @@ -53,16 +53,11 @@ QT_USE_NAMESPACE \inherits Item \preliminary - This type is part of the \b{QtAudioEngine 1.0} module. - PlayVariation must be defined inside a \l Sound or be added to it using \l{QtAudioEngine::Sound::addPlayVariation()}{Sound.addPlayVariation()} if PlayVariation is created dynamically. \qml - import QtQuick 2.0 - import QtAudioEngine 1.0 - Rectangle { color:"white" width: 300 diff --git a/src/imports/audioengine/qdeclarative_sound_p.cpp b/src/imports/audioengine/qdeclarative_sound_p.cpp index f19b8dbb3..497b8349a 100644 --- a/src/imports/audioengine/qdeclarative_sound_p.cpp +++ b/src/imports/audioengine/qdeclarative_sound_p.cpp @@ -159,16 +159,12 @@ void QDeclarativeSoundCone::setEngine(QDeclarativeAudioEngine *engine) \inherits Item \preliminary - This type is part of the \b{QtAudioEngine 1.0} module. - Sound can be accessed through QtAudioEngine::AudioEngine::sounds with its unique name and must be defined inside AudioEngine or be added to it using \l{QtAudioEngine::AudioEngine::addSound()}{AudioEngine.addSound()} if \l Sound is created dynamically. \qml - import QtQuick 2.0 - import QtAudioEngine 1.0 Rectangle { color:"white" diff --git a/src/imports/audioengine/qdeclarative_soundinstance_p.cpp b/src/imports/audioengine/qdeclarative_soundinstance_p.cpp index bdb2e775a..c29972478 100644 --- a/src/imports/audioengine/qdeclarative_soundinstance_p.cpp +++ b/src/imports/audioengine/qdeclarative_soundinstance_p.cpp @@ -52,15 +52,10 @@ QT_USE_NAMESPACE \inherits Item \preliminary - This type is part of the \b{QtAudioEngine 1.0} module. - There are two ways to create SoundInstance objects. You can obtain it by calling newInstance method of a \l Sound: \qml - import QtQuick 2.0 - import QtAudioEngine 1.0 - Rectangle { id:root color:"white" @@ -98,9 +93,6 @@ QT_USE_NAMESPACE easier qml bindings: \qml - import QtQuick 2.0 - import QtAudioEngine 1.0 - Rectangle { id:root color:"white" diff --git a/src/multimedia/doc/src/multimedia.qdoc b/src/multimedia/doc/src/multimedia.qdoc index 5849af59d..813847d88 100644 --- a/src/multimedia/doc/src/multimedia.qdoc +++ b/src/multimedia/doc/src/multimedia.qdoc @@ -177,12 +177,12 @@ what changed, and what you might need to change when porting code. \section2 QML Types The QML types are accessed by using: \code -import QtMultimedia 5.5 +import QtMultimedia 5.6 \endcode \annotatedlist multimedia_qml The following types are accessed by using \l{Qt Audio Engine QML Types}{Qt Audio Engine}: \code -import QtAudioEngine 1.0 +import QtAudioEngine 1.1 \endcode \annotatedlist multimedia_audioengine diff --git a/src/multimedia/doc/src/qtaudioengine.qdoc b/src/multimedia/doc/src/qtaudioengine.qdoc index 3b65379d3..2de2bb250 100644 --- a/src/multimedia/doc/src/qtaudioengine.qdoc +++ b/src/multimedia/doc/src/qtaudioengine.qdoc @@ -26,7 +26,7 @@ ****************************************************************************/ /*! -\qmlmodule QtAudioEngine 1.0 +\qmlmodule QtAudioEngine 1.1 \title Qt Audio Engine QML Types \ingroup qmlmodules \brief Provides QML types for 3D positional audio playback and content management. @@ -37,7 +37,7 @@ Engine provides types for 3D positional audio playback and content management. The QML types can be imported into your application using the following import statement in your .qml file: \code -import QtAudioEngine 1.0 +import QtAudioEngine 1.1 \endcode \section1 Qt Audio Engine Features diff --git a/src/multimedia/doc/src/qtmultimedia-index.qdoc b/src/multimedia/doc/src/qtmultimedia-index.qdoc index e51ec97e0..989b8886e 100644 --- a/src/multimedia/doc/src/qtmultimedia-index.qdoc +++ b/src/multimedia/doc/src/qtmultimedia-index.qdoc @@ -54,7 +54,7 @@ import statement in your \c {.qml} file. \code - import QtMultimedia 5.5 + import QtMultimedia 5.6 \endcode If you intend to use the C++ classes in your application, include the C++ diff --git a/src/multimedia/doc/src/qtmultimedia5.qdoc b/src/multimedia/doc/src/qtmultimedia5.qdoc index 0d3e087a0..21854ae7c 100644 --- a/src/multimedia/doc/src/qtmultimedia5.qdoc +++ b/src/multimedia/doc/src/qtmultimedia5.qdoc @@ -26,7 +26,7 @@ ****************************************************************************/ /*! -\qmlmodule QtMultimedia 5.5 +\qmlmodule QtMultimedia 5.6 \title Qt Multimedia QML Types \ingroup qmlmodules \brief Provides QML types for multimedia support. @@ -42,7 +42,7 @@ The QML types for \l{Qt Multimedia} support the basic use cases such as: The QML types can be imported into your application using the following import statement in your .qml file: \code -import QtMultimedia 5.5 +import QtMultimedia 5.6 \endcode \section1 QML types -- cgit v1.2.1 From c82402e158100d1c755bdcbaab731952ad487821 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 12 Feb 2016 16:23:59 +0100 Subject: consistently put {qt,qml}_{module,plugin} at the end of project files this fixes static builds by ensuring that all dependencies are exported. Task-number: QTBUG-51071 Change-Id: I8e1554b648327ea2fb342b882ce8e439bd6f271d Reviewed-by: Yoann Lopes --- src/multimedia/multimedia.pro | 4 ++-- src/multimediawidgets/multimediawidgets.pro | 4 ++-- src/plugins/alsa/alsa.pro | 8 ++++---- src/plugins/android/src/src.pro | 9 +++++---- src/plugins/android/videonode/videonode.pro | 11 ++++++----- src/plugins/audiocapture/audiocapture.pro | 8 ++++---- src/plugins/avfoundation/camera/camera.pro | 8 ++++---- src/plugins/avfoundation/mediaplayer/mediaplayer.pro | 8 ++++---- src/plugins/coreaudio/coreaudio.pro | 8 ++++---- src/plugins/directshow/directshow.pro | 7 ++++--- src/plugins/gstreamer/audiodecoder/audiodecoder.pro | 7 +++---- src/plugins/gstreamer/camerabin/camerabin.pro | 8 ++++---- src/plugins/gstreamer/mediacapture/mediacapture.pro | 8 ++++---- src/plugins/gstreamer/mediaplayer/mediaplayer.pro | 8 ++++---- src/plugins/m3u/m3u.pro | 8 ++++---- src/plugins/opensles/opensles.pro | 8 ++++---- src/plugins/pulseaudio/pulseaudio.pro | 8 ++++---- src/plugins/qnx-audio/audio/audio.pro | 5 +++-- src/plugins/qnx/qnx.pro | 8 ++++---- src/plugins/resourcepolicy/resourcepolicy.pro | 7 +++---- src/plugins/v4l/v4l.pro | 8 ++++---- src/plugins/videonode/egl/egl.pro | 11 ++++++----- src/plugins/videonode/imx6/imx6.pro | 11 ++++++----- src/plugins/windowsaudio/windowsaudio.pro | 8 ++++---- src/plugins/winrt/winrt.pro | 8 ++++---- src/plugins/wmf/wmf.pro | 8 ++++---- src/qtmultimediaquicktools/qtmultimediaquicktools.pro | 4 ++-- .../mockserviceplugin1/mockserviceplugin1.pro | 14 +++++++------- .../mockserviceplugin2/mockserviceplugin2.pro | 14 +++++++------- .../mockserviceplugin3/mockserviceplugin3.pro | 14 +++++++------- .../mockserviceplugin4/mockserviceplugin4.pro | 14 +++++++------- .../mockserviceplugin5/mockserviceplugin5.pro | 14 +++++++------- 32 files changed, 141 insertions(+), 137 deletions(-) diff --git a/src/multimedia/multimedia.pro b/src/multimedia/multimedia.pro index b16a792fb..acde6fe8e 100644 --- a/src/multimedia/multimedia.pro +++ b/src/multimedia/multimedia.pro @@ -12,8 +12,6 @@ MODULE_PLUGIN_TYPES = \ QMAKE_DOCS = $$PWD/doc/qtmultimedia.qdocconf -load(qt_module) - INCLUDEPATH *= . PRIVATE_HEADERS += \ @@ -87,3 +85,5 @@ ANDROID_FEATURES += \ win32: LIBS_PRIVATE += -luuid HEADERS += $$PUBLIC_HEADERS $$PRIVATE_HEADERS + +load(qt_module) diff --git a/src/multimediawidgets/multimediawidgets.pro b/src/multimediawidgets/multimediawidgets.pro index ec96be57c..60321fba8 100644 --- a/src/multimediawidgets/multimediawidgets.pro +++ b/src/multimediawidgets/multimediawidgets.pro @@ -7,8 +7,6 @@ qtHaveModule(opengl):!contains(QT_CONFIG, opengles1) { DEFINES += QT_NO_OPENGL } -load(qt_module) - PRIVATE_HEADERS += \ qvideowidget_p.h \ qpaintervideosurface_p.h \ @@ -44,3 +42,5 @@ maemo6 { } HEADERS += $$PUBLIC_HEADERS $$PRIVATE_HEADERS + +load(qt_module) diff --git a/src/plugins/alsa/alsa.pro b/src/plugins/alsa/alsa.pro index 481c57eaf..56657f100 100644 --- a/src/plugins/alsa/alsa.pro +++ b/src/plugins/alsa/alsa.pro @@ -1,10 +1,6 @@ TARGET = qtaudio_alsa QT += multimedia-private -PLUGIN_TYPE = audio -PLUGIN_CLASS_NAME = QAlsaPlugin -load(qt_plugin) - LIBS += -lasound HEADERS += \ @@ -21,3 +17,7 @@ SOURCES += \ OTHER_FILES += \ alsa.json + +PLUGIN_TYPE = audio +PLUGIN_CLASS_NAME = QAlsaPlugin +load(qt_plugin) diff --git a/src/plugins/android/src/src.pro b/src/plugins/android/src/src.pro index 6a472a0a8..166bcc42b 100644 --- a/src/plugins/android/src/src.pro +++ b/src/plugins/android/src/src.pro @@ -1,9 +1,6 @@ TARGET = qtmedia_android -QT += multimedia-private core-private network -PLUGIN_TYPE = mediaservice -PLUGIN_CLASS_NAME = QAndroidMediaServicePlugin -load(qt_plugin) +QT += multimedia-private core-private network HEADERS += \ qandroidmediaserviceplugin.h @@ -17,3 +14,7 @@ include (mediaplayer/mediaplayer.pri) include (mediacapture/mediacapture.pri) OTHER_FILES += android_mediaservice.json + +PLUGIN_TYPE = mediaservice +PLUGIN_CLASS_NAME = QAndroidMediaServicePlugin +load(qt_plugin) diff --git a/src/plugins/android/videonode/videonode.pro b/src/plugins/android/videonode/videonode.pro index 661e36436..daf07c9ec 100644 --- a/src/plugins/android/videonode/videonode.pro +++ b/src/plugins/android/videonode/videonode.pro @@ -1,10 +1,6 @@ TARGET = qtsgvideonode_android -QT += quick multimedia-private qtmultimediaquicktools-private -PLUGIN_TYPE = video/videonode -PLUGIN_EXTENDS = quick -PLUGIN_CLASS_NAME = QAndroidSGVideoNodeFactoryPlugin -load(qt_plugin) +QT += quick multimedia-private qtmultimediaquicktools-private HEADERS += \ qandroidsgvideonodeplugin.h \ @@ -15,3 +11,8 @@ SOURCES += \ qandroidsgvideonode.cpp OTHER_FILES += android_videonode.json + +PLUGIN_TYPE = video/videonode +PLUGIN_EXTENDS = quick +PLUGIN_CLASS_NAME = QAndroidSGVideoNodeFactoryPlugin +load(qt_plugin) diff --git a/src/plugins/audiocapture/audiocapture.pro b/src/plugins/audiocapture/audiocapture.pro index 833e4b5fc..ba2e5c802 100644 --- a/src/plugins/audiocapture/audiocapture.pro +++ b/src/plugins/audiocapture/audiocapture.pro @@ -1,10 +1,6 @@ TARGET = qtmedia_audioengine QT += multimedia-private -PLUGIN_TYPE=mediaservice -PLUGIN_CLASS_NAME = AudioCaptureServicePlugin -load(qt_plugin) - HEADERS += audioencodercontrol.h \ audiocontainercontrol.h \ audiomediarecordercontrol.h \ @@ -25,3 +21,7 @@ SOURCES += audioencodercontrol.cpp \ OTHER_FILES += \ audiocapture.json + +PLUGIN_TYPE = mediaservice +PLUGIN_CLASS_NAME = AudioCaptureServicePlugin +load(qt_plugin) diff --git a/src/plugins/avfoundation/camera/camera.pro b/src/plugins/avfoundation/camera/camera.pro index a82d88ded..4e443cc1d 100644 --- a/src/plugins/avfoundation/camera/camera.pro +++ b/src/plugins/avfoundation/camera/camera.pro @@ -4,10 +4,6 @@ CONFIG += no_keywords TARGET = qavfcamera QT += multimedia-private network -PLUGIN_TYPE = mediaservice -PLUGIN_CLASS_NAME = AVFServicePlugin -load(qt_plugin) - LIBS += -framework AudioToolbox \ -framework CoreAudio \ -framework QuartzCore \ @@ -79,3 +75,7 @@ OBJECTIVE_SOURCES += avfcamerazoomcontrol.mm \ avfmediarecordercontrol_ios.mm } + +PLUGIN_TYPE = mediaservice +PLUGIN_CLASS_NAME = AVFServicePlugin +load(qt_plugin) diff --git a/src/plugins/avfoundation/mediaplayer/mediaplayer.pro b/src/plugins/avfoundation/mediaplayer/mediaplayer.pro index 28cdc2727..ff9e5bca9 100644 --- a/src/plugins/avfoundation/mediaplayer/mediaplayer.pro +++ b/src/plugins/avfoundation/mediaplayer/mediaplayer.pro @@ -7,10 +7,6 @@ CONFIG += no_keywords TARGET = qavfmediaplayer QT += multimedia-private network -PLUGIN_TYPE = mediaservice -PLUGIN_CLASS_NAME = AVFMediaPlayerServicePlugin -load(qt_plugin) - LIBS += -framework AVFoundation -framework CoreMedia DEFINES += QMEDIA_AVF_MEDIAPLAYER @@ -74,3 +70,7 @@ ios { OTHER_FILES += \ avfmediaplayer.json + +PLUGIN_TYPE = mediaservice +PLUGIN_CLASS_NAME = AVFMediaPlayerServicePlugin +load(qt_plugin) diff --git a/src/plugins/coreaudio/coreaudio.pro b/src/plugins/coreaudio/coreaudio.pro index 146851493..0757b463c 100644 --- a/src/plugins/coreaudio/coreaudio.pro +++ b/src/plugins/coreaudio/coreaudio.pro @@ -1,10 +1,6 @@ TARGET = qtaudio_coreaudio QT += multimedia-private -PLUGIN_TYPE = audio -PLUGIN_CLASS_NAME = CoreAudioPlugin - -load(qt_plugin) OTHER_FILES += \ coreaudio.json @@ -37,3 +33,7 @@ ios { LIBS += \ -framework CoreAudio \ -framework AudioToolbox + +PLUGIN_TYPE = audio +PLUGIN_CLASS_NAME = CoreAudioPlugin +load(qt_plugin) diff --git a/src/plugins/directshow/directshow.pro b/src/plugins/directshow/directshow.pro index 4d7183923..280b52619 100644 --- a/src/plugins/directshow/directshow.pro +++ b/src/plugins/directshow/directshow.pro @@ -2,9 +2,6 @@ TARGET = dsengine win32:!qtHaveModule(opengl)|contains(QT_CONFIG,dynamicgl) { LIBS_PRIVATE += -lgdi32 -luser32 } -PLUGIN_TYPE=mediaservice -PLUGIN_CLASS_NAME = DSServicePlugin -load(qt_plugin) QT += multimedia-private @@ -21,3 +18,7 @@ include(camera/camera.pri) OTHER_FILES += \ directshow.json \ directshow_camera.json + +PLUGIN_TYPE = mediaservice +PLUGIN_CLASS_NAME = DSServicePlugin +load(qt_plugin) diff --git a/src/plugins/gstreamer/audiodecoder/audiodecoder.pro b/src/plugins/gstreamer/audiodecoder/audiodecoder.pro index 8cd1d587e..4e816e920 100644 --- a/src/plugins/gstreamer/audiodecoder/audiodecoder.pro +++ b/src/plugins/gstreamer/audiodecoder/audiodecoder.pro @@ -1,9 +1,5 @@ TARGET = gstaudiodecoder -PLUGIN_TYPE = mediaservice -PLUGIN_CLASS_NAME = QGstreamerAudioDecoderServicePlugin -load(qt_plugin) - include(../common.pri) INCLUDEPATH += $$PWD @@ -23,3 +19,6 @@ SOURCES += \ OTHER_FILES += \ audiodecoder.json +PLUGIN_TYPE = mediaservice +PLUGIN_CLASS_NAME = QGstreamerAudioDecoderServicePlugin +load(qt_plugin) diff --git a/src/plugins/gstreamer/camerabin/camerabin.pro b/src/plugins/gstreamer/camerabin/camerabin.pro index b807071f2..214489f3e 100644 --- a/src/plugins/gstreamer/camerabin/camerabin.pro +++ b/src/plugins/gstreamer/camerabin/camerabin.pro @@ -2,10 +2,6 @@ TARGET = gstcamerabin QT += multimedia-private -PLUGIN_TYPE = mediaservice -PLUGIN_CLASS_NAME = CameraBinServicePlugin -load(qt_plugin) - include(../common.pri) INCLUDEPATH += $$PWD \ @@ -101,3 +97,7 @@ config_linux_v4l: { OTHER_FILES += \ camerabin.json + +PLUGIN_TYPE = mediaservice +PLUGIN_CLASS_NAME = CameraBinServicePlugin +load(qt_plugin) diff --git a/src/plugins/gstreamer/mediacapture/mediacapture.pro b/src/plugins/gstreamer/mediacapture/mediacapture.pro index 5baa0fd8f..db5210d4d 100644 --- a/src/plugins/gstreamer/mediacapture/mediacapture.pro +++ b/src/plugins/gstreamer/mediacapture/mediacapture.pro @@ -1,9 +1,5 @@ TARGET = gstmediacapture -PLUGIN_TYPE = mediaservice -PLUGIN_CLASS_NAME = QGstreamerCaptureServicePlugin -load(qt_plugin) - include(../common.pri) INCLUDEPATH += $$PWD @@ -50,3 +46,7 @@ use_gstreamer_camera:config_linux_v4l { OTHER_FILES += \ mediacapture.json } + +PLUGIN_TYPE = mediaservice +PLUGIN_CLASS_NAME = QGstreamerCaptureServicePlugin +load(qt_plugin) diff --git a/src/plugins/gstreamer/mediaplayer/mediaplayer.pro b/src/plugins/gstreamer/mediaplayer/mediaplayer.pro index b986fc787..5ccf89bfd 100644 --- a/src/plugins/gstreamer/mediaplayer/mediaplayer.pro +++ b/src/plugins/gstreamer/mediaplayer/mediaplayer.pro @@ -1,9 +1,5 @@ TARGET = gstmediaplayer -PLUGIN_TYPE = mediaservice -PLUGIN_CLASS_NAME = QGstreamerPlayerServicePlugin -load(qt_plugin) - include(../common.pri) INCLUDEPATH += $$PWD @@ -28,3 +24,7 @@ SOURCES += \ OTHER_FILES += \ mediaplayer.json + +PLUGIN_TYPE = mediaservice +PLUGIN_CLASS_NAME = QGstreamerPlayerServicePlugin +load(qt_plugin) diff --git a/src/plugins/m3u/m3u.pro b/src/plugins/m3u/m3u.pro index 3897e2de8..d46911e0d 100644 --- a/src/plugins/m3u/m3u.pro +++ b/src/plugins/m3u/m3u.pro @@ -1,12 +1,12 @@ TARGET = qtmultimedia_m3u QT += multimedia-private -PLUGIN_TYPE=playlistformats -PLUGIN_CLASS_NAME = QM3uPlaylistPlugin -load(qt_plugin) - HEADERS += qm3uhandler.h SOURCES += qm3uhandler.cpp OTHER_FILES += \ m3u.json + +PLUGIN_TYPE = playlistformats +PLUGIN_CLASS_NAME = QM3uPlaylistPlugin +load(qt_plugin) diff --git a/src/plugins/opensles/opensles.pro b/src/plugins/opensles/opensles.pro index aa8e05444..2bb0f3cf5 100644 --- a/src/plugins/opensles/opensles.pro +++ b/src/plugins/opensles/opensles.pro @@ -1,10 +1,6 @@ TARGET = qtaudio_opensles QT += multimedia-private core-private -PLUGIN_TYPE = audio -PLUGIN_CLASS_NAME = QOpenSLESPlugin -load(qt_plugin) - LIBS += -lOpenSLES HEADERS += \ @@ -23,3 +19,7 @@ SOURCES += \ OTHER_FILES += \ opensles.json + +PLUGIN_TYPE = audio +PLUGIN_CLASS_NAME = QOpenSLESPlugin +load(qt_plugin) diff --git a/src/plugins/pulseaudio/pulseaudio.pro b/src/plugins/pulseaudio/pulseaudio.pro index e8ab9317c..7f4d3de22 100644 --- a/src/plugins/pulseaudio/pulseaudio.pro +++ b/src/plugins/pulseaudio/pulseaudio.pro @@ -1,10 +1,6 @@ TARGET = qtmedia_pulse QT += multimedia-private -PLUGIN_TYPE = audio -PLUGIN_CLASS_NAME = QPulseAudioPlugin -load(qt_plugin) - CONFIG += link_pkgconfig PKGCONFIG += libpulse @@ -24,3 +20,7 @@ SOURCES += qpulseaudioplugin.cpp \ OTHER_FILES += \ pulseaudio.json + +PLUGIN_TYPE = audio +PLUGIN_CLASS_NAME = QPulseAudioPlugin +load(qt_plugin) diff --git a/src/plugins/qnx-audio/audio/audio.pro b/src/plugins/qnx-audio/audio/audio.pro index 35ddf73de..bf4300a71 100644 --- a/src/plugins/qnx-audio/audio/audio.pro +++ b/src/plugins/qnx-audio/audio/audio.pro @@ -2,8 +2,6 @@ TARGET = qtmedia_qnx_audio QT += multimedia-private CONFIG += no_private_qt_headers_warning -PLUGIN_TYPE = audio -load(qt_plugin) LIBS += -lasound @@ -20,3 +18,6 @@ SOURCES += qnxaudioplugin.cpp \ qnxaudioutils.cpp OTHER_FILES += qnx_audio.json + +PLUGIN_TYPE = audio +load(qt_plugin) diff --git a/src/plugins/qnx/qnx.pro b/src/plugins/qnx/qnx.pro index f01562116..4d76fa5f7 100644 --- a/src/plugins/qnx/qnx.pro +++ b/src/plugins/qnx/qnx.pro @@ -1,10 +1,6 @@ TARGET = qtmedia_qnx QT += multimedia-private gui-private -PLUGIN_TYPE=mediaservice -PLUGIN_CLASS_NAME = BbServicePlugin -load(qt_plugin) - LIBS += -lscreen include(common/common.pri) @@ -20,3 +16,7 @@ blackberry { SOURCES += neutrinoserviceplugin.cpp OTHER_FILES += neutrino_mediaservice.json } + +PLUGIN_TYPE = mediaservice +PLUGIN_CLASS_NAME = BbServicePlugin +load(qt_plugin) diff --git a/src/plugins/resourcepolicy/resourcepolicy.pro b/src/plugins/resourcepolicy/resourcepolicy.pro index 4805c5250..e333bac09 100644 --- a/src/plugins/resourcepolicy/resourcepolicy.pro +++ b/src/plugins/resourcepolicy/resourcepolicy.pro @@ -4,10 +4,6 @@ QT += multimedia-private CONFIG += no_private_qt_headers_warning link_pkgconfig PKGCONFIG += libresourceqt5 -PLUGIN_TYPE = resourcepolicy -PLUGIN_CLASS_NAME = ResourceQtPolicyPlugin -load(qt_plugin) - INCLUDEPATH += $$PWD \ $${SOURCE_DIR}/src/multimedia @@ -21,3 +17,6 @@ SOURCES += \ $$PWD/resourcepolicyimpl.cpp \ $$PWD/resourcepolicyint.cpp +PLUGIN_TYPE = resourcepolicy +PLUGIN_CLASS_NAME = ResourceQtPolicyPlugin +load(qt_plugin) diff --git a/src/plugins/v4l/v4l.pro b/src/plugins/v4l/v4l.pro index c5e953538..28d89e3e9 100644 --- a/src/plugins/v4l/v4l.pro +++ b/src/plugins/v4l/v4l.pro @@ -1,11 +1,11 @@ TARGET = qtmedia_v4lengine QT += multimedia-private -PLUGIN_TYPE = mediaservice -PLUGIN_CLASS_NAME = V4LServicePlugin -load(qt_plugin) - HEADERS += v4lserviceplugin.h SOURCES += v4lserviceplugin.cpp include(radio/radio.pri) + +PLUGIN_TYPE = mediaservice +PLUGIN_CLASS_NAME = V4LServicePlugin +load(qt_plugin) diff --git a/src/plugins/videonode/egl/egl.pro b/src/plugins/videonode/egl/egl.pro index a6256cea1..7151123ea 100644 --- a/src/plugins/videonode/egl/egl.pro +++ b/src/plugins/videonode/egl/egl.pro @@ -1,12 +1,8 @@ TARGET = eglvideonode + QT += multimedia-private qtmultimediaquicktools-private CONFIG += egl -PLUGIN_TYPE=video/videonode -PLUGIN_EXTENDS = quick -PLUGIN_CLASS_NAME = QSGVideoNodeFactory_EGL -load(qt_plugin) - HEADERS += \ qsgvideonode_egl.h @@ -15,3 +11,8 @@ SOURCES += \ OTHER_FILES += \ egl.json + +PLUGIN_TYPE = video/videonode +PLUGIN_EXTENDS = quick +PLUGIN_CLASS_NAME = QSGVideoNodeFactory_EGL +load(qt_plugin) diff --git a/src/plugins/videonode/imx6/imx6.pro b/src/plugins/videonode/imx6/imx6.pro index 36e25e86b..c8085a31e 100644 --- a/src/plugins/videonode/imx6/imx6.pro +++ b/src/plugins/videonode/imx6/imx6.pro @@ -1,10 +1,6 @@ TARGET = imx6vivantevideonode -QT += multimedia-private qtmultimediaquicktools-private -PLUGIN_TYPE=video/videonode -PLUGIN_EXTENDS = quick -PLUGIN_CLASS_NAME = QSGVivanteVideoNodeFactory -load(qt_plugin) +QT += multimedia-private qtmultimediaquicktools-private HEADERS += \ qsgvivantevideonode.h \ @@ -20,3 +16,8 @@ SOURCES += \ OTHER_FILES += \ imx6.json + +PLUGIN_TYPE = video/videonode +PLUGIN_EXTENDS = quick +PLUGIN_CLASS_NAME = QSGVivanteVideoNodeFactory +load(qt_plugin) diff --git a/src/plugins/windowsaudio/windowsaudio.pro b/src/plugins/windowsaudio/windowsaudio.pro index 7e8e4320b..ce64847dc 100644 --- a/src/plugins/windowsaudio/windowsaudio.pro +++ b/src/plugins/windowsaudio/windowsaudio.pro @@ -1,10 +1,6 @@ TARGET = qtaudio_windows QT += multimedia-private -PLUGIN_TYPE = audio -PLUGIN_CLASS_NAME = QWindowsAudioPlugin -load(qt_plugin) - LIBS += -lstrmiids -lole32 -loleaut32 !wince*:LIBS += -lwinmm @@ -24,3 +20,7 @@ SOURCES += \ OTHER_FILES += \ windowsaudio.json + +PLUGIN_TYPE = audio +PLUGIN_CLASS_NAME = QWindowsAudioPlugin +load(qt_plugin) diff --git a/src/plugins/winrt/winrt.pro b/src/plugins/winrt/winrt.pro index 2f87ea8ff..87e44cce2 100644 --- a/src/plugins/winrt/winrt.pro +++ b/src/plugins/winrt/winrt.pro @@ -1,10 +1,6 @@ TARGET = winrtengine QT += multimedia-private -PLUGIN_TYPE=mediaservice -PLUGIN_CLASS_NAME = WinRTServicePlugin -load(qt_plugin) - LIBS += -lmfplat -lmfuuid -loleaut32 -ld3d11 -lruntimeobject HEADERS += \ @@ -43,3 +39,7 @@ SOURCES += \ OTHER_FILES += \ winrt.json + +PLUGIN_TYPE = mediaservice +PLUGIN_CLASS_NAME = WinRTServicePlugin +load(qt_plugin) diff --git a/src/plugins/wmf/wmf.pro b/src/plugins/wmf/wmf.pro index 1f43bb128..e83c51595 100644 --- a/src/plugins/wmf/wmf.pro +++ b/src/plugins/wmf/wmf.pro @@ -5,10 +5,6 @@ win32:!qtHaveModule(opengl) { LIBS_PRIVATE += -lgdi32 -luser32 } -PLUGIN_TYPE=mediaservice -PLUGIN_CLASS_NAME = WMFServicePlugin -load(qt_plugin) - INCLUDEPATH += . HEADERS += \ @@ -32,3 +28,7 @@ include (decoder/decoder.pri) OTHER_FILES += \ wmf.json + +PLUGIN_TYPE = mediaservice +PLUGIN_CLASS_NAME = WMFServicePlugin +load(qt_plugin) diff --git a/src/qtmultimediaquicktools/qtmultimediaquicktools.pro b/src/qtmultimediaquicktools/qtmultimediaquicktools.pro index b38f209e3..0a5110f59 100644 --- a/src/qtmultimediaquicktools/qtmultimediaquicktools.pro +++ b/src/qtmultimediaquicktools/qtmultimediaquicktools.pro @@ -2,8 +2,6 @@ TARGET = QtMultimediaQuick_p QT = core quick multimedia-private CONFIG += internal_module -load(qt_module) - DEFINES += QT_BUILD_QTMM_QUICK_LIB # Header files must go inside source directory of a module @@ -47,3 +45,5 @@ OTHER_FILES += \ shaders/biplanaryuvvideo_swizzle.frag \ shaders/triplanaryuvvideo.vert \ shaders/triplanaryuvvideo.frag + +load(qt_module) diff --git a/tests/auto/unit/qmediaserviceprovider/mockserviceplugin1/mockserviceplugin1.pro b/tests/auto/unit/qmediaserviceprovider/mockserviceplugin1/mockserviceplugin1.pro index 68dee28a9..2b7412d16 100644 --- a/tests/auto/unit/qmediaserviceprovider/mockserviceplugin1/mockserviceplugin1.pro +++ b/tests/auto/unit/qmediaserviceprovider/mockserviceplugin1/mockserviceplugin1.pro @@ -1,7 +1,13 @@ TARGET = mockserviceplugin1 QT += multimedia-private -PLUGIN_TYPE=mediaservice +HEADERS += ../mockservice.h +SOURCES += mockserviceplugin1.cpp +OTHER_FILES += mockserviceplugin1.json + +DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 + +PLUGIN_TYPE = mediaservice PLUGIN_CLASS_NAME = MockServicePlugin1 load(qt_plugin) @@ -14,10 +20,4 @@ win32 { } } -HEADERS += ../mockservice.h -SOURCES += mockserviceplugin1.cpp -OTHER_FILES += mockserviceplugin1.json - target.path = $$[QT_INSTALL_TESTS]/tst_qmediaserviceprovider/$${PLUGIN_TYPE} - -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/unit/qmediaserviceprovider/mockserviceplugin2/mockserviceplugin2.pro b/tests/auto/unit/qmediaserviceprovider/mockserviceplugin2/mockserviceplugin2.pro index 98a3ca4a4..ff793ec85 100644 --- a/tests/auto/unit/qmediaserviceprovider/mockserviceplugin2/mockserviceplugin2.pro +++ b/tests/auto/unit/qmediaserviceprovider/mockserviceplugin2/mockserviceplugin2.pro @@ -1,7 +1,13 @@ TARGET = mockserviceplugin2 QT += multimedia-private -PLUGIN_TYPE=mediaservice +HEADERS += ../mockservice.h +SOURCES += mockserviceplugin2.cpp +OTHER_FILES += mockserviceplugin2.json + +DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 + +PLUGIN_TYPE = mediaservice PLUGIN_CLASS_NAME = MockServicePlugin2 load(qt_plugin) @@ -14,10 +20,4 @@ win32 { } } -HEADERS += ../mockservice.h -SOURCES += mockserviceplugin2.cpp -OTHER_FILES += mockserviceplugin2.json - target.path = $$[QT_INSTALL_TESTS]/tst_qmediaserviceprovider/$${PLUGIN_TYPE} - -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/unit/qmediaserviceprovider/mockserviceplugin3/mockserviceplugin3.pro b/tests/auto/unit/qmediaserviceprovider/mockserviceplugin3/mockserviceplugin3.pro index 50def293f..15e9dc659 100644 --- a/tests/auto/unit/qmediaserviceprovider/mockserviceplugin3/mockserviceplugin3.pro +++ b/tests/auto/unit/qmediaserviceprovider/mockserviceplugin3/mockserviceplugin3.pro @@ -1,7 +1,13 @@ TARGET = mockserviceplugin3 QT += multimedia-private -PLUGIN_TYPE=mediaservice +HEADERS += ../mockservice.h +SOURCES += mockserviceplugin3.cpp +OTHER_FILES += mockserviceplugin3.json + +DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 + +PLUGIN_TYPE = mediaservice PLUGIN_CLASS_NAME = MockServicePlugin3 load(qt_plugin) @@ -14,10 +20,4 @@ win32 { } } -HEADERS += ../mockservice.h -SOURCES += mockserviceplugin3.cpp -OTHER_FILES += mockserviceplugin3.json - target.path = $$[QT_INSTALL_TESTS]/tst_qmediaserviceprovider/$${PLUGIN_TYPE} - -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/unit/qmediaserviceprovider/mockserviceplugin4/mockserviceplugin4.pro b/tests/auto/unit/qmediaserviceprovider/mockserviceplugin4/mockserviceplugin4.pro index 57b715f52..894d92939 100644 --- a/tests/auto/unit/qmediaserviceprovider/mockserviceplugin4/mockserviceplugin4.pro +++ b/tests/auto/unit/qmediaserviceprovider/mockserviceplugin4/mockserviceplugin4.pro @@ -1,7 +1,13 @@ TARGET = mockserviceplugin4 QT += multimedia-private -PLUGIN_TYPE=mediaservice +HEADERS += ../mockservice.h +SOURCES += mockserviceplugin4.cpp +OTHER_FILES += mockserviceplugin4.json + +DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 + +PLUGIN_TYPE = mediaservice PLUGIN_CLASS_NAME = MockServicePlugin4 load(qt_plugin) @@ -14,10 +20,4 @@ win32 { } } -HEADERS += ../mockservice.h -SOURCES += mockserviceplugin4.cpp -OTHER_FILES += mockserviceplugin4.json - target.path = $$[QT_INSTALL_TESTS]/tst_qmediaserviceprovider/$${PLUGIN_TYPE} - -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/unit/qmediaserviceprovider/mockserviceplugin5/mockserviceplugin5.pro b/tests/auto/unit/qmediaserviceprovider/mockserviceplugin5/mockserviceplugin5.pro index 9657e3cc1..093c24746 100644 --- a/tests/auto/unit/qmediaserviceprovider/mockserviceplugin5/mockserviceplugin5.pro +++ b/tests/auto/unit/qmediaserviceprovider/mockserviceplugin5/mockserviceplugin5.pro @@ -1,7 +1,13 @@ TARGET = mockserviceplugin5 QT += multimedia-private -PLUGIN_TYPE=mediaservice +HEADERS += ../mockservice.h +SOURCES += mockserviceplugin5.cpp +OTHER_FILES += mockserviceplugin5.json + +DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 + +PLUGIN_TYPE = mediaservice PLUGIN_CLASS_NAME = MockServicePlugin5 load(qt_plugin) @@ -14,10 +20,4 @@ win32 { } } -HEADERS += ../mockservice.h -SOURCES += mockserviceplugin5.cpp -OTHER_FILES += mockserviceplugin5.json - target.path = $$[QT_INSTALL_TESTS]/tst_qmediaserviceprovider/$${PLUGIN_TYPE} - -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 -- cgit v1.2.1 From 3408abef86f49b0d2bd5de7f8dcf24a125166242 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 12 Feb 2016 16:25:16 +0100 Subject: rely on the automatically defined QT_BUILD_*_LIB Change-Id: I8c1c755270aa0a703103925656f7c1b555e4db1f Reviewed-by: Yoann Lopes --- .../qtmultimediaquicktools_headers/qtmultimediaquickdefs_p.h | 2 +- src/qtmultimediaquicktools/qtmultimediaquicktools.pro | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/multimedia/qtmultimediaquicktools_headers/qtmultimediaquickdefs_p.h b/src/multimedia/qtmultimediaquicktools_headers/qtmultimediaquickdefs_p.h index ac8f0ac71..0421e6cb9 100644 --- a/src/multimedia/qtmultimediaquicktools_headers/qtmultimediaquickdefs_p.h +++ b/src/multimedia/qtmultimediaquicktools_headers/qtmultimediaquickdefs_p.h @@ -48,7 +48,7 @@ #include #ifndef QT_STATIC -# if defined(QT_BUILD_QTMM_QUICK_LIB) +# if defined(QT_BUILD_QTMULTIMEDIAQUICKTOOLS_LIB) # define Q_MULTIMEDIAQUICK_EXPORT Q_DECL_EXPORT # else # define Q_MULTIMEDIAQUICK_EXPORT Q_DECL_IMPORT diff --git a/src/qtmultimediaquicktools/qtmultimediaquicktools.pro b/src/qtmultimediaquicktools/qtmultimediaquicktools.pro index 0a5110f59..e1425c3ec 100644 --- a/src/qtmultimediaquicktools/qtmultimediaquicktools.pro +++ b/src/qtmultimediaquicktools/qtmultimediaquicktools.pro @@ -1,9 +1,8 @@ TARGET = QtMultimediaQuick_p + QT = core quick multimedia-private CONFIG += internal_module -DEFINES += QT_BUILD_QTMM_QUICK_LIB - # Header files must go inside source directory of a module # to be installed by syncqt. INCLUDEPATH += ../multimedia/qtmultimediaquicktools_headers/ -- cgit v1.2.1 From 3ef3e5b1019cd727ec9ca5a16c7615b016db19ea Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 12 Feb 2016 16:31:29 +0100 Subject: remove redundant statements from project files - TARGET is unnecessary if it matches the project file's basename - CONFIG+=no_private_qt_headers_warning is added by qt_build_config.prf - load(qt_build_config) is done by .qmake.conf Change-Id: I3eb45a758dfee34be3c78fc13d996780741c95e9 Reviewed-by: Joerg Bornemann Reviewed-by: Yoann Lopes --- src/plugins/avfoundation/mediaplayer/mediaplayer.pro | 1 - src/plugins/gstreamer/common.pri | 1 - src/plugins/qnx-audio/audio/audio.pro | 3 +-- src/plugins/resourcepolicy/resourcepolicy.pro | 2 +- tests/auto/unit/qaudiodecoder/qaudiodecoder.pro | 8 +------- tests/auto/unit/qaudioprobe/qaudioprobe.pro | 2 +- tests/auto/unit/qaudiorecorder/qaudiorecorder.pro | 2 +- tests/auto/unit/qmediaobject/qmediaobject.pro | 2 +- tests/auto/unit/qmediaplayer/qmediaplayer.pro | 2 +- tests/auto/unit/qmediaplayerwidgets/qmediaplayerwidgets.pro | 2 +- tests/auto/unit/qmediarecorder/qmediarecorder.pro | 2 +- .../mockserviceplugin1/mockserviceplugin1.pro | 1 - .../mockserviceplugin2/mockserviceplugin2.pro | 1 - .../mockserviceplugin3/mockserviceplugin3.pro | 1 - .../mockserviceplugin4/mockserviceplugin4.pro | 1 - .../mockserviceplugin5/mockserviceplugin5.pro | 1 - tests/auto/unit/qradiodata/qradiodata.pro | 2 +- tests/auto/unit/qradiotuner/qradiotuner.pro | 2 +- tests/auto/unit/qsamplecache/qsamplecache.pro | 2 +- tests/auto/unit/qvideoprobe/qvideoprobe.pro | 2 +- tests/auto/unit/qwavedecoder/qwavedecoder.pro | 2 +- 21 files changed, 14 insertions(+), 28 deletions(-) diff --git a/src/plugins/avfoundation/mediaplayer/mediaplayer.pro b/src/plugins/avfoundation/mediaplayer/mediaplayer.pro index ff9e5bca9..bca16f48d 100644 --- a/src/plugins/avfoundation/mediaplayer/mediaplayer.pro +++ b/src/plugins/avfoundation/mediaplayer/mediaplayer.pro @@ -1,4 +1,3 @@ -load(qt_build_config) #DEFINES += QT_DEBUG_AVF # Avoid clash with a variable named `slots' in a Quartz header diff --git a/src/plugins/gstreamer/common.pri b/src/plugins/gstreamer/common.pri index eb6a29987..babdb7cfb 100644 --- a/src/plugins/gstreamer/common.pri +++ b/src/plugins/gstreamer/common.pri @@ -1,6 +1,5 @@ QT += core-private multimedia-private network -CONFIG += no_private_qt_headers_warning qtHaveModule(widgets) { QT += widgets multimediawidgets-private diff --git a/src/plugins/qnx-audio/audio/audio.pro b/src/plugins/qnx-audio/audio/audio.pro index bf4300a71..bd69dfe1e 100644 --- a/src/plugins/qnx-audio/audio/audio.pro +++ b/src/plugins/qnx-audio/audio/audio.pro @@ -1,7 +1,6 @@ TARGET = qtmedia_qnx_audio -QT += multimedia-private -CONFIG += no_private_qt_headers_warning +QT += multimedia-private LIBS += -lasound diff --git a/src/plugins/resourcepolicy/resourcepolicy.pro b/src/plugins/resourcepolicy/resourcepolicy.pro index e333bac09..91a946665 100644 --- a/src/plugins/resourcepolicy/resourcepolicy.pro +++ b/src/plugins/resourcepolicy/resourcepolicy.pro @@ -1,7 +1,7 @@ TARGET = resourceqt QT += multimedia-private -CONFIG += no_private_qt_headers_warning link_pkgconfig +CONFIG += link_pkgconfig PKGCONFIG += libresourceqt5 INCLUDEPATH += $$PWD \ diff --git a/tests/auto/unit/qaudiodecoder/qaudiodecoder.pro b/tests/auto/unit/qaudiodecoder/qaudiodecoder.pro index ff9ba8f05..0bf841b35 100644 --- a/tests/auto/unit/qaudiodecoder/qaudiodecoder.pro +++ b/tests/auto/unit/qaudiodecoder/qaudiodecoder.pro @@ -1,14 +1,8 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2012-02-07T15:27:07 -# -#------------------------------------------------- - QT += multimedia multimedia-private testlib gui TARGET = tst_qaudiodecoder -CONFIG += testcase no_private_qt_headers_warning +CONFIG += testcase TEMPLATE = app diff --git a/tests/auto/unit/qaudioprobe/qaudioprobe.pro b/tests/auto/unit/qaudioprobe/qaudioprobe.pro index fe2000716..f52bafb94 100644 --- a/tests/auto/unit/qaudioprobe/qaudioprobe.pro +++ b/tests/auto/unit/qaudioprobe/qaudioprobe.pro @@ -1,4 +1,4 @@ -CONFIG += testcase no_private_qt_headers_warning +CONFIG += testcase TARGET = tst_qaudioprobe QT += multimedia-private testlib diff --git a/tests/auto/unit/qaudiorecorder/qaudiorecorder.pro b/tests/auto/unit/qaudiorecorder/qaudiorecorder.pro index 7ee5222c6..beab48213 100644 --- a/tests/auto/unit/qaudiorecorder/qaudiorecorder.pro +++ b/tests/auto/unit/qaudiorecorder/qaudiorecorder.pro @@ -1,4 +1,4 @@ -CONFIG += testcase no_private_qt_headers_warning +CONFIG += testcase TARGET = tst_qaudiorecorder QT += multimedia-private testlib diff --git a/tests/auto/unit/qmediaobject/qmediaobject.pro b/tests/auto/unit/qmediaobject/qmediaobject.pro index 597ddd009..787982fe5 100644 --- a/tests/auto/unit/qmediaobject/qmediaobject.pro +++ b/tests/auto/unit/qmediaobject/qmediaobject.pro @@ -1,4 +1,4 @@ -CONFIG += testcase no_private_qt_headers_warning +CONFIG += testcase TARGET = tst_qmediaobject QT += multimedia-private testlib diff --git a/tests/auto/unit/qmediaplayer/qmediaplayer.pro b/tests/auto/unit/qmediaplayer/qmediaplayer.pro index cbdbf71f4..04ce09733 100644 --- a/tests/auto/unit/qmediaplayer/qmediaplayer.pro +++ b/tests/auto/unit/qmediaplayer/qmediaplayer.pro @@ -1,4 +1,4 @@ -CONFIG += testcase no_private_qt_headers_warning +CONFIG += testcase TARGET = tst_qmediaplayer QT += network multimedia-private testlib SOURCES += tst_qmediaplayer.cpp diff --git a/tests/auto/unit/qmediaplayerwidgets/qmediaplayerwidgets.pro b/tests/auto/unit/qmediaplayerwidgets/qmediaplayerwidgets.pro index ce723fbe1..c84d66e9c 100644 --- a/tests/auto/unit/qmediaplayerwidgets/qmediaplayerwidgets.pro +++ b/tests/auto/unit/qmediaplayerwidgets/qmediaplayerwidgets.pro @@ -1,4 +1,4 @@ -CONFIG += testcase no_private_qt_headers_warning +CONFIG += testcase TARGET = tst_qmediaplayerwidgets QT += network multimedia-private multimediawidgets-private testlib widgets SOURCES += tst_qmediaplayerwidgets.cpp diff --git a/tests/auto/unit/qmediarecorder/qmediarecorder.pro b/tests/auto/unit/qmediarecorder/qmediarecorder.pro index f6fac0440..99e0de53b 100644 --- a/tests/auto/unit/qmediarecorder/qmediarecorder.pro +++ b/tests/auto/unit/qmediarecorder/qmediarecorder.pro @@ -1,4 +1,4 @@ -CONFIG += testcase no_private_qt_headers_warning +CONFIG += testcase TARGET = tst_qmediarecorder QT += multimedia-private testlib SOURCES += tst_qmediarecorder.cpp diff --git a/tests/auto/unit/qmediaserviceprovider/mockserviceplugin1/mockserviceplugin1.pro b/tests/auto/unit/qmediaserviceprovider/mockserviceplugin1/mockserviceplugin1.pro index 2b7412d16..7fcaadbc2 100644 --- a/tests/auto/unit/qmediaserviceprovider/mockserviceplugin1/mockserviceplugin1.pro +++ b/tests/auto/unit/qmediaserviceprovider/mockserviceplugin1/mockserviceplugin1.pro @@ -1,4 +1,3 @@ -TARGET = mockserviceplugin1 QT += multimedia-private HEADERS += ../mockservice.h diff --git a/tests/auto/unit/qmediaserviceprovider/mockserviceplugin2/mockserviceplugin2.pro b/tests/auto/unit/qmediaserviceprovider/mockserviceplugin2/mockserviceplugin2.pro index ff793ec85..4ac001ec9 100644 --- a/tests/auto/unit/qmediaserviceprovider/mockserviceplugin2/mockserviceplugin2.pro +++ b/tests/auto/unit/qmediaserviceprovider/mockserviceplugin2/mockserviceplugin2.pro @@ -1,4 +1,3 @@ -TARGET = mockserviceplugin2 QT += multimedia-private HEADERS += ../mockservice.h diff --git a/tests/auto/unit/qmediaserviceprovider/mockserviceplugin3/mockserviceplugin3.pro b/tests/auto/unit/qmediaserviceprovider/mockserviceplugin3/mockserviceplugin3.pro index 15e9dc659..34cd2fed1 100644 --- a/tests/auto/unit/qmediaserviceprovider/mockserviceplugin3/mockserviceplugin3.pro +++ b/tests/auto/unit/qmediaserviceprovider/mockserviceplugin3/mockserviceplugin3.pro @@ -1,4 +1,3 @@ -TARGET = mockserviceplugin3 QT += multimedia-private HEADERS += ../mockservice.h diff --git a/tests/auto/unit/qmediaserviceprovider/mockserviceplugin4/mockserviceplugin4.pro b/tests/auto/unit/qmediaserviceprovider/mockserviceplugin4/mockserviceplugin4.pro index 894d92939..0900bfc40 100644 --- a/tests/auto/unit/qmediaserviceprovider/mockserviceplugin4/mockserviceplugin4.pro +++ b/tests/auto/unit/qmediaserviceprovider/mockserviceplugin4/mockserviceplugin4.pro @@ -1,4 +1,3 @@ -TARGET = mockserviceplugin4 QT += multimedia-private HEADERS += ../mockservice.h diff --git a/tests/auto/unit/qmediaserviceprovider/mockserviceplugin5/mockserviceplugin5.pro b/tests/auto/unit/qmediaserviceprovider/mockserviceplugin5/mockserviceplugin5.pro index 093c24746..37f287f9d 100644 --- a/tests/auto/unit/qmediaserviceprovider/mockserviceplugin5/mockserviceplugin5.pro +++ b/tests/auto/unit/qmediaserviceprovider/mockserviceplugin5/mockserviceplugin5.pro @@ -1,4 +1,3 @@ -TARGET = mockserviceplugin5 QT += multimedia-private HEADERS += ../mockservice.h diff --git a/tests/auto/unit/qradiodata/qradiodata.pro b/tests/auto/unit/qradiodata/qradiodata.pro index a4937cc51..01a1f005f 100644 --- a/tests/auto/unit/qradiodata/qradiodata.pro +++ b/tests/auto/unit/qradiodata/qradiodata.pro @@ -1,4 +1,4 @@ -CONFIG += testcase no_private_qt_headers_warning +CONFIG += testcase TARGET = tst_qradiodata QT += multimedia-private testlib SOURCES += tst_qradiodata.cpp diff --git a/tests/auto/unit/qradiotuner/qradiotuner.pro b/tests/auto/unit/qradiotuner/qradiotuner.pro index e0638c1f8..c449e03ae 100644 --- a/tests/auto/unit/qradiotuner/qradiotuner.pro +++ b/tests/auto/unit/qradiotuner/qradiotuner.pro @@ -1,4 +1,4 @@ -CONFIG += testcase no_private_qt_headers_warning +CONFIG += testcase TARGET = tst_qradiotuner QT += multimedia-private testlib SOURCES += tst_qradiotuner.cpp diff --git a/tests/auto/unit/qsamplecache/qsamplecache.pro b/tests/auto/unit/qsamplecache/qsamplecache.pro index 1f0db1b58..d6fa7c4e0 100644 --- a/tests/auto/unit/qsamplecache/qsamplecache.pro +++ b/tests/auto/unit/qsamplecache/qsamplecache.pro @@ -1,4 +1,4 @@ -CONFIG += no_private_qt_headers_warning testcase +CONFIG += testcase TARGET = tst_qsamplecache QT += multimedia-private testlib diff --git a/tests/auto/unit/qvideoprobe/qvideoprobe.pro b/tests/auto/unit/qvideoprobe/qvideoprobe.pro index 0bd4102a8..88e8eebbe 100644 --- a/tests/auto/unit/qvideoprobe/qvideoprobe.pro +++ b/tests/auto/unit/qvideoprobe/qvideoprobe.pro @@ -1,4 +1,4 @@ -CONFIG += testcase no_private_qt_headers_warning +CONFIG += testcase TARGET = tst_qvideoprobe QT += multimedia-private testlib diff --git a/tests/auto/unit/qwavedecoder/qwavedecoder.pro b/tests/auto/unit/qwavedecoder/qwavedecoder.pro index 1b6af7e86..a24273f3c 100644 --- a/tests/auto/unit/qwavedecoder/qwavedecoder.pro +++ b/tests/auto/unit/qwavedecoder/qwavedecoder.pro @@ -4,7 +4,7 @@ SOURCES += tst_qwavedecoder.cpp \ ../../../../src/multimedia/audio/qwavedecoder_p.cpp QT += multimedia-private testlib network -CONFIG += no_private_qt_headers_warning testcase +CONFIG += testcase TESTDATA += data/* DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 -- cgit v1.2.1 From 8f9bc2ed726f0927914426e9ff7713e09d0ca8b1 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 12 Feb 2016 16:31:39 +0100 Subject: standardize statement order in project files a bit Change-Id: I96bbe1343eedbad6b48579d700bbb6b5b80d69f1 Reviewed-by: Joerg Bornemann --- src/plugins/avfoundation/camera/camera.pro | 3 ++- src/plugins/avfoundation/mediaplayer/mediaplayer.pro | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/plugins/avfoundation/camera/camera.pro b/src/plugins/avfoundation/camera/camera.pro index 4e443cc1d..8563eb655 100644 --- a/src/plugins/avfoundation/camera/camera.pro +++ b/src/plugins/avfoundation/camera/camera.pro @@ -1,7 +1,8 @@ +TARGET = qavfcamera + # Avoid clash with a variable named `slots' in a Quartz header CONFIG += no_keywords -TARGET = qavfcamera QT += multimedia-private network LIBS += -framework AudioToolbox \ diff --git a/src/plugins/avfoundation/mediaplayer/mediaplayer.pro b/src/plugins/avfoundation/mediaplayer/mediaplayer.pro index bca16f48d..d0edd5cc4 100644 --- a/src/plugins/avfoundation/mediaplayer/mediaplayer.pro +++ b/src/plugins/avfoundation/mediaplayer/mediaplayer.pro @@ -1,9 +1,9 @@ +TARGET = qavfmediaplayer #DEFINES += QT_DEBUG_AVF # Avoid clash with a variable named `slots' in a Quartz header CONFIG += no_keywords -TARGET = qavfmediaplayer QT += multimedia-private network LIBS += -framework AVFoundation -framework CoreMedia -- cgit v1.2.1 From 58019c256eb7cc2b5c65ab4feedb7103079d7438 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 26 Feb 2016 10:29:22 +0100 Subject: Fix constructor parameters in tst_QMediaPlaylist. Fix warning: tst_qmediaplaylist.cpp: In member function 'void tst_QMediaPlaylist::mediaPlayListControl()': tst_qmediaplaylist.cpp:1221:49: warning: the address of 'parent' will always evaluate as 'true' [-Waddress] Change-Id: I46391550d07a8f58442269d0e5eae418258adbff Reviewed-by: Yoann Lopes --- tests/auto/unit/qmediaplaylist/tst_qmediaplaylist.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/unit/qmediaplaylist/tst_qmediaplaylist.cpp b/tests/auto/unit/qmediaplaylist/tst_qmediaplaylist.cpp index 104046d0e..fb7773834 100644 --- a/tests/auto/unit/qmediaplaylist/tst_qmediaplaylist.cpp +++ b/tests/auto/unit/qmediaplaylist/tst_qmediaplaylist.cpp @@ -1223,7 +1223,7 @@ void tst_QMediaPlaylist::mediaPlayListControl() { // To check changes in abstract classe's pure virtual functions QObject parent; - MockMediaPlaylistControl plylistctrl(&parent); + MockMediaPlaylistControl plylistctrl(false, &parent); } // MaemoAPI-1850:test QMediaPlayListSourceControl constructor -- cgit v1.2.1 From 1816f89b6fc1f62ea2b97fabf43963b3312a7c08 Mon Sep 17 00:00:00 2001 From: Dyami Caliri Date: Mon, 22 Feb 2016 08:37:00 -0800 Subject: PulseAudio: fix playback for short streams in pull mode If the provided stream's length is shorter than the stream prebuf attribute, the stream will never play. We adjust the prebuf attribute in this case. Change-Id: Ia397ac967ad2fa357a7aba137fbb78de272440ed Reviewed-by: Yoann Lopes --- src/plugins/pulseaudio/qaudiooutput_pulse.cpp | 38 ++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/src/plugins/pulseaudio/qaudiooutput_pulse.cpp b/src/plugins/pulseaudio/qaudiooutput_pulse.cpp index a654af86c..5d2ba8653 100644 --- a/src/plugins/pulseaudio/qaudiooutput_pulse.cpp +++ b/src/plugins/pulseaudio/qaudiooutput_pulse.cpp @@ -133,6 +133,18 @@ static void outputStreamDrainComplete(pa_stream *stream, int success, void *user #endif } +static void streamAdjustPrebufferCallback(pa_stream *stream, int success, void *userdata) +{ + Q_UNUSED(stream); + Q_UNUSED(success); + Q_UNUSED(userdata); + +#ifdef DEBUG_PULSE + qDebug() << "Adjust prebuffer completed successfully: " << (bool)success; +#endif +} + + QPulseAudioOutput::QPulseAudioOutput(const QByteArray &device) : m_device(device) , m_errorState(QAudio::NoError) @@ -207,17 +219,19 @@ void QPulseAudioOutput::start(QIODevice *device) // Handle change of mode if (m_audioSource && !m_pullMode) { delete m_audioSource; - m_audioSource = 0; } + m_audioSource = 0; close(); - if (!open()) - return; - m_pullMode = true; m_audioSource = device; + if (!open()) { + m_audioSource = 0; + return; + } + setState(QAudio::ActiveState); } @@ -229,17 +243,18 @@ QIODevice *QPulseAudioOutput::start() // Handle change of mode if (m_audioSource && !m_pullMode) { delete m_audioSource; - m_audioSource = 0; } + m_audioSource = 0; close(); + m_pullMode = false; + if (!open()) return Q_NULLPTR; m_audioSource = new PulseOutputPrivate(this); m_audioSource->open(QIODevice::WriteOnly|QIODevice::Unbuffered); - m_pullMode = false; setState(QAudio::IdleState); @@ -349,6 +364,17 @@ bool QPulseAudioOutput::open() m_bufferSize = buffer->tlength; m_maxBufferSize = buffer->maxlength; m_audioBuffer = new char[m_maxBufferSize]; + + const qint64 streamSize = m_audioSource ? m_audioSource->size() : 0; + if (m_pullMode && streamSize > 0 && static_cast(buffer->prebuf) > streamSize) { + pa_buffer_attr newBufferAttr; + newBufferAttr = *buffer; + newBufferAttr.prebuf = streamSize; + pa_operation *o = pa_stream_set_buffer_attr(m_stream, &newBufferAttr, streamAdjustPrebufferCallback, NULL); + if (o) + pa_operation_unref(o); + } + #ifdef DEBUG_PULSE qDebug() << "Buffering info:"; qDebug() << "\tMax length: " << buffer->maxlength; -- cgit v1.2.1 From 787211c1d2082874ea07be4c5987032221ee48fe Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 1 Mar 2016 14:58:18 +0100 Subject: Polish the QtWidgets/Player example. Point the file dialog to the Movies folder. Add command proper command line handling. Change the logic to use QUrl everywhere. Change-Id: I1e54e600187153f52a55e3a381a24e4f2eeda3ab Reviewed-by: Yoann Lopes --- examples/multimediawidgets/player/main.cpp | 20 +++++++++++ examples/multimediawidgets/player/player.cpp | 53 ++++++++++++++++------------ examples/multimediawidgets/player/player.h | 5 ++- 3 files changed, 55 insertions(+), 23 deletions(-) diff --git a/examples/multimediawidgets/player/main.cpp b/examples/multimediawidgets/player/main.cpp index c32cbc83e..a3dabe15d 100644 --- a/examples/multimediawidgets/player/main.cpp +++ b/examples/multimediawidgets/player/main.cpp @@ -41,13 +41,33 @@ #include "player.h" #include +#include +#include +#include int main(int argc, char *argv[]) { QApplication app(argc, argv); + QCoreApplication::setApplicationName("Player Example"); + QCoreApplication::setOrganizationName("QtProject"); + QCoreApplication::setApplicationVersion(QT_VERSION_STR); + QCommandLineParser parser; + parser.setApplicationDescription("Qt MultiMedia Player Example"); + parser.addHelpOption(); + parser.addVersionOption(); + parser.addPositionalArgument("url", "The URL to open."); + parser.process(app); + Player player; + if (!parser.positionalArguments().isEmpty() && player.isPlayerAvailable()) { + QList urls; + foreach (const QString &a, parser.positionalArguments()) + urls.append(QUrl::fromUserInput(a, QDir::currentPath(), QUrl::AssumeLocalFile)); + player.addToPlaylist(urls); + } + #if defined(Q_WS_SIMULATOR) player.setAttribute(Qt::WA_LockLandscapeOrientation); player.showMaximized(); diff --git a/examples/multimediawidgets/player/player.cpp b/examples/multimediawidgets/player/player.cpp index b450bc361..e787aa269 100644 --- a/examples/multimediawidgets/player/player.cpp +++ b/examples/multimediawidgets/player/player.cpp @@ -167,7 +167,7 @@ Player::Player(QWidget *parent) setLayout(layout); - if (!player->isAvailable()) { + if (!isPlayerAvailable()) { QMessageBox::warning(this, tr("Service not available"), tr("The QMediaPlayer object does not have a valid service.\n"\ "Please check the media service plugins are installed.")); @@ -182,38 +182,47 @@ Player::Player(QWidget *parent) } metaDataChanged(); - - QStringList arguments = qApp->arguments(); - arguments.removeAt(0); - addToPlaylist(arguments); } Player::~Player() { } +bool Player::isPlayerAvailable() const +{ + return player->isAvailable(); +} + void Player::open() { - QStringList fileNames = QFileDialog::getOpenFileNames(this, tr("Open Files")); - addToPlaylist(fileNames); + QFileDialog fileDialog(this); + fileDialog.setAcceptMode(QFileDialog::AcceptOpen); + fileDialog.setWindowTitle(tr("Open Files")); + QStringList supportedMimeTypes = player->supportedMimeTypes(); + if (!supportedMimeTypes.isEmpty()) { + supportedMimeTypes.append("audio/x-m3u"); // MP3 playlists + fileDialog.setMimeTypeFilters(supportedMimeTypes); + } + fileDialog.setDirectory(QStandardPaths::standardLocations(QStandardPaths::MoviesLocation).value(0, QDir::homePath())); + if (fileDialog.exec() == QDialog::Accepted) + addToPlaylist(fileDialog.selectedUrls()); } -void Player::addToPlaylist(const QStringList& fileNames) +static bool isPlaylist(const QUrl &url) // Check for ".m3u" playlists. { - foreach (QString const &argument, fileNames) { - QFileInfo fileInfo(argument); - if (fileInfo.exists()) { - QUrl url = QUrl::fromLocalFile(fileInfo.absoluteFilePath()); - if (fileInfo.suffix().toLower() == QLatin1String("m3u")) { - playlist->load(url); - } else - playlist->addMedia(url); - } else { - QUrl url(argument); - if (url.isValid()) { - playlist->addMedia(url); - } - } + if (!url.isLocalFile()) + return false; + const QFileInfo fileInfo(url.toLocalFile()); + return fileInfo.exists() && !fileInfo.suffix().compare(QLatin1String("m3u"), Qt::CaseInsensitive); +} + +void Player::addToPlaylist(const QList urls) +{ + foreach (const QUrl &url, urls) { + if (isPlaylist(url)) + playlist->load(url); + else + playlist->addMedia(url); } } diff --git a/examples/multimediawidgets/player/player.h b/examples/multimediawidgets/player/player.h index 61f3cff27..7f5d0881b 100644 --- a/examples/multimediawidgets/player/player.h +++ b/examples/multimediawidgets/player/player.h @@ -69,6 +69,10 @@ public: Player(QWidget *parent = 0); ~Player(); + bool isPlayerAvailable() const; + + void addToPlaylist(const QList urls); + signals: void fullScreenChanged(bool fullScreen); @@ -93,7 +97,6 @@ private slots: #ifndef PLAYER_NO_COLOROPTIONS void showColorDialog(); #endif - void addToPlaylist(const QStringList &fileNames); private: void setTrackInfo(const QString &info); -- cgit v1.2.1 From 176179fb32277f50b86d86e4870affaf74bc6fa0 Mon Sep 17 00:00:00 2001 From: Dyami Caliri Date: Fri, 26 Feb 2016 14:24:05 -0800 Subject: PulseAudio: remove debug warning of Underrun The QAudio::UnderrunError is a normal error and is already reported to the user. Change-Id: I0ee5d827666fb08b5eb199255b3b3c5610f743c2 Reviewed-by: Yoann Lopes --- src/plugins/pulseaudio/qaudiooutput_pulse.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/plugins/pulseaudio/qaudiooutput_pulse.cpp b/src/plugins/pulseaudio/qaudiooutput_pulse.cpp index 5d2ba8653..c1d46fac4 100644 --- a/src/plugins/pulseaudio/qaudiooutput_pulse.cpp +++ b/src/plugins/pulseaudio/qaudiooutput_pulse.cpp @@ -85,7 +85,6 @@ static void outputStreamUnderflowCallback(pa_stream *stream, void *userdata) { Q_UNUSED(stream) ((QPulseAudioOutput*)userdata)->streamUnderflowCallback(); - qWarning() << "Got a buffer underflow!"; } static void outputStreamOverflowCallback(pa_stream *stream, void *userdata) -- cgit v1.2.1 From d2d0d93f7654fdcca118dd17a745e560d524496b Mon Sep 17 00:00:00 2001 From: Sergio Martins Date: Wed, 2 Mar 2016 12:48:39 +0000 Subject: Fix gstreamer camera when env var QT_NO_GLIB is set It would fall into the glib code path because it was only checking if QT_NO_GLIB was defined, but ignoring the env variable. gst_bus_add_watch_full only works with a glib event loop running. Task-Id: QTBUG-51607 Change-Id: I726afd5d6e114eacea6e5bc71e7a6e2d1c5bbd74 Reviewed-by: Yoann Lopes --- src/gsttools/qgstreamerbushelper.cpp | 40 ++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/gsttools/qgstreamerbushelper.cpp b/src/gsttools/qgstreamerbushelper.cpp index 7db62b83c..03cf64ba8 100644 --- a/src/gsttools/qgstreamerbushelper.cpp +++ b/src/gsttools/qgstreamerbushelper.cpp @@ -35,6 +35,8 @@ #include #include #include +#include +#include #include "qgstreamerbushelper_p.h" @@ -47,31 +49,31 @@ class QGstreamerBusHelperPrivate : public QObject public: QGstreamerBusHelperPrivate(QGstreamerBusHelper *parent, GstBus* bus) : QObject(parent), + m_tag(0), m_bus(bus), - m_helper(parent) + m_helper(parent), + m_intervalTimer(nullptr) { -#ifdef QT_NO_GLIB - Q_UNUSED(bus); - - m_intervalTimer = new QTimer(this); - m_intervalTimer->setInterval(250); - - connect(m_intervalTimer, SIGNAL(timeout()), SLOT(interval())); - m_intervalTimer->start(); -#else - m_tag = gst_bus_add_watch_full(bus, 0, busCallback, this, NULL); -#endif - + // glib event loop can be disabled either by env variable or QT_NO_GLIB define, so check the dispacher + QAbstractEventDispatcher *dispatcher = QCoreApplication::eventDispatcher(); + const bool hasGlib = dispatcher && dispatcher->inherits("QEventDispatcherGlib"); + if (!hasGlib) { + m_intervalTimer = new QTimer(this); + m_intervalTimer->setInterval(250); + connect(m_intervalTimer, SIGNAL(timeout()), SLOT(interval())); + m_intervalTimer->start(); + } else { + m_tag = gst_bus_add_watch_full(bus, G_PRIORITY_DEFAULT, busCallback, this, NULL); + } } ~QGstreamerBusHelperPrivate() { m_helper = 0; -#ifdef QT_NO_GLIB - m_intervalTimer->stop(); -#else - g_source_remove(m_tag); -#endif + delete m_intervalTimer; + + if (m_tag) + g_source_remove(m_tag); } GstBus* bus() const { return m_bus; } @@ -110,9 +112,7 @@ private: guint m_tag; GstBus* m_bus; QGstreamerBusHelper* m_helper; -#ifdef QT_NO_GLIB QTimer* m_intervalTimer; -#endif private slots: void doProcessMessage(const QGstreamerMessage& msg) -- cgit v1.2.1 From 3198bf4944edd8f25996c2b4c4516f606165af59 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Wed, 2 Mar 2016 15:19:22 +0100 Subject: Add explicit and make public headers compile with -Wzero-as-null-pointer-constant ... or equivalent. QtBase 5.6 headers already compile that way, so let the other modules follow suit. Cleaned up placement of * and & in parameters as a drive-by. Added explicit where it was missing as a drive-by. This is not a source-incompatible change, because code that breaks by this is a bug. Let's not have this sitting around in an LTS. Task-number: QTBUG-45291 Change-Id: If81ed0c71393aee21d347f5ade4bf3fcc07cd82f Reviewed-by: Yoann Lopes --- src/multimedia/audio/qaudiodecoder.h | 2 +- src/multimedia/audio/qaudioinput.h | 4 ++-- src/multimedia/audio/qaudiooutput.h | 4 ++-- src/multimedia/audio/qaudioprobe.h | 2 +- src/multimedia/audio/qaudiosystemplugin.h | 2 +- src/multimedia/audio/qsound.h | 2 +- src/multimedia/audio/qsoundeffect.h | 2 +- src/multimedia/camera/qcamera.h | 8 ++++---- src/multimedia/camera/qcameraexposure.h | 8 ++++---- src/multimedia/camera/qcameraimagecapture.h | 4 ++-- src/multimedia/controls/qaudiodecodercontrol.h | 2 +- src/multimedia/controls/qaudioencodersettingscontrol.h | 4 ++-- src/multimedia/controls/qaudioinputselectorcontrol.h | 2 +- src/multimedia/controls/qaudiooutputselectorcontrol.h | 2 +- src/multimedia/controls/qaudiorolecontrol.h | 2 +- src/multimedia/controls/qcameracapturebufferformatcontrol.h | 2 +- src/multimedia/controls/qcameracapturedestinationcontrol.h | 2 +- src/multimedia/controls/qcameracontrol.h | 2 +- src/multimedia/controls/qcameraexposurecontrol.h | 2 +- src/multimedia/controls/qcamerafeedbackcontrol.h | 2 +- src/multimedia/controls/qcameraflashcontrol.h | 2 +- src/multimedia/controls/qcamerafocuscontrol.h | 2 +- src/multimedia/controls/qcameraimagecapturecontrol.h | 2 +- src/multimedia/controls/qcameraimageprocessingcontrol.h | 2 +- src/multimedia/controls/qcamerainfocontrol.h | 2 +- src/multimedia/controls/qcameralockscontrol.h | 2 +- src/multimedia/controls/qcameraviewfindersettingscontrol.h | 4 ++-- src/multimedia/controls/qcamerazoomcontrol.h | 2 +- src/multimedia/controls/qimageencodercontrol.h | 4 ++-- src/multimedia/controls/qmediaaudioprobecontrol.h | 2 +- src/multimedia/controls/qmediaavailabilitycontrol.h | 2 +- src/multimedia/controls/qmediacontainercontrol.h | 2 +- src/multimedia/controls/qmediagaplessplaybackcontrol.h | 2 +- src/multimedia/controls/qmedianetworkaccesscontrol.h | 2 +- src/multimedia/controls/qmediaplayercontrol.h | 2 +- src/multimedia/controls/qmediarecordercontrol.h | 2 +- src/multimedia/controls/qmediastreamscontrol.h | 2 +- src/multimedia/controls/qmediavideoprobecontrol.h | 2 +- src/multimedia/controls/qmetadatareadercontrol.h | 2 +- src/multimedia/controls/qmetadatawritercontrol.h | 2 +- src/multimedia/controls/qradiodatacontrol.h | 2 +- src/multimedia/controls/qradiotunercontrol.h | 2 +- src/multimedia/controls/qvideodeviceselectorcontrol.h | 2 +- src/multimedia/controls/qvideoencodersettingscontrol.h | 6 +++--- src/multimedia/controls/qvideorenderercontrol.h | 2 +- src/multimedia/controls/qvideowindowcontrol.h | 2 +- src/multimedia/playback/qmediaplayer.h | 8 ++++---- src/multimedia/playback/qmediaplaylist.h | 10 +++++----- src/multimedia/qmediacontrol.h | 4 ++-- src/multimedia/radio/qradiodata.h | 2 +- src/multimedia/radio/qradiotuner.h | 2 +- src/multimedia/recording/qaudiorecorder.h | 2 +- src/multimedia/recording/qmediarecorder.h | 10 +++++----- src/multimedia/video/qabstractvideofilter.h | 2 +- src/multimedia/video/qabstractvideosurface.h | 2 +- src/multimedia/video/qvideoprobe.h | 2 +- src/multimediawidgets/qcameraviewfinder.h | 2 +- src/multimediawidgets/qgraphicsvideoitem.h | 4 ++-- src/multimediawidgets/qvideowidget.h | 2 +- src/multimediawidgets/qvideowidgetcontrol.h | 2 +- 60 files changed, 87 insertions(+), 87 deletions(-) diff --git a/src/multimedia/audio/qaudiodecoder.h b/src/multimedia/audio/qaudiodecoder.h index fd54670cf..aef5427fd 100644 --- a/src/multimedia/audio/qaudiodecoder.h +++ b/src/multimedia/audio/qaudiodecoder.h @@ -69,7 +69,7 @@ public: ServiceMissingError }; - QAudioDecoder(QObject *parent = 0); + explicit QAudioDecoder(QObject *parent = Q_NULLPTR); ~QAudioDecoder(); static QMultimedia::SupportEstimate hasSupport(const QString &mimeType, const QStringList& codecs = QStringList()); diff --git a/src/multimedia/audio/qaudioinput.h b/src/multimedia/audio/qaudioinput.h index bb809251c..6effa788f 100644 --- a/src/multimedia/audio/qaudioinput.h +++ b/src/multimedia/audio/qaudioinput.h @@ -56,8 +56,8 @@ class Q_MULTIMEDIA_EXPORT QAudioInput : public QObject Q_OBJECT public: - explicit QAudioInput(const QAudioFormat &format = QAudioFormat(), QObject *parent = 0); - explicit QAudioInput(const QAudioDeviceInfo &audioDeviceInfo, const QAudioFormat &format = QAudioFormat(), QObject *parent = 0); + explicit QAudioInput(const QAudioFormat &format = QAudioFormat(), QObject *parent = Q_NULLPTR); + explicit QAudioInput(const QAudioDeviceInfo &audioDeviceInfo, const QAudioFormat &format = QAudioFormat(), QObject *parent = Q_NULLPTR); ~QAudioInput(); QAudioFormat format() const; diff --git a/src/multimedia/audio/qaudiooutput.h b/src/multimedia/audio/qaudiooutput.h index b36a30948..c05e34264 100644 --- a/src/multimedia/audio/qaudiooutput.h +++ b/src/multimedia/audio/qaudiooutput.h @@ -56,8 +56,8 @@ class Q_MULTIMEDIA_EXPORT QAudioOutput : public QObject Q_OBJECT public: - explicit QAudioOutput(const QAudioFormat &format = QAudioFormat(), QObject *parent = 0); - explicit QAudioOutput(const QAudioDeviceInfo &audioDeviceInfo, const QAudioFormat &format = QAudioFormat(), QObject *parent = 0); + explicit QAudioOutput(const QAudioFormat &format = QAudioFormat(), QObject *parent = Q_NULLPTR); + explicit QAudioOutput(const QAudioDeviceInfo &audioDeviceInfo, const QAudioFormat &format = QAudioFormat(), QObject *parent = Q_NULLPTR); ~QAudioOutput(); QAudioFormat format() const; diff --git a/src/multimedia/audio/qaudioprobe.h b/src/multimedia/audio/qaudioprobe.h index f462f7aa7..c1efc275a 100644 --- a/src/multimedia/audio/qaudioprobe.h +++ b/src/multimedia/audio/qaudioprobe.h @@ -47,7 +47,7 @@ class Q_MULTIMEDIA_EXPORT QAudioProbe : public QObject { Q_OBJECT public: - explicit QAudioProbe(QObject *parent = 0); + explicit QAudioProbe(QObject *parent = Q_NULLPTR); ~QAudioProbe(); bool setSource(QMediaObject *source); diff --git a/src/multimedia/audio/qaudiosystemplugin.h b/src/multimedia/audio/qaudiosystemplugin.h index 2ee170e38..dafe7e166 100644 --- a/src/multimedia/audio/qaudiosystemplugin.h +++ b/src/multimedia/audio/qaudiosystemplugin.h @@ -72,7 +72,7 @@ class Q_MULTIMEDIA_EXPORT QAudioSystemPlugin : public QObject, public QAudioSyst Q_INTERFACES(QAudioSystemFactoryInterface) public: - QAudioSystemPlugin(QObject *parent = 0); + explicit QAudioSystemPlugin(QObject *parent = Q_NULLPTR); ~QAudioSystemPlugin(); virtual QList availableDevices(QAudio::Mode) const = 0; diff --git a/src/multimedia/audio/qsound.h b/src/multimedia/audio/qsound.h index 0ac65010e..559000d5d 100644 --- a/src/multimedia/audio/qsound.h +++ b/src/multimedia/audio/qsound.h @@ -52,7 +52,7 @@ public: static void play(const QString& filename); - explicit QSound(const QString& filename, QObject* parent = 0); + explicit QSound(const QString &filename, QObject *parent = Q_NULLPTR); ~QSound(); int loops() const; diff --git a/src/multimedia/audio/qsoundeffect.h b/src/multimedia/audio/qsoundeffect.h index fa6425589..40d17a7e7 100644 --- a/src/multimedia/audio/qsoundeffect.h +++ b/src/multimedia/audio/qsoundeffect.h @@ -74,7 +74,7 @@ public: Error }; - explicit QSoundEffect(QObject *parent = 0); + explicit QSoundEffect(QObject *parent = Q_NULLPTR); ~QSoundEffect(); static QStringList supportedMimeTypes(); diff --git a/src/multimedia/camera/qcamera.h b/src/multimedia/camera/qcamera.h index ea81c02c4..2b4a058d8 100644 --- a/src/multimedia/camera/qcamera.h +++ b/src/multimedia/camera/qcamera.h @@ -159,10 +159,10 @@ public: FrontFace }; - QCamera(QObject *parent = 0); - QCamera(const QByteArray& deviceName, QObject *parent = 0); - QCamera(const QCameraInfo& cameraInfo, QObject *parent = 0); - QCamera(QCamera::Position position, QObject *parent = 0); + explicit QCamera(QObject *parent = Q_NULLPTR); + explicit QCamera(const QByteArray& deviceName, QObject *parent = Q_NULLPTR); + explicit QCamera(const QCameraInfo& cameraInfo, QObject *parent = Q_NULLPTR); + explicit QCamera(QCamera::Position position, QObject *parent = Q_NULLPTR); ~QCamera(); #if QT_DEPRECATED_SINCE(5, 3) diff --git a/src/multimedia/camera/qcameraexposure.h b/src/multimedia/camera/qcameraexposure.h index fa781b8fc..fc81a44b8 100644 --- a/src/multimedia/camera/qcameraexposure.h +++ b/src/multimedia/camera/qcameraexposure.h @@ -129,9 +129,9 @@ public: qreal requestedAperture() const; qreal requestedShutterSpeed() const; - QList supportedIsoSensitivities(bool *continuous = 0) const; - QList supportedApertures(bool * continuous = 0) const; - QList supportedShutterSpeeds(bool *continuous = 0) const; + QList supportedIsoSensitivities(bool *continuous = Q_NULLPTR) const; + QList supportedApertures(bool *continuous = Q_NULLPTR) const; + QList supportedShutterSpeeds(bool *continuous = Q_NULLPTR) const; public Q_SLOTS: void setFlashMode(FlashModes mode); @@ -162,7 +162,7 @@ Q_SIGNALS: private: friend class QCamera; friend class QCameraPrivate; - explicit QCameraExposure(QCamera *parent = 0); + explicit QCameraExposure(QCamera *parent = Q_NULLPTR); virtual ~QCameraExposure(); Q_DISABLE_COPY(QCameraExposure) diff --git a/src/multimedia/camera/qcameraimagecapture.h b/src/multimedia/camera/qcameraimagecapture.h index c75d6c622..a8d2d4abc 100644 --- a/src/multimedia/camera/qcameraimagecapture.h +++ b/src/multimedia/camera/qcameraimagecapture.h @@ -81,7 +81,7 @@ public: }; Q_DECLARE_FLAGS(CaptureDestinations, CaptureDestination) - QCameraImageCapture(QMediaObject *mediaObject, QObject *parent = 0); + explicit QCameraImageCapture(QMediaObject *mediaObject, QObject *parent = Q_NULLPTR); ~QCameraImageCapture(); bool isAvailable() const; @@ -98,7 +98,7 @@ public: QString imageCodecDescription(const QString &codecName) const; QList supportedResolutions(const QImageEncoderSettings &settings = QImageEncoderSettings(), - bool *continuous = 0) const; + bool *continuous = Q_NULLPTR) const; QImageEncoderSettings encodingSettings() const; void setEncodingSettings(const QImageEncoderSettings& settings); diff --git a/src/multimedia/controls/qaudiodecodercontrol.h b/src/multimedia/controls/qaudiodecodercontrol.h index f319f7414..2d5912165 100644 --- a/src/multimedia/controls/qaudiodecodercontrol.h +++ b/src/multimedia/controls/qaudiodecodercontrol.h @@ -86,7 +86,7 @@ Q_SIGNALS: void durationChanged(qint64 duration); protected: - QAudioDecoderControl(QObject* parent = 0); + explicit QAudioDecoderControl(QObject *parent = Q_NULLPTR); }; #define QAudioDecoderControl_iid "org.qt-project.qt.audiodecodercontrol/5.0" diff --git a/src/multimedia/controls/qaudioencodersettingscontrol.h b/src/multimedia/controls/qaudioencodersettingscontrol.h index ebaf92333..e17377f40 100644 --- a/src/multimedia/controls/qaudioencodersettingscontrol.h +++ b/src/multimedia/controls/qaudioencodersettingscontrol.h @@ -61,13 +61,13 @@ public: virtual QString codecDescription(const QString &codecName) const = 0; virtual QList supportedSampleRates(const QAudioEncoderSettings &settings, - bool *continuous = 0) const = 0; + bool *continuous = Q_NULLPTR) const = 0; virtual QAudioEncoderSettings audioSettings() const = 0; virtual void setAudioSettings(const QAudioEncoderSettings&) = 0; protected: - QAudioEncoderSettingsControl(QObject *parent = 0); + explicit QAudioEncoderSettingsControl(QObject *parent = Q_NULLPTR); }; #define QAudioEncoderSettingsControl_iid "org.qt-project.qt.audioencodersettingscontrol/5.0" diff --git a/src/multimedia/controls/qaudioinputselectorcontrol.h b/src/multimedia/controls/qaudioinputselectorcontrol.h index d37481243..ebed8002e 100644 --- a/src/multimedia/controls/qaudioinputselectorcontrol.h +++ b/src/multimedia/controls/qaudioinputselectorcontrol.h @@ -62,7 +62,7 @@ Q_SIGNALS: void availableInputsChanged(); protected: - QAudioInputSelectorControl(QObject *parent = 0); + explicit QAudioInputSelectorControl(QObject *parent = Q_NULLPTR); }; #define QAudioInputSelectorControl_iid "org.qt-project.qt.audioinputselectorcontrol/5.0" diff --git a/src/multimedia/controls/qaudiooutputselectorcontrol.h b/src/multimedia/controls/qaudiooutputselectorcontrol.h index 132d90d7d..3abfd1571 100644 --- a/src/multimedia/controls/qaudiooutputselectorcontrol.h +++ b/src/multimedia/controls/qaudiooutputselectorcontrol.h @@ -62,7 +62,7 @@ Q_SIGNALS: void availableOutputsChanged(); protected: - QAudioOutputSelectorControl(QObject *parent = 0); + explicit QAudioOutputSelectorControl(QObject *parent = Q_NULLPTR); }; #define QAudioOutputSelectorControl_iid "org.qt-project.qt.audiooutputselectorcontrol/5.0" diff --git a/src/multimedia/controls/qaudiorolecontrol.h b/src/multimedia/controls/qaudiorolecontrol.h index 983b2aed0..1ae1378c8 100644 --- a/src/multimedia/controls/qaudiorolecontrol.h +++ b/src/multimedia/controls/qaudiorolecontrol.h @@ -58,7 +58,7 @@ Q_SIGNALS: void audioRoleChanged(QAudio::Role role); protected: - explicit QAudioRoleControl(QObject *parent = 0); + explicit QAudioRoleControl(QObject *parent = Q_NULLPTR); }; #define QAudioRoleControl_iid "org.qt-project.qt.audiorolecontrol/5.6" diff --git a/src/multimedia/controls/qcameracapturebufferformatcontrol.h b/src/multimedia/controls/qcameracapturebufferformatcontrol.h index 2f699c651..8be7f36c5 100644 --- a/src/multimedia/controls/qcameracapturebufferformatcontrol.h +++ b/src/multimedia/controls/qcameracapturebufferformatcontrol.h @@ -56,7 +56,7 @@ Q_SIGNALS: void bufferFormatChanged(QVideoFrame::PixelFormat); protected: - QCameraCaptureBufferFormatControl(QObject* parent = 0); + explicit QCameraCaptureBufferFormatControl(QObject *parent = Q_NULLPTR); }; #define QCameraCaptureBufferFormatControl_iid "org.qt-project.qt.cameracapturebufferformatcontrol/5.0" diff --git a/src/multimedia/controls/qcameracapturedestinationcontrol.h b/src/multimedia/controls/qcameracapturedestinationcontrol.h index efe7f0234..a5238add4 100644 --- a/src/multimedia/controls/qcameracapturedestinationcontrol.h +++ b/src/multimedia/controls/qcameracapturedestinationcontrol.h @@ -56,7 +56,7 @@ Q_SIGNALS: void captureDestinationChanged(QCameraImageCapture::CaptureDestinations); protected: - QCameraCaptureDestinationControl(QObject* parent = 0); + explicit QCameraCaptureDestinationControl(QObject *parent = Q_NULLPTR); }; #define QCameraCaptureDestinationControl_iid "org.qt-project.qt.cameracapturedestinationcontrol/5.0" diff --git a/src/multimedia/controls/qcameracontrol.h b/src/multimedia/controls/qcameracontrol.h index ec7c2017c..6b1cc9f30 100644 --- a/src/multimedia/controls/qcameracontrol.h +++ b/src/multimedia/controls/qcameracontrol.h @@ -77,7 +77,7 @@ Q_SIGNALS: void captureModeChanged(QCamera::CaptureModes); protected: - QCameraControl(QObject* parent = 0); + explicit QCameraControl(QObject *parent = Q_NULLPTR); }; #define QCameraControl_iid "org.qt-project.qt.cameracontrol/5.0" diff --git a/src/multimedia/controls/qcameraexposurecontrol.h b/src/multimedia/controls/qcameraexposurecontrol.h index 6f7ef4698..b905d378f 100644 --- a/src/multimedia/controls/qcameraexposurecontrol.h +++ b/src/multimedia/controls/qcameraexposurecontrol.h @@ -81,7 +81,7 @@ Q_SIGNALS: void parameterRangeChanged(int parameter); protected: - QCameraExposureControl(QObject* parent = 0); + explicit QCameraExposureControl(QObject *parent = Q_NULLPTR); }; #define QCameraExposureControl_iid "org.qt-project.qt.cameraexposurecontrol/5.0" diff --git a/src/multimedia/controls/qcamerafeedbackcontrol.h b/src/multimedia/controls/qcamerafeedbackcontrol.h index 44ba9dda1..d256e52ad 100644 --- a/src/multimedia/controls/qcamerafeedbackcontrol.h +++ b/src/multimedia/controls/qcamerafeedbackcontrol.h @@ -78,7 +78,7 @@ public: virtual bool setEventFeedbackSound(EventType, const QString &filePath) = 0; protected: - QCameraFeedbackControl(QObject* parent = 0); + explicit QCameraFeedbackControl(QObject *parent = Q_NULLPTR); }; #define QCameraFeedbackControl_iid "org.qt-project.qt.camerafeedbackcontrol/5.0" diff --git a/src/multimedia/controls/qcameraflashcontrol.h b/src/multimedia/controls/qcameraflashcontrol.h index 653321e36..d00b7356a 100644 --- a/src/multimedia/controls/qcameraflashcontrol.h +++ b/src/multimedia/controls/qcameraflashcontrol.h @@ -62,7 +62,7 @@ Q_SIGNALS: void flashReady(bool); protected: - QCameraFlashControl(QObject* parent = 0); + explicit QCameraFlashControl(QObject *parent = Q_NULLPTR); }; #define QCameraFlashControl_iid "org.qt-project.qt.cameraflashcontrol/5.0" diff --git a/src/multimedia/controls/qcamerafocuscontrol.h b/src/multimedia/controls/qcamerafocuscontrol.h index 868f5e493..3562fb8e2 100644 --- a/src/multimedia/controls/qcamerafocuscontrol.h +++ b/src/multimedia/controls/qcamerafocuscontrol.h @@ -71,7 +71,7 @@ Q_SIGNALS: void focusZonesChanged(); protected: - QCameraFocusControl(QObject* parent = 0); + explicit QCameraFocusControl(QObject *parent = Q_NULLPTR); }; #define QCameraFocusControl_iid "org.qt-project.qt.camerafocuscontrol/5.0" diff --git a/src/multimedia/controls/qcameraimagecapturecontrol.h b/src/multimedia/controls/qcameraimagecapturecontrol.h index 93ec9a7da..bd8e31c84 100644 --- a/src/multimedia/controls/qcameraimagecapturecontrol.h +++ b/src/multimedia/controls/qcameraimagecapturecontrol.h @@ -74,7 +74,7 @@ Q_SIGNALS: void error(int id, int error, const QString &errorString); protected: - QCameraImageCaptureControl(QObject* parent = 0); + explicit QCameraImageCaptureControl(QObject *parent = Q_NULLPTR); }; #define QCameraImageCaptureControl_iid "org.qt-project.qt.cameraimagecapturecontrol/5.0" diff --git a/src/multimedia/controls/qcameraimageprocessingcontrol.h b/src/multimedia/controls/qcameraimageprocessingcontrol.h index 01686dc46..d0a1c16b3 100644 --- a/src/multimedia/controls/qcameraimageprocessingcontrol.h +++ b/src/multimedia/controls/qcameraimageprocessingcontrol.h @@ -76,7 +76,7 @@ public: virtual void setParameter(ProcessingParameter parameter, const QVariant &value) = 0; protected: - QCameraImageProcessingControl(QObject* parent = 0); + explicit QCameraImageProcessingControl(QObject *parent = Q_NULLPTR); }; #define QCameraImageProcessingControl_iid "org.qt-project.qt.cameraimageprocessingcontrol/5.0" diff --git a/src/multimedia/controls/qcamerainfocontrol.h b/src/multimedia/controls/qcamerainfocontrol.h index c9a564ea7..acdb30dca 100644 --- a/src/multimedia/controls/qcamerainfocontrol.h +++ b/src/multimedia/controls/qcamerainfocontrol.h @@ -52,7 +52,7 @@ public: virtual int cameraOrientation(const QString &deviceName) const = 0; protected: - QCameraInfoControl(QObject *parent = 0); + explicit QCameraInfoControl(QObject *parent = Q_NULLPTR); }; #define QCameraInfoControl_iid "org.qt-project.qt.camerainfocontrol/5.3" diff --git a/src/multimedia/controls/qcameralockscontrol.h b/src/multimedia/controls/qcameralockscontrol.h index 421563758..1fe8273b8 100644 --- a/src/multimedia/controls/qcameralockscontrol.h +++ b/src/multimedia/controls/qcameralockscontrol.h @@ -61,7 +61,7 @@ Q_SIGNALS: void lockStatusChanged(QCamera::LockType type, QCamera::LockStatus status, QCamera::LockChangeReason reason); protected: - QCameraLocksControl(QObject* parent = 0); + explicit QCameraLocksControl(QObject *parent = Q_NULLPTR); }; #define QCameraLocksControl_iid "org.qt-project.qt.cameralockscontrol/5.0" diff --git a/src/multimedia/controls/qcameraviewfindersettingscontrol.h b/src/multimedia/controls/qcameraviewfindersettingscontrol.h index a48ae450e..84fe2d46b 100644 --- a/src/multimedia/controls/qcameraviewfindersettingscontrol.h +++ b/src/multimedia/controls/qcameraviewfindersettingscontrol.h @@ -64,7 +64,7 @@ public: virtual void setViewfinderParameter(ViewfinderParameter parameter, const QVariant &value) = 0; protected: - QCameraViewfinderSettingsControl(QObject *parent = 0); + explicit QCameraViewfinderSettingsControl(QObject *parent = Q_NULLPTR); }; #define QCameraViewfinderSettingsControl_iid "org.qt-project.qt.cameraviewfindersettingscontrol/5.0" @@ -86,7 +86,7 @@ public: virtual void setViewfinderSettings(const QCameraViewfinderSettings &settings) = 0; protected: - QCameraViewfinderSettingsControl2(QObject *parent = 0); + explicit QCameraViewfinderSettingsControl2(QObject *parent = Q_NULLPTR); }; #define QCameraViewfinderSettingsControl2_iid "org.qt-project.qt.cameraviewfindersettingscontrol2/5.5" diff --git a/src/multimedia/controls/qcamerazoomcontrol.h b/src/multimedia/controls/qcamerazoomcontrol.h index 07575a25c..f16052c92 100644 --- a/src/multimedia/controls/qcamerazoomcontrol.h +++ b/src/multimedia/controls/qcamerazoomcontrol.h @@ -69,7 +69,7 @@ Q_SIGNALS: void currentDigitalZoomChanged(qreal digitalZoom); protected: - QCameraZoomControl(QObject* parent = 0); + explicit QCameraZoomControl(QObject *parent = Q_NULLPTR); }; #define QCameraZoomControl_iid "org.qt-project.qt.camerazoomcontrol/5.0" diff --git a/src/multimedia/controls/qimageencodercontrol.h b/src/multimedia/controls/qimageencodercontrol.h index f448754e6..6dccd966e 100644 --- a/src/multimedia/controls/qimageencodercontrol.h +++ b/src/multimedia/controls/qimageencodercontrol.h @@ -62,13 +62,13 @@ public: virtual QString imageCodecDescription(const QString &codecName) const = 0; virtual QList supportedResolutions(const QImageEncoderSettings &settings, - bool *continuous = 0) const = 0; + bool *continuous = Q_NULLPTR) const = 0; virtual QImageEncoderSettings imageSettings() const = 0; virtual void setImageSettings(const QImageEncoderSettings &settings) = 0; protected: - QImageEncoderControl(QObject *parent = 0); + explicit QImageEncoderControl(QObject *parent = Q_NULLPTR); }; #define QImageEncoderControl_iid "org.qt-project.qt.imageencodercontrol/5.0" diff --git a/src/multimedia/controls/qmediaaudioprobecontrol.h b/src/multimedia/controls/qmediaaudioprobecontrol.h index b6961ec94..04ec7aca9 100644 --- a/src/multimedia/controls/qmediaaudioprobecontrol.h +++ b/src/multimedia/controls/qmediaaudioprobecontrol.h @@ -50,7 +50,7 @@ Q_SIGNALS: void flush(); protected: - explicit QMediaAudioProbeControl(QObject *parent = 0); + explicit QMediaAudioProbeControl(QObject *parent = Q_NULLPTR); }; #define QMediaAudioProbeControl_iid "org.qt-project.qt.mediaaudioprobecontrol/5.0" diff --git a/src/multimedia/controls/qmediaavailabilitycontrol.h b/src/multimedia/controls/qmediaavailabilitycontrol.h index 1f788f82f..eddadb441 100644 --- a/src/multimedia/controls/qmediaavailabilitycontrol.h +++ b/src/multimedia/controls/qmediaavailabilitycontrol.h @@ -56,7 +56,7 @@ Q_SIGNALS: void availabilityChanged(QMultimedia::AvailabilityStatus availability); protected: - QMediaAvailabilityControl(QObject* parent = 0); + explicit QMediaAvailabilityControl(QObject *parent = Q_NULLPTR); }; #define QMediaAvailabilityControl_iid "org.qt-project.qt.mediaavailabilitycontrol/5.0" diff --git a/src/multimedia/controls/qmediacontainercontrol.h b/src/multimedia/controls/qmediacontainercontrol.h index 83b201cdd..ae15967e9 100644 --- a/src/multimedia/controls/qmediacontainercontrol.h +++ b/src/multimedia/controls/qmediacontainercontrol.h @@ -56,7 +56,7 @@ public: virtual QString containerDescription(const QString &formatMimeType) const = 0; protected: - QMediaContainerControl(QObject *parent = 0); + explicit QMediaContainerControl(QObject *parent = Q_NULLPTR); }; #define QMediaContainerControl_iid "org.qt-project.qt.mediacontainercontrol/5.0" diff --git a/src/multimedia/controls/qmediagaplessplaybackcontrol.h b/src/multimedia/controls/qmediagaplessplaybackcontrol.h index 79bb6168f..9158aed74 100644 --- a/src/multimedia/controls/qmediagaplessplaybackcontrol.h +++ b/src/multimedia/controls/qmediagaplessplaybackcontrol.h @@ -60,7 +60,7 @@ Q_SIGNALS: void advancedToNextMedia(); protected: - QMediaGaplessPlaybackControl(QObject* parent = 0); + explicit QMediaGaplessPlaybackControl(QObject *parent = Q_NULLPTR); }; #define QMediaGaplessPlaybackControl_iid "org.qt-project.qt.mediagaplessplaybackcontrol/5.0" diff --git a/src/multimedia/controls/qmedianetworkaccesscontrol.h b/src/multimedia/controls/qmedianetworkaccesscontrol.h index 2db6b4a60..f70cbedde 100644 --- a/src/multimedia/controls/qmedianetworkaccesscontrol.h +++ b/src/multimedia/controls/qmedianetworkaccesscontrol.h @@ -59,7 +59,7 @@ Q_SIGNALS: void configurationChanged(const QNetworkConfiguration& configuration); protected: - QMediaNetworkAccessControl(QObject *parent = 0); + explicit QMediaNetworkAccessControl(QObject *parent = Q_NULLPTR); }; #define QMediaNetworkAccessControl_iid "org.qt-project.qt.medianetworkaccesscontrol/5.0" diff --git a/src/multimedia/controls/qmediaplayercontrol.h b/src/multimedia/controls/qmediaplayercontrol.h index 61622aa8e..b8f915a3d 100644 --- a/src/multimedia/controls/qmediaplayercontrol.h +++ b/src/multimedia/controls/qmediaplayercontrol.h @@ -104,7 +104,7 @@ Q_SIGNALS: void error(int error, const QString &errorString); protected: - QMediaPlayerControl(QObject* parent = 0); + explicit QMediaPlayerControl(QObject *parent = Q_NULLPTR); }; #define QMediaPlayerControl_iid "org.qt-project.qt.mediaplayercontrol/5.0" diff --git a/src/multimedia/controls/qmediarecordercontrol.h b/src/multimedia/controls/qmediarecordercontrol.h index c3afa9b58..58e4d5aa1 100644 --- a/src/multimedia/controls/qmediarecordercontrol.h +++ b/src/multimedia/controls/qmediarecordercontrol.h @@ -82,7 +82,7 @@ public Q_SLOTS: virtual void setVolume(qreal volume) = 0; protected: - QMediaRecorderControl(QObject* parent = 0); + explicit QMediaRecorderControl(QObject *parent = Q_NULLPTR); }; #define QMediaRecorderControl_iid "org.qt-project.qt.mediarecordercontrol/5.0" diff --git a/src/multimedia/controls/qmediastreamscontrol.h b/src/multimedia/controls/qmediastreamscontrol.h index ca2ad53bc..eee2803c7 100644 --- a/src/multimedia/controls/qmediastreamscontrol.h +++ b/src/multimedia/controls/qmediastreamscontrol.h @@ -67,7 +67,7 @@ Q_SIGNALS: void activeStreamsChanged(); protected: - QMediaStreamsControl(QObject *parent = 0); + explicit QMediaStreamsControl(QObject *parent = Q_NULLPTR); }; #define QMediaStreamsControl_iid "org.qt-project.qt.mediastreamscontrol/5.0" diff --git a/src/multimedia/controls/qmediavideoprobecontrol.h b/src/multimedia/controls/qmediavideoprobecontrol.h index 78f89400d..8a81ab9aa 100644 --- a/src/multimedia/controls/qmediavideoprobecontrol.h +++ b/src/multimedia/controls/qmediavideoprobecontrol.h @@ -52,7 +52,7 @@ Q_SIGNALS: void flush(); protected: - explicit QMediaVideoProbeControl(QObject *parent = 0); + explicit QMediaVideoProbeControl(QObject *parent = Q_NULLPTR); }; #define QMediaVideoProbeControl_iid "org.qt-project.qt.mediavideoprobecontrol/5.0" diff --git a/src/multimedia/controls/qmetadatareadercontrol.h b/src/multimedia/controls/qmetadatareadercontrol.h index 7cf8a5f0d..285e08dd5 100644 --- a/src/multimedia/controls/qmetadatareadercontrol.h +++ b/src/multimedia/controls/qmetadatareadercontrol.h @@ -65,7 +65,7 @@ Q_SIGNALS: void metaDataAvailableChanged(bool available); protected: - QMetaDataReaderControl(QObject *parent = 0); + explicit QMetaDataReaderControl(QObject *parent = Q_NULLPTR); }; #define QMetaDataReaderControl_iid "org.qt-project.qt.metadatareadercontrol/5.0" diff --git a/src/multimedia/controls/qmetadatawritercontrol.h b/src/multimedia/controls/qmetadatawritercontrol.h index 7b6cef9c4..970feab0c 100644 --- a/src/multimedia/controls/qmetadatawritercontrol.h +++ b/src/multimedia/controls/qmetadatawritercontrol.h @@ -68,7 +68,7 @@ Q_SIGNALS: void metaDataAvailableChanged(bool available); protected: - QMetaDataWriterControl(QObject *parent = 0); + explicit QMetaDataWriterControl(QObject *parent = Q_NULLPTR); }; #define QMetaDataWriterControl_iid "org.qt-project.qt.metadatawritercontrol/5.0" diff --git a/src/multimedia/controls/qradiodatacontrol.h b/src/multimedia/controls/qradiodatacontrol.h index e519c414e..91fa2a69b 100644 --- a/src/multimedia/controls/qradiodatacontrol.h +++ b/src/multimedia/controls/qradiodatacontrol.h @@ -70,7 +70,7 @@ Q_SIGNALS: void error(QRadioData::Error err); protected: - QRadioDataControl(QObject *parent = 0); + explicit QRadioDataControl(QObject *parent = Q_NULLPTR); }; #define QRadioDataControl_iid "org.qt-project.qt.radiodatacontrol/5.0" diff --git a/src/multimedia/controls/qradiotunercontrol.h b/src/multimedia/controls/qradiotunercontrol.h index fbcad5167..273120f5a 100644 --- a/src/multimedia/controls/qradiotunercontrol.h +++ b/src/multimedia/controls/qradiotunercontrol.h @@ -101,7 +101,7 @@ Q_SIGNALS: void antennaConnectedChanged(bool connectionStatus); protected: - QRadioTunerControl(QObject *parent = 0); + explicit QRadioTunerControl(QObject *parent = Q_NULLPTR); }; #define QRadioTunerControl_iid "org.qt-project.qt.radiotunercontrol/5.0" diff --git a/src/multimedia/controls/qvideodeviceselectorcontrol.h b/src/multimedia/controls/qvideodeviceselectorcontrol.h index 840c31efa..655b70dba 100644 --- a/src/multimedia/controls/qvideodeviceselectorcontrol.h +++ b/src/multimedia/controls/qvideodeviceselectorcontrol.h @@ -65,7 +65,7 @@ Q_SIGNALS: void devicesChanged(); protected: - QVideoDeviceSelectorControl(QObject *parent = 0); + explicit QVideoDeviceSelectorControl(QObject *parent = Q_NULLPTR); }; #define QVideoDeviceSelectorControl_iid "org.qt-project.qt.videodeviceselectorcontrol/5.0" diff --git a/src/multimedia/controls/qvideoencodersettingscontrol.h b/src/multimedia/controls/qvideoencodersettingscontrol.h index 8638c3886..7b80cd51f 100644 --- a/src/multimedia/controls/qvideoencodersettingscontrol.h +++ b/src/multimedia/controls/qvideoencodersettingscontrol.h @@ -59,10 +59,10 @@ public: virtual ~QVideoEncoderSettingsControl(); virtual QList supportedResolutions(const QVideoEncoderSettings &settings, - bool *continuous = 0) const = 0; + bool *continuous = Q_NULLPTR) const = 0; virtual QList supportedFrameRates(const QVideoEncoderSettings &settings, - bool *continuous = 0) const = 0; + bool *continuous = Q_NULLPTR) const = 0; virtual QStringList supportedVideoCodecs() const = 0; virtual QString videoCodecDescription(const QString &codecName) const = 0; @@ -71,7 +71,7 @@ public: virtual void setVideoSettings(const QVideoEncoderSettings &settings) = 0; protected: - QVideoEncoderSettingsControl(QObject *parent = 0); + explicit QVideoEncoderSettingsControl(QObject *parent = Q_NULLPTR); }; #define QVideoEncoderSettingsControl_iid "org.qt-project.qt.videoencodersettingscontrol/5.0" diff --git a/src/multimedia/controls/qvideorenderercontrol.h b/src/multimedia/controls/qvideorenderercontrol.h index 754d83049..132a7cf07 100644 --- a/src/multimedia/controls/qvideorenderercontrol.h +++ b/src/multimedia/controls/qvideorenderercontrol.h @@ -50,7 +50,7 @@ public: virtual void setSurface(QAbstractVideoSurface *surface) = 0; protected: - QVideoRendererControl(QObject *parent = 0); + explicit QVideoRendererControl(QObject *parent = Q_NULLPTR); }; #define QVideoRendererControl_iid "org.qt-project.qt.videorenderercontrol/5.0" diff --git a/src/multimedia/controls/qvideowindowcontrol.h b/src/multimedia/controls/qvideowindowcontrol.h index c57eef070..ca786dbcd 100644 --- a/src/multimedia/controls/qvideowindowcontrol.h +++ b/src/multimedia/controls/qvideowindowcontrol.h @@ -88,7 +88,7 @@ Q_SIGNALS: void nativeSizeChanged(); protected: - QVideoWindowControl(QObject *parent = 0); + explicit QVideoWindowControl(QObject *parent = Q_NULLPTR); }; #define QVideoWindowControl_iid "org.qt-project.qt.videowindowcontrol/5.0" diff --git a/src/multimedia/playback/qmediaplayer.h b/src/multimedia/playback/qmediaplayer.h index 437bf58ad..30a08f88b 100644 --- a/src/multimedia/playback/qmediaplayer.h +++ b/src/multimedia/playback/qmediaplayer.h @@ -113,13 +113,13 @@ public: MediaIsPlaylist }; - QMediaPlayer(QObject *parent = 0, Flags flags = 0); + explicit QMediaPlayer(QObject *parent = Q_NULLPTR, Flags flags = Flags()); ~QMediaPlayer(); static QMultimedia::SupportEstimate hasSupport(const QString &mimeType, const QStringList& codecs = QStringList(), - Flags flags = 0); - static QStringList supportedMimeTypes(Flags flags = 0); + Flags flags = Flags()); + static QStringList supportedMimeTypes(Flags flags = Flags()); void setVideoOutput(QVideoWidget *); void setVideoOutput(QGraphicsVideoItem *); @@ -168,7 +168,7 @@ public Q_SLOTS: void setPlaybackRate(qreal rate); - void setMedia(const QMediaContent &media, QIODevice *stream = 0); + void setMedia(const QMediaContent &media, QIODevice *stream = Q_NULLPTR); void setPlaylist(QMediaPlaylist *playlist); void setNetworkConfigurations(const QList &configurations); diff --git a/src/multimedia/playback/qmediaplaylist.h b/src/multimedia/playback/qmediaplaylist.h index 1388ac10f..3b6551ead 100644 --- a/src/multimedia/playback/qmediaplaylist.h +++ b/src/multimedia/playback/qmediaplaylist.h @@ -61,7 +61,7 @@ public: enum PlaybackMode { CurrentItemOnce, CurrentItemInLoop, Sequential, Loop, Random }; enum Error { NoError, FormatError, FormatNotSupportedError, NetworkError, AccessDeniedError }; - QMediaPlaylist(QObject *parent = 0); + explicit QMediaPlaylist(QObject *parent = Q_NULLPTR); virtual ~QMediaPlaylist(); QMediaObject *mediaObject() const; @@ -89,11 +89,11 @@ public: bool removeMedia(int start, int end); bool clear(); - void load(const QNetworkRequest &request, const char *format = 0); - void load(const QUrl &location, const char *format = 0); - void load(QIODevice * device, const char *format = 0); + void load(const QNetworkRequest &request, const char *format = Q_NULLPTR); + void load(const QUrl &location, const char *format = Q_NULLPTR); + void load(QIODevice *device, const char *format = Q_NULLPTR); - bool save(const QUrl &location, const char *format = 0); + bool save(const QUrl &location, const char *format = Q_NULLPTR); bool save(QIODevice * device, const char *format); Error error() const; diff --git a/src/multimedia/qmediacontrol.h b/src/multimedia/qmediacontrol.h index 480d96ea3..95c3e1029 100644 --- a/src/multimedia/qmediacontrol.h +++ b/src/multimedia/qmediacontrol.h @@ -53,8 +53,8 @@ public: ~QMediaControl(); protected: - QMediaControl(QObject *parent = 0); - QMediaControl(QMediaControlPrivate &dd, QObject *parent = 0); + explicit QMediaControl(QObject *parent = Q_NULLPTR); + explicit QMediaControl(QMediaControlPrivate &dd, QObject *parent = Q_NULLPTR); QMediaControlPrivate *d_ptr; diff --git a/src/multimedia/radio/qradiodata.h b/src/multimedia/radio/qradiodata.h index edc7acb49..894a9dd34 100644 --- a/src/multimedia/radio/qradiodata.h +++ b/src/multimedia/radio/qradiodata.h @@ -76,7 +76,7 @@ public: College }; - QRadioData(QMediaObject *mediaObject, QObject *parent = 0); + explicit QRadioData(QMediaObject *mediaObject, QObject *parent = Q_NULLPTR); ~QRadioData(); QMultimedia::AvailabilityStatus availability() const; diff --git a/src/multimedia/radio/qradiotuner.h b/src/multimedia/radio/qradiotuner.h index 7a394d0aa..09b8757a5 100644 --- a/src/multimedia/radio/qradiotuner.h +++ b/src/multimedia/radio/qradiotuner.h @@ -72,7 +72,7 @@ public: enum StereoMode { ForceStereo, ForceMono, Auto }; enum SearchMode { SearchFast, SearchGetStationId }; - QRadioTuner(QObject *parent = 0); + explicit QRadioTuner(QObject *parent = Q_NULLPTR); ~QRadioTuner(); QMultimedia::AvailabilityStatus availability() const; diff --git a/src/multimedia/recording/qaudiorecorder.h b/src/multimedia/recording/qaudiorecorder.h index 24b79ea30..d63a44b6a 100644 --- a/src/multimedia/recording/qaudiorecorder.h +++ b/src/multimedia/recording/qaudiorecorder.h @@ -56,7 +56,7 @@ class Q_MULTIMEDIA_EXPORT QAudioRecorder : public QMediaRecorder Q_OBJECT Q_PROPERTY(QString audioInput READ audioInput WRITE setAudioInput NOTIFY audioInputChanged) public: - QAudioRecorder(QObject *parent = 0); + explicit QAudioRecorder(QObject *parent = Q_NULLPTR); ~QAudioRecorder(); QStringList audioInputs() const; diff --git a/src/multimedia/recording/qmediarecorder.h b/src/multimedia/recording/qmediarecorder.h index 6f275b305..71e8ab5cf 100644 --- a/src/multimedia/recording/qmediarecorder.h +++ b/src/multimedia/recording/qmediarecorder.h @@ -100,7 +100,7 @@ public: OutOfSpaceError }; - QMediaRecorder(QMediaObject *mediaObject, QObject *parent = 0); + explicit QMediaRecorder(QMediaObject *mediaObject, QObject *parent = Q_NULLPTR); ~QMediaRecorder(); QMediaObject *mediaObject() const; @@ -131,16 +131,16 @@ public: QString audioCodecDescription(const QString &codecName) const; QList supportedAudioSampleRates(const QAudioEncoderSettings &settings = QAudioEncoderSettings(), - bool *continuous = 0) const; + bool *continuous = Q_NULLPTR) const; QStringList supportedVideoCodecs() const; QString videoCodecDescription(const QString &codecName) const; QList supportedResolutions(const QVideoEncoderSettings &settings = QVideoEncoderSettings(), - bool *continuous = 0) const; + bool *continuous = Q_NULLPTR) const; QList supportedFrameRates(const QVideoEncoderSettings &settings = QVideoEncoderSettings(), - bool *continuous = 0) const; + bool *continuous = Q_NULLPTR) const; QAudioEncoderSettings audioSettings() const; QVideoEncoderSettings videoSettings() const; @@ -187,7 +187,7 @@ Q_SIGNALS: void availabilityChanged(QMultimedia::AvailabilityStatus availability); protected: - QMediaRecorder(QMediaRecorderPrivate &dd, QMediaObject *mediaObject, QObject *parent = 0); + QMediaRecorder(QMediaRecorderPrivate &dd, QMediaObject *mediaObject, QObject *parent = Q_NULLPTR); bool setMediaObject(QMediaObject *object); QMediaRecorderPrivate *d_ptr; diff --git a/src/multimedia/video/qabstractvideofilter.h b/src/multimedia/video/qabstractvideofilter.h index 77f035e0a..51b6ee7b4 100644 --- a/src/multimedia/video/qabstractvideofilter.h +++ b/src/multimedia/video/qabstractvideofilter.h @@ -62,7 +62,7 @@ class Q_MULTIMEDIA_EXPORT QAbstractVideoFilter : public QObject Q_PROPERTY(bool active READ isActive WRITE setActive NOTIFY activeChanged) public: - explicit QAbstractVideoFilter(QObject *parent = 0); + explicit QAbstractVideoFilter(QObject *parent = Q_NULLPTR); ~QAbstractVideoFilter(); bool isActive() const; diff --git a/src/multimedia/video/qabstractvideosurface.h b/src/multimedia/video/qabstractvideosurface.h index f8aefc3ba..e2b684125 100644 --- a/src/multimedia/video/qabstractvideosurface.h +++ b/src/multimedia/video/qabstractvideosurface.h @@ -58,7 +58,7 @@ public: ResourceError }; - explicit QAbstractVideoSurface(QObject *parent = 0); + explicit QAbstractVideoSurface(QObject *parent = Q_NULLPTR); ~QAbstractVideoSurface(); virtual QList supportedPixelFormats( diff --git a/src/multimedia/video/qvideoprobe.h b/src/multimedia/video/qvideoprobe.h index 5de594f06..d3c8dbfda 100644 --- a/src/multimedia/video/qvideoprobe.h +++ b/src/multimedia/video/qvideoprobe.h @@ -47,7 +47,7 @@ class Q_MULTIMEDIA_EXPORT QVideoProbe : public QObject { Q_OBJECT public: - explicit QVideoProbe(QObject *parent = 0); + explicit QVideoProbe(QObject *parent = Q_NULLPTR); ~QVideoProbe(); bool setSource(QMediaObject *source); diff --git a/src/multimediawidgets/qcameraviewfinder.h b/src/multimediawidgets/qcameraviewfinder.h index 65556c417..9bb2bda43 100644 --- a/src/multimediawidgets/qcameraviewfinder.h +++ b/src/multimediawidgets/qcameraviewfinder.h @@ -55,7 +55,7 @@ class Q_MULTIMEDIAWIDGETS_EXPORT QCameraViewfinder : public QVideoWidget { Q_OBJECT public: - QCameraViewfinder(QWidget *parent = 0); + explicit QCameraViewfinder(QWidget *parent = Q_NULLPTR); ~QCameraViewfinder(); QMediaObject *mediaObject() const; diff --git a/src/multimediawidgets/qgraphicsvideoitem.h b/src/multimediawidgets/qgraphicsvideoitem.h index 76dbae2e0..e43de0157 100644 --- a/src/multimediawidgets/qgraphicsvideoitem.h +++ b/src/multimediawidgets/qgraphicsvideoitem.h @@ -57,7 +57,7 @@ class Q_MULTIMEDIAWIDGETS_EXPORT QGraphicsVideoItem : public QGraphicsObject, pu Q_PROPERTY(QSizeF size READ size WRITE setSize) Q_PROPERTY(QSizeF nativeSize READ nativeSize NOTIFY nativeSizeChanged) public: - QGraphicsVideoItem(QGraphicsItem *parent = 0); + explicit QGraphicsVideoItem(QGraphicsItem *parent = Q_NULLPTR); ~QGraphicsVideoItem(); QMediaObject *mediaObject() const; @@ -75,7 +75,7 @@ public: QRectF boundingRect() const; - void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0); + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = Q_NULLPTR); Q_SIGNALS: void nativeSizeChanged(const QSizeF &size); diff --git a/src/multimediawidgets/qvideowidget.h b/src/multimediawidgets/qvideowidget.h index 2f5eade30..1e67de886 100644 --- a/src/multimediawidgets/qvideowidget.h +++ b/src/multimediawidgets/qvideowidget.h @@ -58,7 +58,7 @@ class Q_MULTIMEDIAWIDGETS_EXPORT QVideoWidget : public QWidget, public QMediaBin Q_PROPERTY(int saturation READ saturation WRITE setSaturation NOTIFY saturationChanged) public: - QVideoWidget(QWidget *parent = 0); + explicit QVideoWidget(QWidget *parent = Q_NULLPTR); ~QVideoWidget(); QMediaObject *mediaObject() const; diff --git a/src/multimediawidgets/qvideowidgetcontrol.h b/src/multimediawidgets/qvideowidgetcontrol.h index c77d646db..dca9f2dd0 100644 --- a/src/multimediawidgets/qvideowidgetcontrol.h +++ b/src/multimediawidgets/qvideowidgetcontrol.h @@ -79,7 +79,7 @@ Q_SIGNALS: void saturationChanged(int saturation); protected: - QVideoWidgetControl(QObject *parent = 0); + explicit QVideoWidgetControl(QObject *parent = Q_NULLPTR); }; #define QVideoWidgetControl_iid "org.qt-project.qt.videowidgetcontrol/5.0" -- cgit v1.2.1 From 77c9ab4a3871110c6fb569c4e7b17181867c17ad Mon Sep 17 00:00:00 2001 From: Andreas Holzammer Date: Wed, 9 Mar 2016 11:28:00 +0100 Subject: Port DirectShow backend to wince dshow.h needs to be included before Qt headers as they include the windows header with NOMINMAX macro set. DirectShow header needs min/max macro definition to compile. The min/max macro then conflicts with QDateTime header, hence needs to be undefined again for some occasions. Windows Embedded Compact then defines INTERFACE as macro, which conflicts. Windows Embedded Compact does not support audio end point selection. Feature has been disabled for this platform. Windows Embedded Compact does not support setting meta data, control has been disabled. Windows Embedded Compact does not support VMR, feature was disabled. Direct Show renders always top to buttom. Change-Id: Id17700835e2105fb127b12e3448bea16e3b52546 Reviewed-by: Yoann Lopes --- config.tests/directshow/directshow.pro | 2 +- config.tests/directshow/main.cpp | 2 ++ src/plugins/directshow/directshow.pro | 2 +- src/plugins/directshow/dsserviceplugin.cpp | 4 ++- src/plugins/directshow/player/directshowglobal.h | 5 +-- src/plugins/directshow/player/directshowioreader.h | 4 +-- .../directshow/player/directshowmediatype.cpp | 2 ++ .../directshow/player/directshowmediatype.h | 3 +- .../directshow/player/directshowmediatypelist.h | 4 +-- .../player/directshowmetadatacontrol.cpp | 9 ++++- .../directshow/player/directshowmetadatacontrol.h | 2 ++ src/plugins/directshow/player/directshowpinenum.h | 3 +- .../directshow/player/directshowplayercontrol.cpp | 2 ++ .../directshow/player/directshowplayercontrol.h | 2 ++ .../directshow/player/directshowplayerservice.cpp | 41 ++++++++++++++++++++-- .../directshow/player/directshowplayerservice.h | 6 ++++ .../directshow/player/directshowsamplescheduler.h | 4 +-- .../player/directshowvideorenderercontrol.h | 4 +-- .../directshow/player/mediasamplevideobuffer.h | 4 +-- src/plugins/directshow/player/player.pri | 24 ++++++++----- 20 files changed, 100 insertions(+), 29 deletions(-) diff --git a/config.tests/directshow/directshow.pro b/config.tests/directshow/directshow.pro index 6493e54ab..6dfc54a01 100644 --- a/config.tests/directshow/directshow.pro +++ b/config.tests/directshow/directshow.pro @@ -3,4 +3,4 @@ CONFIG += console SOURCES += main.cpp -LIBS += -lstrmiids -ldmoguids -luuid -lmsdmo -lole32 -loleaut32 +!wince: LIBS += -lstrmiids -ldmoguids -luuid -lmsdmo -lole32 -loleaut32 diff --git a/config.tests/directshow/main.cpp b/config.tests/directshow/main.cpp index d5e4db589..15ff3b9fc 100644 --- a/config.tests/directshow/main.cpp +++ b/config.tests/directshow/main.cpp @@ -32,8 +32,10 @@ ****************************************************************************/ #include +#ifndef _WIN32_WCE #include #include +#endif int main(int, char**) { diff --git a/src/plugins/directshow/directshow.pro b/src/plugins/directshow/directshow.pro index 280b52619..117b02ade 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) -include(camera/camera.pri) +!wince: include(camera/camera.pri) OTHER_FILES += \ directshow.json \ diff --git a/src/plugins/directshow/dsserviceplugin.cpp b/src/plugins/directshow/dsserviceplugin.cpp index 4af38b1cc..e889a651d 100644 --- a/src/plugins/directshow/dsserviceplugin.cpp +++ b/src/plugins/directshow/dsserviceplugin.cpp @@ -31,14 +31,16 @@ ** ****************************************************************************/ +#include + #include #include #include #include "dsserviceplugin.h" -#include "dsvideodevicecontrol.h" #ifdef QMEDIA_DIRECTSHOW_CAMERA +#include "dsvideodevicecontrol.h" #include #include "dscameraservice.h" #endif diff --git a/src/plugins/directshow/player/directshowglobal.h b/src/plugins/directshow/player/directshowglobal.h index d8f1d1200..a563ed361 100644 --- a/src/plugins/directshow/player/directshowglobal.h +++ b/src/plugins/directshow/player/directshowglobal.h @@ -34,10 +34,10 @@ #ifndef DIRECTSHOWGLOBAL_H #define DIRECTSHOWGLOBAL_H -#include - #include +#include + template T *com_cast(IUnknown *unknown, const IID &iid) { T *iface = 0; @@ -112,6 +112,7 @@ DECLARE_INTERFACE_(IFileSourceFilter ,IUnknown) #ifndef __IAMOpenProgress_INTERFACE_DEFINED__ #define __IAMOpenProgress_INTERFACE_DEFINED__ +#undef INTERFACE #define INTERFACE IAMOpenProgress DECLARE_INTERFACE_(IAMOpenProgress ,IUnknown) { diff --git a/src/plugins/directshow/player/directshowioreader.h b/src/plugins/directshow/player/directshowioreader.h index dd66b3a3c..203ca759a 100644 --- a/src/plugins/directshow/player/directshowioreader.h +++ b/src/plugins/directshow/player/directshowioreader.h @@ -34,12 +34,12 @@ #ifndef DIRECTSHOWIOREADER_H #define DIRECTSHOWIOREADER_H +#include + #include #include #include -#include - QT_BEGIN_NAMESPACE class QIODevice; QT_END_NAMESPACE diff --git a/src/plugins/directshow/player/directshowmediatype.cpp b/src/plugins/directshow/player/directshowmediatype.cpp index 1be641f41..fcb254fe9 100644 --- a/src/plugins/directshow/player/directshowmediatype.cpp +++ b/src/plugins/directshow/player/directshowmediatype.cpp @@ -192,9 +192,11 @@ QVideoSurfaceFormat::Direction DirectShowMediaType::scanLineDirection(QVideoFram case QVideoFrame::Format_BGR24: case QVideoFrame::Format_RGB565: case QVideoFrame::Format_RGB555: +#ifndef Q_OS_WINCE return bmiHeader.biHeight < 0 ? QVideoSurfaceFormat::TopToBottom : QVideoSurfaceFormat::BottomToTop; +#endif default: return QVideoSurfaceFormat::TopToBottom; } diff --git a/src/plugins/directshow/player/directshowmediatype.h b/src/plugins/directshow/player/directshowmediatype.h index 8d5e74f1f..5045ff600 100644 --- a/src/plugins/directshow/player/directshowmediatype.h +++ b/src/plugins/directshow/player/directshowmediatype.h @@ -34,9 +34,10 @@ #ifndef DIRECTSHOWMEDIATYPE_H #define DIRECTSHOWMEDIATYPE_H +#include + #include -#include #include class DirectShowMediaType : public AM_MEDIA_TYPE diff --git a/src/plugins/directshow/player/directshowmediatypelist.h b/src/plugins/directshow/player/directshowmediatypelist.h index 008293a1f..860334532 100644 --- a/src/plugins/directshow/player/directshowmediatypelist.h +++ b/src/plugins/directshow/player/directshowmediatypelist.h @@ -34,10 +34,10 @@ #ifndef DIRECTSHOWMEDIATYPELIST_H #define DIRECTSHOWMEDIATYPELIST_H -#include - #include +#include + class DirectShowMediaTypeList : public IUnknown { public: diff --git a/src/plugins/directshow/player/directshowmetadatacontrol.cpp b/src/plugins/directshow/player/directshowmetadatacontrol.cpp index 5400ac8d4..c30320128 100644 --- a/src/plugins/directshow/player/directshowmetadatacontrol.cpp +++ b/src/plugins/directshow/player/directshowmetadatacontrol.cpp @@ -31,13 +31,20 @@ ** ****************************************************************************/ +#include +#ifdef min +#undef min +#endif +#ifdef max +#undef max +#endif + #include #include #include #include #include -#include #include #include diff --git a/src/plugins/directshow/player/directshowmetadatacontrol.h b/src/plugins/directshow/player/directshowmetadatacontrol.h index 55504ba4b..fee305c1f 100644 --- a/src/plugins/directshow/player/directshowmetadatacontrol.h +++ b/src/plugins/directshow/player/directshowmetadatacontrol.h @@ -34,6 +34,8 @@ #ifndef DIRECTSHOWMETADATACONTROL_H #define DIRECTSHOWMETADATACONTROL_H +#include + #include #include "directshowglobal.h" diff --git a/src/plugins/directshow/player/directshowpinenum.h b/src/plugins/directshow/player/directshowpinenum.h index 3cc62e226..e3c5a4a67 100644 --- a/src/plugins/directshow/player/directshowpinenum.h +++ b/src/plugins/directshow/player/directshowpinenum.h @@ -34,9 +34,10 @@ #ifndef DIRECTSHOWPINENUM_H #define DIRECTSHOWPINENUM_H +#include + #include -#include class DirectShowPinEnum : public IEnumPins { diff --git a/src/plugins/directshow/player/directshowplayercontrol.cpp b/src/plugins/directshow/player/directshowplayercontrol.cpp index 3449c9270..ff3c9af52 100644 --- a/src/plugins/directshow/player/directshowplayercontrol.cpp +++ b/src/plugins/directshow/player/directshowplayercontrol.cpp @@ -31,6 +31,8 @@ ** ****************************************************************************/ +#include + #include "directshowplayercontrol.h" #include "directshowplayerservice.h" diff --git a/src/plugins/directshow/player/directshowplayercontrol.h b/src/plugins/directshow/player/directshowplayercontrol.h index f67c4108b..f1f387c51 100644 --- a/src/plugins/directshow/player/directshowplayercontrol.h +++ b/src/plugins/directshow/player/directshowplayercontrol.h @@ -34,6 +34,8 @@ #ifndef DIRECTSHOWPLAYERCONTROL_H #define DIRECTSHOWPLAYERCONTROL_H +#include + #include "qmediacontent.h" #include "qmediaplayercontrol.h" diff --git a/src/plugins/directshow/player/directshowplayerservice.cpp b/src/plugins/directshow/player/directshowplayerservice.cpp index 8e9e50cbf..73279accb 100644 --- a/src/plugins/directshow/player/directshowplayerservice.cpp +++ b/src/plugins/directshow/player/directshowplayerservice.cpp @@ -31,14 +31,25 @@ ** ****************************************************************************/ +#include +#ifdef min +#undef min +#endif +#ifdef max +#undef max +#endif + #include "directshowplayerservice.h" +#ifndef Q_OS_WINCE #include "directshowaudioendpointcontrol.h" -#include "directshowiosource.h" #include "directshowmetadatacontrol.h" +#include "vmr9videowindowcontrol.h" +#endif +#include "directshowiosource.h" #include "directshowplayercontrol.h" #include "directshowvideorenderercontrol.h" -#include "vmr9videowindowcontrol.h" + #ifdef HAVE_EVR #include "directshowevrvideowindowcontrol.h" @@ -79,10 +90,14 @@ 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) @@ -106,8 +121,10 @@ 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(); @@ -138,10 +155,14 @@ 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); } @@ -150,12 +171,18 @@ 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 && !m_videoWindowControl) { + if (!m_videoRendererControl +#ifndef Q_OS_WINCE + && !m_videoWindowControl +#endif + ){ m_videoRendererControl = new DirectShowVideoRendererControl(m_loop); connect(m_videoRendererControl, SIGNAL(filterChanged()), @@ -163,6 +190,7 @@ 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; @@ -185,6 +213,7 @@ QMediaControl *DirectShowPlayerService::requestControl(const char *name) return m_videoWindowControl; } +#endif } return 0; } @@ -200,12 +229,14 @@ 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 } } @@ -231,7 +262,9 @@ 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; @@ -1135,7 +1168,9 @@ 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 4d3762f74..f02f2039f 100644 --- a/src/plugins/directshow/player/directshowplayerservice.h +++ b/src/plugins/directshow/player/directshowplayerservice.h @@ -34,6 +34,8 @@ #ifndef DIRECTSHOWPLAYERSERVICE_H #define DIRECTSHOWPLAYERSERVICE_H +#include + #include "qmediaplayer.h" #include "qmediaresource.h" #include "qmediaservice.h" @@ -168,10 +170,14 @@ 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/directshowsamplescheduler.h b/src/plugins/directshow/player/directshowsamplescheduler.h index f9ef372ec..ad2df794c 100644 --- a/src/plugins/directshow/player/directshowsamplescheduler.h +++ b/src/plugins/directshow/player/directshowsamplescheduler.h @@ -34,12 +34,12 @@ #ifndef DIRECTSHOWSAMPLESCHEDULER_H #define DIRECTSHOWSAMPLESCHEDULER_H +#include + #include #include #include -#include - class DirectShowTimedSample; class DirectShowSampleScheduler : public QObject, public IMemInputPin diff --git a/src/plugins/directshow/player/directshowvideorenderercontrol.h b/src/plugins/directshow/player/directshowvideorenderercontrol.h index 484fda263..d08d124ca 100644 --- a/src/plugins/directshow/player/directshowvideorenderercontrol.h +++ b/src/plugins/directshow/player/directshowvideorenderercontrol.h @@ -34,10 +34,10 @@ #ifndef DIRECTSHOWVIDEORENDERERCONTROL_H #define DIRECTSHOWVIDEORENDERERCONTROL_H -#include "qvideorenderercontrol.h" - #include +#include "qvideorenderercontrol.h" + class DirectShowEventLoop; QT_USE_NAMESPACE diff --git a/src/plugins/directshow/player/mediasamplevideobuffer.h b/src/plugins/directshow/player/mediasamplevideobuffer.h index e38518571..60c4cb8b0 100644 --- a/src/plugins/directshow/player/mediasamplevideobuffer.h +++ b/src/plugins/directshow/player/mediasamplevideobuffer.h @@ -34,10 +34,10 @@ #ifndef MEDIASAMPLEVIDEOBUFFER_H #define MEDIASAMPLEVIDEOBUFFER_H -#include - #include +#include + class MediaSampleVideoBuffer : public QAbstractVideoBuffer { public: diff --git a/src/plugins/directshow/player/player.pri b/src/plugins/directshow/player/player.pri index 5ecb912b2..c5fb8442a 100644 --- a/src/plugins/directshow/player/player.pri +++ b/src/plugins/directshow/player/player.pri @@ -1,45 +1,53 @@ INCLUDEPATH += $$PWD -LIBS += -lstrmiids -ldmoguids -luuid -lmsdmo -lole32 -loleaut32 -lgdi32 +LIBS += -lstrmiids -ldmoguids -luuid -lole32 -loleaut32 +!wince: LIBS += -lmsdmo -lgdi32 + qtHaveModule(widgets): QT += widgets DEFINES += QMEDIA_DIRECTSHOW_PLAYER HEADERS += \ - $$PWD/directshowaudioendpointcontrol.h \ $$PWD/directshoweventloop.h \ $$PWD/directshowglobal.h \ $$PWD/directshowioreader.h \ $$PWD/directshowiosource.h \ $$PWD/directshowmediatype.h \ $$PWD/directshowmediatypelist.h \ - $$PWD/directshowmetadatacontrol.h \ $$PWD/directshowpinenum.h \ $$PWD/directshowplayercontrol.h \ $$PWD/directshowplayerservice.h \ $$PWD/directshowsamplescheduler.h \ $$PWD/directshowvideorenderercontrol.h \ $$PWD/mediasamplevideobuffer.h \ - $$PWD/videosurfacefilter.h \ - $$PWD/vmr9videowindowcontrol.h + $$PWD/videosurfacefilter.h SOURCES += \ - $$PWD/directshowaudioendpointcontrol.cpp \ $$PWD/directshoweventloop.cpp \ $$PWD/directshowioreader.cpp \ $$PWD/directshowiosource.cpp \ $$PWD/directshowmediatype.cpp \ $$PWD/directshowmediatypelist.cpp \ - $$PWD/directshowmetadatacontrol.cpp \ $$PWD/directshowpinenum.cpp \ $$PWD/directshowplayercontrol.cpp \ $$PWD/directshowplayerservice.cpp \ $$PWD/directshowsamplescheduler.cpp \ $$PWD/directshowvideorenderercontrol.cpp \ $$PWD/mediasamplevideobuffer.cpp \ - $$PWD/videosurfacefilter.cpp \ + $$PWD/videosurfacefilter.cpp + +!wince { +HEADERS += \ + $$PWD/directshowaudioendpointcontrol.h \ + $$PWD/directshowmetadatacontrol.h \ + $$PWD/vmr9videowindowcontrol.h + +SOURCES += \ + $$PWD/directshowaudioendpointcontrol.cpp \ + $$PWD/directshowmetadatacontrol.cpp \ $$PWD/vmr9videowindowcontrol.cpp +} config_evr { DEFINES += HAVE_EVR -- cgit v1.2.1 From 680cc0c97431de03487206fee575fa89c24b8842 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lisandro=20Dami=C3=A1n=20Nicanor=20P=C3=A9rez=20Meyer?= Date: Sat, 5 Mar 2016 10:36:42 -0300 Subject: ALSA: simplify checking the available version. Make use of SND_LIB_VERSION instead of SND_LIB_[MAJOR MINOR SUBMINOR] in order to simplify the tests. Task-number: QTBUG-51681 Change-Id: Ib9f28ff15ddc643cc426ded3a5779fb4ff651139 Reviewed-by: Dmitry Shachnev Reviewed-by: Christian Stromme Reviewed-by: Oswald Buddenhagen --- config.tests/alsa/alsatest.cpp | 2 +- src/plugins/alsa/qalsaaudiodeviceinfo.cpp | 8 ++++---- src/plugins/alsa/qalsaaudioinput.cpp | 4 ++-- src/plugins/alsa/qalsaaudiooutput.cpp | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/config.tests/alsa/alsatest.cpp b/config.tests/alsa/alsatest.cpp index 1b59cb17b..0b45819b6 100644 --- a/config.tests/alsa/alsatest.cpp +++ b/config.tests/alsa/alsatest.cpp @@ -32,7 +32,7 @@ ****************************************************************************/ #include -#if (!(SND_LIB_MAJOR == 1 && (SND_LIB_MINOR > 0 || SND_LIB_SUBMINOR >= 10))) +#if SND_LIB_VERSION < 0x1000a // 1.0.10 #error "Alsa version found too old, require >= 1.0.10" #endif diff --git a/src/plugins/alsa/qalsaaudiodeviceinfo.cpp b/src/plugins/alsa/qalsaaudiodeviceinfo.cpp index 3d310871f..31ad47ce8 100644 --- a/src/plugins/alsa/qalsaaudiodeviceinfo.cpp +++ b/src/plugins/alsa/qalsaaudiodeviceinfo.cpp @@ -141,7 +141,7 @@ bool QAlsaAudioDeviceInfo::open() QList devices = availableDevices(mode); if(dev.compare(QLatin1String("default")) == 0) { -#if (SND_LIB_MAJOR == 1 && (SND_LIB_MINOR > 0 || SND_LIB_SUBMINOR >= 14)) +#if SND_LIB_VERSION >= 0x1000e // 1.0.14 if (devices.size() > 0) dev = QLatin1String(devices.first().constData()); else @@ -150,7 +150,7 @@ bool QAlsaAudioDeviceInfo::open() dev = QLatin1String("hw:0,0"); #endif } else { -#if (SND_LIB_MAJOR == 1 && (SND_LIB_MINOR > 0 || SND_LIB_SUBMINOR >= 14)) +#if SND_LIB_VERSION >= 0x1000e // 1.0.14 dev = device; #else int idx = 0; @@ -194,7 +194,7 @@ bool QAlsaAudioDeviceInfo::testSettings(const QAudioFormat& format) const snd_pcm_hw_params_t *params; QString dev; -#if (SND_LIB_MAJOR == 1 && (SND_LIB_MINOR > 0 || SND_LIB_SUBMINOR >= 14)) +#if SND_LIB_VERSION >= 0x1000e // 1.0.14 dev = device; if (dev.compare(QLatin1String("default")) == 0) { QList devices = availableDevices(QAudio::AudioOutput); @@ -335,7 +335,7 @@ QList QAlsaAudioDeviceInfo::availableDevices(QAudio::Mode mode) QList devices; QByteArray filter; -#if (SND_LIB_MAJOR == 1 && (SND_LIB_MINOR > 0 || SND_LIB_SUBMINOR >= 14)) +#if SND_LIB_VERSION >= 0x1000e // 1.0.14 // Create a list of all current audio devices that support mode void **hints, **n; char *name, *descr, *io; diff --git a/src/plugins/alsa/qalsaaudioinput.cpp b/src/plugins/alsa/qalsaaudioinput.cpp index d6d8adcff..d9c775148 100644 --- a/src/plugins/alsa/qalsaaudioinput.cpp +++ b/src/plugins/alsa/qalsaaudioinput.cpp @@ -303,7 +303,7 @@ bool QAlsaAudioInput::open() QString dev = QString(QLatin1String(m_device.constData())); QList devices = QAlsaAudioDeviceInfo::availableDevices(QAudio::AudioInput); if(dev.compare(QLatin1String("default")) == 0) { -#if (SND_LIB_MAJOR == 1 && (SND_LIB_MINOR > 0 || SND_LIB_SUBMINOR >= 14)) +#if SND_LIB_VERSION >= 0x1000e // 1.0.14 if (devices.size() > 0) dev = QLatin1String(devices.first()); else @@ -312,7 +312,7 @@ bool QAlsaAudioInput::open() dev = QLatin1String("hw:0,0"); #endif } else { -#if (SND_LIB_MAJOR == 1 && (SND_LIB_MINOR > 0 || SND_LIB_SUBMINOR >= 14)) +#if SND_LIB_VERSION >= 0x1000e // 1.0.14 dev = QLatin1String(m_device); #else int idx = 0; diff --git a/src/plugins/alsa/qalsaaudiooutput.cpp b/src/plugins/alsa/qalsaaudiooutput.cpp index a382b666a..5702cfc78 100644 --- a/src/plugins/alsa/qalsaaudiooutput.cpp +++ b/src/plugins/alsa/qalsaaudiooutput.cpp @@ -306,7 +306,7 @@ bool QAlsaAudioOutput::open() QString dev = QString(QLatin1String(m_device.constData())); QList devices = QAlsaAudioDeviceInfo::availableDevices(QAudio::AudioOutput); if(dev.compare(QLatin1String("default")) == 0) { -#if (SND_LIB_MAJOR == 1 && (SND_LIB_MINOR > 0 || SND_LIB_SUBMINOR >= 14)) +#if SND_LIB_VERSION >= 0x1000e // 1.0.14 if (devices.size() > 0) dev = QLatin1String(devices.first()); else @@ -315,7 +315,7 @@ bool QAlsaAudioOutput::open() dev = QLatin1String("hw:0,0"); #endif } else { -#if (SND_LIB_MAJOR == 1 && (SND_LIB_MINOR > 0 || SND_LIB_SUBMINOR >= 14)) +#if SND_LIB_VERSION >= 0x1000e // 1.0.14 dev = QLatin1String(m_device); #else int idx = 0; -- cgit v1.2.1 From b0440668353f7b238e33142a060941d5c104b5d3 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Tue, 8 Mar 2016 10:15:57 +0100 Subject: Reinitialize audio when changing device in examples Different devices might have different audio formats supported. Always relying on the format of the default device can cause the audio endpoint to not start/initialize. Change-Id: I4d05949fd023f2cc7eb1f75db3577242e0e66680 Reviewed-by: Oliver Wolff --- examples/multimedia/audioinput/audioinput.cpp | 10 +++++----- examples/multimedia/audiooutput/audiooutput.cpp | 9 +++++---- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/examples/multimedia/audioinput/audioinput.cpp b/examples/multimedia/audioinput/audioinput.cpp index f3bf9f805..fd73d4f16 100644 --- a/examples/multimedia/audioinput/audioinput.cpp +++ b/examples/multimedia/audioinput/audioinput.cpp @@ -237,7 +237,7 @@ InputTest::InputTest() , m_audioInfo(0) , m_audioInput(0) , m_input(0) - , m_pullMode(false) + , m_pullMode(true) , m_buffer(BufferSize, 0) { initializeWindow(); @@ -291,8 +291,6 @@ void InputTest::initializeWindow() void InputTest::initializeAudio() { - m_pullMode = true; - m_format.setSampleRate(8000); m_format.setChannelCount(1); m_format.setSampleSize(16); @@ -300,12 +298,14 @@ void InputTest::initializeAudio() m_format.setByteOrder(QAudioFormat::LittleEndian); m_format.setCodec("audio/pcm"); - QAudioDeviceInfo info(QAudioDeviceInfo::defaultInputDevice()); + QAudioDeviceInfo info(m_device); if (!info.isFormatSupported(m_format)) { qWarning() << "Default format not supported - trying to use nearest"; m_format = info.nearestFormat(m_format); } + if (m_audioInfo) + delete m_audioInfo; m_audioInfo = new AudioInfo(m_format, this); connect(m_audioInfo, SIGNAL(update()), SLOT(refreshDisplay())); @@ -381,7 +381,7 @@ void InputTest::deviceChanged(int index) delete m_audioInput; m_device = m_deviceBox->itemData(index).value(); - createAudioInput(); + initializeAudio(); } void InputTest::sliderChanged(int value) diff --git a/examples/multimedia/audiooutput/audiooutput.cpp b/examples/multimedia/audiooutput/audiooutput.cpp index 9368a611e..a00ffbb00 100644 --- a/examples/multimedia/audiooutput/audiooutput.cpp +++ b/examples/multimedia/audiooutput/audiooutput.cpp @@ -167,6 +167,7 @@ AudioTest::AudioTest() , m_generator(0) , m_audioOutput(0) , m_output(0) + , m_pullMode(true) , m_buffer(BufferSize, 0) { initializeWindow(); @@ -222,8 +223,6 @@ void AudioTest::initializeAudio() { connect(m_pushTimer, SIGNAL(timeout()), SLOT(pushTimerExpired())); - m_pullMode = true; - m_format.setSampleRate(DataSampleRateHz); m_format.setChannelCount(1); m_format.setSampleSize(16); @@ -231,12 +230,14 @@ void AudioTest::initializeAudio() m_format.setByteOrder(QAudioFormat::LittleEndian); m_format.setSampleType(QAudioFormat::SignedInt); - QAudioDeviceInfo info(QAudioDeviceInfo::defaultOutputDevice()); + QAudioDeviceInfo info(m_device); if (!info.isFormatSupported(m_format)) { qWarning() << "Default format not supported - trying to use nearest"; m_format = info.nearestFormat(m_format); } + if (m_generator) + delete m_generator; m_generator = new Generator(m_format, DurationSeconds*1000000, ToneSampleRateHz, this); createAudioOutput(); @@ -264,7 +265,7 @@ void AudioTest::deviceChanged(int index) m_audioOutput->stop(); m_audioOutput->disconnect(this); m_device = m_deviceBox->itemData(index).value(); - createAudioOutput(); + initializeAudio(); } void AudioTest::volumeChanged(int value) -- cgit v1.2.1 From 399ec97f101f8bc4917139bf658bb08fd5316811 Mon Sep 17 00:00:00 2001 From: Yoann Lopes Date: Wed, 27 Jan 2016 17:07:52 +0100 Subject: Windows EVR: show frames when pausing from stopped state. The QAbstractVideoSurface was started only when calling play(), causing frames received before (e.g. when pausing from stopped state) to not be rendered. The surface is now started as soon as a media type is agreed between the EVR and the upstream element. Conversely, the surface is stopped whenever the media type is cleared. Change-Id: Ia96a07dbd277adce67de5a9cfbf9acc0d33b6497 Reviewed-by: Christian Stromme --- src/plugins/common/evr/evrcustompresenter.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/plugins/common/evr/evrcustompresenter.cpp b/src/plugins/common/evr/evrcustompresenter.cpp index 3afd2342f..49623e891 100644 --- a/src/plugins/common/evr/evrcustompresenter.cpp +++ b/src/plugins/common/evr/evrcustompresenter.cpp @@ -842,8 +842,6 @@ HRESULT EVRCustomPresenter::OnClockStart(MFTIME, LONGLONG clockStartOffset) return hr; } - startSurface(); - // Now try to get new output samples from the mixer. processOutputLoop(); @@ -891,8 +889,6 @@ HRESULT EVRCustomPresenter::OnClockStop(MFTIME) cancelFrameStep(); } - stopSurface(); - return S_OK; } @@ -1400,6 +1396,7 @@ HRESULT EVRCustomPresenter::setMediaType(IMFMediaType *mediaType) // Clearing the media type is allowed in any state (including shutdown). if (!mediaType) { + stopSurface(); qt_evr_safe_release(&m_mediaType); releaseResources(); return S_OK; @@ -1460,6 +1457,8 @@ HRESULT EVRCustomPresenter::setMediaType(IMFMediaType *mediaType) m_mediaType = mediaType; m_mediaType->AddRef(); + startSurface(); + done: if (FAILED(hr)) releaseResources(); -- cgit v1.2.1 From b17e0cd5dd28b93b1ea567c676f0e183acb6dd7c Mon Sep 17 00:00:00 2001 From: Yoann Lopes Date: Fri, 5 Feb 2016 14:07:20 +0100 Subject: PulseAudio: change the way volume is applied. We used to change the PulseAudio sink input volume. Doing so had some potential unwanted side effects depending on the PulseAudio server configuration. When flat volumes were enabled, it would affect the global system volume. It could also affect the volume of other streams having the same audio role. Volumes in Qt Multimedia are supposed to be relative to the application volume and should not affect anything else than the object on which it was changed. To guarantee that, PulseAudio volume APIs are not used anymore. Instead, software-based volume attenuation is applied on the audio samples before being passed to PulseAudio. Applies to QSoundEffect, QAudioOutput and QAudioInput. Task-number: QTBUG-40823 Task-number: QTBUG-49461 Change-Id: I690716976bda8fe666969ca2cbdf6d8d0b419733 Reviewed-by: Christian Stromme --- src/multimedia/audio/qsoundeffect_pulse_p.cpp | 214 +++++++------------------- src/multimedia/audio/qsoundeffect_pulse_p.h | 13 +- src/plugins/pulseaudio/qaudioinput_pulse.cpp | 99 +++--------- src/plugins/pulseaudio/qaudioinput_pulse.h | 8 +- src/plugins/pulseaudio/qaudiooutput_pulse.cpp | 84 ++++------ src/plugins/pulseaudio/qaudiooutput_pulse.h | 2 - 6 files changed, 113 insertions(+), 307 deletions(-) diff --git a/src/multimedia/audio/qsoundeffect_pulse_p.cpp b/src/multimedia/audio/qsoundeffect_pulse_p.cpp index ecc42cac5..43d4a6cb0 100644 --- a/src/multimedia/audio/qsoundeffect_pulse_p.cpp +++ b/src/multimedia/audio/qsoundeffect_pulse_p.cpp @@ -49,10 +49,7 @@ #include "qsoundeffect_pulse_p.h" -#if defined(Q_WS_MAEMO_6) || defined(NEMO_AUDIO) -#include -#endif - +#include #include #include @@ -124,26 +121,9 @@ public: return m_context; } - inline pa_cvolume * calcVolume(pa_cvolume *dest, int soundEffectVolume) - { - pa_volume_t v = m_vol * soundEffectVolume / 100; - for (int i = 0; i < dest->channels; ++i) - dest->values[i] = v; - return dest; - } - - void updateStatus(const pa_cvolume& volume) - { - if (m_vol != pa_cvolume_max(&volume)) { - m_vol = pa_cvolume_max(&volume); - emit volumeChanged(); - } - } - Q_SIGNALS: void contextReady(); void contextFailed(); - void volumeChanged(); private Q_SLOTS: void onContextFailed() @@ -158,8 +138,6 @@ private Q_SLOTS: void prepare() { - m_vol = PA_VOLUME_NORM; - m_context = 0; m_mainLoop = pa_threaded_mainloop_new(); if (m_mainLoop == 0) { @@ -232,11 +210,6 @@ private: case PA_CONTEXT_SETTING_NAME: break; case PA_CONTEXT_READY: - #if defined(Q_WS_MAEMO_6) || defined(NEMO_AUDIO) - pa_ext_stream_restore_read(c, &stream_restore_info_callback, self); - pa_ext_stream_restore_set_subscribe_cb(c, &stream_restore_monitor_callback, self); - pa_ext_stream_restore_subscribe(c, 1, 0, self); - #endif QMetaObject::invokeMethod(self, "contextReady", Qt::QueuedConnection); break; case PA_CONTEXT_FAILED: @@ -247,37 +220,6 @@ private: } } -#if defined(Q_WS_MAEMO_6) || defined(NEMO_AUDIO) - - static void stream_restore_monitor_callback(pa_context *c, void *userdata) - { - PulseDaemon *self = reinterpret_cast(userdata); - pa_ext_stream_restore_read(c, &stream_restore_info_callback, self); - } - - static void stream_restore_info_callback(pa_context *c, - const pa_ext_stream_restore_info *info, - int eol, void *userdata) - { - Q_UNUSED(c) - - PulseDaemon *self = reinterpret_cast(userdata); - - if (!eol) { - if (QString(info->name).startsWith(QLatin1String("sink-input-by-media-role:x-maemo"))) { -#ifdef QT_PA_DEBUG - qDebug() << "x-maemo volume =(" << info->volume.values[0] * 100 / PA_VOLUME_NORM << "," - << info->volume.values[1] * 100 / PA_VOLUME_NORM << "), " - << "mute = " << info->mute; -#endif - self->updateStatus(info->volume); - } - } - } -#endif - - pa_volume_t m_vol; - bool m_prepared; pa_context *m_context; pa_threaded_mainloop *m_mainLoop; @@ -385,9 +327,6 @@ QSoundEffectPrivate::QSoundEffectPrivate(QObject* parent): m_sample(0), m_position(0), m_resourcesAvailable(false) -#if defined(Q_WS_MAEMO_6) || defined(NEMO_AUDIO) - , m_customVolume(false) -#endif { m_ref = new QSoundEffectRef(this); pa_sample_spec_init(&m_pulseSpec); @@ -538,60 +477,32 @@ void QSoundEffectPrivate::setLoopCount(int loopCount) qreal QSoundEffectPrivate::volume() const { + QReadLocker locker(&m_volumeLock); return m_volume; } void QSoundEffectPrivate::setVolume(qreal volume) { -#if defined(Q_WS_MAEMO_6) || defined(NEMO_AUDIO) - m_customVolume = true; -#endif - m_volume = volume; - emit volumeChanged(); - updateVolume(); -} + QWriteLocker locker(&m_volumeLock); -void QSoundEffectPrivate::updateVolume() -{ - if (m_sinkInputId < 0) + if (qFuzzyCompare(m_volume, volume)) return; -#if defined(Q_WS_MAEMO_6) || defined(NEMO_AUDIO) - if (!m_customVolume) - return; -#endif - PulseDaemonLocker locker; - pa_cvolume volume; - volume.channels = m_pulseSpec.channels; - if (pulseDaemon()->context()) - pa_operation_unref(pa_context_set_sink_input_volume(pulseDaemon()->context(), m_sinkInputId, pulseDaemon()->calcVolume(&volume, qRound(m_volume * 100)), setvolume_callback, m_ref->getRef())); - Q_ASSERT(pa_cvolume_valid(&volume)); -#ifdef QT_PA_DEBUG - qDebug() << this << "updateVolume =" << pa_cvolume_max(&volume); -#endif + + m_volume = qBound(qreal(0), volume, qreal(1)); + emit volumeChanged(); } bool QSoundEffectPrivate::isMuted() const { + QReadLocker locker(&m_volumeLock); return m_muted; } void QSoundEffectPrivate::setMuted(bool muted) { + QWriteLocker locker(&m_volumeLock); m_muted = muted; emit mutedChanged(); - updateMuted(); -} - -void QSoundEffectPrivate::updateMuted() -{ - if (m_sinkInputId < 0) - return; - PulseDaemonLocker locker; - if (pulseDaemon()->context()) - pa_operation_unref(pa_context_set_sink_input_mute(pulseDaemon()->context(), m_sinkInputId, m_muted, setmuted_callback, m_ref->getRef())); -#ifdef QT_PA_DEBUG - qDebug() << this << "updateMuted = " << m_muted; -#endif } bool QSoundEffectPrivate::isLoaded() const @@ -801,7 +712,6 @@ void QSoundEffectPrivate::unloadPulseStream() pa_stream_set_underflow_callback(m_pulseStream, 0, 0); pa_stream_disconnect(m_pulseStream); pa_stream_unref(m_pulseStream); - disconnect(pulseDaemon(), SIGNAL(volumeChanged()), this, SLOT(updateVolume())); disconnect(pulseDaemon(), SIGNAL(contextFailed()), this, SLOT(contextFailed())); m_pulseStream = 0; m_reloadCategory = false; // category will be reloaded when we connect anyway @@ -822,11 +732,8 @@ void QSoundEffectPrivate::prepare() << "actual writeBytes =" << writeBytes << "m_playQueued =" << m_playQueued; #endif - m_position = int(writeBytes); - if (pa_stream_write(m_pulseStream, reinterpret_cast(const_cast(m_sample->data().data())), writeBytes, - stream_write_done_callback, 0, PA_SEEK_RELATIVE) != 0) { - qWarning("QSoundEffect(pulseaudio): pa_stream_write, error = %s", pa_strerror(pa_context_errno(pulseDaemon()->context()))); - } + m_position = writeToStream(m_sample->data().data(), writeBytes); + if (m_playQueued) { m_playQueued = false; setLoopsRemaining(m_loopCount); @@ -854,15 +761,13 @@ void QSoundEffectPrivate::uploadSample() } } - int writtenBytes = 0; int writableSize = int(pa_stream_writable_size(m_pulseStream)); int firstPartLength = qMin(m_sample->data().size() - m_position, writableSize); - if (pa_stream_write(m_pulseStream, reinterpret_cast(const_cast(m_sample->data().data()) + m_position), - firstPartLength, stream_write_done_callback, 0, PA_SEEK_RELATIVE) != 0) { - qWarning("QSoundEffect(pulseaudio): pa_stream_write, error = %s", pa_strerror(pa_context_errno(pulseDaemon()->context()))); - } - writtenBytes = firstPartLength; - m_position += firstPartLength; + + int writtenBytes = writeToStream(m_sample->data().data() + m_position, + firstPartLength); + + m_position += writtenBytes; if (m_position == m_sample->data().size()) { m_position = 0; if (m_runningCount > 0) @@ -871,11 +776,8 @@ void QSoundEffectPrivate::uploadSample() { while (writtenBytes < writableSize) { int writeSize = qMin(writableSize - writtenBytes, m_sample->data().size()); - if (pa_stream_write(m_pulseStream, reinterpret_cast(const_cast(m_sample->data().data())), - writeSize, stream_write_done_callback, 0, PA_SEEK_RELATIVE) != 0) { - qWarning("QSoundEffect(pulseaudio): pa_stream_write, error = %s", pa_strerror(pa_context_errno(pulseDaemon()->context()))); - } - writtenBytes += writeSize; + writtenBytes += writeToStream(m_sample->data().data(), writeSize); + if (writeSize < m_sample->data().size()) { m_position = writeSize; break; @@ -893,6 +795,39 @@ void QSoundEffectPrivate::uploadSample() #endif } +int QSoundEffectPrivate::writeToStream(const void *data, int size) +{ + m_volumeLock.lockForRead(); + qreal volume = m_muted ? 0 : m_volume; + m_volumeLock.unlock(); + pa_free_cb_t writeDoneCb = stream_write_done_callback; + + if (volume < 1.0f) { + // Don't use PulseAudio volume, as it might affect all other streams of the same category + // or even affect the system volume if flat volumes are enabled + void *dest = NULL; + size_t nbytes = size; + if (pa_stream_begin_write(m_pulseStream, &dest, &nbytes) < 0) { + qWarning("QSoundEffect(pulseaudio): pa_stream_begin_write, error = %s", + pa_strerror(pa_context_errno(pulseDaemon()->context()))); + return 0; + } + + size = int(nbytes); + QAudioHelperInternal::qMultiplySamples(volume, m_sample->format(), data, dest, size); + data = dest; + writeDoneCb = NULL; + } + + if (pa_stream_write(m_pulseStream, data, size, writeDoneCb, 0, PA_SEEK_RELATIVE) < 0) { + qWarning("QSoundEffect(pulseaudio): pa_stream_write, error = %s", + pa_strerror(pa_context_errno(pulseDaemon()->context()))); + return 0; + } + + return size; +} + void QSoundEffectPrivate::playSample() { #ifdef QT_PA_DEBUG @@ -939,8 +874,6 @@ void QSoundEffectPrivate::streamReady() #endif PulseDaemonLocker locker; m_sinkInputId = pa_stream_get_index(m_pulseStream); - updateMuted(); - updateVolume(); #ifdef QT_PA_DEBUG const pa_buffer_attr *realBufAttr = pa_stream_get_buffer_attr(m_pulseStream); qDebug() << this << "m_sinkInputId =" << m_sinkInputId @@ -966,7 +899,6 @@ void QSoundEffectPrivate::createPulseStream() pa_stream *stream = pa_stream_new_with_proplist(pulseDaemon()->context(), m_name.constData(), &m_pulseSpec, 0, propList); pa_proplist_free(propList); - connect(pulseDaemon(), SIGNAL(volumeChanged()), this, SLOT(updateVolume())); connect(pulseDaemon(), SIGNAL(contextFailed()), this, SLOT(contextFailed())); if (stream == 0) { @@ -994,9 +926,7 @@ void QSoundEffectPrivate::createPulseStream() #else if (pa_stream_connect_playback(m_pulseStream, 0, 0, #endif - m_muted ? pa_stream_flags_t(PA_STREAM_START_MUTED | PA_STREAM_START_CORKED) - : pa_stream_flags_t(PA_STREAM_START_UNMUTED | PA_STREAM_START_CORKED), - 0, 0) < 0) { + PA_STREAM_START_CORKED, 0, 0) < 0) { qWarning("QSoundEffect(pulseaudio): Failed to connect stream, error = %s", pa_strerror(pa_context_errno(pulseDaemon()->context()))); } @@ -1115,46 +1045,6 @@ void QSoundEffectPrivate::stream_adjust_prebuffer_callback(pa_stream *s, int suc QMetaObject::invokeMethod(self, "streamReady", Qt::QueuedConnection); } -void QSoundEffectPrivate::setvolume_callback(pa_context *c, int success, void *userdata) -{ -#ifdef QT_PA_DEBUG - qDebug() << "setvolume_callback"; -#endif - Q_UNUSED(c); - Q_UNUSED(userdata); - QSoundEffectRef *ref = reinterpret_cast(userdata); - QSoundEffectPrivate *self = ref->soundEffect(); - ref->release(); - if (!self) - return; -#ifdef QT_PA_DEBUG - qDebug() << self << "setvolume_callback"; -#endif - if (!success) { - qWarning("QSoundEffect(pulseaudio): faild to set volume"); - } -} - -void QSoundEffectPrivate::setmuted_callback(pa_context *c, int success, void *userdata) -{ -#ifdef QT_PA_DEBUG - qDebug() << "setmuted_callback"; -#endif - Q_UNUSED(c); - Q_UNUSED(userdata); - QSoundEffectRef *ref = reinterpret_cast(userdata); - QSoundEffectPrivate *self = ref->soundEffect(); - ref->release(); - if (!self) - return; -#ifdef QT_PA_DEBUG - qDebug() << self << "setmuted_callback"; -#endif - if (!success) { - qWarning("QSoundEffect(pulseaudio): faild to set muted"); - } -} - void QSoundEffectPrivate::stream_underrun_callback(pa_stream *s, void *userdata) { Q_UNUSED(s); diff --git a/src/multimedia/audio/qsoundeffect_pulse_p.h b/src/multimedia/audio/qsoundeffect_pulse_p.h index 9b3564cc9..0f16b98a2 100644 --- a/src/multimedia/audio/qsoundeffect_pulse_p.h +++ b/src/multimedia/audio/qsoundeffect_pulse_p.h @@ -50,6 +50,7 @@ #include #include +#include #include #include #include "qsamplecache_p.h" @@ -111,8 +112,6 @@ private Q_SLOTS: void prepare(); void streamReady(); void emptyComplete(void *stream); - void updateVolume(); - void updateMuted(); void handleAvailabilityChanged(bool available); @@ -124,6 +123,8 @@ private: void createPulseStream(); void unloadPulseStream(); + int writeToStream(const void *data, int size); + void setPlaying(bool playing); void setStatus(QSoundEffect::Status status); void setLoopsRemaining(int loopsRemaining); @@ -136,8 +137,6 @@ private: static void stream_write_done_callback(void *p); static void stream_adjust_prebuffer_callback(pa_stream *s, int success, void *userdata); static void stream_reset_buffer_callback(pa_stream *s, int success, void *userdata); - static void setvolume_callback(pa_context *c, int success, void *userdata); - static void setmuted_callback(pa_context *c, int success, void *userdata); pa_stream *m_pulseStream; int m_sinkInputId; @@ -165,11 +164,9 @@ private: bool m_resourcesAvailable; - QMediaPlayerResourceSetInterface *m_resources; + mutable QReadWriteLock m_volumeLock; -#if defined(Q_WS_MAEMO_6) || defined(NEMO_AUDIO) - bool m_customVolume; -#endif + QMediaPlayerResourceSetInterface *m_resources; }; QT_END_NAMESPACE diff --git a/src/plugins/pulseaudio/qaudioinput_pulse.cpp b/src/plugins/pulseaudio/qaudioinput_pulse.cpp index 77b438ff9..93d410598 100644 --- a/src/plugins/pulseaudio/qaudioinput_pulse.cpp +++ b/src/plugins/pulseaudio/qaudioinput_pulse.cpp @@ -34,6 +34,7 @@ #include #include #include +#include #include "qaudioinput_pulse.h" #include "qaudiodeviceinfo_pulse.h" @@ -118,39 +119,12 @@ static void inputStreamSuccessCallback(pa_stream *stream, int success, void *use pa_threaded_mainloop_signal(pulseEngine->mainloop(), 0); } -void QPulseAudioInput::sourceInfoCallback(pa_context *context, const pa_source_info *i, int eol, void *userdata) -{ - Q_UNUSED(context); - Q_UNUSED(eol); - - Q_ASSERT(userdata); - if (i) { - QPulseAudioInput *that = reinterpret_cast(userdata); - that->m_volume = pa_sw_volume_to_linear(pa_cvolume_avg(&i->volume)); - } -} - -void QPulseAudioInput::inputVolumeCallback(pa_context *context, int success, void *userdata) -{ - Q_UNUSED(success); - - if (!success) - qWarning() << "QAudioInput: failed to set input volume"; - - QPulseAudioInput *that = reinterpret_cast(userdata); - - // Regardless of success or failure, we update the volume property - if (that->m_stream) - pa_context_get_source_info_by_index(context, pa_stream_get_device_index(that->m_stream), sourceInfoCallback, userdata); -} - QPulseAudioInput::QPulseAudioInput(const QByteArray &device) : m_totalTimeValue(0) , m_audioSource(0) , m_errorState(QAudio::NoError) , m_deviceState(QAudio::StoppedState) , m_volume(qreal(1.0f)) - , m_customVolumeRequired(false) , m_pullMode(true) , m_opened(false) , m_bytesAvailable(0) @@ -356,9 +330,6 @@ bool QPulseAudioInput::open() if (actualBufferAttr->tlength != (uint32_t)-1) m_bufferSize = actualBufferAttr->tlength; - if (m_customVolumeRequired) - setPulseVolume(); - pulseEngine->unlock(); connect(pulseEngine, &QPulseAudioEngine::contextFailed, this, &QPulseAudioInput::onPulseContextFailed); @@ -407,32 +378,6 @@ void QPulseAudioInput::close() m_opened = false; } -/* Call this with the stream opened and the mainloop locked */ -void QPulseAudioInput::setPulseVolume() -{ - QPulseAudioEngine *pulseEngine = QPulseAudioEngine::instance(); - Q_ASSERT(pulseEngine->context() != 0); - - pa_cvolume cvolume; - - if (qFuzzyCompare(m_volume, 0.0)) { - pa_cvolume_mute(&cvolume, m_spec.channels); - } else { - pa_cvolume_set(&cvolume, m_spec.channels, pa_sw_volume_from_linear(m_volume)); - } - - pa_operation *op = pa_context_set_source_volume_by_index(pulseEngine->context(), - pa_stream_get_device_index(m_stream), - &cvolume, - inputVolumeCallback, - this); - - if (op == NULL) - qWarning() << "QAudioInput: Failed to set volume"; - else - pa_operation_unref(op); -} - int QPulseAudioInput::checkBytesReady() { if (m_deviceState != QAudio::ActiveState && m_deviceState != QAudio::IdleState) { @@ -494,7 +439,9 @@ qint64 QPulseAudioInput::read(char *data, qint64 len) qint64 actualLength = 0; if (m_pullMode) { - actualLength = m_audioSource->write(static_cast(audioBuffer), readLength); + QByteArray adjusted(readLength, Qt::Uninitialized); + applyVolume(audioBuffer, adjusted.data(), readLength); + actualLength = m_audioSource->write(adjusted); if (actualLength < qint64(readLength)) { pulseEngine->unlock(); @@ -506,7 +453,7 @@ qint64 QPulseAudioInput::read(char *data, qint64 len) } } else { actualLength = qMin(static_cast(len - readBytes), static_cast(readLength)); - memcpy(data + readBytes, audioBuffer, actualLength); + applyVolume(audioBuffer, data + readBytes, actualLength); } #ifdef DEBUG_PULSE @@ -517,7 +464,10 @@ qint64 QPulseAudioInput::read(char *data, qint64 len) #ifdef DEBUG_PULSE qDebug() << "QPulseAudioInput::read -- appending " << readLength - actualLength << " bytes of data to temp buffer"; #endif - m_tempBuffer.append(static_cast(audioBuffer) + actualLength, readLength - actualLength); + int diff = readLength - actualLength; + int oldSize = m_tempBuffer.size(); + m_tempBuffer.resize(m_tempBuffer.size() + diff); + applyVolume(static_cast(audioBuffer) + actualLength, m_tempBuffer.data() + oldSize, diff); QMetaObject::invokeMethod(this, "userFeed", Qt::QueuedConnection); } @@ -544,6 +494,14 @@ qint64 QPulseAudioInput::read(char *data, qint64 len) return readBytes; } +void QPulseAudioInput::applyVolume(const void *src, void *dest, int len) +{ + if (m_volume < 1.f) + QAudioHelperInternal::qMultiplySamples(m_volume, m_format, src, dest, len); + else + memcpy(dest, src, len); +} + void QPulseAudioInput::resume() { if (m_deviceState == QAudio::SuspendedState || m_deviceState == QAudio::IdleState) { @@ -567,30 +525,17 @@ void QPulseAudioInput::resume() void QPulseAudioInput::setVolume(qreal vol) { - if (vol >= 0.0 && vol <= 1.0) { - QPulseAudioEngine *pulseEngine = QPulseAudioEngine::instance(); - pulseEngine->lock(); - m_customVolumeRequired = true; - if (!qFuzzyCompare(m_volume, vol)) { - m_volume = vol; - if (m_opened) { - setPulseVolume(); - } - } - pulseEngine->unlock(); - } + if (qFuzzyCompare(m_volume, vol)) + return; + + m_volume = qBound(qreal(0), vol, qreal(1)); } qreal QPulseAudioInput::volume() const { - QPulseAudioEngine *pulseEngine = QPulseAudioEngine::instance(); - pulseEngine->lock(); - qreal vol = m_volume; - pulseEngine->unlock(); - return vol; + return m_volume; } - void QPulseAudioInput::setBufferSize(int value) { m_bufferSize = value; diff --git a/src/plugins/pulseaudio/qaudioinput_pulse.h b/src/plugins/pulseaudio/qaudioinput_pulse.h index 7b898c480..c130f8cac 100644 --- a/src/plugins/pulseaudio/qaudioinput_pulse.h +++ b/src/plugins/pulseaudio/qaudioinput_pulse.h @@ -100,8 +100,6 @@ public: QAudio::Error m_errorState; QAudio::State m_deviceState; qreal m_volume; - bool m_customVolumeRequired; - pa_cvolume m_chVolume; private slots: void userFeed(); @@ -112,13 +110,11 @@ private: void setState(QAudio::State state); void setError(QAudio::Error error); + void applyVolume(const void *src, void *dest, int len); + int checkBytesReady(); bool open(); void close(); - void setPulseVolume(); - - static void sourceInfoCallback(pa_context *c, const pa_source_info *i, int eol, void *userdata); - static void inputVolumeCallback(pa_context *context, int success, void *userdata); bool m_pullMode; bool m_opened; diff --git a/src/plugins/pulseaudio/qaudiooutput_pulse.cpp b/src/plugins/pulseaudio/qaudiooutput_pulse.cpp index c1d46fac4..a850c9b0e 100644 --- a/src/plugins/pulseaudio/qaudiooutput_pulse.cpp +++ b/src/plugins/pulseaudio/qaudiooutput_pulse.cpp @@ -34,6 +34,7 @@ #include #include #include +#include #include "qaudiooutput_pulse.h" #include "qaudiodeviceinfo_pulse.h" @@ -162,7 +163,6 @@ QPulseAudioOutput::QPulseAudioOutput(const QByteArray &device) , m_audioBuffer(0) , m_resuming(false) , m_volume(1.0) - , m_customVolumeRequired(false) { connect(m_tickTimer, SIGNAL(timeout()), SLOT(userFeed())); } @@ -312,27 +312,6 @@ bool QPulseAudioOutput::open() pa_stream_set_overflow_callback(m_stream, outputStreamOverflowCallback, this); pa_stream_set_latency_update_callback(m_stream, outputStreamLatencyCallback, this); - pa_volume_t paVolume; - - /* streams without a custom volume set are expected to already have a - * sensible volume set by Pulse, so we don't set it explicitly. - * - * explicit setting also breaks volume handling on sailfish, where each - * stream's volume is set separately inside pulseaudio, with the - * exception of streams that already have a volume set (i.e. if we set - * it here, we'd ignore system volume). - */ - if (m_customVolumeRequired) { - if (qFuzzyCompare(m_volume, 0.0)) { - paVolume = PA_VOLUME_MUTED; - m_volume = 0.0; - } else { - paVolume = qFloor(m_volume * PA_VOLUME_NORM + 0.5); - } - - pa_cvolume_set(&m_chVolume, m_spec.channels, paVolume); - } - if (m_bufferSize <= 0 && m_category == LOW_LATENCY_CATEGORY_NAME) { m_bufferSize = bytesPerSecond * LowLatencyBufferSizeMs / qint64(1000); } @@ -344,7 +323,7 @@ bool QPulseAudioOutput::open() requestedBuffer.prebuf = (uint32_t)-1; requestedBuffer.tlength = m_bufferSize; - if (pa_stream_connect_playback(m_stream, m_device.data(), (m_bufferSize > 0) ? &requestedBuffer : NULL, (pa_stream_flags_t)0, m_customVolumeRequired ? &m_chVolume : NULL, NULL) < 0) { + if (pa_stream_connect_playback(m_stream, m_device.data(), (m_bufferSize > 0) ? &requestedBuffer : NULL, (pa_stream_flags_t)0, NULL, NULL) < 0) { qWarning() << "pa_stream_connect_playback() failed!"; pa_stream_unref(m_stream); m_stream = 0; @@ -491,8 +470,33 @@ qint64 QPulseAudioOutput::write(const char *data, qint64 len) QPulseAudioEngine *pulseEngine = QPulseAudioEngine::instance(); pulseEngine->lock(); + len = qMin(len, static_cast(pa_stream_writable_size(m_stream))); - pa_stream_write(m_stream, data, len, 0, 0, PA_SEEK_RELATIVE); + + if (m_volume < 1.0f) { + // Don't use PulseAudio volume, as it might affect all other streams of the same category + // or even affect the system volume if flat volumes are enabled + void *dest = NULL; + size_t nbytes = len; + if (pa_stream_begin_write(m_stream, &dest, &nbytes) < 0) { + qWarning("QAudioOutput(pulseaudio): pa_stream_begin_write, error = %s", + pa_strerror(pa_context_errno(pulseEngine->context()))); + setError(QAudio::IOError); + return 0; + } + + len = int(nbytes); + QAudioHelperInternal::qMultiplySamples(m_volume, m_format, data, dest, len); + data = reinterpret_cast(dest); + } + + if (pa_stream_write(m_stream, data, len, NULL, 0, PA_SEEK_RELATIVE) < 0) { + qWarning("QAudioOutput(pulseaudio): pa_stream_write, error = %s", + pa_strerror(pa_context_errno(pulseEngine->context()))); + setError(QAudio::IOError); + return 0; + } + pulseEngine->unlock(); m_totalTimeValue += len; @@ -664,34 +668,10 @@ qint64 PulseOutputPrivate::writeData(const char *data, qint64 len) void QPulseAudioOutput::setVolume(qreal vol) { - if (vol >= 0.0 && vol <= 1.0) { - if (!qFuzzyCompare(m_volume, vol)) { - m_customVolumeRequired = true; - m_volume = vol; - if (m_opened) { - QPulseAudioEngine *pulseEngine = QPulseAudioEngine::instance(); - pulseEngine->lock(); - pa_volume_t paVolume; - if (qFuzzyCompare(vol, 0.0)) { - pa_cvolume_mute(&m_chVolume, m_spec.channels); - m_volume = 0.0; - } else { - paVolume = qFloor(m_volume * PA_VOLUME_NORM + 0.5); - pa_cvolume_set(&m_chVolume, m_spec.channels, paVolume); - } - pa_operation *op = pa_context_set_sink_input_volume(pulseEngine->context(), - pa_stream_get_index(m_stream), - &m_chVolume, - NULL, - NULL); - if (op == NULL) - qWarning()<<"QAudioOutput: Failed to set volume"; - else - pa_operation_unref(op); - pulseEngine->unlock(); - } - } - } + if (qFuzzyCompare(m_volume, vol)) + return; + + m_volume = qBound(qreal(0), vol, qreal(1)); } qreal QPulseAudioOutput::volume() const diff --git a/src/plugins/pulseaudio/qaudiooutput_pulse.h b/src/plugins/pulseaudio/qaudiooutput_pulse.h index e24fd514b..a165da86a 100644 --- a/src/plugins/pulseaudio/qaudiooutput_pulse.h +++ b/src/plugins/pulseaudio/qaudiooutput_pulse.h @@ -135,8 +135,6 @@ private: QString m_category; qreal m_volume; - bool m_customVolumeRequired; - pa_cvolume m_chVolume; pa_sample_spec m_spec; }; -- cgit v1.2.1 From caf0cbca71231dbb6403108ba41d2117d3ce6c6d Mon Sep 17 00:00:00 2001 From: BogDan Vatra Date: Thu, 17 Mar 2016 15:50:52 +0200 Subject: Android: Use default API version (16) Change-Id: I379a4708b2d79824ee6266471e7aec983b87cd68 Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/plugins/android/jar/jar.pri | 1 - 1 file changed, 1 deletion(-) diff --git a/src/plugins/android/jar/jar.pri b/src/plugins/android/jar/jar.pri index 713123baf..5408fb109 100644 --- a/src/plugins/android/jar/jar.pri +++ b/src/plugins/android/jar/jar.pri @@ -1,7 +1,6 @@ load(qt_build_paths) CONFIG += java DESTDIR = $$MODULE_BASE_OUTDIR/jar -API_VERSION = android-11 JAVACLASSPATH += $$PWD/src -- cgit v1.2.1 From bf899dbf4d541bb85e292208a1e97ed3ae95d19e Mon Sep 17 00:00:00 2001 From: Mark Brand Date: Wed, 16 Mar 2016 15:18:00 +0100 Subject: fix case of included files Cross-compiling for mingw requires lowercase filenames. Change-Id: I135deca455ca2ff6bb3969aca990fe9d1c2dd345 Reviewed-by: Oswald Buddenhagen Reviewed-by: Friedemann Kleint Reviewed-by: Mark Brand --- src/plugins/common/evr/evrdefs.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/common/evr/evrdefs.h b/src/plugins/common/evr/evrdefs.h index 3b2c2530a..7b1af0593 100644 --- a/src/plugins/common/evr/evrdefs.h +++ b/src/plugins/common/evr/evrdefs.h @@ -35,12 +35,12 @@ #define EVRDEFS_H #include -#include +#include #include #include #include #include -#include +#include extern const CLSID clsid_EnhancedVideoRenderer; extern const GUID mr_VIDEO_RENDER_SERVICE; -- cgit v1.2.1 From d48fbf286b6ae88218286d35493cd5416a7713a9 Mon Sep 17 00:00:00 2001 From: Dan Cape Date: Mon, 29 Feb 2016 15:26:12 -0500 Subject: QNX: Fixed issue with non Qt-related mm-renderer windows Windowgrabber would catch events from windows that were not related to Qt Media Playback. Now there is a check to ensure the window id to compare against is set before assigning the window to the Windowgrabber. Change-Id: Ic85198de5fdb05e9fa740fc7b3b81f3bdffd631d Reviewed-by: Marc Mutz Reviewed-by: James McDonnell Reviewed-by: Rafael Roquetto --- src/plugins/qnx/common/windowgrabber.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/plugins/qnx/common/windowgrabber.cpp b/src/plugins/qnx/common/windowgrabber.cpp index 51ce0dbf4..c16e38206 100644 --- a/src/plugins/qnx/common/windowgrabber.cpp +++ b/src/plugins/qnx/common/windowgrabber.cpp @@ -276,7 +276,8 @@ bool WindowGrabber::handleScreenEvent(screen_event_t screen_event) return false; } - if (m_windowId == idString) { + // Grab windows that have a non-empty ID string and a matching window id to grab + if (idString[0] != '\0' && m_windowId == idString) { m_window = window; start(); } -- cgit v1.2.1 From 71a6b1b62041981f894cb2b6589fce92f137bbc4 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 18 Mar 2016 16:23:35 +0100 Subject: DirectShow: Fix MinGW warnings about signedness of comparison. Use a switch on int instead of else if. common\evr\evrcustompresenter.cpp: In member function 'virtual bool EVRCustomPresenter::event(QEvent*)': common\evr\evrcustompresenter.cpp:1882:22: warning: comparison between 'enum QEvent::Type' and 'enum EVRCustomPresenter::PresenterEvents' [-Wenum-compare] if (e->type() == StartSurface) { ^ common\evr\evrcustompresenter.cpp:1885:29: warning: comparison between 'enum QEvent::Type' and 'enum EVRCustomPresenter::PresenterEvents' [-Wenum-compare] } else if (e->type() == StopSurface) { ^ common\evr\evrcustompresenter.cpp:1888:29: warning: comparison between 'enum QEvent::Type' and 'enum EVRCustomPresenter::PresenterEvents' [-Wenum-compare] } else if (e->type() == PresentSample) { Change-Id: I8533e2c6d9b0a01b7b95e1d8bb119b50d4aabd25 Reviewed-by: Mark Brand --- src/plugins/common/evr/evrcustompresenter.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/plugins/common/evr/evrcustompresenter.cpp b/src/plugins/common/evr/evrcustompresenter.cpp index 49623e891..4acf3aa64 100644 --- a/src/plugins/common/evr/evrcustompresenter.cpp +++ b/src/plugins/common/evr/evrcustompresenter.cpp @@ -1872,18 +1872,19 @@ float EVRCustomPresenter::getMaxRate(bool thin) bool EVRCustomPresenter::event(QEvent *e) { - if (e->type() == StartSurface) { + switch (int(e->type())) { + case StartSurface: startSurface(); return true; - } else if (e->type() == StopSurface) { + case StopSurface: stopSurface(); return true; - } else if (e->type() == PresentSample) { - PresentSampleEvent *ev = static_cast(e); - presentSample(ev->sample()); + case PresentSample: + presentSample(static_cast(e)->sample()); return true; + default: + break; } - return QObject::event(e); } -- cgit v1.2.1 From 7b68ca81dd1bd79f7f936b5f81c78daad629d584 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Mon, 29 Feb 2016 13:37:39 +0100 Subject: Purge sRGB chunks from PNGs in examples. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Subjects each *.png file that matched grep -law "sRGB" to: pngcrush -ow -brute -rem allb -reduce Change-Id: Iff326d7e63d6e0106204beb1f42700032cb6b79a Reviewed-by: Topi Reiniö --- examples/multimedia/spectrum/app/images/record.png | Bin 670 -> 466 bytes .../multimedia/video/qmlvideofx/images/qt-logo.png | Bin 13923 -> 9186 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/examples/multimedia/spectrum/app/images/record.png b/examples/multimedia/spectrum/app/images/record.png index e7493aad9..184fce809 100644 Binary files a/examples/multimedia/spectrum/app/images/record.png and b/examples/multimedia/spectrum/app/images/record.png differ diff --git a/examples/multimedia/video/qmlvideofx/images/qt-logo.png b/examples/multimedia/video/qmlvideofx/images/qt-logo.png index 7d3e97eb3..ecbff0ca3 100644 Binary files a/examples/multimedia/video/qmlvideofx/images/qt-logo.png and b/examples/multimedia/video/qmlvideofx/images/qt-logo.png differ -- cgit v1.2.1 From 45ca387cb03f3a3e49ed7f125b05a864645c459c Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Mon, 29 Feb 2016 13:37:39 +0100 Subject: Purge sRGB chunks from PNGs in documentation. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Subjects each *.png file that matched grep -law "sRGB" to: pngcrush -ow -brute -rem allb -reduce -force Change-Id: I2ac34243ebe39c93860c5ac595c2f1eca4322eb8 Reviewed-by: Topi Reiniö --- .../audiooutput/doc/images/audiooutput-example.png | Bin 11966 -> 9249 bytes .../doc/images/declarative-radio-example.png | Bin 12113 -> 9809 bytes .../spectrum/doc/images/spectrum-demo.png | Bin 10500 -> 8691 bytes src/multimedia/doc/src/images/annotatedurl.png | Bin 40129 -> 34705 bytes .../doc/src/images/video-graphics-memory.png | Bin 14934 -> 12945 bytes .../doc/src/images/video-qml-paint-rate.png | Bin 6350 -> 6121 bytes 6 files changed, 0 insertions(+), 0 deletions(-) diff --git a/examples/multimedia/audiooutput/doc/images/audiooutput-example.png b/examples/multimedia/audiooutput/doc/images/audiooutput-example.png index 5588fbb57..1abf5571f 100644 Binary files a/examples/multimedia/audiooutput/doc/images/audiooutput-example.png and b/examples/multimedia/audiooutput/doc/images/audiooutput-example.png differ diff --git a/examples/multimedia/declarative-radio/doc/images/declarative-radio-example.png b/examples/multimedia/declarative-radio/doc/images/declarative-radio-example.png index 5b29174c5..882180b21 100644 Binary files a/examples/multimedia/declarative-radio/doc/images/declarative-radio-example.png and b/examples/multimedia/declarative-radio/doc/images/declarative-radio-example.png differ diff --git a/examples/multimedia/spectrum/doc/images/spectrum-demo.png b/examples/multimedia/spectrum/doc/images/spectrum-demo.png index 9ccb489a9..077cbb68d 100644 Binary files a/examples/multimedia/spectrum/doc/images/spectrum-demo.png and b/examples/multimedia/spectrum/doc/images/spectrum-demo.png differ diff --git a/src/multimedia/doc/src/images/annotatedurl.png b/src/multimedia/doc/src/images/annotatedurl.png index 38d86fb49..b6cf8637c 100644 Binary files a/src/multimedia/doc/src/images/annotatedurl.png and b/src/multimedia/doc/src/images/annotatedurl.png differ diff --git a/src/multimedia/doc/src/images/video-graphics-memory.png b/src/multimedia/doc/src/images/video-graphics-memory.png index 9479cce4c..4bea33322 100644 Binary files a/src/multimedia/doc/src/images/video-graphics-memory.png and b/src/multimedia/doc/src/images/video-graphics-memory.png differ diff --git a/src/multimedia/doc/src/images/video-qml-paint-rate.png b/src/multimedia/doc/src/images/video-qml-paint-rate.png index 1519ff64e..cb7d822d9 100644 Binary files a/src/multimedia/doc/src/images/video-qml-paint-rate.png and b/src/multimedia/doc/src/images/video-qml-paint-rate.png differ -- cgit v1.2.1 From 15c42ebccb45fcfd2d7d0c6a52af1f81eb1eb706 Mon Sep 17 00:00:00 2001 From: Dan Cape Date: Fri, 19 Jun 2015 16:26:49 -0400 Subject: QNX: Fix video playback on VMWare Mark eglImage as not supported on VMWare since that path requires that the image data be in GPU accessible memory which is not the case for video Change-Id: I2ea1ec52842adf0bc1ca39c882e6771e6a992c65 Reviewed-by: Marc Mutz Reviewed-by: Rafael Roquetto --- src/plugins/qnx/common/windowgrabber.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/plugins/qnx/common/windowgrabber.cpp b/src/plugins/qnx/common/windowgrabber.cpp index c16e38206..39d87c781 100644 --- a/src/plugins/qnx/common/windowgrabber.cpp +++ b/src/plugins/qnx/common/windowgrabber.cpp @@ -40,6 +40,7 @@ #include #include +#include #ifdef Q_OS_BLACKBERRY #include @@ -343,6 +344,9 @@ void WindowGrabber::checkForEglImageExtension() m_eglImageSupported = m_context->hasExtension(QByteArrayLiteral("GL_OES_EGL_image")) && eglExtensions.contains(QByteArrayLiteral("EGL_KHR_image")); + if (strstr(reinterpret_cast(glGetString(GL_VENDOR)), "VMware")) + m_eglImageSupported = false; + m_eglImageCheck = true; } -- cgit v1.2.1 From 0d8366273dcb9af5dae641c7efbc6db878942422 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Wed, 17 Feb 2016 11:19:47 +0100 Subject: Add Wasapi audio backend WASAPI is a Windows audio backend for low latency audio. This backend works for WinRT as well as classic desktop apps. Task-number: QTBUG-42287 Change-Id: I7a1b7b103b64fadc50a9955a9d59443791f6d026 Reviewed-by: Yoann Lopes --- src/plugins/plugins.pro | 3 +- src/plugins/wasapi/qwasapiaudiodeviceinfo.cpp | 164 ++++++++ src/plugins/wasapi/qwasapiaudiodeviceinfo.h | 82 ++++ src/plugins/wasapi/qwasapiaudioinput.cpp | 560 +++++++++++++++++++++++++ src/plugins/wasapi/qwasapiaudioinput.h | 117 ++++++ src/plugins/wasapi/qwasapiaudiooutput.cpp | 572 ++++++++++++++++++++++++++ src/plugins/wasapi/qwasapiaudiooutput.h | 118 ++++++ src/plugins/wasapi/qwasapiplugin.cpp | 77 ++++ src/plugins/wasapi/qwasapiplugin.h | 70 ++++ src/plugins/wasapi/qwasapiutils.cpp | 314 ++++++++++++++ src/plugins/wasapi/qwasapiutils.h | 143 +++++++ src/plugins/wasapi/wasapi.json | 3 + src/plugins/wasapi/wasapi.pro | 30 ++ 13 files changed, 2252 insertions(+), 1 deletion(-) create mode 100644 src/plugins/wasapi/qwasapiaudiodeviceinfo.cpp create mode 100644 src/plugins/wasapi/qwasapiaudiodeviceinfo.h create mode 100644 src/plugins/wasapi/qwasapiaudioinput.cpp create mode 100644 src/plugins/wasapi/qwasapiaudioinput.h create mode 100644 src/plugins/wasapi/qwasapiaudiooutput.cpp create mode 100644 src/plugins/wasapi/qwasapiaudiooutput.h create mode 100644 src/plugins/wasapi/qwasapiplugin.cpp create mode 100644 src/plugins/wasapi/qwasapiplugin.h create mode 100644 src/plugins/wasapi/qwasapiutils.cpp create mode 100644 src/plugins/wasapi/qwasapiutils.h create mode 100644 src/plugins/wasapi/wasapi.json create mode 100644 src/plugins/wasapi/wasapi.pro diff --git a/src/plugins/plugins.pro b/src/plugins/plugins.pro index 8b3322024..67b06a61b 100644 --- a/src/plugins/plugins.pro +++ b/src/plugins/plugins.pro @@ -34,7 +34,8 @@ win32:!winrt:!wince { } winrt { - SUBDIRS += winrt + SUBDIRS += wasapi \ + winrt } unix:!mac:!android { diff --git a/src/plugins/wasapi/qwasapiaudiodeviceinfo.cpp b/src/plugins/wasapi/qwasapiaudiodeviceinfo.cpp new file mode 100644 index 000000000..283e8b740 --- /dev/null +++ b/src/plugins/wasapi/qwasapiaudiodeviceinfo.cpp @@ -0,0 +1,164 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies). +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwasapiaudiodeviceinfo.h" +#include "qwasapiutils.h" + +#include + +QT_BEGIN_NAMESPACE + +Q_LOGGING_CATEGORY(lcMmDeviceInfo, "qt.multimedia.deviceinfo") + +QWasapiAudioDeviceInfo::QWasapiAudioDeviceInfo(QByteArray dev, QAudio::Mode mode) + : m_deviceName(dev) +{ + qCDebug(lcMmDeviceInfo) << __FUNCTION__ << dev << mode; + m_interface = QWasapiUtils::createOrGetInterface(dev, mode); + + QAudioFormat referenceFormat = m_interface->m_mixFormat; + + const int rates[] = {8000, 11025, 160000, 22050, 32000, 44100, 48000, 88200, 96000, 192000}; + for (int rate : rates) { + QAudioFormat f = referenceFormat; + f.setSampleRate(rate); + if (isFormatSupported(f)) + m_sampleRates.append(rate); + } + + for (int i = 1; i <= 18; ++i) { + QAudioFormat f = referenceFormat; + f.setChannelCount(i); + if (isFormatSupported(f)) + m_channelCounts.append(i); + } + + const int sizes[] = {8, 12, 16, 20, 24, 32, 64}; + for (int s : sizes) { + QAudioFormat f = referenceFormat; + f.setSampleSize(s); + if (isFormatSupported(f)) + m_sampleSizes.append(s); + } + + referenceFormat.setSampleType(QAudioFormat::SignedInt); + if (isFormatSupported(referenceFormat)) + m_sampleTypes.append(QAudioFormat::SignedInt); + + referenceFormat.setSampleType(QAudioFormat::Float); + if (isFormatSupported(referenceFormat)) + m_sampleTypes.append(QAudioFormat::Float); +} + +QWasapiAudioDeviceInfo::~QWasapiAudioDeviceInfo() +{ + qCDebug(lcMmDeviceInfo) << __FUNCTION__; +} + +bool QWasapiAudioDeviceInfo::isFormatSupported(const QAudioFormat& format) const +{ + qCDebug(lcMmDeviceInfo) << __FUNCTION__ << format; + + WAVEFORMATEX nfmt; + if (!QWasapiUtils::convertToNativeFormat(format, &nfmt)) + return false; + + WAVEFORMATEX closest; + WAVEFORMATEX *pClosest = &closest; + HRESULT hr; + hr = m_interface->m_client->IsFormatSupported(AUDCLNT_SHAREMODE_SHARED, &nfmt, &pClosest); + + if (hr == S_OK) // S_FALSE is inside SUCCEEDED() + return true; + + if (lcMmDeviceInfo().isDebugEnabled()) { + QAudioFormat f; + QWasapiUtils::convertFromNativeFormat(pClosest, &f); + qCDebug(lcMmDeviceInfo) << __FUNCTION__ << hr << "Closest match is:" << f; + } + + return false; +} + +QAudioFormat QWasapiAudioDeviceInfo::preferredFormat() const +{ + qCDebug(lcMmDeviceInfo) << __FUNCTION__; + return m_interface->m_mixFormat; +} + +QString QWasapiAudioDeviceInfo::deviceName() const +{ + qCDebug(lcMmDeviceInfo) << __FUNCTION__; + return m_deviceName; +} + +QStringList QWasapiAudioDeviceInfo::supportedCodecs() +{ + qCDebug(lcMmDeviceInfo) << __FUNCTION__; + return QStringList() << QStringLiteral("audio/pcm"); +} + +QList QWasapiAudioDeviceInfo::supportedSampleRates() +{ + qCDebug(lcMmDeviceInfo) << __FUNCTION__; + return m_sampleRates; +} + +QList QWasapiAudioDeviceInfo::supportedChannelCounts() +{ + qCDebug(lcMmDeviceInfo) << __FUNCTION__; + return m_channelCounts; +} + +QList QWasapiAudioDeviceInfo::supportedSampleSizes() +{ + qCDebug(lcMmDeviceInfo) << __FUNCTION__; + return m_sampleSizes; +} + +QList QWasapiAudioDeviceInfo::supportedByteOrders() +{ + qCDebug(lcMmDeviceInfo) << __FUNCTION__; + return QList() << m_interface->m_mixFormat.byteOrder(); +} + +QList QWasapiAudioDeviceInfo::supportedSampleTypes() +{ + qCDebug(lcMmDeviceInfo) << __FUNCTION__; + return m_sampleTypes; +} + +QT_END_NAMESPACE diff --git a/src/plugins/wasapi/qwasapiaudiodeviceinfo.h b/src/plugins/wasapi/qwasapiaudiodeviceinfo.h new file mode 100644 index 000000000..1bf4d846d --- /dev/null +++ b/src/plugins/wasapi/qwasapiaudiodeviceinfo.h @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies). +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWASAPIAUDIODEVICEINFO_H +#define QWASAPIAUDIODEVICEINFO_H + +#include +#include +#include +#include +#include +#include + +#include + +QT_BEGIN_NAMESPACE + +Q_DECLARE_LOGGING_CATEGORY(lcMmDeviceInfo) + +class AudioInterface; +class QWasapiAudioDeviceInfo : public QAbstractAudioDeviceInfo +{ + Q_OBJECT +public: + explicit QWasapiAudioDeviceInfo(QByteArray dev,QAudio::Mode mode); + ~QWasapiAudioDeviceInfo(); + + QAudioFormat preferredFormat() const Q_DECL_OVERRIDE; + bool isFormatSupported(const QAudioFormat& format) const Q_DECL_OVERRIDE; + QString deviceName() const Q_DECL_OVERRIDE; + QStringList supportedCodecs() Q_DECL_OVERRIDE; + QList supportedSampleRates() Q_DECL_OVERRIDE; + QList supportedChannelCounts() Q_DECL_OVERRIDE; + QList supportedSampleSizes() Q_DECL_OVERRIDE; + QList supportedByteOrders() Q_DECL_OVERRIDE; + QList supportedSampleTypes() Q_DECL_OVERRIDE; + +private: + Microsoft::WRL::ComPtr m_interface; + QString m_deviceName; + QList m_sampleRates; + QList m_channelCounts; + QList m_sampleSizes; + QList m_sampleTypes; +}; + +QT_END_NAMESPACE + +#endif // QWASAPIAUDIODEVICEINFO_H diff --git a/src/plugins/wasapi/qwasapiaudioinput.cpp b/src/plugins/wasapi/qwasapiaudioinput.cpp new file mode 100644 index 000000000..1cc1c38f7 --- /dev/null +++ b/src/plugins/wasapi/qwasapiaudioinput.cpp @@ -0,0 +1,560 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies). +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwasapiaudioinput.h" +#include "qwasapiutils.h" + +#include +#include +#include + +#include + +using namespace Microsoft::WRL; + +QT_BEGIN_NAMESPACE + +Q_LOGGING_CATEGORY(lcMmAudioInput, "qt.multimedia.audioinput") + +class WasapiInputDevicePrivate : public QIODevice +{ + Q_OBJECT +public: + WasapiInputDevicePrivate(QWasapiAudioInput* input); + ~WasapiInputDevicePrivate(); + + qint64 readData(char* data, qint64 len); + qint64 writeData(const char* data, qint64 len); + +private: + QWasapiAudioInput *m_input; +}; + +WasapiInputDevicePrivate::WasapiInputDevicePrivate(QWasapiAudioInput* input) + : m_input(input) +{ + qCDebug(lcMmAudioInput) << __FUNCTION__; +} + +WasapiInputDevicePrivate::~WasapiInputDevicePrivate() +{ + qCDebug(lcMmAudioInput) << __FUNCTION__; +} + +qint64 WasapiInputDevicePrivate::readData(char* data, qint64 len) +{ + qCDebug(lcMmAudioInput) << __FUNCTION__; + + const quint32 channelCount = m_input->m_currentFormat.channelCount(); + const quint32 sampleBytes = m_input->m_currentFormat.sampleSize() / 8; + + const quint32 requestedFrames = len / channelCount / sampleBytes; + quint32 availableFrames = 0; + HRESULT hr = m_input->m_capture->GetNextPacketSize(&availableFrames); + + quint32 readFrames = qMin(requestedFrames, availableFrames); + const qint64 readBytes = readFrames * channelCount * sampleBytes; + + BYTE* buffer; + DWORD flags; + + QMutexLocker locker(&m_input->m_mutex); + + quint64 devicePosition; + hr = m_input->m_capture->GetBuffer(&buffer, &readFrames, &flags, &devicePosition, NULL); + if (hr != S_OK) { + m_input->m_currentError = QAudio::FatalError; + emit m_input->errorChanged(m_input->m_currentError); + hr = m_input->m_capture->ReleaseBuffer(readFrames); + qCDebug(lcMmAudioInput) << __FUNCTION__ << "Could not acquire input buffer."; + return 0; + } + if (Q_UNLIKELY(flags & AUDCLNT_BUFFERFLAGS_SILENT)) { + // In case this flag is set, user is supposed to ignore the content + // of the buffer and manually write silence + qCDebug(lcMmAudioInput) << __FUNCTION__ << "AUDCLNT_BUFFERFLAGS_SILENT: " + << "Ignoring buffer and writing silence."; + memset(data, 0, readBytes); + } else { + memcpy(data, buffer, readBytes); + } + + hr = m_input->m_capture->ReleaseBuffer(readFrames); + if (hr != S_OK) + qFatal("Could not release buffer"); + + if (m_input->m_interval && m_input->m_openTime.elapsed() - m_input->m_openTimeOffset > m_input->m_interval) { + QMetaObject::invokeMethod(m_input, "notify", Qt::QueuedConnection); + m_input->m_openTimeOffset = m_input->m_openTime.elapsed(); + } + + m_input->m_bytesProcessed += readBytes; + + if (m_input->m_currentState != QAudio::ActiveState) { + m_input->m_currentState = QAudio::ActiveState; + QMetaObject::invokeMethod(m_input, "stateChanged", Qt::QueuedConnection, + Q_ARG(QAudio::State, QAudio::ActiveState)); + } + return readBytes; +} + +qint64 WasapiInputDevicePrivate::writeData(const char* data, qint64 len) +{ + qCDebug(lcMmAudioInput) << __FUNCTION__; + Q_UNUSED(data) + Q_UNUSED(len) + return 0; +} + +QWasapiAudioInput::QWasapiAudioInput(const QByteArray &device) + : m_deviceName(device) +#if defined(CLASSIC_APP_BUILD) || _MSC_VER >= 1900 + , m_volumeCache(qreal(1.)) +#endif + , m_currentState(QAudio::StoppedState) + , m_currentError(QAudio::NoError) + , m_bufferFrames(0) + , m_bufferBytes(4096) + , m_eventThread(0) +{ + qCDebug(lcMmAudioInput) << __FUNCTION__ << device; + Q_UNUSED(device) +} + +QWasapiAudioInput::~QWasapiAudioInput() +{ + qCDebug(lcMmAudioInput) << __FUNCTION__; + stop(); +} + +void QWasapiAudioInput::setVolume(qreal vol) +{ + qCDebug(lcMmAudioInput) << __FUNCTION__ << vol; +#if defined(CLASSIC_APP_BUILD) || _MSC_VER >= 1900 // Volume is only supported MSVC2015 and beyond + m_volumeCache = vol; + if (m_volumeControl) { + quint32 channelCount; + HRESULT hr = m_volumeControl->GetChannelCount(&channelCount); + for (quint32 i = 0; i < channelCount; ++i) { + // ### TODO: Use QAudioHelperInternal::qScaleVolumeFromLinear when integrated + hr = m_volumeControl->SetChannelVolume(i, vol); + RETURN_VOID_IF_FAILED("Could not set audio volume."); + } + } +#endif // defined(CLASSIC_APP_BUILD) || _MSC_VER >= 1900 +} + +qreal QWasapiAudioInput::volume() const +{ + qCDebug(lcMmAudioInput) << __FUNCTION__; +#if defined(CLASSIC_APP_BUILD) || _MSC_VER >= 1900 // Volume is only supported MSVC2015 and beyond + return m_volumeCache; +#else + return qreal(1.0); +#endif +} + +void QWasapiAudioInput::process() +{ + qCDebug(lcMmAudioInput) << __FUNCTION__; + const quint32 channelCount = m_currentFormat.channelCount(); + const quint32 sampleBytes = m_currentFormat.sampleSize() / 8; + BYTE* buffer; + HRESULT hr; + DWORD waitRet; + + bool processing = true; + do { + waitRet = WaitForSingleObjectEx(m_event, 2000, FALSE); + if (waitRet != WAIT_OBJECT_0) { + qFatal("Returned while waiting for event."); + return; + } + + QMutexLocker locker(&m_mutex); + + if (m_currentState != QAudio::ActiveState && m_currentState != QAudio::IdleState) + break; + + if (!m_pullMode) { + QMetaObject::invokeMethod(m_eventDevice, "readyRead", Qt::QueuedConnection); + ResetEvent(m_event); + continue; + } + + quint32 packetFrames; + hr = m_capture->GetNextPacketSize(&packetFrames); + + while (packetFrames != 0 && m_currentState == QAudio::ActiveState) { + DWORD flags; + quint64 devicePosition; + hr = m_capture->GetBuffer(&buffer, &packetFrames, &flags, &devicePosition, NULL); + if (hr != S_OK) { + m_currentError = QAudio::FatalError; + QMetaObject::invokeMethod(this, "errorChanged", Qt::QueuedConnection, + Q_ARG(QAudio::Error, QAudio::UnderrunError)); + // Also Error Buffers need to be released + hr = m_capture->ReleaseBuffer(packetFrames); + qCDebug(lcMmAudioInput) << __FUNCTION__ << "Could not acquire input buffer."; + return; + } + const quint32 writeBytes = packetFrames * channelCount * sampleBytes; + if (Q_UNLIKELY(flags & AUDCLNT_BUFFERFLAGS_SILENT)) { + // In case this flag is set, user is supposed to ignore the content + // of the buffer and manually write silence + qCDebug(lcMmAudioInput) << __FUNCTION__ << "AUDCLNT_BUFFERFLAGS_SILENT: " + << "Ignoring buffer and writing silence."; + buffer = new BYTE[writeBytes]; + memset(buffer, 0, writeBytes); + } + + qint64 written = m_eventDevice->write(reinterpret_cast(buffer), writeBytes); + + if (Q_UNLIKELY(flags & AUDCLNT_BUFFERFLAGS_SILENT)) + delete [] buffer; + + if (written < static_cast(writeBytes)) { + if (m_currentError != QAudio::UnderrunError) { + m_currentError = QAudio::UnderrunError; + QMetaObject::invokeMethod(this, "errorChanged", Qt::QueuedConnection, + Q_ARG(QAudio::Error, QAudio::UnderrunError)); + } + } + hr = m_capture->ReleaseBuffer(packetFrames); + if (hr != S_OK) + qFatal("Could not release buffer"); + + m_bytesProcessed += writeBytes; + + hr = m_capture->GetNextPacketSize(&packetFrames); + } + ResetEvent(m_event); + + if (m_interval && m_openTime.elapsed() - m_openTimeOffset > m_interval) { + QMetaObject::invokeMethod(this, "notify", Qt::QueuedConnection); + m_openTimeOffset = m_openTime.elapsed(); + } + processing = m_currentState == QAudio::ActiveState || m_currentState == QAudio::IdleState; + } while (processing); +} + +bool QWasapiAudioInput::initStart(bool pull) +{ + if (m_currentState == QAudio::ActiveState || m_currentState == QAudio::IdleState) + stop(); + + QMutexLocker locker(&m_mutex); + + m_interface = QWasapiUtils::createOrGetInterface(m_deviceName, QAudio::AudioInput); + Q_ASSERT(m_interface); + + m_pullMode = pull; + WAVEFORMATEX nFmt; + WAVEFORMATEX closest; + WAVEFORMATEX *pClose = &closest; + + if (!m_currentFormat.isValid() || !QWasapiUtils::convertToNativeFormat(m_currentFormat, &nFmt)) { + m_currentError = QAudio::OpenError; + emit errorChanged(m_currentError); + return false; + } + + HRESULT hr; + + hr = m_interface->m_client->IsFormatSupported(AUDCLNT_SHAREMODE_SHARED, &nFmt, &pClose); + if (hr != S_OK) { + m_currentError = QAudio::OpenError; + emit errorChanged(m_currentError); + return false; + } + + REFERENCE_TIME t = ((10000.0 * 10000 / nFmt.nSamplesPerSec * 1024) + 0.5); + if (m_bufferBytes) + t = m_currentFormat.durationForBytes(m_bufferBytes) * 10; + + const DWORD flags = AUDCLNT_STREAMFLAGS_EVENTCALLBACK; + hr = m_interface->m_client->Initialize(AUDCLNT_SHAREMODE_SHARED, flags, t, 0, &nFmt, NULL); + EMIT_RETURN_FALSE_IF_FAILED("Could not initialize audio client.", QAudio::OpenError) + + hr = m_interface->m_client->GetService(IID_PPV_ARGS(&m_capture)); + EMIT_RETURN_FALSE_IF_FAILED("Could not acquire render service.", QAudio::OpenError) + +#if defined(CLASSIC_APP_BUILD) || _MSC_VER >= 1900 // Volume is only supported MSVC2015 and beyond for WinRT + hr = m_interface->m_client->GetService(IID_PPV_ARGS(&m_volumeControl)); + if (FAILED(hr)) + qCDebug(lcMmAudioInput) << "Could not acquire volume control."; +#endif // defined(CLASSIC_APP_BUILD) || _MSC_VER >= 1900 + + hr = m_interface->m_client->GetBufferSize(&m_bufferFrames); + EMIT_RETURN_FALSE_IF_FAILED("Could not access buffer size.", QAudio::OpenError) + + m_event = CreateEventEx(NULL, NULL, 0, EVENT_ALL_ACCESS); + m_eventThread = new QWasapiProcessThread(this, false); + m_eventThread->m_event = m_event; + hr = m_interface->m_client->SetEventHandle(m_event); + EMIT_RETURN_FALSE_IF_FAILED("Could not set event handle.", QAudio::OpenError) + + if (!m_pullMode) { + m_eventDevice = new WasapiInputDevicePrivate(this); + m_eventDevice->open(QIODevice::ReadOnly|QIODevice::Unbuffered); + } + + hr = m_interface->m_client->Start(); + EMIT_RETURN_FALSE_IF_FAILED("Could not start audio render client.", QAudio::OpenError) + + m_openTime.restart(); + m_openTimeOffset = 0; + m_bytesProcessed = 0; + + return true; +} + +QAudio::Error QWasapiAudioInput::error() const +{ + qCDebug(lcMmAudioInput) << __FUNCTION__ << m_currentError; + return m_currentError; +} + +QAudio::State QWasapiAudioInput::state() const +{ + qCDebug(lcMmAudioInput) << __FUNCTION__; + return m_currentState; +} + +void QWasapiAudioInput::start(QIODevice* device) +{ + qCDebug(lcMmAudioInput) << __FUNCTION__ << device; + if (!initStart(true)) { + qCDebug(lcMmAudioInput) << __FUNCTION__ << "failed"; + return; + } + m_eventDevice = device; + + m_mutex.lock(); + m_currentState = QAudio::ActiveState; + m_mutex.unlock(); + emit stateChanged(m_currentState); + m_eventThread->start(); +} + +QIODevice *QWasapiAudioInput::start() +{ + qCDebug(lcMmAudioInput) << __FUNCTION__; + if (!initStart(false)) { + qCDebug(lcMmAudioInput) << __FUNCTION__ << "failed"; + return nullptr; + } + + m_mutex.lock(); + m_currentState = QAudio::IdleState; + m_mutex.unlock(); + emit stateChanged(m_currentState); + m_eventThread->start(); + return m_eventDevice; +} + +void QWasapiAudioInput::stop() +{ + qCDebug(lcMmAudioInput) << __FUNCTION__; + if (m_currentState == QAudio::StoppedState) + return; + + m_mutex.lock(); + m_currentState = QAudio::StoppedState; + m_mutex.unlock(); + emit stateChanged(m_currentState); + + if (m_currentError != QAudio::NoError) { + m_mutex.lock(); + m_currentError = QAudio::NoError; + m_mutex.unlock(); + emit errorChanged(m_currentError); + } + + HRESULT hr = m_interface->m_client->Stop(); + hr = m_interface->m_client->Reset(); + + if (m_eventThread) { + SetEvent(m_eventThread->m_event); + while (m_eventThread->isRunning()) + QThread::yieldCurrentThread(); + m_eventThread->deleteLater(); + m_eventThread = 0; + } +} + +void QWasapiAudioInput::setFormat(const QAudioFormat& fmt) +{ + qCDebug(lcMmAudioInput) << __FUNCTION__ << fmt; + if (m_currentState != QAudio::StoppedState) + return; + m_currentFormat = fmt; +} + +QAudioFormat QWasapiAudioInput::format() const +{ + qCDebug(lcMmAudioInput) << __FUNCTION__; + return m_currentFormat; +} + +int QWasapiAudioInput::bytesReady() const +{ + qCDebug(lcMmAudioInput) << __FUNCTION__; + if (m_currentState != QAudio::IdleState && m_currentState != QAudio::ActiveState) + return 0; + + const quint32 channelCount = m_currentFormat.channelCount(); + const quint32 sampleBytes = m_currentFormat.sampleSize() / 8; + + quint32 packetFrames; + HRESULT hr = m_capture->GetNextPacketSize(&packetFrames); + + if (FAILED(hr)) + return 0; + const quint32 writeBytes = packetFrames * channelCount * sampleBytes; + + return writeBytes; +} + +void QWasapiAudioInput::resume() +{ + qCDebug(lcMmAudioInput) << __FUNCTION__; + if (m_currentState != QAudio::SuspendedState) + return; + + HRESULT hr = m_interface->m_client->Start(); + EMIT_RETURN_VOID_IF_FAILED("Could not start audio render client.", QAudio::FatalError) + + m_mutex.lock(); + m_currentError = QAudio::NoError; + m_currentState = QAudio::ActiveState; + m_mutex.unlock(); + emit stateChanged(m_currentState); + m_eventThread->start(); +} + +void QWasapiAudioInput::setBufferSize(int value) +{ + qCDebug(lcMmAudioInput) << __FUNCTION__ << value; + if (m_currentState == QAudio::ActiveState || m_currentState == QAudio::IdleState) + return; + m_bufferBytes = value; +} + +int QWasapiAudioInput::bufferSize() const +{ + qCDebug(lcMmAudioInput) << __FUNCTION__; + if (m_currentState == QAudio::ActiveState || m_currentState == QAudio::IdleState) + return m_bufferFrames * m_currentFormat.channelCount()* m_currentFormat.sampleSize() / 8; + + return m_bufferBytes; +} + +int QWasapiAudioInput::periodSize() const +{ + qCDebug(lcMmAudioInput) << __FUNCTION__; + REFERENCE_TIME defaultDevicePeriod; + REFERENCE_TIME minimumPeriod; + HRESULT hr = m_interface->m_client->GetDevicePeriod(&defaultDevicePeriod, &minimumPeriod); + if (FAILED(hr)) + return 0; + const int res = m_currentFormat.bytesForDuration(minimumPeriod / 10); + return res; +} + +void QWasapiAudioInput::setNotifyInterval(int ms) +{ + qCDebug(lcMmAudioInput) << __FUNCTION__ << ms; + m_interval = qMax(0, ms); +} + +int QWasapiAudioInput::notifyInterval() const +{ + qCDebug(lcMmAudioInput) << __FUNCTION__; + return m_interval; +} + +qint64 QWasapiAudioInput::processedUSecs() const +{ + qCDebug(lcMmAudioInput) << __FUNCTION__; + if (m_currentState == QAudio::StoppedState) + return 0; + qint64 res = qint64(1000000) * m_bytesProcessed / + (m_currentFormat.channelCount() * (m_currentFormat.sampleSize() / 8)) / + m_currentFormat.sampleRate(); + + return res; +} + +void QWasapiAudioInput::suspend() +{ + qCDebug(lcMmAudioInput) << __FUNCTION__; + if (m_currentState != QAudio::ActiveState) + return; + + m_mutex.lock(); + m_currentState = QAudio::SuspendedState; + m_mutex.unlock(); + emit stateChanged(m_currentState); + + HRESULT hr = m_interface->m_client->Stop(); + EMIT_RETURN_VOID_IF_FAILED("Could not suspend audio render client.", QAudio::FatalError); + + if (m_eventThread) { + SetEvent(m_eventThread->m_event); + while (m_eventThread->isRunning()) + QThread::yieldCurrentThread(); + } + qCDebug(lcMmAudioInput) << __FUNCTION__ << "Thread has stopped"; +} + +qint64 QWasapiAudioInput::elapsedUSecs() const +{ + qCDebug(lcMmAudioInput) << __FUNCTION__; + if (m_currentState == QAudio::StoppedState) + return 0; + return m_openTime.elapsed() * qint64(1000); +} + +void QWasapiAudioInput::reset() +{ + qCDebug(lcMmAudioInput) << __FUNCTION__; + stop(); +} + +QT_END_NAMESPACE + +#include "qwasapiaudioinput.moc" diff --git a/src/plugins/wasapi/qwasapiaudioinput.h b/src/plugins/wasapi/qwasapiaudioinput.h new file mode 100644 index 000000000..829cad153 --- /dev/null +++ b/src/plugins/wasapi/qwasapiaudioinput.h @@ -0,0 +1,117 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies). +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QAUDIOINPUTWASAPI_H +#define QAUDIOINPUTWASAPI_H + +#include +#include +#include +#include +#include + +#include + +struct IAudioCaptureClient; +struct IAudioStreamVolume; + +QT_BEGIN_NAMESPACE + +class AudioInterface; +class WasapiInputDevicePrivate; +class QWasapiProcessThread; + +Q_DECLARE_LOGGING_CATEGORY(lcMmAudioInput) + +class QWasapiAudioInput : public QAbstractAudioInput +{ + Q_OBJECT +public: + explicit QWasapiAudioInput(const QByteArray &device); + ~QWasapiAudioInput(); + + void start(QIODevice* device) Q_DECL_OVERRIDE; + QIODevice* start() Q_DECL_OVERRIDE; + void stop() Q_DECL_OVERRIDE; + void reset() Q_DECL_OVERRIDE; + void suspend() Q_DECL_OVERRIDE; + void resume() Q_DECL_OVERRIDE; + int bytesReady() const Q_DECL_OVERRIDE; + int periodSize() const Q_DECL_OVERRIDE; + void setBufferSize(int value) Q_DECL_OVERRIDE; + int bufferSize() const Q_DECL_OVERRIDE; + void setNotifyInterval(int milliSeconds) Q_DECL_OVERRIDE; + int notifyInterval() const Q_DECL_OVERRIDE; + qint64 processedUSecs() const Q_DECL_OVERRIDE; + qint64 elapsedUSecs() const Q_DECL_OVERRIDE; + QAudio::Error error() const Q_DECL_OVERRIDE; + QAudio::State state() const Q_DECL_OVERRIDE; + void setFormat(const QAudioFormat& fmt) Q_DECL_OVERRIDE; + QAudioFormat format() const Q_DECL_OVERRIDE; + void setVolume(qreal) Q_DECL_OVERRIDE; + qreal volume() const Q_DECL_OVERRIDE; + + void process(); +private: + bool initStart(bool pull); + friend class WasapiInputDevicePrivate; + friend class WasapiInputPrivate; + QByteArray m_deviceName; + Microsoft::WRL::ComPtr m_interface; + Microsoft::WRL::ComPtr m_capture; +#if defined(CLASSIC_APP_BUILD) || _MSC_VER >= 1900 + Microsoft::WRL::ComPtr m_volumeControl; + qreal m_volumeCache; +#endif + QMutex m_mutex; + QAudio::State m_currentState; + QAudio::Error m_currentError; + QAudioFormat m_currentFormat; + qint64 m_bytesProcessed; + QTime m_openTime; + int m_openTimeOffset; + int m_interval; + bool m_pullMode; + quint32 m_bufferFrames; + quint32 m_bufferBytes; + HANDLE m_event; + QWasapiProcessThread *m_eventThread; + QIODevice *m_eventDevice; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/plugins/wasapi/qwasapiaudiooutput.cpp b/src/plugins/wasapi/qwasapiaudiooutput.cpp new file mode 100644 index 000000000..a45bc1f07 --- /dev/null +++ b/src/plugins/wasapi/qwasapiaudiooutput.cpp @@ -0,0 +1,572 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies). +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwasapiaudiooutput.h" +#include "qwasapiutils.h" +#include +#include +#include +#include + +#include +#include + +using namespace Microsoft::WRL; + +QT_BEGIN_NAMESPACE + +Q_LOGGING_CATEGORY(lcMmAudioOutput, "qt.multimedia.audiooutput") + +class WasapiOutputDevicePrivate : public QIODevice +{ + Q_OBJECT +public: + WasapiOutputDevicePrivate(QWasapiAudioOutput* output); + ~WasapiOutputDevicePrivate(); + + qint64 readData(char* data, qint64 len); + qint64 writeData(const char* data, qint64 len); + +private: + QWasapiAudioOutput *m_output; + QTimer m_timer; +}; + +WasapiOutputDevicePrivate::WasapiOutputDevicePrivate(QWasapiAudioOutput* output) + : m_output(output) +{ + qCDebug(lcMmAudioOutput) << __FUNCTION__; + + m_timer.setSingleShot(true); + connect(&m_timer, &QTimer::timeout, [=](){ + if (m_output->m_currentState == QAudio::ActiveState) { + m_output->m_currentState = QAudio::IdleState; + emit m_output->stateChanged(m_output->m_currentState); + m_output->m_currentError = QAudio::UnderrunError; + emit m_output->errorChanged(m_output->m_currentError); + } + }); +} + +WasapiOutputDevicePrivate::~WasapiOutputDevicePrivate() +{ + qCDebug(lcMmAudioOutput) << __FUNCTION__; +} + +qint64 WasapiOutputDevicePrivate::readData(char* data, qint64 len) +{ + qCDebug(lcMmAudioOutput) << __FUNCTION__; + Q_UNUSED(data) + Q_UNUSED(len) + + return 0; +} + +qint64 WasapiOutputDevicePrivate::writeData(const char* data, qint64 len) +{ + if (m_output->state() != QAudio::ActiveState && m_output->state() != QAudio::IdleState) + return 0; + + QMutexLocker locker(&m_output->m_mutex); + m_timer.stop(); + + const quint32 channelCount = m_output->m_currentFormat.channelCount(); + const quint32 sampleBytes = m_output->m_currentFormat.sampleSize() / 8; + const quint32 freeBytes = static_cast(m_output->bytesFree()); + const quint32 bytesToWrite = qMin(freeBytes, static_cast(len)); + const quint32 framesToWrite = bytesToWrite / (channelCount * sampleBytes); + + BYTE *buffer; + HRESULT hr; + hr = m_output->m_renderer->GetBuffer(framesToWrite, &buffer); + if (hr != S_OK) { + m_output->m_currentError = QAudio::UnderrunError; + QMetaObject::invokeMethod(m_output, "errorChanged", Qt::QueuedConnection, + Q_ARG(QAudio::Error, QAudio::UnderrunError)); + // Also Error Buffers need to be released + hr = m_output->m_renderer->ReleaseBuffer(framesToWrite, 0); + return 0; + } + + memcpy_s(buffer, bytesToWrite, data, bytesToWrite); + + hr = m_output->m_renderer->ReleaseBuffer(framesToWrite, 0); + if (hr != S_OK) + qFatal("Could not release buffer"); + + if (m_output->m_interval && m_output->m_openTime.elapsed() - m_output->m_openTimeOffset > m_output->m_interval) { + QMetaObject::invokeMethod(m_output, "notify", Qt::QueuedConnection); + m_output->m_openTimeOffset = m_output->m_openTime.elapsed(); + } + + m_output->m_bytesProcessed += bytesToWrite; + + if (m_output->m_currentState != QAudio::ActiveState) { + m_output->m_currentState = QAudio::ActiveState; + emit m_output->stateChanged(m_output->m_currentState); + } + if (m_output->m_currentError != QAudio::NoError) { + m_output->m_currentError = QAudio::NoError; + emit m_output->errorChanged(m_output->m_currentError); + } + + quint32 paddingFrames; + hr = m_output->m_interface->m_client->GetCurrentPadding(&paddingFrames); + const quint32 paddingBytes = paddingFrames * m_output->m_currentFormat.channelCount() * m_output->m_currentFormat.sampleSize() / 8; + + m_timer.setInterval(m_output->m_currentFormat.durationForBytes(paddingBytes) / 1000); + m_timer.start(); + return bytesToWrite; +} + +QWasapiAudioOutput::QWasapiAudioOutput(const QByteArray &device) + : m_deviceName(device) +#if defined(CLASSIC_APP_BUILD) || _MSC_VER >= 1900 + , m_volumeCache(qreal(1.)) +#endif + , m_currentState(QAudio::StoppedState) + , m_currentError(QAudio::NoError) + , m_interval(1000) + , m_pullMode(true) + , m_bufferFrames(0) + , m_bufferBytes(4096) + , m_eventThread(0) +{ + qCDebug(lcMmAudioOutput) << __FUNCTION__ << device; +} + +QWasapiAudioOutput::~QWasapiAudioOutput() +{ + qCDebug(lcMmAudioOutput) << __FUNCTION__; + stop(); +} + +void QWasapiAudioOutput::setVolume(qreal vol) +{ + qCDebug(lcMmAudioOutput) << __FUNCTION__ << vol; +#if defined(CLASSIC_APP_BUILD) || _MSC_VER >= 1900 // Volume is only supported MSVC2015 and beyond for WinRT + m_volumeCache = vol; + if (m_volumeControl) { + quint32 channelCount; + HRESULT hr = m_volumeControl->GetChannelCount(&channelCount); + for (quint32 i = 0; i < channelCount; ++i) { + // ### TODO: Use QAudioHelperInternal::qScaleVolumeFromLinear when integrated + hr = m_volumeControl->SetChannelVolume(i, vol); + RETURN_VOID_IF_FAILED("Could not set audio volume."); + } + } +#endif // defined(CLASSIC_APP_BUILD) || _MSC_VER >= 1900 +} + +qreal QWasapiAudioOutput::volume() const +{ + qCDebug(lcMmAudioOutput) << __FUNCTION__; +#if defined(CLASSIC_APP_BUILD) || _MSC_VER >= 1900 // Volume is only supported MSVC2015 and beyond for WinRT + return m_volumeCache; +#else + return qreal(1.0); +#endif +} + +void QWasapiAudioOutput::process() +{ + qCDebug(lcMmAudioOutput) << __FUNCTION__; + const quint32 channelCount = m_currentFormat.channelCount(); + const quint32 sampleBytes = m_currentFormat.sampleSize() / 8; + BYTE* buffer; + HRESULT hr; + DWORD waitRet; + + bool processing = true; + do { + waitRet = WaitForSingleObjectEx(m_event, 2000, FALSE); + if (waitRet != WAIT_OBJECT_0) { + qFatal("Returned while waiting for event."); + return; + } + + QMutexLocker locker(&m_mutex); + + if (m_currentState != QAudio::ActiveState && m_currentState != QAudio::IdleState) + break; + + quint32 paddingFrames; + hr = m_interface->m_client->GetCurrentPadding(&paddingFrames); + + quint32 availableFrames = m_bufferFrames - paddingFrames; + hr = m_renderer->GetBuffer(availableFrames, &buffer); + if (hr != S_OK) { + m_currentError = QAudio::UnderrunError; + QMetaObject::invokeMethod(this, "errorChanged", Qt::QueuedConnection, + Q_ARG(QAudio::Error, QAudio::UnderrunError)); + // Also Error Buffers need to be released + hr = m_renderer->ReleaseBuffer(availableFrames, 0); + ResetEvent(m_event); + continue; // We will continue trying + } + + const quint32 readBytes = availableFrames * channelCount * sampleBytes; + qint64 read = m_eventDevice->read((char*)buffer, readBytes); + if (read < static_cast(readBytes)) { + // Fill the rest of the buffer with zero to avoid audio glitches + if (m_currentError != QAudio::UnderrunError) { + m_currentError = QAudio::UnderrunError; + QMetaObject::invokeMethod(this, "errorChanged", Qt::QueuedConnection, + Q_ARG(QAudio::Error, QAudio::UnderrunError)); + } + if (m_currentState != QAudio::IdleState) { + m_currentState = QAudio::IdleState; + QMetaObject::invokeMethod(this, "stateChanged", Qt::QueuedConnection, + Q_ARG(QAudio::State, QAudio::IdleState)); + } + } + + hr = m_renderer->ReleaseBuffer(availableFrames, 0); + if (hr != S_OK) + qFatal("Could not release buffer"); + ResetEvent(m_event); + + if (m_interval && m_openTime.elapsed() - m_openTimeOffset > m_interval) { + QMetaObject::invokeMethod(this, "notify", Qt::QueuedConnection); + m_openTimeOffset = m_openTime.elapsed(); + } + + m_bytesProcessed += read; + processing = m_currentState == QAudio::ActiveState || m_currentState == QAudio::IdleState; + } while (processing); +} + +bool QWasapiAudioOutput::initStart(bool pull) +{ + if (m_currentState == QAudio::ActiveState || m_currentState == QAudio::IdleState) + stop(); + + QMutexLocker locker(&m_mutex); + + m_interface = QWasapiUtils::createOrGetInterface(m_deviceName, QAudio::AudioOutput); + Q_ASSERT(m_interface); + + m_pullMode = pull; + WAVEFORMATEX nFmt; + WAVEFORMATEX closest; + WAVEFORMATEX *pClose = &closest; + + if (!m_currentFormat.isValid() || !QWasapiUtils::convertToNativeFormat(m_currentFormat, &nFmt)) { + m_currentError = QAudio::OpenError; + emit errorChanged(m_currentError); + return false; + } + + HRESULT hr; + + hr = m_interface->m_client->IsFormatSupported(AUDCLNT_SHAREMODE_SHARED, &nFmt, &pClose); + if (hr != S_OK) { + m_currentError = QAudio::OpenError; + emit errorChanged(m_currentError); + return false; + } + + REFERENCE_TIME t = ((10000.0 * 10000 / nFmt.nSamplesPerSec * 1024) + 0.5); + if (m_bufferBytes) + t = m_currentFormat.durationForBytes(m_bufferBytes) * 100; + + DWORD flags = pull ? AUDCLNT_STREAMFLAGS_EVENTCALLBACK : 0; + hr = m_interface->m_client->Initialize(AUDCLNT_SHAREMODE_SHARED, flags, t, 0, &nFmt, NULL); + EMIT_RETURN_FALSE_IF_FAILED("Could not initialize audio client.", QAudio::OpenError) + + hr = m_interface->m_client->GetService(IID_PPV_ARGS(&m_renderer)); + EMIT_RETURN_FALSE_IF_FAILED("Could not acquire render service.", QAudio::OpenError) + +#if defined(CLASSIC_APP_BUILD) || _MSC_VER >= 1900 // Volume is only supported MSVC2015 and beyond + hr = m_interface->m_client->GetService(IID_PPV_ARGS(&m_volumeControl)); + if (FAILED(hr)) + qCDebug(lcMmAudioOutput) << "Could not acquire volume control."; +#endif // defined(CLASSIC_APP_BUILD) || _MSC_VER >= 1900 + + hr = m_interface->m_client->GetBufferSize(&m_bufferFrames); + EMIT_RETURN_FALSE_IF_FAILED("Could not access buffer size.", QAudio::OpenError) + + if (m_pullMode) { + m_eventThread = new QWasapiProcessThread(this); + m_event = CreateEventEx(NULL, NULL, 0, EVENT_ALL_ACCESS); + m_eventThread->m_event = m_event; + + hr = m_interface->m_client->SetEventHandle(m_event); + EMIT_RETURN_FALSE_IF_FAILED("Could not set event handle.", QAudio::OpenError) + } else { + m_eventDevice = new WasapiOutputDevicePrivate(this); + m_eventDevice->open(QIODevice::WriteOnly|QIODevice::Unbuffered); + } + // Send some initial data, do not exit on failure, latest in process + // those an error will be caught + BYTE *pdata = nullptr; + hr = m_renderer->GetBuffer(m_bufferFrames, &pdata); + hr = m_renderer->ReleaseBuffer(m_bufferFrames, AUDCLNT_BUFFERFLAGS_SILENT); + + hr = m_interface->m_client->Start(); + EMIT_RETURN_FALSE_IF_FAILED("Could not start audio render client.", QAudio::OpenError) + + m_openTime.restart(); + m_openTimeOffset = 0; + m_bytesProcessed = 0; + return true; +} + +QAudio::Error QWasapiAudioOutput::error() const +{ + qCDebug(lcMmAudioOutput) << __FUNCTION__ << m_currentError; + return m_currentError; +} + +QAudio::State QWasapiAudioOutput::state() const +{ + qCDebug(lcMmAudioOutput) << __FUNCTION__; + return m_currentState; +} + +void QWasapiAudioOutput::start(QIODevice *device) +{ + qCDebug(lcMmAudioOutput) << __FUNCTION__ << device; + if (!initStart(true)) { + qCDebug(lcMmAudioOutput) << __FUNCTION__ << "failed"; + return; + } + m_eventDevice = device; + + m_mutex.lock(); + m_currentState = QAudio::ActiveState; + m_mutex.unlock(); + emit stateChanged(m_currentState); + m_eventThread->start(); +} + +QIODevice *QWasapiAudioOutput::start() +{ + qCDebug(lcMmAudioOutput) << __FUNCTION__; + + if (!initStart(false)) { + qCDebug(lcMmAudioOutput) << __FUNCTION__ << "failed"; + return nullptr; + } + + m_mutex.lock(); + m_currentState = QAudio::IdleState; + m_mutex.unlock(); + emit stateChanged(m_currentState); + + return m_eventDevice; +} + +void QWasapiAudioOutput::stop() +{ + qCDebug(lcMmAudioOutput) << __FUNCTION__; + if (m_currentState == QAudio::StoppedState) + return; + + if (!m_pullMode) { + HRESULT hr; + hr = m_interface->m_client->Stop(); + hr = m_interface->m_client->Reset(); + } + + m_mutex.lock(); + m_currentState = QAudio::StoppedState; + m_mutex.unlock(); + emit stateChanged(m_currentState); + if (m_currentError != QAudio::NoError) { + m_mutex.lock(); + m_currentError = QAudio::NoError; + m_mutex.unlock(); + emit errorChanged(m_currentError); + } + + HRESULT hr = m_interface->m_client->Stop(); + if (m_currentState == QAudio::StoppedState) { + hr = m_interface->m_client->Reset(); + } + + if (m_eventThread) { + SetEvent(m_eventThread->m_event); + while (m_eventThread->isRunning()) + QThread::yieldCurrentThread(); + m_eventThread->deleteLater(); + m_eventThread = 0; + } +} + +int QWasapiAudioOutput::bytesFree() const +{ + qCDebug(lcMmAudioOutput) << __FUNCTION__; + if (m_currentState != QAudio::ActiveState && m_currentState != QAudio::IdleState) + return 0; + + quint32 paddingFrames; + HRESULT hr = m_interface->m_client->GetCurrentPadding(&paddingFrames); + if (FAILED(hr)) { + qCDebug(lcMmAudioOutput) << __FUNCTION__ << "Could not query padding frames."; + return bufferSize(); + } + + const quint32 availableFrames = m_bufferFrames - paddingFrames; + const quint32 res = availableFrames * m_currentFormat.channelCount() * m_currentFormat.sampleSize() / 8; + return res; +} + +int QWasapiAudioOutput::periodSize() const +{ + qCDebug(lcMmAudioOutput) << __FUNCTION__; + REFERENCE_TIME defaultDevicePeriod; + HRESULT hr = m_interface->m_client->GetDevicePeriod(&defaultDevicePeriod, NULL); + if (FAILED(hr)) + return 0; + const QAudioFormat f = m_currentFormat.isValid() ? m_currentFormat : m_interface->m_mixFormat; + const int res = m_currentFormat.bytesForDuration(defaultDevicePeriod / 10); + return res; +} + +void QWasapiAudioOutput::setBufferSize(int value) +{ + qCDebug(lcMmAudioOutput) << __FUNCTION__ << value; + if (m_currentState == QAudio::ActiveState || m_currentState == QAudio::IdleState) + return; + m_bufferBytes = value; +} + +int QWasapiAudioOutput::bufferSize() const +{ + qCDebug(lcMmAudioOutput) << __FUNCTION__; + if (m_currentState == QAudio::ActiveState || m_currentState == QAudio::IdleState) + return m_bufferFrames * m_currentFormat.channelCount()* m_currentFormat.sampleSize() / 8; + + return m_bufferBytes; +} + +void QWasapiAudioOutput::setNotifyInterval(int ms) +{ + qCDebug(lcMmAudioOutput) << __FUNCTION__ << ms; + m_interval = qMax(0, ms); +} + +int QWasapiAudioOutput::notifyInterval() const +{ + qCDebug(lcMmAudioOutput) << __FUNCTION__; + return m_interval; +} + +qint64 QWasapiAudioOutput::processedUSecs() const +{ + qCDebug(lcMmAudioOutput) << __FUNCTION__; + if (m_currentState == QAudio::StoppedState) + return 0; + qint64 res = qint64(1000000) * m_bytesProcessed / + (m_currentFormat.channelCount() * (m_currentFormat.sampleSize() / 8)) / + m_currentFormat.sampleRate(); + + return res; +} + +void QWasapiAudioOutput::resume() +{ + qCDebug(lcMmAudioOutput) << __FUNCTION__; + + if (m_currentState != QAudio::SuspendedState) + return; + + HRESULT hr = m_interface->m_client->Start(); + EMIT_RETURN_VOID_IF_FAILED("Could not start audio render client.", QAudio::FatalError) + + m_mutex.lock(); + m_currentError = QAudio::NoError; + m_currentState = m_pullMode ? QAudio::ActiveState : QAudio::IdleState; + m_mutex.unlock(); + emit stateChanged(m_currentState); + if (m_eventThread) + m_eventThread->start(); +} + +void QWasapiAudioOutput::setFormat(const QAudioFormat& fmt) +{ + qCDebug(lcMmAudioOutput) << __FUNCTION__ << fmt; + if (m_currentState != QAudio::StoppedState) + return; + m_currentFormat = fmt; +} + +QAudioFormat QWasapiAudioOutput::format() const +{ + qCDebug(lcMmAudioOutput) << __FUNCTION__; + return m_currentFormat; +} + +void QWasapiAudioOutput::suspend() +{ + qCDebug(lcMmAudioOutput) << __FUNCTION__; + + if (m_currentState != QAudio::ActiveState && m_currentState != QAudio::IdleState) + return; + + m_mutex.lock(); + m_currentState = QAudio::SuspendedState; + m_mutex.unlock(); + emit stateChanged(m_currentState); + + HRESULT hr = m_interface->m_client->Stop(); + EMIT_RETURN_VOID_IF_FAILED("Could not suspend audio render client.", QAudio::FatalError); + if (m_eventThread) { + SetEvent(m_eventThread->m_event); + while (m_eventThread->isRunning()) + QThread::yieldCurrentThread(); + qCDebug(lcMmAudioOutput) << __FUNCTION__ << "Thread has stopped"; + } +} + +qint64 QWasapiAudioOutput::elapsedUSecs() const +{ + qCDebug(lcMmAudioOutput) << __FUNCTION__; + if (m_currentState == QAudio::StoppedState) + return 0; + return m_openTime.elapsed() * qint64(1000); +} + +void QWasapiAudioOutput::reset() +{ + qCDebug(lcMmAudioOutput) << __FUNCTION__; + stop(); +} + +QT_END_NAMESPACE + +#include "qwasapiaudiooutput.moc" diff --git a/src/plugins/wasapi/qwasapiaudiooutput.h b/src/plugins/wasapi/qwasapiaudiooutput.h new file mode 100644 index 000000000..4575c8672 --- /dev/null +++ b/src/plugins/wasapi/qwasapiaudiooutput.h @@ -0,0 +1,118 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies). +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QAUDIOOUTPUTWASAPI_H +#define QAUDIOOUTPUTWASAPI_H + +#include +#include +#include +#include +#include + +#include +#include + +struct IAudioRenderClient; +struct IAudioStreamVolume; + +QT_BEGIN_NAMESPACE + +class AudioInterface; +class WasapiOutputDevicePrivate; +class QWasapiProcessThread; + +Q_DECLARE_LOGGING_CATEGORY(lcMmAudioOutput) + +class QWasapiAudioOutput : public QAbstractAudioOutput +{ + Q_OBJECT +public: + explicit QWasapiAudioOutput(const QByteArray &device); + ~QWasapiAudioOutput(); + + void start(QIODevice* device) Q_DECL_OVERRIDE; + QIODevice* start() Q_DECL_OVERRIDE; + void stop() Q_DECL_OVERRIDE; + void reset() Q_DECL_OVERRIDE; + void suspend() Q_DECL_OVERRIDE; + void resume() Q_DECL_OVERRIDE; + int bytesFree() const Q_DECL_OVERRIDE; + int periodSize() const Q_DECL_OVERRIDE; + void setBufferSize(int value) Q_DECL_OVERRIDE; + int bufferSize() const Q_DECL_OVERRIDE; + void setNotifyInterval(int milliSeconds) Q_DECL_OVERRIDE; + int notifyInterval() const Q_DECL_OVERRIDE; + qint64 processedUSecs() const Q_DECL_OVERRIDE; + qint64 elapsedUSecs() const Q_DECL_OVERRIDE; + QAudio::Error error() const Q_DECL_OVERRIDE; + QAudio::State state() const Q_DECL_OVERRIDE; + void setFormat(const QAudioFormat& fmt) Q_DECL_OVERRIDE; + QAudioFormat format() const Q_DECL_OVERRIDE; + void setVolume(qreal) Q_DECL_OVERRIDE; + qreal volume() const Q_DECL_OVERRIDE; + + void process(); +private: + bool initStart(bool pull); + friend class WasapiOutputDevicePrivate; + friend class WasapiOutputPrivate; + QByteArray m_deviceName; + Microsoft::WRL::ComPtr m_interface; + Microsoft::WRL::ComPtr m_renderer; +#if defined(CLASSIC_APP_BUILD) || _MSC_VER >= 1900 + Microsoft::WRL::ComPtr m_volumeControl; + qreal m_volumeCache; +#endif + QMutex m_mutex; + QAudio::State m_currentState; + QAudio::Error m_currentError; + QAudioFormat m_currentFormat; + qint64 m_bytesProcessed; + QTime m_openTime; + int m_openTimeOffset; + int m_interval; + bool m_pullMode; + quint32 m_bufferFrames; + quint32 m_bufferBytes; + HANDLE m_event; + QWasapiProcessThread *m_eventThread; + QIODevice *m_eventDevice; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/plugins/wasapi/qwasapiplugin.cpp b/src/plugins/wasapi/qwasapiplugin.cpp new file mode 100644 index 000000000..7b64a101d --- /dev/null +++ b/src/plugins/wasapi/qwasapiplugin.cpp @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies). +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwasapiplugin.h" +#include "qwasapiaudiodeviceinfo.h" +#include "qwasapiaudioinput.h" +#include "qwasapiaudiooutput.h" +#include "qwasapiutils.h" + +QT_BEGIN_NAMESPACE + +Q_LOGGING_CATEGORY(lcMmPlugin, "qt.multimedia.plugin") + +QWasapiPlugin::QWasapiPlugin(QObject *parent) + : QAudioSystemPlugin(parent) +{ + qCDebug(lcMmPlugin) << __FUNCTION__; +} + +QList QWasapiPlugin::availableDevices(QAudio::Mode mode) const +{ + qCDebug(lcMmPlugin) << __FUNCTION__ << mode; + return QWasapiUtils::availableDevices(mode); +} + +QAbstractAudioInput *QWasapiPlugin::createInput(const QByteArray &device) +{ + qCDebug(lcMmPlugin) << __FUNCTION__ << device; + return new QWasapiAudioInput(device); +} + +QAbstractAudioOutput *QWasapiPlugin::createOutput(const QByteArray &device) +{ + qCDebug(lcMmPlugin) << __FUNCTION__ << device; + return new QWasapiAudioOutput(device); +} + +QAbstractAudioDeviceInfo *QWasapiPlugin::createDeviceInfo(const QByteArray &device, QAudio::Mode mode) +{ + qCDebug(lcMmPlugin) << __FUNCTION__ << device << mode; + return new QWasapiAudioDeviceInfo(device, mode); +} + +QT_END_NAMESPACE diff --git a/src/plugins/wasapi/qwasapiplugin.h b/src/plugins/wasapi/qwasapiplugin.h new file mode 100644 index 000000000..18c2e9575 --- /dev/null +++ b/src/plugins/wasapi/qwasapiplugin.h @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies). +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWASAPIPLUGIN_H +#define QWASAPIPLUGIN_H + +#include +#include +#include + +QT_BEGIN_NAMESPACE + +Q_DECLARE_LOGGING_CATEGORY(lcMmPlugin) + +class QWasapiPlugin : public QAudioSystemPlugin +{ + Q_OBJECT + + Q_PLUGIN_METADATA(IID "org.qt-project.qt.audiosystemfactory/5.0" FILE "wasapi.json") + +public: + explicit QWasapiPlugin(QObject *parent = 0); + ~QWasapiPlugin() {} + + QList availableDevices(QAudio::Mode mode) const Q_DECL_OVERRIDE; + QAbstractAudioInput *createInput(const QByteArray &device) Q_DECL_OVERRIDE; + QAbstractAudioOutput *createOutput(const QByteArray &device) Q_DECL_OVERRIDE; + QAbstractAudioDeviceInfo *createDeviceInfo(const QByteArray &device, QAudio::Mode mode) Q_DECL_OVERRIDE; + +private: + QList m_deviceNames; + QList m_deviceIds; +}; + +QT_END_NAMESPACE + +#endif // QWASAPIPLUGIN_H diff --git a/src/plugins/wasapi/qwasapiutils.cpp b/src/plugins/wasapi/qwasapiutils.cpp new file mode 100644 index 000000000..87daa4e45 --- /dev/null +++ b/src/plugins/wasapi/qwasapiutils.cpp @@ -0,0 +1,314 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies). +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwasapiutils.h" + +#include +#include + +// For Desktop Win32 support +#ifdef CLASSIC_APP_BUILD +#define Q_OS_WINRT +#endif +#include + +#include +#include +#include +#include +#include + +#include + +using namespace ABI::Windows::Devices::Enumeration; +using namespace ABI::Windows::Foundation; +using namespace ABI::Windows::Foundation::Collections; +using namespace ABI::Windows::Media::Devices; +using namespace Microsoft::WRL; +using namespace Microsoft::WRL::Wrappers; + +#define RETURN_EMPTY_LIST_IF_FAILED(msg) RETURN_IF_FAILED(msg, return QList()) + +QT_BEGIN_NAMESPACE + +Q_LOGGING_CATEGORY(lcMmAudioInterface, "qt.multimedia.audiointerface") +Q_LOGGING_CATEGORY(lcMmUtils, "qt.multimedia.utils") + +#ifdef CLASSIC_APP_BUILD +// Opening bracket has to be in the same line as MSVC2013 and 2015 complain on +// different lines otherwise +#pragma warning (suppress: 4273) +HRESULT QEventDispatcherWinRT::runOnXamlThread(const std::function &delegate, bool waitForRun) { + Q_UNUSED(waitForRun) + return delegate(); +} +#endif + +namespace QWasapiUtils { +struct DeviceMapping { + QList outputDeviceNames; + QList outputDeviceIds; + QList inputDeviceNames; + QList inputDeviceIds; +}; +Q_GLOBAL_STATIC(DeviceMapping, gMapping) +} + +AudioInterface::AudioInterface() +{ + qCDebug(lcMmAudioInterface) << __FUNCTION__; + m_currentState = Initialized; +} + +AudioInterface::~AudioInterface() +{ + qCDebug(lcMmAudioInterface) << __FUNCTION__; +} + +HRESULT AudioInterface::ActivateCompleted(IActivateAudioInterfaceAsyncOperation *op) +{ + qCDebug(lcMmAudioInterface) << __FUNCTION__; + + IUnknown *aInterface; + HRESULT hr; + HRESULT hrActivate; + hr = op->GetActivateResult(&hrActivate, &aInterface); + if (FAILED(hr) || FAILED(hrActivate)) { + qCDebug(lcMmAudioInterface) << __FUNCTION__ << "Could not query activate results."; + m_currentState = Error; + return hr; + } + + hr = aInterface->QueryInterface(IID_PPV_ARGS(&m_client)); + if (FAILED(hr)) { + qCDebug(lcMmAudioInterface) << __FUNCTION__ << "Could not access AudioClient interface."; + m_currentState = Error; + return hr; + } + + WAVEFORMATEX *format; + hr = m_client->GetMixFormat(&format); + if (FAILED(hr)) { + qCDebug(lcMmAudioInterface) << __FUNCTION__ << "Could not get mix format."; + m_currentState = Error; + return hr; + } + + QWasapiUtils::convertFromNativeFormat(format, &m_mixFormat); + + m_currentState = Activated; + return S_OK; +} + +bool QWasapiUtils::convertToNativeFormat(const QAudioFormat &qt, WAVEFORMATEX *native) +{ + if (!native + || !qt.isValid() + || qt.codec() != QStringLiteral("audio/pcm") + || qt.sampleRate() <= 0 + || qt.channelCount() <= 0 + || qt.sampleSize() <= 0 + || qt.byteOrder() != QAudioFormat::LittleEndian) { + return false; + } + + native->nSamplesPerSec = qt.sampleRate(); + native->wBitsPerSample = qt.sampleSize(); + native->nChannels = qt.channelCount(); + native->nBlockAlign = (native->wBitsPerSample * native->nChannels) / 8; + native->nAvgBytesPerSec = native->nBlockAlign * native->nSamplesPerSec; + native->cbSize = 0; + + if (qt.sampleType() == QAudioFormat::Float) + native->wFormatTag = WAVE_FORMAT_IEEE_FLOAT; + else + native->wFormatTag = WAVE_FORMAT_PCM; + + return true; +} + +bool QWasapiUtils::convertFromNativeFormat(const WAVEFORMATEX *native, QAudioFormat *qt) +{ + if (!native || !qt) + return false; + + qt->setByteOrder(QAudioFormat::LittleEndian); + qt->setChannelCount(native->nChannels); + qt->setCodec(QStringLiteral("audio/pcm")); + qt->setSampleRate(native->nSamplesPerSec); + qt->setSampleSize(native->wBitsPerSample); + qt->setSampleType(native->wFormatTag == WAVE_FORMAT_IEEE_FLOAT ? QAudioFormat::Float : QAudioFormat::SignedInt); + + return true; +} + +QList QWasapiUtils::availableDevices(QAudio::Mode mode) +{ + qCDebug(lcMmUtils) << __FUNCTION__ << mode; + + ComPtr statics; + HRESULT hr; + + hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Devices_Enumeration_DeviceInformation).Get(), + &statics); + Q_ASSERT_SUCCEEDED(hr); + + ComPtr 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 &deviceNames = mode == QAudio::AudioInput ? gMapping->inputDeviceNames : gMapping->outputDeviceNames; + QList &deviceIds = mode == QAudio::AudioInput ? gMapping->inputDeviceIds : gMapping->outputDeviceIds; + + // We need to refresh due to plugable devices (ie USB) + deviceNames.clear(); + deviceIds.clear(); + + ComPtr> op; + hr = statics->FindAllAsyncDeviceClass(dc, &op ); + RETURN_EMPTY_LIST_IF_FAILED("Could not query audio devices."); + + ComPtr> resultVector; + hr = QWinRTFunctions::await(op, resultVector.GetAddressOf()); + RETURN_EMPTY_LIST_IF_FAILED("Could not receive audio device list."); + + quint32 deviceCount; + hr = resultVector->get_Size(&deviceCount); + RETURN_EMPTY_LIST_IF_FAILED("Could not access audio device count."); + qCDebug(lcMmUtils) << "Found " << deviceCount << " audio devices for" << mode; + + for (quint32 i = 0; i < deviceCount; ++i) { + ComPtr item; + hr = resultVector->GetAt(i, &item); + if (FAILED(hr)) { + qErrnoWarning(hr, "Could not access audio device item."); + continue; + } + + HString hString; + quint32 size; + + hr = item->get_Name(hString.GetAddressOf()); + if (FAILED(hr)) { + qErrnoWarning(hr, "Could not access audio device name."); + continue; + } + const wchar_t *nameWStr = hString.GetRawBuffer(&size); + const QString deviceName = QString::fromWCharArray(nameWStr, size); + + hr = item->get_Id(hString.GetAddressOf()); + if (FAILED(hr)) { + qErrnoWarning(hr, "Could not access audio device id."); + continue; + } + 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)) { + qErrnoWarning(hr, "Could not access audio device enabled."); + continue; + } + + 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); + } + } + return deviceNames; +} + +Microsoft::WRL::ComPtr QWasapiUtils::createOrGetInterface(const QByteArray &dev, QAudio::Mode mode) +{ + qCDebug(lcMmUtils) << __FUNCTION__ << dev << mode; + Q_ASSERT((mode == QAudio::AudioInput ? gMapping->inputDeviceNames.indexOf(dev) : gMapping->outputDeviceNames.indexOf(dev)) != -1); + + Microsoft::WRL::ComPtr result; + HRESULT hr = QEventDispatcherWinRT::runOnXamlThread([dev, mode, &result]() { + HRESULT hr; + QString id = mode == QAudio::AudioInput ? gMapping->inputDeviceIds.at(gMapping->inputDeviceNames.indexOf(dev)) : + gMapping->outputDeviceIds.at(gMapping->outputDeviceNames.indexOf(dev)); + + result = Make(); + + ComPtr op; + + // We cannot use QWinRTFunctions::await here as that will return + // E_NO_INTERFACE. Instead we leave the lambda and wait for the + // status to get out of Activating + result->setState(AudioInterface::Activating); + hr = ActivateAudioInterfaceAsync(reinterpret_cast(id.utf16()), __uuidof(IAudioClient), NULL, result.Get(), op.GetAddressOf()); + if (FAILED(hr)) { + qErrnoWarning(hr, "Could not invoke audio interface activation."); + result->setState(AudioInterface::Error); + } + return hr; + }); + qCDebug(lcMmUtils) << "Activation stated:" << hr; + while (result->state() == AudioInterface::Activating) { + QThread::yieldCurrentThread(); + } + qCDebug(lcMmUtils) << "Activation done:" << hr; + return result; +} + +QT_END_NAMESPACE diff --git a/src/plugins/wasapi/qwasapiutils.h b/src/plugins/wasapi/qwasapiutils.h new file mode 100644 index 000000000..21eff3583 --- /dev/null +++ b/src/plugins/wasapi/qwasapiutils.h @@ -0,0 +1,143 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies). +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWASAPIUTILS_H +#define QWASAPIUTILS_H +#include "qwasapiaudiodeviceinfo.h" +#include "qwasapiaudioinput.h" +#include "qwasapiaudiooutput.h" +#include +#include +#include +#include + +#include +#include +#include + +struct IAudioClient; + +QT_BEGIN_NAMESPACE + +Q_DECLARE_LOGGING_CATEGORY(lcMmAudioInterface) +Q_DECLARE_LOGGING_CATEGORY(lcMmUtils) + +#define EMIT_RETURN_FALSE_IF_FAILED(msg, err) \ + if (FAILED(hr)) { \ + m_currentError = err; \ + emit errorChanged(m_currentError); \ + } \ + RETURN_FALSE_IF_FAILED(msg) + +#define EMIT_RETURN_VOID_IF_FAILED(msg, err) \ + if (FAILED(hr)) { \ + m_currentError = err; \ + emit errorChanged(m_currentError); \ + } \ + RETURN_VOID_IF_FAILED(msg) + +class AudioInterface : public Microsoft::WRL::RuntimeClass, Microsoft::WRL::FtmBase, IActivateAudioInterfaceCompletionHandler> +{ +public: + enum State { + Initialized = 0, + Activating, + Activated, + Error + } ; + + explicit AudioInterface(); + + ~AudioInterface(); + + virtual HRESULT STDMETHODCALLTYPE ActivateCompleted(IActivateAudioInterfaceAsyncOperation *op); + + inline State state() const { return m_currentState; } + void setState(State s) { m_currentState = s; } + + Microsoft::WRL::ComPtr m_client; + QWasapiAudioDeviceInfo *m_parent; + State m_currentState; + QAudioFormat m_mixFormat; +}; + +class QWasapiProcessThread : public QThread +{ +public: + explicit QWasapiProcessThread(QObject *item, bool output = true) : QThread(), + m_endpoint(item), + m_output(output) + { + qCDebug(lcMmUtils) << __FUNCTION__ << item; + } + + ~QWasapiProcessThread() + { + qCDebug(lcMmUtils) << __FUNCTION__; + CloseHandle(m_event); + } + + void run() + { + qCDebug(lcMmUtils) << __FUNCTION__ << m_endpoint; + if (m_output) { + QWasapiAudioOutput *output = static_cast(m_endpoint); + output->process(); + } else { + QWasapiAudioInput *input = static_cast(m_endpoint); + input->process(); + } + } + + HANDLE m_event; +private: + QObject *m_endpoint; + bool m_output; +}; + +namespace QWasapiUtils +{ + bool convertToNativeFormat(const QAudioFormat &qt, WAVEFORMATEX *native); + bool convertFromNativeFormat(const WAVEFORMATEX *native, QAudioFormat *qt); + + QList availableDevices(QAudio::Mode mode); + Microsoft::WRL::ComPtr createOrGetInterface(const QByteArray &dev, QAudio::Mode mode); +} + +QT_END_NAMESPACE + +#endif // QWASAPIUTILS_H diff --git a/src/plugins/wasapi/wasapi.json b/src/plugins/wasapi/wasapi.json new file mode 100644 index 000000000..8d6876490 --- /dev/null +++ b/src/plugins/wasapi/wasapi.json @@ -0,0 +1,3 @@ +{ + "Keys": ["wasapi"] +} diff --git a/src/plugins/wasapi/wasapi.pro b/src/plugins/wasapi/wasapi.pro new file mode 100644 index 000000000..11dfd8abe --- /dev/null +++ b/src/plugins/wasapi/wasapi.pro @@ -0,0 +1,30 @@ +TARGET = qtaudio_wasapi +QT += core-private multimedia-private + +HEADERS += \ + qwasapiplugin.h \ + qwasapiaudiodeviceinfo.h \ + qwasapiaudioinput.h \ + qwasapiaudiooutput.h \ + qwasapiutils.h + +SOURCES += \ + qwasapiplugin.cpp \ + qwasapiaudiodeviceinfo.cpp \ + qwasapiaudioinput.cpp \ + qwasapiaudiooutput.cpp \ + qwasapiutils.cpp + +OTHER_FILES += \ + wasapi.json + +LIBS += Mmdevapi.lib + +win32-* { + DEFINES += CLASSIC_APP_BUILD + LIBS += runtimeobject.lib +} + +PLUGIN_TYPE = audio +PLUGIN_CLASS_NAME = QWasapiPlugin +load(qt_plugin) -- cgit v1.2.1 From 6569c2561932d2dea7ff902971a2e8d91a5b1fe9 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Tue, 22 Mar 2016 10:01:09 +0100 Subject: tst_qdeclarativeaudio: fix ubsan build The test uses QDeclarativePlaylist, but no out-of-line methods or data members, so it got by with just including the header. But a ubsan build requires access to the class' typeinfo objects, so add QDeclarativePlaylist's implementation to the test, too. Change-Id: Ib6bb155b71c0082969f77a13a0e50132a782db2d Reviewed-by: Yoann Lopes --- tests/auto/unit/qdeclarativeaudio/qdeclarativeaudio.pro | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/auto/unit/qdeclarativeaudio/qdeclarativeaudio.pro b/tests/auto/unit/qdeclarativeaudio/qdeclarativeaudio.pro index e36c7dc1f..86ca3068a 100644 --- a/tests/auto/unit/qdeclarativeaudio/qdeclarativeaudio.pro +++ b/tests/auto/unit/qdeclarativeaudio/qdeclarativeaudio.pro @@ -5,10 +5,12 @@ QT += multimedia-private qml testlib HEADERS += \ ../../../../src/imports/multimedia/qdeclarativeaudio_p.h \ + ../../../../src/imports/multimedia/qdeclarativeplaylist_p.h \ ../../../../src/imports/multimedia/qdeclarativemediametadata_p.h SOURCES += \ tst_qdeclarativeaudio.cpp \ + ../../../../src/imports/multimedia/qdeclarativeplaylist.cpp \ ../../../../src/imports/multimedia/qdeclarativeaudio.cpp INCLUDEPATH += ../../../../src/imports/multimedia -- cgit v1.2.1 From 3fb3231a9e22dcb780d5b31ec57896429d40b0e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Str=C3=B8mme?= Date: Wed, 30 Mar 2016 19:13:11 +0200 Subject: DirectShow: Release all filters when disconnecting the graph. When disconnecting the graph we need to make sure that all the filters in the graph are released, even the ones that are automatically added. Since we can't know in advance which filters the graph consists of, we need release them one by one. Task-number: QTBUG-49281 Change-Id: Ifdf2fb6fe1c90ab85b47565c5fe82b6ebe55b183 Reviewed-by: Friedemann Kleint Reviewed-by: Yoann Lopes --- src/plugins/directshow/camera/dscamerasession.cpp | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/plugins/directshow/camera/dscamerasession.cpp b/src/plugins/directshow/camera/dscamerasession.cpp index 2e92cb37d..3421f2cd1 100644 --- a/src/plugins/directshow/camera/dscamerasession.cpp +++ b/src/plugins/directshow/camera/dscamerasession.cpp @@ -1092,9 +1092,19 @@ void DSCameraSession::disconnectGraph() pPin = NULL; } - m_filterGraph->RemoveFilter(m_nullRendererFilter); - m_filterGraph->RemoveFilter(m_previewFilter); - m_filterGraph->RemoveFilter(m_sourceFilter); + // To avoid increasing the memory usage every time the graph is re-connected it's + // important that all filters are released; also the ones added by the "Intelligent Connect". + IEnumFilters *enumFilters = NULL; + hr = m_filterGraph->EnumFilters(&enumFilters); + if (SUCCEEDED(hr)) { + IBaseFilter *filter = NULL; + while (enumFilters->Next(1, &filter, NULL) == S_OK) { + m_filterGraph->RemoveFilter(filter); + enumFilters->Reset(); + filter->Release(); + } + enumFilters->Release(); + } } static bool qt_frameRateRangeGreaterThan(const QCamera::FrameRateRange &r1, const QCamera::FrameRateRange &r2) -- cgit v1.2.1 From 5d278bd7b8ef5b524a110c5a8106247a391deeba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Str=C3=B8mme?= Date: Tue, 5 Apr 2016 17:10:22 +0200 Subject: Remove AndroidManifest.xml from qmlvideofx example. The manifest in qmlvideofx example is useless, and with the strict requirement of API level 16 or higher (585287d0@qttools), it means it's not working out of the box anymore. To avoid similar issues in the future, this change just removes the manifest (instead of bumping the min. version). Task-number: QTBUG-52374 Change-Id: I6c672bdbe23935852c87c93e425003b7b6827771 Reviewed-by: Eskil Abrahamsen Blomfeldt --- .../video/qmlvideofx/android/AndroidManifest.xml | 48 ---------------------- .../multimedia/video/qmlvideofx/qmlvideofx.pro | 5 --- 2 files changed, 53 deletions(-) delete mode 100644 examples/multimedia/video/qmlvideofx/android/AndroidManifest.xml diff --git a/examples/multimedia/video/qmlvideofx/android/AndroidManifest.xml b/examples/multimedia/video/qmlvideofx/android/AndroidManifest.xml deleted file mode 100644 index 0612d484c..000000000 --- a/examples/multimedia/video/qmlvideofx/android/AndroidManifest.xml +++ /dev/null @@ -1,48 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/examples/multimedia/video/qmlvideofx/qmlvideofx.pro b/examples/multimedia/video/qmlvideofx/qmlvideofx.pro index e9633954c..678ba4c97 100644 --- a/examples/multimedia/video/qmlvideofx/qmlvideofx.pro +++ b/examples/multimedia/video/qmlvideofx/qmlvideofx.pro @@ -13,9 +13,4 @@ include($$PWD/../snippets/performancemonitor/performancemonitordeclarative.pri) target.path = $$[QT_INSTALL_EXAMPLES]/multimedia/video/qmlvideofx INSTALLS += target -ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android - -OTHER_FILES += \ - android/AndroidManifest.xml - QMAKE_INFO_PLIST = Info.plist -- cgit v1.2.1 From c9e668cdb634c6ae90a08f289442a50f07ef9405 Mon Sep 17 00:00:00 2001 From: Andreas Holzammer Date: Wed, 6 Apr 2016 12:47:09 +0200 Subject: wince: revert flipping Video content It turned out in my previous tests, that the codec which I used is buggy and does not play well with this documented behavior. Change-Id: I8aff9f68d449da10de4fa33073d5d5cbe9b2a281 Reviewed-by: Yoann Lopes --- src/plugins/directshow/player/directshowmediatype.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/plugins/directshow/player/directshowmediatype.cpp b/src/plugins/directshow/player/directshowmediatype.cpp index fcb254fe9..1be641f41 100644 --- a/src/plugins/directshow/player/directshowmediatype.cpp +++ b/src/plugins/directshow/player/directshowmediatype.cpp @@ -192,11 +192,9 @@ QVideoSurfaceFormat::Direction DirectShowMediaType::scanLineDirection(QVideoFram case QVideoFrame::Format_BGR24: case QVideoFrame::Format_RGB565: case QVideoFrame::Format_RGB555: -#ifndef Q_OS_WINCE return bmiHeader.biHeight < 0 ? QVideoSurfaceFormat::TopToBottom : QVideoSurfaceFormat::BottomToTop; -#endif default: return QVideoSurfaceFormat::TopToBottom; } -- cgit v1.2.1 From b26003419f054722c16cfc9bc3b4366261543bff Mon Sep 17 00:00:00 2001 From: BogDan Vatra Date: Wed, 27 Jan 2016 10:48:04 +0200 Subject: Android: Use the new QtAndroidPrivate::runOnAndroidThreadSync Change-Id: I47cb99d84ad87f3b0f6578d3fbdc22d788b31c57 Reviewed-by: Christian Stromme --- .../src/wrappers/jni/androidsurfaceview.cpp | 67 +++++++++------------- .../android/src/wrappers/jni/androidsurfaceview.h | 7 +-- 2 files changed, 27 insertions(+), 47 deletions(-) diff --git a/src/plugins/android/src/wrappers/jni/androidsurfaceview.cpp b/src/plugins/android/src/wrappers/jni/androidsurfaceview.cpp index d2c150d00..6eec85171 100644 --- a/src/plugins/android/src/wrappers/jni/androidsurfaceview.cpp +++ b/src/plugins/android/src/wrappers/jni/androidsurfaceview.cpp @@ -137,8 +137,32 @@ AndroidSurfaceView::AndroidSurfaceView() , m_surfaceHolder(0) , m_pendingVisible(-1) { - setAutoDelete(false); - QtAndroidPrivate::runOnUiThread(this, QJNIEnvironmentPrivate()); + QtAndroidPrivate::runOnAndroidThreadSync([this] { + m_surfaceView = QJNIObjectPrivate("android/view/SurfaceView", + "(Landroid/content/Context;)V", + QtAndroidPrivate::activity()); + }, QJNIEnvironmentPrivate()); + + Q_ASSERT(m_surfaceView.isValid()); + + QJNIObjectPrivate holder = m_surfaceView.callObjectMethod("getHolder", + "()Landroid/view/SurfaceHolder;"); + if (!holder.isValid()) { + m_surfaceView = QJNIObjectPrivate(); + } else { + m_surfaceHolder = new AndroidSurfaceHolder(holder); + connect(m_surfaceHolder, &AndroidSurfaceHolder::surfaceCreated, + this, &AndroidSurfaceView::surfaceCreated); + { // Lock now to avoid a race with handleSurfaceCreated() + QMutexLocker locker(shLock); + m_window = QWindow::fromWinId(WId(m_surfaceView.object())); + + if (m_pendingVisible != -1) + m_window->setVisible(m_pendingVisible); + if (m_pendingGeometry.isValid()) + m_window->setGeometry(m_pendingGeometry); + } + } } AndroidSurfaceView::~AndroidSurfaceView() @@ -168,43 +192,4 @@ void AndroidSurfaceView::setGeometry(int x, int y, int width, int height) m_pendingGeometry = QRect(x, y, width, height); } -bool AndroidSurfaceView::event(QEvent *e) -{ - if (e->type() == QEvent::User) { - Q_ASSERT(m_surfaceView.isValid()); - - QJNIObjectPrivate holder = m_surfaceView.callObjectMethod("getHolder", - "()Landroid/view/SurfaceHolder;"); - if (!holder.isValid()) { - m_surfaceView = QJNIObjectPrivate(); - } else { - m_surfaceHolder = new AndroidSurfaceHolder(holder); - connect(m_surfaceHolder, &AndroidSurfaceHolder::surfaceCreated, - this, &AndroidSurfaceView::surfaceCreated); - { // Lock now to avoid a race with handleSurfaceCreated() - QMutexLocker locker(shLock); - m_window = QWindow::fromWinId(WId(m_surfaceView.object())); - - if (m_pendingVisible != -1) - m_window->setVisible(m_pendingVisible); - if (m_pendingGeometry.isValid()) - m_window->setGeometry(m_pendingGeometry); - } - } - - return true; - } - - return QObject::event(e); -} - -// Called on the Android UI thread. -void AndroidSurfaceView::run() -{ - m_surfaceView = QJNIObjectPrivate("android/view/SurfaceView", - "(Landroid/content/Context;)V", - QtAndroidPrivate::activity()); - QCoreApplication::postEvent(this, new QEvent(QEvent::User)); -} - QT_END_NAMESPACE diff --git a/src/plugins/android/src/wrappers/jni/androidsurfaceview.h b/src/plugins/android/src/wrappers/jni/androidsurfaceview.h index 3d28f5325..ef603061d 100644 --- a/src/plugins/android/src/wrappers/jni/androidsurfaceview.h +++ b/src/plugins/android/src/wrappers/jni/androidsurfaceview.h @@ -74,7 +74,7 @@ private: friend class AndroidSurfaceView; }; -class AndroidSurfaceView : public QObject, public QRunnable +class AndroidSurfaceView : public QObject { Q_OBJECT public: @@ -86,14 +86,9 @@ public: void setVisible(bool v); void setGeometry(int x, int y, int width, int height); - bool event(QEvent *); - Q_SIGNALS: void surfaceCreated(); -protected: - void run() override; - private: QJNIObjectPrivate m_surfaceView; QWindow *m_window; -- cgit v1.2.1 From c8eed01f1ffe5ad03a82d0bb7c49b71d5cec09b3 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Wed, 6 Apr 2016 12:08:15 +0200 Subject: winrt: add default capabilities A module compiled for WinRT should define a default set of capabilities to enable all features specified by the module. Task-number: QTBUG-38802 Change-Id: I57c3aec60c72b1383b836cee2087b801196def1d Reviewed-by: Oliver Wolff Reviewed-by: Yoann Lopes --- src/multimedia/multimedia.pro | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/multimedia/multimedia.pro b/src/multimedia/multimedia.pro index acde6fe8e..761e488ba 100644 --- a/src/multimedia/multimedia.pro +++ b/src/multimedia/multimedia.pro @@ -82,6 +82,10 @@ ANDROID_FEATURES += \ android.hardware.camera.autofocus \ android.hardware.microphone +MODULE_WINRT_CAPABILITIES_DEVICE += \ + microphone \ + webcam + win32: LIBS_PRIVATE += -luuid HEADERS += $$PUBLIC_HEADERS $$PRIVATE_HEADERS -- cgit v1.2.1