Revision control
Copy as Markdown
// 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"