From c609b0e6f8ab46e3e5282dd32fa124cb9e3fe110 Mon Sep 17 00:00:00 2001 From: Antti Kokko Date: Thu, 2 Nov 2017 13:16:17 +0200 Subject: Add changes file for Qt 5.9.3 Change-Id: Iaaee504e176f5b23c6894243a5f830ba88854355 Reviewed-by: Andy Shaw Reviewed-by: Christian Stromme --- dist/changes-5.9.3 | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 dist/changes-5.9.3 diff --git a/dist/changes-5.9.3 b/dist/changes-5.9.3 new file mode 100644 index 000000000..568224232 --- /dev/null +++ b/dist/changes-5.9.3 @@ -0,0 +1,58 @@ +Qt 5.9.3 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.9.0. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + +http://doc.qt.io/qt-5/index.html + +The Qt version 5.9 series is binary compatible with the 5.8.x series. +Applications compiled for 5.8 will continue to run with 5.9. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* Qt 5.9.3 Changes * +**************************************************************************** + +QtMultimedia +------------ + +- [QTBUG-53268] Fixed regression that caused relevant properties of the surface + format to be discarded when the video node was created. +- [QTBUG-62255] Fixed loading of remote m3u files. + +**************************************************************************** +* Platform Specific Changes * +**************************************************************************** + +Linux +----- + +- [QTBUG-62789] Fixed memory leak in QGstreamerAudioDecoderSession. +- [QTBUG-62245] Fixed input query in V4L code to correctly detect all cameras. +- Fixed memory leak in CameraBinImageCapture. + +QNX +--- + +- Switched to mmr_event_t based metadata retrieval, as PPS based retrieval is no + longer supported by Multimedia for QNX 7.0.0. + + +Android +------- + +- [QTBUG-51213] The scan line for the video surface format is now correctly + set to bottom-up. + +WinRT +----- + +- [QTBUG-63308] Added permission check for the camera. -- cgit v1.2.3 From 07ab9ae86cc536aada3692589061daac5d014bc3 Mon Sep 17 00:00:00 2001 From: Topi Reinio Date: Wed, 8 Nov 2017 13:27:16 +0100 Subject: Doc: Maintain the list of highlighted examples locally Previously the list was maintained in qtbase. Also, add highlighting for 'Media Player Example'. Task-number: QTBUG-60627 Change-Id: I030863ac89e2bac6a2322a52afaece2cc1c8dcd3 Reviewed-by: Nico Vertriest --- src/multimedia/doc/qtmultimedia.qdocconf | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/multimedia/doc/qtmultimedia.qdocconf b/src/multimedia/doc/qtmultimedia.qdocconf index e3d3827c5..074fcb75e 100644 --- a/src/multimedia/doc/qtmultimedia.qdocconf +++ b/src/multimedia/doc/qtmultimedia.qdocconf @@ -43,6 +43,9 @@ qhp.QtMultimedia.subprojects.examples.sortPages = true exampledirs += ../../../examples \ snippets +manifestmeta.highlighted.names = "QtMultimedia/QML Video Shader Effects Example" \ + "QtMultimedia/Media Player Example" + headerdirs += ../.. imagedirs += src/images \ -- cgit v1.2.3 From de00842296bf0e9e5d377deb95598276041f55e0 Mon Sep 17 00:00:00 2001 From: Antti Kokko Date: Wed, 8 Nov 2017 12:01:52 +0200 Subject: Add changes file for Qt 5.10.0 Change-Id: I24113695c1bb73fec5992bdcdc51199cb62c8d2c Reviewed-by: Christian Stromme --- dist/changes-5.10.0 | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 dist/changes-5.10.0 diff --git a/dist/changes-5.10.0 b/dist/changes-5.10.0 new file mode 100644 index 000000000..cbdb75b09 --- /dev/null +++ b/dist/changes-5.10.0 @@ -0,0 +1,41 @@ +Qt 5.10 introduces many new features and improvements as well as bugfixes +over the 5.9.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/index.html + +The Qt version 5.10 series is binary compatible with the 5.9.x series. +Applications compiled for 5.9 will continue to run with 5.10. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* Qt 5.10.0 Changes * +**************************************************************************** + + - [QTBUG-57045] Fixed crash when calling pause in the onPositionChanged + handler. + +**************************************************************************** +* Platform Specific Changes * +**************************************************************************** + +QNX +--- + - Added support for setting audio roles. + +Linux +----- + - [QTBUG-62621] Unsupported audio formats in PulseAudio will now be rejected + instead of being played incorrectly. + - [QTBUG-63427] QSoundEffect with PulseAudio now supports 24 bit samples. + +Windows +------- + - Added support for QMediaMetaData::Orientation. -- cgit v1.2.3 From 01c1973c68e1ba0c505e1c07e0aa0652faccc0c5 Mon Sep 17 00:00:00 2001 From: Alexander Ivash Date: Mon, 13 Nov 2017 22:57:05 +0300 Subject: QWasapiAudioDeviceInfo: fix QByteArray => QString conversion QByteArray was created inside 'QWasapiUtils::availableDevices' using 'toLocal8Bit' so needs to be converted to QString via 'fromLocal8Bit' Task-number: QTBUG-64262 Change-Id: I70cdaf35dbdbee671fbf7c4e1b46b18c13ca98cc Reviewed-by: Thiago Macieira Reviewed-by: Maurice Kalinowski --- src/plugins/wasapi/qwasapiaudiodeviceinfo.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/wasapi/qwasapiaudiodeviceinfo.cpp b/src/plugins/wasapi/qwasapiaudiodeviceinfo.cpp index e1a46841d..53345dec8 100644 --- a/src/plugins/wasapi/qwasapiaudiodeviceinfo.cpp +++ b/src/plugins/wasapi/qwasapiaudiodeviceinfo.cpp @@ -47,7 +47,7 @@ QT_BEGIN_NAMESPACE Q_LOGGING_CATEGORY(lcMmDeviceInfo, "qt.multimedia.deviceinfo") QWasapiAudioDeviceInfo::QWasapiAudioDeviceInfo(QByteArray dev, QAudio::Mode mode) - : m_deviceName(dev) + : m_deviceName(QString::fromLocal8Bit(dev)) { qCDebug(lcMmDeviceInfo) << __FUNCTION__ << dev << mode; m_interface = QWasapiUtils::createOrGetInterface(dev, mode); -- cgit v1.2.3 From b04e044e24d67dc6092d964247900e081b628623 Mon Sep 17 00:00:00 2001 From: Val Doroshchuk Date: Mon, 30 Oct 2017 13:48:43 +0100 Subject: WindowsAudio: Remove unneeded Sleep() when stopping playback To terminate playback waveOutReset is already used. Task-number: QTBUG-35916 Change-Id: I50d6c25c944b01d7dfe62b2f80ec153231818a33 Reviewed-by: Christian Stromme --- src/plugins/windowsaudio/qwindowsaudiooutput.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/plugins/windowsaudio/qwindowsaudiooutput.cpp b/src/plugins/windowsaudio/qwindowsaudiooutput.cpp index 815b78979..eb4caf128 100644 --- a/src/plugins/windowsaudio/qwindowsaudiooutput.cpp +++ b/src/plugins/windowsaudio/qwindowsaudiooutput.cpp @@ -298,10 +298,7 @@ void QWindowsAudioOutput::close() deviceState = QAudio::StoppedState; errorState = QAudio::NoError; - int delay = (buffer_size-bytesFree())*1000/(settings.sampleRate() - *settings.channelCount()*(settings.sampleSize()/8)); waveOutReset(hWaveOut); - Sleep(delay+10); freeBlocks(waveBlocks); waveOutClose(hWaveOut); -- cgit v1.2.3 From a621c53dd9103c3d41cb16763f7b7dba372b67a6 Mon Sep 17 00:00:00 2001 From: Val Doroshchuk Date: Mon, 13 Nov 2017 09:36:41 +0100 Subject: Fix crash when no supported formats are returned If waveInGetDevCaps or waveOutGetDevCaps returns MMSYSERR_NOERROR it does not mean that there are supported formats in the dwFormats field. Task-number: QTBUG-54242 Change-Id: I767ccc9570681685a27abd979ba9754034058e6f Reviewed-by: Christian Stromme --- src/plugins/windowsaudio/qwindowsaudiodeviceinfo.cpp | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/plugins/windowsaudio/qwindowsaudiodeviceinfo.cpp b/src/plugins/windowsaudio/qwindowsaudiodeviceinfo.cpp index 83e9ccfc8..c054c0f76 100644 --- a/src/plugins/windowsaudio/qwindowsaudiodeviceinfo.cpp +++ b/src/plugins/windowsaudio/qwindowsaudiodeviceinfo.cpp @@ -238,21 +238,16 @@ void QWindowsAudioDeviceInfo::updateLists() if (!sizez.isEmpty()) return; - bool hasCaps = false; DWORD fmt = 0; if(mode == QAudio::AudioOutput) { WAVEOUTCAPS woc; - if (waveOutGetDevCaps(devId, &woc, sizeof(WAVEOUTCAPS)) == MMSYSERR_NOERROR) { - hasCaps = true; + if (waveOutGetDevCaps(devId, &woc, sizeof(WAVEOUTCAPS)) == MMSYSERR_NOERROR) fmt = woc.dwFormats; - } } else { WAVEINCAPS woc; - if (waveInGetDevCaps(devId, &woc, sizeof(WAVEINCAPS)) == MMSYSERR_NOERROR) { - hasCaps = true; + if (waveInGetDevCaps(devId, &woc, sizeof(WAVEINCAPS)) == MMSYSERR_NOERROR) fmt = woc.dwFormats; - } } sizez.clear(); @@ -260,7 +255,7 @@ void QWindowsAudioDeviceInfo::updateLists() channelz.clear(); typez.clear(); - if (hasCaps) { + if (fmt) { // Check sample size if ((fmt & WAVE_FORMAT_1M08) || (fmt & WAVE_FORMAT_1S08) -- cgit v1.2.3 From 3598915a360c596da48c9e7b00ba8469cba5249a Mon Sep 17 00:00:00 2001 From: Christian Stromme Date: Mon, 27 Nov 2017 22:55:20 +0100 Subject: Revert "Android: Set the correct scan line for the video surface format" The change causes the video output to be shown upside down. This reverts commit 2ec485482d185f92e4de33f634bc3ef9dd6c9188. Task-number: QTBUG-64764 Change-Id: I9d3e63d2c0cce17d945b62ffead38ab5f58ace7f Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/plugins/android/src/common/qandroidvideooutput.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/plugins/android/src/common/qandroidvideooutput.cpp b/src/plugins/android/src/common/qandroidvideooutput.cpp index eb41d4a8e..b425b9d89 100644 --- a/src/plugins/android/src/common/qandroidvideooutput.cpp +++ b/src/plugins/android/src/common/qandroidvideooutput.cpp @@ -324,7 +324,6 @@ void QAndroidTextureVideoOutput::onFrameAvailable() if (!m_surface->isActive()) { QVideoSurfaceFormat format(frame.size(), frame.pixelFormat(), QAbstractVideoBuffer::GLTextureHandle); - format.setScanLineDirection(QVideoSurfaceFormat::BottomToTop); m_surface->start(format); } -- cgit v1.2.3 From 06eac9ba70ace125ea2835ef9aec854f231405b2 Mon Sep 17 00:00:00 2001 From: Val Doroshchuk Date: Tue, 24 Oct 2017 14:45:29 +0200 Subject: Windows: Fix EVR's rendering of GLTextureHandle frames When ANGLE is used and video frames have GLTextureHandle handle type black screen is shown while audio is working correctly. Fixed a bug when opengl texture has not been ever creating. Fixed a crash when releasing resources due to empty QOpenGLContext. Also moved gl initialization related code to OpenGLResources. Task-number: QTBUG-61407 Change-Id: Ifc92a4a2fa2e769494ef962203446a9b3e7dd86d Reviewed-by: Christian Stromme --- src/plugins/common/evr/evrd3dpresentengine.cpp | 159 +++++++++++++------------ 1 file changed, 86 insertions(+), 73 deletions(-) diff --git a/src/plugins/common/evr/evrd3dpresentengine.cpp b/src/plugins/common/evr/evrd3dpresentengine.cpp index 043d0ad73..754faef2d 100644 --- a/src/plugins/common/evr/evrd3dpresentengine.cpp +++ b/src/plugins/common/evr/evrd3dpresentengine.cpp @@ -47,6 +47,7 @@ #include #include #include +#include #ifdef MAYBE_ANGLE # include @@ -128,11 +129,65 @@ class OpenGLResources : public QObject { public: OpenGLResources() - : egl(new EGLWrapper) - , eglDisplay(0) - , eglSurface(0) - , glTexture(0) - {} + : m_egl(new EGLWrapper) + , m_eglDisplay(nullptr) + , m_eglSurface(nullptr) + , m_glTexture(0) + , m_glContext(QOpenGLContext::currentContext()) + { + Q_ASSERT(m_glContext); + } + + unsigned int glTexture() const + { + return m_glTexture; + } + + bool createTexture(const QVideoSurfaceFormat &format, IDirect3DDevice9Ex *device, + IDirect3DTexture9 **texture) + { + if (!m_glContext) + return false; + + m_glContext->functions()->glGenTextures(1, &m_glTexture); + QPlatformNativeInterface *nativeInterface = QGuiApplication::platformNativeInterface(); + m_eglDisplay = static_cast( + nativeInterface->nativeResourceForContext("eglDisplay", m_glContext)); + EGLConfig *eglConfig = static_cast( + nativeInterface->nativeResourceForContext("eglConfig", m_glContext)); + + const bool hasAlpha = m_glContext->format().hasAlpha(); + + EGLint attribs[] = { + EGL_WIDTH, format.frameWidth(), + EGL_HEIGHT, format.frameHeight(), + EGL_TEXTURE_FORMAT, (hasAlpha ? EGL_TEXTURE_RGBA : EGL_TEXTURE_RGB), + EGL_TEXTURE_TARGET, EGL_TEXTURE_2D, + EGL_NONE + }; + + m_eglSurface = m_egl->createPbufferSurface(m_eglDisplay, eglConfig, attribs); + + HANDLE share_handle = 0; + PFNEGLQUERYSURFACEPOINTERANGLEPROC eglQuerySurfacePointerANGLE = + reinterpret_cast( + m_egl->getProcAddress("eglQuerySurfacePointerANGLE")); + Q_ASSERT(eglQuerySurfacePointerANGLE); + eglQuerySurfacePointerANGLE( + m_eglDisplay, + m_eglSurface, + EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE, &share_handle); + + device->CreateTexture(format.frameWidth(), format.frameHeight(), 1, + D3DUSAGE_RENDERTARGET, + (hasAlpha ? D3DFMT_A8R8G8B8 : D3DFMT_X8R8G8B8), + D3DPOOL_DEFAULT, texture, &share_handle); + + m_glContext->functions()->glBindTexture(GL_TEXTURE_2D, m_glTexture); + m_egl->bindTexImage(m_eglDisplay, m_eglSurface, EGL_BACK_BUFFER); + + return texture != NULL; + } void release() { @@ -142,24 +197,32 @@ public: deleteLater(); } - EGLWrapper *egl; - EGLDisplay *eglDisplay; - EGLSurface eglSurface; - unsigned int glTexture; - private: + EGLWrapper *m_egl; + EGLDisplay *m_eglDisplay; + EGLSurface m_eglSurface; + unsigned int m_glTexture; + QOpenGLContext *m_glContext; + ~OpenGLResources() { - Q_ASSERT(QOpenGLContext::currentContext() != NULL); + QScopedPointer surface; + if (m_glContext != QOpenGLContext::currentContext()) { + surface.reset(new QOffscreenSurface); + surface->create(); + m_glContext->makeCurrent(surface.data()); + } - if (eglSurface && egl) { - egl->releaseTexImage(eglDisplay, eglSurface, EGL_BACK_BUFFER); - egl->destroySurface(eglDisplay, eglSurface); + if (m_eglSurface && m_egl) { + m_egl->releaseTexImage(m_eglDisplay, m_eglSurface, EGL_BACK_BUFFER); + m_egl->destroySurface(m_eglDisplay, m_eglSurface); } - if (glTexture) - QOpenGLContext::currentContext()->functions()->glDeleteTextures(1, &glTexture); + if (m_glTexture) + m_glContext->functions()->glDeleteTextures(1, &m_glTexture); - delete egl; + delete m_egl; + if (surface) + m_glContext->doneCurrent(); } }; @@ -257,9 +320,9 @@ QVariant IMFSampleVideoBuffer::handle() const if (handleType() != GLTextureHandle) return handle; - if (m_engine->m_glResources && (m_textureUpdated || m_engine->updateTexture(m_surface))) { + if (m_textureUpdated || m_engine->updateTexture(m_surface)) { m_textureUpdated = true; - handle = QVariant::fromValue(m_engine->m_glResources->glTexture); + handle = QVariant::fromValue(m_engine->m_glResources->glTexture()); } #endif @@ -553,61 +616,11 @@ QVideoFrame D3DPresentEngine::makeVideoFrame(IMFSample *sample) bool D3DPresentEngine::createRenderTexture() { - if (m_texture) - return true; - - Q_ASSERT(QOpenGLContext::currentContext() != NULL); - - if (!m_glResources) - m_glResources = new OpenGLResources; - - QOpenGLContext *currentContext = QOpenGLContext::currentContext(); - if (!currentContext) - return false; - - QPlatformNativeInterface *nativeInterface = QGuiApplication::platformNativeInterface(); - m_glResources->eglDisplay = static_cast( - nativeInterface->nativeResourceForContext("eglDisplay", currentContext)); - EGLConfig *eglConfig = static_cast( - nativeInterface->nativeResourceForContext("eglConfig", currentContext)); - - currentContext->functions()->glGenTextures(1, &m_glResources->glTexture); - - bool hasAlpha = currentContext->format().hasAlpha(); - - EGLint attribs[] = { - EGL_WIDTH, m_surfaceFormat.frameWidth(), - EGL_HEIGHT, m_surfaceFormat.frameHeight(), - EGL_TEXTURE_FORMAT, hasAlpha ? EGL_TEXTURE_RGBA : EGL_TEXTURE_RGB, - EGL_TEXTURE_TARGET, EGL_TEXTURE_2D, - EGL_NONE - }; - - EGLSurface pbuffer = m_glResources->egl->createPbufferSurface(m_glResources->eglDisplay, eglConfig, attribs); - - HANDLE share_handle = 0; - PFNEGLQUERYSURFACEPOINTERANGLEPROC eglQuerySurfacePointerANGLE = - reinterpret_cast(m_glResources->egl->getProcAddress("eglQuerySurfacePointerANGLE")); - Q_ASSERT(eglQuerySurfacePointerANGLE); - eglQuerySurfacePointerANGLE( - m_glResources->eglDisplay, - pbuffer, - EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE, &share_handle); - - - m_device->CreateTexture(m_surfaceFormat.frameWidth(), m_surfaceFormat.frameHeight(), 1, - D3DUSAGE_RENDERTARGET, - hasAlpha ? D3DFMT_A8R8G8B8 : D3DFMT_X8R8G8B8, - D3DPOOL_DEFAULT, - &m_texture, - &share_handle); - - m_glResources->eglSurface = pbuffer; - - QOpenGLContext::currentContext()->functions()->glBindTexture(GL_TEXTURE_2D, m_glResources->glTexture); - m_glResources->egl->bindTexImage(m_glResources->eglDisplay, m_glResources->eglSurface, EGL_BACK_BUFFER); + if (m_glResources) + m_glResources->release(); - return m_texture != NULL; + m_glResources = new OpenGLResources; + return m_glResources->createTexture(m_surfaceFormat, m_device, &m_texture); } bool D3DPresentEngine::updateTexture(IDirect3DSurface9 *src) -- cgit v1.2.3 From c60d87c314d467997701729104ce02c9ed5c6501 Mon Sep 17 00:00:00 2001 From: Christian Stromme Date: Mon, 27 Nov 2017 22:55:20 +0100 Subject: Revert "Android: Set the correct scan line for the video surface format" The change causes the video output to be shown upside down. This reverts commit 2ec485482d185f92e4de33f634bc3ef9dd6c9188. Task-number: QTBUG-64764 Change-Id: I9d3e63d2c0cce17d945b62ffead38ab5f58ace7f Reviewed-by: Eskil Abrahamsen Blomfeldt (cherry picked from commit 3598915a360c596da48c9e7b00ba8469cba5249a) --- src/plugins/android/src/common/qandroidvideooutput.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/plugins/android/src/common/qandroidvideooutput.cpp b/src/plugins/android/src/common/qandroidvideooutput.cpp index eb41d4a8e..b425b9d89 100644 --- a/src/plugins/android/src/common/qandroidvideooutput.cpp +++ b/src/plugins/android/src/common/qandroidvideooutput.cpp @@ -324,7 +324,6 @@ void QAndroidTextureVideoOutput::onFrameAvailable() if (!m_surface->isActive()) { QVideoSurfaceFormat format(frame.size(), frame.pixelFormat(), QAbstractVideoBuffer::GLTextureHandle); - format.setScanLineDirection(QVideoSurfaceFormat::BottomToTop); m_surface->start(format); } -- cgit v1.2.3 From 45deae83fdb245bfb94cc5b880f1740d3bf33b30 Mon Sep 17 00:00:00 2001 From: VaL Doroshchuk Date: Tue, 5 Dec 2017 09:50:12 +0100 Subject: ALSA: Don't check the device name in open() Each time when open() is called device name was checked for availability. Which could impact to performance especially for embedded devices. Also the check of device name is done while calling snd_pcm_open(). Task-number: QTBUG-63007 Change-Id: Ib0afe7326552968870f4ca95a7807ae8f704fd3f Reviewed-by: Christian Stromme --- src/plugins/alsa/qalsaaudiooutput.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/plugins/alsa/qalsaaudiooutput.cpp b/src/plugins/alsa/qalsaaudiooutput.cpp index cd97ae85b..ddbe04de9 100644 --- a/src/plugins/alsa/qalsaaudiooutput.cpp +++ b/src/plugins/alsa/qalsaaudiooutput.cpp @@ -316,9 +316,6 @@ bool QAlsaAudioOutput::open() return false; } - if (!QAlsaAudioDeviceInfo::availableDevices(QAudio::AudioOutput).contains(m_device)) - return false; - QString dev; #if SND_LIB_VERSION < 0x1000e // 1.0.14 if (m_device != "default") -- cgit v1.2.3 From f089c870c73999b767400fcb8c315e678b38bf2e Mon Sep 17 00:00:00 2001 From: VaL Doroshchuk Date: Mon, 4 Dec 2017 15:42:16 +0100 Subject: GStreamer: Emit an error if no input device provided for QCamera Prevents building a camera source if no input device name is provided. And emit an error immediately. Task-number: QTBUG-64155 Change-Id: I509bee1df0acb372d26f45fd27057f8b7e141c2a Reviewed-by: Christian Stromme --- src/plugins/gstreamer/camerabin/camerabinsession.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/plugins/gstreamer/camerabin/camerabinsession.cpp b/src/plugins/gstreamer/camerabin/camerabinsession.cpp index 4941c6ef6..823cfe408 100644 --- a/src/plugins/gstreamer/camerabin/camerabinsession.cpp +++ b/src/plugins/gstreamer/camerabin/camerabinsession.cpp @@ -466,6 +466,9 @@ GstElement *CameraBinSession::buildCameraSource() #if CAMERABIN_DEBUG qDebug() << Q_FUNC_INFO; #endif + if (m_inputDevice.isEmpty()) + return nullptr; + if (!m_inputDeviceHasChanged) return m_cameraSrc; @@ -482,7 +485,7 @@ GstElement *CameraBinSession::buildCameraSource() if (!m_cameraSrc) m_cameraSrc = camSrc; - if (m_cameraSrc && !m_inputDevice.isEmpty()) { + if (m_cameraSrc) { #if CAMERABIN_DEBUG qDebug() << "set camera device" << m_inputDevice; #endif -- cgit v1.2.3 From 0e7fb980e37e73748c7bdb0dbf17950c8afafc79 Mon Sep 17 00:00:00 2001 From: VaL Doroshchuk Date: Mon, 4 Dec 2017 15:20:44 +0100 Subject: GStreamer: Always notify CameraBinSession if a device has been selected CameraBinSession is never notified if a device has been unplugged and replaced by new one with the same index. Since QGstreamerVideoInputDeviceControl is for internal usage and dependent classes already check against the device name, we don't need to check it here. Task-number: QTBUG-64080 Change-Id: I064289335642d5d673f9db1ea206850968002d2e Reviewed-by: Christian Stromme --- src/gsttools/qgstreamervideoinputdevicecontrol.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/gsttools/qgstreamervideoinputdevicecontrol.cpp b/src/gsttools/qgstreamervideoinputdevicecontrol.cpp index 2f08575aa..86e6772b7 100644 --- a/src/gsttools/qgstreamervideoinputdevicecontrol.cpp +++ b/src/gsttools/qgstreamervideoinputdevicecontrol.cpp @@ -90,9 +90,8 @@ int QGstreamerVideoInputDeviceControl::selectedDevice() const void QGstreamerVideoInputDeviceControl::setSelectedDevice(int index) { - if (index != m_selectedDevice) { - m_selectedDevice = index; - emit selectedDeviceChanged(index); - emit selectedDeviceChanged(deviceName(index)); - } + // Always update selected device and proxy it to clients + m_selectedDevice = index; + emit selectedDeviceChanged(index); + emit selectedDeviceChanged(deviceName(index)); } -- cgit v1.2.3 From 10304528c20fb9a385c617a38b6be35d1b18598a Mon Sep 17 00:00:00 2001 From: Val Doroshchuk Date: Thu, 16 Nov 2017 15:02:23 +0100 Subject: DirectShow: Use pixel aspect ratio Originally pixel aspect ratio was clearing (set to 1,1) within renegotiating the media type. Which caused samples with not standard pixel aspect ratio (1,1) to be rendered with black squares on the top and the bottom. (Original size was kept but PAR cleared) Added a fix to keep PAR while adjusting the media type to optimal one and set original PAR to QVideoSurfaceFormat. Task-number: QTBUG-64438 Change-Id: I6d1a5c441b89bbd5cea86667cc570bb7eb19068b Reviewed-by: Yoann Lopes --- src/plugins/common/evr/evrcustompresenter.cpp | 7 ------- src/plugins/common/evr/evrd3dpresentengine.cpp | 4 ++++ 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/plugins/common/evr/evrcustompresenter.cpp b/src/plugins/common/evr/evrcustompresenter.cpp index 958204079..b07dbe719 100644 --- a/src/plugins/common/evr/evrcustompresenter.cpp +++ b/src/plugins/common/evr/evrcustompresenter.cpp @@ -1350,13 +1350,6 @@ HRESULT EVRCustomPresenter::createOptimalVideoType(IMFMediaType *proposedType, I // Modify the new type. - // Set the pixel aspect ratio (PAR) to 1:1 (see assumption #1, above) - // The ratio is packed in a single UINT64. A helper function is normally available for - // that (MFSetAttributeRatio) but it's not correctly defined in MinGW 4.9.1. - hr = mtOptimal->SetUINT64(MF_MT_PIXEL_ASPECT_RATIO, (((UINT64) 1) << 32) | ((UINT64) 1)); - if (FAILED(hr)) - goto done; - hr = proposedType->GetUINT64(MF_MT_FRAME_SIZE, &size); width = int(HI32(size)); height = int(LO32(size)); diff --git a/src/plugins/common/evr/evrd3dpresentengine.cpp b/src/plugins/common/evr/evrd3dpresentengine.cpp index fd9ccdef1..32d0acf91 100644 --- a/src/plugins/common/evr/evrd3dpresentengine.cpp +++ b/src/plugins/common/evr/evrd3dpresentengine.cpp @@ -518,6 +518,10 @@ done: : qt_evr_pixelFormatFromD3DFormat(d3dFormat), m_useTextureRendering ? QAbstractVideoBuffer::GLTextureHandle : QAbstractVideoBuffer::NoHandle); + UINT32 horizontal = 1, vertical = 1; + hr = MFGetAttributeRatio(format, MF_MT_PIXEL_ASPECT_RATIO, &horizontal, &vertical); + if (SUCCEEDED(hr)) + m_surfaceFormat.setPixelAspectRatio(horizontal, vertical); } else { releaseResources(); } -- cgit v1.2.3 From bb06d6d0b9b3fbea877e03cf3e6287ce73b8c8f6 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 12 Dec 2017 09:54:51 +0100 Subject: Bump version Change-Id: If1449d48ce39d9a65ae4792707ad87a918c2dce3 --- .qmake.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.qmake.conf b/.qmake.conf index 2108ac6fd..4f571fb57 100644 --- a/.qmake.conf +++ b/.qmake.conf @@ -1,3 +1,3 @@ load(qt_build_config) -MODULE_VERSION = 5.9.3 +MODULE_VERSION = 5.9.4 -- cgit v1.2.3 From 5f3c14d765783c275118e18f7ec47d02a7794f8f Mon Sep 17 00:00:00 2001 From: VaL Doroshchuk Date: Tue, 12 Dec 2017 10:40:18 +0100 Subject: Fix rendering issue with QGraphicsView and QOpenGLWidget viewport Since QOpenGLWidget always renders offscreen (uses QOffscreenSurface) the surface size is always (1, 1). Task-number: QTBUG-53099 Change-Id: I3803efba57e04c676eda85f0e29efa34f8d8d5e5 Reviewed-by: Laszlo Agocs --- src/multimediawidgets/qpaintervideosurface.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/multimediawidgets/qpaintervideosurface.cpp b/src/multimediawidgets/qpaintervideosurface.cpp index 6e93e150d..0147690e1 100644 --- a/src/multimediawidgets/qpaintervideosurface.cpp +++ b/src/multimediawidgets/qpaintervideosurface.cpp @@ -1254,8 +1254,8 @@ QAbstractVideoSurface::Error QVideoSurfaceGlslPainter::paint( if (scissorTestEnabled) glEnable(GL_SCISSOR_TEST); - const int width = QOpenGLContext::currentContext()->surface()->size().width(); - const int height = QOpenGLContext::currentContext()->surface()->size().height(); + const int width = painter->viewport().width(); + const int height = painter->viewport().height(); const QTransform transform = painter->deviceTransform(); -- cgit v1.2.3 From 10998733af8a3d54b795ee57a8df9a1b3e776aae Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Thu, 23 Nov 2017 14:55:04 +0100 Subject: AVFoundation: Use 90 for the front facing camera's orientation Since the information is not available as to what the orientation is from the AVFoundation API then we need to rely on common sense. Since the back facing camera is 270, then it stands to reason that the front one would be 90. This has been tested on macOS and iOS and all three cameras behave correctly. Task-number: QTBUG-37955 Change-Id: I1ab079cb5d4337948541e58321df51efbadf3e39 Reviewed-by: Andy Nichols --- src/plugins/avfoundation/camera/avfcamerasession.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/avfoundation/camera/avfcamerasession.mm b/src/plugins/avfoundation/camera/avfcamerasession.mm index 0b7c0e9d8..8e3436d39 100644 --- a/src/plugins/avfoundation/camera/avfcamerasession.mm +++ b/src/plugins/avfoundation/camera/avfcamerasession.mm @@ -234,7 +234,7 @@ void AVFCameraSession::updateCameraDevices() break; case AVCaptureDevicePositionFront: info.position = QCamera::FrontFace; - info.orientation = 270; + info.orientation = 90; break; default: info.position = QCamera::UnspecifiedPosition; -- cgit v1.2.3 From 08ff740f7d5350c8f03db95fdbfd32bf84d4c527 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Tue, 12 Dec 2017 13:32:48 +0100 Subject: winrt: Add audiocapture backend to standard build The backend itself works without modifications. The user has to take care to store at a location which the sandboxing allows. Task-number: QTBUG-60904 Change-Id: I52107d766fdbc5b952ea805b01662093be482459 Reviewed-by: Oliver Wolff --- src/plugins/plugins.pro | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/plugins/plugins.pro b/src/plugins/plugins.pro index 98a1bf242..71b9ec6e1 100644 --- a/src/plugins/plugins.pro +++ b/src/plugins/plugins.pro @@ -40,7 +40,8 @@ win32:!winrt { winrt { - SUBDIRS += winrt + SUBDIRS += winrt \ + audiocapture } unix:!mac:!android { -- cgit v1.2.3 From 68abdc5bb2042a0f896e822eecd5ed49350c0c43 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Tue, 12 Dec 2017 13:33:34 +0100 Subject: winrt: Store output to cache location By default sandboxing does not allow to store a file outside the package. Task-number: QTBUG-60904 Change-Id: I586616713315eadafd6bb24a8f8c12eb794557f6 Reviewed-by: Andy Shaw --- examples/multimedia/audiorecorder/audiorecorder.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/examples/multimedia/audiorecorder/audiorecorder.cpp b/examples/multimedia/audiorecorder/audiorecorder.cpp index 312b2d2aa..9dd3368e0 100644 --- a/examples/multimedia/audiorecorder/audiorecorder.cpp +++ b/examples/multimedia/audiorecorder/audiorecorder.cpp @@ -58,6 +58,7 @@ #include #include #include +#include static qreal getPeakValue(const QAudioFormat &format); static QVector getBufferLevels(const QAudioBuffer &buffer); @@ -221,7 +222,17 @@ void AudioRecorder::togglePause() void AudioRecorder::setOutputLocation() { +#ifdef Q_OS_WINRT + // UWP does not allow to store outside the sandbox + const QString cacheDir = QStandardPaths::writableLocation(QStandardPaths::CacheLocation); + if (!QDir().mkpath(cacheDir)) { + qWarning() << "Failed to create cache directory"; + return; + } + QString fileName = cacheDir + QLatin1String("/output.wav"); +#else QString fileName = QFileDialog::getSaveFileName(); +#endif m_audioRecorder->setOutputLocation(QUrl::fromLocalFile(fileName)); m_outputLocationSet = true; } -- cgit v1.2.3 From 7097e38a48db6ea25314121e70c48e8561399d98 Mon Sep 17 00:00:00 2001 From: VaL Doroshchuk Date: Fri, 1 Dec 2017 14:35:00 +0100 Subject: Fix memory leak in QSoundEffect If qthread is being exited all objects that belong to it also should be cleaned up. Task-number: QTBUG-64407 Change-Id: Ida09fcfac7e1ee2741c6e1b76a672a7a5775addc Reviewed-by: Christian Stromme --- src/multimedia/audio/qsamplecache_p.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/multimedia/audio/qsamplecache_p.cpp b/src/multimedia/audio/qsamplecache_p.cpp index 487346832..c76f51899 100644 --- a/src/multimedia/audio/qsamplecache_p.cpp +++ b/src/multimedia/audio/qsamplecache_p.cpp @@ -140,8 +140,11 @@ void QSampleCache::loadingRelease() QMutexLocker locker(&m_loadingMutex); m_loadingRefCount--; if (m_loadingRefCount == 0) { - if (m_loadingThread.isRunning()) + if (m_loadingThread.isRunning()) { + m_networkAccessManager->deleteLater(); + m_networkAccessManager = nullptr; m_loadingThread.exit(); + } } } -- cgit v1.2.3 From 8ec92863f13061c3dd2d56376eddfe258915589f Mon Sep 17 00:00:00 2001 From: Val Doroshchuk Date: Mon, 16 Oct 2017 13:26:15 +0200 Subject: DirectShow: Fix memory leak in CLSID_FilterGraph Fixed memory leak when using Filter Graph Manager by moving creation of the manager to worker thread and changing threading model from shared to application thread. Task-number: QTBUG-52713 Change-Id: I7725697ced1992959d18588303c329b4dfd56b2e Reviewed-by: Christian Stromme --- .../directshow/player/directshowplayerservice.cpp | 31 +++++++++++++++++----- .../directshow/player/directshowplayerservice.h | 4 ++- 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/src/plugins/directshow/player/directshowplayerservice.cpp b/src/plugins/directshow/player/directshowplayerservice.cpp index 8ee5d67a1..2218ca5ed 100644 --- a/src/plugins/directshow/player/directshowplayerservice.cpp +++ b/src/plugins/directshow/player/directshowplayerservice.cpp @@ -318,18 +318,15 @@ void DirectShowPlayerService::load(const QMediaContent &media, QIODevice *stream m_graphStatus = InvalidMedia; m_error = QMediaPlayer::ResourceError; } else { - // {36b73882-c2c8-11cf-8b46-00805f6cef60} - static const GUID iid_IFilterGraph2 = { - 0x36b73882, 0xc2c8, 0x11cf, {0x8b, 0x46, 0x00, 0x80, 0x5f, 0x6c, 0xef, 0x60} }; m_graphStatus = Loading; - m_graph = com_new(CLSID_FilterGraph, iid_IFilterGraph2); - if (stream) m_pendingTasks = SetStreamSource; else m_pendingTasks = SetUrlSource; + m_pendingTasks |= CreateGraph; + ::SetEvent(m_taskHandle); } @@ -340,6 +337,17 @@ void DirectShowPlayerService::load(const QMediaContent &media, QIODevice *stream updateStatus(); } +void DirectShowPlayerService::doCreateGraph(QMutexLocker *locker) +{ + Q_UNUSED(locker); + + // {36b73882-c2c8-11cf-8b46-00805f6cef60} + static const GUID iid_IFilterGraph2 = { + 0x36b73882, 0xc2c8, 0x11cf, {0x8b, 0x46, 0x00, 0x80, 0x5f, 0x6c, 0xef, 0x60} }; + + m_graph = com_new(CLSID_FilterGraphNoThread, iid_IFilterGraph2); +} + void DirectShowPlayerService::doSetUrlSource(QMutexLocker *locker) { IBaseFilter *source = 0; @@ -1686,6 +1694,8 @@ void DirectShowPlayerService::run() { QMutexLocker locker(&m_mutex); + CoInitialize(NULL); + for (;;) { while (m_pendingTasks == 0) { DWORD result = 0; @@ -1700,12 +1710,17 @@ void DirectShowPlayerService::run() } locker.relock(); - if (result == WAIT_OBJECT_0 + 1) { + if (m_graph && result == WAIT_OBJECT_0 + 1) { graphEvent(&locker); } } - if (m_pendingTasks & ReleaseGraph) { + if (m_pendingTasks & CreateGraph) { + m_pendingTasks ^= CreateGraph; + m_executingTask = CreateGraph; + + doCreateGraph(&locker); + } else if (m_pendingTasks & ReleaseGraph) { m_pendingTasks ^= ReleaseGraph; m_executingTask = ReleaseGraph; @@ -1798,6 +1813,8 @@ void DirectShowPlayerService::run() } m_executingTask = 0; } + + CoUninitialize(); } QT_END_NAMESPACE diff --git a/src/plugins/directshow/player/directshowplayerservice.h b/src/plugins/directshow/player/directshowplayerservice.h index 01d05449e..cc7b4dd3e 100644 --- a/src/plugins/directshow/player/directshowplayerservice.h +++ b/src/plugins/directshow/player/directshowplayerservice.h @@ -124,6 +124,7 @@ private: void run(); + void doCreateGraph(QMutexLocker *locker); void doSetUrlSource(QMutexLocker *locker); void doSetStreamSource(QMutexLocker *locker); void doRender(QMutexLocker *locker); @@ -169,7 +170,8 @@ private: ReleaseVideoProbe = 0x40000, ReleaseFilters = ReleaseGraph | ReleaseAudioOutput | ReleaseVideoOutput | ReleaseAudioProbe - | ReleaseVideoProbe + | ReleaseVideoProbe, + CreateGraph = 0x80000 }; enum Event -- cgit v1.2.3 From b69259b65707acc9fc3c0818f6affe53938cebc3 Mon Sep 17 00:00:00 2001 From: Val Doroshchuk Date: Fri, 24 Nov 2017 08:36:36 +0100 Subject: DirectShow: Fix rendering of overlapping MDI subwindows Media type MEDIASUBTYPE_RGB32 is 32 bytes per pixel (like 0x00RRGGBB). When MDI subwindows are overlapping bottom window with QImage::Format_RGB32 requires 0xffRRGGBB. If "not used byte" is not 0xFF rendering will not be correct (0x00 produces empty image). Changed samples to ARGB32 to provide alpha channel, which is 0xFF in most cases. If alpha channel is not set to 0xFF, the bottom window will still be rendered incorrectly. Task-number: QTBUG-51405 Change-Id: I69f15d3835f901a04bf39b079394c6292b793610 Reviewed-by: Christian Stromme --- src/plugins/directshow/camera/dscamerasession.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/directshow/camera/dscamerasession.cpp b/src/plugins/directshow/camera/dscamerasession.cpp index 55ab868ce..dc0dfc8b3 100644 --- a/src/plugins/directshow/camera/dscamerasession.cpp +++ b/src/plugins/directshow/camera/dscamerasession.cpp @@ -815,8 +815,8 @@ bool DSCameraSession::configurePreviewFormat() return false; } - // Set sample grabber format (always RGB32) - static const AM_MEDIA_TYPE grabberFormat { MEDIATYPE_Video, MEDIASUBTYPE_RGB32, 0, 0, 0, FORMAT_VideoInfo, nullptr, 0, nullptr}; + // Set sample grabber format + static const AM_MEDIA_TYPE grabberFormat { MEDIATYPE_Video, MEDIASUBTYPE_ARGB32, 0, 0, 0, FORMAT_VideoInfo, nullptr, 0, nullptr}; if (!m_previewSampleGrabber->setMediaType(&grabberFormat)) return false; -- cgit v1.2.3 From 5629823b05ca7d24924ac879b5a0469a3cb03e78 Mon Sep 17 00:00:00 2001 From: Val Doroshchuk Date: Wed, 18 Oct 2017 16:17:44 +0200 Subject: DirectShow: Add initialization of com library to service plugin In case when QCoreApplication is used the COM library was not initialized on the calling thread before the COM library calls were made. QApplication initializes it by calling OleInitialize(). Task-number: QTBUG-59320 Change-Id: I50a71b1bcc8a63f5a8ffd22c5d044f9c56de15f9 Reviewed-by: Timur Pocheptsov Reviewed-by: Christian Stromme --- src/plugins/directshow/dsserviceplugin.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/plugins/directshow/dsserviceplugin.cpp b/src/plugins/directshow/dsserviceplugin.cpp index 51be7e500..cb4f0cdf9 100644 --- a/src/plugins/directshow/dsserviceplugin.cpp +++ b/src/plugins/directshow/dsserviceplugin.cpp @@ -123,7 +123,9 @@ QMediaServiceProviderHint::Features DSServicePlugin::supportedFeatures( QByteArray DSServicePlugin::defaultDevice(const QByteArray &service) const { if (service == Q_MEDIASERVICE_CAMERA) { + addRefCount(); const QList &devs = DSVideoDeviceControl::availableDevices(); + releaseRefCount(); if (!devs.isEmpty()) return devs.first().first; } @@ -135,7 +137,9 @@ QList DSServicePlugin::devices(const QByteArray &service) const QList result; if (service == Q_MEDIASERVICE_CAMERA) { + addRefCount(); const QList &devs = DSVideoDeviceControl::availableDevices(); + releaseRefCount(); for (const DSVideoDeviceInfo &info : devs) result.append(info.first); } @@ -146,7 +150,9 @@ QList DSServicePlugin::devices(const QByteArray &service) const QString DSServicePlugin::deviceDescription(const QByteArray &service, const QByteArray &device) { if (service == Q_MEDIASERVICE_CAMERA) { + addRefCount(); const QList &devs = DSVideoDeviceControl::availableDevices(); + releaseRefCount(); for (const DSVideoDeviceInfo &info : devs) { if (info.first == device) return info.second; -- cgit v1.2.3 From 9caee039533168fbb546b563859770414e54fc94 Mon Sep 17 00:00:00 2001 From: VaL Doroshchuk Date: Fri, 27 Oct 2017 14:02:14 +0200 Subject: GStreamer: Prevent calling CameraBinSession::setStateHelper twice Since CameraBinSession::setStateHelper() is supposed to handle only pending states, added a fix to prevent calling it twice. Otherwise CameraBinSession::load() can be called few times which might lead an error from gstreamer. Possible call stack: CameraBinSession::setState() CameraBinSession::setStateHelper() CameraBinSession::load() CameraBinSession::setStatus() CameraBinSession::setStateHelper() CameraBinSession::load() << gst_element_set_state is called also twice Task-number: QTBUG-53204 Change-Id: I00c66f91cd3b885c70848245da725ff68943fad2 Reviewed-by: Christian Stromme --- src/plugins/gstreamer/camerabin/camerabinsession.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/plugins/gstreamer/camerabin/camerabinsession.cpp b/src/plugins/gstreamer/camerabin/camerabinsession.cpp index 4941c6ef6..f06d95ea3 100644 --- a/src/plugins/gstreamer/camerabin/camerabinsession.cpp +++ b/src/plugins/gstreamer/camerabin/camerabinsession.cpp @@ -729,18 +729,21 @@ void CameraBinSession::setState(QCamera::State newState) if (newState == m_pendingState) return; - m_pendingState = newState; - emit pendingStateChanged(m_pendingState); + emit pendingStateChanged(newState); #if CAMERABIN_DEBUG qDebug() << Q_FUNC_INFO << newState; #endif setStateHelper(newState); + m_pendingState = newState; } void CameraBinSession::setStateHelper(QCamera::State state) { + if (state == m_pendingState) + return; + switch (state) { case QCamera::UnloadedState: unload(); -- cgit v1.2.3 From 93630cd621b472d73fc8456ca396cda012a1aee0 Mon Sep 17 00:00:00 2001 From: Jochen Seemann Date: Thu, 23 Nov 2017 21:12:24 +0100 Subject: examples: use Qt5-style connects where possible Additionally, remove obsolete CHECKED_CONNECT macro from the spectrum example. Change-Id: Id6fe01718679463c2b025d688c970583d64d60e9 Reviewed-by: VaL Doroshchuk Reviewed-by: Christian Stromme --- examples/multimedia/audiodecoder/audiodecoder.cpp | 26 +++++--- examples/multimedia/audiodecoder/main.cpp | 3 +- .../multimedia/declarative-camera/qmlcamera.cpp | 3 +- examples/multimedia/radio/radio.cpp | 24 ++++--- examples/multimedia/spectrum/app/engine.cpp | 28 ++++---- examples/multimedia/spectrum/app/levelmeter.cpp | 3 +- examples/multimedia/spectrum/app/mainwidget.cpp | 78 +++++++++++----------- .../multimedia/spectrum/app/settingsdialog.cpp | 20 +++--- examples/multimedia/spectrum/app/spectrum.h | 16 ----- .../multimedia/spectrum/app/spectrumanalyser.cpp | 4 +- .../spectrum/app/tonegeneratordialog.cpp | 20 +++--- examples/multimedia/video/qmlvideo/main.cpp | 2 +- .../qmlapplicationviewer/qmlapplicationviewer.cpp | 4 +- .../snippets/frequencymonitor/frequencymonitor.cpp | 12 ++-- .../customvideoitem/videoplayer.cpp | 23 ++++--- .../customvideowidget/videoplayer.cpp | 19 +++--- 16 files changed, 145 insertions(+), 140 deletions(-) diff --git a/examples/multimedia/audiodecoder/audiodecoder.cpp b/examples/multimedia/audiodecoder/audiodecoder.cpp index 5145d529e..86904f7c9 100644 --- a/examples/multimedia/audiodecoder/audiodecoder.cpp +++ b/examples/multimedia/audiodecoder/audiodecoder.cpp @@ -67,15 +67,23 @@ AudioDecoder::AudioDecoder(bool isPlayback, bool isDelete) format.setSampleType(QAudioFormat::SignedInt); m_decoder.setAudioFormat(format); - connect(&m_decoder, SIGNAL(bufferReady()), this, SLOT(bufferReady())); - connect(&m_decoder, SIGNAL(error(QAudioDecoder::Error)), this, SLOT(error(QAudioDecoder::Error))); - connect(&m_decoder, SIGNAL(stateChanged(QAudioDecoder::State)), this, SLOT(stateChanged(QAudioDecoder::State))); - connect(&m_decoder, SIGNAL(finished()), this, SLOT(finished())); - connect(&m_decoder, SIGNAL(positionChanged(qint64)), this, SLOT(updateProgress())); - connect(&m_decoder, SIGNAL(durationChanged(qint64)), this, SLOT(updateProgress())); - - connect(&m_soundEffect, SIGNAL(statusChanged()), this, SLOT(playbackStatusChanged())); - connect(&m_soundEffect, SIGNAL(playingChanged()), this, SLOT(playingChanged())); + connect(&m_decoder, &QAudioDecoder::bufferReady, + this, &AudioDecoder::bufferReady); + connect(&m_decoder, QOverload::of(&QAudioDecoder::error), + this, QOverload::of(&AudioDecoder::error)); + connect(&m_decoder, &QAudioDecoder::stateChanged, + this, &AudioDecoder::stateChanged); + connect(&m_decoder, &QAudioDecoder::finished, + this, &AudioDecoder::finished); + connect(&m_decoder, &QAudioDecoder::positionChanged, + this, &AudioDecoder::updateProgress); + connect(&m_decoder, &QAudioDecoder::durationChanged, + this, &AudioDecoder::updateProgress); + + connect(&m_soundEffect, &QSoundEffect::statusChanged, + this, &AudioDecoder::playbackStatusChanged); + connect(&m_soundEffect, &QSoundEffect::playingChanged, + this, &AudioDecoder::playingChanged); m_progress = -1.0; } diff --git a/examples/multimedia/audiodecoder/main.cpp b/examples/multimedia/audiodecoder/main.cpp index 2b4b9dab4..c0947b83f 100644 --- a/examples/multimedia/audiodecoder/main.cpp +++ b/examples/multimedia/audiodecoder/main.cpp @@ -95,7 +95,8 @@ int main(int argc, char *argv[]) targetFile.setFile(sourceFile.dir().absoluteFilePath("out.wav")); AudioDecoder decoder(isPlayback, isDelete); - QObject::connect(&decoder, SIGNAL(done()), &app, SLOT(quit())); + QObject::connect(&decoder, &AudioDecoder::done, + &app, &QCoreApplication::quit); decoder.setSourceFilename(sourceFile.absoluteFilePath()); decoder.setTargetFilename(targetFile.absoluteFilePath()); decoder.start(); diff --git a/examples/multimedia/declarative-camera/qmlcamera.cpp b/examples/multimedia/declarative-camera/qmlcamera.cpp index 1118e0dc0..edffe6bb0 100644 --- a/examples/multimedia/declarative-camera/qmlcamera.cpp +++ b/examples/multimedia/declarative-camera/qmlcamera.cpp @@ -59,7 +59,8 @@ int main(int argc, char* argv[]) view.setResizeMode(QQuickView::SizeRootObjectToView); // Qt.quit() called in embedded .qml by default only emits // quit() signal, so do this (optionally use Qt.exit()). - QObject::connect(view.engine(), SIGNAL(quit()), qApp, SLOT(quit())); + QObject::connect(view.engine(), &QQmlEngine::quit, + qApp, &QGuiApplication::quit); view.setSource(QUrl("qrc:///declarative-camera.qml")); view.resize(800, 480); view.show(); diff --git a/examples/multimedia/radio/radio.cpp b/examples/multimedia/radio/radio.cpp index c6bac969a..f4c9f5531 100644 --- a/examples/multimedia/radio/radio.cpp +++ b/examples/multimedia/radio/radio.cpp @@ -53,7 +53,8 @@ Radio::Radio() { radio = new QRadioTuner; - connect(radio, SIGNAL(error(QRadioTuner::Error)), this, SLOT(error(QRadioTuner::Error))); + connect(radio, QOverload::of(&QRadioTuner::error), + this, QOverload::of(&Radio::error)); if (radio->isBandSupported(QRadioTuner::FM)) radio->setBand(QRadioTuner::FM); @@ -68,7 +69,8 @@ Radio::Radio() freq = new QLabel; freq->setText(QString("%1 kHz").arg(radio->frequency()/1000)); topBar->addWidget(freq); - connect(radio, SIGNAL(frequencyChanged(int)), SLOT(freqChanged(int))); + connect(radio, &QRadioTuner::frequencyChanged, + this, &Radio::freqChanged); signal = new QLabel; if (radio->isAvailable()) @@ -76,34 +78,40 @@ Radio::Radio() else signal->setText(tr("No radio found")); topBar->addWidget(signal); - connect(radio, SIGNAL(signalStrengthChanged(int)), SLOT(signalChanged(int))); + connect(radio, &QRadioTuner::signalStrengthChanged, + this, &Radio::signalChanged); volumeSlider = new QSlider(Qt::Vertical,this); volumeSlider->setRange(0, 100); volumeSlider->setValue(50); - connect(volumeSlider, SIGNAL(valueChanged(int)), SLOT(updateVolume(int))); + connect(volumeSlider, &QSlider::valueChanged, + this, &Radio::updateVolume); topBar->addWidget(volumeSlider); layout->addLayout(buttonBar); searchLeft = new QPushButton; searchLeft->setText(tr("scan Down")); - connect(searchLeft, SIGNAL(clicked()), SLOT(searchDown())); + connect(searchLeft, &QPushButton::clicked, + this, &Radio::searchDown); buttonBar->addWidget(searchLeft); left = new QPushButton; left->setText(tr("Freq Down")); - connect(left, SIGNAL(clicked()), SLOT(freqDown())); + connect(left, &QPushButton::clicked, + this, &Radio::freqDown); buttonBar->addWidget(left); right = new QPushButton; - connect(right, SIGNAL(clicked()), SLOT(freqUp())); + connect(right, &QPushButton::clicked, + this, &Radio::freqUp); right->setText(tr("Freq Up")); buttonBar->addWidget(right); searchRight = new QPushButton; searchRight->setText(tr("scan Up")); - connect(searchRight, SIGNAL(clicked()), SLOT(searchUp())); + connect(searchRight, &QPushButton::clicked, + this, &Radio::searchUp); buttonBar->addWidget(searchRight); window->setLayout(layout); diff --git a/examples/multimedia/spectrum/app/engine.cpp b/examples/multimedia/spectrum/app/engine.cpp index eb289ca6c..7e11d012b 100644 --- a/examples/multimedia/spectrum/app/engine.cpp +++ b/examples/multimedia/spectrum/app/engine.cpp @@ -108,10 +108,8 @@ Engine::Engine(QObject *parent) { qRegisterMetaType("FrequencySpectrum"); qRegisterMetaType("WindowFunction"); - CHECKED_CONNECT(&m_spectrumAnalyser, - SIGNAL(spectrumChanged(FrequencySpectrum)), - this, - SLOT(spectrumChanged(FrequencySpectrum))); + connect(&m_spectrumAnalyser, QOverload::of(&SpectrumAnalyser::spectrumChanged), + this, QOverload::of(&Engine::spectrumChanged)); // This code might misinterpret things like "-something -category". But // it's unlikely that that needs to be supported so we'll let it go. @@ -243,16 +241,17 @@ void Engine::startRecording() setRecordPosition(0, true); stopPlayback(); m_mode = QAudio::AudioInput; - CHECKED_CONNECT(m_audioInput, SIGNAL(stateChanged(QAudio::State)), - this, SLOT(audioStateChanged(QAudio::State))); - CHECKED_CONNECT(m_audioInput, SIGNAL(notify()), - this, SLOT(audioNotify())); + connect(m_audioInput, &QAudioInput::stateChanged, + this, &Engine::audioStateChanged); + connect(m_audioInput, &QAudioInput::notify, + this, &Engine::audioNotify); + m_count = 0; m_dataLength = 0; emit dataLengthChanged(0); m_audioInputIODevice = m_audioInput->start(); - CHECKED_CONNECT(m_audioInputIODevice, SIGNAL(readyRead()), - this, SLOT(audioDataReady())); + connect(m_audioInputIODevice, &QIODevice::readyRead, + this, &Engine::audioDataReady); } } } @@ -275,10 +274,11 @@ void Engine::startPlayback() setPlayPosition(0, true); stopRecording(); m_mode = QAudio::AudioOutput; - CHECKED_CONNECT(m_audioOutput, SIGNAL(stateChanged(QAudio::State)), - this, SLOT(audioStateChanged(QAudio::State))); - CHECKED_CONNECT(m_audioOutput, SIGNAL(notify()), - this, SLOT(audioNotify())); + connect(m_audioOutput, &QAudioOutput::stateChanged, + this, &Engine::audioStateChanged); + connect(m_audioOutput, &QAudioOutput::notify, + this, &Engine::audioNotify); + m_count = 0; if (m_file) { m_file->seek(0); diff --git a/examples/multimedia/spectrum/app/levelmeter.cpp b/examples/multimedia/spectrum/app/levelmeter.cpp index a2741d23f..1c720905c 100644 --- a/examples/multimedia/spectrum/app/levelmeter.cpp +++ b/examples/multimedia/spectrum/app/levelmeter.cpp @@ -77,7 +77,8 @@ LevelMeter::LevelMeter(QWidget *parent) setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred); setMinimumWidth(30); - connect(m_redrawTimer, SIGNAL(timeout()), this, SLOT(redrawTimerExpired())); + connect(m_redrawTimer, &QTimer::timeout, + this, &LevelMeter::redrawTimerExpired); m_redrawTimer->start(RedrawInterval); } diff --git a/examples/multimedia/spectrum/app/mainwidget.cpp b/examples/multimedia/spectrum/app/mainwidget.cpp index 6585fec94..945313f32 100644 --- a/examples/multimedia/spectrum/app/mainwidget.cpp +++ b/examples/multimedia/spectrum/app/mainwidget.cpp @@ -339,62 +339,62 @@ void MainWidget::createUi() void MainWidget::connectUi() { - CHECKED_CONNECT(m_recordButton, SIGNAL(clicked()), - m_engine, SLOT(startRecording())); + connect(m_recordButton, &QPushButton::clicked, + m_engine, &Engine::startRecording); - CHECKED_CONNECT(m_pauseButton, SIGNAL(clicked()), - m_engine, SLOT(suspend())); + connect(m_pauseButton, &QPushButton::clicked, + m_engine, &Engine::suspend); - CHECKED_CONNECT(m_playButton, SIGNAL(clicked()), - m_engine, SLOT(startPlayback())); + connect(m_playButton, &QPushButton::clicked, + m_engine, &Engine::startPlayback); - CHECKED_CONNECT(m_settingsButton, SIGNAL(clicked()), - this, SLOT(showSettingsDialog())); + connect(m_settingsButton, &QPushButton::clicked, + this, &MainWidget::showSettingsDialog); - CHECKED_CONNECT(m_engine, SIGNAL(stateChanged(QAudio::Mode,QAudio::State)), - this, SLOT(stateChanged(QAudio::Mode,QAudio::State))); + connect(m_engine, &Engine::stateChanged, + this, &MainWidget::stateChanged); - CHECKED_CONNECT(m_engine, SIGNAL(formatChanged(const QAudioFormat &)), - this, SLOT(formatChanged(const QAudioFormat &))); + connect(m_engine, &Engine::formatChanged, + this, &MainWidget::formatChanged); m_progressBar->bufferLengthChanged(m_engine->bufferLength()); - CHECKED_CONNECT(m_engine, SIGNAL(bufferLengthChanged(qint64)), - this, SLOT(bufferLengthChanged(qint64))); + connect(m_engine, &Engine::bufferLengthChanged, + this, &MainWidget::bufferLengthChanged); - CHECKED_CONNECT(m_engine, SIGNAL(dataLengthChanged(qint64)), - this, SLOT(updateButtonStates())); + connect(m_engine, &Engine::dataLengthChanged, + this, &MainWidget::updateButtonStates); - CHECKED_CONNECT(m_engine, SIGNAL(recordPositionChanged(qint64)), - m_progressBar, SLOT(recordPositionChanged(qint64))); + connect(m_engine, &Engine::recordPositionChanged, + m_progressBar, &ProgressBar::recordPositionChanged); - CHECKED_CONNECT(m_engine, SIGNAL(playPositionChanged(qint64)), - m_progressBar, SLOT(playPositionChanged(qint64))); + connect(m_engine, &Engine::playPositionChanged, + m_progressBar, &ProgressBar::playPositionChanged); - CHECKED_CONNECT(m_engine, SIGNAL(recordPositionChanged(qint64)), - this, SLOT(audioPositionChanged(qint64))); + connect(m_engine, &Engine::recordPositionChanged, + this, &MainWidget::audioPositionChanged); - CHECKED_CONNECT(m_engine, SIGNAL(playPositionChanged(qint64)), - this, SLOT(audioPositionChanged(qint64))); + connect(m_engine, &Engine::playPositionChanged, + this, &MainWidget::audioPositionChanged); - CHECKED_CONNECT(m_engine, SIGNAL(levelChanged(qreal, qreal, int)), - m_levelMeter, SLOT(levelChanged(qreal, qreal, int))); + connect(m_engine, &Engine::levelChanged, + m_levelMeter, &LevelMeter::levelChanged); - CHECKED_CONNECT(m_engine, SIGNAL(spectrumChanged(qint64, qint64, const FrequencySpectrum &)), - this, SLOT(spectrumChanged(qint64, qint64, const FrequencySpectrum &))); + connect(m_engine, QOverload::of(&Engine::spectrumChanged), + this, QOverload::of(&MainWidget::spectrumChanged)); - CHECKED_CONNECT(m_engine, SIGNAL(infoMessage(QString, int)), - this, SLOT(infoMessage(QString, int))); + connect(m_engine, &Engine::infoMessage, + this, &MainWidget::infoMessage); - CHECKED_CONNECT(m_engine, SIGNAL(errorMessage(QString, QString)), - this, SLOT(errorMessage(QString, QString))); + connect(m_engine, &Engine::errorMessage, + this, &MainWidget::errorMessage); - CHECKED_CONNECT(m_spectrograph, SIGNAL(infoMessage(QString, int)), - this, SLOT(infoMessage(QString, int))); + connect(m_spectrograph, &Spectrograph::infoMessage, + this, &MainWidget::infoMessage); #ifndef DISABLE_WAVEFORM - CHECKED_CONNECT(m_engine, SIGNAL(bufferChanged(qint64, qint64, const QByteArray &)), - m_waveform, SLOT(bufferChanged(qint64, qint64, const QByteArray &))); + connect(m_engine, &Engine::bufferChanged, + m_waveform, &Waveform::bufferChanged); #endif } @@ -410,9 +410,9 @@ void MainWidget::createMenus() m_generateToneAction->setCheckable(true); m_recordAction->setCheckable(true); - connect(m_loadFileAction, SIGNAL(triggered(bool)), this, SLOT(showFileDialog())); - connect(m_generateToneAction, SIGNAL(triggered(bool)), this, SLOT(showToneGeneratorDialog())); - connect(m_recordAction, SIGNAL(triggered(bool)), this, SLOT(initializeRecord())); + connect(m_loadFileAction, &QAction::triggered, this, &MainWidget::showFileDialog); + connect(m_generateToneAction, &QAction::triggered, this, &MainWidget::showToneGeneratorDialog); + connect(m_recordAction, &QAction::triggered, this, &MainWidget::initializeRecord); } void MainWidget::updateButtonStates() diff --git a/examples/multimedia/spectrum/app/settingsdialog.cpp b/examples/multimedia/spectrum/app/settingsdialog.cpp index 109817cd2..f1723077e 100644 --- a/examples/multimedia/spectrum/app/settingsdialog.cpp +++ b/examples/multimedia/spectrum/app/settingsdialog.cpp @@ -114,12 +114,12 @@ SettingsDialog::SettingsDialog( windowFunctionLayout.take(); // ownership transferred to dialogLayout // Connect - CHECKED_CONNECT(m_inputDeviceComboBox, SIGNAL(activated(int)), - this, SLOT(inputDeviceChanged(int))); - CHECKED_CONNECT(m_outputDeviceComboBox, SIGNAL(activated(int)), - this, SLOT(outputDeviceChanged(int))); - CHECKED_CONNECT(m_windowFunctionComboBox, SIGNAL(activated(int)), - this, SLOT(windowFunctionChanged(int))); + connect(m_inputDeviceComboBox, QOverload::of(&QComboBox::activated), + this, &SettingsDialog::inputDeviceChanged); + connect(m_outputDeviceComboBox, QOverload::of(&QComboBox::activated), + this, &SettingsDialog::outputDeviceChanged); + connect(m_windowFunctionComboBox, QOverload::of(&QComboBox::activated), + this, &SettingsDialog::windowFunctionChanged); // Add standard buttons to layout QDialogButtonBox *buttonBox = new QDialogButtonBox(this); @@ -127,10 +127,10 @@ SettingsDialog::SettingsDialog( dialogLayout->addWidget(buttonBox); // Connect standard buttons - CHECKED_CONNECT(buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), - this, SLOT(accept())); - CHECKED_CONNECT(buttonBox->button(QDialogButtonBox::Cancel), SIGNAL(clicked()), - this, SLOT(reject())); + connect(buttonBox->button(QDialogButtonBox::Ok), &QPushButton::clicked, + this, &SettingsDialog::accept); + connect(buttonBox->button(QDialogButtonBox::Cancel), &QPushButton::clicked, + this, &SettingsDialog::reject); setLayout(dialogLayout); } diff --git a/examples/multimedia/spectrum/app/spectrum.h b/examples/multimedia/spectrum/app/spectrum.h index 1d0eedeff..aea9ce7c5 100644 --- a/examples/multimedia/spectrum/app/spectrum.h +++ b/examples/multimedia/spectrum/app/spectrum.h @@ -130,22 +130,6 @@ struct SweptTone qreal amplitude; }; - -//----------------------------------------------------------------------------- -// Macros -//----------------------------------------------------------------------------- - -// Macro which connects a signal to a slot, and which causes application to -// abort if the connection fails. This is intended to catch programming errors -// such as mis-typing a signal or slot name. It is necessary to write our own -// macro to do this - the following idiom -// Q_ASSERT(connect(source, signal, receiver, slot)); -// will not work because Q_ASSERT compiles to a no-op in release builds. - -#define CHECKED_CONNECT(source, signal, receiver, slot) \ - if (!connect(source, signal, receiver, slot)) \ - qt_assert_x(Q_FUNC_INFO, "CHECKED_CONNECT failed", __FILE__, __LINE__); - // Handle some dependencies between macros defined in the .pro file #ifdef DISABLE_WAVEFORM diff --git a/examples/multimedia/spectrum/app/spectrumanalyser.cpp b/examples/multimedia/spectrum/app/spectrumanalyser.cpp index 466c67188..ee024147f 100644 --- a/examples/multimedia/spectrum/app/spectrumanalyser.cpp +++ b/examples/multimedia/spectrum/app/spectrumanalyser.cpp @@ -172,8 +172,8 @@ SpectrumAnalyser::SpectrumAnalyser(QObject *parent) , m_count(0) #endif { - CHECKED_CONNECT(m_thread, SIGNAL(calculationComplete(FrequencySpectrum)), - this, SLOT(calculationComplete(FrequencySpectrum))); + connect(m_thread, &SpectrumAnalyserThread::calculationComplete, + this, &SpectrumAnalyser::calculationComplete); } SpectrumAnalyser::~SpectrumAnalyser() diff --git a/examples/multimedia/spectrum/app/tonegeneratordialog.cpp b/examples/multimedia/spectrum/app/tonegeneratordialog.cpp index 55f998417..76fe5d2e3 100644 --- a/examples/multimedia/spectrum/app/tonegeneratordialog.cpp +++ b/examples/multimedia/spectrum/app/tonegeneratordialog.cpp @@ -106,12 +106,12 @@ ToneGeneratorDialog::ToneGeneratorDialog(QWidget *parent) dialogLayout->addWidget(m_toneGeneratorControl); // Connect - CHECKED_CONNECT(m_toneGeneratorSweepCheckBox, SIGNAL(toggled(bool)), - this, SLOT(frequencySweepEnabled(bool))); - CHECKED_CONNECT(m_frequencySlider, SIGNAL(valueChanged(int)), - m_frequencySpinBox, SLOT(setValue(int))); - CHECKED_CONNECT(m_frequencySpinBox, SIGNAL(valueChanged(int)), - m_frequencySlider, SLOT(setValue(int))); + connect(m_toneGeneratorSweepCheckBox, &QCheckBox::toggled, + this, &ToneGeneratorDialog::frequencySweepEnabled); + connect(m_frequencySlider, &QSlider::valueChanged, + m_frequencySpinBox, &QSpinBox::setValue); + connect(m_frequencySpinBox, QOverload::of(&QSpinBox::valueChanged), + m_frequencySlider, &QSlider::setValue); // Add standard buttons to layout QDialogButtonBox *buttonBox = new QDialogButtonBox(this); @@ -119,10 +119,10 @@ ToneGeneratorDialog::ToneGeneratorDialog(QWidget *parent) dialogLayout->addWidget(buttonBox); // Connect standard buttons - CHECKED_CONNECT(buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), - this, SLOT(accept())); - CHECKED_CONNECT(buttonBox->button(QDialogButtonBox::Cancel), SIGNAL(clicked()), - this, SLOT(reject())); + connect(buttonBox->button(QDialogButtonBox::Ok), &QPushButton::clicked, + this, &ToneGeneratorDialog::accept); + connect(buttonBox->button(QDialogButtonBox::Cancel), &QPushButton::clicked, + this, &ToneGeneratorDialog::reject); setLayout(dialogLayout); } diff --git a/examples/multimedia/video/qmlvideo/main.cpp b/examples/multimedia/video/qmlvideo/main.cpp index a09ea534e..e288c0ae4 100644 --- a/examples/multimedia/video/qmlvideo/main.cpp +++ b/examples/multimedia/video/qmlvideo/main.cpp @@ -122,7 +122,7 @@ int main(int argc, char *argv[]) QQuickView viewer; viewer.setSource(QUrl("qrc:///qml/qmlvideo/main.qml")); - QObject::connect(viewer.engine(), SIGNAL(quit()), &viewer, SLOT(close())); + QObject::connect(viewer.engine(), &QQmlEngine::quit, &viewer, &QQuickView::close); QQuickItem *rootObject = viewer.rootObject(); rootObject->setProperty("source1", url1); diff --git a/examples/multimedia/video/qmlvideofx/qmlapplicationviewer/qmlapplicationviewer.cpp b/examples/multimedia/video/qmlvideofx/qmlapplicationviewer/qmlapplicationviewer.cpp index 33cead8e0..27102b0c5 100644 --- a/examples/multimedia/video/qmlvideofx/qmlapplicationviewer/qmlapplicationviewer.cpp +++ b/examples/multimedia/video/qmlvideofx/qmlapplicationviewer/qmlapplicationviewer.cpp @@ -90,7 +90,7 @@ QmlApplicationViewer::QmlApplicationViewer(QWindow *parent) : QQuickView(parent) , d(new QmlApplicationViewerPrivate(this)) { - connect(engine(), SIGNAL(quit()), QCoreApplication::instance(), SLOT(quit())); + connect(engine(), &QQmlEngine::quit, QCoreApplication::instance(), &QCoreApplication::quit); setResizeMode(QQuickView::SizeRootObjectToView); } @@ -98,7 +98,7 @@ QmlApplicationViewer::QmlApplicationViewer(QQuickView *view, QWindow *parent) : QQuickView(parent) , d(new QmlApplicationViewerPrivate(view)) { - connect(view->engine(), SIGNAL(quit()), QCoreApplication::instance(), SLOT(quit())); + connect(view->engine(), &QQmlEngine::quit, QCoreApplication::instance(), &QCoreApplication::quit); view->setResizeMode(QQuickView::SizeRootObjectToView); } diff --git a/examples/multimedia/video/snippets/frequencymonitor/frequencymonitor.cpp b/examples/multimedia/video/snippets/frequencymonitor/frequencymonitor.cpp index fb31c7b1e..d611497fe 100644 --- a/examples/multimedia/video/snippets/frequencymonitor/frequencymonitor.cpp +++ b/examples/multimedia/video/snippets/frequencymonitor/frequencymonitor.cpp @@ -105,18 +105,18 @@ FrequencyMonitorPrivate::FrequencyMonitorPrivate(FrequencyMonitor *parent) , m_stalledTimer(new QTimer(this)) { m_instantaneousElapsed.start(); - connect(m_averageTimer, SIGNAL(timeout()), - this, SLOT(calculateAverageFrequency())); + connect(m_averageTimer, &QTimer::timeout, + this, &FrequencyMonitorPrivate::calculateAverageFrequency); if (DefaultSamplingInterval) m_averageTimer->start(DefaultSamplingInterval); m_averageElapsed.start(); - connect(m_traceTimer, SIGNAL(timeout()), - q_ptr, SLOT(trace())); + connect(m_traceTimer, &QTimer::timeout, + q_ptr, &FrequencyMonitor::trace); if (DefaultTraceInterval) m_traceTimer->start(DefaultTraceInterval); m_stalledTimer->setSingleShot(true); - connect(m_stalledTimer, SIGNAL(timeout()), - this, SLOT(stalled())); + connect(m_stalledTimer, &QTimer::timeout, + this, &FrequencyMonitorPrivate::stalled); } void FrequencyMonitorPrivate::calculateInstantaneousFrequency() diff --git a/examples/multimediawidgets/customvideosurface/customvideoitem/videoplayer.cpp b/examples/multimediawidgets/customvideosurface/customvideoitem/videoplayer.cpp index 7da566a20..60b93a116 100644 --- a/examples/multimediawidgets/customvideosurface/customvideoitem/videoplayer.cpp +++ b/examples/multimediawidgets/customvideosurface/customvideoitem/videoplayer.cpp @@ -80,24 +80,25 @@ VideoPlayer::VideoPlayer(QWidget *parent) rotateSlider->setRange(-180, 180); rotateSlider->setValue(0); - connect(rotateSlider, SIGNAL(valueChanged(int)), - this, SLOT(rotateVideo(int))); + connect(rotateSlider, &QSlider::valueChanged, + this, &VideoPlayer::rotateVideo); QAbstractButton *openButton = new QPushButton(tr("Open...")); - connect(openButton, SIGNAL(clicked()), this, SLOT(openFile())); + connect(openButton, &QAbstractButton::clicked, + this, &VideoPlayer::openFile); playButton = new QPushButton; playButton->setEnabled(false); playButton->setIcon(style()->standardIcon(QStyle::SP_MediaPlay)); - connect(playButton, SIGNAL(clicked()), - this, SLOT(play())); + connect(playButton, &QAbstractButton::clicked, + this, &VideoPlayer::play); positionSlider = new QSlider(Qt::Horizontal); positionSlider->setRange(0, 0); - connect(positionSlider, SIGNAL(sliderMoved(int)), - this, SLOT(setPosition(int))); + connect(positionSlider, &QSlider::sliderMoved, + this, &VideoPlayer::setPosition); QBoxLayout *controlLayout = new QHBoxLayout; controlLayout->setMargin(0); @@ -113,10 +114,10 @@ VideoPlayer::VideoPlayer(QWidget *parent) setLayout(layout); mediaPlayer.setVideoOutput(videoItem); - connect(&mediaPlayer, SIGNAL(stateChanged(QMediaPlayer::State)), - this, SLOT(mediaStateChanged(QMediaPlayer::State))); - connect(&mediaPlayer, SIGNAL(positionChanged(qint64)), this, SLOT(positionChanged(qint64))); - connect(&mediaPlayer, SIGNAL(durationChanged(qint64)), this, SLOT(durationChanged(qint64))); + connect(&mediaPlayer, &QMediaPlayer::stateChanged, + this, &VideoPlayer::mediaStateChanged); + connect(&mediaPlayer, &QMediaPlayer::positionChanged, this, &VideoPlayer::positionChanged); + connect(&mediaPlayer, &QMediaPlayer::durationChanged, this, &VideoPlayer::durationChanged); } VideoPlayer::~VideoPlayer() diff --git a/examples/multimediawidgets/customvideosurface/customvideowidget/videoplayer.cpp b/examples/multimediawidgets/customvideosurface/customvideowidget/videoplayer.cpp index 7d0759c35..7730f8140 100644 --- a/examples/multimediawidgets/customvideosurface/customvideowidget/videoplayer.cpp +++ b/examples/multimediawidgets/customvideosurface/customvideowidget/videoplayer.cpp @@ -64,20 +64,21 @@ VideoPlayer::VideoPlayer(QWidget *parent) VideoWidget *videoWidget = new VideoWidget; QAbstractButton *openButton = new QPushButton(tr("Open...")); - connect(openButton, SIGNAL(clicked()), this, SLOT(openFile())); + connect(openButton, &QAbstractButton::clicked, + this, &VideoPlayer::openFile); playButton = new QPushButton; playButton->setEnabled(false); playButton->setIcon(style()->standardIcon(QStyle::SP_MediaPlay)); - connect(playButton, SIGNAL(clicked()), - this, SLOT(play())); + connect(playButton, &QAbstractButton::clicked, + this, &VideoPlayer::play); positionSlider = new QSlider(Qt::Horizontal); positionSlider->setRange(0, 0); - connect(positionSlider, SIGNAL(sliderMoved(int)), - this, SLOT(setPosition(int))); + connect(positionSlider, &QSlider::sliderMoved, + this, &VideoPlayer::setPosition); QBoxLayout *controlLayout = new QHBoxLayout; controlLayout->setMargin(0); @@ -92,10 +93,10 @@ VideoPlayer::VideoPlayer(QWidget *parent) setLayout(layout); mediaPlayer.setVideoOutput(videoWidget->videoSurface()); - connect(&mediaPlayer, SIGNAL(stateChanged(QMediaPlayer::State)), - this, SLOT(mediaStateChanged(QMediaPlayer::State))); - connect(&mediaPlayer, SIGNAL(positionChanged(qint64)), this, SLOT(positionChanged(qint64))); - connect(&mediaPlayer, SIGNAL(durationChanged(qint64)), this, SLOT(durationChanged(qint64))); + connect(&mediaPlayer, &QMediaPlayer::stateChanged, + this, &VideoPlayer::mediaStateChanged); + connect(&mediaPlayer, &QMediaPlayer::positionChanged, this, &VideoPlayer::positionChanged); + connect(&mediaPlayer, &QMediaPlayer::durationChanged, this, &VideoPlayer::durationChanged); } VideoPlayer::~VideoPlayer() -- cgit v1.2.3 From 1083ed94683c3356f9ee19210cfe9b0dd53e4815 Mon Sep 17 00:00:00 2001 From: VaL Doroshchuk Date: Mon, 18 Dec 2017 09:41:16 +0100 Subject: PulseAudio: Fix deadlock for QSoundEffect in setMuted, setVolume The deadlock would happen when one of the protected functions were reentered, as the lock used was not recursive. Since reading and writing to the volume and muted properties don't happen that often, the rw-mutex was replaced by a normal non-recursive mutex, which is now unlocked before the property changed signal is emitted. Task-number: QTBUG-65220 Change-Id: I1a224e9ff03f14593a854a7c1049c8a0445e29e6 Reviewed-by: Christian Stromme --- src/multimedia/audio/qsoundeffect_pulse_p.cpp | 13 ++++++++----- src/multimedia/audio/qsoundeffect_pulse_p.h | 5 +++-- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/multimedia/audio/qsoundeffect_pulse_p.cpp b/src/multimedia/audio/qsoundeffect_pulse_p.cpp index bf647ea1f..a86f22872 100644 --- a/src/multimedia/audio/qsoundeffect_pulse_p.cpp +++ b/src/multimedia/audio/qsoundeffect_pulse_p.cpp @@ -535,31 +535,34 @@ void QSoundEffectPrivate::setLoopCount(int loopCount) qreal QSoundEffectPrivate::volume() const { - QReadLocker locker(&m_volumeLock); + QMutexLocker locker(&m_volumeLock); return m_volume; } void QSoundEffectPrivate::setVolume(qreal volume) { - QWriteLocker locker(&m_volumeLock); + QMutexLocker locker(&m_volumeLock); if (qFuzzyCompare(m_volume, volume)) return; m_volume = qBound(qreal(0), volume, qreal(1)); + locker.unlock(); emit volumeChanged(); } bool QSoundEffectPrivate::isMuted() const { - QReadLocker locker(&m_volumeLock); + QMutexLocker locker(&m_volumeLock); return m_muted; } void QSoundEffectPrivate::setMuted(bool muted) { - QWriteLocker locker(&m_volumeLock); + m_volumeLock.lock(); m_muted = muted; + m_volumeLock.unlock(); + emit mutedChanged(); } @@ -884,7 +887,7 @@ int QSoundEffectPrivate::writeToStream(const void *data, int size) if (size < 1) return 0; - m_volumeLock.lockForRead(); + m_volumeLock.lock(); qreal volume = m_muted ? 0 : m_volume; m_volumeLock.unlock(); pa_free_cb_t writeDoneCb = stream_write_done_callback; diff --git a/src/multimedia/audio/qsoundeffect_pulse_p.h b/src/multimedia/audio/qsoundeffect_pulse_p.h index 7be88c55a..268a99326 100644 --- a/src/multimedia/audio/qsoundeffect_pulse_p.h +++ b/src/multimedia/audio/qsoundeffect_pulse_p.h @@ -56,7 +56,7 @@ #include #include -#include +#include #include #include #include "qsamplecache_p.h" @@ -175,7 +175,8 @@ private: bool m_resourcesAvailable; - mutable QReadWriteLock m_volumeLock; + // Protects volume while PuseAudio is accessing it + mutable QMutex m_volumeLock; QMediaPlayerResourceSetInterface *m_resources; }; -- cgit v1.2.3 From 13363975133c2a213daf4b05989cdc24a74d6c15 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 20 Dec 2017 12:06:29 +0100 Subject: Bump version Change-Id: If64a03c6cc1ff0885464427109a9caf4a2bb7b9d --- .qmake.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.qmake.conf b/.qmake.conf index 138038d54..0338efe07 100644 --- a/.qmake.conf +++ b/.qmake.conf @@ -1,3 +1,3 @@ load(qt_build_config) -MODULE_VERSION = 5.10.0 +MODULE_VERSION = 5.10.1 -- cgit v1.2.3 From bfebd23f150fa660177fff6aa372ae46e42038c3 Mon Sep 17 00:00:00 2001 From: Val Doroshchuk Date: Thu, 2 Nov 2017 09:08:37 +0100 Subject: Update player state after QMediaPlayer::EndOfMedia Return up-to-date player state if mediaStatusChanged() with QMediaPlayer::EndOfMedia is already received but stateChanged() is not. mediaStatusChanged() is always emitted first which could cause the player to keep outdated state before stateChanged() is received. Task-number: QTBUG-57197 Change-Id: I0706069d2f4875076442fdf8ac7e938272ab843c Reviewed-by: Christian Stromme --- src/multimedia/playback/qmediaplayer.cpp | 12 ++++++++++- .../tst_qmediaplayerbackend.cpp | 23 ++++++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/src/multimedia/playback/qmediaplayer.cpp b/src/multimedia/playback/qmediaplayer.cpp index 16fdec8ea..a3484a6ff 100644 --- a/src/multimedia/playback/qmediaplayer.cpp +++ b/src/multimedia/playback/qmediaplayer.cpp @@ -718,7 +718,17 @@ void QMediaPlayer::setNetworkConfigurations(const QList & QMediaPlayer::State QMediaPlayer::state() const { - return d_func()->state; + Q_D(const QMediaPlayer); + + // In case if EndOfMedia status is already received + // but state is not. + if (d->control != 0 + && d->status == QMediaPlayer::EndOfMedia + && d->state != d->control->state()) { + return d->control->state(); + } + + return d->state; } QMediaPlayer::MediaStatus QMediaPlayer::mediaStatus() const diff --git a/tests/auto/integration/qmediaplayerbackend/tst_qmediaplayerbackend.cpp b/tests/auto/integration/qmediaplayerbackend/tst_qmediaplayerbackend.cpp index 082e81b34..3deb534eb 100644 --- a/tests/auto/integration/qmediaplayerbackend/tst_qmediaplayerbackend.cpp +++ b/tests/auto/integration/qmediaplayerbackend/tst_qmediaplayerbackend.cpp @@ -77,6 +77,7 @@ private slots: void surfaceTest_data(); void surfaceTest(); void metadata(); + void playerStateAtEOS(); private: QMediaContent selectVideoFile(const QStringList& mediaCandidates); @@ -1412,6 +1413,28 @@ void tst_QMediaPlayerBackend::metadata() QVERIFY(player.availableMetaData().isEmpty()); } +void tst_QMediaPlayerBackend::playerStateAtEOS() +{ + if (!isWavSupported()) + QSKIP("Sound format is not supported"); + + QMediaPlayer player; + + bool endOfMediaReceived = false; + connect(&player, &QMediaPlayer::mediaStatusChanged, [&](QMediaPlayer::MediaStatus status) { + if (status == QMediaPlayer::EndOfMedia) { + QCOMPARE(player.state(), QMediaPlayer::StoppedState); + endOfMediaReceived = true; + } + }); + + player.setMedia(localWavFile); + player.play(); + + QTRY_COMPARE(player.mediaStatus(), QMediaPlayer::EndOfMedia); + QVERIFY(endOfMediaReceived); +} + TestVideoSurface::TestVideoSurface(bool storeFrames): m_totalFrames(0), m_storeFrames(storeFrames) -- cgit v1.2.3 From 48e0fc2ca67a4adbc4f051413ea3febdb24a6822 Mon Sep 17 00:00:00 2001 From: VaL Doroshchuk Date: Fri, 15 Dec 2017 08:57:18 +0100 Subject: Fix precision loss in QDeclarativeVideoRendererBackend::adjustedViewport Applied casting to keep precision. Task-number: QTBUG-64044 Change-Id: If3cb29b5c049302de38e5417811792405c896334 Reviewed-by: Christian Stromme --- src/qtmultimediaquicktools/qdeclarativevideooutput_render.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/qtmultimediaquicktools/qdeclarativevideooutput_render.cpp b/src/qtmultimediaquicktools/qdeclarativevideooutput_render.cpp index f1b7662b5..0cb6659ca 100644 --- a/src/qtmultimediaquicktools/qdeclarativevideooutput_render.cpp +++ b/src/qtmultimediaquicktools/qdeclarativevideooutput_render.cpp @@ -382,9 +382,9 @@ QAbstractVideoSurface *QDeclarativeVideoRendererBackend::videoSurface() const QRectF QDeclarativeVideoRendererBackend::adjustedViewport() const { const QRectF viewport = m_surface->surfaceFormat().viewport(); - const QSize pixelAspectRatio = m_surface->surfaceFormat().pixelAspectRatio(); + const QSizeF pixelAspectRatio = m_surface->surfaceFormat().pixelAspectRatio(); - if (pixelAspectRatio.height() != 0) { + if (pixelAspectRatio.isValid()) { const qreal ratio = pixelAspectRatio.width() / pixelAspectRatio.height(); QRectF result = viewport; result.setX(result.x() * ratio); -- cgit v1.2.3 From c8bf0cd37c5f526e3687dfeff9e23d15104328b5 Mon Sep 17 00:00:00 2001 From: Val Doroshchuk Date: Fri, 24 Nov 2017 08:36:36 +0100 Subject: DirectShow: Fix rendering of overlapping MDI subwindows Media type MEDIASUBTYPE_RGB32 is 32 bytes per pixel (like 0x00RRGGBB). When MDI subwindows are overlapping bottom window with QImage::Format_RGB32 requires 0xffRRGGBB. If "not used byte" is not 0xFF rendering will not be correct (0x00 produces empty image). Changed samples to ARGB32 to provide alpha channel, which is 0xFF in most cases. If alpha channel is not set to 0xFF, the bottom window will still be rendered incorrectly. Task-number: QTBUG-51405 Change-Id: I69f15d3835f901a04bf39b079394c6292b793610 Reviewed-by: Christian Stromme (cherry picked from commit b69259b65707acc9fc3c0818f6affe53938cebc3) --- src/plugins/directshow/camera/dscamerasession.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/directshow/camera/dscamerasession.cpp b/src/plugins/directshow/camera/dscamerasession.cpp index 55ab868ce..dc0dfc8b3 100644 --- a/src/plugins/directshow/camera/dscamerasession.cpp +++ b/src/plugins/directshow/camera/dscamerasession.cpp @@ -815,8 +815,8 @@ bool DSCameraSession::configurePreviewFormat() return false; } - // Set sample grabber format (always RGB32) - static const AM_MEDIA_TYPE grabberFormat { MEDIATYPE_Video, MEDIASUBTYPE_RGB32, 0, 0, 0, FORMAT_VideoInfo, nullptr, 0, nullptr}; + // Set sample grabber format + static const AM_MEDIA_TYPE grabberFormat { MEDIATYPE_Video, MEDIASUBTYPE_ARGB32, 0, 0, 0, FORMAT_VideoInfo, nullptr, 0, nullptr}; if (!m_previewSampleGrabber->setMediaType(&grabberFormat)) return false; -- cgit v1.2.3 From 4a6f459d193b621a77e002944eb28e4e96f2e2c7 Mon Sep 17 00:00:00 2001 From: VaL Doroshchuk Date: Tue, 19 Dec 2017 10:42:39 +0100 Subject: QML: Use alpha channel for ARGB32 video frames Added a fix to use alpha channel for ARGB32 video frames. Previously alpha component was always ignored and used 1.0 instead. To see transparent videos it is still needed to enable blending by adjusting an opacity property of qml element. Task-number: QTBUG-43098 Change-Id: If3aaf8ab695021b3a49a1790d900366e9c336b33 Reviewed-by: Christian Stromme --- src/qtmultimediaquicktools/qsgvideonode_rgb.cpp | 15 ++++++++++++--- src/qtmultimediaquicktools/qsgvideonode_texture.cpp | 15 ++++++++++++--- src/qtmultimediaquicktools/shaders/rgbvideo_swizzle.frag | 4 +++- 3 files changed, 27 insertions(+), 7 deletions(-) diff --git a/src/qtmultimediaquicktools/qsgvideonode_rgb.cpp b/src/qtmultimediaquicktools/qsgvideonode_rgb.cpp index 0dfa11ab9..d039e1e0b 100644 --- a/src/qtmultimediaquicktools/qsgvideonode_rgb.cpp +++ b/src/qtmultimediaquicktools/qsgvideonode_rgb.cpp @@ -113,11 +113,19 @@ protected: class QSGVideoMaterialShader_RGB_swizzle : public QSGVideoMaterialShader_RGB { public: - QSGVideoMaterialShader_RGB_swizzle() - : QSGVideoMaterialShader_RGB() + QSGVideoMaterialShader_RGB_swizzle(bool hasAlpha) + : m_hasAlpha(hasAlpha) { setShaderSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/qtmultimediaquicktools/shaders/rgbvideo_swizzle.frag")); } + +protected: + void initialize() override { + QSGVideoMaterialShader_RGB::initialize(); + program()->setUniformValue(program()->uniformLocation("hasAlpha"), GLboolean(m_hasAlpha)); + } + + bool m_hasAlpha; }; @@ -145,7 +153,8 @@ public: } QSGMaterialShader *createShader() const override { - return needsSwizzling() ? new QSGVideoMaterialShader_RGB_swizzle + const bool hasAlpha = m_format.pixelFormat() == QVideoFrame::Format_ARGB32; + return needsSwizzling() ? new QSGVideoMaterialShader_RGB_swizzle(hasAlpha) : new QSGVideoMaterialShader_RGB; } diff --git a/src/qtmultimediaquicktools/qsgvideonode_texture.cpp b/src/qtmultimediaquicktools/qsgvideonode_texture.cpp index a26d59532..f5545afc7 100644 --- a/src/qtmultimediaquicktools/qsgvideonode_texture.cpp +++ b/src/qtmultimediaquicktools/qsgvideonode_texture.cpp @@ -108,11 +108,19 @@ protected: class QSGVideoMaterialShader_Texture_swizzle : public QSGVideoMaterialShader_Texture { public: - QSGVideoMaterialShader_Texture_swizzle() - : QSGVideoMaterialShader_Texture() + QSGVideoMaterialShader_Texture_swizzle(bool hasAlpha) + : m_hasAlpha(hasAlpha) { setShaderSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/qtmultimediaquicktools/shaders/rgbvideo_swizzle.frag")); } + +protected: + void initialize() override { + QSGVideoMaterialShader_Texture::initialize(); + program()->setUniformValue(program()->uniformLocation("hasAlpha"), GLboolean(m_hasAlpha)); + } + + int m_hasAlpha; }; @@ -138,7 +146,8 @@ public: } QSGMaterialShader *createShader() const override { - return needsSwizzling() ? new QSGVideoMaterialShader_Texture_swizzle + const bool hasAlpha = m_format.pixelFormat() == QVideoFrame::Format_ARGB32; + return needsSwizzling() ? new QSGVideoMaterialShader_Texture_swizzle(hasAlpha) : new QSGVideoMaterialShader_Texture; } diff --git a/src/qtmultimediaquicktools/shaders/rgbvideo_swizzle.frag b/src/qtmultimediaquicktools/shaders/rgbvideo_swizzle.frag index f01dc86a0..df66bde63 100644 --- a/src/qtmultimediaquicktools/shaders/rgbvideo_swizzle.frag +++ b/src/qtmultimediaquicktools/shaders/rgbvideo_swizzle.frag @@ -1,8 +1,10 @@ uniform sampler2D rgbTexture; uniform lowp float opacity; varying highp vec2 qt_TexCoord; +uniform bool hasAlpha; void main() { - gl_FragColor = vec4(texture2D(rgbTexture, qt_TexCoord).bgr, 1.0) * opacity; + vec4 v = texture2D(rgbTexture, qt_TexCoord); + gl_FragColor = vec4(v.bgr, hasAlpha ? v.a : 1.0) * opacity; } -- cgit v1.2.3 From 13df2988efbe9a82225ccbf4cad463391d94c8e8 Mon Sep 17 00:00:00 2001 From: Jani Heikkinen Date: Fri, 5 Jan 2018 10:02:08 +0200 Subject: Blacklist qmediaplayerbackend tests in all versions of windows It was already blacklisted in most of builds and started to fail in remaining ones as well Task-number: QTBUG-46368 Task-number: QTBUG-65574 Change-Id: I809f8efd2887facfe85bf2d98f2251b0a7b82484 Reviewed-by: Liang Qi --- tests/auto/integration/qmediaplayerbackend/BLACKLIST | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/auto/integration/qmediaplayerbackend/BLACKLIST b/tests/auto/integration/qmediaplayerbackend/BLACKLIST index 4f8656e0a..68660a39b 100644 --- a/tests/auto/integration/qmediaplayerbackend/BLACKLIST +++ b/tests/auto/integration/qmediaplayerbackend/BLACKLIST @@ -1,8 +1,7 @@ # QTBUG-46368 osx -windows 32bit developer-build -windows 64bit developer-build +windows # Media player plugin not built at the moment on this platform opensuse-13.1 64bit -- cgit v1.2.3