Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Q
qgroundcontrol
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Valentin Platzgummer
qgroundcontrol
Commits
f1559638
Commit
f1559638
authored
Aug 30, 2016
by
dogmaphobic
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Work on RTSP Video Stream, x86 Android, etc.
parent
5fc24cfa
Changes
16
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
734 additions
and
524 deletions
+734
-524
QGCCommon.pri
QGCCommon.pri
+12
-6
qgroundcontrol.pro
qgroundcontrol.pro
+9
-0
qgroundcontrol.qrc
qgroundcontrol.qrc
+2
-0
FlightDisplayView.qml
src/FlightDisplay/FlightDisplayView.qml
+4
-21
FlightDisplayViewDummy.qml
src/FlightDisplay/FlightDisplayViewDummy.qml
+15
-0
FlightDisplayViewUVC.qml
src/FlightDisplay/FlightDisplayViewUVC.qml
+35
-0
FlightDisplayViewVideo.qml
src/FlightDisplay/FlightDisplayViewVideo.qml
+0
-1
VideoManager.cc
src/FlightDisplay/VideoManager.cc
+98
-39
VideoManager.h
src/FlightDisplay/VideoManager.h
+21
-1
QGCVideoBackground.qml
src/FlightMap/QGCVideoBackground.qml
+0
-15
VideoReceiver.cc
src/VideoStreaming/VideoReceiver.cc
+45
-8
VideoStreaming.pri
src/VideoStreaming/VideoStreaming.pri
+6
-2
VideoSurface.cc
src/VideoStreaming/VideoSurface.cc
+4
-2
VideoSurface.h
src/VideoStreaming/VideoSurface.h
+3
-2
gstqtvideosinkplugin.cpp
src/VideoStreaming/gstqtvideosink/gstqtvideosinkplugin.cpp
+2
-2
GeneralSettings.qml
src/ui/preferences/GeneralSettings.qml
+478
-425
No files found.
QGCCommon.pri
View file @
f1559638
...
...
@@ -30,12 +30,18 @@ linux {
CONFIG += LinuxBuild
DEFINES += __STDC_LIMIT_MACROS __rasp_pi2__
} else : android-g++ {
message("Android build")
CONFIG += AndroidBuild MobileBuild
DEFINES += __android__
DEFINES += __STDC_LIMIT_MACROS
DEFINES += QGC_ENABLE_BLUETOOTH
target.path = $$DESTDIR
equals(ANDROID_TARGET_ARCH, x86) {
CONFIG += Androidx86Build
DEFINES += __androidx86__
message("Android x86 build")
} else {
message("Android Arm build")
}
} else {
error("Unsuported Linux toolchain, only GCC 32- or 64-bit is supported")
}
...
...
@@ -54,11 +60,11 @@ linux {
DEFINES += __macos__
CONFIG += x86_64
CONFIG -= x86
equals(QT_MAJOR_VERSION, 5) | greaterThan(QT_MINOR_VERSION, 5) {
QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.7
} else {
QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.6
}
equals(QT_MAJOR_VERSION, 5) | greaterThan(QT_MINOR_VERSION, 5) {
QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.7
} else {
QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.6
}
QMAKE_MAC_SDK = macosx10.11
QMAKE_CXXFLAGS += -fvisibility=hidden
} else {
...
...
qgroundcontrol.pro
View file @
f1559638
...
...
@@ -46,6 +46,15 @@ contains (DEFINES, QGC_DISABLE_BLUETOOTH) {
DEFINES
+=
QGC_ENABLE_BLUETOOTH
}
#
USB
Camera
and
UVC
Video
Sources
contains
(
DEFINES
,
QGC_DISABLE_UVC
)
{
message
(
"Skipping support for UVC devices (manual override from command line)"
)
DEFINES
-=
QGC_DISABLE_UVC
}
else
:
exists
(
user_config
.
pri
)
:
infile
(
user_config
.
pri
,
DEFINES
,
QGC_DISABLE_UVC
)
{
message
(
"Skipping support for UVC devices (manual override from user_config.pri)"
)
DEFINES
-=
QGC_DISABLE_UVC
}
LinuxBuild
{
CONFIG
+=
link_pkgconfig
}
...
...
qgroundcontrol.qrc
View file @
f1559638
...
...
@@ -15,6 +15,8 @@
<file alias="LogDownload.qml">src/ViewWidgets/LogDownload.qml</file>
<file alias="FirmwareUpgrade.qml">src/VehicleSetup/FirmwareUpgrade.qml</file>
<file alias="FlightDisplayView.qml">src/FlightDisplay/FlightDisplayView.qml</file>
<file alias="FlightDisplayViewUVC.qml">src/FlightDisplay/FlightDisplayViewUVC.qml</file>
<file alias="FlightDisplayViewDummy.qml">src/FlightDisplay/FlightDisplayViewDummy.qml</file>
<file alias="PX4FlightModes.qml">src/AutoPilotPlugins/PX4/PX4FlightModes.qml</file>
<file alias="PX4AdvancedFlightModes.qml">src/AutoPilotPlugins/PX4/PX4AdvancedFlightModes.qml</file>
<file alias="PX4SimpleFlightModes.qml">src/AutoPilotPlugins/PX4/PX4SimpleFlightModes.qml</file>
...
...
src/FlightDisplay/FlightDisplayView.qml
View file @
f1559638
...
...
@@ -184,34 +184,17 @@ QGCView {
}
}
]
//--
UDP
Video Streaming
//-- Video Streaming
FlightDisplayViewVideo
{
anchors.fill
:
parent
visible
:
QGroundControl
.
videoManager
.
isGStreamer
}
//-- UVC Video (USB Camera or Video Device)
Rectangle
{
id
:
noVideo
Loader
{
id
:
cameraLoader
anchors.fill
:
parent
color
:
Qt
.
rgba
(
0
,
0
,
0
,
0.75
)
visible
:
!
QGroundControl
.
videoManager
.
isGStreamer
Camera
{
id
:
camera
deviceId
:
QGroundControl
.
videoManager
.
videoSourceID
captureMode
:
Camera
.
CaptureViewfinder
}
VideoOutput
{
id
:
viewFinder
source
:
camera
anchors.fill
:
parent
visible
:
!
QGroundControl
.
videoManager
.
isGStreamer
}
onVisibleChanged
:
{
if
(
visible
)
camera
.
start
()
else
camera
.
stop
()
}
source
:
QGroundControl
.
videoManager
.
uvcEnabled
?
"
qrc:/qml/FlightDisplayViewUVC.qml
"
:
"
qrc:/qml/FlightDisplayViewDummy.qml
"
}
}
...
...
src/FlightDisplay/FlightDisplayViewDummy.qml
0 → 100644
View file @
f1559638
/****************************************************************************
*
* (c) 2009-2016 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* QGroundControl is licensed according to the terms in the file
* COPYING.md in the root of the source code directory.
*
****************************************************************************/
import
QtQuick
2.5
Rectangle
{
anchors.fill
:
parent
color
:
Qt
.
rgba
(
0
,
0
,
0
,
0.75
)
}
src/FlightDisplay/FlightDisplayViewUVC.qml
0 → 100644
View file @
f1559638
/****************************************************************************
*
* (c) 2009-2016 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* QGroundControl is licensed according to the terms in the file
* COPYING.md in the root of the source code directory.
*
****************************************************************************/
import
QtQuick
2.5
import
QtMultimedia
5.5
import
QGroundControl
1.0
Rectangle
{
anchors.fill
:
parent
color
:
Qt
.
rgba
(
0
,
0
,
0
,
0.75
)
Camera
{
id
:
camera
deviceId
:
QGroundControl
.
videoManager
.
videoSourceID
captureMode
:
Camera
.
CaptureViewfinder
}
VideoOutput
{
source
:
camera
anchors.fill
:
parent
fillMode
:
VideoOutput
.
PreserveAspectCrop
visible
:
!
QGroundControl
.
videoManager
.
isGStreamer
}
onVisibleChanged
:
{
if
(
visible
)
camera
.
start
()
else
camera
.
stop
()
}
}
src/FlightDisplay/FlightDisplayViewVideo.qml
View file @
f1559638
...
...
@@ -41,7 +41,6 @@ Item {
display
:
QGroundControl
.
videoManager
.
videoSurface
receiver
:
QGroundControl
.
videoManager
.
videoReceiver
visible
:
QGroundControl
.
videoManager
.
videoRunning
runVideo
:
true
/* TODO: Come up with a way to make this an option
QGCAttitudeHUD {
id: attitudeHUD
...
...
src/FlightDisplay/VideoManager.cc
View file @
f1559638
...
...
@@ -19,51 +19,33 @@
#include "VideoManager.h"
static
const
char
*
kVideoSourceKey
=
"VideoSource"
;
static
const
char
*
kGStreamerSource
=
"UDP Video Stream"
;
static
const
char
*
kVideoUDPPortKey
=
"VideoUDPPort"
;
static
const
char
*
kVideoRTSPUrlKey
=
"VideoRTSPUrl"
;
static
const
char
*
kUDPStream
=
"UDP Video Stream"
;
static
const
char
*
kRTSPStream
=
"RTSP Video Stream"
;
QGC_LOGGING_CATEGORY
(
VideoManagerLog
,
"VideoManagerLog"
)
//-----------------------------------------------------------------------------
VideoManager
::
VideoManager
(
QGCApplication
*
app
)
:
QGCTool
(
app
)
,
_videoSurface
(
NULL
)
,
_videoReceiver
(
NULL
)
,
_videoRunning
(
false
)
,
_udpPort
(
5600
)
//-- Defalut Port 5600 == Solo UDP Port
,
_init
(
false
)
{
/*
* This is the receiving end of an UDP RTP stream. The sender can be setup with this command:
*
* gst-launch-1.0 uvch264src initial-bitrate=1000000 average-bitrate=1000000 iframe-period=1000 name=src auto-start=true src.vidsrc ! \
* video/x-h264,width=1280,height=720,framerate=24/1 ! h264parse ! rtph264pay ! udpsink host=192.168.1.9 port=5600
*
* Where the main parameters are:
*
* uvch264src: Your h264 video source (the example above uses a Logitech C920 on an Raspberry PI 2+ or Odroid C1
* host=192.168.1.9 This is the IP address of QGC. You can use Avahi/Zeroconf to find QGC using the "_qgroundcontrol._udp" service.
*
* Advanced settings (you should probably read the gstreamer documentation before changing these):
*
* initial-bitrate=1000000 average-bitrate=1000000
* The bit rate to use. The greater, the better quality at the cost of higher bandwidth.
*
* width=1280,height=720,framerate=24/1
* The video resolution and frame rate. This depends on the camera used.
*
* iframe-period=1000
* Interval between iFrames. The greater the interval the lesser bandwidth at the cost of a longer time to recover from lost packets.
*
* Do not change anything else unless you know what you are doing. Any other change will require a matching change on the receiving end.
*
*/
_videoSurface
=
new
VideoSurface
;
_videoReceiver
=
new
VideoReceiver
(
this
);
_videoReceiver
->
setUri
(
QLatin1Literal
(
"udp://0.0.0.0:5600"
));
// Port 5600=Solo UDP port, if you change it, you will break Solo video support
//-- Get saved settings
QSettings
settings
;
setVideoSource
(
settings
.
value
(
kVideoSourceKey
,
kUDPStream
).
toString
());
setUdpPort
(
settings
.
value
(
kVideoUDPPortKey
,
5600
).
toUInt
());
setRtspURL
(
settings
.
value
(
kVideoRTSPUrlKey
,
"rtsp://192.168.42.1:554/live"
).
toString
());
//-- Example RTSP URL
_init
=
true
;
#if defined(QGC_GST_STREAMING)
_
videoReceiver
->
setVideoSink
(
_videoSurface
->
videoSink
()
);
_
updateVideo
(
);
connect
(
&
_frameTimer
,
&
QTimer
::
timeout
,
this
,
&
VideoManager
::
_updateTimer
);
_frameTimer
.
start
(
1000
);
#endif
//-- Get saved video source
QSettings
settings
;
setVideoSource
(
settings
.
value
(
kVideoSourceKey
,
kGStreamerSource
).
toString
());
}
//-----------------------------------------------------------------------------
...
...
@@ -96,12 +78,21 @@ bool
VideoManager
::
isGStreamer
()
{
#if defined(QGC_GST_STREAMING)
return
_videoSource
==
k
GStreamerSource
;
return
_videoSource
==
k
UDPStream
||
_videoSource
==
kRTSPStream
;
#else
return
false
;
#endif
}
//-----------------------------------------------------------------------------
#ifndef QGC_DISABLE_UVC
bool
VideoManager
::
uvcEnabled
()
{
return
QCameraInfo
::
availableCameras
().
count
()
>
0
;
}
#endif
//-----------------------------------------------------------------------------
void
VideoManager
::
setVideoSource
(
QString
vSource
)
...
...
@@ -110,6 +101,7 @@ VideoManager::setVideoSource(QString vSource)
QSettings
settings
;
settings
.
setValue
(
kVideoSourceKey
,
vSource
);
emit
videoSourceChanged
();
#ifndef QGC_DISABLE_UVC
QList
<
QCameraInfo
>
cameras
=
QCameraInfo
::
availableCameras
();
foreach
(
const
QCameraInfo
&
cameraInfo
,
cameras
)
{
if
(
cameraInfo
.
description
()
==
vSource
)
{
...
...
@@ -119,8 +111,51 @@ VideoManager::setVideoSource(QString vSource)
break
;
}
}
#endif
emit
isGStreamerChanged
();
qCDebug
(
VideoManagerLog
)
<<
"New Video Source:"
<<
vSource
;
/*
* Not working. Requires restart for now
if(isGStreamer())
_updateVideo();
*/
if
(
_videoReceiver
)
{
if
(
isGStreamer
())
{
_videoReceiver
->
start
();
}
else
{
_videoReceiver
->
stop
();
}
}
}
//-----------------------------------------------------------------------------
void
VideoManager
::
setUdpPort
(
quint16
port
)
{
_udpPort
=
port
;
QSettings
settings
;
settings
.
setValue
(
kVideoUDPPortKey
,
port
);
emit
udpPortChanged
();
/*
* Not working. Requires restart for now
if(_videoSource == kUDPStream)
_updateVideo();
*/
}
//-----------------------------------------------------------------------------
void
VideoManager
::
setRtspURL
(
QString
url
)
{
_rtspURL
=
url
;
QSettings
settings
;
settings
.
setValue
(
kVideoRTSPUrlKey
,
url
);
emit
rtspURLChanged
();
/*
* Not working. Requires restart for now
if(_videoSource == kRTSPStream)
_updateVideo();
*/
}
//-----------------------------------------------------------------------------
...
...
@@ -129,20 +164,23 @@ VideoManager::videoSourceList()
{
_videoSourceList
.
clear
();
#if defined(QGC_GST_STREAMING)
_videoSourceList
.
append
(
kGStreamerSource
);
_videoSourceList
.
append
(
kUDPStream
);
_videoSourceList
.
append
(
kRTSPStream
);
#endif
#ifndef QGC_DISABLE_UVC
QList
<
QCameraInfo
>
cameras
=
QCameraInfo
::
availableCameras
();
foreach
(
const
QCameraInfo
&
cameraInfo
,
cameras
)
{
qCDebug
(
VideoManagerLog
)
<<
"UVC Video source ID:"
<<
cameraInfo
.
deviceName
()
<<
" Name:"
<<
cameraInfo
.
description
();
_videoSourceList
.
append
(
cameraInfo
.
description
());
}
#endif
return
_videoSourceList
;
}
//-----------------------------------------------------------------------------
#if defined(QGC_GST_STREAMING)
void
VideoManager
::
_updateTimer
(
void
)
void
VideoManager
::
_updateTimer
()
{
#if defined(QGC_GST_STREAMING)
if
(
_videoRunning
)
{
time_t
elapsed
=
0
;
...
...
@@ -150,7 +188,7 @@ void VideoManager::_updateTimer(void)
{
elapsed
=
time
(
0
)
-
_videoSurface
->
lastFrame
();
}
if
(
elapsed
>
2
)
if
(
elapsed
>
2
&&
_videoSurface
)
{
_videoRunning
=
false
;
_videoSurface
->
setLastFrame
(
0
);
...
...
@@ -167,5 +205,26 @@ void VideoManager::_updateTimer(void)
}
}
}
}
#endif
}
//-----------------------------------------------------------------------------
void
VideoManager
::
_updateVideo
()
{
if
(
_init
)
{
if
(
_videoReceiver
)
delete
_videoReceiver
;
if
(
_videoSurface
)
delete
_videoSurface
;
_videoSurface
=
new
VideoSurface
;
_videoReceiver
=
new
VideoReceiver
(
this
);
_videoReceiver
->
setVideoSink
(
_videoSurface
->
videoSink
());
#if defined(QGC_GST_STREAMING)
if
(
_videoSource
==
kUDPStream
)
_videoReceiver
->
setUri
(
QStringLiteral
(
"udp://0.0.0.0:%1"
).
arg
(
_udpPort
));
else
_videoReceiver
->
setUri
(
_rtspURL
);
#endif
_videoReceiver
->
start
();
}
}
src/FlightDisplay/VideoManager.h
View file @
f1559638
...
...
@@ -35,6 +35,9 @@ public:
Q_PROPERTY
(
QString
videoSource
READ
videoSource
WRITE
setVideoSource
NOTIFY
videoSourceChanged
)
Q_PROPERTY
(
QStringList
videoSourceList
READ
videoSourceList
NOTIFY
videoSourceListChanged
)
Q_PROPERTY
(
bool
videoRunning
READ
videoRunning
NOTIFY
videoRunningChanged
)
Q_PROPERTY
(
quint16
udpPort
READ
udpPort
WRITE
setUdpPort
NOTIFY
udpPortChanged
)
Q_PROPERTY
(
QString
rtspURL
READ
rtspURL
WRITE
setRtspURL
NOTIFY
rtspURLChanged
)
Q_PROPERTY
(
bool
uvcEnabled
READ
uvcEnabled
CONSTANT
)
Q_PROPERTY
(
VideoSurface
*
videoSurface
MEMBER
_videoSurface
CONSTANT
)
Q_PROPERTY
(
VideoReceiver
*
videoReceiver
MEMBER
_videoReceiver
CONSTANT
)
...
...
@@ -44,7 +47,18 @@ public:
QString
videoSourceID
()
{
return
_videoSourceID
;
}
QString
videoSource
()
{
return
_videoSource
;
}
QStringList
videoSourceList
();
quint16
udpPort
()
{
return
_udpPort
;
}
QString
rtspURL
()
{
return
_rtspURL
;
}
#if defined(QGC_DISABLE_UVC)
bool
uvcEnabled
()
{
return
false
;
}
#else
bool
uvcEnabled
();
#endif
void
setVideoSource
(
QString
vSource
);
void
setUdpPort
(
quint16
port
);
void
setRtspURL
(
QString
url
);
// Override from QGCTool
void
setToolbox
(
QGCToolbox
*
toolbox
);
...
...
@@ -56,9 +70,12 @@ signals:
void
videoSourceListChanged
();
void
isGStreamerChanged
();
void
videoSourceIDChanged
();
void
udpPortChanged
();
void
rtspURLChanged
();
private:
void
_updateTimer
(
void
);
void
_updateTimer
();
void
_updateVideo
();
private:
VideoSurface
*
_videoSurface
;
...
...
@@ -70,6 +87,9 @@ private:
QString
_videoSource
;
QString
_videoSourceID
;
QStringList
_videoSourceList
;
quint16
_udpPort
;
QString
_rtspURL
;
bool
_init
;
};
#endif
src/FlightMap/QGCVideoBackground.qml
View file @
f1559638
...
...
@@ -22,20 +22,5 @@ VideoItem {
id
:
videoBackground
property
var
display
property
var
receiver
property
var
runVideo
:
false
surface
:
display
onRunVideoChanged
:
{
if
(
videoBackground
.
receiver
&&
videoBackground
.
display
)
{
if
(
videoBackground
.
runVideo
)
{
videoBackground
.
receiver
.
start
();
}
else
{
videoBackground
.
receiver
.
stop
();
}
}
}
Component.onCompleted
:
{
if
(
videoBackground
.
runVideo
&&
videoBackground
.
receiver
)
{
videoBackground
.
receiver
.
start
();
}
}
}
src/VideoStreaming/VideoReceiver.cc
View file @
f1559638
...
...
@@ -49,6 +49,21 @@ void VideoReceiver::setVideoSink(GstElement* sink)
}
#endif
static
void
newPadCB
(
GstElement
*
element
,
GstPad
*
pad
,
gpointer
data
)
{
gchar
*
name
;
name
=
gst_pad_get_name
(
pad
);
g_print
(
"A new pad %s was created
\n
"
,
name
);
GstCaps
*
p_caps
=
gst_pad_get_pad_template_caps
(
pad
);
gchar
*
description
=
gst_caps_to_string
(
p_caps
);
qDebug
()
<<
p_caps
<<
", "
<<
description
;
g_free
(
description
);
GstElement
*
p_rtph264depay
=
GST_ELEMENT
(
data
);
if
(
gst_element_link_pads
(
element
,
name
,
p_rtph264depay
,
"sink"
)
==
false
)
qCritical
()
<<
"newPadCB : failed to link elements
\n
"
;
g_free
(
name
);
}
void
VideoReceiver
::
start
()
{
#if defined(QGC_GST_STREAMING)
...
...
@@ -56,7 +71,6 @@ void VideoReceiver::start()
qCritical
()
<<
"VideoReceiver::start() failed because URI is not specified"
;
return
;
}
if
(
_videoSink
==
NULL
)
{
qCritical
()
<<
"VideoReceiver::start() failed because video sink is not set"
;
return
;
...
...
@@ -72,29 +86,44 @@ void VideoReceiver::start()
GstElement
*
parser
=
NULL
;
GstElement
*
decoder
=
NULL
;
bool
isUdp
=
_uri
.
contains
(
"udp://"
);
do
{
if
((
_pipeline
=
gst_pipeline_new
(
"receiver"
))
==
NULL
)
{
qCritical
()
<<
"VideoReceiver::start() failed. Error with gst_pipeline_new()"
;
break
;
}
if
((
dataSource
=
gst_element_factory_make
(
"udpsrc"
,
"udp-source"
))
==
NULL
)
{
qCritical
()
<<
"VideoReceiver::start() failed. Error with gst_element_factory_make('udpsrc')"
;
break
;
if
(
isUdp
)
{
dataSource
=
gst_element_factory_make
(
"udpsrc"
,
"udp-source"
);
}
else
{
dataSource
=
gst_element_factory_make
(
"rtspsrc"
,
"rtsp-source"
);
}
if
(
(
caps
=
gst_caps_from_string
(
"application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)H264"
))
==
NULL
)
{
qCritical
()
<<
"VideoReceiver::start() failed. Error with
gst_caps_from_string
()"
;
if
(
!
dataSource
)
{
qCritical
()
<<
"VideoReceiver::start() failed. Error with
data source for gst_element_factory_make
()"
;
break
;
}
g_object_set
(
G_OBJECT
(
dataSource
),
"uri"
,
qPrintable
(
_uri
),
"caps"
,
caps
,
NULL
);
if
(
isUdp
)
{
if
((
caps
=
gst_caps_from_string
(
"application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)H264"
))
==
NULL
)
{
qCritical
()
<<
"VideoReceiver::start() failed. Error with gst_caps_from_string()"
;
break
;
}
g_object_set
(
G_OBJECT
(
dataSource
),
"uri"
,
qPrintable
(
_uri
),
"caps"
,
caps
,
NULL
);
}
else
{
g_object_set
(
G_OBJECT
(
dataSource
),
"location"
,
qPrintable
(
_uri
),
"latency"
,
0
,
NULL
);
}
if
((
demux
=
gst_element_factory_make
(
"rtph264depay"
,
"rtp-h264-depacketizer"
))
==
NULL
)
{
qCritical
()
<<
"VideoReceiver::start() failed. Error with gst_element_factory_make('rtph264depay')"
;
break
;
}
if
(
!
isUdp
)
{
g_signal_connect
(
dataSource
,
"pad-added"
,
G_CALLBACK
(
newPadCB
),
demux
);
}
if
((
parser
=
gst_element_factory_make
(
"h264parse"
,
"h264-parser"
))
==
NULL
)
{
qCritical
()
<<
"VideoReceiver::start() failed. Error with gst_element_factory_make('h264parse')"
;
break
;
...
...
@@ -107,7 +136,15 @@ void VideoReceiver::start()
gst_bin_add_many
(
GST_BIN
(
_pipeline
),
dataSource
,
demux
,
parser
,
decoder
,
_videoSink
,
NULL
);
if
(
gst_element_link_many
(
dataSource
,
demux
,
parser
,
decoder
,
_videoSink
,
NULL
)
!=
(
gboolean
)
TRUE
)
{
gboolean
res
=
FALSE
;
if
(
isUdp
)
{
res
=
gst_element_link_many
(
dataSource
,
demux
,
parser
,
decoder
,
_videoSink
,
NULL
);
}
else
{
res
=
gst_element_link_many
(
demux
,
parser
,
decoder
,
_videoSink
,
NULL
);
}
if
(
!
res
)
{
qCritical
()
<<
"VideoReceiver::start() failed. Error with gst_element_link_many()"
;
break
;
}
...
...
src/VideoStreaming/VideoStreaming.pri
View file @
f1559638
...
...
@@ -73,8 +73,12 @@ LinuxBuild {
QMAKE_POST_LINK += $$escape_expand(\\n) xcopy \"$$GST_ROOT_WIN\\lib\\gstreamer-1.0\\validate\\*.dll\" \"$$DESTDIR_WIN\\gstreamer-plugins\\validate\\\" /Y $$escape_expand(\\n)
}
} else:AndroidBuild {
#- gstreamer assumed to be installed in $$PWD/../../android/gstreamer-1.0-android-armv7-1.5.2
GST_ROOT = $$PWD/../../gstreamer-1.0-android-armv7-1.5.2
#- gstreamer assumed to be installed in $$PWD/../../android/gstreamer-1.0-android-armv7-1.5.2 (or x86)
Androidx86Build {
GST_ROOT = $$PWD/../../gstreamer-1.0-android-x86-1.5.2
} else {
GST_ROOT = $$PWD/../../gstreamer-1.0-android-armv7-1.5.2
}
exists($$GST_ROOT) {
QMAKE_CXXFLAGS += -pthread
CONFIG += VideoEnabled
...
...
src/VideoStreaming/VideoSurface.cc
View file @
f1559638
...
...
@@ -27,6 +27,7 @@ VideoSurface::VideoSurface(QObject *parent)
#if defined(QGC_GST_STREAMING)
,
_data
(
new
VideoSurfacePrivate
)
,
_lastFrame
(
0
)
,
_refed
(
false
)
#endif
{
}
...
...
@@ -34,7 +35,7 @@ VideoSurface::VideoSurface(QObject *parent)
VideoSurface
::~
VideoSurface
()
{
#if defined(QGC_GST_STREAMING)
if
(
_data
->
videoSink
!=
NULL
)
{
if
(
!
_refed
&&
_data
->
videoSink
!=
NULL
)
{
gst_element_set_state
(
_data
->
videoSink
,
GST_STATE_NULL
);
}
delete
_data
;
...
...
@@ -42,7 +43,7 @@ VideoSurface::~VideoSurface()
}
#if defined(QGC_GST_STREAMING)
GstElement
*
VideoSurface
::
videoSink
()
const
GstElement
*
VideoSurface
::
videoSink
()
{
if
(
_data
->
videoSink
==
NULL
)
{
if
((
_data
->
videoSink
=
gst_element_factory_make
(
"qtquick2videosink"
,
NULL
))
==
NULL
)
{
...
...
@@ -50,6 +51,7 @@ GstElement* VideoSurface::videoSink() const
return
NULL
;
}
g_signal_connect
(
_data
->
videoSink
,
"update"
,
G_CALLBACK
(
onUpdateThunk
),
(
void
*
)
this
);
_refed
=
true
;
}
return
_data
->
videoSink
;
}
...
...
src/VideoStreaming/VideoSurface.h
View file @
f1559638
...
...
@@ -40,7 +40,7 @@ public:
* is called. The surface will always keep a reference to this element.
*/
#if defined(QGC_GST_STREAMING)
GstElement
*
videoSink
()
const
;
GstElement
*
videoSink
();
time_t
lastFrame
()
{
return
_lastFrame
;
}
void
setLastFrame
(
time_t
t
)
{
_lastFrame
=
t
;
}
#endif
...
...
@@ -55,7 +55,8 @@ private:
friend
class
VideoItem
;
#if defined(QGC_GST_STREAMING)
VideoSurfacePrivate
*
const
_data
;
time_t
_lastFrame
;
time_t
_lastFrame
;
bool
_refed
;
#endif
};
...
...
src/VideoStreaming/gstqtvideosink/gstqtvideosinkplugin.cpp
View file @
f1559638
...
...
@@ -27,7 +27,7 @@
#include "gstqwidgetvideosink.h"
#define PACKAGE "mini-qt-gstreamer"
#define PACKAGE_NAME "QgcQtGStreamer"
#define PACKAGE_NAME "QgcQtGStreamer"
#define PACKAGE_ORIGIN "http://gstreamer.freedesktop.org/"
#define PACKAGE_VERSION "1.2.0"
...
...
@@ -44,7 +44,7 @@ static gboolean plugin_init(GstPlugin *plugin)
G_STRINGIFY
(
QGC_VIDEOSINK_PLUGIN
),
0
,
"Debug category for GstQtVideoSink"
);
if
(
!
gst_element_register
(
plugin
,
G_STRINGIFY
(
QGC_VIDEOSINK_PLUGIN
),
if
(
!
gst_element_register
(
plugin
,
G_STRINGIFY
(
QGC_VIDEOSINK_PLUGIN
),
GST_RANK_NONE
,
GST_TYPE_QT_VIDEO_SINK
))
{
GST_ERROR
(
"Failed to register "
G_STRINGIFY
(
QGC_VIDEOSINK_PLUGIN
));
return
FALSE
;
...
...
src/ui/preferences/GeneralSettings.qml
View file @
f1559638
...
...
@@ -31,493 +31,546 @@ QGCView {
anchors.margins
:
ScreenTools
.
defaultFontPixelWidth
property
Fact
_percentRemainingAnnounce
:
QGroundControl
.
batteryPercentRemainingAnnounce
property
real
_editFieldWidth
:
ScreenTools
.
defaultFontPixelWidth
*
20
property
real
_labelWidth
:
ScreenTools
.
defaultFontPixelWidth
*
15
property
real
_editFieldWidth
:
ScreenTools
.
defaultFontPixelWidth
*
30
QGCPalette
{
id
:
qgcPal
}
QGCViewPanel
{
id
:
panel
anchors.fill
:
parent
QGCFlickable
{
clip
:
true
anchors.fill
:
parent
contentHeight
:
settingsColumn
.
height
contentWidth
:
settingsColumn
.
width
Column
{
id
:
settingsColumn
width
:
qgcView
.
width
spacing
:
ScreenTools
.
defaultFontPixelHeight
*
0.5
anchors.margins
:
ScreenTools
.
defaultFontPixelWidth
spacing
:
ScreenTools
.
defaultFontPixelHeight
/
2
//-----------------------------------------------------------------
//-- Base UI Font Point Size
Row
{
spacing
:
ScreenTools
.
defaultFontPixelWidth
//-- Units
Item
{
width
:
qgcView
.
width
*
0.8
height
:
unitLabel
.
height
anchors.margins
:
ScreenTools
.
defaultFontPixelWidth
anchors.horizontalCenter
:
parent
.
horizontalCenter
QGCLabel
{
id
:
baseFon
tLabel
text
:
qsTr
(
"
Base UI font size:
"
)
anchors.verticalCenter
:
parent
.
verticalCenter
id
:
uni
tLabel
text
:
qsTr
(
"
Units (Requires Restart)
"
)
font.family
:
ScreenTools
.
demiboldFontFamily
}
Row
{
id
:
baseFontRow
spacing
:
ScreenTools
.
defaultFontPixelWidth
/
2
anchors.verticalCenter
:
parent
.
verticalCenter
QGCButton
{
id
:
decrementButton
width
:
height
height
:
baseFontEdit
.
height
text
:
"
-
"
onClicked
:
{
if
(
ScreenTools
.
defaultFontPointSize
>
6
)
{
QGroundControl
.
baseFontPointSize
=
QGroundControl
.
baseFontPointSize
-
1
}
}
Rectangle
{
height
:
unitsCol
.
height
+
(
ScreenTools
.
defaultFontPixelHeight
*
2
)
width
:
qgcView
.
width
*
0.8
color
:
qgcPal
.
windowShade
anchors.margins
:
ScreenTools
.
defaultFontPixelWidth
anchors.horizontalCenter
:
parent
.
horizontalCenter
Column
{
id
:
unitsCol
spacing
:
ScreenTools
.
defaultFontPixelWidth
anchors.centerIn
:
parent
Row
{
spacing
:
ScreenTools
.
defaultFontPixelWidth
QGCLabel
{
width
:
_labelWidth
anchors.baseline
:
distanceUnitsCombo
.
baseline
text
:
qsTr
(
"
Distance:
"
)
}
FactComboBox
{
id
:
distanceUnitsCombo
width
:
_editFieldWidth
fact
:
QGroundControl
.
distanceUnits
indexModel
:
false
}
}
QGCTextField
{
id
:
baseFontEdit
width
:
_editFieldWidth
-
(
decrementButton
.
width
*
2
)
-
(
baseFontRow
.
spacing
*
2
)
text
:
QGroundControl
.
baseFontPointSize
showUnits
:
true
unitsLabel
:
"
pt
"
maximumLength
:
6
validator
:
DoubleValidator
{
bottom
:
6.0
;
top
:
48.0
;
decimals
:
2
;}
onEditingFinished
:
{
var
point
=
parseFloat
(
text
)
if
(
point
>=
6.0
&&
point
<=
48.0
)
QGroundControl
.
baseFontPointSize
=
point
;
Row
{
spacing
:
ScreenTools
.
defaultFontPixelWidth
QGCLabel
{
width
:
_labelWidth
anchors.baseline
:
areaUnitsCombo
.
baseline
text
:
qsTr
(
"
Area:
"
)
}
FactComboBox
{
id
:
areaUnitsCombo
width
:
_editFieldWidth
fact
:
QGroundControl
.
areaUnits
indexModel
:
false
}
}
QGCButton
{
width
:
height
height
:
baseFontEdit
.
height
text
:
"
+
"
onClicked
:
{
if
(
ScreenTools
.
defaultFontPointSize
<
49
)
{
QGroundControl
.
baseFontPointSize
=
QGroundControl
.
baseFontPointSize
+
1
}
Row
{
spacing
:
ScreenTools
.
defaultFontPixelWidth
QGCLabel
{
width
:
_labelWidth
anchors.baseline
:
speedUnitsCombo
.
baseline
text
:
qsTr
(
"
Speed:
"
)
}
FactComboBox
{
id
:
speedUnitsCombo
width
:
_editFieldWidth
fact
:
QGroundControl
.
speedUnits
indexModel
:
false
}
}
}
QGCLabel
{
anchors.verticalCenter
:
parent
.
verticalCenter
text
:
qsTr
(
"
(requires app restart)
"
)
}
}
//-----------------------------------------------------------------
//-- Units
Row
{
spacing
:
ScreenTools
.
defaultFontPixelWidth
QGCLabel
{
width
:
baseFontLabel
.
width
anchors.baseline
:
distanceUnitsCombo
.
baseline
text
:
qsTr
(
"
Distance units:
"
)
}
FactComboBox
{
id
:
distanceUnitsCombo
width
:
_editFieldWidth
fact
:
QGroundControl
.
distanceUnits
indexModel
:
false
}
QGCLabel
{
anchors.baseline
:
distanceUnitsCombo
.
baseline
text
:
qsTr
(
"
(requires app restart)
"
)
}
}
Row
{
spacing
:
ScreenTools
.
defaultFontPixelWidth
QGCLabel
{
width
:
baseFontLabel
.
width
anchors.baseline
:
areaUnitsCombo
.
baseline
text
:
qsTr
(
"
Area units:
"
)
}
FactComboBox
{
id
:
areaUnitsCombo
width
:
_editFieldWidth
fact
:
QGroundControl
.
areaUnits
indexModel
:
false
}
QGCLabel
{
anchors.baseline
:
areaUnitsCombo
.
baseline
text
:
qsTr
(
"
(requires app restart)
"
)
}
}
Row
{
spacing
:
ScreenTools
.
defaultFontPixelWidth
QGCLabel
{
width
:
baseFontLabel
.
width
anchors.baseline
:
speedUnitsCombo
.
baseline
text
:
qsTr
(
"
Speed units:
"
)
}
FactComboBox
{
id
:
speedUnitsCombo
width
:
_editFieldWidth
fact
:
QGroundControl
.
speedUnits
indexModel
:
false
}
QGCLabel
{
anchors.baseline
:
speedUnitsCombo
.
baseline
text
:
qsTr
(
"
(requires app restart)
"
)
}
}
//-- Video Source
Item
{
height
:
ScreenTools
.
defaultFontPixelHeight
/
2
width
:
parent
.
width
}
//-----------------------------------------------------------------
//-- Audio preferences
QGCCheckBox
{
text
:
qsTr
(
"
Mute all audio output
"
)
checked
:
QGroundControl
.
isAudioMuted
onClicked
:
{
QGroundControl
.
isAudioMuted
=
checked
}
}
//-----------------------------------------------------------------
//-- Prompt Save Log
QGCCheckBox
{
id
:
promptSaveLog
text
:
qsTr
(
"
Prompt to save Flight Data Log after each flight
"
)
checked
:
QGroundControl
.
isSaveLogPrompt
visible
:
!
ScreenTools
.
isMobile
onClicked
:
{
QGroundControl
.
isSaveLogPrompt
=
checked
}
}
//-----------------------------------------------------------------
//-- Prompt Save even if not armed
QGCCheckBox
{
text
:
qsTr
(
"
Prompt to save Flight Data Log even if vehicle was not armed
"
)
checked
:
QGroundControl
.
isSaveLogPromptNotArmed
visible
:
!
ScreenTools
.
isMobile
enabled
:
promptSaveLog
.
checked
onClicked
:
{
QGroundControl
.
isSaveLogPromptNotArmed
=
checked
width
:
qgcView
.
width
*
0.8
height
:
videoLabel
.
height
anchors.margins
:
ScreenTools
.
defaultFontPixelWidth
anchors.horizontalCenter
:
parent
.
horizontalCenter
QGCLabel
{
id
:
videoLabel
text
:
qsTr
(
"
Video (Requires Restart)
"
)
font.family
:
ScreenTools
.
demiboldFontFamily
}
}
//-----------------------------------------------------------------
//-- Clear settings
QGCCheckBox
{
id
:
clearCheck
text
:
qsTr
(
"
Clear all settings on next start
"
)
checked
:
false
onClicked
:
{
checked
?
clearDialog
.
visible
=
true
:
QGroundControl
.
clearDeleteAllSettingsNextBoot
()
}
MessageDialog
{
id
:
clearDialog
visible
:
false
icon
:
StandardIcon
.
Warning
standardButtons
:
StandardButton
.
Yes
|
StandardButton
.
No
title
:
qsTr
(
"
Clear Settings
"
)
text
:
qsTr
(
"
All saved settings will be reset the next time you start QGroundControl. Is this really what you want?
"
)
onYes
:
{
QGroundControl
.
deleteAllSettingsNextBoot
()
clearDialog
.
visible
=
false
Rectangle
{
height
:
videoCol
.
height
+
(
ScreenTools
.
defaultFontPixelHeight
*
2
)
width
:
qgcView
.
width
*
0.8
color
:
qgcPal
.
windowShade
anchors.margins
:
ScreenTools
.
defaultFontPixelWidth
anchors.horizontalCenter
:
parent
.
horizontalCenter
Column
{
id
:
videoCol
spacing
:
ScreenTools
.
defaultFontPixelWidth
anchors.centerIn
:
parent
Row
{
spacing
:
ScreenTools
.
defaultFontPixelWidth
QGCLabel
{
anchors.baseline
:
videoSource
.
baseline
text
:
qsTr
(
"
Video Source:
"
)
width
:
_labelWidth
}
QGCComboBox
{
id
:
videoSource
width
:
_editFieldWidth
model
:
QGroundControl
.
videoManager
.
videoSourceList
Component.onCompleted
:
{
var
index
=
videoSource
.
find
(
QGroundControl
.
videoManager
.
videoSource
)
if
(
index
>=
0
)
{
videoSource
.
currentIndex
=
index
}
}
onActivated
:
{
if
(
index
!=
-
1
)
{
currentIndex
=
index
QGroundControl
.
videoManager
.
videoSource
=
model
[
index
]
}
}
}
}
onNo
:
{
clearCheck
.
checked
=
false
clearDialog
.
visible
=
false
Row
{
spacing
:
ScreenTools
.
defaultFontPixelWidth
visible
:
QGroundControl
.
videoManager
.
isGStreamer
&&
videoSource
.
currentIndex
===
0
QGCLabel
{
anchors.baseline
:
udpField
.
baseline
text
:
qsTr
(
"
UDP Port:
"
)
width
:
_labelWidth
}
QGCTextField
{
id
:
udpField
width
:
_editFieldWidth
text
:
QGroundControl
.
videoManager
.
udpPort
validator
:
IntValidator
{
bottom
:
1024
;
top
:
65535
;}
inputMethodHints
:
Qt
.
ImhDigitsOnly
onEditingFinished
:
{
QGroundControl
.
videoManager
.
udpPort
=
parseInt
(
text
)
}
}
}
}
}
//-----------------------------------------------------------------
//-- Battery talker
Row
{
spacing
:
ScreenTools
.
defaultFontPixelWidth
QGCCheckBox
{
id
:
announcePercentCheckbox
anchors.baseline
:
announcePercent
.
baseline
text
:
qsTr
(
"
Announce battery lower than:
"
)
checked
:
_percentRemainingAnnounce
.
value
!=
0
onClicked
:
{
if
(
checked
)
{
_percentRemainingAnnounce
.
value
=
_percentRemainingAnnounce
.
defaultValueString
}
else
{
_percentRemainingAnnounce
.
value
=
0
Row
{
spacing
:
ScreenTools
.
defaultFontPixelWidth
visible
:
QGroundControl
.
videoManager
.
isGStreamer
&&
videoSource
.
currentIndex
===
1
QGCLabel
{
anchors.baseline
:
rtspField
.
baseline
text
:
qsTr
(
"
RTSP URL:
"
)
width
:
_labelWidth
}
QGCTextField
{
id
:
rtspField
width
:
_editFieldWidth
text
:
QGroundControl
.
videoManager
.
rtspURL
onEditingFinished
:
{
QGroundControl
.
videoManager
.
rtspURL
=
text
}
}
}
}
FactTextField
{
id
:
announcePercent
fact
:
_percentRemainingAnnounce
enabled
:
announcePercentCheckbox
.
checked
}
}
Item
{
height
:
ScreenTools
.
defaultFontPixelHeight
/
2
width
:
parent
.
width
}
//-----------------------------------------------------------------
//-- Video Source
Row
{
spacing
:
ScreenTools
.
defaultFontPixelWidth
//-- Offline mission editing
Item
{
width
:
qgcView
.
width
*
0.8
height
:
offlineLabel
.
height
anchors.margins
:
ScreenTools
.
defaultFontPixelWidth
anchors.horizontalCenter
:
parent
.
horizontalCenter
QGCLabel
{
anchors.baseline
:
videoSource
.
baseline
text
:
qsTr
(
"
Video Source:
"
)
id
:
offlineLabel
text
:
qsTr
(
"
Offline Mission Editing
"
)
font.family
:
ScreenTools
.
demiboldFontFamily
}
QGCComboBox
{
id
:
videoSource
width
:
_editFieldWidth
model
:
QGroundControl
.
videoManager
.
videoSourceList
Component.onCompleted
:
{
var
index
=
videoSource
.
find
(
QGroundControl
.
videoManager
.
videoSource
)
if
(
index
>=
0
)
{
videoSource
.
currentIndex
=
index
}
Rectangle
{
height
:
offlineCol
.
height
+
(
ScreenTools
.
defaultFontPixelHeight
*
2
)
width
:
qgcView
.
width
*
0.8
color
:
qgcPal
.
windowShade
anchors.margins
:
ScreenTools
.
defaultFontPixelWidth
anchors.horizontalCenter
:
parent
.
horizontalCenter
Column
{
id
:
offlineCol
spacing
:
ScreenTools
.
defaultFontPixelWidth
anchors.centerIn
:
parent
Row
{
spacing
:
ScreenTools
.
defaultFontPixelWidth
QGCLabel
{
text
:
qsTr
(
"
Firmware:
"
)
width
:
_labelWidth
anchors.baseline
:
offlineTypeCombo
.
baseline
}
FactComboBox
{
id
:
offlineTypeCombo
width
:
_editFieldWidth
fact
:
QGroundControl
.
offlineEditingFirmwareType
indexModel
:
false
}
}
onActivated
:
{
if
(
index
!=
-
1
)
{
currentIndex
=
index
QGroundControl
.
videoManager
.
videoSource
=
model
[
index
]
Row
{
spacing
:
ScreenTools
.
defaultFontPixelWidth
QGCLabel
{
text
:
qsTr
(
"
Vehicle:
"
)
width
:
_labelWidth
anchors.baseline
:
offlineVehicleCombo
.
baseline
}
FactComboBox
{
id
:
offlineVehicleCombo
width
:
_editFieldWidth
fact
:
QGroundControl
.
offlineEditingVehicleType
indexModel
:
false
}
}
}
}
//-----------------------------------------------------------------
//-- Map Providers
Row
{
/*
TODO: Map settings should come from QGroundControl.mapEngineManager. What is currently in
QGroundControl.flightMapSettings should be moved there so all map related funtions are in
one place.
*/
spacing
:
ScreenTools
.
defaultFontPixelWidth
visible
:
QGroundControl
.
flightMapSettings
.
googleMapEnabled
QGCLabel
{
id
:
mapProvidersLabel
anchors.baseline
:
mapProviders
.
baseline
text
:
qsTr
(
"
Map Provider:
"
)
}
QGCComboBox
{
id
:
mapProviders
width
:
_editFieldWidth
model
:
QGroundControl
.
flightMapSettings
.
mapProviders
Component.onCompleted
:
{
var
index
=
mapProviders
.
find
(
QGroundControl
.
flightMapSettings
.
mapProvider
)
if
(
index
<
0
)
{
console
.
warn
(
qsTr
(
"
Active map provider not in combobox
"
),
QGroundControl
.
flightMapSettings
.
mapProvider
)
}
else
{
mapProviders
.
currentIndex
=
index
Row
{
spacing
:
ScreenTools
.
defaultFontPixelWidth
visible
:
offlineVehicleCombo
.
currentText
!=
"
Multicopter
"
QGCLabel
{
text
:
qsTr
(
"
Cruise speed:
"
)
width
:
_labelWidth
anchors.baseline
:
cruiseSpeedField
.
baseline
}
FactTextField
{
id
:
cruiseSpeedField
width
:
_editFieldWidth
fact
:
QGroundControl
.
offlineEditingCruiseSpeed
enabled
:
true
}
}
onActivated
:
{
if
(
index
!=
-
1
)
{
currentIndex
=
index
console
.
log
(
qsTr
(
"
New map provider:
"
)
+
model
[
index
])
QGroundControl
.
flightMapSettings
.
mapProvider
=
model
[
index
]
Row
{
spacing
:
ScreenTools
.
defaultFontPixelWidth
visible
:
offlineVehicleCombo
.
currentText
!=
"
Fixedwing
"
QGCLabel
{
id
:
hoverSpeedLabel
text
:
qsTr
(
"
Hover speed:
"
)
width
:
_labelWidth
anchors.baseline
:
hoverSpeedField
.
baseline
}
FactTextField
{
id
:
hoverSpeedField
width
:
_editFieldWidth
fact
:
QGroundControl
.
offlineEditingHoverSpeed
enabled
:
true
}
}
}
}
//-----------------------------------------------------------------
//-- Palette Styles
Row
{
spacing
:
ScreenTools
.
defaultFontPixelWidth
//-- Miscelanous
Item
{
width
:
qgcView
.
width
*
0.8
height
:
miscLabel
.
height
anchors.margins
:
ScreenTools
.
defaultFontPixelWidth
anchors.horizontalCenter
:
parent
.
horizontalCenter
QGCLabel
{
width
:
mapProvidersLabel
.
width
anchors.baseline
:
paletteCombo
.
baseline
text
:
qsTr
(
"
Style:
"
)
id
:
miscLabel
text
:
qsTr
(
"
Miscelaneous
"
)
font.family
:
ScreenTools
.
demiboldFontFamily
}
QGCComboBox
{
id
:
paletteCombo
width
:
_editFieldWidth
model
:
[
qsTr
(
"
Indoor
"
),
qsTr
(
"
Outdoor
"
)
]
currentIndex
:
QGroundControl
.
isDarkStyle
?
0
:
1
onActivated
:
{
if
(
index
!=
-
1
)
{
currentIndex
=
index
QGroundControl
.
isDarkStyle
=
index
===
0
?
true
:
false
}
Rectangle
{
height
:
miscCol
.
height
+
(
ScreenTools
.
defaultFontPixelHeight
*
2
)
width
:
qgcView
.
width
*
0.8
color
:
qgcPal
.
windowShade
anchors.margins
:
ScreenTools
.
defaultFontPixelWidth
anchors.horizontalCenter
:
parent
.
horizontalCenter
Column
{
id
:
miscCol
spacing
:
ScreenTools
.
defaultFontPixelWidth
anchors.centerIn
:
parent
//-----------------------------------------------------------------
//-- Base UI Font Point Size
Row
{
spacing
:
ScreenTools
.
defaultFontPixelWidth
QGCLabel
{
id
:
baseFontLabel
text
:
qsTr
(
"
Base UI font size:
"
)
anchors.verticalCenter
:
parent
.
verticalCenter
}
Row
{
id
:
baseFontRow
spacing
:
ScreenTools
.
defaultFontPixelWidth
/
2
anchors.verticalCenter
:
parent
.
verticalCenter
QGCButton
{
id
:
decrementButton
width
:
height
height
:
baseFontEdit
.
height
text
:
"
-
"
onClicked
:
{
if
(
ScreenTools
.
defaultFontPointSize
>
6
)
{
QGroundControl
.
baseFontPointSize
=
QGroundControl
.
baseFontPointSize
-
1
}
}
}
QGCTextField
{
id
:
baseFontEdit
width
:
_editFieldWidth
-
(
decrementButton
.
width
*
2
)
-
(
baseFontRow
.
spacing
*
2
)
text
:
QGroundControl
.
baseFontPointSize
showUnits
:
true
unitsLabel
:
"
pt
"
maximumLength
:
6
validator
:
DoubleValidator
{
bottom
:
6.0
;
top
:
48.0
;
decimals
:
2
;}
onEditingFinished
:
{
var
point
=
parseFloat
(
text
)
if
(
point
>=
6.0
&&
point
<=
48.0
)
QGroundControl
.
baseFontPointSize
=
point
;
}
}
QGCButton
{
width
:
height
height
:
baseFontEdit
.
height
text
:
"
+
"
onClicked
:
{
if
(
ScreenTools
.
defaultFontPointSize
<
49
)
{
QGroundControl
.
baseFontPointSize
=
QGroundControl
.
baseFontPointSize
+
1
}
}
}
}
QGCLabel
{
anchors.verticalCenter
:
parent
.
verticalCenter
text
:
qsTr
(
"
(Requires Restart)
"
)
}
}
//-----------------------------------------------------------------
//-- Audio preferences
QGCCheckBox
{
text
:
qsTr
(
"
Mute all audio output
"
)
checked
:
QGroundControl
.
isAudioMuted
onClicked
:
{
QGroundControl
.
isAudioMuted
=
checked
}
}
//-----------------------------------------------------------------
//-- Prompt Save Log
QGCCheckBox
{
id
:
promptSaveLog
text
:
qsTr
(
"
Prompt to save Flight Data Log after each flight
"
)
checked
:
QGroundControl
.
isSaveLogPrompt
visible
:
!
ScreenTools
.
isMobile
onClicked
:
{
QGroundControl
.
isSaveLogPrompt
=
checked
}
}
//-----------------------------------------------------------------
//-- Prompt Save even if not armed
QGCCheckBox
{
text
:
qsTr
(
"
Prompt to save Flight Data Log even if vehicle was not armed
"
)
checked
:
QGroundControl
.
isSaveLogPromptNotArmed
visible
:
!
ScreenTools
.
isMobile
enabled
:
promptSaveLog
.
checked
onClicked
:
{
QGroundControl
.
isSaveLogPromptNotArmed
=
checked
}
}
//-----------------------------------------------------------------
//-- Clear settings
QGCCheckBox
{
id
:
clearCheck
text
:
qsTr
(
"
Clear all settings on next start
"
)
checked
:
false
onClicked
:
{
checked
?
clearDialog
.
visible
=
true
:
QGroundControl
.
clearDeleteAllSettingsNextBoot
()
}
MessageDialog
{
id
:
clearDialog
visible
:
false
icon
:
StandardIcon
.
Warning
standardButtons
:
StandardButton
.
Yes
|
StandardButton
.
No
title
:
qsTr
(
"
Clear Settings
"
)
text
:
qsTr
(
"
All saved settings will be reset the next time you start QGroundControl. Is this really what you want?
"
)
onYes
:
{
QGroundControl
.
deleteAllSettingsNextBoot
()
clearDialog
.
visible
=
false
}
onNo
:
{
clearCheck
.
checked
=
false
clearDialog
.
visible
=
false
}
}
}
//-----------------------------------------------------------------
//-- Battery talker
Row
{
spacing
:
ScreenTools
.
defaultFontPixelWidth
QGCCheckBox
{
id
:
announcePercentCheckbox
anchors.verticalCenter
:
parent
.
verticalCenter
text
:
qsTr
(
"
Announce battery lower than:
"
)
checked
:
_percentRemainingAnnounce
.
value
!=
0
onClicked
:
{
if
(
checked
)
{
_percentRemainingAnnounce
.
value
=
_percentRemainingAnnounce
.
defaultValueString
}
else
{
_percentRemainingAnnounce
.
value
=
0
}
}
}
FactTextField
{
id
:
announcePercent
fact
:
_percentRemainingAnnounce
enabled
:
announcePercentCheckbox
.
checked
anchors.verticalCenter
:
parent
.
verticalCenter
}
}
//-----------------------------------------------------------------
//-- Virtual joystick settings
QGCCheckBox
{
text
:
qsTr
(
"
Virtual Joystick
"
)
checked
:
QGroundControl
.
virtualTabletJoystick
onClicked
:
QGroundControl
.
virtualTabletJoystick
=
checked
}
//-----------------------------------------------------------------
//-- Map Providers
Row
{
/*
TODO: Map settings should come from QGroundControl.mapEngineManager. What is currently in
QGroundControl.flightMapSettings should be moved there so all map related funtions are in
one place.
*/
spacing
:
ScreenTools
.
defaultFontPixelWidth
visible
:
QGroundControl
.
flightMapSettings
.
googleMapEnabled
QGCLabel
{
id
:
mapProvidersLabel
anchors.baseline
:
mapProviders
.
baseline
text
:
qsTr
(
"
Map Provider:
"
)
width
:
_labelWidth
}
QGCComboBox
{
id
:
mapProviders
width
:
_editFieldWidth
model
:
QGroundControl
.
flightMapSettings
.
mapProviders
Component.onCompleted
:
{
var
index
=
mapProviders
.
find
(
QGroundControl
.
flightMapSettings
.
mapProvider
)
if
(
index
<
0
)
{
console
.
warn
(
qsTr
(
"
Active map provider not in combobox
"
),
QGroundControl
.
flightMapSettings
.
mapProvider
)
}
else
{
mapProviders
.
currentIndex
=
index
}
}
onActivated
:
{
if
(
index
!=
-
1
)
{
currentIndex
=
index
console
.
log
(
qsTr
(
"
New map provider:
"
)
+
model
[
index
])
QGroundControl
.
flightMapSettings
.
mapProvider
=
model
[
index
]
}
}
}
}
//-----------------------------------------------------------------
//-- Palette Styles
Row
{
spacing
:
ScreenTools
.
defaultFontPixelWidth
QGCLabel
{
anchors.baseline
:
paletteCombo
.
baseline
text
:
qsTr
(
"
Style:
"
)
width
:
_labelWidth
}
QGCComboBox
{
id
:
paletteCombo
width
:
_editFieldWidth
model
:
[
qsTr
(
"
Indoor
"
),
qsTr
(
"
Outdoor
"
)
]
currentIndex
:
QGroundControl
.
isDarkStyle
?
0
:
1
onActivated
:
{
if
(
index
!=
-
1
)
{
currentIndex
=
index
QGroundControl
.
isDarkStyle
=
index
===
0
?
true
:
false
}
}
}
}
}
}
Item
{
height
:
ScreenTools
.
defaultFontPixelHeight
/
2
width
:
parent
.
width
}
//-----------------------------------------------------------------
//-- Autoconnect settings
QGCLabel
{
text
:
"
Autoconnect to the following devices:
"
}
Row
{
spacing
:
ScreenTools
.
defaultFontPixelWidth
*
2
QGCCheckBox
{
text
:
qsTr
(
"
Pixhawk
"
)
visible
:
!
ScreenTools
.
isiOS
checked
:
QGroundControl
.
linkManager
.
autoconnectPixhawk
onClicked
:
QGroundControl
.
linkManager
.
autoconnectPixhawk
=
checked
}
QGCCheckBox
{
text
:
qsTr
(
"
SiK Radio
"
)
visible
:
!
ScreenTools
.
isiOS
checked
:
QGroundControl
.
linkManager
.
autoconnect3DRRadio
onClicked
:
QGroundControl
.
linkManager
.
autoconnect3DRRadio
=
checked
}
QGCCheckBox
{
text
:
qsTr
(
"
PX4 Flow
"
)
visible
:
!
ScreenTools
.
isiOS
checked
:
QGroundControl
.
linkManager
.
autoconnectPX4Flow
onClicked
:
QGroundControl
.
linkManager
.
autoconnectPX4Flow
=
checked
}
QGCCheckBox
{
text
:
qsTr
(
"
UDP
"
)
checked
:
QGroundControl
.
linkManager
.
autoconnectUDP
onClicked
:
QGroundControl
.
linkManager
.
autoconnectUDP
=
checked
}
QGCCheckBox
{
text
:
qsTr
(
"
RTK GPS
"
)
checked
:
QGroundControl
.
linkManager
.
autoconnectRTKGPS
onClicked
:
QGroundControl
.
linkManager
.
autoconnectRTKGPS
=
checked
}
}
Item
{
height
:
ScreenTools
.
defaultFontPixelHeight
/
2
width
:
parent
.
width
}
//-----------------------------------------------------------------
//-- Virtual joystick settings
QGCCheckBox
{
text
:
qsTr
(
"
Virtual Joystick
"
)
checked
:
QGroundControl
.
virtualTabletJoystick
onClicked
:
QGroundControl
.
virtualTabletJoystick
=
checked
}
Item
{
height
:
ScreenTools
.
defaultFontPixelHeight
/
2
width
:
parent
.
width
}
//-----------------------------------------------------------------
//-- Offline mission editing settings
QGCLabel
{
text
:
"
Offline mission editing
"
}
Row
{
spacing
:
ScreenTools
.
defaultFontPixelWidth
QGCLabel
{
text
:
qsTr
(
"
Firmware:
"
)
width
:
hoverSpeedLabel
.
width
anchors.baseline
:
offlineTypeCombo
.
baseline
}
FactComboBox
{
id
:
offlineTypeCombo
width
:
ScreenTools
.
defaultFontPixelWidth
*
18
fact
:
QGroundControl
.
offlineEditingFirmwareType
indexModel
:
false
}
}
Row
{
spacing
:
ScreenTools
.
defaultFontPixelWidth
width
:
qgcView
.
width
*
0.8
height
:
autoConnectLabel
.
height
anchors.margins
:
ScreenTools
.
defaultFontPixelWidth
anchors.horizontalCenter
:
parent
.
horizontalCenter
QGCLabel
{
text
:
qsTr
(
"
Vehicle:
"
)
width
:
hoverSpeedLabel
.
width
anchors.baseline
:
offlineVehicleCombo
.
baseline
}
FactComboBox
{
id
:
offlineVehicleCombo
width
:
offlineTypeCombo
.
width
fact
:
QGroundControl
.
offlineEditingVehicleType
indexModel
:
false
id
:
autoConnectLabel
text
:
qsTr
(
"
Autoconnect to the following devices:
"
)
font.family
:
ScreenTools
.
demiboldFontFamily
}
}
Row
{
spacing
:
ScreenTools
.
defaultFontPixelWidth
visible
:
offlineVehicleCombo
.
currentText
!=
"
Multicopter
"
QGCLabel
{
text
:
qsTr
(
"
Cruise speed:
"
)
width
:
hoverSpeedLabel
.
width
anchors.baseline
:
cruiseSpeedField
.
baseline
}
FactTextField
{
id
:
cruiseSpeedField
width
:
offlineTypeCombo
.
width
fact
:
QGroundControl
.
offlineEditingCruiseSpeed
enabled
:
true
}
}
Row
{
spacing
:
ScreenTools
.
defaultFontPixelWidth
visible
:
offlineVehicleCombo
.
currentText
!=
"
Fixedwing
"
QGCLabel
{
id
:
hoverSpeedLabel
text
:
qsTr
(
"
Hover speed:
"
)
width
:
baseFontLabel
.
width
anchors.baseline
:
hoverSpeedField
.
baseline
}
FactTextField
{
id
:
hoverSpeedField
width
:
offlineTypeCombo
.
width
fact
:
QGroundControl
.
offlineEditingHoverSpeed
enabled
:
true
Rectangle
{
height
:
autoConnectCol
.
height
+
(
ScreenTools
.
defaultFontPixelHeight
*
2
)
width
:
qgcView
.
width
*
0.8
color
:
qgcPal
.
windowShade
anchors.margins
:
ScreenTools
.
defaultFontPixelWidth
anchors.horizontalCenter
:
parent
.
horizontalCenter
Column
{
id
:
autoConnectCol
spacing
:
ScreenTools
.
defaultFontPixelWidth
anchors.centerIn
:
parent
//-----------------------------------------------------------------
//-- Autoconnect settings
Row
{
spacing
:
ScreenTools
.
defaultFontPixelWidth
*
2
QGCCheckBox
{
text
:
qsTr
(
"
Pixhawk
"
)
visible
:
!
ScreenTools
.
isiOS
checked
:
QGroundControl
.
linkManager
.
autoconnectPixhawk
onClicked
:
QGroundControl
.
linkManager
.
autoconnectPixhawk
=
checked
}
QGCCheckBox
{
text
:
qsTr
(
"
SiK Radio
"
)
visible
:
!
ScreenTools
.
isiOS
checked
:
QGroundControl
.
linkManager
.
autoconnect3DRRadio
onClicked
:
QGroundControl
.
linkManager
.
autoconnect3DRRadio
=
checked
}
QGCCheckBox
{
text
:
qsTr
(
"
PX4 Flow
"
)
visible
:
!
ScreenTools
.
isiOS
checked
:
QGroundControl
.
linkManager
.
autoconnectPX4Flow
onClicked
:
QGroundControl
.
linkManager
.
autoconnectPX4Flow
=
checked
}
QGCCheckBox
{
text
:
qsTr
(
"
UDP
"
)
checked
:
QGroundControl
.
linkManager
.
autoconnectUDP
onClicked
:
QGroundControl
.
linkManager
.
autoconnectUDP
=
checked
}
QGCCheckBox
{
text
:
qsTr
(
"
RTK GPS
"
)
checked
:
QGroundControl
.
linkManager
.
autoconnectRTKGPS
onClicked
:
QGroundControl
.
linkManager
.
autoconnectRTKGPS
=
checked
}
}
}
}
Item
{
height
:
ScreenTools
.
defaultFontPixelHeight
/
2
width
:
parent
.
width
}
}
}
}
// settingsColumn
}
// QGCFlickable
}
// QGCViewPanel
}
// QGCView
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment