diff --git a/qgroundcontrol.qrc b/qgroundcontrol.qrc
index 5a743ba..40388bb 100644
--- a/qgroundcontrol.qrc
+++ b/qgroundcontrol.qrc
@@ -179,6 +179,7 @@
src/VehicleSetup/VehicleSummary.qml
src/FlightDisplay/VirtualJoystick.qml
src/FlightMap/Widgets/CameraPageWidget.qml
+ src/FlightMap/Widgets/VideoPageWidget.qml
src/FlightMap/Widgets/ValuePageWidget.qml
src/FlightMap/Widgets/HealthPageWidget.qml
src/FlightMap/Widgets/VibrationPageWidget.qml
diff --git a/src/FlightDisplay/FlightDisplayView.qml b/src/FlightDisplay/FlightDisplayView.qml
index 3c87dc1..e2ff0b2 100644
--- a/src/FlightDisplay/FlightDisplayView.qml
+++ b/src/FlightDisplay/FlightDisplayView.qml
@@ -43,8 +43,6 @@ QGCView {
property var _geoFenceController: _planMasterController.geoFenceController
property var _rallyPointController: _planMasterController.rallyPointController
property var _activeVehicle: QGroundControl.multiVehicleManager.activeVehicle
- property var _videoReceiver: QGroundControl.videoManager.videoReceiver
- property bool _recordingVideo: _videoReceiver && _videoReceiver.recording
property bool _mainIsMap: QGroundControl.videoManager.hasVideo ? QGroundControl.loadBoolGlobalSetting(_mainIsMapKey, true) : true
property bool _isPipVisible: QGroundControl.videoManager.hasVideo ? QGroundControl.loadBoolGlobalSetting(_PIPVisibleKey, true) : false
property real _savedZoomLevel: 0
@@ -346,63 +344,6 @@ QGCView {
property var qgcView: root
}
- // Button to start/stop video recording
- Item {
- z: _flightVideoPipControl.z + 1
- anchors.margins: ScreenTools.defaultFontPixelHeight / 2
- anchors.bottom: _flightVideo.bottom
- anchors.right: _flightVideo.right
- height: ScreenTools.defaultFontPixelHeight * 2
- width: height
- visible: _videoReceiver && _videoReceiver.videoRunning && QGroundControl.settingsManager.videoSettings.showRecControl.rawValue && _flightVideo.visible && !_isCamera && !QGroundControl.videoManager.fullScreen
- opacity: 0.75
-
- readonly property string recordBtnBackground: "BackgroundName"
-
- Rectangle {
- id: recordBtnBackground
- anchors.top: parent.top
- anchors.bottom: parent.bottom
- width: height
- radius: _recordingVideo ? 0 : height
- color: "red"
-
- SequentialAnimation on visible {
- running: _recordingVideo
- loops: Animation.Infinite
- PropertyAnimation { to: false; duration: 1000 }
- PropertyAnimation { to: true; duration: 1000 }
- }
- }
-
- QGCColoredImage {
- anchors.top: parent.top
- anchors.bottom: parent.bottom
- anchors.horizontalCenter: parent.horizontalCenter
- width: height * 0.625
- sourceSize.width: width
- source: "/qmlimages/CameraIcon.svg"
- visible: recordBtnBackground.visible
- fillMode: Image.PreserveAspectFit
- color: "white"
- }
-
- MouseArea {
- anchors.fill: parent
- onClicked: {
- if (_videoReceiver) {
- if (_recordingVideo) {
- _videoReceiver.stopRecording()
- // reset blinking animation
- recordBtnBackground.visible = true
- } else {
- _videoReceiver.startRecording()
- }
- }
- }
- }
- }
-
MultiVehicleList {
anchors.margins: _margins
anchors.top: singleMultiSelector.bottom
diff --git a/src/FlightDisplay/FlightDisplayViewVideo.qml b/src/FlightDisplay/FlightDisplayViewVideo.qml
index a3d39fd..f9673ea 100644
--- a/src/FlightDisplay/FlightDisplayViewVideo.qml
+++ b/src/FlightDisplay/FlightDisplayViewVideo.qml
@@ -34,7 +34,7 @@ Item {
color: Qt.rgba(0,0,0,0.75)
visible: !(_videoReceiver && _videoReceiver.videoRunning)
QGCLabel {
- text: qsTr("WAITING FOR VIDEO")
+ text: _videoReceiver && _videoReceiver.enabled ? qsTr("WAITING FOR VIDEO") : qsTr("VIDEO DISABLED")
font.family: ScreenTools.demiboldFontFamily
color: "white"
font.pointSize: _mainIsMap ? ScreenTools.smallFontPointSize : ScreenTools.largeFontPointSize
diff --git a/src/FlightMap/Widgets/VideoPageWidget.qml b/src/FlightMap/Widgets/VideoPageWidget.qml
new file mode 100644
index 0000000..a58fb34
--- /dev/null
+++ b/src/FlightMap/Widgets/VideoPageWidget.qml
@@ -0,0 +1,128 @@
+/****************************************************************************
+ *
+ * (c) 2009-2016 QGROUNDCONTROL PROJECT
+ *
+ * QGroundControl is licensed according to the terms in the file
+ * COPYING.md in the root of the source code directory.
+ *
+ ****************************************************************************/
+
+import QtQuick 2.4
+import QtPositioning 5.2
+import QtQuick.Layouts 1.2
+import QtQuick.Controls 1.4
+import QtQuick.Dialogs 1.2
+import QtQuick.Controls.Styles 1.4
+import QtGraphicalEffects 1.0
+
+import QGroundControl 1.0
+import QGroundControl.ScreenTools 1.0
+import QGroundControl.Controls 1.0
+import QGroundControl.Palette 1.0
+import QGroundControl.Vehicle 1.0
+import QGroundControl.Controllers 1.0
+import QGroundControl.FactSystem 1.0
+import QGroundControl.FactControls 1.0
+
+/// Video streaming page for Instrument Panel PageView
+Item {
+ width: pageWidth
+ height: videoGrid.height + (ScreenTools.defaultFontPixelHeight * 2)
+ anchors.margins: ScreenTools.defaultFontPixelWidth * 2
+ anchors.centerIn: parent
+
+ property var _activeVehicle: QGroundControl.multiVehicleManager.activeVehicle
+ property bool _communicationLost: _activeVehicle ? _activeVehicle.connectionLost : false
+ property var _videoReceiver: QGroundControl.videoManager.videoReceiver
+ property bool _recordingVideo: _videoReceiver && _videoReceiver.recording
+ property bool _videoRunning: _videoReceiver && _videoReceiver.videoRunning
+
+ QGCPalette { id:qgcPal; colorGroupEnabled: parent.enabled }
+
+ GridLayout {
+ id: videoGrid
+ columns: 2
+ columnSpacing: ScreenTools.defaultFontPixelWidth * 2
+ rowSpacing: ScreenTools.defaultFontPixelHeight
+ anchors.centerIn: parent
+ QGCLabel {
+ text: qsTr("Enable Stream")
+ font.pointSize: ScreenTools.smallFontPointSize
+ }
+ Switch {
+ checked: _videoRunning
+ enabled: _activeVehicle
+ onClicked: {
+ if(checked) {
+ _videoReceiver.start()
+ } else {
+ _videoReceiver.stop()
+ }
+ }
+ style: SwitchStyle {
+ groove: Rectangle {
+ implicitWidth: ScreenTools.defaultFontPixelWidth * 6
+ implicitHeight: ScreenTools.defaultFontPixelHeight
+ color: control.checked ? qgcPal.colorGreen : qgcPal.colorGrey
+ radius: 3
+ border.color: qgcPal.button
+ border.width: 1
+ }
+ }
+ }
+ QGCLabel {
+ text: qsTr("Stream Recording")
+ font.pointSize: ScreenTools.smallFontPointSize
+ visible: QGroundControl.settingsManager.videoSettings.showRecControl.rawValue
+ }
+ // Button to start/stop video recording
+ Item {
+ anchors.margins: ScreenTools.defaultFontPixelHeight / 2
+ height: ScreenTools.defaultFontPixelHeight * 2
+ width: height
+ Layout.alignment: Qt.AlignHCenter
+ visible: QGroundControl.settingsManager.videoSettings.showRecControl.rawValue
+
+ Rectangle {
+ id: recordBtnBackground
+ anchors.top: parent.top
+ anchors.bottom: parent.bottom
+ width: height
+ radius: _recordingVideo ? 0 : height
+ color: _videoRunning ? "red" : "gray"
+ SequentialAnimation on opacity {
+ running: _recordingVideo
+ loops: Animation.Infinite
+ PropertyAnimation { to: 0.5; duration: 500 }
+ PropertyAnimation { to: 1.0; duration: 500 }
+ }
+ }
+
+ QGCColoredImage {
+ anchors.top: parent.top
+ anchors.bottom: parent.bottom
+ anchors.horizontalCenter: parent.horizontalCenter
+ width: height * 0.625
+ sourceSize.width: width
+ source: "/qmlimages/CameraIcon.svg"
+ visible: recordBtnBackground.visible
+ fillMode: Image.PreserveAspectFit
+ color: "white"
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ enabled: _videoRunning
+ onClicked: {
+ if (_recordingVideo) {
+ _videoReceiver.stopRecording()
+ // reset blinking animation
+ recordBtnBackground.opacity = 1
+ } else {
+ _videoReceiver.startRecording()
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/QmlControls/PageView.qml b/src/QmlControls/PageView.qml
index 8019638..6dfdc6c 100644
--- a/src/QmlControls/PageView.qml
+++ b/src/QmlControls/PageView.qml
@@ -38,7 +38,7 @@ Rectangle {
width: parent.height -(_margins * 2)
sourceSize.width: width
fillMode: Image.PreserveAspectFit
- visible: pageWidgetLoader.item.showSettingsIcon
+ visible: pageWidgetLoader.item ? (pageWidgetLoader.item.showSettingsIcon ? pageWidgetLoader.item.showSettingsIcon : false) : false
QGCMouseArea {
fillItem: parent
diff --git a/src/VideoStreaming/VideoReceiver.cc b/src/VideoStreaming/VideoReceiver.cc
index 5091f21..7c79b98 100644
--- a/src/VideoStreaming/VideoReceiver.cc
+++ b/src/VideoStreaming/VideoReceiver.cc
@@ -67,6 +67,7 @@ VideoReceiver::VideoReceiver(QObject* parent)
, _videoSurface(NULL)
, _videoRunning(false)
, _showFullScreen(false)
+ , _enabled(true)
{
_videoSurface = new VideoSurface;
#if defined(QGC_GST_STREAMING)
@@ -147,8 +148,10 @@ VideoReceiver::_connected()
_timer.stop();
_socket->deleteLater();
_socket = NULL;
- _serverPresent = true;
- start();
+ if(_enabled) {
+ _serverPresent = true;
+ start();
+ }
}
#endif
@@ -161,7 +164,9 @@ VideoReceiver::_socketError(QAbstractSocket::SocketError socketError)
_socket->deleteLater();
_socket = NULL;
//-- Try again in 5 seconds
- _timer.start(5000);
+ if(_enabled) {
+ _timer.start(5000);
+ }
}
#endif
@@ -175,18 +180,19 @@ VideoReceiver::_timeout()
delete _socket;
_socket = NULL;
}
- //-- RTSP will try to connect to the server. If it cannot connect,
- // it will simply give up and never try again. Instead, we keep
- // attempting a connection on this timer. Once a connection is
- // found to be working, only then we actually start the stream.
- QUrl url(_uri);
- _socket = new QTcpSocket;
- _socket->setProxy(QNetworkProxy::NoProxy);
- connect(_socket, static_cast(&QTcpSocket::error), this, &VideoReceiver::_socketError);
- connect(_socket, &QTcpSocket::connected, this, &VideoReceiver::_connected);
- //qCDebug(VideoReceiverLog) << "Trying to connect to:" << url.host() << url.port();
- _socket->connectToHost(url.host(), url.port());
- _timer.start(5000);
+ if(_enabled) {
+ //-- RTSP will try to connect to the server. If it cannot connect,
+ // it will simply give up and never try again. Instead, we keep
+ // attempting a connection on this timer. Once a connection is
+ // found to be working, only then we actually start the stream.
+ QUrl url(_uri);
+ _socket = new QTcpSocket;
+ _socket->setProxy(QNetworkProxy::NoProxy);
+ connect(_socket, static_cast(&QTcpSocket::error), this, &VideoReceiver::_socketError);
+ connect(_socket, &QTcpSocket::connected, this, &VideoReceiver::_connected);
+ _socket->connectToHost(url.host(), url.port());
+ _timer.start(5000);
+ }
}
#endif
@@ -203,6 +209,8 @@ VideoReceiver::_timeout()
void
VideoReceiver::start()
{
+ _enabled = true;
+ emit enabledChanged();
#if defined(QGC_GST_STREAMING)
qCDebug(VideoReceiverLog) << "start()";
@@ -416,6 +424,8 @@ VideoReceiver::start()
void
VideoReceiver::stop()
{
+ _enabled = false;
+ emit enabledChanged();
#if defined(QGC_GST_STREAMING)
qCDebug(VideoReceiverLog) << "stop()";
if(!_streaming) {
@@ -814,7 +824,7 @@ VideoReceiver::_updateTimer()
stop();
}
} else {
- if(!running() && !_uri.isEmpty()) {
+ if(!running() && !_uri.isEmpty() && _enabled) {
start();
}
}
diff --git a/src/VideoStreaming/VideoReceiver.h b/src/VideoStreaming/VideoReceiver.h
index 7e7cfaf..b32cd7b 100644
--- a/src/VideoStreaming/VideoReceiver.h
+++ b/src/VideoStreaming/VideoReceiver.h
@@ -38,9 +38,10 @@ public:
Q_PROPERTY(bool recording READ recording NOTIFY recordingChanged)
#endif
Q_PROPERTY(VideoSurface* videoSurface READ videoSurface CONSTANT)
- Q_PROPERTY(bool videoRunning READ videoRunning NOTIFY videoRunningChanged)
- Q_PROPERTY(QString imageFile READ imageFile NOTIFY imageFileChanged)
- Q_PROPERTY(bool showFullScreen READ showFullScreen WRITE setShowFullScreen NOTIFY showFullScreenChanged)
+ Q_PROPERTY(bool videoRunning READ videoRunning NOTIFY videoRunningChanged)
+ Q_PROPERTY(QString imageFile READ imageFile NOTIFY imageFileChanged)
+ Q_PROPERTY(bool showFullScreen READ showFullScreen WRITE setShowFullScreen NOTIFY showFullScreenChanged)
+ Q_PROPERTY(bool enabled READ enabled NOTIFY enabledChanged)
explicit VideoReceiver(QObject* parent = 0);
~VideoReceiver();
@@ -57,6 +58,8 @@ public:
bool videoRunning () { return _videoRunning; }
QString imageFile () { return _imageFile; }
bool showFullScreen () { return _showFullScreen; }
+ bool enabled () { return _enabled; }
+
void grabImage (QString imageFile);
void setShowFullScreen (bool show) { _showFullScreen = show; emit showFullScreenChanged(); }
@@ -65,6 +68,7 @@ signals:
void videoRunningChanged ();
void imageFileChanged ();
void showFullScreenChanged ();
+ void enabledChanged ();
#if defined(QGC_GST_STREAMING)
void recordingChanged ();
void msgErrorReceived ();
@@ -136,6 +140,7 @@ private:
VideoSurface* _videoSurface;
bool _videoRunning;
bool _showFullScreen;
+ bool _enabled;
};
diff --git a/src/api/QGCCorePlugin.cc b/src/api/QGCCorePlugin.cc
index de2d76d..475b98a 100644
--- a/src/api/QGCCorePlugin.cc
+++ b/src/api/QGCCorePlugin.cc
@@ -39,6 +39,7 @@ public:
, defaultOptions (NULL)
, valuesPageWidgetInfo (NULL)
, cameraPageWidgetInfo (NULL)
+ , videoPageWidgetInfo (NULL)
, healthPageWidgetInfo (NULL)
, vibrationPageWidgetInfo (NULL)
{
@@ -80,6 +81,7 @@ public:
QmlComponentInfo* valuesPageWidgetInfo;
QmlComponentInfo* cameraPageWidgetInfo;
+ QmlComponentInfo* videoPageWidgetInfo;
QmlComponentInfo* healthPageWidgetInfo;
QmlComponentInfo* vibrationPageWidgetInfo;
QVariantList instrumentPageWidgetList;
@@ -148,13 +150,19 @@ QVariantList &QGCCorePlugin::settingsPages()
QVariantList& QGCCorePlugin::instrumentPages(void)
{
if (!_p->valuesPageWidgetInfo) {
- _p->valuesPageWidgetInfo = new QmlComponentInfo(tr("Values"), QUrl::fromUserInput("qrc:/qml/ValuePageWidget.qml"));
- _p->cameraPageWidgetInfo = new QmlComponentInfo(tr("Camera"), QUrl::fromUserInput("qrc:/qml/CameraPageWidget.qml"));
- _p->healthPageWidgetInfo = new QmlComponentInfo(tr("Health"), QUrl::fromUserInput("qrc:/qml/HealthPageWidget.qml"));
+ _p->valuesPageWidgetInfo = new QmlComponentInfo(tr("Values"), QUrl::fromUserInput("qrc:/qml/ValuePageWidget.qml"));
+ _p->cameraPageWidgetInfo = new QmlComponentInfo(tr("Camera"), QUrl::fromUserInput("qrc:/qml/CameraPageWidget.qml"));
+#if defined(QGC_GST_STREAMING)
+ _p->videoPageWidgetInfo = new QmlComponentInfo(tr("Video"), QUrl::fromUserInput("qrc:/qml/VideoPageWidget.qml"));
+#endif
+ _p->healthPageWidgetInfo = new QmlComponentInfo(tr("Health"), QUrl::fromUserInput("qrc:/qml/HealthPageWidget.qml"));
_p->vibrationPageWidgetInfo = new QmlComponentInfo(tr("Vibration"), QUrl::fromUserInput("qrc:/qml/VibrationPageWidget.qml"));
_p->instrumentPageWidgetList.append(QVariant::fromValue(_p->valuesPageWidgetInfo));
_p->instrumentPageWidgetList.append(QVariant::fromValue(_p->cameraPageWidgetInfo));
+#if defined(QGC_GST_STREAMING)
+ _p->instrumentPageWidgetList.append(QVariant::fromValue(_p->videoPageWidgetInfo));
+#endif
_p->instrumentPageWidgetList.append(QVariant::fromValue(_p->healthPageWidgetInfo));
_p->instrumentPageWidgetList.append(QVariant::fromValue(_p->vibrationPageWidgetInfo));
}