1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40
41#include "qcamera_p.h"
42#include "qmediaserviceprovider_p.h"
43
44#include <qcamerainfo.h>
45#include <qcameracontrol.h>
46#include <qcameralockscontrol.h>
47#include <qcameraexposurecontrol.h>
48#include <qcamerafocuscontrol.h>
49#include <qmediarecordercontrol.h>
50#include <qcameraimageprocessingcontrol.h>
51#include <qcameraimagecapturecontrol.h>
52#include <qvideodeviceselectorcontrol.h>
53#include <qcamerainfocontrol.h>
54#include <qcameraviewfindersettingscontrol.h>
55
56#include <QDebug>
57
58QT_BEGIN_NAMESPACE
59
60static void qRegisterCameraMetaTypes()
61{
62 qRegisterMetaType<QCamera::Error>("QCamera::Error");
63 qRegisterMetaType<QCamera::State>("QCamera::State");
64 qRegisterMetaType<QCamera::Status>("QCamera::Status");
65 qRegisterMetaType<QCamera::CaptureModes>("QCamera::CaptureModes");
66 qRegisterMetaType<QCamera::LockType>("QCamera::LockType");
67 qRegisterMetaType<QCamera::LockStatus>("QCamera::LockStatus");
68 qRegisterMetaType<QCamera::LockChangeReason>("QCamera::LockChangeReason");
69 qRegisterMetaType<QCamera::Position>("QCamera::Position");
70}
71
72Q_CONSTRUCTOR_FUNCTION(qRegisterCameraMetaTypes)
73
74Q_DECL_CONSTEXPR static bool qt_sizeLessThan(const QSize &s1, const QSize &s2) Q_DECL_NOTHROW
75{
76 return (s1.width() * s1.height()) < (s2.width() * s2.height());
77}
78
79Q_DECL_CONSTEXPR static bool qt_frameRateRangeLessThan(const QCamera::FrameRateRange &s1, const QCamera::FrameRateRange &s2) Q_DECL_NOTHROW
80{
81 return qFuzzyCompare(s1.maximumFrameRate, s2.maximumFrameRate) ? (s1.minimumFrameRate < s2.minimumFrameRate)
82 : (s1.maximumFrameRate < s2.maximumFrameRate);
83}
84
85/*!
86 \class QCamera
87
88
89 \brief The QCamera class provides interface for system camera devices.
90
91 \inmodule QtMultimedia
92 \ingroup multimedia
93 \ingroup multimedia_camera
94
95 QCamera can be used with QCameraViewfinder for viewfinder display,
96 QMediaRecorder for video recording and QCameraImageCapture for image taking.
97
98 You can use QCameraInfo to list available cameras and choose which one to use.
99
100 \snippet multimedia-snippets/camera.cpp Camera selection
101
102 See the \l{Camera Overview}{camera overview} for more information.
103*/
104
105void QCameraPrivate::_q_error(int error, const QString &errorString)
106{
107 Q_Q(QCamera);
108
109 this->error = QCamera::Error(error);
110 this->errorString = errorString;
111
112 emit q->error(this->error);
113}
114
115void QCameraPrivate::setState(QCamera::State newState)
116{
117 unsetError();
118
119 if (!control) {
120 _q_error(QCamera::ServiceMissingError, QCamera::tr("The camera service is missing"));
121 return;
122 }
123
124 restartPending = false;
125 control->setState(newState);
126}
127
128void QCameraPrivate::_q_updateState(QCamera::State newState)
129{
130 Q_Q(QCamera);
131
132 //omit changins state to Loaded when the camera is temporarily
133 //stopped to apply shanges
134 if (restartPending)
135 return;
136
137 if (newState != state) {
138 state = newState;
139 emit q->stateChanged(state);
140 }
141}
142
143void QCameraPrivate::_q_preparePropertyChange(int changeType)
144{
145 if (!control)
146 return;
147
148 QCamera::Status status = control->status();
149
150 //all the changes are allowed until the camera is starting
151 if (control->state() != QCamera::ActiveState)
152 return;
153
154 if (control->canChangeProperty(QCameraControl::PropertyChangeType(changeType), status))
155 return;
156
157 restartPending = true;
158 control->setState(QCamera::LoadedState);
159 QMetaObject::invokeMethod(q_ptr, "_q_restartCamera", Qt::QueuedConnection);
160}
161
162void QCameraPrivate::_q_restartCamera()
163{
164 if (restartPending) {
165 restartPending = false;
166 control->setState(QCamera::ActiveState);
167 }
168}
169
170void QCameraPrivate::init()
171{
172 Q_Q(QCamera);
173 provider = QMediaServiceProvider::defaultServiceProvider();
174 initControls();
175 cameraExposure = new QCameraExposure(q);
176 cameraFocus = new QCameraFocus(q);
177 imageProcessing = new QCameraImageProcessing(q);
178}
179
180void QCameraPrivate::initControls()
181{
182 Q_Q(QCamera);
183
184 if (service) {
185 control = qobject_cast<QCameraControl *>(service->requestControl(QCameraControl_iid));
186 locksControl = qobject_cast<QCameraLocksControl *>(service->requestControl(QCameraLocksControl_iid));
187 deviceControl = qobject_cast<QVideoDeviceSelectorControl*>(service->requestControl(QVideoDeviceSelectorControl_iid));
188 infoControl = qobject_cast<QCameraInfoControl*>(service->requestControl(QCameraInfoControl_iid));
189 viewfinderSettingsControl2 = qobject_cast<QCameraViewfinderSettingsControl2*>(service->requestControl(QCameraViewfinderSettingsControl2_iid));
190 if (!viewfinderSettingsControl2)
191 viewfinderSettingsControl = qobject_cast<QCameraViewfinderSettingsControl*>(service->requestControl(QCameraViewfinderSettingsControl_iid));
192
193 if (control) {
194 q->connect(control, SIGNAL(stateChanged(QCamera::State)), q, SLOT(_q_updateState(QCamera::State)));
195 q->connect(control, SIGNAL(statusChanged(QCamera::Status)), q, SIGNAL(statusChanged(QCamera::Status)));
196 q->connect(control, SIGNAL(captureModeChanged(QCamera::CaptureModes)),
197 q, SIGNAL(captureModeChanged(QCamera::CaptureModes)));
198 q->connect(control, SIGNAL(error(int,QString)), q, SLOT(_q_error(int,QString)));
199
200 }
201
202 if (locksControl) {
203 q->connect(locksControl, SIGNAL(lockStatusChanged(QCamera::LockType,QCamera::LockStatus,QCamera::LockChangeReason)),
204 q, SLOT(_q_updateLockStatus(QCamera::LockType,QCamera::LockStatus,QCamera::LockChangeReason)));
205 }
206
207 error = QCamera::NoError;
208 } else {
209 control = nullptr;
210 locksControl = nullptr;
211 deviceControl = nullptr;
212 infoControl = nullptr;
213 viewfinderSettingsControl = nullptr;
214 viewfinderSettingsControl2 = nullptr;
215
216 error = QCamera::ServiceMissingError;
217 errorString = QCamera::tr("The camera service is missing");
218 }
219}
220
221void QCameraPrivate::clear()
222{
223 delete cameraExposure;
224 delete cameraFocus;
225 delete imageProcessing;
226
227 if (service) {
228 if (control)
229 service->releaseControl(control);
230 if (locksControl)
231 service->releaseControl(locksControl);
232 if (deviceControl)
233 service->releaseControl(deviceControl);
234 if (infoControl)
235 service->releaseControl(infoControl);
236 if (viewfinderSettingsControl)
237 service->releaseControl(viewfinderSettingsControl);
238 if (viewfinderSettingsControl2)
239 service->releaseControl(viewfinderSettingsControl2);
240
241 provider->releaseService(service);
242 }
243
244 cameraExposure = nullptr;
245 cameraFocus = nullptr;
246 imageProcessing = nullptr;
247 control = nullptr;
248 locksControl = nullptr;
249 deviceControl = nullptr;
250 infoControl = nullptr;
251 viewfinderSettingsControl = nullptr;
252 viewfinderSettingsControl2 = nullptr;
253 service = nullptr;
254}
255
256void QCameraPrivate::updateLockStatus()
257{
258 Q_Q(QCamera);
259
260 QCamera::LockStatus oldStatus = lockStatus;
261
262 QMap<QCamera::LockStatus, int> lockStatusPriority;
263 lockStatusPriority.insert(QCamera::Locked, 1);
264 lockStatusPriority.insert(QCamera::Unlocked, 2);
265 lockStatusPriority.insert(QCamera::Searching, 3);
266
267 lockStatus = requestedLocks ? QCamera::Locked : QCamera::Unlocked;
268 int priority = 0;
269
270 QList<QCamera::LockStatus> lockStatuses;
271
272 if (requestedLocks & QCamera::LockFocus)
273 lockStatuses << q->lockStatus(QCamera::LockFocus);
274
275 if (requestedLocks & QCamera::LockExposure)
276 lockStatuses << q->lockStatus(QCamera::LockExposure);
277
278 if (requestedLocks & QCamera::LockWhiteBalance)
279 lockStatuses << q->lockStatus(QCamera::LockWhiteBalance);
280
281
282 for (QCamera::LockStatus currentStatus : qAsConst(lockStatuses)) {
283 int currentPriority = lockStatusPriority.value(currentStatus, -1);
284 if (currentPriority > priority) {
285 priority = currentPriority;
286 lockStatus = currentStatus;
287 }
288 }
289
290 if (!supressLockChangedSignal && oldStatus != lockStatus) {
291 emit q->lockStatusChanged(lockStatus, lockChangeReason);
292
293 if (lockStatus == QCamera::Locked)
294 emit q->locked();
295 else if (lockStatus == QCamera::Unlocked && lockChangeReason == QCamera::LockFailed)
296 emit q->lockFailed();
297 }
298/*
299 qDebug() << "Requested locks:" << (requestedLocks & QCamera::LockExposure ? 'e' : ' ')
300 << (requestedLocks & QCamera::LockFocus ? 'f' : ' ')
301 << (requestedLocks & QCamera::LockWhiteBalance ? 'w' : ' ');
302 qDebug() << "Lock status: f:" << q->lockStatus(QCamera::LockFocus)
303 << " e:" << q->lockStatus(QCamera::LockExposure)
304 << " w:" << q->lockStatus(QCamera::LockWhiteBalance)
305 << " composite:" << lockStatus;
306*/
307}
308
309void QCameraPrivate::_q_updateLockStatus(QCamera::LockType type, QCamera::LockStatus status, QCamera::LockChangeReason reason)
310{
311 Q_Q(QCamera);
312 lockChangeReason = reason;
313 updateLockStatus();
314 emit q->lockStatusChanged(type, status, reason);
315}
316
317
318/*!
319 Construct a QCamera with a \a parent.
320*/
321
322QCamera::QCamera(QObject *parent):
323 QMediaObject(*new QCameraPrivate,
324 parent,
325 QMediaServiceProvider::defaultServiceProvider()->requestService(Q_MEDIASERVICE_CAMERA))
326{
327 Q_D(QCamera);
328 d->init();
329
330 // Select the default camera
331 if (d->service != nullptr && d->deviceControl)
332 d->deviceControl->setSelectedDevice(d->deviceControl->defaultDevice());
333}
334
335/*!
336 Construct a QCamera from \a deviceName and \a parent.
337
338 If no camera with that \a deviceName exists, the camera object will
339 be invalid.
340*/
341
342QCamera::QCamera(const QByteArray& deviceName, QObject *parent):
343 QMediaObject(*new QCameraPrivate, parent,
344 QMediaServiceProvider::defaultServiceProvider()->requestService(Q_MEDIASERVICE_CAMERA,
345 QMediaServiceProviderHint(deviceName)))
346{
347 Q_D(QCamera);
348 d->init();
349
350 bool found = false;
351 // Pass device name to service.
352 if (d->deviceControl) {
353 const QString name = QString::fromLatin1(deviceName);
354 for (int i = 0; i < d->deviceControl->deviceCount(); i++) {
355 if (d->deviceControl->deviceName(i) == name) {
356 d->deviceControl->setSelectedDevice(i);
357 found = true;
358 break;
359 }
360 }
361 }
362
363 // The camera should not be used if device with requested name does not exist.
364 if (!found) {
365 if (d->service) {
366 if (d->control)
367 d->service->releaseControl(d->control);
368 if (d->deviceControl)
369 d->service->releaseControl(d->deviceControl);
370 if (d->infoControl)
371 d->service->releaseControl(d->infoControl);
372 }
373 d->control = nullptr;
374 d->deviceControl = nullptr;
375 d->infoControl = nullptr;
376 d->error = QCamera::ServiceMissingError;
377 d->errorString = QCamera::tr("The camera service is missing");
378 }
379}
380
381/*!
382 \since 5.3
383
384 Construct a QCamera from a camera description \a cameraInfo and \a parent.
385*/
386
387QCamera::QCamera(const QCameraInfo &cameraInfo, QObject *parent)
388 : QCamera(cameraInfo.deviceName().toLatin1(), parent)
389{
390}
391
392/*!
393 \since 5.3
394
395 Construct a QCamera which uses a hardware camera located a the specified \a position.
396
397 For example on a mobile phone it can be used to easily choose between front-facing and
398 back-facing cameras.
399
400 If no camera is available at the specified \a position or if \a position is
401 QCamera::UnspecifiedPosition, the default camera is used.
402*/
403
404QCamera::QCamera(QCamera::Position position, QObject *parent)
405 : QMediaObject(*new QCameraPrivate,
406 parent,
407 QMediaServiceProvider::defaultServiceProvider()->requestService(Q_MEDIASERVICE_CAMERA, QMediaServiceProviderHint(position)))
408{
409 Q_D(QCamera);
410 d->init();
411
412 if (d->service != nullptr && d->deviceControl) {
413 bool selectDefault = true;
414
415 if (d->infoControl && position != UnspecifiedPosition) {
416 for (int i = 0; i < d->deviceControl->deviceCount(); i++) {
417 if (d->infoControl->cameraPosition(d->deviceControl->deviceName(i)) == position) {
418 d->deviceControl->setSelectedDevice(i);
419 selectDefault = false;
420 break;
421 }
422 }
423 }
424
425 if (selectDefault)
426 d->deviceControl->setSelectedDevice(d->deviceControl->defaultDevice());
427 }
428}
429
430/*!
431 Destroys the camera object.
432*/
433
434QCamera::~QCamera()
435{
436 Q_D(QCamera);
437 d->clear();
438}
439
440/*!
441 Returns the availability state of the camera service.
442*/
443QMultimedia::AvailabilityStatus QCamera::availability() const
444{
445 Q_D(const QCamera);
446 if (d->control == nullptr)
447 return QMultimedia::ServiceMissing;
448
449 if (d->deviceControl && d->deviceControl->deviceCount() == 0)
450 return QMultimedia::ResourceError;
451
452 if (d->error != QCamera::NoError)
453 return QMultimedia::ResourceError;
454
455 return QMediaObject::availability();
456}
457
458
459/*!
460 Returns the camera exposure control object.
461*/
462QCameraExposure *QCamera::exposure() const
463{
464 return d_func()->cameraExposure;
465}
466
467/*!
468 Returns the camera focus control object.
469*/
470QCameraFocus *QCamera::focus() const
471{
472 return d_func()->cameraFocus;
473}
474
475/*!
476 Returns the camera image processing control object.
477*/
478QCameraImageProcessing *QCamera::imageProcessing() const
479{
480 return d_func()->imageProcessing;
481}
482
483/*!
484 Sets the QVideoWidget based camera \a viewfinder.
485 The previously set viewfinder is detached.
486
487 //! QVideoWidget is forward declared.
488*/
489void QCamera::setViewfinder(QVideoWidget *viewfinder)
490{
491 Q_D(QCamera);
492 d->_q_preparePropertyChange(QCameraControl::Viewfinder);
493
494 if (d->viewfinder)
495 unbind(d->viewfinder);
496
497 // We don't know (in this library) that QVideoWidget inherits QObject
498 QObject *viewFinderObject = reinterpret_cast<QObject*>(viewfinder);
499
500 d->viewfinder = viewFinderObject && bind(viewFinderObject) ? viewFinderObject : nullptr;
501}
502
503/*!
504 Sets the QGraphicsVideoItem based camera \a viewfinder.
505 The previously set viewfinder is detached.
506
507 //! QGraphicsVideoItem is forward declared.
508*/
509void QCamera::setViewfinder(QGraphicsVideoItem *viewfinder)
510{
511 Q_D(QCamera);
512 d->_q_preparePropertyChange(QCameraControl::Viewfinder);
513
514 if (d->viewfinder)
515 unbind(d->viewfinder);
516
517 // We don't know (in this library) that QGraphicsVideoItem (multiply) inherits QObject
518 // but QObject inheritance depends on QObject coming first, so try this out.
519 QObject *viewFinderObject = reinterpret_cast<QObject*>(viewfinder);
520
521 d->viewfinder = viewFinderObject && bind(viewFinderObject) ? viewFinderObject : nullptr;
522}
523
524/*!
525 Sets a video \a surface as the viewfinder of a camera.
526
527 If a viewfinder has already been set on the camera the new surface
528 will replace it.
529*/
530
531void QCamera::setViewfinder(QAbstractVideoSurface *surface)
532{
533 Q_D(QCamera);
534
535 d->surfaceViewfinder.setVideoSurface(surface);
536
537 if (d->viewfinder != &d->surfaceViewfinder) {
538 if (d->viewfinder)
539 unbind(d->viewfinder);
540
541 d->viewfinder = nullptr;
542
543 if (surface && bind(&d->surfaceViewfinder))
544 d->viewfinder = &d->surfaceViewfinder;
545 } else if (!surface) {
546 //unbind the surfaceViewfinder if null surface is set
547 unbind(&d->surfaceViewfinder);
548 d->viewfinder = nullptr;
549 }
550}
551
552/*!
553 Returns the viewfinder settings being used by the camera.
554
555 Settings may change when the camera is started, for example if the viewfinder settings
556 are undefined or if unsupported values are set.
557
558 If viewfinder settings are not supported by the camera, it always returns a null
559 QCameraViewfinderSettings object.
560
561 \sa setViewfinderSettings()
562
563 \since 5.5
564*/
565QCameraViewfinderSettings QCamera::viewfinderSettings() const
566{
567 Q_D(const QCamera);
568
569 if (d->viewfinderSettingsControl2)
570 return d->viewfinderSettingsControl2->viewfinderSettings();
571
572 QCameraViewfinderSettings settings;
573 if (d->viewfinderSettingsControl) {
574 if (d->viewfinderSettingsControl->isViewfinderParameterSupported(QCameraViewfinderSettingsControl::Resolution))
575 settings.setResolution(d->viewfinderSettingsControl->viewfinderParameter(QCameraViewfinderSettingsControl::Resolution).toSize());
576
577 if (d->viewfinderSettingsControl->isViewfinderParameterSupported(QCameraViewfinderSettingsControl::MinimumFrameRate))
578 settings.setMinimumFrameRate(d->viewfinderSettingsControl->viewfinderParameter(QCameraViewfinderSettingsControl::MinimumFrameRate).toReal());
579
580 if (d->viewfinderSettingsControl->isViewfinderParameterSupported(QCameraViewfinderSettingsControl::MaximumFrameRate))
581 settings.setMaximumFrameRate(d->viewfinderSettingsControl->viewfinderParameter(QCameraViewfinderSettingsControl::MaximumFrameRate).toReal());
582
583 if (d->viewfinderSettingsControl->isViewfinderParameterSupported(QCameraViewfinderSettingsControl::PixelAspectRatio))
584 settings.setPixelAspectRatio(d->viewfinderSettingsControl->viewfinderParameter(QCameraViewfinderSettingsControl::PixelAspectRatio).toSize());
585
586 if (d->viewfinderSettingsControl->isViewfinderParameterSupported(QCameraViewfinderSettingsControl::PixelFormat))
587 settings.setPixelFormat(qvariant_cast<QVideoFrame::PixelFormat>(d->viewfinderSettingsControl->viewfinderParameter(QCameraViewfinderSettingsControl::PixelFormat)));
588 }
589 return settings;
590}
591
592/*!
593 Sets the viewfinder \a settings.
594
595 If some parameters are not specified, or null settings are passed, the camera will choose
596 default values.
597
598 If the camera is used to capture videos or images, the viewfinder settings might be
599 ignored if they conflict with the capture settings. You can check the actual viewfinder settings
600 once the camera is in the \c QCamera::ActiveStatus status.
601
602 Changing the viewfinder settings while the camera is in the QCamera::ActiveState state may
603 cause the camera to be restarted.
604
605 \sa viewfinderSettings(), supportedViewfinderResolutions(), supportedViewfinderFrameRateRanges(),
606 supportedViewfinderPixelFormats()
607
608 \since 5.5
609*/
610void QCamera::setViewfinderSettings(const QCameraViewfinderSettings &settings)
611{
612 Q_D(QCamera);
613
614 if (d->viewfinderSettingsControl || d->viewfinderSettingsControl2)
615 d->_q_preparePropertyChange(QCameraControl::ViewfinderSettings);
616
617 if (d->viewfinderSettingsControl2) {
618 d->viewfinderSettingsControl2->setViewfinderSettings(settings);
619
620 } else if (d->viewfinderSettingsControl) {
621 if (d->viewfinderSettingsControl->isViewfinderParameterSupported(QCameraViewfinderSettingsControl::Resolution))
622 d->viewfinderSettingsControl->setViewfinderParameter(QCameraViewfinderSettingsControl::Resolution, settings.resolution());
623
624 if (d->viewfinderSettingsControl->isViewfinderParameterSupported(QCameraViewfinderSettingsControl::MinimumFrameRate))
625 d->viewfinderSettingsControl->setViewfinderParameter(QCameraViewfinderSettingsControl::MinimumFrameRate, settings.minimumFrameRate());
626
627 if (d->viewfinderSettingsControl->isViewfinderParameterSupported(QCameraViewfinderSettingsControl::MaximumFrameRate))
628 d->viewfinderSettingsControl->setViewfinderParameter(QCameraViewfinderSettingsControl::MaximumFrameRate, settings.maximumFrameRate());
629
630 if (d->viewfinderSettingsControl->isViewfinderParameterSupported(QCameraViewfinderSettingsControl::PixelAspectRatio))
631 d->viewfinderSettingsControl->setViewfinderParameter(QCameraViewfinderSettingsControl::PixelAspectRatio, settings.pixelAspectRatio());
632
633 if (d->viewfinderSettingsControl->isViewfinderParameterSupported(QCameraViewfinderSettingsControl::PixelFormat))
634 d->viewfinderSettingsControl->setViewfinderParameter(QCameraViewfinderSettingsControl::PixelFormat, settings.pixelFormat());
635 }
636}
637
638/*!
639 Returns a list of supported viewfinder settings.
640
641 The list is ordered by preference; preferred settings come first.
642
643 The optional \a settings argument can be used to conveniently filter the results.
644 If \a settings is non null, the returned list is reduced to settings matching the given partial
645 \a settings.
646
647 The status of the camera must be LoadedStatus before calling this function, otherwise the returned list
648 is empty.
649
650 \sa setViewfinderSettings(), supportedViewfinderResolutions(), supportedViewfinderFrameRateRanges(),
651 supportedViewfinderPixelFormats()
652
653 \since 5.5
654*/
655QList<QCameraViewfinderSettings> QCamera::supportedViewfinderSettings(const QCameraViewfinderSettings &settings) const
656{
657 Q_D(const QCamera);
658
659 if (!d->viewfinderSettingsControl2)
660 return QList<QCameraViewfinderSettings>();
661
662 if (settings.isNull())
663 return d->viewfinderSettingsControl2->supportedViewfinderSettings();
664
665 QList<QCameraViewfinderSettings> results;
666 const QList<QCameraViewfinderSettings> supported = d->viewfinderSettingsControl2->supportedViewfinderSettings();
667 for (const QCameraViewfinderSettings &s : supported) {
668 if ((settings.resolution().isEmpty() || settings.resolution() == s.resolution())
669 && (qFuzzyIsNull(settings.minimumFrameRate()) || qFuzzyCompare((float)settings.minimumFrameRate(), (float)s.minimumFrameRate()))
670 && (qFuzzyIsNull(settings.maximumFrameRate()) || qFuzzyCompare((float)settings.maximumFrameRate(), (float)s.maximumFrameRate()))
671 && (settings.pixelFormat() == QVideoFrame::Format_Invalid || settings.pixelFormat() == s.pixelFormat())
672 && (settings.pixelAspectRatio().isEmpty() || settings.pixelAspectRatio() == s.pixelAspectRatio())) {
673 results.append(s);
674 }
675 }
676
677 return results;
678}
679
680/*!
681 Returns a list of supported viewfinder resolutions.
682
683 This is a convenience function which retrieves unique resolutions from the supported settings.
684
685 If non null viewfinder \a settings are passed, the returned list is reduced to resolutions
686 supported with partial \a settings applied.
687
688 The camera must be loaded before calling this function, otherwise the returned list
689 is empty.
690
691 \sa QCameraViewfinderSettings::resolution(), setViewfinderSettings()
692
693 \since 5.5
694*/
695QList<QSize> QCamera::supportedViewfinderResolutions(const QCameraViewfinderSettings &settings) const
696{
697 QList<QSize> resolutions;
698 const QList<QCameraViewfinderSettings> capabilities = supportedViewfinderSettings(settings);
699 for (const QCameraViewfinderSettings &s : capabilities) {
700 if (!resolutions.contains(s.resolution()))
701 resolutions.append(s.resolution());
702 }
703 std::sort(resolutions.begin(), resolutions.end(), qt_sizeLessThan);
704
705 return resolutions;
706}
707
708/*!
709 Returns a list of supported viewfinder frame rate ranges.
710
711 This is a convenience function which retrieves unique frame rate ranges from the supported settings.
712
713 If non null viewfinder \a settings are passed, the returned list is reduced to frame rate ranges
714 supported with partial \a settings applied.
715
716 The camera must be loaded before calling this function, otherwise the returned list
717 is empty.
718
719 \sa QCameraViewfinderSettings::minimumFrameRate(), QCameraViewfinderSettings::maximumFrameRate(),
720 setViewfinderSettings()
721
722 \since 5.5
723*/
724QList<QCamera::FrameRateRange> QCamera::supportedViewfinderFrameRateRanges(const QCameraViewfinderSettings &settings) const
725{
726 QList<QCamera::FrameRateRange> frameRateRanges;
727 const QList<QCameraViewfinderSettings> capabilities = supportedViewfinderSettings(settings);
728 for (const QCameraViewfinderSettings &s : capabilities) {
729 QCamera::FrameRateRange range(s.minimumFrameRate(), s.maximumFrameRate());
730 if (!frameRateRanges.contains(range))
731 frameRateRanges.append(range);
732 }
733 std::sort(frameRateRanges.begin(), frameRateRanges.end(), qt_frameRateRangeLessThan);
734
735 return frameRateRanges;
736}
737
738/*!
739 Returns a list of supported viewfinder pixel formats.
740
741 This is a convenience function which retrieves unique pixel formats from the supported settings.
742
743 If non null viewfinder \a settings are passed, the returned list is reduced to pixel formats
744 supported with partial \a settings applied.
745
746 The camera must be loaded before calling this function, otherwise the returned list
747 is empty.
748
749 \sa QCameraViewfinderSettings::pixelFormat(), setViewfinderSettings()
750
751 \since 5.5
752*/
753QList<QVideoFrame::PixelFormat> QCamera::supportedViewfinderPixelFormats(const QCameraViewfinderSettings &settings) const
754{
755 QList<QVideoFrame::PixelFormat> pixelFormats;
756 const QList<QCameraViewfinderSettings> capabilities = supportedViewfinderSettings(settings);
757 for (const QCameraViewfinderSettings &s : capabilities) {
758 if (!pixelFormats.contains(s.pixelFormat()))
759 pixelFormats.append(s.pixelFormat());
760 }
761
762 return pixelFormats;
763}
764
765/*!
766 Returns the error state of the object.
767*/
768
769QCamera::Error QCamera::error() const
770{
771 return d_func()->error;
772}
773
774/*!
775 Returns a string describing a camera's error state.
776*/
777QString QCamera::errorString() const
778{
779 return d_func()->errorString;
780}
781
782
783/*!
784 Returns true if the capture \a mode is suported.
785*/
786bool QCamera::isCaptureModeSupported(QCamera::CaptureModes mode) const
787{
788 return d_func()->control ? d_func()->control->isCaptureModeSupported(mode) : false;
789}
790
791/*!
792 \property QCamera::captureMode
793
794 The type of media (video or still images),
795 the camera is configured to capture.
796
797 It's allowed to change capture mode in any camera state,
798 but if the camera is currently active,
799 chaging capture mode is likely to lead to camera status
800 chaged to QCamera::LoadedStatus, QCamera::LoadingStatus,
801 and when the camera is ready to QCamera::ActiveStatus.
802*/
803
804QCamera::CaptureModes QCamera::captureMode() const
805{
806 return d_func()->control ? d_func()->control->captureMode() : QCamera::CaptureStillImage;
807}
808
809void QCamera::setCaptureMode(QCamera::CaptureModes mode)
810{
811 Q_D(QCamera);
812
813 if (mode != captureMode()) {
814 if (d->control) {
815 d->_q_preparePropertyChange(QCameraControl::CaptureMode);
816 d->control->setCaptureMode(mode);
817 }
818 }
819}
820
821
822/*!
823 Starts the camera.
824
825 State is changed to QCamera::ActiveState if camera is started
826 successfully, otherwise error() signal is emitted.
827
828 While the camera state is changed to QCamera::ActiveState,
829 starting the camera service can be asynchronous with the actual
830 status reported with QCamera::status property.
831*/
832void QCamera::start()
833{
834 Q_D(QCamera);
835 d->setState(QCamera::ActiveState);
836}
837
838/*!
839 Stops the camera.
840 The camera state is changed from QCamera::ActiveState to QCamera::LoadedState.
841*/
842void QCamera::stop()
843{
844 Q_D(QCamera);
845 d->setState(QCamera::LoadedState);
846}
847
848/*!
849 Open the camera device.
850 The camera state is changed to QCamera::LoadedStatus.
851
852 It's not necessary to explcitly load the camera,
853 unless unless the application have to read the supported camera
854 settings and change the default depending on the camera capabilities.
855
856 In all the other cases it's possible to start the camera directly
857 from unloaded state.
858*/
859void QCamera::load()
860{
861 Q_D(QCamera);
862 d->setState(QCamera::LoadedState);
863}
864
865/*!
866 Close the camera device and deallocate the related resources.
867 The camera state is changed to QCamera::UnloadedStatus.
868*/
869void QCamera::unload()
870{
871 Q_D(QCamera);
872 d->setState(QCamera::UnloadedState);
873}
874
875#if QT_DEPRECATED_SINCE(5, 3)
876/*!
877 Returns a list of camera device's available from the default service provider.
878 \deprecated
879 \sa QCameraInfo::availableCameras()
880*/
881
882QList<QByteArray> QCamera::availableDevices()
883{
884 return QMediaServiceProvider::defaultServiceProvider()->devices(QByteArray(Q_MEDIASERVICE_CAMERA));
885}
886
887/*!
888 Returns the description of the \a device.
889 \deprecated
890 \sa QCameraInfo::availableCameras(), QCameraInfo::description()
891*/
892
893QString QCamera::deviceDescription(const QByteArray &device)
894{
895 return QMediaServiceProvider::defaultServiceProvider()->deviceDescription(QByteArray(Q_MEDIASERVICE_CAMERA), device);
896}
897#endif
898
899QCamera::State QCamera::state() const
900{
901 return d_func()->state;
902}
903
904QCamera::Status QCamera::status() const
905{
906 if(d_func()->control)
907 return (QCamera::Status)d_func()->control->status();
908
909 return QCamera::UnavailableStatus;
910}
911
912
913/*!
914 Returns the lock types, camera supports.
915*/
916QCamera::LockTypes QCamera::supportedLocks() const
917{
918 Q_D(const QCamera);
919
920 return d->locksControl
921 ? d->locksControl->supportedLocks()
922 : QCamera::LockTypes();
923}
924
925/*!
926 Returns the requested lock types.
927*/
928QCamera::LockTypes QCamera::requestedLocks() const
929{
930 return d_func()->requestedLocks;
931}
932
933/*!
934 Returns the status of requested camera settings locks.
935*/
936QCamera::LockStatus QCamera::lockStatus() const
937{
938 return d_func()->lockStatus;
939}
940
941/*!
942 Returns the lock status for a given \a lockType.
943*/
944QCamera::LockStatus QCamera::lockStatus(QCamera::LockType lockType) const
945{
946 const QCameraPrivate *d = d_func();
947
948 if (!(lockType & d->requestedLocks))
949 return QCamera::Unlocked;
950
951 if (d->locksControl)
952 return d->locksControl->lockStatus(lockType);
953
954 return QCamera::Locked;
955}
956
957/*!
958 \fn void QCamera::searchAndLock(QCamera::LockTypes locks)
959
960 Locks the camera settings with the requested \a locks, including focusing in the single autofocus mode,
961 exposure and white balance if the exposure and white balance modes are not manual.
962
963 The camera settings are usually locked before taking one or multiple still images,
964 in responce to the shutter button being half pressed.
965
966 The QCamera::locked() signal is emitted when camera settings are successfully locked,
967 otherwise QCamera::lockFailed() is emitted.
968
969 QCamera also emits lockStatusChanged(QCamera::LockType, QCamera::LockStatus)
970 on individual lock status changes and lockStatusChanged(QCamera::LockStatus) signal on composite status changes.
971
972 Locking serves two roles: it initializes calculation of automatic parameter
973 (focusing, calculating the correct exposure and white balance) and allows
974 to keep some or all of those parameters during number of shots.
975
976 If the camera doesn't support keeping one of parameters between shots, the related
977 lock state changes to QCamera::Unlocked.
978
979 It's also acceptable to relock already locked settings,
980 depending on the lock parameter this initiates new focusing, exposure or white balance calculation.
981 */
982void QCamera::searchAndLock(QCamera::LockTypes locks)
983{
984 Q_D(QCamera);
985
986 QCamera::LockStatus oldStatus = d->lockStatus;
987 d->supressLockChangedSignal = true;
988
989 if (d->locksControl) {
990 locks &= d->locksControl->supportedLocks();
991 d->requestedLocks |= locks;
992 d->locksControl->searchAndLock(locks);
993 }
994
995 d->supressLockChangedSignal = false;
996
997 d->lockStatus = oldStatus;
998 d->updateLockStatus();
999}
1000
1001/*!
1002 Lock all the supported camera settings.
1003 */
1004void QCamera::searchAndLock()
1005{
1006 searchAndLock(LockExposure | LockWhiteBalance | LockFocus);
1007}
1008
1009/*!
1010 Unlocks the camera settings specified with \a locks or cancel the current locking if one is active.
1011 */
1012void QCamera::unlock(QCamera::LockTypes locks)
1013{
1014 Q_D(QCamera);
1015
1016 QCamera::LockStatus oldStatus = d->lockStatus;
1017 d->supressLockChangedSignal = true;
1018
1019 d->requestedLocks &= ~locks;
1020
1021 if (d->locksControl) {
1022 locks &= d->locksControl->supportedLocks();
1023 d->locksControl->unlock(locks);
1024 }
1025
1026 d->supressLockChangedSignal = false;
1027
1028 d->lockStatus = oldStatus;
1029 d->updateLockStatus();
1030}
1031
1032/*!
1033 Unlock all the requested camera locks.
1034 */
1035void QCamera::unlock()
1036{
1037 unlock(d_func()->requestedLocks);
1038}
1039
1040
1041/*!
1042 \class QCamera::FrameRateRange
1043 \inmodule QtMultimedia
1044 \ingroup multimedia
1045 \ingroup multimedia_camera
1046 \since 5.5
1047
1048 \brief A FrameRateRange represents a range of frame rates as minimum and maximum rate.
1049
1050 If the minimum frame rate is equal to the maximum frame rate, the frame rate is fixed.
1051 If not, the actual frame rate fluctuates between the minimum and the maximum.
1052
1053 \sa QCamera::supportedViewfinderFrameRateRanges(), QCameraViewfinderSettings
1054*/
1055
1056/*!
1057 \fn QCamera::FrameRateRange::FrameRateRange()
1058
1059 Constructs a null frame rate range, with both minimumFrameRate and maximumFrameRate
1060 equal to \c 0.0.
1061*/
1062
1063/*!
1064 \fn QCamera::FrameRateRange::FrameRateRange(qreal minimum, qreal maximum)
1065
1066 Constructs a frame rate range with the given \a minimum and \a maximum frame rates.
1067*/
1068
1069/*!
1070 \variable QCamera::FrameRateRange::minimumFrameRate
1071 The minimum frame rate supported by the range, in frames per second.
1072*/
1073
1074/*!
1075 \variable QCamera::FrameRateRange::maximumFrameRate
1076 The maximum frame rate supported by the range, in frames per second.
1077*/
1078
1079/*!
1080 \enum QCamera::State
1081 \value UnloadedState
1082 The initial camera state, with camera not loaded,
1083 the camera capabilities except of supported capture modes
1084 are unknown.
1085
1086 While the supported settings are unknown in this state,
1087 it's allowed to set the camera capture settings like codec,
1088 resolution, or frame rate.
1089
1090 \value LoadedState
1091 The camera is loaded and ready to be configured.
1092
1093 In the Idle state it's allowed to query camera capabilities,
1094 set capture resolution, codecs, etc.
1095
1096 The viewfinder is not active in the loaded state.
1097
1098 \value ActiveState
1099 In the active state as soon as camera is started
1100 the viewfinder displays video frames and the
1101 camera is ready for capture.
1102*/
1103
1104
1105/*!
1106 \property QCamera::state
1107 \brief The current state of the camera object.
1108*/
1109
1110/*!
1111 \enum QCamera::Status
1112 \value ActiveStatus
1113 The camera has been started and can produce data.
1114 The viewfinder displays video frames in active state.
1115
1116 Depending on backend, changing some camera settings like
1117 capture mode, codecs or resolution in ActiveState may lead
1118 to changing the camera status to LoadedStatus and StartingStatus while
1119 the settings are applied and back to ActiveStatus when the camera is ready.
1120
1121 \value StartingStatus
1122 The camera is starting in result of state transition to QCamera::ActiveState.
1123 The camera service is not ready to capture yet.
1124
1125 \value StoppingStatus
1126 The camera is stopping in result of state transition from QCamera::ActiveState
1127 to QCamera::LoadedState or QCamera::UnloadedState.
1128
1129 \value StandbyStatus
1130 The camera is in the power saving standby mode.
1131 The camera may come to the standby mode after some time of inactivity
1132 in the QCamera::LoadedState state.
1133
1134 \value LoadedStatus
1135 The camera is loaded and ready to be configured.
1136 This status indicates the camera device is opened and
1137 it's possible to query for supported image and video capture settings,
1138 like resolution, framerate and codecs.
1139
1140 \value LoadingStatus
1141 The camera device loading in result of state transition from
1142 QCamera::UnloadedState to QCamera::LoadedState or QCamera::ActiveState.
1143
1144 \value UnloadingStatus
1145 The camera device is unloading in result of state transition from
1146 QCamera::LoadedState or QCamera::ActiveState to QCamera::UnloadedState.
1147
1148 \value UnloadedStatus
1149 The initial camera status, with camera not loaded.
1150 The camera capabilities including supported capture settings may be unknown.
1151
1152 \value UnavailableStatus
1153 The camera or camera backend is not available.
1154*/
1155
1156
1157/*!
1158 \property QCamera::status
1159 \brief The current status of the camera object.
1160*/
1161
1162
1163/*!
1164 \enum QCamera::CaptureMode
1165 \value CaptureViewfinder Camera is only configured to display viewfinder.
1166 \value CaptureStillImage Camera is configured for still frames capture.
1167 \value CaptureVideo Camera is configured for video capture.
1168*/
1169
1170/*!
1171 \enum QCamera::LockType
1172
1173 \value NoLock
1174 \value LockExposure
1175 Lock camera exposure.
1176 \value LockWhiteBalance
1177 Lock the white balance.
1178 \value LockFocus
1179 Lock camera focus.
1180*/
1181
1182
1183/*!
1184 \property QCamera::lockStatus
1185 \brief The overall status for all the requested camera locks.
1186*/
1187
1188/*!
1189 \fn void QCamera::locked()
1190
1191 Signals all the requested camera settings are locked.
1192*/
1193
1194/*!
1195 \fn void QCamera::lockFailed()
1196
1197 Signals locking of at least one requested camera settings failed.
1198*/
1199
1200/*!
1201 \fn QCamera::lockStatusChanged(QCamera::LockStatus status, QCamera::LockChangeReason reason)
1202
1203 Signals the overall \a status for all the requested camera locks was changed with specified \a reason.
1204*/
1205
1206/*!
1207 \fn QCamera::lockStatusChanged(QCamera::LockType lock, QCamera::LockStatus status, QCamera::LockChangeReason reason)
1208 Signals the \a lock \a status was changed with specified \a reason.
1209*/
1210
1211/*!
1212 \enum QCamera::LockStatus
1213 \value Unlocked
1214 The application is not interested in camera settings value.
1215 The camera may keep this parameter without changes, this is common with camera focus,
1216 or adjust exposure and white balance constantly to keep the viewfinder image nice.
1217
1218 \value Searching
1219 The application has requested the camera focus, exposure or white balance lock with
1220 QCamera::searchAndLock(). This state indicates the camera is focusing or calculating exposure and white balance.
1221
1222 \value Locked
1223 The camera focus, exposure or white balance is locked.
1224 The camera is ready to capture, application may check the exposure parameters.
1225
1226 The locked state usually means the requested parameter stays the same,
1227 except of the cases when the parameter is requested to be constantly updated.
1228 For example in continuous focusing mode, the focus is considered locked as long
1229 and the object is in focus, even while the actual focusing distance may be constantly changing.
1230*/
1231
1232/*!
1233 \enum QCamera::LockChangeReason
1234
1235 \value UserRequest
1236 The lock status changed in result of user request, usually to unlock camera settings.
1237 \value LockAcquired
1238 The lock status successfuly changed to QCamera::Locked.
1239 \value LockFailed
1240 The camera failed to acquire the requested lock in result of
1241 autofocus failure, exposure out of supported range, etc.
1242 \value LockLost
1243 The camera is not able to maintain the requested lock any more.
1244 Lock status is changed to QCamera::Unlocked.
1245 \value LockTemporaryLost
1246 The lock is lost, but the camera is working hard to reacquire it.
1247 This value may be used in continuous focusing mode,
1248 when the camera loses the focus, the focus lock state is changed to Qcamera::Searching
1249 with LockTemporaryLost reason.
1250*/
1251
1252/*!
1253 \enum QCamera::Error
1254
1255 \value NoError No errors have occurred.
1256 \value CameraError An error has occurred.
1257 \value InvalidRequestError System resource doesn't support requested functionality.
1258 \value ServiceMissingError No camera service available.
1259 \value NotSupportedFeatureError The feature is not supported.
1260*/
1261
1262/*!
1263 \fn void QCamera::error(QCamera::Error value)
1264
1265 Signal emitted when error state changes to \a value.
1266*/
1267
1268/*!
1269 \enum QCamera::Position
1270 \since 5.3
1271
1272 This enum specifies the physical position of the camera on the system hardware.
1273
1274 \value UnspecifiedPosition The camera position is unspecified or unknown.
1275
1276 \value BackFace The camera is on the back face of the system hardware. For example on a
1277 mobile device, it means it is on the opposite side to that of the screen.
1278
1279 \value FrontFace The camera is on the front face of the system hardware. For example on a
1280 mobile device, it means it is on the same side as that of the screen. Viewfinder frames of
1281 front-facing cameras are mirrored horizontally, so the users can see themselves as looking
1282 into a mirror. Captured images or videos are not mirrored.
1283
1284 \sa QCameraInfo::position()
1285*/
1286
1287/*!
1288 \fn void QCamera::captureModeChanged(QCamera::CaptureModes mode)
1289
1290 Signals the capture \a mode has changed.
1291*/
1292
1293/*!
1294 \fn QCamera::stateChanged(QCamera::State state)
1295
1296 Signals the camera \a state has changed.
1297
1298 Usually the state changes is caused by calling
1299 load(), unload(), start() and stop(),
1300 but the state can also be changed change as a result of camera error.
1301*/
1302
1303/*!
1304 \fn QCamera::statusChanged(QCamera::Status status)
1305
1306 Signals the camera \a status has changed.
1307
1308*/
1309
1310QT_END_NAMESPACE
1311
1312#include "moc_qcamera.cpp"
1313