From c37caa8070a8280cae2e4c73b8146aa490d14117 Mon Sep 17 00:00:00 2001 From: Yoann Lopes Date: Wed, 7 Sep 2016 15:17:24 +0200 Subject: Remove unnecessary import statement in QML snippet Change-Id: I1f34e52c4a8f72a91b1c673fe7e152335d8a0ade Reviewed-by: Venugopal Shivashankar --- src/imports/multimedia/qdeclarativeplaylist.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/imports/multimedia/qdeclarativeplaylist.cpp b/src/imports/multimedia/qdeclarativeplaylist.cpp index 19413dec8..fc31e762f 100644 --- a/src/imports/multimedia/qdeclarativeplaylist.cpp +++ b/src/imports/multimedia/qdeclarativeplaylist.cpp @@ -88,9 +88,6 @@ void QDeclarativePlaylistItem::setSource(const QUrl &source) item's source URL can be accessed using the \c source role. \qml - import QtQuick 2.0 - import QtMultimedia 5.6 - Item { width: 400; height: 300; -- cgit v1.2.3 From 07d55b154e19f3f4f8525b541c44500273be70ab Mon Sep 17 00:00:00 2001 From: Yoann Lopes Date: Fri, 9 Sep 2016 11:49:54 +0200 Subject: Don't try to compile Vivante video node plugin without OpenGL ES Task-number: QTBUG-54315 Change-Id: I559f67e1f24cbed5155fd0e4330cd12150d4dbf9 Reviewed-by: Laszlo Agocs --- qtmultimedia.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qtmultimedia.pro b/qtmultimedia.pro index 98bb3152f..a49700d16 100644 --- a/qtmultimedia.pro +++ b/qtmultimedia.pro @@ -33,7 +33,7 @@ win32 { } qtCompileTest(resourcepolicy) - qtCompileTest(gpu_vivante) + contains(QT_CONFIG, opengles2):qtCompileTest(gpu_vivante) } load(qt_parts) -- cgit v1.2.3 From bf5c7ca718a4a84e28a17ff69c4b18abee81ff93 Mon Sep 17 00:00:00 2001 From: Yoann Lopes Date: Wed, 10 Aug 2016 12:53:13 +0200 Subject: Make tst_QMediaObject::notifySignals() less flaky Rather than expecting a certain amount of signals to be fired within a fixed period, check that all the required signals are emitted and that it doesn't take longer than expected. Use a margin of error to take into account timers firing later because of high system load. Change-Id: I1569ce524e87efc47eb8d11066e509e5dc90f6f8 (cherry picked from commit 586abbd9732f9ccce127429fe0698c25a09ecefb) Reviewed-by: Christian Stromme --- tests/auto/unit/qmediaobject/tst_qmediaobject.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/tests/auto/unit/qmediaobject/tst_qmediaobject.cpp b/tests/auto/unit/qmediaobject/tst_qmediaobject.cpp index 355af5676..e79d9b586 100644 --- a/tests/auto/unit/qmediaobject/tst_qmediaobject.cpp +++ b/tests/auto/unit/qmediaobject/tst_qmediaobject.cpp @@ -293,14 +293,19 @@ void tst_QMediaObject::notifySignals() QFETCH(int, count); QtTestMediaObject object; + QSignalSpy spy(&object, SIGNAL(aChanged(int))); + object.setNotifyInterval(interval); object.addPropertyWatch("a"); - QSignalSpy spy(&object, SIGNAL(aChanged(int))); + QElapsedTimer timer; + timer.start(); - QTestEventLoop::instance().enterLoop(1); + QTRY_COMPARE(spy.count(), count); - QCOMPARE(spy.count(), count); + qint64 elapsed = timer.elapsed(); + int expectedElapsed = count * interval * 1.3; // give it some margin of error + QVERIFY2(elapsed < expectedElapsed, QString("elapsed: %1, expected: %2").arg(elapsed).arg(expectedElapsed).toLocal8Bit().constData()); } void tst_QMediaObject::notifyInterval_data() -- cgit v1.2.3 From 4bae7697257e5294721211fdd0b9bad5731f70c9 Mon Sep 17 00:00:00 2001 From: Yoann Lopes Date: Tue, 20 Sep 2016 19:28:40 +0300 Subject: PulseAudio: make code more robust Some asynchronous operations return a pa_operation pointer, which can be null if the operation fails. In some cases we were not checking that the returned object was non null, leading to some asserts being raised in pa_operation_unref. Change-Id: Iff1cc67b7f79b758fa81d79e658debb1d737b29f Reviewed-by: Christian Stromme --- src/multimedia/audio/qsoundeffect_pulse_p.cpp | 61 +++++++++++++++++++------ src/plugins/pulseaudio/qpulseaudioengine.cpp | 65 ++++++++++++++++++++------- 2 files changed, 95 insertions(+), 31 deletions(-) diff --git a/src/multimedia/audio/qsoundeffect_pulse_p.cpp b/src/multimedia/audio/qsoundeffect_pulse_p.cpp index 1fb10d121..5bb5119a8 100644 --- a/src/multimedia/audio/qsoundeffect_pulse_p.cpp +++ b/src/multimedia/audio/qsoundeffect_pulse_p.cpp @@ -437,7 +437,11 @@ void QSoundEffectPrivate::setSource(const QUrl &url) if (m_pulseStream && !pa_stream_is_corked(m_pulseStream)) { pa_stream_set_write_callback(m_pulseStream, 0, 0); pa_stream_set_underflow_callback(m_pulseStream, 0, 0); - pa_operation_unref(pa_stream_cork(m_pulseStream, 1, 0, 0)); + pa_operation *op = pa_stream_cork(m_pulseStream, 1, 0, 0); + if (op) + pa_operation_unref(op); + else + qWarning("QSoundEffect(pulseaudio): failed to cork stream"); } setPlaying(false); @@ -619,7 +623,11 @@ void QSoundEffectPrivate::emptyStream(EmptyStreamOptions options) m_emptying = true; pa_stream_set_write_callback(m_pulseStream, 0, 0); pa_stream_set_underflow_callback(m_pulseStream, 0, 0); - pa_operation_unref(pa_stream_flush(m_pulseStream, flushCompleteCb, m_ref->getRef())); + pa_operation *op = pa_stream_flush(m_pulseStream, flushCompleteCb, m_ref->getRef()); + if (op) + pa_operation_unref(op); + else + qWarning("QSoundEffect(pulseaudio): failed to flush stream"); } void QSoundEffectPrivate::emptyComplete(void *stream, bool reload) @@ -631,8 +639,13 @@ void QSoundEffectPrivate::emptyComplete(void *stream, bool reload) m_emptying = false; - if ((pa_stream *)stream == m_pulseStream) - pa_operation_unref(pa_stream_cork(m_pulseStream, 1, reload ? stream_cork_callback : 0, m_ref->getRef())); + if ((pa_stream *)stream == m_pulseStream) { + pa_operation *op = pa_stream_cork(m_pulseStream, 1, reload ? stream_cork_callback : 0, m_ref->getRef()); + if (op) + pa_operation_unref(op); + else + qWarning("QSoundEffect(pulseaudio): failed to cork stream"); + } } void QSoundEffectPrivate::sampleReady() @@ -666,7 +679,11 @@ void QSoundEffectPrivate::sampleReady() pa_buffer_attr newBufferAttr; newBufferAttr = *bufferAttr; newBufferAttr.prebuf = m_sample->data().size(); - pa_operation_unref(pa_stream_set_buffer_attr(m_pulseStream, &newBufferAttr, stream_adjust_prebuffer_callback, m_ref->getRef())); + pa_operation *op = pa_stream_set_buffer_attr(m_pulseStream, &newBufferAttr, stream_adjust_prebuffer_callback, m_ref->getRef()); + if (op) + pa_operation_unref(op); + else + qWarning("QSoundEffect(pulseaudio): failed to adjust pre-buffer attribute"); } else { streamReady(); } @@ -679,12 +696,20 @@ void QSoundEffectPrivate::sampleReady() newBufferAttr.minreq = bufferAttr->tlength / 2; newBufferAttr.prebuf = -1; newBufferAttr.fragsize = -1; - pa_operation_unref(pa_stream_set_buffer_attr(m_pulseStream, &newBufferAttr, stream_reset_buffer_callback, m_ref->getRef())); + pa_operation *op = pa_stream_set_buffer_attr(m_pulseStream, &newBufferAttr, stream_reset_buffer_callback, m_ref->getRef()); + if (op) + pa_operation_unref(op); + else + qWarning("QSoundEffect(pulseaudio): failed to adjust pre-buffer attribute"); } else if (bufferAttr->prebuf > uint32_t(m_sample->data().size())) { pa_buffer_attr newBufferAttr; newBufferAttr = *bufferAttr; newBufferAttr.prebuf = m_sample->data().size(); - pa_operation_unref(pa_stream_set_buffer_attr(m_pulseStream, &newBufferAttr, stream_adjust_prebuffer_callback, m_ref->getRef())); + pa_operation *op = pa_stream_set_buffer_attr(m_pulseStream, &newBufferAttr, stream_adjust_prebuffer_callback, m_ref->getRef()); + if (op) + pa_operation_unref(op); + else + qWarning("QSoundEffect(pulseaudio): failed to adjust pre-buffer attribute"); } else { streamReady(); } @@ -989,7 +1014,11 @@ void QSoundEffectPrivate::stream_state_callback(pa_stream *s, void *userdata) pa_buffer_attr newBufferAttr; newBufferAttr = *bufferAttr; newBufferAttr.prebuf = self->m_sample->data().size(); - pa_stream_set_buffer_attr(self->m_pulseStream, &newBufferAttr, stream_adjust_prebuffer_callback, self->m_ref->getRef()); + pa_operation *op = pa_stream_set_buffer_attr(self->m_pulseStream, &newBufferAttr, stream_adjust_prebuffer_callback, self->m_ref->getRef()); + if (op) + pa_operation_unref(op); + else + qWarning("QSoundEffect(pulseaudio): failed to adjust pre-buffer attribute"); } else { QMetaObject::invokeMethod(self, "streamReady", Qt::QueuedConnection); } @@ -1026,7 +1055,7 @@ void QSoundEffectPrivate::stream_reset_buffer_callback(pa_stream *s, int success return; if (!success) - qWarning("QSoundEffect(pulseaudio): faild to reset buffer attribute"); + qWarning("QSoundEffect(pulseaudio): failed to reset buffer attribute"); #ifdef QT_PA_DEBUG qDebug() << self << "stream_reset_buffer_callback"; #endif @@ -1036,7 +1065,11 @@ void QSoundEffectPrivate::stream_reset_buffer_callback(pa_stream *s, int success pa_buffer_attr newBufferAttr; newBufferAttr = *bufferAttr; newBufferAttr.prebuf = self->m_sample->data().size(); - pa_stream_set_buffer_attr(self->m_pulseStream, &newBufferAttr, stream_adjust_prebuffer_callback, userdata); + pa_operation *op = pa_stream_set_buffer_attr(self->m_pulseStream, &newBufferAttr, stream_adjust_prebuffer_callback, userdata); + if (op) + pa_operation_unref(op); + else + qWarning("QSoundEffect(pulseaudio): failed to adjust pre-buffer attribute"); } else { QMetaObject::invokeMethod(self, "streamReady", Qt::QueuedConnection); } @@ -1055,7 +1088,7 @@ void QSoundEffectPrivate::stream_adjust_prebuffer_callback(pa_stream *s, int suc return; if (!success) - qWarning("QSoundEffect(pulseaudio): faild to adjust pre-buffer attribute"); + qWarning("QSoundEffect(pulseaudio): failed to adjust pre-buffer attribute"); #ifdef QT_PA_DEBUG qDebug() << self << "stream_adjust_prebuffer_callback"; #endif @@ -1090,7 +1123,7 @@ void QSoundEffectPrivate::stream_cork_callback(pa_stream *s, int success, void * return; if (!success) - qWarning("QSoundEffect(pulseaudio): faild to stop"); + qWarning("QSoundEffect(pulseaudio): failed to stop"); #ifdef QT_PA_DEBUG qDebug() << self << "stream_cork_callback"; #endif @@ -1110,7 +1143,7 @@ void QSoundEffectPrivate::stream_flush_callback(pa_stream *s, int success, void return; if (!success) - qWarning("QSoundEffect(pulseaudio): faild to drain"); + qWarning("QSoundEffect(pulseaudio): failed to drain"); QMetaObject::invokeMethod(self, "emptyComplete", Qt::QueuedConnection, Q_ARG(void*, s), Q_ARG(bool, false)); } @@ -1128,7 +1161,7 @@ void QSoundEffectPrivate::stream_flush_reload_callback(pa_stream *s, int success return; if (!success) - qWarning("QSoundEffect(pulseaudio): faild to drain"); + qWarning("QSoundEffect(pulseaudio): failed to drain"); QMetaObject::invokeMethod(self, "emptyComplete", Qt::QueuedConnection, Q_ARG(void*, s), Q_ARG(bool, true)); } diff --git a/src/plugins/pulseaudio/qpulseaudioengine.cpp b/src/plugins/pulseaudio/qpulseaudioengine.cpp index e9510fd6a..b3d5044b7 100644 --- a/src/plugins/pulseaudio/qpulseaudioengine.cpp +++ b/src/plugins/pulseaudio/qpulseaudioengine.cpp @@ -170,15 +170,30 @@ static void event_cb(pa_context* context, pa_subscription_event_type_t t, uint32 case PA_SUBSCRIPTION_EVENT_NEW: case PA_SUBSCRIPTION_EVENT_CHANGE: switch (facility) { - case PA_SUBSCRIPTION_EVENT_SERVER: - pa_operation_unref(pa_context_get_server_info(context, serverInfoCallback, userdata)); + case PA_SUBSCRIPTION_EVENT_SERVER: { + pa_operation *op = pa_context_get_server_info(context, serverInfoCallback, userdata); + if (op) + pa_operation_unref(op); + else + qWarning("PulseAudioService: failed to get server info"); break; - case PA_SUBSCRIPTION_EVENT_SINK: - pa_operation_unref(pa_context_get_sink_info_by_index(context, index, sinkInfoCallback, userdata)); + } + case PA_SUBSCRIPTION_EVENT_SINK: { + pa_operation *op = pa_context_get_sink_info_by_index(context, index, sinkInfoCallback, userdata); + if (op) + pa_operation_unref(op); + else + qWarning("PulseAudioService: failed to get sink info"); break; - case PA_SUBSCRIPTION_EVENT_SOURCE: - pa_operation_unref(pa_context_get_source_info_by_index(context, index, sourceInfoCallback, userdata)); + } + case PA_SUBSCRIPTION_EVENT_SOURCE: { + pa_operation *op = pa_context_get_source_info_by_index(context, index, sourceInfoCallback, userdata); + if (op) + pa_operation_unref(op); + else + qWarning("PulseAudioService: failed to get source info"); break; + } default: break; } @@ -328,11 +343,15 @@ void QPulseAudioEngine::prepare() pa_context_set_state_callback(m_context, contextStateCallback, this); pa_context_set_subscribe_callback(m_context, event_cb, this); - pa_operation_unref(pa_context_subscribe(m_context, + pa_operation *op = pa_context_subscribe(m_context, pa_subscription_mask_t(PA_SUBSCRIPTION_MASK_SINK | PA_SUBSCRIPTION_MASK_SOURCE | PA_SUBSCRIPTION_MASK_SERVER), - NULL, NULL)); + NULL, NULL); + if (op) + pa_operation_unref(op); + else + qWarning("PulseAudioService: failed to subscribe to context notifications"); } else { pa_context_unref(m_context); m_context = 0; @@ -376,21 +395,33 @@ void QPulseAudioEngine::updateDevices() // Get default input and output devices pa_operation *operation = pa_context_get_server_info(m_context, serverInfoCallback, this); - while (pa_operation_get_state(operation) == PA_OPERATION_RUNNING) - pa_threaded_mainloop_wait(m_mainLoop); - pa_operation_unref(operation); + if (operation) { + while (pa_operation_get_state(operation) == PA_OPERATION_RUNNING) + pa_threaded_mainloop_wait(m_mainLoop); + pa_operation_unref(operation); + } else { + qWarning("PulseAudioService: failed to get server info"); + } // Get output devices operation = pa_context_get_sink_info_list(m_context, sinkInfoCallback, this); - while (pa_operation_get_state(operation) == PA_OPERATION_RUNNING) - pa_threaded_mainloop_wait(m_mainLoop); - pa_operation_unref(operation); + if (operation) { + while (pa_operation_get_state(operation) == PA_OPERATION_RUNNING) + pa_threaded_mainloop_wait(m_mainLoop); + pa_operation_unref(operation); + } else { + qWarning("PulseAudioService: failed to get sink info"); + } // Get input devices operation = pa_context_get_source_info_list(m_context, sourceInfoCallback, this); - while (pa_operation_get_state(operation) == PA_OPERATION_RUNNING) - pa_threaded_mainloop_wait(m_mainLoop); - pa_operation_unref(operation); + if (operation) { + while (pa_operation_get_state(operation) == PA_OPERATION_RUNNING) + pa_threaded_mainloop_wait(m_mainLoop); + pa_operation_unref(operation); + } else { + qWarning("PulseAudioService: failed to get source info"); + } unlock(); } -- cgit v1.2.3 From 6b94b3ca91df6ee047e99c63061dc33b1fb1c0f7 Mon Sep 17 00:00:00 2001 From: Yoann Lopes Date: Wed, 21 Sep 2016 12:01:23 +0300 Subject: GStreamer: print a warning when the camerabin plugin is missing Don't create the camera service when the camerabin plugin is not available on the system and print a warning. Task-number: QTBUG-50775 Change-Id: I56c7e6297bebe4b90596cb3c0323f1d38231bceb Reviewed-by: Christian Stromme --- src/plugins/gstreamer/camerabin/camerabinserviceplugin.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/plugins/gstreamer/camerabin/camerabinserviceplugin.cpp b/src/plugins/gstreamer/camerabin/camerabinserviceplugin.cpp index bee81a953..0658b0af0 100644 --- a/src/plugins/gstreamer/camerabin/camerabinserviceplugin.cpp +++ b/src/plugins/gstreamer/camerabin/camerabinserviceplugin.cpp @@ -60,8 +60,19 @@ QMediaService* CameraBinServicePlugin::create(const QString &key) { QGstUtils::initializeGst(); - if (key == QLatin1String(Q_MEDIASERVICE_CAMERA)) + if (key == QLatin1String(Q_MEDIASERVICE_CAMERA)) { + if (!CameraBinService::isCameraBinAvailable()) { + guint major, minor, micro, nano; + gst_version(&major, &minor, µ, &nano); + qWarning("Error: cannot create camera service, the 'camerabin' plugin is missing for " + "GStreamer %u.%u." + "\nPlease install the 'bad' GStreamer plugin package.", + major, minor); + return Q_NULLPTR; + } + return new CameraBinService(sourceFactory()); + } qWarning() << "Gstreamer camerabin service plugin: unsupported key:" << key; return 0; -- cgit v1.2.3 From 7d00a457e455e159a3dde30ad798be744cf38bb1 Mon Sep 17 00:00:00 2001 From: Yoann Lopes Date: Wed, 21 Sep 2016 10:59:20 +0300 Subject: Stabilize tst_QAudioOutput::pullSuspendResume() Don't wait after resume(); the test is meant to check the state of the QAudioOutput right after the call, not later. The state and the error status are supposed to change immediately, even if the backend runs in another thread. Ignore any state change that can happen because of underrun errors (likely to happen on CI). Removed the test from blacklist. Change-Id: Idaef6a9e0dfcfc89424fb2383cf3830a3184f975 Reviewed-by: Milla Pohjanheimo Reviewed-by: Christian Stromme --- tests/auto/integration/qaudiooutput/BLACKLIST | 5 ----- tests/auto/integration/qaudiooutput/tst_qaudiooutput.cpp | 7 ++----- 2 files changed, 2 insertions(+), 10 deletions(-) delete mode 100644 tests/auto/integration/qaudiooutput/BLACKLIST diff --git a/tests/auto/integration/qaudiooutput/BLACKLIST b/tests/auto/integration/qaudiooutput/BLACKLIST deleted file mode 100644 index 4d45efe06..000000000 --- a/tests/auto/integration/qaudiooutput/BLACKLIST +++ /dev/null @@ -1,5 +0,0 @@ -[pullSuspendResume] -redhatenterpriselinuxworkstation-6.6 -rhel-7.1 -ubuntu-14.04 -opensuse-13.1 64bit diff --git a/tests/auto/integration/qaudiooutput/tst_qaudiooutput.cpp b/tests/auto/integration/qaudiooutput/tst_qaudiooutput.cpp index b887d3f9a..dfe9d3e54 100644 --- a/tests/auto/integration/qaudiooutput/tst_qaudiooutput.cpp +++ b/tests/auto/integration/qaudiooutput/tst_qaudiooutput.cpp @@ -612,9 +612,6 @@ void tst_QAudioOutput::pullSuspendResume() audioOutput.resume(); - // Give backends running in separate threads a chance to suspend. - QTest::qWait(100); - // Check that QAudioOutput immediately transitions to ActiveState QVERIFY2((stateSignal.count() == 1), QString("didn't emit signal after resume(), got %1 signals instead").arg(stateSignal.count()).toLocal8Bit().constData()); @@ -626,8 +623,8 @@ void tst_QAudioOutput::pullSuspendResume() QTest::qWait(3000); // 3 seconds should be plenty QVERIFY2(audioFile->atEnd(), "didn't play to EOF"); - QVERIFY2((stateSignal.count() == 1), - QString("didn't emit IdleState signal when at EOF, got %1 signals instead").arg(stateSignal.count()).toLocal8Bit().constData()); + QVERIFY(stateSignal.count() > 0); + QCOMPARE(qvariant_cast(stateSignal.last().at(0)), QAudio::IdleState); QVERIFY2((audioOutput.state() == QAudio::IdleState), "didn't transitions to IdleState when at EOF"); stateSignal.clear(); -- cgit v1.2.3 From 0fd79396510501dfb1dad24bfd51147d364d919c Mon Sep 17 00:00:00 2001 From: Yoann Lopes Date: Wed, 7 Sep 2016 15:41:48 +0200 Subject: Fix QML module version in documentation Upated to 5.7 from 5.6. Change-Id: Ife0bc905aa81a8e776c5fc3eeafbc5706e5352d3 Reviewed-by: Venugopal Shivashankar --- src/multimedia/doc/src/multimedia.qdoc | 2 +- src/multimedia/doc/src/qtmultimedia-index.qdoc | 2 +- src/multimedia/doc/src/qtmultimedia5.qdoc | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/multimedia/doc/src/multimedia.qdoc b/src/multimedia/doc/src/multimedia.qdoc index 813847d88..84df488d2 100644 --- a/src/multimedia/doc/src/multimedia.qdoc +++ b/src/multimedia/doc/src/multimedia.qdoc @@ -177,7 +177,7 @@ 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.6 +import QtMultimedia 5.7 \endcode \annotatedlist multimedia_qml The following types are accessed by using \l{Qt Audio Engine QML Types}{Qt Audio Engine}: diff --git a/src/multimedia/doc/src/qtmultimedia-index.qdoc b/src/multimedia/doc/src/qtmultimedia-index.qdoc index 989b8886e..a474a355e 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.6 + import QtMultimedia 5.7 \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 21854ae7c..bc200819b 100644 --- a/src/multimedia/doc/src/qtmultimedia5.qdoc +++ b/src/multimedia/doc/src/qtmultimedia5.qdoc @@ -26,7 +26,7 @@ ****************************************************************************/ /*! -\qmlmodule QtMultimedia 5.6 +\qmlmodule QtMultimedia 5.7 \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.6 +import QtMultimedia 5.7 \endcode \section1 QML types -- cgit v1.2.3 From 9d9a29bcc31101e394ea484f61985cac75524ba1 Mon Sep 17 00:00:00 2001 From: Milla Pohjanheimo Date: Fri, 23 Sep 2016 09:21:05 +0300 Subject: Stabilize tst_QAudioOutput::pull() and push() autotests Same as 7d00a457e455e159a3dde30ad798be744cf38bb1. Change-Id: Iaf4a9d4eb5b5afe307a82af6f1a7fdf3e49f08ac Reviewed-by: Yoann Lopes --- tests/auto/integration/qaudiooutput/tst_qaudiooutput.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/auto/integration/qaudiooutput/tst_qaudiooutput.cpp b/tests/auto/integration/qaudiooutput/tst_qaudiooutput.cpp index dfe9d3e54..e36d38f4a 100644 --- a/tests/auto/integration/qaudiooutput/tst_qaudiooutput.cpp +++ b/tests/auto/integration/qaudiooutput/tst_qaudiooutput.cpp @@ -532,8 +532,8 @@ void tst_QAudioOutput::pull() QTest::qWait(3000); // 3 seconds should be plenty QVERIFY2(audioFile->atEnd(), "didn't play to EOF"); - QVERIFY2((stateSignal.count() == 1), - QString("didn't emit IdleState signal when at EOF, got %1 signals instead").arg(stateSignal.count()).toLocal8Bit().constData()); + QVERIFY(stateSignal.count() > 0); + QCOMPARE(qvariant_cast(stateSignal.last().at(0)), QAudio::IdleState); QVERIFY2((audioOutput.state() == QAudio::IdleState), "didn't transitions to IdleState when at EOF"); stateSignal.clear(); @@ -709,8 +709,8 @@ void tst_QAudioOutput::push() QTest::qWait(3000); // 3 seconds should be plenty QVERIFY2(audioFile->atEnd(), "didn't play to EOF"); - QVERIFY2((stateSignal.count() == 1), - QString("didn't emit IdleState signal when at EOF, got %1 signals instead").arg(stateSignal.count()).toLocal8Bit().constData()); + QVERIFY(stateSignal.count() > 0); + QCOMPARE(qvariant_cast(stateSignal.last().at(0)), QAudio::IdleState); QVERIFY2((audioOutput.state() == QAudio::IdleState), "didn't transitions to IdleState when at EOF"); stateSignal.clear(); -- cgit v1.2.3 From c4bf444f5cf71518fb52bc4f19515a9a662a107d Mon Sep 17 00:00:00 2001 From: Milla Pohjanheimo Date: Tue, 27 Sep 2016 10:50:28 +0300 Subject: Stabilize pushSuspendResume() autotest Same as 7d00a457e455e159a3dde30ad798be744cf38bb1. Change-Id: Ia7b01eef7650c1db23562d1a36a4a19748c92fc7 Reviewed-by: Yoann Lopes --- tests/auto/integration/qaudiooutput/tst_qaudiooutput.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/auto/integration/qaudiooutput/tst_qaudiooutput.cpp b/tests/auto/integration/qaudiooutput/tst_qaudiooutput.cpp index e36d38f4a..8990590ee 100644 --- a/tests/auto/integration/qaudiooutput/tst_qaudiooutput.cpp +++ b/tests/auto/integration/qaudiooutput/tst_qaudiooutput.cpp @@ -844,8 +844,8 @@ void tst_QAudioOutput::pushSuspendResume() QTest::qWait(1000); // 1 seconds should be plenty QVERIFY2(audioFile->atEnd(), "didn't play to EOF"); - QVERIFY2((stateSignal.count() == 1), - QString("didn't emit IdleState signal when at EOF, got %1 signals instead").arg(stateSignal.count()).toLocal8Bit().constData()); + QVERIFY(stateSignal.count() > 0); + QCOMPARE(qvariant_cast(stateSignal.last().at(0)), QAudio::IdleState); QVERIFY2((audioOutput.state() == QAudio::IdleState), "didn't transitions to IdleState when at EOF"); stateSignal.clear(); -- cgit v1.2.3 From 81a48edb548a9ad86414b3a115d718c932c11058 Mon Sep 17 00:00:00 2001 From: Yoann Lopes Date: Wed, 17 Aug 2016 13:55:10 +0200 Subject: AVFoundation: fix metadata control Correctly emit metaDataAvailableChanged and metaDataChanged signals. Task-number: QTBUG-46368 Change-Id: Ic79acd519b47f4d864fa335c8f75758fe9185c39 Reviewed-by: Christian Stromme --- .../mediaplayer/avfmediaplayermetadatacontrol.h | 2 +- .../mediaplayer/avfmediaplayermetadatacontrol.mm | 110 +++++++++++---------- 2 files changed, 59 insertions(+), 53 deletions(-) diff --git a/src/plugins/avfoundation/mediaplayer/avfmediaplayermetadatacontrol.h b/src/plugins/avfoundation/mediaplayer/avfmediaplayermetadatacontrol.h index d40e70c2a..e28fc2936 100644 --- a/src/plugins/avfoundation/mediaplayer/avfmediaplayermetadatacontrol.h +++ b/src/plugins/avfoundation/mediaplayer/avfmediaplayermetadatacontrol.h @@ -58,7 +58,7 @@ private Q_SLOTS: private: AVFMediaPlayerSession *m_session; - QMap m_tags; + QVariantMap m_tags; void *m_asset; }; diff --git a/src/plugins/avfoundation/mediaplayer/avfmediaplayermetadatacontrol.mm b/src/plugins/avfoundation/mediaplayer/avfmediaplayermetadatacontrol.mm index 336f8637c..b84ff5952 100644 --- a/src/plugins/avfoundation/mediaplayer/avfmediaplayermetadatacontrol.mm +++ b/src/plugins/avfoundation/mediaplayer/avfmediaplayermetadatacontrol.mm @@ -75,6 +75,41 @@ QStringList AVFMediaPlayerMetaDataControl::availableMetaData() const return m_tags.keys(); } +static QString itemKey(AVMetadataItem *item) +{ + NSString *keyString = [item commonKey]; + + if (keyString.length != 0) { + if ([keyString isEqualToString:AVMetadataCommonKeyTitle]) { + return QMediaMetaData::Title; + } else if ([keyString isEqualToString: AVMetadataCommonKeySubject]) { + return QMediaMetaData::SubTitle; + } else if ([keyString isEqualToString: AVMetadataCommonKeyDescription]) { + return QMediaMetaData::Description; + } else if ([keyString isEqualToString: AVMetadataCommonKeyPublisher]) { + return QMediaMetaData::Publisher; + } else if ([keyString isEqualToString: AVMetadataCommonKeyCreationDate]) { + return QMediaMetaData::Date; + } else if ([keyString isEqualToString: AVMetadataCommonKeyType]) { + return QMediaMetaData::MediaType; + } else if ([keyString isEqualToString: AVMetadataCommonKeyLanguage]) { + return QMediaMetaData::Language; + } else if ([keyString isEqualToString: AVMetadataCommonKeyCopyrights]) { + return QMediaMetaData::Copyright; + } else if ([keyString isEqualToString: AVMetadataCommonKeyAlbumName]) { + return QMediaMetaData::AlbumTitle; + } else if ([keyString isEqualToString: AVMetadataCommonKeyAuthor]) { + return QMediaMetaData::Author; + } else if ([keyString isEqualToString: AVMetadataCommonKeyArtist]) { + return QMediaMetaData::ContributingArtist; + } else if ([keyString isEqualToString: AVMetadataCommonKeyArtwork]) { + return QMediaMetaData::PosterUrl; + } + } + + return QString(); +} + void AVFMediaPlayerMetaDataControl::updateTags() { #ifdef QT_DEBUG_AVF @@ -83,67 +118,38 @@ void AVFMediaPlayerMetaDataControl::updateTags() AVAsset *currentAsset = (AVAsset*)m_session->currentAssetHandle(); //Don't read the tags from the same asset more than once - if (currentAsset == m_asset) { + if (currentAsset == m_asset) return; - } m_asset = currentAsset; + QVariantMap oldTags = m_tags; //Since we've changed assets, clear old tags m_tags.clear(); - - NSArray *metadataFormats = [currentAsset availableMetadataFormats]; - for ( NSString *format in metadataFormats) { -#ifdef QT_DEBUG_AVF - qDebug() << "format: " << [format UTF8String]; -#endif - NSArray *metadataItems = [currentAsset metadataForFormat:format]; - for (AVMetadataItem* item in metadataItems) { - NSString *keyString = [item commonKey]; - NSString *value = [item stringValue]; - - if (keyString.length != 0) { - //Process "commonMetadata" tags here: - if ([keyString isEqualToString:AVMetadataCommonKeyTitle]) { - m_tags.insert(QMediaMetaData::Title, QString([value UTF8String])); - } else if ([keyString isEqualToString: AVMetadataCommonKeyCreator]) { - m_tags.insert(QMediaMetaData::Author, QString([value UTF8String])); - } else if ([keyString isEqualToString: AVMetadataCommonKeySubject]) { - m_tags.insert(QMediaMetaData::SubTitle, QString([value UTF8String])); - } else if ([keyString isEqualToString: AVMetadataCommonKeyDescription]) { - m_tags.insert(QMediaMetaData::Description, QString([value UTF8String])); - } else if ([keyString isEqualToString: AVMetadataCommonKeyPublisher]) { - m_tags.insert(QMediaMetaData::Publisher, QString([value UTF8String])); - } else if ([keyString isEqualToString: AVMetadataCommonKeyContributor]) { - m_tags.insert(QMediaMetaData::ContributingArtist, QString([value UTF8String])); - } else if ([keyString isEqualToString: AVMetadataCommonKeyCreationDate]) { - m_tags.insert(QMediaMetaData::Date, QString([value UTF8String])); - } else if ([keyString isEqualToString: AVMetadataCommonKeyType]) { - m_tags.insert(QMediaMetaData::MediaType, QString([value UTF8String])); - } else if ([keyString isEqualToString: AVMetadataCommonKeyLanguage]) { - m_tags.insert(QMediaMetaData::Language, QString([value UTF8String])); - } else if ([keyString isEqualToString: AVMetadataCommonKeyCopyrights]) { - m_tags.insert(QMediaMetaData::Copyright, QString([value UTF8String])); - } else if ([keyString isEqualToString: AVMetadataCommonKeyAlbumName]) { - m_tags.insert(QMediaMetaData::AlbumTitle, QString([value UTF8String])); - } else if ([keyString isEqualToString: AVMetadataCommonKeyAuthor]) { - m_tags.insert(QMediaMetaData::Author, QString([value UTF8String])); - } else if ([keyString isEqualToString: AVMetadataCommonKeyArtist]) { - m_tags.insert(QMediaMetaData::AlbumArtist, QString([value UTF8String])); - } else if ([keyString isEqualToString: AVMetadataCommonKeyArtwork]) { - m_tags.insert(QMediaMetaData::PosterUrl, QString([value UTF8String])); + bool changed = false; + + // TODO: also process ID3, iTunes and QuickTime metadata + + NSArray *metadataItems = [currentAsset commonMetadata]; + for (AVMetadataItem* item in metadataItems) { + const QString key = itemKey(item); + if (!key.isEmpty()) { + const QString value = QString::fromNSString([item stringValue]); + if (!value.isNull()) { + m_tags.insert(key, value); + if (value != oldTags.value(key)) { + changed = true; + Q_EMIT metaDataChanged(key, value); } } - - if ([format isEqualToString:AVMetadataFormatID3Metadata]) { - //TODO: Process ID3 metadata - } else if ([format isEqualToString:AVMetadataFormatiTunesMetadata]) { - //TODO: Process iTunes metadata - } else if ([format isEqualToString:AVMetadataFormatQuickTimeUserData]) { - //TODO: Process QuickTime metadata - } } } - Q_EMIT metaDataChanged(); + if (oldTags.isEmpty() != m_tags.isEmpty()) { + Q_EMIT metaDataAvailableChanged(!m_tags.isEmpty()); + changed = true; + } + + if (changed) + Q_EMIT metaDataChanged(); } -- cgit v1.2.3 From 91d12e6242bac85f0ea59db2d98235792f82dd44 Mon Sep 17 00:00:00 2001 From: Yoann Lopes Date: Fri, 8 Jul 2016 15:28:34 +0200 Subject: Clamp volume in QMediaRecorder and QSoundEffect Change-Id: Ie61c33592873b7e5a2ed1b8ccf3386b20edb2cef Reviewed-by: Christian Stromme --- src/multimedia/audio/qsoundeffect.cpp | 6 +----- src/multimedia/recording/qmediarecorder.cpp | 4 +++- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/multimedia/audio/qsoundeffect.cpp b/src/multimedia/audio/qsoundeffect.cpp index 865d40753..61b294114 100644 --- a/src/multimedia/audio/qsoundeffect.cpp +++ b/src/multimedia/audio/qsoundeffect.cpp @@ -273,11 +273,7 @@ qreal QSoundEffect::volume() const */ void QSoundEffect::setVolume(qreal volume) { - if (volume < qreal(0.0) || volume > qreal(1.0)) { - qWarning("SoundEffect: volume should be between 0.0 and 1.0"); - return; - } - + volume = qBound(qreal(0.0), volume, qreal(1.0)); if (qFuzzyCompare(d->volume(), volume)) return; diff --git a/src/multimedia/recording/qmediarecorder.cpp b/src/multimedia/recording/qmediarecorder.cpp index e1c01e387..1d5d7cb6f 100644 --- a/src/multimedia/recording/qmediarecorder.cpp +++ b/src/multimedia/recording/qmediarecorder.cpp @@ -563,8 +563,10 @@ void QMediaRecorder::setVolume(qreal volume) { Q_D(QMediaRecorder); - if (d->control) + if (d->control) { + volume = qMax(qreal(0.0), volume); d->control->setVolume(volume); + } } /*! -- cgit v1.2.3 From 2f3cf6bca788c6a08357a9d672deb4119877a1fd Mon Sep 17 00:00:00 2001 From: Yoann Lopes Date: Fri, 8 Jul 2016 14:49:37 +0200 Subject: Clamp out-of-range volume values in QAudioInput and QAudioOutput Change-Id: I6da76524533e16f6987fad6029b1f42960972383 Reviewed-by: Christian Stromme --- src/multimedia/audio/qaudioinput.cpp | 3 ++- src/multimedia/audio/qaudiooutput.cpp | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/multimedia/audio/qaudioinput.cpp b/src/multimedia/audio/qaudioinput.cpp index 5f827d013..8df8696d2 100644 --- a/src/multimedia/audio/qaudioinput.cpp +++ b/src/multimedia/audio/qaudioinput.cpp @@ -332,7 +332,8 @@ int QAudioInput::notifyInterval() const */ void QAudioInput::setVolume(qreal volume) { - d->setVolume(volume); + qreal v = qBound(qreal(0.0), volume, qreal(1.0)); + d->setVolume(v); } /*! diff --git a/src/multimedia/audio/qaudiooutput.cpp b/src/multimedia/audio/qaudiooutput.cpp index 5c866663e..f3c59f3e0 100644 --- a/src/multimedia/audio/qaudiooutput.cpp +++ b/src/multimedia/audio/qaudiooutput.cpp @@ -349,7 +349,8 @@ QAudio::State QAudioOutput::state() const */ void QAudioOutput::setVolume(qreal volume) { - d->setVolume(volume); + qreal v = qBound(qreal(0.0), volume, qreal(1.0)); + d->setVolume(v); } /*! -- cgit v1.2.3 From 5472ea150693d7eadf21f0e7db8354896eaca2d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Str=C3=B8mme?= Date: Wed, 31 Aug 2016 18:02:08 +0200 Subject: Remove useless cast Casting to same type. Change-Id: I93935b75edac56c958d0669eff216b9dcf16a153 Reviewed-by: Yoann Lopes --- src/multimedia/playback/qmedianetworkplaylistprovider.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/multimedia/playback/qmedianetworkplaylistprovider.cpp b/src/multimedia/playback/qmedianetworkplaylistprovider.cpp index 88c253494..76cee7616 100644 --- a/src/multimedia/playback/qmedianetworkplaylistprovider.cpp +++ b/src/multimedia/playback/qmedianetworkplaylistprovider.cpp @@ -68,7 +68,7 @@ void QMediaNetworkPlaylistProviderPrivate::_q_handleParserError(QPlaylistFilePar QMediaPlaylist::Error playlistError = QMediaPlaylist::NoError; - switch ((QPlaylistFileParser::ParserError)err) { + switch (err) { case QPlaylistFileParser::NoError: return; case QPlaylistFileParser::FormatError: -- cgit v1.2.3 From 309dcb92590a9c159a8f4497d8f9582552dd8730 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Str=C3=B8mme?= Date: Wed, 31 Aug 2016 18:06:08 +0200 Subject: Doc: Add comment about stream requirements Change-Id: I92e16722dc5cc8df23cf4ed0d048a0d2a23956eb Reviewed-by: Yoann Lopes --- src/multimedia/playback/qmediaplayer.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/multimedia/playback/qmediaplayer.cpp b/src/multimedia/playback/qmediaplayer.cpp index e6e4c7c1a..d349654ff 100644 --- a/src/multimedia/playback/qmediaplayer.cpp +++ b/src/multimedia/playback/qmediaplayer.cpp @@ -956,8 +956,8 @@ void QMediaPlayer::setPlaybackRate(qreal rate) Sets the current \a media source. If a \a stream is supplied; media data will be read from it instead of resolving the media - source. In this case the media source may still be used to resolve additional information - about the media such as mime type. + source. In this case the media source may still be used to resolve additional information + about the media such as mime type. The \a stream must be open and readable. Setting the media to a null QMediaContent will cause the player to discard all information relating to the current media source and to cease all I/O operations related -- cgit v1.2.3 From 026aec5079375c866cd88ba176c88d2842d1b260 Mon Sep 17 00:00:00 2001 From: Milla Pohjanheimo Date: Thu, 29 Sep 2016 15:55:31 +0300 Subject: Blacklist testSetSourceWhilePlaying() in 5.6 The test is flaky and running it 300 times didn't reproduce the failure. Change-Id: Ib03722579dbe58c05cb324fdca37eb7e5b732e33 Reviewed-by: Yoann Lopes --- tests/auto/integration/qsoundeffect/BLACKLIST | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 tests/auto/integration/qsoundeffect/BLACKLIST diff --git a/tests/auto/integration/qsoundeffect/BLACKLIST b/tests/auto/integration/qsoundeffect/BLACKLIST new file mode 100644 index 000000000..abf85ae93 --- /dev/null +++ b/tests/auto/integration/qsoundeffect/BLACKLIST @@ -0,0 +1,3 @@ +#QTBUG-55735 +[testSetSourceWhilePlaying] +linux -- cgit v1.2.3 From 1a34596b426f8a685453699ad44c45075a6c3681 Mon Sep 17 00:00:00 2001 From: Nico Vertriest Date: Mon, 3 Oct 2016 15:42:36 +0200 Subject: Doc: corrected reference to parameter "end" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Ia4c521b4eee8efd7afe6efd1f00f3c15fd138d9b Reviewed-by: Topi Reiniƶ --- src/imports/multimedia/qdeclarativeplaylist.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/imports/multimedia/qdeclarativeplaylist.cpp b/src/imports/multimedia/qdeclarativeplaylist.cpp index e8df8c376..549e0702d 100644 --- a/src/imports/multimedia/qdeclarativeplaylist.cpp +++ b/src/imports/multimedia/qdeclarativeplaylist.cpp @@ -510,7 +510,7 @@ bool QDeclarativePlaylist::removeItem(int index) /*! \qmlmethod bool QtMultimedia::Playlist::removeItems(int start, int end) - Removes items in the playlist from \a start to \end inclusive. + Removes items in the playlist from \a start to \a end inclusive. Returns true if the items are removed successfully. -- cgit v1.2.3 From 256ff7bb1551f6c62c4ac861472ea29f45dbab3a Mon Sep 17 00:00:00 2001 From: Nico Vertriest Date: Mon, 3 Oct 2016 16:02:28 +0200 Subject: Doc: added definition for parameter gain Change-Id: I710e99e6889e49755241e8448163167374f23f52 Reviewed-by: Venugopal Shivashankar --- src/multimedia/controls/qmediarecordercontrol.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/multimedia/controls/qmediarecordercontrol.cpp b/src/multimedia/controls/qmediarecordercontrol.cpp index 4654d16eb..abffc6811 100644 --- a/src/multimedia/controls/qmediarecordercontrol.cpp +++ b/src/multimedia/controls/qmediarecordercontrol.cpp @@ -166,7 +166,9 @@ QMediaRecorderControl::~QMediaRecorderControl() /*! \fn void QMediaRecorderControl::setVolume(qreal gain) - Sets the linear audio \a gain of a media recorder. + Sets the audio \a gain of a media recorder control. + + The gain is scaled linearly, ranging from \c 0 (silence) to \c 100 (full volume). */ /*! -- cgit v1.2.3