Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qqnxplatformcamera.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 Research In Motion
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
6#include "qqnxvideosink_p.h"
7
8#include <qcameradevice.h>
9#include <qmediadevices.h>
10
11#include <private/qmediastoragelocation_p.h>
12
13#include <camera/camera_api.h>
14#include <camera/camera_3a.h>
15
16#include <algorithm>
17#include <array>
18
19#include <dlfcn.h>
20
22{
24 camera_focusmode_t qnx;
25};
26
27constexpr std::array<FocusModeMapping, 6> focusModes {{
28 { QCamera::FocusModeAuto, CAMERA_FOCUSMODE_CONTINUOUS_AUTO },
29 { QCamera::FocusModeAutoFar, CAMERA_FOCUSMODE_CONTINUOUS_AUTO },
30 { QCamera::FocusModeInfinity, CAMERA_FOCUSMODE_CONTINUOUS_AUTO },
31 { QCamera::FocusModeAutoNear, CAMERA_FOCUSMODE_CONTINUOUS_MACRO },
32 { QCamera::FocusModeHyperfocal, CAMERA_FOCUSMODE_EDOF },
33 { QCamera::FocusModeManual, CAMERA_FOCUSMODE_MANUAL },
34}};
35
36template <typename Mapping, typename From, typename To, size_t N>
37static constexpr To convert(const std::array<Mapping, N> &mapping,
38 From Mapping::* from, To Mapping::* to, From value, To defaultValue)
39{
40 for (const Mapping &m : mapping) {
41 const auto fromValue = m.*from;
42 const auto toValue = m.*to;
43
44 if (value == fromValue)
45 return toValue;
46 }
47
48 return defaultValue;
49}
50
51static constexpr camera_focusmode_t qnxFocusMode(QCamera::FocusMode mode)
52{
54 &FocusModeMapping::qnx, mode, CAMERA_FOCUSMODE_CONTINUOUS_AUTO);
55}
56
57static constexpr QCamera::FocusMode qtFocusMode(camera_focusmode_t mode)
58{
61}
62
64
67{
68 if (parent)
69 setCamera(parent->cameraDevice());
70 else
72}
73
75{
76 stop();
77}
78
80{
81 return m_qnxCamera && m_qnxCamera->isActive();
82}
83
85{
86 if (active)
87 start();
88 else
89 stop();
90}
91
93{
94 if (!m_qnxCamera || isActive())
95 return;
96
97 if (m_session)
98 m_videoSink = m_session->videoSink();
99
100 m_qnxCamera->start();
101
102 Q_EMIT activeChanged(true);
103}
104
106{
107 if (!m_qnxCamera)
108 return;
109
110 m_qnxCamera->stop();
111
112 m_videoSink = nullptr;
113
114 Q_EMIT activeChanged(false);
115}
116
118{
119 if (m_cameraDevice == camera)
120 return;
121
122 const auto cameraUnit = static_cast<camera_unit_t>(camera.id().toUInt());
123
124 m_qnxCamera = std::make_unique<QQnxCamera>(cameraUnit);
125
126 connect(m_qnxCamera.get(), &QQnxCamera::focusModeChanged,
127 [this](camera_focusmode_t mode) { Q_EMIT focusModeChanged(qtFocusMode(mode)); });
130 connect(m_qnxCamera.get(), &QQnxCamera::frameAvailable,
131 this, &QQnxPlatformCamera::onFrameAvailable, Qt::QueuedConnection);
132
133 m_cameraDevice = camera;
134
135 updateCameraFeatures();
136}
137
139{
140 const QSize resolution = format.resolution();
141
142 if (resolution.isEmpty()) {
143 qWarning("QQnxPlatformCamera: invalid resolution requested");
144 return false;
145 }
146
147 return m_qnxCamera->setCameraFormat(resolution.width(),
148 resolution.height(), format.maxFrameRate());
149}
150
152{
153 if (m_session == session)
154 return;
155
156 m_session = static_cast<QQnxMediaCaptureSession *>(session);
157}
158
160{
161 if (!m_qnxCamera)
162 return false;
163
164 return m_qnxCamera->supportedFocusModes().contains(::qnxFocusMode(mode));
165}
166
168{
169 if (!m_qnxCamera)
170 return;
171
172 m_qnxCamera->setFocusMode(::qnxFocusMode(mode));
173}
174
176{
177 if (!m_qnxCamera)
178 return;
179
180 m_qnxCamera->setCustomFocusPoint(point);
181}
182
184{
185 if (!m_qnxCamera)
186 return;
187
188 const int maxDistance = m_qnxCamera->maxFocusStep();
189
190 if (maxDistance < 0)
191 return;
192
193 const int qnxDistance = maxDistance * std::min(distance, 1.0f);
194
195 m_qnxCamera->setManualFocusStep(qnxDistance);
196}
197
198void QQnxPlatformCamera::zoomTo(float factor, float)
199{
200 if (!m_qnxCamera)
201 return;
202
203 const uint32_t minZoom = m_qnxCamera->minimumZoomLevel();
204 const uint32_t maxZoom = m_qnxCamera->maximumZoomLevel();
205
206 if (maxZoom <= minZoom)
207 return;
208
209 // QNX has an integer based API. Interpolate between the levels according to the factor we get
210 const float max = maxZoomFactor();
211 const float min = minZoomFactor();
212
213 if (max <= min)
214 return;
215
216 factor = qBound(min, factor, max) - min;
217
218 const uint32_t zoom = minZoom
219 + static_cast<uint32_t>(qRound(factor*(maxZoom - minZoom)/(max - min)));
220
221 if (m_qnxCamera->setZoomFactor(zoom))
222 zoomFactorChanged(factor);
223}
224
226{
227 if (!m_qnxCamera)
228 return;
229
230 m_qnxCamera->setEvOffset(ev);
231}
232
234{
235 if (!m_qnxCamera)
236 return 0;
237
238 return m_qnxCamera->manualIsoSensitivity();
239}
240
242{
243 if (!m_qnxCamera)
244 return;
245
246 const uint32_t isoValue = std::max(0, value);
247
248 m_qnxCamera->setManualIsoSensitivity(isoValue);
249}
250
252{
253 if (!m_qnxCamera)
254 return;
255
256 m_qnxCamera->setManualExposureTime(seconds);
257}
258
260{
261 if (!m_qnxCamera)
262 return 0.0;
263
264 return static_cast<float>(m_qnxCamera->manualExposureTime());
265}
266
268{
269 if (m_maxColorTemperature != 0)
270 return true;
271
273}
274
276{
277 if (!m_qnxCamera)
278 return;
279
281 m_qnxCamera->setWhiteBalanceMode(CAMERA_WHITEBALANCEMODE_AUTO);
282 } else {
283 m_qnxCamera->setWhiteBalanceMode(CAMERA_WHITEBALANCEMODE_MANUAL);
285 }
286}
287
289{
290 if (!m_qnxCamera)
291 return;
292
293 const auto normalizedTemp = std::clamp<uint32_t>(std::max(0, temperature),
294 m_minColorTemperature, m_maxColorTemperature);
295
296 if (m_qnxCamera->hasContinuousWhiteBalanceValues()) {
297 m_qnxCamera->setManualWhiteBalance(normalizedTemp);
298 } else {
299 uint32_t delta = std::numeric_limits<uint32_t>::max();
300 uint32_t closestTemp = 0;
301
302 for (uint32_t value : m_qnxCamera->supportedWhiteBalanceValues()) {
303 const auto &[min, max] = std::minmax(value, normalizedTemp);
304 const uint32_t currentDelta = max - min;
305
306 if (currentDelta < delta) {
307 closestTemp = value;
308 delta = currentDelta;
309 }
310 }
311
312 m_qnxCamera->setManualWhiteBalance(closestTemp);
313 }
314}
315
317{
318 if (!m_qnxCamera) {
319 qWarning("QQnxPlatformCamera: cannot start video recording - no no camera assigned");
320 return false;
321 }
322
323 if (!isVideoEncodingSupported()) {
324 qWarning("QQnxPlatformCamera: cannot start video recording - not supported");
325 return false;
326 }
327
328 if (!m_qnxCamera->isActive()) {
329 qWarning("QQnxPlatformCamera: cannot start video recording - camera not started");
330 return false;
331 }
332
333 const QString container = m_encoderSettings.mimeType().preferredSuffix();
336
337#if 0
338 {
339 static void *libScreen = nullptr;
340
341 if (!libScreen)
342 libScreen = dlopen("/usr/lib/libscreen.so.1", RTLD_GLOBAL);
343 }
344#endif
345
346 qDebug() << "Recording to" << location;
347 return m_qnxCamera->startVideoRecording(location);
348}
349
351{
352 m_videoFrameRequests.emplace_back(std::move(cb));
353}
354
355bool QQnxPlatformCamera::isVideoEncodingSupported() const
356{
357 return m_qnxCamera && m_qnxCamera->hasFeature(CAMERA_FEATURE_VIDEO);
358}
359
361{
362 m_outputUrl = url;
363}
364
366{
367 m_encoderSettings = settings;
368}
369
370void QQnxPlatformCamera::updateCameraFeatures()
371{
372 if (!m_qnxCamera)
373 return;
374
375 QCamera::Features features = {};
376
377 if (m_qnxCamera->hasFeature(CAMERA_FEATURE_REGIONFOCUS))
379
380 supportedFeaturesChanged(features);
381
382 minimumZoomFactorChanged(m_qnxCamera->minimumZoomLevel());
383 maximumZoomFactorChanged(m_qnxCamera->maximumZoomLevel());
384
385 const QList<uint32_t> wbValues = m_qnxCamera->supportedWhiteBalanceValues();
386
387 if (wbValues.isEmpty()) {
388 m_minColorTemperature = m_maxColorTemperature = 0;
389 } else {
390 const auto &[minTemp, maxTemp] = std::minmax_element(wbValues.begin(), wbValues.end());
391
392 m_minColorTemperature = *minTemp;
393 m_maxColorTemperature = *maxTemp;
394 }
395}
396
397void QQnxPlatformCamera::onFrameAvailable()
398{
399 if (!m_videoSink)
400 return;
401
402 std::unique_ptr<QQnxCameraFrameBuffer> currentFrame = m_qnxCamera->takeCurrentFrame();
403
404 if (!currentFrame)
405 return;
406
407 const QVideoFrame actualFrame(currentFrame.get(),
408 QVideoFrameFormat(currentFrame->size(), currentFrame->pixelFormat()));
409
410 currentFrame.release(); // QVideoFrame has taken ownership of the internal
411 // buffer
412
413 m_videoSink->setVideoFrame(actualFrame);
414
415 if (!m_videoFrameRequests.empty()) {
416 VideoFrameCallback cb = std::move(m_videoFrameRequests.front());
417 m_videoFrameRequests.pop_front();
418 cb(actualFrame);
419 }
420}
421
423
424#include "moc_qqnxplatformcamera_p.cpp"
The QCameraDevice class provides general information about camera devices.
The QCameraFormat class describes a video format supported by a camera device. \inmodule QtMultimedia...
The QCamera class provides interface for system camera devices.
Definition qcamera.h:28
WhiteBalanceMode
\value WhiteBalanceAuto Auto white balance mode.
Definition qcamera.h:112
@ WhiteBalanceAuto
Definition qcamera.h:113
FocusMode
\value FocusModeAuto Continuous auto focus mode.
Definition qcamera.h:67
@ FocusModeAutoNear
Definition qcamera.h:69
@ FocusModeInfinity
Definition qcamera.h:72
@ FocusModeAutoFar
Definition qcamera.h:70
@ FocusModeAuto
Definition qcamera.h:68
@ FocusModeManual
Definition qcamera.h:73
@ FocusModeHyperfocal
Definition qcamera.h:71
Definition qlist.h:74
bool isEmpty() const noexcept
Definition qlist.h:390
iterator end()
Definition qlist.h:609
iterator begin()
Definition qlist.h:608
QCameraDevice defaultVideoInput
\qmlproperty cameraDevice QtMultimedia::MediaDevices::defaultVideoInput Returns the default camera on...
QString preferredSuffix
the preferred suffix for the MIME type
Definition qmimetype.h:38
QObject * parent() const
Returns a pointer to the parent object.
Definition qobject.h:311
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
Definition qobject.cpp:2823
float minZoomFactor() const
static int colorTemperatureForWhiteBalance(QCamera::WhiteBalanceMode mode)
float maxZoomFactor() const
void maximumZoomFactorChanged(float)
void customFocusPointChanged(const QPointF &point)
void zoomFactorChanged(float zoom)
void supportedFeaturesChanged(QCamera::Features)
void minimumZoomFactorChanged(float factor)
virtual void setVideoFrame(const QVideoFrame &frame)
void activeChanged(bool)
\inmodule QtCore\reentrant
Definition qpoint.h:214
void focusModeChanged(camera_focusmode_t mode)
void frameAvailable()
void customFocusPointChanged(const QPointF &point)
QQnxVideoSink * videoSink() const
QQnxPlatformCamera(QCamera *parent)
void setManualExposureTime(float seconds) override
void setMediaEncoderSettings(const QMediaEncoderSettings &settings)
void setExposureCompensation(float ev) override
void requestVideoFrame(VideoFrameCallback cb)
std::function< void(const QVideoFrame &)> VideoFrameCallback
void setCamera(const QCameraDevice &camera) override
void setCaptureSession(QPlatformMediaCaptureSession *session) override
void setOutputUrl(const QUrl &url)
void setManualIsoSensitivity(int value) override
bool isWhiteBalanceModeSupported(QCamera::WhiteBalanceMode mode) const override
void setCustomFocusPoint(const QPointF &point) override
int isoSensitivity() const override
void setColorTemperature(int temperature) override
void setWhiteBalanceMode(QCamera::WhiteBalanceMode mode) override
float exposureTime() const override
bool isFocusModeSupported(QCamera::FocusMode mode) const override
void setFocusDistance(float distance) override
void zoomTo(float newZoomFactor, float rate=-1.) override
bool isActive() const override
void setFocusMode(QCamera::FocusMode mode) override
bool setCameraFormat(const QCameraFormat &format) override
void setActive(bool active) override
\inmodule QtCore
Definition qsize.h:25
constexpr int height() const noexcept
Returns the height.
Definition qsize.h:132
constexpr int width() const noexcept
Returns the width.
Definition qsize.h:129
constexpr bool isEmpty() const noexcept
Returns true if either of the width and height is less than or equal to 0; otherwise returns false.
Definition qsize.h:123
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:127
\inmodule QtCore
Definition qurl.h:94
QString toLocalFile() const
Returns the path of this URL formatted as a local file path.
Definition qurl.cpp:3411
The QVideoFrameFormat class specifies the stream format of a video presentation surface.
The QVideoFrame class represents a frame of video data.
Definition qvideoframe.h:26
QCamera * camera
Definition camera.cpp:19
Q_MULTIMEDIA_EXPORT QString generateFileName(const QString &requestedName, QStandardPaths::StandardLocation type, const QString &extension)
Combined button and popup list for selecting options.
@ QueuedConnection
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
int qRound(qfloat16 d) noexcept
Definition qfloat16.h:281
#define qDebug
[1]
Definition qlogging.h:160
#define qWarning
Definition qlogging.h:162
constexpr const T & qBound(const T &min, const T &val, const T &max)
Definition qminmax.h:44
GLint location
GLenum mode
const GLfloat * m
GLsizei GLsizei GLfloat distance
GLint GLsizei GLsizei GLenum format
GLenum GLenum GLenum GLenum mapping
static constexpr To convert(const std::array< Mapping, N > &mapping, From Mapping::*from, To Mapping::*to, From value, To defaultValue)
static constexpr camera_focusmode_t qnxFocusMode(QCamera::FocusMode mode)
constexpr std::array< FocusModeMapping, 6 > focusModes
static constexpr QCamera::FocusMode qtFocusMode(camera_focusmode_t mode)
SSL_CTX int(* cb)(SSL *ssl, unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg)
#define Q_EMIT
QSettings settings("MySoft", "Star Runner")
[0]
QUrl url("example.com")
[constructor-url-reference]
QCamera::FocusMode qt
camera_focusmode_t qnx
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent