12#if QT_CONFIG(linux_v4l)
13#include <linux/videodev2.h>
14#include <private/qcore_unix_p.h>
17#include <QtCore/qdebug.h>
27 QGstElement capsFilter(
"capsfilter",
"videoCapsFilter");
31 QGstElement videoconvert(
"videoconvert",
"videoConvert");
46 gstCamera(
std::move(videotestsrc)),
47 gstCapsFilter(
std::move(capsFilter)),
48 gstVideoConvert(
std::move(videoconvert)),
49 gstVideoScale(
std::move(videoscale))
52 gstCameraBin =
QGstBin(
"camerabin");
53 gstCameraBin.
add(gstCamera, gstCapsFilter, gstDecode, gstVideoConvert, gstVideoScale);
54 gstCamera.
link(gstCapsFilter, gstDecode, gstVideoConvert, gstVideoScale);
60#if QT_CONFIG(linux_v4l)
61 if (v4l2FileDescriptor >= 0)
63 v4l2FileDescriptor = -1;
75 if (m_active == active)
77 if (m_cameraDevice.
isNull() && active)
87 if (m_cameraDevice ==
camera)
98 gstNewCamera = gst_device_create_element(
device,
"camerasrc");
110 gstCamera.
unlink(gstCapsFilter);
111 gstCapsFilter.
unlink(gstDecode);
112 gstDecode.
unlink(gstVideoConvert);
114 gstCameraBin.
remove(gstCamera);
115 gstCameraBin.
remove(gstDecode);
120 gstCapsFilter.
set(
"caps", caps);
122 gstCameraBin.
add(gstNewCamera, gstNewDecode);
124 gstNewDecode.link(gstVideoConvert);
125 gstCapsFilter.
link(gstNewDecode);
127 if (!gstNewCamera.
link(gstCapsFilter))
128 qWarning() <<
"linking camera failed" << gstCamera.
name() << caps.toString();
133 gstNewDecode.syncStateWithParent();
136 gstCamera = gstNewCamera;
137 gstDecode = gstNewDecode;
139 updateCameraProperties();
154 gstCameraBin.
add(newGstDecode);
155 newGstDecode.syncStateWithParent();
158 gstCamera.
unlink(gstCapsFilter);
159 gstCapsFilter.
unlink(gstDecode);
160 gstDecode.
unlink(gstVideoConvert);
162 gstCapsFilter.
set(
"caps", caps);
164 newGstDecode.link(gstVideoConvert);
165 gstCapsFilter.
link(newGstDecode);
166 if (!gstCamera.
link(gstCapsFilter))
167 qWarning() <<
"linking filtered camera to decoder failed" << gstCamera.
name() << caps.toString();
170 gstCameraBin.
remove(gstDecode);
173 gstDecode = newGstDecode;
178void QGstreamerCamera::updateCameraProperties()
180#if QT_CONFIG(linux_v4l)
186#if QT_CONFIG(gstreamer_photography)
187 if (
auto *
p = photography())
188 gst_photography_set_white_balance_mode(
p, GST_PHOTOGRAPHY_WB_MODE_AUTO);
196#if QT_CONFIG(gstreamer_photography)
197GstPhotography *QGstreamerCamera::photography()
const
199 if (!gstCamera.
isNull() && GST_IS_PHOTOGRAPHY(gstCamera.
element()))
200 return GST_PHOTOGRAPHY(gstCamera.
element());
210#if QT_CONFIG(gstreamer_photography)
211 auto p = photography();
213 GstPhotographyFocusMode photographyMode = GST_PHOTOGRAPHY_FOCUS_MODE_CONTINUOUS_NORMAL;
217 photographyMode = GST_PHOTOGRAPHY_FOCUS_MODE_MACRO;
223 photographyMode = GST_PHOTOGRAPHY_FOCUS_MODE_HYPERFOCAL;
226 photographyMode = GST_PHOTOGRAPHY_FOCUS_MODE_INFINITY;
229 photographyMode = GST_PHOTOGRAPHY_FOCUS_MODE_MANUAL;
235 if (gst_photography_set_focus_mode(
p, photographyMode))
243#if QT_CONFIG(gstreamer_photography)
254#if QT_CONFIG(gstreamer_photography)
255 if (
auto *
p = photography()) {
257 gst_photography_get_flash_mode(
p, &
flashMode);
261 flashMode = GST_PHOTOGRAPHY_FLASH_MODE_AUTO;
264 flashMode = GST_PHOTOGRAPHY_FLASH_MODE_OFF;
267 flashMode = GST_PHOTOGRAPHY_FLASH_MODE_ON;
271 if (gst_photography_set_flash_mode(
p,
flashMode))
279#if QT_CONFIG(gstreamer_photography)
289#if QT_CONFIG(gstreamer_photography)
300#if QT_CONFIG(linux_v4l)
301 if (
isV4L2Camera() && v4l2AutoExposureSupported && v4l2ManualExposureSupported) {
305 setV4L2Parameter(V4L2_CID_EXPOSURE_AUTO,
value);
311#if QT_CONFIG(gstreamer_photography)
312 auto *
p = photography();
316 GstPhotographySceneMode sceneMode = GST_PHOTOGRAPHY_SCENE_MODE_AUTO;
320 sceneMode = GST_PHOTOGRAPHY_SCENE_MODE_MANUAL;
323 sceneMode = GST_PHOTOGRAPHY_SCENE_MODE_PORTRAIT;
326 sceneMode = GST_PHOTOGRAPHY_SCENE_MODE_SPORT;
329 sceneMode = GST_PHOTOGRAPHY_SCENE_MODE_NIGHT;
332 sceneMode = GST_PHOTOGRAPHY_SCENE_MODE_AUTO;
335 sceneMode = GST_PHOTOGRAPHY_SCENE_MODE_LANDSCAPE;
338 sceneMode = GST_PHOTOGRAPHY_SCENE_MODE_SNOW;
341 sceneMode = GST_PHOTOGRAPHY_SCENE_MODE_BEACH;
344 sceneMode = GST_PHOTOGRAPHY_SCENE_MODE_ACTION;
347 sceneMode = GST_PHOTOGRAPHY_SCENE_MODE_NIGHT_PORTRAIT;
350 sceneMode = GST_PHOTOGRAPHY_SCENE_MODE_THEATRE;
353 sceneMode = GST_PHOTOGRAPHY_SCENE_MODE_SUNSET;
356 sceneMode = GST_PHOTOGRAPHY_SCENE_MODE_STEADY_PHOTO;
359 sceneMode = GST_PHOTOGRAPHY_SCENE_MODE_FIREWORKS;
362 sceneMode = GST_PHOTOGRAPHY_SCENE_MODE_PARTY;
365 sceneMode = GST_PHOTOGRAPHY_SCENE_MODE_CANDLELIGHT;
368 sceneMode = GST_PHOTOGRAPHY_SCENE_MODE_BARCODE;
374 if (gst_photography_set_scene_mode(
p, sceneMode))
383#if QT_CONFIG(linux_v4l)
384 if (
isV4L2Camera() && v4l2ManualExposureSupported && v4l2AutoExposureSupported)
387#if QT_CONFIG(gstreamer_photography)
398#if QT_CONFIG(linux_v4l)
399 if (
isV4L2Camera() && (v4l2MinExposureAdjustment != 0 || v4l2MaxExposureAdjustment != 0)) {
400 int value =
qBound(v4l2MinExposureAdjustment, (
int)(compensation*1000), v4l2MaxExposureAdjustment);
401 setV4L2Parameter(V4L2_CID_AUTO_EXPOSURE_BIAS,
value);
407#if QT_CONFIG(gstreamer_photography)
408 if (
auto *
p = photography()) {
409 if (gst_photography_set_ev_compensation(
p, compensation))
418#if QT_CONFIG(linux_v4l)
422 setV4L2Parameter(V4L2_CID_ISO_SENSITIVITY_AUTO, iso <= 0 ? V4L2_ISO_SENSITIVITY_AUTO : V4L2_ISO_SENSITIVITY_MANUAL);
425 setV4L2Parameter(V4L2_CID_ISO_SENSITIVITY, iso);
430#if QT_CONFIG(gstreamer_photography)
431 if (
auto *
p = photography()) {
432 if (gst_photography_set_iso_speed(
p, iso))
440#if QT_CONFIG(linux_v4l)
444 return getV4L2Parameter(V4L2_CID_ISO_SENSITIVITY);
447#if QT_CONFIG(gstreamer_photography)
448 if (
auto *
p = photography()) {
450 if (gst_photography_get_iso_speed(
p, &speed))
460#if QT_CONFIG(linux_v4l)
461 if (
isV4L2Camera() && v4l2ManualExposureSupported && v4l2AutoExposureSupported) {
462 int exposure =
qBound(v4l2MinExposure,
qRound(secs*10000.), v4l2MaxExposure);
463 setV4L2Parameter(V4L2_CID_EXPOSURE_ABSOLUTE, exposure);
469#if QT_CONFIG(gstreamer_photography)
470 if (
auto *
p = photography()) {
471 if (gst_photography_set_exposure(
p, guint(secs*1000000)))
479#if QT_CONFIG(linux_v4l)
481 return getV4L2Parameter(V4L2_CID_EXPOSURE_ABSOLUTE)/10000.;
484#if QT_CONFIG(gstreamer_photography)
485 if (
auto *
p = photography()) {
486 guint32 exposure = 0;
487 if (gst_photography_get_exposure(
p, &exposure))
488 return exposure/1000000.;
499#if QT_CONFIG(linux_v4l)
501 if (v4l2AutoWhiteBalanceSupported && v4l2ColorTemperatureSupported)
505#if QT_CONFIG(gstreamer_photography)
506 if (
auto *
p = photography()) {
518#if GST_CHECK_VERSION(1, 18, 0)
519 GstPhotographyInterface *iface = GST_PHOTOGRAPHY_GET_INTERFACE(
p);
520 if (iface->set_color_temperature && iface->get_color_temperature)
538#if QT_CONFIG(linux_v4l)
541 int t = setV4L2ColorTemperature(temperature);
549#if QT_CONFIG(gstreamer_photography)
550 if (
auto *
p = photography()) {
551 GstPhotographyWhiteBalanceMode gstMode = GST_PHOTOGRAPHY_WB_MODE_AUTO;
554 gstMode = GST_PHOTOGRAPHY_WB_MODE_DAYLIGHT;
557 gstMode = GST_PHOTOGRAPHY_WB_MODE_CLOUDY;
560 gstMode = GST_PHOTOGRAPHY_WB_MODE_SHADE;
563 gstMode = GST_PHOTOGRAPHY_WB_MODE_SUNSET;
566 gstMode = GST_PHOTOGRAPHY_WB_MODE_TUNGSTEN;
569 gstMode = GST_PHOTOGRAPHY_WB_MODE_FLUORESCENT;
575 if (gst_photography_set_white_balance_mode(
p, gstMode)) {
585 if (temperature == 0) {
592#if QT_CONFIG(linux_v4l)
594 int t = setV4L2ColorTemperature(temperature);
601#if QT_CONFIG(gstreamer_photography) && GST_CHECK_VERSION(1, 18, 0)
602 if (
auto *
p = photography()) {
603 GstPhotographyInterface *iface = GST_PHOTOGRAPHY_GET_INTERFACE(
p);
604 Q_ASSERT(iface->set_color_temperature);
605 iface->set_color_temperature(
p, temperature);
611#if QT_CONFIG(linux_v4l)
612void QGstreamerCamera::initV4L2Controls()
614 v4l2AutoWhiteBalanceSupported =
false;
615 v4l2ColorTemperatureSupported =
false;
616 QCamera::Features features;
623 if (v4l2FileDescriptor == -1) {
624 qWarning() <<
"Unable to open the camera" << deviceName
629 struct v4l2_queryctrl queryControl;
630 ::memset(&queryControl, 0,
sizeof(queryControl));
631 queryControl.id = V4L2_CID_AUTO_WHITE_BALANCE;
633 if (::ioctl(v4l2FileDescriptor, VIDIOC_QUERYCTRL, &queryControl) == 0) {
634 v4l2AutoWhiteBalanceSupported =
true;
635 setV4L2Parameter(V4L2_CID_AUTO_WHITE_BALANCE,
true);
638 ::memset(&queryControl, 0,
sizeof(queryControl));
639 queryControl.id = V4L2_CID_WHITE_BALANCE_TEMPERATURE;
640 if (::ioctl(v4l2FileDescriptor, VIDIOC_QUERYCTRL, &queryControl) == 0) {
641 v4l2MinColorTemp = queryControl.minimum;
642 v4l2MaxColorTemp = queryControl.maximum;
643 v4l2ColorTemperatureSupported =
true;
647 ::memset(&queryControl, 0,
sizeof(queryControl));
648 queryControl.id = V4L2_CID_EXPOSURE_AUTO;
649 if (::ioctl(v4l2FileDescriptor, VIDIOC_QUERYCTRL, &queryControl) == 0) {
650 v4l2AutoExposureSupported =
true;
653 ::memset(&queryControl, 0,
sizeof(queryControl));
654 queryControl.id = V4L2_CID_EXPOSURE_ABSOLUTE;
655 if (::ioctl(v4l2FileDescriptor, VIDIOC_QUERYCTRL, &queryControl) == 0) {
656 v4l2ManualExposureSupported =
true;
657 v4l2MinExposure = queryControl.minimum;
658 v4l2MaxExposure = queryControl.maximum;
662 ::memset(&queryControl, 0,
sizeof(queryControl));
663 queryControl.id = V4L2_CID_AUTO_EXPOSURE_BIAS;
664 if (::ioctl(v4l2FileDescriptor, VIDIOC_QUERYCTRL, &queryControl) == 0) {
665 v4l2MinExposureAdjustment = queryControl.minimum;
666 v4l2MaxExposureAdjustment = queryControl.maximum;
670 ::memset(&queryControl, 0,
sizeof(queryControl));
671 queryControl.id = V4L2_CID_ISO_SENSITIVITY_AUTO;
672 if (::ioctl(v4l2FileDescriptor, VIDIOC_QUERYCTRL, &queryControl) == 0) {
673 queryControl.id = V4L2_CID_ISO_SENSITIVITY;
674 if (::ioctl(v4l2FileDescriptor, VIDIOC_QUERYCTRL, &queryControl) == 0) {
684int QGstreamerCamera::setV4L2ColorTemperature(
int temperature)
686 struct v4l2_control control;
687 ::memset(&control, 0,
sizeof(control));
689 if (v4l2AutoWhiteBalanceSupported) {
690 setV4L2Parameter(V4L2_CID_AUTO_WHITE_BALANCE, temperature == 0 ?
true :
false);
691 }
else if (temperature == 0) {
695 if (temperature != 0 && v4l2ColorTemperatureSupported) {
696 temperature =
qBound(v4l2MinColorTemp, temperature, v4l2MaxColorTemp);
697 if (!setV4L2Parameter(V4L2_CID_WHITE_BALANCE_TEMPERATURE,
qBound(v4l2MinColorTemp, temperature, v4l2MaxColorTemp)))
708 struct v4l2_control control{
id,
value};
709 if (::ioctl(v4l2FileDescriptor, VIDIOC_S_CTRL, &control) != 0) {
716int QGstreamerCamera::getV4L2Parameter(
quint32 id)
const
718 struct v4l2_control control{
id, 0};
719 if (::ioctl(v4l2FileDescriptor, VIDIOC_G_CTRL, &control) != 0) {
723 return control.value;
730#include "moc_qgstreamercamera_p.cpp"
IOBluetoothDevice * device
const char * constData() const noexcept
Returns a pointer to the const data stored in the byte array.
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.
void addGhostPad(const QGstElement &child, const char *name)
void remove(const QGstElement &element)
void add(const QGstElement &element)
static QGstCaps fromCameraFormat(const QCameraFormat &format)
GstElement * element() const
bool setStateSync(GstState state)
bool syncStateWithParent()
void unlink(const QGstElement &next)
QGstPad staticPad(const char *name) const
bool link(const QGstElement &next)
const char * name() const
void set(const char *property, const char *str)
void doInIdleProbe(std::function< void()> work)
void setWhiteBalanceMode(QCamera::WhiteBalanceMode mode) override
bool isFocusModeSupported(QCamera::FocusMode mode) const override
bool isActive() const override
bool isV4L2Camera() const
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
QString v4l2Device() const
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()
\macro QT_RESTRICTED_CAST_FROM_ASCII
static QString fromUtf8(QByteArrayView utf8)
This is an overloaded member function, provided for convenience. It differs from the above function o...
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
QByteArray toLocal8Bit() const &
Combined button and popup list for selecting options.
QTextStream & hex(QTextStream &stream)
Calls QTextStream::setIntegerBase(16) on stream and returns stream.
static int qt_safe_open(const char *pathname, int flags, mode_t mode=0777)
static int qt_safe_close(int fd)
static const QCssKnownValue properties[NumProperties - 1]
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
int qRound(qfloat16 d) noexcept
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