Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Valentin Platzgummer
qgroundcontrol
Commits
f7be8bff
Commit
f7be8bff
authored
Apr 28, 2020
by
DoinLakeFlyer
Browse files
Merge remote-tracking branch 'origin/TerrainProfile' into TerrainProfile
parents
ecb051f3
aa8a9ac6
Changes
38
Expand all
Hide whitespace changes
Inline
Side-by-side
src/PlanView/MissionItemMapVisual.qml
View file @
f7be8bff
...
...
@@ -23,6 +23,7 @@ Item {
property
var
map
///< Map control to place item in
property
var
vehicle
///< Vehicle associated with this item
property
var
interactive
:
true
///< Vehicle associated with this item
signal
clicked
(
int
sequenceNumber
)
...
...
@@ -34,7 +35,7 @@ Item {
if
(
component
.
status
===
Component
.
Error
)
{
console
.
log
(
"
Error loading Qml:
"
,
object
.
mapVisualQML
,
component
.
errorString
())
}
_visualItem
=
component
.
createObject
(
map
,
{
"
map
"
:
_root
.
map
,
vehicle
:
_root
.
vehicle
})
_visualItem
=
component
.
createObject
(
map
,
{
"
map
"
:
_root
.
map
,
vehicle
:
_root
.
vehicle
,
'
opacity
'
:
Qt
.
binding
(
function
()
{
return
_root
.
opacity
}),
'
interactive
'
:
Qt
.
binding
(
function
()
{
return
_root
.
interactive
})
})
_visualItem
.
clicked
.
connect
(
_root
.
clicked
)
}
}
...
...
src/PlanView/PlanView.qml
View file @
f7be8bff
...
...
@@ -388,8 +388,9 @@ Item {
// This is the center rectangle of the map which is not obscured by tools
property
rect
centerViewport
:
Qt
.
rect
(
_leftToolWidth
+
_margin
,
_margin
,
editorMap
.
width
-
_leftToolWidth
-
_rightToolWidth
-
(
_margin
*
2
),
(
terrainStatus
.
visible
?
terrainStatus
.
y
:
height
-
_margin
)
-
_margin
)
property
real
_leftToolWidth
:
toolStrip
.
x
+
toolStrip
.
width
property
real
_rightToolWidth
:
rightPanel
.
width
+
rightPanel
.
anchors
.
rightMargin
property
real
_leftToolWidth
:
toolStrip
.
x
+
toolStrip
.
width
property
real
_rightToolWidth
:
rightPanel
.
width
+
rightPanel
.
anchors
.
rightMargin
property
real
_nonInteractiveOpacity
:
0.5
// Initial map position duplicates Fly view position
Component.onCompleted
:
editorMap
.
center
=
QGroundControl
.
flightMapPosition
...
...
@@ -436,18 +437,20 @@ Item {
// Add the mission item visuals to the map
Repeater
{
model
:
_editingLayer
==
_layerMission
?
_missionController
.
visualItems
:
undefined
model
:
_missionController
.
visualItems
delegate
:
MissionItemMapVisual
{
map
:
editorMap
onClicked
:
_missionController
.
setCurrentPlanViewSeqNum
(
sequenceNumber
,
false
)
visible
:
_editingLayer
==
_layerMission
opacity
:
_editingLayer
==
_layerMission
?
1
:
editorMap
.
_nonInteractiveOpacity
interactive
:
_editingLayer
==
_layerMission
}
}
// Add lines between waypoints
MissionLineView
{
showSpecialVisual
:
_missionController
.
isROIBeginCurrentItem
model
:
_editingLayer
==
_layerMission
?
_missionController
.
simpleFlightPathSegments
:
undefined
model
:
_missionController
.
simpleFlightPathSegments
opacity
:
_editingLayer
==
_layerMission
?
1
:
editorMap
.
_nonInteractiveOpacity
}
// Direction arrows in waypoint lines
...
...
@@ -464,13 +467,14 @@ Item {
// Incomplete segment lines
MapItemView
{
model
:
_editingLayer
==
_layerMission
?
_missionController
.
incompleteComplexItemLines
:
undefined
model
:
_missionController
.
incompleteComplexItemLines
delegate
:
MapPolyline
{
path
:
[
object
.
coordinate1
,
object
.
coordinate2
]
line.width
:
1
line.color
:
"
red
"
z
:
QGroundControl
.
zOrderWaypointLines
opacity
:
_editingLayer
==
_layerMission
?
1
:
editorMap
.
_nonInteractiveOpacity
}
}
...
...
@@ -513,8 +517,7 @@ Item {
// Add the vehicles to the map
MapItemView
{
model
:
QGroundControl
.
multiVehicleManager
.
vehicles
delegate
:
VehicleMapItem
{
delegate
:
VehicleMapItem
{
vehicle
:
object
coordinate
:
object
.
coordinate
map
:
editorMap
...
...
@@ -529,6 +532,7 @@ Item {
interactive
:
_editingLayer
==
_layerGeoFence
homePosition
:
_missionController
.
plannedHomePosition
planView
:
true
opacity
:
_editingLayer
!=
_layerGeoFence
?
editorMap
.
_nonInteractiveOpacity
:
1
}
RallyPointMapVisuals
{
...
...
@@ -536,6 +540,7 @@ Item {
myRallyPointController
:
_rallyPointController
interactive
:
_editingLayer
==
_layerRallyPoints
planView
:
true
opacity
:
_editingLayer
!=
_layerRallyPoints
?
editorMap
.
_nonInteractiveOpacity
:
1
}
// Airspace overlap support
...
...
@@ -851,6 +856,7 @@ Item {
flightMap
:
editorMap
visible
:
_editingLayer
==
_layerGeoFence
}
// Rally Point Editor
RallyPointEditorHeader
{
id
:
rallyPointHeader
...
...
src/PlanView/RallyPointMapVisuals.qml
View file @
f7be8bff
...
...
@@ -47,7 +47,7 @@ Item {
MissionItemIndicatorDrag
{
mapControl
:
_root
.
map
itemCoordinate
:
rallyPointObject
.
coordinate
visible
:
rallyPointObject
===
myRallyPointController
.
currentRallyPoint
visible
:
rallyPointObject
===
myRallyPointController
.
currentRallyPoint
&&
_root
.
interactive
property
var
rallyPointObject
...
...
@@ -63,6 +63,7 @@ Item {
anchorPoint.x
:
sourceItem
.
anchorPointX
anchorPoint.y
:
sourceItem
.
anchorPointY
z
:
QGroundControl
.
zOrderMapItems
opacity
:
_root
.
opacity
property
var
rallyPointObject
...
...
@@ -84,6 +85,7 @@ Item {
model
:
_rallyPoints
delegate
:
Item
{
opacity
:
_root
.
opacity
property
var
_visuals
:
[
]
Component.onCompleted
:
{
...
...
src/PlanView/SimpleItemMapVisual.qml
View file @
f7be8bff
...
...
@@ -24,6 +24,7 @@ Item {
property
var
map
///< Map control to place item in
property
var
vehicle
///< Vehicle associated with this item
property
bool
interactive
:
true
property
var
_missionItem
:
object
property
var
_itemVisual
...
...
@@ -95,6 +96,7 @@ Item {
mapControl
:
_root
.
map
itemIndicator
:
_itemVisual
itemCoordinate
:
_missionItem
.
coordinate
visible
:
_root
.
interactive
onItemCoordinateChanged
:
_missionItem
.
coordinate
=
itemCoordinate
}
...
...
@@ -109,7 +111,8 @@ Item {
z
:
QGroundControl
.
zOrderMapItems
missionItem
:
_missionItem
sequenceNumber
:
_missionItem
.
sequenceNumber
onClicked
:
_root
.
clicked
(
_missionItem
.
sequenceNumber
)
onClicked
:
if
(
_root
.
interactive
)
_root
.
clicked
(
_missionItem
.
sequenceNumber
)
opacity
:
_root
.
opacity
}
}
}
src/PlanView/StructureScanMapVisual.qml
View file @
f7be8bff
...
...
@@ -27,6 +27,7 @@ Item {
property
var
_missionItem
:
object
property
var
_structurePolygon
:
object
.
structurePolygon
property
var
_flightPolygon
:
object
.
flightPolygon
property
bool
interactive
:
parent
.
interactive
signal
clicked
(
int
sequenceNumber
)
...
...
@@ -43,12 +44,12 @@ Item {
QGCMapPolygonVisuals
{
mapControl
:
map
mapPolygon
:
_structurePolygon
interactive
:
_missionItem
.
isCurrentItem
interactive
:
_missionItem
.
isCurrentItem
&&
_root
.
interactive
borderWidth
:
1
borderColor
:
"
black
"
interiorColor
:
"
green
"
altColor
:
"
red
"
interiorOpacity
:
0.
2
5
interiorOpacity
:
0.5
*
_root
.
opacity
}
QGCMapPolygonVisuals
{
...
...
@@ -57,6 +58,7 @@ Item {
interactive
:
false
borderWidth
:
2
borderColor
:
"
white
"
interiorOpacity
:
_root
.
opacity
}
// Entry point
...
...
@@ -68,7 +70,7 @@ Item {
anchorPoint.y
:
sourceItem
.
anchorPointY
z
:
QGroundControl
.
zOrderMapItems
coordinate
:
_missionItem
.
coordinate
visible
:
_missionItem
.
exitCoordinate
.
isValid
visible
:
_missionItem
.
exitCoordinate
.
isValid
&&
_root
.
interactive
sourceItem
:
MissionItemIndexLabel
{
index
:
_missionItem
.
sequenceNumber
...
...
@@ -88,7 +90,7 @@ Item {
anchorPoint.y
:
sourceItem
.
anchorPointY
z
:
QGroundControl
.
zOrderMapItems
coordinate
:
_missionItem
.
exitCoordinate
visible
:
_missionItem
.
exitCoordinate
.
isValid
visible
:
_missionItem
.
exitCoordinate
.
isValid
&&
_root
.
interactive
sourceItem
:
MissionItemIndexLabel
{
index
:
_missionItem
.
lastSequenceNumber
...
...
src/PlanView/TakeoffItemMapVisual.qml
View file @
f7be8bff
...
...
@@ -24,6 +24,7 @@ Item {
property
var
map
///< Map control to place item in
property
var
vehicle
///< Vehicle associated with this item
property
bool
interactive
:
true
property
var
_missionItem
:
object
property
var
_takeoffIndicatorItem
...
...
@@ -78,6 +79,7 @@ Item {
mapControl
:
_root
.
map
itemIndicator
:
_takeoffIndicatorItem
itemCoordinate
:
_missionItem
.
specifiesCoordinate
?
_missionItem
.
coordinate
:
_missionItem
.
launchCoordinate
visible
:
_root
.
interactive
onItemCoordinateChanged
:
{
if
(
_missionItem
.
specifiesCoordinate
)
{
...
...
@@ -96,7 +98,7 @@ Item {
mapControl
:
_root
.
map
itemIndicator
:
_launchIndicatorItem
itemCoordinate
:
_missionItem
.
launchCoordinate
visible
:
!
_missionItem
.
launchTakeoffAtSameLocation
visible
:
!
_missionItem
.
launchTakeoffAtSameLocation
&&
_root
.
interactive
onItemCoordinateChanged
:
_missionItem
.
launchCoordinate
=
itemCoordinate
}
...
...
@@ -111,6 +113,7 @@ Item {
missionItem
:
_missionItem
sequenceNumber
:
_missionItem
.
sequenceNumber
onClicked
:
_root
.
clicked
(
_missionItem
.
sequenceNumber
)
opacity
:
_root
.
opacity
}
}
...
...
@@ -121,7 +124,7 @@ Item {
coordinate
:
_missionItem
.
launchCoordinate
anchorPoint.x
:
sourceItem
.
anchorPointX
anchorPoint.y
:
sourceItem
.
anchorPointY
visible
:
!
_missionItem
.
launchTakeoffAtSameLocation
visible
:
!
_missionItem
.
launchTakeoffAtSameLocation
&&
_root
.
interactive
sourceItem
:
MissionItemIndexLabel
{
...
...
@@ -129,6 +132,7 @@ Item {
label
:
qsTr
(
"
Launch
"
)
highlightSelected
:
true
onClicked
:
_root
.
clicked
(
_missionItem
.
sequenceNumber
)
visible
:
_root
.
interactive
}
}
}
...
...
@@ -140,7 +144,7 @@ Item {
MouseArea
{
anchors.fill
:
map
z
:
QGroundControl
.
zOrderMapItems
+
1
// Over item indicators
visible
:
!
_missionItem
.
launchCoordinate
.
isValid
visible
:
!
_missionItem
.
launchCoordinate
.
isValid
&&
_root
.
interactive
readonly
property
int
_decimalPlaces
:
8
...
...
src/PlanView/TransectStyleMapVisuals.qml
View file @
f7be8bff
...
...
@@ -24,6 +24,7 @@ Item {
property
var
map
///< Map control to place item in
property
bool
polygonInteractive
:
true
property
bool
interactive
:
true
property
var
_missionItem
:
object
property
var
_mapPolygon
:
object
.
surveyAreaPolygon
...
...
@@ -70,12 +71,12 @@ Item {
id
:
mapPolygonVisuals
mapControl
:
map
mapPolygon
:
_mapPolygon
interactive
:
polygonInteractive
&&
_missionItem
.
isCurrentItem
interactive
:
polygonInteractive
&&
_missionItem
.
isCurrentItem
&&
_root
.
interactive
borderWidth
:
1
borderColor
:
"
black
"
interiorColor
:
QGroundControl
.
globalPalette
.
surveyPolygonInterior
altColor
:
QGroundControl
.
globalPalette
.
surveyPolygonTerrainCollision
interiorOpacity
:
0.5
interiorOpacity
:
0.5
*
_root
.
opacity
}
// Full set of transects lines. Shown when item is selected.
...
...
@@ -87,6 +88,7 @@ Item {
line.width
:
2
path
:
_transectPoints
visible
:
_currentItem
opacity
:
_root
.
opacity
}
}
...
...
@@ -99,6 +101,7 @@ Item {
line.width
:
2
path
:
_showPartialEntryExit
?
[
_transectPoints
[
0
],
_transectPoints
[
1
]
]
:
[]
visible
:
_showPartialEntryExit
opacity
:
_root
.
opacity
}
}
Component
{
...
...
@@ -109,6 +112,7 @@ Item {
line.width
:
2
path
:
_showPartialEntryExit
?
[
_transectPoints
[
_lastPointIndex
-
1
],
_transectPoints
[
_lastPointIndex
]
]
:
[]
visible
:
_showPartialEntryExit
opacity
:
_root
.
opacity
}
}
...
...
@@ -122,11 +126,12 @@ Item {
z
:
QGroundControl
.
zOrderMapItems
coordinate
:
_missionItem
.
coordinate
visible
:
_missionItem
.
exitCoordinate
.
isValid
opacity
:
_root
.
opacity
sourceItem
:
MissionItemIndexLabel
{
index
:
_missionItem
.
sequenceNumber
checked
:
_missionItem
.
isCurrentItem
onClicked
:
_root
.
clicked
(
_missionItem
.
sequenceNumber
)
onClicked
:
if
(
_root
.
interactive
)
_root
.
clicked
(
_missionItem
.
sequenceNumber
)
}
}
}
...
...
@@ -139,6 +144,7 @@ Item {
toCoord
:
_transectPoints
[
_firstTrueTransectIndex
+
1
]
arrowPosition
:
1
visible
:
_currentItem
opacity
:
_root
.
opacity
}
}
...
...
@@ -150,6 +156,7 @@ Item {
toCoord
:
_transectPoints
[
nextTrueTransectIndex
+
1
]
arrowPosition
:
1
visible
:
_currentItem
&&
_transectCount
>
3
opacity
:
_root
.
opacity
property
int
nextTrueTransectIndex
:
_firstTrueTransectIndex
+
(
_hasTurnaround
?
4
:
2
)
}
...
...
@@ -163,6 +170,7 @@ Item {
toCoord
:
_transectPoints
[
_lastTrueTransectIndex
]
arrowPosition
:
3
visible
:
_currentItem
opacity
:
_root
.
opacity
}
}
...
...
@@ -174,6 +182,7 @@ Item {
toCoord
:
_transectPoints
[
prevTrueTransectIndex
]
arrowPosition
:
13
visible
:
_currentItem
&&
_transectCount
>
3
opacity
:
_root
.
opacity
property
int
prevTrueTransectIndex
:
_lastTrueTransectIndex
-
(
_hasTurnaround
?
4
:
2
)
}
...
...
@@ -189,11 +198,12 @@ Item {
z
:
QGroundControl
.
zOrderMapItems
coordinate
:
_missionItem
.
exitCoordinate
visible
:
_missionItem
.
exitCoordinate
.
isValid
opacity
:
_root
.
opacity
sourceItem
:
MissionItemIndexLabel
{
index
:
_missionItem
.
lastSequenceNumber
checked
:
_missionItem
.
isCurrentItem
onClicked
:
_root
.
clicked
(
_missionItem
.
sequenceNumber
)
onClicked
:
if
(
_root
.
interactive
)
_root
.
clicked
(
_missionItem
.
sequenceNumber
)
}
}
}
...
...
src/QGCApplication.h
View file @
f7be8bff
...
...
@@ -11,7 +11,6 @@
#include
<QApplication>
#include
<QTimer>
#include
<QQmlApplicationEngine>
#include
<QElapsedTimer>
#include
<QMap>
#include
<QSet>
...
...
@@ -38,6 +37,7 @@
#endif
// Work around circular header includes
class
QQmlApplicationEngine
;
class
QGCSingleton
;
class
QGCToolbox
;
class
QGCFileDownload
;
...
...
src/QmlControls/AppMessages.qml
View file @
f7be8bff
...
...
@@ -11,6 +11,7 @@ import QtQuick 2.3
import
QtQuick
.
Controls
1.2
import
QtQuick
.
Controls
.
Styles
1.4
import
QtQuick
.
Dialogs
1.2
import
QtQuick
.
Layouts
1.12
import
QGroundControl
1.0
import
QGroundControl
.
Palette
1.0
...
...
@@ -29,35 +30,71 @@ Item {
id
:
filtersDialogComponent
QGCViewDialog
{
QGCFlickable
{
anchors.fill
:
parent
anchors.fill
:
parent
contentHeight
:
categoryColumn
.
height
clip
:
true
Column
{
id
:
categoryColumn
spacing
:
ScreenTools
.
defaultFontPixelHeight
/
2
QGCButton
{
text
:
qsTr
(
"
Clear All
"
)
onClicked
:
{
var
logCats
=
QGroundControl
.
loggingCategories
()
for
(
var
i
=
0
;
i
<
logCats
.
length
;
i
++
)
{
QGroundControl
.
setCategoryLoggingOn
(
logCats
[
i
],
false
)
}
QGroundControl
.
updateLoggingFilterRules
()
categoryRepeater
.
model
=
undefined
categoryRepeater
.
model
=
QGroundControl
.
loggingCategories
()
ColumnLayout
{
anchors.fill
:
parent
RowLayout
{
spacing
:
ScreenTools
.
defaultFontPixelHeight
/
2
Layout.alignment
:
Qt
.
AlignVCenter
Layout.fillHeight
:
true
Layout.fillWidth
:
true
QGCLabel
{
text
:
qsTr
(
"
Search:
"
)
}
QGCTextField
{
id
:
searchText
text
:
""
Layout.fillWidth
:
true
enabled
:
true
}
QGCButton
{
text
:
qsTr
(
"
Clear
"
)
onClicked
:
searchText
.
text
=
""
}
}
Repeater
{
id
:
categoryRepeater
model
:
QGroundControl
.
loggingCategories
()
QGCCheckBox
{
text
:
modelData
checked
:
QGroundControl
.
categoryLoggingOn
(
modelData
)
onClicked
:
{
QGroundControl
.
setCategoryLoggingOn
(
modelData
,
checked
)
Row
{
spacing
:
ScreenTools
.
defaultFontPixelHeight
/
2
QGCButton
{
text
:
qsTr
(
"
Clear All
"
)
onClicked
:
categoryRepeater
.
setAllLogs
(
false
)
}
}
Column
{
id
:
categoryColumn
spacing
:
ScreenTools
.
defaultFontPixelHeight
/
2
Repeater
{
id
:
categoryRepeater
model
:
QGroundControl
.
loggingCategories
()
function
setAllLogs
(
value
)
{
var
logCategories
=
QGroundControl
.
loggingCategories
()
for
(
var
category
of
logCategories
)
{
QGroundControl
.
setCategoryLoggingOn
(
category
,
value
)
}
QGroundControl
.
updateLoggingFilterRules
()
// Update model for repeater
categoryRepeater
.
model
=
undefined
categoryRepeater
.
model
=
QGroundControl
.
loggingCategories
()
}
QGCCheckBox
{
text
:
modelData
visible
:
searchText
.
text
?
text
.
match
(
`(
${
searchText
.
text
}
)`
,
"
i
"
)
:
true
checked
:
QGroundControl
.
categoryLoggingOn
(
modelData
)
onClicked
:
{
QGroundControl
.
setCategoryLoggingOn
(
modelData
,
checked
)
QGroundControl
.
updateLoggingFilterRules
()
}
}
}
}
...
...
src/VideoManager/VideoManager.cc
View file @
f7be8bff
This diff is collapsed.
Click to expand it.
src/VideoManager/VideoManager.h
View file @
f7be8bff
...
...
@@ -49,8 +49,12 @@ public:
Q_PROPERTY
(
double
hfov
READ
hfov
NOTIFY
aspectRatioChanged
)
Q_PROPERTY
(
double
thermalHfov
READ
thermalHfov
NOTIFY
aspectRatioChanged
)
Q_PROPERTY
(
bool
autoStreamConfigured
READ
autoStreamConfigured
NOTIFY
autoStreamConfiguredChanged
)
Q_PROPERTY
(
bool
hasThermal
READ
hasThermal
NOTIFY
aspectRatio
Changed
)
Q_PROPERTY
(
bool
hasThermal
READ
hasThermal
NOTIFY
decoding
Changed
)
Q_PROPERTY
(
QString
imageFile
READ
imageFile
NOTIFY
imageFileChanged
)
Q_PROPERTY
(
bool
streaming
READ
streaming
NOTIFY
streamingChanged
)
Q_PROPERTY
(
bool
decoding
READ
decoding
NOTIFY
decodingChanged
)
Q_PROPERTY
(
bool
recording
READ
recording
NOTIFY
recordingChanged
)
Q_PROPERTY
(
QSize
videoSize
READ
videoSize
NOTIFY
videoSizeChanged
)
virtual
bool
hasVideo
();
virtual
bool
isGStreamer
();
...
...
@@ -65,9 +69,27 @@ public:
virtual
bool
hasThermal
();
virtual
QString
imageFile
();
bool
streaming
(
void
)
{
return
_streaming
;
}
virtual
VideoReceiver
*
videoReceiver
()
{
return
_videoReceiver
;
}
virtual
VideoReceiver
*
thermalVideoReceiver
()
{
return
_thermalVideoReceiver
;
}
bool
decoding
(
void
)
{
return
_decoding
;
}
bool
recording
(
void
)
{
return
_recording
;
}
QSize
videoSize
(
void
)
{
const
quint32
size
=
_videoSize
;
return
QSize
((
size
>>
16
)
&
0xFFFF
,
size
&
0xFFFF
);
}
// FIXME: AV: they should be removed after finishing multiple video stream support
// new arcitecture does not assume direct access to video receiver from QML side, even if it works for now
virtual
VideoReceiver
*
videoReceiver
()
{
return
_videoReceiver
[
0
];
}
virtual
VideoReceiver
*
thermalVideoReceiver
()
{
return
_videoReceiver
[
1
];
}
#if defined(QGC_DISABLE_UVC)
virtual
bool
uvcEnabled
()
{
return
false
;
}
...
...
@@ -99,6 +121,11 @@ signals:
void
aspectRatioChanged
();
void
autoStreamConfiguredChanged
();
void
imageFileChanged
();
void
streamingChanged
();
void
decodingChanged
();
void
recordingChanged
();
void
recordingStarted
();
void
videoSizeChanged
();
protected
slots
:
void
_videoSourceChanged
();
...
...
@@ -115,31 +142,37 @@ protected:
friend
class
FinishVideoInitialization
;
void
_initVideo
();
void
_updateSettings
();
void
_setVideoUri
(
const
QString
&
uri
);
void
_setThermalVideoUri
(
const
QString
&
uri
);
bool
_updateSettings
(
unsigned
id
);
bool
_updateVideoUri
(
unsigned
id
,
const
QString
&
uri
);
void
_cleanupOldVideos
();
void
_restartVideo
();
void
_streamingChanged
();
void
_recordingStarted
();
void
_recordingChanged
();
void
_screenshotComplete
();
void
_restartAllVideos
();
void
_restartVideo
(
unsigned
id
);
void
_startReceiver
(
unsigned
id
);
void
_stopReceiver
(
unsigned
id
);
protected:
QString
_videoFile
;
QString
_imageFile
;
SubtitleWriter
_subtitleWriter
;
bool
_isTaisync
=
false
;
VideoReceiver
*
_videoReceiver
=
nullptr
;
VideoReceiver
*
_thermalVideoReceiver
=
nullptr
;
void
*
_videoSink
=
nullptr
;
void
*
_thermalVideoSink
=
nullptr
;
VideoSettings
*
_videoSettings
=
nullptr
;
QString
_videoUri
;
QString
_thermalVideoUri
;
QString
_videoSourceID
;
bool
_fullScreen
=
false
;
Vehicle
*
_activeVehicle
=
nullptr
;
QString
_videoFile
;
QString
_imageFile
;
SubtitleWriter
_subtitleWriter
;
bool
_isTaisync
=
false
;
VideoReceiver
*
_videoReceiver
[
2
]
=
{
nullptr
,
nullptr
};
void
*
_videoSink
[
2
]
=
{
nullptr
,
nullptr
};
QString
_videoUri
[
2
];
// FIXME: AV: _videoStarted seems to be access from 3 different threads, from time to time
// 1) Video Receiver thread
// 2) Video Manager/main app thread
// 3) Qt rendering thread (during video sink creation process which should happen in this thread)
// It works for now but...
bool
_videoStarted
[
2
]
=
{
false
,
false
};
bool
_lowLatencyStreaming
[
2
]
=
{
false
,
false
};
QAtomicInteger
<
bool
>
_streaming
=
false
;
QAtomicInteger
<
bool
>
_decoding
=
false
;
QAtomicInteger
<
bool
>
_recording
=
false
;
QAtomicInteger
<
quint32
>
_videoSize
=
0
;
VideoSettings
*
_videoSettings
=
nullptr
;
QString
_videoSourceID
;
bool
_fullScreen
=
false
;
Vehicle
*
_activeVehicle
=
nullptr
;
};
#endif
src/VideoReceiver/GStreamer.cc
View file @
f7be8bff
...
...
@@ -105,9 +105,28 @@ static void qgcputenv(const QString& key, const QString& root, const QString& pa
}
#endif
static
void
blacklist
()
{
GstRegistry
*
reg
;
if
((
reg
=
gst_registry_get
())
==
nullptr
)
{
return
;
}
GstPluginFeature
*
plugin
;
if
((
plugin
=
gst_registry_lookup_feature
(
reg
,
"bcmdec"
))
!=
nullptr
)
{
qCCritical
(
GStreamerLog
)
<<
"Disable bcmdec"
;
gst_plugin_feature_set_rank
(
plugin
,
GST_RANK_NONE
);
}
}
void
GStreamer
::
initialize
(
int
argc
,
char
*
argv
[],
int
debuglevel
)
{
qRegisterMetaType
<
VideoReceiver
::
STATUS
>
(
"STATUS"
);
#ifdef Q_OS_MAC
#ifdef QGC_INSTALL_RELEASE
QString
currentDir
=
QCoreApplication
::
applicationDirPath
();
...
...
@@ -171,6 +190,8 @@ GStreamer::initialize(int argc, char* argv[], int debuglevel)
gst_ios_post_init
();
#endif
blacklist
();
/* the plugin must be loaded before loading the qml file to register the
* GstGLVideoItem qml item
* FIXME Add a QQmlExtensionPlugin into qmlglsink to register GstGLVideoItem
...
...
src/VideoReceiver/GstVideoReceiver.cc
View file @
f7be8bff
This diff is collapsed.
Click to expand it.
src/VideoReceiver/GstVideoReceiver.h
View file @
f7be8bff
...
...
@@ -89,7 +89,7 @@ public:
~
GstVideoReceiver
(
void
);
public
slots
:
virtual
void
start
(
const
QString
&
uri
,
unsigned
timeout
);
virtual
void
start
(
const
QString
&
uri
,
unsigned
timeout
,
int
buffer
=
0
);
virtual
void
stop
(
void
);
virtual
void
startDecoding
(
void
*
sink
);
virtual
void
stopDecoding
(
void
);
...
...
@@ -102,11 +102,6 @@ protected slots:
virtual
void
_handleEOS
(
void
);
protected:
void
_setVideoSize
(
const
QSize
&
size
)
{
_videoSize
=
((
quint32
)
size
.
width
()
<<
16
)
|
(
quint32
)
size
.
height
();
emit
videoSizeChanged
();
}
virtual
GstElement
*
_makeSource
(
const
QString
&
uri
);
virtual
GstElement
*
_makeDecoder
(
GstCaps
*
caps
,
GstElement
*
videoSink
);
virtual
GstElement
*
_makeFileSink
(
const
QString
&
videoFile
,
FILE_FORMAT
format
);
...
...
@@ -118,16 +113,19 @@ protected:
virtual
void
_noteTeeFrame
(
void
);
virtual
void
_noteVideoSinkFrame
(
void
);
virtual
void
_noteEndOfStream
(
void
);
virtual
void
_unlinkBranch
(
GstElement
*
from
);
virtual
bool
_unlinkBranch
(
GstElement
*
from
);
virtual
void
_shutdownDecodingBranch
(
void
);
virtual
void
_shutdownRecordingBranch
(
void
);
private:
bool
_needDispatch
(
void
);
void
_dispatchSignal
(
std
::
function
<
void
()
>
emitter
);
static
gboolean
_onBusMessage
(
GstBus
*
bus
,
GstMessage
*
message
,
gpointer
user_data
);
static
void
_onNewPad
(
GstElement
*
element
,
GstPad
*
pad
,
gpointer
data
);
static
void
_wrapWithGhostPad
(
GstElement
*
element
,
GstPad
*
pad
,
gpointer
data
);
static
void
_linkPad
WithOptionalBuffer
(
GstElement
*
element
,
GstPad
*
pad
,
gpointer
data
);
static
void
_linkPad
(
GstElement
*
element
,
GstPad
*
pad
,
gpointer
data
);
static
gboolean
_padProbe
(
GstElement
*
element
,
GstPad
*
pad
,
gpointer
user_data
);
static
gboolean
_filterParserCaps
(
GstElement
*
bin
,
GstPad
*
pad
,
GstElement
*
element
,
GstQuery
*
query
,
gpointer
data
);
static
gboolean
_autoplugQueryCaps
(
GstElement
*
bin
,
GstPad
*
pad
,
GstElement
*
element
,
GstQuery
*
query
,
gpointer
data
);
static
gboolean
_autoplugQueryContext
(
GstElement
*
bin
,
GstPad
*
pad
,
GstElement
*
element
,
GstQuery
*
query
,
gpointer
data
);
static
gboolean
_autoplugQuery
(
GstElement
*
bin
,
GstPad
*
pad
,
GstElement
*
element
,
GstQuery
*
query
,
gpointer
data
);
...
...
@@ -136,6 +134,9 @@ private:
static
GstPadProbeReturn
_eosProbe
(
GstPad
*
pad
,
GstPadProbeInfo
*
info
,
gpointer
user_data
);
static
GstPadProbeReturn
_keyframeWatch
(
GstPad
*
pad
,
GstPadProbeInfo
*
info
,
gpointer
user_data
);
bool
_streaming
;
bool
_decoding
;
bool
_recording
;
bool
_removingDecoder
;
bool
_removingRecorder
;
GstElement
*
_source
;
...
...
@@ -157,10 +158,12 @@ private:
//-- RTSP UDP reconnect timeout
uint64_t
_udpReconnect_us
;
QString
_uri
;
unsigned
_timeout
;
int
_buffer
;
Worker
_
api
Handler
;
Worker
_
notificationHandler
;
Worker
_
slot
Handler
;
uint32_t
_
signalDepth
;
bool
_endOfStream
;
...
...
src/VideoReceiver/README.md
View file @
f7be8bff
...
...
@@ -39,7 +39,7 @@ gst-launch-1.0 videotestsrc ! video/x-raw,width=640,height=480 ! videoconvert !
On the receiving end, if you want to test it from the command line, you can use something like:
```
gst-launch-1.0 udpsrc port=5600 caps='application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)H264' ! rtph264depay ! h264parse ! avdec_h264 ! autovideosink fps-update-interval=1000 sync=false
gst-launch-1.0 udpsrc port=5600 caps='application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)H264' !
rtpjitterbuffer !
rtph264depay ! h264parse ! avdec_h264 ! autovideosink fps-update-interval=1000 sync=false
```
### Additional Protocols
...
...
src/VideoReceiver/VideoReceiver.h
View file @
f7be8bff
...
...
@@ -17,9 +17,6 @@
#include
<QObject>
#include
<QSize>
#include
<QQuickItem>
#include
<atomic>
class
VideoReceiver
:
public
QObject
{
...
...
@@ -28,10 +25,6 @@ class VideoReceiver : public QObject
public:
explicit
VideoReceiver
(
QObject
*
parent
=
nullptr
)
:
QObject
(
parent
)
,
_streaming
(
false
)
,
_decoding
(
false
)
,
_recording
(
false
)
,
_videoSize
(
0
)
{}
virtual
~
VideoReceiver
(
void
)
{}
...
...
@@ -44,50 +37,42 @@ public:
FILE_FORMAT_MAX
}
FILE_FORMAT
;
Q_PROPERTY
(
bool
streaming
READ
streaming
NOTIFY
streamingChanged
)
Q_PROPERTY
(
bool
decoding
READ
decoding
NOTIFY
decodingChanged
)
Q_PROPERTY
(
bool
recording
READ
recording
NOTIFY
recordingChanged
)
Q_PROPERTY
(
QSize
videoSize
READ
videoSize
NOTIFY
videoSizeChanged
)
bool
streaming
(
void
)
{
return
_streaming
;
}
bool
decoding
(
void
)
{
return
_decoding
;
}
bool
recording
(
void
)
{
return
_recording
;
}
typedef
enum
{
STATUS_OK
=
0
,
STATUS_FAIL
,
STATUS_INVALID_STATE
,
STATUS_INVALID_URL
,
STATUS_NOT_IMPLEMENTED
}
STATUS
;
QSize
videoSize
(
void
)
{
const
quint32
size
=
_videoSize
;
return
QSize
((
size
>>
16
)
&
0xFFFF
,
size
&
0xFFFF
);
}
Q_ENUM
(
STATUS
)
signals:
void
timeout
(
void
);
void
streamingChanged
(
void
);
void
decodingChanged
(
void
);
void
recordingChanged
(
void
);
void
streamingChanged
(
bool
active
);
void
decodingChanged
(
bool
active
);
void
recordingChanged
(
bool
active
);
void
recordingStarted
(
void
);
void
videoSizeChanged
(
void
);
void
screenshotComplete
(
void
);
void
videoSizeChanged
(
QSize
size
);
void
onStartComplete
(
STATUS
status
);
void
onStopComplete
(
STATUS
status
);
void
onStartDecodingComplete
(
STATUS
status
);
void
onStopDecodingComplete
(
STATUS
status
);
void
onStartRecordingComplete
(
STATUS
status
);
void
onStopRecordingComplete
(
STATUS
status
);
void
onTakeScreenshotComplete
(
STATUS
status
);
public
slots
:
virtual
void
start
(
const
QString
&
uri
,
unsigned
timeout
)
=
0
;
// buffer:
// -1 - disable buffer and video sync
// 0 - default buffer length
// N - buffer length, ms
virtual
void
start
(
const
QString
&
uri
,
unsigned
timeout
,
int
buffer
=
0
)
=
0
;
virtual
void
stop
(
void
)
=
0
;
virtual
void
startDecoding
(
void
*
sink
)
=
0
;
virtual
void
stopDecoding
(
void
)
=
0
;
virtual
void
startRecording
(
const
QString
&
videoFile
,
FILE_FORMAT
format
)
=
0
;
virtual
void
stopRecording
(
void
)
=
0
;
virtual
void
takeScreenshot
(
const
QString
&
imageFile
)
=
0
;
protected:
std
::
atomic
<
bool
>
_streaming
;
std
::
atomic
<
bool
>
_decoding
;
std
::
atomic
<
bool
>
_recording
;
std
::
atomic
<
quint32
>
_videoSize
;
};
src/api/QGCCorePlugin.cc
View file @
f7be8bff
...
...
@@ -485,6 +485,15 @@ void* QGCCorePlugin::createVideoSink(QObject* parent, QQuickItem* widget)
#endif
}
void
QGCCorePlugin
::
releaseVideoSink
(
void
*
sink
)
{
#if defined(QGC_GST_STREAMING)
GStreamer
::
releaseVideoSink
(
sink
);
#else
Q_UNUSED
(
sink
)
#endif
}
bool
QGCCorePlugin
::
guidedActionsControllerLogging
()
const
{
return
GuidedActionsControllerLog
().
isDebugEnabled
();
...
...
src/api/QGCCorePlugin.h
View file @
f7be8bff
...
...
@@ -119,6 +119,8 @@ public:
virtual
VideoReceiver
*
createVideoReceiver
(
QObject
*
parent
);
/// Allows the plugin to override the creation of VideoSink.
virtual
void
*
createVideoSink
(
QObject
*
parent
,
QQuickItem
*
widget
);
/// Allows the plugin to override the release of VideoSink.
virtual
void
releaseVideoSink
(
void
*
sink
);
/// Allows the plugin to see all mavlink traffic to a vehicle
/// @return true: Allow vehicle to continue processing, false: Vehicle should not process message
...
...
Prev
1
2
Next
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new 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