summaryrefslogtreecommitdiffstats
path: root/src/plugins/avfoundation/camera/avfmediarecordercontrol_ios.mm
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/avfoundation/camera/avfmediarecordercontrol_ios.mm')
-rw-r--r--src/plugins/avfoundation/camera/avfmediarecordercontrol_ios.mm414
1 files changed, 0 insertions, 414 deletions
diff --git a/src/plugins/avfoundation/camera/avfmediarecordercontrol_ios.mm b/src/plugins/avfoundation/camera/avfmediarecordercontrol_ios.mm
deleted file mode 100644
index 33064827d..000000000
--- a/src/plugins/avfoundation/camera/avfmediarecordercontrol_ios.mm
+++ /dev/null
@@ -1,414 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies).
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-#include "avfmediarecordercontrol_ios.h"
-#include "avfcamerarenderercontrol.h"
-#include "avfcamerasession.h"
-#include "avfcameracontrol.h"
-#include "avfcameraservice.h"
-#include "avfcameradebug.h"
-#include "avfaudioencodersettingscontrol.h"
-#include "avfvideoencodersettingscontrol.h"
-#include "avfmediacontainercontrol.h"
-#include "avfcamerautility.h"
-
-#include <QtCore/qmath.h>
-#include <QtCore/qdebug.h>
-
-QT_USE_NAMESPACE
-
-namespace {
-
-bool qt_is_writable_file_URL(NSURL *fileURL)
-{
- Q_ASSERT(fileURL);
-
- if (![fileURL isFileURL])
- return false;
-
- if (NSString *path = [[fileURL path] stringByExpandingTildeInPath]) {
- return [[NSFileManager defaultManager]
- isWritableFileAtPath:[path stringByDeletingLastPathComponent]];
- }
-
- return false;
-}
-
-bool qt_file_exists(NSURL *fileURL)
-{
- Q_ASSERT(fileURL);
-
- if (NSString *path = [[fileURL path] stringByExpandingTildeInPath])
- return [[NSFileManager defaultManager] fileExistsAtPath:path];
-
- return false;
-}
-
-}
-
-AVFMediaRecorderControlIOS::AVFMediaRecorderControlIOS(AVFCameraService *service, QObject *parent)
- : QMediaRecorderControl(parent)
- , m_service(service)
- , m_state(QMediaRecorder::StoppedState)
- , m_lastStatus(QMediaRecorder::UnloadedStatus)
- , m_audioSettings(nil)
- , m_videoSettings(nil)
-{
- Q_ASSERT(service);
-
- m_writer.reset([[QT_MANGLE_NAMESPACE(AVFMediaAssetWriter) alloc] initWithDelegate:this]);
- if (!m_writer) {
- qDebugCamera() << Q_FUNC_INFO << "failed to create an asset writer";
- return;
- }
-
- AVFCameraControl *cameraControl = m_service->cameraControl();
- if (!cameraControl) {
- qDebugCamera() << Q_FUNC_INFO << "camera control is nil";
- return;
- }
-
- connect(cameraControl, SIGNAL(captureModeChanged(QCamera::CaptureModes)),
- SLOT(captureModeChanged(QCamera::CaptureModes)));
- connect(cameraControl, SIGNAL(statusChanged(QCamera::Status)),
- SLOT(cameraStatusChanged(QCamera::Status)));
-}
-
-AVFMediaRecorderControlIOS::~AVFMediaRecorderControlIOS()
-{
- [m_writer abort];
-
- if (m_audioSettings)
- [m_audioSettings release];
- if (m_videoSettings)
- [m_videoSettings release];
-}
-
-QUrl AVFMediaRecorderControlIOS::outputLocation() const
-{
- return m_outputLocation;
-}
-
-bool AVFMediaRecorderControlIOS::setOutputLocation(const QUrl &location)
-{
- m_outputLocation = location;
- return location.scheme() == QLatin1String("file") || location.scheme().isEmpty();
-}
-
-QMediaRecorder::State AVFMediaRecorderControlIOS::state() const
-{
- return m_state;
-}
-
-QMediaRecorder::Status AVFMediaRecorderControlIOS::status() const
-{
- return m_lastStatus;
-}
-
-qint64 AVFMediaRecorderControlIOS::duration() const
-{
- return m_writer.data().durationInMs;
-}
-
-bool AVFMediaRecorderControlIOS::isMuted() const
-{
- return false;
-}
-
-qreal AVFMediaRecorderControlIOS::volume() const
-{
- return 1.;
-}
-
-void AVFMediaRecorderControlIOS::applySettings()
-{
- AVFCameraSession *session = m_service->session();
- if (!session)
- return;
-
- if (m_state != QMediaRecorder::StoppedState
- || (session->state() != QCamera::ActiveState && session->state() != QCamera::LoadedState)
- || !m_service->cameraControl()->captureMode().testFlag(QCamera::CaptureVideo)) {
- return;
- }
-
- // audio settings
- m_audioSettings = m_service->audioEncoderSettingsControl()->applySettings();
- if (m_audioSettings)
- [m_audioSettings retain];
-
- // video settings
- AVCaptureConnection *conn = [m_service->videoOutput()->videoDataOutput() connectionWithMediaType:AVMediaTypeVideo];
- m_videoSettings = m_service->videoEncoderSettingsControl()->applySettings(conn);
- if (m_videoSettings)
- [m_videoSettings retain];
-}
-
-void AVFMediaRecorderControlIOS::unapplySettings()
-{
- m_service->audioEncoderSettingsControl()->unapplySettings();
-
- AVCaptureConnection *conn = [m_service->videoOutput()->videoDataOutput() connectionWithMediaType:AVMediaTypeVideo];
- m_service->videoEncoderSettingsControl()->unapplySettings(conn);
-
- if (m_audioSettings) {
- [m_audioSettings release];
- m_audioSettings = nil;
- }
- if (m_videoSettings) {
- [m_videoSettings release];
- m_videoSettings = nil;
- }
-}
-
-void AVFMediaRecorderControlIOS::setState(QMediaRecorder::State state)
-{
- Q_ASSERT(m_service->session()
- && m_service->session()->captureSession());
-
- if (!m_writer) {
- qDebugCamera() << Q_FUNC_INFO << "Invalid recorder";
- return;
- }
-
- if (state == m_state)
- return;
-
- switch (state) {
- case QMediaRecorder::RecordingState:
- {
- AVFCameraControl *cameraControl = m_service->cameraControl();
- Q_ASSERT(cameraControl);
-
- if (!(cameraControl->captureMode() & QCamera::CaptureVideo)) {
- qDebugCamera() << Q_FUNC_INFO << "wrong capture mode, CaptureVideo expected";
- Q_EMIT error(QMediaRecorder::ResourceError, tr("Failed to start recording"));
- return;
- }
-
- if (cameraControl->status() != QCamera::ActiveStatus) {
- qDebugCamera() << Q_FUNC_INFO << "can not start record while camera is not active";
- Q_EMIT error(QMediaRecorder::ResourceError, tr("Failed to start recording"));
- return;
- }
-
- const QString path(m_outputLocation.scheme() == QLatin1String("file") ?
- m_outputLocation.path() : m_outputLocation.toString());
- const QUrl fileURL(QUrl::fromLocalFile(m_storageLocation.generateFileName(path, QCamera::CaptureVideo,
- QLatin1String("clip_"),
- m_service->mediaContainerControl()->containerFormat())));
-
- NSURL *nsFileURL = fileURL.toNSURL();
- if (!nsFileURL) {
- qWarning() << Q_FUNC_INFO << "invalid output URL:" << fileURL;
- Q_EMIT error(QMediaRecorder::ResourceError, tr("Invalid output file URL"));
- return;
- }
- if (!qt_is_writable_file_URL(nsFileURL)) {
- qWarning() << Q_FUNC_INFO << "invalid output URL:" << fileURL
- << "(the location is not writable)";
- Q_EMIT error(QMediaRecorder::ResourceError, tr("Non-writeable file location"));
- return;
- }
- if (qt_file_exists(nsFileURL)) {
- // We test for/handle this error here since AWAssetWriter will raise an
- // Objective-C exception, which is not good at all.
- qWarning() << Q_FUNC_INFO << "invalid output URL:" << fileURL
- << "(file already exists)";
- Q_EMIT error(QMediaRecorder::ResourceError, tr("File already exists"));
- return;
- }
-
- AVCaptureSession *session = m_service->session()->captureSession();
- // We stop session now so that no more frames for renderer's queue
- // generated, will restart in assetWriterStarted.
- [session stopRunning];
-
- applySettings();
-
- // Make sure the video is recorded in device orientation.
- // The top of the video will match the side of the device which is on top
- // when recording starts (regardless of the UI orientation).
- AVFCameraInfo cameraInfo = m_service->session()->activeCameraInfo();
- int screenOrientation = 360 - m_orientationHandler.currentOrientation();
- float rotation = 0;
- if (cameraInfo.position == QCamera::FrontFace)
- rotation = (screenOrientation + cameraInfo.orientation) % 360;
- else
- rotation = (screenOrientation + (360 - cameraInfo.orientation)) % 360;
-
- if ([m_writer setupWithFileURL:nsFileURL
- cameraService:m_service
- audioSettings:m_audioSettings
- videoSettings:m_videoSettings
- transform:CGAffineTransformMakeRotation(qDegreesToRadians(rotation))]) {
-
- m_state = QMediaRecorder::RecordingState;
- m_lastStatus = QMediaRecorder::StartingStatus;
-
- Q_EMIT actualLocationChanged(fileURL);
- Q_EMIT stateChanged(m_state);
- Q_EMIT statusChanged(m_lastStatus);
-
- // Apple recommends to call startRunning and do all
- // setup on a special queue, and that's what we had
- // initially (dispatch_async to writerQueue). Unfortunately,
- // writer's queue is not the only queue/thread that can
- // access/modify the session, and as a result we have
- // all possible data/race-conditions with Obj-C exceptions
- // at best and something worse in general.
- // Now we try to only modify session on the same thread.
- [m_writer start];
- } else {
- [session startRunning];
- Q_EMIT error(QMediaRecorder::FormatError, tr("Failed to start recording"));
- }
- } break;
- case QMediaRecorder::PausedState:
- {
- Q_EMIT error(QMediaRecorder::FormatError, tr("Recording pause not supported"));
- return;
- } break;
- case QMediaRecorder::StoppedState:
- {
- // Do not check the camera status, we can stop if we started.
- stopWriter();
- }
- }
-}
-
-void AVFMediaRecorderControlIOS::setMuted(bool muted)
-{
- Q_UNUSED(muted);
- qDebugCamera() << Q_FUNC_INFO << "not implemented";
-}
-
-void AVFMediaRecorderControlIOS::setVolume(qreal volume)
-{
- Q_UNUSED(volume);
- qDebugCamera() << Q_FUNC_INFO << "not implemented";
-}
-
-void AVFMediaRecorderControlIOS::assetWriterStarted()
-{
- m_lastStatus = QMediaRecorder::RecordingStatus;
- Q_EMIT statusChanged(QMediaRecorder::RecordingStatus);
-}
-
-void AVFMediaRecorderControlIOS::assetWriterFinished()
-{
- AVFCameraControl *cameraControl = m_service->cameraControl();
- Q_ASSERT(cameraControl);
-
- const QMediaRecorder::Status lastStatus = m_lastStatus;
- const QMediaRecorder::State lastState = m_state;
- if (cameraControl->captureMode() & QCamera::CaptureVideo)
- m_lastStatus = QMediaRecorder::LoadedStatus;
- else
- m_lastStatus = QMediaRecorder::UnloadedStatus;
-
- unapplySettings();
-
- m_service->videoOutput()->resetCaptureDelegate();
- [m_service->session()->captureSession() startRunning];
- m_state = QMediaRecorder::StoppedState;
- if (m_lastStatus != lastStatus)
- Q_EMIT statusChanged(m_lastStatus);
- if (m_state != lastState)
- Q_EMIT stateChanged(m_state);
-}
-
-void AVFMediaRecorderControlIOS::captureModeChanged(QCamera::CaptureModes newMode)
-{
- AVFCameraControl *cameraControl = m_service->cameraControl();
- Q_ASSERT(cameraControl);
-
- const QMediaRecorder::Status lastStatus = m_lastStatus;
-
- if (newMode & QCamera::CaptureVideo) {
- if (cameraControl->status() == QCamera::ActiveStatus)
- m_lastStatus = QMediaRecorder::LoadedStatus;
- } else {
- if (m_lastStatus == QMediaRecorder::RecordingStatus)
- return stopWriter();
- else
- m_lastStatus = QMediaRecorder::UnloadedStatus;
- }
-
- if (m_lastStatus != lastStatus)
- Q_EMIT statusChanged(m_lastStatus);
-}
-
-void AVFMediaRecorderControlIOS::cameraStatusChanged(QCamera::Status newStatus)
-{
- AVFCameraControl *cameraControl = m_service->cameraControl();
- Q_ASSERT(cameraControl);
-
- const QMediaRecorder::Status lastStatus = m_lastStatus;
- const bool isCapture = cameraControl->captureMode() & QCamera::CaptureVideo;
- if (newStatus == QCamera::StartingStatus) {
- if (isCapture && m_lastStatus == QMediaRecorder::UnloadedStatus)
- m_lastStatus = QMediaRecorder::LoadingStatus;
- } else if (newStatus == QCamera::ActiveStatus) {
- if (isCapture && m_lastStatus == QMediaRecorder::LoadingStatus)
- m_lastStatus = QMediaRecorder::LoadedStatus;
- } else {
- if (m_lastStatus == QMediaRecorder::RecordingStatus)
- return stopWriter();
- if (newStatus == QCamera::UnloadedStatus)
- m_lastStatus = QMediaRecorder::UnloadedStatus;
- }
-
- if (lastStatus != m_lastStatus)
- Q_EMIT statusChanged(m_lastStatus);
-}
-
-void AVFMediaRecorderControlIOS::stopWriter()
-{
- if (m_lastStatus == QMediaRecorder::RecordingStatus) {
- m_lastStatus = QMediaRecorder::FinalizingStatus;
-
- Q_EMIT statusChanged(m_lastStatus);
-
- [m_writer stop];
- }
-}
-
-#include "moc_avfmediarecordercontrol_ios.cpp"