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#include "qcamerafocus.h"
41#include "qmediaobject_p.h"
42
43#include <qcamera.h>
44#include <qcameracontrol.h>
45#include <qcameraexposurecontrol.h>
46#include <qcamerafocuscontrol.h>
47#include <qcamerazoomcontrol.h>
48#include <qmediarecordercontrol.h>
49#include <qcameraimagecapturecontrol.h>
50#include <qvideodeviceselectorcontrol.h>
51
52#include <QtCore/QDebug>
53
54QT_BEGIN_NAMESPACE
55
56static void qRegisterCameraFocusMetaTypes()
57{
58 qRegisterMetaType<QCameraFocus::FocusModes>(typeName: "QCameraFocus::FocusModes");
59 qRegisterMetaType<QCameraFocus::FocusPointMode>(typeName: "QCameraFocus::FocusPointMode");
60}
61
62Q_CONSTRUCTOR_FUNCTION(qRegisterCameraFocusMetaTypes)
63
64
65class QCameraFocusFakeZoomControl : public QCameraZoomControl
66{
67public:
68 QCameraFocusFakeZoomControl(QObject *parent) :
69 QCameraZoomControl(parent) {}
70
71 qreal maximumOpticalZoom() const override { return 1.0; }
72 qreal maximumDigitalZoom() const override { return 1.0; }
73
74 qreal requestedOpticalZoom() const override { return 1.0; }
75 qreal requestedDigitalZoom() const override { return 1.0; }
76 qreal currentOpticalZoom() const override { return 1.0; }
77 qreal currentDigitalZoom() const override { return 1.0; }
78
79 void zoomTo(qreal, qreal) override { qWarning(msg: "The camera doesn't support zooming."); }
80};
81
82class QCameraFocusFakeFocusControl : public QCameraFocusControl
83{
84public:
85 QCameraFocusFakeFocusControl(QObject *parent) :
86 QCameraFocusControl(parent) {}
87
88 QCameraFocus::FocusModes focusMode() const override { return QCameraFocus::AutoFocus; }
89 void setFocusMode(QCameraFocus::FocusModes) override { qWarning(msg: "Focus mode selection is not supported"); }
90 bool isFocusModeSupported(QCameraFocus::FocusModes) const override { return false; }
91
92 QCameraFocus::FocusPointMode focusPointMode() const override { return QCameraFocus::FocusPointAuto; }
93 void setFocusPointMode(QCameraFocus::FocusPointMode) override { qWarning(msg: "Focus points mode selection is not supported"); }
94 bool isFocusPointModeSupported(QCameraFocus::FocusPointMode) const override { return false; }
95 QPointF customFocusPoint() const override { return QPointF(0.5,0.5); }
96 void setCustomFocusPoint(const QPointF &) override { qWarning(msg: "Focus points selection is not supported"); }
97
98 QCameraFocusZoneList focusZones() const override { return QCameraFocusZoneList(); }
99};
100
101
102
103class QCameraFocusZoneData : public QSharedData
104{
105public:
106 QCameraFocusZoneData():
107 status(QCameraFocusZone::Invalid)
108 {
109
110 }
111
112 QCameraFocusZoneData(const QRectF &_area, QCameraFocusZone::FocusZoneStatus _status):
113 area(_area),
114 status(_status)
115 {
116
117 }
118
119
120 QCameraFocusZoneData(const QCameraFocusZoneData &other):
121 QSharedData(other),
122 area(other.area),
123 status(other.status)
124 {
125 }
126
127 QCameraFocusZoneData& operator=(const QCameraFocusZoneData &other)
128 {
129 area = other.area;
130 status = other.status;
131 return *this;
132 }
133
134 QRectF area;
135 QCameraFocusZone::FocusZoneStatus status;
136};
137
138
139/*!
140 \class QCameraFocusZone
141
142 \brief The QCameraFocusZone class provides information on zones used for autofocusing a camera.
143
144 \inmodule QtMultimedia
145 \ingroup multimedia
146 \ingroup multimedia_camera
147
148 For cameras that support autofocusing, in order for a camera to autofocus on
149 part of a sensor frame, it considers different zones within the frame. Which
150 zones to use, and where the zones are located vary between different cameras.
151
152 This class exposes what zones are used by a particular camera, and a list of the
153 zones can be retrieved by a \l QCameraFocus instance.
154
155 You can use this information to present visual feedback - for example, drawing
156 rectangles around areas of the camera frame that are in focus, or changing the
157 color of a zone as it comes into focus.
158
159 \snippet multimedia-snippets/camera.cpp Camera focus zones
160
161 \sa QCameraFocus
162*/
163
164/*!
165 \enum QCameraFocusZone::FocusZoneStatus
166
167 \value Invalid This zone is not valid
168 \value Unused This zone may be used for autofocusing, but is not currently.
169 \value Selected This zone is currently being used for autofocusing, but is not in focus.
170 \value Focused This zone is being used for autofocusing and is currently in focus.
171*/
172
173/*!
174 * \internal
175 * Creates a new, empty QCameraFocusZone.
176 */
177QCameraFocusZone::QCameraFocusZone()
178 :d(new QCameraFocusZoneData)
179{
180
181}
182
183/*!
184 * \internal
185 * Creates a new QCameraFocusZone with the supplied \a area and \a status.
186 */
187QCameraFocusZone::QCameraFocusZone(const QRectF &area, QCameraFocusZone::FocusZoneStatus status)
188 :d(new QCameraFocusZoneData(area, status))
189{
190}
191
192/*!
193 * Creates a new QCameraFocusZone as a copy of \a other.
194 */
195QCameraFocusZone::QCameraFocusZone(const QCameraFocusZone &other)
196 :d(other.d)
197{
198
199}
200
201/*!
202 * Destroys this QCameraFocusZone.
203 */
204QCameraFocusZone::~QCameraFocusZone()
205{
206
207}
208
209/*!
210 * Assigns \a other to this QCameraFocusZone.
211 */
212QCameraFocusZone& QCameraFocusZone::operator=(const QCameraFocusZone &other)
213{
214 d = other.d;
215 return *this;
216}
217
218/*!
219 * Returns true if this focus zone is the same as \a other.
220 */
221bool QCameraFocusZone::operator==(const QCameraFocusZone &other) const
222{
223 return d == other.d ||
224 (d->area == other.d->area && d->status == other.d->status);
225}
226
227/*!
228 * Returns true if this focus zone is not the same as \a other.
229 */
230bool QCameraFocusZone::operator!=(const QCameraFocusZone &other) const
231{
232 return !(*this == other);
233}
234
235/*!
236 * Returns true if this focus zone has a valid area and status.
237 */
238bool QCameraFocusZone::isValid() const
239{
240 return d->status != Invalid && !d->area.isValid();
241}
242
243/*!
244 * Returns the area of the camera frame that this focus zone encompasses.
245 *
246 * Coordinates are in frame relative coordinates - \c QPointF(0,0) is the top
247 * left of the frame, and \c QPointF(1,1) is the bottom right.
248 */
249QRectF QCameraFocusZone::area() const
250{
251 return d->area;
252}
253
254/*!
255 * Returns the current status of this focus zone.
256 */
257QCameraFocusZone::FocusZoneStatus QCameraFocusZone::status() const
258{
259 return d->status;
260}
261
262/*!
263 * \internal
264 * Sets the current status of this focus zone to \a status.
265 */
266void QCameraFocusZone::setStatus(QCameraFocusZone::FocusZoneStatus status)
267{
268 d->status = status;
269}
270
271
272/*!
273 \class QCameraFocus
274
275 \brief The QCameraFocus class provides an interface for focus and zoom related camera settings.
276
277 \inmodule QtMultimedia
278 \ingroup multimedia
279 \ingroup multimedia_camera
280
281 On hardware that supports it, this class lets you adjust the focus
282 or zoom (both optical and digital). This also includes things
283 like "Macro" mode for close up work (e.g. reading barcodes, or
284 recognising letters), or "touch to focus" - indicating an
285 interesting area of the viewfinder for the hardware to attempt
286 to focus on.
287
288 \snippet multimedia-snippets/camera.cpp Camera custom zoom
289
290 Zooming can be accomplished in a number of ways - usually the more
291 expensive but higher quality approach is an optical zoom, which allows
292 using the full extent of the camera sensor to gather image pixels. In
293 addition it is possible to digitally zoom, which will generally just
294 enlarge part of the sensor frame and throw away other parts. If the
295 camera hardware supports optical zoom this should generally always
296 be used first. The \l maximumOpticalZoom() method allows this to be
297 checked. The \l zoomTo() method allows changing both optical and
298 digital zoom at once.
299
300 \snippet multimedia-snippets/camera.cpp Camera combined zoom
301
302 \section2 Some notes on autofocus
303 Some hardware supports a movable focus lens assembly, and typically
304 this hardware also supports automatically focusing via some heuristic.
305 You can influence this via the \l FocusPointMode setting - typically
306 the center of the frame is brought into focus, but some hardware
307 also supports focusing on any faces detected in the frame, or on
308 a specific point (usually provided by a user in a "touch to focus"
309 scenario).
310
311 This class (in combination with \l QCameraFocusZone)
312 can expose information on what parts of the camera sensor image
313 are in focus or are being used for autofocusing via the \l focusZones()
314 property:
315
316 \snippet multimedia-snippets/camera.cpp Camera focus zones
317
318 \sa QCameraFocusZone
319*/
320
321
322class QCameraFocusPrivate : public QMediaObjectPrivate
323{
324 Q_DECLARE_NON_CONST_PUBLIC(QCameraFocus)
325public:
326 void initControls();
327
328 QCamera *camera;
329
330 QCameraFocusControl *focusControl;
331 QCameraZoomControl *zoomControl;
332 bool available;
333};
334
335
336void QCameraFocusPrivate::initControls()
337{
338 Q_Q(QCameraFocus);
339
340 focusControl = nullptr;
341 zoomControl = nullptr;
342
343 QMediaService *service = camera->service();
344 if (service) {
345 focusControl = qobject_cast<QCameraFocusControl *>(object: service->requestControl(QCameraFocusControl_iid));
346 zoomControl = qobject_cast<QCameraZoomControl *>(object: service->requestControl(QCameraZoomControl_iid));
347 }
348
349 available = focusControl != nullptr;
350
351 if (!focusControl)
352 focusControl = new QCameraFocusFakeFocusControl(q);
353
354 if (!zoomControl)
355 zoomControl = new QCameraFocusFakeZoomControl(q);
356
357 q->connect(sender: focusControl, SIGNAL(focusZonesChanged()), receiver: q, SIGNAL(focusZonesChanged()));
358
359 q->connect(sender: zoomControl, SIGNAL(currentOpticalZoomChanged(qreal)),
360 receiver: q, SIGNAL(opticalZoomChanged(qreal)));
361 q->connect(sender: zoomControl, SIGNAL(currentDigitalZoomChanged(qreal)),
362 receiver: q, SIGNAL(digitalZoomChanged(qreal)));
363 q->connect(sender: zoomControl, SIGNAL(maximumOpticalZoomChanged(qreal)),
364 receiver: q, SIGNAL(maximumOpticalZoomChanged(qreal)));
365 q->connect(sender: zoomControl, SIGNAL(maximumDigitalZoomChanged(qreal)),
366 receiver: q, SIGNAL(maximumDigitalZoomChanged(qreal)));
367}
368
369/*!
370 \internal
371 Construct a QCameraFocus for \a camera.
372*/
373
374QCameraFocus::QCameraFocus(QCamera *camera)
375 : QObject(*new QCameraFocusPrivate, camera)
376{
377 Q_D(QCameraFocus);
378 d->camera = camera;
379 d->initControls();
380}
381
382
383/*!
384 Destroys the camera focus object.
385*/
386
387QCameraFocus::~QCameraFocus()
388{
389}
390
391/*!
392 Returns true if focus related settings are supported by this camera.
393
394 You may need to also check if any specific features are supported.
395*/
396bool QCameraFocus::isAvailable() const
397{
398 return d_func()->available;
399}
400
401/*!
402 \property QCameraFocus::focusMode
403 \brief the current camera focus mode.
404
405
406 This controls the way the camera lens assembly is configured.
407
408 \sa QCameraFocus::isFocusModeSupported()
409*/
410
411QCameraFocus::FocusModes QCameraFocus::focusMode() const
412{
413 return d_func()->focusControl->focusMode();
414}
415
416void QCameraFocus::setFocusMode(QCameraFocus::FocusModes mode)
417{
418 d_func()->focusControl->setFocusMode(mode);
419}
420
421/*!
422 Returns true if the focus \a mode is supported by camera.
423*/
424
425bool QCameraFocus::isFocusModeSupported(FocusModes mode) const
426{
427 return d_func()->focusControl->isFocusModeSupported(mode);
428}
429
430/*!
431 \property QCameraFocus::focusPointMode
432 \brief the current camera focus point selection mode.
433
434 If the camera focus mode is set to use an autofocusing mode,
435 this property controls the way the camera will select areas
436 of the frame to use for autofocusing.
437
438 \sa QCameraFocus::isFocusPointModeSupported()
439*/
440
441QCameraFocus::FocusPointMode QCameraFocus::focusPointMode() const
442{
443 return d_func()->focusControl->focusPointMode();
444}
445
446void QCameraFocus::setFocusPointMode(QCameraFocus::FocusPointMode mode)
447{
448 d_func()->focusControl->setFocusPointMode(mode);
449}
450
451/*!
452 Returns true if focus point \a mode is supported.
453 */
454bool QCameraFocus::isFocusPointModeSupported(QCameraFocus::FocusPointMode mode) const
455{
456 return d_func()->focusControl->isFocusPointModeSupported(mode);
457}
458
459/*!
460 \property QCameraFocus::customFocusPoint
461
462 This property represents the position of the custom focus point, in relative frame coordinates:
463 QPointF(0,0) points to the left top frame point, QPointF(0.5,0.5) points to the frame center.
464
465 The custom focus point property is used only in \c FocusPointCustom focus mode.
466 */
467
468QPointF QCameraFocus::customFocusPoint() const
469{
470 return d_func()->focusControl->customFocusPoint();
471}
472
473void QCameraFocus::setCustomFocusPoint(const QPointF &point)
474{
475 d_func()->focusControl->setCustomFocusPoint(point);
476}
477
478/*!
479 \property QCameraFocus::focusZones
480
481 Returns the list of active focus zones.
482
483 If QCamera::FocusPointAuto or QCamera::FocusPointFaceDetection focus mode is selected
484 this method returns the list of zones the camera is actually focused on.
485
486 The coordinates system is the same as for custom focus points:
487 QPointF(0,0) points to the left top frame point, QPointF(0.5,0.5) points to the frame center.
488 */
489QCameraFocusZoneList QCameraFocus::focusZones() const
490{
491 return d_func()->focusControl->focusZones();
492}
493
494/*!
495 Returns the maximum optical zoom.
496
497 This will be \c 1.0 on cameras that do not support optical zoom.
498*/
499
500qreal QCameraFocus::maximumOpticalZoom() const
501{
502 return d_func()->zoomControl->maximumOpticalZoom();
503}
504
505/*!
506 Returns the maximum digital zoom
507
508 This will be \c 1.0 on cameras that do not support digital zoom.
509*/
510
511qreal QCameraFocus::maximumDigitalZoom() const
512{
513 return d_func()->zoomControl->maximumDigitalZoom();
514}
515
516/*!
517 \property QCameraFocus::opticalZoom
518 \brief the current optical zoom value.
519
520 \sa QCameraFocus::digitalZoom
521*/
522
523qreal QCameraFocus::opticalZoom() const
524{
525 return d_func()->zoomControl->currentOpticalZoom();
526}
527
528/*!
529 \property QCameraFocus::digitalZoom
530 \brief the current digital zoom value.
531
532 \sa QCameraFocus::opticalZoom
533*/
534qreal QCameraFocus::digitalZoom() const
535{
536 return d_func()->zoomControl->currentDigitalZoom();
537}
538
539
540/*!
541 Set the camera \a optical and \a digital zoom values.
542
543 Since there may be a physical component to move, the change in
544 zoom value may not be instantaneous.
545
546*/
547void QCameraFocus::zoomTo(qreal optical, qreal digital)
548{
549 d_func()->zoomControl->zoomTo(optical, digital);
550}
551
552/*!
553 \enum QCameraFocus::FocusMode
554
555 \value ManualFocus Manual or fixed focus mode.
556 \value HyperfocalFocus Focus to hyperfocal distance, with the maximum depth of field achieved.
557 All objects at distances from half of this
558 distance out to infinity will be acceptably sharp.
559 \value InfinityFocus Focus strictly to infinity.
560 \value AutoFocus One-shot auto focus mode.
561 \value ContinuousFocus Continuous auto focus mode.
562 \value MacroFocus One shot auto focus to objects close to camera.
563*/
564
565/*!
566 \enum QCameraFocus::FocusPointMode
567
568 \value FocusPointAuto Automatically select one or multiple focus points.
569 \value FocusPointCenter Focus to the frame center.
570 \value FocusPointFaceDetection Focus on faces in the frame.
571 \value FocusPointCustom Focus to the custom point, defined by QCameraFocus::customFocusPoint property.
572*/
573
574/*!
575 \fn void QCameraFocus::opticalZoomChanged(qreal value)
576
577 Signal emitted when optical zoom value changes to new \a value.
578*/
579
580/*!
581 \fn void QCameraFocus::digitalZoomChanged(qreal value)
582
583 Signal emitted when digital zoom value changes to new \a value.
584*/
585
586/*!
587 \fn void QCameraFocus::maximumOpticalZoomChanged(qreal zoom)
588
589 Signal emitted when the maximum supported optical \a zoom value changed.
590*/
591
592/*!
593 \fn void QCameraFocus::maximumDigitalZoomChanged(qreal zoom)
594
595 Signal emitted when the maximum supported digital \a zoom value changed.
596
597 The maximum supported zoom value can depend on other camera settings,
598 like capture mode or resolution.
599*/
600
601
602
603/*!
604 \fn QCameraFocus::focusZonesChanged()
605
606 This signal is emitted when the set of zones used in autofocusing is changed.
607
608 This can change when a zone is focused or loses focus, or new focus zones
609 have been detected.
610*/
611
612QT_END_NAMESPACE
613
614#include "moc_qcamerafocus.cpp"
615

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