diff options
Diffstat (limited to 'src/plugins/avfoundation')
86 files changed, 0 insertions, 14879 deletions
diff --git a/src/plugins/avfoundation/avfoundation.pro b/src/plugins/avfoundation/avfoundation.pro deleted file mode 100644 index 1110e196b..000000000 --- a/src/plugins/avfoundation/avfoundation.pro +++ /dev/null @@ -1,4 +0,0 @@ -TEMPLATE = subdirs - -SUBDIRS += mediaplayer -!tvos: SUBDIRS += camera diff --git a/src/plugins/avfoundation/camera/avfaudioencodersettingscontrol.h b/src/plugins/avfoundation/camera/avfaudioencodersettingscontrol.h deleted file mode 100644 index 94aa6a8f0..000000000 --- a/src/plugins/avfoundation/camera/avfaudioencodersettingscontrol.h +++ /dev/null @@ -1,75 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** 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$ -** -****************************************************************************/ - -#ifndef AVFAUDIOENCODERSETTINGSCONTROL_H -#define AVFAUDIOENCODERSETTINGSCONTROL_H - -#include <qaudioencodersettingscontrol.h> - -@class NSDictionary; -@class AVCaptureAudioDataOutput; - -QT_BEGIN_NAMESPACE - -class AVFCameraService; - -class AVFAudioEncoderSettingsControl : public QAudioEncoderSettingsControl -{ -public: - explicit AVFAudioEncoderSettingsControl(AVFCameraService *service); - - QStringList supportedAudioCodecs() const override; - QString codecDescription(const QString &codecName) const override; - QList<int> supportedSampleRates(const QAudioEncoderSettings &settings, bool *continuous = nullptr) const override; - QAudioEncoderSettings audioSettings() const override; - void setAudioSettings(const QAudioEncoderSettings &settings) override; - - NSDictionary *applySettings(); - void unapplySettings(); - -private: - AVFCameraService *m_service; - - QAudioEncoderSettings m_requestedSettings; - QAudioEncoderSettings m_actualSettings; -}; - -QT_END_NAMESPACE - -#endif // AVFAUDIOENCODERSETTINGSCONTROL_H diff --git a/src/plugins/avfoundation/camera/avfaudioencodersettingscontrol.mm b/src/plugins/avfoundation/camera/avfaudioencodersettingscontrol.mm deleted file mode 100644 index 1aeb44ff6..000000000 --- a/src/plugins/avfoundation/camera/avfaudioencodersettingscontrol.mm +++ /dev/null @@ -1,226 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** 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 "avfaudioencodersettingscontrol.h" - -#include "avfcameraservice.h" -#include "avfcamerasession.h" - -#include <AVFoundation/AVFoundation.h> -#include <CoreAudio/CoreAudioTypes.h> - -QT_BEGIN_NAMESPACE - -struct AudioCodecInfo -{ - QString description; - int id; - - AudioCodecInfo() : id(0) { } - AudioCodecInfo(const QString &desc, int i) - : description(desc), id(i) - { } -}; - -typedef QMap<QString, AudioCodecInfo> SupportedAudioCodecs; -Q_GLOBAL_STATIC_WITH_ARGS(QString , defaultCodec, (QLatin1String("aac"))) -Q_GLOBAL_STATIC(SupportedAudioCodecs, supportedCodecs) - -AVFAudioEncoderSettingsControl::AVFAudioEncoderSettingsControl(AVFCameraService *service) - : QAudioEncoderSettingsControl() - , m_service(service) -{ - if (supportedCodecs->isEmpty()) { - supportedCodecs->insert(QStringLiteral("lpcm"), - AudioCodecInfo(QStringLiteral("Linear PCM"), - kAudioFormatLinearPCM)); - supportedCodecs->insert(QStringLiteral("ulaw"), - AudioCodecInfo(QStringLiteral("PCM Mu-Law 2:1"), - kAudioFormatULaw)); - supportedCodecs->insert(QStringLiteral("alaw"), - AudioCodecInfo(QStringLiteral("PCM A-Law 2:1"), - kAudioFormatALaw)); - supportedCodecs->insert(QStringLiteral("ima4"), - AudioCodecInfo(QStringLiteral("IMA 4:1 ADPCM"), - kAudioFormatAppleIMA4)); - supportedCodecs->insert(QStringLiteral("alac"), - AudioCodecInfo(QStringLiteral("Apple Lossless Audio Codec"), - kAudioFormatAppleLossless)); - supportedCodecs->insert(QStringLiteral("aac"), - AudioCodecInfo(QStringLiteral("MPEG-4 Low Complexity AAC"), - kAudioFormatMPEG4AAC)); - supportedCodecs->insert(QStringLiteral("aach"), - AudioCodecInfo(QStringLiteral("MPEG-4 High Efficiency AAC"), - kAudioFormatMPEG4AAC_HE)); - supportedCodecs->insert(QStringLiteral("aacl"), - AudioCodecInfo(QStringLiteral("MPEG-4 AAC Low Delay"), - kAudioFormatMPEG4AAC_LD)); - supportedCodecs->insert(QStringLiteral("aace"), - AudioCodecInfo(QStringLiteral("MPEG-4 AAC Enhanced Low Delay"), - kAudioFormatMPEG4AAC_ELD)); - supportedCodecs->insert(QStringLiteral("aacf"), - AudioCodecInfo(QStringLiteral("MPEG-4 AAC Enhanced Low Delay with SBR"), - kAudioFormatMPEG4AAC_ELD_SBR)); - supportedCodecs->insert(QStringLiteral("aacp"), - AudioCodecInfo(QStringLiteral("MPEG-4 HE AAC V2"), - kAudioFormatMPEG4AAC_HE_V2)); - supportedCodecs->insert(QStringLiteral("ilbc"), - AudioCodecInfo(QStringLiteral("iLBC"), - kAudioFormatiLBC)); - } -} - -QStringList AVFAudioEncoderSettingsControl::supportedAudioCodecs() const -{ - return supportedCodecs->keys(); -} - -QString AVFAudioEncoderSettingsControl::codecDescription(const QString &codecName) const -{ - return supportedCodecs->value(codecName).description; -} - -QList<int> AVFAudioEncoderSettingsControl::supportedSampleRates(const QAudioEncoderSettings &settings, bool *continuous) const -{ - Q_UNUSED(settings); - - if (continuous) - *continuous = true; - - return QList<int>() << 8000 << 96000; -} - -QAudioEncoderSettings AVFAudioEncoderSettingsControl::audioSettings() const -{ - return m_actualSettings; -} - -void AVFAudioEncoderSettingsControl::setAudioSettings(const QAudioEncoderSettings &settings) -{ - if (m_requestedSettings == settings) - return; - - m_requestedSettings = m_actualSettings = settings; -} - -NSDictionary *AVFAudioEncoderSettingsControl::applySettings() -{ - if (m_service->session()->state() != QCamera::LoadedState && - m_service->session()->state() != QCamera::ActiveState) { - return nil; - } - - NSMutableDictionary *settings = [NSMutableDictionary dictionary]; - - QString codec = m_requestedSettings.codec().isEmpty() ? *defaultCodec : m_requestedSettings.codec(); - if (!supportedCodecs->contains(codec)) { - qWarning("Unsupported codec: '%s'", codec.toLocal8Bit().constData()); - codec = *defaultCodec; - } - [settings setObject:[NSNumber numberWithInt:supportedCodecs->value(codec).id] forKey:AVFormatIDKey]; - m_actualSettings.setCodec(codec); - -#ifdef Q_OS_OSX - if (m_requestedSettings.encodingMode() == QMultimedia::ConstantQualityEncoding) { - int quality; - switch (m_requestedSettings.quality()) { - case QMultimedia::VeryLowQuality: - quality = AVAudioQualityMin; - break; - case QMultimedia::LowQuality: - quality = AVAudioQualityLow; - break; - case QMultimedia::HighQuality: - quality = AVAudioQualityHigh; - break; - case QMultimedia::VeryHighQuality: - quality = AVAudioQualityMax; - break; - case QMultimedia::NormalQuality: - default: - quality = AVAudioQualityMedium; - break; - } - [settings setObject:[NSNumber numberWithInt:quality] forKey:AVEncoderAudioQualityKey]; - - } else -#endif - if (m_requestedSettings.bitRate() > 0){ - [settings setObject:[NSNumber numberWithInt:m_requestedSettings.bitRate()] forKey:AVEncoderBitRateKey]; - } - - int sampleRate = m_requestedSettings.sampleRate(); - int channelCount = m_requestedSettings.channelCount(); - -#ifdef Q_OS_IOS - // Some keys are mandatory only on iOS - if (codec == QLatin1String("lpcm")) { - [settings setObject:[NSNumber numberWithInt:16] forKey:AVLinearPCMBitDepthKey]; - [settings setObject:[NSNumber numberWithInt:NO] forKey:AVLinearPCMIsBigEndianKey]; - [settings setObject:[NSNumber numberWithInt:NO] forKey:AVLinearPCMIsFloatKey]; - [settings setObject:[NSNumber numberWithInt:NO] forKey:AVLinearPCMIsNonInterleaved]; - } - - if (codec == QLatin1String("alac")) - [settings setObject:[NSNumber numberWithInt:24] forKey:AVEncoderBitDepthHintKey]; - - if (sampleRate <= 0) - sampleRate = codec == QLatin1String("ilbc") ? 8000 : 44100; - if (channelCount <= 0) - channelCount = codec == QLatin1String("ilbc") ? 1 : 2; -#endif - - if (sampleRate > 0) { - [settings setObject:[NSNumber numberWithInt:sampleRate] forKey:AVSampleRateKey]; - m_actualSettings.setSampleRate(sampleRate); - } - if (channelCount > 0) { - [settings setObject:[NSNumber numberWithInt:channelCount] forKey:AVNumberOfChannelsKey]; - m_actualSettings.setChannelCount(channelCount); - } - - return settings; -} - -void AVFAudioEncoderSettingsControl::unapplySettings() -{ - m_actualSettings = m_requestedSettings; -} - -QT_END_NAMESPACE diff --git a/src/plugins/avfoundation/camera/avfaudioinputselectorcontrol.h b/src/plugins/avfoundation/camera/avfaudioinputselectorcontrol.h deleted file mode 100644 index a902a71f9..000000000 --- a/src/plugins/avfoundation/camera/avfaudioinputselectorcontrol.h +++ /dev/null @@ -1,83 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** 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$ -** -****************************************************************************/ - -#ifndef AVFAUDIOINPUTSELECTORCONTROL_H -#define AVFAUDIOINPUTSELECTORCONTROL_H - -#include <QtMultimedia/qaudioinputselectorcontrol.h> -#include <QtCore/qstringlist.h> - -#import <AVFoundation/AVFoundation.h> - -QT_BEGIN_NAMESPACE - -class AVFCameraSession; -class AVFCameraService; - -class AVFAudioInputSelectorControl : public QAudioInputSelectorControl -{ -Q_OBJECT -public: - AVFAudioInputSelectorControl(AVFCameraService *service, QObject *parent = nullptr); - ~AVFAudioInputSelectorControl(); - - QList<QString> availableInputs() const override; - QString inputDescription(const QString &name) const override; - QString defaultInput() const override; - QString activeInput() const override; - -public Q_SLOTS: - void setActiveInput(const QString &name) override; - -public: - //device changed since the last createCaptureDevice() - bool isDirty() const { return m_dirty; } - AVCaptureDevice *createCaptureDevice(); - -private: - QString m_activeInput; - bool m_dirty; - QString m_defaultDevice; - QStringList m_devices; - QMap<QString, QString> m_deviceDescriptions; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/avfoundation/camera/avfaudioinputselectorcontrol.mm b/src/plugins/avfoundation/camera/avfaudioinputselectorcontrol.mm deleted file mode 100644 index de29fd970..000000000 --- a/src/plugins/avfoundation/camera/avfaudioinputselectorcontrol.mm +++ /dev/null @@ -1,119 +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 "avfcameradebug.h" -#include "avfaudioinputselectorcontrol.h" -#include "avfcameraservice.h" - -#import <AVFoundation/AVFoundation.h> - -QT_USE_NAMESPACE - -AVFAudioInputSelectorControl::AVFAudioInputSelectorControl(AVFCameraService *service, QObject *parent) - : QAudioInputSelectorControl(parent) - , m_dirty(true) -{ - Q_UNUSED(service); - NSArray *videoDevices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeAudio]; - for (AVCaptureDevice *device in videoDevices) { - QString deviceId = QString::fromUtf8([[device uniqueID] UTF8String]); - m_devices << deviceId; - m_deviceDescriptions.insert(deviceId, - QString::fromUtf8([[device localizedName] UTF8String])); - } - - AVCaptureDevice *defaultDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeAudio]; - if (defaultDevice) { - m_defaultDevice = QString::fromUtf8([defaultDevice.uniqueID UTF8String]); - m_activeInput = m_defaultDevice; - } -} - -AVFAudioInputSelectorControl::~AVFAudioInputSelectorControl() -{ -} - -QList<QString> AVFAudioInputSelectorControl::availableInputs() const -{ - return m_devices; -} - -QString AVFAudioInputSelectorControl::inputDescription(const QString &name) const -{ - return m_deviceDescriptions.value(name); -} - -QString AVFAudioInputSelectorControl::defaultInput() const -{ - return m_defaultDevice; -} - -QString AVFAudioInputSelectorControl::activeInput() const -{ - return m_activeInput; -} - -void AVFAudioInputSelectorControl::setActiveInput(const QString &name) -{ - if (name != m_activeInput) { - m_activeInput = name; - m_dirty = true; - - Q_EMIT activeInputChanged(m_activeInput); - } -} - -AVCaptureDevice *AVFAudioInputSelectorControl::createCaptureDevice() -{ - m_dirty = false; - AVCaptureDevice *device = nullptr; - - if (!m_activeInput.isEmpty()) { - device = [AVCaptureDevice deviceWithUniqueID: - [NSString stringWithUTF8String: - m_activeInput.toUtf8().constData()]]; - } - - if (!device) - device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeAudio]; - - return device; -} - -#include "moc_avfaudioinputselectorcontrol.cpp" diff --git a/src/plugins/avfoundation/camera/avfcamera.json b/src/plugins/avfoundation/camera/avfcamera.json deleted file mode 100644 index e4310b62c..000000000 --- a/src/plugins/avfoundation/camera/avfcamera.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "Keys": ["avfoundationcamera"], - "Services": ["org.qt-project.qt.camera"] -} diff --git a/src/plugins/avfoundation/camera/avfcameracontrol.h b/src/plugins/avfoundation/camera/avfcameracontrol.h deleted file mode 100644 index df371e864..000000000 --- a/src/plugins/avfoundation/camera/avfcameracontrol.h +++ /dev/null @@ -1,83 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** 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$ -** -****************************************************************************/ - -#ifndef AVFCAMERACONTROL_H -#define AVFCAMERACONTROL_H - -#include <QtCore/qobject.h> - -#include <QtMultimedia/qcameracontrol.h> - -QT_BEGIN_NAMESPACE - -class AVFCameraSession; -class AVFCameraService; - -class AVFCameraControl : public QCameraControl -{ -Q_OBJECT -public: - AVFCameraControl(AVFCameraService *service, QObject *parent = nullptr); - ~AVFCameraControl(); - - QCamera::State state() const override; - void setState(QCamera::State state) override; - - QCamera::Status status() const override; - - QCamera::CaptureModes captureMode() const override; - void setCaptureMode(QCamera::CaptureModes) override; - bool isCaptureModeSupported(QCamera::CaptureModes mode) const override; - - bool canChangeProperty(PropertyChangeType changeType, QCamera::Status status) const override; - -private Q_SLOTS: - void updateStatus(); - -private: - AVFCameraSession *m_session; - - QCamera::State m_state; - QCamera::Status m_lastStatus; - QCamera::CaptureModes m_captureMode; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/avfoundation/camera/avfcameracontrol.mm b/src/plugins/avfoundation/camera/avfcameracontrol.mm deleted file mode 100644 index c47eecfdf..000000000 --- a/src/plugins/avfoundation/camera/avfcameracontrol.mm +++ /dev/null @@ -1,134 +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 "avfcameradebug.h" -#include "avfcameracontrol.h" -#include "avfcamerasession.h" -#include "avfcameraservice.h" - -QT_USE_NAMESPACE - -AVFCameraControl::AVFCameraControl(AVFCameraService *service, QObject *parent) - : QCameraControl(parent) - , m_session(service->session()) - , m_state(QCamera::UnloadedState) - , m_lastStatus(QCamera::UnloadedStatus) - , m_captureMode(QCamera::CaptureStillImage) -{ - Q_UNUSED(service); - connect(m_session, SIGNAL(stateChanged(QCamera::State)), SLOT(updateStatus())); - connect(this, &AVFCameraControl::captureModeChanged, m_session, &AVFCameraSession::onCaptureModeChanged); -} - -AVFCameraControl::~AVFCameraControl() -{ -} - -QCamera::State AVFCameraControl::state() const -{ - return m_state; -} - -void AVFCameraControl::setState(QCamera::State state) -{ - if (m_state == state) - return; - m_state = state; - m_session->setState(state); - - Q_EMIT stateChanged(m_state); - updateStatus(); -} - -QCamera::Status AVFCameraControl::status() const -{ - static QCamera::Status statusTable[3][3] = { - { QCamera::UnloadedStatus, QCamera::UnloadingStatus, QCamera::StoppingStatus }, //Unloaded state - { QCamera::LoadingStatus, QCamera::LoadedStatus, QCamera::StoppingStatus }, //Loaded state - { QCamera::LoadingStatus, QCamera::StartingStatus, QCamera::ActiveStatus } //ActiveState - }; - - return statusTable[m_state][m_session->state()]; -} - -void AVFCameraControl::updateStatus() -{ - QCamera::Status newStatus = status(); - - if (m_lastStatus != newStatus) { - qDebugCamera() << "Camera status changed: " << m_lastStatus << " -> " << newStatus; - m_lastStatus = newStatus; - Q_EMIT statusChanged(m_lastStatus); - } -} - -QCamera::CaptureModes AVFCameraControl::captureMode() const -{ - return m_captureMode; -} - -void AVFCameraControl::setCaptureMode(QCamera::CaptureModes mode) -{ - if (m_captureMode == mode) - return; - - if (!isCaptureModeSupported(mode)) { - Q_EMIT error(QCamera::NotSupportedFeatureError, tr("Requested capture mode is not supported")); - return; - } - - m_captureMode = mode; - Q_EMIT captureModeChanged(mode); -} - -bool AVFCameraControl::isCaptureModeSupported(QCamera::CaptureModes mode) const -{ - //all the capture modes are supported, including QCamera::CaptureStillImage | QCamera::CaptureVideo - return (mode & (QCamera::CaptureStillImage | QCamera::CaptureVideo)) == mode; -} - -bool AVFCameraControl::canChangeProperty(QCameraControl::PropertyChangeType changeType, QCamera::Status status) const -{ - Q_UNUSED(changeType); - Q_UNUSED(status); - - return true; -} - -#include "moc_avfcameracontrol.cpp" diff --git a/src/plugins/avfoundation/camera/avfcameradebug.h b/src/plugins/avfoundation/camera/avfcameradebug.h deleted file mode 100644 index 8838122e0..000000000 --- a/src/plugins/avfoundation/camera/avfcameradebug.h +++ /dev/null @@ -1,57 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** 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$ -** -****************************************************************************/ - -#ifndef AVFDEBUG_H -#define AVFDEBUG_H - -#include "qtmultimediaglobal.h" - -#include <QtCore/qdebug.h> - -QT_USE_NAMESPACE - -//#define AVF_DEBUG_CAMERA - -#ifdef AVF_DEBUG_CAMERA -#define qDebugCamera qDebug -#else -#define qDebugCamera QT_NO_QDEBUG_MACRO -#endif - -#endif diff --git a/src/plugins/avfoundation/camera/avfcameradevicecontrol.h b/src/plugins/avfoundation/camera/avfcameradevicecontrol.h deleted file mode 100644 index 0a16c0408..000000000 --- a/src/plugins/avfoundation/camera/avfcameradevicecontrol.h +++ /dev/null @@ -1,85 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** 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$ -** -****************************************************************************/ - -#ifndef AVFCAMERADEVICECONTROL_H -#define AVFCAMERADEVICECONTROL_H - -#include <QtMultimedia/qvideodeviceselectorcontrol.h> -#include <QtCore/qstringlist.h> - -#import <AVFoundation/AVFoundation.h> - -QT_BEGIN_NAMESPACE - -class AVFCameraSession; -class AVFCameraService; - -class AVFCameraDeviceControl : public QVideoDeviceSelectorControl -{ -Q_OBJECT -public: - AVFCameraDeviceControl(AVFCameraService *service, QObject *parent = nullptr); - ~AVFCameraDeviceControl(); - - int deviceCount() const override; - - QString deviceName(int index) const override; - QString deviceDescription(int index) const override; - - int defaultDevice() const override; - int selectedDevice() const override; - -public Q_SLOTS: - void setSelectedDevice(int index) override; - -public: - //device changed since the last createCaptureDevice() - bool isDirty() const { return m_dirty; } - AVCaptureDevice *createCaptureDevice(); - -private: - AVFCameraService *m_service; - - int m_selectedDevice; - bool m_dirty; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/avfoundation/camera/avfcameradevicecontrol.mm b/src/plugins/avfoundation/camera/avfcameradevicecontrol.mm deleted file mode 100644 index 907373b61..000000000 --- a/src/plugins/avfoundation/camera/avfcameradevicecontrol.mm +++ /dev/null @@ -1,123 +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 "avfcameradebug.h" -#include "avfcameradevicecontrol.h" -#include "avfcameraservice.h" -#include "avfcamerasession.h" - -QT_USE_NAMESPACE - -AVFCameraDeviceControl::AVFCameraDeviceControl(AVFCameraService *service, QObject *parent) - : QVideoDeviceSelectorControl(parent) - , m_service(service) - , m_selectedDevice(0) - , m_dirty(true) -{ - Q_UNUSED(m_service); -} - -AVFCameraDeviceControl::~AVFCameraDeviceControl() -{ -} - -int AVFCameraDeviceControl::deviceCount() const -{ - return AVFCameraSession::availableCameraDevices().count(); -} - -QString AVFCameraDeviceControl::deviceName(int index) const -{ - const QList<AVFCameraInfo> &devices = AVFCameraSession::availableCameraDevices(); - if (index < 0 || index >= devices.count()) - return QString(); - - return QString::fromUtf8(devices.at(index).deviceId); -} - -QString AVFCameraDeviceControl::deviceDescription(int index) const -{ - const QList<AVFCameraInfo> &devices = AVFCameraSession::availableCameraDevices(); - if (index < 0 || index >= devices.count()) - return QString(); - - return devices.at(index).description; -} - -int AVFCameraDeviceControl::defaultDevice() const -{ - return AVFCameraSession::defaultCameraIndex(); -} - -int AVFCameraDeviceControl::selectedDevice() const -{ - return m_selectedDevice; -} - -void AVFCameraDeviceControl::setSelectedDevice(int index) -{ - if (index >= 0 && - index < deviceCount() && - index != m_selectedDevice) { - m_dirty = true; - m_selectedDevice = index; - Q_EMIT selectedDeviceChanged(index); - Q_EMIT selectedDeviceChanged(deviceName(index)); - } -} - -AVCaptureDevice *AVFCameraDeviceControl::createCaptureDevice() -{ - m_dirty = false; - AVCaptureDevice *device = nullptr; - - QString deviceId = deviceName(m_selectedDevice); - if (!deviceId.isEmpty()) { - device = [AVCaptureDevice deviceWithUniqueID: - [NSString stringWithUTF8String: - deviceId.toUtf8().constData()]]; - } - - if (!device) - device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; - - return device; -} - -#include "moc_avfcameradevicecontrol.cpp" diff --git a/src/plugins/avfoundation/camera/avfcameraexposurecontrol.h b/src/plugins/avfoundation/camera/avfcameraexposurecontrol.h deleted file mode 100644 index 0e2846889..000000000 --- a/src/plugins/avfoundation/camera/avfcameraexposurecontrol.h +++ /dev/null @@ -1,89 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** 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$ -** -****************************************************************************/ - -#ifndef AVFCAMERAEXPOSURECONTROL_H -#define AVFCAMERAEXPOSURECONTROL_H - -#include <QtMultimedia/qcameraexposurecontrol.h> -#include <QtMultimedia/qcameraexposure.h> - -#include <QtCore/qglobal.h> - -QT_BEGIN_NAMESPACE - -class AVFCameraSession; -class AVFCameraService; - -class AVFCameraExposureControl : public QCameraExposureControl -{ - Q_OBJECT - -public: - AVFCameraExposureControl(AVFCameraService *service); - - bool isParameterSupported(ExposureParameter parameter) const override; - QVariantList supportedParameterRange(ExposureParameter parameter, - bool *continuous) const override; - - QVariant requestedValue(ExposureParameter parameter) const override; - QVariant actualValue(ExposureParameter parameter) const override; - bool setValue(ExposureParameter parameter, const QVariant &value) override; - -private Q_SLOTS: - void cameraStateChanged(); - -private: - AVFCameraService *m_service; - AVFCameraSession *m_session; - - QVariant m_requestedMode; - QVariant m_requestedCompensation; - QVariant m_requestedShutterSpeed; - QVariant m_requestedISO; - - // Aux. setters: - bool setExposureMode(const QVariant &value); - bool setExposureCompensation(const QVariant &value); - bool setShutterSpeed(const QVariant &value); - bool setISO(const QVariant &value); -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/avfoundation/camera/avfcameraexposurecontrol.mm b/src/plugins/avfoundation/camera/avfcameraexposurecontrol.mm deleted file mode 100644 index 62387604f..000000000 --- a/src/plugins/avfoundation/camera/avfcameraexposurecontrol.mm +++ /dev/null @@ -1,661 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** 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 "avfcameraexposurecontrol.h" -#include "avfcamerautility.h" -#include "avfcamerasession.h" -#include "avfcameraservice.h" -#include "avfcameradebug.h" - -#include <QtCore/qvariant.h> -#include <QtCore/qpointer.h> -#include <QtCore/qdebug.h> -#include <QtCore/qpair.h> - -#include <AVFoundation/AVFoundation.h> - -#include <limits> - -QT_BEGIN_NAMESPACE - -namespace { - -// All these methods to work with exposure/ISO/SS in custom mode do not support macOS. - -#ifdef Q_OS_IOS - -// Misc. helpers to check values/ranges: - -bool qt_check_ISO_conversion(float isoValue) -{ - if (isoValue >= std::numeric_limits<int>::max()) - return false; - if (isoValue <= std::numeric_limits<int>::min()) - return false; - return true; -} - -bool qt_check_ISO_range(AVCaptureDeviceFormat *format) -{ - // Qt is using int for ISO, AVFoundation - float. It looks like the ISO range - // at the moment can be represented by int (it's max - min > 100, etc.). - Q_ASSERT(format); - if (format.maxISO - format.minISO < 1.) { - // ISO is in some strange units? - return false; - } - - return qt_check_ISO_conversion(format.minISO) - && qt_check_ISO_conversion(format.maxISO); -} - -bool qt_check_exposure_duration(AVCaptureDevice *captureDevice, CMTime duration) -{ - Q_ASSERT(captureDevice); - - AVCaptureDeviceFormat *activeFormat = captureDevice.activeFormat; - if (!activeFormat) { - qDebugCamera() << Q_FUNC_INFO << "failed to obtain capture device format"; - return false; - } - - return CMTimeCompare(duration, activeFormat.minExposureDuration) != -1 - && CMTimeCompare(activeFormat.maxExposureDuration, duration) != -1; -} - -bool qt_check_ISO_value(AVCaptureDevice *captureDevice, int newISO) -{ - Q_ASSERT(captureDevice); - - AVCaptureDeviceFormat *activeFormat = captureDevice.activeFormat; - if (!activeFormat) { - qDebugCamera() << Q_FUNC_INFO << "failed to obtain capture device format"; - return false; - } - - return !(newISO < activeFormat.minISO || newISO > activeFormat.maxISO); -} - -bool qt_exposure_duration_equal(AVCaptureDevice *captureDevice, qreal qDuration) -{ - Q_ASSERT(captureDevice); - const CMTime avDuration = CMTimeMakeWithSeconds(qDuration, captureDevice.exposureDuration.timescale); - return !CMTimeCompare(avDuration, captureDevice.exposureDuration); -} - -bool qt_iso_equal(AVCaptureDevice *captureDevice, int iso) -{ - Q_ASSERT(captureDevice); - return qFuzzyCompare(float(iso), captureDevice.ISO); -} - -bool qt_exposure_bias_equal(AVCaptureDevice *captureDevice, qreal bias) -{ - Q_ASSERT(captureDevice); - return qFuzzyCompare(bias, qreal(captureDevice.exposureTargetBias)); -} - -// Converters: - -bool qt_convert_exposure_mode(AVCaptureDevice *captureDevice, QCameraExposure::ExposureMode mode, - AVCaptureExposureMode &avMode) -{ - // Test if mode supported and convert. - Q_ASSERT(captureDevice); - - if (mode == QCameraExposure::ExposureAuto) { - if ([captureDevice isExposureModeSupported:AVCaptureExposureModeContinuousAutoExposure]) { - avMode = AVCaptureExposureModeContinuousAutoExposure; - return true; - } - } - - if (mode == QCameraExposure::ExposureManual) { - if ([captureDevice isExposureModeSupported:AVCaptureExposureModeCustom]) { - avMode = AVCaptureExposureModeCustom; - return true; - } - } - - return false; -} - -// We set ISO/exposure duration with completion handlers, completion handlers try -// to avoid dangling pointers (thus QPointer for QObjects) and not to create -// a reference loop (in case we have ARC). - -void qt_set_exposure_bias(QPointer<AVFCameraService> service, QPointer<AVFCameraExposureControl> control, - AVCaptureDevice *captureDevice, float bias) -{ - Q_ASSERT(captureDevice); - - __block AVCaptureDevice *device = captureDevice; //For ARC. - - void (^completionHandler)(CMTime syncTime) = ^(CMTime) { - // Test that service control is still alive and that - // capture device is our device, if yes - emit actual value changed. - if (service) { - if (control) { - if (service->session() && service->session()->videoCaptureDevice() == device) - Q_EMIT control->actualValueChanged(int(QCameraExposureControl::ExposureCompensation)); - } - } - device = nil; - }; - - [captureDevice setExposureTargetBias:bias completionHandler:completionHandler]; -} - -void qt_set_duration_iso(QPointer<AVFCameraService> service, QPointer<AVFCameraExposureControl> control, - AVCaptureDevice *captureDevice, CMTime duration, float iso) -{ - Q_ASSERT(captureDevice); - - __block AVCaptureDevice *device = captureDevice; //For ARC. - const bool setDuration = CMTimeCompare(duration, AVCaptureExposureDurationCurrent); - const bool setISO = !qFuzzyCompare(iso, AVCaptureISOCurrent); - - void (^completionHandler)(CMTime syncTime) = ^(CMTime) { - // Test that service control is still alive and that - // capture device is our device, if yes - emit actual value changed. - if (service) { - if (control) { - if (service->session() && service->session()->videoCaptureDevice() == device) { - if (setDuration) - Q_EMIT control->actualValueChanged(int(QCameraExposureControl::ShutterSpeed)); - if (setISO) - Q_EMIT control->actualValueChanged(int(QCameraExposureControl::ISO)); - } - } - } - device = nil; - }; - - [captureDevice setExposureModeCustomWithDuration:duration - ISO:iso - completionHandler:completionHandler]; -} - -#endif // defined(Q_OS_IOS) - -} // Unnamed namespace. - -AVFCameraExposureControl::AVFCameraExposureControl(AVFCameraService *service) - : m_service(service), - m_session(nullptr) -{ - Q_ASSERT(service); - m_session = m_service->session(); - Q_ASSERT(m_session); - - connect(m_session, SIGNAL(stateChanged(QCamera::State)), SLOT(cameraStateChanged())); -} - -bool AVFCameraExposureControl::isParameterSupported(ExposureParameter parameter) const -{ -#ifdef Q_OS_IOS - AVCaptureDevice *captureDevice = m_session->videoCaptureDevice(); - if (!captureDevice) - return false; - - // These are the parameters we have an API to support: - return parameter == QCameraExposureControl::ISO - || parameter == QCameraExposureControl::ShutterSpeed - || parameter == QCameraExposureControl::ExposureCompensation - || parameter == QCameraExposureControl::ExposureMode; -#else - Q_UNUSED(parameter); - return false; -#endif -} - -QVariantList AVFCameraExposureControl::supportedParameterRange(ExposureParameter parameter, - bool *continuous) const -{ - QVariantList parameterRange; -#ifdef Q_OS_IOS - - AVCaptureDevice *captureDevice = m_session->videoCaptureDevice(); - if (!captureDevice || !isParameterSupported(parameter)) { - qDebugCamera() << Q_FUNC_INFO << "parameter not supported"; - return parameterRange; - } - - if (continuous) - *continuous = false; - - AVCaptureDeviceFormat *activeFormat = captureDevice.activeFormat; - - if (parameter == QCameraExposureControl::ISO) { - if (!activeFormat) { - qDebugCamera() << Q_FUNC_INFO << "failed to obtain capture device format"; - return parameterRange; - } - - if (!qt_check_ISO_range(activeFormat)) { - qDebugCamera() << Q_FUNC_INFO << "ISO range can not be represented as int"; - return parameterRange; - } - - parameterRange << QVariant(int(activeFormat.minISO)); - parameterRange << QVariant(int(activeFormat.maxISO)); - if (continuous) - *continuous = true; - } else if (parameter == QCameraExposureControl::ExposureCompensation) { - parameterRange << captureDevice.minExposureTargetBias; - parameterRange << captureDevice.maxExposureTargetBias; - if (continuous) - *continuous = true; - } else if (parameter == QCameraExposureControl::ShutterSpeed) { - if (!activeFormat) { - qDebugCamera() << Q_FUNC_INFO << "failed to obtain capture device format"; - return parameterRange; - } - - // CMTimeGetSeconds returns Float64, test the conversion below, if it's valid? - parameterRange << qreal(CMTimeGetSeconds(activeFormat.minExposureDuration)); - parameterRange << qreal(CMTimeGetSeconds(activeFormat.maxExposureDuration)); - - if (continuous) - *continuous = true; - } else if (parameter == QCameraExposureControl::ExposureMode) { - if ([captureDevice isExposureModeSupported:AVCaptureExposureModeCustom]) - parameterRange << QVariant::fromValue(QCameraExposure::ExposureManual); - - if ([captureDevice isExposureModeSupported:AVCaptureExposureModeContinuousAutoExposure]) - parameterRange << QVariant::fromValue(QCameraExposure::ExposureAuto); - } -#else - Q_UNUSED(parameter); - Q_UNUSED(continuous); -#endif - return parameterRange; -} - -QVariant AVFCameraExposureControl::requestedValue(ExposureParameter parameter) const -{ - if (!isParameterSupported(parameter)) { - qDebugCamera() << Q_FUNC_INFO << "parameter not supported"; - return QVariant(); - } - - if (parameter == QCameraExposureControl::ExposureMode) - return m_requestedMode; - - if (parameter == QCameraExposureControl::ExposureCompensation) - return m_requestedCompensation; - - if (parameter == QCameraExposureControl::ShutterSpeed) - return m_requestedShutterSpeed; - - if (parameter == QCameraExposureControl::ISO) - return m_requestedISO; - - return QVariant(); -} - -QVariant AVFCameraExposureControl::actualValue(ExposureParameter parameter) const -{ -#ifdef Q_OS_IOS - AVCaptureDevice *captureDevice = m_session->videoCaptureDevice(); - if (!captureDevice || !isParameterSupported(parameter)) { - // Actually, at the moment !captiredevice => !isParameterSupported. - qDebugCamera() << Q_FUNC_INFO << "parameter not supported"; - return QVariant(); - } - - if (parameter == QCameraExposureControl::ExposureMode) { - // This code expects exposureMode to be continuous by default ... - if (captureDevice.exposureMode == AVCaptureExposureModeContinuousAutoExposure) - return QVariant::fromValue(QCameraExposure::ExposureAuto); - return QVariant::fromValue(QCameraExposure::ExposureManual); - } - - if (parameter == QCameraExposureControl::ExposureCompensation) - return captureDevice.exposureTargetBias; - - if (parameter == QCameraExposureControl::ShutterSpeed) - return qreal(CMTimeGetSeconds(captureDevice.exposureDuration)); - - if (parameter == QCameraExposureControl::ISO) { - if (captureDevice.activeFormat && qt_check_ISO_range(captureDevice.activeFormat) - && qt_check_ISO_conversion(captureDevice.ISO)) { - // Can be represented as int ... - return int(captureDevice.ISO); - } else { - qDebugCamera() << Q_FUNC_INFO << "ISO can not be represented as int"; - return QVariant(); - } - } -#else - Q_UNUSED(parameter); -#endif - return QVariant(); -} - -bool AVFCameraExposureControl::setValue(ExposureParameter parameter, const QVariant &value) -{ - if (parameter == QCameraExposureControl::ExposureMode) - return setExposureMode(value); - else if (parameter == QCameraExposureControl::ExposureCompensation) - return setExposureCompensation(value); - else if (parameter == QCameraExposureControl::ShutterSpeed) - return setShutterSpeed(value); - else if (parameter == QCameraExposureControl::ISO) - return setISO(value); - - return false; -} - -bool AVFCameraExposureControl::setExposureMode(const QVariant &value) -{ -#ifdef Q_OS_IOS - if (!value.canConvert<QCameraExposure::ExposureMode>()) { - qDebugCamera() << Q_FUNC_INFO << "invalid exposure mode value," - << "QCameraExposure::ExposureMode expected"; - return false; - } - - const QCameraExposure::ExposureMode qtMode = value.value<QCameraExposure::ExposureMode>(); - if (qtMode != QCameraExposure::ExposureAuto && qtMode != QCameraExposure::ExposureManual) { - qDebugCamera() << Q_FUNC_INFO << "exposure mode not supported"; - return false; - } - - AVCaptureDevice *captureDevice = m_session->videoCaptureDevice(); - if (!captureDevice) { - m_requestedMode = value; - Q_EMIT requestedValueChanged(int(QCameraExposureControl::ExposureMode)); - return true; - } - - AVCaptureExposureMode avMode = AVCaptureExposureModeAutoExpose; - if (!qt_convert_exposure_mode(captureDevice, qtMode, avMode)) { - qDebugCamera() << Q_FUNC_INFO << "exposure mode not supported"; - return false; - } - - const AVFConfigurationLock lock(captureDevice); - if (!lock) { - qDebugCamera() << Q_FUNC_INFO << "failed to lock a capture device" - << "for configuration"; - return false; - } - - m_requestedMode = value; - [captureDevice setExposureMode:avMode]; - Q_EMIT requestedValueChanged(int(QCameraExposureControl::ExposureMode)); - Q_EMIT actualValueChanged(int(QCameraExposureControl::ExposureMode)); - - return true; -#else - Q_UNUSED(value); - return false; -#endif -} - -bool AVFCameraExposureControl::setExposureCompensation(const QVariant &value) -{ -#ifdef Q_OS_IOS - if (!value.canConvert<qreal>()) { - qDebugCamera() << Q_FUNC_INFO << "invalid exposure compensation" - <<"value, floating point number expected"; - return false; - } - - const qreal bias = value.toReal(); - AVCaptureDevice *captureDevice = m_session->videoCaptureDevice(); - if (!captureDevice) { - m_requestedCompensation = value; - Q_EMIT requestedValueChanged(int(QCameraExposureControl::ExposureCompensation)); - return true; - } - - if (bias < captureDevice.minExposureTargetBias || bias > captureDevice.maxExposureTargetBias) { - // TODO: mixed fp types! - qDebugCamera() << Q_FUNC_INFO << "exposure compenstation value is" - << "out of range"; - return false; - } - - const AVFConfigurationLock lock(captureDevice); - if (!lock) { - qDebugCamera() << Q_FUNC_INFO << "failed to lock for configuration"; - return false; - } - - qt_set_exposure_bias(m_service, this, captureDevice, bias); - m_requestedCompensation = value; - Q_EMIT requestedValueChanged(int(QCameraExposureControl::ExposureCompensation)); - - return true; -#else - Q_UNUSED(value); - return false; -#endif -} - -bool AVFCameraExposureControl::setShutterSpeed(const QVariant &value) -{ -#ifdef Q_OS_IOS - if (value.isNull()) - return setExposureMode(QVariant::fromValue(QCameraExposure::ExposureAuto)); - - if (!value.canConvert<qreal>()) { - qDebugCamera() << Q_FUNC_INFO << "invalid shutter speed" - << "value, floating point number expected"; - return false; - } - - AVCaptureDevice *captureDevice = m_session->videoCaptureDevice(); - if (!captureDevice) { - m_requestedShutterSpeed = value; - Q_EMIT requestedValueChanged(int(QCameraExposureControl::ShutterSpeed)); - return true; - } - - const CMTime newDuration = CMTimeMakeWithSeconds(value.toReal(), - captureDevice.exposureDuration.timescale); - if (!qt_check_exposure_duration(captureDevice, newDuration)) { - qDebugCamera() << Q_FUNC_INFO << "shutter speed value is out of range"; - return false; - } - - const AVFConfigurationLock lock(captureDevice); - if (!lock) { - qDebugCamera() << Q_FUNC_INFO << "failed to lock for configuration"; - return false; - } - - // Setting the shutter speed (exposure duration in Apple's terms, - // since there is no shutter actually) will also reset - // exposure mode into custom mode. - qt_set_duration_iso(m_service, this, captureDevice, newDuration, AVCaptureISOCurrent); - - m_requestedShutterSpeed = value; - Q_EMIT requestedValueChanged(int(QCameraExposureControl::ShutterSpeed)); - - return true; -#else - Q_UNUSED(value); - return false; -#endif -} - -bool AVFCameraExposureControl::setISO(const QVariant &value) -{ -#ifdef Q_OS_IOS - if (value.isNull()) - return setExposureMode(QVariant::fromValue(QCameraExposure::ExposureAuto)); - - if (!value.canConvert<int>()) { - qDebugCamera() << Q_FUNC_INFO << "invalid ISO value, int expected"; - return false; - } - - AVCaptureDevice *captureDevice = m_session->videoCaptureDevice(); - if (!captureDevice) { - m_requestedISO = value; - Q_EMIT requestedValueChanged(int(QCameraExposureControl::ISO)); - return true; - } - - if (!qt_check_ISO_value(captureDevice, value.toInt())) { - qDebugCamera() << Q_FUNC_INFO << "ISO value is out of range"; - return false; - } - - const AVFConfigurationLock lock(captureDevice); - if (!lock) { - qDebugCamera() << Q_FUNC_INFO << "failed to lock a capture device" - << "for configuration"; - return false; - } - - // Setting the ISO will also reset - // exposure mode to the custom mode. - qt_set_duration_iso(m_service, this, captureDevice, AVCaptureExposureDurationCurrent, value.toInt()); - - m_requestedISO = value; - Q_EMIT requestedValueChanged(int(QCameraExposureControl::ISO)); - - return true; -#else - Q_UNUSED(value); - return false; -#endif -} - -void AVFCameraExposureControl::cameraStateChanged() -{ -#ifdef Q_OS_IOS - if (m_session->state() != QCamera::ActiveState) - return; - - AVCaptureDevice *captureDevice = m_session->videoCaptureDevice(); - if (!captureDevice) { - qDebugCamera() << Q_FUNC_INFO << "capture device is nil, but the session" - << "state is 'active'"; - return; - } - - Q_EMIT parameterRangeChanged(int(QCameraExposureControl::ExposureCompensation)); - Q_EMIT parameterRangeChanged(int(QCameraExposureControl::ExposureMode)); - Q_EMIT parameterRangeChanged(int(QCameraExposureControl::ShutterSpeed)); - Q_EMIT parameterRangeChanged(int(QCameraExposureControl::ISO)); - - const AVFConfigurationLock lock(captureDevice); - - CMTime newDuration = AVCaptureExposureDurationCurrent; - bool setCustomMode = false; - - if (!m_requestedShutterSpeed.isNull() - && !qt_exposure_duration_equal(captureDevice, m_requestedShutterSpeed.toReal())) { - newDuration = CMTimeMakeWithSeconds(m_requestedShutterSpeed.toReal(), - captureDevice.exposureDuration.timescale); - if (!qt_check_exposure_duration(captureDevice, newDuration)) { - qDebugCamera() << Q_FUNC_INFO << "requested exposure duration is out of range"; - return; - } - setCustomMode = true; - } - - float newISO = AVCaptureISOCurrent; - if (!m_requestedISO.isNull() && !qt_iso_equal(captureDevice, m_requestedISO.toInt())) { - newISO = m_requestedISO.toInt(); - if (!qt_check_ISO_value(captureDevice, newISO)) { - qDebugCamera() << Q_FUNC_INFO << "requested ISO value is out of range"; - return; - } - setCustomMode = true; - } - - if (!m_requestedCompensation.isNull() - && !qt_exposure_bias_equal(captureDevice, m_requestedCompensation.toReal())) { - // TODO: mixed fpns. - const qreal bias = m_requestedCompensation.toReal(); - if (bias < captureDevice.minExposureTargetBias || bias > captureDevice.maxExposureTargetBias) { - qDebugCamera() << Q_FUNC_INFO << "exposure compenstation value is" - << "out of range"; - return; - } - if (!lock) { - qDebugCamera() << Q_FUNC_INFO << "failed to lock for configuration"; - return; - } - qt_set_exposure_bias(m_service, this, captureDevice, bias); - } - - // Setting shutter speed (exposure duration) or ISO values - // also reset exposure mode into Custom. With this settings - // we ignore any attempts to set exposure mode. - - if (setCustomMode) { - if (!lock) - qDebugCamera() << Q_FUNC_INFO << "failed to lock for configuration"; - else - qt_set_duration_iso(m_service, this, captureDevice, newDuration, newISO); - return; - } - - if (!m_requestedMode.isNull()) { - QCameraExposure::ExposureMode qtMode = m_requestedMode.value<QCameraExposure::ExposureMode>(); - AVCaptureExposureMode avMode = AVCaptureExposureModeContinuousAutoExposure; - if (!qt_convert_exposure_mode(captureDevice, qtMode, avMode)) { - qDebugCamera() << Q_FUNC_INFO << "requested exposure mode is not supported"; - return; - } - - if (avMode == captureDevice.exposureMode) - return; - - if (!lock) { - qDebugCamera() << Q_FUNC_INFO << "failed to lock for configuration"; - return; - } - - [captureDevice setExposureMode:avMode]; - Q_EMIT actualValueChanged(int(QCameraExposureControl::ExposureMode)); - } -#endif -} - -QT_END_NAMESPACE - -#include "moc_avfcameraexposurecontrol.cpp" diff --git a/src/plugins/avfoundation/camera/avfcameraflashcontrol.h b/src/plugins/avfoundation/camera/avfcameraflashcontrol.h deleted file mode 100644 index 58403e829..000000000 --- a/src/plugins/avfoundation/camera/avfcameraflashcontrol.h +++ /dev/null @@ -1,83 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** 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$ -** -****************************************************************************/ - -#ifndef AVFCAMERAFLASHCONTROL_H -#define AVFCAMERAFLASHCONTROL_H - -#include <QtMultimedia/qcameraflashcontrol.h> -#include <QtMultimedia/qcamera.h> - -#include <QtCore/qlist.h> - -QT_BEGIN_NAMESPACE - -class AVFCameraService; -class AVFCameraSession; - -class AVFCameraFlashControl : public QCameraFlashControl -{ - Q_OBJECT -public: - AVFCameraFlashControl(AVFCameraService *service); - - QCameraExposure::FlashModes flashMode() const override; - void setFlashMode(QCameraExposure::FlashModes mode) override; - bool isFlashModeSupported(QCameraExposure::FlashModes mode) const override; - bool isFlashReady() const override; - -private Q_SLOTS: - void cameraStateChanged(QCamera::State newState); - -private: - bool applyFlashSettings(); - - AVFCameraService *m_service; - AVFCameraSession *m_session; - - // Set of bits: - QCameraExposure::FlashModes m_supportedModes; - // Only one bit set actually: - QCameraExposure::FlashModes m_flashMode; -}; - -QT_END_NAMESPACE - - -#endif // AVFCAMERAFLASHCONTROL_H - diff --git a/src/plugins/avfoundation/camera/avfcameraflashcontrol.mm b/src/plugins/avfoundation/camera/avfcameraflashcontrol.mm deleted file mode 100644 index 42303ce17..000000000 --- a/src/plugins/avfoundation/camera/avfcameraflashcontrol.mm +++ /dev/null @@ -1,233 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** 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 "avfcameraflashcontrol.h" -#include "avfcamerautility.h" -#include "avfcamerasession.h" -#include "avfcameraservice.h" -#include "avfcameradebug.h" - -#include <QtCore/qdebug.h> - -#include <AVFoundation/AVFoundation.h> - - -AVFCameraFlashControl::AVFCameraFlashControl(AVFCameraService *service) - : m_service(service) - , m_session(nullptr) - , m_supportedModes(QCameraExposure::FlashOff) - , m_flashMode(QCameraExposure::FlashOff) -{ - Q_ASSERT(service); - m_session = m_service->session(); - Q_ASSERT(m_session); - - connect(m_session, SIGNAL(stateChanged(QCamera::State)), SLOT(cameraStateChanged(QCamera::State))); -} - -QCameraExposure::FlashModes AVFCameraFlashControl::flashMode() const -{ - return m_flashMode; -} - -void AVFCameraFlashControl::setFlashMode(QCameraExposure::FlashModes mode) -{ - if (m_flashMode == mode) - return; - - if (m_session->state() == QCamera::ActiveState && !isFlashModeSupported(mode)) { - qDebugCamera() << Q_FUNC_INFO << "unsupported mode" << mode; - return; - } - - m_flashMode = mode; - - if (m_session->state() != QCamera::ActiveState) - return; - - applyFlashSettings(); -} - -bool AVFCameraFlashControl::isFlashModeSupported(QCameraExposure::FlashModes mode) const -{ - // From what QCameraExposure has, we can support only these: - // FlashAuto = 0x1, - // FlashOff = 0x2, - // FlashOn = 0x4, - // AVCaptureDevice has these flash modes: - // AVCaptureFlashModeAuto - // AVCaptureFlashModeOff - // AVCaptureFlashModeOn - // QCameraExposure also has: - // FlashTorch = 0x20, --> "Constant light source." - // FlashVideoLight = 0x40. --> "Constant light source." - // AVCaptureDevice: - // AVCaptureTorchModeOff (no mapping) - // AVCaptureTorchModeOn --> FlashVideoLight - // AVCaptureTorchModeAuto (no mapping) - - return m_supportedModes & mode; -} - -bool AVFCameraFlashControl::isFlashReady() const -{ - if (m_session->state() != QCamera::ActiveState) - return false; - - AVCaptureDevice *captureDevice = m_session->videoCaptureDevice(); - if (!captureDevice) - return false; - - if (!captureDevice.hasFlash && !captureDevice.hasTorch) - return false; - - if (!isFlashModeSupported(m_flashMode)) - return false; - -#ifdef Q_OS_IOS - // AVCaptureDevice's docs: - // "The flash may become unavailable if, for example, - // the device overheats and needs to cool off." - if (m_flashMode != QCameraExposure::FlashVideoLight) - return [captureDevice isFlashAvailable]; - - return [captureDevice isTorchAvailable]; -#endif - - return true; -} - -void AVFCameraFlashControl::cameraStateChanged(QCamera::State newState) -{ - if (newState == QCamera::UnloadedState) { - m_supportedModes = QCameraExposure::FlashOff; - Q_EMIT flashReady(false); - } else if (newState == QCamera::ActiveState) { - m_supportedModes = QCameraExposure::FlashOff; - AVCaptureDevice *captureDevice = m_session->videoCaptureDevice(); - if (!captureDevice) { - qDebugCamera() << Q_FUNC_INFO << "no capture device in 'Active' state"; - Q_EMIT flashReady(false); - return; - } - - if (captureDevice.hasFlash) { - if ([captureDevice isFlashModeSupported:AVCaptureFlashModeOn]) - m_supportedModes |= QCameraExposure::FlashOn; - if ([captureDevice isFlashModeSupported:AVCaptureFlashModeAuto]) - m_supportedModes |= QCameraExposure::FlashAuto; - } - - if (captureDevice.hasTorch && [captureDevice isTorchModeSupported:AVCaptureTorchModeOn]) - m_supportedModes |= QCameraExposure::FlashVideoLight; - - Q_EMIT flashReady(applyFlashSettings()); - } -} - -bool AVFCameraFlashControl::applyFlashSettings() -{ - Q_ASSERT(m_session->requestedState() == QCamera::ActiveState); - - AVCaptureDevice *captureDevice = m_session->videoCaptureDevice(); - if (!captureDevice) { - qDebugCamera() << Q_FUNC_INFO << "no capture device found"; - return false; - } - - if (!isFlashModeSupported(m_flashMode)) { - qDebugCamera() << Q_FUNC_INFO << "unsupported mode" << m_flashMode; - return false; - } - - if (!captureDevice.hasFlash && !captureDevice.hasTorch) { - // FlashOff is the only mode we support. - // Return false - flash is not ready. - return false; - } - - const AVFConfigurationLock lock(captureDevice); - - if (m_flashMode != QCameraExposure::FlashVideoLight) { - if (captureDevice.torchMode != AVCaptureTorchModeOff) { -#ifdef Q_OS_IOS - if (![captureDevice isTorchAvailable]) { - qDebugCamera() << Q_FUNC_INFO << "torch is not available at the moment"; - return false; - } -#endif - captureDevice.torchMode = AVCaptureTorchModeOff; - } -#ifdef Q_OS_IOS - if (![captureDevice isFlashAvailable]) { - // We'd like to switch flash (into some mode), but it's not available: - qDebugCamera() << Q_FUNC_INFO << "flash is not available at the moment"; - return false; - } -#endif - } else { - if (captureDevice.flashMode != AVCaptureFlashModeOff) { -#ifdef Q_OS_IOS - if (![captureDevice isFlashAvailable]) { - qDebugCamera() << Q_FUNC_INFO << "flash is not available at the moment"; - return false; - } -#endif - captureDevice.flashMode = AVCaptureFlashModeOff; - } - -#ifdef Q_OS_IOS - if (![captureDevice isTorchAvailable]) { - qDebugCamera() << Q_FUNC_INFO << "torch is not available at the moment"; - return false; - } -#endif - } - - if (m_flashMode == QCameraExposure::FlashOff) - captureDevice.flashMode = AVCaptureFlashModeOff; - else if (m_flashMode == QCameraExposure::FlashOn) - captureDevice.flashMode = AVCaptureFlashModeOn; - else if (m_flashMode == QCameraExposure::FlashAuto) - captureDevice.flashMode = AVCaptureFlashModeAuto; - else if (m_flashMode == QCameraExposure::FlashVideoLight) - captureDevice.torchMode = AVCaptureTorchModeOn; - - return true; -} diff --git a/src/plugins/avfoundation/camera/avfcamerafocuscontrol.h b/src/plugins/avfoundation/camera/avfcamerafocuscontrol.h deleted file mode 100644 index 26135e534..000000000 --- a/src/plugins/avfoundation/camera/avfcamerafocuscontrol.h +++ /dev/null @@ -1,87 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** 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$ -** -****************************************************************************/ - -#ifndef AVFCAMERAFOCUSCONTROL_H -#define AVFCAMERAFOCUSCONTROL_H - -#include <QtCore/qscopedpointer.h> -#include <QtCore/qglobal.h> - -#include <qcamerafocuscontrol.h> - -@class AVCaptureDevice; - -QT_BEGIN_NAMESPACE - -class AVFCameraService; -class AVFCameraSession; - -class AVFCameraFocusControl : public QCameraFocusControl -{ - Q_OBJECT -public: - explicit AVFCameraFocusControl(AVFCameraService *service); - - QCameraFocus::FocusModes focusMode() const override; - void setFocusMode(QCameraFocus::FocusModes mode) override; - bool isFocusModeSupported(QCameraFocus::FocusModes mode) const override; - - QCameraFocus::FocusPointMode focusPointMode() const override; - void setFocusPointMode(QCameraFocus::FocusPointMode mode) override; - bool isFocusPointModeSupported(QCameraFocus::FocusPointMode mode) const override; - QPointF customFocusPoint() const override; - void setCustomFocusPoint(const QPointF &point) override; - - QCameraFocusZoneList focusZones() const override; - -private Q_SLOTS: - void cameraStateChanged(); - -private: - - AVFCameraSession *m_session; - QCameraFocus::FocusModes m_focusMode; - QCameraFocus::FocusPointMode m_focusPointMode; - QPointF m_customFocusPoint; - QPointF m_actualFocusPoint; -}; - -QT_END_NAMESPACE - -#endif // AVFCAMERAFOCUSCONTROL_H diff --git a/src/plugins/avfoundation/camera/avfcamerafocuscontrol.mm b/src/plugins/avfoundation/camera/avfcamerafocuscontrol.mm deleted file mode 100644 index 265ccf3fd..000000000 --- a/src/plugins/avfoundation/camera/avfcamerafocuscontrol.mm +++ /dev/null @@ -1,306 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** 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 "avfcamerafocuscontrol.h" -#include "avfcamerautility.h" -#include "avfcameraservice.h" -#include "avfcamerasession.h" -#include "avfcameradebug.h" - -#include <QtCore/qdebug.h> - -#include <AVFoundation/AVFoundation.h> - -QT_BEGIN_NAMESPACE - -namespace { - -bool qt_focus_mode_supported(QCameraFocus::FocusModes mode) -{ - // Check if QCameraFocus::FocusMode has counterpart in AVFoundation. - - // AVFoundation has 'Manual', 'Auto' and 'Continuous', - // where 'Manual' is actually 'Locked' + writable property 'lensPosition'. - // Since Qt does not provide an API to manipulate a lens position, 'Maual' mode - // (at the moment) is not supported. - return mode == QCameraFocus::AutoFocus - || mode == QCameraFocus::ContinuousFocus; -} - -bool qt_focus_point_mode_supported(QCameraFocus::FocusPointMode mode) -{ - return mode == QCameraFocus::FocusPointAuto - || mode == QCameraFocus::FocusPointCustom - || mode == QCameraFocus::FocusPointCenter; -} - -AVCaptureFocusMode avf_focus_mode(QCameraFocus::FocusModes requestedMode) -{ - if (requestedMode == QCameraFocus::AutoFocus) - return AVCaptureFocusModeAutoFocus; - - return AVCaptureFocusModeContinuousAutoFocus; -} - -} - -AVFCameraFocusControl::AVFCameraFocusControl(AVFCameraService *service) - : m_session(service->session()), - m_focusMode(QCameraFocus::ContinuousFocus), - m_focusPointMode(QCameraFocus::FocusPointAuto), - m_customFocusPoint(0.5f, 0.5f), - m_actualFocusPoint(m_customFocusPoint) -{ - Q_ASSERT(m_session); - connect(m_session, SIGNAL(stateChanged(QCamera::State)), SLOT(cameraStateChanged())); -} - -QCameraFocus::FocusModes AVFCameraFocusControl::focusMode() const -{ - return m_focusMode; -} - -void AVFCameraFocusControl::setFocusMode(QCameraFocus::FocusModes mode) -{ - if (m_focusMode == mode) - return; - - AVCaptureDevice *captureDevice = m_session->videoCaptureDevice(); - if (!captureDevice) { - if (qt_focus_mode_supported(mode)) { - m_focusMode = mode; - Q_EMIT focusModeChanged(m_focusMode); - } else { - qDebugCamera() << Q_FUNC_INFO - << "focus mode not supported"; - } - return; - } - - if (isFocusModeSupported(mode)) { - const AVFConfigurationLock lock(captureDevice); - if (!lock) { - qDebugCamera() << Q_FUNC_INFO - << "failed to lock for configuration"; - return; - } - - captureDevice.focusMode = avf_focus_mode(mode); - m_focusMode = mode; - } else { - qDebugCamera() << Q_FUNC_INFO << "focus mode not supported"; - return; - } - - Q_EMIT focusModeChanged(m_focusMode); -} - -bool AVFCameraFocusControl::isFocusModeSupported(QCameraFocus::FocusModes mode) const -{ - AVCaptureDevice *captureDevice = m_session->videoCaptureDevice(); - if (!captureDevice) - return false; - - if (!qt_focus_mode_supported(mode)) - return false; - - return [captureDevice isFocusModeSupported:avf_focus_mode(mode)]; -} - -QCameraFocus::FocusPointMode AVFCameraFocusControl::focusPointMode() const -{ - return m_focusPointMode; -} - -void AVFCameraFocusControl::setFocusPointMode(QCameraFocus::FocusPointMode mode) -{ - if (m_focusPointMode == mode) - return; - - AVCaptureDevice *captureDevice = m_session->videoCaptureDevice(); - if (!captureDevice) { - if (qt_focus_point_mode_supported(mode)) { - m_focusPointMode = mode; - Q_EMIT focusPointModeChanged(mode); - } - return; - } - - if (isFocusPointModeSupported(mode)) { - const AVFConfigurationLock lock(captureDevice); - if (!lock) { - qDebugCamera() << Q_FUNC_INFO << "failed to lock for configuration"; - return; - } - - bool resetPOI = false; - if (mode == QCameraFocus::FocusPointCenter || mode == QCameraFocus::FocusPointAuto) { - if (m_actualFocusPoint != QPointF(0.5, 0.5)) { - m_actualFocusPoint = QPointF(0.5, 0.5); - resetPOI = true; - } - } else if (mode == QCameraFocus::FocusPointCustom) { - if (m_actualFocusPoint != m_customFocusPoint) { - m_actualFocusPoint = m_customFocusPoint; - resetPOI = true; - } - } // else for any other mode in future. - - if (resetPOI) { - const CGPoint focusPOI = CGPointMake(m_actualFocusPoint.x(), m_actualFocusPoint.y()); - [captureDevice setFocusPointOfInterest:focusPOI]; - } - m_focusPointMode = mode; - } else { - qDebugCamera() << Q_FUNC_INFO << "focus point mode is not supported"; - return; - } - - Q_EMIT focusPointModeChanged(mode); -} - -bool AVFCameraFocusControl::isFocusPointModeSupported(QCameraFocus::FocusPointMode mode) const -{ - AVCaptureDevice *captureDevice = m_session->videoCaptureDevice(); - if (!captureDevice) - return false; - - if (!qt_focus_point_mode_supported(mode)) - return false; - - return [captureDevice isFocusPointOfInterestSupported]; -} - -QPointF AVFCameraFocusControl::customFocusPoint() const -{ - return m_customFocusPoint; -} - -void AVFCameraFocusControl::setCustomFocusPoint(const QPointF &point) -{ - if (m_customFocusPoint == point) - return; - - if (!QRectF(0.f, 0.f, 1.f, 1.f).contains(point)) { - qDebugCamera() << Q_FUNC_INFO << "invalid focus point (out of range)"; - return; - } - - m_customFocusPoint = point; - Q_EMIT customFocusPointChanged(m_customFocusPoint); - - AVCaptureDevice *captureDevice = m_session->videoCaptureDevice(); - if (!captureDevice || m_focusPointMode != QCameraFocus::FocusPointCustom) - return; - - if ([captureDevice isFocusPointOfInterestSupported]) { - const AVFConfigurationLock lock(captureDevice); - if (!lock) { - qDebugCamera() << Q_FUNC_INFO << "failed to lock for configuration"; - return; - } - - m_actualFocusPoint = m_customFocusPoint; - const CGPoint focusPOI = CGPointMake(point.x(), point.y()); - [captureDevice setFocusPointOfInterest:focusPOI]; - if (m_focusMode != QCameraFocus::ContinuousFocus) - [captureDevice setFocusMode:AVCaptureFocusModeAutoFocus]; - } else { - qDebugCamera() << Q_FUNC_INFO << "focus point of interest not supported"; - return; - } -} - -QCameraFocusZoneList AVFCameraFocusControl::focusZones() const -{ - // Unsupported. - return QCameraFocusZoneList(); -} - -void AVFCameraFocusControl::cameraStateChanged() -{ - if (m_session->state() != QCamera::ActiveState) - return; - - AVCaptureDevice *captureDevice = m_session->videoCaptureDevice(); - if (!captureDevice) { - qDebugCamera() << Q_FUNC_INFO << "capture device is nil in 'active' state"; - return; - } - - const AVFConfigurationLock lock(captureDevice); - if (m_customFocusPoint != m_actualFocusPoint - && m_focusPointMode == QCameraFocus::FocusPointCustom) { - if (![captureDevice isFocusPointOfInterestSupported]) { - qDebugCamera() << Q_FUNC_INFO - << "focus point of interest not supported"; - return; - } - - if (!lock) { - qDebugCamera() << Q_FUNC_INFO << "failed to lock for configuration"; - return; - } - - m_actualFocusPoint = m_customFocusPoint; - const CGPoint focusPOI = CGPointMake(m_customFocusPoint.x(), m_customFocusPoint.y()); - [captureDevice setFocusPointOfInterest:focusPOI]; - } - - if (m_focusMode != QCameraFocus::ContinuousFocus) { - const AVCaptureFocusMode avMode = avf_focus_mode(m_focusMode); - if (captureDevice.focusMode != avMode) { - if (![captureDevice isFocusModeSupported:avMode]) { - qDebugCamera() << Q_FUNC_INFO << "focus mode not supported"; - return; - } - - if (!lock) { - qDebugCamera() << Q_FUNC_INFO << "failed to lock for configuration"; - return; - } - - [captureDevice setFocusMode:avMode]; - } - } -} - -QT_END_NAMESPACE - -#include "moc_avfcamerafocuscontrol.cpp" diff --git a/src/plugins/avfoundation/camera/avfcamerainfocontrol.h b/src/plugins/avfoundation/camera/avfcamerainfocontrol.h deleted file mode 100644 index c3aa11918..000000000 --- a/src/plugins/avfoundation/camera/avfcamerainfocontrol.h +++ /dev/null @@ -1,59 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** 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$ -** -****************************************************************************/ - -#ifndef AVFCAMERAINFOCONTROL_H -#define AVFCAMERAINFOCONTROL_H - -#include <qcamerainfocontrol.h> - -QT_BEGIN_NAMESPACE - -class AVFCameraInfoControl : public QCameraInfoControl -{ - Q_OBJECT -public: - explicit AVFCameraInfoControl(QObject *parent = nullptr); - - QCamera::Position cameraPosition(const QString &deviceName) const override; - int cameraOrientation(const QString &deviceName) const override; -}; - -QT_END_NAMESPACE - -#endif // AVFCAMERAINFOCONTROL_H diff --git a/src/plugins/avfoundation/camera/avfcamerainfocontrol.mm b/src/plugins/avfoundation/camera/avfcamerainfocontrol.mm deleted file mode 100644 index 26905b0c2..000000000 --- a/src/plugins/avfoundation/camera/avfcamerainfocontrol.mm +++ /dev/null @@ -1,60 +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 "avfcamerainfocontrol.h" -#include "avfcamerasession.h" - -QT_BEGIN_NAMESPACE - -AVFCameraInfoControl::AVFCameraInfoControl(QObject *parent) - : QCameraInfoControl(parent) -{ -} - -QCamera::Position AVFCameraInfoControl::cameraPosition(const QString &deviceName) const -{ - return AVFCameraSession::cameraDeviceInfo(deviceName.toUtf8()).position; -} - -int AVFCameraInfoControl::cameraOrientation(const QString &deviceName) const -{ - return AVFCameraSession::cameraDeviceInfo(deviceName.toUtf8()).orientation; -} - -QT_END_NAMESPACE diff --git a/src/plugins/avfoundation/camera/avfcamerametadatacontrol.h b/src/plugins/avfoundation/camera/avfcamerametadatacontrol.h deleted file mode 100644 index cba29c394..000000000 --- a/src/plugins/avfoundation/camera/avfcamerametadatacontrol.h +++ /dev/null @@ -1,69 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** 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$ -** -****************************************************************************/ - -#ifndef AVFCAMERAMETADATACONTROL_H -#define AVFCAMERAMETADATACONTROL_H - -#include <qmetadatawritercontrol.h> - -QT_BEGIN_NAMESPACE - -class AVFCameraService; - -class AVFCameraMetaDataControl : public QMetaDataWriterControl -{ - Q_OBJECT -public: - AVFCameraMetaDataControl(AVFCameraService *service, QObject *parent = nullptr); - virtual ~AVFCameraMetaDataControl(); - - bool isMetaDataAvailable() const override; - bool isWritable() const override; - - QVariant metaData(const QString &key) const override; - void setMetaData(const QString &key, const QVariant &value) override; - QStringList availableMetaData() const override; - -private: - QMap<QString, QVariant> m_tags; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/avfoundation/camera/avfcamerametadatacontrol.mm b/src/plugins/avfoundation/camera/avfcamerametadatacontrol.mm deleted file mode 100644 index 95a8a0d79..000000000 --- a/src/plugins/avfoundation/camera/avfcamerametadatacontrol.mm +++ /dev/null @@ -1,83 +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 "avfcamerametadatacontrol.h" -#include "avfcamerasession.h" -#include "avfcameraservice.h" - -QT_USE_NAMESPACE - -//metadata support is not implemented yet - -AVFCameraMetaDataControl::AVFCameraMetaDataControl(AVFCameraService *service, QObject *parent) - :QMetaDataWriterControl(parent) -{ - Q_UNUSED(service); -} - -AVFCameraMetaDataControl::~AVFCameraMetaDataControl() -{ -} - -bool AVFCameraMetaDataControl::isMetaDataAvailable() const -{ - return !m_tags.isEmpty(); -} - -bool AVFCameraMetaDataControl::isWritable() const -{ - return false; -} - -QVariant AVFCameraMetaDataControl::metaData(const QString &key) const -{ - return m_tags.value(key); -} - -void AVFCameraMetaDataControl::setMetaData(const QString &key, const QVariant &value) -{ - m_tags.insert(key, value); -} - -QStringList AVFCameraMetaDataControl::availableMetaData() const -{ - return m_tags.keys(); -} - -#include "moc_avfcamerametadatacontrol.cpp" diff --git a/src/plugins/avfoundation/camera/avfcamerarenderercontrol.h b/src/plugins/avfoundation/camera/avfcamerarenderercontrol.h deleted file mode 100644 index 3ef3d07d4..000000000 --- a/src/plugins/avfoundation/camera/avfcamerarenderercontrol.h +++ /dev/null @@ -1,108 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** 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$ -** -****************************************************************************/ - -#ifndef AVFCAMERARENDERERCONTROL_H -#define AVFCAMERARENDERERCONTROL_H - -#include <QtMultimedia/qvideorenderercontrol.h> -#include <QtMultimedia/qvideoframe.h> -#include <QtCore/qmutex.h> - -#import <AVFoundation/AVFoundation.h> - -@class AVFCaptureFramesDelegate; - -QT_BEGIN_NAMESPACE - -class AVFCameraSession; -class AVFCameraService; -class AVFCameraRendererControl; - -class AVFCameraRendererControl : public QVideoRendererControl -{ -Q_OBJECT -public: - AVFCameraRendererControl(QObject *parent = nullptr); - ~AVFCameraRendererControl(); - - QAbstractVideoSurface *surface() const override; - void setSurface(QAbstractVideoSurface *surface) override; - - void configureAVCaptureSession(AVFCameraSession *cameraSession); - void syncHandleViewfinderFrame(const QVideoFrame &frame); - - AVCaptureVideoDataOutput *videoDataOutput() const; - - bool supportsTextures() const { return m_supportsTextures; } - -#ifdef Q_OS_IOS - AVFCaptureFramesDelegate *captureDelegate() const; - void resetCaptureDelegate() const; -#endif - -Q_SIGNALS: - void surfaceChanged(QAbstractVideoSurface *surface); - -private Q_SLOTS: - void handleViewfinderFrame(); - void updateCaptureConnection(); - -private: - QAbstractVideoSurface *m_surface; - AVFCaptureFramesDelegate *m_viewfinderFramesDelegate; - AVFCameraSession *m_cameraSession; - AVCaptureVideoDataOutput *m_videoDataOutput; - - bool m_supportsTextures; - bool m_needsHorizontalMirroring; - -#ifdef Q_OS_IOS - CVOpenGLESTextureCacheRef m_textureCache; -#endif - - QVideoFrame m_lastViewfinderFrame; - QMutex m_vfMutex; - dispatch_queue_t m_delegateQueue; - - friend class CVImageVideoBuffer; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/avfoundation/camera/avfcamerarenderercontrol.mm b/src/plugins/avfoundation/camera/avfcamerarenderercontrol.mm deleted file mode 100644 index a03d38b8c..000000000 --- a/src/plugins/avfoundation/camera/avfcamerarenderercontrol.mm +++ /dev/null @@ -1,411 +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 "avfcameraviewfindersettingscontrol.h" -#include "private/qabstractvideobuffer_p.h" -#include "avfcamerarenderercontrol.h" -#include "avfcamerasession.h" -#include "avfcameraservice.h" -#include "avfcameradebug.h" - -#ifdef Q_OS_IOS -#include <QtGui/qopengl.h> -#endif - -#include <QtMultimedia/qabstractvideosurface.h> -#include <QtMultimedia/qabstractvideobuffer.h> - -#include <QtMultimedia/qvideosurfaceformat.h> - -QT_USE_NAMESPACE - -class CVImageVideoBuffer : public QAbstractPlanarVideoBuffer -{ -public: - CVImageVideoBuffer(CVImageBufferRef buffer, AVFCameraRendererControl *renderer) -#ifndef Q_OS_IOS - : QAbstractPlanarVideoBuffer(NoHandle) -#else - : QAbstractPlanarVideoBuffer(renderer->supportsTextures() - && CVPixelBufferGetPixelFormatType(buffer) == kCVPixelFormatType_32BGRA - ? GLTextureHandle : NoHandle) - , m_texture(nullptr) - , m_renderer(renderer) -#endif - , m_buffer(buffer) - , m_mode(NotMapped) - { -#ifndef Q_OS_IOS - Q_UNUSED(renderer); -#endif // Q_OS_IOS - CVPixelBufferRetain(m_buffer); - } - - ~CVImageVideoBuffer() - { - CVImageVideoBuffer::unmap(); -#ifdef Q_OS_IOS - if (m_texture) - CFRelease(m_texture); -#endif - CVPixelBufferRelease(m_buffer); - } - - MapMode mapMode() const { return m_mode; } - - int map(QAbstractVideoBuffer::MapMode mode, int *numBytes, int bytesPerLine[4], uchar *data[4]) - { - // We only support RGBA or NV12 (or Apple's version of NV12), - // they are either 0 planes or 2. - const size_t nPlanes = CVPixelBufferGetPlaneCount(m_buffer); - Q_ASSERT(nPlanes <= 2); - - if (!nPlanes) { - data[0] = map(mode, numBytes, bytesPerLine); - return data[0] ? 1 : 0; - } - - // For a bi-planar format we have to set the parameters correctly: - if (mode != QAbstractVideoBuffer::NotMapped && m_mode == QAbstractVideoBuffer::NotMapped) { - CVPixelBufferLockBaseAddress(m_buffer, mode == QAbstractVideoBuffer::ReadOnly - ? kCVPixelBufferLock_ReadOnly - : 0); - - if (numBytes) - *numBytes = CVPixelBufferGetDataSize(m_buffer); - - if (bytesPerLine) { - // At the moment we handle only bi-planar format. - bytesPerLine[0] = CVPixelBufferGetBytesPerRowOfPlane(m_buffer, 0); - bytesPerLine[1] = CVPixelBufferGetBytesPerRowOfPlane(m_buffer, 1); - } - - if (data) { - data[0] = static_cast<uchar*>(CVPixelBufferGetBaseAddressOfPlane(m_buffer, 0)); - data[1] = static_cast<uchar*>(CVPixelBufferGetBaseAddressOfPlane(m_buffer, 1)); - } - - m_mode = mode; - } - - return nPlanes; - } - - uchar *map(MapMode mode, int *numBytes, int *bytesPerLine) - { - if (mode != NotMapped && m_mode == NotMapped) { - CVPixelBufferLockBaseAddress(m_buffer, mode == QAbstractVideoBuffer::ReadOnly - ? kCVPixelBufferLock_ReadOnly - : 0); - if (numBytes) - *numBytes = CVPixelBufferGetDataSize(m_buffer); - - if (bytesPerLine) - *bytesPerLine = CVPixelBufferGetBytesPerRow(m_buffer); - - m_mode = mode; - return static_cast<uchar*>(CVPixelBufferGetBaseAddress(m_buffer)); - } else { - return nullptr; - } - } - - void unmap() - { - if (m_mode != NotMapped) { - CVPixelBufferUnlockBaseAddress(m_buffer, m_mode == QAbstractVideoBuffer::ReadOnly - ? kCVPixelBufferLock_ReadOnly - : 0); - m_mode = NotMapped; - } - } - - QVariant handle() const - { -#ifdef Q_OS_IOS - // Called from the render thread, so there is a current OpenGL context - - if (!m_renderer->m_textureCache) { - CVReturn err = CVOpenGLESTextureCacheCreate(kCFAllocatorDefault, - nullptr, - [EAGLContext currentContext], - nullptr, - &m_renderer->m_textureCache); - - if (err != kCVReturnSuccess) - qWarning("Error creating texture cache"); - } - - if (m_renderer->m_textureCache && !m_texture) { - CVOpenGLESTextureCacheFlush(m_renderer->m_textureCache, 0); - - CVReturn err = CVOpenGLESTextureCacheCreateTextureFromImage(kCFAllocatorDefault, - m_renderer->m_textureCache, - m_buffer, - nullptr, - GL_TEXTURE_2D, - GL_RGBA, - CVPixelBufferGetWidth(m_buffer), - CVPixelBufferGetHeight(m_buffer), - GL_RGBA, - GL_UNSIGNED_BYTE, - 0, - &m_texture); - if (err != kCVReturnSuccess) - qWarning("Error creating texture from buffer"); - } - - if (m_texture) - return CVOpenGLESTextureGetName(m_texture); - else - return 0; -#else - return QVariant(); -#endif - } - -private: -#ifdef Q_OS_IOS - mutable CVOpenGLESTextureRef m_texture; - AVFCameraRendererControl *m_renderer; -#endif - CVImageBufferRef m_buffer; - MapMode m_mode; -}; - - -@interface AVFCaptureFramesDelegate : NSObject <AVCaptureVideoDataOutputSampleBufferDelegate> - -- (AVFCaptureFramesDelegate *) initWithRenderer:(AVFCameraRendererControl*)renderer; - -- (void) captureOutput:(AVCaptureOutput *)captureOutput - didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer - fromConnection:(AVCaptureConnection *)connection; - -@end - -@implementation AVFCaptureFramesDelegate -{ -@private - AVFCameraRendererControl *m_renderer; -} - -- (AVFCaptureFramesDelegate *) initWithRenderer:(AVFCameraRendererControl*)renderer -{ - if (!(self = [super init])) - return nil; - - self->m_renderer = renderer; - return self; -} - -- (void)captureOutput:(AVCaptureOutput *)captureOutput - didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer - fromConnection:(AVCaptureConnection *)connection -{ - Q_UNUSED(connection); - Q_UNUSED(captureOutput); - - // NB: on iOS captureOutput/connection can be nil (when recording a video - - // avfmediaassetwriter). - - CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer); - - int width = CVPixelBufferGetWidth(imageBuffer); - int height = CVPixelBufferGetHeight(imageBuffer); - QVideoFrame::PixelFormat format = - AVFCameraViewfinderSettingsControl2::QtPixelFormatFromCVFormat(CVPixelBufferGetPixelFormatType(imageBuffer)); - if (format == QVideoFrame::Format_Invalid) - return; - - QVideoFrame frame(new CVImageVideoBuffer(imageBuffer, m_renderer), - QSize(width, height), - format); - - m_renderer->syncHandleViewfinderFrame(frame); -} - -@end - - -AVFCameraRendererControl::AVFCameraRendererControl(QObject *parent) - : QVideoRendererControl(parent) - , m_surface(nullptr) - , m_supportsTextures(false) - , m_needsHorizontalMirroring(false) -#ifdef Q_OS_IOS - , m_textureCache(nullptr) -#endif -{ - m_viewfinderFramesDelegate = [[AVFCaptureFramesDelegate alloc] initWithRenderer:this]; -} - -AVFCameraRendererControl::~AVFCameraRendererControl() -{ - [m_cameraSession->captureSession() removeOutput:m_videoDataOutput]; - [m_viewfinderFramesDelegate release]; - if (m_delegateQueue) - dispatch_release(m_delegateQueue); -#ifdef Q_OS_IOS - if (m_textureCache) - CFRelease(m_textureCache); -#endif -} - -QAbstractVideoSurface *AVFCameraRendererControl::surface() const -{ - return m_surface; -} - -void AVFCameraRendererControl::setSurface(QAbstractVideoSurface *surface) -{ - if (m_surface != surface) { - m_surface = surface; - m_supportsTextures = m_surface - ? !m_surface->supportedPixelFormats(QAbstractVideoBuffer::GLTextureHandle).isEmpty() - : false; - Q_EMIT surfaceChanged(surface); - } -} - -void AVFCameraRendererControl::configureAVCaptureSession(AVFCameraSession *cameraSession) -{ - m_cameraSession = cameraSession; - connect(m_cameraSession, SIGNAL(readyToConfigureConnections()), - this, SLOT(updateCaptureConnection())); - - m_needsHorizontalMirroring = false; - - m_videoDataOutput = [[[AVCaptureVideoDataOutput alloc] init] autorelease]; - - // Configure video output - m_delegateQueue = dispatch_queue_create("vf_queue", nullptr); - [m_videoDataOutput - setSampleBufferDelegate:m_viewfinderFramesDelegate - queue:m_delegateQueue]; - - [m_cameraSession->captureSession() addOutput:m_videoDataOutput]; -} - -void AVFCameraRendererControl::updateCaptureConnection() -{ - AVCaptureConnection *connection = [m_videoDataOutput connectionWithMediaType:AVMediaTypeVideo]; - if (connection == nil || !m_cameraSession->videoCaptureDevice()) - return; - - // Frames of front-facing cameras should be mirrored horizontally (it's the default when using - // AVCaptureVideoPreviewLayer but not with AVCaptureVideoDataOutput) - if (connection.isVideoMirroringSupported) - connection.videoMirrored = m_cameraSession->videoCaptureDevice().position == AVCaptureDevicePositionFront; - - // If the connection does't support mirroring, we'll have to do it ourselves - m_needsHorizontalMirroring = !connection.isVideoMirrored - && m_cameraSession->videoCaptureDevice().position == AVCaptureDevicePositionFront; -} - -//can be called from non main thread -void AVFCameraRendererControl::syncHandleViewfinderFrame(const QVideoFrame &frame) -{ - QMutexLocker lock(&m_vfMutex); - if (!m_lastViewfinderFrame.isValid()) { - static QMetaMethod handleViewfinderFrameSlot = metaObject()->method( - metaObject()->indexOfMethod("handleViewfinderFrame()")); - - handleViewfinderFrameSlot.invoke(this, Qt::QueuedConnection); - } - - m_lastViewfinderFrame = frame; - - if (m_cameraSession && m_lastViewfinderFrame.isValid()) - m_cameraSession->onCameraFrameFetched(m_lastViewfinderFrame); -} - -AVCaptureVideoDataOutput *AVFCameraRendererControl::videoDataOutput() const -{ - return m_videoDataOutput; -} - -#ifdef Q_OS_IOS - -AVFCaptureFramesDelegate *AVFCameraRendererControl::captureDelegate() const -{ - return m_viewfinderFramesDelegate; -} - -void AVFCameraRendererControl::resetCaptureDelegate() const -{ - [m_videoDataOutput setSampleBufferDelegate:m_viewfinderFramesDelegate queue:m_delegateQueue]; -} - -#endif - -void AVFCameraRendererControl::handleViewfinderFrame() -{ - QVideoFrame frame; - { - QMutexLocker lock(&m_vfMutex); - frame = m_lastViewfinderFrame; - m_lastViewfinderFrame = QVideoFrame(); - } - - if (m_surface && frame.isValid()) { - if (m_surface->isActive() && (m_surface->surfaceFormat().pixelFormat() != frame.pixelFormat() - || m_surface->surfaceFormat().frameSize() != frame.size())) { - m_surface->stop(); - } - - if (!m_surface->isActive()) { - QVideoSurfaceFormat format(frame.size(), frame.pixelFormat(), frame.handleType()); - if (m_needsHorizontalMirroring) - format.setProperty("mirrored", true); - - if (!m_surface->start(format)) { - qWarning() << "Failed to start viewfinder m_surface, format:" << format; - } else { - qDebugCamera() << "Viewfinder started: " << format; - } - } - - if (m_surface->isActive()) - m_surface->present(frame); - } -} - - -#include "moc_avfcamerarenderercontrol.cpp" diff --git a/src/plugins/avfoundation/camera/avfcameraservice.h b/src/plugins/avfoundation/camera/avfcameraservice.h deleted file mode 100644 index 1397a7dee..000000000 --- a/src/plugins/avfoundation/camera/avfcameraservice.h +++ /dev/null @@ -1,132 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** 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$ -** -****************************************************************************/ - -#ifndef AVFCAMERASERVICE_H -#define AVFCAMERASERVICE_H - -#include <QtCore/qobject.h> -#include <QtCore/qset.h> -#include <qmediaservice.h> - - -QT_BEGIN_NAMESPACE -class QCameraControl; -class QMediaRecorderControl; -class AVFCameraControl; -class AVFCameraInfoControl; -class AVFCameraMetaDataControl; -class AVFVideoWindowControl; -class AVFVideoWidgetControl; -class AVFCameraRendererControl; -class AVFImageCaptureControl; -class AVFCameraSession; -class AVFCameraDeviceControl; -class AVFAudioInputSelectorControl; -class AVFCameraFocusControl; -class AVFCameraExposureControl; -class AVFCameraZoomControl; -class AVFCameraViewfinderSettingsControl2; -class AVFCameraViewfinderSettingsControl; -class AVFImageEncoderControl; -class AVFCameraFlashControl; -class AVFMediaRecorderControl; -class AVFMediaRecorderControlIOS; -class AVFAudioEncoderSettingsControl; -class AVFVideoEncoderSettingsControl; -class AVFMediaContainerControl; -class AVFCameraWindowControl; -class AVFCaptureDestinationControl; - -class AVFCameraService : public QMediaService -{ -Q_OBJECT -public: - AVFCameraService(QObject *parent = nullptr); - ~AVFCameraService(); - - QMediaControl* requestControl(const char *name); - void releaseControl(QMediaControl *control); - - AVFCameraSession *session() const { return m_session; } - AVFCameraControl *cameraControl() const { return m_cameraControl; } - AVFCameraDeviceControl *videoDeviceControl() const { return m_videoDeviceControl; } - AVFAudioInputSelectorControl *audioInputSelectorControl() const { return m_audioInputSelectorControl; } - AVFCameraMetaDataControl *metaDataControl() const { return m_metaDataControl; } - QMediaRecorderControl *recorderControl() const { return m_recorderControl; } - AVFImageCaptureControl *imageCaptureControl() const { return m_imageCaptureControl; } - AVFCameraFocusControl *cameraFocusControl() const { return m_cameraFocusControl; } - AVFCameraExposureControl *cameraExposureControl() const {return m_cameraExposureControl; } - AVFCameraZoomControl *cameraZoomControl() const {return m_cameraZoomControl; } - AVFCameraRendererControl *videoOutput() const {return m_videoOutput; } - AVFCameraViewfinderSettingsControl2 *viewfinderSettingsControl2() const {return m_viewfinderSettingsControl2; } - AVFCameraViewfinderSettingsControl *viewfinderSettingsControl() const {return m_viewfinderSettingsControl; } - AVFImageEncoderControl *imageEncoderControl() const {return m_imageEncoderControl; } - AVFCameraFlashControl *flashControl() const {return m_flashControl; } - AVFAudioEncoderSettingsControl *audioEncoderSettingsControl() const { return m_audioEncoderSettingsControl; } - AVFVideoEncoderSettingsControl *videoEncoderSettingsControl() const {return m_videoEncoderSettingsControl; } - AVFMediaContainerControl *mediaContainerControl() const { return m_mediaContainerControl; } - AVFCaptureDestinationControl *captureDestinationControl() const { return m_captureDestinationControl; } - -private: - AVFCameraSession *m_session; - AVFCameraControl *m_cameraControl; - AVFCameraInfoControl *m_cameraInfoControl; - AVFCameraDeviceControl *m_videoDeviceControl; - AVFAudioInputSelectorControl *m_audioInputSelectorControl; - AVFCameraRendererControl *m_videoOutput; - AVFCameraMetaDataControl *m_metaDataControl; - QMediaRecorderControl *m_recorderControl; - AVFImageCaptureControl *m_imageCaptureControl; - AVFCameraFocusControl *m_cameraFocusControl; - AVFCameraExposureControl *m_cameraExposureControl; - AVFCameraZoomControl *m_cameraZoomControl; - AVFCameraViewfinderSettingsControl2 *m_viewfinderSettingsControl2; - AVFCameraViewfinderSettingsControl *m_viewfinderSettingsControl; - AVFImageEncoderControl *m_imageEncoderControl; - AVFCameraFlashControl *m_flashControl; - AVFAudioEncoderSettingsControl *m_audioEncoderSettingsControl; - AVFVideoEncoderSettingsControl *m_videoEncoderSettingsControl; - AVFMediaContainerControl *m_mediaContainerControl; - AVFCameraWindowControl *m_captureWindowControl; - AVFCaptureDestinationControl *m_captureDestinationControl; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/avfoundation/camera/avfcameraservice.mm b/src/plugins/avfoundation/camera/avfcameraservice.mm deleted file mode 100644 index 79bf73910..000000000 --- a/src/plugins/avfoundation/camera/avfcameraservice.mm +++ /dev/null @@ -1,267 +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 <QtCore/qvariant.h> -#include <QtCore/qdebug.h> - -#include "avfcameraservice.h" -#include "avfcameracontrol.h" -#include "avfcamerainfocontrol.h" -#include "avfcamerasession.h" -#include "avfcameradevicecontrol.h" -#include "avfaudioinputselectorcontrol.h" -#include "avfcamerametadatacontrol.h" -#include "avfmediarecordercontrol.h" -#include "avfimagecapturecontrol.h" -#include "avfcamerarenderercontrol.h" -#include "avfmediarecordercontrol.h" -#include "avfimagecapturecontrol.h" -#include "avfmediavideoprobecontrol.h" -#include "avfcamerafocuscontrol.h" -#include "avfcameraexposurecontrol.h" -#include "avfcameraviewfindersettingscontrol.h" -#include "avfimageencodercontrol.h" -#include "avfcameraflashcontrol.h" -#include "avfaudioencodersettingscontrol.h" -#include "avfvideoencodersettingscontrol.h" -#include "avfmediacontainercontrol.h" -#include "avfcapturedestinationcontrol.h" -#include "avfcamerawindowcontrol.h" - -#ifdef Q_OS_IOS -#include "avfcamerazoomcontrol.h" -#include "avfmediarecordercontrol_ios.h" -#endif - -#include <private/qmediaplaylistnavigator_p.h> -#include <qmediaplaylist.h> - -QT_USE_NAMESPACE - -AVFCameraService::AVFCameraService(QObject *parent): - QMediaService(parent), - m_videoOutput(nullptr), - m_captureWindowControl(nullptr) -{ - m_session = new AVFCameraSession(this); - m_cameraControl = new AVFCameraControl(this); - m_cameraInfoControl = new AVFCameraInfoControl(this); - m_videoDeviceControl = new AVFCameraDeviceControl(this); - m_audioInputSelectorControl = new AVFAudioInputSelectorControl(this); - - m_metaDataControl = new AVFCameraMetaDataControl(this); -#ifndef Q_OS_IOS - // This will connect a slot to 'captureModeChanged' - // and will break viewfinder by attaching AVCaptureMovieFileOutput - // in this slot. - m_recorderControl = new AVFMediaRecorderControl(this); -#else - m_recorderControl = new AVFMediaRecorderControlIOS(this); -#endif - m_imageCaptureControl = new AVFImageCaptureControl(this); - m_cameraFocusControl = new AVFCameraFocusControl(this); - m_cameraExposureControl = nullptr; -#ifdef Q_OS_IOS - m_cameraExposureControl = new AVFCameraExposureControl(this); -#endif - - m_cameraZoomControl = nullptr; -#ifdef Q_OS_IOS - m_cameraZoomControl = new AVFCameraZoomControl(this); -#endif - m_viewfinderSettingsControl2 = new AVFCameraViewfinderSettingsControl2(this); - m_viewfinderSettingsControl = new AVFCameraViewfinderSettingsControl(this); - m_imageEncoderControl = new AVFImageEncoderControl(this); - m_flashControl = new AVFCameraFlashControl(this); - m_audioEncoderSettingsControl = new AVFAudioEncoderSettingsControl(this); - m_videoEncoderSettingsControl = new AVFVideoEncoderSettingsControl(this); - m_mediaContainerControl = new AVFMediaContainerControl(this); - m_captureDestinationControl = new AVFCaptureDestinationControl; -} - -AVFCameraService::~AVFCameraService() -{ - m_cameraControl->setState(QCamera::UnloadedState); - -#ifdef Q_OS_IOS - delete m_recorderControl; -#endif - - if (m_captureWindowControl) { - m_session->setCapturePreviewOutput(nullptr); - delete m_captureWindowControl; - m_captureWindowControl = nullptr; - } - - if (m_videoOutput) { - m_session->setVideoOutput(nullptr); - delete m_videoOutput; - m_videoOutput = nullptr; - } - - //delete controls before session, - //so they have a chance to do deinitialization - delete m_imageCaptureControl; - //delete m_recorderControl; - delete m_metaDataControl; - delete m_cameraControl; - delete m_cameraFocusControl; - delete m_cameraExposureControl; -#ifdef Q_OS_IOS - delete m_cameraZoomControl; -#endif - delete m_viewfinderSettingsControl2; - delete m_viewfinderSettingsControl; - delete m_imageEncoderControl; - delete m_flashControl; - delete m_audioEncoderSettingsControl; - delete m_videoEncoderSettingsControl; - delete m_mediaContainerControl; - delete m_captureDestinationControl; - - delete m_session; -} - -QMediaControl *AVFCameraService::requestControl(const char *name) -{ - if (qstrcmp(name, QCameraControl_iid) == 0) - return m_cameraControl; - - if (qstrcmp(name, QCameraInfoControl_iid) == 0) - return m_cameraInfoControl; - - if (qstrcmp(name, QVideoDeviceSelectorControl_iid) == 0) - return m_videoDeviceControl; - - if (qstrcmp(name, QAudioInputSelectorControl_iid) == 0) - return m_audioInputSelectorControl; - - //metadata support is not implemented yet - //if (qstrcmp(name, QMetaDataWriterControl_iid) == 0) - // return m_metaDataControl; - - if (qstrcmp(name, QMediaRecorderControl_iid) == 0) - return m_recorderControl; - - if (qstrcmp(name, QCameraImageCaptureControl_iid) == 0) - return m_imageCaptureControl; - - if (qstrcmp(name, QCameraExposureControl_iid) == 0) - return m_cameraExposureControl; - - if (qstrcmp(name, QCameraFocusControl_iid) == 0) - return m_cameraFocusControl; - - if (qstrcmp(name, QCameraViewfinderSettingsControl2_iid) == 0) - return m_viewfinderSettingsControl2; - - if (qstrcmp(name, QCameraViewfinderSettingsControl_iid) == 0) - return m_viewfinderSettingsControl; - - if (qstrcmp(name, QImageEncoderControl_iid) == 0) - return m_imageEncoderControl; - - if (qstrcmp(name, QCameraFlashControl_iid) == 0) - return m_flashControl; - - if (qstrcmp(name, QAudioEncoderSettingsControl_iid) == 0) - return m_audioEncoderSettingsControl; - - if (qstrcmp(name, QVideoEncoderSettingsControl_iid) == 0) - return m_videoEncoderSettingsControl; - - if (qstrcmp(name, QMediaContainerControl_iid) == 0) - return m_mediaContainerControl; - - if (qstrcmp(name,QMediaVideoProbeControl_iid) == 0) { - AVFMediaVideoProbeControl *videoProbe = nullptr; - videoProbe = new AVFMediaVideoProbeControl(this); - m_session->addProbe(videoProbe); - return videoProbe; - } - -#ifdef Q_OS_IOS - if (qstrcmp(name, QCameraZoomControl_iid) == 0) - return m_cameraZoomControl; -#endif - - if (qstrcmp(name, QCameraCaptureDestinationControl_iid) == 0) - return m_captureDestinationControl; - - if (!m_captureWindowControl) { - if (qstrcmp(name, QVideoWindowControl_iid) == 0) { - m_captureWindowControl = new AVFCameraWindowControl(this); - m_session->setCapturePreviewOutput(m_captureWindowControl); - return m_captureWindowControl; - } - } - - if (!m_videoOutput) { - if (qstrcmp(name, QVideoRendererControl_iid) == 0) - m_videoOutput = new AVFCameraRendererControl(this); - - if (m_videoOutput) { - m_session->setVideoOutput(m_videoOutput); - return m_videoOutput; - } - } - - return nullptr; -} - -void AVFCameraService::releaseControl(QMediaControl *control) -{ - AVFMediaVideoProbeControl *videoProbe = qobject_cast<AVFMediaVideoProbeControl *>(control); - if (videoProbe) { - m_session->removeProbe(videoProbe); - delete videoProbe; - } else if (m_videoOutput == control) { - m_session->setVideoOutput(nullptr); - delete m_videoOutput; - m_videoOutput = nullptr; - } - else if (m_captureWindowControl == control) { - m_session->setCapturePreviewOutput(nullptr); - delete m_captureWindowControl; - m_captureWindowControl = nullptr; - } -} - - -#include "moc_avfcameraservice.cpp" diff --git a/src/plugins/avfoundation/camera/avfcameraserviceplugin.h b/src/plugins/avfoundation/camera/avfcameraserviceplugin.h deleted file mode 100644 index bd5f83249..000000000 --- a/src/plugins/avfoundation/camera/avfcameraserviceplugin.h +++ /dev/null @@ -1,76 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** 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$ -** -****************************************************************************/ - - -#ifndef AVFSERVICEPLUGIN_H -#define AVFSERVICEPLUGIN_H - -#include <qmediaserviceproviderplugin.h> -#include <QtCore/qmap.h> - -QT_BEGIN_NAMESPACE - -class AVFServicePlugin : public QMediaServiceProviderPlugin, - public QMediaServiceSupportedDevicesInterface, - public QMediaServiceDefaultDeviceInterface, - public QMediaServiceCameraInfoInterface -{ - Q_OBJECT - Q_INTERFACES(QMediaServiceSupportedDevicesInterface) - Q_INTERFACES(QMediaServiceDefaultDeviceInterface) - Q_INTERFACES(QMediaServiceCameraInfoInterface) - Q_PLUGIN_METADATA(IID "org.qt-project.qt.mediaserviceproviderfactory/5.0" FILE "avfcamera.json") - -public: - AVFServicePlugin(); - - QMediaService* create(QString const &key) override; - void release(QMediaService *service) override; - - QByteArray defaultDevice(const QByteArray &service) const override; - QList<QByteArray> devices(const QByteArray &service) const override; - QString deviceDescription(const QByteArray &service, const QByteArray &device) override; - - QCamera::Position cameraPosition(const QByteArray &device) const override; - int cameraOrientation(const QByteArray &device) const override; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/avfoundation/camera/avfcameraserviceplugin.mm b/src/plugins/avfoundation/camera/avfcameraserviceplugin.mm deleted file mode 100644 index 08bd8c9bd..000000000 --- a/src/plugins/avfoundation/camera/avfcameraserviceplugin.mm +++ /dev/null @@ -1,113 +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 <QtCore/qstring.h> -#include <QtCore/qdebug.h> - -#include "avfcameraserviceplugin.h" -#include "avfcameraservice.h" -#include "avfcamerasession.h" - -#include <qmediaserviceproviderplugin.h> - -QT_BEGIN_NAMESPACE - -AVFServicePlugin::AVFServicePlugin() -{ -} - -QMediaService* AVFServicePlugin::create(QString const& key) -{ - if (key == QLatin1String(Q_MEDIASERVICE_CAMERA)) - return new AVFCameraService; - else - qWarning() << "unsupported key:" << key; - - return nullptr; -} - -void AVFServicePlugin::release(QMediaService *service) -{ - delete service; -} - -QByteArray AVFServicePlugin::defaultDevice(const QByteArray &service) const -{ - if (service == Q_MEDIASERVICE_CAMERA) { - int i = AVFCameraSession::defaultCameraIndex(); - if (i != -1) - return AVFCameraSession::availableCameraDevices().at(i).deviceId; - } - - return QByteArray(); -} - -QList<QByteArray> AVFServicePlugin::devices(const QByteArray &service) const -{ - QList<QByteArray> devs; - - if (service == Q_MEDIASERVICE_CAMERA) { - const QList<AVFCameraInfo> &cameras = AVFCameraSession::availableCameraDevices(); - devs.reserve(cameras.size()); - for (const AVFCameraInfo &info : cameras) - devs.append(info.deviceId); - } - - return devs; -} - -QString AVFServicePlugin::deviceDescription(const QByteArray &service, const QByteArray &device) -{ - if (service == Q_MEDIASERVICE_CAMERA) - return AVFCameraSession::cameraDeviceInfo(device).description; - - return QString(); -} - -QCamera::Position AVFServicePlugin::cameraPosition(const QByteArray &device) const -{ - return AVFCameraSession::cameraDeviceInfo(device).position; -} - -int AVFServicePlugin::cameraOrientation(const QByteArray &device) const -{ - return AVFCameraSession::cameraDeviceInfo(device).orientation; -} - -QT_END_NAMESPACE diff --git a/src/plugins/avfoundation/camera/avfcamerasession.h b/src/plugins/avfoundation/camera/avfcamerasession.h deleted file mode 100644 index a449bb806..000000000 --- a/src/plugins/avfoundation/camera/avfcamerasession.h +++ /dev/null @@ -1,144 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** 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$ -** -****************************************************************************/ - -#ifndef AVFCAMERASESSION_H -#define AVFCAMERASESSION_H - -#include <QtCore/qmutex.h> -#include <QtMultimedia/qcamera.h> -#include <QVideoFrame> - -#import <AVFoundation/AVFoundation.h> - -@class AVFCameraSessionObserver; - -QT_BEGIN_NAMESPACE - -class AVFCameraControl; -class AVFCameraService; -class AVFCameraRendererControl; -class AVFMediaVideoProbeControl; -class AVFCameraWindowControl; - -struct AVFCameraInfo -{ - AVFCameraInfo() : position(QCamera::UnspecifiedPosition), orientation(0) - { } - - QByteArray deviceId; - QString description; - QCamera::Position position; - int orientation; -}; - -class AVFCameraSession : public QObject -{ - Q_OBJECT -public: - AVFCameraSession(AVFCameraService *service, QObject *parent = nullptr); - ~AVFCameraSession(); - - static int defaultCameraIndex(); - static const QList<AVFCameraInfo> &availableCameraDevices(); - static AVFCameraInfo cameraDeviceInfo(const QByteArray &device); - AVFCameraInfo activeCameraInfo() const { return m_activeCameraInfo; } - - void setVideoOutput(AVFCameraRendererControl *output); - void setCapturePreviewOutput(AVFCameraWindowControl *output); - AVCaptureSession *captureSession() const { return m_captureSession; } - AVCaptureDevice *videoCaptureDevice() const; - - QCamera::State state() const; - QCamera::State requestedState() const { return m_state; } - bool isActive() const { return m_active; } - - void addProbe(AVFMediaVideoProbeControl *probe); - void removeProbe(AVFMediaVideoProbeControl *probe); - FourCharCode defaultCodec(); - - AVCaptureDeviceInput *videoInput() const {return m_videoInput;} - -public Q_SLOTS: - void setState(QCamera::State state); - - void processRuntimeError(); - void processSessionStarted(); - void processSessionStopped(); - - void onCaptureModeChanged(QCamera::CaptureModes mode); - - void onCameraFrameFetched(const QVideoFrame &frame); - -Q_SIGNALS: - void readyToConfigureConnections(); - void stateChanged(QCamera::State newState); - void activeChanged(bool); - void newViewfinderFrame(const QVideoFrame &frame); - void error(int error, const QString &errorString); - -private: - static void updateCameraDevices(); - void attachVideoInputDevice(); - bool applyImageEncoderSettings(); - bool applyViewfinderSettings(); - - static int m_defaultCameraIndex; - static QList<AVFCameraInfo> m_cameraDevices; - AVFCameraInfo m_activeCameraInfo; - - AVFCameraService *m_service; - AVFCameraRendererControl *m_videoOutput; - AVFCameraWindowControl *m_capturePreviewWindowOutput; - - QCamera::State m_state; - bool m_active; - - AVCaptureSession *m_captureSession; - AVCaptureDeviceInput *m_videoInput; - AVFCameraSessionObserver *m_observer; - - QSet<AVFMediaVideoProbeControl *> m_videoProbes; - QMutex m_videoProbesMutex; - - FourCharCode m_defaultCodec; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/avfoundation/camera/avfcamerasession.mm b/src/plugins/avfoundation/camera/avfcamerasession.mm deleted file mode 100644 index ebefa07e5..000000000 --- a/src/plugins/avfoundation/camera/avfcamerasession.mm +++ /dev/null @@ -1,492 +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 "avfcameradebug.h" -#include "avfcamerasession.h" -#include "avfcameraservice.h" -#include "avfcameracontrol.h" -#include "avfcamerarenderercontrol.h" -#include "avfcameradevicecontrol.h" -#include "avfaudioinputselectorcontrol.h" -#include "avfmediavideoprobecontrol.h" -#include "avfcameraviewfindersettingscontrol.h" -#include "avfimageencodercontrol.h" -#include "avfcamerautility.h" -#include "avfcamerawindowcontrol.h" - -#include <CoreFoundation/CoreFoundation.h> -#include <Foundation/Foundation.h> - -#include <QtCore/qdatetime.h> -#include <QtCore/qurl.h> -#include <QtCore/qelapsedtimer.h> - -#include <QtCore/qdebug.h> - -QT_USE_NAMESPACE - -int AVFCameraSession::m_defaultCameraIndex; -QList<AVFCameraInfo> AVFCameraSession::m_cameraDevices; - -@interface AVFCameraSessionObserver : NSObject - -- (AVFCameraSessionObserver *) initWithCameraSession:(AVFCameraSession*)session; -- (void) processRuntimeError:(NSNotification *)notification; -- (void) processSessionStarted:(NSNotification *)notification; -- (void) processSessionStopped:(NSNotification *)notification; - -@end - -@implementation AVFCameraSessionObserver -{ -@private - AVFCameraSession *m_session; - AVCaptureSession *m_captureSession; -} - -- (AVFCameraSessionObserver *) initWithCameraSession:(AVFCameraSession*)session -{ - if (!(self = [super init])) - return nil; - - self->m_session = session; - self->m_captureSession = session->captureSession(); - - [m_captureSession retain]; - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(processRuntimeError:) - name:AVCaptureSessionRuntimeErrorNotification - object:m_captureSession]; - - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(processSessionStarted:) - name:AVCaptureSessionDidStartRunningNotification - object:m_captureSession]; - - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(processSessionStopped:) - name:AVCaptureSessionDidStopRunningNotification - object:m_captureSession]; - - return self; -} - -- (void) dealloc -{ - [[NSNotificationCenter defaultCenter] removeObserver:self - name:AVCaptureSessionRuntimeErrorNotification - object:m_captureSession]; - - [[NSNotificationCenter defaultCenter] removeObserver:self - name:AVCaptureSessionDidStartRunningNotification - object:m_captureSession]; - - [[NSNotificationCenter defaultCenter] removeObserver:self - name:AVCaptureSessionDidStopRunningNotification - object:m_captureSession]; - [m_captureSession release]; - [super dealloc]; -} - -- (void) processRuntimeError:(NSNotification *)notification -{ - Q_UNUSED(notification); - QMetaObject::invokeMethod(m_session, "processRuntimeError", Qt::AutoConnection); -} - -- (void) processSessionStarted:(NSNotification *)notification -{ - Q_UNUSED(notification); - QMetaObject::invokeMethod(m_session, "processSessionStarted", Qt::AutoConnection); -} - -- (void) processSessionStopped:(NSNotification *)notification -{ - Q_UNUSED(notification); - QMetaObject::invokeMethod(m_session, "processSessionStopped", Qt::AutoConnection); -} - -@end - -AVFCameraSession::AVFCameraSession(AVFCameraService *service, QObject *parent) - : QObject(parent) - , m_service(service) - , m_capturePreviewWindowOutput(nullptr) - , m_state(QCamera::UnloadedState) - , m_active(false) - , m_videoInput(nil) - , m_defaultCodec(0) -{ - m_captureSession = [[AVCaptureSession alloc] init]; - m_observer = [[AVFCameraSessionObserver alloc] initWithCameraSession:this]; - - //configuration is commited during transition to Active state - [m_captureSession beginConfiguration]; -} - -AVFCameraSession::~AVFCameraSession() -{ - if (m_capturePreviewWindowOutput) { - m_capturePreviewWindowOutput->setLayer(nil); - } - - if (m_videoInput) { - [m_captureSession removeInput:m_videoInput]; - [m_videoInput release]; - } - - [m_observer release]; - [m_captureSession release]; -} - -int AVFCameraSession::defaultCameraIndex() -{ - updateCameraDevices(); - return m_defaultCameraIndex; -} - -const QList<AVFCameraInfo> &AVFCameraSession::availableCameraDevices() -{ - updateCameraDevices(); - return m_cameraDevices; -} - -AVFCameraInfo AVFCameraSession::cameraDeviceInfo(const QByteArray &device) -{ - updateCameraDevices(); - - for (const AVFCameraInfo &info : qAsConst(m_cameraDevices)) { - if (info.deviceId == device) - return info; - } - - return AVFCameraInfo(); -} - -void AVFCameraSession::updateCameraDevices() -{ -#ifdef Q_OS_IOS - // Cameras can't change dynamically on iOS. Update only once. - if (!m_cameraDevices.isEmpty()) - return; -#else - // On OS X, cameras can be added or removed. Update the list every time, but not more than - // once every 500 ms - static QElapsedTimer timer; - if (timer.isValid() && timer.elapsed() < 500) // ms - return; -#endif - - m_defaultCameraIndex = -1; - m_cameraDevices.clear(); - - AVCaptureDevice *defaultDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; - NSArray *videoDevices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]; - for (AVCaptureDevice *device in videoDevices) { - if (defaultDevice && [defaultDevice.uniqueID isEqualToString:device.uniqueID]) - m_defaultCameraIndex = m_cameraDevices.count(); - - AVFCameraInfo info; - info.deviceId = QByteArray([[device uniqueID] UTF8String]); - info.description = QString::fromNSString([device localizedName]); - - // There is no API to get the camera sensor orientation, however, cameras are always - // mounted in landscape on iDevices. - // - Back-facing cameras have the top side of the sensor aligned with the right side of - // the screen when held in portrait ==> 270 degrees clockwise angle - // - Front-facing cameras have the top side of the sensor aligned with the left side of - // the screen when held in portrait ==> 270 degrees clockwise angle - // On OS X, the position will always be unspecified and the sensor orientation unknown. - switch (device.position) { - case AVCaptureDevicePositionBack: - info.position = QCamera::BackFace; - info.orientation = 270; - break; - case AVCaptureDevicePositionFront: - info.position = QCamera::FrontFace; - info.orientation = 270; - break; - default: - info.position = QCamera::UnspecifiedPosition; - info.orientation = 0; - break; - } - - m_cameraDevices.append(info); - } - -#ifndef Q_OS_IOS - timer.restart(); -#endif -} - -void AVFCameraSession::setVideoOutput(AVFCameraRendererControl *output) -{ - m_videoOutput = output; - if (output) - output->configureAVCaptureSession(this); -} - -void AVFCameraSession::setCapturePreviewOutput(AVFCameraWindowControl *output) -{ -#ifdef QT_DEBUG_AVF - qDebug() << Q_FUNC_INFO << output; -#endif - - if (m_capturePreviewWindowOutput == output) - return; - - if (m_capturePreviewWindowOutput) - m_capturePreviewWindowOutput->setLayer(nil); - - m_capturePreviewWindowOutput = output; - - if (m_capturePreviewWindowOutput) { - AVCaptureVideoPreviewLayer *previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:m_captureSession]; - m_capturePreviewWindowOutput->setLayer(previewLayer); - if (AVFCameraViewfinderSettingsControl2 *vfControl = m_service->viewfinderSettingsControl2()) { - m_capturePreviewWindowOutput->setNativeSize(vfControl->viewfinderSettings().resolution()); - } - } -} - -AVCaptureDevice *AVFCameraSession::videoCaptureDevice() const -{ - if (m_videoInput) - return m_videoInput.device; - - return nullptr; -} - -QCamera::State AVFCameraSession::state() const -{ - if (m_active) - return QCamera::ActiveState; - - return m_state == QCamera::ActiveState ? QCamera::LoadedState : m_state; -} - -void AVFCameraSession::setState(QCamera::State newState) -{ - if (m_state == newState) - return; - - qDebugCamera() << Q_FUNC_INFO << m_state << " -> " << newState; - - QCamera::State oldState = m_state; - m_state = newState; - - //attach video input during Unloaded->Loaded transition - if (oldState == QCamera::UnloadedState) - attachVideoInputDevice(); - - if (m_state == QCamera::ActiveState) { - Q_EMIT readyToConfigureConnections(); - m_defaultCodec = 0; - defaultCodec(); - - bool activeFormatSet = applyImageEncoderSettings() - | applyViewfinderSettings(); - - [m_captureSession commitConfiguration]; - - if (activeFormatSet) { - // According to the doc, the capture device must be locked before - // startRunning to prevent the format we set to be overriden by the - // session preset. - [videoCaptureDevice() lockForConfiguration:nil]; - } - - [m_captureSession startRunning]; - - if (activeFormatSet) - [videoCaptureDevice() unlockForConfiguration]; - } - - if (oldState == QCamera::ActiveState) { - [m_captureSession stopRunning]; - [m_captureSession beginConfiguration]; - } - - Q_EMIT stateChanged(m_state); -} - -void AVFCameraSession::processRuntimeError() -{ - qWarning() << tr("Runtime camera error"); - Q_EMIT error(QCamera::CameraError, tr("Runtime camera error")); -} - -void AVFCameraSession::processSessionStarted() -{ - qDebugCamera() << Q_FUNC_INFO; - if (!m_active) { - m_active = true; - Q_EMIT activeChanged(m_active); - Q_EMIT stateChanged(state()); - } -} - -void AVFCameraSession::processSessionStopped() -{ - qDebugCamera() << Q_FUNC_INFO; - if (m_active) { - m_active = false; - Q_EMIT activeChanged(m_active); - Q_EMIT stateChanged(state()); - } -} - -void AVFCameraSession::onCaptureModeChanged(QCamera::CaptureModes mode) -{ - Q_UNUSED(mode); - - const QCamera::State s = state(); - if (s == QCamera::LoadedState || s == QCamera::ActiveState) { - applyImageEncoderSettings(); - applyViewfinderSettings(); - } -} - -void AVFCameraSession::attachVideoInputDevice() -{ - //Attach video input device: - if (m_service->videoDeviceControl()->isDirty()) { - if (m_videoInput) { - [m_captureSession removeInput:m_videoInput]; - [m_videoInput release]; - m_videoInput = nullptr; - m_activeCameraInfo = AVFCameraInfo(); - } - - AVCaptureDevice *videoDevice = m_service->videoDeviceControl()->createCaptureDevice(); - - NSError *error = nil; - m_videoInput = [AVCaptureDeviceInput - deviceInputWithDevice:videoDevice - error:&error]; - - if (!m_videoInput) { - qWarning() << "Failed to create video device input"; - } else { - if ([m_captureSession canAddInput:m_videoInput]) { - m_activeCameraInfo = m_cameraDevices.at(m_service->videoDeviceControl()->selectedDevice()); - [m_videoInput retain]; - [m_captureSession addInput:m_videoInput]; - } else { - qWarning() << "Failed to connect video device input"; - } - } - } -} - -bool AVFCameraSession::applyImageEncoderSettings() -{ - if (AVFImageEncoderControl *control = m_service->imageEncoderControl()) - return control->applySettings(); - - return false; -} - -bool AVFCameraSession::applyViewfinderSettings() -{ - if (AVFCameraViewfinderSettingsControl2 *vfControl = m_service->viewfinderSettingsControl2()) { - QCamera::CaptureModes currentMode = m_service->cameraControl()->captureMode(); - QCameraViewfinderSettings vfSettings(vfControl->requestedSettings()); - // Viewfinder and image capture solutions must be the same, if an image capture - // resolution is set, it takes precedence over the viewfinder resolution. - if (currentMode.testFlag(QCamera::CaptureStillImage)) { - const QSize imageResolution(m_service->imageEncoderControl()->requestedSettings().resolution()); - if (!imageResolution.isNull() && imageResolution.isValid()) - vfSettings.setResolution(imageResolution); - } - - vfControl->applySettings(vfSettings); - - if (m_capturePreviewWindowOutput) - m_capturePreviewWindowOutput->setNativeSize(vfControl->viewfinderSettings().resolution()); - - return !vfSettings.isNull(); - } - - return false; -} - -void AVFCameraSession::addProbe(AVFMediaVideoProbeControl *probe) -{ - m_videoProbesMutex.lock(); - if (probe) - m_videoProbes << probe; - m_videoProbesMutex.unlock(); -} - -void AVFCameraSession::removeProbe(AVFMediaVideoProbeControl *probe) -{ - m_videoProbesMutex.lock(); - m_videoProbes.remove(probe); - m_videoProbesMutex.unlock(); -} - -FourCharCode AVFCameraSession::defaultCodec() -{ - if (!m_defaultCodec) { - if (AVCaptureDevice *device = videoCaptureDevice()) { - AVCaptureDeviceFormat *format = device.activeFormat; - if (!format || !format.formatDescription) - return m_defaultCodec; - m_defaultCodec = CMVideoFormatDescriptionGetCodecType(format.formatDescription); - } - } - return m_defaultCodec; -} - -void AVFCameraSession::onCameraFrameFetched(const QVideoFrame &frame) -{ - Q_EMIT newViewfinderFrame(frame); - - m_videoProbesMutex.lock(); - QSet<AVFMediaVideoProbeControl *>::const_iterator i = m_videoProbes.constBegin(); - while (i != m_videoProbes.constEnd()) { - (*i)->newFrameProbed(frame); - ++i; - } - m_videoProbesMutex.unlock(); -} - -#include "moc_avfcamerasession.cpp" diff --git a/src/plugins/avfoundation/camera/avfcamerautility.h b/src/plugins/avfoundation/camera/avfcamerautility.h deleted file mode 100644 index 2e8bf39b4..000000000 --- a/src/plugins/avfoundation/camera/avfcamerautility.h +++ /dev/null @@ -1,179 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** 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$ -** -****************************************************************************/ - -#ifndef AVFCAMERAUTILITY_H -#define AVFCAMERAUTILITY_H - -#include <QtCore/qglobal.h> -#include <QtCore/qdebug.h> -#include <QtCore/qlist.h> -#include <QtCore/qpair.h> -#include <QtCore/qsize.h> - -#include <AVFoundation/AVFoundation.h> - -// In case we have SDK below 10.7/7.0: -@class AVCaptureDeviceFormat; - -QT_BEGIN_NAMESPACE - -class AVFConfigurationLock -{ -public: - explicit AVFConfigurationLock(AVCaptureDevice *captureDevice) - : m_captureDevice(captureDevice), - m_locked(false) - { - Q_ASSERT(m_captureDevice); - NSError *error = nil; - m_locked = [m_captureDevice lockForConfiguration:&error]; - } - - ~AVFConfigurationLock() - { - if (m_locked) - [m_captureDevice unlockForConfiguration]; - } - - operator bool() const - { - return m_locked; - } - -private: - Q_DISABLE_COPY(AVFConfigurationLock) - - AVCaptureDevice *m_captureDevice; - bool m_locked; -}; - -struct AVFObjectDeleter { - static void cleanup(NSObject *obj) - { - if (obj) - [obj release]; - } -}; - -template<class T> -class AVFScopedPointer : public QScopedPointer<NSObject, AVFObjectDeleter> -{ -public: - AVFScopedPointer() {} - explicit AVFScopedPointer(T *ptr) : QScopedPointer(ptr) {} - operator T*() const - { - // Quite handy operator to enable Obj-C messages: [ptr someMethod]; - return data(); - } - - T *data() const - { - return static_cast<T *>(QScopedPointer::data()); - } - - T *take() - { - return static_cast<T *>(QScopedPointer::take()); - } -}; - -template<> -class AVFScopedPointer<dispatch_queue_t> -{ -public: - AVFScopedPointer() : m_queue(nullptr) {} - explicit AVFScopedPointer(dispatch_queue_t q) : m_queue(q) {} - - ~AVFScopedPointer() - { - if (m_queue) - dispatch_release(m_queue); - } - - operator dispatch_queue_t() const - { - // Quite handy operator to enable Obj-C messages: [ptr someMethod]; - return m_queue; - } - - dispatch_queue_t data() const - { - return m_queue; - } - - void reset(dispatch_queue_t q = nullptr) - { - if (m_queue) - dispatch_release(m_queue); - m_queue = q; - } - -private: - dispatch_queue_t m_queue; - - Q_DISABLE_COPY(AVFScopedPointer) -}; - -typedef QPair<qreal, qreal> AVFPSRange; -AVFPSRange qt_connection_framerates(AVCaptureConnection *videoConnection); - -QList<AVCaptureDeviceFormat *> qt_unique_device_formats(AVCaptureDevice *captureDevice, - FourCharCode preferredFormat); -QSize qt_device_format_resolution(AVCaptureDeviceFormat *format); -QSize qt_device_format_high_resolution(AVCaptureDeviceFormat *format); -QSize qt_device_format_pixel_aspect_ratio(AVCaptureDeviceFormat *format); -QList<AVFPSRange> qt_device_format_framerates(AVCaptureDeviceFormat *format); -AVCaptureDeviceFormat *qt_find_best_resolution_match(AVCaptureDevice *captureDevice, const QSize &res, - FourCharCode preferredFormat, bool stillImage = true); -AVCaptureDeviceFormat *qt_find_best_framerate_match(AVCaptureDevice *captureDevice, - FourCharCode preferredFormat, - Float64 fps); -AVFrameRateRange *qt_find_supported_framerate_range(AVCaptureDeviceFormat *format, Float64 fps); - -bool qt_formats_are_equal(AVCaptureDeviceFormat *f1, AVCaptureDeviceFormat *f2); -bool qt_set_active_format(AVCaptureDevice *captureDevice, AVCaptureDeviceFormat *format, bool preserveFps); - -AVFPSRange qt_current_framerates(AVCaptureDevice *captureDevice, AVCaptureConnection *videoConnection); -void qt_set_framerate_limits(AVCaptureDevice *captureDevice, AVCaptureConnection *videoConnection, - qreal minFPS, qreal maxFPS); - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/avfoundation/camera/avfcamerautility.mm b/src/plugins/avfoundation/camera/avfcamerautility.mm deleted file mode 100644 index 25ccc4b01..000000000 --- a/src/plugins/avfoundation/camera/avfcamerautility.mm +++ /dev/null @@ -1,575 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** 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 "avfcamerautility.h" -#include "avfcameradebug.h" - -#include <QtCore/qvector.h> -#include <QtCore/qpair.h> -#include <private/qmultimediautils_p.h> - -#include <functional> -#include <algorithm> -#include <limits> -#include <tuple> - -QT_BEGIN_NAMESPACE - -AVFPSRange qt_connection_framerates(AVCaptureConnection *videoConnection) -{ - Q_ASSERT(videoConnection); - - AVFPSRange newRange; - // "The value in the videoMinFrameDuration is equivalent to the reciprocal - // of the maximum framerate, the value in the videoMaxFrameDuration is equivalent - // to the reciprocal of the minimum framerate." - if (videoConnection.supportsVideoMinFrameDuration) { - const CMTime cmMin = videoConnection.videoMinFrameDuration; - if (CMTimeCompare(cmMin, kCMTimeInvalid)) { // Has some non-default value: - if (const Float64 minSeconds = CMTimeGetSeconds(cmMin)) - newRange.second = 1. / minSeconds; - } - } - - if (videoConnection.supportsVideoMaxFrameDuration) { - const CMTime cmMax = videoConnection.videoMaxFrameDuration; - if (CMTimeCompare(cmMax, kCMTimeInvalid)) { - if (const Float64 maxSeconds = CMTimeGetSeconds(cmMax)) - newRange.first = 1. / maxSeconds; - } - } - - return newRange; -} - -namespace { - -inline bool qt_area_sane(const QSize &size) -{ - return !size.isNull() && size.isValid() - && std::numeric_limits<int>::max() / size.width() >= size.height(); -} - -template <template <typename...> class Comp> // std::less or std::greater (or std::equal_to) -struct ByResolution -{ - bool operator() (AVCaptureDeviceFormat *f1, AVCaptureDeviceFormat *f2)const - { - Q_ASSERT(f1 && f2); - const QSize r1(qt_device_format_resolution(f1)); - const QSize r2(qt_device_format_resolution(f2)); - // use std::tuple for lexicograpical sorting: - const Comp<std::tuple<int, int>> op = {}; - return op(std::make_tuple(r1.width(), r1.height()), - std::make_tuple(r2.width(), r2.height())); - } -}; - -struct FormatHasNoFPSRange : std::unary_function<AVCaptureDeviceFormat *, bool> -{ - bool operator() (AVCaptureDeviceFormat *format) - { - Q_ASSERT(format); - return !format.videoSupportedFrameRateRanges || !format.videoSupportedFrameRateRanges.count; - } -}; - -Float64 qt_find_min_framerate_distance(AVCaptureDeviceFormat *format, Float64 fps) -{ - Q_ASSERT(format && format.videoSupportedFrameRateRanges - && format.videoSupportedFrameRateRanges.count); - - AVFrameRateRange *range = [format.videoSupportedFrameRateRanges objectAtIndex:0]; - Float64 distance = qAbs(range.maxFrameRate - fps); - for (NSUInteger i = 1, e = format.videoSupportedFrameRateRanges.count; i < e; ++i) { - range = [format.videoSupportedFrameRateRanges objectAtIndex:i]; - distance = qMin(distance, qAbs(range.maxFrameRate - fps)); - } - - return distance; -} - -} // Unnamed namespace. - -QVector<AVCaptureDeviceFormat *> qt_unique_device_formats(AVCaptureDevice *captureDevice, FourCharCode filter) -{ - // 'filter' is the format we prefer if we have duplicates. - Q_ASSERT(captureDevice); - - QVector<AVCaptureDeviceFormat *> formats; - - if (!captureDevice.formats || !captureDevice.formats.count) - return formats; - - formats.reserve(captureDevice.formats.count); - for (AVCaptureDeviceFormat *format in captureDevice.formats) { - const QSize resolution(qt_device_format_resolution(format)); - if (resolution.isNull() || !resolution.isValid()) - continue; - formats << format; - } - - if (!formats.size()) - return formats; - - std::sort(formats.begin(), formats.end(), ByResolution<std::less>()); - - QSize size(qt_device_format_resolution(formats[0])); - FourCharCode codec = CMVideoFormatDescriptionGetCodecType(formats[0].formatDescription); - int last = 0; - for (int i = 1; i < formats.size(); ++i) { - const QSize nextSize(qt_device_format_resolution(formats[i])); - if (nextSize == size) { - if (codec == filter) - continue; - formats[last] = formats[i]; - } else { - ++last; - formats[last] = formats[i]; - size = nextSize; - } - codec = CMVideoFormatDescriptionGetCodecType(formats[i].formatDescription); - } - formats.resize(last + 1); - - return formats; -} - -QSize qt_device_format_resolution(AVCaptureDeviceFormat *format) -{ - if (!format || !format.formatDescription) - return QSize(); - - const CMVideoDimensions res = CMVideoFormatDescriptionGetDimensions(format.formatDescription); - return QSize(res.width, res.height); -} - -QSize qt_device_format_high_resolution(AVCaptureDeviceFormat *format) -{ - Q_ASSERT(format); - QSize res; -#if defined(Q_OS_IOS) - const CMVideoDimensions hrDim(format.highResolutionStillImageDimensions); - res.setWidth(hrDim.width); - res.setHeight(hrDim.height); -#endif - return res; -} - -QVector<AVFPSRange> qt_device_format_framerates(AVCaptureDeviceFormat *format) -{ - Q_ASSERT(format); - - QVector<AVFPSRange> qtRanges; - - if (!format.videoSupportedFrameRateRanges || !format.videoSupportedFrameRateRanges.count) - return qtRanges; - - qtRanges.reserve(format.videoSupportedFrameRateRanges.count); - for (AVFrameRateRange *range in format.videoSupportedFrameRateRanges) - qtRanges << AVFPSRange(range.minFrameRate, range.maxFrameRate); - - return qtRanges; -} - -QSize qt_device_format_pixel_aspect_ratio(AVCaptureDeviceFormat *format) -{ - Q_ASSERT(format); - - if (!format.formatDescription) { - qDebugCamera() << Q_FUNC_INFO << "no format description found"; - return QSize(); - } - - const CMVideoDimensions res = CMVideoFormatDescriptionGetDimensions(format.formatDescription); - const CGSize resPAR = CMVideoFormatDescriptionGetPresentationDimensions(format.formatDescription, true, false); - - if (qAbs(resPAR.width - res.width) < 1.) { - // "Pixel aspect ratio is used to adjust the width, leaving the height alone." - return QSize(1, 1); - } - - if (!res.width || !resPAR.width) - return QSize(); - - int n, d; - qt_real_to_fraction(resPAR.width > res.width - ? res.width / qreal(resPAR.width) - : resPAR.width / qreal(res.width), - &n, &d); - - return QSize(n, d); -} - -AVCaptureDeviceFormat *qt_find_best_resolution_match(AVCaptureDevice *captureDevice, - const QSize &request, - FourCharCode filter, - bool stillImage) -{ - Q_ASSERT(captureDevice); - Q_ASSERT(!request.isNull() && request.isValid()); - - if (!captureDevice.formats || !captureDevice.formats.count) - return nullptr; - - QVector<AVCaptureDeviceFormat *> formats(qt_unique_device_formats(captureDevice, filter)); - - for (int i = 0; i < formats.size(); ++i) { - AVCaptureDeviceFormat *format = formats[i]; - if (qt_device_format_resolution(format) == request) - return format; - // iOS only (still images). - if (stillImage && qt_device_format_high_resolution(format) == request) - return format; - } - - if (!qt_area_sane(request)) - return nullptr; - - typedef QPair<QSize, AVCaptureDeviceFormat *> FormatPair; - - QVector<FormatPair> pairs; // default|HR sizes - pairs.reserve(formats.size()); - - for (int i = 0; i < formats.size(); ++i) { - AVCaptureDeviceFormat *format = formats[i]; - const QSize res(qt_device_format_resolution(format)); - if (!res.isNull() && res.isValid() && qt_area_sane(res)) - pairs << FormatPair(res, format); - const QSize highRes(qt_device_format_high_resolution(format)); - if (stillImage && !highRes.isNull() && highRes.isValid() && qt_area_sane(highRes)) - pairs << FormatPair(highRes, format); - } - - if (!pairs.size()) - return nullptr; - - AVCaptureDeviceFormat *best = pairs[0].second; - QSize next(pairs[0].first); - int wDiff = qAbs(request.width() - next.width()); - int hDiff = qAbs(request.height() - next.height()); - const int area = request.width() * request.height(); - int areaDiff = qAbs(area - next.width() * next.height()); - for (int i = 1; i < pairs.size(); ++i) { - next = pairs[i].first; - const int newWDiff = qAbs(next.width() - request.width()); - const int newHDiff = qAbs(next.height() - request.height()); - const int newAreaDiff = qAbs(area - next.width() * next.height()); - - if ((newWDiff < wDiff && newHDiff < hDiff) - || ((newWDiff <= wDiff || newHDiff <= hDiff) && newAreaDiff <= areaDiff)) { - wDiff = newWDiff; - hDiff = newHDiff; - best = pairs[i].second; - areaDiff = newAreaDiff; - } - } - - return best; -} - -AVCaptureDeviceFormat *qt_find_best_framerate_match(AVCaptureDevice *captureDevice, - FourCharCode filter, - Float64 fps) -{ - Q_ASSERT(captureDevice); - Q_ASSERT(fps > 0.); - - const qreal epsilon = 0.1; - - QVector<AVCaptureDeviceFormat *>sorted(qt_unique_device_formats(captureDevice, filter)); - // Sort formats by their resolution in decreasing order: - std::sort(sorted.begin(), sorted.end(), ByResolution<std::greater>()); - // We can use only formats with framerate ranges: - sorted.erase(std::remove_if(sorted.begin(), sorted.end(), FormatHasNoFPSRange()), sorted.end()); - - if (!sorted.size()) - return nil; - - for (int i = 0; i < sorted.size(); ++i) { - AVCaptureDeviceFormat *format = sorted[i]; - for (AVFrameRateRange *range in format.videoSupportedFrameRateRanges) { - if (range.maxFrameRate - range.minFrameRate < epsilon) { - // On OS X ranges are points (built-in camera). - if (qAbs(fps - range.maxFrameRate) < epsilon) - return format; - } - - if (fps >= range.minFrameRate && fps <= range.maxFrameRate) - return format; - } - } - - Float64 distance = qt_find_min_framerate_distance(sorted[0], fps); - AVCaptureDeviceFormat *match = sorted[0]; - for (int i = 1; i < sorted.size(); ++i) { - const Float64 newDistance = qt_find_min_framerate_distance(sorted[i], fps); - if (newDistance < distance) { - distance = newDistance; - match = sorted[i]; - } - } - - return match; -} - -AVFrameRateRange *qt_find_supported_framerate_range(AVCaptureDeviceFormat *format, Float64 fps) -{ - Q_ASSERT(format && format.videoSupportedFrameRateRanges - && format.videoSupportedFrameRateRanges.count); - - const qreal epsilon = 0.1; - - for (AVFrameRateRange *range in format.videoSupportedFrameRateRanges) { - if (range.maxFrameRate - range.minFrameRate < epsilon) { - // On OS X ranges are points (built-in camera). - if (qAbs(fps - range.maxFrameRate) < epsilon) - return range; - } - - if (fps >= range.minFrameRate && fps <= range.maxFrameRate) - return range; - } - - AVFrameRateRange *match = [format.videoSupportedFrameRateRanges objectAtIndex:0]; - Float64 distance = qAbs(match.maxFrameRate - fps); - for (NSUInteger i = 1, e = format.videoSupportedFrameRateRanges.count; i < e; ++i) { - AVFrameRateRange *range = [format.videoSupportedFrameRateRanges objectAtIndex:i]; - const Float64 newDistance = qAbs(range.maxFrameRate - fps); - if (newDistance < distance) { - distance = newDistance; - match = range; - } - } - - return match; -} - -bool qt_formats_are_equal(AVCaptureDeviceFormat *f1, AVCaptureDeviceFormat *f2) -{ - if (f1 == f2) - return true; - - if (![f1.mediaType isEqualToString:f2.mediaType]) - return false; - - return CMFormatDescriptionEqual(f1.formatDescription, f2.formatDescription); -} - -bool qt_set_active_format(AVCaptureDevice *captureDevice, AVCaptureDeviceFormat *format, bool preserveFps) -{ - static bool firstSet = true; - - if (!captureDevice || !format) - return false; - - if (qt_formats_are_equal(captureDevice.activeFormat, format)) { - if (firstSet) { - // The capture device format is persistent. The first time we set a format, report that - // it changed even if the formats are the same. - // This prevents the session from resetting the format to the default value. - firstSet = false; - return true; - } - return false; - } - - firstSet = false; - - const AVFConfigurationLock lock(captureDevice); - if (!lock) { - qWarning("Failed to set active format (lock failed)"); - return false; - } - - // Changing the activeFormat resets the frame rate. - AVFPSRange fps; - if (preserveFps) - fps = qt_current_framerates(captureDevice, nil); - - captureDevice.activeFormat = format; - - if (preserveFps) - qt_set_framerate_limits(captureDevice, nil, fps.first, fps.second); - - return true; -} - -void qt_set_framerate_limits(AVCaptureConnection *videoConnection, qreal minFPS, qreal maxFPS) -{ - Q_ASSERT(videoConnection); - - if (minFPS < 0. || maxFPS < 0. || (maxFPS && maxFPS < minFPS)) { - qDebugCamera() << Q_FUNC_INFO << "invalid framerates (min, max):" - << minFPS << maxFPS; - return; - } - - CMTime minDuration = kCMTimeInvalid; - if (maxFPS > 0.) { - if (!videoConnection.supportsVideoMinFrameDuration) - qDebugCamera() << Q_FUNC_INFO << "maximum framerate is not supported"; - else - minDuration = CMTimeMake(1, maxFPS); - } - if (videoConnection.supportsVideoMinFrameDuration) - videoConnection.videoMinFrameDuration = minDuration; - - CMTime maxDuration = kCMTimeInvalid; - if (minFPS > 0.) { - if (!videoConnection.supportsVideoMaxFrameDuration) - qDebugCamera() << Q_FUNC_INFO << "minimum framerate is not supported"; - else - maxDuration = CMTimeMake(1, minFPS); - } - if (videoConnection.supportsVideoMaxFrameDuration) - videoConnection.videoMaxFrameDuration = maxDuration; -} - -CMTime qt_adjusted_frame_duration(AVFrameRateRange *range, qreal fps) -{ - Q_ASSERT(range); - Q_ASSERT(fps > 0.); - - if (range.maxFrameRate - range.minFrameRate < 0.1) { - // Can happen on OS X. - return range.minFrameDuration; - } - - if (fps <= range.minFrameRate) - return range.maxFrameDuration; - if (fps >= range.maxFrameRate) - return range.minFrameDuration; - - int n, d; - qt_real_to_fraction(1. / fps, &n, &d); - return CMTimeMake(n, d); -} - -void qt_set_framerate_limits(AVCaptureDevice *captureDevice, qreal minFPS, qreal maxFPS) -{ - Q_ASSERT(captureDevice); - if (!captureDevice.activeFormat) { - qDebugCamera() << Q_FUNC_INFO << "no active capture device format"; - return; - } - - if (minFPS < 0. || maxFPS < 0. || (maxFPS && maxFPS < minFPS)) { - qDebugCamera() << Q_FUNC_INFO << "invalid framerates (min, max):" - << minFPS << maxFPS; - return; - } - - CMTime minFrameDuration = kCMTimeInvalid; - CMTime maxFrameDuration = kCMTimeInvalid; - if (maxFPS || minFPS) { - AVFrameRateRange *range = qt_find_supported_framerate_range(captureDevice.activeFormat, - maxFPS ? maxFPS : minFPS); - if (!range) { - qDebugCamera() << Q_FUNC_INFO << "no framerate range found, (min, max):" - << minFPS << maxFPS; - return; - } - - if (maxFPS) - minFrameDuration = qt_adjusted_frame_duration(range, maxFPS); - if (minFPS) - maxFrameDuration = qt_adjusted_frame_duration(range, minFPS); - } - - const AVFConfigurationLock lock(captureDevice); - if (!lock) { - qDebugCamera() << Q_FUNC_INFO << "failed to lock for configuration"; - return; - } - - // While Apple's docs say kCMTimeInvalid will end in default - // settings for this format, kCMTimeInvalid on OS X ends with a runtime - // exception: - // "The activeVideoMinFrameDuration passed is not supported by the device." - // Instead, use the first item in the supported frame rates. -#ifdef Q_OS_IOS - [captureDevice setActiveVideoMinFrameDuration:minFrameDuration]; - [captureDevice setActiveVideoMaxFrameDuration:maxFrameDuration]; -#elif defined(Q_OS_MACOS) - if (CMTimeCompare(minFrameDuration, kCMTimeInvalid) == 0 - && CMTimeCompare(maxFrameDuration, kCMTimeInvalid) == 0) { - AVFrameRateRange *range = captureDevice.activeFormat.videoSupportedFrameRateRanges.firstObject; - minFrameDuration = range.minFrameDuration; - maxFrameDuration = range.maxFrameDuration; - } - - if (CMTimeCompare(minFrameDuration, kCMTimeInvalid)) - [captureDevice setActiveVideoMinFrameDuration:minFrameDuration]; - - if (CMTimeCompare(maxFrameDuration, kCMTimeInvalid)) - [captureDevice setActiveVideoMaxFrameDuration:maxFrameDuration]; -#endif // Q_OS_MACOS -} - -void qt_set_framerate_limits(AVCaptureDevice *captureDevice, AVCaptureConnection *videoConnection, - qreal minFPS, qreal maxFPS) -{ - Q_UNUSED(videoConnection); - Q_ASSERT(captureDevice); - qt_set_framerate_limits(captureDevice, minFPS, maxFPS); -} - -AVFPSRange qt_current_framerates(AVCaptureDevice *captureDevice, AVCaptureConnection *videoConnection) -{ - Q_UNUSED(videoConnection); - Q_ASSERT(captureDevice); - - AVFPSRange fps; - const CMTime minDuration = captureDevice.activeVideoMinFrameDuration; - if (CMTimeCompare(minDuration, kCMTimeInvalid)) { - if (const Float64 minSeconds = CMTimeGetSeconds(minDuration)) - fps.second = 1. / minSeconds; // Max FPS = 1 / MinDuration. - } - - const CMTime maxDuration = captureDevice.activeVideoMaxFrameDuration; - if (CMTimeCompare(maxDuration, kCMTimeInvalid)) { - if (const Float64 maxSeconds = CMTimeGetSeconds(maxDuration)) - fps.first = 1. / maxSeconds; // Min FPS = 1 / MaxDuration. - } - - return fps; -} - -QT_END_NAMESPACE diff --git a/src/plugins/avfoundation/camera/avfcameraviewfindersettingscontrol.h b/src/plugins/avfoundation/camera/avfcameraviewfindersettingscontrol.h deleted file mode 100644 index 7cd59117f..000000000 --- a/src/plugins/avfoundation/camera/avfcameraviewfindersettingscontrol.h +++ /dev/null @@ -1,117 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** 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$ -** -****************************************************************************/ - -#ifndef AVFCAMERAVIEWFINDERSETTINGSCONTROL_H -#define AVFCAMERAVIEWFINDERSETTINGSCONTROL_H - -#include <QtMultimedia/qcameraviewfindersettingscontrol.h> -#include <QtMultimedia/qcameraviewfindersettings.h> -#include <QtMultimedia/qvideoframe.h> - -#include <QtCore/qpointer.h> -#include <QtCore/qglobal.h> -#include <QtCore/qsize.h> - -@class AVCaptureDevice; -@class AVCaptureVideoDataOutput; -@class AVCaptureConnection; -@class AVCaptureDeviceFormat; - -QT_BEGIN_NAMESPACE - -class AVFCameraSession; -class AVFCameraService; - -class AVFCameraViewfinderSettingsControl2 : public QCameraViewfinderSettingsControl2 -{ - Q_OBJECT - - friend class AVFCameraSession; - friend class AVFCameraViewfinderSettingsControl; -public: - AVFCameraViewfinderSettingsControl2(AVFCameraService *service); - - QList<QCameraViewfinderSettings> supportedViewfinderSettings() const override; - QCameraViewfinderSettings viewfinderSettings() const override; - void setViewfinderSettings(const QCameraViewfinderSettings &settings) override; - - // "Converters": - static QVideoFrame::PixelFormat QtPixelFormatFromCVFormat(unsigned avPixelFormat); - static bool CVPixelFormatFromQtFormat(QVideoFrame::PixelFormat qtFormat, unsigned &conv); - -private: - void setResolution(const QSize &resolution); - void setFramerate(qreal minFPS, qreal maxFPS, bool useActive); - void setPixelFormat(QVideoFrame::PixelFormat newFormat); - AVCaptureDeviceFormat *findBestFormatMatch(const QCameraViewfinderSettings &settings) const; - QList<QVideoFrame::PixelFormat> viewfinderPixelFormats() const; - bool convertPixelFormatIfSupported(QVideoFrame::PixelFormat format, unsigned &avfFormat) const; - bool applySettings(const QCameraViewfinderSettings &settings); - QCameraViewfinderSettings requestedSettings() const; - - AVCaptureConnection *videoConnection() const; - - AVFCameraService *m_service; - QCameraViewfinderSettings m_settings; -}; - -class AVFCameraViewfinderSettingsControl : public QCameraViewfinderSettingsControl -{ - Q_OBJECT -public: - AVFCameraViewfinderSettingsControl(AVFCameraService *service); - - bool isViewfinderParameterSupported(ViewfinderParameter parameter) const override; - QVariant viewfinderParameter(ViewfinderParameter parameter) const override; - void setViewfinderParameter(ViewfinderParameter parameter, const QVariant &value) override; - -private: - void setResolution(const QVariant &resolution); - void setAspectRatio(const QVariant &aspectRatio); - void setFrameRate(const QVariant &fps, bool max); - void setPixelFormat(const QVariant &pf); - bool initSettingsControl() const; - - AVFCameraService *m_service; - mutable QPointer<AVFCameraViewfinderSettingsControl2> m_settingsControl; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/avfoundation/camera/avfcameraviewfindersettingscontrol.mm b/src/plugins/avfoundation/camera/avfcameraviewfindersettingscontrol.mm deleted file mode 100644 index dd0393f96..000000000 --- a/src/plugins/avfoundation/camera/avfcameraviewfindersettingscontrol.mm +++ /dev/null @@ -1,599 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** 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 "avfcameraviewfindersettingscontrol.h" -#include "avfcamerarenderercontrol.h" -#include "avfcamerautility.h" -#include "avfcamerasession.h" -#include "avfcameraservice.h" -#include "avfcameradebug.h" - -#include <QtMultimedia/qabstractvideosurface.h> - -#include <QtCore/qvariant.h> -#include <QtCore/qvector.h> -#include <QtCore/qdebug.h> -#include <QtCore/qlist.h> -#include <private/qmultimediautils_p.h> - -#include <algorithm> - -#include <AVFoundation/AVFoundation.h> - -QT_BEGIN_NAMESPACE - -namespace { - -bool qt_framerates_sane(const QCameraViewfinderSettings &settings) -{ - const qreal minFPS = settings.minimumFrameRate(); - const qreal maxFPS = settings.maximumFrameRate(); - - if (minFPS < 0. || maxFPS < 0.) - return false; - - return !maxFPS || maxFPS >= minFPS; -} - -} // Unnamed namespace. - -AVFCameraViewfinderSettingsControl2::AVFCameraViewfinderSettingsControl2(AVFCameraService *service) - : m_service(service) -{ - Q_ASSERT(service); -} - -QList<QCameraViewfinderSettings> AVFCameraViewfinderSettingsControl2::supportedViewfinderSettings() const -{ - QList<QCameraViewfinderSettings> supportedSettings; - - AVCaptureDevice *captureDevice = m_service->session()->videoCaptureDevice(); - if (!captureDevice) { - qDebugCamera() << Q_FUNC_INFO << "no capture device found"; - return supportedSettings; - } - - QVector<AVFPSRange> framerates; - - QVector<QVideoFrame::PixelFormat> pixelFormats(viewfinderPixelFormats()); - - if (!pixelFormats.size()) - pixelFormats << QVideoFrame::Format_Invalid; // The default value. - - if (!captureDevice.formats || !captureDevice.formats.count) { - qDebugCamera() << Q_FUNC_INFO << "no capture device formats found"; - return supportedSettings; - } - - const QVector<AVCaptureDeviceFormat *> formats(qt_unique_device_formats(captureDevice, - m_service->session()->defaultCodec())); - for (int i = 0; i < formats.size(); ++i) { - AVCaptureDeviceFormat *format = formats[i]; - - const QSize res(qt_device_format_resolution(format)); - if (res.isNull() || !res.isValid()) - continue; - const QSize par(qt_device_format_pixel_aspect_ratio(format)); - if (par.isNull() || !par.isValid()) - continue; - - framerates = qt_device_format_framerates(format); - if (!framerates.size()) - framerates << AVFPSRange(); // The default value. - - for (int i = 0; i < pixelFormats.size(); ++i) { - for (int j = 0; j < framerates.size(); ++j) { - QCameraViewfinderSettings newSet; - newSet.setResolution(res); - newSet.setPixelAspectRatio(par); - newSet.setPixelFormat(pixelFormats[i]); - newSet.setMinimumFrameRate(framerates[j].first); - newSet.setMaximumFrameRate(framerates[j].second); - supportedSettings << newSet; - } - } - } - - return supportedSettings; -} - -QCameraViewfinderSettings AVFCameraViewfinderSettingsControl2::viewfinderSettings() const -{ - QCameraViewfinderSettings settings = m_settings; - - AVCaptureDevice *captureDevice = m_service->session()->videoCaptureDevice(); - if (!captureDevice) { - qDebugCamera() << Q_FUNC_INFO << "no capture device found"; - return settings; - } - - if (m_service->session()->state() != QCamera::LoadedState && - m_service->session()->state() != QCamera::ActiveState) { - return settings; - } - - if (!captureDevice.activeFormat) { - qDebugCamera() << Q_FUNC_INFO << "no active capture device format"; - return settings; - } - - const QSize res(qt_device_format_resolution(captureDevice.activeFormat)); - const QSize par(qt_device_format_pixel_aspect_ratio(captureDevice.activeFormat)); - if (res.isNull() || !res.isValid() || par.isNull() || !par.isValid()) { - qDebugCamera() << Q_FUNC_INFO << "failed to obtain resolution/pixel aspect ratio"; - return settings; - } - - settings.setResolution(res); - settings.setPixelAspectRatio(par); - - const AVFPSRange fps = qt_current_framerates(captureDevice, videoConnection()); - settings.setMinimumFrameRate(fps.first); - settings.setMaximumFrameRate(fps.second); - - AVCaptureVideoDataOutput *videoOutput = m_service->videoOutput() ? m_service->videoOutput()->videoDataOutput() : nullptr; - if (videoOutput) { - NSObject *obj = [videoOutput.videoSettings objectForKey:(id)kCVPixelBufferPixelFormatTypeKey]; - if (obj && [obj isKindOfClass:[NSNumber class]]) { - NSNumber *nsNum = static_cast<NSNumber *>(obj); - settings.setPixelFormat(QtPixelFormatFromCVFormat([nsNum unsignedIntValue])); - } - } - - return settings; -} - -void AVFCameraViewfinderSettingsControl2::setViewfinderSettings(const QCameraViewfinderSettings &settings) -{ - if (m_settings == settings) - return; - - m_settings = settings; -#if defined(Q_OS_IOS) - bool active = m_service->session()->state() == QCamera::ActiveState; - if (active) - [m_service->session()->captureSession() beginConfiguration]; - applySettings(m_settings); - if (active) - [m_service->session()->captureSession() commitConfiguration]; -#else - applySettings(m_settings); -#endif -} - -QVideoFrame::PixelFormat AVFCameraViewfinderSettingsControl2::QtPixelFormatFromCVFormat(unsigned avPixelFormat) -{ - // BGRA <-> ARGB "swap" is intentional: - // to work correctly with GL_RGBA, color swap shaders - // (in QSG node renderer etc.). - switch (avPixelFormat) { - case kCVPixelFormatType_32ARGB: - return QVideoFrame::Format_BGRA32; - case kCVPixelFormatType_32BGRA: - return QVideoFrame::Format_ARGB32; - case kCVPixelFormatType_24RGB: - return QVideoFrame::Format_RGB24; - case kCVPixelFormatType_24BGR: - return QVideoFrame::Format_BGR24; - case kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange: - case kCVPixelFormatType_420YpCbCr8BiPlanarFullRange: - return QVideoFrame::Format_NV12; - case kCVPixelFormatType_422YpCbCr8: - return QVideoFrame::Format_UYVY; - case kCVPixelFormatType_422YpCbCr8_yuvs: - return QVideoFrame::Format_YUYV; - default: - return QVideoFrame::Format_Invalid; - } -} - -bool AVFCameraViewfinderSettingsControl2::CVPixelFormatFromQtFormat(QVideoFrame::PixelFormat qtFormat, unsigned &conv) -{ - // BGRA <-> ARGB "swap" is intentional: - // to work correctly with GL_RGBA, color swap shaders - // (in QSG node renderer etc.). - switch (qtFormat) { - case QVideoFrame::Format_ARGB32: - conv = kCVPixelFormatType_32BGRA; - break; - case QVideoFrame::Format_BGRA32: - conv = kCVPixelFormatType_32ARGB; - break; - case QVideoFrame::Format_NV12: - conv = kCVPixelFormatType_420YpCbCr8BiPlanarFullRange; - break; - case QVideoFrame::Format_UYVY: - conv = kCVPixelFormatType_422YpCbCr8; - break; - case QVideoFrame::Format_YUYV: - conv = kCVPixelFormatType_422YpCbCr8_yuvs; - break; - // These two formats below are not supported - // by QSGVideoNodeFactory_RGB, so for now I have to - // disable them. - /* - case QVideoFrame::Format_RGB24: - conv = kCVPixelFormatType_24RGB; - break; - case QVideoFrame::Format_BGR24: - conv = kCVPixelFormatType_24BGR; - break; - */ - default: - return false; - } - - return true; -} - -AVCaptureDeviceFormat *AVFCameraViewfinderSettingsControl2::findBestFormatMatch(const QCameraViewfinderSettings &settings) const -{ - AVCaptureDevice *captureDevice = m_service->session()->videoCaptureDevice(); - if (!captureDevice || settings.isNull()) - return nil; - - const QSize &resolution = settings.resolution(); - if (!resolution.isNull() && resolution.isValid()) { - // Either the exact match (including high resolution for images on iOS) - // or a format with a resolution close to the requested one. - return qt_find_best_resolution_match(captureDevice, resolution, - m_service->session()->defaultCodec(), false); - } - - // No resolution requested, what about framerates? - if (!qt_framerates_sane(settings)) { - qDebugCamera() << Q_FUNC_INFO << "invalid framerate requested (min/max):" - << settings.minimumFrameRate() << settings.maximumFrameRate(); - return nil; - } - - const qreal minFPS(settings.minimumFrameRate()); - const qreal maxFPS(settings.maximumFrameRate()); - if (minFPS || maxFPS) - return qt_find_best_framerate_match(captureDevice, - m_service->session()->defaultCodec(), - maxFPS ? maxFPS : minFPS); - // Ignore PAR for the moment (PAR without resolution can - // pick a format with really bad resolution). - // No need to test pixel format, just return settings. - - return nil; -} - -QVector<QVideoFrame::PixelFormat> AVFCameraViewfinderSettingsControl2::viewfinderPixelFormats() const -{ - QVector<QVideoFrame::PixelFormat> qtFormats; - - AVCaptureVideoDataOutput *videoOutput = m_service->videoOutput() ? m_service->videoOutput()->videoDataOutput() : nullptr; - if (!videoOutput) { - qDebugCamera() << Q_FUNC_INFO << "no video output found"; - return qtFormats; - } - - NSArray *pixelFormats = [videoOutput availableVideoCVPixelFormatTypes]; - - for (NSObject *obj in pixelFormats) { - if (![obj isKindOfClass:[NSNumber class]]) - continue; - - NSNumber *formatAsNSNumber = static_cast<NSNumber *>(obj); - // It's actually FourCharCode (== UInt32): - const QVideoFrame::PixelFormat qtFormat(QtPixelFormatFromCVFormat([formatAsNSNumber unsignedIntValue])); - if (qtFormat != QVideoFrame::Format_Invalid - && !qtFormats.contains(qtFormat)) { // Can happen, for example, with 8BiPlanar existing in video/full range. - qtFormats << qtFormat; - } - } - - return qtFormats; -} - -bool AVFCameraViewfinderSettingsControl2::convertPixelFormatIfSupported(QVideoFrame::PixelFormat qtFormat, - unsigned &avfFormat)const -{ - AVCaptureVideoDataOutput *videoOutput = m_service->videoOutput() ? m_service->videoOutput()->videoDataOutput() : nullptr; - if (!videoOutput) - return false; - - unsigned conv = 0; - if (!CVPixelFormatFromQtFormat(qtFormat, conv)) - return false; - - NSArray *formats = [videoOutput availableVideoCVPixelFormatTypes]; - if (!formats || !formats.count) - return false; - - if (m_service->videoOutput()->surface()) { - const QAbstractVideoSurface *surface = m_service->videoOutput()->surface(); - QAbstractVideoBuffer::HandleType h = m_service->videoOutput()->supportsTextures() - ? QAbstractVideoBuffer::GLTextureHandle - : QAbstractVideoBuffer::NoHandle; - if (!surface->supportedPixelFormats(h).contains(qtFormat)) - return false; - } - - bool found = false; - for (NSObject *obj in formats) { - if (![obj isKindOfClass:[NSNumber class]]) - continue; - - NSNumber *nsNum = static_cast<NSNumber *>(obj); - if ([nsNum unsignedIntValue] == conv) { - avfFormat = conv; - found = true; - } - } - - return found; -} - -bool AVFCameraViewfinderSettingsControl2::applySettings(const QCameraViewfinderSettings &settings) -{ - if (m_service->session()->state() != QCamera::LoadedState && - m_service->session()->state() != QCamera::ActiveState) { - return false; - } - - AVCaptureDevice *captureDevice = m_service->session()->videoCaptureDevice(); - if (!captureDevice) - return false; - - bool activeFormatChanged = false; - - AVCaptureDeviceFormat *match = findBestFormatMatch(settings); - if (match) { - activeFormatChanged = qt_set_active_format(captureDevice, match, false); - } else { - qDebugCamera() << Q_FUNC_INFO << "matching device format not found"; - // We still can update the pixel format at least. - } - - AVCaptureVideoDataOutput *videoOutput = m_service->videoOutput() ? m_service->videoOutput()->videoDataOutput() : nullptr; - if (videoOutput) { - unsigned avfPixelFormat = 0; - if (!convertPixelFormatIfSupported(settings.pixelFormat(), avfPixelFormat)) { - // If the the pixel format is not specified or invalid, pick the preferred video surface - // format, or if no surface is set, the preferred capture device format - - const QVector<QVideoFrame::PixelFormat> deviceFormats = viewfinderPixelFormats(); - QAbstractVideoSurface *surface = m_service->videoOutput()->surface(); - QVideoFrame::PixelFormat pickedFormat = deviceFormats.first(); - if (surface) { - pickedFormat = QVideoFrame::Format_Invalid; - QAbstractVideoBuffer::HandleType h = m_service->videoOutput()->supportsTextures() - ? QAbstractVideoBuffer::GLTextureHandle - : QAbstractVideoBuffer::NoHandle; - QList<QVideoFrame::PixelFormat> surfaceFormats = surface->supportedPixelFormats(h); - for (int i = 0; i < surfaceFormats.count(); ++i) { - const QVideoFrame::PixelFormat surfaceFormat = surfaceFormats.at(i); - if (deviceFormats.contains(surfaceFormat)) { - pickedFormat = surfaceFormat; - break; - } - } - } - - CVPixelFormatFromQtFormat(pickedFormat, avfPixelFormat); - } - - NSMutableDictionary *videoSettings = [NSMutableDictionary dictionaryWithCapacity:1]; - [videoSettings setObject:[NSNumber numberWithUnsignedInt:avfPixelFormat] - forKey:(id)kCVPixelBufferPixelFormatTypeKey]; - - const AVFConfigurationLock lock(captureDevice); - if (!lock) - qWarning("Failed to set active format (lock failed)"); - - videoOutput.videoSettings = videoSettings; - } - - qt_set_framerate_limits(captureDevice, videoConnection(), settings.minimumFrameRate(), settings.maximumFrameRate()); - - return activeFormatChanged; -} - -QCameraViewfinderSettings AVFCameraViewfinderSettingsControl2::requestedSettings() const -{ - return m_settings; -} - -AVCaptureConnection *AVFCameraViewfinderSettingsControl2::videoConnection() const -{ - if (!m_service->videoOutput() || !m_service->videoOutput()->videoDataOutput()) - return nil; - - return [m_service->videoOutput()->videoDataOutput() connectionWithMediaType:AVMediaTypeVideo]; -} - -AVFCameraViewfinderSettingsControl::AVFCameraViewfinderSettingsControl(AVFCameraService *service) - : m_service(service) -{ - // Legacy viewfinder settings control. - Q_ASSERT(service); - initSettingsControl(); -} - -bool AVFCameraViewfinderSettingsControl::isViewfinderParameterSupported(ViewfinderParameter parameter) const -{ - return parameter == Resolution - || parameter == PixelAspectRatio - || parameter == MinimumFrameRate - || parameter == MaximumFrameRate - || parameter == PixelFormat; -} - -QVariant AVFCameraViewfinderSettingsControl::viewfinderParameter(ViewfinderParameter parameter) const -{ - if (!isViewfinderParameterSupported(parameter)) { - qDebugCamera() << Q_FUNC_INFO << "parameter is not supported"; - return QVariant(); - } - - if (!initSettingsControl()) { - qDebugCamera() << Q_FUNC_INFO << "initialization failed"; - return QVariant(); - } - - const QCameraViewfinderSettings settings(m_settingsControl->viewfinderSettings()); - if (parameter == Resolution) - return settings.resolution(); - if (parameter == PixelAspectRatio) - return settings.pixelAspectRatio(); - if (parameter == MinimumFrameRate) - return settings.minimumFrameRate(); - if (parameter == MaximumFrameRate) - return settings.maximumFrameRate(); - if (parameter == PixelFormat) - return QVariant::fromValue(settings.pixelFormat()); - - return QVariant(); -} - -void AVFCameraViewfinderSettingsControl::setViewfinderParameter(ViewfinderParameter parameter, const QVariant &value) -{ - if (!isViewfinderParameterSupported(parameter)) { - qDebugCamera() << Q_FUNC_INFO << "parameter is not supported"; - return; - } - - if (parameter == Resolution) - setResolution(value); - if (parameter == PixelAspectRatio) - setAspectRatio(value); - if (parameter == MinimumFrameRate) - setFrameRate(value, false); - if (parameter == MaximumFrameRate) - setFrameRate(value, true); - if (parameter == PixelFormat) - setPixelFormat(value); -} - -void AVFCameraViewfinderSettingsControl::setResolution(const QVariant &newValue) -{ - if (!newValue.canConvert<QSize>()) { - qDebugCamera() << Q_FUNC_INFO << "QSize type expected"; - return; - } - - if (!initSettingsControl()) { - qDebugCamera() << Q_FUNC_INFO << "initialization failed"; - return; - } - - const QSize res(newValue.toSize()); - if (res.isNull() || !res.isValid()) { - qDebugCamera() << Q_FUNC_INFO << "invalid resolution:" << res; - return; - } - - QCameraViewfinderSettings settings(m_settingsControl->viewfinderSettings()); - settings.setResolution(res); - m_settingsControl->setViewfinderSettings(settings); -} - -void AVFCameraViewfinderSettingsControl::setAspectRatio(const QVariant &newValue) -{ - if (!newValue.canConvert<QSize>()) { - qDebugCamera() << Q_FUNC_INFO << "QSize type expected"; - return; - } - - if (!initSettingsControl()) { - qDebugCamera() << Q_FUNC_INFO << "initialization failed"; - return; - } - - const QSize par(newValue.value<QSize>()); - if (par.isNull() || !par.isValid()) { - qDebugCamera() << Q_FUNC_INFO << "invalid pixel aspect ratio:" << par; - return; - } - - QCameraViewfinderSettings settings(m_settingsControl->viewfinderSettings()); - settings.setPixelAspectRatio(par); - m_settingsControl->setViewfinderSettings(settings); -} - -void AVFCameraViewfinderSettingsControl::setFrameRate(const QVariant &newValue, bool max) -{ - if (!newValue.canConvert<qreal>()) { - qDebugCamera() << Q_FUNC_INFO << "qreal type expected"; - return; - } - - if (!initSettingsControl()) { - qDebugCamera() << Q_FUNC_INFO << "initialization failed"; - return; - } - - const qreal fps(newValue.toReal()); - QCameraViewfinderSettings settings(m_settingsControl->viewfinderSettings()); - max ? settings.setMaximumFrameRate(fps) : settings.setMinimumFrameRate(fps); - m_settingsControl->setViewfinderSettings(settings); -} - -void AVFCameraViewfinderSettingsControl::setPixelFormat(const QVariant &newValue) -{ - if (!newValue.canConvert<QVideoFrame::PixelFormat>()) { - qDebugCamera() << Q_FUNC_INFO - << "QVideoFrame::PixelFormat type expected"; - return; - } - - if (!initSettingsControl()) { - qDebugCamera() << Q_FUNC_INFO << "initialization failed"; - return; - } - - QCameraViewfinderSettings settings(m_settingsControl->viewfinderSettings()); - settings.setPixelFormat(newValue.value<QVideoFrame::PixelFormat>()); - m_settingsControl->setViewfinderSettings(settings); -} - -bool AVFCameraViewfinderSettingsControl::initSettingsControl()const -{ - if (!m_settingsControl) - m_settingsControl = m_service->viewfinderSettingsControl2(); - - return !m_settingsControl.isNull(); -} - -QT_END_NAMESPACE - -#include "moc_avfcameraviewfindersettingscontrol.cpp" diff --git a/src/plugins/avfoundation/camera/avfcamerawindowcontrol.h b/src/plugins/avfoundation/camera/avfcamerawindowcontrol.h deleted file mode 100644 index d1a950e38..000000000 --- a/src/plugins/avfoundation/camera/avfcamerawindowcontrol.h +++ /dev/null @@ -1,129 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2020 The Qt Company Ltd. -** 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$ -** -****************************************************************************/ - -#ifndef AVFCAMERAWINDOWCONTROL_H -#define AVFCAMERAWINDOWCONTROL_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QVideoWindowControl> - -@class AVCaptureVideoPreviewLayer; -#if defined(Q_OS_MACOS) -@class NSView; -typedef NSView NativeView; -#else -@class UIView; -typedef UIView NativeView; -#endif - -QT_BEGIN_NAMESPACE - -class AVFCameraWindowControl : public QVideoWindowControl -{ - Q_OBJECT -public: - AVFCameraWindowControl(QObject *parent = nullptr); - virtual ~AVFCameraWindowControl() override; - - // QVideoWindowControl interface -public: - WId winId() const override; - void setWinId(WId id) override; - - QRect displayRect() const override; - void setDisplayRect(const QRect &rect) override; - - bool isFullScreen() const override; - void setFullScreen(bool fullScreen) override; - - void repaint() override; - - QSize nativeSize() const override; - - Qt::AspectRatioMode aspectRatioMode() const override; - void setAspectRatioMode(Qt::AspectRatioMode mode) override; - - int brightness() const override; - void setBrightness(int brightness) override; - - int contrast() const override; - void setContrast(int contrast) override; - - int hue() const override; - void setHue(int hue) override; - - int saturation() const override; - void setSaturation(int saturation) override; - - // AVF Camera implementation details - void setNativeSize(QSize size); - void setLayer(AVCaptureVideoPreviewLayer *capturePreviewLayer); - -private: - void updateAspectRatio(); - void updateCaptureLayerBounds(); - - void retainNativeLayer(); - void releaseNativeLayer(); - - void attachNativeLayer(); - void detachNativeLayer(); - - WId m_winId{0}; - QRect m_displayRect; - bool m_fullscreen{false}; - Qt::AspectRatioMode m_aspectRatioMode{Qt::IgnoreAspectRatio}; - QSize m_nativeSize; - AVCaptureVideoPreviewLayer *m_captureLayer{nullptr}; - NativeView *m_nativeView{nullptr}; -}; - -QT_END_NAMESPACE - -#endif // AVFCAMERAWINDOWCONTROL_H diff --git a/src/plugins/avfoundation/camera/avfcamerawindowcontrol.mm b/src/plugins/avfoundation/camera/avfcamerawindowcontrol.mm deleted file mode 100644 index 5154d0646..000000000 --- a/src/plugins/avfoundation/camera/avfcamerawindowcontrol.mm +++ /dev/null @@ -1,262 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2020 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 "avfcamerawindowcontrol.h" - -#import <AVFoundation/AVFoundation.h> -#import <QuartzCore/CATransaction.h> - -#if QT_HAS_INCLUDE(<AppKit/AppKit.h>) -#import <AppKit/AppKit.h> -#endif - -#if QT_HAS_INCLUDE(<UIKit/UIKit.h>) -#import <UIKit/UIKit.h> -#endif - -QT_USE_NAMESPACE - -AVFCameraWindowControl::AVFCameraWindowControl(QObject *parent) - : QVideoWindowControl(parent) -{ - setObjectName(QStringLiteral("AVFCameraWindowControl")); -} - -AVFCameraWindowControl::~AVFCameraWindowControl() -{ - releaseNativeLayer(); -} - -WId AVFCameraWindowControl::winId() const -{ - return m_winId; -} - -void AVFCameraWindowControl::setWinId(WId id) -{ - if (m_winId == id) - return; - - m_winId = id; - - detachNativeLayer(); - m_nativeView = (NativeView*)m_winId; - attachNativeLayer(); -} - -QRect AVFCameraWindowControl::displayRect() const -{ - return m_displayRect; -} - -void AVFCameraWindowControl::setDisplayRect(const QRect &rect) -{ - if (m_displayRect != rect) { - m_displayRect = rect; - updateCaptureLayerBounds(); - } -} - -bool AVFCameraWindowControl::isFullScreen() const -{ - return m_fullscreen; -} - -void AVFCameraWindowControl::setFullScreen(bool fullscreen) -{ - if (m_fullscreen != fullscreen) { - m_fullscreen = fullscreen; - Q_EMIT fullScreenChanged(fullscreen); - } -} - -void AVFCameraWindowControl::repaint() -{ - if (m_captureLayer) - [m_captureLayer setNeedsDisplay]; -} - -QSize AVFCameraWindowControl::nativeSize() const -{ - return m_nativeSize; -} - -void AVFCameraWindowControl::setNativeSize(QSize size) -{ - if (m_nativeSize != size) { - m_nativeSize = size; - Q_EMIT nativeSizeChanged(); - } -} - -Qt::AspectRatioMode AVFCameraWindowControl::aspectRatioMode() const -{ - return m_aspectRatioMode; -} - -void AVFCameraWindowControl::setAspectRatioMode(Qt::AspectRatioMode mode) -{ - if (m_aspectRatioMode != mode) { - m_aspectRatioMode = mode; - updateAspectRatio(); - } -} - -int AVFCameraWindowControl::brightness() const -{ - return 0; -} - -void AVFCameraWindowControl::setBrightness(int brightness) -{ - if (0 != brightness) - qWarning("AVFCameraWindowControl doesn't support changing Brightness"); -} - -int AVFCameraWindowControl::contrast() const -{ - return 0; -} - -void AVFCameraWindowControl::setContrast(int contrast) -{ - if (0 != contrast) - qWarning("AVFCameraWindowControl doesn't support changing Contrast"); -} - -int AVFCameraWindowControl::hue() const -{ - return 0; -} - -void AVFCameraWindowControl::setHue(int hue) -{ - if (0 != hue) - qWarning("AVFCameraWindowControl doesn't support changing Hue"); -} - -int AVFCameraWindowControl::saturation() const -{ - return 0; -} - -void AVFCameraWindowControl::setSaturation(int saturation) -{ - if (0 != saturation) - qWarning("AVFCameraWindowControl doesn't support changing Saturation"); -} - -void AVFCameraWindowControl::setLayer(AVCaptureVideoPreviewLayer *capturePreviewLayer) -{ - if (m_captureLayer == capturePreviewLayer) - return; - - releaseNativeLayer(); - - m_captureLayer = capturePreviewLayer; - - if (m_captureLayer) - retainNativeLayer(); -} - -void AVFCameraWindowControl::updateAspectRatio() -{ - if (m_captureLayer) { - switch (m_aspectRatioMode) { - case Qt::IgnoreAspectRatio: - [m_captureLayer setVideoGravity:AVLayerVideoGravityResize]; - break; - case Qt::KeepAspectRatio: - [m_captureLayer setVideoGravity:AVLayerVideoGravityResizeAspect]; - break; - case Qt::KeepAspectRatioByExpanding: - [m_captureLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill]; - break; - default: - break; - } - } -} - -void AVFCameraWindowControl::updateCaptureLayerBounds() -{ - if (m_captureLayer && m_nativeView) { - [CATransaction begin]; - [CATransaction setDisableActions: YES]; // disable animation/flicks - m_captureLayer.frame = m_displayRect.toCGRect(); - [CATransaction commit]; - } -} - -void AVFCameraWindowControl::retainNativeLayer() -{ - [m_captureLayer retain]; - - updateAspectRatio(); - attachNativeLayer(); -} - -void AVFCameraWindowControl::releaseNativeLayer() -{ - if (m_captureLayer) { - detachNativeLayer(); - [m_captureLayer release]; - m_captureLayer = nullptr; - } -} - -void AVFCameraWindowControl::attachNativeLayer() -{ - if (m_captureLayer && m_nativeView) { -#if defined(Q_OS_MACOS) - m_nativeView.wantsLayer = YES; -#endif - CALayer *nativeLayer = m_nativeView.layer; - [nativeLayer addSublayer:m_captureLayer]; - updateCaptureLayerBounds(); - } -} - -void AVFCameraWindowControl::detachNativeLayer() -{ - if (m_captureLayer && m_nativeView) - [m_captureLayer removeFromSuperlayer]; -} - -#include "moc_avfcamerawindowcontrol.cpp" diff --git a/src/plugins/avfoundation/camera/avfcamerazoomcontrol.h b/src/plugins/avfoundation/camera/avfcamerazoomcontrol.h deleted file mode 100644 index 2307dfc28..000000000 --- a/src/plugins/avfoundation/camera/avfcamerazoomcontrol.h +++ /dev/null @@ -1,85 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** 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$ -** -****************************************************************************/ - -#ifndef AVFCAMERAZOOMCONTROL_H -#define AVFCAMERAZOOMCONTROL_H - -#include <QtMultimedia/qcamerazoomcontrol.h> -#include <QtMultimedia/qcamera.h> - -#include <AVFoundation/AVFoundation.h> - -QT_BEGIN_NAMESPACE - -class AVFCameraService; -class AVFCameraSession; -class AVFCameraControl; - -class AVFCameraZoomControl : public QCameraZoomControl -{ - Q_OBJECT -public: - AVFCameraZoomControl(AVFCameraService *service); - - qreal maximumOpticalZoom() const override; - qreal maximumDigitalZoom() const override; - - qreal requestedOpticalZoom() const override; - qreal requestedDigitalZoom() const override; - qreal currentOpticalZoom() const override; - qreal currentDigitalZoom() const override; - - void zoomTo(qreal optical, qreal digital) override; - -private Q_SLOTS: - void cameraStateChanged(); - -private: - void zoomToRequestedDigital(); - - AVFCameraSession *m_session; - - CGFloat m_maxZoomFactor; - CGFloat m_zoomFactor; - CGFloat m_requestedZoomFactor; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/avfoundation/camera/avfcamerazoomcontrol.mm b/src/plugins/avfoundation/camera/avfcamerazoomcontrol.mm deleted file mode 100644 index 119a1fc0a..000000000 --- a/src/plugins/avfoundation/camera/avfcamerazoomcontrol.mm +++ /dev/null @@ -1,179 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** 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 "avfcamerazoomcontrol.h" -#include "avfcameraservice.h" -#include "avfcamerautility.h" -#include "avfcamerasession.h" -#include "avfcameracontrol.h" -#include "avfcameradebug.h" - -#include <QtCore/qglobal.h> -#include <QtCore/qdebug.h> - -QT_BEGIN_NAMESPACE - -AVFCameraZoomControl::AVFCameraZoomControl(AVFCameraService *service) - : m_session(service->session()), - m_maxZoomFactor(1.), - m_zoomFactor(1.), - m_requestedZoomFactor(1.) -{ - Q_ASSERT(m_session); - connect(m_session, SIGNAL(stateChanged(QCamera::State)), - SLOT(cameraStateChanged())); -} - -qreal AVFCameraZoomControl::maximumOpticalZoom() const -{ - // Not supported. - return 1.; -} - -qreal AVFCameraZoomControl::maximumDigitalZoom() const -{ - return m_maxZoomFactor; -} - -qreal AVFCameraZoomControl::requestedOpticalZoom() const -{ - // Not supported. - return 1; -} - -qreal AVFCameraZoomControl::requestedDigitalZoom() const -{ - return m_requestedZoomFactor; -} - -qreal AVFCameraZoomControl::currentOpticalZoom() const -{ - // Not supported. - return 1.; -} - -qreal AVFCameraZoomControl::currentDigitalZoom() const -{ - return m_zoomFactor; -} - -void AVFCameraZoomControl::zoomTo(qreal optical, qreal digital) -{ - Q_UNUSED(optical); - Q_UNUSED(digital); - - if (qFuzzyCompare(CGFloat(digital), m_requestedZoomFactor)) - return; - - m_requestedZoomFactor = digital; - Q_EMIT requestedDigitalZoomChanged(digital); - - zoomToRequestedDigital(); -} - -void AVFCameraZoomControl::cameraStateChanged() -{ - const QCamera::State state = m_session->state(); - if (state != QCamera::ActiveState) { - if (state == QCamera::UnloadedState && m_maxZoomFactor > 1.) { - m_maxZoomFactor = 1.; - Q_EMIT maximumDigitalZoomChanged(1.); - } - return; - } - - AVCaptureDevice *captureDevice = m_session->videoCaptureDevice(); - if (!captureDevice || !captureDevice.activeFormat) { - qDebugCamera() << Q_FUNC_INFO << "camera state is active, but" - << "video capture device and/or active format is nil"; - return; - } - - if (captureDevice.activeFormat.videoMaxZoomFactor > 1.) { - if (!qFuzzyCompare(m_maxZoomFactor, captureDevice.activeFormat.videoMaxZoomFactor)) { - m_maxZoomFactor = captureDevice.activeFormat.videoMaxZoomFactor; - Q_EMIT maximumDigitalZoomChanged(m_maxZoomFactor); - } - } else if (!qFuzzyCompare(m_maxZoomFactor, CGFloat(1.))) { - m_maxZoomFactor = 1.; - - Q_EMIT maximumDigitalZoomChanged(1.); - } - - zoomToRequestedDigital(); -} - -void AVFCameraZoomControl::zoomToRequestedDigital() -{ - AVCaptureDevice *captureDevice = m_session->videoCaptureDevice(); - if (!captureDevice || !captureDevice.activeFormat) - return; - - if (qFuzzyCompare(captureDevice.activeFormat.videoMaxZoomFactor, CGFloat(1.))) - return; - - const CGFloat clampedZoom = qBound(CGFloat(1.), m_requestedZoomFactor, - captureDevice.activeFormat.videoMaxZoomFactor); - const CGFloat deviceZoom = captureDevice.videoZoomFactor; - if (qFuzzyCompare(clampedZoom, deviceZoom)) { - // Nothing to set, but check if a signal must be emitted: - if (!qFuzzyCompare(m_zoomFactor, deviceZoom)) { - m_zoomFactor = deviceZoom; - Q_EMIT currentDigitalZoomChanged(deviceZoom); - } - return; - } - - const AVFConfigurationLock lock(captureDevice); - if (!lock) { - qDebugCamera() << Q_FUNC_INFO << "failed to lock for configuration"; - return; - } - - captureDevice.videoZoomFactor = clampedZoom; - - if (!qFuzzyCompare(clampedZoom, m_zoomFactor)) { - m_zoomFactor = clampedZoom; - Q_EMIT currentDigitalZoomChanged(clampedZoom); - } -} - -QT_END_NAMESPACE - -#include "moc_avfcamerazoomcontrol.cpp" diff --git a/src/plugins/avfoundation/camera/avfcapturedestinationcontrol.h b/src/plugins/avfoundation/camera/avfcapturedestinationcontrol.h deleted file mode 100644 index 04493437e..000000000 --- a/src/plugins/avfoundation/camera/avfcapturedestinationcontrol.h +++ /dev/null @@ -1,63 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** 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$ -** -****************************************************************************/ - -#ifndef AVFCAPTUREDESTINATIONCONTROL_H -#define AVFCAPTUREDESTINATIONCONTROL_H - -#include <qcameracapturedestinationcontrol.h> - -QT_BEGIN_NAMESPACE - -class AVFCaptureDestinationControl : public QCameraCaptureDestinationControl -{ -public: - AVFCaptureDestinationControl() = default; - ~AVFCaptureDestinationControl() = default; - - bool isCaptureDestinationSupported(QCameraImageCapture::CaptureDestinations destination) const override; - QCameraImageCapture::CaptureDestinations captureDestination() const override; - void setCaptureDestination(QCameraImageCapture::CaptureDestinations destination) override; - -private: - QCameraImageCapture::CaptureDestinations m_destination = QCameraImageCapture::CaptureToFile; -}; - -QT_END_NAMESPACE - -#endif // AVFCAPTUREDESTINATIONCONTROL_H diff --git a/src/plugins/avfoundation/camera/avfcapturedestinationcontrol.mm b/src/plugins/avfoundation/camera/avfcapturedestinationcontrol.mm deleted file mode 100644 index d0700d69d..000000000 --- a/src/plugins/avfoundation/camera/avfcapturedestinationcontrol.mm +++ /dev/null @@ -1,62 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** 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 "avfcapturedestinationcontrol.h" - -QT_BEGIN_NAMESPACE - -bool AVFCaptureDestinationControl::isCaptureDestinationSupported(QCameraImageCapture::CaptureDestinations destination) const -{ - return destination & (QCameraImageCapture::CaptureToFile | QCameraImageCapture::CaptureToBuffer); -} - -QCameraImageCapture::CaptureDestinations AVFCaptureDestinationControl::captureDestination() const -{ - return m_destination; -} - -void AVFCaptureDestinationControl::setCaptureDestination(QCameraImageCapture::CaptureDestinations destination) -{ - if (m_destination != destination) { - m_destination = destination; - Q_EMIT captureDestinationChanged(m_destination); - } -} - -QT_END_NAMESPACE diff --git a/src/plugins/avfoundation/camera/avfimagecapturecontrol.h b/src/plugins/avfoundation/camera/avfimagecapturecontrol.h deleted file mode 100644 index 314e867e7..000000000 --- a/src/plugins/avfoundation/camera/avfimagecapturecontrol.h +++ /dev/null @@ -1,100 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** 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$ -** -****************************************************************************/ - -#ifndef AVFIMAGECAPTURECONTROL_H -#define AVFIMAGECAPTURECONTROL_H - -#import <AVFoundation/AVFoundation.h> - -#include <QtCore/qqueue.h> -#include <QtCore/qsemaphore.h> -#include <QtCore/qsharedpointer.h> -#include <QtMultimedia/qcameraimagecapturecontrol.h> -#include "avfcamerasession.h" -#include "avfstoragelocation.h" - -QT_BEGIN_NAMESPACE - -class AVFImageCaptureControl : public QCameraImageCaptureControl -{ -Q_OBJECT -public: - struct CaptureRequest { - int captureId; - QSharedPointer<QSemaphore> previewReady; - }; - - AVFImageCaptureControl(AVFCameraService *service, QObject *parent = nullptr); - ~AVFImageCaptureControl(); - - bool isReadyForCapture() const override; - - QCameraImageCapture::DriveMode driveMode() const override { return QCameraImageCapture::SingleImageCapture; } - void setDriveMode(QCameraImageCapture::DriveMode ) override {} - AVCaptureStillImageOutput *stillImageOutput() const {return m_stillImageOutput;} - - int capture(const QString &fileName) override; - void cancelCapture() override; - -private Q_SLOTS: - void updateCaptureConnection(); - void updateReadyStatus(); - void onNewViewfinderFrame(const QVideoFrame &frame); - -private: - void makeCapturePreview(CaptureRequest request, const QVideoFrame &frame, int rotation); - - AVFCameraService *m_service; - AVFCameraSession *m_session; - AVFCameraControl *m_cameraControl; - bool m_ready; - int m_lastCaptureId; - AVCaptureStillImageOutput *m_stillImageOutput; - AVCaptureConnection *m_videoConnection; - AVFStorageLocation m_storageLocation; - - QMutex m_requestsMutex; - QQueue<CaptureRequest> m_captureRequests; -}; - -Q_DECLARE_TYPEINFO(AVFImageCaptureControl::CaptureRequest, Q_PRIMITIVE_TYPE); - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/avfoundation/camera/avfimagecapturecontrol.mm b/src/plugins/avfoundation/camera/avfimagecapturecontrol.mm deleted file mode 100644 index f2c019fdc..000000000 --- a/src/plugins/avfoundation/camera/avfimagecapturecontrol.mm +++ /dev/null @@ -1,266 +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 "avfcameradebug.h" -#include "avfimagecapturecontrol.h" -#include "avfcameraservice.h" -#include "avfcamerautility.h" -#include "avfcameracontrol.h" -#include "avfcapturedestinationcontrol.h" -#include <private/qmemoryvideobuffer_p.h> - -#include <QtCore/qurl.h> -#include <QtCore/qfile.h> -#include <QtCore/qbuffer.h> -#include <QtConcurrent/qtconcurrentrun.h> -#include <QtGui/qimagereader.h> - -QT_USE_NAMESPACE - -AVFImageCaptureControl::AVFImageCaptureControl(AVFCameraService *service, QObject *parent) - : QCameraImageCaptureControl(parent) - , m_service(service) - , m_session(service->session()) - , m_cameraControl(service->cameraControl()) - , m_ready(false) - , m_lastCaptureId(0) - , m_videoConnection(nil) -{ - Q_UNUSED(service); - m_stillImageOutput = [[AVCaptureStillImageOutput alloc] init]; - - NSDictionary *outputSettings = [[NSDictionary alloc] initWithObjectsAndKeys: - AVVideoCodecJPEG, AVVideoCodecKey, nil]; - - [m_stillImageOutput setOutputSettings:outputSettings]; - [outputSettings release]; - connect(m_cameraControl, SIGNAL(captureModeChanged(QCamera::CaptureModes)), SLOT(updateReadyStatus())); - connect(m_cameraControl, SIGNAL(statusChanged(QCamera::Status)), SLOT(updateReadyStatus())); - - connect(m_session, SIGNAL(readyToConfigureConnections()), SLOT(updateCaptureConnection())); - connect(m_cameraControl, SIGNAL(captureModeChanged(QCamera::CaptureModes)), SLOT(updateCaptureConnection())); - - connect(m_session, &AVFCameraSession::newViewfinderFrame, - this, &AVFImageCaptureControl::onNewViewfinderFrame, - Qt::DirectConnection); -} - -AVFImageCaptureControl::~AVFImageCaptureControl() -{ -} - -bool AVFImageCaptureControl::isReadyForCapture() const -{ - return m_videoConnection && - m_cameraControl->captureMode().testFlag(QCamera::CaptureStillImage) && - m_cameraControl->status() == QCamera::ActiveStatus; -} - -void AVFImageCaptureControl::updateReadyStatus() -{ - if (m_ready != isReadyForCapture()) { - m_ready = !m_ready; - qDebugCamera() << "ReadyToCapture status changed:" << m_ready; - Q_EMIT readyForCaptureChanged(m_ready); - } -} - -int AVFImageCaptureControl::capture(const QString &fileName) -{ - m_lastCaptureId++; - - if (!isReadyForCapture()) { - QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection, - Q_ARG(int, m_lastCaptureId), - Q_ARG(int, QCameraImageCapture::NotReadyError), - Q_ARG(QString, tr("Camera not ready"))); - return m_lastCaptureId; - } - - auto destination = m_service->captureDestinationControl()->captureDestination(); - QString actualFileName; - if (destination & QCameraImageCapture::CaptureToFile) { - actualFileName = m_storageLocation.generateFileName(fileName, - QCamera::CaptureStillImage, - QLatin1String("img_"), - QLatin1String("jpg")); - - qDebugCamera() << "Capture image to" << actualFileName; - } - - CaptureRequest request = { m_lastCaptureId, QSharedPointer<QSemaphore>::create()}; - m_requestsMutex.lock(); - m_captureRequests.enqueue(request); - m_requestsMutex.unlock(); - - [m_stillImageOutput captureStillImageAsynchronouslyFromConnection:m_videoConnection - completionHandler: ^(CMSampleBufferRef imageSampleBuffer, NSError *error) { - - if (error) { - QStringList messageParts; - messageParts << QString::fromUtf8([[error localizedDescription] UTF8String]); - messageParts << QString::fromUtf8([[error localizedFailureReason] UTF8String]); - messageParts << QString::fromUtf8([[error localizedRecoverySuggestion] UTF8String]); - - QString errorMessage = messageParts.join(" "); - qDebugCamera() << "Image capture failed:" << errorMessage; - - QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection, - Q_ARG(int, request.captureId), - Q_ARG(int, QCameraImageCapture::ResourceError), - Q_ARG(QString, errorMessage)); - return; - } - - // Wait for the preview to be generated before saving the JPEG (but only - // if we have AVFCameraRendererControl attached). - // It is possible to stop camera immediately after trying to capture an - // image; this can result in a blocked callback's thread, waiting for a - // new viewfinder's frame to arrive/semaphore to be released. It is also - // unspecified on which thread this callback gets executed, (probably it's - // not the same thread that initiated a capture and stopped the camera), - // so we cannot reliably check the camera's status. Instead, we wait - // with a timeout and treat a failure to acquire a semaphore as an error. - if (!m_service->videoOutput() || request.previewReady->tryAcquire(1, 1000)) { - qDebugCamera() << "Image capture completed"; - - NSData *nsJpgData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageSampleBuffer]; - QByteArray jpgData = QByteArray::fromRawData((const char *)[nsJpgData bytes], [nsJpgData length]); - - if (destination & QCameraImageCapture::CaptureToBuffer) { - QBuffer data(&jpgData); - QImageReader reader(&data, "JPEG"); - QSize size = reader.size(); - QVideoFrame frame(new QMemoryVideoBuffer(QByteArray(jpgData.constData(), jpgData.size()), -1), size, QVideoFrame::Format_Jpeg); - QMetaObject::invokeMethod(this, "imageAvailable", Qt::QueuedConnection, - Q_ARG(int, request.captureId), - Q_ARG(QVideoFrame, frame)); - } - - if (!(destination & QCameraImageCapture::CaptureToFile)) - return; - - QFile f(actualFileName); - if (f.open(QFile::WriteOnly)) { - if (f.write(jpgData) != -1) { - QMetaObject::invokeMethod(this, "imageSaved", Qt::QueuedConnection, - Q_ARG(int, request.captureId), - Q_ARG(QString, actualFileName)); - } else { - QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection, - Q_ARG(int, request.captureId), - Q_ARG(int, QCameraImageCapture::OutOfSpaceError), - Q_ARG(QString, f.errorString())); - } - } else { - QString errorMessage = tr("Could not open destination file:\n%1").arg(actualFileName); - QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection, - Q_ARG(int, request.captureId), - Q_ARG(int, QCameraImageCapture::ResourceError), - Q_ARG(QString, errorMessage)); - } - } else { - const QLatin1String errorMessage("Image capture failed: timed out waiting" - " for a preview frame."); - qDebugCamera() << errorMessage; - QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection, - Q_ARG(int, request.captureId), - Q_ARG(int, QCameraImageCapture::ResourceError), - Q_ARG(QString, errorMessage)); - } - }]; - - return request.captureId; -} - -void AVFImageCaptureControl::onNewViewfinderFrame(const QVideoFrame &frame) -{ - QMutexLocker locker(&m_requestsMutex); - - if (m_captureRequests.isEmpty()) - return; - - CaptureRequest request = m_captureRequests.dequeue(); - Q_EMIT imageExposed(request.captureId); - - QtConcurrent::run(&AVFImageCaptureControl::makeCapturePreview, this, - request, - frame, - 0 /* rotation */); -} - -void AVFImageCaptureControl::makeCapturePreview(CaptureRequest request, - const QVideoFrame &frame, - int rotation) -{ - QTransform transform; - transform.rotate(rotation); - - Q_EMIT imageCaptured(request.captureId, frame.image().transformed(transform)); - - request.previewReady->release(); -} - -void AVFImageCaptureControl::cancelCapture() -{ - //not supported -} - -void AVFImageCaptureControl::updateCaptureConnection() -{ - if (m_session->videoCaptureDevice() - && m_cameraControl->captureMode().testFlag(QCamera::CaptureStillImage)) { - qDebugCamera() << Q_FUNC_INFO; - AVCaptureSession *captureSession = m_session->captureSession(); - - if (![captureSession.outputs containsObject:m_stillImageOutput]) { - if ([captureSession canAddOutput:m_stillImageOutput]) { - // Lock the video capture device to make sure the active format is not reset - const AVFConfigurationLock lock(m_session->videoCaptureDevice()); - [captureSession addOutput:m_stillImageOutput]; - m_videoConnection = [m_stillImageOutput connectionWithMediaType:AVMediaTypeVideo]; - updateReadyStatus(); - } - } else { - m_videoConnection = [m_stillImageOutput connectionWithMediaType:AVMediaTypeVideo]; - } - } -} - -#include "moc_avfimagecapturecontrol.cpp" diff --git a/src/plugins/avfoundation/camera/avfimageencodercontrol.h b/src/plugins/avfoundation/camera/avfimageencodercontrol.h deleted file mode 100644 index 7e2e34294..000000000 --- a/src/plugins/avfoundation/camera/avfimageencodercontrol.h +++ /dev/null @@ -1,85 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** 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$ -** -****************************************************************************/ - -#ifndef AVFIMAGEENCODERCONTROL_H -#define AVFIMAGEENCODERCONTROL_H - -#include <QtMultimedia/qmediaencodersettings.h> -#include <QtMultimedia/qimageencodercontrol.h> - -#include <QtCore/qglobal.h> -#include <QtCore/qstring.h> -#include <QtCore/qlist.h> - -@class AVCaptureDeviceFormat; - -QT_BEGIN_NAMESPACE - -class AVFCameraService; - -class AVFImageEncoderControl : public QImageEncoderControl -{ - Q_OBJECT - - friend class AVFCameraSession; -public: - AVFImageEncoderControl(AVFCameraService *service); - - QStringList supportedImageCodecs() const override; - QString imageCodecDescription(const QString &codecName) const override; - QList<QSize> supportedResolutions(const QImageEncoderSettings &settings, - bool *continuous) const override; - QImageEncoderSettings imageSettings() const override; - void setImageSettings(const QImageEncoderSettings &settings) override; - - QImageEncoderSettings requestedSettings() const; - -private: - AVFCameraService *m_service; - QImageEncoderSettings m_settings; - - bool applySettings(); - bool videoCaptureDeviceIsValid() const; -}; - -QSize qt_image_high_resolution(AVCaptureDeviceFormat *fomat); - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/avfoundation/camera/avfimageencodercontrol.mm b/src/plugins/avfoundation/camera/avfimageencodercontrol.mm deleted file mode 100644 index 93de3e63c..000000000 --- a/src/plugins/avfoundation/camera/avfimageencodercontrol.mm +++ /dev/null @@ -1,240 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** 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 "avfcameraviewfindersettingscontrol.h" -#include "avfimageencodercontrol.h" -#include "avfimagecapturecontrol.h" -#include "avfcamerautility.h" -#include "avfcamerasession.h" -#include "avfcameraservice.h" -#include "avfcameradebug.h" -#include "avfcameracontrol.h" - -#include <QtMultimedia/qmediaencodersettings.h> - -#include <QtCore/qdebug.h> - -#include <AVFoundation/AVFoundation.h> - -QT_BEGIN_NAMESPACE - -AVFImageEncoderControl::AVFImageEncoderControl(AVFCameraService *service) - : m_service(service) -{ - Q_ASSERT(service); -} - -QStringList AVFImageEncoderControl::supportedImageCodecs() const -{ - return QStringList() << QLatin1String("jpeg"); -} - -QString AVFImageEncoderControl::imageCodecDescription(const QString &codecName) const -{ - if (codecName == QLatin1String("jpeg")) - return tr("JPEG image"); - - return QString(); -} - -QList<QSize> AVFImageEncoderControl::supportedResolutions(const QImageEncoderSettings &settings, - bool *continuous) const -{ - Q_UNUSED(settings); - - QList<QSize> resolutions; - - if (!videoCaptureDeviceIsValid()) - return resolutions; - - AVCaptureDevice *captureDevice = m_service->session()->videoCaptureDevice(); - const QVector<AVCaptureDeviceFormat *> formats(qt_unique_device_formats(captureDevice, - m_service->session()->defaultCodec())); - - for (int i = 0; i < formats.size(); ++i) { - AVCaptureDeviceFormat *format = formats[i]; - - const QSize res(qt_device_format_resolution(format)); - if (!res.isNull() && res.isValid()) - resolutions << res; -#ifdef Q_OS_IOS - // From Apple's docs (iOS): - // By default, AVCaptureStillImageOutput emits images with the same dimensions as - // its source AVCaptureDevice instance’s activeFormat.formatDescription. However, - // if you set this property to YES, the receiver emits still images at the capture - // device’s highResolutionStillImageDimensions value. - const QSize hrRes(qt_device_format_high_resolution(format)); - if (!hrRes.isNull() && hrRes.isValid()) - resolutions << res; -#endif - } - - if (continuous) - *continuous = false; - - return resolutions; -} - -QImageEncoderSettings AVFImageEncoderControl::requestedSettings() const -{ - return m_settings; -} - -QImageEncoderSettings AVFImageEncoderControl::imageSettings() const -{ - QImageEncoderSettings settings; - - if (!videoCaptureDeviceIsValid()) - return settings; - - AVCaptureDevice *captureDevice = m_service->session()->videoCaptureDevice(); - if (!captureDevice.activeFormat) { - qDebugCamera() << Q_FUNC_INFO << "no active format"; - return settings; - } - - QSize res(qt_device_format_resolution(captureDevice.activeFormat)); -#ifdef Q_OS_IOS - if (!m_service->imageCaptureControl() || !m_service->imageCaptureControl()->stillImageOutput()) { - qDebugCamera() << Q_FUNC_INFO << "no still image output"; - return settings; - } - - AVCaptureStillImageOutput *stillImageOutput = m_service->imageCaptureControl()->stillImageOutput(); - if (stillImageOutput.highResolutionStillImageOutputEnabled) - res = qt_device_format_high_resolution(captureDevice.activeFormat); -#endif - if (res.isNull() || !res.isValid()) { - qDebugCamera() << Q_FUNC_INFO << "failed to exctract the image resolution"; - return settings; - } - - settings.setResolution(res); - - settings.setCodec(QLatin1String("jpeg")); - - return settings; -} - -void AVFImageEncoderControl::setImageSettings(const QImageEncoderSettings &settings) -{ - if (m_settings == settings) - return; - - m_settings = settings; - applySettings(); -} - -bool AVFImageEncoderControl::applySettings() -{ - if (!videoCaptureDeviceIsValid()) - return false; - - AVFCameraSession *session = m_service->session(); - if (!session || (session->state() != QCamera::ActiveState - && session->state() != QCamera::LoadedState) - || !m_service->cameraControl()->captureMode().testFlag(QCamera::CaptureStillImage)) { - return false; - } - - if (!m_service->imageCaptureControl() - || !m_service->imageCaptureControl()->stillImageOutput()) { - qDebugCamera() << Q_FUNC_INFO << "no still image output"; - return false; - } - - if (m_settings.codec().size() - && m_settings.codec() != QLatin1String("jpeg")) { - qDebugCamera() << Q_FUNC_INFO << "unsupported codec:" << m_settings.codec(); - return false; - } - - QSize res(m_settings.resolution()); - if (res.isNull()) { - qDebugCamera() << Q_FUNC_INFO << "invalid resolution:" << res; - return false; - } - - if (!res.isValid()) { - // Invalid == default value. - // Here we could choose the best format available, but - // activeFormat is already equal to 'preset high' by default, - // which is good enough, otherwise we can end in some format with low framerates. - return false; - } - - bool activeFormatChanged = false; - - AVCaptureDevice *captureDevice = m_service->session()->videoCaptureDevice(); - AVCaptureDeviceFormat *match = qt_find_best_resolution_match(captureDevice, res, - m_service->session()->defaultCodec()); - - if (!match) { - qDebugCamera() << Q_FUNC_INFO << "unsupported resolution:" << res; - return false; - } - - activeFormatChanged = qt_set_active_format(captureDevice, match, true); - -#ifdef Q_OS_IOS - AVCaptureStillImageOutput *imageOutput = m_service->imageCaptureControl()->stillImageOutput(); - if (res == qt_device_format_high_resolution(captureDevice.activeFormat)) - imageOutput.highResolutionStillImageOutputEnabled = YES; - else - imageOutput.highResolutionStillImageOutputEnabled = NO; -#endif - - return activeFormatChanged; -} - -bool AVFImageEncoderControl::videoCaptureDeviceIsValid() const -{ - if (!m_service->session() || !m_service->session()->videoCaptureDevice()) - return false; - - AVCaptureDevice *captureDevice = m_service->session()->videoCaptureDevice(); - if (!captureDevice.formats || !captureDevice.formats.count) - return false; - - return true; -} - -QT_END_NAMESPACE - -#include "moc_avfimageencodercontrol.cpp" diff --git a/src/plugins/avfoundation/camera/avfmediaassetwriter.h b/src/plugins/avfoundation/camera/avfmediaassetwriter.h deleted file mode 100644 index f063dab4b..000000000 --- a/src/plugins/avfoundation/camera/avfmediaassetwriter.h +++ /dev/null @@ -1,75 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** 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$ -** -****************************************************************************/ - -#ifndef AVFMEDIAASSETWRITER_H -#define AVFMEDIAASSETWRITER_H - -#include "avfcamerautility.h" - -#include <QtCore/qglobal.h> - -#include <AVFoundation/AVFoundation.h> - -QT_BEGIN_NAMESPACE - -class AVFMediaRecorderControlIOS; -class AVFCameraService; - -QT_END_NAMESPACE - -@interface QT_MANGLE_NAMESPACE(AVFMediaAssetWriter) : NSObject<AVCaptureVideoDataOutputSampleBufferDelegate, - AVCaptureAudioDataOutputSampleBufferDelegate> -- (id)initWithDelegate:(QT_PREPEND_NAMESPACE(AVFMediaRecorderControlIOS) *)delegate; - -- (bool)setupWithFileURL:(NSURL *)fileURL - cameraService:(QT_PREPEND_NAMESPACE(AVFCameraService) *)service - audioSettings:(NSDictionary *)audioSettings - videoSettings:(NSDictionary *)videoSettings - transform:(CGAffineTransform)transform; - -// This to be called from the recorder control's thread: -- (void)start; -- (void)stop; -// This to be called from the recorder control's dtor: -- (void)abort; -- (qint64)durationInMs; - -@end - -#endif // AVFMEDIAASSETWRITER_H diff --git a/src/plugins/avfoundation/camera/avfmediaassetwriter.mm b/src/plugins/avfoundation/camera/avfmediaassetwriter.mm deleted file mode 100644 index 57c5cb8c5..000000000 --- a/src/plugins/avfoundation/camera/avfmediaassetwriter.mm +++ /dev/null @@ -1,514 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** 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 "avfaudioinputselectorcontrol.h" -#include "avfmediarecordercontrol_ios.h" -#include "avfcamerarenderercontrol.h" -#include "avfmediaassetwriter.h" -#include "avfcameraservice.h" -#include "avfcamerasession.h" -#include "avfcameradebug.h" -#include "avfmediacontainercontrol.h" - -#include <QtCore/qmetaobject.h> -#include <QtCore/qatomic.h> - -QT_USE_NAMESPACE - -namespace { - -bool qt_camera_service_isValid(AVFCameraService *service) -{ - if (!service || !service->session()) - return false; - - AVFCameraSession *session = service->session(); - if (!session->captureSession()) - return false; - - if (!session->videoInput()) - return false; - - if (!service->videoOutput() - || !service->videoOutput()->videoDataOutput()) { - return false; - } - - return true; -} - -enum WriterState -{ - WriterStateIdle, - WriterStateActive, - WriterStateAborted -}; - -using AVFAtomicInt64 = QAtomicInteger<qint64>; - -} // unnamed namespace - -@interface QT_MANGLE_NAMESPACE(AVFMediaAssetWriter) (PrivateAPI) -- (bool)addAudioCapture; -- (bool)addWriterInputs; -- (void)setQueues; -- (void)updateDuration:(CMTime)newTimeStamp; -@end - -@implementation QT_MANGLE_NAMESPACE(AVFMediaAssetWriter) -{ -@private - AVFCameraService *m_service; - - AVFScopedPointer<AVAssetWriterInput> m_cameraWriterInput; - AVFScopedPointer<AVCaptureDeviceInput> m_audioInput; - AVFScopedPointer<AVCaptureAudioDataOutput> m_audioOutput; - AVFScopedPointer<AVAssetWriterInput> m_audioWriterInput; - - AVCaptureDevice *m_audioCaptureDevice; - - // Queue to write sample buffers: - AVFScopedPointer<dispatch_queue_t> m_writerQueue; - // High priority serial queue for video output: - AVFScopedPointer<dispatch_queue_t> m_videoQueue; - // Serial queue for audio output: - AVFScopedPointer<dispatch_queue_t> m_audioQueue; - - AVFScopedPointer<AVAssetWriter> m_assetWriter; - - AVFMediaRecorderControlIOS *m_delegate; - - bool m_setStartTime; - - QAtomicInt m_state; - - CMTime m_startTime; - CMTime m_lastTimeStamp; - - NSDictionary *m_audioSettings; - NSDictionary *m_videoSettings; - - AVFAtomicInt64 m_durationInMs; -} - -- (id)initWithDelegate:(AVFMediaRecorderControlIOS *)delegate -{ - Q_ASSERT(delegate); - - if (self = [super init]) { - m_delegate = delegate; - m_setStartTime = true; - m_state.storeRelaxed(WriterStateIdle); - m_startTime = kCMTimeInvalid; - m_lastTimeStamp = kCMTimeInvalid; - m_durationInMs.storeRelaxed(0); - m_audioSettings = nil; - m_videoSettings = nil; - } - - return self; -} - -- (bool)setupWithFileURL:(NSURL *)fileURL - cameraService:(AVFCameraService *)service - audioSettings:(NSDictionary *)audioSettings - videoSettings:(NSDictionary *)videoSettings - transform:(CGAffineTransform)transform -{ - Q_ASSERT(fileURL); - - if (!qt_camera_service_isValid(service)) { - qDebugCamera() << Q_FUNC_INFO << "invalid camera service"; - return false; - } - - m_service = service; - m_audioSettings = audioSettings; - m_videoSettings = videoSettings; - - m_writerQueue.reset(dispatch_queue_create("asset-writer-queue", DISPATCH_QUEUE_SERIAL)); - if (!m_writerQueue) { - qDebugCamera() << Q_FUNC_INFO << "failed to create an asset writer's queue"; - return false; - } - - m_videoQueue.reset(dispatch_queue_create("video-output-queue", DISPATCH_QUEUE_SERIAL)); - if (!m_videoQueue) { - qDebugCamera() << Q_FUNC_INFO << "failed to create video queue"; - return false; - } - dispatch_set_target_queue(m_videoQueue, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 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"; - // But we still can write video! - } - - m_assetWriter.reset([[AVAssetWriter alloc] initWithURL:fileURL - fileType:m_service->mediaContainerControl()->fileType() - error:nil]); - if (!m_assetWriter) { - qDebugCamera() << Q_FUNC_INFO << "failed to create asset writer"; - return false; - } - - bool audioCaptureOn = false; - - if (m_audioQueue) - audioCaptureOn = [self addAudioCapture]; - - if (![self addWriterInputs]) { - if (audioCaptureOn) { - AVCaptureSession *session = m_service->session()->captureSession(); - [session removeOutput:m_audioOutput]; - [session removeInput:m_audioInput]; - m_audioOutput.reset(); - m_audioInput.reset(); - m_audioCaptureDevice = 0; - } - m_assetWriter.reset(); - return false; - } - - m_cameraWriterInput.data().transform = transform; - - // Ready to start ... - return true; -} - -- (void)start -{ - [self setQueues]; - - m_setStartTime = true; - - m_state.storeRelease(WriterStateActive); - - [m_assetWriter startWriting]; - AVCaptureSession *session = m_service->session()->captureSession(); - if (!session.running) - [session startRunning]; -} - -- (void)stop -{ - if (m_state.loadAcquire() != WriterStateActive) - return; - - if ([m_assetWriter status] != AVAssetWriterStatusWriting) - return; - - // Do this here so that - - // 1. '-abort' should not try calling finishWriting again and - // 2. async block (see below) will know if recorder control was deleted - // before the block's execution: - m_state.storeRelease(WriterStateIdle); - // Now, since we have to ensure no sample buffers are - // appended after a call to finishWriting, we must - // ensure writer's queue sees this change in m_state - // _before_ we call finishWriting: - dispatch_sync(m_writerQueue, ^{}); - // Done, but now we also want to prevent video queue - // from updating our viewfinder: - dispatch_sync(m_videoQueue, ^{}); - - // Now we're safe to stop: - [m_assetWriter finishWritingWithCompletionHandler:^{ - // This block is async, so by the time it's executed, - // it's possible that render control was deleted already ... - if (m_state.loadAcquire() == WriterStateAborted) - return; - - AVCaptureSession *session = m_service->session()->captureSession(); - if (session.running) - [session stopRunning]; - [session removeOutput:m_audioOutput]; - [session removeInput:m_audioInput]; - QMetaObject::invokeMethod(m_delegate, "assetWriterFinished", Qt::QueuedConnection); - }]; -} - -- (void)abort -{ - // -abort is to be called from recorder control's dtor. - - if (m_state.fetchAndStoreRelease(WriterStateAborted) != WriterStateActive) { - // Not recording, nothing to stop. - return; - } - - // From Apple's docs: - // "To guarantee that all sample buffers are successfully written, - // you must ensure that all calls to appendSampleBuffer: and - // appendPixelBuffer:withPresentationTime: have returned before - // invoking this method." - // - // The only way we can ensure this is: - dispatch_sync(m_writerQueue, ^{}); - // At this point next block (if any) on the writer's queue - // will see m_state preventing it from any further processing. - dispatch_sync(m_videoQueue, ^{}); - // After this point video queue will not try to modify our - // viewfider, so we're safe to delete now. - - [m_assetWriter finishWritingWithCompletionHandler:^{ - }]; -} - -- (void)setStartTimeFrom:(CMSampleBufferRef)sampleBuffer -{ - // Writer's queue only. - Q_ASSERT(m_setStartTime); - Q_ASSERT(sampleBuffer); - - if (m_state.loadAcquire() != WriterStateActive) - return; - - QMetaObject::invokeMethod(m_delegate, "assetWriterStarted", Qt::QueuedConnection); - - m_durationInMs.storeRelease(0); - m_startTime = CMSampleBufferGetPresentationTimeStamp(sampleBuffer); - m_lastTimeStamp = m_startTime; - [m_assetWriter startSessionAtSourceTime:m_startTime]; - m_setStartTime = false; -} - -- (void)writeVideoSampleBuffer:(CMSampleBufferRef)sampleBuffer -{ - // This code is executed only on a writer's queue. - Q_ASSERT(sampleBuffer); - - if (m_state.loadAcquire() == WriterStateActive) { - if (m_setStartTime) - [self setStartTimeFrom:sampleBuffer]; - - if (m_cameraWriterInput.data().readyForMoreMediaData) { - [self updateDuration:CMSampleBufferGetPresentationTimeStamp(sampleBuffer)]; - [m_cameraWriterInput appendSampleBuffer:sampleBuffer]; - } - } - - CFRelease(sampleBuffer); -} - -- (void)writeAudioSampleBuffer:(CMSampleBufferRef)sampleBuffer -{ - Q_ASSERT(sampleBuffer); - - // This code is executed only on a writer's queue. - if (m_state.loadAcquire() == WriterStateActive) { - if (m_setStartTime) - [self setStartTimeFrom:sampleBuffer]; - - if (m_audioWriterInput.data().readyForMoreMediaData) { - [self updateDuration:CMSampleBufferGetPresentationTimeStamp(sampleBuffer)]; - [m_audioWriterInput appendSampleBuffer:sampleBuffer]; - } - } - - CFRelease(sampleBuffer); -} - -- (void)captureOutput:(AVCaptureOutput *)captureOutput - didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer - fromConnection:(AVCaptureConnection *)connection -{ - Q_UNUSED(connection); - - if (m_state.loadAcquire() != WriterStateActive) - return; - - if (!CMSampleBufferDataIsReady(sampleBuffer)) { - qDebugCamera() << Q_FUNC_INFO << "sample buffer is not ready, skipping."; - return; - } - - CFRetain(sampleBuffer); - - if (captureOutput != m_audioOutput.data()) { - if (m_state.loadRelaxed() != WriterStateActive) { - CFRelease(sampleBuffer); - return; - } - // Find renderercontrol's delegate and invoke its method to - // show updated viewfinder's frame. - if (m_service && m_service->videoOutput()) { - NSObject<AVCaptureVideoDataOutputSampleBufferDelegate> *vfDelegate = - (NSObject<AVCaptureVideoDataOutputSampleBufferDelegate> *)m_service->videoOutput()->captureDelegate(); - if (vfDelegate) - [vfDelegate captureOutput:nil didOutputSampleBuffer:sampleBuffer fromConnection:nil]; - } - - dispatch_async(m_writerQueue, ^{ - [self writeVideoSampleBuffer:sampleBuffer]; - }); - } else { - dispatch_async(m_writerQueue, ^{ - [self writeAudioSampleBuffer:sampleBuffer]; - }); - } -} - -- (bool)addAudioCapture -{ - Q_ASSERT(m_service && m_service->session() && m_service->session()->captureSession()); - - if (!m_service->audioInputSelectorControl()) - return false; - - AVCaptureSession *captureSession = m_service->session()->captureSession(); - - m_audioCaptureDevice = m_service->audioInputSelectorControl()->createCaptureDevice(); - if (!m_audioCaptureDevice) { - qWarning() << Q_FUNC_INFO << "no audio input device available"; - return false; - } else { - NSError *error = nil; - m_audioInput.reset([[AVCaptureDeviceInput deviceInputWithDevice:m_audioCaptureDevice error:&error] retain]); - - if (!m_audioInput || error) { - qWarning() << Q_FUNC_INFO << "failed to create audio device input"; - m_audioCaptureDevice = 0; - m_audioInput.reset(); - return false; - } else if (![captureSession canAddInput:m_audioInput]) { - qWarning() << Q_FUNC_INFO << "could not connect the audio input"; - m_audioCaptureDevice = 0; - m_audioInput.reset(); - return false; - } else { - [captureSession addInput:m_audioInput]; - } - } - - - m_audioOutput.reset([[AVCaptureAudioDataOutput alloc] init]); - if (m_audioOutput.data() && [captureSession canAddOutput:m_audioOutput]) { - [captureSession addOutput:m_audioOutput]; - } else { - qDebugCamera() << Q_FUNC_INFO << "failed to add audio output"; - [captureSession removeInput:m_audioInput]; - m_audioCaptureDevice = 0; - m_audioInput.reset(); - m_audioOutput.reset(); - return false; - } - - return true; -} - -- (bool)addWriterInputs -{ - Q_ASSERT(m_service && m_service->videoOutput() - && m_service->videoOutput()->videoDataOutput()); - Q_ASSERT(m_assetWriter.data()); - - m_cameraWriterInput.reset([[AVAssetWriterInput alloc] initWithMediaType:AVMediaTypeVideo - outputSettings:m_videoSettings - sourceFormatHint:m_service->session()->videoCaptureDevice().activeFormat.formatDescription]); - if (!m_cameraWriterInput) { - qDebugCamera() << Q_FUNC_INFO << "failed to create camera writer input"; - return false; - } - - if ([m_assetWriter canAddInput:m_cameraWriterInput]) { - [m_assetWriter addInput:m_cameraWriterInput]; - } else { - qDebugCamera() << Q_FUNC_INFO << "failed to add camera writer input"; - m_cameraWriterInput.reset(); - return false; - } - - m_cameraWriterInput.data().expectsMediaDataInRealTime = YES; - - if (m_audioOutput.data()) { - CMFormatDescriptionRef sourceFormat = m_audioCaptureDevice ? m_audioCaptureDevice.activeFormat.formatDescription : 0; - m_audioWriterInput.reset([[AVAssetWriterInput alloc] initWithMediaType:AVMediaTypeAudio - outputSettings:m_audioSettings - sourceFormatHint:sourceFormat]); - if (!m_audioWriterInput) { - qDebugCamera() << Q_FUNC_INFO << "failed to create audio writer input"; - // But we still can record video. - } else if ([m_assetWriter canAddInput:m_audioWriterInput]) { - [m_assetWriter addInput:m_audioWriterInput]; - m_audioWriterInput.data().expectsMediaDataInRealTime = YES; - } else { - qDebugCamera() << Q_FUNC_INFO << "failed to add audio writer input"; - m_audioWriterInput.reset(); - // We can (still) write video though ... - } - } - - return true; -} - -- (void)setQueues -{ - Q_ASSERT(m_service && m_service->videoOutput() && m_service->videoOutput()->videoDataOutput()); - Q_ASSERT(m_videoQueue); - - [m_service->videoOutput()->videoDataOutput() setSampleBufferDelegate:self queue:m_videoQueue]; - - if (m_audioOutput.data()) { - Q_ASSERT(m_audioQueue); - [m_audioOutput setSampleBufferDelegate:self queue:m_audioQueue]; - } -} - -- (void)updateDuration:(CMTime)newTimeStamp -{ - Q_ASSERT(CMTimeCompare(m_startTime, kCMTimeInvalid)); - Q_ASSERT(CMTimeCompare(m_lastTimeStamp, kCMTimeInvalid)); - if (CMTimeCompare(newTimeStamp, m_lastTimeStamp) > 0) { - - const CMTime duration = CMTimeSubtract(newTimeStamp, m_startTime); - if (!CMTimeCompare(duration, kCMTimeInvalid)) - return; - - m_durationInMs.storeRelease(CMTimeGetSeconds(duration) * 1000); - m_lastTimeStamp = newTimeStamp; - } -} - -- (qint64)durationInMs -{ - return m_durationInMs.loadAcquire(); -} - -@end diff --git a/src/plugins/avfoundation/camera/avfmediacontainercontrol.h b/src/plugins/avfoundation/camera/avfmediacontainercontrol.h deleted file mode 100644 index e43e70baf..000000000 --- a/src/plugins/avfoundation/camera/avfmediacontainercontrol.h +++ /dev/null @@ -1,69 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** 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$ -** -****************************************************************************/ - -#ifndef AVFMEDIACONTAINERCONTROL_H -#define AVFMEDIACONTAINERCONTROL_H - -#include <qmediacontainercontrol.h> - -@class NSString; - -QT_BEGIN_NAMESPACE - -class AVFCameraService; - -class AVFMediaContainerControl : public QMediaContainerControl -{ -public: - explicit AVFMediaContainerControl(AVFCameraService *service); - - QStringList supportedContainers() const override; - QString containerFormat() const override; - void setContainerFormat(const QString &format) override; - QString containerDescription(const QString &formatMimeType) const override; - - NSString *fileType() const; - -private: - QString m_format; -}; - -QT_END_NAMESPACE - -#endif // AVFMEDIACONTAINERCONTROL_H diff --git a/src/plugins/avfoundation/camera/avfmediacontainercontrol.mm b/src/plugins/avfoundation/camera/avfmediacontainercontrol.mm deleted file mode 100644 index 89fb50a19..000000000 --- a/src/plugins/avfoundation/camera/avfmediacontainercontrol.mm +++ /dev/null @@ -1,112 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** 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 "avfmediacontainercontrol.h" - -#include <AVFoundation/AVMediaFormat.h> - -QT_BEGIN_NAMESPACE - -struct ContainerInfo -{ - QString description; - NSString *fileType; - - ContainerInfo() : fileType(nil) { } - ContainerInfo(const QString &desc, NSString *type) - : description(desc), fileType(type) - { } -}; - -typedef QMap<QString, ContainerInfo> SupportedContainers; -Q_GLOBAL_STATIC(SupportedContainers, containers); - -AVFMediaContainerControl::AVFMediaContainerControl(AVFCameraService *) - : QMediaContainerControl() - , m_format(QStringLiteral("mov")) // .mov is the default container format on Apple platforms -{ - if (containers->isEmpty()) { - containers->insert(QStringLiteral("mov"), - ContainerInfo(QStringLiteral("QuickTime movie file format"), - AVFileTypeQuickTimeMovie)); - containers->insert(QStringLiteral("mp4"), - ContainerInfo(QStringLiteral("MPEG-4 file format"), - AVFileTypeMPEG4)); - containers->insert(QStringLiteral("m4v"), - ContainerInfo(QStringLiteral("iTunes video file format"), - AVFileTypeAppleM4V)); -#ifdef Q_OS_IOS - containers->insert(QStringLiteral("3gp"), - ContainerInfo(QStringLiteral("3GPP file format"), - AVFileType3GPP)); -#endif - } -} - -QStringList AVFMediaContainerControl::supportedContainers() const -{ - return containers->keys(); -} - -QString AVFMediaContainerControl::containerFormat() const -{ - return m_format; -} - -void AVFMediaContainerControl::setContainerFormat(const QString &format) -{ - if (!containers->contains(format)) { - qWarning("Unsupported container format: '%s'", format.toLocal8Bit().constData()); - return; - } - - m_format = format; -} - -QString AVFMediaContainerControl::containerDescription(const QString &formatMimeType) const -{ - return containers->value(formatMimeType).description; -} - -NSString *AVFMediaContainerControl::fileType() const -{ - return containers->value(m_format).fileType; -} - -QT_END_NAMESPACE diff --git a/src/plugins/avfoundation/camera/avfmediarecordercontrol.h b/src/plugins/avfoundation/camera/avfmediarecordercontrol.h deleted file mode 100644 index fbba5eca4..000000000 --- a/src/plugins/avfoundation/camera/avfmediarecordercontrol.h +++ /dev/null @@ -1,120 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** 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$ -** -****************************************************************************/ - -#ifndef AVFMEDIARECORDERCONTROL_H -#define AVFMEDIARECORDERCONTROL_H - -#include <QtCore/qurl.h> -#include <QtMultimedia/qmediarecordercontrol.h> - -#import <AVFoundation/AVFoundation.h> -#include "avfstoragelocation.h" -#include "avfcamerautility.h" - -@class AVFMediaRecorderDelegate; - -QT_BEGIN_NAMESPACE - -class AVFCameraSession; -class AVFCameraControl; -class AVFAudioInputSelectorControl; -class AVFCameraService; - -class AVFMediaRecorderControl : public QMediaRecorderControl -{ -Q_OBJECT -public: - AVFMediaRecorderControl(AVFCameraService *service, QObject *parent = nullptr); - ~AVFMediaRecorderControl(); - - QUrl outputLocation() const override; - bool setOutputLocation(const QUrl &location) override; - - QMediaRecorder::State state() const override; - QMediaRecorder::Status status() const override; - - qint64 duration() const override; - - bool isMuted() const override; - qreal volume() const override; - - void applySettings() override; - void unapplySettings(); - -public Q_SLOTS: - void setState(QMediaRecorder::State state) override; - void setMuted(bool muted) override; - void setVolume(qreal volume) override; - - void handleRecordingStarted(); - void handleRecordingFinished(); - void handleRecordingFailed(const QString &message); - -private Q_SLOTS: - void setupSessionForCapture(); - void updateStatus(); - -private: - AVFCameraService *m_service; - AVFCameraControl *m_cameraControl; - AVFAudioInputSelectorControl *m_audioInputControl; - AVFCameraSession *m_session; - - bool m_connected; - QUrl m_outputLocation; - QMediaRecorder::State m_state; - QMediaRecorder::Status m_lastStatus; - - bool m_recordingStarted; - bool m_recordingFinished; - - bool m_muted; - qreal m_volume; - - AVCaptureDeviceInput *m_audioInput; - AVCaptureMovieFileOutput *m_movieOutput; - AVFMediaRecorderDelegate *m_recorderDelagate; - AVFStorageLocation m_storageLocation; - - AVFPSRange m_restoreFPS; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/avfoundation/camera/avfmediarecordercontrol.mm b/src/plugins/avfoundation/camera/avfmediarecordercontrol.mm deleted file mode 100644 index 7296b7dc1..000000000 --- a/src/plugins/avfoundation/camera/avfmediarecordercontrol.mm +++ /dev/null @@ -1,430 +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 "avfcameradebug.h" -#include "avfmediarecordercontrol.h" -#include "avfcamerasession.h" -#include "avfcameraservice.h" -#include "avfcameracontrol.h" -#include "avfaudioinputselectorcontrol.h" -#include "avfaudioencodersettingscontrol.h" -#include "avfvideoencodersettingscontrol.h" -#include "avfmediacontainercontrol.h" - -#include <QtCore/qurl.h> -#include <QtCore/qfileinfo.h> -#include <QtMultimedia/qcameracontrol.h> - - -QT_USE_NAMESPACE - -@interface AVFMediaRecorderDelegate : NSObject <AVCaptureFileOutputRecordingDelegate> -{ -@private - AVFMediaRecorderControl *m_recorder; -} - -- (AVFMediaRecorderDelegate *) initWithRecorder:(AVFMediaRecorderControl*)recorder; - -- (void) captureOutput:(AVCaptureFileOutput *)captureOutput - didStartRecordingToOutputFileAtURL:(NSURL *)fileURL - fromConnections:(NSArray *)connections; - -- (void) captureOutput:(AVCaptureFileOutput *)captureOutput - didFinishRecordingToOutputFileAtURL:(NSURL *)fileURL - fromConnections:(NSArray *)connections - error:(NSError *)error; -@end - -@implementation AVFMediaRecorderDelegate - -- (AVFMediaRecorderDelegate *) initWithRecorder:(AVFMediaRecorderControl*)recorder -{ - if (!(self = [super init])) - return nil; - - self->m_recorder = recorder; - return self; -} - -- (void) captureOutput:(AVCaptureFileOutput *)captureOutput - didStartRecordingToOutputFileAtURL:(NSURL *)fileURL - fromConnections:(NSArray *)connections -{ - Q_UNUSED(captureOutput); - Q_UNUSED(fileURL); - Q_UNUSED(connections); - - QMetaObject::invokeMethod(m_recorder, "handleRecordingStarted", Qt::QueuedConnection); -} - -- (void) captureOutput:(AVCaptureFileOutput *)captureOutput - didFinishRecordingToOutputFileAtURL:(NSURL *)fileURL - fromConnections:(NSArray *)connections - error:(NSError *)error -{ - Q_UNUSED(captureOutput); - Q_UNUSED(fileURL); - Q_UNUSED(connections); - - if (error) { - QStringList messageParts; - messageParts << QString::fromUtf8([[error localizedDescription] UTF8String]); - messageParts << QString::fromUtf8([[error localizedFailureReason] UTF8String]); - messageParts << QString::fromUtf8([[error localizedRecoverySuggestion] UTF8String]); - - QString errorMessage = messageParts.join(" "); - - QMetaObject::invokeMethod(m_recorder, "handleRecordingFailed", Qt::QueuedConnection, - Q_ARG(QString, errorMessage)); - } else { - QMetaObject::invokeMethod(m_recorder, "handleRecordingFinished", Qt::QueuedConnection); - } -} - -@end - - -AVFMediaRecorderControl::AVFMediaRecorderControl(AVFCameraService *service, QObject *parent) - : QMediaRecorderControl(parent) - , m_service(service) - , m_cameraControl(service->cameraControl()) - , m_audioInputControl(service->audioInputSelectorControl()) - , m_session(service->session()) - , m_connected(false) - , m_state(QMediaRecorder::StoppedState) - , m_lastStatus(QMediaRecorder::UnloadedStatus) - , m_recordingStarted(false) - , m_recordingFinished(false) - , m_muted(false) - , m_volume(1.0) - , m_audioInput(nil) - , m_restoreFPS(-1, -1) -{ - m_movieOutput = [[AVCaptureMovieFileOutput alloc] init]; - m_recorderDelagate = [[AVFMediaRecorderDelegate alloc] initWithRecorder:this]; - - connect(m_cameraControl, SIGNAL(stateChanged(QCamera::State)), SLOT(updateStatus())); - connect(m_cameraControl, SIGNAL(statusChanged(QCamera::Status)), SLOT(updateStatus())); - connect(m_cameraControl, SIGNAL(captureModeChanged(QCamera::CaptureModes)), SLOT(setupSessionForCapture())); - connect(m_session, SIGNAL(readyToConfigureConnections()), SLOT(setupSessionForCapture())); - connect(m_session, SIGNAL(stateChanged(QCamera::State)), SLOT(setupSessionForCapture())); -} - -AVFMediaRecorderControl::~AVFMediaRecorderControl() -{ - if (m_movieOutput) { - [m_session->captureSession() removeOutput:m_movieOutput]; - [m_movieOutput release]; - } - - if (m_audioInput) { - [m_session->captureSession() removeInput:m_audioInput]; - [m_audioInput release]; - } - - [m_recorderDelagate release]; -} - -QUrl AVFMediaRecorderControl::outputLocation() const -{ - return m_outputLocation; -} - -bool AVFMediaRecorderControl::setOutputLocation(const QUrl &location) -{ - m_outputLocation = location; - return location.scheme() == QLatin1String("file") || location.scheme().isEmpty(); -} - -QMediaRecorder::State AVFMediaRecorderControl::state() const -{ - return m_state; -} - -QMediaRecorder::Status AVFMediaRecorderControl::status() const -{ - QMediaRecorder::Status status = m_lastStatus; - //bool videoEnabled = m_cameraControl->captureMode().testFlag(QCamera::CaptureVideo); - - if (m_cameraControl->status() == QCamera::ActiveStatus && m_connected) { - if (m_state == QMediaRecorder::StoppedState) { - if (m_recordingStarted && !m_recordingFinished) - status = QMediaRecorder::FinalizingStatus; - else - status = QMediaRecorder::LoadedStatus; - } else { - status = m_recordingStarted ? QMediaRecorder::RecordingStatus : - QMediaRecorder::StartingStatus; - } - } else { - //camera not started yet - status = m_cameraControl->state() == QCamera::ActiveState && m_connected ? - QMediaRecorder::LoadingStatus: - QMediaRecorder::UnloadedStatus; - } - - return status; -} - -void AVFMediaRecorderControl::updateStatus() -{ - QMediaRecorder::Status newStatus = status(); - - if (m_lastStatus != newStatus) { - qDebugCamera() << "Camera recorder status changed: " << m_lastStatus << " -> " << newStatus; - m_lastStatus = newStatus; - Q_EMIT statusChanged(m_lastStatus); - } -} - - -qint64 AVFMediaRecorderControl::duration() const -{ - if (!m_movieOutput) - return 0; - - return qint64(CMTimeGetSeconds(m_movieOutput.recordedDuration) * 1000); -} - -bool AVFMediaRecorderControl::isMuted() const -{ - return m_muted; -} - -qreal AVFMediaRecorderControl::volume() const -{ - return m_volume; -} - -void AVFMediaRecorderControl::applySettings() -{ - if (m_state != QMediaRecorder::StoppedState - || (m_session->state() != QCamera::ActiveState && m_session->state() != QCamera::LoadedState) - || !m_service->cameraControl()->captureMode().testFlag(QCamera::CaptureVideo)) { - return; - } - - // Configure audio settings - [m_movieOutput setOutputSettings:m_service->audioEncoderSettingsControl()->applySettings() - forConnection:[m_movieOutput connectionWithMediaType:AVMediaTypeAudio]]; - - // Configure video settings - AVCaptureConnection *videoConnection = [m_movieOutput connectionWithMediaType:AVMediaTypeVideo]; - NSDictionary *videoSettings = m_service->videoEncoderSettingsControl()->applySettings(videoConnection); - - const AVFConfigurationLock lock(m_session->videoCaptureDevice()); // prevents activeFormat from being overridden - - [m_movieOutput setOutputSettings:videoSettings forConnection:videoConnection]; -} - -void AVFMediaRecorderControl::unapplySettings() -{ - m_service->audioEncoderSettingsControl()->unapplySettings(); - m_service->videoEncoderSettingsControl()->unapplySettings([m_movieOutput connectionWithMediaType:AVMediaTypeVideo]); -} - -void AVFMediaRecorderControl::setState(QMediaRecorder::State state) -{ - if (m_state == state) - return; - - qDebugCamera() << Q_FUNC_INFO << m_state << " -> " << state; - - switch (state) { - case QMediaRecorder::RecordingState: - { - if (m_connected) { - QString outputLocationPath = m_outputLocation.scheme() == QLatin1String("file") ? - m_outputLocation.path() : m_outputLocation.toString(); - - QString extension = m_service->mediaContainerControl()->containerFormat(); - - QUrl actualLocation = QUrl::fromLocalFile( - m_storageLocation.generateFileName(outputLocationPath, - QCamera::CaptureVideo, - QLatin1String("clip_"), - extension)); - - qDebugCamera() << "Video capture location:" << actualLocation.toString(); - - applySettings(); - - [m_movieOutput startRecordingToOutputFileURL:actualLocation.toNSURL() - recordingDelegate:m_recorderDelagate]; - - m_state = QMediaRecorder::RecordingState; - m_recordingStarted = false; - m_recordingFinished = false; - - Q_EMIT actualLocationChanged(actualLocation); - updateStatus(); - Q_EMIT stateChanged(m_state); - } else { - Q_EMIT error(QMediaRecorder::FormatError, tr("Recorder not configured")); - } - - } break; - case QMediaRecorder::PausedState: - { - Q_EMIT error(QMediaRecorder::FormatError, tr("Recording pause not supported")); - return; - } break; - case QMediaRecorder::StoppedState: - { - m_lastStatus = QMediaRecorder::FinalizingStatus; - Q_EMIT statusChanged(m_lastStatus); - [m_movieOutput stopRecording]; - unapplySettings(); - } - } -} - -void AVFMediaRecorderControl::setMuted(bool muted) -{ - if (m_muted != muted) { - m_muted = muted; - Q_EMIT mutedChanged(muted); - } -} - -void AVFMediaRecorderControl::setVolume(qreal volume) -{ - if (m_volume != volume) { - m_volume = volume; - Q_EMIT volumeChanged(volume); - } -} - -void AVFMediaRecorderControl::handleRecordingStarted() -{ - m_recordingStarted = true; - updateStatus(); -} - -void AVFMediaRecorderControl::handleRecordingFinished() -{ - m_recordingFinished = true; - if (m_state != QMediaRecorder::StoppedState) { - m_state = QMediaRecorder::StoppedState; - Q_EMIT stateChanged(m_state); - } - updateStatus(); -} - -void AVFMediaRecorderControl::handleRecordingFailed(const QString &message) -{ - m_recordingFinished = true; - if (m_state != QMediaRecorder::StoppedState) { - m_state = QMediaRecorder::StoppedState; - Q_EMIT stateChanged(m_state); - } - updateStatus(); - - Q_EMIT error(QMediaRecorder::ResourceError, message); -} - -void AVFMediaRecorderControl::setupSessionForCapture() -{ - if (!m_session->videoCaptureDevice()) - return; - - //adding movie output causes high CPU usage even when while recording is not active, - //connect it only while video capture mode is enabled. - // Similarly, connect the Audio input only in that mode, since it's only necessary - // when recording anyway. Adding an Audio input will trigger the microphone permission - // request on iOS, but it shoudn't do so until we actually try to record. - AVCaptureSession *captureSession = m_session->captureSession(); - - if (!m_connected - && m_cameraControl->captureMode().testFlag(QCamera::CaptureVideo) - && m_session->state() != QCamera::UnloadedState) { - - // Lock the video capture device to make sure the active format is not reset - const AVFConfigurationLock lock(m_session->videoCaptureDevice()); - - // Add audio input - // Allow recording even if something wrong happens with the audio input initialization - AVCaptureDevice *audioDevice = m_audioInputControl->createCaptureDevice(); - if (!audioDevice) { - qWarning("No audio input device available"); - } else { - NSError *error = nil; - m_audioInput = [AVCaptureDeviceInput deviceInputWithDevice:audioDevice error:&error]; - - if (!m_audioInput) { - qWarning() << "Failed to create audio device input"; - } else if (![captureSession canAddInput:m_audioInput]) { - qWarning() << "Could not connect the audio input"; - m_audioInput = nullptr; - } else { - [m_audioInput retain]; - [captureSession addInput:m_audioInput]; - } - } - - if ([captureSession canAddOutput:m_movieOutput]) { - [captureSession addOutput:m_movieOutput]; - m_connected = true; - } else { - Q_EMIT error(QMediaRecorder::ResourceError, tr("Could not connect the video recorder")); - qWarning() << "Could not connect the video recorder"; - } - } else if (m_connected - && (!m_cameraControl->captureMode().testFlag(QCamera::CaptureVideo) - || m_session->state() == QCamera::UnloadedState)) { - - // Lock the video capture device to make sure the active format is not reset - const AVFConfigurationLock lock(m_session->videoCaptureDevice()); - - [captureSession removeOutput:m_movieOutput]; - - if (m_audioInput) { - [captureSession removeInput:m_audioInput]; - [m_audioInput release]; - m_audioInput = nil; - } - - m_connected = false; - } - - updateStatus(); -} - -#include "moc_avfmediarecordercontrol.cpp" diff --git a/src/plugins/avfoundation/camera/avfmediarecordercontrol_ios.h b/src/plugins/avfoundation/camera/avfmediarecordercontrol_ios.h deleted file mode 100644 index 9afb1068d..000000000 --- a/src/plugins/avfoundation/camera/avfmediarecordercontrol_ios.h +++ /dev/null @@ -1,115 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** 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$ -** -****************************************************************************/ - -#ifndef AVFMEDIARECORDERCONTROL_IOS_H -#define AVFMEDIARECORDERCONTROL_IOS_H - -#include "avfmediaassetwriter.h" -#include "avfstoragelocation.h" -#include "avfcamerautility.h" - -#include <QtMultimedia/qmediarecordercontrol.h> -#include <private/qvideooutputorientationhandler_p.h> - -#include <QtCore/qglobal.h> -#include <QtCore/qurl.h> - -#include <AVFoundation/AVFoundation.h> - -QT_BEGIN_NAMESPACE - -class AVFCameraService; -class QString; -class QUrl; - -class AVFMediaRecorderControlIOS : public QMediaRecorderControl -{ - Q_OBJECT -public: - AVFMediaRecorderControlIOS(AVFCameraService *service, QObject *parent = nullptr); - ~AVFMediaRecorderControlIOS() override; - - QUrl outputLocation() const override; - bool setOutputLocation(const QUrl &location) override; - - QMediaRecorder::State state() const override; - QMediaRecorder::Status status() const override; - - qint64 duration() const override; - - bool isMuted() const override; - qreal volume() const override; - - void applySettings() override; - void unapplySettings(); - -public Q_SLOTS: - void setState(QMediaRecorder::State state) override; - void setMuted(bool muted) override; - void setVolume(qreal volume) override; - -private: - - Q_INVOKABLE void assetWriterStarted(); - Q_INVOKABLE void assetWriterFinished(); - -private Q_SLOTS: - void captureModeChanged(QCamera::CaptureModes); - void cameraStatusChanged(QCamera::Status newStatus); - -private: - void stopWriter(); - - AVFCameraService *m_service; - AVFScopedPointer<QT_MANGLE_NAMESPACE(AVFMediaAssetWriter)> m_writer; - - QUrl m_outputLocation; - AVFStorageLocation m_storageLocation; - - QMediaRecorder::State m_state; - QMediaRecorder::Status m_lastStatus; - - NSDictionary *m_audioSettings; - NSDictionary *m_videoSettings; - QVideoOutputOrientationHandler m_orientationHandler; -}; - -QT_END_NAMESPACE - -#endif // AVFMEDIARECORDERCONTROL_IOS_H 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" diff --git a/src/plugins/avfoundation/camera/avfmediavideoprobecontrol.h b/src/plugins/avfoundation/camera/avfmediavideoprobecontrol.h deleted file mode 100644 index 69a452a97..000000000 --- a/src/plugins/avfoundation/camera/avfmediavideoprobecontrol.h +++ /dev/null @@ -1,60 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** 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$ -** -****************************************************************************/ - -#ifndef AVFMEDIAVIDEOPROBECONTROL_H -#define AVFMEDIAVIDEOPROBECONTROL_H - -#include <qmediavideoprobecontrol.h> - -QT_BEGIN_NAMESPACE - -class AVFMediaVideoProbeControl : public QMediaVideoProbeControl -{ - Q_OBJECT -public: - explicit AVFMediaVideoProbeControl(QObject *parent = nullptr); - ~AVFMediaVideoProbeControl(); - - void newFrameProbed(const QVideoFrame& frame); - -}; - -QT_END_NAMESPACE - -#endif // AVFMEDIAVIDEOPROBECONTROL_H diff --git a/src/plugins/avfoundation/camera/avfmediavideoprobecontrol.mm b/src/plugins/avfoundation/camera/avfmediavideoprobecontrol.mm deleted file mode 100644 index 7621661c3..000000000 --- a/src/plugins/avfoundation/camera/avfmediavideoprobecontrol.mm +++ /dev/null @@ -1,61 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies). -** Copyright (C) 2016 Integrated Computer Solutions, Inc -** 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 "avfmediavideoprobecontrol.h" -#include <qvideoframe.h> - -QT_BEGIN_NAMESPACE - -AVFMediaVideoProbeControl::AVFMediaVideoProbeControl(QObject *parent) : - QMediaVideoProbeControl(parent) -{ -} - -AVFMediaVideoProbeControl::~AVFMediaVideoProbeControl() -{ - -} - -void AVFMediaVideoProbeControl::newFrameProbed(const QVideoFrame &frame) -{ - Q_EMIT videoFrameProbed(frame); -} - -QT_END_NAMESPACE diff --git a/src/plugins/avfoundation/camera/avfstoragelocation.h b/src/plugins/avfoundation/camera/avfstoragelocation.h deleted file mode 100644 index 76621983d..000000000 --- a/src/plugins/avfoundation/camera/avfstoragelocation.h +++ /dev/null @@ -1,71 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** 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$ -** -****************************************************************************/ - -#ifndef AVFSTORAGE_H -#define AVFSTORAGE_H - -#include "qtmultimediaglobal.h" - -#include <QtCore/qdir.h> -#include <QtMultimedia/qcamera.h> - -QT_BEGIN_NAMESPACE - -class AVFStorageLocation -{ -public: - AVFStorageLocation(); - ~AVFStorageLocation(); - - QString generateFileName(const QString &requestedName, - QCamera::CaptureMode mode, - const QString &prefix, - const QString &ext) const; - - - QDir defaultDir(QCamera::CaptureMode mode) const; - QString generateFileName(const QString &prefix, const QDir &dir, const QString &ext) const; - -private: - mutable QMap<QString, int> m_lastUsedIndex; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/avfoundation/camera/avfstoragelocation.mm b/src/plugins/avfoundation/camera/avfstoragelocation.mm deleted file mode 100644 index 6a1cdca17..000000000 --- a/src/plugins/avfoundation/camera/avfstoragelocation.mm +++ /dev/null @@ -1,136 +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 "avfstoragelocation.h" -#include "QtCore/qstandardpaths.h" - - -QT_BEGIN_NAMESPACE - - -AVFStorageLocation::AVFStorageLocation() -{ -} - -AVFStorageLocation::~AVFStorageLocation() -{ -} - -/*! - * Generate the actual file name from user requested one. - * requestedName may be either empty (the default dir and naming theme is used), - * points to existing dir (the default name used) - * or specify the full actual path. - */ -QString AVFStorageLocation::generateFileName(const QString &requestedName, - QCamera::CaptureMode mode, - const QString &prefix, - const QString &ext) const -{ - if (requestedName.isEmpty()) - return generateFileName(prefix, defaultDir(mode), ext); - - if (QFileInfo(requestedName).isDir()) - return generateFileName(prefix, QDir(requestedName), ext); - - return requestedName; -} - -QDir AVFStorageLocation::defaultDir(QCamera::CaptureMode mode) const -{ - QStringList dirCandidates; - - if (mode == QCamera::CaptureVideo) { - dirCandidates << QStandardPaths::writableLocation(QStandardPaths::MoviesLocation); - } else { - dirCandidates << QStandardPaths::writableLocation(QStandardPaths::PicturesLocation); - } - - dirCandidates << QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation); - dirCandidates << QDir::homePath(); - dirCandidates << QDir::currentPath(); - dirCandidates << QDir::tempPath(); - - for (const QString &path : qAsConst(dirCandidates)) { - if (QFileInfo(path).isWritable()) - return QDir(path); - } - - return QDir(); -} - -QString AVFStorageLocation::generateFileName(const QString &prefix, const QDir &dir, const QString &ext) const -{ - QString lastClipKey = dir.absolutePath()+QLatin1Char(' ')+prefix+QLatin1Char(' ')+ext; - int lastClip = m_lastUsedIndex.value(lastClipKey, 0); - - if (lastClip == 0) { - //first run, find the maximum clip number during the fist capture - const auto list = dir.entryList(QStringList() << QString("%1*.%2").arg(prefix).arg(ext)); - for (const QString &fileName : list) { - int imgNumber = QStringView{fileName}.mid(prefix.length(), fileName.size()-prefix.length()-ext.length()-1).toInt(); - lastClip = qMax(lastClip, imgNumber); - } - } - - - //don't just rely on cached lastClip value, - //someone else may create a file after camera started - while (true) { - QString name = QString("%1%2.%3").arg(prefix) - .arg(lastClip+1, - 4, //fieldWidth - 10, - QLatin1Char('0')) - .arg(ext); - - QString path = dir.absoluteFilePath(name); - if (!QFileInfo(path).exists()) { - m_lastUsedIndex[lastClipKey] = lastClip+1; - return path; - } - - lastClip++; - } - - return QString(); -} - - -QT_END_NAMESPACE diff --git a/src/plugins/avfoundation/camera/avfvideoencodersettingscontrol.h b/src/plugins/avfoundation/camera/avfvideoencodersettingscontrol.h deleted file mode 100644 index 7c9574f3d..000000000 --- a/src/plugins/avfoundation/camera/avfvideoencodersettingscontrol.h +++ /dev/null @@ -1,88 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** 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$ -** -****************************************************************************/ - -#ifndef AVFVIDEOENCODERSETTINGSCONTROL_H -#define AVFVIDEOENCODERSETTINGSCONTROL_H - -#include <qvideoencodersettingscontrol.h> - -#include "avfcamerautility.h" -#import <AVFoundation/AVFoundation.h> - -@class NSDictionary; - -QT_BEGIN_NAMESPACE - -class AVFCameraService; - -class AVFVideoEncoderSettingsControl : public QVideoEncoderSettingsControl -{ - Q_OBJECT - -public: - explicit AVFVideoEncoderSettingsControl(AVFCameraService *service); - - QList<QSize> supportedResolutions(const QVideoEncoderSettings &requestedVideoSettings, - bool *continuous = nullptr) const override; - - QList<qreal> supportedFrameRates(const QVideoEncoderSettings &requestedVideoSettings, - bool *continuous = nullptr) const override; - - QStringList supportedVideoCodecs() const override; - QString videoCodecDescription(const QString &codecName) const override; - - QVideoEncoderSettings videoSettings() const override; - void setVideoSettings(const QVideoEncoderSettings &requestedVideoSettings) override; - - NSDictionary *applySettings(AVCaptureConnection *connection); - void unapplySettings(AVCaptureConnection *connection); - -private: - AVFCameraService *m_service; - - QVideoEncoderSettings m_requestedSettings; - QVideoEncoderSettings m_actualSettings; - - AVCaptureDeviceFormat *m_restoreFormat; - AVFPSRange m_restoreFps; -}; - -QT_END_NAMESPACE - -#endif // AVFVIDEOENCODERSETTINGSCONTROL_H diff --git a/src/plugins/avfoundation/camera/avfvideoencodersettingscontrol.mm b/src/plugins/avfoundation/camera/avfvideoencodersettingscontrol.mm deleted file mode 100644 index 70ec38988..000000000 --- a/src/plugins/avfoundation/camera/avfvideoencodersettingscontrol.mm +++ /dev/null @@ -1,385 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** 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 "avfvideoencodersettingscontrol.h" - -#include "avfcameraservice.h" -#include "avfcamerautility.h" -#include "avfcamerasession.h" -#include "avfcamerarenderercontrol.h" - -#include <AVFoundation/AVFoundation.h> - -QT_BEGIN_NAMESPACE - -Q_GLOBAL_STATIC_WITH_ARGS(QStringList, supportedCodecs, (QStringList() << QLatin1String("avc1") - << QLatin1String("jpeg") - #ifdef Q_OS_OSX - << QLatin1String("ap4h") - << QLatin1String("apcn") - #endif - )) - -static bool format_supports_framerate(AVCaptureDeviceFormat *format, qreal fps) -{ - if (format && fps > qreal(0)) { - const qreal epsilon = 0.1; - for (AVFrameRateRange *range in format.videoSupportedFrameRateRanges) { - if (range.maxFrameRate - range.minFrameRate < epsilon) { - if (qAbs(fps - range.maxFrameRate) < epsilon) - return true; - } - - if (fps >= range.minFrameRate && fps <= range.maxFrameRate) - return true; - } - } - - return false; -} - -static bool real_list_contains(const QList<qreal> &list, qreal value) -{ - for (qreal r : list) { - if (qFuzzyCompare(r, value)) - return true; - } - return false; -} - -AVFVideoEncoderSettingsControl::AVFVideoEncoderSettingsControl(AVFCameraService *service) - : QVideoEncoderSettingsControl() - , m_service(service) - , m_restoreFormat(nil) -{ -} - -QList<QSize> AVFVideoEncoderSettingsControl::supportedResolutions(const QVideoEncoderSettings &settings, - bool *continuous) const -{ - Q_UNUSED(settings); - - if (continuous) - *continuous = true; - - // AVFoundation seems to support any resolution for recording, with the following limitations: - // - The recording resolution can't be higher than the camera's active resolution - // - On OS X, the recording resolution is automatically adjusted to have the same aspect ratio as - // the camera's active resolution - QList<QSize> resolutions; - resolutions.append(QSize(32, 32)); - - AVCaptureDevice *device = m_service->session()->videoCaptureDevice(); - if (device) { - int maximumWidth = 0; - const QVector<AVCaptureDeviceFormat *> formats(qt_unique_device_formats(device, - m_service->session()->defaultCodec())); - for (int i = 0; i < formats.size(); ++i) { - const QSize res(qt_device_format_resolution(formats[i])); - if (res.width() > maximumWidth) - maximumWidth = res.width(); - } - - if (maximumWidth > 0) - resolutions.append(QSize(maximumWidth, maximumWidth)); - } - - if (resolutions.count() == 1) - resolutions.append(QSize(3840, 3840)); - - return resolutions; -} - -QList<qreal> AVFVideoEncoderSettingsControl::supportedFrameRates(const QVideoEncoderSettings &settings, - bool *continuous) const -{ - QList<qreal> uniqueFrameRates; - - AVCaptureDevice *device = m_service->session()->videoCaptureDevice(); - if (!device) - return uniqueFrameRates; - - if (continuous) - *continuous = false; - - QVector<AVFPSRange> allRates; - - if (!settings.resolution().isValid()) { - const QVector<AVCaptureDeviceFormat *> formats(qt_unique_device_formats(device, 0)); - for (int i = 0; i < formats.size(); ++i) { - AVCaptureDeviceFormat *format = formats.at(i); - allRates += qt_device_format_framerates(format); - } - } else { - AVCaptureDeviceFormat *format = qt_find_best_resolution_match(device, - settings.resolution(), - m_service->session()->defaultCodec()); - if (format) - allRates = qt_device_format_framerates(format); - } - - for (int j = 0; j < allRates.size(); ++j) { - if (!real_list_contains(uniqueFrameRates, allRates[j].first)) - uniqueFrameRates.append(allRates[j].first); - if (!real_list_contains(uniqueFrameRates, allRates[j].second)) - uniqueFrameRates.append(allRates[j].second); - } - - return uniqueFrameRates; -} - -QStringList AVFVideoEncoderSettingsControl::supportedVideoCodecs() const -{ - return *supportedCodecs; -} - -QString AVFVideoEncoderSettingsControl::videoCodecDescription(const QString &codecName) const -{ - if (codecName == QLatin1String("avc1")) - return QStringLiteral("H.264"); - else if (codecName == QLatin1String("jpeg")) - return QStringLiteral("M-JPEG"); -#ifdef Q_OS_OSX - else if (codecName == QLatin1String("ap4h")) - return QStringLiteral("Apple ProRes 4444"); - else if (codecName == QLatin1String("apcn")) - return QStringLiteral("Apple ProRes 422 Standard Definition"); -#endif - - return QString(); -} - -QVideoEncoderSettings AVFVideoEncoderSettingsControl::videoSettings() const -{ - return m_actualSettings; -} - -void AVFVideoEncoderSettingsControl::setVideoSettings(const QVideoEncoderSettings &settings) -{ - if (m_requestedSettings == settings) - return; - - m_requestedSettings = m_actualSettings = settings; -} - -NSDictionary *AVFVideoEncoderSettingsControl::applySettings(AVCaptureConnection *connection) -{ - if (m_service->session()->state() != QCamera::LoadedState && - m_service->session()->state() != QCamera::ActiveState) { - return nil; - } - - AVCaptureDevice *device = m_service->session()->videoCaptureDevice(); - if (!device) - return nil; - - AVFPSRange currentFps = qt_current_framerates(device, connection); - const bool needFpsChange = m_requestedSettings.frameRate() > 0 - && m_requestedSettings.frameRate() != currentFps.second; - - NSMutableDictionary *videoSettings = [NSMutableDictionary dictionary]; - - // -- Codec - - // AVVideoCodecKey is the only mandatory key - QString codec = m_requestedSettings.codec().isEmpty() ? supportedCodecs->first() : m_requestedSettings.codec(); - if (!supportedCodecs->contains(codec)) { - qWarning("Unsupported codec: '%s'", codec.toLocal8Bit().constData()); - codec = supportedCodecs->first(); - } - [videoSettings setObject:codec.toNSString() forKey:AVVideoCodecKey]; - m_actualSettings.setCodec(codec); - - // -- Resolution - - int w = m_requestedSettings.resolution().width(); - int h = m_requestedSettings.resolution().height(); - - if (AVCaptureDeviceFormat *currentFormat = device.activeFormat) { - CMFormatDescriptionRef formatDesc = currentFormat.formatDescription; - CMVideoDimensions dim = CMVideoFormatDescriptionGetDimensions(formatDesc); - - // We have to change the device's activeFormat in 3 cases: - // - the requested recording resolution is higher than the current device resolution - // - the requested recording resolution has a different aspect ratio than the current device aspect ratio - // - the requested frame rate is not available for the current device format - AVCaptureDeviceFormat *newFormat = nil; - if ((w <= 0 || h <= 0) - && m_requestedSettings.frameRate() > 0 - && !format_supports_framerate(currentFormat, m_requestedSettings.frameRate())) { - - newFormat = qt_find_best_framerate_match(device, - m_service->session()->defaultCodec(), - m_requestedSettings.frameRate()); - - } else if (w > 0 && h > 0) { - AVCaptureDeviceFormat *f = qt_find_best_resolution_match(device, - m_requestedSettings.resolution(), - m_service->session()->defaultCodec()); - - if (f) { - CMVideoDimensions d = CMVideoFormatDescriptionGetDimensions(f.formatDescription); - qreal fAspectRatio = qreal(d.width) / d.height; - - if (w > dim.width || h > dim.height - || qAbs((qreal(dim.width) / dim.height) - fAspectRatio) > 0.01) { - newFormat = f; - } - } - } - - if (qt_set_active_format(device, newFormat, !needFpsChange)) { - m_restoreFormat = [currentFormat retain]; - formatDesc = newFormat.formatDescription; - dim = CMVideoFormatDescriptionGetDimensions(formatDesc); - } - - if (w > 0 && h > 0) { - // Make sure the recording resolution has the same aspect ratio as the device's - // current resolution - qreal deviceAspectRatio = qreal(dim.width) / dim.height; - qreal recAspectRatio = qreal(w) / h; - if (qAbs(deviceAspectRatio - recAspectRatio) > 0.01) { - if (recAspectRatio > deviceAspectRatio) - w = qRound(h * deviceAspectRatio); - else - h = qRound(w / deviceAspectRatio); - } - - // recording resolution can't be higher than the device's active resolution - w = qMin(w, dim.width); - h = qMin(h, dim.height); - } - } - - if (w > 0 && h > 0) { - // Width and height must be divisible by 2 - w += w & 1; - h += h & 1; - - [videoSettings setObject:[NSNumber numberWithInt:w] forKey:AVVideoWidthKey]; - [videoSettings setObject:[NSNumber numberWithInt:h] forKey:AVVideoHeightKey]; - m_actualSettings.setResolution(w, h); - } else { - m_actualSettings.setResolution(qt_device_format_resolution(device.activeFormat)); - } - - // -- FPS - - if (needFpsChange) { - m_restoreFps = currentFps; - const qreal fps = m_requestedSettings.frameRate(); - qt_set_framerate_limits(device, connection, fps, fps); - } - m_actualSettings.setFrameRate(qt_current_framerates(device, connection).second); - - // -- Codec Settings - - NSMutableDictionary *codecProperties = [NSMutableDictionary dictionary]; - int bitrate = -1; - float quality = -1.f; - - if (m_requestedSettings.encodingMode() == QMultimedia::ConstantQualityEncoding) { - if (m_requestedSettings.quality() != QMultimedia::NormalQuality) { - if (codec != QLatin1String("jpeg")) { - qWarning("ConstantQualityEncoding is not supported for codec: '%s'", codec.toLocal8Bit().constData()); - } else { - switch (m_requestedSettings.quality()) { - case QMultimedia::VeryLowQuality: - quality = 0.f; - break; - case QMultimedia::LowQuality: - quality = 0.25f; - break; - case QMultimedia::HighQuality: - quality = 0.75f; - break; - case QMultimedia::VeryHighQuality: - quality = 1.f; - break; - default: - quality = -1.f; // NormalQuality, let the system decide - break; - } - } - } - } else if (m_requestedSettings.encodingMode() == QMultimedia::AverageBitRateEncoding){ - if (codec != QLatin1String("avc1")) - qWarning("AverageBitRateEncoding is not supported for codec: '%s'", codec.toLocal8Bit().constData()); - else - bitrate = m_requestedSettings.bitRate(); - } else { - qWarning("Encoding mode is not supported"); - } - - if (bitrate != -1) - [codecProperties setObject:[NSNumber numberWithInt:bitrate] forKey:AVVideoAverageBitRateKey]; - if (quality != -1.f) - [codecProperties setObject:[NSNumber numberWithFloat:quality] forKey:AVVideoQualityKey]; - - [videoSettings setObject:codecProperties forKey:AVVideoCompressionPropertiesKey]; - - return videoSettings; -} - -void AVFVideoEncoderSettingsControl::unapplySettings(AVCaptureConnection *connection) -{ - m_actualSettings = m_requestedSettings; - - AVCaptureDevice *device = m_service->session()->videoCaptureDevice(); - if (!device) - return; - - const bool needFpsChanged = m_restoreFps.first || m_restoreFps.second; - - if (m_restoreFormat) { - qt_set_active_format(device, m_restoreFormat, !needFpsChanged); - [m_restoreFormat release]; - m_restoreFormat = nil; - } - - if (needFpsChanged) { - qt_set_framerate_limits(device, connection, m_restoreFps.first, m_restoreFps.second); - m_restoreFps = AVFPSRange(); - } -} - -QT_END_NAMESPACE - -#include "moc_avfvideoencodersettingscontrol.cpp" diff --git a/src/plugins/avfoundation/camera/camera.pro b/src/plugins/avfoundation/camera/camera.pro deleted file mode 100644 index 76aa8af85..000000000 --- a/src/plugins/avfoundation/camera/camera.pro +++ /dev/null @@ -1,94 +0,0 @@ -TARGET = qavfcamera - -# Avoid clash with a variable named `slots' in a Quartz header -CONFIG += no_keywords - -QT += multimedia-private network - -LIBS += -framework CoreFoundation \ - -framework Foundation \ - -framework AudioToolbox \ - -framework CoreAudio \ - -framework QuartzCore \ - -framework CoreMedia -osx:LIBS += -framework AppKit \ - -framework AudioUnit -ios:LIBS += -framework CoreGraphics \ - -framework CoreVideo - -QMAKE_USE += avfoundation - -OTHER_FILES += avfcamera.json - -HEADERS += \ - avfcameradebug.h \ - avfcameraserviceplugin.h \ - avfcameracontrol.h \ - avfcamerametadatacontrol.h \ - avfimagecapturecontrol.h \ - avfcameraservice.h \ - avfcamerasession.h \ - avfstoragelocation.h \ - avfaudioinputselectorcontrol.h \ - avfcamerainfocontrol.h \ - avfmediavideoprobecontrol.h \ - avfcamerarenderercontrol.h \ - avfcameradevicecontrol.h \ - avfcamerafocuscontrol.h \ - avfcameraexposurecontrol.h \ - avfcamerautility.h \ - avfcameraviewfindersettingscontrol.h \ - avfimageencodercontrol.h \ - avfcameraflashcontrol.h \ - avfvideoencodersettingscontrol.h \ - avfmediacontainercontrol.h \ - avfaudioencodersettingscontrol.h \ - avfcamerawindowcontrol.h \ - avfcapturedestinationcontrol.h - -OBJECTIVE_SOURCES += \ - avfcameraserviceplugin.mm \ - avfcameracontrol.mm \ - avfcamerametadatacontrol.mm \ - avfimagecapturecontrol.mm \ - avfcameraservice.mm \ - avfcamerasession.mm \ - avfstoragelocation.mm \ - avfaudioinputselectorcontrol.mm \ - avfcamerainfocontrol.mm \ - avfmediavideoprobecontrol.mm \ - avfcameradevicecontrol.mm \ - avfcamerarenderercontrol.mm \ - avfcamerafocuscontrol.mm \ - avfcameraexposurecontrol.mm \ - avfcamerautility.mm \ - avfcameraviewfindersettingscontrol.mm \ - avfimageencodercontrol.mm \ - avfcameraflashcontrol.mm \ - avfvideoencodersettingscontrol.mm \ - avfmediacontainercontrol.mm \ - avfaudioencodersettingscontrol.mm \ - avfcamerawindowcontrol.mm \ - avfcapturedestinationcontrol.mm - -osx { - -HEADERS += avfmediarecordercontrol.h -OBJECTIVE_SOURCES += avfmediarecordercontrol.mm - -} - -ios { - -HEADERS += avfcamerazoomcontrol.h \ - avfmediaassetwriter.h \ - avfmediarecordercontrol_ios.h -OBJECTIVE_SOURCES += avfcamerazoomcontrol.mm \ - avfmediaassetwriter.mm \ - avfmediarecordercontrol_ios.mm - -} - -PLUGIN_TYPE = mediaservice -PLUGIN_CLASS_NAME = AVFServicePlugin -load(qt_plugin) diff --git a/src/plugins/avfoundation/mediaplayer/avfdisplaylink.h b/src/plugins/avfoundation/mediaplayer/avfdisplaylink.h deleted file mode 100644 index ba0803807..000000000 --- a/src/plugins/avfoundation/mediaplayer/avfdisplaylink.h +++ /dev/null @@ -1,90 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** 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$ -** -****************************************************************************/ - -#ifndef AVFDISPLAYLINK_H -#define AVFDISPLAYLINK_H - -#include <QtCore/qobject.h> -#include <QtCore/qmutex.h> - -#if defined(Q_OS_IOS) || defined(Q_OS_TVOS) -#include <CoreVideo/CVBase.h> -#else -#include <QuartzCore/CVDisplayLink.h> -#endif - -QT_BEGIN_NAMESPACE - -class AVFDisplayLink : public QObject -{ - Q_OBJECT -public: - explicit AVFDisplayLink(QObject *parent = nullptr); - virtual ~AVFDisplayLink(); - bool isValid() const; - bool isActive() const; - -public Q_SLOTS: - void start(); - void stop(); - -Q_SIGNALS: - void tick(const CVTimeStamp &ts); - -public: - void displayLinkEvent(const CVTimeStamp *); - -protected: - virtual bool event(QEvent *) override; - -private: -#if defined(Q_OS_IOS) || defined(Q_OS_TVOS) - void *m_displayLink; -#else - CVDisplayLinkRef m_displayLink; -#endif - QMutex m_displayLinkMutex; - bool m_pendingDisplayLinkEvent; - bool m_isActive; - CVTimeStamp m_frameTimeStamp; -}; - -QT_END_NAMESPACE - -#endif // AVFDISPLAYLINK_H diff --git a/src/plugins/avfoundation/mediaplayer/avfdisplaylink.mm b/src/plugins/avfoundation/mediaplayer/avfdisplaylink.mm deleted file mode 100644 index bae18bc0a..000000000 --- a/src/plugins/avfoundation/mediaplayer/avfdisplaylink.mm +++ /dev/null @@ -1,241 +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 "avfdisplaylink.h" -#include <QtCore/qcoreapplication.h> - -#ifdef QT_DEBUG_AVF -#include <QtCore/qdebug.h> -#endif - -#if defined(Q_OS_IOS) || defined(Q_OS_TVOS) -#import <QuartzCore/CADisplayLink.h> -#import <Foundation/NSRunLoop.h> -#define _m_displayLink static_cast<DisplayLinkObserver*>(m_displayLink) -#else -#endif - -QT_USE_NAMESPACE - -#if defined(Q_OS_IOS) || defined(Q_OS_TVOS) -@interface DisplayLinkObserver : NSObject - -- (void)start; -- (void)stop; -- (void)displayLinkNotification:(CADisplayLink *)sender; - -@end - -@implementation DisplayLinkObserver -{ - AVFDisplayLink *m_avfDisplayLink; - CADisplayLink *m_displayLink; -} - -- (id)initWithAVFDisplayLink:(AVFDisplayLink *)link -{ - self = [super init]; - - if (self) { - m_avfDisplayLink = link; - m_displayLink = [[CADisplayLink displayLinkWithTarget:self selector:@selector(displayLinkNotification:)] retain]; - } - - return self; -} - -- (void) dealloc -{ - if (m_displayLink) { - [m_displayLink release]; - m_displayLink = nullptr; - } - - [super dealloc]; -} - -- (void)start -{ - [m_displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; -} - -- (void)stop -{ - [m_displayLink removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; -} - -- (void)displayLinkNotification:(CADisplayLink *)sender -{ - Q_UNUSED(sender); - m_avfDisplayLink->displayLinkEvent(nullptr); -} - -@end -#else -static CVReturn CVDisplayLinkCallback(CVDisplayLinkRef displayLink, - const CVTimeStamp *inNow, - const CVTimeStamp *inOutputTime, - CVOptionFlags flagsIn, - CVOptionFlags *flagsOut, - void *displayLinkContext) -{ - Q_UNUSED(displayLink); - Q_UNUSED(inNow); - Q_UNUSED(flagsIn); - Q_UNUSED(flagsOut); - - AVFDisplayLink *link = (AVFDisplayLink *)displayLinkContext; - - link->displayLinkEvent(inOutputTime); - return kCVReturnSuccess; -} -#endif - -AVFDisplayLink::AVFDisplayLink(QObject *parent) - : QObject(parent) - , m_displayLink(nullptr) - , m_pendingDisplayLinkEvent(false) - , m_isActive(false) -{ -#if defined(Q_OS_IOS) || defined(Q_OS_TVOS) - m_displayLink = [[DisplayLinkObserver alloc] initWithAVFDisplayLink:this]; -#else - // create display link for the main display - CVDisplayLinkCreateWithCGDisplay(kCGDirectMainDisplay, &m_displayLink); - if (m_displayLink) { - // set the current display of a display link. - CVDisplayLinkSetCurrentCGDisplay(m_displayLink, kCGDirectMainDisplay); - - // set the renderer output callback function - CVDisplayLinkSetOutputCallback(m_displayLink, &CVDisplayLinkCallback, this); - } -#endif -} - -AVFDisplayLink::~AVFDisplayLink() -{ -#ifdef QT_DEBUG_AVF - qDebug() << Q_FUNC_INFO; -#endif - - if (m_displayLink) { - stop(); -#if defined(Q_OS_IOS) || defined(Q_OS_TVOS) - [_m_displayLink release]; -#else - CVDisplayLinkRelease(m_displayLink); -#endif - m_displayLink = nullptr; - } -} - -bool AVFDisplayLink::isValid() const -{ - return m_displayLink != nullptr; -} - -bool AVFDisplayLink::isActive() const -{ - return m_isActive; -} - -void AVFDisplayLink::start() -{ - if (m_displayLink && !m_isActive) { -#if defined(Q_OS_IOS) || defined(Q_OS_TVOS) - [_m_displayLink start]; -#else - CVDisplayLinkStart(m_displayLink); -#endif - m_isActive = true; - } -} - -void AVFDisplayLink::stop() -{ - if (m_displayLink && m_isActive) { -#if defined(Q_OS_IOS) || defined(Q_OS_TVOS) - [_m_displayLink stop]; -#else - CVDisplayLinkStop(m_displayLink); -#endif - m_isActive = false; - } -} - -void AVFDisplayLink::displayLinkEvent(const CVTimeStamp *ts) -{ - // This function is called from a - // thread != gui thread. So we post the event. - // But we need to make sure that we don't post faster - // than the event loop can eat: - m_displayLinkMutex.lock(); - bool pending = m_pendingDisplayLinkEvent; - m_pendingDisplayLinkEvent = true; -#if defined(Q_OS_IOS) || defined(Q_OS_TVOS) - Q_UNUSED(ts); - memset(&m_frameTimeStamp, 0, sizeof(CVTimeStamp)); -#else - m_frameTimeStamp = *ts; -#endif - m_displayLinkMutex.unlock(); - - if (!pending) - qApp->postEvent(this, new QEvent(QEvent::User), Qt::HighEventPriority); -} - -bool AVFDisplayLink::event(QEvent *event) -{ - switch (event->type()){ - case QEvent::User: { - m_displayLinkMutex.lock(); - m_pendingDisplayLinkEvent = false; - CVTimeStamp ts = m_frameTimeStamp; - m_displayLinkMutex.unlock(); - - Q_EMIT tick(ts); - - return false; - } - break; - default: - break; - } - return QObject::event(event); -} diff --git a/src/plugins/avfoundation/mediaplayer/avfmediaplayer.json b/src/plugins/avfoundation/mediaplayer/avfmediaplayer.json deleted file mode 100644 index 5626edec0..000000000 --- a/src/plugins/avfoundation/mediaplayer/avfmediaplayer.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "Keys": ["avfoundationmediaplayer"], - "Services": ["org.qt-project.qt.mediaplayer"] -} diff --git a/src/plugins/avfoundation/mediaplayer/avfmediaplayercontrol.h b/src/plugins/avfoundation/mediaplayer/avfmediaplayercontrol.h deleted file mode 100644 index ac0ba0ab2..000000000 --- a/src/plugins/avfoundation/mediaplayer/avfmediaplayercontrol.h +++ /dev/null @@ -1,99 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** 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$ -** -****************************************************************************/ - -#ifndef AVFMEDIAPLAYERCONTROL_H -#define AVFMEDIAPLAYERCONTROL_H - -#include <QtMultimedia/QMediaPlayerControl> -#include <QtCore/QObject> - -QT_BEGIN_NAMESPACE - -class AVFMediaPlayerSession; - -class AVFMediaPlayerControl : public QMediaPlayerControl -{ - Q_OBJECT -public: - explicit AVFMediaPlayerControl(QObject *parent = nullptr); - ~AVFMediaPlayerControl(); - - void setSession(AVFMediaPlayerSession *session); - - QMediaPlayer::State state() const override; - QMediaPlayer::MediaStatus mediaStatus() const override; - - QMediaContent media() const override; - const QIODevice *mediaStream() const override; - void setMedia(const QMediaContent &content, QIODevice *stream) override; - - qint64 position() const override; - qint64 duration() const override; - - int bufferStatus() const override; - - int volume() const override; - bool isMuted() const override; - - bool isAudioAvailable() const override; - bool isVideoAvailable() const override; - - bool isSeekable() const override; - QMediaTimeRange availablePlaybackRanges() const override; - - qreal playbackRate() const override; - void setPlaybackRate(qreal rate) override; - -public Q_SLOTS: - void setPosition(qint64 pos) override; - - void play() override; - void pause() override; - void stop() override; - - void setVolume(int volume) override; - void setMuted(bool muted) override; - -private: - AVFMediaPlayerSession *m_session; -}; - -QT_END_NAMESPACE - -#endif // AVFMEDIAPLAYERCONTROL_H diff --git a/src/plugins/avfoundation/mediaplayer/avfmediaplayercontrol.mm b/src/plugins/avfoundation/mediaplayer/avfmediaplayercontrol.mm deleted file mode 100644 index bf7ebb4a0..000000000 --- a/src/plugins/avfoundation/mediaplayer/avfmediaplayercontrol.mm +++ /dev/null @@ -1,192 +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 "avfmediaplayercontrol.h" -#include "avfmediaplayersession.h" - -QT_USE_NAMESPACE - -AVFMediaPlayerControl::AVFMediaPlayerControl(QObject *parent) : - QMediaPlayerControl(parent) -{ -} - -AVFMediaPlayerControl::~AVFMediaPlayerControl() -{ -#ifdef QT_DEBUG_AVF - qDebug() << Q_FUNC_INFO; -#endif -} - -void AVFMediaPlayerControl::setSession(AVFMediaPlayerSession *session) -{ - m_session = session; - - connect(m_session, SIGNAL(positionChanged(qint64)), this, SIGNAL(positionChanged(qint64))); - connect(m_session, SIGNAL(durationChanged(qint64)), this, SIGNAL(durationChanged(qint64))); - connect(m_session, SIGNAL(bufferStatusChanged(int)), this, SIGNAL(bufferStatusChanged(int))); - connect(m_session, SIGNAL(stateChanged(QMediaPlayer::State)), - this, SIGNAL(stateChanged(QMediaPlayer::State))); - connect(m_session, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)), - this, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus))); - connect(m_session, SIGNAL(volumeChanged(int)), this, SIGNAL(volumeChanged(int))); - connect(m_session, SIGNAL(mutedChanged(bool)), this, SIGNAL(mutedChanged(bool))); - connect(m_session, SIGNAL(audioAvailableChanged(bool)), this, SIGNAL(audioAvailableChanged(bool))); - connect(m_session, SIGNAL(videoAvailableChanged(bool)), this, SIGNAL(videoAvailableChanged(bool))); - connect(m_session, SIGNAL(error(int,QString)), this, SIGNAL(error(int,QString))); - connect(m_session, &AVFMediaPlayerSession::playbackRateChanged, - this, &AVFMediaPlayerControl::playbackRateChanged); - connect(m_session, &AVFMediaPlayerSession::seekableChanged, - this, &AVFMediaPlayerControl::seekableChanged); -} - -QMediaPlayer::State AVFMediaPlayerControl::state() const -{ - return m_session->state(); -} - -QMediaPlayer::MediaStatus AVFMediaPlayerControl::mediaStatus() const -{ - return m_session->mediaStatus(); -} - -QMediaContent AVFMediaPlayerControl::media() const -{ - return m_session->media(); -} - -const QIODevice *AVFMediaPlayerControl::mediaStream() const -{ - return m_session->mediaStream(); -} - -void AVFMediaPlayerControl::setMedia(const QMediaContent &content, QIODevice *stream) -{ - const QMediaContent oldContent = m_session->media(); - - m_session->setMedia(content, stream); - - if (content != oldContent) - Q_EMIT mediaChanged(content); -} - -qint64 AVFMediaPlayerControl::position() const -{ - return m_session->position(); -} - -qint64 AVFMediaPlayerControl::duration() const -{ - return m_session->duration(); -} - -int AVFMediaPlayerControl::bufferStatus() const -{ - return m_session->bufferStatus(); -} - -int AVFMediaPlayerControl::volume() const -{ - return m_session->volume(); -} - -bool AVFMediaPlayerControl::isMuted() const -{ - return m_session->isMuted(); -} - -bool AVFMediaPlayerControl::isAudioAvailable() const -{ - return m_session->isAudioAvailable(); -} - -bool AVFMediaPlayerControl::isVideoAvailable() const -{ - return m_session->isVideoAvailable(); -} - -bool AVFMediaPlayerControl::isSeekable() const -{ - return m_session->isSeekable(); -} - -QMediaTimeRange AVFMediaPlayerControl::availablePlaybackRanges() const -{ - return m_session->availablePlaybackRanges(); -} - -qreal AVFMediaPlayerControl::playbackRate() const -{ - return m_session->playbackRate(); -} - -void AVFMediaPlayerControl::setPlaybackRate(qreal rate) -{ - m_session->setPlaybackRate(rate); -} - -void AVFMediaPlayerControl::setPosition(qint64 pos) -{ - m_session->setPosition(pos); -} - -void AVFMediaPlayerControl::play() -{ - m_session->play(); -} - -void AVFMediaPlayerControl::pause() -{ - m_session->pause(); -} - -void AVFMediaPlayerControl::stop() -{ - m_session->stop(); -} - -void AVFMediaPlayerControl::setVolume(int volume) -{ - m_session->setVolume(volume); -} - -void AVFMediaPlayerControl::setMuted(bool muted) -{ - m_session->setMuted(muted); -} diff --git a/src/plugins/avfoundation/mediaplayer/avfmediaplayermetadatacontrol.h b/src/plugins/avfoundation/mediaplayer/avfmediaplayermetadatacontrol.h deleted file mode 100644 index ae99c7eda..000000000 --- a/src/plugins/avfoundation/mediaplayer/avfmediaplayermetadatacontrol.h +++ /dev/null @@ -1,74 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** 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$ -** -****************************************************************************/ - -#ifndef AVFMEDIAPLAYERMETADATACONTROL_H -#define AVFMEDIAPLAYERMETADATACONTROL_H - -#include <QtMultimedia/QMetaDataReaderControl> - -QT_BEGIN_NAMESPACE - -class AVFMediaPlayerSession; - -class AVFMediaPlayerMetaDataControl : public QMetaDataReaderControl -{ - Q_OBJECT -public: - explicit AVFMediaPlayerMetaDataControl(AVFMediaPlayerSession *session, QObject *parent = nullptr); - virtual ~AVFMediaPlayerMetaDataControl(); - - bool isMetaDataAvailable() const override; - bool isWritable() const; - - QVariant metaData(const QString &key) const override; - QStringList availableMetaData() const override; - -private Q_SLOTS: - void updateTags(); - -private: - AVFMediaPlayerSession *m_session; - QVariantMap m_tags; - void *m_asset; - -}; - -QT_END_NAMESPACE - -#endif // AVFMEDIAPLAYERMETADATACONTROL_H diff --git a/src/plugins/avfoundation/mediaplayer/avfmediaplayermetadatacontrol.mm b/src/plugins/avfoundation/mediaplayer/avfmediaplayermetadatacontrol.mm deleted file mode 100644 index b9ec38c0f..000000000 --- a/src/plugins/avfoundation/mediaplayer/avfmediaplayermetadatacontrol.mm +++ /dev/null @@ -1,161 +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 "avfmediaplayermetadatacontrol.h" -#include "avfmediaplayersession.h" - -#include <QtMultimedia/qmediametadata.h> - -#import <AVFoundation/AVFoundation.h> - -QT_USE_NAMESPACE - -AVFMediaPlayerMetaDataControl::AVFMediaPlayerMetaDataControl(AVFMediaPlayerSession *session, QObject *parent) - : QMetaDataReaderControl(parent) - , m_session(session) - , m_asset(nullptr) -{ - QObject::connect(m_session, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)), this, SLOT(updateTags())); -} - -AVFMediaPlayerMetaDataControl::~AVFMediaPlayerMetaDataControl() -{ -#ifdef QT_DEBUG_AVF - qDebug() << Q_FUNC_INFO; -#endif -} - -bool AVFMediaPlayerMetaDataControl::isMetaDataAvailable() const -{ - return !m_tags.isEmpty(); -} - -bool AVFMediaPlayerMetaDataControl::isWritable() const -{ - return false; -} - -QVariant AVFMediaPlayerMetaDataControl::metaData(const QString &key) const -{ - return m_tags.value(key); -} - -QStringList AVFMediaPlayerMetaDataControl::availableMetaData() const -{ - return m_tags.keys(); -} - -static QString itemKey(AVMetadataItem *item) -{ - NSString *keyString = [item commonKey]; - - if (keyString.length != 0) { - if ([keyString isEqualToString:AVMetadataCommonKeyTitle]) { - return QMediaMetaData::Title; - } else if ([keyString isEqualToString: AVMetadataCommonKeySubject]) { - return QMediaMetaData::SubTitle; - } else if ([keyString isEqualToString: AVMetadataCommonKeyDescription]) { - return QMediaMetaData::Description; - } else if ([keyString isEqualToString: AVMetadataCommonKeyPublisher]) { - return QMediaMetaData::Publisher; - } else if ([keyString isEqualToString: AVMetadataCommonKeyCreationDate]) { - return QMediaMetaData::Date; - } else if ([keyString isEqualToString: AVMetadataCommonKeyType]) { - return QMediaMetaData::MediaType; - } else if ([keyString isEqualToString: AVMetadataCommonKeyLanguage]) { - return QMediaMetaData::Language; - } else if ([keyString isEqualToString: AVMetadataCommonKeyCopyrights]) { - return QMediaMetaData::Copyright; - } else if ([keyString isEqualToString: AVMetadataCommonKeyAlbumName]) { - return QMediaMetaData::AlbumTitle; - } else if ([keyString isEqualToString: AVMetadataCommonKeyAuthor]) { - return QMediaMetaData::Author; - } else if ([keyString isEqualToString: AVMetadataCommonKeyArtist]) { - return QMediaMetaData::ContributingArtist; - } else if ([keyString isEqualToString: AVMetadataCommonKeyArtwork]) { - return QMediaMetaData::PosterUrl; - } - } - - return QString(); -} - -void AVFMediaPlayerMetaDataControl::updateTags() -{ -#ifdef QT_DEBUG_AVF - qDebug() << Q_FUNC_INFO; -#endif - AVAsset *currentAsset = static_cast<AVAsset*>(m_session->currentAssetHandle()); - - //Don't read the tags from the same asset more than once - if (currentAsset == m_asset) - return; - - m_asset = currentAsset; - - QVariantMap oldTags = m_tags; - //Since we've changed assets, clear old tags - m_tags.clear(); - bool changed = false; - - // TODO: also process ID3, iTunes and QuickTime metadata - - NSArray *metadataItems = [currentAsset commonMetadata]; - for (AVMetadataItem* item in metadataItems) { - const QString key = itemKey(item); - if (!key.isEmpty()) { - const QString value = QString::fromNSString([item stringValue]); - if (!value.isNull()) { - m_tags.insert(key, value); - if (value != oldTags.value(key)) { - changed = true; - Q_EMIT metaDataChanged(key, value); - } - } - } - } - - if (oldTags.isEmpty() != m_tags.isEmpty()) { - Q_EMIT metaDataAvailableChanged(!m_tags.isEmpty()); - changed = true; - } - - if (changed) - Q_EMIT metaDataChanged(); -} diff --git a/src/plugins/avfoundation/mediaplayer/avfmediaplayerservice.h b/src/plugins/avfoundation/mediaplayer/avfmediaplayerservice.h deleted file mode 100644 index 6a4b915cf..000000000 --- a/src/plugins/avfoundation/mediaplayer/avfmediaplayerservice.h +++ /dev/null @@ -1,70 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** 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$ -** -****************************************************************************/ - -#ifndef AVFMEDIAPLAYERSERVICE_H -#define AVFMEDIAPLAYERSERVICE_H - -#include <QtMultimedia/QMediaService> - -QT_BEGIN_NAMESPACE - -class AVFMediaPlayerSession; -class AVFMediaPlayerControl; -class AVFMediaPlayerMetaDataControl; -class AVFVideoOutput; - -class AVFMediaPlayerService : public QMediaService -{ -public: - explicit AVFMediaPlayerService(QObject *parent = nullptr); - ~AVFMediaPlayerService(); - - QMediaControl* requestControl(const char *name) override; - void releaseControl(QMediaControl *control) override; - -private: - AVFMediaPlayerSession *m_session; - AVFMediaPlayerControl *m_control; - QMediaControl *m_videoOutput; - AVFMediaPlayerMetaDataControl *m_playerMetaDataControl; -}; - -QT_END_NAMESPACE - -#endif // AVFMEDIAPLAYERSERVICE_H diff --git a/src/plugins/avfoundation/mediaplayer/avfmediaplayerservice.mm b/src/plugins/avfoundation/mediaplayer/avfmediaplayerservice.mm deleted file mode 100644 index bc59fa921..000000000 --- a/src/plugins/avfoundation/mediaplayer/avfmediaplayerservice.mm +++ /dev/null @@ -1,134 +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 "avfmediaplayerservice.h" -#include "avfmediaplayersession.h" -#include "avfmediaplayercontrol.h" -#include "avfmediaplayermetadatacontrol.h" -#include "avfvideooutput.h" -#if QT_CONFIG(opengl) -#include "avfvideorenderercontrol.h" -#endif -#ifndef QT_NO_WIDGETS -# include "avfvideowidgetcontrol.h" -#endif -#include "avfvideowindowcontrol.h" - -#import <AVFoundation/AVFoundation.h> - -QT_USE_NAMESPACE - -AVFMediaPlayerService::AVFMediaPlayerService(QObject *parent) - : QMediaService(parent) - , m_videoOutput(nullptr) -{ - m_session = new AVFMediaPlayerSession(this); - m_control = new AVFMediaPlayerControl(this); - m_control->setSession(m_session); - m_playerMetaDataControl = new AVFMediaPlayerMetaDataControl(m_session, this); - - connect(m_control, SIGNAL(mediaChanged(QMediaContent)), m_playerMetaDataControl, SLOT(updateTags())); -} - -AVFMediaPlayerService::~AVFMediaPlayerService() -{ -#ifdef QT_DEBUG_AVF - qDebug() << Q_FUNC_INFO; -#endif - delete m_session; -} - -QMediaControl *AVFMediaPlayerService::requestControl(const char *name) -{ -#ifdef QT_DEBUG_AVF - qDebug() << Q_FUNC_INFO << name; -#endif - - if (qstrcmp(name, QMediaPlayerControl_iid) == 0) - return m_control; - - if (qstrcmp(name, QMetaDataReaderControl_iid) == 0) - return m_playerMetaDataControl; - -#if QT_CONFIG(opengl) - if (qstrcmp(name, QVideoRendererControl_iid) == 0) { - if (!m_videoOutput) - m_videoOutput = new AVFVideoRendererControl(this); - - m_session->setVideoOutput(qobject_cast<AVFVideoOutput*>(m_videoOutput)); - return m_videoOutput; - } -#endif -#ifndef QT_NO_WIDGETS - if (qstrcmp(name, QVideoWidgetControl_iid) == 0) { - if (!m_videoOutput) - m_videoOutput = new AVFVideoWidgetControl(this); - - m_session->setVideoOutput(qobject_cast<AVFVideoOutput*>(m_videoOutput)); - return m_videoOutput; - } -#endif - if (qstrcmp(name, QVideoWindowControl_iid) == 0) { - if (!m_videoOutput) - m_videoOutput = new AVFVideoWindowControl(this); - - m_session->setVideoOutput(qobject_cast<AVFVideoOutput*>(m_videoOutput)); - return m_videoOutput; - } - return nullptr; -} - -void AVFMediaPlayerService::releaseControl(QMediaControl *control) -{ -#ifdef QT_DEBUG_AVF - qDebug() << Q_FUNC_INFO << control; -#endif - if (m_videoOutput == control) { -#if QT_CONFIG(opengl) - AVFVideoRendererControl *renderControl = qobject_cast<AVFVideoRendererControl*>(m_videoOutput); - - if (renderControl) - renderControl->setSurface(nullptr); -#endif - m_videoOutput = nullptr; - m_session->setVideoOutput(nullptr); - - delete control; - } -} diff --git a/src/plugins/avfoundation/mediaplayer/avfmediaplayerserviceplugin.h b/src/plugins/avfoundation/mediaplayer/avfmediaplayerserviceplugin.h deleted file mode 100644 index e08f0f46e..000000000 --- a/src/plugins/avfoundation/mediaplayer/avfmediaplayerserviceplugin.h +++ /dev/null @@ -1,77 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** 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$ -** -****************************************************************************/ - - -#ifndef AVFMEDIAPLAYERSERVICEPLUGIN_H -#define AVFMEDIAPLAYERSERVICEPLUGIN_H - -#include <QtCore/qglobal.h> -#include <QtMultimedia/qmediaserviceproviderplugin.h> - -QT_BEGIN_NAMESPACE - -class AVFMediaPlayerServicePlugin - : public QMediaServiceProviderPlugin - , public QMediaServiceSupportedFormatsInterface - , public QMediaServiceFeaturesInterface -{ - Q_OBJECT - Q_INTERFACES(QMediaServiceSupportedFormatsInterface) - Q_INTERFACES(QMediaServiceFeaturesInterface) - Q_PLUGIN_METADATA(IID "org.qt-project.qt.mediaserviceproviderfactory/5.0" FILE "avfmediaplayer.json") - -public: - explicit AVFMediaPlayerServicePlugin(); - - QMediaService* create(QString const& key) override; - void release(QMediaService *service) override; - - QMediaServiceProviderHint::Features supportedFeatures(const QByteArray &service) const override; - QMultimedia::SupportEstimate hasSupport(const QString &mimeType, const QStringList& codecs) const override; - QStringList supportedMimeTypes() const override; - -private: - void buildSupportedTypes(); - - QStringList m_supportedMimeTypes; -}; - -QT_END_NAMESPACE - -#endif // AVFMEDIAPLAYERSERVICEPLUGIN_H diff --git a/src/plugins/avfoundation/mediaplayer/avfmediaplayerserviceplugin.mm b/src/plugins/avfoundation/mediaplayer/avfmediaplayerserviceplugin.mm deleted file mode 100644 index 59b29a3d2..000000000 --- a/src/plugins/avfoundation/mediaplayer/avfmediaplayerserviceplugin.mm +++ /dev/null @@ -1,107 +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 "avfmediaplayerserviceplugin.h" -#include <QtCore/QDebug> - -#include "avfmediaplayerservice.h" - -#import <AVFoundation/AVFoundation.h> - -QT_USE_NAMESPACE - -AVFMediaPlayerServicePlugin::AVFMediaPlayerServicePlugin() -{ - buildSupportedTypes(); -} - -QMediaService *AVFMediaPlayerServicePlugin::create(const QString &key) -{ -#ifdef QT_DEBUG_AVF - qDebug() << "AVFMediaPlayerServicePlugin::create" << key; -#endif - if (key == QLatin1String(Q_MEDIASERVICE_MEDIAPLAYER)) - return new AVFMediaPlayerService; - - qWarning() << "unsupported key: " << key; - return nullptr; -} - -void AVFMediaPlayerServicePlugin::release(QMediaService *service) -{ - delete service; -} - -QMediaServiceProviderHint::Features AVFMediaPlayerServicePlugin::supportedFeatures(const QByteArray &service) const -{ - if (service == Q_MEDIASERVICE_MEDIAPLAYER) - return QMediaServiceProviderHint::VideoSurface; - else - return QMediaServiceProviderHint::Features(); -} - -QMultimedia::SupportEstimate AVFMediaPlayerServicePlugin::hasSupport(const QString &mimeType, const QStringList &codecs) const -{ - Q_UNUSED(codecs); - - if (m_supportedMimeTypes.contains(mimeType)) - return QMultimedia::ProbablySupported; - - return QMultimedia::MaybeSupported; -} - -QStringList AVFMediaPlayerServicePlugin::supportedMimeTypes() const -{ - return m_supportedMimeTypes; -} - -void AVFMediaPlayerServicePlugin::buildSupportedTypes() -{ - //Populate m_supportedMimeTypes with mimetypes AVAsset supports - NSArray *mimeTypes = [AVURLAsset audiovisualMIMETypes]; - for (NSString *mimeType in mimeTypes) - { - m_supportedMimeTypes.append(QString::fromUtf8([mimeType UTF8String])); - } -#ifdef QT_DEBUG_AVF - qDebug() << "AVFMediaPlayerServicePlugin::buildSupportedTypes"; - qDebug() << "Supported Types: " << m_supportedMimeTypes; -#endif - -} diff --git a/src/plugins/avfoundation/mediaplayer/avfmediaplayersession.h b/src/plugins/avfoundation/mediaplayer/avfmediaplayersession.h deleted file mode 100644 index db29e88aa..000000000 --- a/src/plugins/avfoundation/mediaplayer/avfmediaplayersession.h +++ /dev/null @@ -1,161 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** 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$ -** -****************************************************************************/ - -#ifndef AVFMEDIAPLAYERSESSION_H -#define AVFMEDIAPLAYERSESSION_H - -#include <QtCore/QObject> -#include <QtCore/QByteArray> -#include <QtCore/QSet> -#include <QtCore/QResource> - -#include <QtMultimedia/QMediaPlayerControl> -#include <QtMultimedia/QMediaPlayer> - -QT_BEGIN_NAMESPACE - -class AVFMediaPlayerService; -class AVFVideoOutput; - -class AVFMediaPlayerSession : public QObject -{ - Q_OBJECT -public: - AVFMediaPlayerSession(AVFMediaPlayerService *service, QObject *parent = nullptr); - virtual ~AVFMediaPlayerSession(); - - void setVideoOutput(AVFVideoOutput *output); - void *currentAssetHandle(); - - QMediaPlayer::State state() const; - QMediaPlayer::MediaStatus mediaStatus() const; - - QMediaContent media() const; - QIODevice *mediaStream() const; - void setMedia(const QMediaContent &content, QIODevice *stream); - - qint64 position() const; - qint64 duration() const; - - int bufferStatus() const; - - int volume() const; - bool isMuted() const; - - bool isAudioAvailable() const; - bool isVideoAvailable() const; - - bool isSeekable() const; - QMediaTimeRange availablePlaybackRanges() const; - - qreal playbackRate() const; - -public Q_SLOTS: - void setPlaybackRate(qreal rate); - - void setPosition(qint64 pos); - - void play(); - void pause(); - void stop(); - - void setVolume(int volume); - void setMuted(bool muted); - - void processEOS(); - void processLoadStateChange(QMediaPlayer::State newState); - void processPositionChange(); - void processMediaLoadError(); - - void processLoadStateChange(); - void processLoadStateFailure(); - - void processBufferStateChange(int bufferStatus); - - void processDurationChange(qint64 duration); - - void streamReady(); - void streamDestroyed(); - -Q_SIGNALS: - void positionChanged(qint64 position); - void durationChanged(qint64 duration); - void stateChanged(QMediaPlayer::State newState); - void bufferStatusChanged(int bufferStatus); - void mediaStatusChanged(QMediaPlayer::MediaStatus status); - void volumeChanged(int volume); - void mutedChanged(bool muted); - void audioAvailableChanged(bool audioAvailable); - void videoAvailableChanged(bool videoAvailable); - void playbackRateChanged(qreal rate); - void seekableChanged(bool seekable); - void error(int error, const QString &errorString); - -private: - void setAudioAvailable(bool available); - void setVideoAvailable(bool available); - void setSeekable(bool seekable); - void resetStream(QIODevice *stream = nullptr); - - AVFMediaPlayerService *m_service; - AVFVideoOutput *m_videoOutput; - - QMediaPlayer::State m_state; - QMediaPlayer::MediaStatus m_mediaStatus; - QIODevice *m_mediaStream; - QMediaContent m_resources; - - bool m_muted; - bool m_tryingAsync; - int m_volume; - qreal m_rate; - qint64 m_requestedPosition; - - qint64 m_duration; - int m_bufferStatus; - bool m_videoAvailable; - bool m_audioAvailable; - bool m_seekable; - - void *m_observer; -}; - -QT_END_NAMESPACE - -#endif // AVFMEDIAPLAYERSESSION_H diff --git a/src/plugins/avfoundation/mediaplayer/avfmediaplayersession.mm b/src/plugins/avfoundation/mediaplayer/avfmediaplayersession.mm deleted file mode 100644 index 95121f58a..000000000 --- a/src/plugins/avfoundation/mediaplayer/avfmediaplayersession.mm +++ /dev/null @@ -1,1067 +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 "avfmediaplayersession.h" -#include "avfmediaplayerservice.h" -#include "avfvideooutput.h" - -#include <qpointer.h> -#include <QFileInfo> - -#import <AVFoundation/AVFoundation.h> - -QT_USE_NAMESPACE - -//AVAsset Keys -static NSString* const AVF_TRACKS_KEY = @"tracks"; -static NSString* const AVF_PLAYABLE_KEY = @"playable"; - -//AVPlayerItem keys -static NSString* const AVF_STATUS_KEY = @"status"; -static NSString* const AVF_BUFFER_LIKELY_KEEP_UP_KEY = @"playbackLikelyToKeepUp"; - -//AVPlayer keys -static NSString* const AVF_RATE_KEY = @"rate"; -static NSString* const AVF_CURRENT_ITEM_KEY = @"currentItem"; -static NSString* const AVF_CURRENT_ITEM_DURATION_KEY = @"currentItem.duration"; - -static void *AVFMediaPlayerSessionObserverRateObservationContext = &AVFMediaPlayerSessionObserverRateObservationContext; -static void *AVFMediaPlayerSessionObserverStatusObservationContext = &AVFMediaPlayerSessionObserverStatusObservationContext; -static void *AVFMediaPlayerSessionObserverBufferLikelyToKeepUpContext = &AVFMediaPlayerSessionObserverBufferLikelyToKeepUpContext; -static void *AVFMediaPlayerSessionObserverCurrentItemObservationContext = &AVFMediaPlayerSessionObserverCurrentItemObservationContext; -static void *AVFMediaPlayerSessionObserverCurrentItemDurationObservationContext = &AVFMediaPlayerSessionObserverCurrentItemDurationObservationContext; - -@interface AVFMediaPlayerSessionObserver : NSObject<AVAssetResourceLoaderDelegate> - -@property (readonly, getter=player) AVPlayer* m_player; -@property (readonly, getter=playerItem) AVPlayerItem* m_playerItem; -@property (readonly, getter=playerLayer) AVPlayerLayer* m_playerLayer; -@property (readonly, getter=session) AVFMediaPlayerSession* m_session; - -- (AVFMediaPlayerSessionObserver *) initWithMediaPlayerSession:(AVFMediaPlayerSession *)session; -- (void) setURL:(NSURL *)url mimeType:(NSString *)mimeType; -- (void) unloadMedia; -- (void) prepareToPlayAsset:(AVURLAsset *)asset withKeys:(NSArray *)requestedKeys; -- (void) assetFailedToPrepareForPlayback:(NSError *)error; -- (void) playerItemDidReachEnd:(NSNotification *)notification; -- (void) playerItemTimeJumped:(NSNotification *)notification; -- (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object - change:(NSDictionary *)change context:(void *)context; -- (void) detatchSession; -- (void) dealloc; -- (BOOL) resourceLoader:(AVAssetResourceLoader *)resourceLoader shouldWaitForLoadingOfRequestedResource:(AVAssetResourceLoadingRequest *)loadingRequest; -@end - -@implementation AVFMediaPlayerSessionObserver -{ -@private - AVFMediaPlayerSession *m_session; - AVPlayer *m_player; - AVPlayerItem *m_playerItem; - AVPlayerLayer *m_playerLayer; - NSURL *m_URL; - BOOL m_bufferIsLikelyToKeepUp; - NSData *m_data; - NSString *m_mimeType; -} - -@synthesize m_player, m_playerItem, m_playerLayer, m_session; - -- (AVFMediaPlayerSessionObserver *) initWithMediaPlayerSession:(AVFMediaPlayerSession *)session -{ - if (!(self = [super init])) - return nil; - - self->m_session = session; - self->m_bufferIsLikelyToKeepUp = FALSE; - return self; -} - -- (void) setURL:(NSURL *)url mimeType:(NSString *)mimeType -{ - [m_mimeType release]; - m_mimeType = [mimeType retain]; - - if (m_URL != url) - { - [m_URL release]; - m_URL = [url copy]; - - //Create an asset for inspection of a resource referenced by a given URL. - //Load the values for the asset keys "tracks", "playable". - - // use __block to avoid maintaining strong references on variables captured by the - // following block callback - __block AVURLAsset *asset = [[AVURLAsset URLAssetWithURL:m_URL options:nil] retain]; - [asset.resourceLoader setDelegate:self queue:dispatch_get_main_queue()]; - - __block NSArray *requestedKeys = [[NSArray arrayWithObjects:AVF_TRACKS_KEY, AVF_PLAYABLE_KEY, nil] retain]; - - __block AVFMediaPlayerSessionObserver *blockSelf = self; - QPointer<AVFMediaPlayerSession> session(m_session); - - // Tells the asset to load the values of any of the specified keys that are not already loaded. - [asset loadValuesAsynchronouslyForKeys:requestedKeys completionHandler: - ^{ - dispatch_async( dispatch_get_main_queue(), - ^{ - if (session) - [blockSelf prepareToPlayAsset:asset withKeys:requestedKeys]; - [asset release]; - [requestedKeys release]; - }); - }]; - } -} - -- (void) unloadMedia -{ - if (m_playerItem) { - [m_playerItem removeObserver:self forKeyPath:AVF_STATUS_KEY]; - [m_playerItem removeObserver:self forKeyPath:AVF_BUFFER_LIKELY_KEEP_UP_KEY]; - - [[NSNotificationCenter defaultCenter] removeObserver:self - name:AVPlayerItemDidPlayToEndTimeNotification - object:m_playerItem]; - [[NSNotificationCenter defaultCenter] removeObserver:self - name:AVPlayerItemTimeJumpedNotification - object:m_playerItem]; - m_playerItem = 0; - } - if (m_player) { - [m_player setRate:0.0]; - [m_player removeObserver:self forKeyPath:AVF_CURRENT_ITEM_DURATION_KEY]; - [m_player removeObserver:self forKeyPath:AVF_CURRENT_ITEM_KEY]; - [m_player removeObserver:self forKeyPath:AVF_RATE_KEY]; - [m_player release]; - m_player = 0; - } - if (m_playerLayer) { - [m_playerLayer release]; - m_playerLayer = 0; - } -#if defined(Q_OS_IOS) - [[AVAudioSession sharedInstance] setActive:NO error:nil]; -#endif -} - -- (void) prepareToPlayAsset:(AVURLAsset *)asset - withKeys:(NSArray *)requestedKeys -{ - //Make sure that the value of each key has loaded successfully. - for (NSString *thisKey in requestedKeys) - { - NSError *error = nil; - AVKeyValueStatus keyStatus = [asset statusOfValueForKey:thisKey error:&error]; -#ifdef QT_DEBUG_AVF - qDebug() << Q_FUNC_INFO << [thisKey UTF8String] << " status: " << keyStatus; -#endif - if (keyStatus == AVKeyValueStatusFailed) - { - [self assetFailedToPrepareForPlayback:error]; - return; - } - } - - //Use the AVAsset playable property to detect whether the asset can be played. -#ifdef QT_DEBUG_AVF - qDebug() << Q_FUNC_INFO << "isPlayable: " << [asset isPlayable]; -#endif - if (!asset.playable) - { - //Generate an error describing the failure. - NSString *localizedDescription = NSLocalizedString(@"Item cannot be played", @"Item cannot be played description"); - NSString *localizedFailureReason = NSLocalizedString(@"The assets tracks were loaded, but could not be made playable.", @"Item cannot be played failure reason"); - NSDictionary *errorDict = [NSDictionary dictionaryWithObjectsAndKeys: - localizedDescription, NSLocalizedDescriptionKey, - localizedFailureReason, NSLocalizedFailureReasonErrorKey, - nil]; - NSError *assetCannotBePlayedError = [NSError errorWithDomain:@"StitchedStreamPlayer" code:0 userInfo:errorDict]; - - [self assetFailedToPrepareForPlayback:assetCannotBePlayedError]; - - return; - } - - //At this point we're ready to set up for playback of the asset. - //Stop observing our prior AVPlayerItem, if we have one. - if (m_playerItem) - { - //Remove existing player item key value observers and notifications. - [self unloadMedia]; - } - - //Create a new instance of AVPlayerItem from the now successfully loaded AVAsset. - m_playerItem = [AVPlayerItem playerItemWithAsset:asset]; - - //Observe the player item "status" key to determine when it is ready to play. - [m_playerItem addObserver:self - forKeyPath:AVF_STATUS_KEY - options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew - context:AVFMediaPlayerSessionObserverStatusObservationContext]; - - [m_playerItem addObserver:self - forKeyPath:AVF_BUFFER_LIKELY_KEEP_UP_KEY - options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew - context:AVFMediaPlayerSessionObserverBufferLikelyToKeepUpContext]; - - //When the player item has played to its end time we'll toggle - //the movie controller Pause button to be the Play button - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(playerItemDidReachEnd:) - name:AVPlayerItemDidPlayToEndTimeNotification - object:m_playerItem]; - - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(playerItemTimeJumped:) - name:AVPlayerItemTimeJumpedNotification - object:m_playerItem]; - - //Get a new AVPlayer initialized to play the specified player item. - m_player = [AVPlayer playerWithPlayerItem:m_playerItem]; - [m_player retain]; - - //Set the initial volume on new player object - if (self.session) { - [m_player setVolume:m_session->volume() / 100.0f]; - [m_player setMuted:m_session->isMuted()]; - } - - //Create a new player layer if we don't have one already - if (!m_playerLayer) - { - m_playerLayer = [AVPlayerLayer playerLayerWithPlayer:m_player]; - [m_playerLayer retain]; - m_playerLayer.videoGravity = AVLayerVideoGravityResizeAspectFill; - m_playerLayer.anchorPoint = CGPointMake(0.0f, 0.0f); - } - - //Observe the AVPlayer "currentItem" property to find out when any - //AVPlayer replaceCurrentItemWithPlayerItem: replacement will/did - //occur. - [m_player addObserver:self - forKeyPath:AVF_CURRENT_ITEM_KEY - options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew - context:AVFMediaPlayerSessionObserverCurrentItemObservationContext]; - - //Observe the AVPlayer "rate" property to update the scrubber control. - [m_player addObserver:self - forKeyPath:AVF_RATE_KEY - options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew - context:AVFMediaPlayerSessionObserverRateObservationContext]; - - //Observe the duration for getting the buffer state - [m_player addObserver:self - forKeyPath:AVF_CURRENT_ITEM_DURATION_KEY - options:0 - context:AVFMediaPlayerSessionObserverCurrentItemDurationObservationContext]; -#if defined(Q_OS_IOS) - [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback withOptions:AVAudioSessionCategoryOptionMixWithOthers error:nil]; - [[AVAudioSession sharedInstance] setActive:YES error:nil]; -#endif -} - --(void) assetFailedToPrepareForPlayback:(NSError *)error -{ - Q_UNUSED(error); - QMetaObject::invokeMethod(m_session, "processMediaLoadError", Qt::AutoConnection); -#ifdef QT_DEBUG_AVF - qDebug() << Q_FUNC_INFO; - qDebug() << [[error localizedDescription] UTF8String]; - qDebug() << [[error localizedFailureReason] UTF8String]; - qDebug() << [[error localizedRecoverySuggestion] UTF8String]; -#endif -} - -- (void) playerItemDidReachEnd:(NSNotification *)notification -{ - Q_UNUSED(notification); - if (self.session) - QMetaObject::invokeMethod(m_session, "processEOS", Qt::AutoConnection); -} - -- (void) playerItemTimeJumped:(NSNotification *)notification -{ - Q_UNUSED(notification); - if (self.session) - QMetaObject::invokeMethod(m_session, "processPositionChange", Qt::AutoConnection); -} - -- (void) observeValueForKeyPath:(NSString*) path - ofObject:(id)object - change:(NSDictionary*)change - context:(void*)context -{ - //AVPlayerItem "status" property value observer. - if (context == AVFMediaPlayerSessionObserverStatusObservationContext) - { - AVPlayerStatus status = (AVPlayerStatus)[[change objectForKey:NSKeyValueChangeNewKey] integerValue]; - switch (status) - { - //Indicates that the status of the player is not yet known because - //it has not tried to load new media resources for playback - case AVPlayerStatusUnknown: - { - //QMetaObject::invokeMethod(m_session, "processLoadStateChange", Qt::AutoConnection); - } - break; - - case AVPlayerStatusReadyToPlay: - { - //Once the AVPlayerItem becomes ready to play, i.e. - //[playerItem status] == AVPlayerItemStatusReadyToPlay, - //its duration can be fetched from the item. - if (self.session) - QMetaObject::invokeMethod(m_session, "processLoadStateChange", Qt::AutoConnection); - } - break; - - case AVPlayerStatusFailed: - { - AVPlayerItem *playerItem = static_cast<AVPlayerItem*>(object); - [self assetFailedToPrepareForPlayback:playerItem.error]; - - if (self.session) - QMetaObject::invokeMethod(m_session, "processLoadStateFailure", Qt::AutoConnection); - } - break; - } - } - else if (context == AVFMediaPlayerSessionObserverBufferLikelyToKeepUpContext) - { - const bool isPlaybackLikelyToKeepUp = [m_playerItem isPlaybackLikelyToKeepUp]; - if (isPlaybackLikelyToKeepUp != m_bufferIsLikelyToKeepUp) { - m_bufferIsLikelyToKeepUp = isPlaybackLikelyToKeepUp; - QMetaObject::invokeMethod(m_session, "processBufferStateChange", Qt::AutoConnection, - Q_ARG(int, isPlaybackLikelyToKeepUp ? 100 : 0)); - } - } - //AVPlayer "rate" property value observer. - else if (context == AVFMediaPlayerSessionObserverRateObservationContext) - { - //QMetaObject::invokeMethod(m_session, "setPlaybackRate", Qt::AutoConnection, Q_ARG(qreal, [m_player rate])); - } - //AVPlayer "currentItem" property observer. - //Called when the AVPlayer replaceCurrentItemWithPlayerItem: - //replacement will/did occur. - else if (context == AVFMediaPlayerSessionObserverCurrentItemObservationContext) - { - AVPlayerItem *newPlayerItem = [change objectForKey:NSKeyValueChangeNewKey]; - if (m_playerItem != newPlayerItem) - m_playerItem = newPlayerItem; - } - else if (context == AVFMediaPlayerSessionObserverCurrentItemDurationObservationContext) - { - const CMTime time = [m_playerItem duration]; - const qint64 duration = static_cast<qint64>(float(time.value) / float(time.timescale) * 1000.0f); - if (self.session) - QMetaObject::invokeMethod(m_session, "processDurationChange", Qt::AutoConnection, Q_ARG(qint64, duration)); - } - else - { - [super observeValueForKeyPath:path ofObject:object change:change context:context]; - } -} - -- (void) detatchSession -{ -#ifdef QT_DEBUG_AVF - qDebug() << Q_FUNC_INFO; -#endif - m_session = 0; -} - -- (void) dealloc -{ -#ifdef QT_DEBUG_AVF - qDebug() << Q_FUNC_INFO; -#endif - [self unloadMedia]; - - if (m_URL) { - [m_URL release]; - } - - [m_mimeType release]; - [super dealloc]; -} - -- (BOOL) resourceLoader:(AVAssetResourceLoader *)resourceLoader shouldWaitForLoadingOfRequestedResource:(AVAssetResourceLoadingRequest *)loadingRequest -{ - Q_UNUSED(resourceLoader); - - if (![loadingRequest.request.URL.scheme isEqualToString:@"iodevice"]) - return NO; - - QIODevice *device = m_session->mediaStream(); - if (!device) - return NO; - - device->seek(loadingRequest.dataRequest.requestedOffset); - if (loadingRequest.contentInformationRequest) { - loadingRequest.contentInformationRequest.contentType = m_mimeType; - loadingRequest.contentInformationRequest.contentLength = device->size(); - loadingRequest.contentInformationRequest.byteRangeAccessSupported = YES; - } - - if (loadingRequest.dataRequest) { - NSInteger requestedLength = loadingRequest.dataRequest.requestedLength; - int maxBytes = qMin(32 * 1064, int(requestedLength)); - char buffer[maxBytes]; - NSInteger submitted = 0; - while (submitted < requestedLength) { - qint64 len = device->read(buffer, maxBytes); - if (len < 1) - break; - - [loadingRequest.dataRequest respondWithData:[NSData dataWithBytes:buffer length:len]]; - submitted += len; - } - - // Finish loading even if not all bytes submitted. - [loadingRequest finishLoading]; - } - - return YES; -} -@end - -AVFMediaPlayerSession::AVFMediaPlayerSession(AVFMediaPlayerService *service, QObject *parent) - : QObject(parent) - , m_service(service) - , m_videoOutput(nullptr) - , m_state(QMediaPlayer::StoppedState) - , m_mediaStatus(QMediaPlayer::NoMedia) - , m_mediaStream(nullptr) - , m_muted(false) - , m_tryingAsync(false) - , m_volume(100) - , m_rate(1.0) - , m_requestedPosition(-1) - , m_duration(0) - , m_bufferStatus(0) - , m_videoAvailable(false) - , m_audioAvailable(false) - , m_seekable(false) -{ - m_observer = [[AVFMediaPlayerSessionObserver alloc] initWithMediaPlayerSession:this]; -} - -AVFMediaPlayerSession::~AVFMediaPlayerSession() -{ -#ifdef QT_DEBUG_AVF - qDebug() << Q_FUNC_INFO; -#endif - //Detatch the session from the sessionObserver (which could still be alive trying to communicate with this session). - [static_cast<AVFMediaPlayerSessionObserver*>(m_observer) detatchSession]; - [static_cast<AVFMediaPlayerSessionObserver*>(m_observer) release]; -} - -void AVFMediaPlayerSession::setVideoOutput(AVFVideoOutput *output) -{ -#ifdef QT_DEBUG_AVF - qDebug() << Q_FUNC_INFO << output; -#endif - - if (m_videoOutput == output) - return; - - //Set the current output layer to null to stop rendering - if (m_videoOutput) { - m_videoOutput->setLayer(nullptr); - } - - m_videoOutput = output; - - if (m_videoOutput && m_state != QMediaPlayer::StoppedState) - m_videoOutput->setLayer([static_cast<AVFMediaPlayerSessionObserver*>(m_observer) playerLayer]); -} - -void *AVFMediaPlayerSession::currentAssetHandle() -{ -#ifdef QT_DEBUG_AVF - qDebug() << Q_FUNC_INFO; -#endif - AVAsset *currentAsset = [[static_cast<AVFMediaPlayerSessionObserver*>(m_observer) playerItem] asset]; - return currentAsset; -} - -QMediaPlayer::State AVFMediaPlayerSession::state() const -{ - return m_state; -} - -QMediaPlayer::MediaStatus AVFMediaPlayerSession::mediaStatus() const -{ - return m_mediaStatus; -} - -QMediaContent AVFMediaPlayerSession::media() const -{ - return m_resources; -} - -QIODevice *AVFMediaPlayerSession::mediaStream() const -{ - return m_mediaStream; -} - -static void setURL(void *observer, const QByteArray &url, const QString &mimeType = QString()) -{ - NSString *urlString = [NSString stringWithUTF8String:url.constData()]; - NSURL *nsurl = [NSURL URLWithString:urlString]; - [static_cast<AVFMediaPlayerSessionObserver*>(observer) setURL:nsurl mimeType:[NSString stringWithUTF8String:mimeType.toLatin1().constData()]]; -} - -static void setStreamURL(void *observer, const QByteArray &url) -{ - setURL(observer, QByteArrayLiteral("iodevice://") + url, QFileInfo(url).suffix()); -} - -void AVFMediaPlayerSession::setMedia(const QMediaContent &content, QIODevice *stream) -{ -#ifdef QT_DEBUG_AVF - qDebug() << Q_FUNC_INFO << content.request().url(); -#endif - - [static_cast<AVFMediaPlayerSessionObserver*>(m_observer) unloadMedia]; - - m_resources = content; - resetStream(stream); - - setAudioAvailable(false); - setVideoAvailable(false); - setSeekable(false); - m_requestedPosition = -1; - Q_EMIT positionChanged(position()); - - const QMediaPlayer::MediaStatus oldMediaStatus = m_mediaStatus; - const QMediaPlayer::State oldState = m_state; - - if (!m_mediaStream && (content.isNull() || content.request().url().isEmpty())) { - m_mediaStatus = QMediaPlayer::NoMedia; - if (m_mediaStatus != oldMediaStatus) - Q_EMIT mediaStatusChanged(m_mediaStatus); - - m_state = QMediaPlayer::StoppedState; - if (m_state != oldState) - Q_EMIT stateChanged(m_state); - - return; - } - - m_mediaStatus = QMediaPlayer::LoadingMedia; - if (m_mediaStatus != oldMediaStatus) - Q_EMIT mediaStatusChanged(m_mediaStatus); - - if (m_mediaStream) { - // If there is a data, try to load it, - // otherwise wait for readyRead. - if (m_mediaStream->size()) - setStreamURL(m_observer, m_resources.request().url().toEncoded()); - } else { - //Load AVURLAsset - //initialize asset using content's URL - setURL(m_observer, m_resources.request().url().toEncoded()); - } - - m_state = QMediaPlayer::StoppedState; - if (m_state != oldState) - Q_EMIT stateChanged(m_state); -} - -qint64 AVFMediaPlayerSession::position() const -{ - AVPlayerItem *playerItem = [static_cast<AVFMediaPlayerSessionObserver*>(m_observer) playerItem]; - - if (!playerItem) - return m_requestedPosition != -1 ? m_requestedPosition : 0; - - CMTime time = [playerItem currentTime]; - return static_cast<quint64>(float(time.value) / float(time.timescale) * 1000.0f); -} - -qint64 AVFMediaPlayerSession::duration() const -{ -#ifdef QT_DEBUG_AVF - qDebug() << Q_FUNC_INFO; -#endif - return m_duration; -} - -int AVFMediaPlayerSession::bufferStatus() const -{ -#ifdef QT_DEBUG_AVF - qDebug() << Q_FUNC_INFO; -#endif - return m_bufferStatus; -} - -int AVFMediaPlayerSession::volume() const -{ - return m_volume; -} - -bool AVFMediaPlayerSession::isMuted() const -{ - return m_muted; -} - -void AVFMediaPlayerSession::setAudioAvailable(bool available) -{ - if (m_audioAvailable == available) - return; - - m_audioAvailable = available; - Q_EMIT audioAvailableChanged(available); -} - -bool AVFMediaPlayerSession::isAudioAvailable() const -{ - return m_audioAvailable; -} - -void AVFMediaPlayerSession::setVideoAvailable(bool available) -{ - if (m_videoAvailable == available) - return; - - m_videoAvailable = available; - Q_EMIT videoAvailableChanged(available); -} - -bool AVFMediaPlayerSession::isVideoAvailable() const -{ - return m_videoAvailable; -} - -bool AVFMediaPlayerSession::isSeekable() const -{ - return m_seekable; -} - -void AVFMediaPlayerSession::setSeekable(bool seekable) -{ - if (m_seekable == seekable) - return; - - m_seekable = seekable; - Q_EMIT seekableChanged(seekable); -} - -QMediaTimeRange AVFMediaPlayerSession::availablePlaybackRanges() const -{ - AVPlayerItem *playerItem = [static_cast<AVFMediaPlayerSessionObserver*>(m_observer) playerItem]; - - if (playerItem) { - QMediaTimeRange timeRanges; - - NSArray *ranges = [playerItem loadedTimeRanges]; - for (NSValue *timeRange in ranges) { - CMTimeRange currentTimeRange = [timeRange CMTimeRangeValue]; - qint64 startTime = qint64(float(currentTimeRange.start.value) / currentTimeRange.start.timescale * 1000.0); - timeRanges.addInterval(startTime, startTime + qint64(float(currentTimeRange.duration.value) / currentTimeRange.duration.timescale * 1000.0)); - } - if (!timeRanges.isEmpty()) - return timeRanges; - } - return QMediaTimeRange(0, duration()); -} - -qreal AVFMediaPlayerSession::playbackRate() const -{ - return m_rate; -} - -void AVFMediaPlayerSession::setPlaybackRate(qreal rate) -{ -#ifdef QT_DEBUG_AVF - qDebug() << Q_FUNC_INFO << rate; -#endif - - if (qFuzzyCompare(m_rate, rate)) - return; - - m_rate = rate; - - AVPlayer *player = [static_cast<AVFMediaPlayerSessionObserver*>(m_observer) player]; - if (player && m_state == QMediaPlayer::PlayingState) - [player setRate:m_rate]; - - Q_EMIT playbackRateChanged(m_rate); -} - -void AVFMediaPlayerSession::setPosition(qint64 pos) -{ -#ifdef QT_DEBUG_AVF - qDebug() << Q_FUNC_INFO << pos; -#endif - - if (pos == position()) - return; - - AVPlayerItem *playerItem = [static_cast<AVFMediaPlayerSessionObserver*>(m_observer) playerItem]; - if (!playerItem) { - m_requestedPosition = pos; - Q_EMIT positionChanged(m_requestedPosition); - return; - } - - if (!isSeekable()) { - if (m_requestedPosition != -1) { - m_requestedPosition = -1; - Q_EMIT positionChanged(position()); - } - return; - } - - pos = qMax(qint64(0), pos); - if (duration() > 0) - pos = qMin(pos, duration()); - - CMTime newTime = [playerItem currentTime]; - newTime.value = (pos / 1000.0f) * newTime.timescale; - [playerItem seekToTime:newTime toleranceBefore:kCMTimeZero toleranceAfter:kCMTimeZero completionHandler:nil]; - - Q_EMIT positionChanged(pos); - - // Reset media status if the current status is EndOfMedia - if (m_mediaStatus == QMediaPlayer::EndOfMedia) { - QMediaPlayer::MediaStatus newMediaStatus = (m_state == QMediaPlayer::PausedState) ? QMediaPlayer::BufferedMedia - : QMediaPlayer::LoadedMedia; - Q_EMIT mediaStatusChanged((m_mediaStatus = newMediaStatus)); - } -} - -void AVFMediaPlayerSession::play() -{ -#ifdef QT_DEBUG_AVF - qDebug() << Q_FUNC_INFO << "currently: " << m_state; -#endif - - if (m_mediaStatus == QMediaPlayer::NoMedia || m_mediaStatus == QMediaPlayer::InvalidMedia) - return; - - if (m_state == QMediaPlayer::PlayingState) - return; - - if (m_videoOutput) { - m_videoOutput->setLayer([static_cast<AVFMediaPlayerSessionObserver*>(m_observer) playerLayer]); - } - - // Reset media status if the current status is EndOfMedia - if (m_mediaStatus == QMediaPlayer::EndOfMedia) - setPosition(0); - - if (m_mediaStatus == QMediaPlayer::LoadedMedia || m_mediaStatus == QMediaPlayer::BufferedMedia) { - // Setting the rate starts playback - [[static_cast<AVFMediaPlayerSessionObserver*>(m_observer) player] setRate:m_rate]; - } - - m_state = QMediaPlayer::PlayingState; - processLoadStateChange(); - - Q_EMIT stateChanged(m_state); -} - -void AVFMediaPlayerSession::pause() -{ -#ifdef QT_DEBUG_AVF - qDebug() << Q_FUNC_INFO << "currently: " << m_state; -#endif - - if (m_mediaStatus == QMediaPlayer::NoMedia) - return; - - if (m_state == QMediaPlayer::PausedState) - return; - - m_state = QMediaPlayer::PausedState; - - if (m_videoOutput) { - m_videoOutput->setLayer([static_cast<AVFMediaPlayerSessionObserver*>(m_observer) playerLayer]); - } - - [[static_cast<AVFMediaPlayerSessionObserver*>(m_observer) player] pause]; - - // Reset media status if the current status is EndOfMedia - if (m_mediaStatus == QMediaPlayer::EndOfMedia) - setPosition(0); - - - Q_EMIT stateChanged(m_state); -} - -void AVFMediaPlayerSession::stop() -{ -#ifdef QT_DEBUG_AVF - qDebug() << Q_FUNC_INFO << "currently: " << m_state; -#endif - - if (m_state == QMediaPlayer::StoppedState) - return; - - // AVPlayer doesn't have stop(), only pause() and play(). - [[static_cast<AVFMediaPlayerSessionObserver*>(m_observer) player] pause]; - setPosition(0); - - if (m_videoOutput) { - m_videoOutput->setLayer(nullptr); - } - - if (m_mediaStatus == QMediaPlayer::BufferedMedia) - Q_EMIT mediaStatusChanged((m_mediaStatus = QMediaPlayer::LoadedMedia)); - - Q_EMIT positionChanged(position()); - Q_EMIT stateChanged((m_state = QMediaPlayer::StoppedState)); -} - -void AVFMediaPlayerSession::setVolume(int volume) -{ -#ifdef QT_DEBUG_AVF - qDebug() << Q_FUNC_INFO << volume; -#endif - - if (m_volume == volume) - return; - - m_volume = volume; - - AVPlayer *player = [static_cast<AVFMediaPlayerSessionObserver*>(m_observer) player]; - if (player) - [player setVolume:volume / 100.0f]; - - Q_EMIT volumeChanged(m_volume); -} - -void AVFMediaPlayerSession::setMuted(bool muted) -{ -#ifdef QT_DEBUG_AVF - qDebug() << Q_FUNC_INFO << muted; -#endif - - if (m_muted == muted) - return; - - m_muted = muted; - - AVPlayer *player = [static_cast<AVFMediaPlayerSessionObserver*>(m_observer) player]; - if (player) - [player setMuted:muted]; - - Q_EMIT mutedChanged(muted); -} - -void AVFMediaPlayerSession::processEOS() -{ - //AVPlayerItem has reached end of track/stream -#ifdef QT_DEBUG_AVF - qDebug() << Q_FUNC_INFO; -#endif - Q_EMIT positionChanged(position()); - m_mediaStatus = QMediaPlayer::EndOfMedia; - m_state = QMediaPlayer::StoppedState; - - // At this point, frames should not be rendered anymore. - // Clear the output layer to make sure of that. - if (m_videoOutput) - m_videoOutput->setLayer(nullptr); - - Q_EMIT mediaStatusChanged(m_mediaStatus); - Q_EMIT stateChanged(m_state); -} - -void AVFMediaPlayerSession::processLoadStateChange(QMediaPlayer::State newState) -{ - AVPlayerStatus currentStatus = [[static_cast<AVFMediaPlayerSessionObserver*>(m_observer) player] status]; - -#ifdef QT_DEBUG_AVF - qDebug() << Q_FUNC_INFO << currentStatus << ", " << m_mediaStatus << ", " << newState; -#endif - - if (m_mediaStatus == QMediaPlayer::NoMedia) - return; - - if (currentStatus == AVPlayerStatusReadyToPlay) { - - QMediaPlayer::MediaStatus newStatus = m_mediaStatus; - - AVPlayerItem *playerItem = [static_cast<AVFMediaPlayerSessionObserver*>(m_observer) playerItem]; - - if (playerItem) { - // Check each track for audio and video content - AVAssetTrack *videoTrack = nil; - NSArray *tracks = playerItem.tracks; - for (AVPlayerItemTrack *track in tracks) { - AVAssetTrack *assetTrack = track.assetTrack; - if (assetTrack) { - if ([assetTrack.mediaType isEqualToString:AVMediaTypeAudio]) - setAudioAvailable(true); - if ([assetTrack.mediaType isEqualToString:AVMediaTypeVideo]) { - setVideoAvailable(true); - if (!videoTrack) - videoTrack = assetTrack; - } - } - } - - setSeekable([[playerItem seekableTimeRanges] count] > 0); - - // Get the native size of the video, and reset the bounds of the player layer - AVPlayerLayer *playerLayer = [static_cast<AVFMediaPlayerSessionObserver*>(m_observer) playerLayer]; - if (videoTrack && playerLayer) { - if (!playerLayer.bounds.size.width || !playerLayer.bounds.size.height) { - playerLayer.bounds = CGRectMake(0.0f, 0.0f, - videoTrack.naturalSize.width, - videoTrack.naturalSize.height); - } - - if (m_videoOutput && newState != QMediaPlayer::StoppedState) { - m_videoOutput->setLayer(playerLayer); - } - } - - if (m_requestedPosition != -1) { - setPosition(m_requestedPosition); - m_requestedPosition = -1; - } - } - - newStatus = (newState != QMediaPlayer::StoppedState) ? QMediaPlayer::BufferedMedia - : QMediaPlayer::LoadedMedia; - - if (newStatus != m_mediaStatus) - Q_EMIT mediaStatusChanged((m_mediaStatus = newStatus)); - - } - - if (newState == QMediaPlayer::PlayingState && [static_cast<AVFMediaPlayerSessionObserver*>(m_observer) player]) { - // Setting the rate is enough to start playback, no need to call play() - [[static_cast<AVFMediaPlayerSessionObserver*>(m_observer) player] setRate:m_rate]; - } -} - - -void AVFMediaPlayerSession::processLoadStateChange() -{ - processLoadStateChange(m_state); -} - - -void AVFMediaPlayerSession::processLoadStateFailure() -{ - Q_EMIT stateChanged((m_state = QMediaPlayer::StoppedState)); -} - -void AVFMediaPlayerSession::processBufferStateChange(int bufferStatus) -{ - if (bufferStatus == m_bufferStatus) - return; - - auto status = m_mediaStatus; - // Buffered -> unbuffered. - if (!bufferStatus) { - status = QMediaPlayer::StalledMedia; - } else if (status == QMediaPlayer::StalledMedia) { - status = QMediaPlayer::BufferedMedia; - // Resume playback. - if (m_state == QMediaPlayer::PlayingState) - [[static_cast<AVFMediaPlayerSessionObserver*>(m_observer) player] setRate:m_rate]; - } - - if (m_mediaStatus != status) - Q_EMIT mediaStatusChanged(m_mediaStatus = status); - - m_bufferStatus = bufferStatus; - Q_EMIT bufferStatusChanged(bufferStatus); -} - -void AVFMediaPlayerSession::processDurationChange(qint64 duration) -{ - if (duration == m_duration) - return; - - m_duration = duration; - Q_EMIT durationChanged(duration); -} - -void AVFMediaPlayerSession::processPositionChange() -{ - if (m_state == QMediaPlayer::StoppedState) - return; - - Q_EMIT positionChanged(position()); -} - -void AVFMediaPlayerSession::processMediaLoadError() -{ - if (m_requestedPosition != -1) { - m_requestedPosition = -1; - Q_EMIT positionChanged(position()); - } - - Q_EMIT mediaStatusChanged((m_mediaStatus = QMediaPlayer::InvalidMedia)); - - Q_EMIT error(QMediaPlayer::FormatError, tr("Failed to load media")); -} - -void AVFMediaPlayerSession::streamReady() -{ - setStreamURL(m_observer, m_resources.request().url().toEncoded()); -} - -void AVFMediaPlayerSession::streamDestroyed() -{ - resetStream(nullptr); -} - -void AVFMediaPlayerSession::resetStream(QIODevice *stream) -{ - if (m_mediaStream) { - disconnect(m_mediaStream, &QIODevice::readyRead, this, &AVFMediaPlayerSession::streamReady); - disconnect(m_mediaStream, &QIODevice::destroyed, this, &AVFMediaPlayerSession::streamDestroyed); - } - - m_mediaStream = stream; - - if (m_mediaStream) { - connect(m_mediaStream, &QIODevice::readyRead, this, &AVFMediaPlayerSession::streamReady); - connect(m_mediaStream, &QIODevice::destroyed, this, &AVFMediaPlayerSession::streamDestroyed); - } -} diff --git a/src/plugins/avfoundation/mediaplayer/avfvideoframerenderer.h b/src/plugins/avfoundation/mediaplayer/avfvideoframerenderer.h deleted file mode 100644 index d4f74964a..000000000 --- a/src/plugins/avfoundation/mediaplayer/avfvideoframerenderer.h +++ /dev/null @@ -1,92 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** 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$ -** -****************************************************************************/ - -#ifndef AVFVIDEOFRAMERENDERER_H -#define AVFVIDEOFRAMERENDERER_H - -#include <QtCore/QObject> -#include <QtGui/QImage> -#include <QtGui/QOpenGLContext> -#include <QtCore/QSize> - -#import "Metal/Metal.h" -#import "MetalKit/MetalKit.h" - -@class CARenderer; -@class AVPlayerLayer; - -QT_BEGIN_NAMESPACE - -class QOpenGLFramebufferObject; -class QWindow; -class QOpenGLContext; -class QAbstractVideoSurface; - -class AVFVideoFrameRenderer : public QObject -{ -public: - AVFVideoFrameRenderer(QAbstractVideoSurface *surface, QObject *parent = nullptr); - - virtual ~AVFVideoFrameRenderer(); - - quint64 renderLayerToTexture(AVPlayerLayer *layer); - quint64 renderLayerToMTLTexture(AVPlayerLayer *layer); - QImage renderLayerToImage(AVPlayerLayer *layer); - -private: - QOpenGLFramebufferObject* initRenderer(AVPlayerLayer *layer); - void renderLayerToFBO(AVPlayerLayer *layer, QOpenGLFramebufferObject *fbo); - - CARenderer *m_videoLayerRenderer; - QAbstractVideoSurface *m_surface; - QOpenGLFramebufferObject *m_fbo[2]; - QWindow *m_offscreenSurface; - QOpenGLContext *m_glContext; - QSize m_targetSize; - - uint m_currentBuffer; - bool m_isContextShared; - - id<MTLDevice> m_metalDevice = nil; - id<MTLTexture> m_metalTexture = nil; -}; - -QT_END_NAMESPACE - -#endif // AVFVIDEOFRAMERENDERER_H diff --git a/src/plugins/avfoundation/mediaplayer/avfvideoframerenderer.mm b/src/plugins/avfoundation/mediaplayer/avfvideoframerenderer.mm deleted file mode 100644 index f81412d65..000000000 --- a/src/plugins/avfoundation/mediaplayer/avfvideoframerenderer.mm +++ /dev/null @@ -1,276 +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 "avfvideoframerenderer.h" - -#include <QtMultimedia/qabstractvideosurface.h> -#include <QtOpenGL/QOpenGLFramebufferObject> -#include <QtGui/QWindow> - -#ifdef QT_DEBUG_AVF -#include <QtCore/qdebug.h> -#endif - -#import <CoreVideo/CVBase.h> -#import <AVFoundation/AVFoundation.h> - -QT_USE_NAMESPACE - -AVFVideoFrameRenderer::AVFVideoFrameRenderer(QAbstractVideoSurface *surface, QObject *parent) - : QObject(parent) - , m_videoLayerRenderer(nullptr) - , m_surface(surface) - , m_offscreenSurface(nullptr) - , m_glContext(nullptr) - , m_currentBuffer(1) - , m_isContextShared(true) -{ - m_fbo[0] = nullptr; - m_fbo[1] = nullptr; -} - -AVFVideoFrameRenderer::~AVFVideoFrameRenderer() -{ -#ifdef QT_DEBUG_AVF - qDebug() << Q_FUNC_INFO; -#endif - - [m_videoLayerRenderer release]; - [m_metalDevice release]; - delete m_fbo[0]; - delete m_fbo[1]; - delete m_offscreenSurface; - delete m_glContext; -} - -quint64 AVFVideoFrameRenderer::renderLayerToTexture(AVPlayerLayer *layer) -{ - //Is layer valid - if (!layer) - return 0; - - //If the glContext isn't shared, it doesn't make sense to return a texture for us - if (m_offscreenSurface && !m_isContextShared) - return 0; - - QOpenGLFramebufferObject *fbo = initRenderer(layer); - - if (!fbo) - return 0; - - renderLayerToFBO(layer, fbo); - if (m_glContext) - m_glContext->doneCurrent(); - - return fbo->texture(); -} - -quint64 AVFVideoFrameRenderer::renderLayerToMTLTexture(AVPlayerLayer *layer) -{ - m_targetSize = QSize(layer.bounds.size.width, layer.bounds.size.height); - - if (!m_metalDevice) - m_metalDevice = MTLCreateSystemDefaultDevice(); - - if (!m_metalTexture) { - auto desc = [[MTLTextureDescriptor alloc] init]; - desc.textureType = MTLTextureType2D; - desc.width = NSUInteger(m_targetSize.width()); - desc.height = NSUInteger(m_targetSize.height()); - desc.resourceOptions = MTLResourceStorageModePrivate; - desc.usage = MTLTextureUsageRenderTarget; - desc.pixelFormat = MTLPixelFormatRGBA8Unorm; - - m_metalTexture = [m_metalDevice newTextureWithDescriptor: desc]; - [desc release]; - } - - if (!m_videoLayerRenderer) { - m_videoLayerRenderer = [CARenderer rendererWithMTLTexture:m_metalTexture options:nil]; - [m_videoLayerRenderer retain]; - } - - if (m_videoLayerRenderer.layer != layer) { - m_videoLayerRenderer.layer = layer; - m_videoLayerRenderer.bounds = layer.bounds; - } - - [m_videoLayerRenderer beginFrameAtTime:CACurrentMediaTime() timeStamp:NULL]; - [m_videoLayerRenderer addUpdateRect:layer.bounds]; - [m_videoLayerRenderer render]; - [m_videoLayerRenderer endFrame]; - - return quint64(m_metalTexture); -} - -QImage AVFVideoFrameRenderer::renderLayerToImage(AVPlayerLayer *layer) -{ - //Is layer valid - if (!layer) { - return QImage(); - } - - QOpenGLFramebufferObject *fbo = initRenderer(layer); - - if (!fbo) - return QImage(); - - renderLayerToFBO(layer, fbo); - QImage fboImage = fbo->toImage(); - if (m_glContext) - m_glContext->doneCurrent(); - - return fboImage; -} - -QOpenGLFramebufferObject *AVFVideoFrameRenderer::initRenderer(AVPlayerLayer *layer) -{ - - //Get size from AVPlayerLayer - m_targetSize = QSize(layer.bounds.size.width, layer.bounds.size.height); - - QOpenGLContext *shareContext = !m_glContext && m_surface - ? qobject_cast<QOpenGLContext*>(m_surface->property("GLContext").value<QObject*>()) - : nullptr; - - //Make sure we have an OpenGL context to make current - if (shareContext || (!QOpenGLContext::currentContext() && !m_glContext)) { - - //Create Hidden QWindow surface to create context in this thread - delete m_offscreenSurface; - m_offscreenSurface = new QWindow(); - m_offscreenSurface->setSurfaceType(QWindow::OpenGLSurface); - //Needs geometry to be a valid surface, but size is not important - m_offscreenSurface->setGeometry(0, 0, 1, 1); - m_offscreenSurface->create(); - - delete m_glContext; - m_glContext = new QOpenGLContext(); - m_glContext->setFormat(m_offscreenSurface->requestedFormat()); - - if (shareContext) { - m_glContext->setShareContext(shareContext); - m_isContextShared = true; - } else { -#ifdef QT_DEBUG_AVF - qWarning("failed to get Render Thread context"); -#endif - m_isContextShared = false; - } - if (!m_glContext->create()) { - qWarning("failed to create QOpenGLContext"); - return nullptr; - } - - // CARenderer must be re-created with different current context, so release it now. - // See lines below where m_videoLayerRenderer is constructed. - if (m_videoLayerRenderer) { - [m_videoLayerRenderer release]; - m_videoLayerRenderer = nullptr; - } - } - - //Need current context - if (m_glContext) - m_glContext->makeCurrent(m_offscreenSurface); - - //Create the CARenderer if needed - if (!m_videoLayerRenderer) { - m_videoLayerRenderer = [CARenderer rendererWithCGLContext: CGLGetCurrentContext() options: nil]; - [m_videoLayerRenderer retain]; - } - - //Set/Change render source if needed - if (m_videoLayerRenderer.layer != layer) { - m_videoLayerRenderer.layer = layer; - m_videoLayerRenderer.bounds = layer.bounds; - } - - //Do we have FBO's already? - if ((!m_fbo[0] && !m_fbo[0]) || (m_fbo[0]->size() != m_targetSize)) { - delete m_fbo[0]; - delete m_fbo[1]; - m_fbo[0] = new QOpenGLFramebufferObject(m_targetSize); - m_fbo[1] = new QOpenGLFramebufferObject(m_targetSize); - } - - //Switch buffer target - m_currentBuffer = !m_currentBuffer; - return m_fbo[m_currentBuffer]; -} - -void AVFVideoFrameRenderer::renderLayerToFBO(AVPlayerLayer *layer, QOpenGLFramebufferObject *fbo) -{ - //Start Rendering - //NOTE: This rendering method will NOT work on iOS as there is no CARenderer in iOS - if (!fbo->bind()) { - qWarning("AVFVideoRender FBO failed to bind"); - return; - } - - glClearColor(0.0f, 0.0f, 0.0f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT); - - glViewport(0, 0, m_targetSize.width(), m_targetSize.height()); - - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - - //Render to FBO with inverted Y - glOrtho(0.0, m_targetSize.width(), 0.0, m_targetSize.height(), 0.0, 1.0); - - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); - - [m_videoLayerRenderer beginFrameAtTime:CACurrentMediaTime() timeStamp:NULL]; - [m_videoLayerRenderer addUpdateRect:layer.bounds]; - [m_videoLayerRenderer render]; - [m_videoLayerRenderer endFrame]; - - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - - glFinish(); //Rendering needs to be done before passing texture to video frame - - fbo->release(); -} diff --git a/src/plugins/avfoundation/mediaplayer/avfvideoframerenderer_ios.h b/src/plugins/avfoundation/mediaplayer/avfvideoframerenderer_ios.h deleted file mode 100644 index d1de1f511..000000000 --- a/src/plugins/avfoundation/mediaplayer/avfvideoframerenderer_ios.h +++ /dev/null @@ -1,120 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** 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$ -** -****************************************************************************/ - -#ifndef AVFVIDEOFRAMERENDERER_H -#define AVFVIDEOFRAMERENDERER_H - -#include <QtCore/QObject> -#include <QtGui/QImage> -#include <QtGui/QOpenGLContext> -#include <QtCore/QSize> - -#import "Metal/Metal.h" -#import "MetalKit/MetalKit.h" - -@class AVPlayerLayer; -@class AVPlayerItemVideoOutput; - -QT_BEGIN_NAMESPACE - -class QOpenGLContext; -class QOpenGLFramebufferObject; -class QOpenGLShaderProgram; -class QOffscreenSurface; -class QAbstractVideoSurface; - -typedef struct __CVBuffer *CVBufferRef; -typedef CVBufferRef CVImageBufferRef; -typedef CVImageBufferRef CVPixelBufferRef; -#if defined(Q_OS_IOS) || defined(Q_OS_TVOS) -typedef struct __CVOpenGLESTextureCache *CVOpenGLESTextureCacheRef; -typedef CVImageBufferRef CVOpenGLESTextureRef; -// helpers to avoid boring if def -typedef CVOpenGLESTextureCacheRef CVOGLTextureCacheRef; -typedef CVOpenGLESTextureRef CVOGLTextureRef; -#define CVOGLTextureGetTarget CVOpenGLESTextureGetTarget -#define CVOGLTextureGetName CVOpenGLESTextureGetName -#define CVOGLTextureCacheCreate CVOpenGLESTextureCacheCreate -#define CVOGLTextureCacheCreateTextureFromImage CVOpenGLESTextureCacheCreateTextureFromImage -#define CVOGLTextureCacheFlush CVOpenGLESTextureCacheFlush -#else -typedef struct __CVOpenGLTextureCache *CVOpenGLTextureCacheRef; -typedef CVImageBufferRef CVOpenGLTextureRef; -// helpers to avoid boring if def -typedef CVOpenGLTextureCacheRef CVOGLTextureCacheRef; -typedef CVOpenGLTextureRef CVOGLTextureRef; -#define CVOGLTextureGetTarget CVOpenGLTextureGetTarget -#define CVOGLTextureGetName CVOpenGLTextureGetName -#define CVOGLTextureCacheCreate CVOpenGLTextureCacheCreate -#define CVOGLTextureCacheCreateTextureFromImage CVOpenGLTextureCacheCreateTextureFromImage -#define CVOGLTextureCacheFlush CVOpenGLTextureCacheFlush -#endif - -class AVFVideoFrameRenderer : public QObject -{ -public: - AVFVideoFrameRenderer(QAbstractVideoSurface *surface, QObject *parent = nullptr); - - virtual ~AVFVideoFrameRenderer(); - - void setPlayerLayer(AVPlayerLayer *layer); - - quint64 renderLayerToTexture(AVPlayerLayer *layer); - quint64 renderLayerToMTLTexture(AVPlayerLayer *layer); - QImage renderLayerToImage(AVPlayerLayer *layer); - -private: - void initRenderer(); - CVPixelBufferRef copyPixelBufferFromLayer(AVPlayerLayer *layer, size_t& width, size_t& height); - CVOGLTextureRef createCacheTextureFromLayer(AVPlayerLayer *layer, size_t& width, size_t& height); - - QOpenGLContext *m_glContext; - QOffscreenSurface *m_offscreenSurface; - QAbstractVideoSurface *m_surface; - CVOGLTextureCacheRef m_textureCache; - AVPlayerItemVideoOutput* m_videoOutput; - bool m_isContextShared; - - id<MTLDevice> m_metalDevice = nil; - CVMetalTextureCacheRef m_metalTextureCache = nil; -}; - -QT_END_NAMESPACE - -#endif // AVFVIDEOFRAMERENDERER_H diff --git a/src/plugins/avfoundation/mediaplayer/avfvideoframerenderer_ios.mm b/src/plugins/avfoundation/mediaplayer/avfvideoframerenderer_ios.mm deleted file mode 100644 index cbaa1aa11..000000000 --- a/src/plugins/avfoundation/mediaplayer/avfvideoframerenderer_ios.mm +++ /dev/null @@ -1,307 +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 "avfvideoframerenderer_ios.h" - -#include <QtMultimedia/qabstractvideosurface.h> -#include <QtOpenGL/QOpenGLFramebufferObject> -#include <QtOpenGL/QOpenGLShaderProgram> -#include <QtGui/QOffscreenSurface> - -#ifdef QT_DEBUG_AVF -#include <QtCore/qdebug.h> -#endif - -#import <CoreVideo/CVBase.h> -#import <AVFoundation/AVFoundation.h> -QT_USE_NAMESPACE - -AVFVideoFrameRenderer::AVFVideoFrameRenderer(QAbstractVideoSurface *surface, QObject *parent) - : QObject(parent) - , m_glContext(nullptr) - , m_offscreenSurface(nullptr) - , m_surface(surface) - , m_textureCache(nullptr) - , m_videoOutput(nullptr) - , m_isContextShared(true) -{ -} - -AVFVideoFrameRenderer::~AVFVideoFrameRenderer() -{ -#ifdef QT_DEBUG_AVF - qDebug() << Q_FUNC_INFO; -#endif - - [m_videoOutput release]; // sending to nil is fine - if (m_textureCache) - CFRelease(m_textureCache); - if (m_metalTextureCache) - CFRelease(m_metalTextureCache); - [m_metalDevice release]; - delete m_offscreenSurface; - delete m_glContext; -} - -void AVFVideoFrameRenderer::setPlayerLayer(AVPlayerLayer *layer) -{ - Q_UNUSED(layer); - if (m_videoOutput) { - [m_videoOutput release]; - m_videoOutput = nullptr; - // will be re-created in first call to copyPixelBufferFromLayer - } -} - -quint64 AVFVideoFrameRenderer::renderLayerToMTLTexture(AVPlayerLayer *layer) -{ - if (!m_metalDevice) - m_metalDevice = MTLCreateSystemDefaultDevice(); - - if (!m_metalTextureCache) { - CVReturn err = CVMetalTextureCacheCreate(kCFAllocatorDefault, nullptr, - m_metalDevice, nullptr, &m_metalTextureCache); - if (err) { - qWarning() << "Error at CVMetalTextureCacheCreate" << err; - return 0; - } - } - - size_t width = 0, height = 0; - CVPixelBufferRef pixelBuffer = copyPixelBufferFromLayer(layer, width, height); - - if (!pixelBuffer) - return 0; - - CVMetalTextureCacheFlush(m_metalTextureCache, 0); - - CVMetalTextureRef texture = nil; - CVReturn err = CVMetalTextureCacheCreateTextureFromImage(kCFAllocatorDefault, m_metalTextureCache, pixelBuffer, NULL, - MTLPixelFormatBGRA8Unorm_sRGB, width, height, 0, &texture); - - if (!texture || err) - qWarning("CVMetalTextureCacheCreateTextureFromImage failed (error: %d)", err); - - CVPixelBufferRelease(pixelBuffer); - quint64 tex = 0; - if (texture) { - tex = quint64(CVMetalTextureGetTexture(texture)); - CFRelease(texture); - } - - return tex; -} - -quint64 AVFVideoFrameRenderer::renderLayerToTexture(AVPlayerLayer *layer) -{ - initRenderer(); - - // If the glContext isn't shared, it doesn't make sense to return a texture for us - if (!m_isContextShared) - return 0; - - size_t dummyWidth = 0, dummyHeight = 0; - auto texture = createCacheTextureFromLayer(layer, dummyWidth, dummyHeight); - auto tex = quint64(CVOGLTextureGetName(texture)); - CFRelease(texture); - - return tex; -} - -static NSString* const AVF_PIXEL_FORMAT_KEY = (NSString*)kCVPixelBufferPixelFormatTypeKey; -static NSNumber* const AVF_PIXEL_FORMAT_VALUE = [NSNumber numberWithUnsignedInt:kCVPixelFormatType_32BGRA]; -static NSDictionary* const AVF_OUTPUT_SETTINGS = [NSDictionary dictionaryWithObject:AVF_PIXEL_FORMAT_VALUE forKey:AVF_PIXEL_FORMAT_KEY]; - - -CVPixelBufferRef AVFVideoFrameRenderer::copyPixelBufferFromLayer(AVPlayerLayer *layer, - size_t& width, size_t& height) -{ - //Is layer valid - if (!layer) { -#ifdef QT_DEBUG_AVF - qWarning("copyPixelBufferFromLayer: invalid layer"); -#endif - return nullptr; - } - - if (!m_videoOutput) { - m_videoOutput = [[AVPlayerItemVideoOutput alloc] initWithPixelBufferAttributes:AVF_OUTPUT_SETTINGS]; - [m_videoOutput setDelegate:nil queue:nil]; - AVPlayerItem * item = [[layer player] currentItem]; - [item addOutput:m_videoOutput]; - } - - CFTimeInterval currentCAFrameTime = CACurrentMediaTime(); - CMTime currentCMFrameTime = [m_videoOutput itemTimeForHostTime:currentCAFrameTime]; - // happens when buffering / loading - if (CMTimeCompare(currentCMFrameTime, kCMTimeZero) < 0) { - return nullptr; - } - - CVPixelBufferRef pixelBuffer = [m_videoOutput copyPixelBufferForItemTime:currentCMFrameTime - itemTimeForDisplay:nil]; - if (!pixelBuffer) { -#ifdef QT_DEBUG_AVF - qWarning("copyPixelBufferForItemTime returned nil"); - CMTimeShow(currentCMFrameTime); -#endif - return nullptr; - } - - width = CVPixelBufferGetWidth(pixelBuffer); - height = CVPixelBufferGetHeight(pixelBuffer); - return pixelBuffer; -} - -CVOGLTextureRef AVFVideoFrameRenderer::createCacheTextureFromLayer(AVPlayerLayer *layer, - size_t& width, size_t& height) -{ - CVPixelBufferRef pixelBuffer = copyPixelBufferFromLayer(layer, width, height); - - if (!pixelBuffer) - return nullptr; - - CVOGLTextureCacheFlush(m_textureCache, 0); - - CVOGLTextureRef texture = nullptr; - CVReturn err = CVOGLTextureCacheCreateTextureFromImage(kCFAllocatorDefault, m_textureCache, pixelBuffer, nullptr, - GL_TEXTURE_2D, GL_RGBA, - (GLsizei) width, (GLsizei) height, - GL_BGRA, GL_UNSIGNED_BYTE, 0, - &texture); - - if (!texture || err) { -#ifdef QT_DEBUG_AVF - qWarning("CVOGLTextureCacheCreateTextureFromImage failed (error: %d)", err); -#endif - } - - CVPixelBufferRelease(pixelBuffer); - - return texture; -} - -QImage AVFVideoFrameRenderer::renderLayerToImage(AVPlayerLayer *layer) -{ - size_t width = 0; - size_t height = 0; - CVPixelBufferRef pixelBuffer = copyPixelBufferFromLayer(layer, width, height); - - if (!pixelBuffer) - return QImage(); - - OSType pixelFormat = CVPixelBufferGetPixelFormatType(pixelBuffer); - if (pixelFormat != kCVPixelFormatType_32BGRA) { -#ifdef QT_DEBUG_AVF - qWarning("CVPixelBuffer format is not BGRA32 (got: %d)", static_cast<quint32>(pixelFormat)); -#endif - return QImage(); - } - - CVPixelBufferLockBaseAddress(pixelBuffer, 0); - char *data = (char *)CVPixelBufferGetBaseAddress(pixelBuffer); - size_t stride = CVPixelBufferGetBytesPerRow(pixelBuffer); - - // format here is not relevant, only using for storage - QImage img = QImage(width, height, QImage::Format_ARGB32); - for (size_t j = 0; j < height; j++) { - memcpy(img.scanLine(j), data, width * 4); - data += stride; - } - - CVPixelBufferUnlockBaseAddress(pixelBuffer, 0); - CVPixelBufferRelease(pixelBuffer); - return img; -} - -void AVFVideoFrameRenderer::initRenderer() -{ - // even for using a texture directly, we need to be able to make a context current, - // so we need an offscreen, and we shouldn't assume we can make the surface context - // current on that offscreen, so use our own (sharing with it). Slightly - // excessive but no performance penalty and makes the QImage path easier to maintain - - //Make sure we have an OpenGL context to make current - if (!m_glContext) { - //Create OpenGL context and set share context from surface - QOpenGLContext *shareContext = nullptr; - if (m_surface) { - shareContext = qobject_cast<QOpenGLContext*>(m_surface->property("GLContext").value<QObject*>()); - } - - m_glContext = new QOpenGLContext(); - if (shareContext) { - m_glContext->setShareContext(shareContext); - m_isContextShared = true; - } else { -#ifdef QT_DEBUG_AVF - qWarning("failed to get Render Thread context"); -#endif - m_isContextShared = false; - } - if (!m_glContext->create()) { -#ifdef QT_DEBUG_AVF - qWarning("failed to create QOpenGLContext"); -#endif - return; - } - } - - if (!m_offscreenSurface) { - m_offscreenSurface = new QOffscreenSurface(); - m_offscreenSurface->setFormat(m_glContext->format()); - m_offscreenSurface->create(); - } - - //Need current context - m_glContext->makeCurrent(m_offscreenSurface); - - if (!m_textureCache) { - // Create a new open gl texture cache - CVReturn err = CVOGLTextureCacheCreate(kCFAllocatorDefault, nullptr, - [EAGLContext currentContext], - nullptr, &m_textureCache); - if (err) { - #ifdef QT_DEBUG_AVF - qWarning("Error at CVOGLTextureCacheCreate %d", err); - #endif - } - } - -} diff --git a/src/plugins/avfoundation/mediaplayer/avfvideooutput.h b/src/plugins/avfoundation/mediaplayer/avfvideooutput.h deleted file mode 100644 index d3bcfecf7..000000000 --- a/src/plugins/avfoundation/mediaplayer/avfvideooutput.h +++ /dev/null @@ -1,60 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** 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$ -** -****************************************************************************/ - -#ifndef AVFVIDEOOUTPUT_H -#define AVFVIDEOOUTPUT_H - -#include <QtCore/qobject.h> - -QT_BEGIN_NAMESPACE - -class AVFVideoOutput -{ -public: - virtual ~AVFVideoOutput() {} - virtual void setLayer(void *playerLayer) = 0; -}; - -#define AVFVideoOutput_iid \ - "org.qt-project.qt.AVFVideoOutput/5.0" -Q_DECLARE_INTERFACE(AVFVideoOutput, AVFVideoOutput_iid) - -QT_END_NAMESPACE - -#endif // AVFVIDEOOUTPUT_H diff --git a/src/plugins/avfoundation/mediaplayer/avfvideooutput.mm b/src/plugins/avfoundation/mediaplayer/avfvideooutput.mm deleted file mode 100644 index 327681f50..000000000 --- a/src/plugins/avfoundation/mediaplayer/avfvideooutput.mm +++ /dev/null @@ -1,42 +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 "avfvideooutput.h" - -QT_USE_NAMESPACE diff --git a/src/plugins/avfoundation/mediaplayer/avfvideorenderercontrol.h b/src/plugins/avfoundation/mediaplayer/avfvideorenderercontrol.h deleted file mode 100644 index c1a629944..000000000 --- a/src/plugins/avfoundation/mediaplayer/avfvideorenderercontrol.h +++ /dev/null @@ -1,92 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** 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$ -** -****************************************************************************/ - -#ifndef AVFVIDEORENDERERCONTROL_H -#define AVFVIDEORENDERERCONTROL_H - -#include <QtMultimedia/QVideoRendererControl> -#include <QtCore/QMutex> -#include <QtCore/QSize> - -#include "avfvideooutput.h" - -#import <CoreVideo/CVBase.h> - -QT_BEGIN_NAMESPACE - -class AVFDisplayLink; -class AVFVideoFrameRenderer; - -class AVFVideoRendererControl : public QVideoRendererControl, public AVFVideoOutput -{ - Q_OBJECT - Q_INTERFACES(AVFVideoOutput) -public: - explicit AVFVideoRendererControl(QObject *parent = nullptr); - virtual ~AVFVideoRendererControl(); - - QAbstractVideoSurface *surface() const override; - void setSurface(QAbstractVideoSurface *surface) override; - - void setLayer(void *playerLayer) override; - -private Q_SLOTS: - void updateVideoFrame(const CVTimeStamp &ts); - -Q_SIGNALS: - void surfaceChanged(QAbstractVideoSurface *surface); - -private: - void setupVideoOutput(); - - QMutex m_mutex; - QAbstractVideoSurface *m_surface; - - void *m_playerLayer; - - AVFVideoFrameRenderer *m_frameRenderer; - AVFDisplayLink *m_displayLink; - QSize m_nativeSize; - bool m_enableOpenGL; - bool m_enableMetal; -}; - -QT_END_NAMESPACE - -#endif // AVFVIDEORENDERERCONTROL_H diff --git a/src/plugins/avfoundation/mediaplayer/avfvideorenderercontrol.mm b/src/plugins/avfoundation/mediaplayer/avfvideorenderercontrol.mm deleted file mode 100644 index 726dc5193..000000000 --- a/src/plugins/avfoundation/mediaplayer/avfvideorenderercontrol.mm +++ /dev/null @@ -1,301 +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 "avfvideorenderercontrol.h" -#include "avfdisplaylink.h" - -#if defined(Q_OS_IOS) || defined(Q_OS_TVOS) -#include "avfvideoframerenderer_ios.h" -#else -#include "avfvideoframerenderer.h" -#endif - -#include <QtMultimedia/qabstractvideobuffer.h> -#include <QtMultimedia/qabstractvideosurface.h> -#include <QtMultimedia/qvideosurfaceformat.h> - -#include <private/qimagevideobuffer_p.h> - -#include <QtCore/qdebug.h> - -#import <AVFoundation/AVFoundation.h> - -QT_USE_NAMESPACE - -class TextureVideoBuffer : public QAbstractVideoBuffer -{ -public: - TextureVideoBuffer(HandleType type, quint64 tex) - : QAbstractVideoBuffer(type) - , m_texture(tex) - {} - - virtual ~TextureVideoBuffer() - { - } - - MapMode mapMode() const { return NotMapped; } - uchar *map(MapMode, int*, int*) { return 0; } - void unmap() {} - - QVariant handle() const - { - return QVariant::fromValue<unsigned long long>(m_texture); - } - -private: - quint64 m_texture; -}; - -AVFVideoRendererControl::AVFVideoRendererControl(QObject *parent) - : QVideoRendererControl(parent) - , m_surface(nullptr) - , m_playerLayer(nullptr) - , m_frameRenderer(nullptr) - , m_enableOpenGL(false) - , m_enableMetal(false) - -{ - m_displayLink = new AVFDisplayLink(this); - connect(m_displayLink, SIGNAL(tick(CVTimeStamp)), SLOT(updateVideoFrame(CVTimeStamp))); -} - -AVFVideoRendererControl::~AVFVideoRendererControl() -{ -#ifdef QT_DEBUG_AVF - qDebug() << Q_FUNC_INFO; -#endif - m_displayLink->stop(); - [static_cast<AVPlayerLayer*>(m_playerLayer) release]; -} - -QAbstractVideoSurface *AVFVideoRendererControl::surface() const -{ - return m_surface; -} - -void AVFVideoRendererControl::setSurface(QAbstractVideoSurface *surface) -{ -#ifdef QT_DEBUG_AVF - qDebug() << "Set video surface" << surface; -#endif - - //When we have a valid surface, we can setup a frame renderer - //and schedule surface updates with the display link. - if (surface == m_surface) - return; - - QMutexLocker locker(&m_mutex); - - if (m_surface && m_surface->isActive()) - m_surface->stop(); - - m_surface = surface; - - //If the surface changed, then the current frame renderer is no longer valid - delete m_frameRenderer; - m_frameRenderer = nullptr; - - //If there is now no surface to render too - if (m_surface == nullptr) { - m_displayLink->stop(); - return; - } - - //Surface changed, so we need a new frame renderer - m_frameRenderer = new AVFVideoFrameRenderer(m_surface, this); -#if defined(Q_OS_IOS) || defined(Q_OS_TVOS) - if (m_playerLayer) { - m_frameRenderer->setPlayerLayer(static_cast<AVPlayerLayer*>(m_playerLayer)); - } -#endif - - auto checkHandleType = [this] { - m_enableOpenGL = m_surface->supportedPixelFormats(QAbstractVideoBuffer::GLTextureHandle).contains(QVideoFrame::Format_BGR32); - m_enableMetal = m_surface->supportedPixelFormats(QAbstractVideoBuffer::MTLTextureHandle).contains(QVideoFrame::Format_BGR32); - }; - checkHandleType(); - connect(m_surface, &QAbstractVideoSurface::supportedFormatsChanged, this, checkHandleType); - - //If we already have a layer, but changed surfaces start rendering again - if (m_playerLayer && !m_displayLink->isActive()) { - m_displayLink->start(); - } - -} - -void AVFVideoRendererControl::setLayer(void *playerLayer) -{ - if (m_playerLayer == playerLayer) - return; - - [static_cast<AVPlayerLayer*>(m_playerLayer) release]; - - m_playerLayer = [static_cast<AVPlayerLayer*>(playerLayer) retain]; - - //If there is an active surface, make sure it has been stopped so that - //we can update it's state with the new content. - if (m_surface && m_surface->isActive()) - m_surface->stop(); - -#if defined(Q_OS_IOS) || defined(Q_OS_TVOS) - if (m_frameRenderer) { - m_frameRenderer->setPlayerLayer(static_cast<AVPlayerLayer*>(playerLayer)); - } -#endif - - //If there is no layer to render, stop scheduling updates - if (m_playerLayer == nullptr) { - m_displayLink->stop(); - return; - } - - setupVideoOutput(); - - //If we now have both a valid surface and layer, start scheduling updates - if (m_surface && !m_displayLink->isActive()) { - m_displayLink->start(); - } -} - -void AVFVideoRendererControl::updateVideoFrame(const CVTimeStamp &ts) -{ - Q_UNUSED(ts); - - AVPlayerLayer *playerLayer = static_cast<AVPlayerLayer*>(m_playerLayer); - - if (!playerLayer) { - qWarning("updateVideoFrame called without AVPlayerLayer (which shouldn't happen"); - return; - } - - if (!playerLayer.readyForDisplay || !m_surface) - return; - - if (m_enableMetal) { - quint64 tex = m_frameRenderer->renderLayerToMTLTexture(playerLayer); - if (tex == 0) - return; - - auto buffer = new TextureVideoBuffer(QAbstractVideoBuffer::MTLTextureHandle, tex); - QVideoFrame frame(buffer, m_nativeSize, QVideoFrame::Format_BGR32); - if (m_surface->isActive() && m_surface->surfaceFormat().pixelFormat() != frame.pixelFormat()) - m_surface->stop(); - - if (!m_surface->isActive()) { - QVideoSurfaceFormat format(frame.size(), frame.pixelFormat(), QAbstractVideoBuffer::MTLTextureHandle); -#if defined(Q_OS_IOS) || defined(Q_OS_TVOS) - format.setScanLineDirection(QVideoSurfaceFormat::TopToBottom); -#else - format.setScanLineDirection(QVideoSurfaceFormat::BottomToTop); -#endif - if (!m_surface->start(format)) - qWarning("Failed to activate video surface"); - } - - if (m_surface->isActive()) - m_surface->present(frame); - - return; - } - - if (m_enableOpenGL) { - quint64 tex = m_frameRenderer->renderLayerToTexture(playerLayer); - //Make sure we got a valid texture - if (tex == 0) - return; - - QAbstractVideoBuffer *buffer = new TextureVideoBuffer(QAbstractVideoBuffer::GLTextureHandle, tex); - QVideoFrame frame = QVideoFrame(buffer, m_nativeSize, QVideoFrame::Format_BGR32); - - if (m_surface && frame.isValid()) { - if (m_surface->isActive() && m_surface->surfaceFormat().pixelFormat() != frame.pixelFormat()) - m_surface->stop(); - - if (!m_surface->isActive()) { - QVideoSurfaceFormat format(frame.size(), frame.pixelFormat(), QAbstractVideoBuffer::GLTextureHandle); -#if defined(Q_OS_IOS) || defined(Q_OS_TVOS) - format.setScanLineDirection(QVideoSurfaceFormat::TopToBottom); -#else - format.setScanLineDirection(QVideoSurfaceFormat::BottomToTop); -#endif - if (!m_surface->start(format)) { - //Surface doesn't support GLTextureHandle - qWarning("Failed to activate video surface"); - } - } - - if (m_surface->isActive()) - m_surface->present(frame); - } - } else { - //fallback to rendering frames to QImages - QImage frameData = m_frameRenderer->renderLayerToImage(playerLayer); - - if (frameData.isNull()) { - return; - } - - QAbstractVideoBuffer *buffer = new QImageVideoBuffer(frameData); - QVideoFrame frame = QVideoFrame(buffer, m_nativeSize, QVideoFrame::Format_ARGB32); - if (m_surface && frame.isValid()) { - if (m_surface->isActive() && m_surface->surfaceFormat().pixelFormat() != frame.pixelFormat()) - m_surface->stop(); - - if (!m_surface->isActive()) { - QVideoSurfaceFormat format(frame.size(), frame.pixelFormat(), QAbstractVideoBuffer::NoHandle); - - if (!m_surface->start(format)) { - qWarning("Failed to activate video surface"); - } - } - - if (m_surface->isActive()) - m_surface->present(frame); - } - - } -} - -void AVFVideoRendererControl::setupVideoOutput() -{ - AVPlayerLayer *playerLayer = static_cast<AVPlayerLayer*>(m_playerLayer); - if (playerLayer) - m_nativeSize = QSize(playerLayer.bounds.size.width, playerLayer.bounds.size.height); -} diff --git a/src/plugins/avfoundation/mediaplayer/avfvideowidget.h b/src/plugins/avfoundation/mediaplayer/avfvideowidget.h deleted file mode 100644 index faf71f1a4..000000000 --- a/src/plugins/avfoundation/mediaplayer/avfvideowidget.h +++ /dev/null @@ -1,85 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** 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$ -** -****************************************************************************/ - -#ifndef AVFVIDEOWIDGET_H -#define AVFVIDEOWIDGET_H - -#include <QtWidgets/QWidget> - -@class AVPlayerLayer; -#if defined(Q_OS_OSX) -@class NSView; -#else -@class UIView; -#endif - -QT_BEGIN_NAMESPACE - -class AVFVideoWidget : public QWidget -{ -public: - AVFVideoWidget(QWidget *parent); - virtual ~AVFVideoWidget(); - - QSize sizeHint() const override; - Qt::AspectRatioMode aspectRatioMode() const; - void setAspectRatioMode(Qt::AspectRatioMode mode); - void setPlayerLayer(AVPlayerLayer *layer); - -protected: - void resizeEvent(QResizeEvent *) override; - void paintEvent(QPaintEvent *) override; - -private: - void updateAspectRatio(); - void updatePlayerLayerBounds(const QSize &size); - - QSize m_nativeSize; - Qt::AspectRatioMode m_aspectRatioMode; - AVPlayerLayer *m_playerLayer; -#if defined(Q_OS_OSX) - NSView *m_nativeView; -#else - UIView *m_nativeView; -#endif -}; - -QT_END_NAMESPACE - -#endif // AVFVIDEOWIDGET_H diff --git a/src/plugins/avfoundation/mediaplayer/avfvideowidget.mm b/src/plugins/avfoundation/mediaplayer/avfvideowidget.mm deleted file mode 100644 index 0987342b4..000000000 --- a/src/plugins/avfoundation/mediaplayer/avfvideowidget.mm +++ /dev/null @@ -1,187 +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 "avfvideowidget.h" - -#import <AVFoundation/AVFoundation.h> -#import <QuartzCore/CATransaction.h> - -#if defined(Q_OS_MACOS) -#import <AppKit/AppKit.h> -#else -#import <UIKit/UIKit.h> -#endif - -#include <QtCore/QDebug> -#include <QtGui/QResizeEvent> -#include <QtGui/QPaintEvent> -#include <QtGui/QPainter> - -QT_USE_NAMESPACE - -AVFVideoWidget::AVFVideoWidget(QWidget *parent) - : QWidget(parent) - , m_aspectRatioMode(Qt::KeepAspectRatio) - , m_playerLayer(nullptr) - , m_nativeView(nullptr) -{ - setAutoFillBackground(false); -} - -AVFVideoWidget::~AVFVideoWidget() -{ -#ifdef QT_DEBUG_AVF - qDebug() << Q_FUNC_INFO; -#endif - - if (m_playerLayer) { - [m_playerLayer removeFromSuperlayer]; - [m_playerLayer release]; - } -} - -QSize AVFVideoWidget::sizeHint() const -{ - return m_nativeSize; -} - -Qt::AspectRatioMode AVFVideoWidget::aspectRatioMode() const -{ - return m_aspectRatioMode; -} - -void AVFVideoWidget::setAspectRatioMode(Qt::AspectRatioMode mode) -{ - if (m_aspectRatioMode != mode) { - m_aspectRatioMode = mode; - - updateAspectRatio(); - } -} - -void AVFVideoWidget::setPlayerLayer(AVPlayerLayer *layer) -{ - if (m_playerLayer == layer) - return; - - if (!m_nativeView) { - //make video widget a native window -#if defined(Q_OS_OSX) - m_nativeView = (NSView*)this->winId(); - [m_nativeView setWantsLayer:YES]; -#else - m_nativeView = (UIView*)this->winId(); -#endif - } - - if (m_playerLayer) { - [m_playerLayer removeFromSuperlayer]; - [m_playerLayer release]; - } - - m_playerLayer = layer; - - CALayer *nativeLayer = [m_nativeView layer]; - - if (layer) { - [layer retain]; - - m_nativeSize = QSize(m_playerLayer.bounds.size.width, - m_playerLayer.bounds.size.height); - - updateAspectRatio(); - [nativeLayer addSublayer:m_playerLayer]; - updatePlayerLayerBounds(this->size()); - } -#ifdef QT_DEBUG_AVF - NSArray *sublayers = [nativeLayer sublayers]; - qDebug() << "playerlayer: " << "at z:" << [m_playerLayer zPosition] - << " frame: " << m_playerLayer.frame.size.width << "x" << m_playerLayer.frame.size.height; - qDebug() << "superlayer: " << "at z:" << [nativeLayer zPosition] - << " frame: " << nativeLayer.frame.size.width << "x" << nativeLayer.frame.size.height; - int i = 0; - for (CALayer *layer in sublayers) { - qDebug() << "layer " << i << ": at z:" << [layer zPosition] - << " frame: " << layer.frame.size.width << "x" << layer.frame.size.height; - i++; - } -#endif - -} - -void AVFVideoWidget::resizeEvent(QResizeEvent *event) -{ - updatePlayerLayerBounds(event->size()); - QWidget::resizeEvent(event); -} - -void AVFVideoWidget::paintEvent(QPaintEvent *event) -{ - QPainter painter(this); - painter.fillRect(rect(), Qt::black); - - QWidget::paintEvent(event); -} - -void AVFVideoWidget::updateAspectRatio() -{ - if (m_playerLayer) { - switch (m_aspectRatioMode) { - case Qt::IgnoreAspectRatio: - [m_playerLayer setVideoGravity:AVLayerVideoGravityResize]; - break; - case Qt::KeepAspectRatio: - [m_playerLayer setVideoGravity:AVLayerVideoGravityResizeAspect]; - break; - case Qt::KeepAspectRatioByExpanding: - [m_playerLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill]; - break; - default: - break; - } - } -} - -void AVFVideoWidget::updatePlayerLayerBounds(const QSize &size) -{ - [CATransaction begin]; - [CATransaction setDisableActions: YES]; // disable animation/flicks - m_playerLayer.bounds = QRect(QPoint(0, 0), size).toCGRect(); - [CATransaction commit]; -} diff --git a/src/plugins/avfoundation/mediaplayer/avfvideowidgetcontrol.h b/src/plugins/avfoundation/mediaplayer/avfvideowidgetcontrol.h deleted file mode 100644 index 22379d273..000000000 --- a/src/plugins/avfoundation/mediaplayer/avfvideowidgetcontrol.h +++ /dev/null @@ -1,95 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** 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$ -** -****************************************************************************/ - -#ifndef AVFVIDEOWIDGETCONTROL_H -#define AVFVIDEOWIDGETCONTROL_H - -#include <qvideowidgetcontrol.h> -#include "avfvideooutput.h" - -@class AVPlayerLayer; - -QT_BEGIN_NAMESPACE - -class AVFVideoWidget; - -class AVFVideoWidgetControl : public QVideoWidgetControl, public AVFVideoOutput -{ - Q_OBJECT - Q_INTERFACES(AVFVideoOutput) -public: - AVFVideoWidgetControl(QObject *parent = nullptr); - virtual ~AVFVideoWidgetControl(); - - void setLayer(void *playerLayer) override; - - QWidget *videoWidget() override; - - bool isFullScreen() const override; - void setFullScreen(bool fullScreen) override; - - Qt::AspectRatioMode aspectRatioMode() const override; - void setAspectRatioMode(Qt::AspectRatioMode mode) override; - - int brightness() const override; - void setBrightness(int brightness) override; - - int contrast() const override; - void setContrast(int contrast) override; - - int hue() const override; - void setHue(int hue) override; - - int saturation() const override; - void setSaturation(int saturation) override; - -private: - AVFVideoWidget *m_videoWidget; - - bool m_fullscreen; - int m_brightness; - int m_contrast; - int m_hue; - int m_saturation; - -}; - -QT_END_NAMESPACE - -#endif // AVFVIDEOWIDGETCONTROL_H diff --git a/src/plugins/avfoundation/mediaplayer/avfvideowidgetcontrol.mm b/src/plugins/avfoundation/mediaplayer/avfvideowidgetcontrol.mm deleted file mode 100644 index 91ece817e..000000000 --- a/src/plugins/avfoundation/mediaplayer/avfvideowidgetcontrol.mm +++ /dev/null @@ -1,145 +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 "avfvideowidgetcontrol.h" -#include "avfvideowidget.h" - -#ifdef QT_DEBUG_AVF -#include <QtCore/QDebug> -#endif - -#import <AVFoundation/AVFoundation.h> - -QT_USE_NAMESPACE - -AVFVideoWidgetControl::AVFVideoWidgetControl(QObject *parent) - : QVideoWidgetControl(parent) - , m_fullscreen(false) - , m_brightness(0) - , m_contrast(0) - , m_hue(0) - , m_saturation(0) -{ - m_videoWidget = new AVFVideoWidget(nullptr); -} - -AVFVideoWidgetControl::~AVFVideoWidgetControl() -{ -#ifdef QT_DEBUG_AVF - qDebug() << Q_FUNC_INFO; -#endif - delete m_videoWidget; -} - -void AVFVideoWidgetControl::setLayer(void *playerLayer) -{ -#ifdef QT_DEBUG_AVF - qDebug() << Q_FUNC_INFO << playerLayer; -#endif - - m_videoWidget->setPlayerLayer(static_cast<AVPlayerLayer*>(playerLayer)); - -} - -QWidget *AVFVideoWidgetControl::videoWidget() -{ - return m_videoWidget; -} - -bool AVFVideoWidgetControl::isFullScreen() const -{ - return m_fullscreen; -} - -void AVFVideoWidgetControl::setFullScreen(bool fullScreen) -{ - m_fullscreen = fullScreen; -} - -Qt::AspectRatioMode AVFVideoWidgetControl::aspectRatioMode() const -{ - return m_videoWidget->aspectRatioMode(); -} - -void AVFVideoWidgetControl::setAspectRatioMode(Qt::AspectRatioMode mode) -{ - m_videoWidget->setAspectRatioMode(mode); -} - -int AVFVideoWidgetControl::brightness() const -{ - return m_brightness; -} - -void AVFVideoWidgetControl::setBrightness(int brightness) -{ - m_brightness = brightness; -} - -int AVFVideoWidgetControl::contrast() const -{ - return m_contrast; -} - -void AVFVideoWidgetControl::setContrast(int contrast) -{ - m_contrast = contrast; -} - -int AVFVideoWidgetControl::hue() const -{ - return m_hue; -} - -void AVFVideoWidgetControl::setHue(int hue) -{ - m_hue = hue; -} - -int AVFVideoWidgetControl::saturation() const -{ - return m_saturation; -} - -void AVFVideoWidgetControl::setSaturation(int saturation) -{ - m_saturation = saturation; -} - -#include "moc_avfvideowidgetcontrol.cpp" diff --git a/src/plugins/avfoundation/mediaplayer/avfvideowindowcontrol.h b/src/plugins/avfoundation/mediaplayer/avfvideowindowcontrol.h deleted file mode 100644 index 763656c6c..000000000 --- a/src/plugins/avfoundation/mediaplayer/avfvideowindowcontrol.h +++ /dev/null @@ -1,118 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** 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$ -** -****************************************************************************/ - -#ifndef AVFVIDEOWINDOWCONTROL_H -#define AVFVIDEOWINDOWCONTROL_H - -#include <QVideoWindowControl> - -@class AVPlayerLayer; -#if defined(Q_OS_OSX) -@class NSView; -typedef NSView NativeView; -#else -@class UIView; -typedef UIView NativeView; -#endif - -#include "avfvideooutput.h" - -QT_BEGIN_NAMESPACE - -class AVFVideoWindowControl : public QVideoWindowControl, public AVFVideoOutput -{ - Q_OBJECT - Q_INTERFACES(AVFVideoOutput) - -public: - AVFVideoWindowControl(QObject *parent = nullptr); - virtual ~AVFVideoWindowControl(); - - // QVideoWindowControl interface -public: - WId winId() const override; - void setWinId(WId id) override; - - QRect displayRect() const override; - void setDisplayRect(const QRect &rect) override; - - bool isFullScreen() const override; - void setFullScreen(bool fullScreen) override; - - void repaint() override; - QSize nativeSize() const override; - - Qt::AspectRatioMode aspectRatioMode() const override; - void setAspectRatioMode(Qt::AspectRatioMode mode) override; - - int brightness() const override; - void setBrightness(int brightness) override; - - int contrast() const override; - void setContrast(int contrast) override; - - int hue() const override; - void setHue(int hue) override; - - int saturation() const override; - void setSaturation(int saturation) override; - - // AVFVideoOutput interface - void setLayer(void *playerLayer) override; - -private: - void updateAspectRatio(); - void updatePlayerLayerBounds(); - - WId m_winId; - QRect m_displayRect; - bool m_fullscreen; - int m_brightness; - int m_contrast; - int m_hue; - int m_saturation; - Qt::AspectRatioMode m_aspectRatioMode; - QSize m_nativeSize; - AVPlayerLayer *m_playerLayer; - NativeView *m_nativeView; -}; - -QT_END_NAMESPACE - -#endif // AVFVIDEOWINDOWCONTROL_H diff --git a/src/plugins/avfoundation/mediaplayer/avfvideowindowcontrol.mm b/src/plugins/avfoundation/mediaplayer/avfvideowindowcontrol.mm deleted file mode 100644 index d61129ec9..000000000 --- a/src/plugins/avfoundation/mediaplayer/avfvideowindowcontrol.mm +++ /dev/null @@ -1,255 +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 "avfvideowindowcontrol.h" - -#include <AVFoundation/AVFoundation.h> -#import <QuartzCore/CATransaction.h> - -#if QT_HAS_INCLUDE(<AppKit/AppKit.h>) -#include <AppKit/AppKit.h> -#endif - -#if QT_HAS_INCLUDE(<UIKit/UIKit.h>) -#include <UIKit/UIKit.h> -#endif - -QT_USE_NAMESPACE - -AVFVideoWindowControl::AVFVideoWindowControl(QObject *parent) - : QVideoWindowControl(parent) - , m_winId(0) - , m_fullscreen(false) - , m_brightness(0) - , m_contrast(0) - , m_hue(0) - , m_saturation(0) - , m_aspectRatioMode(Qt::IgnoreAspectRatio) - , m_playerLayer(nullptr) - , m_nativeView(nullptr) -{ -} - -AVFVideoWindowControl::~AVFVideoWindowControl() -{ - if (m_playerLayer) { - [m_playerLayer removeFromSuperlayer]; - [m_playerLayer release]; - } -} - -WId AVFVideoWindowControl::winId() const -{ - return m_winId; -} - -void AVFVideoWindowControl::setWinId(WId id) -{ - m_winId = id; - m_nativeView = (NativeView*)m_winId; -} - -QRect AVFVideoWindowControl::displayRect() const -{ - return m_displayRect; -} - -void AVFVideoWindowControl::setDisplayRect(const QRect &rect) -{ - if (m_displayRect != rect) { - m_displayRect = rect; - updatePlayerLayerBounds(); - } -} - -bool AVFVideoWindowControl::isFullScreen() const -{ - return m_fullscreen; -} - -void AVFVideoWindowControl::setFullScreen(bool fullScreen) -{ - if (m_fullscreen != fullScreen) { - m_fullscreen = fullScreen; - Q_EMIT QVideoWindowControl::fullScreenChanged(fullScreen); - } -} - -void AVFVideoWindowControl::repaint() -{ - if (m_playerLayer) - [m_playerLayer setNeedsDisplay]; -} - -QSize AVFVideoWindowControl::nativeSize() const -{ - return m_nativeSize; -} - -Qt::AspectRatioMode AVFVideoWindowControl::aspectRatioMode() const -{ - return m_aspectRatioMode; -} - -void AVFVideoWindowControl::setAspectRatioMode(Qt::AspectRatioMode mode) -{ - if (m_aspectRatioMode != mode) { - m_aspectRatioMode = mode; - updateAspectRatio(); - } -} - -int AVFVideoWindowControl::brightness() const -{ - return m_brightness; -} - -void AVFVideoWindowControl::setBrightness(int brightness) -{ - if (m_brightness != brightness) { - m_brightness = brightness; - Q_EMIT QVideoWindowControl::brightnessChanged(brightness); - } -} - -int AVFVideoWindowControl::contrast() const -{ - return m_contrast; -} - -void AVFVideoWindowControl::setContrast(int contrast) -{ - if (m_contrast != contrast) { - m_contrast = contrast; - Q_EMIT QVideoWindowControl::contrastChanged(contrast); - } -} - -int AVFVideoWindowControl::hue() const -{ - return m_hue; -} - -void AVFVideoWindowControl::setHue(int hue) -{ - if (m_hue != hue) { - m_hue = hue; - Q_EMIT QVideoWindowControl::hueChanged(hue); - } -} - -int AVFVideoWindowControl::saturation() const -{ - return m_saturation; -} - -void AVFVideoWindowControl::setSaturation(int saturation) -{ - if (m_saturation != saturation) { - m_saturation = saturation; - Q_EMIT QVideoWindowControl::saturationChanged(saturation); - } -} - -void AVFVideoWindowControl::setLayer(void *playerLayer) -{ - AVPlayerLayer *layer = static_cast<AVPlayerLayer*>(playerLayer); - if (m_playerLayer == layer) - return; - - if (!m_winId) { - qDebug("AVFVideoWindowControl: No video window"); - return; - } - -#if defined(Q_OS_OSX) - [m_nativeView setWantsLayer:YES]; -#endif - - if (m_playerLayer) { - [m_playerLayer removeFromSuperlayer]; - [m_playerLayer release]; - } - - m_playerLayer = layer; - - CALayer *nativeLayer = [m_nativeView layer]; - - if (layer) { - [layer retain]; - - m_nativeSize = QSize(m_playerLayer.bounds.size.width, - m_playerLayer.bounds.size.height); - - updateAspectRatio(); - [nativeLayer addSublayer:m_playerLayer]; - updatePlayerLayerBounds(); - } -} - -void AVFVideoWindowControl::updateAspectRatio() -{ - if (m_playerLayer) { - switch (m_aspectRatioMode) { - case Qt::IgnoreAspectRatio: - [m_playerLayer setVideoGravity:AVLayerVideoGravityResize]; - break; - case Qt::KeepAspectRatio: - [m_playerLayer setVideoGravity:AVLayerVideoGravityResizeAspect]; - break; - case Qt::KeepAspectRatioByExpanding: - [m_playerLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill]; - break; - default: - break; - } - } -} - -void AVFVideoWindowControl::updatePlayerLayerBounds() -{ - if (m_playerLayer) { - [CATransaction begin]; - [CATransaction setDisableActions: YES]; // disable animation/flicks - m_playerLayer.frame = m_displayRect.toCGRect(); - [CATransaction commit]; - } -} - -#include "moc_avfvideowindowcontrol.cpp" diff --git a/src/plugins/avfoundation/mediaplayer/mediaplayer.pro b/src/plugins/avfoundation/mediaplayer/mediaplayer.pro deleted file mode 100644 index 604866058..000000000 --- a/src/plugins/avfoundation/mediaplayer/mediaplayer.pro +++ /dev/null @@ -1,76 +0,0 @@ -TARGET = qavfmediaplayer - -#DEFINES += QT_DEBUG_AVF -# Avoid clash with a variable named `slots' in a Quartz header -CONFIG += no_keywords - -QT += opengl multimedia-private network - -LIBS += -framework CoreMedia -framework CoreVideo -framework QuartzCore -framework Metal - -QMAKE_USE += avfoundation - -HEADERS += \ - avfmediaplayercontrol.h \ - avfmediaplayermetadatacontrol.h \ - avfmediaplayerservice.h \ - avfmediaplayersession.h \ - avfmediaplayerserviceplugin.h \ - avfvideooutput.h \ - avfvideowindowcontrol.h - -OBJECTIVE_SOURCES += \ - avfmediaplayercontrol.mm \ - avfmediaplayermetadatacontrol.mm \ - avfmediaplayerservice.mm \ - avfmediaplayerserviceplugin.mm \ - avfmediaplayersession.mm \ - avfvideooutput.mm \ - avfvideowindowcontrol.mm - - qtHaveModule(widgets) { - QT += multimediawidgets-private - HEADERS += \ - avfvideowidgetcontrol.h \ - avfvideowidget.h - - OBJECTIVE_SOURCES += \ - avfvideowidgetcontrol.mm \ - avfvideowidget.mm - } - -ios|tvos { - qtConfig(opengl) { - HEADERS += \ - avfvideoframerenderer_ios.h \ - avfvideorenderercontrol.h \ - avfdisplaylink.h - - OBJECTIVE_SOURCES += \ - avfvideoframerenderer_ios.mm \ - avfvideorenderercontrol.mm \ - avfdisplaylink.mm - } - LIBS += -framework Foundation -} else { - LIBS += -framework AppKit - - qtConfig(opengl) { - HEADERS += \ - avfvideoframerenderer.h \ - avfvideorenderercontrol.h \ - avfdisplaylink.h - - OBJECTIVE_SOURCES += \ - avfvideoframerenderer.mm \ - avfvideorenderercontrol.mm \ - avfdisplaylink.mm - } -} - -OTHER_FILES += \ - avfmediaplayer.json - -PLUGIN_TYPE = mediaservice -PLUGIN_CLASS_NAME = AVFMediaPlayerServicePlugin -load(qt_plugin) |