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>
This commit is contained in:
Yoann Lopes
2014-02-10 19:33:51 +01:00
parent cddbe8736d
commit 888759e334
32 changed files with 1297 additions and 89 deletions

View File

@@ -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 examples of the Qt Toolkit.
@@ -63,9 +63,16 @@ Item {
}
Text {
id: btnText
anchors.fill: buttonImage
anchors.margins: 5
text: button.text
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
elide: Text.ElideRight
color: button.color
anchors.centerIn: buttonImage; font.bold: true
text: button.text; style: Text.Raised; styleColor: "black"
font.bold: true
style: Text.Raised
styleColor: "black"
font.pixelSize: 14
}
}

View File

@@ -0,0 +1,76 @@
/****************************************************************************
**
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
** of its contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
import QtQuick 2.0
Item {
id: cameraListButton
property alias value : popup.currentValue
property alias model : popup.model
width : 144
height: 70
visible: model.length > 0
BorderImage {
id: buttonImage
source: "images/toolbutton.sci"
width: cameraListButton.width; height: cameraListButton.height
}
CameraButton {
anchors.fill: parent
text: popup.currentItem != null ? popup.currentItem.displayName : ""
onClicked: popup.toggle()
}
CameraListPopup {
id: popup
anchors.right: parent.left
anchors.rightMargin: 16
anchors.top: parent.top
visible: opacity > 0
currentValue: cameraListButton.value
onSelected: popup.toggle()
}
}

View File

@@ -0,0 +1,95 @@
/****************************************************************************
**
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
** of its contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
import QtQuick 2.0
Popup {
id: cameraListPopup
property alias model : view.model
property variant currentValue
property variant currentItem : model[view.currentIndex]
property int itemWidth : 200
property int itemHeight : 50
width: itemWidth + view.anchors.margins*2
height: view.count * itemHeight + view.anchors.margins*2
signal selected
ListView {
id: view
anchors.fill: parent
anchors.margins: 5
snapMode: ListView.SnapOneItem
highlightFollowsCurrentItem: true
highlight: Rectangle { color: "gray"; radius: 5 }
currentIndex: 0
delegate: Item {
width: cameraListPopup.itemWidth
height: cameraListPopup.itemHeight
Text {
text: modelData.displayName
anchors.fill: parent
anchors.margins: 5
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
elide: Text.ElideRight
color: "white"
font.bold: true
style: Text.Raised
styleColor: "black"
font.pixelSize: 14
}
MouseArea {
anchors.fill: parent
onClicked: {
view.currentIndex = index
cameraListPopup.currentValue = modelData.deviceId
cameraListPopup.selected(modelData.deviceId)
}
}
}
}
}

View File

@@ -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 examples of the Qt Toolkit.
@@ -70,37 +70,11 @@ Item {
anchors.right: parent.left
anchors.rightMargin: 16
anchors.top: parent.top
state: "invisible"
visible: opacity > 0
currentValue: propertyButton.value
states: [
State {
name: "invisible"
PropertyChanges { target: popup; opacity: 0 }
},
State {
name: "visible"
PropertyChanges { target: popup; opacity: 1.0 }
}
]
transitions: Transition {
NumberAnimation { properties: "opacity"; duration: 100 }
}
function toggle() {
if (state == "visible")
state = "invisible";
else
state = "visible";
}
onSelected: {
popup.state = "invisible"
}
onSelected: popup.toggle()
}
}

View File

@@ -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 examples of the Qt Toolkit.
@@ -40,7 +40,7 @@
import QtQuick 2.0
Rectangle {
Popup {
id: propertyPopup
property alias model : view.model
@@ -54,12 +54,6 @@ Rectangle {
width: columns*itemWidth + view.anchors.margins*2
height: Math.ceil(model.count/columns)*itemHeight + view.anchors.margins*2 + 25
radius: 5
border.color: "#000000"
border.width: 2
smooth: true
color: "#5e5e5e"
signal selected
function indexForValue(value) {

View File

@@ -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 examples of the Qt Toolkit.
@@ -39,7 +39,7 @@
****************************************************************************/
import QtQuick 2.0
import QtMultimedia 5.0
import QtMultimedia 5.4
FocusScope {
property Camera camera
@@ -53,7 +53,7 @@ FocusScope {
Rectangle {
id: buttonPaneShadow
width: buttonsColumn.width + 16
width: bottomColumn.width + 16
height: parent.height
anchors.top: parent.top
anchors.right: parent.right
@@ -130,12 +130,16 @@ FocusScope {
id: bottomColumn
spacing: 8
CameraListButton {
model: QtMultimedia.availableCameras
onValueChanged: captureControls.camera.deviceId = value
}
CameraButton {
text: "Switch to Video"
onClicked: captureControls.videoModeSelected()
}
CameraButton {
id: quitButton
text: "Quit"

View File

@@ -0,0 +1,76 @@
/****************************************************************************
**
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
** of its contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
import QtQuick 2.0
Rectangle {
id: popup
radius: 5
border.color: "#000000"
border.width: 2
smooth: true
color: "#5e5e5e"
state: "invisible"
states: [
State {
name: "invisible"
PropertyChanges { target: popup; opacity: 0 }
},
State {
name: "visible"
PropertyChanges { target: popup; opacity: 1.0 }
}
]
transitions: Transition {
NumberAnimation { properties: "opacity"; duration: 100 }
}
function toggle() {
if (state == "visible")
state = "invisible";
else
state = "visible";
}
}

View File

@@ -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 examples of the Qt Toolkit.
@@ -39,7 +39,7 @@
****************************************************************************/
import QtQuick 2.0
import QtMultimedia 5.0
import QtMultimedia 5.4
FocusScope {
property Camera camera
@@ -53,7 +53,7 @@ FocusScope {
Rectangle {
id: buttonPaneShadow
width: buttonsColumn.width + 16
width: bottomColumn.width + 16
height: parent.height
anchors.top: parent.top
anchors.right: parent.right
@@ -105,6 +105,11 @@ FocusScope {
id: bottomColumn
spacing: 8
CameraListButton {
model: QtMultimedia.availableCameras
onValueChanged: captureControls.camera.deviceId = value
}
CameraButton {
text: "Switch to Photo"
onClicked: captureControls.photoModeSelected()

View File

@@ -39,7 +39,7 @@
****************************************************************************/
import QtQuick 2.0
import QtMultimedia 5.2
import QtMultimedia 5.4
Rectangle {
id : cameraUI

View File

@@ -7,9 +7,12 @@
<file>FocusButton.qml</file>
<file>PhotoCaptureControls.qml</file>
<file>declarative-camera.qml</file>
<file>Popup.qml</file>
<file>CameraPropertyPopup.qml</file>
<file>CameraPropertyButton.qml</file>
<file>CameraButton.qml</file>
<file>CameraListPopup.qml</file>
<file>CameraListButton.qml</file>
<file>images/camera_auto_mode.png</file>
<file>images/camera_camera_setting.png</file>
<file>images/camera_flash_auto.png</file>

View File

@@ -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>();
}

View File

@@ -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

View File

@@ -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_camera = new QCamera;
m_currentCameraInfo = QCameraInfo(*m_camera);
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);
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, SIGNAL(stateChanged(QCamera::State)), this, SLOT(_q_updateState(QCamera::State)));
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, 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->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()
{
delete m_metaData;
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;
delete m_camera;
}
void QDeclarativeCamera::classBegin()
@@ -219,6 +245,173 @@ void QDeclarativeCamera::componentComplete()
setCameraState(m_pendingState);
}
/*!
\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;
}

View File

@@ -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;

View File

@@ -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

View File

@@ -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

View File

@@ -58,6 +58,16 @@ QCameraViewfinder *viewfinder = 0;
QMediaRecorder *recorder = 0;
QCameraImageCapture *imageCapture = 0;
//! [Camera overview check]
bool checkCameraAvailability()
{
if (QCameraInfo::availableCameras().count() > 0)
return true;
else
return false;
}
//! [Camera overview check]
void overview_viewfinder()
{
//! [Camera overview viewfinder]
@@ -70,6 +80,13 @@ void overview_viewfinder()
//! [Camera overview viewfinder]
}
void overview_camera_by_position()
{
//! [Camera overview position]
camera = new QCamera(QCamera::FrontFace);
//! [Camera overview position]
}
// -.-
class MyVideoSurface : public QAbstractVideoSurface
{

View File

@@ -90,6 +90,65 @@ Many of these tasks have classes to assist them.
\target camera-tldr
\section1 Camera Implementation Details
\section2 Detecting and Selecting Camera
Before using the camera APIs, you should check that a camera is available at runtime. If there
is none, you could for example disable camera related features in your application. To perform this
check in C++, use the \l QCameraInfo::availableCameras() function, as shown in the example below:
\snippet multimedia-snippets/camera.cpp Camera overview check
In QML, use the \l{QtMultimedia::QtMultimedia::availableCameras}{QtMultimedia.availableCameras}
property:
\qml
import QtQuick 2.0
import QtMultimedia 5.4
Item {
property bool isCameraAvailable: QtMultimedia.availableCameras.length > 0
}
\endqml
After determining whether a camera is available, access it using the \l QCamera class in C++ or
the \l Camera type in QML.
When multiple cameras are available, you can specify which one to use.
In C++:
\snippet multimedia-snippets/camera.cpp Camera selection
In QML, you can set the \c Camera \l{Camera::deviceId}{deviceId} property. All available IDs can
be retrieved from \l{QtMultimedia::QtMultimedia::availableCameras}{QtMultimedia.availableCameras}:
\qml
Camera {
deviceId: QtMultimedia.availableCameras[0].deviceId
}
\endqml
You can also select the camera by its physical position on the system rather than its device ID.
This is useful on mobile devices, which often have a front-facing and a back-facing camera.
In C++:
\snippet multimedia-snippets/camera.cpp Camera overview position
In QML:
\qml
Camera {
position: Camera.FrontFace
}
\endqml
If neither device ID nor position is specified, the default camera will be used. On desktop
platforms, the default camera is set by the user in the system settings. On a mobile device, the
back-facing camera is usually the default camera. You can get information about the default camera
using \l QCameraInfo::defaultCamera() in C++ or
\l{QtMultimedia::QtMultimedia::defaultCamera}{QtMultimedia.defaultCamera} in QML.
\section2 Viewfinder
While not strictly necessary, it's often useful to be able to see
@@ -105,7 +164,7 @@ simple viewfinder:
\qml
import QtQuick 2.0
import QtMultimedia 5.0
import QtMultimedia 5.4
VideoOutput {
source: camera

View File

@@ -177,7 +177,7 @@ what changed, and what you might need to change when porting code.
\section2 QML Types
The QML types are accessed by using:
\code
import QtMultimedia 5.0
import QtMultimedia 5.4
\endcode
\annotatedlist multimedia_qml
The following types are accessed by using \l{Qt Audio Engine QML Types}{Qt Audio Engine}:

View File

@@ -46,7 +46,7 @@
import statement in your \c {.qml} file.
\code
import QtMultimedia 5.0
import QtMultimedia 5.4
\endcode
If you intend to use the C++ classes in your application, include the C++

View File

@@ -26,7 +26,7 @@
****************************************************************************/
/*!
\qmlmodule QtMultimedia 5.0
\qmlmodule QtMultimedia 5.4
\title Qt Multimedia QML Types
\ingroup qmlmodules
\brief Provides QML types for multimedia support.
@@ -42,7 +42,7 @@ The QML types for \l{Qt Multimedia} support the basic use cases such as:
The QML types can be imported into your application using the following import
statement in your .qml file:
\code
import QtMultimedia 5.0
import QtMultimedia 5.4
\endcode
\section1 QML types

View File

@@ -421,6 +421,8 @@ void QDeclarativeVideoOutput::_q_screenOrientationChanged(int orientation)
The orientation change will also affect the mapping
of coordinates from source to viewport.
\sa autoOrientation
*/
int QDeclarativeVideoOutput::orientation() const
{
@@ -477,6 +479,7 @@ void QDeclarativeVideoOutput::setOrientation(int orientation)
By default \c autoOrientation is disabled.
\sa orientation
\since QtMultimedia 5.2
*/
bool QDeclarativeVideoOutput::autoOrientation() const

View File

@@ -1,7 +1,9 @@
TEMPLATE = subdirs
SUBDIRS += \
qdeclarativemultimediaglobal \
qdeclarativeaudio \
qdeclarativecamera
disabled {
SUBDIRS += \

View File

@@ -0,0 +1,15 @@
TARGET = tst_qdeclarativecamera
CONFIG += warn_on qmltestcase
QT += multimedia-private
include (../qmultimedia_common/mock.pri)
include (../qmultimedia_common/mockcamera.pri)
SOURCES += \
tst_qdeclarativecamera.cpp
DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
OTHER_FILES += \
tst_qdeclarativecamera.qml

View File

@@ -0,0 +1,55 @@
/****************************************************************************
**
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** 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 <QtQuickTest/quicktest.h>
#include "mockcameraservice.h"
#include "mockmediaserviceprovider.h"
int main(int argc, char **argv)
{
MockMediaServiceProvider provider;
MockCameraService mockCameraService;
provider.service = &mockCameraService;
QMediaServiceProvider::setDefaultServiceProvider(&provider);
return quick_test_main(argc, argv, "QDeclarativeCamera", QUICK_TEST_SOURCE_DIR);
}

View File

@@ -0,0 +1,155 @@
/****************************************************************************
**
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** 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$
**
****************************************************************************/
import QtQuick 2.0
import QtTest 1.0
import QtMultimedia 5.4
TestCase {
Component {
id: cameraComponent
Camera { }
}
Loader {
id: cameraLoader
}
SignalSpy {
id: deviceIdSpy
target: cameraLoader.item
signalName: "deviceIdChanged"
}
function test_deviceId() {
deviceIdSpy.clear();
cameraLoader.sourceComponent = cameraComponent;
var camera = cameraLoader.item;
// default camera
compare(camera.deviceId, "othercamera", "deviceId");
compare(camera.displayName, "othercamera desc", "displayName");
compare(camera.position, Camera.UnspecifiedPosition, "position");
compare(camera.orientation, 0, "orientation");
// setting an invalid camera ID should leave the item unchanged
camera.deviceId = "invalidcamera";
compare(camera.deviceId, "othercamera");
compare(deviceIdSpy.count, 0);
compare(camera.displayName, "othercamera desc", "displayName");
compare(camera.position, Camera.UnspecifiedPosition, "position");
compare(camera.orientation, 0, "orientation");
// change to another valid camera
camera.deviceId = "backcamera";
compare(camera.deviceId, "backcamera");
compare(deviceIdSpy.count, 1);
compare(camera.displayName, "backcamera desc", "displayName");
compare(camera.position, Camera.BackFace, "position");
compare(camera.orientation, 90, "orientation");
// setting an empty device ID should load the default camera
camera.deviceId = "";
compare(camera.deviceId, "othercamera", "deviceId");
compare(deviceIdSpy.count, 2);
cameraLoader.sourceComponent = undefined;
}
function test_position() {
deviceIdSpy.clear();
cameraLoader.sourceComponent = cameraComponent;
var camera = cameraLoader.item;
// default camera
compare(camera.position, Camera.UnspecifiedPosition, "position");
compare(camera.deviceId, "othercamera", "deviceId");
// setting an unavailable camera position should leave the item unchanged
camera.position = Camera.FrontFace;
compare(camera.position, Camera.UnspecifiedPosition, "position");
compare(camera.deviceId, "othercamera", "deviceId");
compare(deviceIdSpy.count, 0);
// change to an available position
camera.position = Camera.BackFace;
compare(camera.position, Camera.BackFace, "position");
compare(camera.deviceId, "backcamera", "deviceId");
compare(deviceIdSpy.count, 1);
// setting UnspecifiedPosition should load the default camera
camera.position = Camera.UnspecifiedPosition;
compare(camera.position, Camera.UnspecifiedPosition, "position");
compare(camera.deviceId, "othercamera", "deviceId");
compare(deviceIdSpy.count, 2);
cameraLoader.sourceComponent = undefined;
}
SignalSpy {
id: cameraStateSpy
target: cameraLoader.item
signalName: "cameraStateChanged"
}
function test_cameraState() {
deviceIdSpy.clear();
cameraStateSpy.clear();
cameraLoader.sourceComponent = cameraComponent;
var camera = cameraLoader.item;
// camera should be in ActiveState by default
compare(camera.cameraState, Camera.ActiveState, "cameraState");
compare(camera.deviceId, "othercamera", "deviceId");
// Changing the camera device should unload the previous camera and apply the current state
// to the new camera
camera.deviceId = "backcamera";
compare(camera.deviceId, "backcamera", "deviceId");
compare(camera.cameraState, Camera.ActiveState, "cameraState");
compare(cameraStateSpy.count, 2);
compare(cameraStateSpy.signalArguments[0][0], Camera.UnloadedState);
compare(cameraStateSpy.signalArguments[1][0], Camera.ActiveState);
cameraLoader.sourceComponent = undefined;
}
}

View File

@@ -0,0 +1,15 @@
TARGET = tst_qdeclarativemultimediaglobal
CONFIG += warn_on qmltestcase
QT += multimedia-private
include (../qmultimedia_common/mock.pri)
include (../qmultimedia_common/mockcamera.pri)
SOURCES += \
tst_qdeclarativemultimediaglobal.cpp
DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
OTHER_FILES += \
tst_qdeclarativemultimediaglobal.qml

View File

@@ -0,0 +1,55 @@
/****************************************************************************
**
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** 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 <QtQuickTest/quicktest.h>
#include "mockcameraservice.h"
#include "mockmediaserviceprovider.h"
int main(int argc, char **argv)
{
MockMediaServiceProvider provider;
MockCameraService mockCameraService;
provider.service = &mockCameraService;
QMediaServiceProvider::setDefaultServiceProvider(&provider);
return quick_test_main(argc, argv, "QDeclarativeMultimediaGlobal", QUICK_TEST_SOURCE_DIR);
}

View File

@@ -0,0 +1,79 @@
/****************************************************************************
**
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** 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$
**
****************************************************************************/
import QtQuick 2.0
import QtTest 1.0
import QtMultimedia 5.4
TestCase {
function test_0_globalObject() {
verify(typeof QtMultimedia !== 'undefined');
}
function test_1_defaultCamera() {
verify(typeof QtMultimedia.defaultCamera !== 'undefined');
var camera = QtMultimedia.defaultCamera;
compare(camera.deviceId, "othercamera", "deviceId");
compare(camera.displayName, "othercamera desc", "displayName");
compare(camera.position, Camera.UnspecifiedPosition, "position");
compare(camera.orientation, 0, "orientation");
}
function test_2_availableCameras() {
verify(typeof QtMultimedia.availableCameras !== 'undefined');
compare(QtMultimedia.availableCameras.length, 2);
var camera = QtMultimedia.availableCameras[0];
compare(camera.deviceId, "backcamera", "deviceId");
compare(camera.displayName, "backcamera desc", "displayName");
compare(camera.position, Camera.BackFace, "position");
compare(camera.orientation, 90, "orientation");
camera = QtMultimedia.availableCameras[1];
compare(camera.deviceId, "othercamera", "deviceId");
compare(camera.displayName, "othercamera desc", "displayName");
compare(camera.position, Camera.UnspecifiedPosition, "position");
compare(camera.orientation, 0, "orientation");
}
}

View File

@@ -1,5 +1,5 @@
INCLUDEPATH += $$PWD \
../../../src/multimedia \
../../../../src/multimedia \
HEADERS *= \
../qmultimedia_common/mockmediaserviceprovider.h \

View File

@@ -1,8 +1,8 @@
# Camera related mock backend files
INCLUDEPATH += $$PWD \
../../../src/multimedia \
../../../src/multimedia/video \
../../../src/multimedia/camera
../../../../src/multimedia \
../../../../src/multimedia/video \
../../../../src/multimedia/camera
HEADERS *= \
../qmultimedia_common/mockcameraservice.h \

View File

@@ -42,7 +42,7 @@
#ifndef MOCKMEDIASERVICEPROVIDER_H
#define MOCKMEDIASERVICEPROVIDER_H
#include "private/qmediaserviceprovider_p.h"
#include "qmediaserviceprovider_p.h"
#include "qmediaservice.h"
#include "mockvideodeviceselectorcontrol.h"
#include "mockcamerainfocontrol.h"