Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
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
3
4#undef QT_NO_CONTEXTLESS_CONNECT // Remove after porting connect() calls
5
9#include "qqnxvideosink_p.h"
10
11#include <qcameradevice.h>
12#include <qmediadevices.h>
13
14#include <private/qmediastoragelocation_p.h>
15#include <private/qvideoframe_p.h>
16
17#include <camera/camera_api.h>
18#include <camera/camera_3a.h>
19
20#include <algorithm>
21#include <array>
22
23#include <dlfcn.h>
24
26{
28 camera_focusmode_t qnx;
29};
30
31constexpr std::array<FocusModeMapping, 6> focusModes {{
32 { QCamera::FocusModeAuto, CAMERA_FOCUSMODE_CONTINUOUS_AUTO },
33 { QCamera::FocusModeAutoFar, CAMERA_FOCUSMODE_CONTINUOUS_AUTO },
34 { QCamera::FocusModeInfinity, CAMERA_FOCUSMODE_CONTINUOUS_AUTO },
35 { QCamera::FocusModeAutoNear, CAMERA_FOCUSMODE_CONTINUOUS_MACRO },
36 { QCamera::FocusModeHyperfocal, CAMERA_FOCUSMODE_EDOF },
37 { QCamera::FocusModeManual, CAMERA_FOCUSMODE_MANUAL },
38}};
39
40template <typename Mapping, typename From, typename To, size_t N>
41static constexpr To convert(const std::array<Mapping, N> &mapping,
42 From Mapping::* from, To Mapping::* to, From value, To defaultValue)
43{
44 for (const Mapping &m : mapping) {
45 const auto fromValue = m.*from;
46 const auto toValue = m.*to;
47
48 if (value == fromValue)
49 return toValue;
50 }
51
52 return defaultValue;
53}
54
55static constexpr camera_focusmode_t qnxFocusMode(QCamera::FocusMode mode)
56{
58 &FocusModeMapping::qnx, mode, CAMERA_FOCUSMODE_CONTINUOUS_AUTO);
59}
60
66
68
77
82
84{
85 return m_qnxCamera && m_qnxCamera->isActive();
86}
87
89{
90 if (active)
91 start();
92 else
93 stop();
94}
95
97{
98 if (!m_qnxCamera || isActive())
99 return;
100
101 if (m_session)
102 m_videoSink = m_session->videoSink();
103
104 m_qnxCamera->start();
105
106 Q_EMIT activeChanged(true);
107}
108
110{
111 if (!m_qnxCamera)
112 return;
113
114 m_qnxCamera->stop();
115
116 m_videoSink = nullptr;
117
118 Q_EMIT activeChanged(false);
119}
120
122{
123 if (m_cameraDevice == camera)
124 return;
125
126 const auto cameraUnit = static_cast<camera_unit_t>(camera.id().toUInt());
127
128 m_qnxCamera = std::make_unique<QQnxCamera>(cameraUnit);
129
130 connect(m_qnxCamera.get(), &QQnxCamera::focusModeChanged,
131 [this](camera_focusmode_t mode) { Q_EMIT focusModeChanged(qtFocusMode(mode)); });
134 connect(m_qnxCamera.get(), &QQnxCamera::frameAvailable,
135 this, &QQnxPlatformCamera::onFrameAvailable, Qt::QueuedConnection);
136
137 m_cameraDevice = camera;
138
139 updateCameraFeatures();
140}
141
143{
144 const QSize resolution = format.resolution();
145
146 if (resolution.isEmpty()) {
147 qWarning("QQnxPlatformCamera: invalid resolution requested");
148 return false;
149 }
150
151 return m_qnxCamera->setCameraFormat(resolution.width(),
152 resolution.height(), format.maxFrameRate());
153}
154
156{
157 if (m_session == session)
158 return;
159
160 m_session = static_cast<QQnxMediaCaptureSession *>(session);
161}
162
164{
165 if (!m_qnxCamera)
166 return false;
167
168 return m_qnxCamera->supportedFocusModes().contains(::qnxFocusMode(mode));
169}
170
172{
173 if (!m_qnxCamera)
174 return;
175
176 m_qnxCamera->setFocusMode(::qnxFocusMode(mode));
177}
178
180{
181 if (!m_qnxCamera)
182 return;
183
184 m_qnxCamera->setCustomFocusPoint(point);
185}
186
188{
189 if (!m_qnxCamera)
190 return;
191
192 const int maxDistance = m_qnxCamera->maxFocusStep();
193
194 if (maxDistance < 0)
195 return;
196
197 const int qnxDistance = maxDistance * std::min(distance, 1.0f);
198
199 m_qnxCamera->setManualFocusStep(qnxDistance);
200}
201
202void QQnxPlatformCamera::zoomTo(float factor, float)
203{
204 if (!m_qnxCamera)
205 return;
206
207 const uint32_t minZoom = m_qnxCamera->minimumZoomLevel();
208 const uint32_t maxZoom = m_qnxCamera->maximumZoomLevel();
209
210 if (maxZoom <= minZoom)
211 return;
212
213 // QNX has an integer based API. Interpolate between the levels according to the factor we get
214 const float max = maxZoomFactor();
215 const float min = minZoomFactor();
216
217 if (max <= min)
218 return;
219
220 factor = qBound(min, factor, max) - min;
221
222 const uint32_t zoom = minZoom
223 + static_cast<uint32_t>(qRound(factor*(maxZoom - minZoom)/(max - min)));
224
225 if (m_qnxCamera->setZoomFactor(zoom))
226 zoomFactorChanged(factor);
227}
228
230{
231 if (!m_qnxCamera)
232 return;
233
234 m_qnxCamera->setEvOffset(ev);
235}
236
238{
239 if (!m_qnxCamera)
240 return 0;
241
242 return m_qnxCamera->manualIsoSensitivity();
243}
244
246{
247 if (!m_qnxCamera)
248 return;
249
250 const uint32_t isoValue = std::max(0, value);
251
252 m_qnxCamera->setManualIsoSensitivity(isoValue);
253}
254
256{
257 if (!m_qnxCamera)
258 return;
259
260 m_qnxCamera->setManualExposureTime(seconds);
261}
262
264{
265 if (!m_qnxCamera)
266 return 0.0;
267
268 return static_cast<float>(m_qnxCamera->manualExposureTime());
269}
270
272{
273 if (m_maxColorTemperature != 0)
274 return true;
275
277}
278
280{
281 if (!m_qnxCamera)
282 return;
283
285 m_qnxCamera->setWhiteBalanceMode(CAMERA_WHITEBALANCEMODE_AUTO);
286 } else {
287 m_qnxCamera->setWhiteBalanceMode(CAMERA_WHITEBALANCEMODE_MANUAL);
289 }
290}
291
293{
294 if (!m_qnxCamera)
295 return;
296
297 const auto normalizedTemp = std::clamp<uint32_t>(std::max(0, temperature),
298 m_minColorTemperature, m_maxColorTemperature);
299
300 if (m_qnxCamera->hasContinuousWhiteBalanceValues()) {
301 m_qnxCamera->setManualWhiteBalance(normalizedTemp);
302 } else {
303 uint32_t delta = std::numeric_limits<uint32_t>::max();
304 uint32_t closestTemp = 0;
305
306 for (uint32_t value : m_qnxCamera->supportedWhiteBalanceValues()) {
307 const auto &[min, max] = std::minmax(value, normalizedTemp);
308 const uint32_t currentDelta = max - min;
309
310 if (currentDelta < delta) {
311 closestTemp = value;
312 delta = currentDelta;
313 }
314 }
315
316 m_qnxCamera->setManualWhiteBalance(closestTemp);
317 }
318}
319
321{
322 if (!m_qnxCamera) {
323 qWarning("QQnxPlatformCamera: cannot start video recording - no no camera assigned");
324 return false;
325 }
326
327 if (!isVideoEncodingSupported()) {
328 qWarning("QQnxPlatformCamera: cannot start video recording - not supported");
329 return false;
330 }
331
332 if (!m_qnxCamera->isActive()) {
333 qWarning("QQnxPlatformCamera: cannot start video recording - camera not started");
334 return false;
335 }
336
337 const QString container = m_encoderSettings.mimeType().preferredSuffix();
340
341#if 0
342 {
343 static void *libScreen = nullptr;
344
345 if (!libScreen)
346 libScreen = dlopen("/usr/lib/libscreen.so.1", RTLD_GLOBAL);
347 }
348#endif
349
350 qDebug() << "Recording to" << location;
351 return m_qnxCamera->startVideoRecording(location);
352}
353
355{
356 m_videoFrameRequests.emplace_back(std::move(cb));
357}
358
359bool QQnxPlatformCamera::isVideoEncodingSupported() const
360{
361 return m_qnxCamera && m_qnxCamera->hasFeature(CAMERA_FEATURE_VIDEO);
362}
363
365{
366 m_outputUrl = url;
367}
368
373
374void QQnxPlatformCamera::updateCameraFeatures()
375{
376 if (!m_qnxCamera)
377 return;
378
379 QCamera::Features features = {};
380
381 if (m_qnxCamera->hasFeature(CAMERA_FEATURE_REGIONFOCUS))
383
384 supportedFeaturesChanged(features);
385
386 minimumZoomFactorChanged(m_qnxCamera->minimumZoomLevel());
387 maximumZoomFactorChanged(m_qnxCamera->maximumZoomLevel());
388
389 const QList<uint32_t> wbValues = m_qnxCamera->supportedWhiteBalanceValues();
390
391 if (wbValues.isEmpty()) {
392 m_minColorTemperature = m_maxColorTemperature = 0;
393 } else {
394 const auto &[minTemp, maxTemp] = std::minmax_element(wbValues.begin(), wbValues.end());
395
396 m_minColorTemperature = *minTemp;
397 m_maxColorTemperature = *maxTemp;
398 }
399}
400
401void QQnxPlatformCamera::onFrameAvailable()
402{
403 if (!m_videoSink)
404 return;
405
406 std::unique_ptr<QQnxCameraFrameBuffer> currentFrameBuffer = m_qnxCamera->takeCurrentFrame();
407
408 if (!currentFrameBuffer)
409 return;
410
411 QVideoFrameFormat format(currentFrameBuffer->size(), currentFrameBuffer->pixelFormat());
412 const QVideoFrame actualFrame =
413 QVideoFramePrivate::createFrame(std::move(currentFrameBuffer), std::move(format));
414
415 m_videoSink->setVideoFrame(actualFrame);
416
417 if (!m_videoFrameRequests.empty()) {
418 VideoFrameCallback cb = std::move(m_videoFrameRequests.front());
419 m_videoFrameRequests.pop_front();
420 cb(actualFrame);
421 }
422}
423
425
426#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
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:346
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
Definition qobject.cpp:2960
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:217
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:133
constexpr int width() const noexcept
Returns the width.
Definition qsize.h:130
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:124
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
\inmodule QtCore
Definition qurl.h:94
QString toLocalFile() const
Returns the path of this URL formatted as a local file path.
Definition qurl.cpp:3425
The QVideoFrameFormat class specifies the stream format of a video presentation surface.
static QVideoFrame createFrame(std::unique_ptr< Buffer > buffer, QVideoFrameFormat format)
The QVideoFrame class represents a frame of video data.
Definition qvideoframe.h:27
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:327
#define qDebug
[1]
Definition qlogging.h:165
#define qWarning
Definition qlogging.h:167
constexpr const T & qBound(const T &min, const T &val, const T &max)
Definition qminmax.h:23
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