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
qpipewire_camera.cpp
Go to the documentation of this file.
1
// Copyright (C) 2026 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
4
#
include
"qpipewire_camera_p.h"
5
6
#
include
<
QtMultimedia
/
private
/
qpipewire_cameracontextmanager_p
.
h
>
7
#
include
<
QtMultimedia
/
private
/
qpipewire_videostream_p
.
h
>
8
#
include
<
QtCore
/
qloggingcategory
.
h
>
9
10
QT_BEGIN_NAMESPACE
11
12
namespace
QtPipeWire
{
13
14
using
namespace
Qt
::
StringLiterals
;
15
16
Q_STATIC_LOGGING_CATEGORY
(
lcPipewireCamera
,
"qt.multimedia.pipewire.camera"
)
17
18
QPipeWireCamera
::
QPipeWireCamera
(
QCamera
*
camera
) :
QPlatformCamera
(
camera
)
19
{
20
Q_ASSERT
(
QCameraContextManager
::
isSupported
());
21
}
22
23
QPipeWireCamera
::~
QPipeWireCamera
()
24
{
25
stopStream
();
26
}
27
28
bool
QPipeWireCamera
::
isActive
()
const
29
{
30
return
m_active
;
31
}
32
33
void
QPipeWireCamera
::
setActive
(
bool
active
)
34
{
35
if
(
m_active
==
active
)
36
return
;
37
38
if
(
active
&&
m_cameraDevice
.
isNull
())
39
return
;
40
41
if
(
m_cameraFormat
.
isNull
())
42
resolveCameraFormat
({});
43
44
m_active
=
active
;
45
46
if
(
m_active
)
47
startStream
();
48
else
{
49
stopStream
();
50
// Tells any attached sink to drop what it is showing
51
emit
newVideoFrame
({});
52
}
53
54
emit
activeChanged
(
m_active
);
55
}
56
57
void
QPipeWireCamera
::
setCamera
(
const
QCameraDevice
&
camera
)
58
{
59
if
(
m_cameraDevice
==
camera
)
60
return
;
61
62
const
bool
wasActive
=
m_active
;
63
stopStream
();
64
65
m_cameraDevice
=
camera
;
66
resolveCameraFormat
({});
67
68
if
(
wasActive
)
69
startStream
();
70
}
71
72
bool
QPipeWireCamera
::
setCameraFormat
(
const
QCameraFormat
&
format
)
73
{
74
if
(!
format
.
isNull
() && !
m_cameraDevice
.
videoFormats
().
contains
(
format
))
75
return
false
;
76
77
if
(!
resolveCameraFormat
(
format
))
78
return
true
;
79
80
if
(
m_active
) {
81
stopStream
();
82
startStream
();
83
}
84
85
return
true
;
86
}
87
88
bool
QPipeWireCamera
::
resolveCameraFormat
(
const
QCameraFormat
&
format
)
89
{
90
QCameraFormat
resolved
=
format
;
91
if
(
resolved
.
isNull
())
92
resolved
=
findBestCameraFormat
(
m_cameraDevice
);
93
94
if
(
resolved
==
m_cameraFormat
)
95
return
false
;
96
97
m_cameraFormat
=
resolved
;
98
return
true
;
99
}
100
101
QVideoFrameFormat
QPipeWireCamera
::
frameFormat
()
const
102
{
103
// Until the stream has negotiated a format, report what was requested, so
104
// that a sink has something to work with.
105
if
(
m_stream
) {
106
QVideoFrameFormat
negotiated
=
m_stream
->
frameFormat
();
107
if
(
negotiated
.
isValid
())
108
return
negotiated
;
109
}
110
111
return
QPlatformCamera
::
frameFormat
();
112
}
113
114
void
QPipeWireCamera
::
startStream
()
115
{
116
Q_ASSERT
(!
m_stream
);
117
118
QCameraContextManager
&
context
= *
QCameraContextManager
::
instance
();
119
120
const
std
::
optional
<
QByteArray
>
target
=
121
QCameraContextManager
::
deviceMonitor
().
findTargetObject
(
m_cameraDevice
.
id
());
122
if
(!
target
) {
123
const
QByteArray
id
=
m_cameraDevice
.
id
();
124
if
(!
id
.
startsWith
(
"pw:"
)) {
125
updateError
(
QCamera
::
CameraError
,
126
u"The camera id \"%1\" does not name a PipeWire camera. Camera ids are "
127
"not interchangeable between backends."_s
.
arg
(
QString
::
fromUtf8
(
id
)));
128
}
else
{
129
updateError
(
QCamera
::
CameraError
,
130
u"No PipeWire camera with the id \"%1\" is present."_s.
arg
(
131
QString
::
fromUtf8
(
id
)));
132
}
133
return
;
134
}
135
136
m_stream
=
std
::
make_unique
<
QPipeWireVideoStream
>(
137
context
, *
target
,
m_cameraFormat
.
pixelFormat
(),
m_cameraFormat
.
resolution
(),
138
m_cameraFormat
.
maxFrameRate
());
139
140
connect
(
m_stream
.
get
(), &
QPipeWireVideoStream
::
newVideoFrame
,
this
,
141
&
QPipeWireCamera
::
newVideoFrame
,
Qt
::
DirectConnection
);
142
connect
(
m_stream
.
get
(), &
QPipeWireVideoStream
::
errorOccurred
,
this
,
143
[
this
](
const
QString
&
errorString
) {
144
updateError
(
QCamera
::
CameraError
,
errorString
);
145
},
Qt
::
QueuedConnection
);
146
147
if
(!
m_stream
->
start
()) {
148
m_stream
.
reset
();
149
updateError
(
QCamera
::
CameraError
, u"Could not start the PipeWire camera stream."_s);
150
return
;
151
}
152
153
qCDebug
(
lcPipewireCamera
) <<
"streaming from"
<< *
target
<<
"as"
<<
m_cameraFormat
.
pixelFormat
()
154
<<
m_cameraFormat
.
resolution
();
155
}
156
157
void
QPipeWireCamera
::
stopStream
()
158
{
159
m_stream
.
reset
();
160
}
161
162
}
// namespace QtPipeWire
163
164
QT_END_NAMESPACE
QT_BEGIN_NAMESPACE
Combined button and popup list for selecting options.
Definition
qsequentialanimationgroup.cpp:47
QtPipeWire
Definition
qpipewire_async_support.cpp:10
QtPipeWire::Q_STATIC_LOGGING_CATEGORY
Q_STATIC_LOGGING_CATEGORY(lcPipewireAudioSink, "qt.multimedia.pipewire.audiosink")
qtmultimedia
src
multimedia
pipewire
qpipewire_camera.cpp
Generated on
for Qt by
1.16.1