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
Show 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) {
equals(QT_MAJOR_VERSION, 5) | greaterThan(QT_MINOR_VERSION, 5) {
QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.7
} else {
} 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
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
Loader
{
id
:
cameraLoader
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')"
;
if
(
isUdp
)
{
dataSource
=
gst_element_factory_make
(
"udpsrc"
,
"udp-source"
);
}
else
{
dataSource
=
gst_element_factory_make
(
"rtspsrc"
,
"rtsp-source"
);
}
if
(
!
dataSource
)
{
qCritical
()
<<
"VideoReceiver::start() failed. Error with data source for gst_element_factory_make()"
;
break
;
}
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
#- 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
...
...
@@ -56,6 +56,7 @@ private:
#if defined(QGC_GST_STREAMING)
VideoSurfacePrivate
*
const
_data
;
time_t
_lastFrame
;
bool
_refed
;
#endif
};
...
...
src/VideoStreaming/gstqtvideosink/gstqtvideosinkplugin.cpp
View file @
f1559638
src/ui/preferences/GeneralSettings.qml
View file @
f1559638
...
...
@@ -31,54 +31,308 @@ 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
//-----------------------------------------------------------------
//-- Units
Item
{
width
:
qgcView
.
width
*
0.8
height
:
unitLabel
.
height
anchors.margins
:
ScreenTools
.
defaultFontPixelWidth
anchors.horizontalCenter
:
parent
.
horizontalCenter
QGCLabel
{
id
:
unitLabel
text
:
qsTr
(
"
Units (Requires Restart)
"
)
font.family
:
ScreenTools
.
demiboldFontFamily
}
}
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
}
}
Row
{
spacing
:
ScreenTools
.
defaultFontPixelWidth
QGCLabel
{
width
:
_labelWidth
anchors.baseline
:
areaUnitsCombo
.
baseline
text
:
qsTr
(
"
Area:
"
)
}
FactComboBox
{
id
:
areaUnitsCombo
width
:
_editFieldWidth
fact
:
QGroundControl
.
areaUnits
indexModel
:
false
}
}
Row
{
spacing
:
ScreenTools
.
defaultFontPixelWidth
QGCLabel
{
width
:
_labelWidth
anchors.baseline
:
speedUnitsCombo
.
baseline
text
:
qsTr
(
"
Speed:
"
)
}
FactComboBox
{
id
:
speedUnitsCombo
width
:
_editFieldWidth
fact
:
QGroundControl
.
speedUnits
indexModel
:
false
}
}
}
}
//-----------------------------------------------------------------
//-- Video Source
Item
{
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
}
}
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
]
}
}
}
}
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
)
}
}
}
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
}
}
}
}
}
//-----------------------------------------------------------------
//-- Offline mission editing
Item
{
width
:
qgcView
.
width
*
0.8
height
:
offlineLabel
.
height
anchors.margins
:
ScreenTools
.
defaultFontPixelWidth
anchors.horizontalCenter
:
parent
.
horizontalCenter
QGCLabel
{
id
:
offlineLabel
text
:
qsTr
(
"
Offline Mission Editing
"
)
font.family
:
ScreenTools
.
demiboldFontFamily
}
}
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
}
}
Row
{
spacing
:
ScreenTools
.
defaultFontPixelWidth
QGCLabel
{
text
:
qsTr
(
"
Vehicle:
"
)
width
:
_labelWidth
anchors.baseline
:
offlineVehicleCombo
.
baseline
}
FactComboBox
{
id
:
offlineVehicleCombo
width
:
_editFieldWidth
fact
:
QGroundControl
.
offlineEditingVehicleType
indexModel
:
false
}
}
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
}
}
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
}
}
}
}
//-----------------------------------------------------------------
//-- Miscelanous
Item
{
width
:
qgcView
.
width
*
0.8
height
:
miscLabel
.
height
anchors.margins
:
ScreenTools
.
defaultFontPixelWidth
anchors.horizontalCenter
:
parent
.
horizontalCenter
QGCLabel
{
id
:
miscLabel
text
:
qsTr
(
"
Miscelaneous
"
)
font.family
:
ScreenTools
.
demiboldFontFamily
}
}
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
)
...
...
@@ -87,19 +341,16 @@ QGCView {
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
...
...
@@ -107,89 +358,11 @@ QGCView {
}
}
}
QGCLabel
{
anchors.verticalCenter
:
parent
.
verticalCenter
text
:
qsTr
(
"
(requires app r
estart)
"
)
text
:
qsTr
(
"
(Requires R
estart)
"
)
}
}
//-----------------------------------------------------------------
//-- 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)
"
)
}
}
Item
{
height
:
ScreenTools
.
defaultFontPixelHeight
/
2
width
:
parent
.
width
}
//-----------------------------------------------------------------
//-- Audio preferences
QGCCheckBox
{
...
...
@@ -251,13 +424,11 @@ QGCView {
//-- Battery talker
Row
{
spacing
:
ScreenTools
.
defaultFontPixelWidth
QGCCheckBox
{
id
:
announcePercentCheckbox
anchors.baseline
:
announcePercent
.
baseline
anchors.verticalCenter
:
parent
.
verticalCenter
text
:
qsTr
(
"
Announce battery lower than:
"
)
checked
:
_percentRemainingAnnounce
.
value
!=
0
onClicked
:
{
if
(
checked
)
{
_percentRemainingAnnounce
.
value
=
_percentRemainingAnnounce
.
defaultValueString
...
...
@@ -266,64 +437,36 @@ QGCView {
}
}
}
FactTextField
{
id
:
announcePercent
fact
:
_percentRemainingAnnounce
enabled
:
announcePercentCheckbox
.
checked
anchors.verticalCenter
:
parent
.
verticalCenter
}
}
Item
{
height
:
ScreenTools
.
defaultFontPixelHeight
/
2
width
:
parent
.
width
}
//-----------------------------------------------------------------
//-- Video Source
Row
{
spacing
:
ScreenTools
.
defaultFontPixelWidth
QGCLabel
{
anchors.baseline
:
videoSource
.
baseline
text
:
qsTr
(
"
Video Source:
"
)
}
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
]
}
}
}
//-- 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
...
...
@@ -349,19 +492,16 @@ QGCView {
//-- Palette Styles
Row
{
spacing
:
ScreenTools
.
defaultFontPixelWidth
QGCLabel
{
width
:
mapProvidersLabel
.
width
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
...
...
@@ -370,154 +510,67 @@ QGCView {
}
}
}
}
}
//-----------------------------------------------------------------
//-- Autoconnect settings
Item
{
height
:
ScreenTools
.
defaultFontPixelHeight
/
2
width
:
parent
.
width
width
:
qgcView
.
width
*
0.8
height
:
autoConnectLabel
.
height
anchors.margins
:
ScreenTools
.
defaultFontPixelWidth
anchors.horizontalCenter
:
parent
.
horizontalCenter
QGCLabel
{
id
:
autoConnectLabel
text
:
qsTr
(
"
Autoconnect to the following devices:
"
)
font.family
:
ScreenTools
.
demiboldFontFamily
}
}
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
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
QGCLabel
{
text
:
qsTr
(
"
Vehicle:
"
)
width
:
hoverSpeedLabel
.
width
anchors.baseline
:
offlineVehicleCombo
.
baseline
}
FactComboBox
{
id
:
offlineVehicleCombo
width
:
offlineTypeCombo
.
width
fact
:
QGroundControl
.
offlineEditingVehicleType
indexModel
:
false
}
}
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
}
}
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