Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qv4l2camera.cpp
Go to the documentation of this file.
1// Copyright (C) 2021 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
5
6#include <QtMultimedia/private/qcameradevice_p.h>
7#include <QtMultimedia/private/qmemoryvideobuffer_p.h>
8#include <QtMultimedia/private/qmultimediautils_p.h>
9#include <QtMultimedia/private/qv4l2filedescriptor_p.h>
10#include <QtMultimedia/private/qv4l2memorytransfer_p.h>
11#include <QtMultimedia/private/qvideoframe_p.h>
12#include <QtCore/qloggingcategory.h>
13#include <QtCore/qsocketnotifier.h>
14#include <QtCore/private/qcore_unix_p.h>
15
17
18namespace QtV4L2 {
19
20Q_STATIC_LOGGING_CATEGORY(qLcV4L2Camera, "qt.multimedia.v4l2.camera");
21
22static const struct
23{
26} formatMap[] = {
27 // ### How do we handle V4L2_PIX_FMT_H264 and V4L2_PIX_FMT_MPEG4?
47};
48
50{
51 auto *f = formatMap;
52 while (f->v4l2Format) {
53 if (f->v4l2Format == v4l2Format)
54 return f->fmt;
55 ++f;
56 }
57 return QVideoFrameFormat::Format_Invalid;
58}
59
60uint32_t v4l2FormatForPixelFormat(QVideoFrameFormat::PixelFormat format)
61{
62 auto *f = formatMap;
63 while (f->v4l2Format) {
64 if (f->fmt == format)
65 return f->v4l2Format;
66 ++f;
67 }
68 return 0;
69}
70
72
78
79bool QV4L2Camera::isActive() const
80{
81 return m_active;
82}
83
85{
86 if (m_active == active)
87 return;
89 return;
90
93
95 if (m_active)
97 else
99
101
103}
104
106{
107 if (m_cameraDevice == camera)
108 return;
109
111 closeV4L2Fd();
112
115
117
118 if (m_active)
120}
121
123{
125 return false;
126
128 return true;
129
130 if (m_active) {
132 closeV4L2Fd();
133
136 }
137
138 return true;
139}
140
142{
143 auto fmt = format;
144 if (fmt.isNull())
146
147 if (fmt == m_cameraFormat)
148 return false;
149
151 return true;
152}
153
193
200
210
220
230
232{
234 return true;
235 return mode == QCamera::FlashOff;
236}
237
246
256
258{
259 if (mode == QCamera::TorchOn)
261 return mode == QCamera::TorchOff;
262}
263
275
284
295
307
309{
311 return -1;
313}
314
325
327{
329}
330
338
349
363
365{
367
369 if (!buffer) {
370 qCWarning(qLcV4L2Camera) << "Cannot take buffer";
371
372 if (errno == ENODEV) {
373 // camera got removed while being active
375 closeV4L2Fd();
376 }
377
378 return;
379 }
380
383
385
386 if (m_firstFrameTime.tv_sec == -1)
390 frame.setStartTime(secs * 1000000 + usecs);
392
394
396 qCWarning(qLcV4L2Camera) << "Cannot add buffer";
397}
398
400{
401 m_cameraBusy = true;
402 updateError(QCamera::CameraError, QLatin1String("Camera is in use"));
403}
404
406{
407 m_v4l2Info = {};
409
412
413 closeV4L2Fd();
414
416 if (descriptor == -1) {
417 qCWarning(qLcV4L2Camera) << "Unable to open the camera" << deviceName
418 << "for read to query the parameter info:"
420 updateError(QCamera::CameraError, QLatin1String("Cannot open camera"));
421 return;
422 }
423
426
427 qCDebug(qLcV4L2Camera) << "FD=" << descriptor;
428
430 ::memset(&queryControl, 0, sizeof(queryControl));
432
436 }
437
438 ::memset(&queryControl, 0, sizeof(queryControl));
445 }
446
447 ::memset(&queryControl, 0, sizeof(queryControl));
451 }
452
453 ::memset(&queryControl, 0, sizeof(queryControl));
460 }
461
462 ::memset(&queryControl, 0, sizeof(queryControl));
468 }
469
470 ::memset(&queryControl, 0, sizeof(queryControl));
478 }
479 }
480
481 ::memset(&queryControl, 0, sizeof(queryControl));
487 }
488
489 ::memset(&queryControl, 0, sizeof(queryControl));
492 m_v4l2Info.rangedFocus = true;
493 }
494
495 ::memset(&queryControl, 0, sizeof(queryControl));
502 }
503
504 ::memset(&queryControl, 0, sizeof(queryControl));
509 }
510 // zoom factors are in arbitrary units, so we simply normalize them to go from 1 to 2
511 // if they are different
514
516}
517
519{
521
522 m_v4l2Info = {};
523 m_cameraBusy = false;
524 m_v4l2FileDescriptor = nullptr;
525}
526
528{
529 struct v4l2_control control;
530 ::memset(&control, 0, sizeof(control));
531
534 } else if (temperature == 0) {
535 temperature = 5600;
536 }
537
540 if (!setV4L2Parameter(
543 temperature = 0;
544 } else {
545 temperature = 0;
546 }
547
548 return temperature;
549}
550
552{
555 qWarning() << "Unable to set the V4L2 Parameter" << Qt::hex << id << "to" << value
557 return false;
558 }
559 return true;
560}
561
563{
564 struct v4l2_control control{ id, 0 };
566 qWarning() << "Unable to get the V4L2 Parameter" << Qt::hex << id << qt_error_string(errno);
567 return 0;
568 }
569 return control.value;
570}
571
573{
575 return;
576
580
581 v4l2_format fmt = {};
583
589
590 qCDebug(qLcV4L2Camera) << "setting camera format to" << size << fmt.fmt.pix.pixelformat;
591
593 if (errno == EBUSY) {
595 return;
596 }
597 qWarning() << "Couldn't set video format on v4l2 camera" << qt_error_string(errno);
598 }
599
601 m_cameraBusy = false;
602
605
607 default:
610 break;
613 break;
616 break;
618 // ##### is this correct???
620 break;
623 break;
624 }
625
628
633
636}
637
639{
640 if (m_cameraBusy)
641 return;
642
644
646
648 return;
649
650 if (errno == EBUSY) {
652 return;
653 }
654
655 qCDebug(qLcV4L2Camera) << "Cannot init V4L2_MEMORY_USERPTR; trying V4L2_MEMORY_MMAP";
656
658
659 if (!m_memoryTransfer) {
660 qCWarning(qLcV4L2Camera) << "Cannot init v4l2 memory transfer," << qt_error_string(errno);
661 updateError(QCamera::CameraError, QLatin1String("Cannot init V4L2 memory transfer"));
662 }
663}
664
666{
668 return;
669
670 m_notifier = nullptr;
671
673 // TODO: handle the case carefully to avoid possible memory corruption
674 if (errno != ENODEV)
675 qWarning() << "failed to stop capture";
676 }
677
678 m_memoryTransfer = nullptr;
679 m_cameraBusy = false;
680}
681
683{
685 return;
686
689
691 return;
692
694 qWarning() << "Couldn't start v4l2 camera stream";
695 return;
696 }
697
698 m_notifier =
701
702 m_firstFrameTime = { -1, -1 };
703}
704
711
712} // namespace QtV4L2
713
714QT_END_NAMESPACE
715
716#include "moc_qv4l2camera_p.cpp"
Combined button and popup list for selecting options.
uint32_t v4l2FormatForPixelFormat(QVideoFrameFormat::PixelFormat format)
QVideoFrameFormat::PixelFormat fmt
QVideoFrameFormat::PixelFormat formatForV4L2Format(uint32_t v4l2Format)
Q_STATIC_LOGGING_CATEGORY(qLcV4L2Camera, "qt.multimedia.v4l2.camera")
uint32_t v4l2Format