diff options
author | Timur Pocheptsov <timur.pocheptsov@qt.io> | 2024-02-08 13:18:59 +0100 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2024-02-09 20:45:06 +0000 |
commit | a46ea51c86b76e9beb320ad9975af3199af09343 (patch) | |
tree | e4c2788c905b5f95cd7d011b63f07370696ea77b | |
parent | 12361ebe2d7f21b026b86861c72117c79b34f423 (diff) |
Media capture session - protect against recursive call
When setting audio input/output for the second time we can end up as nullptr
for input/output device, because of recursive call to setAudioInput/Output with nullptr
from disconnect callback function of our previous input/output. Also, avoid emitting
changed signal twice.
Pick-to: 6.6 6.5
Task-number: QTBUG-122053
Change-Id: Ie47363591a2dc60868a391ccbc3229bd2ff235de
Reviewed-by: Artem Dyomin <artem.dyomin@qt.io>
(cherry picked from commit 0053d80e068f9b1edd451d87772cff134e3a9e57)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r-- | src/multimedia/recording/qmediacapturesession.cpp | 15 | ||||
-rw-r--r-- | tests/auto/integration/qmediacapturesession/tst_qmediacapturesession.cpp | 24 |
2 files changed, 37 insertions, 2 deletions
diff --git a/src/multimedia/recording/qmediacapturesession.cpp b/src/multimedia/recording/qmediacapturesession.cpp index e8c3ed138..0ff804bf4 100644 --- a/src/multimedia/recording/qmediacapturesession.cpp +++ b/src/multimedia/recording/qmediacapturesession.cpp @@ -184,7 +184,11 @@ void QMediaCaptureSession::setAudioInput(QAudioInput *input) QAudioInput *oldInput = d_ptr->audioInput; if (oldInput == input) return; - d_ptr->audioInput = input; + + // To avoid double emit of audioInputChanged + // from recursive setAudioInput(nullptr) call. + d_ptr->audioInput = nullptr; + if (d_ptr->captureSession) d_ptr->captureSession->setAudioInput(nullptr); if (oldInput) @@ -194,6 +198,7 @@ void QMediaCaptureSession::setAudioInput(QAudioInput *input) if (d_ptr->captureSession) d_ptr->captureSession->setAudioInput(input->handle()); } + d_ptr->audioInput = input; emit audioInputChanged(); } @@ -502,7 +507,12 @@ void QMediaCaptureSession::setAudioOutput(QAudioOutput *output) QAudioOutput *oldOutput = d_ptr->audioOutput; if (oldOutput == output) return; - d_ptr->audioOutput = output; + + // We don't want to end up with signal emitted + // twice (from recursive call setAudioInput(nullptr) + // from oldOutput->setDisconnectFunction(): + d_ptr->audioOutput = nullptr; + if (d_ptr->captureSession) d_ptr->captureSession->setAudioOutput(nullptr); if (oldOutput) @@ -512,6 +522,7 @@ void QMediaCaptureSession::setAudioOutput(QAudioOutput *output) if (d_ptr->captureSession) d_ptr->captureSession->setAudioOutput(output->handle()); } + d_ptr->audioOutput = output; emit audioOutputChanged(); } /*! diff --git a/tests/auto/integration/qmediacapturesession/tst_qmediacapturesession.cpp b/tests/auto/integration/qmediacapturesession/tst_qmediacapturesession.cpp index 671bf63ec..c8d487704 100644 --- a/tests/auto/integration/qmediacapturesession/tst_qmediacapturesession.cpp +++ b/tests/auto/integration/qmediacapturesession/tst_qmediacapturesession.cpp @@ -79,6 +79,8 @@ private slots: void capture_is_not_available_when_Camera_is_null(); void can_add_ImageCapture_and_capture_during_recording(); + void can_reset_audio_input_output(); + private: void recordOk(QMediaCaptureSession &session); void recordFail(QMediaCaptureSession &session); @@ -1014,6 +1016,28 @@ void tst_QMediaCaptureSession::testAudioMute() QFile(actualLocation).remove(); } +void tst_QMediaCaptureSession::can_reset_audio_input_output() +{ + QAudioInput in1; + QMediaCaptureSession session; + session.setAudioInput(&in1); + QVERIFY(session.audioInput() != nullptr); + QAudioInput in2; + QSignalSpy changeSpy1(&session, &QMediaCaptureSession::audioInputChanged); + session.setAudioInput(&in2); + QVERIFY(session.audioInput() != nullptr); + QCOMPARE(changeSpy1.count(), 1); + + QAudioOutput out1; + session.setAudioOutput(&out1); + QVERIFY(session.audioOutput() != nullptr); + QSignalSpy changeSpy2(&session, &QMediaCaptureSession::audioOutputChanged); + QAudioOutput out2; + session.setAudioOutput(&out2); + QVERIFY(session.audioOutput() != nullptr); + QCOMPARE(changeSpy2.count(), 1); +} + QTEST_MAIN(tst_QMediaCaptureSession) #include "tst_qmediacapturesession.moc" |