4#undef QT_NO_CONTEXTLESS_CONNECT
11#include <qcameradevice.h>
12#include <qmediadevices.h>
14#include <private/qmediastoragelocation_p.h>
15#include <private/qvideoframe_p.h>
17#include <camera/camera_api.h>
18#include <camera/camera_3a.h>
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 },
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)
44 for (
const Mapping &m : mapping) {
45 const auto fromValue = m.*from;
46 const auto toValue = m.*to;
48 if (value == fromValue)
57 return convert(focusModes, &FocusModeMapping::qt,
58 &FocusModeMapping::qnx, mode, CAMERA_FOCUSMODE_CONTINUOUS_AUTO);
63 return convert(focusModes, &FocusModeMapping::qnx,
64 &FocusModeMapping::qt, mode, QCamera::FocusModeAuto);
69QQnxPlatformCamera::QQnxPlatformCamera(QCamera *parent)
70 : QPlatformCamera(parent)
73 setCamera(parent->cameraDevice());
75 setCamera(QMediaDevices::defaultVideoInput());
85 return m_qnxCamera && m_qnxCamera->isActive();
98 if (!m_qnxCamera || isActive())
104 m_qnxCamera->start();
106 Q_EMIT activeChanged(
true);
116 m_videoSink =
nullptr;
118 Q_EMIT activeChanged(
false);
123 if (m_cameraDevice == camera)
126 const auto cameraUnit =
static_cast<camera_unit_t>(camera.id().toUInt());
128 m_qnxCamera = std::make_unique<QQnxCamera>(cameraUnit);
130 connect(m_qnxCamera.get(), &QQnxCamera::focusModeChanged,
131 [
this](camera_focusmode_t mode) { Q_EMIT focusModeChanged(qtFocusMode(mode)); });
132 connect(m_qnxCamera.get(), &QQnxCamera::customFocusPointChanged,
133 this, &QQnxPlatformCamera::customFocusPointChanged);
134 connect(m_qnxCamera.get(), &QQnxCamera::frameAvailable,
135 this, &QQnxPlatformCamera::onFrameAvailable, Qt::QueuedConnection);
137 m_cameraDevice = camera;
139 updateCameraFeatures();
144 const QSize resolution = format.resolution();
146 if (resolution.isEmpty()) {
147 qWarning(
"QQnxPlatformCamera: invalid resolution requested");
151 return m_qnxCamera->setCameraFormat(resolution.width(),
152 resolution.height(), format.maxFrameRate());
157 if (m_session == session)
168 return m_qnxCamera->supportedFocusModes().contains(::qnxFocusMode(mode));
176 m_qnxCamera->setFocusMode(::qnxFocusMode(mode));
184 m_qnxCamera->setCustomFocusPoint(point);
192 const int maxDistance = m_qnxCamera->maxFocusStep();
197 const int qnxDistance = maxDistance *
std::min(distance, 1.0f);
199 m_qnxCamera->setManualFocusStep(qnxDistance);
207 const uint32_t minZoom = m_qnxCamera->minimumZoomLevel();
208 const uint32_t maxZoom = m_qnxCamera->maximumZoomLevel();
210 if (maxZoom <= minZoom)
214 const float max = maxZoomFactor();
215 const float min = minZoomFactor();
220 factor = qBound(min, factor, max) - min;
222 const uint32_t zoom = minZoom
223 +
static_cast<uint32_t>(qRound(factor*(maxZoom - minZoom)/(max - min)));
225 if (m_qnxCamera->setZoomFactor(zoom))
226 zoomFactorChanged(factor);
234 m_qnxCamera->setEvOffset(ev);
242 return m_qnxCamera->manualIsoSensitivity();
250 const uint32_t isoValue =
std::max(0, value);
252 m_qnxCamera->setManualIsoSensitivity(isoValue);
260 m_qnxCamera->setManualExposureTime(seconds);
268 return static_cast<
float>(m_qnxCamera->manualExposureTime());
273 if (m_maxColorTemperature != 0)
276 return mode == QCamera::WhiteBalanceAuto;
284 if (mode == QCamera::WhiteBalanceAuto) {
285 m_qnxCamera->setWhiteBalanceMode(CAMERA_WHITEBALANCEMODE_AUTO);
287 m_qnxCamera->setWhiteBalanceMode(CAMERA_WHITEBALANCEMODE_MANUAL);
297 const auto normalizedTemp = std::clamp<uint32_t>(std::max(0, temperature),
298 m_minColorTemperature, m_maxColorTemperature);
300 if (m_qnxCamera->hasContinuousWhiteBalanceValues()) {
301 m_qnxCamera->setManualWhiteBalance(normalizedTemp);
303 uint32_t delta = std::numeric_limits<uint32_t>::max();
304 uint32_t closestTemp = 0;
306 for (uint32_t value : m_qnxCamera->supportedWhiteBalanceValues()) {
307 const auto &[min, max] = std::minmax(value, normalizedTemp);
308 const uint32_t currentDelta = max - min;
310 if (currentDelta < delta) {
312 delta = currentDelta;
316 m_qnxCamera->setManualWhiteBalance(closestTemp);
323 qWarning(
"QQnxPlatformCamera: cannot start video recording - no no camera assigned");
327 if (!isVideoEncodingSupported()) {
328 qWarning(
"QQnxPlatformCamera: cannot start video recording - not supported");
332 if (!m_qnxCamera->isActive()) {
333 qWarning(
"QQnxPlatformCamera: cannot start video recording - camera not started");
337 const QString container = m_encoderSettings.preferredSuffix();
338 const QString location = QMediaStorageLocation::generateFileName(m_outputUrl.toLocalFile(),
339 QStandardPaths::MoviesLocation, container);
343 static void *libScreen =
nullptr;
346 libScreen = dlopen(
"/usr/lib/libscreen.so.1", RTLD_GLOBAL);
350 qDebug() <<
"Recording to" << location;
351 return m_qnxCamera->startVideoRecording(location);
356 m_videoFrameRequests.emplace_back(std::move(cb));
361 return m_qnxCamera && m_qnxCamera->hasFeature(CAMERA_FEATURE_VIDEO);
371 m_encoderSettings = settings;
379 QCamera::Features features = {};
381 if (m_qnxCamera->hasFeature(CAMERA_FEATURE_REGIONFOCUS))
382 features |= QCamera::Feature::CustomFocusPoint;
384 supportedFeaturesChanged(features);
386 minimumZoomFactorChanged(m_qnxCamera->minimumZoomLevel());
387 maximumZoomFactorChanged(m_qnxCamera->maximumZoomLevel());
389 const QList<uint32_t> wbValues = m_qnxCamera->supportedWhiteBalanceValues();
391 if (wbValues.isEmpty()) {
392 m_minColorTemperature = m_maxColorTemperature = 0;
394 const auto &[minTemp, maxTemp] =
std::minmax_element(wbValues.begin(), wbValues.end());
396 m_minColorTemperature = *minTemp;
397 m_maxColorTemperature = *maxTemp;
406 std::unique_ptr<QQnxCameraFrameBuffer> currentFrameBuffer = m_qnxCamera->takeCurrentFrame();
408 if (!currentFrameBuffer)
411 QVideoFrameFormat format(currentFrameBuffer->size(), currentFrameBuffer->pixelFormat());
412 const QVideoFrame actualFrame =
413 QVideoFramePrivate::createFrame(std::move(currentFrameBuffer), std::move(format));
415 m_videoSink->setVideoFrame(actualFrame);
417 if (!m_videoFrameRequests.empty()) {
418 VideoFrameCallback cb = std::move(m_videoFrameRequests.front());
419 m_videoFrameRequests.pop_front();
426#include "moc_qqnxplatformcamera_p.cpp"