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:
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user