summaryrefslogtreecommitdiffstats
path: root/src/imports
diff options
context:
space:
mode:
authorYoann Lopes <yoann.lopes@digia.com>2014-02-10 19:33:51 +0100
committerYoann Lopes <yoann.lopes@digia.com>2014-07-17 18:58:00 +0200
commit888759e334e81117843afb6d0f8991db8aec5ca8 (patch)
treed0b6eb0b094557d5c25bf865998915f0839d596d /src/imports
parentcddbe8736d995b4bfdfbbf1abfc3d6aeae3eb214 (diff)
New camera selection API in QML.
Also added a new QtMultimedia global object which makes it possible to retrieve the list of available cameras. It can be extended with new utility functions in the future. Includes documentation, example and auto tests. Task-number: QTBUG-23770 Change-Id: Ifea076329c3582ea99246ee1131853344a7b773f Reviewed-by: Christian Stromme <christian.stromme@digia.com>
Diffstat (limited to 'src/imports')
-rw-r--r--src/imports/multimedia/multimedia.cpp17
-rw-r--r--src/imports/multimedia/multimedia.pro6
-rw-r--r--src/imports/multimedia/qdeclarativecamera.cpp246
-rw-r--r--src/imports/multimedia/qdeclarativecamera_p.h32
-rw-r--r--src/imports/multimedia/qdeclarativemultimediaglobal.cpp220
-rw-r--r--src/imports/multimedia/qdeclarativemultimediaglobal_p.h66
6 files changed, 553 insertions, 34 deletions
diff --git a/src/imports/multimedia/multimedia.cpp b/src/imports/multimedia/multimedia.cpp
index 18c74e006..99d6ba422 100644
--- a/src/imports/multimedia/multimedia.cpp
+++ b/src/imports/multimedia/multimedia.cpp
@@ -47,6 +47,7 @@
#include <private/qdeclarativevideooutput_p.h>
+#include "qdeclarativemultimediaglobal_p.h"
#include "qdeclarativemediametadata_p.h"
#include "qdeclarativeaudio_p.h"
#include "qdeclarativeradio_p.h"
@@ -73,15 +74,14 @@ public:
{
Q_ASSERT(QLatin1String(uri) == QLatin1String("QtMultimedia"));
+ // 5.0 types
qmlRegisterType<QSoundEffect>(uri, 5, 0, "SoundEffect");
qmlRegisterType<QDeclarativeAudio>(uri, 5, 0, "Audio");
qmlRegisterType<QDeclarativeAudio>(uri, 5, 0, "MediaPlayer");
qmlRegisterType<QDeclarativeVideoOutput>(uri, 5, 0, "VideoOutput");
- qmlRegisterType<QDeclarativeVideoOutput, 2>(uri, 5, 2, "VideoOutput");
qmlRegisterType<QDeclarativeRadio>(uri, 5, 0, "Radio");
qmlRegisterType<QDeclarativeRadioData>(uri, 5, 0, "RadioData");
qmlRegisterType<QDeclarativeCamera>(uri, 5, 0, "Camera");
- qmlRegisterRevision<QDeclarativeCamera, 1>(uri, 5, 4);
qmlRegisterType<QDeclarativeTorch>(uri, 5, 0, "Torch");
qmlRegisterUncreatableType<QDeclarativeCameraCapture>(uri, 5, 0, "CameraCapture",
trUtf8("CameraCapture is provided by Camera"));
@@ -96,11 +96,18 @@ public:
qmlRegisterUncreatableType<QDeclarativeCameraImageProcessing>(uri, 5, 0, "CameraImageProcessing",
trUtf8("CameraImageProcessing is provided by Camera"));
- // Make types available for the 5.3 version
- // Adding "import QtMultimedia 5.3" in QML will fail unless at least one type is registered
- // for that version.
+ // 5.2 types
+ qmlRegisterRevision<QDeclarativeVideoOutput, 2>(uri, 5, 2);
+
+ // 5.3 types
+ // Nothing changed, but adding "import QtMultimedia 5.3" in QML will fail unless at
+ // least one type is registered for that version.
qmlRegisterType<QSoundEffect>(uri, 5, 3, "SoundEffect");
+ // 5.4 types
+ qmlRegisterSingletonType(uri, 5, 4, "QtMultimedia", QDeclarativeMultimedia::initGlobalObject);
+ qmlRegisterRevision<QDeclarativeCamera, 1>(uri, 5, 4);
+
qmlRegisterType<QDeclarativeMediaMetaData>();
}
diff --git a/src/imports/multimedia/multimedia.pro b/src/imports/multimedia/multimedia.pro
index 75974ec10..71358caed 100644
--- a/src/imports/multimedia/multimedia.pro
+++ b/src/imports/multimedia/multimedia.pro
@@ -14,7 +14,8 @@ HEADERS += \
qdeclarativecameraimageprocessing_p.h \
qdeclarativecamerapreviewprovider_p.h \
qdeclarativetorch_p.h \
- qdeclarativecameraviewfinder_p.h
+ qdeclarativecameraviewfinder_p.h \
+ qdeclarativemultimediaglobal_p.h
SOURCES += \
multimedia.cpp \
@@ -30,7 +31,8 @@ SOURCES += \
qdeclarativecameraimageprocessing.cpp \
qdeclarativecamerapreviewprovider.cpp \
qdeclarativetorch.cpp \
- qdeclarativecameraviewfinder.cpp
+ qdeclarativecameraviewfinder.cpp \
+ qdeclarativemultimediaglobal.cpp
QML_FILES += \
Video.qml
diff --git a/src/imports/multimedia/qdeclarativecamera.cpp b/src/imports/multimedia/qdeclarativecamera.cpp
index 7e43875a0..04a8c2131 100644
--- a/src/imports/multimedia/qdeclarativecamera.cpp
+++ b/src/imports/multimedia/qdeclarativecamera.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
@@ -53,6 +53,7 @@
#include <qmediaplayercontrol.h>
#include <qmediaservice.h>
#include <qvideorenderercontrol.h>
+#include <qvideodeviceselectorcontrol.h>
#include <QtQml/qqmlinfo.h>
#include <QtCore/QTimer>
@@ -84,9 +85,7 @@ void QDeclarativeCamera::_q_availabilityChanged(QMultimedia::AvailabilityStatus
\ingroup camera_qml
\inqmlmodule QtMultimedia
- \inherits Item
-
- Camera is part of the \b{QtMultimedia 5.0} module.
+ \inherits QtObject
You can use \c Camera to capture images and movies from a camera, and manipulate
the capture and processing settings that get applied to the images. To display the
@@ -95,7 +94,7 @@ void QDeclarativeCamera::_q_availabilityChanged(QMultimedia::AvailabilityStatus
\qml
import QtQuick 2.0
- import QtMultimedia 5.0
+ import QtMultimedia 5.4
Item {
width: 640
@@ -132,6 +131,12 @@ void QDeclarativeCamera::_q_availabilityChanged(QMultimedia::AvailabilityStatus
}
\endqml
+ If multiple cameras are available, you can select which one to use by setting the \l deviceId
+ property to a value from
+ \l{QtMultimedia::QtMultimedia::availableCameras}{QtMultimedia.availableCameras}.
+ On a mobile device, you can conveniently switch between front-facing and back-facing cameras
+ by setting the \l position property.
+
The various settings and functionality of the Camera stack is spread
across a few different child properties of Camera.
@@ -161,6 +166,8 @@ void QDeclarativeCamera::_q_availabilityChanged(QMultimedia::AvailabilityStatus
set manually or automatically. These settings properties contain the current set value.
For example, when autofocus is enabled the focus zones are exposed in the
\l {CameraFocus}{focus} property.
+
+ For additional information, read also the \l{Camera Overview}{camera overview}.
*/
/*!
@@ -176,37 +183,56 @@ QDeclarativeCamera::QDeclarativeCamera(QObject *parent) :
QObject(parent),
m_camera(0),
m_metaData(0),
+ m_viewfinder(0),
m_pendingState(ActiveState),
m_componentComplete(false)
{
- m_camera = new QCamera(this);
-
- m_imageCapture = new QDeclarativeCameraCapture(m_camera, this);
- m_videoRecorder = new QDeclarativeCameraRecorder(m_camera, this);
- m_exposure = new QDeclarativeCameraExposure(m_camera, this);
- m_flash = new QDeclarativeCameraFlash(m_camera, this);
- m_focus = new QDeclarativeCameraFocus(m_camera, this);
- m_imageProcessing = new QDeclarativeCameraImageProcessing(m_camera, this);
-
- connect(m_camera, SIGNAL(captureModeChanged(QCamera::CaptureModes)), this, SIGNAL(captureModeChanged()));
- connect(m_camera, SIGNAL(lockStatusChanged(QCamera::LockStatus,QCamera::LockChangeReason)), this, SIGNAL(lockStatusChanged()));
- connect(m_camera, SIGNAL(stateChanged(QCamera::State)), this, SLOT(_q_updateState(QCamera::State)));
+ m_camera = new QCamera;
+ m_currentCameraInfo = QCameraInfo(*m_camera);
+
+ m_imageCapture = new QDeclarativeCameraCapture(m_camera);
+ m_videoRecorder = new QDeclarativeCameraRecorder(m_camera);
+ m_exposure = new QDeclarativeCameraExposure(m_camera);
+ m_flash = new QDeclarativeCameraFlash(m_camera);
+ m_focus = new QDeclarativeCameraFocus(m_camera);
+ m_imageProcessing = new QDeclarativeCameraImageProcessing(m_camera);
+
+ connect(m_camera, SIGNAL(captureModeChanged(QCamera::CaptureModes)),
+ this, SIGNAL(captureModeChanged()));
+ connect(m_camera, SIGNAL(lockStatusChanged(QCamera::LockStatus,QCamera::LockChangeReason)),
+ this, SIGNAL(lockStatusChanged()));
+ connect(m_camera, &QCamera::stateChanged, this, &QDeclarativeCamera::_q_updateState);
connect(m_camera, SIGNAL(statusChanged(QCamera::Status)), this, SIGNAL(cameraStatusChanged()));
connect(m_camera, SIGNAL(error(QCamera::Error)), this, SLOT(_q_error(QCamera::Error)));
- connect(m_camera, SIGNAL(availabilityChanged(QMultimedia::AvailabilityStatus)), this, SLOT(_q_availabilityChanged(QMultimedia::AvailabilityStatus)));
-
- connect(m_camera->focus(), SIGNAL(opticalZoomChanged(qreal)), this, SIGNAL(opticalZoomChanged(qreal)));
- connect(m_camera->focus(), SIGNAL(digitalZoomChanged(qreal)), this, SIGNAL(digitalZoomChanged(qreal)));
- connect(m_camera->focus(), SIGNAL(maximumOpticalZoomChanged(qreal)), this, SIGNAL(maximumOpticalZoomChanged(qreal)));
- connect(m_camera->focus(), SIGNAL(maximumDigitalZoomChanged(qreal)), this, SIGNAL(maximumDigitalZoomChanged(qreal)));
+ connect(m_camera, SIGNAL(availabilityChanged(QMultimedia::AvailabilityStatus)),
+ this, SLOT(_q_availabilityChanged(QMultimedia::AvailabilityStatus)));
+
+ connect(m_camera->focus(), &QCameraFocus::opticalZoomChanged,
+ this, &QDeclarativeCamera::opticalZoomChanged);
+ connect(m_camera->focus(), &QCameraFocus::digitalZoomChanged,
+ this, &QDeclarativeCamera::digitalZoomChanged);
+ connect(m_camera->focus(), &QCameraFocus::maximumOpticalZoomChanged,
+ this, &QDeclarativeCamera::maximumOpticalZoomChanged);
+ connect(m_camera->focus(), &QCameraFocus::maximumDigitalZoomChanged,
+ this, &QDeclarativeCamera::maximumDigitalZoomChanged);
}
/*! Destructor, clean up memory */
QDeclarativeCamera::~QDeclarativeCamera()
{
+ m_camera->unload();
+
+ // These must be deleted before QCamera
+ delete m_imageCapture;
+ delete m_videoRecorder;
+ delete m_exposure;
+ delete m_flash;
+ delete m_focus;
+ delete m_imageProcessing;
delete m_metaData;
+ delete m_viewfinder;
- m_camera->unload();
+ delete m_camera;
}
void QDeclarativeCamera::classBegin()
@@ -220,6 +246,173 @@ void QDeclarativeCamera::componentComplete()
}
/*!
+ \qmlproperty string QtMultimedia::Camera::deviceId
+
+ This property holds the unique identifier for the camera device being used. It may not be human-readable.
+
+ You can get all available device IDs from \l{QtMultimedia::QtMultimedia::availableCameras}{QtMultimedia.availableCameras}.
+ If no value is provided or if set to an empty string, the system's default camera will be used.
+
+ If possible, \l cameraState, \l captureMode, \l digitalZoom and other camera parameters are
+ preserved when changing the camera device.
+
+ \sa displayName, position
+ \since QtMultimedia 5.4
+*/
+
+QString QDeclarativeCamera::deviceId() const
+{
+ return m_currentCameraInfo.deviceName();
+}
+
+void QDeclarativeCamera::setDeviceId(const QString &name)
+{
+ if (name == m_currentCameraInfo.deviceName())
+ return;
+
+ setupDevice(name);
+}
+
+/*!
+ \qmlproperty enumeration QtMultimedia::Camera::position
+
+ This property holds the physical position of the camera on the hardware system.
+
+ The position can be one of the following:
+
+ \list
+ \li \c Camera.UnspecifiedPosition - the camera position is unspecified or unknown.
+ \li \c Camera.BackFace - the camera is on the back face of the system hardware. For example on a
+ mobile device, it means it is on the opposite side to that of the screem.
+ \li \c Camera.FrontFace - the camera is on the front face of the system hardware. For example on
+ a mobile device, it means it is on the same side as that of the screen. Viewfinder frames of
+ front-facing cameras are mirrored horizontally, so the users can see themselves as looking
+ into a mirror. Captured images or videos are not mirrored.
+ \endlist
+
+ On a mobile device it can be used to easily choose between front-facing and back-facing cameras.
+ If this property is set to \c Camera.UnspecifiedPosition, the system's default camera will be
+ used.
+
+ If possible, \l cameraState, \l captureMode, \l digitalZoom and other camera parameters are
+ preserved when changing the camera device.
+
+ \sa deviceId
+ \since QtMultimedia 5.4
+*/
+
+QDeclarativeCamera::Position QDeclarativeCamera::position() const
+{
+ return QDeclarativeCamera::Position(m_currentCameraInfo.position());
+}
+
+void QDeclarativeCamera::setPosition(Position position)
+{
+ QCamera::Position pos = QCamera::Position(position);
+ if (pos == m_currentCameraInfo.position())
+ return;
+
+ QString id;
+
+ if (pos == QCamera::UnspecifiedPosition) {
+ id = QCameraInfo::defaultCamera().deviceName();
+ } else {
+ QList<QCameraInfo> cameras = QCameraInfo::availableCameras(pos);
+ if (!cameras.isEmpty())
+ id = cameras.first().deviceName();
+ }
+
+ if (!id.isEmpty())
+ setupDevice(id);
+}
+
+/*!
+ \qmlproperty string QtMultimedia::Camera::displayName
+
+ This property holds the human-readable name of the camera.
+
+ You can use this property to display the name of the camera in a user interface.
+
+ \readonly
+ \sa deviceId
+ \since QtMultimedia 5.4
+*/
+
+QString QDeclarativeCamera::displayName() const
+{
+ return m_currentCameraInfo.description();
+}
+
+/*!
+ \qmlproperty int QtMultimedia::Camera::orientation
+
+ This property holds the physical orientation of the camera sensor.
+
+ The value is the orientation angle (clockwise, in steps of 90 degrees) of the camera sensor in
+ relation to the display in its natural orientation.
+
+ For example, suppose a mobile device which is naturally in portrait orientation. The back-facing
+ camera is mounted in landscape. If the top side of the camera sensor is aligned with the right
+ edge of the screen in natural orientation, \c orientation returns \c 270. If the top side of a
+ front-facing camera sensor is aligned with the right edge of the screen, \c orientation
+ returns \c 90.
+
+ \readonly
+ \sa VideoOutput::orientation
+ \since QtMultimedia 5.4
+*/
+
+int QDeclarativeCamera::orientation() const
+{
+ return m_currentCameraInfo.orientation();
+}
+
+void QDeclarativeCamera::setupDevice(const QString &deviceName)
+{
+ QMediaService *service = m_camera->service();
+ if (!service)
+ return;
+
+ QVideoDeviceSelectorControl *deviceControl = qobject_cast<QVideoDeviceSelectorControl*>(service->requestControl(QVideoDeviceSelectorControl_iid));
+ if (!deviceControl)
+ return;
+
+ int deviceIndex = -1;
+
+ if (deviceName.isEmpty()) {
+ deviceIndex = deviceControl->defaultDevice();
+ } else {
+ for (int i = 0; i < deviceControl->deviceCount(); ++i) {
+ if (deviceControl->deviceName(i) == deviceName) {
+ deviceIndex = i;
+ break;
+ }
+ }
+ }
+
+ if (deviceIndex == -1)
+ return;
+
+ State previousState = cameraState();
+ setCameraState(UnloadedState);
+
+ deviceControl->setSelectedDevice(deviceIndex);
+
+ QCameraInfo oldCameraInfo = m_currentCameraInfo;
+ m_currentCameraInfo = QCameraInfo(*m_camera);
+
+ emit deviceIdChanged();
+ if (oldCameraInfo.description() != m_currentCameraInfo.description())
+ emit displayNameChanged();
+ if (oldCameraInfo.position() != m_currentCameraInfo.position())
+ emit positionChanged();
+ if (oldCameraInfo.orientation() != m_currentCameraInfo.orientation())
+ emit orientationChanged();
+
+ setCameraState(previousState);
+}
+
+/*!
Returns any camera error.
\sa QDeclarativeCameraError::Error
*/
@@ -286,6 +479,7 @@ QDeclarativeCamera::Availability QDeclarativeCamera::availability() const
\endtable
+ The default capture mode is \c CaptureStillImage.
*/
QDeclarativeCamera::CaptureMode QDeclarativeCamera::captureMode() const
{
@@ -798,7 +992,7 @@ void QDeclarativeCamera::setDigitalZoom(qreal value)
QDeclarativeMediaMetaData *QDeclarativeCamera::metaData()
{
if (!m_metaData)
- m_metaData = new QDeclarativeMediaMetaData(m_camera, this);
+ m_metaData = new QDeclarativeMediaMetaData(m_camera);
return m_metaData;
}
@@ -824,7 +1018,7 @@ QDeclarativeMediaMetaData *QDeclarativeCamera::metaData()
QDeclarativeCameraViewfinder *QDeclarativeCamera::viewfinder()
{
if (!m_viewfinder)
- m_viewfinder = new QDeclarativeCameraViewfinder(m_camera, this);
+ m_viewfinder = new QDeclarativeCameraViewfinder(m_camera);
return m_viewfinder;
}
diff --git a/src/imports/multimedia/qdeclarativecamera_p.h b/src/imports/multimedia/qdeclarativecamera_p.h
index e7745abd9..d9b819a27 100644
--- a/src/imports/multimedia/qdeclarativecamera_p.h
+++ b/src/imports/multimedia/qdeclarativecamera_p.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
@@ -57,6 +57,7 @@
#include "qdeclarativecamerarecorder_p.h"
#include <qcamera.h>
+#include <qcamerainfo.h>
#include <qcameraimageprocessing.h>
#include <qcameraimagecapture.h>
@@ -79,6 +80,11 @@ class QDeclarativeCamera : public QObject, public QQmlParserStatus
Q_OBJECT
Q_INTERFACES(QQmlParserStatus)
+ Q_PROPERTY(QString deviceId READ deviceId WRITE setDeviceId NOTIFY deviceIdChanged REVISION 1)
+ Q_PROPERTY(Position position READ position WRITE setPosition NOTIFY positionChanged REVISION 1)
+ Q_PROPERTY(QString displayName READ displayName NOTIFY displayNameChanged REVISION 1)
+ Q_PROPERTY(int orientation READ orientation NOTIFY orientationChanged REVISION 1)
+
Q_PROPERTY(CaptureMode captureMode READ captureMode WRITE setCaptureMode NOTIFY captureModeChanged)
Q_PROPERTY(State cameraState READ cameraState WRITE setCameraState NOTIFY cameraStateChanged)
Q_PROPERTY(Status cameraStatus READ cameraStatus NOTIFY cameraStatusChanged)
@@ -103,6 +109,7 @@ class QDeclarativeCamera : public QObject, public QQmlParserStatus
Q_PROPERTY(QDeclarativeMediaMetaData *metaData READ metaData CONSTANT REVISION 1)
Q_PROPERTY(QDeclarativeCameraViewfinder *viewfinder READ viewfinder CONSTANT REVISION 1)
+ Q_ENUMS(Position)
Q_ENUMS(CaptureMode)
Q_ENUMS(State)
Q_ENUMS(Status)
@@ -119,6 +126,12 @@ class QDeclarativeCamera : public QObject, public QQmlParserStatus
Q_ENUMS(Availability)
public:
+ enum Position {
+ UnspecifiedPosition = QCamera::UnspecifiedPosition,
+ BackFace = QCamera::BackFace,
+ FrontFace = QCamera::FrontFace
+ };
+
enum CaptureMode {
CaptureViewfinder = QCamera::CaptureViewfinder,
CaptureStillImage = QCamera::CaptureStillImage,
@@ -239,6 +252,15 @@ public:
QDeclarativeMediaMetaData *metaData();
+ QString deviceId() const;
+ void setDeviceId(const QString &name);
+
+ Position position() const;
+ void setPosition(Position position);
+
+ QString displayName() const;
+ int orientation() const;
+
CaptureMode captureMode() const;
State cameraState() const;
Status cameraStatus() const;
@@ -274,6 +296,11 @@ Q_SIGNALS:
void errorChanged();
void error(QDeclarativeCamera::Error errorCode, const QString &errorString);
+ Q_REVISION(1) void deviceIdChanged();
+ Q_REVISION(1) void positionChanged();
+ Q_REVISION(1) void displayNameChanged();
+ Q_REVISION(1) void orientationChanged();
+
void captureModeChanged();
void cameraStateChanged(QDeclarativeCamera::State);
void cameraStatusChanged();
@@ -300,7 +327,10 @@ protected:
private:
Q_DISABLE_COPY(QDeclarativeCamera)
+ void setupDevice(const QString &deviceName);
+
QCamera *m_camera;
+ QCameraInfo m_currentCameraInfo;
QDeclarativeCameraCapture *m_imageCapture;
QDeclarativeCameraRecorder *m_videoRecorder;
diff --git a/src/imports/multimedia/qdeclarativemultimediaglobal.cpp b/src/imports/multimedia/qdeclarativemultimediaglobal.cpp
new file mode 100644
index 000000000..ff1b4bc6a
--- /dev/null
+++ b/src/imports/multimedia/qdeclarativemultimediaglobal.cpp
@@ -0,0 +1,220 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins 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 "qdeclarativemultimediaglobal_p.h"
+
+#include <qcamerainfo.h>
+#include <qjsengine.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+\qmltype QtMultimedia
+\inqmlmodule QtMultimedia
+\ingroup multimedia_qml
+\since QtMultimedia 5.4
+\brief Provides a global object with useful functions from Qt Multimedia.
+
+The \c QtMultimedia object is a global object with utility functions and properties.
+
+It is not instantiable; to use it, call the members of the global \c QtMultimedia object directly.
+For example:
+
+\qml
+import QtQuick 2.0
+import QtMultimedia 5.4
+
+Camera {
+ deviceId: QtMultimedia.defaultCamera.deviceId
+}
+\endqml
+
+*/
+
+/*!
+ \qmlproperty object QtMultimedia::QtMultimedia::defaultCamera
+ \readonly
+
+ The \c defaultCamera object provides information about the default camera on the system.
+
+ Its properties are \c deviceId, \c displayName, \c position and \c orientation. See
+ \l{QtMultimedia::QtMultimedia::availableCameras}{availableCameras} for a description of each
+ of them.
+
+ If there is no default camera, \c defaultCamera.deviceId will contain an empty string.
+
+ \note This property is static; it is not updated if the system's default camera changes after the
+ application started.
+*/
+
+/*!
+ \qmlproperty list<object> QtMultimedia::QtMultimedia::availableCameras
+ \readonly
+
+ This property provides information about the cameras available on the system.
+
+ Each object in the list has the following properties:
+
+ \table
+ \row
+ \li \c deviceId
+ \li
+ This read-only property holds the unique identifier of the camera.
+
+ You can choose which device to use with a \l Camera object by setting its
+ \l{Camera::deviceId}{deviceId} property to this value.
+
+ \row
+ \li \c displayName
+ \li
+ This read-only property holds the human-readable name of the camera.
+ You can use this property to display the name of the camera in a user interface.
+
+ \row
+ \li \c position
+ \li
+ This read-only property holds the physical position of the camera on the hardware system.
+ Please see \l{Camera::position}{Camera.position} for more information.
+
+ \row
+ \li \c orientation
+ \li
+ This read-only property holds the physical orientation of the camera sensor.
+ Please see \l{Camera::orientation}{Camera.orientation} for more information.
+
+ \endtable
+
+ \note This property is static; it is not updated when cameras are added or removed from
+ the system, like USB cameras on a desktop platform.
+
+ The following example shows how to display a list of available cameras. The user can change
+ the active camera by selecting one of the items in the list.
+
+ \qml
+ import QtQuick 2.0
+ import QtMultimedia 5.4
+
+ Item {
+
+ Camera {
+ id: camera
+ }
+
+ VideoOutput {
+ anchors.fill: parent
+ source: camera
+ }
+
+ ListView {
+ anchors.fill: parent
+
+ model: QtMultimedia.availableCameras
+ delegate: Text {
+ text: modelData.displayName
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: camera.deviceId = modelData.deviceId
+ }
+ }
+ }
+ }
+
+ \endqml
+*/
+
+namespace QDeclarativeMultimedia {
+
+#define FREEZE_SOURCE "(function deepFreeze(o) { "\
+ " var prop, propKey;" \
+ " Object.freeze(o);" \
+ " for (propKey in o) {" \
+ " prop = o[propKey];" \
+ " if (!o.hasOwnProperty(propKey) || !(typeof prop === \"object\") || " \
+ " Object.isFrozen(prop)) {" \
+ " continue;" \
+ " }" \
+ " deepFreeze(prop);" \
+ " }" \
+ "})"
+
+static void deepFreeze(QJSEngine *jsEngine, const QJSValue &obj)
+{
+ QJSValue freezeFunc = jsEngine->evaluate(QString::fromUtf8(FREEZE_SOURCE));
+ freezeFunc.call(QJSValueList() << obj);
+}
+
+static QJSValue cameraInfoToJSValue(QJSEngine *jsEngine, const QCameraInfo &camera)
+{
+ QJSValue o = jsEngine->newObject();
+ o.setProperty(QStringLiteral("deviceId"), camera.deviceName());
+ o.setProperty(QStringLiteral("displayName"), camera.description());
+ o.setProperty(QStringLiteral("position"), int(camera.position()));
+ o.setProperty(QStringLiteral("orientation"), camera.orientation());
+ return o;
+}
+
+QJSValue initGlobalObject(QQmlEngine *qmlEngine, QJSEngine *jsEngine)
+{
+ Q_UNUSED(qmlEngine)
+
+ QJSValue globalObject = jsEngine->newObject();
+
+ // property object defaultCamera
+ globalObject.setProperty(QStringLiteral("defaultCamera"),
+ cameraInfoToJSValue(jsEngine, QCameraInfo::defaultCamera()));
+
+ // property list<object> availableCameras
+ QList<QCameraInfo> cameras = QCameraInfo::availableCameras();
+ QJSValue availableCameras = jsEngine->newArray(cameras.count());
+ for (int i = 0; i < cameras.count(); ++i)
+ availableCameras.setProperty(i, cameraInfoToJSValue(jsEngine, cameras.at(i)));
+ globalObject.setProperty(QStringLiteral("availableCameras"), availableCameras);
+
+ // freeze global object to prevent properties to be modified from QML
+ deepFreeze(jsEngine, globalObject);
+
+ return globalObject;
+}
+
+}
+
+QT_END_NAMESPACE
diff --git a/src/imports/multimedia/qdeclarativemultimediaglobal_p.h b/src/imports/multimedia/qdeclarativemultimediaglobal_p.h
new file mode 100644
index 000000000..58d8a6db5
--- /dev/null
+++ b/src/imports/multimedia/qdeclarativemultimediaglobal_p.h
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins 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 QDECLARATIVEMULTIMEDIAGLOBAL_P_H
+#define QDECLARATIVEMULTIMEDIAGLOBAL_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtQml/qqml.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace QDeclarativeMultimedia {
+ QJSValue initGlobalObject(QQmlEngine *, QJSEngine *);
+}
+
+QT_END_NAMESPACE
+
+#endif // QDECLARATIVEMULTIMEDIAGLOBAL_P_H