From 80411380fbf614d833cd42dee80d01510326ccd3 Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Tue, 19 Mar 2019 14:12:07 +0100 Subject: winrt: Use highest supported resolution for camera preview/image capture Using the lowest supported resolution yields ugly results and has weird side effects (green bars). If no resolution is explicitly given, we should use the maximum supported solution for preview as well as capture. Task-number: QTBUG-72874 Change-Id: Ie0fae65180e66156c6de468f2cabb9122fe665ba Reviewed-by: VaL Doroshchuk --- src/plugins/winrt/qwinrtcameracontrol.cpp | 16 ++++++++++------ src/plugins/winrt/qwinrtimageencodercontrol.cpp | 9 ++++++++- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/src/plugins/winrt/qwinrtcameracontrol.cpp b/src/plugins/winrt/qwinrtcameracontrol.cpp index c00f65624..ede3f6b04 100644 --- a/src/plugins/winrt/qwinrtcameracontrol.cpp +++ b/src/plugins/winrt/qwinrtcameracontrol.cpp @@ -1398,6 +1398,10 @@ HRESULT QWinRTCameraControl::onInitializationCompleted(IAsyncAction *, AsyncStat &captureResolutions); RETURN_HR_IF_FAILED("Failed to find a suitable video format"); + std::sort(captureResolutions.begin(), captureResolutions.end(), [](QSize size1, QSize size2) { + return size1.width() * size1.height() < size2.width() * size2.height(); + }); + // Set capture resolutions. d->imageEncoderControl->setSupportedResolutionsList(captureResolutions.toList()); const QSize captureResolution = d->imageEncoderControl->imageSettings().resolution(); @@ -1412,17 +1416,17 @@ HRESULT QWinRTCameraControl::onInitializationCompleted(IAsyncAction *, AsyncStat Q_ASSERT_SUCCEEDED(hr); // Set preview resolution. - QVector filtered; + QSize maxSize; const float captureAspectRatio = float(captureResolution.width()) / captureResolution.height(); for (const QSize &resolution : qAsConst(previewResolutions)) { const float aspectRatio = float(resolution.width()) / resolution.height(); - if (qAbs(aspectRatio - captureAspectRatio) <= ASPECTRATIO_EPSILON) - filtered.append(resolution); + if ((qAbs(aspectRatio - captureAspectRatio) <= ASPECTRATIO_EPSILON) + && (maxSize.width() * maxSize.height() < resolution.width() * resolution.height())) { + maxSize = resolution; + } } - std::sort(filtered.begin(), filtered.end(), - [](QSize size1, QSize size2) { return size1.width() * size1.height() < size2.width() * size2.height(); }); - const QSize &viewfinderResolution = filtered.first(); + const QSize &viewfinderResolution = maxSize; const quint32 viewfinderResolutionIndex = quint32(previewResolutions.indexOf(viewfinderResolution)); hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_Media_MediaProperties_MediaEncodingProfile).Get(), &d->encodingProfile); diff --git a/src/plugins/winrt/qwinrtimageencodercontrol.cpp b/src/plugins/winrt/qwinrtimageencodercontrol.cpp index 7ea851b77..2aed5f8a6 100644 --- a/src/plugins/winrt/qwinrtimageencodercontrol.cpp +++ b/src/plugins/winrt/qwinrtimageencodercontrol.cpp @@ -105,8 +105,15 @@ void QWinRTImageEncoderControl::applySettings() if (d->imageEncoderSetting.codec().isEmpty()) d->imageEncoderSetting.setCodec(QStringLiteral("jpeg")); + if (d->supportedResolutions.isEmpty()) + return; + QSize requestResolution = d->imageEncoderSetting.resolution(); - if (d->supportedResolutions.isEmpty() || d->supportedResolutions.contains(requestResolution)) + if (!requestResolution.isValid()) { + d->imageEncoderSetting.setResolution(d->supportedResolutions.last()); + return; + } + if (d->supportedResolutions.contains(requestResolution)) return; // Find closest resolution from the list -- cgit v1.2.3 From f41819387531a5ddfbad2e80ceec7b57a5ebb7c6 Mon Sep 17 00:00:00 2001 From: Val Doroshchuk Date: Thu, 28 Mar 2019 10:22:36 +0100 Subject: Android: Use CaptureStillImage as default capture mode Fixes tst_QCameraBackend::testCaptureMode. Change-Id: I2f6486102ebcbf7e1ab0feea8c13658772d5b90f Fixes: QTBUG-73582 Reviewed-by: Oliver Wolff --- src/plugins/android/src/mediacapture/qandroidcamerasession.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/android/src/mediacapture/qandroidcamerasession.cpp b/src/plugins/android/src/mediacapture/qandroidcamerasession.cpp index 15aa027e4..8ba3ed12c 100644 --- a/src/plugins/android/src/mediacapture/qandroidcamerasession.cpp +++ b/src/plugins/android/src/mediacapture/qandroidcamerasession.cpp @@ -64,7 +64,7 @@ QAndroidCameraSession::QAndroidCameraSession(QObject *parent) , m_camera(0) , m_nativeOrientation(0) , m_videoOutput(0) - , m_captureMode(QCamera::CaptureViewfinder) + , m_captureMode(QCamera::CaptureStillImage) , m_state(QCamera::UnloadedState) , m_savedState(-1) , m_status(QCamera::UnloadedStatus) -- cgit v1.2.3 From 5f15380e7c807c8111c32fc9bcf53189a868d23c Mon Sep 17 00:00:00 2001 From: Ihor Dutchak Date: Sun, 17 Mar 2019 00:46:30 +0200 Subject: DirectShow: don't change camera zoom level if not requested DirectShowCameraZoomControl sets camera zoom level to 1x each time, when camera goes into LoadedStatus (e.g. on stream stop), which is inconveniant, specially if camera has physical remote, and zoom level may be changed externally. Disable this behavior, if zoom level was not requested explicitly by zoomTo(...) function from client code. Fixes: QTBUG-74180 Change-Id: I99ff76af04f80c630a0c397db5713e6706ebf175 Reviewed-by: VaL Doroshchuk Reviewed-by: Ihor Dutchak --- src/plugins/directshow/camera/directshowcamerazoomcontrol.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/directshow/camera/directshowcamerazoomcontrol.cpp b/src/plugins/directshow/camera/directshowcamerazoomcontrol.cpp index 209cb5d96..079976e15 100644 --- a/src/plugins/directshow/camera/directshowcamerazoomcontrol.cpp +++ b/src/plugins/directshow/camera/directshowcamerazoomcontrol.cpp @@ -176,7 +176,7 @@ void DirectShowCameraZoomControl::updateZoomValues() } // Check if there is a pending zoom value. - if (!qFuzzyCompare(m_currentOpticalZoom, m_requestedOpticalZoom)) + if (!qFuzzyCompare(m_currentOpticalZoom, m_requestedOpticalZoom) && !qFuzzyIsNull(m_requestedOpticalZoom)) opticalZoomToPrivate(m_requestedOpticalZoom); } -- cgit v1.2.3 From e06c207c066b4a5b469945ae9a8a7cc79682103e Mon Sep 17 00:00:00 2001 From: Val Doroshchuk Date: Thu, 28 Mar 2019 13:21:32 +0100 Subject: Android: Fix tst_QCameraBackend to wait for imageCaptured QCameraImageCapture::imageCaptured is also async and could be delivered after QCameraImageCapture::imageSaved. Fixes tst_QCameraBackend::testCameraCapture and tst_QCameraBackend::testCaptureToBuffer Change-Id: I47ee22c39cd2570f20a3e75a80249ed16ca52d0e Fixes: QTBUG-73582 Reviewed-by: Oliver Wolff Reviewed-by: Andy Shaw --- tests/auto/integration/qcamerabackend/tst_qcamerabackend.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/auto/integration/qcamerabackend/tst_qcamerabackend.cpp b/tests/auto/integration/qcamerabackend/tst_qcamerabackend.cpp index b568f38fc..f5a947a6e 100644 --- a/tests/auto/integration/qcamerabackend/tst_qcamerabackend.cpp +++ b/tests/auto/integration/qcamerabackend/tst_qcamerabackend.cpp @@ -378,7 +378,7 @@ void tst_QCameraBackend::testCameraCapture() QTRY_VERIFY(!savedSignal.isEmpty()); - QCOMPARE(capturedSignal.size(), 1); + QTRY_COMPARE(capturedSignal.size(), 1); QCOMPARE(capturedSignal.last().first().toInt(), id); QCOMPARE(errorSignal.size(), 0); QCOMPARE(imageCapture.error(), QCameraImageCapture::NoError); @@ -436,7 +436,7 @@ void tst_QCameraBackend::testCaptureToBuffer() QTRY_VERIFY(!imageAvailableSignal.isEmpty()); QVERIFY(errorSignal.isEmpty()); - QVERIFY(!capturedSignal.isEmpty()); + QTRY_VERIFY(!capturedSignal.isEmpty()); QVERIFY(!imageAvailableSignal.isEmpty()); QTest::qWait(2000); -- cgit v1.2.3 From ff67f0e8ddbf23354f5ee0ecd9328af1373433c7 Mon Sep 17 00:00:00 2001 From: Val Doroshchuk Date: Wed, 3 Apr 2019 10:02:55 +0200 Subject: Android: Move test files to qrc in tst_QSoundEffect MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since TESTDATA files are not deployed to device, need to add them to qrc. Task-number: QTBUG-73583 Change-Id: Ie0b934b1d9bd46f8748ca93a3502ef1643271217 Reviewed-by: Christian Strømme --- tests/auto/integration/qsoundeffect/qsoundeffect.pro | 3 +++ tests/auto/integration/qsoundeffect/resources.qrc | 8 ++++++++ 2 files changed, 11 insertions(+) create mode 100644 tests/auto/integration/qsoundeffect/resources.qrc diff --git a/tests/auto/integration/qsoundeffect/qsoundeffect.pro b/tests/auto/integration/qsoundeffect/qsoundeffect.pro index 8ec2e458a..868346a2e 100644 --- a/tests/auto/integration/qsoundeffect/qsoundeffect.pro +++ b/tests/auto/integration/qsoundeffect/qsoundeffect.pro @@ -14,3 +14,6 @@ unix:!mac { } TESTDATA += test.wav + +RESOURCES += \ + resources.qrc diff --git a/tests/auto/integration/qsoundeffect/resources.qrc b/tests/auto/integration/qsoundeffect/resources.qrc new file mode 100644 index 000000000..24700560d --- /dev/null +++ b/tests/auto/integration/qsoundeffect/resources.qrc @@ -0,0 +1,8 @@ + + + test.wav + test_corrupted.wav + test_tone.wav + test24.wav + + -- cgit v1.2.3 From 82601d8b43faf560373b73674087955dcf427ead Mon Sep 17 00:00:00 2001 From: Val Doroshchuk Date: Fri, 29 Mar 2019 13:50:15 +0100 Subject: Android: Move inline qml to separate file in tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since androiddeployqt is looking for qml modules in qml/js files only, it is unable to deploy qml plugins for inline qml from cpp. Hence modules are never found while compiling inline qml. Fixes tst_QDeclarativeVideoOutputWindow and tst_QDeclarativeVideoOutput Fixes: QTBUG-73597 Fixes: QTBUG-73598 Change-Id: I43dc1ac38522779ff37f04b055a41b2c05eb7619 Reviewed-by: Christian Strømme --- .../auto/integration/qdeclarativevideooutput/main.qml | 7 +++++++ .../qdeclarativevideooutput.pro | 2 ++ .../auto/integration/qdeclarativevideooutput/qml.qrc | 5 +++++ .../tst_qdeclarativevideooutput.cpp | 19 +++++-------------- .../qdeclarativevideooutput_window/main.qml | 13 +++++++++++++ .../qdeclarativevideooutput_window.pro | 2 ++ .../qdeclarativevideooutput_window/qml.qrc | 5 +++++ .../tst_qdeclarativevideooutput_window.cpp | 16 +--------------- 8 files changed, 40 insertions(+), 29 deletions(-) create mode 100644 tests/auto/integration/qdeclarativevideooutput/main.qml create mode 100644 tests/auto/integration/qdeclarativevideooutput/qml.qrc create mode 100644 tests/auto/integration/qdeclarativevideooutput_window/main.qml create mode 100644 tests/auto/integration/qdeclarativevideooutput_window/qml.qrc diff --git a/tests/auto/integration/qdeclarativevideooutput/main.qml b/tests/auto/integration/qdeclarativevideooutput/main.qml new file mode 100644 index 000000000..e456adf6c --- /dev/null +++ b/tests/auto/integration/qdeclarativevideooutput/main.qml @@ -0,0 +1,7 @@ +import QtQuick 2.0 +import QtMultimedia 5.0 + +VideoOutput { + width: 150 + height: 100 +} diff --git a/tests/auto/integration/qdeclarativevideooutput/qdeclarativevideooutput.pro b/tests/auto/integration/qdeclarativevideooutput/qdeclarativevideooutput.pro index e68e87f79..1f3a00b42 100644 --- a/tests/auto/integration/qdeclarativevideooutput/qdeclarativevideooutput.pro +++ b/tests/auto/integration/qdeclarativevideooutput/qdeclarativevideooutput.pro @@ -3,6 +3,8 @@ TARGET = tst_qdeclarativevideooutput QT += multimedia-private qml testlib quick CONFIG += testcase +RESOURCES += qml.qrc + SOURCES += \ tst_qdeclarativevideooutput.cpp diff --git a/tests/auto/integration/qdeclarativevideooutput/qml.qrc b/tests/auto/integration/qdeclarativevideooutput/qml.qrc new file mode 100644 index 000000000..5f6483ac3 --- /dev/null +++ b/tests/auto/integration/qdeclarativevideooutput/qml.qrc @@ -0,0 +1,5 @@ + + + main.qml + + diff --git a/tests/auto/integration/qdeclarativevideooutput/tst_qdeclarativevideooutput.cpp b/tests/auto/integration/qdeclarativevideooutput/tst_qdeclarativevideooutput.cpp index 707a01512..0e9cf6aa3 100644 --- a/tests/auto/integration/qdeclarativevideooutput/tst_qdeclarativevideooutput.cpp +++ b/tests/auto/integration/qdeclarativevideooutput/tst_qdeclarativevideooutput.cpp @@ -123,7 +123,6 @@ private slots: private: QQmlEngine m_engine; - QByteArray m_plainQML; // Variables used for the mapping test QQmlComponent *m_mappingComponent; @@ -138,17 +137,9 @@ private: void tst_QDeclarativeVideoOutput::initTestCase() { - m_plainQML = \ - "import QtQuick 2.0\n" \ - "import QtMultimedia 5.0\n" \ - "VideoOutput {" \ - " width: 150;" \ - " height: 100;" \ - "}"; - // We initialize the mapping vars here m_mappingComponent = new QQmlComponent(&m_engine); - m_mappingComponent->setData(m_plainQML, QUrl()); + m_mappingComponent->loadUrl(QUrl("qrc:/main.qml")); m_mappingSurface = new SurfaceHolder(this); m_mappingOutput = m_mappingComponent->create(); @@ -173,7 +164,7 @@ tst_QDeclarativeVideoOutput::tst_QDeclarativeVideoOutput() void tst_QDeclarativeVideoOutput::fillMode() { QQmlComponent component(&m_engine); - component.setData(m_plainQML, QUrl()); + component.loadUrl(QUrl("qrc:/main.qml")); QObject *videoOutput = component.create(); QVERIFY(videoOutput != 0); @@ -202,7 +193,7 @@ void tst_QDeclarativeVideoOutput::fillMode() void tst_QDeclarativeVideoOutput::orientation() { QQmlComponent component(&m_engine); - component.setData(m_plainQML, QUrl()); + component.loadUrl(QUrl("qrc:/main.qml")); QObject *videoOutput = component.create(); QVERIFY(videoOutput != 0); @@ -255,7 +246,7 @@ void tst_QDeclarativeVideoOutput::orientation() void tst_QDeclarativeVideoOutput::surfaceSource() { QQmlComponent component(&m_engine); - component.setData(m_plainQML, QUrl()); + component.loadUrl(QUrl("qrc:/main.qml")); QObject *videoOutput = component.create(); QVERIFY(videoOutput != 0); @@ -341,7 +332,7 @@ void tst_QDeclarativeVideoOutput::surfaceSource() void tst_QDeclarativeVideoOutput::sourceRect() { QQmlComponent component(&m_engine); - component.setData(m_plainQML, QUrl()); + component.loadUrl(QUrl("qrc:/main.qml")); QObject *videoOutput = component.create(); QVERIFY(videoOutput != 0); diff --git a/tests/auto/integration/qdeclarativevideooutput_window/main.qml b/tests/auto/integration/qdeclarativevideooutput_window/main.qml new file mode 100644 index 000000000..8866be147 --- /dev/null +++ b/tests/auto/integration/qdeclarativevideooutput_window/main.qml @@ -0,0 +1,13 @@ +import QtQuick 2.0 +import QtMultimedia 5.0 + +Item { + width: 200 + height: 200 + VideoOutput { + objectName: "videoOutput" + x: 25; y: 50 + width: 150 + height: 100 + } +} diff --git a/tests/auto/integration/qdeclarativevideooutput_window/qdeclarativevideooutput_window.pro b/tests/auto/integration/qdeclarativevideooutput_window/qdeclarativevideooutput_window.pro index 975c1d6d0..82108d220 100644 --- a/tests/auto/integration/qdeclarativevideooutput_window/qdeclarativevideooutput_window.pro +++ b/tests/auto/integration/qdeclarativevideooutput_window/qdeclarativevideooutput_window.pro @@ -3,6 +3,8 @@ TARGET = tst_qdeclarativevideooutput_window QT += multimedia-private qml testlib quick CONFIG += testcase +RESOURCES += qml.qrc + SOURCES += \ tst_qdeclarativevideooutput_window.cpp diff --git a/tests/auto/integration/qdeclarativevideooutput_window/qml.qrc b/tests/auto/integration/qdeclarativevideooutput_window/qml.qrc new file mode 100644 index 000000000..5f6483ac3 --- /dev/null +++ b/tests/auto/integration/qdeclarativevideooutput_window/qml.qrc @@ -0,0 +1,5 @@ + + + main.qml + + diff --git a/tests/auto/integration/qdeclarativevideooutput_window/tst_qdeclarativevideooutput_window.cpp b/tests/auto/integration/qdeclarativevideooutput_window/tst_qdeclarativevideooutput_window.cpp index dd739d0e3..645b5d3c6 100644 --- a/tests/auto/integration/qdeclarativevideooutput_window/tst_qdeclarativevideooutput_window.cpp +++ b/tests/auto/integration/qdeclarativevideooutput_window/tst_qdeclarativevideooutput_window.cpp @@ -193,22 +193,8 @@ void tst_QDeclarativeVideoOutputWindow::initTestCase() { qRegisterMetaType(); - const QByteArray qmlSource = - "import QtQuick 2.0\n" - "import QtMultimedia 5.0\n\n" - "Item {" - " width: 200;" - " height: 200;" - " VideoOutput {" - " objectName: \"videoOutput\";" - " x: 25; y: 50;" - " width: 150;" - " height: 100;" - " }" - "}"; - QQmlComponent component(&m_engine); - component.setData(qmlSource, QUrl()); + component.loadUrl(QUrl("qrc:/main.qml")); m_rootItem.reset(qobject_cast(component.create())); m_videoItem = m_rootItem->findChild("videoOutput"); -- cgit v1.2.3 From 110dd5b405ce4f8146da4430e3180833610712ad Mon Sep 17 00:00:00 2001 From: Val Doroshchuk Date: Thu, 28 Mar 2019 14:52:00 +0100 Subject: Android: Fix status of QMediaRecorder after start/stop MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If the camera is ready for capture -> QMediaRecorder::LoadedStatus. If CaptureVideo is changed to CaptureStillImage -> StoppedState and UnloadedStatus. If camera's status is StoppingStatus -> StoppedState and UnloadedStatus. If camera's status is LoadingStatus -> LoadingStatus. If recording is requested -> RecordingState and RecordingStatus. If recording is audio-only -> immediately LoadedStatus, before start and after stop. Fixes tst_QCameraBackend::testVideoRecording Task-number: QTBUG-73582 Change-Id: I976c4e3afab529e0949571c4002e9ceba74cac97 Reviewed-by: Christian Strømme --- .../src/mediacapture/qandroidcapturesession.cpp | 79 ++++++++++------------ .../src/mediacapture/qandroidcapturesession.h | 1 - 2 files changed, 35 insertions(+), 45 deletions(-) diff --git a/src/plugins/android/src/mediacapture/qandroidcapturesession.cpp b/src/plugins/android/src/mediacapture/qandroidcapturesession.cpp index bdc7ed403..bc9bc983e 100644 --- a/src/plugins/android/src/mediacapture/qandroidcapturesession.cpp +++ b/src/plugins/android/src/mediacapture/qandroidcapturesession.cpp @@ -73,16 +73,41 @@ QAndroidCaptureSession::QAndroidCaptureSession(QAndroidCameraSession *cameraSess QMediaStorageLocation::Sounds, AndroidMultimediaUtils::getDefaultMediaDirectory(AndroidMultimediaUtils::Sounds)); - connect(this, SIGNAL(stateChanged(QMediaRecorder::State)), this, SLOT(updateStatus())); - if (cameraSession) { connect(cameraSession, SIGNAL(opened()), this, SLOT(onCameraOpened())); - connect(cameraSession, SIGNAL(statusChanged(QCamera::Status)), this, SLOT(updateStatus())); - connect(cameraSession, SIGNAL(captureModeChanged(QCamera::CaptureModes)), - this, SLOT(updateStatus())); - connect(cameraSession, SIGNAL(readyForCaptureChanged(bool)), this, SLOT(updateStatus())); + connect(cameraSession, &QAndroidCameraSession::statusChanged, this, + [this](QCamera::Status status) { + if (status == QCamera::UnavailableStatus) { + setState(QMediaRecorder::StoppedState); + setStatus(QMediaRecorder::UnavailableStatus); + return; + } + + // Stop recording when stopping the camera. + if (status == QCamera::StoppingStatus) { + setState(QMediaRecorder::StoppedState); + setStatus(QMediaRecorder::UnloadedStatus); + return; + } + + if (status == QCamera::LoadingStatus) + setStatus(QMediaRecorder::LoadingStatus); + }); + connect(cameraSession, &QAndroidCameraSession::captureModeChanged, this, + [this](QCamera::CaptureModes mode) { + if (!mode.testFlag(QCamera::CaptureVideo)) { + setState(QMediaRecorder::StoppedState); + setStatus(QMediaRecorder::UnloadedStatus); + } + }); + connect(cameraSession, &QAndroidCameraSession::readyForCaptureChanged, this, + [this](bool ready) { + if (ready) + setStatus(QMediaRecorder::LoadedStatus); + }); } else { - updateStatus(); + // Audio-only recording. + setStatus(QMediaRecorder::LoadedStatus); } m_notifyTimer.setInterval(1000); @@ -277,6 +302,7 @@ void QAndroidCaptureSession::start() m_state = QMediaRecorder::RecordingState; emit stateChanged(m_state); + setStatus(QMediaRecorder::RecordingStatus); } void QAndroidCaptureSession::stop(bool error) @@ -315,6 +341,8 @@ void QAndroidCaptureSession::stop(bool error) m_state = QMediaRecorder::StoppedState; emit stateChanged(m_state); + if (!m_cameraSession) + setStatus(QMediaRecorder::LoadedStatus); } void QAndroidCaptureSession::setStatus(QMediaRecorder::Status status) @@ -539,43 +567,6 @@ QAndroidCaptureSession::CaptureProfile QAndroidCaptureSession::getProfile(int id return profile; } -void QAndroidCaptureSession::updateStatus() -{ - if (m_cameraSession) { - // Video recording - - // stop recording when stopping the camera - if (m_cameraSession->status() == QCamera::StoppingStatus - || !m_cameraSession->captureMode().testFlag(QCamera::CaptureVideo)) { - setState(QMediaRecorder::StoppedState); - return; - } - - if (m_state == QMediaRecorder::RecordingState) { - setStatus(QMediaRecorder::RecordingStatus); - } else if (m_cameraSession->status() == QCamera::UnavailableStatus) { - setStatus(QMediaRecorder::UnavailableStatus); - } else if (m_cameraSession->captureMode().testFlag(QCamera::CaptureVideo) - && m_cameraSession->isReadyForCapture()) { - if (m_cameraSession->status() == QCamera::StartingStatus) - setStatus(QMediaRecorder::LoadingStatus); - else if (m_cameraSession->status() == QCamera::ActiveStatus) - setStatus(QMediaRecorder::LoadedStatus); - else - setStatus(QMediaRecorder::UnloadedStatus); - } else { - setStatus(QMediaRecorder::UnloadedStatus); - } - - } else { - // Audio-only recording - if (m_state == QMediaRecorder::RecordingState) - setStatus(QMediaRecorder::RecordingStatus); - else - setStatus(QMediaRecorder::LoadedStatus); - } -} - void QAndroidCaptureSession::onError(int what, int extra) { Q_UNUSED(what) diff --git a/src/plugins/android/src/mediacapture/qandroidcapturesession.h b/src/plugins/android/src/mediacapture/qandroidcapturesession.h index 286fd1aa2..8cfb9ad2a 100644 --- a/src/plugins/android/src/mediacapture/qandroidcapturesession.h +++ b/src/plugins/android/src/mediacapture/qandroidcapturesession.h @@ -97,7 +97,6 @@ Q_SIGNALS: private Q_SLOTS: void updateDuration(); void onCameraOpened(); - void updateStatus(); void onError(int what, int extra); void onInfo(int what, int extra); -- cgit v1.2.3 From 49cd7b16b2ae77246da10993958a989753abecb8 Mon Sep 17 00:00:00 2001 From: Val Doroshchuk Date: Thu, 28 Mar 2019 14:19:53 +0100 Subject: Android: Fix tst_QCameraBackend to find FinalizingStatus MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes tst_QCameraBackend::testVideoRecording. Since QMediaRecorder::FinalizingStatus could be sent immediately, it is sane to wait for final QMediaRecorder::LoadedStatus only. But added a fix to check if the FinalizingStatus has been emitted. Task-number: QTBUG-73582 Change-Id: I63fc6b1951a712215ee5d982233924a79ac1c124 Reviewed-by: Oliver Wolff Reviewed-by: Andy Shaw Reviewed-by: Christian Strømme --- tests/auto/integration/qcamerabackend/tst_qcamerabackend.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/tests/auto/integration/qcamerabackend/tst_qcamerabackend.cpp b/tests/auto/integration/qcamerabackend/tst_qcamerabackend.cpp index f5a947a6e..b8d501c12 100644 --- a/tests/auto/integration/qcamerabackend/tst_qcamerabackend.cpp +++ b/tests/auto/integration/qcamerabackend/tst_qcamerabackend.cpp @@ -672,9 +672,16 @@ void tst_QCameraBackend::testVideoRecording() QTRY_COMPARE(recorder.status(), QMediaRecorder::RecordingStatus); QCOMPARE(recorderStatusSignal.last().first().value(), recorder.status()); QTest::qWait(5000); + recorderStatusSignal.clear(); recorder.stop(); - QCOMPARE(recorder.status(), QMediaRecorder::FinalizingStatus); - QCOMPARE(recorderStatusSignal.last().first().value(), recorder.status()); + bool foundFinalizingStatus = false; + for (auto &list : recorderStatusSignal) { + if (list.contains(QVariant(QMediaRecorder::FinalizingStatus))) { + foundFinalizingStatus = true; + break; + } + } + QVERIFY(foundFinalizingStatus); QTRY_COMPARE(recorder.status(), QMediaRecorder::LoadedStatus); QCOMPARE(recorderStatusSignal.last().first().value(), recorder.status()); -- cgit v1.2.3 From 3f8b0a916e9e0ca4e17900e1399ee8ad6bbf35b8 Mon Sep 17 00:00:00 2001 From: Val Doroshchuk Date: Wed, 3 Apr 2019 10:24:53 +0200 Subject: Android/AudioTrack: Fix crash when it is unable to get min buffer size MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit android/media/AudioTrack::getMinBufferSize might return an error instead of a size. Task-number: QTBUG-73583 Change-Id: I52e2d214ab7065bcea9d983979bb0b83717428af Reviewed-by: Christian Strømme --- src/plugins/opensles/qopenslesaudiooutput.cpp | 6 ++++++ src/plugins/opensles/qopenslesengine.cpp | 13 +++++++------ 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/plugins/opensles/qopenslesaudiooutput.cpp b/src/plugins/opensles/qopenslesaudiooutput.cpp index 0b1f444bd..381ce0ec2 100644 --- a/src/plugins/opensles/qopenslesaudiooutput.cpp +++ b/src/plugins/opensles/qopenslesaudiooutput.cpp @@ -569,6 +569,12 @@ bool QOpenSLESAudioOutput::preparePlayer() const int lowLatencyBufferSize = QOpenSLESEngine::getLowLatencyBufferSize(m_format); const int defaultBufferSize = QOpenSLESEngine::getDefaultBufferSize(m_format); + if (defaultBufferSize <= 0) { + qWarning() << "Unable to get minimum buffer size, returned" << defaultBufferSize; + setError(QAudio::FatalError); + return false; + } + // Buffer size if (m_bufferSize <= 0) { m_bufferSize = defaultBufferSize; diff --git a/src/plugins/opensles/qopenslesengine.cpp b/src/plugins/opensles/qopenslesengine.cpp index 1a16cc2a3..43cdcb276 100644 --- a/src/plugins/opensles/qopenslesengine.cpp +++ b/src/plugins/opensles/qopenslesengine.cpp @@ -239,12 +239,13 @@ int QOpenSLESEngine::getDefaultBufferSize(const QAudioFormat &format) }(); const int sampleRate = format.sampleRate(); - return QJNIObjectPrivate::callStaticMethod("android/media/AudioTrack", - "getMinBufferSize", - "(III)I", - sampleRate, - channelConfig, - audioFormat); + const int minBufferSize = QJNIObjectPrivate::callStaticMethod("android/media/AudioTrack", + "getMinBufferSize", + "(III)I", + sampleRate, + channelConfig, + audioFormat); + return minBufferSize > 0 ? minBufferSize : format.bytesForDuration(DEFAULT_PERIOD_TIME_MS); #else return format.bytesForDuration(DEFAULT_PERIOD_TIME_MS); #endif // Q_OS_ANDROID -- cgit v1.2.3 From c785e8fcfd0202a88a5e28f8a1410a83f95a9c9f Mon Sep 17 00:00:00 2001 From: Val Doroshchuk Date: Mon, 8 Apr 2019 11:03:36 +0200 Subject: QWindowsAudioInput: Set volume only if it has been requested Currently if the device gets opened, also its volume is set to 100%. The volume should be set only if it has been requested. Change-Id: I9dc4ab29ad71f3ac6556c6dd32c7b8e5d69efab2 Fixes: QTBUG-75024 Reviewed-by: Oliver Wolff Reviewed-by: Maurice Kalinowski --- src/plugins/windowsaudio/qwindowsaudioinput.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/plugins/windowsaudio/qwindowsaudioinput.cpp b/src/plugins/windowsaudio/qwindowsaudioinput.cpp index 00b36cfe4..717baaff0 100644 --- a/src/plugins/windowsaudio/qwindowsaudioinput.cpp +++ b/src/plugins/windowsaudio/qwindowsaudioinput.cpp @@ -74,7 +74,7 @@ QWindowsAudioInput::QWindowsAudioInput(const QByteArray &device) waveBlockOffset = 0; mixerID = 0; - cachedVolume = 1.0f; + cachedVolume = -1.0f; memset(&mixerLineControls, 0, sizeof(mixerLineControls)); } @@ -228,7 +228,7 @@ qreal QWindowsAudioInput::volume() const return detailsUnsigned.dwValue / 65535.0; } - return cachedVolume; + return qFuzzyCompare(cachedVolume, qreal(-1.0f)) ? 1.0f : cachedVolume; } void QWindowsAudioInput::setFormat(const QAudioFormat& fmt) @@ -429,7 +429,7 @@ void QWindowsAudioInput::initMixer() mixerLineControls.pamxctrl = new MIXERCONTROL[mixerLineControls.cControls]; if (mixerGetLineControls(mixerID, &mixerLineControls, MIXER_GETLINECONTROLSF_ALL) != MMSYSERR_NOERROR) closeMixer(); - else + else if (!qFuzzyCompare(cachedVolume, qreal(-1.0f))) setVolume(cachedVolume); } } -- cgit v1.2.3 From 4fb893c9375a8e721f8de01230e6d5d64dc92375 Mon Sep 17 00:00:00 2001 From: Val Doroshchuk Date: Mon, 8 Apr 2019 15:22:39 +0200 Subject: EVR: Don't repaint with black until the surface is active MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A frame must be presented until pause/play is called. Fixes tst_QMediaPlayerBackend::seekPauseSeek Task-number: QTBUG-65574 Change-Id: I6946c5a5977c44fed80abce364a4222845898016 Reviewed-by: Christian Strømme --- src/plugins/common/evr/evrcustompresenter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/common/evr/evrcustompresenter.cpp b/src/plugins/common/evr/evrcustompresenter.cpp index 872b97bcc..470f670e4 100644 --- a/src/plugins/common/evr/evrcustompresenter.cpp +++ b/src/plugins/common/evr/evrcustompresenter.cpp @@ -1143,7 +1143,7 @@ HRESULT EVRCustomPresenter::flush() sample->Release(); m_frameStep.samples.clear(); - if (m_renderState == RenderStopped) { + if (m_renderState == RenderStopped && m_surface->isActive()) { // Repaint with black. presentSample(NULL); } -- cgit v1.2.3 From c8716f68feb5a38473cbd54972b9a9f095e9e24d Mon Sep 17 00:00:00 2001 From: Val Doroshchuk Date: Mon, 8 Apr 2019 13:26:38 +0200 Subject: Windows: Reset position on pause in QMediaPlayer after EOS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit pause() should reset position to the beginning after EOS. Fixes tst_QMediaPlayerBackend::processEOS Task-number: QTBUG-65574 Change-Id: I4802102bde657d7a3dde0b426c335b021207ae08 Reviewed-by: Christian Strømme --- src/plugins/directshow/player/directshowplayerservice.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/plugins/directshow/player/directshowplayerservice.cpp b/src/plugins/directshow/player/directshowplayerservice.cpp index 08d99d735..3974c59a5 100644 --- a/src/plugins/directshow/player/directshowplayerservice.cpp +++ b/src/plugins/directshow/player/directshowplayerservice.cpp @@ -951,7 +951,6 @@ void DirectShowPlayerService::pause() if (m_executedTasks & Render) { if (m_executedTasks & Stop) { - m_atEnd = false; if (m_seekPosition == -1) { m_dontCacheNextSeekResult = true; m_seekPosition = 0; @@ -977,7 +976,8 @@ void DirectShowPlayerService::doPause(QMutexLocker *locker) control->Release(); if (SUCCEEDED(hr)) { - if (IMediaSeeking *seeking = com_cast(m_graph, IID_IMediaSeeking)) { + IMediaSeeking *seeking = com_cast(m_graph, IID_IMediaSeeking); + if (!m_atEnd && seeking) { LONGLONG position = 0; seeking->GetCurrentPosition(&position); @@ -986,6 +986,7 @@ void DirectShowPlayerService::doPause(QMutexLocker *locker) m_position = position / qt_directShowTimeScale; } else { m_position = 0; + m_atEnd = false; } m_executedTasks |= Pause; -- cgit v1.2.3