Blackberry: Add camera support for BB10 platform
authorTobias Koenig <tobias.koenig.qnx@kdab.com>
Thu, 31 Jan 2013 09:48:16 +0000 (10:48 +0100)
committerThe Qt Project <gerrit-noreply@qt-project.org>
Wed, 6 Feb 2013 17:17:18 +0000 (18:17 +0100)
Reimplement all camera related controls as they are supported by the
BB10 camera API.

Change-Id: Ie7d2258be22c1c1821489bd7074b80cff4242afa
Reviewed-by: Bernd Weimer <bweimer@rim.com>
Reviewed-by: Thomas McGuire <thomas.mcguire@kdab.com>
47 files changed:
src/plugins/blackberry/bbserviceplugin.cpp
src/plugins/blackberry/bbserviceplugin.h
src/plugins/blackberry/blackberry.pro
src/plugins/blackberry/blackberry_mediaservice.json
src/plugins/blackberry/camera/bbcameraaudioencodersettingscontrol.cpp [new file with mode: 0644]
src/plugins/blackberry/camera/bbcameraaudioencodersettingscontrol.h [new file with mode: 0644]
src/plugins/blackberry/camera/bbcameracapturebufferformatcontrol.cpp [new file with mode: 0644]
src/plugins/blackberry/camera/bbcameracapturebufferformatcontrol.h [new file with mode: 0644]
src/plugins/blackberry/camera/bbcameracapturedestinationcontrol.cpp [new file with mode: 0644]
src/plugins/blackberry/camera/bbcameracapturedestinationcontrol.h [new file with mode: 0644]
src/plugins/blackberry/camera/bbcameracontrol.cpp [new file with mode: 0644]
src/plugins/blackberry/camera/bbcameracontrol.h [new file with mode: 0644]
src/plugins/blackberry/camera/bbcameraexposurecontrol.cpp [new file with mode: 0644]
src/plugins/blackberry/camera/bbcameraexposurecontrol.h [new file with mode: 0644]
src/plugins/blackberry/camera/bbcameraflashcontrol.cpp [new file with mode: 0644]
src/plugins/blackberry/camera/bbcameraflashcontrol.h [new file with mode: 0644]
src/plugins/blackberry/camera/bbcamerafocuscontrol.cpp [new file with mode: 0644]
src/plugins/blackberry/camera/bbcamerafocuscontrol.h [new file with mode: 0644]
src/plugins/blackberry/camera/bbcameraimagecapturecontrol.cpp [new file with mode: 0644]
src/plugins/blackberry/camera/bbcameraimagecapturecontrol.h [new file with mode: 0644]
src/plugins/blackberry/camera/bbcameraimageprocessingcontrol.cpp [new file with mode: 0644]
src/plugins/blackberry/camera/bbcameraimageprocessingcontrol.h [new file with mode: 0644]
src/plugins/blackberry/camera/bbcameralockscontrol.cpp [new file with mode: 0644]
src/plugins/blackberry/camera/bbcameralockscontrol.h [new file with mode: 0644]
src/plugins/blackberry/camera/bbcameramediarecordercontrol.cpp [new file with mode: 0644]
src/plugins/blackberry/camera/bbcameramediarecordercontrol.h [new file with mode: 0644]
src/plugins/blackberry/camera/bbcameraorientationhandler.cpp [new file with mode: 0644]
src/plugins/blackberry/camera/bbcameraorientationhandler.h [new file with mode: 0644]
src/plugins/blackberry/camera/bbcameraservice.cpp [new file with mode: 0644]
src/plugins/blackberry/camera/bbcameraservice.h [new file with mode: 0644]
src/plugins/blackberry/camera/bbcamerasession.cpp [new file with mode: 0644]
src/plugins/blackberry/camera/bbcamerasession.h [new file with mode: 0644]
src/plugins/blackberry/camera/bbcameravideoencodersettingscontrol.cpp [new file with mode: 0644]
src/plugins/blackberry/camera/bbcameravideoencodersettingscontrol.h [new file with mode: 0644]
src/plugins/blackberry/camera/bbcameraviewfindersettingscontrol.cpp [new file with mode: 0644]
src/plugins/blackberry/camera/bbcameraviewfindersettingscontrol.h [new file with mode: 0644]
src/plugins/blackberry/camera/bbcamerazoomcontrol.cpp [new file with mode: 0644]
src/plugins/blackberry/camera/bbcamerazoomcontrol.h [new file with mode: 0644]
src/plugins/blackberry/camera/bbimageencodercontrol.cpp [new file with mode: 0644]
src/plugins/blackberry/camera/bbimageencodercontrol.h [new file with mode: 0644]
src/plugins/blackberry/camera/bbmediastoragelocation.cpp [new file with mode: 0644]
src/plugins/blackberry/camera/bbmediastoragelocation.h [new file with mode: 0644]
src/plugins/blackberry/camera/bbvideodeviceselectorcontrol.cpp [new file with mode: 0644]
src/plugins/blackberry/camera/bbvideodeviceselectorcontrol.h [new file with mode: 0644]
src/plugins/blackberry/camera/bbvideorenderercontrol.cpp [new file with mode: 0644]
src/plugins/blackberry/camera/bbvideorenderercontrol.h [new file with mode: 0644]
src/plugins/blackberry/camera/camera.pri [new file with mode: 0644]

index 92dc4ae..90364f3 100644 (file)
 **
 ****************************************************************************/
 #include "bbserviceplugin.h"
+
+#include "bbcameraservice.h"
 #include "bbmediaplayerservice.h"
+#include "bbvideodeviceselectorcontrol.h"
+
+#include <QDebug>
 
 QT_BEGIN_NAMESPACE
 
