diff --git a/qgroundcontrol.qrc b/qgroundcontrol.qrc index 40388bb661e6786ff224f992f803b2bddda38f1d..8fccc74e16e2f4a7e24dbc7d3ed0c096ec67beef 100644 --- a/qgroundcontrol.qrc +++ b/qgroundcontrol.qrc @@ -92,6 +92,7 @@ src/QmlControls/QGCPipable.qml src/QmlControls/QGCRadioButton.qml src/QmlControls/QGCSlider.qml + src/QmlControls/QGCSwitch.qml src/QmlControls/QGCTextField.qml src/QmlControls/QGCToolBarButton.qml src/QmlControls/QGCView.qml diff --git a/src/FlightMap/Widgets/VideoPageWidget.qml b/src/FlightMap/Widgets/VideoPageWidget.qml index e27961beebe4c1b0836d6bc75cdd666985b7abdd..a0046ddfd888c9044dcedf5476b52ec44cd7b592 100644 --- a/src/FlightMap/Widgets/VideoPageWidget.qml +++ b/src/FlightMap/Widgets/VideoPageWidget.qml @@ -12,7 +12,6 @@ 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 @@ -46,12 +45,13 @@ Item { columnSpacing: ScreenTools.defaultFontPixelWidth * 2 rowSpacing: ScreenTools.defaultFontPixelHeight anchors.centerIn: parent + // Enable/Disable Video Streaming QGCLabel { text: qsTr("Enable Stream") font.pointSize: ScreenTools.smallFontPointSize } - Switch { - enabled: _streamingEnabled && _activeVehicle + QGCSwitch { + enabled: _streamingEnabled checked: QGroundControl.settingsManager.videoSettings.streamEnabled.rawValue onClicked: { if(checked) { @@ -62,19 +62,27 @@ Item { _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 + } + // Grid Lines + QGCLabel { + text: qsTr("Grid Lines") + font.pointSize: ScreenTools.smallFontPointSize + visible: QGroundControl.videoManager.isGStreamer && QGroundControl.settingsManager.videoSettings.gridLines.visible + } + QGCSwitch { + enabled: _streamingEnabled && _activeVehicle + checked: QGroundControl.settingsManager.videoSettings.gridLines.rawValue + visible: QGroundControl.videoManager.isGStreamer && QGroundControl.settingsManager.videoSettings.gridLines.visible + onClicked: { + if(checked) { + QGroundControl.settingsManager.videoSettings.gridLines.rawValue = 1 + } else { + QGroundControl.settingsManager.videoSettings.gridLines.rawValue = 0 } } } QGCLabel { - text: qsTr("Stream Recording") + text: _recordingVideo ? qsTr("Stop Recording") : qsTr("Record Stream") font.pointSize: ScreenTools.smallFontPointSize visible: QGroundControl.settingsManager.videoSettings.showRecControl.rawValue } diff --git a/src/QmlControls/QGCSwitch.qml b/src/QmlControls/QGCSwitch.qml new file mode 100644 index 0000000000000000000000000000000000000000..74da42b1306b40dca49bf8d1354fb5a39b589d23 --- /dev/null +++ b/src/QmlControls/QGCSwitch.qml @@ -0,0 +1,30 @@ +/**************************************************************************** + * + * (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.3 +import QtQuick.Controls 1.2 +import QtQuick.Controls.Styles 1.4 + +import QGroundControl.Palette 1.0 +import QGroundControl.ScreenTools 1.0 + +Switch { + id: _root + QGCPalette { id:qgcPal; colorGroupEnabled: true } + style: SwitchStyle { + groove: Rectangle { + implicitWidth: ScreenTools.defaultFontPixelWidth * 6 + implicitHeight: ScreenTools.defaultFontPixelHeight + color: (control.checked && control.enabled) ? qgcPal.colorGreen : qgcPal.colorGrey + radius: 3 + border.color: qgcPal.button + border.width: 1 + } + } +} diff --git a/src/QmlControls/QGroundControl.Controls.qmldir b/src/QmlControls/QGroundControl.Controls.qmldir index ad49c42db7e48ea25142897cd184e6ab7a540404..514aeb14a92752e1b45b73e6da27990a24106432 100644 --- a/src/QmlControls/QGroundControl.Controls.qmldir +++ b/src/QmlControls/QGroundControl.Controls.qmldir @@ -52,6 +52,7 @@ QGCMovableItem 1.0 QGCMovableItem.qml QGCPipable 1.0 QGCPipable.qml QGCRadioButton 1.0 QGCRadioButton.qml QGCSlider 1.0 QGCSlider.qml +QGCSwitch 1.0 QGCSwitch.qml QGCTextField 1.0 QGCTextField.qml QGCToolBarButton 1.0 QGCToolBarButton.qml QGCView 1.0 QGCView.qml diff --git a/src/Settings/Video.SettingsGroup.json b/src/Settings/Video.SettingsGroup.json index 172e393ddb2c91be7b63b338a62b3c38aff1f367..20ee46b381866722d25f8381900954497fad390c 100644 --- a/src/Settings/Video.SettingsGroup.json +++ b/src/Settings/Video.SettingsGroup.json @@ -101,5 +101,12 @@ "longDescription": "Start/Stop Video Stream.", "type": "bool", "defaultValue": true +}, +{ + "name": "DisableWhenDisarmed", + "shortDescription": "Video Stream Disnabled When Armed", + "longDescription": "Disable Video Stream when disarmed.", + "type": "bool", + "defaultValue": false } ] diff --git a/src/Settings/VideoSettings.cc b/src/Settings/VideoSettings.cc index 200f48accb24f38601761c5b6b1ea676e88828b8..cb6ab514f1eeca4f5250f42d4d82017caf65d53e 100644 --- a/src/Settings/VideoSettings.cc +++ b/src/Settings/VideoSettings.cc @@ -31,6 +31,7 @@ const char* VideoSettings::maxVideoSizeName = "MaxVideoSize"; const char* VideoSettings::enableStorageLimitName = "EnableStorageLimit"; const char* VideoSettings::rtspTimeoutName = "RtspTimeout"; const char* VideoSettings::streamEnabledName = "StreamEnabled"; +const char* VideoSettings::disableWhenDisarmedName ="DisableWhenDisarmed"; const char* VideoSettings::videoSourceNoVideo = "No Video Available"; const char* VideoSettings::videoDisabled = "Video Stream Disabled"; @@ -52,6 +53,7 @@ VideoSettings::VideoSettings(QObject* parent) , _enableStorageLimitFact(NULL) , _rtspTimeoutFact(NULL) , _streamEnabledFact(NULL) + , _disableWhenDisarmedFact(NULL) { QQmlEngine::setObjectOwnership(this, QQmlEngine::CppOwnership); qmlRegisterUncreatableType("QGroundControl.SettingsManager", 1, 0, "VideoSettings", "Reference only"); @@ -192,6 +194,14 @@ Fact* VideoSettings::streamEnabled(void) return _streamEnabledFact; } +Fact* VideoSettings::disableWhenDisarmed(void) +{ + if (!_disableWhenDisarmedFact) { + _disableWhenDisarmedFact = _createSettingsFact(disableWhenDisarmedName); + } + return _disableWhenDisarmedFact; +} + bool VideoSettings::streamConfigured(void) { #if !defined(QGC_GST_STREAMING) diff --git a/src/Settings/VideoSettings.h b/src/Settings/VideoSettings.h index ee3200038c7e5a42781d64e9693c77932c20a5b1..63b6840d165d5d110b478f0e34608c53f70dec5b 100644 --- a/src/Settings/VideoSettings.h +++ b/src/Settings/VideoSettings.h @@ -19,33 +19,35 @@ class VideoSettings : public SettingsGroup public: VideoSettings(QObject* parent = NULL); - Q_PROPERTY(Fact* videoSource READ videoSource CONSTANT) - Q_PROPERTY(Fact* udpPort READ udpPort CONSTANT) - Q_PROPERTY(Fact* tcpUrl READ tcpUrl CONSTANT) - Q_PROPERTY(Fact* rtspUrl READ rtspUrl CONSTANT) - Q_PROPERTY(Fact* aspectRatio READ aspectRatio CONSTANT) - Q_PROPERTY(Fact* gridLines READ gridLines CONSTANT) - Q_PROPERTY(Fact* showRecControl READ showRecControl CONSTANT) - Q_PROPERTY(Fact* recordingFormat READ recordingFormat CONSTANT) - Q_PROPERTY(Fact* maxVideoSize READ maxVideoSize CONSTANT) - Q_PROPERTY(Fact* enableStorageLimit READ enableStorageLimit CONSTANT) - Q_PROPERTY(Fact* rtspTimeout READ rtspTimeout CONSTANT) - Q_PROPERTY(Fact* streamEnabled READ streamEnabled CONSTANT) - Q_PROPERTY(bool streamConfigured READ streamConfigured NOTIFY streamConfiguredChanged) + Q_PROPERTY(Fact* videoSource READ videoSource CONSTANT) + Q_PROPERTY(Fact* udpPort READ udpPort CONSTANT) + Q_PROPERTY(Fact* tcpUrl READ tcpUrl CONSTANT) + Q_PROPERTY(Fact* rtspUrl READ rtspUrl CONSTANT) + Q_PROPERTY(Fact* aspectRatio READ aspectRatio CONSTANT) + Q_PROPERTY(Fact* gridLines READ gridLines CONSTANT) + Q_PROPERTY(Fact* showRecControl READ showRecControl CONSTANT) + Q_PROPERTY(Fact* recordingFormat READ recordingFormat CONSTANT) + Q_PROPERTY(Fact* maxVideoSize READ maxVideoSize CONSTANT) + Q_PROPERTY(Fact* enableStorageLimit READ enableStorageLimit CONSTANT) + Q_PROPERTY(Fact* rtspTimeout READ rtspTimeout CONSTANT) + Q_PROPERTY(Fact* streamEnabled READ streamEnabled CONSTANT) + Q_PROPERTY(Fact* disableWhenDisarmed READ disableWhenDisarmed CONSTANT) + Q_PROPERTY(bool streamConfigured READ streamConfigured NOTIFY streamConfiguredChanged) - Fact* videoSource (void); - Fact* udpPort (void); - Fact* rtspUrl (void); - Fact* tcpUrl (void); - Fact* aspectRatio (void); - Fact* gridLines (void); - Fact* showRecControl (void); - Fact* recordingFormat (void); - Fact* maxVideoSize (void); - Fact* enableStorageLimit(void); - Fact* rtspTimeout (void); - Fact* streamEnabled (void); - bool streamConfigured (void); + Fact* videoSource (void); + Fact* udpPort (void); + Fact* rtspUrl (void); + Fact* tcpUrl (void); + Fact* aspectRatio (void); + Fact* gridLines (void); + Fact* showRecControl (void); + Fact* recordingFormat (void); + Fact* maxVideoSize (void); + Fact* enableStorageLimit (void); + Fact* rtspTimeout (void); + Fact* streamEnabled (void); + Fact* disableWhenDisarmed (void); + bool streamConfigured (void); static const char* videoSettingsGroupName; @@ -61,6 +63,7 @@ public: static const char* enableStorageLimitName; static const char* rtspTimeoutName; static const char* streamEnabledName; + static const char* disableWhenDisarmedName; static const char* videoSourceNoVideo; static const char* videoDisabled; @@ -87,6 +90,7 @@ private: SettingsFact* _enableStorageLimitFact; SettingsFact* _rtspTimeoutFact; SettingsFact* _streamEnabledFact; + SettingsFact* _disableWhenDisarmedFact; }; #endif diff --git a/src/Vehicle/Vehicle.cc b/src/Vehicle/Vehicle.cc index 422637e5ab223974eaa81e8f4e09802195ee2dff..99b8ba000166ca52cc3cd746410f57b8f64476f2 100644 --- a/src/Vehicle/Vehicle.cc +++ b/src/Vehicle/Vehicle.cc @@ -33,6 +33,8 @@ #include "QGCCorePlugin.h" #include "ADSBVehicle.h" #include "QGCCameraManager.h" +#include "VideoReceiver.h" +#include "VideoManager.h" QGC_LOGGING_CATEGORY(VehicleLog, "VehicleLog") @@ -1121,6 +1123,11 @@ void Vehicle::_handleHeartbeat(mavlink_message_t& message) _clearCameraTriggerPoints(); } else { _mapTrajectoryStop(); + // Also handle Video Streaming + if(_settingsManager->videoSettings()->disableWhenDisarmed()->rawValue().toBool()) { + _settingsManager->videoSettings()->streamEnabled()->setRawValue(false); + qgcApp()->toolbox()->videoManager()->videoReceiver()->stop(); + } } } diff --git a/src/VideoStreaming/VideoReceiver.cc b/src/VideoStreaming/VideoReceiver.cc index 21695f76add83070db06e32e2e2c0e4f38fba473..341558bd1f57fb58ead5c6ff7de9e51ad2b88354 100644 --- a/src/VideoStreaming/VideoReceiver.cc +++ b/src/VideoStreaming/VideoReceiver.cc @@ -67,8 +67,10 @@ VideoReceiver::VideoReceiver(QObject* parent) , _videoSurface(NULL) , _videoRunning(false) , _showFullScreen(false) + , _videoSettings(NULL) { - _videoSurface = new VideoSurface; + _videoSurface = new VideoSurface; + _videoSettings = qgcApp()->toolbox()->settingsManager()->videoSettings(); #if defined(QGC_GST_STREAMING) _setVideoSink(_videoSurface->videoSink()); _timer.setSingleShot(true); @@ -147,7 +149,7 @@ VideoReceiver::_connected() _timer.stop(); _socket->deleteLater(); _socket = NULL; - if(qgcApp()->toolbox()->settingsManager()->videoSettings()->streamEnabled()->rawValue().toBool()) { + if(_videoSettings->streamEnabled()->rawValue().toBool()) { _serverPresent = true; start(); } @@ -163,7 +165,7 @@ VideoReceiver::_socketError(QAbstractSocket::SocketError socketError) _socket->deleteLater(); _socket = NULL; //-- Try again in 5 seconds - if(qgcApp()->toolbox()->settingsManager()->videoSettings()->streamEnabled()->rawValue().toBool()) { + if(_videoSettings->streamEnabled()->rawValue().toBool()) { _timer.start(5000); } } @@ -179,7 +181,7 @@ VideoReceiver::_timeout() delete _socket; _socket = NULL; } - if(qgcApp()->toolbox()->settingsManager()->videoSettings()->streamEnabled()->rawValue().toBool()) { + if(_videoSettings->streamEnabled()->rawValue().toBool()) { //-- 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 @@ -208,8 +210,8 @@ VideoReceiver::_timeout() void VideoReceiver::start() { - if(!qgcApp()->toolbox()->settingsManager()->videoSettings()->streamEnabled()->rawValue().toBool() || - !qgcApp()->toolbox()->settingsManager()->videoSettings()->streamConfigured()) { + if(!_videoSettings->streamEnabled()->rawValue().toBool() || + !_videoSettings->streamConfigured()) { qCDebug(VideoReceiverLog) << "start() but not enabled/configured"; return; } @@ -560,7 +562,7 @@ void VideoReceiver::_cleanupOldVideos() { //-- Only perform cleanup if storage limit is enabled - if(qgcApp()->toolbox()->settingsManager()->videoSettings()->enableStorageLimit()->rawValue().toBool()) { + if(_videoSettings->enableStorageLimit()->rawValue().toBool()) { QString savePath = qgcApp()->toolbox()->settingsManager()->appSettings()->videoSavePath(); QDir videoDir = QDir(savePath); videoDir.setFilter(QDir::Files | QDir::Readable | QDir::NoSymLinks | QDir::Writable); @@ -576,7 +578,7 @@ VideoReceiver::_cleanupOldVideos() if(!vidList.isEmpty()) { uint64_t total = 0; //-- Settings are stored using MB - uint64_t maxSize = (qgcApp()->toolbox()->settingsManager()->videoSettings()->maxVideoSize()->rawValue().toUInt() * 1024 * 1024); + uint64_t maxSize = (_videoSettings->maxVideoSize()->rawValue().toUInt() * 1024 * 1024); //-- Compute total used storage for(int i = 0; i < vidList.size(); i++) { total += vidList[i].size(); @@ -624,7 +626,7 @@ VideoReceiver::startRecording(void) return; } - uint32_t muxIdx = qgcApp()->toolbox()->settingsManager()->videoSettings()->recordingFormat()->rawValue().toUInt(); + uint32_t muxIdx = _videoSettings->recordingFormat()->rawValue().toUInt(); if(muxIdx >= NUM_MUXES) { qgcApp()->showMessage(tr("Invalid video format defined.")); return; @@ -813,7 +815,7 @@ VideoReceiver::_updateTimer() if(_videoRunning) { uint32_t timeout = 1; if(qgcApp()->toolbox() && qgcApp()->toolbox()->settingsManager()) { - timeout = qgcApp()->toolbox()->settingsManager()->videoSettings()->rtspTimeout()->rawValue().toUInt(); + timeout = _videoSettings->rtspTimeout()->rawValue().toUInt(); } time_t elapsed = 0; time_t lastFrame = _videoSurface->lastFrame(); @@ -824,7 +826,7 @@ VideoReceiver::_updateTimer() stop(); } } else { - if(!running() && !_uri.isEmpty() && qgcApp()->toolbox()->settingsManager()->videoSettings()->streamEnabled()->rawValue().toBool()) { + if(!running() && !_uri.isEmpty() && _videoSettings->streamEnabled()->rawValue().toBool()) { start(); } } diff --git a/src/VideoStreaming/VideoReceiver.h b/src/VideoStreaming/VideoReceiver.h index caced64e9512bec98b9761d038164d4b1e6ec0bb..f21380a78ec4925894f65d01f6b8b5ec7993858c 100644 --- a/src/VideoStreaming/VideoReceiver.h +++ b/src/VideoStreaming/VideoReceiver.h @@ -30,6 +30,8 @@ Q_DECLARE_LOGGING_CATEGORY(VideoReceiverLog) +class VideoSettings; + class VideoReceiver : public QObject { Q_OBJECT @@ -137,6 +139,7 @@ private: VideoSurface* _videoSurface; bool _videoRunning; bool _showFullScreen; + VideoSettings* _videoSettings; }; #endif // VIDEORECEIVER_H diff --git a/src/ui/preferences/GeneralSettings.qml b/src/ui/preferences/GeneralSettings.qml index 4d6c4ae3df6d95ccec2b1dc8c66c955938fe8597..cc853858727291c25c13194bfa825ca344399fcd 100644 --- a/src/ui/preferences/GeneralSettings.qml +++ b/src/ui/preferences/GeneralSettings.qml @@ -37,7 +37,7 @@ QGCView { property Fact _appFontPointSize: QGroundControl.settingsManager.appSettings.appFontPointSize property Fact _userBrandImageIndoor: QGroundControl.settingsManager.brandImageSettings.userBrandImageIndoor property Fact _userBrandImageOutdoor: QGroundControl.settingsManager.brandImageSettings.userBrandImageOutdoor - property real _labelWidth: ScreenTools.defaultFontPixelWidth * 15 + property real _labelWidth: ScreenTools.defaultFontPixelWidth * 20 property real _editFieldWidth: ScreenTools.defaultFontPixelWidth * 30 property Fact _mapProvider: QGroundControl.settingsManager.flightMapSettings.mapProvider property Fact _mapType: QGroundControl.settingsManager.flightMapSettings.mapType @@ -590,13 +590,13 @@ QGCView { spacing: ScreenTools.defaultFontPixelWidth visible: QGroundControl.videoManager.isGStreamer && videoSource.currentIndex && videoSource.currentIndex < 3 && QGroundControl.settingsManager.videoSettings.gridLines.visible QGCLabel { - text: qsTr("Grid Lines:") + text: qsTr("Disable When Disarmed:") width: _labelWidth anchors.verticalCenter: parent.verticalCenter } - FactComboBox { - width: _editFieldWidth - fact: QGroundControl.settingsManager.videoSettings.gridLines + FactCheckBox { + text: "" + fact: QGroundControl.settingsManager.videoSettings.disableWhenDisarmed anchors.verticalCenter: parent.verticalCenter } }