diff options
author | Doris Verria <doris.verria@qt.io> | 2021-12-20 11:53:28 +0100 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2021-12-21 10:16:28 +0000 |
commit | 76149a93cf1e32e296f8a3eccdb65753202be802 (patch) | |
tree | d0ec5b3b066eec5543e171a199095d3a1ff322d2 | |
parent | 9b23e0c8fb1fc2ec92478f1aec595313851a40b7 (diff) |
AVFMediaAssetWriter: Properly reset queues and writer inputs before starting new writing
We were resetting the video queue only if there was a video input
attached to the session, causing the old video queue to still be valid
otherwise. This led to crashes when the next recording would be audio-
only because of a failed assert.
To fix, release the audio and video queues and set them to null when
we set up the writer for a new recording. Do the same for the camera
and audio writer input.
Also, create an audio queue only if there is an audio input attached
to the session.
Fixes: QTBUG-99296
Fixes: QTBUG-99176
Change-Id: If08b7f514ba3f264509ee78b494d8d1544991ad6
Reviewed-by: Piotr Srebrny <piotr.srebrny@qt.io>
Reviewed-by: André de la Rocha <andre.rocha@qt.io>
(cherry picked from commit 4bae921b03c00714efb3ef1eea06d4ca8f9b70d4)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r-- | src/multimedia/platform/darwin/camera/avfmediaassetwriter.mm | 33 |
1 files changed, 20 insertions, 13 deletions
diff --git a/src/multimedia/platform/darwin/camera/avfmediaassetwriter.mm b/src/multimedia/platform/darwin/camera/avfmediaassetwriter.mm index 6e7686c7a..61f248c72 100644 --- a/src/multimedia/platform/darwin/camera/avfmediaassetwriter.mm +++ b/src/multimedia/platform/darwin/camera/avfmediaassetwriter.mm @@ -174,6 +174,7 @@ using AVFAtomicInt64 = QAtomicInteger<qint64>; return false; } + m_videoQueue.reset(); if (session->videoInput() && session->videoOutput() && session->videoOutput()->videoDataOutput()) { m_videoQueue.reset(dispatch_queue_create("video-output-queue", DISPATCH_QUEUE_SERIAL)); if (!m_videoQueue) { @@ -183,12 +184,15 @@ using AVFAtomicInt64 = QAtomicInteger<qint64>; dispatch_set_target_queue(m_videoQueue, dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0)); } - m_audioQueue.reset(dispatch_queue_create("audio-output-queue", DISPATCH_QUEUE_SERIAL)); - if (!m_audioQueue) { - qDebugCamera() << Q_FUNC_INFO << "failed to create audio queue"; - if (!m_videoQueue) - return false; - // But we still can write video! + m_audioQueue.reset(); + if (session->audioInput() && session->audioOutput()) { + m_audioQueue.reset(dispatch_queue_create("audio-output-queue", DISPATCH_QUEUE_SERIAL)); + if (!m_audioQueue) { + qDebugCamera() << Q_FUNC_INFO << "failed to create audio queue"; + if (!m_videoQueue) + return false; + // But we still can write video! + } } auto fileType = QDarwinFormatInfo::avFileTypeForContainerFormat(fileFormat); @@ -504,6 +508,7 @@ using AVFAtomicInt64 = QAtomicInteger<qint64>; AVFCameraSession *session = m_service->session(); + m_cameraWriterInput.reset(); if (m_videoQueue) { Q_ASSERT(session->videoCaptureDevice() && session->videoOutput() && session->videoOutput()->videoDataOutput()); @@ -522,7 +527,8 @@ using AVFAtomicInt64 = QAtomicInteger<qint64>; m_cameraWriterInput.data().expectsMediaDataInRealTime = YES; } - if (session->audioOutput()) { + m_audioWriterInput.reset(); + if (m_audioQueue) { CMFormatDescriptionRef sourceFormat = session->audioCaptureDevice() ? session->audioCaptureDevice().activeFormat.formatDescription : 0; @@ -552,15 +558,16 @@ using AVFAtomicInt64 = QAtomicInteger<qint64>; - (void)setQueues { Q_ASSERT(m_service && m_service->session()); + AVFCameraSession *session = m_service->session(); + if (m_videoQueue) { - Q_ASSERT(m_service->session()->videoOutput() - && m_service->session()->videoOutput()->videoDataOutput()); - [m_service->session()->videoOutput()->videoDataOutput() setSampleBufferDelegate:self queue:m_videoQueue]; + Q_ASSERT(session->videoOutput() && session->videoOutput()->videoDataOutput()); + [session->videoOutput()->videoDataOutput() setSampleBufferDelegate:self queue:m_videoQueue]; } - if (m_service->session()->audioOutput()) { - Q_ASSERT(m_audioQueue); - [m_service->session()->audioOutput() setSampleBufferDelegate:self queue:m_audioQueue]; + if (m_audioQueue) { + Q_ASSERT(session->audioOutput()); + [session->audioOutput() setSampleBufferDelegate:self queue:m_audioQueue]; } } |