diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index c39e90a20a5831a7b4f4c47253d15ead8c3cca7d..320cc7595404cac7e22f70c152c3e09f47c7f884 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -79,6 +79,7 @@ QT += \ svg \ widgets \ xml \ + multimedia !MobileBuild { QT += \ @@ -258,7 +259,7 @@ HEADERS += \ src/comm/QGCMAVLink.h \ src/comm/TCPLink.h \ src/comm/UDPLink.h \ - src/FlightDisplay/FlightDisplayViewController.h \ + src/FlightDisplay/VideoManager.h \ src/FlightMap/FlightMapSettings.h \ src/FlightMap/Widgets/ValuesWidgetController.h \ src/GAudioOutput.h \ @@ -420,7 +421,7 @@ SOURCES += \ src/comm/QGCMAVLink.cc \ src/comm/TCPLink.cc \ src/comm/UDPLink.cc \ - src/FlightDisplay/FlightDisplayViewController.cc \ + src/FlightDisplay/VideoManager.cc \ src/FlightMap/FlightMapSettings.cc \ src/FlightMap/Widgets/ValuesWidgetController.cc \ src/GAudioOutput.cc \ diff --git a/src/FlightDisplay/FlightDisplayView.qml b/src/FlightDisplay/FlightDisplayView.qml index 26cea2d3406db2d1c860ba1537a62e927f4201e3..8b88f6a4af737290b718ff3430585cebdcd0316c 100644 --- a/src/FlightDisplay/FlightDisplayView.qml +++ b/src/FlightDisplay/FlightDisplayView.qml @@ -14,6 +14,7 @@ import QtQuick.Controls.Styles 1.2 import QtQuick.Dialogs 1.2 import QtLocation 5.3 import QtPositioning 5.2 +import QtMultimedia 5.5 import QGroundControl 1.0 import QGroundControl.FlightDisplay 1.0 @@ -33,8 +34,8 @@ QGCView { QGCPalette { id: qgcPal; colorGroupEnabled: enabled } property var _activeVehicle: QGroundControl.multiVehicleManager.activeVehicle - property bool _mainIsMap: _controller.hasVideo ? QGroundControl.loadBoolGlobalSetting(_mainIsMapKey, true) : true - property bool _isPipVisible: _controller.hasVideo ? QGroundControl.loadBoolGlobalSetting(_PIPVisibleKey, true) : false + property bool _mainIsMap: QGroundControl.videoManager.hasVideo ? QGroundControl.loadBoolGlobalSetting(_mainIsMapKey, true) : true + property bool _isPipVisible: QGroundControl.videoManager.hasVideo ? QGroundControl.loadBoolGlobalSetting(_PIPVisibleKey, true) : false property real _roll: _activeVehicle ? _activeVehicle.roll.value : _defaultRoll property real _pitch: _activeVehicle ? _activeVehicle.pitch.value : _defaultPitch @@ -63,8 +64,6 @@ QGCView { readonly property string _mainIsMapKey: "MainFlyWindowIsMap" readonly property string _PIPVisibleKey: "IsPIPVisible" - FlightDisplayViewController { id: _controller } - function setStates() { QGroundControl.saveBoolGlobalSetting(_mainIsMapKey, _mainIsMap) if(_mainIsMap) { @@ -161,14 +160,14 @@ QGCView { } //-- Video View - FlightDisplayViewVideo { + Item { id: _flightVideo z: _mainIsMap ? _panel.z + 2 : _panel.z + 1 width: !_mainIsMap ? _panel.width : pipSize height: !_mainIsMap ? _panel.height : pipSize * (9/16) anchors.left: _panel.left anchors.bottom: _panel.bottom - visible: _controller.hasVideo && (!_mainIsMap || _isPipVisible) + visible: QGroundControl.videoManager.hasVideo && (!_mainIsMap || _isPipVisible) states: [ State { name: "pipMode" @@ -185,6 +184,29 @@ QGCView { } } ] + //-- UDP 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 + anchors.fill: parent + visible: !QGroundControl.videoManager.isGStreamer + } + } } QGCPipable { @@ -195,7 +217,7 @@ QGCView { anchors.left: _panel.left anchors.bottom: _panel.bottom anchors.margins: ScreenTools.defaultFontPixelHeight - visible: _controller.hasVideo + visible: QGroundControl.videoManager.hasVideo isHidden: !_isPipVisible isDark: isBackgroundDark onActivated: { diff --git a/src/FlightDisplay/FlightDisplayViewController.cc b/src/FlightDisplay/FlightDisplayViewController.cc deleted file mode 100644 index 124d3ffeaacce9e457d891c7c7d1f506ccf81474..0000000000000000000000000000000000000000 --- a/src/FlightDisplay/FlightDisplayViewController.cc +++ /dev/null @@ -1,94 +0,0 @@ -/**************************************************************************** - * - * (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. - * - ****************************************************************************/ - - -#include -#include -#include - -#include - -#include "ScreenToolsController.h" -#include "FlightDisplayViewController.h" - -const char* kMainFlightDisplayViewControllerGroup = "FlightDisplayViewController"; - -FlightDisplayViewController::FlightDisplayViewController(QObject *parent) - : QObject(parent) - , _videoRunning(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 you will break Solo video support -#if defined(QGC_GST_STREAMING) - _videoReceiver->setVideoSink(_videoSurface->videoSink()); - connect(&_frameTimer, &QTimer::timeout, this, &FlightDisplayViewController::_updateTimer); - _frameTimer.start(1000); -#endif -} - -FlightDisplayViewController::~FlightDisplayViewController() -{ - -} - -#if defined(QGC_GST_STREAMING) -void FlightDisplayViewController::_updateTimer(void) -{ - if(_videoRunning) - { - time_t elapsed = 0; - if(_videoSurface) - { - elapsed = time(0) - _videoSurface->lastFrame(); - } - if(elapsed > 2) - { - _videoRunning = false; - _videoSurface->setLastFrame(0); - emit videoRunningChanged(); - } - } - else - { - if(_videoSurface && _videoSurface->lastFrame()) { - if(!_videoRunning) - { - _videoRunning = true; - emit videoRunningChanged(); - } - } - } -} -#endif diff --git a/src/FlightDisplay/FlightDisplayViewController.h b/src/FlightDisplay/FlightDisplayViewController.h deleted file mode 100644 index 1392fdeed8cbc9cb35bba1097be87c4a94fc1c52..0000000000000000000000000000000000000000 --- a/src/FlightDisplay/FlightDisplayViewController.h +++ /dev/null @@ -1,58 +0,0 @@ -/**************************************************************************** - * - * (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. - * - ****************************************************************************/ - - -#ifndef FlightDisplayViewController_H -#define FlightDisplayViewController_H - -#include -#include - -#include "VideoSurface.h" -#include "VideoReceiver.h" - -class FlightDisplayViewController : public QObject -{ - Q_OBJECT - -public: - FlightDisplayViewController(QObject* parent = NULL); - ~FlightDisplayViewController(); - - Q_PROPERTY(bool hasVideo READ hasVideo CONSTANT) - - Q_PROPERTY(VideoSurface* videoSurface MEMBER _videoSurface CONSTANT); - Q_PROPERTY(VideoReceiver* videoReceiver MEMBER _videoReceiver CONSTANT); - - Q_PROPERTY(bool videoRunning READ videoRunning NOTIFY videoRunningChanged) - -#if defined(QGC_GST_STREAMING) - bool hasVideo () { return true; } -#else - bool hasVideo () { return false; } -#endif - - bool videoRunning() { return _videoRunning; } - -signals: - void videoRunningChanged(); - -private: - void _updateTimer(void); - -private: - VideoSurface* _videoSurface; - VideoReceiver* _videoReceiver; - bool _videoRunning; -#if defined(QGC_GST_STREAMING) - QTimer _frameTimer; -#endif -}; - -#endif diff --git a/src/FlightDisplay/FlightDisplayViewVideo.qml b/src/FlightDisplay/FlightDisplayViewVideo.qml index 6b0f3a779d815373815f5edb367c08145ea21e5f..653f8ab2fb4faa83bf720cc478bc4bff5499f2ab 100644 --- a/src/FlightDisplay/FlightDisplayViewVideo.qml +++ b/src/FlightDisplay/FlightDisplayViewVideo.qml @@ -27,7 +27,7 @@ Item { id: noVideo anchors.fill: parent color: Qt.rgba(0,0,0,0.75) - visible: !_controller.videoRunning + visible: !QGroundControl.videoManager.videoRunning QGCLabel { text: qsTr("NO VIDEO") font.family: ScreenTools.demiboldFontFamily @@ -38,9 +38,9 @@ Item { } QGCVideoBackground { anchors.fill: parent - display: _controller.videoSurface - receiver: _controller.videoReceiver - visible: _controller.videoRunning + 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 { diff --git a/src/FlightDisplay/VideoManager.cc b/src/FlightDisplay/VideoManager.cc new file mode 100644 index 0000000000000000000000000000000000000000..9739d4f08ca7d92334143ac15abe561fd066a290 --- /dev/null +++ b/src/FlightDisplay/VideoManager.cc @@ -0,0 +1,171 @@ +/**************************************************************************** + * + * (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. + * + ****************************************************************************/ + + +#include +#include +#include +#include + +#include + +#include "ScreenToolsController.h" +#include "VideoManager.h" + +static const char* kVideoSourceKey = "VideoSource"; +static const char* kGStreamerSource = "UDP Video Stream"; + +QGC_LOGGING_CATEGORY(VideoManagerLog, "VideoManagerLog") + +//----------------------------------------------------------------------------- +VideoManager::VideoManager(QGCApplication* app) + : QGCTool(app) + , _videoRunning(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 +#if defined(QGC_GST_STREAMING) + _videoReceiver->setVideoSink(_videoSurface->videoSink()); + connect(&_frameTimer, &QTimer::timeout, this, &VideoManager::_updateTimer); + _frameTimer.start(1000); +#endif + //-- Get saved video source + QSettings settings; + setVideoSource(settings.value(kVideoSourceKey, kGStreamerSource).toString()); +} + +//----------------------------------------------------------------------------- +VideoManager::~VideoManager() +{ + +} + +//----------------------------------------------------------------------------- +void +VideoManager::setToolbox(QGCToolbox *toolbox) +{ + QGCTool::setToolbox(toolbox); + QQmlEngine::setObjectOwnership(this, QQmlEngine::CppOwnership); + qmlRegisterUncreatableType("QGroundControl.VideoManager", 1, 0, "VideoManager", "Reference only"); +} + +//----------------------------------------------------------------------------- +bool +VideoManager::hasVideo() +{ +#if defined(QGC_GST_STREAMING) + return true; +#endif + return !_videoSource.isEmpty(); +} + +//----------------------------------------------------------------------------- +bool +VideoManager::isGStreamer() +{ +#if defined(QGC_GST_STREAMING) + return _videoSource == kGStreamerSource; +#else + return false; +#endif +} + +//----------------------------------------------------------------------------- +void +VideoManager::setVideoSource(QString vSource) +{ + _videoSource = vSource; + QSettings settings; + settings.setValue(kVideoSourceKey, vSource); + emit videoSourceChanged(); + QList cameras = QCameraInfo::availableCameras(); + foreach (const QCameraInfo &cameraInfo, cameras) { + if(cameraInfo.description() == vSource) { + _videoSourceID = cameraInfo.deviceName(); + emit videoSourceIDChanged(); + qCDebug(VideoManagerLog) << "Found USB source:" << _videoSourceID << " Name:" << _videoSource; + break; + } + } + emit isGStreamerChanged(); + qCDebug(VideoManagerLog) << "New Video Source:" << vSource; +} + +//----------------------------------------------------------------------------- +QStringList +VideoManager::videoSourceList() +{ + _videoSourceList.clear(); +#if defined(QGC_GST_STREAMING) + _videoSourceList.append(kGStreamerSource); +#endif + QList cameras = QCameraInfo::availableCameras(); + foreach (const QCameraInfo &cameraInfo, cameras) { + qCDebug(VideoManagerLog) << "UVC Video source ID:" << cameraInfo.deviceName() << " Name:" << cameraInfo.description(); + _videoSourceList.append(cameraInfo.description()); + } + return _videoSourceList; +} + +//----------------------------------------------------------------------------- +#if defined(QGC_GST_STREAMING) +void VideoManager::_updateTimer(void) +{ + if(_videoRunning) + { + time_t elapsed = 0; + if(_videoSurface) + { + elapsed = time(0) - _videoSurface->lastFrame(); + } + if(elapsed > 2) + { + _videoRunning = false; + _videoSurface->setLastFrame(0); + emit videoRunningChanged(); + } + } + else + { + if(_videoSurface && _videoSurface->lastFrame()) { + if(!_videoRunning) + { + _videoRunning = true; + emit videoRunningChanged(); + } + } + } +} +#endif diff --git a/src/FlightDisplay/VideoManager.h b/src/FlightDisplay/VideoManager.h new file mode 100644 index 0000000000000000000000000000000000000000..67dae78f9cf19ccde7ef0242286ee183b7b127be --- /dev/null +++ b/src/FlightDisplay/VideoManager.h @@ -0,0 +1,75 @@ +/**************************************************************************** + * + * (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. + * + ****************************************************************************/ + + +#ifndef VideoManager_H +#define VideoManager_H + +#include +#include + +#include "QGCLoggingCategory.h" +#include "VideoSurface.h" +#include "VideoReceiver.h" +#include "QGCToolbox.h" + +Q_DECLARE_LOGGING_CATEGORY(VideoManagerLog) + +class VideoManager : public QGCTool +{ + Q_OBJECT + +public: + VideoManager (QGCApplication* app); + ~VideoManager (); + + Q_PROPERTY(bool hasVideo READ hasVideo NOTIFY hasVideoChanged) + Q_PROPERTY(bool isGStreamer READ isGStreamer NOTIFY isGStreamerChanged) + Q_PROPERTY(QString videoSourceID READ videoSource NOTIFY videoSourceIDChanged) + 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(VideoSurface* videoSurface MEMBER _videoSurface CONSTANT) + Q_PROPERTY(VideoReceiver* videoReceiver MEMBER _videoReceiver CONSTANT) + + bool hasVideo (); + bool isGStreamer (); + bool videoRunning () { return _videoRunning; } + QString videoSourceID () { return _videoSourceID; } + QString videoSource () { return _videoSource; } + QStringList videoSourceList (); + void setVideoSource (QString vSource); + + // Override from QGCTool + void setToolbox (QGCToolbox *toolbox); + +signals: + void hasVideoChanged (); + void videoRunningChanged (); + void videoSourceChanged (); + void videoSourceListChanged (); + void isGStreamerChanged (); + void videoSourceIDChanged (); + +private: + void _updateTimer(void); + +private: + VideoSurface* _videoSurface; + VideoReceiver* _videoReceiver; + bool _videoRunning; +#if defined(QGC_GST_STREAMING) + QTimer _frameTimer; +#endif + QString _videoSource; + QString _videoSourceID; + QStringList _videoSourceList; +}; + +#endif diff --git a/src/QGCApplication.cc b/src/QGCApplication.cc index 89b3c2e8b8261f3a8830b384e2b599808466e7c8..90a376aeb71e9e60858c2ff4047eb73d1d02ae97 100644 --- a/src/QGCApplication.cc +++ b/src/QGCApplication.cc @@ -82,7 +82,7 @@ #include "CoordinateVector.h" #include "MainToolBarController.h" #include "MissionController.h" -#include "FlightDisplayViewController.h" +#include "VideoManager.h" #include "VideoSurface.h" #include "VideoReceiver.h" #include "LogDownloadController.h" @@ -393,7 +393,6 @@ void QGCApplication::_initCommon(void) qmlRegisterType ("QGroundControl.Controllers", 1, 0, "ScreenToolsController"); qmlRegisterType ("QGroundControl.Controllers", 1, 0, "MainToolBarController"); qmlRegisterType ("QGroundControl.Controllers", 1, 0, "MissionController"); - qmlRegisterType ("QGroundControl.Controllers", 1, 0, "FlightDisplayViewController"); qmlRegisterType ("QGroundControl.Controllers", 1, 0, "ValuesWidgetController"); qmlRegisterType ("QGroundControl.Controllers", 1, 0, "QGCMobileFileDialogController"); qmlRegisterType ("QGroundControl.Controllers", 1, 0, "RCChannelMonitorController"); diff --git a/src/QGCToolbox.cc b/src/QGCToolbox.cc index 6fb4af694e122e3148b90faaad29707f4377c1e0..ba04685970672536604d62903f3e0f0fc923a0b8 100644 --- a/src/QGCToolbox.cc +++ b/src/QGCToolbox.cc @@ -27,6 +27,7 @@ #include "QGCMapEngineManager.h" #include "FollowMe.h" #include "PositionManager.h" +#include "VideoManager.h" QGCToolbox::QGCToolbox(QGCApplication* app) : _audioOutput(NULL) @@ -48,6 +49,7 @@ QGCToolbox::QGCToolbox(QGCApplication* app) , _uasMessageHandler(NULL) , _followMe(NULL) , _qgcPositionManager(NULL) + , _videoManager(NULL) { _audioOutput = new GAudioOutput(app); _autopilotPluginManager = new AutoPilotPluginManager(app); @@ -68,6 +70,7 @@ QGCToolbox::QGCToolbox(QGCApplication* app) _uasMessageHandler = new UASMessageHandler(app); _qgcPositionManager = new QGCPositionManager(app); _followMe = new FollowMe(app); + _videoManager = new VideoManager(app); _audioOutput->setToolbox(this); _autopilotPluginManager->setToolbox(this); @@ -88,10 +91,12 @@ QGCToolbox::QGCToolbox(QGCApplication* app) _uasMessageHandler->setToolbox(this); _followMe->setToolbox(this); _qgcPositionManager->setToolbox(this); + _videoManager->setToolbox(this); } QGCToolbox::~QGCToolbox() { + delete _videoManager; delete _audioOutput; delete _autopilotPluginManager; delete _factSystem; diff --git a/src/QGCToolbox.h b/src/QGCToolbox.h index f4d7598e748d924d6a1ba130cb1e40b5c3e74403..18f8b299c0cade11a3b86e951df614629e8595e4 100644 --- a/src/QGCToolbox.h +++ b/src/QGCToolbox.h @@ -31,6 +31,7 @@ class QGCApplication; class QGCImageProvider; class UASMessageHandler; class QGCPositionManager; +class VideoManager; /// This is used to manage all of our top level services/tools class QGCToolbox { @@ -54,6 +55,7 @@ public: UASMessageHandler* uasMessageHandler(void) { return _uasMessageHandler; } FollowMe* followMe(void) { return _followMe; } QGCPositionManager* qgcPositionManager(void) { return _qgcPositionManager; } + VideoManager* videoManager(void) { return _videoManager; } #ifndef __mobile__ GPSManager* gpsManager(void) { return _gpsManager; } #endif @@ -78,6 +80,7 @@ private: UASMessageHandler* _uasMessageHandler; FollowMe* _followMe; QGCPositionManager* _qgcPositionManager; + VideoManager* _videoManager; }; /// This is the base class for all tools diff --git a/src/QmlControls/QGroundControlQmlGlobal.cc b/src/QmlControls/QGroundControlQmlGlobal.cc index 0aca011312dce80e73bffeb7b1e1b71cf28eedd5..f4d20aaf4824e2fb4176efb80d7a2f55b67cb2e6 100644 --- a/src/QmlControls/QGroundControlQmlGlobal.cc +++ b/src/QmlControls/QGroundControlQmlGlobal.cc @@ -46,6 +46,7 @@ QGroundControlQmlGlobal::QGroundControlQmlGlobal(QGCApplication* app) , _mapEngineManager(NULL) , _qgcPositionManager(NULL) , _missionCommandTree(NULL) + , _videoManager(NULL) , _virtualTabletJoystick(false) , _baseFontPointSize(0.0) { @@ -73,6 +74,7 @@ void QGroundControlQmlGlobal::setToolbox(QGCToolbox* toolbox) _mapEngineManager = toolbox->mapEngineManager(); _qgcPositionManager = toolbox->qgcPositionManager(); _missionCommandTree = toolbox->missionCommandTree(); + _videoManager = toolbox->videoManager(); } diff --git a/src/QmlControls/QGroundControlQmlGlobal.h b/src/QmlControls/QGroundControlQmlGlobal.h index dc7eb2b713794ed14eaa4c794017fb34387059e5..487c13b82cfe0bb12c5c9df60b1eef479a019349 100644 --- a/src/QmlControls/QGroundControlQmlGlobal.h +++ b/src/QmlControls/QGroundControlQmlGlobal.h @@ -71,6 +71,7 @@ public: Q_PROPERTY(QGCMapEngineManager* mapEngineManager READ mapEngineManager CONSTANT) Q_PROPERTY(QGCPositionManager* qgcPositionManger READ qgcPositionManger CONSTANT) Q_PROPERTY(MissionCommandTree* missionCommandTree READ missionCommandTree CONSTANT) + Q_PROPERTY(VideoManager* videoManager READ videoManager CONSTANT) Q_PROPERTY(qreal zOrderTopMost READ zOrderTopMost CONSTANT) ///< z order for top most items, toolbar, main window sub view Q_PROPERTY(qreal zOrderWidgets READ zOrderWidgets CONSTANT) ///< z order value to widgets, for example: zoom controls, hud widgetss @@ -165,6 +166,7 @@ public: QGCMapEngineManager* mapEngineManager () { return _mapEngineManager; } QGCPositionManager* qgcPositionManger () { return _qgcPositionManager; } MissionCommandTree* missionCommandTree () { return _missionCommandTree; } + VideoManager* videoManager () { return _videoManager; } qreal zOrderTopMost () { return 1000; } qreal zOrderWidgets () { return 100; } @@ -234,6 +236,7 @@ private: QGCMapEngineManager* _mapEngineManager; QGCPositionManager* _qgcPositionManager; MissionCommandTree* _missionCommandTree; + VideoManager* _videoManager; bool _virtualTabletJoystick; qreal _baseFontPointSize; diff --git a/src/comm/MockLink.cc b/src/comm/MockLink.cc index cba6807713921fae459f5b2962bedc8288bdb27d..ed00f659d3228e9ff20a22ad1049849d9f719ed7 100644 --- a/src/comm/MockLink.cc +++ b/src/comm/MockLink.cc @@ -11,7 +11,9 @@ #include "MockLink.h" #include "QGCLoggingCategory.h" #include "QGCApplication.h" +#ifndef __mobile__ #include "UnitTest.h" +#endif #include #include @@ -1142,7 +1144,9 @@ void MockLink::_handleLogRequestData(const mavlink_message_t& msg) mavlink_msg_log_request_data_decode(&msg, &request); if (_logDownloadFilename.isEmpty()) { + #ifndef __mobile__ _logDownloadFilename = UnitTest::createRandomFile(_logDownloadFileSize); + #endif } if (request.id != 0) { diff --git a/src/ui/preferences/GeneralSettings.qml b/src/ui/preferences/GeneralSettings.qml index e2f8637fda64d34cc8c3d9476e8cc80eecea4460..1044e9155c1be915b87bcbeff11436400f13be19 100644 --- a/src/ui/preferences/GeneralSettings.qml +++ b/src/ui/preferences/GeneralSettings.qml @@ -12,6 +12,7 @@ import QtQuick 2.5 import QtQuick.Controls 1.2 import QtQuick.Controls.Styles 1.2 import QtQuick.Dialogs 1.1 +import QtMultimedia 5.5 import QGroundControl 1.0 import QGroundControl.FactSystem 1.0 @@ -20,6 +21,7 @@ import QGroundControl.Controls 1.0 import QGroundControl.ScreenTools 1.0 import QGroundControl.MultiVehicleManager 1.0 import QGroundControl.Palette 1.0 +import QGroundControl.Controllers 1.0 QGCView { id: qgcView @@ -29,7 +31,7 @@ QGCView { anchors.margins: ScreenTools.defaultFontPixelWidth property Fact _percentRemainingAnnounce: QGroundControl.batteryPercentRemainingAnnounce - property real _editFieldWidth: ScreenTools.defaultFontPixelWidth * 15 + property real _editFieldWidth: ScreenTools.defaultFontPixelWidth * 20 QGCPalette { id: qgcPal } @@ -277,6 +279,32 @@ QGCView { 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] + } + } + } + } //----------------------------------------------------------------- //-- Map Providers Row {