Revision control
++ // Copyright (C) 2016 The Qt Company Ltd.
++ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
++
++ #include "qplatformcamera_p.h"
++
++ #include <QtMultimedia/private/qcameradevice_p.h>
++ #include <QtMultimedia/private/qmultimedia_ranges_p.h>
++
++ QT_BEGIN_NAMESPACE
++
++ namespace ranges = QtMultimediaPrivate::ranges;
++
++ QPlatformCamera::QPlatformCamera(QObject *parent)
++ : QPlatformVideoSource(parent), m_camera(qobject_cast<QCamera *>(parent))
++ {
++ // TODO: create QPlatformGStreamerElement and use it instead of QPlatformCamera
++ // Then, uncomment the assert
++ Q_ASSERT(parent);
++ qRegisterMetaType<QVideoFrame>();
++ }
++
++ QCameraFormat QPlatformCamera::findBestCameraFormat(const QCameraDevice &camera) const
++ {
++ // check if fmt is better. We try to find the highest resolution that offers
++ // at least 30 FPS
++ // we use 29 FPS to compare against as some cameras report 29.97 FPS...
++
++ auto makeCriteria = [this](const QCameraFormat &fmt) {
++ constexpr float MinSufficientFrameRate = 29.f;
++
++ const auto isValid = fmt.pixelFormat() != QVideoFrameFormat::Format_Invalid;
++ const auto resolution = fmt.resolution();
++ const auto sufficientFrameRate = std::min(fmt.maxFrameRate(), MinSufficientFrameRate);
++ const auto pixelFormatScore =
++ cameraPixelFormatScore(fmt.pixelFormat(), QCameraFormatPrivate::getColorRange(fmt));
++
++ return std::make_tuple(
++ isValid, // 1st: ensure valid formats
++ sufficientFrameRate, // 2nd: ensure the highest frame rate in the range [0; 29]*/
++ resolution.width() * resolution.height(), // 3rd: ensure the highest resolution
++ pixelFormatScore, // 4th: eshure the best pixel format
++ fmt.maxFrameRate()); // 5th: ensure the highest framerate in the whole range
++ };
++
++ const auto formats = camera.videoFormats();
++ if (formats.empty())
++ return QCameraFormat{};
++
++ const auto found =
++ ranges::max(formats, [&](const QCameraFormat &fmtA, const QCameraFormat &fmtB) {
++ return makeCriteria(fmtA) < makeCriteria(fmtB);
++ });
++
++ return found;
++ }
++
++ QVideoFrameFormat QPlatformCamera::frameFormat() const
++ {
++ QVideoFrameFormat result(m_cameraFormat.resolution(),
++ m_framePixelFormat == QVideoFrameFormat::Format_Invalid
++ ? m_cameraFormat.pixelFormat()
++ : m_framePixelFormat);
++ result.setStreamFrameRate(m_cameraFormat.maxFrameRate());
++ return result;
++ }
++
++ void QPlatformCamera::supportedFeaturesChanged(QCamera::Features f)
++ {
++ if (m_supportedFeatures == f)
++ return;
++ m_supportedFeatures = f;
++ Q_EMIT m_camera->supportedFeaturesChanged();
++ }
++
++ void QPlatformCamera::minimumZoomFactorChanged(float factor)
++ {
++ if (m_minZoom == factor)
++ return;
++ m_minZoom = factor;
++ Q_EMIT m_camera->minimumZoomFactorChanged(factor);
++ }
++
++ void QPlatformCamera::maximumZoomFactorChanged(float factor)
++ {
++ if (m_maxZoom == factor)
++ return;
++ m_maxZoom = factor;
++ Q_EMIT m_camera->maximumZoomFactorChanged(factor);
++ }
++
++ void QPlatformCamera::focusModeChanged(QCamera::FocusMode mode)
++ {
++ if (m_focusMode == mode)
++ return;
++ m_focusMode = mode;
++ Q_EMIT m_camera->focusModeChanged();
++ }
++
++ void QPlatformCamera::customFocusPointChanged(const QPointF &point)
++ {
++ if (m_customFocusPoint == point)
++ return;
++ m_customFocusPoint = point;
++ Q_EMIT m_camera->customFocusPointChanged();
++ }
++
++
++ void QPlatformCamera::zoomFactorChanged(float zoom)
++ {
++ if (m_zoomFactor == zoom)
++ return;
++ m_zoomFactor = zoom;
++ Q_EMIT m_camera->zoomFactorChanged(zoom);
++ }
++
++
++ void QPlatformCamera::focusDistanceChanged(float d)
++ {
++ if (m_focusDistance == d)
++ return;
++ m_focusDistance = d;
++ Q_EMIT m_camera->focusDistanceChanged(m_focusDistance);
++ }
++
++
++ void QPlatformCamera::flashReadyChanged(bool ready)
++ {
++ if (m_flashReady == ready)
++ return;
++ m_flashReady = ready;
++ Q_EMIT m_camera->flashReady(m_flashReady);
++ }
++
++ void QPlatformCamera::flashModeChanged(QCamera::FlashMode mode)
++ {
++ if (m_flashMode == mode)
++ return;
++ m_flashMode = mode;
++ Q_EMIT m_camera->flashModeChanged();
++ }
++
++ void QPlatformCamera::torchModeChanged(QCamera::TorchMode mode)
++ {
++ if (m_torchMode == mode)
++ return;
++ m_torchMode = mode;
++ Q_EMIT m_camera->torchModeChanged();
++ }
++
++ void QPlatformCamera::exposureModeChanged(QCamera::ExposureMode mode)
++ {
++ if (m_exposureMode == mode)
++ return;
++ m_exposureMode = mode;
++ Q_EMIT m_camera->exposureModeChanged();
++ }
++
++ void QPlatformCamera::exposureCompensationChanged(float compensation)
++ {
++ if (m_exposureCompensation == compensation)
++ return;
++ m_exposureCompensation = compensation;
++ Q_EMIT m_camera->exposureCompensationChanged(compensation);
++ }
++
++ void QPlatformCamera::exposureCompensationRangeChanged(float min, float max)
++ {
++ if (m_minExposureCompensation == min && m_maxExposureCompensation == max)
++ return;
++ m_minExposureCompensation = min;
++ m_maxExposureCompensation = max;
++ // tell frontend
++ }
++
++ void QPlatformCamera::isoSensitivityChanged(int iso)
++ {
++ if (m_iso == iso)
++ return;
++ m_iso = iso;
++ Q_EMIT m_camera->isoSensitivityChanged(iso);
++ }
++
++ void QPlatformCamera::exposureTimeChanged(float speed)
++ {
++ if (m_exposureTime == speed)
++ return;
++ m_exposureTime = speed;
++ Q_EMIT m_camera->exposureTimeChanged(speed);
++ }
++
++ void QPlatformCamera::whiteBalanceModeChanged(QCamera::WhiteBalanceMode mode)
++ {
++ if (m_whiteBalance == mode)
++ return;
++ m_whiteBalance = mode;
++ Q_EMIT m_camera->whiteBalanceModeChanged();
++ }
++
++ void QPlatformCamera::colorTemperatureChanged(int temperature)
++ {
++ Q_ASSERT(temperature >= 0);
++ Q_ASSERT((temperature > 0 && whiteBalanceMode() == QCamera::WhiteBalanceManual) ||
++ (temperature == 0 && whiteBalanceMode() == QCamera::WhiteBalanceAuto));
++ if (m_colorTemperature == temperature)
++ return;
++ m_colorTemperature = temperature;
++ Q_EMIT m_camera->colorTemperatureChanged();
++ }
++
++ int QPlatformCamera::colorTemperatureForWhiteBalance(QCamera::WhiteBalanceMode mode)
++ {
++ switch (mode) {
++ case QCamera::WhiteBalanceAuto:
++ break;
++ case QCamera::WhiteBalanceManual:
++ case QCamera::WhiteBalanceSunlight:
++ return 5600;
++ case QCamera::WhiteBalanceCloudy:
++ return 6000;
++ case QCamera::WhiteBalanceShade:
++ return 7000;
++ case QCamera::WhiteBalanceTungsten:
++ return 3200;
++ case QCamera::WhiteBalanceFluorescent:
++ return 4000;
++ case QCamera::WhiteBalanceFlash:
++ return 5500;
++ case QCamera::WhiteBalanceSunset:
++ return 3000;
++ }
++ return 0;
++ }
++
++ void QPlatformCamera::updateError(QCamera::Error error, const QString &errorString)
++ {
++ QMetaObject::invokeMethod(this, [this, error, errorString]() {
++ m_error.setAndNotify(error, errorString, *this);
++ });
++ }
++
++ QT_END_NAMESPACE
++
++ #include "moc_qplatformcamera_p.cpp"