QGroundControl
Ground Control Station for MAVLink Drones
Loading...
Searching...
No Matches
VideoSettings.cc
Go to the documentation of this file.
1#include "VideoSettings.h"
2#include "VideoManager.h"
3
5#include <QtCore/QSettings>
6#include <QtCore/QVariantList>
7
8QGC_LOGGING_CATEGORY(VideoSettingsLog, "Settings.VideoSettings")
9
10#ifdef QGC_GST_STREAMING
11#include "GStreamer.h"
12static constexpr bool kGstEnabled = true;
13#else
14static constexpr bool kGstEnabled = false;
15#endif
16#ifndef QGC_DISABLE_UVC
17#include "UVCReceiver.h"
18#endif
19
20DECLARE_SETTINGGROUP(Video, "Video")
21{
22 // Setup enum values for videoSource settings into meta data
23 QVariantList videoSourceList;
24#if defined(QGC_GST_STREAMING) || defined(QGC_QT_STREAMING)
25 videoSourceList.append(videoSourceRTSP);
26 videoSourceList.append(videoSourceUDPH264);
27 videoSourceList.append(videoSourceUDPH265);
28 videoSourceList.append(videoSourceTCP);
29 videoSourceList.append(videoSourceMPEGTS);
30 videoSourceList.append(videoSource3DRSolo);
31 videoSourceList.append(videoSourceParrotDiscovery);
32 videoSourceList.append(videoSourceYuneecMantisG);
33
34 #ifdef QGC_HERELINK_AIRUNIT_VIDEO
35 videoSourceList.append(videoSourceHerelinkAirUnit);
36 #else
37 videoSourceList.append(videoSourceHerelinkHotspot);
38 #endif
39#endif
40#ifndef QGC_DISABLE_UVC
41 QStringList uvcDevices = UVCReceiver::getDeviceNameList();
42 for (const QString& device : uvcDevices) {
43 videoSourceList.append(device);
44 }
45#endif
46 if (videoSourceList.count() == 0) {
47 _noVideo = true;
48 videoSourceList.append(videoSourceNoVideo);
49 setUserVisible(false);
50 } else {
51 videoSourceList.insert(0, videoDisabled);
52 }
53
54 // make translated strings
55 QStringList videoSourceCookedList;
56 for (const QVariant& videoSource: videoSourceList) {
57 videoSourceCookedList.append( VideoSettings::tr(videoSource.toString().toStdString().c_str()) );
58 }
59
60 _nameToMetaDataMap[videoSourceName]->setEnumInfo(videoSourceCookedList, videoSourceList);
61
62 _setForceVideoDecodeList();
63
64 // Migrate legacy gpuZeroCopyEnabled (pre-rename) into the new force-CPU semantics.
65 {
66 QSettings settings;
67 settings.beginGroup(settingsGroup);
68 const bool hasLegacy = settings.contains(QStringLiteral("gpuZeroCopyEnabled"));
69 const bool hasNew = settings.contains(forceCpuVideoPathName);
70 if (hasLegacy) {
71 if (!hasNew) {
72 const bool gpuZeroCopy = settings.value(QStringLiteral("gpuZeroCopyEnabled")).toBool();
73 forceCpuVideoPath()->setRawValue(!gpuZeroCopy);
74 }
75 settings.remove(QStringLiteral("gpuZeroCopyEnabled"));
76 }
77 settings.endGroup();
78 }
79
80 // Set default value for videoSource
81 _setDefaults();
82}
83
84void VideoSettings::_setDefaults()
85{
86 if (_noVideo) {
87 _nameToMetaDataMap[videoSourceName]->setRawDefaultValue(videoSourceNoVideo);
88 } else {
89 _nameToMetaDataMap[videoSourceName]->setRawDefaultValue(videoDisabled);
90 }
91}
92
97DECLARE_SETTINGSFACT(VideoSettings, recordingFormat)
99DECLARE_SETTINGSFACT(VideoSettings, enableStorageLimit)
101DECLARE_SETTINGSFACT(VideoSettings, disableWhenDisarmed)
102
104{
105 if (!_videoSourceFact) {
106 _videoSourceFact = _createSettingsFact(videoSourceName);
107 //-- Check for sources no longer available
108 if(!_videoSourceFact->enumValues().contains(_videoSourceFact->rawValue().toString())) {
109 if (_noVideo) {
110 _videoSourceFact->setRawValue(videoSourceNoVideo);
111 } else {
112 _videoSourceFact->setRawValue(videoDisabled);
113 }
114 }
115 connect(_videoSourceFact, &Fact::valueChanged, this, &VideoSettings::_configChanged);
116 }
117 return _videoSourceFact;
118}
119
121{
122 if (!_forceVideoDecoderFact) {
123 _forceVideoDecoderFact = _createSettingsFact(forceVideoDecoderName);
124
125 _forceVideoDecoderFact->setUserVisible(kGstEnabled);
126
127 connect(_forceVideoDecoderFact, &Fact::valueChanged, this, &VideoSettings::_configChanged);
128 }
129 return _forceVideoDecoderFact;
130}
131
133{
134 if (!_lowLatencyModeFact) {
135 _lowLatencyModeFact = _createSettingsFact(lowLatencyModeName);
136
137 _lowLatencyModeFact->setUserVisible(kGstEnabled);
138
139 connect(_lowLatencyModeFact, &Fact::valueChanged, this, &VideoSettings::_configChanged);
140 }
141 return _lowLatencyModeFact;
142}
143
145{
146 if (!_forceCpuVideoPathFact) {
147 _forceCpuVideoPathFact = _createSettingsFact(forceCpuVideoPathName);
148
149#if defined(QGC_HAS_ANY_GPU_PATH)
150 _forceCpuVideoPathFact->setUserVisible(kGstEnabled);
151#else
152 _forceCpuVideoPathFact->setUserVisible(false);
153#endif
154 }
155 return _forceCpuVideoPathFact;
156}
157
158// videoConversionElement / disablePixelAspectRatio are read by GStreamer::createVideoSink()
159// at bin construction and passed as construct-only properties — no env-var indirection.
161{
162 if (!_videoConversionElementFact) {
163 _videoConversionElementFact = _createSettingsFact(videoConversionElementName);
164 _videoConversionElementFact->setUserVisible(kGstEnabled);
165 }
166 return _videoConversionElementFact;
167}
168
170{
171 if (!_disablePixelAspectRatioFact) {
172 _disablePixelAspectRatioFact = _createSettingsFact(disablePixelAspectRatioName);
173 _disablePixelAspectRatioFact->setUserVisible(kGstEnabled);
174 }
175 return _disablePixelAspectRatioFact;
176}
177
179{
180 if (!_frameSmoothingEnabledFact) {
181 _frameSmoothingEnabledFact = _createSettingsFact(frameSmoothingEnabledName);
182 _frameSmoothingEnabledFact->setUserVisible(kGstEnabled);
183 }
184 return _frameSmoothingEnabledFact;
185}
186
188{
189 if (!_rtspTimeoutFact) {
190 _rtspTimeoutFact = _createSettingsFact(rtspTimeoutName);
191
192 _rtspTimeoutFact->setUserVisible(kGstEnabled);
193
194 connect(_rtspTimeoutFact, &Fact::valueChanged, this, &VideoSettings::_configChanged);
195 }
196 return _rtspTimeoutFact;
197}
198
200{
201 if (!_udpUrlFact) {
202 _udpUrlFact = _createSettingsFact(udpUrlName);
203 connect(_udpUrlFact, &Fact::valueChanged, this, &VideoSettings::_configChanged);
204 }
205 return _udpUrlFact;
206}
207
209{
210 if (!_rtspUrlFact) {
211 _rtspUrlFact = _createSettingsFact(rtspUrlName);
212 connect(_rtspUrlFact, &Fact::valueChanged, this, &VideoSettings::_configChanged);
213 }
214 return _rtspUrlFact;
215}
216
218{
219 if (!_tcpUrlFact) {
220 _tcpUrlFact = _createSettingsFact(tcpUrlName);
221 connect(_tcpUrlFact, &Fact::valueChanged, this, &VideoSettings::_configChanged);
222 }
223 return _tcpUrlFact;
224}
225
227{
228 //-- First, check if it's autoconfigured
229 if(VideoManager::instance()->autoStreamConfigured()) {
230 qCDebug(VideoSettingsLog) << "Stream auto configured";
231 return true;
232 }
233 //-- Check if it's disabled
234 QString vSource = videoSource()->rawValue().toString();
235 if(vSource == videoSourceNoVideo || vSource == videoDisabled) {
236 return false;
237 }
238 //-- If UDP, check for URL
239 if(vSource == videoSourceUDPH264 || vSource == videoSourceUDPH265) {
240 qCDebug(VideoSettingsLog) << "Testing configuration for UDP Stream:" << udpUrl()->rawValue().toString();
241 return !udpUrl()->rawValue().toString().isEmpty();
242 }
243 //-- If RTSP, check for URL
244 if(vSource == videoSourceRTSP) {
245 qCDebug(VideoSettingsLog) << "Testing configuration for RTSP Stream:" << rtspUrl()->rawValue().toString();
246 return !rtspUrl()->rawValue().toString().isEmpty();
247 }
248 //-- If TCP, check for URL
249 if(vSource == videoSourceTCP) {
250 qCDebug(VideoSettingsLog) << "Testing configuration for TCP Stream:" << tcpUrl()->rawValue().toString();
251 return !tcpUrl()->rawValue().toString().isEmpty();
252 }
253 //-- If MPEG-TS, check for URL
254 if(vSource == videoSourceMPEGTS) {
255 qCDebug(VideoSettingsLog) << "Testing configuration for MPEG-TS Stream:" << udpUrl()->rawValue().toString();
256 return !udpUrl()->rawValue().toString().isEmpty();
257 }
258 //-- If Herelink Air unit, good to go
259 if(vSource == videoSourceHerelinkAirUnit) {
260 qCDebug(VideoSettingsLog) << "Stream configured for Herelink Air Unit";
261 return true;
262 }
263 //-- If Herelink Hotspot, good to go
264 if(vSource == videoSourceHerelinkHotspot) {
265 qCDebug(VideoSettingsLog) << "Stream configured for Herelink Hotspot";
266 return true;
267 }
268#ifndef QGC_DISABLE_UVC
270 qCDebug(VideoSettingsLog) << "Stream configured for UVC";
271 return true;
272 }
273#endif
274 return false;
275}
276
277void VideoSettings::_configChanged(QVariant)
278{
280}
281
282void VideoSettings::_setForceVideoDecodeList()
283{
284#ifdef QGC_GST_STREAMING
285 static const QList<GStreamer::VideoDecoderOptions> removeForceVideoDecodeList{
286#if defined(Q_OS_ANDROID)
292#elif defined(Q_OS_LINUX)
295#elif defined(Q_OS_WIN)
298#elif defined(Q_OS_MACOS)
301#elif defined(Q_OS_IOS)
306#endif
307 };
308
309 for (const auto &value : removeForceVideoDecodeList) {
310 _nameToMetaDataMap[forceVideoDecoderName]->removeEnumInfo(value);
311 }
312#endif
313}
#define QGC_LOGGING_CATEGORY(name, categoryStr)
#define DECLARE_SETTINGSFACT_NO_FUNC(CLASS, NAME)
#define DECLARE_SETTINGSFACT(CLASS, NAME)
#define DECLARE_SETTINGGROUP(NAME, GROUP)
static constexpr bool kGstEnabled
void valueChanged(const QVariant &value)
This signal is only meant for use by the QT property system. It should not be connected to by client ...
QMap< QString, FactMetaData * > _nameToMetaDataMap
static bool enabled()
static bool deviceExists(const QString &device)
static QStringList getDeviceNameList()
static VideoManager * instance()
static constexpr const char * videoSourceTCP
static constexpr const char * videoSourceUDPH264
static constexpr const char * videoSourceHerelinkHotspot
bool streamConfigured()
static constexpr const char * videoSourceRTSP
static constexpr const char * videoDisabled
static constexpr const char * videoSourceUDPH265
void streamConfiguredChanged(bool configured)
static constexpr const char * videoSourceNoVideo
static constexpr const char * videoSourceMPEGTS
static constexpr const char * videoSourceHerelinkAirUnit
@ ForceVideoDecoderIntel
Definition GStreamer.h:17
@ ForceVideoDecoderVulkan
Definition GStreamer.h:18
@ ForceVideoDecoderNVIDIA
Definition GStreamer.h:13
@ ForceVideoDecoderVAAPI
Definition GStreamer.h:14
@ ForceVideoDecoderVideoToolbox
Definition GStreamer.h:16
@ ForceVideoDecoderDirectX3D
Definition GStreamer.h:15