@@ -49,6 +54,9 @@ BbServicePlugin::BbServicePlugin()
 
 QMediaService *BbServicePlugin::create(const QString &key)
 {
+    if (key == QLatin1String(Q_MEDIASERVICE_CAMERA))
+        return new BbCameraService();
+
     if (key == QLatin1String(Q_MEDIASERVICE_MEDIAPLAYER))
         return new BbMediaPlayerService();
 
@@ -66,4 +74,39 @@ QMediaServiceProviderHint::Features BbServicePlugin::supportedFeatures(const QBy
     return QMediaServiceProviderHint::Features();
 }
 
+QList<QByteArray> BbServicePlugin::devices(const QByteArray &service) const
+{
+    if (service == Q_MEDIASERVICE_CAMERA) {
+        if (m_cameraDevices.isEmpty())
+            updateDevices();
+
+        return m_cameraDevices;
+    }
+
+    return QList<QByteArray>();
+}
+
+QString BbServicePlugin::deviceDescription(const QByteArray &service, const QByteArray &device)
+{
+    if (service == Q_MEDIASERVICE_CAMERA) {
+        if (m_cameraDevices.isEmpty())
+            updateDevices();
+
+        for (int i = 0; i < m_cameraDevices.count(); i++)
+            if (m_cameraDevices[i] == device)
+                return m_cameraDescriptions[i];
+    }
+
+    return QString();
+}
+
+void BbServicePlugin::updateDevices() const
+{
+    BbVideoDeviceSelectorControl::enumerateDevices(&m_cameraDevices, &m_cameraDescriptions);
+
+    if (m_cameraDevices.isEmpty()) {
+        qWarning() << "No camera devices found";
+    }
+}
+
 QT_END_NAMESPACE
index dbf507f..62fc4a0 100644 (file)
@@ -47,9 +47,11 @@ QT_BEGIN_NAMESPACE
 
 class BbServicePlugin
     : public QMediaServiceProviderPlugin,
+      public QMediaServiceSupportedDevicesInterface,
       public QMediaServiceFeaturesInterface
 {
     Q_OBJECT
+    Q_INTERFACES(QMediaServiceSupportedDevicesInterface)
     Q_INTERFACES(QMediaServiceFeaturesInterface)
     Q_PLUGIN_METADATA(IID "org.qt-project.qt.mediaserviceproviderfactory/5.0" FILE "blackberry_mediaservice.json")
 public:
@@ -58,6 +60,16 @@ public:
     QMediaService *create(const QString &key) Q_DECL_OVERRIDE;
     void release(QMediaService *service) Q_DECL_OVERRIDE;
     QMediaServiceProviderHint::Features supportedFeatures(const QByteArray &service) const Q_DECL_OVERRIDE;
+
+    QList<QByteArray> devices(const QByteArray &service) const Q_DECL_OVERRIDE;
+    QString deviceDescription(const QByteArray &service, const QByteArray &device) Q_DECL_OVERRIDE;
+    QVariant deviceProperty(const QByteArray &service, const QByteArray &device, const QByteArray &property) Q_DECL_OVERRIDE;
+
+private:
+    void updateDevices() const;
+
+    mutable QList<QByteArray> m_cameraDevices;
+    mutable QStringList m_cameraDescriptions;
 };
 
 QT_END_NAMESPACE
index ef414d7..3d9488a 100644 (file)
@@ -10,6 +10,7 @@ LIBS += -lscreen
 HEADERS += bbserviceplugin.h
 SOURCES += bbserviceplugin.cpp
 
+include(camera/camera.pri)
 include(mediaplayer/mediaplayer.pri)
 
 OTHER_FILES += blackberry_mediaservice.json
index c4a27ea..54c1c9f 100644 (file)
@@ -1,3 +1,3 @@
 {
-    "Keys": ["org.qt-project.qt.mediaplayer"]
+    "Keys": ["org.qt-project.qt.camera", "org.qt-project.qt.mediaplayer"]
 }
diff --git a/src/plugins/blackberry/camera/bbcameraaudioencodersettingscontrol.cpp b/src/plugins/blackberry/camera/bbcameraaudioencodersettingscontrol.cpp
new file mode 100644 (file)
index 0000000..2ff800a
--- /dev/null
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.  For licensing terms and
+** conditions see http://qt.digia.com/licensing.  For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 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, Digia gives you certain additional
+** rights.  These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "bbcameraaudioencodersettingscontrol.h"
+
+#include "bbcamerasession.h"
+
+QT_BEGIN_NAMESPACE
+
+BbCameraAudioEncoderSettingsControl::BbCameraAudioEncoderSettingsControl(BbCameraSession *session, QObject *parent)
+    : QAudioEncoderSettingsControl(parent)
+    , m_session(session)
+{
+}
+
+QStringList BbCameraAudioEncoderSettingsControl::supportedAudioCodecs() const
+{
+    return QStringList() << QLatin1String("none") << QLatin1String("aac") << QLatin1String("raw");
+}
+
+QString BbCameraAudioEncoderSettingsControl::codecDescription(const QString &codecName) const
+{
+    if (codecName == QLatin1String("none"))
+        return tr("No compression");
+    else if (codecName == QLatin1String("aac"))
+        return tr("AAC compression");
+    else if (codecName == QLatin1String("raw"))
+        return tr("PCM uncompressed");
+
+    return QString();
+}
+
+QList<int> BbCameraAudioEncoderSettingsControl::supportedSampleRates(const QAudioEncoderSettings &settings, bool *continuous) const
+{
+    Q_UNUSED(settings);
+    Q_UNUSED(continuous);
+
+    // no API provided by BB10 yet
+    return QList<int>();
+}
+
+QAudioEncoderSettings BbCameraAudioEncoderSettingsControl::audioSettings() const
+{
+    return m_session->audioSettings();
+}
+
+void BbCameraAudioEncoderSettingsControl::setAudioSettings(const QAudioEncoderSettings &settings)
+{
+    m_session->setAudioSettings(settings);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/blackberry/camera/bbcameraaudioencodersettingscontrol.h b/src/plugins/blackberry/camera/bbcameraaudioencodersettingscontrol.h
new file mode 100644 (file)
index 0000000..21fb520
--- /dev/null
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.  For licensing terms and
+** conditions see http://qt.digia.com/licensing.  For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 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, Digia gives you certain additional
+** rights.  These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef BBCAMERAAUDIOENCODERSETTINGSCONTROL_H
+#define BBCAMERAAUDIOENCODERSETTINGSCONTROL_H
+
+#include <qaudioencodersettingscontrol.h>
+
+QT_BEGIN_NAMESPACE
+
+class BbCameraSession;
+
+class BbCameraAudioEncoderSettingsControl : public QAudioEncoderSettingsControl
+{
+    Q_OBJECT
+public:
+    explicit BbCameraAudioEncoderSettingsControl(BbCameraSession *session, QObject *parent = 0);
+
+    QStringList supportedAudioCodecs() const Q_DECL_OVERRIDE;
+    QString codecDescription(const QString &codecName) const Q_DECL_OVERRIDE;
+    QList<int> supportedSampleRates(const QAudioEncoderSettings &settings, bool *continuous = 0) const Q_DECL_OVERRIDE;
+    QAudioEncoderSettings audioSettings() const Q_DECL_OVERRIDE;
+    void setAudioSettings(const QAudioEncoderSettings &settings) Q_DECL_OVERRIDE;
+
+private:
+    BbCameraSession *m_session;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/blackberry/camera/bbcameracapturebufferformatcontrol.cpp b/src/plugins/blackberry/camera/bbcameracapturebufferformatcontrol.cpp
new file mode 100644 (file)
index 0000000..57f3c9f
--- /dev/null
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.  For licensing terms and
+** conditions see http://qt.digia.com/licensing.  For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 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, Digia gives you certain additional
+** rights.  These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "bbcameracapturebufferformatcontrol.h"
+
+QT_BEGIN_NAMESPACE
+
+BbCameraCaptureBufferFormatControl::BbCameraCaptureBufferFormatControl(QObject *parent)
+    : QCameraCaptureBufferFormatControl(parent)
+{
+}
+
+QList<QVideoFrame::PixelFormat> BbCameraCaptureBufferFormatControl::supportedBufferFormats() const
+{
+    return (QList<QVideoFrame::PixelFormat>() << QVideoFrame::Format_Jpeg);
+}
+
+QVideoFrame::PixelFormat BbCameraCaptureBufferFormatControl::bufferFormat() const
+{
+    return QVideoFrame::Format_Jpeg;
+}
+
+void BbCameraCaptureBufferFormatControl::setBufferFormat(QVideoFrame::PixelFormat format)
+{
+    Q_UNUSED(format)
+    // Do nothing, we support only Jpeg for now
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/blackberry/camera/bbcameracapturebufferformatcontrol.h b/src/plugins/blackberry/camera/bbcameracapturebufferformatcontrol.h
new file mode 100644 (file)
index 0000000..2897cb2
--- /dev/null
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.  For licensing terms and
+** conditions see http://qt.digia.com/licensing.  For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 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, Digia gives you certain additional
+** rights.  These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef BBCAMERACAPTUREBUFFERFORMATCONTROL_H
+#define BBCAMERACAPTUREBUFFERFORMATCONTROL_H
+
+#include <qcameracapturebufferformatcontrol.h>
+
+QT_BEGIN_NAMESPACE
+
+class BbCameraCaptureBufferFormatControl : public QCameraCaptureBufferFormatControl
+{
+    Q_OBJECT
+public:
+    explicit BbCameraCaptureBufferFormatControl(QObject *parent = 0);
+
+    QList<QVideoFrame::PixelFormat> supportedBufferFormats() const Q_DECL_OVERRIDE;
+    QVideoFrame::PixelFormat bufferFormat() const Q_DECL_OVERRIDE;
+    void setBufferFormat(QVideoFrame::PixelFormat format) Q_DECL_OVERRIDE;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/blackberry/camera/bbcameracapturedestinationcontrol.cpp b/src/plugins/blackberry/camera/bbcameracapturedestinationcontrol.cpp
new file mode 100644 (file)
index 0000000..6b6bcfc
--- /dev/null
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.  For licensing terms and
+** conditions see http://qt.digia.com/licensing.  For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 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, Digia gives you certain additional
+** rights.  These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "bbcameracapturedestinationcontrol.h"
+
+#include "bbcamerasession.h"
+
+QT_BEGIN_NAMESPACE
+
+BbCameraCaptureDestinationControl::BbCameraCaptureDestinationControl(BbCameraSession *session, QObject *parent)
+    : QCameraCaptureDestinationControl(parent)
+    , m_session(session)
+{
+    connect(m_session, SIGNAL(captureDestinationChanged(QCameraImageCapture::CaptureDestinations)),
+            this, SIGNAL(captureDestinationChanged(QCameraImageCapture::CaptureDestinations)));
+}
+
+bool BbCameraCaptureDestinationControl::isCaptureDestinationSupported(QCameraImageCapture::CaptureDestinations destination) const
+{
+    return m_session->isCaptureDestinationSupported(destination);
+}
+
+QCameraImageCapture::CaptureDestinations BbCameraCaptureDestinationControl::captureDestination() const
+{
+    return m_session->captureDestination();;
+}
+
+void BbCameraCaptureDestinationControl::setCaptureDestination(QCameraImageCapture::CaptureDestinations destination)
+{
+    m_session->setCaptureDestination(destination);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/blackberry/camera/bbcameracapturedestinationcontrol.h b/src/plugins/blackberry/camera/bbcameracapturedestinationcontrol.h
new file mode 100644 (file)
index 0000000..93a7d2d
--- /dev/null
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.  For licensing terms and
+** conditions see http://qt.digia.com/licensing.  For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 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, Digia gives you certain additional
+** rights.  These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef BBCAMERACAPTUREDESTINATIONCONTROL_H
+#define BBCAMERACAPTUREDESTINATIONCONTROL_H
+
+#include <qcameracapturedestinationcontrol.h>
+
+QT_BEGIN_NAMESPACE
+
+class BbCameraSession;
+
+class BbCameraCaptureDestinationControl : public QCameraCaptureDestinationControl
+{
+    Q_OBJECT
+public:
+    explicit BbCameraCaptureDestinationControl(BbCameraSession *session, QObject *parent = 0);
+
+    bool isCaptureDestinationSupported(QCameraImageCapture::CaptureDestinations destination) const Q_DECL_OVERRIDE;
+    QCameraImageCapture::CaptureDestinations captureDestination() const Q_DECL_OVERRIDE;
+    void setCaptureDestination(QCameraImageCapture::CaptureDestinations destination) Q_DECL_OVERRIDE;
+
+private:
+    BbCameraSession *m_session;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/blackberry/camera/bbcameracontrol.cpp b/src/plugins/blackberry/camera/bbcameracontrol.cpp
new file mode 100644 (file)
index 0000000..bc3c782
--- /dev/null
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.  For licensing terms and
+** conditions see http://qt.digia.com/licensing.  For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 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, Digia gives you certain additional
+** rights.  These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "bbcameracontrol.h"
+
+#include "bbcamerasession.h"
+
+QT_BEGIN_NAMESPACE
+
+BbCameraControl::BbCameraControl(BbCameraSession *session, QObject *parent)
+    : QCameraControl(parent)
+    , m_session(session)
+{
+    connect(m_session, SIGNAL(statusChanged(QCamera::Status)), this, SIGNAL(statusChanged(QCamera::Status)));
+    connect(m_session, SIGNAL(stateChanged(QCamera::State)), this, SIGNAL(stateChanged(QCamera::State)));
+    connect(m_session, SIGNAL(error(int,QString)), this, SIGNAL(error(int,QString)));
+    connect(m_session, SIGNAL(captureModeChanged(QCamera::CaptureModes)), this, SIGNAL(captureModeChanged(QCamera::CaptureModes)));
+}
+
+QCamera::State BbCameraControl::state() const
+{
+    return m_session->state();
+}
+
+void BbCameraControl::setState(QCamera::State state)
+{
+    m_session->setState(state);
+}
+
+QCamera::CaptureModes BbCameraControl::captureMode() const
+{
+    return m_session->captureMode();
+}
+
+void BbCameraControl::setCaptureMode(QCamera::CaptureModes mode)
+{
+    m_session->setCaptureMode(mode);
+}
+
+QCamera::Status BbCameraControl::status() const
+{
+    return m_session->status();
+}
+
+bool BbCameraControl::isCaptureModeSupported(QCamera::CaptureModes mode) const
+{
+    return m_session->isCaptureModeSupported(mode);
+}
+
+bool BbCameraControl::canChangeProperty(PropertyChangeType /* changeType */, QCamera::Status /* status */) const
+{
+    return false;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/blackberry/camera/bbcameracontrol.h b/src/plugins/blackberry/camera/bbcameracontrol.h
new file mode 100644 (file)
index 0000000..a5792c5
--- /dev/null
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.  For licensing terms and
+** conditions see http://qt.digia.com/licensing.  For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 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, Digia gives you certain additional
+** rights.  These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef BBCAMERACONTROL_H
+#define BBCAMERACONTROL_H
+
+#include <qcameracontrol.h>
+
+QT_BEGIN_NAMESPACE
+
+class BbCameraSession;
+
+class BbCameraControl : public QCameraControl
+{
+    Q_OBJECT
+public:
+    explicit BbCameraControl(BbCameraSession *session, QObject *parent = 0);
+
+    QCamera::State state() const Q_DECL_OVERRIDE;
+    void setState(QCamera::State state) Q_DECL_OVERRIDE;
+
+    QCamera::Status status() const Q_DECL_OVERRIDE;
+
+    QCamera::CaptureModes captureMode() const Q_DECL_OVERRIDE;
+    void setCaptureMode(QCamera::CaptureModes) Q_DECL_OVERRIDE;
+    bool isCaptureModeSupported(QCamera::CaptureModes mode) const Q_DECL_OVERRIDE;
+
+    bool canChangeProperty(PropertyChangeType changeType, QCamera::Status status) const Q_DECL_OVERRIDE;
+
+private:
+    BbCameraSession *m_session;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/blackberry/camera/bbcameraexposurecontrol.cpp b/src/plugins/blackberry/camera/bbcameraexposurecontrol.cpp
new file mode 100644 (file)
index 0000000..a24fdba
--- /dev/null
@@ -0,0 +1,232 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.  For licensing terms and
+** conditions see http://qt.digia.com/licensing.  For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 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, Digia gives you certain additional
+** rights.  These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "bbcameraexposurecontrol.h"
+
+#include "bbcamerasession.h"
+
+#include <QDebug>
+
+QT_BEGIN_NAMESPACE
+
+BbCameraExposureControl::BbCameraExposureControl(BbCameraSession *session, QObject *parent)
+    : QCameraExposureControl(parent)
+    , m_session(session)
+    , m_requestedExposureMode(QCameraExposure::ExposureAuto)
+{
+    connect(m_session, SIGNAL(statusChanged(QCamera::Status)), this, SLOT(statusChanged(QCamera::Status)));
+}
+
+bool BbCameraExposureControl::isParameterSupported(ExposureParameter parameter) const
+{
+    switch (parameter) {
+    case QCameraExposureControl::ISO:
+        return false;
+    case QCameraExposureControl::Aperture:
+        return false;
+    case QCameraExposureControl::ShutterSpeed:
+        return false;
+    case QCameraExposureControl::ExposureCompensation:
+        return false;
+    case QCameraExposureControl::FlashPower:
+        return false;
+    case QCameraExposureControl::FlashCompensation:
+        return false;
+    case QCameraExposureControl::TorchPower:
+        return false;
+    case QCameraExposureControl::SpotMeteringPoint:
+        return false;
+    case QCameraExposureControl::ExposureMode:
+        return true;
+    case QCameraExposureControl::MeteringMode:
+        return false;
+    default:
+        return false;
+    }
+}
+
+QVariantList BbCameraExposureControl::supportedParameterRange(ExposureParameter parameter, bool *continuous) const
+{
+    if (parameter != QCameraExposureControl::ExposureMode) // no other parameter supported by BB10 API at the moment
+        return QVariantList();
+
+    if (m_session->status() != QCamera::ActiveStatus) // we can query supported exposure modes only with active viewfinder
+        return QVariantList();
+
+    if (continuous)
+        *continuous = false;
+
+    int supported = 0;
+    camera_scenemode_t modes[20];
+    const camera_error_t result = camera_get_scene_modes(m_session->handle(), 20, &supported, modes);
+    if (result != CAMERA_EOK) {
+        qWarning() << "Unable to retrieve supported scene modes:" << result;
+        return QVariantList();
+    }
+
+    QVariantList exposureModes;
+    for (int i = 0; i < supported; ++i) {
+        switch (modes[i]) {
+        case CAMERA_SCENE_AUTO:
+            exposureModes << QVariant::fromValue(QCameraExposure::ExposureAuto);
+            break;
+        case CAMERA_SCENE_SPORTS:
+            exposureModes << QVariant::fromValue(QCameraExposure::ExposureSports);
+            break;
+        case CAMERA_SCENE_CLOSEUP:
+            exposureModes << QVariant::fromValue(QCameraExposure::ExposurePortrait);
+            break;
+        case CAMERA_SCENE_ACTION:
+            exposureModes << QVariant::fromValue(QCameraExposure::ExposureSports);
+            break;
+        case CAMERA_SCENE_BEACHANDSNOW:
+            exposureModes << QVariant::fromValue(QCameraExposure::ExposureBeach) << QVariant::fromValue(QCameraExposure::ExposureSnow);
+            break;
+        case CAMERA_SCENE_NIGHT:
+            exposureModes << QVariant::fromValue(QCameraExposure::ExposureNight);
+            break;
+        default: break;
+        }
+    }
+
+    return exposureModes;
+}
+
+QVariant BbCameraExposureControl::requestedValue(ExposureParameter parameter) const
+{
+    if (parameter != QCameraExposureControl::ExposureMode) // no other parameter supported by BB10 API at the moment
+        return QVariant();
+
+    return QVariant::fromValue(m_requestedExposureMode);
+}
+
+QVariant BbCameraExposureControl::actualValue(ExposureParameter parameter) const
+{
+    if (parameter != QCameraExposureControl::ExposureMode) // no other parameter supported by BB10 API at the moment
+        return QVariantList();
+
+    if (m_session->status() != QCamera::ActiveStatus) // we can query actual scene modes only with active viewfinder
+        return QVariantList();
+
+    camera_scenemode_t sceneMode = CAMERA_SCENE_DEFAULT;
+    const camera_error_t result = camera_get_scene_mode(m_session->handle(), &sceneMode);
+
+    if (result != CAMERA_EOK) {
+        qWarning() << "Unable to retrieve scene mode:" << result;
+        return QVariant();
+    }
+
+    switch (sceneMode) {
+    case CAMERA_SCENE_AUTO:
+        return QVariant::fromValue(QCameraExposure::ExposureAuto);
+    case CAMERA_SCENE_SPORTS:
+        return QVariant::fromValue(QCameraExposure::ExposureSports);
+    case CAMERA_SCENE_CLOSEUP:
+        return QVariant::fromValue(QCameraExposure::ExposurePortrait);
+    case CAMERA_SCENE_ACTION:
+        return QVariant::fromValue(QCameraExposure::ExposureSports);
+    case CAMERA_SCENE_BEACHANDSNOW:
+        return (m_requestedExposureMode == QCameraExposure::ExposureBeach ? QVariant::fromValue(QCameraExposure::ExposureBeach)
+                                                                          : QVariant::fromValue(QCameraExposure::ExposureSnow));
+    case CAMERA_SCENE_NIGHT:
+        return QVariant::fromValue(QCameraExposure::ExposureNight);
+    default:
+        return QVariant();
+    }
+}
+
+bool BbCameraExposureControl::setValue(ExposureParameter parameter, const QVariant& value)
+{
+    if (parameter != QCameraExposureControl::ExposureMode) // no other parameter supported by BB10 API at the moment
+        return false;
+
+    if (m_session->status() != QCamera::ActiveStatus) // we can set actual scene modes only with active viewfinder
+        return false;
+
+    camera_scenemode_t sceneMode = CAMERA_SCENE_DEFAULT;
+
+    if (value.isValid()) {
+        m_requestedExposureMode = value.value<QCameraExposure::ExposureMode>();
+        emit requestedValueChanged(QCameraExposureControl::ExposureMode);
+
+        switch (m_requestedExposureMode) {
+        case QCameraExposure::ExposureAuto:
+            sceneMode = CAMERA_SCENE_AUTO;
+            break;
+        case QCameraExposure::ExposureSports:
+            sceneMode = CAMERA_SCENE_SPORTS;
+            break;
+        case QCameraExposure::ExposurePortrait:
+            sceneMode = CAMERA_SCENE_CLOSEUP;
+            break;
+        case QCameraExposure::ExposureBeach:
+            sceneMode = CAMERA_SCENE_BEACHANDSNOW;
+            break;
+        case QCameraExposure::ExposureSnow:
+            sceneMode = CAMERA_SCENE_BEACHANDSNOW;
+            break;
+        case QCameraExposure::ExposureNight:
+            sceneMode = CAMERA_SCENE_NIGHT;
+            break;
+        default:
+            sceneMode = CAMERA_SCENE_DEFAULT;
+            break;
+        }
+    }
+
+    const camera_error_t result = camera_set_scene_mode(m_session->handle(), sceneMode);
+
+    if (result != CAMERA_EOK) {
+        qWarning() << "Unable to set scene mode:" << result;
+        return false;
+    }
+
+    emit actualValueChanged(QCameraExposureControl::ExposureMode);
+
+    return true;
+}
+
+void BbCameraExposureControl::statusChanged(QCamera::Status status)
+{
+    if (status == QCamera::ActiveStatus || status == QCamera::LoadedStatus)
+        emit parameterRangeChanged(QCameraExposureControl::ExposureMode);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/blackberry/camera/bbcameraexposurecontrol.h b/src/plugins/blackberry/camera/bbcameraexposurecontrol.h
new file mode 100644 (file)
index 0000000..f4659b6
--- /dev/null
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.  For licensing terms and
+** conditions see http://qt.digia.com/licensing.  For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 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, Digia gives you certain additional
+** rights.  These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef BBCAMERAEXPOSURECONTROL_H
+#define BBCAMERAEXPOSURECONTROL_H
+
+#include <qcameraexposurecontrol.h>
+
+QT_BEGIN_NAMESPACE
+
+class BbCameraSession;
+
+class BbCameraExposureControl : public QCameraExposureControl
+{
+    Q_OBJECT
+public:
+    explicit BbCameraExposureControl(BbCameraSession *session, QObject *parent = 0);
+
+    virtual bool isParameterSupported(ExposureParameter parameter) const Q_DECL_OVERRIDE;
+    virtual QVariantList supportedParameterRange(ExposureParameter parameter, bool *continuous) const Q_DECL_OVERRIDE;
+
+    virtual QVariant requestedValue(ExposureParameter parameter) const Q_DECL_OVERRIDE;
+    virtual QVariant actualValue(ExposureParameter parameter) const Q_DECL_OVERRIDE;
+    virtual bool setValue(ExposureParameter parameter, const QVariant& value) Q_DECL_OVERRIDE;
+
+private Q_SLOTS:
+    void statusChanged(QCamera::Status status);
+
+private:
+    BbCameraSession *m_session;
+    QCameraExposure::ExposureMode m_requestedExposureMode;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/blackberry/camera/bbcameraflashcontrol.cpp b/src/plugins/blackberry/camera/bbcameraflashcontrol.cpp
new file mode 100644 (file)
index 0000000..06ebe01
--- /dev/null
@@ -0,0 +1,113 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.  For licensing terms and
+** conditions see http://qt.digia.com/licensing.  For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 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, Digia gives you certain additional
+** rights.  These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "bbcameraflashcontrol.h"
+
+#include "bbcamerasession.h"
+
+#include <QDebug>
+
+QT_BEGIN_NAMESPACE
+
+BbCameraFlashControl::BbCameraFlashControl(BbCameraSession *session, QObject *parent)
+    : QCameraFlashControl(parent)
+    , m_session(session)
+    , m_flashMode(QCameraExposure::FlashAuto)
+{
+}
+
+QCameraExposure::FlashModes BbCameraFlashControl::flashMode() const
+{
+    return m_flashMode;
+}
+
+void BbCameraFlashControl::setFlashMode(QCameraExposure::FlashModes mode)
+{
+    if (m_flashMode == mode)
+        return;
+
+    if (m_session->status() != QCamera::ActiveStatus) // can only be changed when viewfinder is active
+        return;
+
+    if (m_flashMode == QCameraExposure::FlashVideoLight) {
+        const camera_error_t result = camera_config_videolight(m_session->handle(), CAMERA_VIDEOLIGHT_OFF);
+        if (result != CAMERA_EOK)
+            qWarning() << "Unable to switch off video light:" << result;
+    }
+
+    m_flashMode = mode;
+
+    if (m_flashMode == QCameraExposure::FlashVideoLight) {
+        const camera_error_t result = camera_config_videolight(m_session->handle(), CAMERA_VIDEOLIGHT_ON);
+        if (result != CAMERA_EOK)
+            qWarning() << "Unable to switch on video light:" << result;
+    } else {
+        camera_flashmode_t flashMode = CAMERA_FLASH_AUTO;
+
+        if (m_flashMode.testFlag(QCameraExposure::FlashAuto)) flashMode = CAMERA_FLASH_AUTO;
+        else if (mode.testFlag(QCameraExposure::FlashOff)) flashMode = CAMERA_FLASH_OFF;
+        else if (mode.testFlag(QCameraExposure::FlashOn)) flashMode = CAMERA_FLASH_ON;
+
+        const camera_error_t result = camera_config_flash(m_session->handle(), flashMode);
+        if (result != CAMERA_EOK)
+            qWarning() << "Unable to configure flash:" << result;
+    }
+}
+
+bool BbCameraFlashControl::isFlashModeSupported(QCameraExposure::FlashModes mode) const
+{
+    bool supportsVideoLight = false;
+    if (m_session->handle() != CAMERA_HANDLE_INVALID) {
+        supportsVideoLight = camera_has_feature(m_session->handle(), CAMERA_FEATURE_VIDEOLIGHT);
+    }
+
+    return  (mode == QCameraExposure::FlashOff ||
+             mode == QCameraExposure::FlashOn ||
+             mode == QCameraExposure::FlashAuto ||
+             ((mode == QCameraExposure::FlashVideoLight) && supportsVideoLight));
+}
+
+bool BbCameraFlashControl::isFlashReady() const
+{
+    //TODO: check for flash charge-level here?!?
+    return true;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/blackberry/camera/bbcameraflashcontrol.h b/src/plugins/blackberry/camera/bbcameraflashcontrol.h
new file mode 100644 (file)
index 0000000..d46dc8c
--- /dev/null
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.  For licensing terms and
+** conditions see http://qt.digia.com/licensing.  For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 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, Digia gives you certain additional
+** rights.  These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef BBCAMERAFLASHCONTROL_H
+#define BBCAMERAFLASHCONTROL_H
+
+#include <qcameraflashcontrol.h>
+
+QT_BEGIN_NAMESPACE
+
+class BbCameraSession;
+
+class BbCameraFlashControl : public QCameraFlashControl
+{
+    Q_OBJECT
+public:
+    explicit BbCameraFlashControl(BbCameraSession *session, QObject *parent = 0);
+
+    QCameraExposure::FlashModes flashMode() const Q_DECL_OVERRIDE;
+    void setFlashMode(QCameraExposure::FlashModes mode) Q_DECL_OVERRIDE;
+    bool isFlashModeSupported(QCameraExposure::FlashModes mode) const Q_DECL_OVERRIDE;
+    bool isFlashReady() const Q_DECL_OVERRIDE;
+
+private:
+    BbCameraSession *m_session;
+    QCameraExposure::FlashModes m_flashMode;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/blackberry/camera/bbcamerafocuscontrol.cpp b/src/plugins/blackberry/camera/bbcamerafocuscontrol.cpp
new file mode 100644 (file)
index 0000000..e0b57d6
--- /dev/null
@@ -0,0 +1,331 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.  For licensing terms and
+** conditions see http://qt.digia.com/licensing.  For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 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, Digia gives you certain additional
+** rights.  These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "bbcamerafocuscontrol.h"
+
+#include "bbcamerasession.h"
+
+#include <QDebug>
+
+QT_BEGIN_NAMESPACE
+
+BbCameraFocusControl::BbCameraFocusControl(BbCameraSession *session, QObject *parent)
+    : QCameraFocusControl(parent)
+    , m_session(session)
+    , m_focusMode(QCameraFocus::FocusModes())
+    , m_focusPointMode(QCameraFocus::FocusPointAuto)
+    , m_customFocusPoint(QPointF(0, 0))
+{
+}
+
+QCameraFocus::FocusModes BbCameraFocusControl::focusMode() const
+{
+    camera_focusmode_t focusMode = CAMERA_FOCUSMODE_OFF;
+
+    const camera_error_t result = camera_get_focus_mode(m_session->handle(), &focusMode);
+    if (result != CAMERA_EOK) {
+        qWarning() << "Unable to retrieve focus mode from camera:" << result;
+        return QCameraFocus::FocusModes();
+    }
+
+    switch (focusMode) {
+    case CAMERA_FOCUSMODE_EDOF:
+        return QCameraFocus::HyperfocalFocus;
+    case CAMERA_FOCUSMODE_MANUAL:
+        return QCameraFocus::ManualFocus;
+    case CAMERA_FOCUSMODE_AUTO:
+        return QCameraFocus::AutoFocus;
+    case CAMERA_FOCUSMODE_MACRO:
+        return QCameraFocus::MacroFocus;
+    case CAMERA_FOCUSMODE_CONTINUOUS_AUTO:
+        return QCameraFocus::ContinuousFocus;
+    case CAMERA_FOCUSMODE_CONTINUOUS_MACRO: // fall through
+    case CAMERA_FOCUSMODE_OFF: // fall through
+    default:
+            return QCameraFocus::FocusModes();
+    }
+}
+
+void BbCameraFocusControl::setFocusMode(QCameraFocus::FocusModes mode)
+{
+    if (m_focusMode == mode)
+        return;
+
+    camera_focusmode_t focusMode = CAMERA_FOCUSMODE_OFF;
+
+    if (mode == QCameraFocus::HyperfocalFocus)
+        focusMode = CAMERA_FOCUSMODE_EDOF;
+    else if (mode == QCameraFocus::ManualFocus)
+        focusMode = CAMERA_FOCUSMODE_MANUAL;
+    else if (mode == QCameraFocus::AutoFocus)
+        focusMode = CAMERA_FOCUSMODE_AUTO;
+    else if (mode == QCameraFocus::MacroFocus)
+        focusMode = CAMERA_FOCUSMODE_MACRO;
+    else if (mode == QCameraFocus::ContinuousFocus)
+        focusMode = CAMERA_FOCUSMODE_CONTINUOUS_AUTO;
+
+    const camera_error_t result = camera_set_focus_mode(m_session->handle(), focusMode);
+
+    if (result != CAMERA_EOK) {
+        qWarning() << "Unable to set focus mode:" << result;
+        return;
+    }
+
+    m_focusMode = mode;
+    emit focusModeChanged(m_focusMode);
+}
+
+bool BbCameraFocusControl::isFocusModeSupported(QCameraFocus::FocusModes mode) const
+{
+    if (m_session->state() == QCamera::UnloadedState)
+        return false;
+
+    if (mode == QCameraFocus::HyperfocalFocus)
+        return false; //TODO how to check?
+    else if (mode == QCameraFocus::ManualFocus)
+        return camera_has_feature(m_session->handle(), CAMERA_FEATURE_MANUALFOCUS);
+    else if (mode == QCameraFocus::AutoFocus)
+        return camera_has_feature(m_session->handle(), CAMERA_FEATURE_AUTOFOCUS);
+    else if (mode == QCameraFocus::MacroFocus)
+        return camera_has_feature(m_session->handle(), CAMERA_FEATURE_MACROFOCUS);
+    else if (mode == QCameraFocus::ContinuousFocus)
+        return camera_has_feature(m_session->handle(), CAMERA_FEATURE_AUTOFOCUS);
+
+    return false;
+}
+
+QCameraFocus::FocusPointMode BbCameraFocusControl::focusPointMode() const
+{
+    return m_focusPointMode;
+}
+
+void BbCameraFocusControl::setFocusPointMode(QCameraFocus::FocusPointMode mode)
+{
+    if (m_session->status() != QCamera::ActiveStatus)
+        return;
+
+    if (m_focusPointMode == mode)
+        return;
+
+    m_focusPointMode = mode;
+    emit focusPointModeChanged(m_focusPointMode);
+
+    if (m_focusPointMode == QCameraFocus::FocusPointAuto) {
+        //TODO: is this correct?
+        const camera_error_t result = camera_set_focus_regions(m_session->handle(), 0, 0);
+        if (result != CAMERA_EOK) {
+            qWarning() << "Unable to set focus region:" << result;
+            return;
+        }
+
+        emit focusZonesChanged();
+    } else if (m_focusPointMode == QCameraFocus::FocusPointCenter) {
+        // get the size of the viewfinder
+        int viewfinderWidth = 0;
+        int viewfinderHeight = 0;
+
+        if (!retrieveViewfinderSize(&viewfinderWidth, &viewfinderHeight))
+            return;
+
+        // define a 40x40 pixel focus region in the center of the viewfinder
+        camera_region_t focusRegion;
+        focusRegion.left = (viewfinderWidth / 2) - 20;
+        focusRegion.top = (viewfinderHeight / 2) - 20;
+        focusRegion.width = 40;
+        focusRegion.height = 40;
+
+        camera_error_t result = camera_set_focus_regions(m_session->handle(), 1, &focusRegion);
+        if (result != CAMERA_EOK) {
+            qWarning() << "Unable to set focus region:" << result;
+            return;
+        }
+
+        // re-set focus mode to apply focus region changes
+        camera_focusmode_t focusMode = CAMERA_FOCUSMODE_OFF;
+        result = camera_get_focus_mode(m_session->handle(), &focusMode);
+        camera_set_focus_mode(m_session->handle(), focusMode);
+
+        emit focusZonesChanged();
+
+    } else if (m_focusPointMode == QCameraFocus::FocusPointFaceDetection) {
+        //TODO: implement later
+    } else if (m_focusPointMode == QCameraFocus::FocusPointCustom) {
+        updateCustomFocusRegion();
+    }
+}
+
+bool BbCameraFocusControl::isFocusPointModeSupported(QCameraFocus::FocusPointMode mode) const
+{
+    if (m_session->state() == QCamera::UnloadedState)
+        return false;
+
+    if (mode == QCameraFocus::FocusPointAuto) {
+        return camera_has_feature(m_session->handle(), CAMERA_FEATURE_AUTOFOCUS);
+    } else if (mode == QCameraFocus::FocusPointCenter) {
+        return camera_has_feature(m_session->handle(), CAMERA_FEATURE_REGIONFOCUS);
+    } else if (mode == QCameraFocus::FocusPointFaceDetection) {
+        return false; //TODO: implement via custom region in combination with face detection in viewfinder
+    } else if (mode == QCameraFocus::FocusPointCustom) {
+        return camera_has_feature(m_session->handle(), CAMERA_FEATURE_REGIONFOCUS);
+    }
+
+    return false;
+}
+
+QPointF BbCameraFocusControl::customFocusPoint() const
+{
+    return m_customFocusPoint;
+}
+
+void BbCameraFocusControl::setCustomFocusPoint(const QPointF &point)
+{
+    if (m_customFocusPoint == point)
+        return;
+
+    m_customFocusPoint = point;
+    emit customFocusPointChanged(m_customFocusPoint);
+
+    updateCustomFocusRegion();
+}
+
+QCameraFocusZoneList BbCameraFocusControl::focusZones() const
+{
+    if (m_session->state() == QCamera::UnloadedState)
+        return QCameraFocusZoneList();
+
+    camera_region_t regions[20];
+    int supported = 0;
+    int asked = 0;
+    camera_error_t result = camera_get_focus_regions(m_session->handle(), 20, &supported, &asked, regions);
+
+    if (result != CAMERA_EOK) {
+        qWarning() << "Unable to retrieve focus regions:" << result;
+        return QCameraFocusZoneList();
+    }
+
+    // retrieve width and height of viewfinder
+    int viewfinderWidth = 0;
+    int viewfinderHeight = 0;
+    if (m_session->captureMode() & QCamera::CaptureStillImage)
+        result = camera_get_photovf_property(m_session->handle(),
+                                             CAMERA_IMGPROP_WIDTH, &viewfinderWidth,
+                                             CAMERA_IMGPROP_HEIGHT, &viewfinderHeight);
+    else if (m_session->captureMode() & QCamera::CaptureVideo)
+        result = camera_get_videovf_property(m_session->handle(),
+                                             CAMERA_IMGPROP_WIDTH, &viewfinderWidth,
+                                             CAMERA_IMGPROP_HEIGHT, &viewfinderHeight);
+
+    if (result != CAMERA_EOK) {
+        qWarning() << "Unable to retrieve viewfinder size:" << result;
+        return QCameraFocusZoneList();
+    }
+
+    QCameraFocusZoneList list;
+    for (int i = 0; i < asked; ++i) {
+        const int x = regions[i].left;
+        const int y = regions[i].top;
+        const int width = regions[i].width;
+        const int height = regions[i].height;
+
+        QRectF rect(static_cast<float>(x)/static_cast<float>(viewfinderWidth),
+                    static_cast<float>(y)/static_cast<float>(viewfinderHeight),
+                    static_cast<float>(width)/static_cast<float>(viewfinderWidth),
+                    static_cast<float>(height)/static_cast<float>(viewfinderHeight));
+
+        list << QCameraFocusZone(rect, QCameraFocusZone::Focused); //TODO: how to know if a zone is unused/selected/focused?!?
+    }
+
+    return list;
+}
+
+void BbCameraFocusControl::updateCustomFocusRegion()
+{
+    // get the size of the viewfinder
+    int viewfinderWidth = 0;
+    int viewfinderHeight = 0;
+
+    if (!retrieveViewfinderSize(&viewfinderWidth, &viewfinderHeight))
+        return;
+
+    // define a 40x40 pixel focus region around the custom focus point
+    camera_region_t focusRegion;
+    focusRegion.left = qMax(0, static_cast<int>(m_customFocusPoint.x() * viewfinderWidth) - 20);
+    focusRegion.top = qMax(0, static_cast<int>(m_customFocusPoint.y() * viewfinderHeight) - 20);
+    focusRegion.width = 40;
+    focusRegion.height = 40;
+
+    camera_error_t result = camera_set_focus_regions(m_session->handle(), 1, &focusRegion);
+    if (result != CAMERA_EOK) {
+        qWarning() << "Unable to set focus region:" << result;
+        return;
+    }
+
+    // re-set focus mode to apply focus region changes
+    camera_focusmode_t focusMode = CAMERA_FOCUSMODE_OFF;
+    result = camera_get_focus_mode(m_session->handle(), &focusMode);
+    camera_set_focus_mode(m_session->handle(), focusMode);
+
+    emit focusZonesChanged();
+}
+
+bool BbCameraFocusControl::retrieveViewfinderSize(int *width, int *height)
+{
+    if (!width || !height)
+        return false;
+
+    camera_error_t result = CAMERA_EOK;
+    if (m_session->captureMode() & QCamera::CaptureStillImage)
+        result = camera_get_photovf_property(m_session->handle(),
+                                             CAMERA_IMGPROP_WIDTH, width,
+                                             CAMERA_IMGPROP_HEIGHT, height);
+    else if (m_session->captureMode() & QCamera::CaptureVideo)
+        result = camera_get_videovf_property(m_session->handle(),
+                                             CAMERA_IMGPROP_WIDTH, width,
+                                             CAMERA_IMGPROP_HEIGHT, height);
+
+    if (result != CAMERA_EOK) {
+        qWarning() << "Unable to retrieve viewfinder size:" << result;
+        return false;
+    }
+
+    return true;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/blackberry/camera/bbcamerafocuscontrol.h b/src/plugins/blackberry/camera/bbcamerafocuscontrol.h
new file mode 100644 (file)
index 0000000..052c29b
--- /dev/null
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.  For licensing terms and
+** conditions see http://qt.digia.com/licensing.  For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 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, Digia gives you certain additional
+** rights.  These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef BBCAMERAFOCUSCONTROL_H
+#define BBCAMERAFOCUSCONTROL_H
+
+#include <qcamerafocuscontrol.h>
+
+QT_BEGIN_NAMESPACE
+
+class BbCameraSession;
+
+class BbCameraFocusControl : public QCameraFocusControl
+{
+    Q_OBJECT
+public:
+    explicit BbCameraFocusControl(BbCameraSession *session, QObject *parent = 0);
+
+    QCameraFocus::FocusModes focusMode() const Q_DECL_OVERRIDE;
+    void setFocusMode(QCameraFocus::FocusModes mode) Q_DECL_OVERRIDE;
+    bool isFocusModeSupported(QCameraFocus::FocusModes mode) const Q_DECL_OVERRIDE;
+    QCameraFocus::FocusPointMode focusPointMode() const Q_DECL_OVERRIDE;
+    void setFocusPointMode(QCameraFocus::FocusPointMode mode) Q_DECL_OVERRIDE;
+    bool isFocusPointModeSupported(QCameraFocus::FocusPointMode mode) const Q_DECL_OVERRIDE;
+    QPointF customFocusPoint() const Q_DECL_OVERRIDE;
+    void setCustomFocusPoint(const QPointF &point) Q_DECL_OVERRIDE;
+    QCameraFocusZoneList focusZones() const Q_DECL_OVERRIDE;
+
+private:
+    void updateCustomFocusRegion();
+    bool retrieveViewfinderSize(int *width, int *height);
+
+    BbCameraSession *m_session;
+
+    QCameraFocus::FocusModes m_focusMode;
+    QCameraFocus::FocusPointMode m_focusPointMode;
+    QPointF m_customFocusPoint;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/blackberry/camera/bbcameraimagecapturecontrol.cpp b/src/plugins/blackberry/camera/bbcameraimagecapturecontrol.cpp
new file mode 100644 (file)
index 0000000..a2f61f7
--- /dev/null
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.  For licensing terms and
+** conditions see http://qt.digia.com/licensing.  For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 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, Digia gives you certain additional
+** rights.  These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "bbcameraimagecapturecontrol.h"
+
+#include "bbcamerasession.h"
+
+QT_BEGIN_NAMESPACE
+
+BbCameraImageCaptureControl::BbCameraImageCaptureControl(BbCameraSession *session, QObject *parent)
+    : QCameraImageCaptureControl(parent)
+    , m_session(session)
+{
+    connect(m_session, SIGNAL(readyForCaptureChanged(bool)), this, SIGNAL(readyForCaptureChanged(bool)));
+    connect(m_session, SIGNAL(imageExposed(int)), this, SIGNAL(imageExposed(int)));
+    connect(m_session, SIGNAL(imageCaptured(int,QImage)), this, SIGNAL(imageCaptured(int,QImage)));
+    connect(m_session, SIGNAL(imageMetadataAvailable(int,QString,QVariant)), this, SIGNAL(imageMetadataAvailable(int,QString,QVariant)));
+    connect(m_session, SIGNAL(imageAvailable(int,QVideoFrame)), this, SIGNAL(imageAvailable(int,QVideoFrame)));
+    connect(m_session, SIGNAL(imageSaved(int,QString)), this, SIGNAL(imageSaved(int,QString)));
+    connect(m_session, SIGNAL(imageCaptureError(int,int,QString)), this, SIGNAL(error(int,int,QString)));
+}
+
+bool BbCameraImageCaptureControl::isReadyForCapture() const
+{
+    return m_session->isReadyForCapture();
+}
+
+QCameraImageCapture::DriveMode BbCameraImageCaptureControl::driveMode() const
+{
+    return m_session->driveMode();
+}
+
+void BbCameraImageCaptureControl::setDriveMode(QCameraImageCapture::DriveMode mode)
+{
+    m_session->setDriveMode(mode);
+}
+
+int BbCameraImageCaptureControl::capture(const QString &fileName)
+{
+    return m_session->capture(fileName);
+}
+
+void BbCameraImageCaptureControl::cancelCapture()
+{
+    m_session->cancelCapture();
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/blackberry/camera/bbcameraimagecapturecontrol.h b/src/plugins/blackberry/camera/bbcameraimagecapturecontrol.h
new file mode 100644 (file)
index 0000000..a73a4f1
--- /dev/null
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.  For licensing terms and
+** conditions see http://qt.digia.com/licensing.  For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 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, Digia gives you certain additional
+** rights.  These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef BBCAMERAIMAGECAPTURECONTROL_H
+#define BBCAMERAIMAGECAPTURECONTROL_H
+
+#include <qcameraimagecapturecontrol.h>
+
+QT_BEGIN_NAMESPACE
+
+class BbCameraSession;
+
+class BbCameraImageCaptureControl : public QCameraImageCaptureControl
+{
+    Q_OBJECT
+public:
+    explicit BbCameraImageCaptureControl(BbCameraSession *session, QObject *parent = 0);
+
+    bool isReadyForCapture() const Q_DECL_OVERRIDE;
+
+    QCameraImageCapture::DriveMode driveMode() const Q_DECL_OVERRIDE;
+    void setDriveMode(QCameraImageCapture::DriveMode mode) Q_DECL_OVERRIDE;
+
+    int capture(const QString &fileName) Q_DECL_OVERRIDE;
+    void cancelCapture() Q_DECL_OVERRIDE;
+
+private:
+    BbCameraSession *m_session;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/blackberry/camera/bbcameraimageprocessingcontrol.cpp b/src/plugins/blackberry/camera/bbcameraimageprocessingcontrol.cpp
new file mode 100644 (file)
index 0000000..54ae48c
--- /dev/null
@@ -0,0 +1,146 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.  For licensing terms and
+** conditions see http://qt.digia.com/licensing.  For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 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, Digia gives you certain additional
+** rights.  These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "bbcameraimageprocessingcontrol.h"
+
+#include "bbcamerasession.h"
+
+#include <QDebug>
+
+QT_BEGIN_NAMESPACE
+
+BbCameraImageProcessingControl::BbCameraImageProcessingControl(BbCameraSession *session, QObject *parent)
+    : QCameraImageProcessingControl(parent)
+    , m_session(session)
+{
+}
+
+bool BbCameraImageProcessingControl::isParameterSupported(ProcessingParameter parameter) const
+{
+    return (parameter == QCameraImageProcessingControl::WhiteBalancePreset);
+}
+
+bool BbCameraImageProcessingControl::isParameterValueSupported(ProcessingParameter parameter, const QVariant &value) const
+{
+    if (parameter != QCameraImageProcessingControl::WhiteBalancePreset)
+        return false;
+
+    if (m_session->handle() == CAMERA_HANDLE_INVALID)
+        return false;
+
+    int supported = 0;
+    camera_whitebalancemode_t modes[20];
+    const camera_error_t result = camera_get_whitebalance_modes(m_session->handle(), 20, &supported, modes);
+
+    if (result != CAMERA_EOK) {
+        qWarning() << "Unable to retrieve supported whitebalance modes:" << result;
+        return false;
+    }
+
+    QSet<QCameraImageProcessing::WhiteBalanceMode> supportedModes;
+    for (int i = 0; i < supported; ++i) {
+        switch (modes[i]) {
+        case CAMERA_WHITEBALANCEMODE_AUTO:
+            supportedModes.insert(QCameraImageProcessing::WhiteBalanceAuto);
+            break;
+        case CAMERA_WHITEBALANCEMODE_MANUAL:
+            supportedModes.insert(QCameraImageProcessing::WhiteBalanceManual);
+            break;
+        default:
+            break;
+        }
+    }
+
+    return supportedModes.contains(value.value<QCameraImageProcessing::WhiteBalanceMode>());
+}
+
+QVariant BbCameraImageProcessingControl::parameter(ProcessingParameter parameter) const
+{
+    if (parameter != QCameraImageProcessingControl::WhiteBalancePreset)
+        return QVariant();
+
+    if (m_session->handle() == CAMERA_HANDLE_INVALID)
+        return QVariant();
+
+    camera_whitebalancemode_t mode;
+    const camera_error_t result = camera_get_whitebalance_mode(m_session->handle(), &mode);
+
+    if (result != CAMERA_EOK) {
+        qWarning() << "Unable to retrieve current whitebalance mode:" << result;
+        return QVariant();
+    }
+
+    switch (mode) {
+    case CAMERA_WHITEBALANCEMODE_AUTO:
+        return QVariant::fromValue(QCameraImageProcessing::WhiteBalanceAuto);
+    case CAMERA_WHITEBALANCEMODE_MANUAL:
+        return QVariant::fromValue(QCameraImageProcessing::WhiteBalanceManual);
+    default:
+        return QVariant();
+    }
+}
+
+void BbCameraImageProcessingControl::setParameter(ProcessingParameter parameter, const QVariant &value)
+{
+    if (parameter != QCameraImageProcessingControl::WhiteBalancePreset)
+        return;
+
+    if (m_session->handle() == CAMERA_HANDLE_INVALID)
+        return;
+
+    camera_whitebalancemode_t mode = CAMERA_WHITEBALANCEMODE_DEFAULT;
+    switch (value.value<QCameraImageProcessing::WhiteBalanceMode>()) {
+    case QCameraImageProcessing::WhiteBalanceAuto:
+        mode = CAMERA_WHITEBALANCEMODE_AUTO;
+        break;
+    case QCameraImageProcessing::WhiteBalanceManual:
+        mode = CAMERA_WHITEBALANCEMODE_MANUAL;
+        break;
+    default:
+        break;
+    }
+
+    const camera_error_t result = camera_set_whitebalance_mode(m_session->handle(), mode);
+
+    if (result != CAMERA_EOK)
+        qWarning() << "Unable to set whitebalance mode:" << result;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/blackberry/camera/bbcameraimageprocessingcontrol.h b/src/plugins/blackberry/camera/bbcameraimageprocessingcontrol.h
new file mode 100644 (file)
index 0000000..ec16d66
--- /dev/null
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.  For licensing terms and
+** conditions see http://qt.digia.com/licensing.  For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 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, Digia gives you certain additional
+** rights.  These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef BBCAMERAIMAGEPROCESSINGCONTROL_H
+#define BBCAMERAIMAGEPROCESSINGCONTROL_H
+
+#include <qcameraimageprocessingcontrol.h>
+
+QT_BEGIN_NAMESPACE
+
+class BbCameraSession;
+
+class BbCameraImageProcessingControl : public QCameraImageProcessingControl
+{
+    Q_OBJECT
+public:
+    explicit BbCameraImageProcessingControl(BbCameraSession *session, QObject *parent = 0);
+
+    bool isParameterSupported(ProcessingParameter) const Q_DECL_OVERRIDE;
+    bool isParameterValueSupported(ProcessingParameter parameter, const QVariant &value) const Q_DECL_OVERRIDE;
+    QVariant parameter(ProcessingParameter parameter) const Q_DECL_OVERRIDE;
+    void setParameter(ProcessingParameter parameter, const QVariant &value) Q_DECL_OVERRIDE;
+
+private:
+    BbCameraSession *m_session;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/blackberry/camera/bbcameralockscontrol.cpp b/src/plugins/blackberry/camera/bbcameralockscontrol.cpp
new file mode 100644 (file)
index 0000000..4719405
--- /dev/null
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.  For licensing terms and
+** conditions see http://qt.digia.com/licensing.  For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 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, Digia gives you certain additional
+** rights.  These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "bbcameralockscontrol.h"
+
+#include "bbcamerasession.h"
+
+QT_BEGIN_NAMESPACE
+
+BbCameraLocksControl::BbCameraLocksControl(BbCameraSession *session, QObject *parent)
+    : QCameraLocksControl(parent)
+    , m_session(session)
+{
+    connect(m_session, SIGNAL(lockStatusChanged(QCamera::LockType,QCamera::LockStatus,QCamera::LockChangeReason)),
+            this, SIGNAL(lockStatusChanged(QCamera::LockType,QCamera::LockStatus,QCamera::LockChangeReason)));
+}
+
+QCamera::LockTypes BbCameraLocksControl::supportedLocks() const
+{
+    return m_session->supportedLocks();
+}
+
+QCamera::LockStatus BbCameraLocksControl::lockStatus(QCamera::LockType lock) const
+{
+    return m_session->lockStatus(lock);
+}
+
+void BbCameraLocksControl::searchAndLock(QCamera::LockTypes locks)
+{
+    m_session->searchAndLock(locks);
+}
+
+void BbCameraLocksControl::unlock(QCamera::LockTypes locks)
+{
+    m_session->unlock(locks);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/blackberry/camera/bbcameralockscontrol.h b/src/plugins/blackberry/camera/bbcameralockscontrol.h
new file mode 100644 (file)
index 0000000..6c4b2da
--- /dev/null
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.  For licensing terms and
+** conditions see http://qt.digia.com/licensing.  For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 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, Digia gives you certain additional
+** rights.  These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef BBCAMERALOCKSCONTROL_H
+#define BBCAMERALOCKSCONTROL_H
+
+#include <qcameralockscontrol.h>
+
+QT_BEGIN_NAMESPACE
+
+class BbCameraSession;
+
+class BbCameraLocksControl : public QCameraLocksControl
+{
+    Q_OBJECT
+public:
+    explicit BbCameraLocksControl(BbCameraSession *session, QObject *parent = 0);
+
+    QCamera::LockTypes supportedLocks() const Q_DECL_OVERRIDE;
+    QCamera::LockStatus lockStatus(QCamera::LockType lock) const Q_DECL_OVERRIDE;
+    void searchAndLock(QCamera::LockTypes locks) Q_DECL_OVERRIDE;
+    void unlock(QCamera::LockTypes locks) Q_DECL_OVERRIDE;
+
+private:
+    BbCameraSession *m_session;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/blackberry/camera/bbcameramediarecordercontrol.cpp b/src/plugins/blackberry/camera/bbcameramediarecordercontrol.cpp
new file mode 100644 (file)
index 0000000..86d32d1
--- /dev/null
@@ -0,0 +1,158 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.  For licensing terms and
+** conditions see http://qt.digia.com/licensing.  For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 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, Digia gives you certain additional
+** rights.  These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "bbcameramediarecordercontrol.h"
+
+#include "bbcamerasession.h"
+
+#include <QDebug>
+#include <QUrl>
+
+#include <audio/audio_manager_device.h>
+#include <audio/audio_manager_volume.h>
+
+QT_BEGIN_NAMESPACE
+
+static audio_manager_device_t currentAudioInputDevice()
+{
+    audio_manager_device_t device = AUDIO_DEVICE_HEADSET;
+
+    const int result = audio_manager_get_default_input_device(&device);
+    if (result != EOK) {
+        qWarning() << "Unable to retrieve default audio input device:" << result;
+        return AUDIO_DEVICE_HEADSET;
+    }
+
+    return device;
+}
+
+BbCameraMediaRecorderControl::BbCameraMediaRecorderControl(BbCameraSession *session, QObject *parent)
+    : QMediaRecorderControl(parent)
+    , m_session(session)
+{
+    connect(m_session, SIGNAL(videoStateChanged(QMediaRecorder::State)), this, SIGNAL(stateChanged(QMediaRecorder::State)));
+    connect(m_session, SIGNAL(videoStatusChanged(QMediaRecorder::Status)), this, SIGNAL(statusChanged(QMediaRecorder::Status)));
+    connect(m_session, SIGNAL(durationChanged(qint64)), this, SIGNAL(durationChanged(qint64)));
+    connect(m_session, SIGNAL(actualLocationChanged(QUrl)), this, SIGNAL(actualLocationChanged(QUrl)));
+    connect(m_session, SIGNAL(videoError(int,QString)), this, SIGNAL(error(int,QString)));
+}
+
+QUrl BbCameraMediaRecorderControl::outputLocation() const
+{
+    return m_session->outputLocation();
+}
+
+bool BbCameraMediaRecorderControl::setOutputLocation(const QUrl &location)
+{
+    return m_session->setOutputLocation(location);
+}
+
+QMediaRecorder::State BbCameraMediaRecorderControl::state() const
+{
+    return m_session->videoState();
+}
+
+QMediaRecorder::Status BbCameraMediaRecorderControl::status() const
+{
+    return m_session->videoStatus();
+}
+
+qint64 BbCameraMediaRecorderControl::duration() const
+{
+    return m_session->duration();
+}
+
+bool BbCameraMediaRecorderControl::isMuted() const
+{
+    bool muted = false;
+
+    const int result = audio_manager_get_input_mute(currentAudioInputDevice(), &muted);
+    if (result != EOK) {
+        emit const_cast<BbCameraMediaRecorderControl*>(this)->error(QMediaRecorder::ResourceError, tr("Unable to retrieve mute status"));
+        return false;
+    }
+
+    return muted;
+}
+
+qreal BbCameraMediaRecorderControl::volume() const
+{
+    double level = 0.0;
+
+    const int result = audio_manager_get_input_level(currentAudioInputDevice(), &level);
+    if (result != EOK) {
+        emit const_cast<BbCameraMediaRecorderControl*>(this)->error(QMediaRecorder::ResourceError, tr("Unable to retrieve audio input volume"));
+        return 0.0;
+    }
+
+    return (level / 100);
+}
+
+void BbCameraMediaRecorderControl::applySettings()
+{
+    m_session->applySettings();
+}
+
+void BbCameraMediaRecorderControl::setState(QMediaRecorder::State state)
+{
+    m_session->setVideoState(state);
+}
+
+void BbCameraMediaRecorderControl::setMuted(bool muted)
+{
+    const int result = audio_manager_set_input_mute(currentAudioInputDevice(), muted);
+    if (result != EOK) {
+        emit error(QMediaRecorder::ResourceError, tr("Unable to set mute status"));
+    } else {
+        emit mutedChanged(muted);
+    }
+}
+
+void BbCameraMediaRecorderControl::setVolume(qreal volume)
+{
+    const int result = audio_manager_set_input_level(currentAudioInputDevice(), (volume * 100));
+    if (result != EOK) {
+        emit error(QMediaRecorder::ResourceError, tr("Unable to set audio input volume"));
+    } else {
+        emit volumeChanged(volume);
+    }
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/blackberry/camera/bbcameramediarecordercontrol.h b/src/plugins/blackberry/camera/bbcameramediarecordercontrol.h
new file mode 100644 (file)
index 0000000..dffd18b
--- /dev/null
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.  For licensing terms and
+** conditions see http://qt.digia.com/licensing.  For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 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, Digia gives you certain additional
+** rights.  These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef BBCAMERAMEDIARECORDERCONTROL_H
+#define BBCAMERAMEDIARECORDERCONTROL_H
+
+#include <qmediarecordercontrol.h>
+
+QT_BEGIN_NAMESPACE
+
+class BbCameraSession;
+
+class BbCameraMediaRecorderControl : public QMediaRecorderControl
+{
+    Q_OBJECT
+public:
+    explicit BbCameraMediaRecorderControl(BbCameraSession *session, QObject *parent = 0);
+
+    QUrl outputLocation() const Q_DECL_OVERRIDE;
+    bool setOutputLocation(const QUrl &location) Q_DECL_OVERRIDE;
+    QMediaRecorder::State state() const Q_DECL_OVERRIDE;
+    QMediaRecorder::Status status() const Q_DECL_OVERRIDE;
+    qint64 duration() const Q_DECL_OVERRIDE;
+    bool isMuted() const Q_DECL_OVERRIDE;
+    qreal volume() const Q_DECL_OVERRIDE;
+    void applySettings() Q_DECL_OVERRIDE;
+
+public Q_SLOTS:
+    void setState(QMediaRecorder::State state) Q_DECL_OVERRIDE;
+    void setMuted(bool muted) Q_DECL_OVERRIDE;
+    void setVolume(qreal volume) Q_DECL_OVERRIDE;
+
+private:
+    BbCameraSession *m_session;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/blackberry/camera/bbcameraorientationhandler.cpp b/src/plugins/blackberry/camera/bbcameraorientationhandler.cpp
new file mode 100644 (file)
index 0000000..7e89162
--- /dev/null
@@ -0,0 +1,100 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.  For licensing terms and
+** conditions see http://qt.digia.com/licensing.  For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 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, Digia gives you certain additional
+** rights.  These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "bbcameraorientationhandler.h"
+
+#include <QAbstractEventDispatcher>
+#include <QCoreApplication>
+#include <QDebug>
+
+#include <bps/orientation.h>
+
+QT_BEGIN_NAMESPACE
+
+BbCameraOrientationHandler::BbCameraOrientationHandler(QObject *parent)
+    : QObject(parent)
+    , m_orientation(0)
+{
+    QCoreApplication::eventDispatcher()->installNativeEventFilter(this);
+    int result = orientation_request_events(0);
+    if (result == BPS_FAILURE)
+        qWarning() << "Unable to register for orientation change events";
+
+    orientation_direction_t direction = ORIENTATION_FACE_UP;
+    int angle = 0;
+
+    result = orientation_get(&direction, &angle);
+    if (result == BPS_FAILURE) {
+        qWarning() << "Unable to retrieve initial orientation";
+    } else {
+        m_orientation = angle;
+    }
+}
+
+BbCameraOrientationHandler::~BbCameraOrientationHandler()
+{
+    const int result = orientation_stop_events(0);
+    if (result == BPS_FAILURE)
+        qWarning() << "Unable to unregister for orientation change events";
+
+    QCoreApplication::eventDispatcher()->removeNativeEventFilter(this);
+}
+
+bool BbCameraOrientationHandler::nativeEventFilter(const QByteArray&, void *message, long*)
+{
+    bps_event_t* const event = static_cast<bps_event_t*>(message);
+    if (!event || bps_event_get_domain(event) != orientation_get_domain())
+        return false;
+
+    const int angle = orientation_event_get_angle(event);
+    if (angle != m_orientation) {
+        m_orientation = angle;
+        emit orientationChanged(m_orientation);
+    }
+
+    return false; // do not drop the event
+}
+
+int BbCameraOrientationHandler::orientation() const
+{
+    return m_orientation;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/blackberry/camera/bbcameraorientationhandler.h b/src/plugins/blackberry/camera/bbcameraorientationhandler.h
new file mode 100644 (file)
index 0000000..3d236b8
--- /dev/null
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.  For licensing terms and
+** conditions see http://qt.digia.com/licensing.  For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 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, Digia gives you certain additional
+** rights.  These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef BBCAMERAORIENTATIONHANDLER_H
+#define BBCAMERAORIENTATIONHANDLER_H
+
+#include <QAbstractNativeEventFilter>
+#include <QObject>
+
+QT_BEGIN_NAMESPACE
+
+class BbCameraOrientationHandler : public QObject, public QAbstractNativeEventFilter
+{
+    Q_OBJECT
+public:
+    explicit BbCameraOrientationHandler(QObject *parent = 0);
+    ~BbCameraOrientationHandler();
+
+    bool nativeEventFilter(const QByteArray &eventType, void *message, long *result) Q_DECL_OVERRIDE;
+
+    int orientation() const;
+
+Q_SIGNALS:
+    void orientationChanged(int degree);
+
+private:
+    int m_orientation;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/blackberry/camera/bbcameraservice.cpp b/src/plugins/blackberry/camera/bbcameraservice.cpp
new file mode 100644 (file)
index 0000000..d9adc7c
--- /dev/null
@@ -0,0 +1,141 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.  For licensing terms and
+** conditions see http://qt.digia.com/licensing.  For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 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, Digia gives you certain additional
+** rights.  These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "bbcameraservice.h"
+
+#include "bbcameraaudioencodersettingscontrol.h"
+#include "bbcameracapturebufferformatcontrol.h"
+#include "bbcameracapturedestinationcontrol.h"
+#include "bbcameracontrol.h"
+#include "bbcameraexposurecontrol.h"
+#include "bbcameraflashcontrol.h"
+#include "bbcamerafocuscontrol.h"
+#include "bbcameraimagecapturecontrol.h"
+#include "bbcameraimageprocessingcontrol.h"
+#include "bbcameralockscontrol.h"
+#include "bbcameramediarecordercontrol.h"
+#include "bbcamerasession.h"
+#include "bbcameravideoencodersettingscontrol.h"
+#include "bbcameraviewfindersettingscontrol.h"
+#include "bbcamerazoomcontrol.h"
+#include "bbimageencodercontrol.h"
+#include "bbvideodeviceselectorcontrol.h"
+#include "bbvideorenderercontrol.h"
+
+#include <QDebug>
+#include <QVariant>
+
+QT_BEGIN_NAMESPACE
+
+BbCameraService::BbCameraService(QObject *parent)
+    : QMediaService(parent)
+    , m_cameraSession(new BbCameraSession(this))
+    , m_cameraAudioEncoderSettingsControl(new BbCameraAudioEncoderSettingsControl(m_cameraSession, this))
+    , m_cameraCaptureBufferFormatControl(new BbCameraCaptureBufferFormatControl(this))
+    , m_cameraCaptureDestinationControl(new BbCameraCaptureDestinationControl(m_cameraSession, this))
+    , m_cameraControl(new BbCameraControl(m_cameraSession, this))
+    , m_cameraExposureControl(new BbCameraExposureControl(m_cameraSession, this))
+    , m_cameraFlashControl(new BbCameraFlashControl(m_cameraSession, this))
+    , m_cameraFocusControl(new BbCameraFocusControl(m_cameraSession, this))
+    , m_cameraImageCaptureControl(new BbCameraImageCaptureControl(m_cameraSession, this))
+    , m_cameraImageProcessingControl(new BbCameraImageProcessingControl(m_cameraSession, this))
+    , m_cameraLocksControl(new BbCameraLocksControl(m_cameraSession, this))
+    , m_cameraMediaRecorderControl(new BbCameraMediaRecorderControl(m_cameraSession, this))
+    , m_cameraVideoEncoderSettingsControl(new BbCameraVideoEncoderSettingsControl(m_cameraSession, this))
+    , m_cameraViewfinderSettingsControl(new BbCameraViewfinderSettingsControl(m_cameraSession, this))
+    , m_cameraZoomControl(new BbCameraZoomControl(m_cameraSession, this))
+    , m_imageEncoderControl(new BbImageEncoderControl(m_cameraSession, this))
+    , m_videoDeviceSelectorControl(new BbVideoDeviceSelectorControl(m_cameraSession, this))
+    , m_videoRendererControl(new BbVideoRendererControl(m_cameraSession, this))
+{
+}
+
+BbCameraService::~BbCameraService()
+{
+}
+
+QMediaControl* BbCameraService::requestControl(const char *name)
+{
+    if (qstrcmp(name, QAudioEncoderSettingsControl_iid) == 0)
+        return m_cameraAudioEncoderSettingsControl;
+    else if (qstrcmp(name, QCameraCaptureBufferFormatControl_iid) == 0)
+        return m_cameraCaptureBufferFormatControl;
+    else if (qstrcmp(name, QCameraCaptureDestinationControl_iid) == 0)
+        return m_cameraCaptureDestinationControl;
+    else if (qstrcmp(name, QCameraControl_iid) == 0)
+        return m_cameraControl;
+    else if (qstrcmp(name, QCameraExposureControl_iid) == 0)
+        return m_cameraExposureControl;
+    else if (qstrcmp(name, QCameraFlashControl_iid) == 0)
+        return m_cameraFlashControl;
+    else if (qstrcmp(name, QCameraFocusControl_iid) == 0)
+        return m_cameraFocusControl;
+    else if (qstrcmp(name, QCameraImageCaptureControl_iid) == 0)
+        return m_cameraImageCaptureControl;
+    else if (qstrcmp(name, QCameraImageProcessingControl_iid) == 0)
+        return m_cameraImageProcessingControl;
+    else if (qstrcmp(name, QCameraLocksControl_iid) == 0)
+        return m_cameraLocksControl;
+    else if (qstrcmp(name, QMediaRecorderControl_iid) == 0)
+        return m_cameraMediaRecorderControl;
+    else if (qstrcmp(name, QVideoEncoderSettingsControl_iid) == 0)
+        return m_cameraVideoEncoderSettingsControl;
+    else if (qstrcmp(name, QCameraViewfinderSettingsControl_iid) == 0)
+        return m_cameraViewfinderSettingsControl;
+    else if (qstrcmp(name, QCameraZoomControl_iid) == 0)
+        return m_cameraZoomControl;
+    else if (qstrcmp(name, QImageEncoderControl_iid) == 0)
+        return m_imageEncoderControl;
+    else if (qstrcmp(name, QVideoDeviceSelectorControl_iid) == 0)
+        return m_videoDeviceSelectorControl;
+    else if (qstrcmp(name, QVideoRendererControl_iid) == 0)
+        return m_videoRendererControl;
+
+    return 0;
+}
+
+void BbCameraService::releaseControl(QMediaControl *control)
+{
+    Q_UNUSED(control)
+
+    // Implemented as a singleton, so we do nothing.
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/blackberry/camera/bbcameraservice.h b/src/plugins/blackberry/camera/bbcameraservice.h
new file mode 100644 (file)
index 0000000..374d03c
--- /dev/null
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.  For licensing terms and
+** conditions see http://qt.digia.com/licensing.  For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 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, Digia gives you certain additional
+** rights.  These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef BBCAMERASERVICE_H
+#define BBCAMERASERVICE_H
+
+#include <QObject>
+
+#include <qmediaservice.h>
+
+QT_BEGIN_NAMESPACE
+
+class BbCameraAudioEncoderSettingsControl;
+class BbCameraCaptureBufferFormatControl;
+class BbCameraCaptureDestinationControl;
+class BbCameraControl;
+class BbCameraExposureControl;
+class BbCameraFlashControl;
+class BbCameraFocusControl;
+class BbCameraImageCaptureControl;
+class BbCameraImageProcessingControl;
+class BbCameraLocksControl;
+class BbCameraMediaRecorderControl;
+class BbCameraSession;
+class BbCameraVideoEncoderSettingsControl;
+class BbCameraViewfinderSettingsControl;
+class BbCameraZoomControl;
+class BbImageEncoderControl;
+class BbVideoDeviceSelectorControl;
+class BbVideoRendererControl;
+
+class BbCameraService : public QMediaService
+{
+    Q_OBJECT
+
+public:
+    explicit BbCameraService(QObject *parent = 0);
+    ~BbCameraService();
+
+    virtual QMediaControl* requestControl(const char *name);
+    virtual void releaseControl(QMediaControl *control);
+
+private:
+    BbCameraSession* m_cameraSession;
+
+    BbCameraAudioEncoderSettingsControl* m_cameraAudioEncoderSettingsControl;
+    BbCameraCaptureBufferFormatControl* m_cameraCaptureBufferFormatControl;
+    BbCameraCaptureDestinationControl* m_cameraCaptureDestinationControl;
+    BbCameraControl* m_cameraControl;
+    BbCameraExposureControl* m_cameraExposureControl;
+    BbCameraFlashControl* m_cameraFlashControl;
+    BbCameraFocusControl* m_cameraFocusControl;
+    BbCameraImageCaptureControl* m_cameraImageCaptureControl;
+    BbCameraImageProcessingControl* m_cameraImageProcessingControl;
+    BbCameraLocksControl* m_cameraLocksControl;
+    BbCameraMediaRecorderControl* m_cameraMediaRecorderControl;
+    BbCameraVideoEncoderSettingsControl* m_cameraVideoEncoderSettingsControl;
+    BbCameraViewfinderSettingsControl* m_cameraViewfinderSettingsControl;
+    BbCameraZoomControl* m_cameraZoomControl;
+    BbImageEncoderControl* m_imageEncoderControl;
+    BbVideoDeviceSelectorControl* m_videoDeviceSelectorControl;
+    BbVideoRendererControl* m_videoRendererControl;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/blackberry/camera/bbcamerasession.cpp b/src/plugins/blackberry/camera/bbcamerasession.cpp
new file mode 100644 (file)
index 0000000..d414c82
--- /dev/null
@@ -0,0 +1,1343 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.  For licensing terms and
+** conditions see http://qt.digia.com/licensing.  For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 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, Digia gives you certain additional
+** rights.  These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "bbcamerasession.h"
+
+#include "bbcameraorientationhandler.h"
+#include "bbcameraviewfindersettingscontrol.h"
+
+#include <QAbstractVideoSurface>
+#include <QBuffer>
+#include <QDebug>
+#include <QImage>
+#include <QUrl>
+#include <QVideoSurfaceFormat>
+#include <qmath.h>
+
+#include <algorithm>
+
+QT_BEGIN_NAMESPACE
+
+static QString errorToString(camera_error_t error)
+{
+    switch (error) {
+    case CAMERA_EOK:
+        return QLatin1String("No error");
+    case CAMERA_EAGAIN:
+        return QLatin1String("Camera unavailable");
+    case CAMERA_EINVAL:
+        return QLatin1String("Inavlid argument");
+    case CAMERA_ENODEV:
+        return QLatin1String("Camera not found");
+    case CAMERA_EMFILE:
+        return QLatin1String("File table overflow");
+    case CAMERA_EBADF:
+        return QLatin1String("Invalid handle passed");
+    case CAMERA_EACCESS:
+        return QLatin1String("No permission");
+    case CAMERA_EBADR:
+        return QLatin1String("Invalid file descriptor");
+    case CAMERA_ENOENT:
+        return QLatin1String("File or directory does not exists");
+    case CAMERA_ENOMEM:
+        return QLatin1String("Memory allocation failed");
+    case CAMERA_EOPNOTSUPP:
+        return QLatin1String("Operation not supported");
+    case CAMERA_ETIMEDOUT:
+        return QLatin1String("Communication timeout");
+    case CAMERA_EALREADY:
+        return QLatin1String("Operation already in progress");
+    case CAMERA_ENOSPC:
+        return QLatin1String("Disk is full");
+    case CAMERA_EUNINIT:
+        return QLatin1String("Camera library not initialized");
+    case CAMERA_EREGFAULT:
+        return QLatin1String("Callback registration failed");
+    case CAMERA_EMICINUSE:
+        return QLatin1String("Microphone in use already");
+    case CAMERA_EDESKTOPCAMERAINUSE:
+        return QLatin1String("Desktop camera in use already");
+    default:
+        return QLatin1String("Unknown error");
+    }
+}
+
+QDebug operator<<(QDebug debug, camera_error_t error)
+{
+    debug.nospace() << errorToString(error);
+    return debug.space();
+}
+
+BbCameraSession::BbCameraSession(QObject *parent)
+    : QObject(parent)
+    , m_nativeCameraOrientation(0)
+    , m_orientationHandler(new BbCameraOrientationHandler(this))
+    , m_status(QCamera::UnloadedStatus)
+    , m_state(QCamera::UnloadedState)
+    , m_captureMode(QCamera::CaptureStillImage)
+    , m_device("bb:RearCamera")
+    , m_surface(0)
+    , m_captureImageDriveMode(QCameraImageCapture::SingleImageCapture)
+    , m_lastImageCaptureId(0)
+    , m_captureDestination(QCameraImageCapture::CaptureToFile)
+    , m_locksApplyMode(IndependentMode)
+    , m_focusLockStatus(QCamera::Unlocked)
+    , m_videoState(QMediaRecorder::StoppedState)
+    , m_videoStatus(QMediaRecorder::LoadedStatus)
+    , m_handle(CAMERA_HANDLE_INVALID)
+{
+    connect(this, SIGNAL(statusChanged(QCamera::Status)), SLOT(updateReadyForCapture()));
+    connect(this, SIGNAL(captureModeChanged(QCamera::CaptureModes)), SLOT(updateReadyForCapture()));
+    connect(m_orientationHandler, SIGNAL(orientationChanged(int)), SLOT(deviceOrientationChanged(int)));
+}
+
+BbCameraSession::~BbCameraSession()
+{
+    stopViewFinder();
+    closeCamera();
+}
+
+camera_handle_t BbCameraSession::handle() const
+{
+    return m_handle;
+}
+
+QCamera::State BbCameraSession::state() const
+{
+    return m_state;
+}
+
+void BbCameraSession::setState(QCamera::State state)
+{
+    if (m_state == state)
+        return;
+
+    const QCamera::State previousState = m_state;
+
+    if (previousState == QCamera::UnloadedState) {
+        if (state == QCamera::LoadedState) {
+            if (openCamera()) {
+                m_state = state;
+            }
+        } else if (state == QCamera::ActiveState) {
+            if (openCamera()) {
+                applyConfiguration();
+                if (startViewFinder()) {
+                    m_state = state;
+                }
+            }
+        }
+    } else if (previousState == QCamera::LoadedState) {
+        if (state == QCamera::UnloadedState) {
+            closeCamera();
+            m_state = state;
+        } else if (state == QCamera::ActiveState) {
+            applyConfiguration();
+            if (startViewFinder()) {
+                m_state = state;
+            }
+        }
+    } else if (previousState == QCamera::ActiveState) {
+        if (state == QCamera::LoadedState) {
+            stopViewFinder();
+            m_state = state;
+        } else if (state == QCamera::UnloadedState) {
+            stopViewFinder();
+            closeCamera();
+            m_state = state;
+        }
+    }
+
+    if (m_state != previousState)
+        emit stateChanged(m_state);
+}
+
+QCamera::Status BbCameraSession::status() const
+{
+    return m_status;
+}
+
+QCamera::CaptureModes BbCameraSession::captureMode() const
+{
+    return m_captureMode;
+}
+
+void BbCameraSession::setCaptureMode(QCamera::CaptureModes captureMode)
+{
+    if (m_captureMode == captureMode)
+        return;
+
+    m_captureMode = captureMode;
+    emit captureModeChanged(m_captureMode);
+}
+
+bool BbCameraSession::isCaptureModeSupported(QCamera::CaptureModes mode) const
+{
+    if (m_handle == CAMERA_HANDLE_INVALID) {
+        // the camera has not been loaded yet via QCamera::load(), so
+        // we open it temporarily to peek for the supported capture modes
+
+        camera_unit_t unit = CAMERA_UNIT_REAR;
+        if (m_device == cameraIdentifierFront())
+            unit = CAMERA_UNIT_FRONT;
+        else if (m_device == cameraIdentifierRear())
+            unit = CAMERA_UNIT_REAR;
+        else if (m_device == cameraIdentifierDesktop())
+            unit = CAMERA_UNIT_DESKTOP;
+
+        camera_handle_t handle;
+        const camera_error_t result = camera_open(unit, CAMERA_MODE_RW, &handle);
+        if (result != CAMERA_EOK)
+            return true;
+
+        const bool supported = isCaptureModeSupported(handle, mode);
+
+        camera_close(handle);
+
+        return supported;
+    } else {
+        return isCaptureModeSupported(m_handle, mode);
+    }
+}
+
+QByteArray BbCameraSession::cameraIdentifierFront()
+{
+    return "bb:FrontCamera";
+}
+
+QByteArray BbCameraSession::cameraIdentifierRear()
+{
+    return "bb:RearCamera";
+}
+
+QByteArray BbCameraSession::cameraIdentifierDesktop()
+{
+    return "bb:DesktopCamera";
+}
+
+void BbCameraSession::setDevice(const QByteArray &device)
+{
+    m_device = device;
+}
+
+QByteArray BbCameraSession::device() const
+{
+    return m_device;
+}
+
+QAbstractVideoSurface* BbCameraSession::surface() const
+{
+    return m_surface;
+}
+
+void BbCameraSession::setSurface(QAbstractVideoSurface *surface)
+{
+    QMutexLocker locker(&m_surfaceMutex);
+
+    if (m_surface == surface)
+        return;
+
+    m_surface = surface;
+}
+
+bool BbCameraSession::isReadyForCapture() const
+{
+    if (m_captureMode & QCamera::CaptureStillImage)
+        return (m_status == QCamera::ActiveStatus);
+
+    if (m_captureMode & QCamera::CaptureVideo)
+        return (m_status == QCamera::ActiveStatus);
+
+    return false;
+}
+
+QCameraImageCapture::DriveMode BbCameraSession::driveMode() const
+{
+    return m_captureImageDriveMode;
+}
+
+void BbCameraSession::setDriveMode(QCameraImageCapture::DriveMode mode)
+{
+    m_captureImageDriveMode = mode;
+}
+
+/**
+ * A helper structure that keeps context data for image capture callbacks.
+ */
+struct ImageCaptureData
+{
+    int requestId;
+    QString fileName;
+    BbCameraSession *session;
+};
+
+static void imageCaptureShutterCallback(camera_handle_t handle, void *context)
+{
+    Q_UNUSED(handle)
+
+    const ImageCaptureData *data = static_cast<ImageCaptureData*>(context);
+
+    // We are inside a worker thread here, so emit imageExposed inside the main thread
+    QMetaObject::invokeMethod(data->session, "imageExposed", Qt::QueuedConnection,
+                              Q_ARG(int, data->requestId));
+}
+
+static void imageCaptureImageCallback(camera_handle_t handle, camera_buffer_t *buffer, void *context)
+{
+    Q_UNUSED(handle)
+
+    QScopedPointer<ImageCaptureData> data(static_cast<ImageCaptureData*>(context));
+
+    if (buffer->frametype != CAMERA_FRAMETYPE_JPEG) {
+        // We are inside a worker thread here, so emit error signal inside the main thread
+        QMetaObject::invokeMethod(data->session, "imageCaptureError", Qt::QueuedConnection,
+                                  Q_ARG(int, data->requestId),
+                                  Q_ARG(QCameraImageCapture::Error, QCameraImageCapture::FormatError),
+                                  Q_ARG(QString, QObject::tr("Camera provides image in unsupported format")));
+        return;
+    }
+
+    const QByteArray rawData((const char*)buffer->framebuf, buffer->framedesc.jpeg.bufsize);
+
+    QImage image;
+    const bool ok = image.loadFromData(rawData, "JPG");
+    if (!ok) {
+        const QString errorMessage = QObject::tr("Could not load JPEG data from frame");
+        // We are inside a worker thread here, so emit error signal inside the main thread
+        QMetaObject::invokeMethod(data->session, "imageCaptureError", Qt::QueuedConnection,
+                                  Q_ARG(int, data->requestId),
+                                  Q_ARG(QCameraImageCapture::Error, QCameraImageCapture::FormatError),
+                                  Q_ARG(QString, errorMessage));
+        return;
+    }
+
+
+    // We are inside a worker thread here, so invoke imageCaptured inside the main thread
+    QMetaObject::invokeMethod(data->session, "imageCaptured", Qt::QueuedConnection,
+                              Q_ARG(int, data->requestId),
+                              Q_ARG(QImage, image),
+                              Q_ARG(QString, data->fileName));
+}
+
+int BbCameraSession::capture(const QString &fileName)
+{
+    m_lastImageCaptureId++;
+
+    if (!isReadyForCapture()) {
+        emit imageCaptureError(m_lastImageCaptureId, QCameraImageCapture::NotReadyError, tr("Camera not ready"));
+        return m_lastImageCaptureId;
+    }
+
+    if (m_captureImageDriveMode == QCameraImageCapture::SingleImageCapture) {
+        // prepare context object for callback
+        ImageCaptureData *context = new ImageCaptureData;
+        context->requestId = m_lastImageCaptureId;
+        context->fileName = fileName;
+        context->session = this;
+
+        const camera_error_t result = camera_take_photo(m_handle,
+                                                        imageCaptureShutterCallback,
+                                                        0,
+                                                        0,
+                                                        imageCaptureImageCallback,
+                                                        context, false);
+
+        if (result != CAMERA_EOK)
+            qWarning() << "Unable to take photo:" << result;
+    } else {
+        // TODO: implement burst mode when available in Qt API
+    }
+
+    return m_lastImageCaptureId;
+}
+
+void BbCameraSession::cancelCapture()
+{
+    // BB10 API doesn't provide functionality for that
+}
+
+bool BbCameraSession::isCaptureDestinationSupported(QCameraImageCapture::CaptureDestinations destination) const
+{
+    // capture to buffer, file and both are supported.
+    return destination & (QCameraImageCapture::CaptureToFile | QCameraImageCapture::CaptureToBuffer);
+}
+
+QCameraImageCapture::CaptureDestinations BbCameraSession::captureDestination() const
+{
+    return m_captureDestination;
+}
+
+void BbCameraSession::setCaptureDestination(QCameraImageCapture::CaptureDestinations destination)
+{
+    if (m_captureDestination != destination) {
+        m_captureDestination = destination;
+        emit captureDestinationChanged(m_captureDestination);
+    }
+}
+
+QList<QSize> BbCameraSession::supportedResolutions(const QImageEncoderSettings&, bool *continuous) const
+{
+    if (continuous)
+        *continuous = false;
+
+    if (m_status == QCamera::UnloadedStatus)
+        return QList<QSize>();
+
+    if (m_captureMode & QCamera::CaptureStillImage) {
+        return supportedResolutions(QCamera::CaptureStillImage);
+    } else if (m_captureMode & QCamera::CaptureVideo) {
+        return supportedResolutions(QCamera::CaptureVideo);
+    }
+
+    return QList<QSize>();
+}
+
+QImageEncoderSettings BbCameraSession::imageSettings() const
+{
+    return m_imageEncoderSettings;
+}
+
+void BbCameraSession::setImageSettings(const QImageEncoderSettings &settings)
+{
+    m_imageEncoderSettings = settings;
+    if (m_imageEncoderSettings.codec().isEmpty())
+        m_imageEncoderSettings.setCodec(QLatin1String("jpeg"));
+}
+
+QCamera::LockTypes BbCameraSession::supportedLocks() const
+{
+    if (m_locksApplyMode == FocusOnlyMode)
+        return QCamera::LockFocus;
+    else
+        return (QCamera::LockExposure | QCamera::LockWhiteBalance | QCamera::LockFocus);
+}
+
+QCamera::LockStatus BbCameraSession::lockStatus(QCamera::LockType lock) const
+{
+    switch (lock) {
+    case QCamera::LockExposure:
+        return QCamera::Unlocked;
+    case QCamera::LockWhiteBalance:
+        return QCamera::Unlocked;
+    case QCamera::LockFocus:
+        return m_focusLockStatus;
+    default:
+        return QCamera::Unlocked;
+    }
+}
+
+void BbCameraSession::searchAndLock(QCamera::LockTypes locks)
+{
+    m_currentLockTypes |= locks;
+
+    uint32_t lockModes = CAMERA_3A_NONE;
+
+    switch (m_locksApplyMode) {
+    case IndependentMode:
+        if (m_currentLockTypes & QCamera::LockExposure)
+            lockModes |= CAMERA_3A_AUTOEXPOSURE;
+        if (m_currentLockTypes & QCamera::LockWhiteBalance)
+            lockModes |= CAMERA_3A_AUTOWHITEBALANCE;
+        if (m_currentLockTypes & QCamera::LockFocus)
+            lockModes |= CAMERA_3A_AUTOFOCUS;
+        break;
+    case FocusExposureBoundMode:
+        if ((m_currentLockTypes & QCamera::LockExposure) || (m_currentLockTypes & QCamera::LockFocus))
+            lockModes = (CAMERA_3A_AUTOEXPOSURE | CAMERA_3A_AUTOFOCUS);
+        break;
+    case AllBoundMode:
+            lockModes = (CAMERA_3A_AUTOEXPOSURE | CAMERA_3A_AUTOFOCUS | CAMERA_3A_AUTOWHITEBALANCE);
+        break;
+    case FocusOnlyMode:
+            lockModes = CAMERA_3A_AUTOFOCUS;
+        break;
+    }
+
+    const camera_error_t result = camera_set_3a_lock(m_handle, lockModes);
+
+    if (result != CAMERA_EOK) {
+        qWarning() << "Unable to set lock modes:" << result;
+    }
+}
+
+void BbCameraSession::unlock(QCamera::LockTypes locks)
+{
+    m_currentLockTypes &= ~locks;
+
+    uint32_t lockModes = CAMERA_3A_NONE;
+
+    switch (m_locksApplyMode) {
+    case IndependentMode:
+        if (m_currentLockTypes & QCamera::LockExposure)
+            lockModes |= CAMERA_3A_AUTOEXPOSURE;
+        if (m_currentLockTypes & QCamera::LockWhiteBalance)
+            lockModes |= CAMERA_3A_AUTOWHITEBALANCE;
+        if (m_currentLockTypes & QCamera::LockFocus)
+            lockModes |= CAMERA_3A_AUTOFOCUS;
+        break;
+    case FocusExposureBoundMode:
+        if ((m_currentLockTypes & QCamera::LockExposure) || (m_currentLockTypes & QCamera::LockFocus))
+            lockModes = (CAMERA_3A_AUTOEXPOSURE | CAMERA_3A_AUTOFOCUS);
+        break;
+    case AllBoundMode:
+            lockModes = (CAMERA_3A_AUTOEXPOSURE | CAMERA_3A_AUTOFOCUS | CAMERA_3A_AUTOWHITEBALANCE);
+        break;
+    case FocusOnlyMode:
+            lockModes = CAMERA_3A_AUTOFOCUS;
+        break;
+    }
+
+    const camera_error_t result = camera_set_3a_lock(m_handle, lockModes);
+
+    if (result != CAMERA_EOK)
+        qWarning() << "Unable to set lock modes:" << result;
+}
+
+QUrl BbCameraSession::outputLocation() const
+{
+    return QUrl::fromLocalFile(m_videoOutputLocation);
+}
+
+bool BbCameraSession::setOutputLocation(const QUrl &location)
+{
+    m_videoOutputLocation = location.toLocalFile();
+
+    return true;
+}
+
+QMediaRecorder::State BbCameraSession::videoState() const
+{
+    return m_videoState;
+}
+
+void BbCameraSession::setVideoState(QMediaRecorder::State state)
+{
+    if (m_videoState == state)
+        return;
+
+    const QMediaRecorder::State previousState = m_videoState;
+
+    if (previousState == QMediaRecorder::StoppedState) {
+        if (state == QMediaRecorder::RecordingState) {
+            if (startVideoRecording()) {
+                m_videoState = state;
+            }
+        } else if (state == QMediaRecorder::PausedState) {
+            // do nothing
+        }
+    } else if (previousState == QMediaRecorder::RecordingState) {
+        if (state == QMediaRecorder::StoppedState) {
+            stopVideoRecording();
+            m_videoState = state;
+        } else if (state == QMediaRecorder::PausedState) {
+            //TODO: (pause) not supported by BB10 API yet
+        }
+    } else if (previousState == QMediaRecorder::PausedState) {
+        if (state == QMediaRecorder::StoppedState) {
+            stopVideoRecording();
+            m_videoState = state;
+        } else if (state == QMediaRecorder::RecordingState) {
+            //TODO: (resume) not supported by BB10 API yet
+        }
+    }
+
+    emit videoStateChanged(m_videoState);
+}
+
+QMediaRecorder::Status BbCameraSession::videoStatus() const
+{
+    return m_videoStatus;
+}
+
+qint64 BbCameraSession::duration() const
+{
+    return (m_videoRecordingDuration.isValid() ? m_videoRecordingDuration.elapsed() : 0);
+}
+
+void BbCameraSession::applySettings()
+{
+    if (m_handle == CAMERA_HANDLE_INVALID)
+        return;
+
+    QString videoCodec = m_videoEncoderSettings.codec();
+    if (videoCodec.isEmpty())
+        videoCodec = QLatin1String("h264");
+
+    camera_videocodec_t cameraVideoCodec = CAMERA_VIDEOCODEC_H264;
+    if (videoCodec == QLatin1String("none"))
+        cameraVideoCodec = CAMERA_VIDEOCODEC_NONE;
+    else if (videoCodec == QLatin1String("avc1"))
+        cameraVideoCodec = CAMERA_VIDEOCODEC_AVC1;
+    else if (videoCodec == QLatin1String("h264"))
+        cameraVideoCodec = CAMERA_VIDEOCODEC_H264;
+
+    QSize resolution = m_videoEncoderSettings.resolution();
+    if (!resolution.isValid()) {
+        const QList<QSize> resolutions = supportedResolutions(QCamera::CaptureVideo);
+        if (!resolutions.isEmpty())
+            resolution = resolutions.first();
+    }
+
+    //TODO: how to retrieve the supported video framerates from BB10 API?
+    qreal frameRate = m_videoEncoderSettings.frameRate();
+    if (frameRate == 0) {
+        const QList<qreal> frameRates = supportedFrameRates(QVideoEncoderSettings(), 0);
+        if (!frameRates.isEmpty())
+            frameRate = frameRates.last();
+    }
+
+    QString audioCodec = m_audioEncoderSettings.codec();
+    if (audioCodec.isEmpty())
+        audioCodec = QLatin1String("aac");
+
+    camera_audiocodec_t cameraAudioCodec = CAMERA_AUDIOCODEC_AAC;
+    if (audioCodec == QLatin1String("none"))
+        cameraAudioCodec = CAMERA_AUDIOCODEC_NONE;
+    else if (audioCodec == QLatin1String("aac"))
+        cameraAudioCodec = CAMERA_AUDIOCODEC_AAC;
+    else if (audioCodec == QLatin1String("raw"))
+        cameraAudioCodec = CAMERA_AUDIOCODEC_RAW;
+
+    const camera_error_t result = camera_set_video_property(m_handle,
+                                                            CAMERA_IMGPROP_WIDTH, resolution.width(),
+                                                            CAMERA_IMGPROP_HEIGHT, resolution.height(),
+                                                            CAMERA_IMGPROP_VIDEOCODEC, cameraVideoCodec,
+                                                            CAMERA_IMGPROP_AUDIOCODEC, cameraAudioCodec);
+
+    if (result != CAMERA_EOK) {
+        qWarning() << "Unable to apply video settings:" << result;
+        emit videoError(QMediaRecorder::ResourceError, tr("Unable to apply video settings"));
+    }
+}
+
+QList<QSize> BbCameraSession::supportedResolutions(const QVideoEncoderSettings &settings, bool *continuous) const
+{
+    Q_UNUSED(settings);
+
+    if (continuous)
+        *continuous = false;
+
+    return supportedResolutions(QCamera::CaptureVideo);
+}
+
+QList<qreal> BbCameraSession::supportedFrameRates(const QVideoEncoderSettings &settings, bool *continuous) const
+{
+    Q_UNUSED(settings);
+
+    if (m_handle == CAMERA_HANDLE_INVALID)
+        return QList<qreal>();
+
+    int supported = 0;
+    double rates[20];
+    bool maxmin = false;
+
+    //TODO: actually we want to retrieve the framerates of the video here, not the viewfinder
+    const camera_error_t result = camera_get_video_vf_framerates(m_handle, 20, &supported, rates, &maxmin);
+    if (result != CAMERA_EOK) {
+        qWarning() << "Unable to retrieve supported viewfinder framerates:" << result;
+        return QList<qreal>();
+    }
+
+    QList<qreal> frameRates;
+    for (int i = 0; i < supported; ++i)
+        frameRates << rates[i];
+
+    if (continuous)
+        *continuous = maxmin;
+
+    return frameRates;
+}
+
+QVideoEncoderSettings BbCameraSession::videoSettings() const
+{
+    return m_videoEncoderSettings;
+}
+
+void BbCameraSession::setVideoSettings(const QVideoEncoderSettings &settings)
+{
+    m_videoEncoderSettings = settings;
+}
+
+QAudioEncoderSettings BbCameraSession::audioSettings() const
+{
+    return m_audioEncoderSettings;
+}
+
+void BbCameraSession::setAudioSettings(const QAudioEncoderSettings &settings)
+{
+    m_audioEncoderSettings = settings;
+}
+
+static QImage convertFrameToImage(camera_buffer_t *buffer)
+{
+    if (buffer->frametype != CAMERA_FRAMETYPE_NV12)
+        return QImage();
+
+    const unsigned int width = buffer->framedesc.nv12.width;
+    const unsigned int height = buffer->framedesc.nv12.height;
+
+    /**
+     * Copying the data from the buffer into our own data array and working
+     * on this copy is actually faster than working on the buffer.
+     * Looks like we hit some cache misses here, since the stride inside the
+     * NV12 frame is really large (4096) in comparison to the actual image width (768)
+     */
+    const unsigned long long size = width*height + width*height/2;
+    unsigned char *data = new unsigned char[size];
+
+    unsigned char *source = buffer->framebuf;
+    unsigned char *dest = data;
+    for (uint row = 0; row < height; ++row) {
+        memcpy(dest, source, width);
+        source += buffer->framedesc.nv12.stride;
+        dest += width;
+    }
+
+    source = buffer->framebuf + buffer->framedesc.nv12.uv_offset;
+    for (uint row = 0; row < height/2; ++row) {
+        memcpy(dest, source, width);
+        source += buffer->framedesc.nv12.uv_stride;
+        dest += width;
+    }
+
+    QImage image(width, height, QImage::Format_RGB32);
+
+    unsigned char *dataPtr = data;
+    unsigned char *uvDataPtr = 0;
+    unsigned int uv_base_offset = width*height;
+    int yValue = 0;
+    int uValue = 0;
+    int vValue = 0;
+    int bValue = 0;
+    int gValue = 0;
+    int rValue = 0;
+    unsigned char *rowStart = 0;
+
+    unsigned char *imageDest = 0;
+    for (unsigned int y = 0; y < height; ++y) {
+        imageDest = const_cast<unsigned char*>(image.constScanLine(y));
+        rowStart = data + (uv_base_offset + (width*qFloor(y/2.0)));
+        for (unsigned int x = 0; x < width; ++x) {
+            uvDataPtr = rowStart + (qFloor(x/2)*2);
+
+            yValue = ((*dataPtr++) - 16) * 1.164;
+            uValue = ((*uvDataPtr++) - 128);
+            vValue = ((*uvDataPtr) - 128);
+
+            bValue = yValue + 2.018 * uValue;
+            gValue = yValue - 0.813 * vValue - 0.391 * uValue;
+            rValue = yValue + 1.596 * vValue;
+
+            *imageDest = qBound(0, bValue, 255);
+            imageDest++;
+            *imageDest = qBound(0, gValue, 255);
+            imageDest++;
+            *imageDest = qBound(0, rValue, 255);
+            imageDest++;
+            *imageDest = 255;
+            imageDest++;
+        }
+    }
+
+    delete [] data;
+
+    return image;
+}
+
+void BbCameraSession::handlePhotoViewFinderData(camera_buffer_t *buffer)
+{
+    QTransform transform;
+
+    transform.rotate(360 - m_nativeCameraOrientation);
+
+    const QImage frame = convertFrameToImage(buffer).transformed(transform);
+
+    QMutexLocker locker(&m_surfaceMutex);
+    if (m_surface) {
+        if (frame.size() != m_surface->surfaceFormat().frameSize()) {
+            m_surface->stop();
+            m_surface->start(QVideoSurfaceFormat(frame.size(), QVideoFrame::Format_RGB32));
+        }
+
+        QVideoFrame videoFrame(frame);
+
+        m_surface->present(videoFrame);
+    }
+}
+
+
+void BbCameraSession::handleVideoViewFinderData(camera_buffer_t *buffer)
+{
+    QTransform transform;
+
+    transform.rotate(360 - m_nativeCameraOrientation);
+
+    const QImage frame = convertFrameToImage(buffer).transformed(transform);
+
+    QMutexLocker locker(&m_surfaceMutex);
+    if (m_surface) {
+        if (frame.size() != m_surface->surfaceFormat().frameSize()) {
+            m_surface->stop();
+            m_surface->start(QVideoSurfaceFormat(frame.size(), QVideoFrame::Format_RGB32));
+        }
+
+        QVideoFrame videoFrame(frame);
+
+        m_surface->present(videoFrame);
+    }
+}
+
+void BbCameraSession::updateReadyForCapture()
+{
+    emit readyForCaptureChanged(isReadyForCapture());
+}
+
+void BbCameraSession::imageCaptured(int requestId, const QImage &image, const QString &fileName)
+{
+    // Generate snap preview as downscaled image
+    {
+        QSize previewSize = image.size();
+        int downScaleSteps = 0;
+        while (previewSize.width() > 800 && downScaleSteps < 8) {
+            previewSize.rwidth() /= 2;
+            previewSize.rheight() /= 2;
+            downScaleSteps++;
+        }
+
+        const QImage snapPreview = image.scaled(previewSize);
+
+        emit imageCaptured(requestId, snapPreview);
+    }
+
+    if (m_captureDestination & QCameraImageCapture::CaptureToBuffer) {
+        QVideoFrame frame(image);
+
+        emit imageAvailable(requestId, frame);
+    }
+
+    if (m_captureDestination & QCameraImageCapture::CaptureToFile) {
+        const QString actualFileName = m_mediaStorageLocation.generateFileName(fileName,
+                                                                               QCamera::CaptureStillImage,
+                                                                               QLatin1String("IMG_"),
+                                                                               QLatin1String("jpg"));
+
+        QFile file(actualFileName);
+        if (file.open(QFile::WriteOnly)) {
+            if (image.save(&file, "JPG")) {
+                emit imageSaved(requestId, actualFileName);
+            } else {
+                emit imageCaptureError(requestId, QCameraImageCapture::OutOfSpaceError, file.errorString());
+            }
+        } else {
+            const QString errorMessage = tr("Could not open destination file:\n%1").arg(actualFileName);
+            emit imageCaptureError(requestId, QCameraImageCapture::ResourceError, errorMessage);
+        }
+    }
+}
+
+void BbCameraSession::handleFocusStatusChanged(int value)
+{
+    const camera_focusstate_t focusState = static_cast<camera_focusstate_t>(value);
+
+    switch (focusState) {
+    case CAMERA_FOCUSSTATE_NONE:
+    case CAMERA_FOCUSSTATE_WAITING:
+        m_focusLockStatus = QCamera::Unlocked;
+        emit lockStatusChanged(QCamera::LockFocus, QCamera::Unlocked, QCamera::UserRequest);
+        break;
+    case CAMERA_FOCUSSTATE_SEARCHING:
+        m_focusLockStatus = QCamera::Searching;
+        emit lockStatusChanged(QCamera::LockFocus, QCamera::Searching, QCamera::UserRequest);
+        break;
+    case CAMERA_FOCUSSTATE_FAILED:
+        m_focusLockStatus = QCamera::Unlocked;
+        emit lockStatusChanged(QCamera::LockFocus, QCamera::Unlocked, QCamera::LockFailed);
+        break;
+    case CAMERA_FOCUSSTATE_LOCKED:
+        m_focusLockStatus = QCamera::Locked;
+        emit lockStatusChanged(QCamera::LockFocus, QCamera::Locked, QCamera::LockAcquired);
+        break;
+    case CAMERA_FOCUSSTATE_SCENECHANGE:
+        m_focusLockStatus = QCamera::Unlocked;
+        emit lockStatusChanged(QCamera::LockFocus, QCamera::Unlocked, QCamera::LockTemporaryLost);
+        break;
+    default:
+        break;
+    }
+}
+
+void BbCameraSession::handleVideoRecordingPaused()
+{
+    //TODO: implement once BB10 API supports pausing a video
+}
+
+void BbCameraSession::handleVideoRecordingResumed()
+{
+    if (m_videoStatus == QMediaRecorder::StartingStatus) {
+        m_videoStatus = QMediaRecorder::RecordingStatus;
+        emit videoStatusChanged(m_videoStatus);
+
+        m_videoRecordingDuration.restart();
+    }
+}
+
+void BbCameraSession::deviceOrientationChanged(int angle)
+{
+    if (m_handle != CAMERA_HANDLE_INVALID)
+        camera_set_device_orientation(m_handle, angle);
+}
+
+bool BbCameraSession::openCamera()
+{
+    if (m_handle != CAMERA_HANDLE_INVALID) // camera is already open
+        return true;
+
+    m_status = QCamera::LoadingStatus;
+    emit statusChanged(m_status);
+
+    camera_unit_t unit = CAMERA_UNIT_REAR;
+    if (m_device == cameraIdentifierFront())
+        unit = CAMERA_UNIT_FRONT;
+    else if (m_device == cameraIdentifierRear())
+        unit = CAMERA_UNIT_REAR;
+    else if (m_device == cameraIdentifierDesktop())
+        unit = CAMERA_UNIT_DESKTOP;
+
+    camera_error_t result = camera_open(unit, CAMERA_MODE_RW, &m_handle);
+    if (result != CAMERA_EOK) {
+        m_handle = CAMERA_HANDLE_INVALID;
+        m_status = QCamera::UnloadedStatus;
+        emit statusChanged(m_status);
+
+        qWarning() << "Unable to open camera:" << result;
+        emit error(QCamera::CameraError, tr("Unable to open camera"));
+        return false;
+    }
+
+    result = camera_get_native_orientation(m_handle, &m_nativeCameraOrientation);
+    if (result != CAMERA_EOK) {
+        qWarning() << "Unable to retrieve native camera orientation:" << result;
+        emit error(QCamera::CameraError, tr("Unable to retrieve native camera orientation"));
+        return false;
+    }
+
+    m_status = QCamera::LoadedStatus;
+    emit statusChanged(m_status);
+
+    return true;
+}
+
+void BbCameraSession::closeCamera()
+{
+    if (m_handle == CAMERA_HANDLE_INVALID) // camera is closed already
+        return;
+
+    m_status = QCamera::UnloadingStatus;
+    emit statusChanged(m_status);
+
+    const camera_error_t result = camera_close(m_handle);
+    if (result != CAMERA_EOK) {
+        m_status = QCamera::LoadedStatus;
+        emit statusChanged(m_status);
+
+        qWarning() << "Unable to close camera:" << result;
+        emit error(QCamera::CameraError, tr("Unable to close camera"));
+        return;
+    }
+
+    m_handle = CAMERA_HANDLE_INVALID;
+
+    m_status = QCamera::UnloadedStatus;
+    emit statusChanged(m_status);
+}
+
+static void photoViewFinderDataCallback(camera_handle_t handle, camera_buffer_t *buffer, void *context)
+{
+    Q_UNUSED(handle)
+
+    BbCameraSession *session = static_cast<BbCameraSession*>(context);
+    session->handlePhotoViewFinderData(buffer);
+}
+
+static void videoViewFinderDataCallback(camera_handle_t handle, camera_buffer_t *buffer, void *context)
+{
+    Q_UNUSED(handle)
+
+    BbCameraSession *session = static_cast<BbCameraSession*>(context);
+    session->handleVideoViewFinderData(buffer);
+}
+
+static void viewFinderStatusCallback(camera_handle_t handle, camera_devstatus_t status, uint16_t value, void *context)
+{
+    Q_UNUSED(handle)
+
+    if (status == CAMERA_STATUS_FOCUS_CHANGE) {
+        BbCameraSession *session = static_cast<BbCameraSession*>(context);
+        QMetaObject::invokeMethod(session, "handleFocusStatusChanged", Qt::QueuedConnection, Q_ARG(int, value));
+    }
+}
+
+bool BbCameraSession::startViewFinder()
+{
+    m_status = QCamera::StartingStatus;
+    emit statusChanged(m_status);
+
+    QSize viewfinderResolution;
+    camera_error_t result = CAMERA_EOK;
+    if (m_captureMode & QCamera::CaptureStillImage) {
+        result = camera_start_photo_viewfinder(m_handle, photoViewFinderDataCallback, viewFinderStatusCallback, this);
+        viewfinderResolution = currentViewfinderResolution(QCamera::CaptureStillImage);
+    } else if (m_captureMode & QCamera::CaptureVideo) {
+        result = camera_start_video_viewfinder(m_handle, videoViewFinderDataCallback, viewFinderStatusCallback, this);
+        viewfinderResolution = currentViewfinderResolution(QCamera::CaptureVideo);
+    }
+
+    if (result != CAMERA_EOK) {
+        qWarning() << "Unable to start viewfinder:" << result;
+        return false;
+    }
+
+    // retrieve information about lock apply modes
+    {
+        int supported = 0;
+        uint32_t modes[20];
+
+        const camera_error_t result = camera_get_3a_lock_modes(m_handle, 20, &supported, modes);
+
+        if (result == CAMERA_EOK) {
+            // see API documentation of camera_get_3a_lock_modes for explanation of case discrimination below
+            if (supported == 4) {
+                m_locksApplyMode = IndependentMode;
+            } else if (supported == 3) {
+                m_locksApplyMode = FocusExposureBoundMode;
+            } else if (supported == 2) {
+                if (modes[0] == (CAMERA_3A_AUTOFOCUS | CAMERA_3A_AUTOEXPOSURE | CAMERA_3A_AUTOWHITEBALANCE))
+                    m_locksApplyMode = AllBoundMode;
+                else
+                    m_locksApplyMode = FocusOnlyMode;
+            }
+        }
+    }
+
+    const int angle = m_orientationHandler->orientation();
+
+    const QSize rotatedSize = ((angle == 0 || angle == 180) ? viewfinderResolution
+                                                            : viewfinderResolution.transposed());
+
+    m_surfaceMutex.lock();
+    if (m_surface) {
+        const bool ok = m_surface->start(QVideoSurfaceFormat(rotatedSize, QVideoFrame::Format_RGB32));
+        if (!ok)
+            qWarning() << "Unable to start camera viewfinder surface";
+    }
+    m_surfaceMutex.unlock();
+
+    m_status = QCamera::ActiveStatus;
+    emit statusChanged(m_status);
+
+    return true;
+}
+
+void BbCameraSession::stopViewFinder()
+{
+    m_status = QCamera::StoppingStatus;
+    emit statusChanged(m_status);
+
+    m_surfaceMutex.lock();
+    if (m_surface) {
+        m_surface->stop();
+    }
+    m_surfaceMutex.unlock();
+
+    camera_error_t result = CAMERA_EOK;
+    if (m_captureMode & QCamera::CaptureStillImage)
+        result = camera_stop_photo_viewfinder(m_handle);
+    else if (m_captureMode & QCamera::CaptureVideo)
+        result = camera_stop_video_viewfinder(m_handle);
+
+    if (result != CAMERA_EOK) {
+        qWarning() << "Unable to stop viewfinder:" << result;
+        return;
+    }
+
+    m_status = QCamera::LoadedStatus;
+    emit statusChanged(m_status);
+}
+
+void BbCameraSession::applyConfiguration()
+{
+    if (m_captureMode & QCamera::CaptureStillImage) {
+        const QList<QSize> photoOutputResolutions = supportedResolutions(QCamera::CaptureStillImage);
+
+        if (!m_imageEncoderSettings.resolution().isValid() || !photoOutputResolutions.contains(m_imageEncoderSettings.resolution()))
+            m_imageEncoderSettings.setResolution(photoOutputResolutions.first());
+
+        const QSize photoResolution = m_imageEncoderSettings.resolution();
+        const qreal aspectRatio = static_cast<qreal>(photoResolution.width())/static_cast<qreal>(photoResolution.height());
+
+        // apply viewfinder configuration
+        QSize viewfinderResolution;
+        QList<QSize> sizes = supportedViewfinderResolutions(QCamera::CaptureStillImage);
+        std::reverse(sizes.begin(), sizes.end()); // use smallest possible resolution
+        foreach (const QSize &size, sizes) {
+            // search for viewfinder resolution with the same aspect ratio
+            if (qFuzzyCompare(aspectRatio, (static_cast<qreal>(size.width())/static_cast<qreal>(size.height())))) {
+                viewfinderResolution = size;
+                break;
+            }
+        }
+
+        Q_ASSERT(viewfinderResolution.isValid());
+
+        camera_error_t result = camera_set_photovf_property(m_handle,
+                                                            CAMERA_IMGPROP_WIDTH, viewfinderResolution.width(),
+                                                            CAMERA_IMGPROP_HEIGHT, viewfinderResolution.height(),
+                                                            CAMERA_IMGPROP_FORMAT, CAMERA_FRAMETYPE_NV12,
+                                                            CAMERA_IMGPROP_ROTATION, m_nativeCameraOrientation);
+
+        if (result != CAMERA_EOK) {
+            qWarning() << "Unable to apply photo viewfinder settings:" << result;
+            return;
+        }
+
+
+        int jpegQuality = 100;
+        switch (m_imageEncoderSettings.quality()) {
+        case QMultimedia::VeryLowQuality:
+            jpegQuality = 20;
+            break;
+        case QMultimedia::LowQuality:
+            jpegQuality = 40;
+            break;
+        case QMultimedia::NormalQuality:
+            jpegQuality = 60;
+            break;
+        case QMultimedia::HighQuality:
+            jpegQuality = 80;
+            break;
+        case QMultimedia::VeryHighQuality:
+            jpegQuality = 100;
+            break;
+        }
+
+        // apply photo configuration
+        result = camera_set_photo_property(m_handle,
+                                           CAMERA_IMGPROP_WIDTH, photoResolution.width(),
+                                           CAMERA_IMGPROP_HEIGHT, photoResolution.height(),
+                                           CAMERA_IMGPROP_JPEGQFACTOR, jpegQuality,
+                                           CAMERA_IMGPROP_ROTATION, m_nativeCameraOrientation);
+
+        if (result != CAMERA_EOK) {
+            qWarning() << "Unable to apply photo settings:" << result;
+            return;
+        }
+
+    } else if (m_captureMode & QCamera::CaptureVideo) {
+        const QList<QSize> videoOutputResolutions = supportedResolutions(QCamera::CaptureVideo);
+
+        if (!m_videoEncoderSettings.resolution().isValid() || !videoOutputResolutions.contains(m_videoEncoderSettings.resolution()))
+            m_videoEncoderSettings.setResolution(videoOutputResolutions.first());
+
+        const QSize videoResolution = m_videoEncoderSettings.resolution();
+        const qreal aspectRatio = static_cast<qreal>(videoResolution.width())/static_cast<qreal>(videoResolution.height());
+
+        // apply viewfinder configuration
+        QSize viewfinderResolution;
+        QList<QSize> sizes = supportedViewfinderResolutions(QCamera::CaptureVideo);
+        std::reverse(sizes.begin(), sizes.end()); // use smallest possible resolution
+        foreach (const QSize &size, sizes) {
+            // search for viewfinder resolution with the same aspect ratio
+            if (qFuzzyCompare(aspectRatio, (static_cast<qreal>(size.width())/static_cast<qreal>(size.height())))) {
+                viewfinderResolution = size;
+                break;
+            }
+        }
+
+        Q_ASSERT(viewfinderResolution.isValid());
+
+        const camera_error_t result = camera_set_videovf_property(m_handle,
+                                                                  CAMERA_IMGPROP_WIDTH, viewfinderResolution.width(),
+                                                                  CAMERA_IMGPROP_HEIGHT, viewfinderResolution.height(),
+                                                                  CAMERA_IMGPROP_ROTATION, m_nativeCameraOrientation);
+
+        if (result != CAMERA_EOK) {
+            qWarning() << "Unable to apply video viewfinder settings:" << result;
+            return;
+        }
+
+        applySettings();
+    }
+}
+
+static void videoRecordingStatusCallback(camera_handle_t handle, camera_devstatus_t status, uint16_t value, void *context)
+{
+    Q_UNUSED(handle)
+    Q_UNUSED(value)
+
+    if (status == CAMERA_STATUS_VIDEO_PAUSE) {
+        BbCameraSession *session = static_cast<BbCameraSession*>(context);
+        QMetaObject::invokeMethod(session, "handleVideoRecordingPaused", Qt::QueuedConnection);
+    } else if (status == CAMERA_STATUS_VIDEO_RESUME) {
+        BbCameraSession *session = static_cast<BbCameraSession*>(context);
+        QMetaObject::invokeMethod(session, "handleVideoRecordingResumed", Qt::QueuedConnection);
+    }
+}
+
+bool BbCameraSession::startVideoRecording()
+{
+    m_videoRecordingDuration.invalidate();
+
+    m_videoStatus = QMediaRecorder::StartingStatus;
+    emit videoStatusChanged(m_videoStatus);
+
+    if (m_videoOutputLocation.isEmpty())
+        m_videoOutputLocation = m_mediaStorageLocation.generateFileName(QLatin1String("VID_"), m_mediaStorageLocation.defaultDir(QCamera::CaptureVideo), QLatin1String("mp4"));
+
+    emit actualLocationChanged(m_videoOutputLocation);
+
+    const camera_error_t result = camera_start_video(m_handle, QFile::encodeName(m_videoOutputLocation), 0, videoRecordingStatusCallback, this);
+    if (result != CAMERA_EOK) {
+        m_videoStatus = QMediaRecorder::LoadedStatus;
+        emit videoStatusChanged(m_videoStatus);
+
+        emit videoError(QMediaRecorder::ResourceError, tr("Unable to start video recording"));
+        return false;
+    }
+
+    return true;
+}
+
+void BbCameraSession::stopVideoRecording()
+{
+    m_videoStatus = QMediaRecorder::FinalizingStatus;
+    emit videoStatusChanged(m_videoStatus);
+
+    const camera_error_t result = camera_stop_video(m_handle);
+    if (result != CAMERA_EOK) {
+        emit videoError(QMediaRecorder::ResourceError, tr("Unable to stop video recording"));
+    }
+
+    m_videoStatus = QMediaRecorder::LoadedStatus;
+    emit videoStatusChanged(m_videoStatus);
+
+    m_videoRecordingDuration.invalidate();
+}
+
+bool BbCameraSession::isCaptureModeSupported(camera_handle_t handle, QCamera::CaptureModes mode) const
+{
+    if (mode & QCamera::CaptureStillImage)
+        return camera_has_feature(handle, CAMERA_FEATURE_PHOTO);
+
+    if (mode & QCamera::CaptureVideo)
+        return camera_has_feature(handle, CAMERA_FEATURE_VIDEO);
+
+    return false;
+}
+
+QList<QSize> BbCameraSession::supportedResolutions(QCamera::CaptureMode mode) const
+{
+    Q_ASSERT(m_handle != CAMERA_HANDLE_INVALID);
+
+    QList<QSize> list;
+
+    camera_error_t result = CAMERA_EOK;
+    camera_res_t resolutions[20];
+    unsigned int supported = 0;
+
+    if (mode == QCamera::CaptureStillImage)
+        result = camera_get_photo_output_resolutions(m_handle, CAMERA_FRAMETYPE_JPEG, 20, &supported, resolutions);
+    else if (mode == QCamera::CaptureVideo)
+        result = camera_get_video_output_resolutions(m_handle, 20, &supported, resolutions);
+
+    if (result != CAMERA_EOK)
+        return list;
+
+    for (unsigned int i = 0; i < supported; ++i)
+        list << QSize(resolutions[i].width, resolutions[i].height);
+
+    return list;
+}
+
+QList<QSize> BbCameraSession::supportedViewfinderResolutions(QCamera::CaptureMode mode) const
+{
+    Q_ASSERT(m_handle != CAMERA_HANDLE_INVALID);
+
+    QList<QSize> list;
+
+    camera_error_t result = CAMERA_EOK;
+    camera_res_t resolutions[20];
+    unsigned int supported = 0;
+
+    if (mode == QCamera::CaptureStillImage)
+        result = camera_get_photo_vf_resolutions(m_handle, 20, &supported, resolutions);
+    else if (mode == QCamera::CaptureVideo)
+        result = camera_get_video_vf_resolutions(m_handle, 20, &supported, resolutions);
+
+    if (result != CAMERA_EOK)
+        return list;
+
+    for (unsigned int i = 0; i < supported; ++i)
+        list << QSize(resolutions[i].width, resolutions[i].height);
+
+    return list;
+}
+
+QSize BbCameraSession::currentViewfinderResolution(QCamera::CaptureMode mode) const
+{
+    Q_ASSERT(m_handle != CAMERA_HANDLE_INVALID);
+
+    camera_error_t result = CAMERA_EOK;
+    int width = 0;
+    int height = 0;
+
+    if (mode == QCamera::CaptureStillImage)
+        result = camera_get_photovf_property(m_handle, CAMERA_IMGPROP_WIDTH, &width,
+                                                       CAMERA_IMGPROP_HEIGHT, &height);
+    else if (mode == QCamera::CaptureVideo)
+        result = camera_get_videovf_property(m_handle, CAMERA_IMGPROP_WIDTH, &width,
+                                                       CAMERA_IMGPROP_HEIGHT, &height);
+
+    if (result != CAMERA_EOK)
+        return QSize();
+
+    return QSize(width, height);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/blackberry/camera/bbcamerasession.h b/src/plugins/blackberry/camera/bbcamerasession.h
new file mode 100644 (file)
index 0000000..647e324
--- /dev/null
@@ -0,0 +1,234 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.  For licensing terms and
+** conditions see http://qt.digia.com/licensing.  For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 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, Digia gives you certain additional
+** rights.  These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef BBCAMERASESSION_H
+#define BBCAMERASESSION_H
+
+#include "bbmediastoragelocation.h"
+
+#include <QCamera>
+#include <QCameraImageCapture>
+#include <QCameraViewfinderSettingsControl>
+#include <QElapsedTimer>
+#include <QMediaRecorder>
+#include <QMutex>
+#include <QObject>
+#include <QPointer>
+
+#include <camera/camera_api.h>
+
+QT_BEGIN_NAMESPACE
+
+class BbCameraOrientationHandler;
+
+class BbCameraSession : public QObject
+{
+    Q_OBJECT
+public:
+    explicit BbCameraSession(QObject *parent = 0);
+    ~BbCameraSession();
+
+    camera_handle_t handle() const;
+
+    // camera control
+    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;
+
+    // video device selector control
+    static QByteArray cameraIdentifierFront();
+    static QByteArray cameraIdentifierRear();
+    static QByteArray cameraIdentifierDesktop();
+
+    void setDevice(const QByteArray &device);
+    QByteArray device() const;
+
+    // video renderer control
+    QAbstractVideoSurface *surface() const;
+    void setSurface(QAbstractVideoSurface *surface);
+
+    // image capture control
+    bool isReadyForCapture() const;
+    QCameraImageCapture::DriveMode driveMode() const;
+    void setDriveMode(QCameraImageCapture::DriveMode mode);
+    int capture(const QString &fileName);
+    void cancelCapture();
+
+    // capture destination control
+    bool isCaptureDestinationSupported(QCameraImageCapture::CaptureDestinations destination) const;
+    QCameraImageCapture::CaptureDestinations captureDestination() const;
+    void setCaptureDestination(QCameraImageCapture::CaptureDestinations destination);
+
+    // image encoder control
+    QList<QSize> supportedResolutions(const QImageEncoderSettings &settings, bool *continuous) const;
+    QImageEncoderSettings imageSettings() const;
+    void setImageSettings(const QImageEncoderSettings &settings);
+
+    // locks control
+    enum LocksApplyMode
+    {
+        IndependentMode,
+        FocusExposureBoundMode,
+        AllBoundMode,
+        FocusOnlyMode
+    };
+
+    QCamera::LockTypes supportedLocks() const;
+    QCamera::LockStatus lockStatus(QCamera::LockType lock) const;
+    void searchAndLock(QCamera::LockTypes locks);
+    void unlock(QCamera::LockTypes locks);
+
+    // media recorder control
+    QUrl outputLocation() const;
+    bool setOutputLocation(const QUrl &location);
+    QMediaRecorder::State videoState() const;
+    void setVideoState(QMediaRecorder::State state);
+    QMediaRecorder::Status videoStatus() const;
+    qint64 duration() const;
+    void applySettings();
+
+    // video encoder settings control
+    QList<QSize> supportedResolutions(const QVideoEncoderSettings &settings, bool *continuous) const;
+    QList<qreal> supportedFrameRates(const QVideoEncoderSettings &settings, bool *continuous) const;
+    QVideoEncoderSettings videoSettings() const;
+    void setVideoSettings(const QVideoEncoderSettings &settings);
+
+    // audio encoder settings control
+    QAudioEncoderSettings audioSettings() const;
+    void setAudioSettings(const QAudioEncoderSettings &settings);
+
+    // methods invoked from BB10 camera API callbacks in separated thread
+    void handlePhotoViewFinderData(camera_buffer_t*);
+    void handleVideoViewFinderData(camera_buffer_t*);
+
+Q_SIGNALS:
+    // camera control
+    void statusChanged(QCamera::Status);
+    void stateChanged(QCamera::State);
+    void error(int error, const QString &errorString);
+    void captureModeChanged(QCamera::CaptureModes);
+
+    // image capture control
+    void readyForCaptureChanged(bool);
+    void imageExposed(int id);
+    void imageCaptured(int id, const QImage &preview);
+    void imageMetadataAvailable(int id, const QString &key, const QVariant &value);
+    void imageAvailable(int id, const QVideoFrame &buffer);
+    void imageSaved(int id, const QString &fileName);
+    void imageCaptureError(int id, int error, const QString &errorString);
+
+    // capture destination control
+    void captureDestinationChanged(QCameraImageCapture::CaptureDestinations destination);
+
+    // locks control
+    void lockStatusChanged(QCamera::LockType type, QCamera::LockStatus status, QCamera::LockChangeReason reason);
+
+    // media recorder control
+    void videoStateChanged(QMediaRecorder::State state);
+    void videoStatusChanged(QMediaRecorder::Status status);
+    void durationChanged(qint64 duration);
+    void actualLocationChanged(const QUrl &location);
+    void videoError(int error, const QString &errorString);
+
+private slots:
+    void updateReadyForCapture();
+    void imageCaptured(int, const QImage&, const QString&);
+    void handleFocusStatusChanged(int);
+    void handleVideoRecordingPaused();
+    void handleVideoRecordingResumed();
+    void deviceOrientationChanged(int);
+
+private:
+    bool openCamera();
+    void closeCamera();
+    bool startViewFinder();
+    void stopViewFinder();
+    void applyConfiguration();
+    bool startVideoRecording();
+    void stopVideoRecording();
+
+    bool isCaptureModeSupported(camera_handle_t handle, QCamera::CaptureModes mode) const;
+    QList<QSize> supportedResolutions(QCamera::CaptureMode mode) const;
+    QList<QSize> supportedViewfinderResolutions(QCamera::CaptureMode mode) const;
+    QSize currentViewfinderResolution(QCamera::CaptureMode mode) const;
+
+    quint32 m_nativeCameraOrientation;
+    BbCameraOrientationHandler* m_orientationHandler;
+
+    QCamera::Status m_status;
+    QCamera::State m_state;
+    QCamera::CaptureModes m_captureMode;
+
+    QByteArray m_device;
+
+    QPointer<QAbstractVideoSurface> m_surface;
+    QMutex m_surfaceMutex;
+
+    QCameraImageCapture::DriveMode m_captureImageDriveMode;
+    int m_lastImageCaptureId;
+    QCameraImageCapture::CaptureDestinations m_captureDestination;
+
+    QImageEncoderSettings m_imageEncoderSettings;
+
+    LocksApplyMode m_locksApplyMode;
+    QCamera::LockStatus m_focusLockStatus;
+    QCamera::LockTypes m_currentLockTypes;
+
+    QString m_videoOutputLocation;
+    QMediaRecorder::State m_videoState;
+    QMediaRecorder::Status m_videoStatus;
+    QElapsedTimer m_videoRecordingDuration;
+
+    QVideoEncoderSettings m_videoEncoderSettings;
+    QAudioEncoderSettings m_audioEncoderSettings;
+
+    BbMediaStorageLocation m_mediaStorageLocation;
+
+    camera_handle_t m_handle;
+};
+
+QDebug operator<<(QDebug debug, camera_error_t error);
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/blackberry/camera/bbcameravideoencodersettingscontrol.cpp b/src/plugins/blackberry/camera/bbcameravideoencodersettingscontrol.cpp
new file mode 100644 (file)
index 0000000..eae448e
--- /dev/null
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.  For licensing terms and
+** conditions see http://qt.digia.com/licensing.  For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 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, Digia gives you certain additional
+** rights.  These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "bbcameravideoencodersettingscontrol.h"
+
+#include "bbcamerasession.h"
+
+QT_BEGIN_NAMESPACE
+
+BbCameraVideoEncoderSettingsControl::BbCameraVideoEncoderSettingsControl(BbCameraSession *session, QObject *parent)
+    : QVideoEncoderSettingsControl(parent)
+    , m_session(session)
+{
+}
+
+QList<QSize> BbCameraVideoEncoderSettingsControl::supportedResolutions(const QVideoEncoderSettings &settings, bool *continuous) const
+{
+    return m_session->supportedResolutions(settings, continuous);
+}
+
+QList<qreal> BbCameraVideoEncoderSettingsControl::supportedFrameRates(const QVideoEncoderSettings &settings, bool *continuous) const
+{
+    return m_session->supportedFrameRates(settings, continuous);
+}
+
+QStringList BbCameraVideoEncoderSettingsControl::supportedVideoCodecs() const
+{
+    return QStringList() << QLatin1String("none") << QLatin1String("avc1") << QLatin1String("h264");
+}
+
+QString BbCameraVideoEncoderSettingsControl::videoCodecDescription(const QString &codecName) const
+{
+    if (codecName == QLatin1String("none"))
+        return tr("No compression");
+    else if (codecName == QLatin1String("avc1"))
+        return tr("AVC1 compression");
+    else if (codecName == QLatin1String("h264"))
+        return tr("H264 compression");
+
+    return QString();
+}
+
+QVideoEncoderSettings BbCameraVideoEncoderSettingsControl::videoSettings() const
+{
+    return m_session->videoSettings();
+}
+
+void BbCameraVideoEncoderSettingsControl::setVideoSettings(const QVideoEncoderSettings &settings)
+{
+    m_session->setVideoSettings(settings);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/blackberry/camera/bbcameravideoencodersettingscontrol.h b/src/plugins/blackberry/camera/bbcameravideoencodersettingscontrol.h
new file mode 100644 (file)
index 0000000..8ecf49c
--- /dev/null
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.  For licensing terms and
+** conditions see http://qt.digia.com/licensing.  For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 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, Digia gives you certain additional
+** rights.  These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef BBCAMERAVIDEOENCODERSETTINGSCONTROL_H
+#define BBCAMERAVIDEOENCODERSETTINGSCONTROL_H
+
+#include <qvideoencodersettingscontrol.h>
+
+QT_BEGIN_NAMESPACE
+
+class BbCameraSession;
+
+class BbCameraVideoEncoderSettingsControl : public QVideoEncoderSettingsControl
+{
+    Q_OBJECT
+public:
+    explicit BbCameraVideoEncoderSettingsControl(BbCameraSession *session, QObject *parent = 0);
+
+    QList<QSize> supportedResolutions(const QVideoEncoderSettings &settings, bool *continuous = 0) const Q_DECL_OVERRIDE;
+    QList<qreal> supportedFrameRates(const QVideoEncoderSettings &settings, bool *continuous = 0) const Q_DECL_OVERRIDE;
+    QStringList supportedVideoCodecs() const Q_DECL_OVERRIDE;
+    QString videoCodecDescription(const QString &codecName) const Q_DECL_OVERRIDE;
+    QVideoEncoderSettings videoSettings() const Q_DECL_OVERRIDE;
+    void setVideoSettings(const QVideoEncoderSettings &settings) Q_DECL_OVERRIDE;
+
+private:
+    BbCameraSession *m_session;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/blackberry/camera/bbcameraviewfindersettingscontrol.cpp b/src/plugins/blackberry/camera/bbcameraviewfindersettingscontrol.cpp
new file mode 100644 (file)
index 0000000..a63d7a7
--- /dev/null
@@ -0,0 +1,247 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.  For licensing terms and
+** conditions see http://qt.digia.com/licensing.  For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 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, Digia gives you certain additional
+** rights.  These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "bbcameraviewfindersettingscontrol.h"
+
+#include "bbcamerasession.h"
+
+#include <QDebug>
+
+QT_BEGIN_NAMESPACE
+
+BbCameraViewfinderSettingsControl::BbCameraViewfinderSettingsControl(BbCameraSession *session, QObject *parent)
+    : QCameraViewfinderSettingsControl(parent)
+    , m_session(session)
+{
+}
+
+bool BbCameraViewfinderSettingsControl::isViewfinderParameterSupported(ViewfinderParameter parameter) const
+{
+    switch (parameter) {
+    case QCameraViewfinderSettingsControl::Resolution:
+        return true;
+    case QCameraViewfinderSettingsControl::PixelAspectRatio:
+        return false;
+    case QCameraViewfinderSettingsControl::MinimumFrameRate:
+        return true;
+    case QCameraViewfinderSettingsControl::MaximumFrameRate:
+        return true;
+    case QCameraViewfinderSettingsControl::PixelFormat:
+        return true;
+    default:
+        return false;
+    }
+}
+
+QVariant BbCameraViewfinderSettingsControl::viewfinderParameter(ViewfinderParameter parameter) const
+{
+    if (parameter == QCameraViewfinderSettingsControl::Resolution) {
+        camera_error_t result = CAMERA_EOK;
+        unsigned int width = 0;
+        unsigned int height = 0;
+
+        if (m_session->captureMode() & QCamera::CaptureStillImage) {
+            result = camera_get_photovf_property(m_session->handle(), CAMERA_IMGPROP_WIDTH, &width,
+                                                                      CAMERA_IMGPROP_HEIGHT, &height);
+        } else if (m_session->captureMode() & QCamera::CaptureVideo) {
+            result = camera_get_videovf_property(m_session->handle(), CAMERA_IMGPROP_WIDTH, &width,
+                                                                      CAMERA_IMGPROP_HEIGHT, &height);
+        }
+
+        if (result != CAMERA_EOK) {
+            qWarning() << "Unable to retrieve resolution of viewfinder:" << result;
+            return QVariant();
+        }
+
+        return QSize(width, height);
+
+    } else if (parameter == QCameraViewfinderSettingsControl::MinimumFrameRate) {
+        camera_error_t result = CAMERA_EOK;
+        double minimumFrameRate = 0;
+
+        if (m_session->captureMode() & QCamera::CaptureStillImage)
+            result = camera_get_photovf_property(m_session->handle(), CAMERA_IMGPROP_MINFRAMERATE, &minimumFrameRate);
+        else if (m_session->captureMode() & QCamera::CaptureVideo)
+            result = camera_get_videovf_property(m_session->handle(), CAMERA_IMGPROP_MINFRAMERATE, &minimumFrameRate);
+
+        if (result != CAMERA_EOK) {
+            qWarning() << "Unable to retrieve minimum framerate of viewfinder:" << result;
+            return QVariant();
+        }
+
+        return QVariant(static_cast<qreal>(minimumFrameRate));
+
+    } else if (parameter == QCameraViewfinderSettingsControl::MaximumFrameRate) {
+        camera_error_t result = CAMERA_EOK;
+        double maximumFrameRate = 0;
+
+        if (m_session->captureMode() & QCamera::CaptureStillImage)
+            result = camera_get_photovf_property(m_session->handle(), CAMERA_IMGPROP_FRAMERATE, &maximumFrameRate);
+        else if (m_session->captureMode() & QCamera::CaptureVideo)
+            result = camera_get_videovf_property(m_session->handle(), CAMERA_IMGPROP_FRAMERATE, &maximumFrameRate);
+
+        if (result != CAMERA_EOK) {
+            qWarning() << "Unable to retrieve maximum framerate of viewfinder:" << result;
+            return QVariant();
+        }
+
+        return QVariant(static_cast<qreal>(maximumFrameRate));
+    } else if (parameter == QCameraViewfinderSettingsControl::PixelFormat) {
+        camera_error_t result = CAMERA_EOK;
+        camera_frametype_t format = CAMERA_FRAMETYPE_UNSPECIFIED;
+
+        if (m_session->captureMode() & QCamera::CaptureStillImage)
+            result = camera_get_photovf_property(m_session->handle(), CAMERA_IMGPROP_FORMAT, &format);
+        else if (m_session->captureMode() & QCamera::CaptureVideo)
+            result = camera_get_videovf_property(m_session->handle(), CAMERA_IMGPROP_FORMAT, &format);
+
+        if (result != CAMERA_EOK) {
+            qWarning() << "Unable to retrieve pixel format of viewfinder:" << result;
+            return QVariant();
+        }
+
+        switch (format) {
+        case CAMERA_FRAMETYPE_UNSPECIFIED:
+            return QVideoFrame::Format_Invalid;
+        case CAMERA_FRAMETYPE_NV12:
+            return QVideoFrame::Format_NV12;
+        case CAMERA_FRAMETYPE_RGB8888:
+            return QVideoFrame::Format_ARGB32;
+        case CAMERA_FRAMETYPE_RGB888:
+            return QVideoFrame::Format_RGB24;
+        case CAMERA_FRAMETYPE_JPEG:
+            return QVideoFrame::Format_Jpeg;
+        case CAMERA_FRAMETYPE_GRAY8:
+            return QVideoFrame::Format_Y8;
+        case CAMERA_FRAMETYPE_METADATA:
+            return QVideoFrame::Format_Invalid;
+        case CAMERA_FRAMETYPE_BAYER:
+            return QVideoFrame::Format_Invalid;
+        case CAMERA_FRAMETYPE_CBYCRY:
+            return QVideoFrame::Format_Invalid;
+        case CAMERA_FRAMETYPE_COMPRESSEDVIDEO:
+            return QVideoFrame::Format_Invalid;
+        case CAMERA_FRAMETYPE_COMPRESSEDAUDIO:
+            return QVideoFrame::Format_Invalid;
+        default:
+            return QVideoFrame::Format_Invalid;
+        }
+    }
+
+    return QVariant();
+}
+
+void BbCameraViewfinderSettingsControl::setViewfinderParameter(ViewfinderParameter parameter, const QVariant &value)
+{
+    if (parameter == QCameraViewfinderSettingsControl::Resolution) {
+        camera_error_t result = CAMERA_EOK;
+        const QSize size = value.toSize();
+
+        if (m_session->captureMode() & QCamera::CaptureStillImage) {
+            result = camera_set_photovf_property(m_session->handle(), CAMERA_IMGPROP_WIDTH, size.width(),
+                                                                      CAMERA_IMGPROP_HEIGHT, size.height());
+        } else if (m_session->captureMode() & QCamera::CaptureVideo) {
+            result = camera_set_videovf_property(m_session->handle(), CAMERA_IMGPROP_WIDTH, size.width(),
+                                                                      CAMERA_IMGPROP_HEIGHT, size.height());
+        }
+
+        if (result != CAMERA_EOK)
+            qWarning() << "Unable to set resolution of viewfinder:" << result;
+
+    } else if (parameter == QCameraViewfinderSettingsControl::MinimumFrameRate) {
+        camera_error_t result = CAMERA_EOK;
+        const double minimumFrameRate = value.toReal();
+
+        if (m_session->captureMode() & QCamera::CaptureStillImage)
+            result = camera_set_photovf_property(m_session->handle(), CAMERA_IMGPROP_MINFRAMERATE, minimumFrameRate);
+        else if (m_session->captureMode() & QCamera::CaptureVideo)
+            result = camera_set_videovf_property(m_session->handle(), CAMERA_IMGPROP_MINFRAMERATE, minimumFrameRate);
+
+        if (result != CAMERA_EOK)
+            qWarning() << "Unable to set minimum framerate of viewfinder:" << result;
+
+    } else if (parameter == QCameraViewfinderSettingsControl::MaximumFrameRate) {
+        camera_error_t result = CAMERA_EOK;
+        const double maximumFrameRate = value.toReal();
+
+        if (m_session->captureMode() & QCamera::CaptureStillImage)
+            result = camera_set_photovf_property(m_session->handle(), CAMERA_IMGPROP_FRAMERATE, maximumFrameRate);
+        else if (m_session->captureMode() & QCamera::CaptureVideo)
+            result = camera_set_videovf_property(m_session->handle(), CAMERA_IMGPROP_FRAMERATE, maximumFrameRate);
+
+        if (result != CAMERA_EOK)
+            qWarning() << "Unable to set maximum framerate of viewfinder:" << result;
+
+    } else if (parameter == QCameraViewfinderSettingsControl::PixelFormat) {
+        camera_error_t result = CAMERA_EOK;
+        camera_frametype_t format = CAMERA_FRAMETYPE_UNSPECIFIED;
+
+        switch (value.value<QVideoFrame::PixelFormat>()) {
+        case QVideoFrame::Format_NV12:
+            format = CAMERA_FRAMETYPE_NV12;
+            break;
+        case QVideoFrame::Format_ARGB32:
+            format = CAMERA_FRAMETYPE_RGB8888;
+            break;
+        case QVideoFrame::Format_RGB24:
+            format = CAMERA_FRAMETYPE_RGB888;
+            break;
+        case QVideoFrame::Format_Jpeg:
+            format = CAMERA_FRAMETYPE_JPEG;
+            break;
+        case QVideoFrame::Format_Y8:
+            format = CAMERA_FRAMETYPE_GRAY8;
+            break;
+        default:
+            format = CAMERA_FRAMETYPE_UNSPECIFIED;
+            break;
+        }
+
+        if (m_session->captureMode() & QCamera::CaptureStillImage)
+            result = camera_set_photovf_property(m_session->handle(), CAMERA_IMGPROP_FORMAT, format);
+        else if (m_session->captureMode() & QCamera::CaptureVideo)
+            result = camera_set_videovf_property(m_session->handle(), CAMERA_IMGPROP_FORMAT, format);
+
+        if (result != CAMERA_EOK)
+            qWarning() << "Unable to set pixel format of viewfinder:" << result;
+    }
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/blackberry/camera/bbcameraviewfindersettingscontrol.h b/src/plugins/blackberry/camera/bbcameraviewfindersettingscontrol.h
new file mode 100644 (file)
index 0000000..f1434c3
--- /dev/null
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.  For licensing terms and
+** conditions see http://qt.digia.com/licensing.  For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 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, Digia gives you certain additional
+** rights.  These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef BBCAMERAVIEWVINDERSETTINGSCONTROL_H
+#define BBCAMERAVIEWVINDERSETTINGSCONTROL_H
+
+#include <qcameraviewfindersettingscontrol.h>
+
+QT_BEGIN_NAMESPACE
+
+class BbCameraSession;
+
+class BbCameraViewfinderSettingsControl : public QCameraViewfinderSettingsControl
+{
+    Q_OBJECT
+public:
+    explicit BbCameraViewfinderSettingsControl(BbCameraSession *session, QObject *parent = 0);
+
+    bool isViewfinderParameterSupported(ViewfinderParameter parameter) const Q_DECL_OVERRIDE;
+    QVariant viewfinderParameter(ViewfinderParameter parameter) const Q_DECL_OVERRIDE;
+    void setViewfinderParameter(ViewfinderParameter parameter, const QVariant &value) Q_DECL_OVERRIDE;
+
+private:
+    BbCameraSession *m_session;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/blackberry/camera/bbcamerazoomcontrol.cpp b/src/plugins/blackberry/camera/bbcamerazoomcontrol.cpp
new file mode 100644 (file)
index 0000000..f73cf00
--- /dev/null
@@ -0,0 +1,157 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.  For licensing terms and
+** conditions see http://qt.digia.com/licensing.  For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 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, Digia gives you certain additional
+** rights.  These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "bbcamerazoomcontrol.h"
+
+#include "bbcamerasession.h"
+
+#include <QDebug>
+
+QT_BEGIN_NAMESPACE
+
+BbCameraZoomControl::BbCameraZoomControl(BbCameraSession *session, QObject *parent)
+    : QCameraZoomControl(parent)
+    , m_session(session)
+    , m_minimumZoomFactor(1.0)
+    , m_maximumZoomFactor(1.0)
+    , m_supportsSmoothZoom(false)
+    , m_requestedZoomFactor(1.0)
+{
+    connect(m_session, SIGNAL(statusChanged(QCamera::Status)), this, SLOT(statusChanged(QCamera::Status)));
+}
+
+qreal BbCameraZoomControl::maximumOpticalZoom() const
+{
+    //TODO: optical zoom support not available in BB10 API yet
+    return 1.0;
+}
+
+qreal BbCameraZoomControl::maximumDigitalZoom() const
+{
+    return m_maximumZoomFactor;
+}
+
+qreal BbCameraZoomControl::requestedOpticalZoom() const
+{
+    //TODO: optical zoom support not available in BB10 API yet
+    return 1.0;
+}
+
+qreal BbCameraZoomControl::requestedDigitalZoom() const
+{
+    return currentDigitalZoom();
+}
+
+qreal BbCameraZoomControl::currentOpticalZoom() const
+{
+    //TODO: optical zoom support not available in BB10 API yet
+    return 1.0;
+}
+
+qreal BbCameraZoomControl::currentDigitalZoom() const
+{
+    if (m_session->status() != QCamera::ActiveStatus)
+        return 1.0;
+
+    unsigned int zoomFactor = 0;
+    camera_error_t result = CAMERA_EOK;
+
+    if (m_session->captureMode() & QCamera::CaptureStillImage)
+        result = camera_get_photovf_property(m_session->handle(), CAMERA_IMGPROP_ZOOMFACTOR, &zoomFactor);
+    else if (m_session->captureMode() & QCamera::CaptureVideo)
+        result = camera_get_videovf_property(m_session->handle(), CAMERA_IMGPROP_ZOOMFACTOR, &zoomFactor);
+
+    if (result != CAMERA_EOK)
+        return 1.0;
+
+    return zoomFactor;
+}
+
+void BbCameraZoomControl::zoomTo(qreal optical, qreal digital)
+{
+    Q_UNUSED(optical)
+
+    if (m_session->status() != QCamera::ActiveStatus)
+        return;
+
+    const qreal actualZoom = qBound(m_minimumZoomFactor, digital, m_maximumZoomFactor);
+
+    const camera_error_t result = camera_set_zoom(m_session->handle(), actualZoom, false);
+
+    if (result != CAMERA_EOK) {
+        qWarning() << "Unable to change zoom factor:" << result;
+        return;
+    }
+
+    if (m_requestedZoomFactor != digital) {
+        m_requestedZoomFactor = digital;
+        emit requestedDigitalZoomChanged(m_requestedZoomFactor);
+    }
+
+    emit currentDigitalZoomChanged(actualZoom);
+}
+
+void BbCameraZoomControl::statusChanged(QCamera::Status status)
+{
+    if (status == QCamera::ActiveStatus) {
+        // retrieve information about zoom limits
+        unsigned int maximumZoomLimit = 0;
+        unsigned int minimumZoomLimit = 0;
+        bool smoothZoom = false;
+
+        const camera_error_t result = camera_get_zoom_limits(m_session->handle(), &maximumZoomLimit, &minimumZoomLimit, &smoothZoom);
+        if (result == CAMERA_EOK) {
+            const qreal oldMaximumZoomFactor = m_maximumZoomFactor;
+            m_maximumZoomFactor = maximumZoomLimit;
+
+            if (oldMaximumZoomFactor != m_maximumZoomFactor)
+                emit maximumDigitalZoomChanged(m_maximumZoomFactor);
+
+            m_minimumZoomFactor = minimumZoomLimit;
+            m_supportsSmoothZoom = smoothZoom;
+        } else {
+            m_maximumZoomFactor = 1.0;
+            m_minimumZoomFactor = 1.0;
+            m_supportsSmoothZoom = false;
+        }
+    }
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/blackberry/camera/bbcamerazoomcontrol.h b/src/plugins/blackberry/camera/bbcamerazoomcontrol.h
new file mode 100644 (file)
index 0000000..a1fecab
--- /dev/null
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.  For licensing terms and
+** conditions see http://qt.digia.com/licensing.  For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 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, Digia gives you certain additional
+** rights.  These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef BBCAMERAZOOMCONTROL_H
+#define BBCAMERAZOOMCONTROL_H
+
+#include <qcamera.h>
+#include <qcamerazoomcontrol.h>
+
+QT_BEGIN_NAMESPACE
+
+class BbCameraSession;
+
+class BbCameraZoomControl : public QCameraZoomControl
+{
+    Q_OBJECT
+public:
+    explicit BbCameraZoomControl(BbCameraSession *session, QObject *parent = 0);
+
+    qreal maximumOpticalZoom() const Q_DECL_OVERRIDE;
+    qreal maximumDigitalZoom() const Q_DECL_OVERRIDE;
+    qreal requestedOpticalZoom() const Q_DECL_OVERRIDE;
+    qreal requestedDigitalZoom() const Q_DECL_OVERRIDE;
+    qreal currentOpticalZoom() const Q_DECL_OVERRIDE;
+    qreal currentDigitalZoom() const Q_DECL_OVERRIDE;
+    void zoomTo(qreal optical, qreal digital) Q_DECL_OVERRIDE;
+
+private Q_SLOTS:
+    void statusChanged(QCamera::Status status);
+
+private:
+    BbCameraSession *m_session;
+
+    qreal m_minimumZoomFactor;
+    qreal m_maximumZoomFactor;
+    bool m_supportsSmoothZoom;
+    qreal m_requestedZoomFactor;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/blackberry/camera/bbimageencodercontrol.cpp b/src/plugins/blackberry/camera/bbimageencodercontrol.cpp
new file mode 100644 (file)
index 0000000..1265b9c
--- /dev/null
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.  For licensing terms and
+** conditions see http://qt.digia.com/licensing.  For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 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, Digia gives you certain additional
+** rights.  These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "bbimageencodercontrol.h"
+
+#include "bbcamerasession.h"
+
+QT_BEGIN_NAMESPACE
+
+BbImageEncoderControl::BbImageEncoderControl(BbCameraSession *session, QObject *parent)
+    : QImageEncoderControl(parent)
+    , m_session(session)
+{
+}
+
+QStringList BbImageEncoderControl::supportedImageCodecs() const
+{
+    return QStringList() << QLatin1String("jpeg");
+}
+
+QString BbImageEncoderControl::imageCodecDescription(const QString &codecName) const
+{
+    if (codecName == QLatin1String("jpeg"))
+        return tr("JPEG image");
+
+    return QString();
+}
+
+QList<QSize> BbImageEncoderControl::supportedResolutions(const QImageEncoderSettings &settings, bool *continuous) const
+{
+    return m_session->supportedResolutions(settings, continuous);
+}
+
+QImageEncoderSettings BbImageEncoderControl::imageSettings() const
+{
+    return m_session->imageSettings();
+}
+
+void BbImageEncoderControl::setImageSettings(const QImageEncoderSettings &settings)
+{
+    m_session->setImageSettings(settings);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/blackberry/camera/bbimageencodercontrol.h b/src/plugins/blackberry/camera/bbimageencodercontrol.h
new file mode 100644 (file)
index 0000000..4db2e7d
--- /dev/null
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.  For licensing terms and
+** conditions see http://qt.digia.com/licensing.  For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 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, Digia gives you certain additional
+** rights.  These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef BBIMAGEENCODERCONTROL_H
+#define BBIMAGEENCODERCONTROL_H
+
+#include <qimageencodercontrol.h>
+
+QT_BEGIN_NAMESPACE
+
+class BbCameraSession;
+
+class BbImageEncoderControl : public QImageEncoderControl
+{
+    Q_OBJECT
+public:
+    explicit BbImageEncoderControl(BbCameraSession *session, QObject *parent = 0);
+
+    QStringList supportedImageCodecs() const Q_DECL_OVERRIDE;
+    QString imageCodecDescription(const QString &codecName) const Q_DECL_OVERRIDE;
+    QList<QSize> supportedResolutions(const QImageEncoderSettings &settings, bool *continuous = 0) const Q_DECL_OVERRIDE;
+    QImageEncoderSettings imageSettings() const Q_DECL_OVERRIDE;
+    void setImageSettings(const QImageEncoderSettings &settings) Q_DECL_OVERRIDE;
+
+private:
+    BbCameraSession *m_session;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/blackberry/camera/bbmediastoragelocation.cpp b/src/plugins/blackberry/camera/bbmediastoragelocation.cpp
new file mode 100644 (file)
index 0000000..3d939ce
--- /dev/null
@@ -0,0 +1,119 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.  For licensing terms and
+** conditions see http://qt.digia.com/licensing.  For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 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, Digia gives you certain additional
+** rights.  These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "bbmediastoragelocation.h"
+
+#include <QStandardPaths>
+
+QT_BEGIN_NAMESPACE
+
+BbMediaStorageLocation::BbMediaStorageLocation()
+{
+}
+
+QDir BbMediaStorageLocation::defaultDir(QCamera::CaptureMode mode) const
+{
+    QStringList dirCandidates;
+
+    dirCandidates << QLatin1String("shared/camera");
+
+    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 BbMediaStorageLocation::generateFileName(const QString &requestedName, QCamera::CaptureMode mode, const QString &prefix, const QString &extension) const
+{
+    if (requestedName.isEmpty())
+        return generateFileName(prefix, defaultDir(mode), extension);
+
+    if (QFileInfo(requestedName).isDir())
+        return generateFileName(prefix, QDir(requestedName), extension);
+
+    return requestedName;
+}
+
+QString BbMediaStorageLocation::generateFileName(const QString &prefix, const QDir &dir, const QString &extension) const
+{
+    const QString lastMediaKey = dir.absolutePath() + QLatin1Char(' ') + prefix + QLatin1Char(' ') + extension;
+    qint64 lastMediaIndex = m_lastUsedIndex.value(lastMediaKey, 0);
+
+    if (lastMediaIndex == 0) {
+        // first run, find the maximum media number during the fist capture
+        Q_FOREACH (const QString &fileName, dir.entryList(QStringList() << QString("%1*.%2").arg(prefix).arg(extension))) {
+            const qint64 mediaIndex = fileName.mid(prefix.length(), fileName.size() - prefix.length() - extension.length() - 1).toInt();
+            lastMediaIndex = qMax(lastMediaIndex, mediaIndex);
+        }
+    }
+
+    // don't just rely on cached lastMediaIndex value,
+    // someone else may create a file after camera started
+    while (true) {
+        const QString name = QString("%1%2.%3").arg(prefix)
+                                               .arg(lastMediaIndex + 1, 8, 10, QLatin1Char('0'))
+                                               .arg(extension);
+
+        const QString path = dir.absoluteFilePath(name);
+        if (!QFileInfo(path).exists()) {
+            m_lastUsedIndex[lastMediaKey] = lastMediaIndex + 1;
+            return path;
+        }
+
+        lastMediaIndex++;
+    }
+
+    return QString();
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/blackberry/camera/bbmediastoragelocation.h b/src/plugins/blackberry/camera/bbmediastoragelocation.h
new file mode 100644 (file)
index 0000000..efa89c8
--- /dev/null
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.  For licensing terms and
+** conditions see http://qt.digia.com/licensing.  For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 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, Digia gives you certain additional
+** rights.  These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef BBMEDIASTORAGELOCATION_H
+#define BBMEDIASTORAGELOCATION_H
+
+#include <QCamera>
+#include <QDir>
+#include <QHash>
+
+QT_BEGIN_NAMESPACE
+
+class BbMediaStorageLocation
+{
+public:
+    BbMediaStorageLocation();
+
+    QDir defaultDir(QCamera::CaptureMode mode) const;
+
+    QString generateFileName(const QString &requestedName, QCamera::CaptureMode mode, const QString &prefix, const QString &extension) const;
+    QString generateFileName(const QString &prefix, const QDir &dir, const QString &extension) const;
+
+private:
+    mutable QHash<QString, qint64> m_lastUsedIndex;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/blackberry/camera/bbvideodeviceselectorcontrol.cpp b/src/plugins/blackberry/camera/bbvideodeviceselectorcontrol.cpp
new file mode 100644 (file)
index 0000000..6a6e9d3
--- /dev/null
@@ -0,0 +1,146 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.  For licensing terms and
+** conditions see http://qt.digia.com/licensing.  For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 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, Digia gives you certain additional
+** rights.  These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "bbvideodeviceselectorcontrol.h"
+
+#include "bbcamerasession.h"
+
+#include <QDebug>
+
+QT_BEGIN_NAMESPACE
+
+BbVideoDeviceSelectorControl::BbVideoDeviceSelectorControl(BbCameraSession *session, QObject *parent)
+    : QVideoDeviceSelectorControl(parent)
+    , m_session(session)
+    , m_selected(0)
+{
+    enumerateDevices(&m_devices, &m_descriptions);
+
+    // pre-select the rear camera
+    const int index = m_devices.indexOf(BbCameraSession::cameraIdentifierRear());
+    if (index != -1)
+        m_selected = index;
+}
+
+int BbVideoDeviceSelectorControl::deviceCount() const
+{
+    return m_devices.count();
+}
+
+QString BbVideoDeviceSelectorControl::deviceName(int index) const
+{
+    if (index < 0 || index >= m_devices.count())
+        return QString();
+
+    return QString::fromUtf8(m_devices.at(index));
+}
+
+QString BbVideoDeviceSelectorControl::deviceDescription(int index) const
+{
+    if (index < 0 || index >= m_descriptions.count())
+        return QString();
+
+    return m_descriptions.at(index);
+}
+
+int BbVideoDeviceSelectorControl::defaultDevice() const
+{
+    return 0;
+}
+
+int BbVideoDeviceSelectorControl::selectedDevice() const
+{
+    return m_selected;
+}
+
+void BbVideoDeviceSelectorControl::enumerateDevices(QList<QByteArray> *devices, QStringList *descriptions)
+{
+    devices->clear();
+    descriptions->clear();
+
+    camera_unit_t cameras[10];
+
+    unsigned int knownCameras = 0;
+    const camera_error_t result = camera_get_supported_cameras(10, &knownCameras, cameras);
+    if (result != CAMERA_EOK) {
+        qWarning() << "Unable to retrieve supported camera types:" << result;
+        return;
+    }
+
+    for (unsigned int i = 0; i < knownCameras; ++i) {
+        switch (cameras[i]) {
+        case CAMERA_UNIT_FRONT:
+            devices->append(BbCameraSession::cameraIdentifierFront());
+            descriptions->append(tr("Front Camera"));
+            break;
+        case CAMERA_UNIT_REAR:
+            devices->append(BbCameraSession::cameraIdentifierRear());
+            descriptions->append(tr("Rear Camera"));
+            break;
+        case CAMERA_UNIT_DESKTOP:
+            devices->append(BbCameraSession::cameraIdentifierDesktop());
+            descriptions->append(tr("Desktop Camera"));
+            break;
+        default:
+            break;
+        }
+    }
+}
+
+void BbVideoDeviceSelectorControl::setSelectedDevice(int index)
+{
+    if (index < 0 || index >= m_devices.count())
+        return;
+
+    if (!m_session)
+        return;
+
+    const QByteArray device = m_devices.at(index);
+    if (device == m_session->device())
+        return;
+
+    m_session->setDevice(device);
+    m_selected = index;
+
+    emit selectedDeviceChanged(QString::fromUtf8(device));
+    emit selectedDeviceChanged(index);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/blackberry/camera/bbvideodeviceselectorcontrol.h b/src/plugins/blackberry/camera/bbvideodeviceselectorcontrol.h
new file mode 100644 (file)
index 0000000..1987f54
--- /dev/null
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.  For licensing terms and
+** conditions see http://qt.digia.com/licensing.  For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 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, Digia gives you certain additional
+** rights.  These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef BBVIDEODEVICESELECTORCONTROL_H
+#define BBVIDEODEVICESELECTORCONTROL_H
+
+#include <qvideodeviceselectorcontrol.h>
+#include <QStringList>
+
+QT_BEGIN_NAMESPACE
+
+class BbCameraSession;
+
+class BbVideoDeviceSelectorControl : public QVideoDeviceSelectorControl
+{
+    Q_OBJECT
+public:
+    explicit BbVideoDeviceSelectorControl(BbCameraSession *session, QObject *parent = 0);
+
+    int deviceCount() const Q_DECL_OVERRIDE;
+    QString deviceName(int index) const Q_DECL_OVERRIDE;
+    QString deviceDescription(int index) const Q_DECL_OVERRIDE;
+    int defaultDevice() const Q_DECL_OVERRIDE;
+    int selectedDevice() const Q_DECL_OVERRIDE;
+
+    static void enumerateDevices(QList<QByteArray> *devices, QStringList *descriptions);
+
+public Q_SLOTS:
+    void setSelectedDevice(int index) Q_DECL_OVERRIDE;
+
+private:
+    BbCameraSession* m_session;
+
+    QList<QByteArray> m_devices;
+    QStringList m_descriptions;
+
+    int m_selected;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/blackberry/camera/bbvideorenderercontrol.cpp b/src/plugins/blackberry/camera/bbvideorenderercontrol.cpp
new file mode 100644 (file)
index 0000000..4fadf9a
--- /dev/null
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.  For licensing terms and
+** conditions see http://qt.digia.com/licensing.  For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 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, Digia gives you certain additional
+** rights.  These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "bbvideorenderercontrol.h"
+
+#include "bbcamerasession.h"
+
+QT_BEGIN_NAMESPACE
+
+BbVideoRendererControl::BbVideoRendererControl(BbCameraSession *session, QObject *parent)
+    : QVideoRendererControl(parent)
+    , m_session(session)
+{
+}
+
+QAbstractVideoSurface* BbVideoRendererControl::surface() const
+{
+    return m_session->surface();
+}
+
+void BbVideoRendererControl::setSurface(QAbstractVideoSurface *surface)
+{
+    m_session->setSurface(surface);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/blackberry/camera/bbvideorenderercontrol.h b/src/plugins/blackberry/camera/bbvideorenderercontrol.h
new file mode 100644 (file)
index 0000000..93b2b64
--- /dev/null
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.  For licensing terms and
+** conditions see http://qt.digia.com/licensing.  For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 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, Digia gives you certain additional
+** rights.  These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef BBVIDEORENDERERCONTROL_H
+#define BBVIDEORENDERERCONTROL_H
+
+#include <qvideorenderercontrol.h>
+
+QT_BEGIN_NAMESPACE
+
+class BbCameraSession;
+
+class BbVideoRendererControl : public QVideoRendererControl
+{
+    Q_OBJECT
+public:
+    explicit BbVideoRendererControl(BbCameraSession *session, QObject *parent = 0);
+
+    QAbstractVideoSurface *surface() const Q_DECL_OVERRIDE;
+    void setSurface(QAbstractVideoSurface *surface) Q_DECL_OVERRIDE;
+
+private:
+    BbCameraSession *m_session;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/blackberry/camera/camera.pri b/src/plugins/blackberry/camera/camera.pri
new file mode 100644 (file)
index 0000000..8186cdc
--- /dev/null
@@ -0,0 +1,49 @@
+INCLUDEPATH += $$PWD
+
+HEADERS += \
+    $$PWD/bbcameraaudioencodersettingscontrol.h \
+    $$PWD/bbcameracapturebufferformatcontrol.h \
+    $$PWD/bbcameracapturedestinationcontrol.h \
+    $$PWD/bbcameracontrol.h \
+    $$PWD/bbcameraexposurecontrol.h \
+    $$PWD/bbcameraflashcontrol.h \
+    $$PWD/bbcamerafocuscontrol.h \
+    $$PWD/bbcameraimagecapturecontrol.h \
+    $$PWD/bbcameraimageprocessingcontrol.h \
+    $$PWD/bbcameralockscontrol.h \
+    $$PWD/bbcameramediarecordercontrol.h \
+    $$PWD/bbcameraorientationhandler.h \
+    $$PWD/bbcameraservice.h \
+    $$PWD/bbcamerasession.h \
+    $$PWD/bbcameravideoencodersettingscontrol.h \
+    $$PWD/bbcameraviewfindersettingscontrol.h \
+    $$PWD/bbcamerazoomcontrol.h \
+    $$PWD/bbimageencodercontrol.h \
+    $$PWD/bbmediastoragelocation.h \
+    $$PWD/bbvideodeviceselectorcontrol.h \
+    $$PWD/bbvideorenderercontrol.h
+
+SOURCES += \
+    $$PWD/bbcameraaudioencodersettingscontrol.cpp \
+    $$PWD/bbcameracapturebufferformatcontrol.cpp \
+    $$PWD/bbcameracapturedestinationcontrol.cpp \
+    $$PWD/bbcameracontrol.cpp \
+    $$PWD/bbcameraexposurecontrol.cpp \
+    $$PWD/bbcameraflashcontrol.cpp \
+    $$PWD/bbcamerafocuscontrol.cpp \
+    $$PWD/bbcameraimagecapturecontrol.cpp \
+    $$PWD/bbcameraimageprocessingcontrol.cpp \
+    $$PWD/bbcameralockscontrol.cpp \
+    $$PWD/bbcameramediarecordercontrol.cpp \
+    $$PWD/bbcameraorientationhandler.cpp \
+    $$PWD/bbcameraservice.cpp \
+    $$PWD/bbcamerasession.cpp \
+    $$PWD/bbcameravideoencodersettingscontrol.cpp \
+    $$PWD/bbcameraviewfindersettingscontrol.cpp \
+    $$PWD/bbcamerazoomcontrol.cpp \
+    $$PWD/bbimageencodercontrol.cpp \
+    $$PWD/bbmediastoragelocation.cpp \
+    $$PWD/bbvideodeviceselectorcontrol.cpp \
+    $$PWD/bbvideorenderercontrol.cpp
+
+LIBS += -lcamapi -laudio_manager