summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDoris Verria <doris.verria@qt.io>2021-12-20 11:53:28 +0100
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2021-12-21 10:16:28 +0000
commit76149a93cf1e32e296f8a3eccdb65753202be802 (patch)
treed0ec5b3b066eec5543e171a199095d3a1ff322d2
parent9b23e0c8fb1fc2ec92478f1aec595313851a40b7 (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.mm33
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];
}
}