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

source code of qtmultimedia/src/multimedia/camera/qcamera.cpp