6#include <QtMultimedia/qcameradevice.h>
7#include <QtMultimedia/qmediacapturesession.h>
8#include <QtCore/qdebug.h>
14#if QT_CONFIG(linux_v4l)
15#include <linux/videodev2.h>
16#include <private/qcore_unix_p.h>
47 gstCamera(
std::move(videotestsrc)),
48 gstCapsFilter(
std::move(capsFilter)),
49 gstVideoConvert(
std::move(videoconvert)),
50 gstVideoScale(
std::move(videoscale))
54 gstCameraBin.
add(gstCamera, gstCapsFilter, gstDecode, gstVideoConvert, gstVideoScale);
55 qLinkGstElements(gstCamera, gstCapsFilter, gstDecode, gstVideoConvert, gstVideoScale);
71 if (m_active == active)
73 if (m_cameraDevice.
isNull() && active)
85 if (m_cameraDevice ==
camera)
95 GstDevice *
device = integration->videoDevice(
camera.id());
99 u
"Failed to create GstDevice for camera: "_s
106 if (
properties.name() ==
"v4l2deviceprovider")
118 qUnlinkGstElements(gstCamera, gstCapsFilter, gstDecode, gstVideoConvert);
119 gstCameraBin.stopAndRemoveElements(gstCamera, gstDecode);
121 gstCapsFilter.set(
"caps", caps);
123 gstCamera = std::move(gstNewCamera);
124 gstDecode = std::move(gstNewDecode);
126 gstCameraBin.add(gstCamera, gstDecode);
127 qLinkGstElements(gstCamera, gstCapsFilter, gstDecode, gstVideoConvert);
129 gstCameraBin.syncChildrenState();
132 updateCameraProperties();
150 newGstDecode.syncStateWithParent();
152 qUnlinkGstElements(gstCamera, gstCapsFilter, gstDecode, gstVideoConvert);
153 gstCameraBin.stopAndRemoveElements(gstDecode);
155 gstCapsFilter.set(
"caps", caps);
157 gstDecode = std::move(newGstDecode);
159 gstCameraBin.add(gstDecode);
160 qLinkGstElements(gstCamera, gstCapsFilter, gstDecode, gstVideoConvert);
161 gstCameraBin.syncChildrenState();
167void QGstreamerCamera::updateCameraProperties()
169#if QT_CONFIG(linux_v4l)
170 if (isV4L2Camera()) {
175#if QT_CONFIG(gstreamer_photography)
176 if (
auto *
p = photography())
177 gst_photography_set_white_balance_mode(
p, GST_PHOTOGRAPHY_WB_MODE_AUTO);
185#if QT_CONFIG(gstreamer_photography)
186GstPhotography *QGstreamerCamera::photography()
const
188 if (!gstCamera.
isNull() && GST_IS_PHOTOGRAPHY(gstCamera.
element()))
189 return GST_PHOTOGRAPHY(gstCamera.
element());
199#if QT_CONFIG(gstreamer_photography)
200 auto p = photography();
202 GstPhotographyFocusMode photographyMode = GST_PHOTOGRAPHY_FOCUS_MODE_CONTINUOUS_NORMAL;
206 photographyMode = GST_PHOTOGRAPHY_FOCUS_MODE_MACRO;
212 photographyMode = GST_PHOTOGRAPHY_FOCUS_MODE_HYPERFOCAL;
215 photographyMode = GST_PHOTOGRAPHY_FOCUS_MODE_INFINITY;
218 photographyMode = GST_PHOTOGRAPHY_FOCUS_MODE_MANUAL;
224 if (gst_photography_set_focus_mode(
p, photographyMode))
232#if QT_CONFIG(gstreamer_photography)
243#if QT_CONFIG(gstreamer_photography)
244 if (
auto *
p = photography()) {
246 gst_photography_get_flash_mode(
p, &
flashMode);
250 flashMode = GST_PHOTOGRAPHY_FLASH_MODE_AUTO;
253 flashMode = GST_PHOTOGRAPHY_FLASH_MODE_OFF;
256 flashMode = GST_PHOTOGRAPHY_FLASH_MODE_ON;
260 if (gst_photography_set_flash_mode(
p,
flashMode))
268#if QT_CONFIG(gstreamer_photography)
278#if QT_CONFIG(gstreamer_photography)
289#if QT_CONFIG(linux_v4l)
290 if (isV4L2Camera() && v4l2AutoExposureSupported && v4l2ManualExposureSupported) {
294 setV4L2Parameter(V4L2_CID_EXPOSURE_AUTO,
value);
300#if QT_CONFIG(gstreamer_photography)
301 auto *
p = photography();
305 GstPhotographySceneMode sceneMode = GST_PHOTOGRAPHY_SCENE_MODE_AUTO;
309 sceneMode = GST_PHOTOGRAPHY_SCENE_MODE_MANUAL;
312 sceneMode = GST_PHOTOGRAPHY_SCENE_MODE_PORTRAIT;
315 sceneMode = GST_PHOTOGRAPHY_SCENE_MODE_SPORT;
318 sceneMode = GST_PHOTOGRAPHY_SCENE_MODE_NIGHT;
321 sceneMode = GST_PHOTOGRAPHY_SCENE_MODE_AUTO;
324 sceneMode = GST_PHOTOGRAPHY_SCENE_MODE_LANDSCAPE;
327 sceneMode = GST_PHOTOGRAPHY_SCENE_MODE_SNOW;
330 sceneMode = GST_PHOTOGRAPHY_SCENE_MODE_BEACH;
333 sceneMode = GST_PHOTOGRAPHY_SCENE_MODE_ACTION;
336 sceneMode = GST_PHOTOGRAPHY_SCENE_MODE_NIGHT_PORTRAIT;
339 sceneMode = GST_PHOTOGRAPHY_SCENE_MODE_THEATRE;
342 sceneMode = GST_PHOTOGRAPHY_SCENE_MODE_SUNSET;
345 sceneMode = GST_PHOTOGRAPHY_SCENE_MODE_STEADY_PHOTO;
348 sceneMode = GST_PHOTOGRAPHY_SCENE_MODE_FIREWORKS;
351 sceneMode = GST_PHOTOGRAPHY_SCENE_MODE_PARTY;
354 sceneMode = GST_PHOTOGRAPHY_SCENE_MODE_CANDLELIGHT;
357 sceneMode = GST_PHOTOGRAPHY_SCENE_MODE_BARCODE;
363 if (gst_photography_set_scene_mode(
p, sceneMode))
372#if QT_CONFIG(linux_v4l)
373 if (isV4L2Camera() && v4l2ManualExposureSupported && v4l2AutoExposureSupported)
376#if QT_CONFIG(gstreamer_photography)
387#if QT_CONFIG(linux_v4l)
388 if (isV4L2Camera() && (v4l2MinExposureAdjustment != 0 || v4l2MaxExposureAdjustment != 0)) {
389 int value =
qBound(v4l2MinExposureAdjustment, (
int)(compensation*1000), v4l2MaxExposureAdjustment);
390 setV4L2Parameter(V4L2_CID_AUTO_EXPOSURE_BIAS,
value);
396#if QT_CONFIG(gstreamer_photography)
397 if (
auto *
p = photography()) {
398 if (gst_photography_set_ev_compensation(
p, compensation))
407#if QT_CONFIG(linux_v4l)
408 if (isV4L2Camera()) {
411 setV4L2Parameter(V4L2_CID_ISO_SENSITIVITY_AUTO, iso <= 0 ? V4L2_ISO_SENSITIVITY_AUTO : V4L2_ISO_SENSITIVITY_MANUAL);
414 setV4L2Parameter(V4L2_CID_ISO_SENSITIVITY, iso);
419#if QT_CONFIG(gstreamer_photography)
420 if (
auto *
p = photography()) {
421 if (gst_photography_set_iso_speed(
p, iso))
429#if QT_CONFIG(linux_v4l)
430 if (isV4L2Camera()) {
433 return getV4L2Parameter(V4L2_CID_ISO_SENSITIVITY);
436#if QT_CONFIG(gstreamer_photography)
437 if (
auto *
p = photography()) {
439 if (gst_photography_get_iso_speed(
p, &speed))
449#if QT_CONFIG(linux_v4l)
450 if (isV4L2Camera() && v4l2ManualExposureSupported && v4l2AutoExposureSupported) {
451 int exposure =
qBound(v4l2MinExposure,
qRound(secs*10000.), v4l2MaxExposure);
452 setV4L2Parameter(V4L2_CID_EXPOSURE_ABSOLUTE, exposure);
458#if QT_CONFIG(gstreamer_photography)
459 if (
auto *
p = photography()) {
460 if (gst_photography_set_exposure(
p, guint(secs*1000000)))
468#if QT_CONFIG(linux_v4l)
469 if (isV4L2Camera()) {
470 return getV4L2Parameter(V4L2_CID_EXPOSURE_ABSOLUTE)/10000.;
473#if QT_CONFIG(gstreamer_photography)
474 if (
auto *
p = photography()) {
475 guint32 exposure = 0;
476 if (gst_photography_get_exposure(
p, &exposure))
477 return exposure/1000000.;
488#if QT_CONFIG(linux_v4l)
489 if (isV4L2Camera()) {
490 if (v4l2AutoWhiteBalanceSupported && v4l2ColorTemperatureSupported)
494#if QT_CONFIG(gstreamer_photography)
495 if (
auto *
p = photography()) {
507#if GST_CHECK_VERSION(1, 18, 0)
508 GstPhotographyInterface *iface = GST_PHOTOGRAPHY_GET_INTERFACE(
p);
509 if (iface->set_color_temperature && iface->get_color_temperature)
527#if QT_CONFIG(linux_v4l)
528 if (isV4L2Camera()) {
530 int t = setV4L2ColorTemperature(temperature);
538#if QT_CONFIG(gstreamer_photography)
539 if (
auto *
p = photography()) {
540 GstPhotographyWhiteBalanceMode gstMode = GST_PHOTOGRAPHY_WB_MODE_AUTO;
543 gstMode = GST_PHOTOGRAPHY_WB_MODE_DAYLIGHT;
546 gstMode = GST_PHOTOGRAPHY_WB_MODE_CLOUDY;
549 gstMode = GST_PHOTOGRAPHY_WB_MODE_SHADE;
552 gstMode = GST_PHOTOGRAPHY_WB_MODE_SUNSET;
555 gstMode = GST_PHOTOGRAPHY_WB_MODE_TUNGSTEN;
558 gstMode = GST_PHOTOGRAPHY_WB_MODE_FLUORESCENT;
564 if (gst_photography_set_white_balance_mode(
p, gstMode)) {
574 if (temperature == 0) {
581#if QT_CONFIG(linux_v4l)
582 if (isV4L2Camera()) {
583 int t = setV4L2ColorTemperature(temperature);
590#if QT_CONFIG(gstreamer_photography) && GST_CHECK_VERSION(1, 18, 0)
591 if (
auto *
p = photography()) {
592 GstPhotographyInterface *iface = GST_PHOTOGRAPHY_GET_INTERFACE(
p);
593 Q_ASSERT(iface->set_color_temperature);
594 iface->set_color_temperature(
p, temperature);
600#if QT_CONFIG(linux_v4l)
601bool QGstreamerCamera::isV4L2Camera()
const
603 return !m_v4l2DevicePath.
isEmpty();
606void QGstreamerCamera::initV4L2Controls()
608 v4l2AutoWhiteBalanceSupported =
false;
609 v4l2ColorTemperatureSupported =
false;
610 QCamera::Features features{};
615 withV4L2DeviceFileDescriptor([&](
int fd) {
616 struct v4l2_queryctrl queryControl = {};
617 queryControl.id = V4L2_CID_AUTO_WHITE_BALANCE;
619 if (::ioctl(
fd, VIDIOC_QUERYCTRL, &queryControl) == 0) {
620 v4l2AutoWhiteBalanceSupported =
true;
621 setV4L2Parameter(V4L2_CID_AUTO_WHITE_BALANCE,
true);
625 queryControl.id = V4L2_CID_WHITE_BALANCE_TEMPERATURE;
626 if (::ioctl(
fd, VIDIOC_QUERYCTRL, &queryControl) == 0) {
627 v4l2MinColorTemp = queryControl.minimum;
628 v4l2MaxColorTemp = queryControl.maximum;
629 v4l2ColorTemperatureSupported =
true;
634 queryControl.id = V4L2_CID_EXPOSURE_AUTO;
635 if (::ioctl(
fd, VIDIOC_QUERYCTRL, &queryControl) == 0) {
636 v4l2AutoExposureSupported =
true;
640 queryControl.id = V4L2_CID_EXPOSURE_ABSOLUTE;
641 if (::ioctl(
fd, VIDIOC_QUERYCTRL, &queryControl) == 0) {
642 v4l2ManualExposureSupported =
true;
643 v4l2MinExposure = queryControl.minimum;
644 v4l2MaxExposure = queryControl.maximum;
649 queryControl.id = V4L2_CID_AUTO_EXPOSURE_BIAS;
650 if (::ioctl(
fd, VIDIOC_QUERYCTRL, &queryControl) == 0) {
651 v4l2MinExposureAdjustment = queryControl.minimum;
652 v4l2MaxExposureAdjustment = queryControl.maximum;
657 queryControl.id = V4L2_CID_ISO_SENSITIVITY_AUTO;
658 if (::ioctl(
fd, VIDIOC_QUERYCTRL, &queryControl) == 0) {
659 queryControl.id = V4L2_CID_ISO_SENSITIVITY;
660 if (::ioctl(
fd, VIDIOC_QUERYCTRL, &queryControl) == 0) {
671int QGstreamerCamera::setV4L2ColorTemperature(
int temperature)
673 if (v4l2AutoWhiteBalanceSupported) {
674 setV4L2Parameter(V4L2_CID_AUTO_WHITE_BALANCE, temperature == 0 ?
true :
false);
675 }
else if (temperature == 0) {
679 if (temperature != 0 && v4l2ColorTemperatureSupported) {
680 temperature =
qBound(v4l2MinColorTemp, temperature, v4l2MaxColorTemp);
681 if (!setV4L2Parameter(V4L2_CID_WHITE_BALANCE_TEMPERATURE,
qBound(v4l2MinColorTemp, temperature, v4l2MaxColorTemp)))
692 return withV4L2DeviceFileDescriptor([&](
int fd) {
693 v4l2_control control{
id,
value };
694 if (::ioctl(
fd, VIDIOC_S_CTRL, &control) != 0) {
703int QGstreamerCamera::getV4L2Parameter(
quint32 id)
const
705 return withV4L2DeviceFileDescriptor([&](
int fd) {
706 v4l2_control control{
id, 0 };
707 if (::ioctl(
fd, VIDIOC_G_CTRL, &control) != 0) {
712 return control.value;
720#include "moc_qgstreamercamera_p.cpp"
IOBluetoothDevice * device
The QCameraDevice class provides general information about camera devices.
bool isNull() const
Returns true if this QCameraDevice is null or invalid.
QList< QCameraFormat > videoFormats
\qmlproperty CameraFormat QtMultimedia::cameraDevice::videoFormats
The QCamera class provides interface for system camera devices.
WhiteBalanceMode
\value WhiteBalanceAuto Auto white balance mode.
@ WhiteBalanceFluorescent
FocusMode
\value FocusModeAuto Continuous auto focus mode.
FlashMode
\value FlashOff Flash is Off.
ExposureMode
\value ExposureAuto Automatic mode.
std::enable_if_t<(std::is_base_of_v< QGstElement, Ts > &&...), void add)(const Ts &...ts)
static QGstBin create(const char *name)
void addGhostPad(const QGstElement &child, const char *name)
static QGstCaps fromCameraFormat(const QCameraFormat &format)
static QGstElement createFromDevice(const QGstDeviceHandle &, const char *name=nullptr)
GstElement * element() const
bool setStateSync(GstState state, std::chrono::nanoseconds timeout=std::chrono::seconds(1))
static QGstElement createFromFactory(const char *factory, const char *name=nullptr)
QGstPipeline getPipeline() const
void modifyPipelineWhileNotRunning(Functor &&fn)
void setWhiteBalanceMode(QCamera::WhiteBalanceMode mode) override
bool isFocusModeSupported(QCamera::FocusMode mode) const override
bool isActive() const override
virtual ~QGstreamerCamera()
bool isFlashModeSupported(QCamera::FlashMode mode) const override
bool isExposureModeSupported(QCamera::ExposureMode mode) const override
bool setCameraFormat(const QCameraFormat &format) override
void setColorTemperature(int temperature) override
void setExposureMode(QCamera::ExposureMode) override
bool isFlashReady() const override
static QMaybe< QPlatformCamera * > create(QCamera *camera)
int isoSensitivity() const override
float exposureTime() const override
bool isWhiteBalanceModeSupported(QCamera::WhiteBalanceMode mode) const override
void setFlashMode(QCamera::FlashMode mode) override
void setFocusMode(QCamera::FocusMode mode) override
void setActive(bool active) override
void setManualIsoSensitivity(int) override
void setCamera(const QCameraDevice &camera) override
void setManualExposureTime(float) override
void setExposureCompensation(float) override
static QGstreamerIntegration * instance()
bool isEmpty() const noexcept
Returns true if the string has no characters; otherwise returns false.
static QString fromUtf8(QByteArrayView utf8)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Combined button and popup list for selecting options.
QTextStream & hex(QTextStream &stream)
Calls QTextStream::setIntegerBase(16) on stream and returns stream.
static const QCssKnownValue properties[NumProperties - 1]
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
int qRound(qfloat16 d) noexcept
std::enable_if_t<(std::is_base_of_v< QGstElement, Ts > &&...), void qLinkGstElements)(const Ts &...ts)
QString errorMessageCannotFindElement(std::string_view element)
Q_DECL_COLD_FUNCTION Q_CORE_EXPORT QString qt_error_string(int errorCode=-1)
constexpr const T & qBound(const T &min, const T &val, const T &max)
GLint GLsizei GLsizei GLenum format
char * toString(const MyType &t)
[31]
bool contains(const AT &t) const noexcept