From 2522fbc195905d34455130ab42bcb9076e021a1e Mon Sep 17 00:00:00 2001 From: Piotr Srebrny Date: Tue, 21 Sep 2021 18:48:32 +0200 Subject: Disconnect QAudioInput from QCaptureMediaSession in destructor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The expected behavior of elements connected to the capture session is to disconnect automatically when deleted. This patch adds this behavior to the QAudioInput object. Additionally, this patch enables automatic handover of QAudioInput between two capture session. Change-Id: If9e3b4ad1bf4c8abf117dc67367716ebc759c1c1 Reviewed-by: André de la Rocha Reviewed-by: Lars Knoll (cherry picked from commit 1d1c4dbf2aa81ff9fc9e386283791ca39deb227f) Reviewed-by: Qt Cherry-pick Bot --- src/multimedia/audio/qaudioinput.cpp | 17 +++++++++ src/multimedia/audio/qaudioinput.h | 5 +-- src/multimedia/platform/qplatformaudioinput_p.h | 1 + src/multimedia/recording/qmediacapturesession.cpp | 12 +++++-- .../tst_qmediacapturesession.cpp | 40 ++++++++++++++++++++++ 5 files changed, 71 insertions(+), 4 deletions(-) diff --git a/src/multimedia/audio/qaudioinput.cpp b/src/multimedia/audio/qaudioinput.cpp index 1d0d68f0f..8472ceb6c 100644 --- a/src/multimedia/audio/qaudioinput.cpp +++ b/src/multimedia/audio/qaudioinput.cpp @@ -43,6 +43,8 @@ #include #include +#include + /*! \qmltype AudioInput \instantiates QAudioInput @@ -99,6 +101,7 @@ QAudioInput::QAudioInput(const QAudioDevice &device, QObject *parent) QAudioInput::~QAudioInput() { + setDisconnectFunction({}); delete d; } @@ -197,4 +200,18 @@ void QAudioInput::setDevice(const QAudioDevice &device) d->setAudioDevice(dev); emit deviceChanged(); } + +/*! + \internal +*/ +void QAudioInput::setDisconnectFunction(std::function disconnectFunction) +{ + if (d->disconnectFunction) { + auto df = d->disconnectFunction; + d->disconnectFunction = {}; + df(); + } + d->disconnectFunction = std::move(disconnectFunction); +} + #include "moc_qaudioinput.cpp" diff --git a/src/multimedia/audio/qaudioinput.h b/src/multimedia/audio/qaudioinput.h index 10c3ae1c9..3b3154fb5 100644 --- a/src/multimedia/audio/qaudioinput.h +++ b/src/multimedia/audio/qaudioinput.h @@ -75,9 +75,10 @@ Q_SIGNALS: void volumeChanged(float volume); void mutedChanged(bool muted); -public: - QPlatformAudioInput *handle() const { return d; } private: + QPlatformAudioInput *handle() const { return d; } + void setDisconnectFunction(std::function disconnectFunction); + friend class QMediaCaptureSession; Q_DISABLE_COPY(QAudioInput) QPlatformAudioInput *d = nullptr; }; diff --git a/src/multimedia/platform/qplatformaudioinput_p.h b/src/multimedia/platform/qplatformaudioinput_p.h index c4e4334b3..c1e3c1ecc 100644 --- a/src/multimedia/platform/qplatformaudioinput_p.h +++ b/src/multimedia/platform/qplatformaudioinput_p.h @@ -71,6 +71,7 @@ public: QAudioDevice device; float volume = 1.; bool muted = false; + std::function disconnectFunction; }; QT_END_NAMESPACE diff --git a/src/multimedia/recording/qmediacapturesession.cpp b/src/multimedia/recording/qmediacapturesession.cpp index 55b223d90..c83a43153 100644 --- a/src/multimedia/recording/qmediacapturesession.cpp +++ b/src/multimedia/recording/qmediacapturesession.cpp @@ -174,6 +174,7 @@ QMediaCaptureSession::~QMediaCaptureSession() } if (d_ptr->imageCapture) d_ptr->imageCapture->setCaptureSession(nullptr); + setAudioInput(nullptr); d_ptr->setVideoSink(nullptr); delete d_ptr->captureSession; delete d_ptr; @@ -199,10 +200,17 @@ QAudioInput *QMediaCaptureSession::audioInput() const */ void QMediaCaptureSession::setAudioInput(QAudioInput *input) { - if (d_ptr->audioInput == input) + QAudioInput *oldInput = d_ptr->audioInput; + if (oldInput == input) return; d_ptr->audioInput = input; - d_ptr->captureSession->setAudioInput(input ? input->handle() : nullptr); + d_ptr->captureSession->setAudioInput(nullptr); + if (oldInput) + oldInput->setDisconnectFunction({}); + if (input) { + input->setDisconnectFunction([this](){ setAudioInput(nullptr); }); + d_ptr->captureSession->setAudioInput(input->handle()); + } emit audioInputChanged(); } diff --git a/tests/auto/integration/qmediacapturesession/tst_qmediacapturesession.cpp b/tests/auto/integration/qmediacapturesession/tst_qmediacapturesession.cpp index 73f4901b4..918466e51 100644 --- a/tests/auto/integration/qmediacapturesession/tst_qmediacapturesession.cpp +++ b/tests/auto/integration/qmediacapturesession/tst_qmediacapturesession.cpp @@ -65,6 +65,8 @@ private slots: void can_add_and_remove_AudioInput_with_and_without_AudioOutput_attached(); void can_change_AudioDevices_on_attached_AudioInput(); void can_change_AudioInput_during_recording(); + void disconnects_deleted_AudioInput(); + void can_move_AudioInput_between_sessions(); void can_add_and_remove_Camera(); void can_disconnect_Camera_when_recording(); @@ -226,6 +228,44 @@ void tst_QMediaCaptureSession::can_change_AudioInput_during_recording() QFile(fileName).remove(); } +void tst_QMediaCaptureSession::disconnects_deleted_AudioInput() +{ + QMediaCaptureSession session; + QSignalSpy audioInputChanged(&session, SIGNAL(audioInputChanged())); + { + QAudioInput input; + session.setAudioInput(&input); + QTRY_COMPARE(audioInputChanged.count(), 1); + } + QVERIFY(session.audioInput() == nullptr); + QTRY_COMPARE(audioInputChanged.count(), 2); +} + +void tst_QMediaCaptureSession::can_move_AudioInput_between_sessions() +{ + QMediaCaptureSession session0; + QMediaCaptureSession session1; + QSignalSpy audioInputChanged0(&session0, SIGNAL(audioInputChanged())); + QSignalSpy audioInputChanged1(&session1, SIGNAL(audioInputChanged())); + + QAudioInput input; + { + QMediaCaptureSession session2; + QSignalSpy audioInputChanged2(&session2, SIGNAL(audioInputChanged())); + session2.setAudioInput(&input); + QTRY_COMPARE(audioInputChanged2.count(), 1); + } + session0.setAudioInput(&input); + QTRY_COMPARE(audioInputChanged0.count(), 1); + QVERIFY(session0.audioInput() != nullptr); + + session1.setAudioInput(&input); + QTRY_COMPARE(audioInputChanged0.count(), 2); + QVERIFY(session0.audioInput() == nullptr); + QTRY_COMPARE(audioInputChanged1.count(), 1); + QVERIFY(session1.audioInput() != nullptr); +} + void tst_QMediaCaptureSession::can_add_and_remove_Camera() { QCamera camera; -- cgit v1.2.1