6#include "capture/qqnxmediacapturesession_p.h"
8#include <QtMultimedia/qcameradevice.h>
9#include <QtMultimedia/qmediadevices.h>
10#include <QtMultimedia/private/qplatformvideosink_p.h>
11#include <QtMultimedia/private/qmediastoragelocation_p.h>
12#include <QtMultimedia/private/qvideoframe_p.h>
14#include <camera/camera_api.h>
15#include <camera/camera_3a.h>
29 { QCamera::FocusModeAuto, CAMERA_FOCUSMODE_CONTINUOUS_AUTO },
30 { QCamera::FocusModeAutoFar, CAMERA_FOCUSMODE_CONTINUOUS_AUTO },
31 { QCamera::FocusModeInfinity, CAMERA_FOCUSMODE_CONTINUOUS_AUTO },
32 { QCamera::FocusModeAutoNear, CAMERA_FOCUSMODE_CONTINUOUS_MACRO },
33 { QCamera::FocusModeHyperfocal, CAMERA_FOCUSMODE_EDOF },
34 { QCamera::FocusModeManual, CAMERA_FOCUSMODE_MANUAL },
37template <
typename Mapping,
typename From,
typename To, size_t N>
38static constexpr To
convert(
const std::array<Mapping, N> &mapping,
39 From Mapping::* from, To Mapping::* to, From value, To defaultValue)
41 for (
const Mapping &m : mapping) {
42 const auto fromValue = m.*from;
43 const auto toValue = m.*to;
45 if (value == fromValue)
54 return convert(focusModes, &FocusModeMapping::qt,
55 &FocusModeMapping::qnx, mode, CAMERA_FOCUSMODE_CONTINUOUS_AUTO);
60 return convert(focusModes, &FocusModeMapping::qnx,
61 &FocusModeMapping::qt, mode, QCamera::FocusModeAuto);
66QQnxPlatformCamera::QQnxPlatformCamera(QCamera *parent)
67 : QPlatformCamera(parent)
70 setCamera(parent->cameraDevice());
72 setCamera(QMediaDevices::defaultVideoInput());
82 return m_qnxCamera && m_qnxCamera->isActive();
95 if (!m_qnxCamera || isActive())
101 m_qnxCamera->start();
103 Q_EMIT activeChanged(
true);
113 m_videoSink =
nullptr;
115 Q_EMIT activeChanged(
false);
120 if (m_cameraDevice == camera)
123 const auto cameraUnit =
static_cast<camera_unit_t>(camera.id().toUInt());
125 m_qnxCamera = std::make_unique<QQnxCamera>(cameraUnit);
127 connect(m_qnxCamera.get(), &QQnxCamera::focusModeChanged,
128 this, [
this](camera_focusmode_t mode) { Q_EMIT focusModeChanged(qtFocusMode(mode)); });
129 connect(m_qnxCamera.get(), &QQnxCamera::customFocusPointChanged,
130 this, &QQnxPlatformCamera::customFocusPointChanged);
134 m_cameraDevice = camera;
136 updateCameraFeatures();
141 const QSize resolution = format.resolution();
143 if (resolution.isEmpty()) {
144 qWarning(
"QQnxPlatformCamera: invalid resolution requested");
148 return m_qnxCamera->setCameraFormat(resolution.width(),
149 resolution.height(), format.maxFrameRate());
154 if (m_session == session)
165 return m_qnxCamera->supportedFocusModes().contains(::qnxFocusMode(mode));
173 m_qnxCamera->setFocusMode(::qnxFocusMode(mode));
181 m_qnxCamera->setCustomFocusPoint(point);
189 const int maxDistance = m_qnxCamera->maxFocusStep();
194 const int qnxDistance = maxDistance *
std::min(distance, 1.0f);
196 m_qnxCamera->setManualFocusStep(qnxDistance);
204 const uint32_t minZoom = m_qnxCamera->minimumZoomLevel();
205 const uint32_t maxZoom = m_qnxCamera->maximumZoomLevel();
207 if (maxZoom <= minZoom)
211 const float max = maxZoomFactor();
212 const float min = minZoomFactor();
217 factor = qBound(min, factor, max) - min;
219 const uint32_t zoom = minZoom
220 +
static_cast<uint32_t>(qRound(factor*(maxZoom - minZoom)/(max - min)));
222 if (m_qnxCamera->setZoomFactor(zoom))
223 zoomFactorChanged(factor);
231 m_qnxCamera->setEvOffset(ev);
239 return m_qnxCamera->manualIsoSensitivity();
247 const uint32_t isoValue =
std::max(0, value);
249 m_qnxCamera->setManualIsoSensitivity(isoValue);
257 m_qnxCamera->setManualExposureTime(seconds);
265 return static_cast<
float>(m_qnxCamera->manualExposureTime());
270 if (m_maxColorTemperature != 0)
273 return mode == QCamera::WhiteBalanceAuto;
281 if (mode == QCamera::WhiteBalanceAuto) {
282 m_qnxCamera->setWhiteBalanceMode(CAMERA_WHITEBALANCEMODE_AUTO);
284 m_qnxCamera->setWhiteBalanceMode(CAMERA_WHITEBALANCEMODE_MANUAL);
294 const auto normalizedTemp = std::clamp<uint32_t>(std::max(0, temperature),
295 m_minColorTemperature, m_maxColorTemperature);
297 if (m_qnxCamera->hasContinuousWhiteBalanceValues()) {
298 m_qnxCamera->setManualWhiteBalance(normalizedTemp);
300 uint32_t delta = std::numeric_limits<uint32_t>::max();
301 uint32_t closestTemp = 0;
303 for (uint32_t value : m_qnxCamera->supportedWhiteBalanceValues()) {
304 const auto &[min, max] = std::minmax(value, normalizedTemp);
305 const uint32_t currentDelta = max - min;
307 if (currentDelta < delta) {
309 delta = currentDelta;
313 m_qnxCamera->setManualWhiteBalance(closestTemp);
320 qWarning(
"QQnxPlatformCamera: cannot start video recording - no no camera assigned");
324 if (!isVideoEncodingSupported()) {
325 qWarning(
"QQnxPlatformCamera: cannot start video recording - not supported");
329 if (!m_qnxCamera->isActive()) {
330 qWarning(
"QQnxPlatformCamera: cannot start video recording - camera not started");
334 const QString container = m_encoderSettings.preferredSuffix();
335 const QString location = QMediaStorageLocation::generateFileName(m_outputUrl.toLocalFile(),
336 QStandardPaths::MoviesLocation, container);
340 static void *libScreen =
nullptr;
343 libScreen = dlopen(
"/usr/lib/libscreen.so.1", RTLD_GLOBAL);
347 qDebug() <<
"Recording to" << location;
348 return m_qnxCamera->startVideoRecording(location);
353 m_videoFrameRequests.emplace_back(std::move(cb));
358 return m_qnxCamera && m_qnxCamera->hasFeature(CAMERA_FEATURE_VIDEO);
368 m_encoderSettings = settings;
376 QCamera::Features features = {};
378 if (m_qnxCamera->hasFeature(CAMERA_FEATURE_REGIONFOCUS))
379 features |= QCamera::Feature::CustomFocusPoint;
381 supportedFeaturesChanged(features);
383 minimumZoomFactorChanged(m_qnxCamera->minimumZoomLevel());
384 maximumZoomFactorChanged(m_qnxCamera->maximumZoomLevel());
386 const QList<uint32_t> wbValues = m_qnxCamera->supportedWhiteBalanceValues();
388 if (wbValues.isEmpty()) {
389 m_minColorTemperature = m_maxColorTemperature = 0;
391 const auto &[minTemp, maxTemp] =
std::minmax_element(wbValues.begin(), wbValues.end());
393 m_minColorTemperature = *minTemp;
394 m_maxColorTemperature = *maxTemp;
403 std::unique_ptr<QQnxCameraFrameBuffer> currentFrameBuffer = m_qnxCamera->takeCurrentFrame();
405 if (!currentFrameBuffer)
408 QVideoFrameFormat format(currentFrameBuffer->size(), currentFrameBuffer->pixelFormat());
409 const QVideoFrame actualFrame =
410 QVideoFramePrivate::createFrame(std::move(currentFrameBuffer), std::move(format));
412 m_videoSink->setVideoFrame(actualFrame);
414 if (!m_videoFrameRequests.empty()) {
415 VideoFrameCallback cb =
std::move(m_videoFrameRequests.front());
416 m_videoFrameRequests.pop_front();
423#include "moc_qqnxplatformcamera_p.cpp"