Initial implementation of Mac camera backend
Based on AVFoundation framework Change-Id: If4cfd105a592f50b42606624548b9ffc870e3e47 Reviewed-by: Gunnar Sletta <gunnar.sletta@nokia.com>
This commit is contained in:
committed by
Qt by Nokia
parent
09a7fda971
commit
37b872da9e
3
src/plugins/avfoundation/avfoundation.pro
Normal file
3
src/plugins/avfoundation/avfoundation.pro
Normal file
@@ -0,0 +1,3 @@
|
||||
TEMPLATE = subdirs
|
||||
|
||||
SUBDIRS += camera
|
||||
@@ -0,0 +1,86 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** This file may be used under the terms of the GNU Lesser General Public
|
||||
** License version 2.1 as published by the Free Software Foundation and
|
||||
** appearing in the file LICENSE.LGPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU Lesser
|
||||
** General Public License version 2.1 requirements will be met:
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $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 = 0);
|
||||
~AVFAudioInputSelectorControl();
|
||||
|
||||
QList<QString> availableInputs() const;
|
||||
QString inputDescription(const QString &name) const;
|
||||
QString defaultInput() const;
|
||||
QString activeInput() const;
|
||||
|
||||
public Q_SLOTS:
|
||||
void setActiveInput(const QString &name);
|
||||
|
||||
public:
|
||||
//device changed since the last createCaptureDevice()
|
||||
bool isDirty() const { return m_dirty; }
|
||||
AVCaptureDevice *createCaptureDevice();
|
||||
|
||||
private:
|
||||
AVFCameraService *m_service;
|
||||
|
||||
QString m_activeInput;
|
||||
bool m_dirty;
|
||||
QStringList m_devices;
|
||||
QMap<QString, QString> m_deviceDescriptions;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif
|
||||
117
src/plugins/avfoundation/camera/avfaudioinputselectorcontrol.mm
Normal file
117
src/plugins/avfoundation/camera/avfaudioinputselectorcontrol.mm
Normal file
@@ -0,0 +1,117 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** This file may be used under the terms of the GNU Lesser General Public
|
||||
** License version 2.1 as published by the Free Software Foundation and
|
||||
** appearing in the file LICENSE.LGPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU Lesser
|
||||
** General Public License version 2.1 requirements will be met:
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $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_service(service)
|
||||
, m_dirty(true)
|
||||
{
|
||||
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]));
|
||||
}
|
||||
|
||||
m_activeInput = m_devices.first();
|
||||
}
|
||||
|
||||
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_devices.first();
|
||||
}
|
||||
|
||||
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 = 0;
|
||||
|
||||
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"
|
||||
3
src/plugins/avfoundation/camera/avfcamera.json
Normal file
3
src/plugins/avfoundation/camera/avfcamera.json
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"Keys": ["org.qt-project.qt.camera"]
|
||||
}
|
||||
86
src/plugins/avfoundation/camera/avfcameracontrol.h
Normal file
86
src/plugins/avfoundation/camera/avfcameracontrol.h
Normal file
@@ -0,0 +1,86 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** This file may be used under the terms of the GNU Lesser General Public
|
||||
** License version 2.1 as published by the Free Software Foundation and
|
||||
** appearing in the file LICENSE.LGPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU Lesser
|
||||
** General Public License version 2.1 requirements will be met:
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $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 = 0);
|
||||
~AVFCameraControl();
|
||||
|
||||
QCamera::State state() const;
|
||||
void setState(QCamera::State state);
|
||||
|
||||
QCamera::Status status() const;
|
||||
|
||||
QCamera::CaptureModes captureMode() const;
|
||||
void setCaptureMode(QCamera::CaptureModes);
|
||||
bool isCaptureModeSupported(QCamera::CaptureModes mode) const;
|
||||
|
||||
bool canChangeProperty(PropertyChangeType changeType, QCamera::Status status) const;
|
||||
|
||||
private Q_SLOTS:
|
||||
void updateStatus();
|
||||
|
||||
private:
|
||||
AVFCameraService *m_service;
|
||||
AVFCameraSession *m_session;
|
||||
|
||||
QCamera::State m_state;
|
||||
QCamera::Status m_lastStatus;
|
||||
QCamera::CaptureModes m_captureMode;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif
|
||||
135
src/plugins/avfoundation/camera/avfcameracontrol.mm
Normal file
135
src/plugins/avfoundation/camera/avfcameracontrol.mm
Normal file
@@ -0,0 +1,135 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** This file may be used under the terms of the GNU Lesser General Public
|
||||
** License version 2.1 as published by the Free Software Foundation and
|
||||
** appearing in the file LICENSE.LGPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU Lesser
|
||||
** General Public License version 2.1 requirements will be met:
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $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_service(service)
|
||||
, m_session(service->session())
|
||||
, m_state(QCamera::UnloadedState)
|
||||
, m_lastStatus(QCamera::UnloadedStatus)
|
||||
, m_captureMode(QCamera::CaptureStillImage)
|
||||
{
|
||||
connect(m_session, SIGNAL(stateChanged(QCamera::State)), SLOT(updateStatus()));
|
||||
}
|
||||
|
||||
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"
|
||||
59
src/plugins/avfoundation/camera/avfcameradebug.h
Normal file
59
src/plugins/avfoundation/camera/avfcameradebug.h
Normal file
@@ -0,0 +1,59 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** This file may be used under the terms of the GNU Lesser General Public
|
||||
** License version 2.1 as published by the Free Software Foundation and
|
||||
** appearing in the file LICENSE.LGPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU Lesser
|
||||
** General Public License version 2.1 requirements will be met:
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef AVFDEBUG_H
|
||||
#define AVFDEBUG_H
|
||||
|
||||
#include "qtmultimediadefs.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
|
||||
72
src/plugins/avfoundation/camera/avfcamerametadatacontrol.h
Normal file
72
src/plugins/avfoundation/camera/avfcamerametadatacontrol.h
Normal file
@@ -0,0 +1,72 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** This file may be used under the terms of the GNU Lesser General Public
|
||||
** License version 2.1 as published by the Free Software Foundation and
|
||||
** appearing in the file LICENSE.LGPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU Lesser
|
||||
** General Public License version 2.1 requirements will be met:
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $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=0);
|
||||
virtual ~AVFCameraMetaDataControl();
|
||||
|
||||
bool isMetaDataAvailable() const;
|
||||
bool isWritable() const;
|
||||
|
||||
QVariant metaData(const QString &key) const;
|
||||
void setMetaData(const QString &key, const QVariant &value);
|
||||
QStringList availableMetaData() const;
|
||||
|
||||
private:
|
||||
AVFCameraService *m_service;
|
||||
QMap<QString, QVariant> m_tags;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif
|
||||
84
src/plugins/avfoundation/camera/avfcamerametadatacontrol.mm
Normal file
84
src/plugins/avfoundation/camera/avfcamerametadatacontrol.mm
Normal file
@@ -0,0 +1,84 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** This file may be used under the terms of the GNU Lesser General Public
|
||||
** License version 2.1 as published by the Free Software Foundation and
|
||||
** appearing in the file LICENSE.LGPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU Lesser
|
||||
** General Public License version 2.1 requirements will be met:
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $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), m_service(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"
|
||||
95
src/plugins/avfoundation/camera/avfcameraservice.h
Normal file
95
src/plugins/avfoundation/camera/avfcameraservice.h
Normal file
@@ -0,0 +1,95 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** This file may be used under the terms of the GNU Lesser General Public
|
||||
** License version 2.1 as published by the Free Software Foundation and
|
||||
** appearing in the file LICENSE.LGPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU Lesser
|
||||
** General Public License version 2.1 requirements will be met:
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $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 AVFCameraControl;
|
||||
class AVFCameraMetaDataControl;
|
||||
class AVFVideoWindowControl;
|
||||
class AVFVideoWidgetControl;
|
||||
class AVFVideoRendererControl;
|
||||
class AVFMediaRecorderControl;
|
||||
class AVFImageCaptureControl;
|
||||
class AVFCameraSession;
|
||||
class AVFVideoDeviceControl;
|
||||
class AVFAudioInputSelectorControl;
|
||||
|
||||
class AVFCameraService : public QMediaService
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
AVFCameraService(QObject *parent = 0);
|
||||
~AVFCameraService();
|
||||
|
||||
QMediaControl* requestControl(const char *name);
|
||||
void releaseControl(QMediaControl *control);
|
||||
|
||||
AVFCameraSession *session() const { return m_session; }
|
||||
AVFCameraControl *cameraControl() const { return m_cameraControl; }
|
||||
AVFVideoDeviceControl *videoDeviceControl() const { return m_videoDeviceControl; }
|
||||
AVFAudioInputSelectorControl *audioInputSelectorControl() const { return m_audioInputSelectorControl; }
|
||||
AVFCameraMetaDataControl *metaDataControl() const { return m_metaDataControl; }
|
||||
AVFMediaRecorderControl *recorderControl() const { return m_recorderControl; }
|
||||
AVFImageCaptureControl *imageCaptureControl() const { return m_imageCaptureControl; }
|
||||
|
||||
|
||||
private:
|
||||
AVFCameraSession *m_session;
|
||||
AVFCameraControl *m_cameraControl;
|
||||
AVFVideoDeviceControl *m_videoDeviceControl;
|
||||
AVFAudioInputSelectorControl *m_audioInputSelectorControl;
|
||||
AVFVideoRendererControl *m_videoOutput;
|
||||
AVFCameraMetaDataControl *m_metaDataControl;
|
||||
AVFMediaRecorderControl *m_recorderControl;
|
||||
AVFImageCaptureControl *m_imageCaptureControl;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif
|
||||
139
src/plugins/avfoundation/camera/avfcameraservice.mm
Normal file
139
src/plugins/avfoundation/camera/avfcameraservice.mm
Normal file
@@ -0,0 +1,139 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** This file may be used under the terms of the GNU Lesser General Public
|
||||
** License version 2.1 as published by the Free Software Foundation and
|
||||
** appearing in the file LICENSE.LGPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU Lesser
|
||||
** General Public License version 2.1 requirements will be met:
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QtCore/qvariant.h>
|
||||
#include <QtCore/qdebug.h>
|
||||
|
||||
#include "avfcameraservice.h"
|
||||
#include "avfcameracontrol.h"
|
||||
#include "avfcamerasession.h"
|
||||
#include "avfvideodevicecontrol.h"
|
||||
#include "avfaudioinputselectorcontrol.h"
|
||||
#include "avfcamerametadatacontrol.h"
|
||||
#include "avfmediarecordercontrol.h"
|
||||
#include "avfimagecapturecontrol.h"
|
||||
#include "avfvideorenderercontrol.h"
|
||||
#include "avfmediarecordercontrol.h"
|
||||
#include "avfimagecapturecontrol.h"
|
||||
|
||||
#include <private/qmediaplaylistnavigator_p.h>
|
||||
#include <qmediaplaylist.h>
|
||||
|
||||
QT_USE_NAMESPACE
|
||||
|
||||
AVFCameraService::AVFCameraService(QObject *parent):
|
||||
QMediaService(parent),
|
||||
m_videoOutput(0)
|
||||
{
|
||||
m_session = new AVFCameraSession(this);
|
||||
m_cameraControl = new AVFCameraControl(this);
|
||||
m_videoDeviceControl = new AVFVideoDeviceControl(this);
|
||||
m_audioInputSelectorControl = new AVFAudioInputSelectorControl(this);
|
||||
|
||||
m_metaDataControl = new AVFCameraMetaDataControl(this);
|
||||
m_recorderControl = new AVFMediaRecorderControl(this);
|
||||
m_imageCaptureControl = new AVFImageCaptureControl(this);
|
||||
}
|
||||
|
||||
AVFCameraService::~AVFCameraService()
|
||||
{
|
||||
m_cameraControl->setState(QCamera::UnloadedState);
|
||||
|
||||
if (m_videoOutput) {
|
||||
m_session->setVideoOutput(0);
|
||||
delete m_videoOutput;
|
||||
m_videoOutput = 0;
|
||||
}
|
||||
|
||||
//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_session;
|
||||
}
|
||||
|
||||
QMediaControl *AVFCameraService::requestControl(const char *name)
|
||||
{
|
||||
if (qstrcmp(name, QCameraControl_iid) == 0)
|
||||
return m_cameraControl;
|
||||
|
||||
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 (!m_videoOutput) {
|
||||
if (qstrcmp(name, QVideoRendererControl_iid) == 0)
|
||||
m_videoOutput = new AVFVideoRendererControl(this);
|
||||
|
||||
if (m_videoOutput) {
|
||||
m_session->setVideoOutput(m_videoOutput);
|
||||
return m_videoOutput;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void AVFCameraService::releaseControl(QMediaControl *control)
|
||||
{
|
||||
if (m_videoOutput == control) {
|
||||
m_videoOutput = 0;
|
||||
m_session->setVideoOutput(0);
|
||||
delete control;
|
||||
}
|
||||
}
|
||||
|
||||
#include "moc_avfcameraservice.cpp"
|
||||
76
src/plugins/avfoundation/camera/avfcameraserviceplugin.h
Normal file
76
src/plugins/avfoundation/camera/avfcameraserviceplugin.h
Normal file
@@ -0,0 +1,76 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** This file may be used under the terms of the GNU Lesser General Public
|
||||
** License version 2.1 as published by the Free Software Foundation and
|
||||
** appearing in the file LICENSE.LGPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU Lesser
|
||||
** General Public License version 2.1 requirements will be met:
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $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
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(QMediaServiceSupportedDevicesInterface)
|
||||
Q_PLUGIN_METADATA(IID "org.qt-project.qt.mediaserviceproviderfactory/5.0" FILE "avfcamera.json")
|
||||
|
||||
public:
|
||||
AVFServicePlugin();
|
||||
|
||||
QMediaService* create(QString const& key);
|
||||
void release(QMediaService *service);
|
||||
|
||||
QList<QByteArray> devices(const QByteArray &service) const;
|
||||
QString deviceDescription(const QByteArray &service, const QByteArray &device);
|
||||
|
||||
private:
|
||||
void updateDevices() const;
|
||||
|
||||
mutable QList<QByteArray> m_cameraDevices;
|
||||
mutable QMap<QByteArray, QString> m_cameraDescriptions;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif
|
||||
112
src/plugins/avfoundation/camera/avfcameraserviceplugin.mm
Normal file
112
src/plugins/avfoundation/camera/avfcameraserviceplugin.mm
Normal file
@@ -0,0 +1,112 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** This file may be used under the terms of the GNU Lesser General Public
|
||||
** License version 2.1 as published by the Free Software Foundation and
|
||||
** appearing in the file LICENSE.LGPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU Lesser
|
||||
** General Public License version 2.1 requirements will be met:
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QtCore/qstring.h>
|
||||
#include <QtCore/qdebug.h>
|
||||
|
||||
#include "avfcameraserviceplugin.h"
|
||||
#include "avfcameraservice.h"
|
||||
|
||||
#include <qmediaserviceproviderplugin.h>
|
||||
|
||||
#import <AVFoundation/AVFoundation.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 0;
|
||||
}
|
||||
|
||||
void AVFServicePlugin::release(QMediaService *service)
|
||||
{
|
||||
delete service;
|
||||
}
|
||||
|
||||
QList<QByteArray> AVFServicePlugin::devices(const QByteArray &service) const
|
||||
{
|
||||
if (service == Q_MEDIASERVICE_CAMERA) {
|
||||
if (m_cameraDevices.isEmpty())
|
||||
updateDevices();
|
||||
|
||||
return m_cameraDevices;
|
||||
}
|
||||
|
||||
return QList<QByteArray>();
|
||||
}
|
||||
|
||||
QString AVFServicePlugin::deviceDescription(const QByteArray &service, const QByteArray &device)
|
||||
{
|
||||
if (service == Q_MEDIASERVICE_CAMERA) {
|
||||
if (m_cameraDevices.isEmpty())
|
||||
updateDevices();
|
||||
|
||||
return m_cameraDescriptions.value(device);
|
||||
}
|
||||
|
||||
return QString();
|
||||
}
|
||||
|
||||
void AVFServicePlugin::updateDevices() const
|
||||
{
|
||||
m_cameraDevices.clear();
|
||||
m_cameraDescriptions.clear();
|
||||
|
||||
NSArray *videoDevices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
|
||||
for (AVCaptureDevice *device in videoDevices) {
|
||||
QByteArray deviceId([[device uniqueID] UTF8String]);
|
||||
m_cameraDevices << deviceId;
|
||||
m_cameraDescriptions.insert(deviceId, QString::fromUtf8([[device localizedName] UTF8String]));
|
||||
}
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
101
src/plugins/avfoundation/camera/avfcamerasession.h
Normal file
101
src/plugins/avfoundation/camera/avfcamerasession.h
Normal file
@@ -0,0 +1,101 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** This file may be used under the terms of the GNU Lesser General Public
|
||||
** License version 2.1 as published by the Free Software Foundation and
|
||||
** appearing in the file LICENSE.LGPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU Lesser
|
||||
** General Public License version 2.1 requirements will be met:
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef AVFCAMERASESSION_H
|
||||
#define AVFCAMERASESSION_H
|
||||
|
||||
#include <QtCore/qmutex.h>
|
||||
#include <QtMultimedia/qcamera.h>
|
||||
|
||||
#import <AVFoundation/AVFoundation.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class AVFCameraControl;
|
||||
class AVFCameraService;
|
||||
class AVFVideoRendererControl;
|
||||
@class AVFCameraSessionObserver;
|
||||
|
||||
class AVFCameraSession : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
AVFCameraSession(AVFCameraService *service, QObject *parent = 0);
|
||||
~AVFCameraSession();
|
||||
|
||||
void setVideoOutput(AVFVideoRendererControl *output);
|
||||
AVCaptureSession *captureSession() const { return m_captureSession; }
|
||||
|
||||
QCamera::State state() const;
|
||||
QCamera::State requestedState() const { return m_state; }
|
||||
bool isActive() const { return m_active; }
|
||||
|
||||
public Q_SLOTS:
|
||||
void setState(QCamera::State state);
|
||||
|
||||
void processRuntimeError();
|
||||
void processSessionStarted();
|
||||
void processSessionStopped();
|
||||
|
||||
Q_SIGNALS:
|
||||
void readyToConfigureConnections();
|
||||
void stateChanged(QCamera::State newState);
|
||||
void activeChanged(bool);
|
||||
void error(int error, const QString &errorString);
|
||||
|
||||
private:
|
||||
void attachInputDevices();
|
||||
|
||||
AVFCameraService *m_service;
|
||||
AVFVideoRendererControl *m_videoOutput;
|
||||
|
||||
QCamera::State m_state;
|
||||
bool m_active;
|
||||
|
||||
AVCaptureSession *m_captureSession;
|
||||
AVCaptureDeviceInput *m_videoInput;
|
||||
AVCaptureDeviceInput *m_audioInput;
|
||||
AVFCameraSessionObserver *m_observer;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif
|
||||
277
src/plugins/avfoundation/camera/avfcamerasession.mm
Normal file
277
src/plugins/avfoundation/camera/avfcamerasession.mm
Normal file
@@ -0,0 +1,277 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** This file may be used under the terms of the GNU Lesser General Public
|
||||
** License version 2.1 as published by the Free Software Foundation and
|
||||
** appearing in the file LICENSE.LGPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU Lesser
|
||||
** General Public License version 2.1 requirements will be met:
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "avfcameradebug.h"
|
||||
#include "avfcamerasession.h"
|
||||
#include "avfcameraservice.h"
|
||||
#include "avfcameracontrol.h"
|
||||
#include "avfvideorenderercontrol.h"
|
||||
#include "avfvideodevicecontrol.h"
|
||||
#include "avfaudioinputselectorcontrol.h"
|
||||
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
#include <Foundation/Foundation.h>
|
||||
|
||||
#include <QtCore/qdatetime.h>
|
||||
#include <QtCore/qurl.h>
|
||||
|
||||
#include <QtCore/qdebug.h>
|
||||
|
||||
QT_USE_NAMESPACE
|
||||
|
||||
@interface AVFCameraSessionObserver : NSObject
|
||||
{
|
||||
@private
|
||||
AVFCameraSession *m_session;
|
||||
AVCaptureSession *m_captureSession;
|
||||
}
|
||||
|
||||
- (AVFCameraSessionObserver *) initWithCameraSession:(AVFCameraSession*)session;
|
||||
- (void) processRuntimeError:(NSNotification *)notification;
|
||||
- (void) processSessionStarted:(NSNotification *)notification;
|
||||
- (void) processSessionStopped:(NSNotification *)notification;
|
||||
|
||||
@end
|
||||
|
||||
@implementation AVFCameraSessionObserver
|
||||
|
||||
- (AVFCameraSessionObserver *) initWithCameraSession:(AVFCameraSession*)session
|
||||
{
|
||||
if (!(self = [super init]))
|
||||
return nil;
|
||||
|
||||
self->m_session = session;
|
||||
self->m_captureSession = session->captureSession();
|
||||
|
||||
[[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) 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_state(QCamera::UnloadedState)
|
||||
, m_active(false)
|
||||
, m_videoInput(nil)
|
||||
, m_audioInput(nil)
|
||||
{
|
||||
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_videoInput) {
|
||||
[m_captureSession removeInput:m_videoInput];
|
||||
[m_videoInput release];
|
||||
}
|
||||
|
||||
if (m_audioInput) {
|
||||
[m_captureSession removeInput:m_audioInput];
|
||||
[m_audioInput release];
|
||||
}
|
||||
|
||||
[m_observer release];
|
||||
[m_captureSession release];
|
||||
}
|
||||
|
||||
void AVFCameraSession::setVideoOutput(AVFVideoRendererControl *output)
|
||||
{
|
||||
m_videoOutput = output;
|
||||
if (output)
|
||||
output->configureAVCaptureSession(m_captureSession);
|
||||
}
|
||||
|
||||
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 audio and video inputs during Unloaded->Loaded transition
|
||||
if (oldState == QCamera::UnloadedState) {
|
||||
attachInputDevices();
|
||||
}
|
||||
|
||||
if (m_state == QCamera::ActiveState) {
|
||||
Q_EMIT readyToConfigureConnections();
|
||||
[m_captureSession commitConfiguration];
|
||||
[m_captureSession startRunning];
|
||||
}
|
||||
|
||||
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::attachInputDevices()
|
||||
{
|
||||
//Attach video input device:
|
||||
if (m_service->videoDeviceControl()->isDirty()) {
|
||||
if (m_videoInput) {
|
||||
[m_captureSession removeInput:m_videoInput];
|
||||
[m_videoInput release];
|
||||
m_videoInput = 0;
|
||||
}
|
||||
|
||||
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_videoInput retain];
|
||||
[m_captureSession addInput:m_videoInput];
|
||||
} else {
|
||||
qWarning() << "Failed to connect video device input";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Attach audio input device:
|
||||
if (m_service->audioInputSelectorControl()->isDirty()) {
|
||||
if (m_audioInput) {
|
||||
[m_captureSession removeInput:m_audioInput];
|
||||
[m_audioInput release];
|
||||
m_audioInput = 0;
|
||||
}
|
||||
|
||||
AVCaptureDevice *audioDevice = m_service->audioInputSelectorControl()->createCaptureDevice();
|
||||
|
||||
NSError *error = nil;
|
||||
m_audioInput = [AVCaptureDeviceInput
|
||||
deviceInputWithDevice:audioDevice
|
||||
error:&error];
|
||||
|
||||
if (!m_audioInput) {
|
||||
qWarning() << "Failed to create audio device input";
|
||||
} else {
|
||||
[m_audioInput retain];
|
||||
[m_captureSession addInput:m_audioInput];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#include "moc_avfcamerasession.cpp"
|
||||
88
src/plugins/avfoundation/camera/avfimagecapturecontrol.h
Normal file
88
src/plugins/avfoundation/camera/avfimagecapturecontrol.h
Normal file
@@ -0,0 +1,88 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** This file may be used under the terms of the GNU Lesser General Public
|
||||
** License version 2.1 as published by the Free Software Foundation and
|
||||
** appearing in the file LICENSE.LGPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU Lesser
|
||||
** General Public License version 2.1 requirements will be met:
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef AVFIMAGECAPTURECONTROL_H
|
||||
#define AVFIMAGECAPTURECONTROL_H
|
||||
|
||||
#import <AVFoundation/AVFoundation.h>
|
||||
|
||||
#include <QtMultimedia/qcameraimagecapturecontrol.h>
|
||||
#include "avfstoragelocation.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class AVFCameraSession;
|
||||
class AVFCameraService;
|
||||
class AVFCameraControl;
|
||||
|
||||
class AVFImageCaptureControl : public QCameraImageCaptureControl
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
AVFImageCaptureControl(AVFCameraService *service, QObject *parent = 0);
|
||||
~AVFImageCaptureControl();
|
||||
|
||||
bool isReadyForCapture() const;
|
||||
|
||||
QCameraImageCapture::DriveMode driveMode() const { return QCameraImageCapture::SingleImageCapture; }
|
||||
void setDriveMode(QCameraImageCapture::DriveMode ) {}
|
||||
|
||||
int capture(const QString &fileName);
|
||||
void cancelCapture();
|
||||
|
||||
private Q_SLOTS:
|
||||
void updateCaptureConnection();
|
||||
void updateReadyStatus();
|
||||
|
||||
private:
|
||||
AVFCameraService *m_service;
|
||||
AVFCameraSession *m_session;
|
||||
AVFCameraControl *m_cameraControl;
|
||||
bool m_ready;
|
||||
int m_lastCaptureId;
|
||||
AVCaptureStillImageOutput *m_stillImageOutput;
|
||||
AVCaptureConnection *m_videoConnection;
|
||||
AVFStorageLocation m_storageLocation;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif
|
||||
222
src/plugins/avfoundation/camera/avfimagecapturecontrol.mm
Normal file
222
src/plugins/avfoundation/camera/avfimagecapturecontrol.mm
Normal file
@@ -0,0 +1,222 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** This file may be used under the terms of the GNU Lesser General Public
|
||||
** License version 2.1 as published by the Free Software Foundation and
|
||||
** appearing in the file LICENSE.LGPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU Lesser
|
||||
** General Public License version 2.1 requirements will be met:
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "avfcameradebug.h"
|
||||
#include "avfimagecapturecontrol.h"
|
||||
#include "avfcamerasession.h"
|
||||
#include "avfcameraservice.h"
|
||||
#include "avfcameracontrol.h"
|
||||
|
||||
#include <QtCore/qurl.h>
|
||||
#include <QtCore/qfile.h>
|
||||
#include <QtCore/qbuffer.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)
|
||||
{
|
||||
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()));
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
QString actualFileName = m_storageLocation.generateFileName(fileName,
|
||||
QCamera::CaptureStillImage,
|
||||
QLatin1String("img_"),
|
||||
QLatin1String("jpg"));
|
||||
|
||||
qDebugCamera() << "Capture image to" << actualFileName;
|
||||
|
||||
int captureId = m_lastCaptureId;
|
||||
[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, captureId),
|
||||
Q_ARG(int, QCameraImageCapture::ResourceError),
|
||||
Q_ARG(QString, errorMessage));
|
||||
} else {
|
||||
qDebugCamera() << "Image captured:" << actualFileName;
|
||||
//we can't find the exact time the image is exposed,
|
||||
//but image capture is very fast on desktop, so emit it here
|
||||
QMetaObject::invokeMethod(this, "imageExposed", Qt::QueuedConnection,
|
||||
Q_ARG(int, captureId));
|
||||
|
||||
NSData *nsJpgData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageSampleBuffer];
|
||||
QByteArray jpgData = QByteArray::fromRawData((const char *)[nsJpgData bytes], [nsJpgData length]);
|
||||
|
||||
//Generate snap preview as downscalled image
|
||||
{
|
||||
QBuffer buffer(&jpgData);
|
||||
QImageReader imageReader(&buffer);
|
||||
QSize imgSize = imageReader.size();
|
||||
int downScaleSteps = 0;
|
||||
while (imgSize.width() > 800 && downScaleSteps < 8) {
|
||||
imgSize.rwidth() /= 2;
|
||||
imgSize.rheight() /= 2;
|
||||
downScaleSteps++;
|
||||
}
|
||||
|
||||
imageReader.setScaledSize(imgSize);
|
||||
QImage snapPreview = imageReader.read();
|
||||
|
||||
QMetaObject::invokeMethod(this, "imageCaptured", Qt::QueuedConnection,
|
||||
Q_ARG(int, captureId),
|
||||
Q_ARG(QImage, snapPreview));
|
||||
}
|
||||
|
||||
qDebugCamera() << "Image captured" << actualFileName;
|
||||
|
||||
QFile f(actualFileName);
|
||||
if (f.open(QFile::WriteOnly)) {
|
||||
if (f.write(jpgData) != -1) {
|
||||
QMetaObject::invokeMethod(this, "imageSaved", Qt::QueuedConnection,
|
||||
Q_ARG(int, captureId),
|
||||
Q_ARG(QString, actualFileName));
|
||||
} else {
|
||||
QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection,
|
||||
Q_ARG(int, 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, captureId),
|
||||
Q_ARG(int, QCameraImageCapture::ResourceError),
|
||||
Q_ARG(QString, errorMessage));
|
||||
}
|
||||
}
|
||||
}];
|
||||
|
||||
return captureId;
|
||||
}
|
||||
|
||||
void AVFImageCaptureControl::cancelCapture()
|
||||
{
|
||||
//not supported
|
||||
}
|
||||
|
||||
void AVFImageCaptureControl::updateCaptureConnection()
|
||||
{
|
||||
if (!m_videoConnection &&
|
||||
m_cameraControl->captureMode().testFlag(QCamera::CaptureStillImage)) {
|
||||
qDebugCamera() << Q_FUNC_INFO;
|
||||
AVCaptureSession *captureSession = m_session->captureSession();
|
||||
|
||||
if ([captureSession canAddOutput:m_stillImageOutput]) {
|
||||
[captureSession addOutput:m_stillImageOutput];
|
||||
|
||||
for (AVCaptureConnection *connection in m_stillImageOutput.connections) {
|
||||
for (AVCaptureInputPort *port in [connection inputPorts]) {
|
||||
if ([[port mediaType] isEqual:AVMediaTypeVideo] ) {
|
||||
m_videoConnection = connection;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_videoConnection)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
updateReadyStatus();
|
||||
}
|
||||
}
|
||||
|
||||
#include "moc_avfimagecapturecontrol.cpp"
|
||||
113
src/plugins/avfoundation/camera/avfmediarecordercontrol.h
Normal file
113
src/plugins/avfoundation/camera/avfmediarecordercontrol.h
Normal file
@@ -0,0 +1,113 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** This file may be used under the terms of the GNU Lesser General Public
|
||||
** License version 2.1 as published by the Free Software Foundation and
|
||||
** appearing in the file LICENSE.LGPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU Lesser
|
||||
** General Public License version 2.1 requirements will be met:
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef AVFMEDIARECORDERCONTROL_H
|
||||
#define AVFMEDIARECORDERCONTROL_H
|
||||
|
||||
#include <QtCore/qurl.h>
|
||||
#include <QtMultimedia/qmediarecordercontrol.h>
|
||||
|
||||
#import <AVFoundation/AVFoundation.h>
|
||||
#include "avfstoragelocation.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class AVFCameraSession;
|
||||
class AVFCameraControl;
|
||||
class AVFCameraService;
|
||||
@class AVFMediaRecorderDelegate;
|
||||
|
||||
class AVFMediaRecorderControl : public QMediaRecorderControl
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
AVFMediaRecorderControl(AVFCameraService *service, QObject *parent = 0);
|
||||
~AVFMediaRecorderControl();
|
||||
|
||||
QUrl outputLocation() const;
|
||||
bool setOutputLocation(const QUrl &location);
|
||||
|
||||
QMediaRecorder::State state() const;
|
||||
QMediaRecorder::Status status() const;
|
||||
|
||||
qint64 duration() const;
|
||||
|
||||
bool isMuted() const;
|
||||
qreal volume() const;
|
||||
|
||||
void applySettings();
|
||||
|
||||
public Q_SLOTS:
|
||||
void setState(QMediaRecorder::State state);
|
||||
void setMuted(bool muted);
|
||||
void setVolume(qreal volume);
|
||||
|
||||
void handleRecordingStarted();
|
||||
void handleRecordingFinished();
|
||||
void handleRecordingFailed(const QString &message);
|
||||
|
||||
private Q_SLOTS:
|
||||
void reconnectMovieOutput();
|
||||
void updateStatus();
|
||||
|
||||
private:
|
||||
AVFCameraControl *m_cameraControl;
|
||||
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;
|
||||
|
||||
AVCaptureMovieFileOutput *m_movieOutput;
|
||||
AVFMediaRecorderDelegate *m_recorderDelagate;
|
||||
AVFStorageLocation m_storageLocation;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif
|
||||
342
src/plugins/avfoundation/camera/avfmediarecordercontrol.mm
Normal file
342
src/plugins/avfoundation/camera/avfmediarecordercontrol.mm
Normal file
@@ -0,0 +1,342 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** This file may be used under the terms of the GNU Lesser General Public
|
||||
** License version 2.1 as published by the Free Software Foundation and
|
||||
** appearing in the file LICENSE.LGPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU Lesser
|
||||
** General Public License version 2.1 requirements will be met:
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "avfcameradebug.h"
|
||||
#include "avfmediarecordercontrol.h"
|
||||
#include "avfcamerasession.h"
|
||||
#include "avfcameraservice.h"
|
||||
#include "avfcameracontrol.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_cameraControl(service->cameraControl())
|
||||
, 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_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(reconnectMovieOutput()));
|
||||
|
||||
reconnectMovieOutput();
|
||||
}
|
||||
|
||||
AVFMediaRecorderControl::~AVFMediaRecorderControl()
|
||||
{
|
||||
if (m_movieOutput)
|
||||
[m_session->captureSession() removeOutput:m_movieOutput];
|
||||
|
||||
[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()
|
||||
{
|
||||
}
|
||||
|
||||
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) {
|
||||
m_state = QMediaRecorder::RecordingState;
|
||||
m_recordingStarted = false;
|
||||
m_recordingFinished = false;
|
||||
|
||||
QString outputLocationPath = m_outputLocation.scheme() == QLatin1String("file") ?
|
||||
m_outputLocation.path() : m_outputLocation.toString();
|
||||
|
||||
QUrl actualLocation = QUrl::fromLocalFile(
|
||||
m_storageLocation.generateFileName(outputLocationPath,
|
||||
QCamera::CaptureVideo,
|
||||
QLatin1String("clip_"),
|
||||
QLatin1String("mp4")));
|
||||
|
||||
qDebugCamera() << "Video capture location:" << actualLocation.toString();
|
||||
|
||||
NSString *urlString = [NSString stringWithUTF8String:actualLocation.toString().toUtf8().constData()];
|
||||
NSURL *fileURL = [NSURL URLWithString:urlString];
|
||||
|
||||
[m_movieOutput startRecordingToOutputFileURL:fileURL recordingDelegate:m_recorderDelagate];
|
||||
|
||||
Q_EMIT actualLocationChanged(actualLocation);
|
||||
} 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_state = QMediaRecorder::StoppedState;
|
||||
[m_movieOutput stopRecording];
|
||||
}
|
||||
}
|
||||
|
||||
updateStatus();
|
||||
Q_EMIT stateChanged(m_state);
|
||||
}
|
||||
|
||||
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;
|
||||
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::reconnectMovieOutput()
|
||||
{
|
||||
//adding movie output causes high CPU usage even when while recording is not active,
|
||||
//connect it only while video capture mode is enabled
|
||||
AVCaptureSession *captureSession = m_session->captureSession();
|
||||
|
||||
if (!m_connected && m_cameraControl->captureMode().testFlag(QCamera::CaptureVideo)) {
|
||||
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)) {
|
||||
[captureSession removeOutput:m_movieOutput];
|
||||
m_connected = false;
|
||||
}
|
||||
|
||||
updateStatus();
|
||||
}
|
||||
|
||||
#include "moc_avfmediarecordercontrol.cpp"
|
||||
73
src/plugins/avfoundation/camera/avfstoragelocation.h
Normal file
73
src/plugins/avfoundation/camera/avfstoragelocation.h
Normal file
@@ -0,0 +1,73 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** This file may be used under the terms of the GNU Lesser General Public
|
||||
** License version 2.1 as published by the Free Software Foundation and
|
||||
** appearing in the file LICENSE.LGPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU Lesser
|
||||
** General Public License version 2.1 requirements will be met:
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef AVFSTORAGE_H
|
||||
#define AVFSTORAGE_H
|
||||
|
||||
#include "qtmultimediadefs.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
|
||||
137
src/plugins/avfoundation/camera/avfstoragelocation.mm
Normal file
137
src/plugins/avfoundation/camera/avfstoragelocation.mm
Normal file
@@ -0,0 +1,137 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** This file may be used under the terms of the GNU Lesser General Public
|
||||
** License version 2.1 as published by the Free Software Foundation and
|
||||
** appearing in the file LICENSE.LGPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU Lesser
|
||||
** General Public License version 2.1 requirements will be met:
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $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();
|
||||
|
||||
Q_FOREACH (const QString &path, 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
|
||||
Q_FOREACH (const QString &fileName, dir.entryList(QStringList() << QString("%1*.%2").arg(prefix).arg(ext))) {
|
||||
int imgNumber = 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
|
||||
89
src/plugins/avfoundation/camera/avfvideodevicecontrol.h
Normal file
89
src/plugins/avfoundation/camera/avfvideodevicecontrol.h
Normal file
@@ -0,0 +1,89 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** This file may be used under the terms of the GNU Lesser General Public
|
||||
** License version 2.1 as published by the Free Software Foundation and
|
||||
** appearing in the file LICENSE.LGPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU Lesser
|
||||
** General Public License version 2.1 requirements will be met:
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef AVFVIDEODEVICECONTROL_H
|
||||
#define AVFVIDEODEVICECONTROL_H
|
||||
|
||||
#include <QtMultimedia/qvideodeviceselectorcontrol.h>
|
||||
#include <QtCore/qstringlist.h>
|
||||
|
||||
#import <AVFoundation/AVFoundation.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class AVFCameraSession;
|
||||
class AVFCameraService;
|
||||
|
||||
class AVFVideoDeviceControl : public QVideoDeviceSelectorControl
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
AVFVideoDeviceControl(AVFCameraService *service, QObject *parent = 0);
|
||||
~AVFVideoDeviceControl();
|
||||
|
||||
int deviceCount() const;
|
||||
|
||||
QString deviceName(int index) const;
|
||||
QString deviceDescription(int index) const;
|
||||
|
||||
int defaultDevice() const;
|
||||
int selectedDevice() const;
|
||||
|
||||
public Q_SLOTS:
|
||||
void setSelectedDevice(int index);
|
||||
|
||||
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;
|
||||
QStringList m_devices;
|
||||
QStringList m_deviceDescriptions;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif
|
||||
119
src/plugins/avfoundation/camera/avfvideodevicecontrol.mm
Normal file
119
src/plugins/avfoundation/camera/avfvideodevicecontrol.mm
Normal file
@@ -0,0 +1,119 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** This file may be used under the terms of the GNU Lesser General Public
|
||||
** License version 2.1 as published by the Free Software Foundation and
|
||||
** appearing in the file LICENSE.LGPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU Lesser
|
||||
** General Public License version 2.1 requirements will be met:
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "avfcameradebug.h"
|
||||
#include "avfvideodevicecontrol.h"
|
||||
#include "avfcameraservice.h"
|
||||
|
||||
QT_USE_NAMESPACE
|
||||
|
||||
AVFVideoDeviceControl::AVFVideoDeviceControl(AVFCameraService *service, QObject *parent)
|
||||
: QVideoDeviceSelectorControl(parent)
|
||||
, m_service(service)
|
||||
, m_selectedDevice(0)
|
||||
, m_dirty(true)
|
||||
{
|
||||
NSArray *videoDevices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
|
||||
for (AVCaptureDevice *device in videoDevices) {
|
||||
m_devices << QString::fromUtf8([[device uniqueID] UTF8String]);
|
||||
m_deviceDescriptions << QString::fromUtf8([[device localizedName] UTF8String]);
|
||||
}
|
||||
}
|
||||
|
||||
AVFVideoDeviceControl::~AVFVideoDeviceControl()
|
||||
{
|
||||
}
|
||||
|
||||
int AVFVideoDeviceControl::deviceCount() const
|
||||
{
|
||||
return m_devices.size();
|
||||
}
|
||||
|
||||
QString AVFVideoDeviceControl::deviceName(int index) const
|
||||
{
|
||||
return m_devices[index];
|
||||
}
|
||||
|
||||
QString AVFVideoDeviceControl::deviceDescription(int index) const
|
||||
{
|
||||
return m_deviceDescriptions[index];
|
||||
}
|
||||
|
||||
int AVFVideoDeviceControl::defaultDevice() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int AVFVideoDeviceControl::selectedDevice() const
|
||||
{
|
||||
return m_selectedDevice;
|
||||
}
|
||||
|
||||
void AVFVideoDeviceControl::setSelectedDevice(int index)
|
||||
{
|
||||
if (index != m_selectedDevice) {
|
||||
m_dirty = true;
|
||||
m_selectedDevice = index;
|
||||
Q_EMIT selectedDeviceChanged(index);
|
||||
Q_EMIT selectedDeviceChanged(m_devices[index]);
|
||||
}
|
||||
}
|
||||
|
||||
AVCaptureDevice *AVFVideoDeviceControl::createCaptureDevice()
|
||||
{
|
||||
m_dirty = false;
|
||||
AVCaptureDevice *device = 0;
|
||||
|
||||
if (!m_devices.isEmpty()) {
|
||||
QString deviceId = m_devices.at(m_selectedDevice);
|
||||
|
||||
device = [AVCaptureDevice deviceWithUniqueID:
|
||||
[NSString stringWithUTF8String:
|
||||
deviceId.toUtf8().constData()]];
|
||||
}
|
||||
|
||||
if (!device)
|
||||
device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
|
||||
|
||||
return device;
|
||||
}
|
||||
|
||||
#include "moc_avfvideodevicecontrol.cpp"
|
||||
90
src/plugins/avfoundation/camera/avfvideorenderercontrol.h
Normal file
90
src/plugins/avfoundation/camera/avfvideorenderercontrol.h
Normal file
@@ -0,0 +1,90 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** This file may be used under the terms of the GNU Lesser General Public
|
||||
** License version 2.1 as published by the Free Software Foundation and
|
||||
** appearing in the file LICENSE.LGPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU Lesser
|
||||
** General Public License version 2.1 requirements will be met:
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef AVFVIDEORENDERERCONTROL_H
|
||||
#define AVFVIDEORENDERERCONTROL_H
|
||||
|
||||
#include <QtMultimedia/qvideorenderercontrol.h>
|
||||
#include <QtMultimedia/qvideoframe.h>
|
||||
#include <QtCore/qmutex.h>
|
||||
|
||||
#import <AVFoundation/AVFoundation.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class AVFCameraSession;
|
||||
class AVFCameraService;
|
||||
class AVFVideoRendererControl;
|
||||
|
||||
@class AVFCaptureFramesDelegate;
|
||||
|
||||
class AVFVideoRendererControl : public QVideoRendererControl
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
AVFVideoRendererControl(QObject *parent = 0);
|
||||
~AVFVideoRendererControl();
|
||||
|
||||
QAbstractVideoSurface *surface() const;
|
||||
void setSurface(QAbstractVideoSurface *surface);
|
||||
|
||||
void configureAVCaptureSession(AVCaptureSession *captureSession);
|
||||
void syncHandleViewfinderFrame(const QVideoFrame &frame);
|
||||
|
||||
Q_SIGNALS:
|
||||
void surfaceChanged(QAbstractVideoSurface *surface);
|
||||
|
||||
private Q_SLOTS:
|
||||
void handleViewfinderFrame();
|
||||
|
||||
private:
|
||||
QAbstractVideoSurface *m_surface;
|
||||
AVFCaptureFramesDelegate *m_viewfinderFramesDelegate;
|
||||
AVCaptureSession *m_captureSession;
|
||||
AVCaptureVideoDataOutput *m_videoDataOutput;
|
||||
|
||||
QVideoFrame m_lastViewfinderFrame;
|
||||
QMutex m_vfMutex;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif
|
||||
237
src/plugins/avfoundation/camera/avfvideorenderercontrol.mm
Normal file
237
src/plugins/avfoundation/camera/avfvideorenderercontrol.mm
Normal file
@@ -0,0 +1,237 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** This file may be used under the terms of the GNU Lesser General Public
|
||||
** License version 2.1 as published by the Free Software Foundation and
|
||||
** appearing in the file LICENSE.LGPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU Lesser
|
||||
** General Public License version 2.1 requirements will be met:
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "avfvideorenderercontrol.h"
|
||||
#include "avfcamerasession.h"
|
||||
#include "avfcameraservice.h"
|
||||
#include "avfcameradebug.h"
|
||||
|
||||
#include <QtMultimedia/qabstractvideosurface.h>
|
||||
#include <QtMultimedia/qabstractvideobuffer.h>
|
||||
#include <QtMultimedia/qvideosurfaceformat.h>
|
||||
|
||||
QT_USE_NAMESPACE
|
||||
|
||||
class CVPixelBufferVideoBuffer : public QAbstractVideoBuffer
|
||||
{
|
||||
public:
|
||||
CVPixelBufferVideoBuffer(CVPixelBufferRef buffer)
|
||||
: QAbstractVideoBuffer(NoHandle)
|
||||
, m_buffer(buffer)
|
||||
, m_mode(NotMapped)
|
||||
{
|
||||
CVPixelBufferRetain(m_buffer);
|
||||
}
|
||||
|
||||
virtual ~CVPixelBufferVideoBuffer()
|
||||
{
|
||||
CVPixelBufferRelease(m_buffer);
|
||||
}
|
||||
|
||||
MapMode mapMode() const { return m_mode; }
|
||||
|
||||
uchar *map(MapMode mode, int *numBytes, int *bytesPerLine)
|
||||
{
|
||||
if (mode != NotMapped && m_mode == NotMapped) {
|
||||
CVPixelBufferLockBaseAddress(m_buffer, 0);
|
||||
|
||||
if (numBytes)
|
||||
*numBytes = CVPixelBufferGetDataSize(m_buffer);
|
||||
|
||||
if (bytesPerLine)
|
||||
*bytesPerLine = CVPixelBufferGetBytesPerRow(m_buffer);
|
||||
|
||||
m_mode = mode;
|
||||
|
||||
return (uchar*)CVPixelBufferGetBaseAddress(m_buffer);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void unmap()
|
||||
{
|
||||
if (m_mode != NotMapped) {
|
||||
m_mode = NotMapped;
|
||||
CVPixelBufferUnlockBaseAddress(m_buffer, 0);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
CVPixelBufferRef m_buffer;
|
||||
MapMode m_mode;
|
||||
};
|
||||
|
||||
@interface AVFCaptureFramesDelegate : NSObject <AVCaptureVideoDataOutputSampleBufferDelegate>
|
||||
{
|
||||
@private
|
||||
AVFVideoRendererControl *m_renderer;
|
||||
}
|
||||
|
||||
- (AVFCaptureFramesDelegate *) initWithRenderer:(AVFVideoRendererControl*)renderer;
|
||||
|
||||
- (void) captureOutput:(AVCaptureOutput *)captureOutput
|
||||
didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer
|
||||
fromConnection:(AVCaptureConnection *)connection;
|
||||
@end
|
||||
|
||||
@implementation AVFCaptureFramesDelegate
|
||||
|
||||
- (AVFCaptureFramesDelegate *) initWithRenderer:(AVFVideoRendererControl*)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);
|
||||
|
||||
CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
|
||||
|
||||
int width = CVPixelBufferGetWidth(imageBuffer);
|
||||
int height = CVPixelBufferGetHeight(imageBuffer);
|
||||
|
||||
QAbstractVideoBuffer *buffer = new CVPixelBufferVideoBuffer(imageBuffer);
|
||||
QVideoFrame frame(buffer, QSize(width, height), QVideoFrame::Format_RGB32);
|
||||
m_renderer->syncHandleViewfinderFrame(frame);
|
||||
}
|
||||
@end
|
||||
|
||||
|
||||
AVFVideoRendererControl::AVFVideoRendererControl(QObject *parent)
|
||||
: QVideoRendererControl(parent)
|
||||
, m_surface(0)
|
||||
{
|
||||
m_viewfinderFramesDelegate = [[AVFCaptureFramesDelegate alloc] initWithRenderer:this];
|
||||
}
|
||||
|
||||
AVFVideoRendererControl::~AVFVideoRendererControl()
|
||||
{
|
||||
[m_captureSession removeOutput:m_videoDataOutput];
|
||||
[m_viewfinderFramesDelegate release];
|
||||
}
|
||||
|
||||
QAbstractVideoSurface *AVFVideoRendererControl::surface() const
|
||||
{
|
||||
return m_surface;
|
||||
}
|
||||
|
||||
void AVFVideoRendererControl::setSurface(QAbstractVideoSurface *surface)
|
||||
{
|
||||
if (m_surface != surface) {
|
||||
m_surface = surface;
|
||||
Q_EMIT surfaceChanged(surface);
|
||||
}
|
||||
}
|
||||
|
||||
void AVFVideoRendererControl::configureAVCaptureSession(AVCaptureSession *captureSession)
|
||||
{
|
||||
m_captureSession = captureSession;
|
||||
|
||||
m_videoDataOutput = [[[AVCaptureVideoDataOutput alloc] init] autorelease];
|
||||
|
||||
// Configure video output
|
||||
dispatch_queue_t queue = dispatch_queue_create("vf_queue", NULL);
|
||||
[m_videoDataOutput
|
||||
setSampleBufferDelegate:m_viewfinderFramesDelegate
|
||||
queue:queue];
|
||||
dispatch_release(queue);
|
||||
|
||||
// Specify the pixel format
|
||||
m_videoDataOutput.videoSettings =
|
||||
[NSDictionary dictionaryWithObject:
|
||||
[NSNumber numberWithInt:kCVPixelFormatType_32BGRA]
|
||||
forKey:(id)kCVPixelBufferPixelFormatTypeKey];
|
||||
|
||||
[m_captureSession addOutput:m_videoDataOutput];
|
||||
}
|
||||
|
||||
//can be called from non main thread
|
||||
void AVFVideoRendererControl::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;
|
||||
}
|
||||
|
||||
void AVFVideoRendererControl::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->stop();
|
||||
|
||||
if (!m_surface->isActive()) {
|
||||
QVideoSurfaceFormat format(frame.size(), frame.pixelFormat());
|
||||
|
||||
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_avfvideorenderercontrol.cpp"
|
||||
52
src/plugins/avfoundation/camera/camera.pro
Normal file
52
src/plugins/avfoundation/camera/camera.pro
Normal file
@@ -0,0 +1,52 @@
|
||||
load(qt_build_config)
|
||||
|
||||
# Avoid clash with a variable named `slots' in a Quartz header
|
||||
CONFIG += no_keywords
|
||||
|
||||
TARGET = qavfcamera
|
||||
QT += multimedia-private network
|
||||
|
||||
PLUGIN_TYPE = mediaservice
|
||||
|
||||
load(qt_plugin)
|
||||
DESTDIR = $$QT.multimedia.plugins/$${PLUGIN_TYPE}
|
||||
|
||||
LIBS += -framework AppKit -framework AudioUnit \
|
||||
-framework AudioToolbox -framework CoreAudio \
|
||||
-framework QuartzCore -framework AVFoundation \
|
||||
-framework CoreMedia
|
||||
|
||||
target.path += $$[QT_INSTALL_PLUGINS]/$${PLUGIN_TYPE}
|
||||
INSTALLS += target
|
||||
|
||||
OTHER_FILES += avfcamera.json
|
||||
|
||||
DEFINES += QMEDIA_AVF_CAMERA
|
||||
|
||||
HEADERS += \
|
||||
avfcameradebug.h \
|
||||
avfcameraserviceplugin.h \
|
||||
avfcameracontrol.h \
|
||||
avfvideorenderercontrol.h \
|
||||
avfcamerametadatacontrol.h \
|
||||
avfimagecapturecontrol.h \
|
||||
avfmediarecordercontrol.h \
|
||||
avfcameraservice.h \
|
||||
avfcamerasession.h \
|
||||
avfstoragelocation.h \
|
||||
avfvideodevicecontrol.h \
|
||||
avfaudioinputselectorcontrol.h \
|
||||
|
||||
OBJECTIVE_SOURCES += \
|
||||
avfcameraserviceplugin.mm \
|
||||
avfcameracontrol.mm \
|
||||
avfvideorenderercontrol.mm \
|
||||
avfcamerametadatacontrol.mm \
|
||||
avfimagecapturecontrol.mm \
|
||||
avfmediarecordercontrol.mm \
|
||||
avfcameraservice.mm \
|
||||
avfcamerasession.mm \
|
||||
avfstoragelocation.mm \
|
||||
avfvideodevicecontrol.mm \
|
||||
avfaudioinputselectorcontrol.mm \
|
||||
|
||||
@@ -38,5 +38,7 @@ unix:!mac {
|
||||
|
||||
mac:!simulator {
|
||||
SUBDIRS += audiocapture qt7
|
||||
|
||||
config_avfoundation: SUBDIRS += avfoundation
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user