Unverified Commit 168a7326 authored by Gus Grubba's avatar Gus Grubba Committed by GitHub

Merge pull request #7103 from mavlink/taisyncLink

Taisync support
parents b5cf395c c00b0256
......@@ -21,6 +21,7 @@ linux {
message("Linux build")
CONFIG += LinuxBuild
DEFINES += __STDC_LIMIT_MACROS
DEFINES += QGC_GST_TAISYNC_ENABLED
linux-clang {
message("Linux clang")
QMAKE_CXXFLAGS += -Qunused-arguments -fcolor-diagnostics
......@@ -29,6 +30,7 @@ linux {
message("Linux R-Pi2 build")
CONFIG += LinuxBuild
DEFINES += __STDC_LIMIT_MACROS __rasp_pi2__
DEFINES += QGC_GST_TAISYNC_ENABLED
} else : android-g++ | android-clang {
CONFIG += AndroidBuild MobileBuild
DEFINES += __android__
......@@ -50,6 +52,7 @@ linux {
message("Windows build")
CONFIG += WindowsBuild
DEFINES += __STDC_LIMIT_MACROS
DEFINES += QGC_GST_TAISYNC_ENABLED
} else {
error("Unsupported Windows toolchain, only Visual Studio 2015 is supported")
}
......@@ -59,6 +62,7 @@ linux {
CONFIG += MacBuild
CONFIG += x86_64
CONFIG -= x86
DEFINES += QGC_GST_TAISYNC_ENABLED
equals(QT_MAJOR_VERSION, 5) | greaterThan(QT_MINOR_VERSION, 5) {
QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.7
} else {
......@@ -83,6 +87,7 @@ linux {
DEFINES += QGC_NO_GOOGLE_MAPS
DEFINES += NO_SERIAL_LINK
DEFINES += QGC_DISABLE_UVC
DEFINES += QGC_GST_TAISYNC_ENABLED
QMAKE_IOS_DEPLOYMENT_TARGET = 8.0
QMAKE_APPLE_TARGETED_DEVICE_FAMILY = 1,2 # Universal
QMAKE_LFLAGS += -Wl,-no_pie
......
......@@ -5,7 +5,7 @@ if [ ! -d /Volumes/RAMDisk ] ; then
exit 1
fi
#-- Set to my local installation
QMAKE=/Users/gus/Applications/Qt/5.11.0/ios/bin/qmake
QMAKE=/Users/gus/Applications/Qt/5.11.2/ios/bin/qmake
#-- Using Travis variables as this will eventually live there
SHADOW_BUILD_DIR=/Volumes/RAMDisk/build-qgroundcontrol-iOS-Release
TRAVIS_BUILD_DIR=/Users/gus/github/work/UpstreamQGC
......
......@@ -628,7 +628,7 @@ HEADERS += \
AndroidBuild {
HEADERS += \
src/Joystick/JoystickAndroid.h \
src/Joystick/JoystickAndroid.h \
}
DebugBuild {
......@@ -714,7 +714,7 @@ iOSBuild {
AndroidBuild {
SOURCES += src/MobileScreenMgr.cc \
src/Joystick/JoystickAndroid.cc \
src/Joystick/JoystickAndroid.cc \
}
SOURCES += \
......@@ -1106,6 +1106,33 @@ SOURCES += \
src/FactSystem/ParameterManager.cc \
src/FactSystem/SettingsFact.cc \
#-------------------------------------------------------------------------------------
# Taisync
contains (DEFINES, QGC_GST_TAISYNC_ENABLED) {
INCLUDEPATH += \
src/Taisync
HEADERS += \
src/Taisync/TaisyncManager.h \
src/Taisync/TaisyncHandler.h \
src/Taisync/TaisyncSettings.h \
SOURCES += \
src/Taisync/TaisyncManager.cc \
src/Taisync/TaisyncHandler.cc \
src/Taisync/TaisyncSettings.cc \
iOSBuild | AndroidBuild {
HEADERS += \
src/Taisync/TaisyncTelemetry.h \
src/Taisync/TaisyncVideoReceiver.h \
SOURCES += \
src/Taisync/TaisyncTelemetry.cc \
src/Taisync/TaisyncVideoReceiver.cc \
}
}
#-------------------------------------------------------------------------------------
# AirMap
......
......@@ -199,6 +199,7 @@
<file alias="SurveyItemEditor.qml">src/PlanView/SurveyItemEditor.qml</file>
<file alias="SyslinkComponent.qml">src/AutoPilotPlugins/Common/SyslinkComponent.qml</file>
<file alias="TcpSettings.qml">src/ui/preferences/TcpSettings.qml</file>
<file alias="TaisyncSettings.qml">src/Taisync/TaisyncSettings.qml</file>
<file alias="test.qml">src/test.qml</file>
<file alias="UdpSettings.qml">src/ui/preferences/UdpSettings.qml</file>
<file alias="ValuePageWidget.qml">src/FlightMap/Widgets/ValuePageWidget.qml</file>
......
......@@ -147,15 +147,20 @@ void Fact::setCookedValue(const QVariant& value)
}
}
void Fact::setEnumStringValue(const QString& value)
int Fact::valueIndex(const QString& value)
{
if (_metaData) {
int index = _metaData->enumStrings().indexOf(value);
if (index != -1) {
setCookedValue(_metaData->enumValues()[index]);
}
} else {
qWarning() << kMissingMetadata << name();
return _metaData->enumStrings().indexOf(value);
}
qWarning() << kMissingMetadata << name();
return -1;
}
void Fact::setEnumStringValue(const QString& value)
{
int index = valueIndex(value);
if (index != -1) {
setCookedValue(_metaData->enumValues()[index]);
}
}
......
......@@ -138,6 +138,7 @@ public:
void setCookedValue (const QVariant& value);
void setEnumIndex (int index);
void setEnumStringValue (const QString& value);
int valueIndex (const QString& value);
// The following methods allow you to defer sending of the valueChanged signals in order to implement
// rate limited signalling for ui performance. Used by FactGroup for example.
......
......@@ -34,10 +34,6 @@ QGC_LOGGING_CATEGORY(VideoManagerLog, "VideoManagerLog")
//-----------------------------------------------------------------------------
VideoManager::VideoManager(QGCApplication* app, QGCToolbox* toolbox)
: QGCTool(app, toolbox)
, _videoReceiver(nullptr)
, _videoSettings(nullptr)
, _fullScreen(false)
, _activeVehicle(nullptr)
{
}
......
......@@ -36,6 +36,7 @@ public:
Q_PROPERTY(bool hasVideo READ hasVideo NOTIFY hasVideoChanged)
Q_PROPERTY(bool isGStreamer READ isGStreamer NOTIFY isGStreamerChanged)
Q_PROPERTY(bool isAutoStream READ isAutoStream NOTIFY isAutoStreamChanged)
Q_PROPERTY(bool isTaisync READ isTaisync WRITE setIsTaisync NOTIFY isTaisyncChanged)
Q_PROPERTY(QString videoSourceID READ videoSourceID NOTIFY videoSourceIDChanged)
Q_PROPERTY(bool uvcEnabled READ uvcEnabled CONSTANT)
Q_PROPERTY(bool fullScreen READ fullScreen WRITE setfullScreen NOTIFY fullScreenChanged)
......@@ -45,6 +46,7 @@ public:
bool hasVideo ();
bool isGStreamer ();
bool isAutoStream ();
bool isTaisync () { return _isTaisync; }
bool fullScreen () { return _fullScreen; }
QString videoSourceID () { return _videoSourceID; }
QString autoURL () { return QString(_streamInfo.uri); }
......@@ -59,6 +61,7 @@ public:
#endif
void setfullScreen (bool f) { _fullScreen = f; emit fullScreenChanged(); }
void setIsTaisync (bool t) { _isTaisync = t; emit isTaisyncChanged(); }
// Override from QGCTool
void setToolbox (QGCToolbox *toolbox);
......@@ -73,6 +76,7 @@ signals:
void fullScreenChanged ();
void isAutoStreamChanged ();
void aspectRatioChanged ();
void isTaisyncChanged ();
private slots:
void _videoSourceChanged ();
......@@ -88,11 +92,13 @@ private:
void _updateSettings ();
void _restartVideo ();
VideoReceiver* _videoReceiver;
VideoSettings* _videoSettings;
private:
bool _isTaisync = false;
VideoReceiver* _videoReceiver = nullptr;
VideoSettings* _videoSettings = nullptr;
QString _videoSourceID;
bool _fullScreen;
Vehicle* _activeVehicle;
bool _fullScreen = false;
Vehicle* _activeVehicle = nullptr;
mavlink_video_stream_information_t _streamInfo;
};
......
......@@ -35,64 +35,48 @@
#else
#include "AirspaceManager.h"
#endif
#if defined(QGC_GST_TAISYNC_ENABLED)
#include "TaisyncManager.h"
#endif
#if defined(QGC_CUSTOM_BUILD)
#include CUSTOMHEADER
#endif
QGCToolbox::QGCToolbox(QGCApplication* app)
: _audioOutput (NULL)
, _factSystem (NULL)
, _firmwarePluginManager(NULL)
#ifndef __mobile__
, _gpsManager (NULL)
#endif
, _imageProvider (NULL)
, _joystickManager (NULL)
, _linkManager (NULL)
, _mavlinkProtocol (NULL)
, _missionCommandTree (NULL)
, _multiVehicleManager (NULL)
, _mapEngineManager (NULL)
, _uasMessageHandler (NULL)
, _followMe (NULL)
, _qgcPositionManager (NULL)
, _videoManager (NULL)
, _mavlinkLogManager (NULL)
, _corePlugin (NULL)
, _settingsManager (NULL)
, _airspaceManager (NULL)
{
// SettingsManager must be first so settings are available to any subsequent tools
_settingsManager = new SettingsManager(app, this);
_settingsManager = new SettingsManager (app, this);
//-- Scan and load plugins
_scanAndLoadPlugins(app);
_audioOutput = new AudioOutput (app, this);
_factSystem = new FactSystem (app, this);
_firmwarePluginManager = new FirmwarePluginManager (app, this);
_audioOutput = new AudioOutput (app, this);
_factSystem = new FactSystem (app, this);
_firmwarePluginManager = new FirmwarePluginManager (app, this);
#ifndef __mobile__
_gpsManager = new GPSManager (app, this);
_gpsManager = new GPSManager (app, this);
#endif
_imageProvider = new QGCImageProvider (app, this);
_joystickManager = new JoystickManager (app, this);
_linkManager = new LinkManager (app, this);
_mavlinkProtocol = new MAVLinkProtocol (app, this);
_missionCommandTree = new MissionCommandTree (app, this);
_multiVehicleManager = new MultiVehicleManager (app, this);
_mapEngineManager = new QGCMapEngineManager (app, this);
_uasMessageHandler = new UASMessageHandler (app, this);
_qgcPositionManager = new QGCPositionManager (app, this);
_followMe = new FollowMe (app, this);
_videoManager = new VideoManager (app, this);
_mavlinkLogManager = new MAVLinkLogManager (app, this);
_imageProvider = new QGCImageProvider (app, this);
_joystickManager = new JoystickManager (app, this);
_linkManager = new LinkManager (app, this);
_mavlinkProtocol = new MAVLinkProtocol (app, this);
_missionCommandTree = new MissionCommandTree (app, this);
_multiVehicleManager = new MultiVehicleManager (app, this);
_mapEngineManager = new QGCMapEngineManager (app, this);
_uasMessageHandler = new UASMessageHandler (app, this);
_qgcPositionManager = new QGCPositionManager (app, this);
_followMe = new FollowMe (app, this);
_videoManager = new VideoManager (app, this);
_mavlinkLogManager = new MAVLinkLogManager (app, this);
//-- Airmap Manager
//-- This should be "pluggable" so an arbitrary AirSpace manager can be used
//-- For now, we instantiate the one and only AirMap provider
#if defined(QGC_AIRMAP_ENABLED)
_airspaceManager = new AirMapManager (app, this);
_airspaceManager = new AirMapManager (app, this);
#else
_airspaceManager = new AirspaceManager (app, this);
_airspaceManager = new AirspaceManager (app, this);
#endif
#if defined(QGC_GST_TAISYNC_ENABLED)
_taisyncManager = new TaisyncManager (app, this);
#endif
}
......@@ -100,7 +84,6 @@ void QGCToolbox::setChildToolboxes(void)
{
// SettingsManager must be first so settings are available to any subsequent tools
_settingsManager->setToolbox(this);
_corePlugin->setToolbox(this);
_audioOutput->setToolbox(this);
_factSystem->setToolbox(this);
......@@ -121,6 +104,9 @@ void QGCToolbox::setChildToolboxes(void)
_videoManager->setToolbox(this);
_mavlinkLogManager->setToolbox(this);
_airspaceManager->setToolbox(this);
#if defined(QGC_GST_TAISYNC_ENABLED)
_taisyncManager->setToolbox(this);
#endif
}
void QGCToolbox::_scanAndLoadPlugins(QGCApplication* app)
......@@ -139,7 +125,7 @@ void QGCToolbox::_scanAndLoadPlugins(QGCApplication* app)
QGCTool::QGCTool(QGCApplication* app, QGCToolbox* toolbox)
: QObject(toolbox)
, _app(app)
, _toolbox(NULL)
, _toolbox(nullptr)
{
}
......
......@@ -33,6 +33,9 @@ class MAVLinkLogManager;
class QGCCorePlugin;
class SettingsManager;
class AirspaceManager;
#if defined(QGC_GST_TAISYNC_ENABLED)
class TaisyncManager;
#endif
/// This is used to manage all of our top level services/tools
class QGCToolbox : public QObject {
......@@ -41,25 +44,28 @@ class QGCToolbox : public QObject {
public:
QGCToolbox(QGCApplication* app);
FirmwarePluginManager* firmwarePluginManager(void) { return _firmwarePluginManager; }
AudioOutput* audioOutput(void) { return _audioOutput; }
JoystickManager* joystickManager(void) { return _joystickManager; }
LinkManager* linkManager(void) { return _linkManager; }
MAVLinkProtocol* mavlinkProtocol(void) { return _mavlinkProtocol; }
MissionCommandTree* missionCommandTree(void) { return _missionCommandTree; }
MultiVehicleManager* multiVehicleManager(void) { return _multiVehicleManager; }
QGCMapEngineManager* mapEngineManager(void) { return _mapEngineManager; }
QGCImageProvider* imageProvider() { return _imageProvider; }
UASMessageHandler* uasMessageHandler(void) { return _uasMessageHandler; }
FollowMe* followMe(void) { return _followMe; }
QGCPositionManager* qgcPositionManager(void) { return _qgcPositionManager; }
VideoManager* videoManager(void) { return _videoManager; }
MAVLinkLogManager* mavlinkLogManager(void) { return _mavlinkLogManager; }
QGCCorePlugin* corePlugin(void) { return _corePlugin; }
SettingsManager* settingsManager(void) { return _settingsManager; }
AirspaceManager* airspaceManager(void) { return _airspaceManager; }
FirmwarePluginManager* firmwarePluginManager () { return _firmwarePluginManager; }
AudioOutput* audioOutput () { return _audioOutput; }
JoystickManager* joystickManager () { return _joystickManager; }
LinkManager* linkManager () { return _linkManager; }
MAVLinkProtocol* mavlinkProtocol () { return _mavlinkProtocol; }
MissionCommandTree* missionCommandTree () { return _missionCommandTree; }
MultiVehicleManager* multiVehicleManager () { return _multiVehicleManager; }
QGCMapEngineManager* mapEngineManager () { return _mapEngineManager; }
QGCImageProvider* imageProvider () { return _imageProvider; }
UASMessageHandler* uasMessageHandler () { return _uasMessageHandler; }
FollowMe* followMe () { return _followMe; }
QGCPositionManager* qgcPositionManager () { return _qgcPositionManager; }
VideoManager* videoManager () { return _videoManager; }
MAVLinkLogManager* mavlinkLogManager () { return _mavlinkLogManager; }
QGCCorePlugin* corePlugin () { return _corePlugin; }
SettingsManager* settingsManager () { return _settingsManager; }
AirspaceManager* airspaceManager () { return _airspaceManager; }
#ifndef __mobile__
GPSManager* gpsManager(void) { return _gpsManager; }
GPSManager* gpsManager () { return _gpsManager; }
#endif
#if defined(QGC_GST_TAISYNC_ENABLED)
TaisyncManager* taisyncManager () { return _taisyncManager; }
#endif
private:
......@@ -67,27 +73,30 @@ private:
void _scanAndLoadPlugins(QGCApplication *app);
AudioOutput* _audioOutput;
FactSystem* _factSystem;
FirmwarePluginManager* _firmwarePluginManager;
AudioOutput* _audioOutput = nullptr;
FactSystem* _factSystem = nullptr;
FirmwarePluginManager* _firmwarePluginManager = nullptr;
#ifndef __mobile__
GPSManager* _gpsManager;
GPSManager* _gpsManager = nullptr;
#endif
QGCImageProvider* _imageProvider = nullptr;
JoystickManager* _joystickManager = nullptr;
LinkManager* _linkManager = nullptr;
MAVLinkProtocol* _mavlinkProtocol = nullptr;
MissionCommandTree* _missionCommandTree = nullptr;
MultiVehicleManager* _multiVehicleManager = nullptr;
QGCMapEngineManager* _mapEngineManager = nullptr;
UASMessageHandler* _uasMessageHandler = nullptr;
FollowMe* _followMe = nullptr;
QGCPositionManager* _qgcPositionManager = nullptr;
VideoManager* _videoManager = nullptr;
MAVLinkLogManager* _mavlinkLogManager = nullptr;
QGCCorePlugin* _corePlugin = nullptr;
SettingsManager* _settingsManager = nullptr;
AirspaceManager* _airspaceManager = nullptr;
#if defined(QGC_GST_TAISYNC_ENABLED)
TaisyncManager* _taisyncManager = nullptr;
#endif
QGCImageProvider* _imageProvider;
JoystickManager* _joystickManager;
LinkManager* _linkManager;
MAVLinkProtocol* _mavlinkProtocol;
MissionCommandTree* _missionCommandTree;
MultiVehicleManager* _multiVehicleManager;
QGCMapEngineManager* _mapEngineManager;
UASMessageHandler* _uasMessageHandler;
FollowMe* _followMe;
QGCPositionManager* _qgcPositionManager;
VideoManager* _videoManager;
MAVLinkLogManager* _mavlinkLogManager;
QGCCorePlugin* _corePlugin;
SettingsManager* _settingsManager;
AirspaceManager* _airspaceManager;
friend class QGCApplication;
};
......
......@@ -29,23 +29,9 @@ double QGroundControlQmlGlobal::_zoom = 2;
QGroundControlQmlGlobal::QGroundControlQmlGlobal(QGCApplication* app, QGCToolbox* toolbox)
: QGCTool (app, toolbox)
, _flightMapInitialZoom (17.0)
, _linkManager (NULL)
, _multiVehicleManager (NULL)
, _mapEngineManager (NULL)
, _qgcPositionManager (NULL)
, _missionCommandTree (NULL)
, _videoManager (NULL)
, _mavlinkLogManager (NULL)
, _corePlugin (NULL)
, _firmwarePluginManager(NULL)
, _settingsManager (NULL)
, _gpsRtkFactGroup (nullptr)
, _airspaceManager (NULL)
, _skipSetupPage (false)
{
// We clear the parent on this object since we run into shutdown problems caused by hybrid qml app. Instead we let it leak on shutdown.
setParent(NULL);
setParent(nullptr);
// Load last coordinates and zoom from config file
QSettings settings;
settings.beginGroup(_flightMapPositionSettingsGroup);
......@@ -80,6 +66,9 @@ void QGroundControlQmlGlobal::setToolbox(QGCToolbox* toolbox)
_settingsManager = toolbox->settingsManager();
_gpsRtkFactGroup = qgcApp()->gpsRtkFactGroup();
_airspaceManager = toolbox->airspaceManager();
#if defined(QGC_GST_TAISYNC_ENABLED)
_taisyncManager = toolbox->taisyncManager();
#endif
}
void QGroundControlQmlGlobal::saveGlobalSetting (const QString& key, const QString& value)
......
......@@ -23,6 +23,11 @@
#include "QGCLoggingCategory.h"
#include "AppSettings.h"
#include "AirspaceManager.h"
#if defined(QGC_GST_TAISYNC_ENABLED)
#include "TaisyncManager.h"
#else
class TaisyncManager;
#endif
#ifdef QT_DEBUG
#include "MockLink.h"
......@@ -52,6 +57,8 @@ public:
Q_PROPERTY(FactGroup* gpsRtk READ gpsRtkFactGroup CONSTANT)
Q_PROPERTY(AirspaceManager* airspaceManager READ airspaceManager CONSTANT)
Q_PROPERTY(bool airmapSupported READ airmapSupported CONSTANT)
Q_PROPERTY(TaisyncManager* taisyncManager READ taisyncManager CONSTANT)
Q_PROPERTY(bool taisyncSupported READ taisyncSupported CONSTANT)
Q_PROPERTY(int supportedFirmwareCount READ supportedFirmwareCount CONSTANT)
......@@ -145,6 +152,13 @@ public:
static QGeoCoordinate flightMapPosition () { return _coord; }
static double flightMapZoom () { return _zoom; }
TaisyncManager* taisyncManager () { return _taisyncManager; }
#if defined(QGC_GST_TAISYNC_ENABLED)
bool taisyncSupported () { return true; }
#else
bool taisyncSupported () { return false; }
#endif
qreal zOrderTopMost () { return 1000; }
qreal zOrderWidgets () { return 100; }
qreal zOrderMapItems () { return 50; }
......@@ -189,21 +203,22 @@ signals:
void skipSetupPageChanged ();
private:
double _flightMapInitialZoom;
LinkManager* _linkManager;
MultiVehicleManager* _multiVehicleManager;
QGCMapEngineManager* _mapEngineManager;
QGCPositionManager* _qgcPositionManager;
MissionCommandTree* _missionCommandTree;
VideoManager* _videoManager;
MAVLinkLogManager* _mavlinkLogManager;
QGCCorePlugin* _corePlugin;
FirmwarePluginManager* _firmwarePluginManager;
SettingsManager* _settingsManager;
FactGroup* _gpsRtkFactGroup;
AirspaceManager* _airspaceManager;
bool _skipSetupPage;
double _flightMapInitialZoom = 17.0;
LinkManager* _linkManager = nullptr;
MultiVehicleManager* _multiVehicleManager = nullptr;
QGCMapEngineManager* _mapEngineManager = nullptr;
QGCPositionManager* _qgcPositionManager = nullptr;
MissionCommandTree* _missionCommandTree = nullptr;
VideoManager* _videoManager = nullptr;
MAVLinkLogManager* _mavlinkLogManager = nullptr;
QGCCorePlugin* _corePlugin = nullptr;
FirmwarePluginManager* _firmwarePluginManager = nullptr;
SettingsManager* _settingsManager = nullptr;
FactGroup* _gpsRtkFactGroup = nullptr;
AirspaceManager* _airspaceManager = nullptr;
TaisyncManager* _taisyncManager = nullptr;
bool _skipSetupPage = false;
static const char* _flightMapPositionSettingsGroup;
static const char* _flightMapPositionLatitudeSettingsKey;
......
......@@ -205,5 +205,19 @@
"shortDescription": "Request start of MAVLink telemetry streams (ArduPilot only)",
"type": "bool",
"defaultValue": true
},
{
"name": "enableTaisync",
"shortDescription": "Enable Taisync Module Support",
"longDescription": "Enable Taisync Module Support",
"type": "bool",
"defaultValue": false
},
{
"name": "enableTaisyncVideo",
"shortDescription": "Enable Taisync Video Support",
"longDescription": "Enable Taisync Video Support",
"type": "bool",
"defaultValue": true
}
]
......@@ -85,6 +85,8 @@ DECLARE_SETTINGSFACT(AppSettings, defaultFirmwareType)
DECLARE_SETTINGSFACT(AppSettings, gstDebugLevel)
DECLARE_SETTINGSFACT(AppSettings, followTarget)
DECLARE_SETTINGSFACT(AppSettings, apmStartMavlinkStreams)
DECLARE_SETTINGSFACT(AppSettings, enableTaisync)
DECLARE_SETTINGSFACT(AppSettings, enableTaisyncVideo)
DECLARE_SETTINGSFACT_NO_FUNC(AppSettings, indoorPalette)
{
......
......@@ -14,7 +14,7 @@
class AppSettings : public SettingsGroup
{
Q_OBJECT
public:
AppSettings(QObject* parent = nullptr);
......@@ -43,6 +43,8 @@ public:
DEFINE_SETTINGFACT(defaultFirmwareType)
DEFINE_SETTINGFACT(gstDebugLevel)
DEFINE_SETTINGFACT(followTarget)
DEFINE_SETTINGFACT(enableTaisync)
DEFINE_SETTINGFACT(enableTaisyncVideo)
// Although this is a global setting it only affects ArduPilot vehicle since PX4 automatically starts the stream from the vehicle side
DEFINE_SETTINGFACT(apmStartMavlinkStreams)
......
......@@ -72,12 +72,5 @@
"shortDescription": "UDP target host port for autoconnect",
"type": "uint32",
"defaultValue": 14550
},
{
"name": "autoConnectTaisyncUSB",
"shortDescription": "Automatically connect to a Taisync Ground Module",
"longDescription": "If this option is enabled GroundControl will automatically connect to a Taisync Ground Module which is connected via USB.",
"type": "bool",
"defaultValue": false
}
]
......@@ -23,7 +23,6 @@ DECLARE_SETTINGSFACT(AutoConnectSettings, autoConnectUDP)
DECLARE_SETTINGSFACT(AutoConnectSettings, udpListenPort)
DECLARE_SETTINGSFACT(AutoConnectSettings, udpTargetHostIP)
DECLARE_SETTINGSFACT(AutoConnectSettings, udpTargetHostPort)
DECLARE_SETTINGSFACT(AutoConnectSettings, autoconnectTaisyncUSB)
DECLARE_SETTINGSFACT_NO_FUNC(AutoConnectSettings, autoConnectPixhawk)
{
......
......@@ -14,7 +14,7 @@
class AutoConnectSettings : public SettingsGroup
{
Q_OBJECT
public:
AutoConnectSettings(QObject* parent = nullptr);
......@@ -31,6 +31,5 @@ public:
DEFINE_SETTINGFACT(udpListenPort)
DEFINE_SETTINGFACT(udpTargetHostIP)
DEFINE_SETTINGFACT(udpTargetHostPort)
DEFINE_SETTINGFACT(autoconnectTaisyncUSB)
};
......@@ -54,13 +54,19 @@
class SettingsGroup : public QObject
{
Q_OBJECT
public:
/// @param name Name for this Settings group
/// @param settingsGroup Group to place settings in for QSettings::setGroup
SettingsGroup(const QString &name, const QString &settingsGroup, QObject* parent = nullptr);
Q_PROPERTY(bool visible MEMBER _visible CONSTANT)
Q_PROPERTY(bool visible READ visible WRITE setVisible NOTIFY visibleChanged)
virtual bool visible () { return _visible; }
virtual void setVisible (bool vis) { _visible = vis; emit visibleChanged(); }
signals:
void visibleChanged ();
protected:
SettingsFact* _createSettingsFact(const QString& factName);
......
/****************************************************************************
*
* (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.
*
****************************************************************************/
#include "TaisyncHandler.h"
#include "SettingsManager.h"
#include "QGCApplication.h"
#include "VideoManager.h"
QGC_LOGGING_CATEGORY(TaisyncLog, "TaisyncLog")
QGC_LOGGING_CATEGORY(TaisyncVerbose, "TaisyncVerbose")
//-----------------------------------------------------------------------------
TaisyncHandler::TaisyncHandler(QObject* parent)
: QObject (parent)
{
}
//-----------------------------------------------------------------------------
TaisyncHandler::~TaisyncHandler()
{
close();
}
//-----------------------------------------------------------------------------
bool TaisyncHandler::close()
{
bool res = (_tcpSocket || _tcpServer);
if(_tcpSocket) {
qCDebug(TaisyncLog) << "Close Taisync TCP socket on port" << _tcpSocket->localPort();
_tcpSocket->close();
_tcpSocket->deleteLater();
_tcpSocket = nullptr;
}
if(_tcpServer) {
qCDebug(TaisyncLog) << "Close Taisync TCP server on port" << _tcpServer->serverPort();;
_tcpServer->close();
_tcpServer->deleteLater();
_tcpServer = nullptr;
}
return res;
}
//-----------------------------------------------------------------------------
bool
TaisyncHandler::_start(uint16_t port, QHostAddress addr)
{
close();
_serverMode = addr == QHostAddress::AnyIPv4;
if(_serverMode) {
if(!_tcpServer) {
qCDebug(TaisyncLog) << "Listen for Taisync TCP on port" << port;
_tcpServer = new QTcpServer(this);
QObject::connect(_tcpServer, &QTcpServer::newConnection, this, &TaisyncHandler::_newConnection);
_tcpServer->listen(QHostAddress::AnyIPv4, port);
}
} else {
_tcpSocket = new QTcpSocket();
QObject::connect(_tcpSocket, &QIODevice::readyRead, this, &TaisyncHandler::_readBytes);
qCDebug(TaisyncLog) << "Connecting to" << addr;
_tcpSocket->connectToHost(addr, port);
if (!_tcpSocket->waitForConnected(1000)) {
close();
return false;
}
emit connected();
}
return true;
}
//-----------------------------------------------------------------------------
void
TaisyncHandler::_newConnection()
{
qCDebug(TaisyncLog) << "New Taisync TCP Connection on port" << _tcpServer->serverPort();
if(_tcpSocket) {
_tcpSocket->close();
_tcpSocket->deleteLater();
}
_tcpSocket = _tcpServer->nextPendingConnection();
if(_tcpSocket) {
QObject::connect(_tcpSocket, &QIODevice::readyRead, this, &TaisyncHandler::_readBytes);
QObject::connect(_tcpSocket, &QAbstractSocket::disconnected, this, &TaisyncHandler::_socketDisconnected);
emit connected();
} else {
qCWarning(TaisyncLog) << "New Taisync TCP Connection provided no socket";
}
}
//-----------------------------------------------------------------------------
void
TaisyncHandler::_socketDisconnected()
{
qCDebug(TaisyncLog) << "Taisync TCP Connection Closed on port" << _tcpSocket->localPort();
if(_tcpSocket) {
_tcpSocket->close();
_tcpSocket->deleteLater();
_tcpSocket = nullptr;
}
emit disconnected();
}
/****************************************************************************
*
* (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.
*
****************************************************************************/
#pragma once
#include "QGCLoggingCategory.h"
#include <QTcpServer>
#include <QTcpSocket>
#if defined(__ios__) || defined(__android__)
#define TAISYNC_VIDEO_UDP_PORT 5600
#define TAISYNC_VIDEO_TCP_PORT 8000
#define TAISYNC_SETTINGS_PORT 8200
#define TAISYNC_TELEM_PORT 8400
#define TAISYNC_TELEM_TARGET_PORT 14550
#else
#define TAISYNC_SETTINGS_PORT 80
#endif
Q_DECLARE_LOGGING_CATEGORY(TaisyncLog)
Q_DECLARE_LOGGING_CATEGORY(TaisyncVerbose)
class TaisyncHandler : public QObject
{
Q_OBJECT
public:
explicit TaisyncHandler (QObject* parent = nullptr);
~TaisyncHandler ();
virtual bool start () = 0;
virtual bool close ();
virtual bool isServerRunning () { return (_serverMode && _tcpServer); }
protected:
virtual bool _start (uint16_t port, QHostAddress addr = QHostAddress::AnyIPv4);
protected slots:
virtual void _newConnection ();
virtual void _socketDisconnected ();
virtual void _readBytes () = 0;
signals:
void connected ();
void disconnected ();
protected:
bool _serverMode = true;
QTcpServer* _tcpServer = nullptr;
QTcpSocket* _tcpSocket = nullptr;
};
This diff is collapsed.
/****************************************************************************
*
* (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.
*
****************************************************************************/
#pragma once
#include "QGCToolbox.h"
#include "QGCLoggingCategory.h"
#include "TaisyncSettings.h"
#include "Fact.h"
#if defined(__ios__) || defined(__android__)
#include "TaisyncTelemetry.h"
#include "TaisyncVideoReceiver.h"
#endif
#include <QTimer>
#include <QTime>
class AppSettings;
class QGCApplication;
//-----------------------------------------------------------------------------
class TaisyncManager : public QGCTool
{
Q_OBJECT
public:
Q_PROPERTY(bool connected READ connected NOTIFY connectedChanged)
Q_PROPERTY(bool linkConnected READ linkConnected NOTIFY linkConnectedChanged)
Q_PROPERTY(bool needReboot READ needReboot NOTIFY needRebootChanged)
Q_PROPERTY(QString linkVidFormat READ linkVidFormat NOTIFY linkChanged)
Q_PROPERTY(int uplinkRSSI READ uplinkRSSI NOTIFY linkChanged)
Q_PROPERTY(int downlinkRSSI READ downlinkRSSI NOTIFY linkChanged)
Q_PROPERTY(QString serialNumber READ serialNumber NOTIFY infoChanged)
Q_PROPERTY(QString fwVersion READ fwVersion NOTIFY infoChanged)
Q_PROPERTY(Fact* radioMode READ radioMode CONSTANT)
Q_PROPERTY(Fact* radioChannel READ radioChannel CONSTANT)
Q_PROPERTY(Fact* videoOutput READ videoOutput CONSTANT)
Q_PROPERTY(Fact* videoMode READ videoMode CONSTANT)
Q_PROPERTY(Fact* videoRate READ videoRate CONSTANT)
Q_PROPERTY(QString rtspURI READ rtspURI NOTIFY rtspURIChanged)
Q_PROPERTY(QString rtspAccount READ rtspAccount NOTIFY rtspAccountChanged)
Q_PROPERTY(QString rtspPassword READ rtspPassword NOTIFY rtspPasswordChanged)
Q_PROPERTY(QString localIPAddr READ localIPAddr NOTIFY localIPAddrChanged)
Q_PROPERTY(QString remoteIPAddr READ remoteIPAddr NOTIFY remoteIPAddrChanged)
Q_PROPERTY(QString netMask READ netMask NOTIFY netMaskChanged)
Q_INVOKABLE bool setRTSPSettings (QString uri, QString account, QString password);
Q_INVOKABLE bool setIPSettings (QString localIP, QString remoteIP, QString netMask);
explicit TaisyncManager (QGCApplication* app, QGCToolbox* toolbox);
~TaisyncManager () override;
void setToolbox (QGCToolbox* toolbox) override;
bool connected () { return _isConnected; }
bool linkConnected () { return _linkConnected; }
bool needReboot () { return _needReboot; }
QString linkVidFormat () { return _linkVidFormat; }
int uplinkRSSI () { return _downlinkRSSI; }
int downlinkRSSI () { return _uplinkRSSI; }
QString serialNumber () { return _serialNumber; }
QString fwVersion () { return _fwVersion; }
Fact* radioMode () { return _radioMode; }
Fact* radioChannel () { return _radioChannel; }
Fact* videoOutput () { return _videoOutput; }
Fact* videoMode () { return _videoMode; }
Fact* videoRate () { return _videoRate; }
QString rtspURI () { return _rtspURI; }
QString rtspAccount () { return _rtspAccount; }
QString rtspPassword () { return _rtspPassword; }
QString localIPAddr () { return _localIPAddr; }
QString remoteIPAddr () { return _remoteIPAddr; }
QString netMask () { return _netMask; }
signals:
void linkChanged ();
void linkConnectedChanged ();
void infoChanged ();
void connectedChanged ();
void decodeIndexChanged ();
void rateIndexChanged ();
void rtspURIChanged ();
void rtspAccountChanged ();
void rtspPasswordChanged ();
void localIPAddrChanged ();
void remoteIPAddrChanged ();
void netMaskChanged ();
void needRebootChanged ();
private slots:
void _connected ();
void _disconnected ();
void _checkTaisync ();
void _updateSettings (QByteArray jSonData);
void _setEnabled ();
void _setVideoEnabled ();
void _radioSettingsChanged (QVariant);
void _videoSettingsChanged (QVariant);
#if defined(__ios__) || defined(__android__)
void _readUDPBytes ();
void _readTelemBytes (QByteArray bytesIn);
#endif
private:
void _close ();
void _reset ();
FactMetaData *_createMetadata (const char *name, QStringList enums);
private:
enum {
REQ_LINK_STATUS = 1,
REQ_DEV_INFO = 2,
REQ_FREQ_SCAN = 4,
REQ_VIDEO_SETTINGS = 8,
REQ_RADIO_SETTINGS = 16,
REQ_RTSP_SETTINGS = 32,
REQ_IP_SETTINGS = 64,
REQ_ALL = 0xFFFFFFFF,
};
uint32_t _reqMask = REQ_ALL;
bool _running = false;
bool _isConnected = false;
AppSettings* _appSettings = nullptr;
TaisyncManager* _taiManager = nullptr;
TaisyncSettings* _taiSettings = nullptr;
#if defined(__ios__) || defined(__android__)
TaisyncTelemetry* _taiTelemetery = nullptr;
TaisyncVideoReceiver* _taiVideo = nullptr;
QUdpSocket* _telemetrySocket= nullptr;
#endif
bool _enableVideo = true;
bool _enabled = true;
bool _linkConnected = false;
bool _needReboot = false;
QTimer _workTimer;
QString _linkVidFormat;
int _downlinkRSSI = 0;
int _uplinkRSSI = 0;
QStringList _decodeList;
int _decodeIndex = 0;
QStringList _rateList;
int _rateIndex = 0;
bool _savedVideoState = true;
QVariant _savedVideoSource;
QVariant _savedVideoUDP;
QVariant _savedAR;
QString _serialNumber;
QString _fwVersion;
Fact* _radioMode = nullptr;
Fact* _radioChannel = nullptr;
Fact* _videoOutput = nullptr;
Fact* _videoMode = nullptr;
Fact* _videoRate = nullptr;
QStringList _radioModeList;
QStringList _videoOutputList;
QStringList _videoRateList;
QString _rtspURI;
QString _rtspAccount;
QString _rtspPassword;
QString _localIPAddr;
QString _remoteIPAddr;
QString _netMask;
QTime _timeoutTimer;
};
/****************************************************************************
*
* (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.
*
****************************************************************************/
#include "TaisyncManager.h"
#include "TaisyncSettings.h"
#include "SettingsManager.h"
#include "QGCApplication.h"
#include "VideoManager.h"
static const char* kPostReq =
"POST %1 HTTP/1.1\r\n"
"Content-Type: application/json\r\n"
"Content-Length: %2\r\n\r\n"
"%3";
static const char* kGetReq = "GET %1 HTTP/1.1\r\n\r\n";
static const char* kRadioURI = "/v1/radio.json";
static const char* kVideoURI = "/v1/video.json";
static const char* kRTSPURI = "/v1/rtspuri.json";
static const char* kIPAddrURI = "/v1/ipaddr.json";
//-----------------------------------------------------------------------------
TaisyncSettings::TaisyncSettings(QObject* parent)
: TaisyncHandler(parent)
{
}
//-----------------------------------------------------------------------------
bool TaisyncSettings::start()
{
qCDebug(TaisyncLog) << "Start Taisync Settings";
#if defined(__ios__) || defined(__android__)
return _start(TAISYNC_SETTINGS_PORT);
#else
return _start(TAISYNC_SETTINGS_PORT, QHostAddress(qgcApp()->toolbox()->taisyncManager()->remoteIPAddr()));
#endif
}
//-----------------------------------------------------------------------------
bool
TaisyncSettings::requestLinkStatus()
{
return _request("/v1/baseband.json");
}
//-----------------------------------------------------------------------------
bool
TaisyncSettings::requestDevInfo()
{
return _request("/v1/device.json");
}
//-----------------------------------------------------------------------------
bool
TaisyncSettings::requestFreqScan()
{
return _request("/v1/freqscan.json");
}
//-----------------------------------------------------------------------------
bool
TaisyncSettings::requestVideoSettings()
{
return _request(kVideoURI);
}
//-----------------------------------------------------------------------------
bool
TaisyncSettings::requestRadioSettings()
{
return _request(kRadioURI);
}
//-----------------------------------------------------------------------------
bool
TaisyncSettings::requestIPSettings()
{
return _request(kIPAddrURI);
}
//-----------------------------------------------------------------------------
bool
TaisyncSettings::requestRTSPURISettings()
{
return _request(kRTSPURI);
}
//-----------------------------------------------------------------------------
bool
TaisyncSettings::_request(const QString& request)
{
if(_tcpSocket) {
QString req = QString(kGetReq).arg(request);
//qCDebug(TaisyncVerbose) << "Request" << req;
_tcpSocket->write(req.toUtf8());
return true;
}
return false;
}
//-----------------------------------------------------------------------------
bool
TaisyncSettings::_post(const QString& post, const QString &postPayload)
{
if(_tcpSocket) {
QString req = QString(kPostReq).arg(post).arg(postPayload.size()).arg(postPayload);
qCDebug(TaisyncVerbose) << "Post" << req;
_tcpSocket->write(req.toUtf8());
return true;
}
return false;
}
//-----------------------------------------------------------------------------
bool
TaisyncSettings::setRadioSettings(const QString& mode, const QString& channel)
{
static const char* kRadioPost = "{\"mode\":\"%1\",\"freq\":\"%2\"}";
QString post = QString(kRadioPost).arg(mode).arg(channel);
return _post(kRadioURI, post);
}
//-----------------------------------------------------------------------------
bool
TaisyncSettings::setVideoSettings(const QString& output, const QString& mode, const QString& rate)
{
static const char* kVideoPost = "{\"decode\":\"%1\",\"mode\":\"%2\",\"maxbitrate\":\"%3\"}";
QString post = QString(kVideoPost).arg(output).arg(mode).arg(rate);
return _post(kVideoURI, post);
}
//-----------------------------------------------------------------------------
bool
TaisyncSettings::setRTSPSettings(const QString& uri, const QString& account, const QString& password)
{
static const char* kRTSPPost = "{\"rtspURI\":\"%1\",\"account\":\"%2\",\"passwd\":\"%3\"}";
QString post = QString(kRTSPPost).arg(uri).arg(account).arg(password);
return _post(kRTSPURI, post);
}
//-----------------------------------------------------------------------------
bool
TaisyncSettings::setIPSettings(const QString& localIP, const QString& remoteIP, const QString& netMask)
{
static const char* kRTSPPost = "{\"ipaddr\":\"%1\",\"netmask\":\"%2\",\"usbEthIp\":\"%3\"}";
QString post = QString(kRTSPPost).arg(localIP).arg(netMask).arg(remoteIP);
return _post(kIPAddrURI, post);
}
//-----------------------------------------------------------------------------
void
TaisyncSettings::_readBytes()
{
QByteArray bytesIn = _tcpSocket->read(_tcpSocket->bytesAvailable());
//-- Go straight to Json payload
int idx = bytesIn.indexOf('{');
//-- We may receive more than one response within one TCP packet.
while(idx >= 0) {
bytesIn = bytesIn.mid(idx);
idx = bytesIn.indexOf('}');
if(idx > 0) {
QByteArray data = bytesIn.left(idx + 1);
emit updateSettings(data);
bytesIn = bytesIn.mid(idx+1);
idx = bytesIn.indexOf('{');
}
}
}
/****************************************************************************
*
* (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.
*
****************************************************************************/
#pragma once
#include "TaisyncHandler.h"
class TaisyncSettings : public TaisyncHandler
{
Q_OBJECT
public:
explicit TaisyncSettings (QObject* parent = nullptr);
bool start () override;
bool requestLinkStatus ();
bool requestDevInfo ();
bool requestFreqScan ();
bool requestVideoSettings ();
bool requestRadioSettings ();
bool requestIPSettings ();
bool requestRTSPURISettings ();
bool setRadioSettings (const QString& mode, const QString& channel);
bool setVideoSettings (const QString& output, const QString& mode, const QString& rate);
bool setRTSPSettings (const QString& uri, const QString& account, const QString& password);
bool setIPSettings (const QString& localIP, const QString& remoteIP, const QString& netMask);
signals:
void updateSettings (QByteArray jSonData);
protected slots:
void _readBytes () override;
private:
bool _request (const QString& request);
bool _post (const QString& post, const QString& postPayload);
};
This diff is collapsed.
/****************************************************************************
*
* (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.
*
****************************************************************************/
#include "TaisyncTelemetry.h"
#include "SettingsManager.h"
#include "QGCApplication.h"
#include "VideoManager.h"
//-----------------------------------------------------------------------------
TaisyncTelemetry::TaisyncTelemetry(QObject* parent)
: TaisyncHandler(parent)
{
}
//-----------------------------------------------------------------------------
bool
TaisyncTelemetry::close()
{
if(TaisyncHandler::close()) {
qCDebug(TaisyncLog) << "Close Taisync Telemetry";
return true;
}
return false;
}
//-----------------------------------------------------------------------------
bool TaisyncTelemetry::start()
{
qCDebug(TaisyncLog) << "Start Taisync Telemetry";
return _start(TAISYNC_TELEM_PORT);
}
//-----------------------------------------------------------------------------
void
TaisyncTelemetry::writeBytes(QByteArray bytes)
{
if(_tcpSocket) {
_tcpSocket->write(bytes);
}
}
//-----------------------------------------------------------------------------
void
TaisyncTelemetry::_newConnection()
{
TaisyncHandler::_newConnection();
qCDebug(TaisyncLog) << "New Taisync Temeletry Connection";
}
//-----------------------------------------------------------------------------
void
TaisyncTelemetry::_readBytes()
{
while(_tcpSocket->bytesAvailable()) {
QByteArray bytesIn = _tcpSocket->read(_tcpSocket->bytesAvailable());
emit bytesReady(bytesIn);
}
}
/****************************************************************************
*
* (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.
*
****************************************************************************/
#pragma once
#include "TaisyncHandler.h"
#include <QUdpSocket>
#include <QTimer>
class TaisyncTelemetry : public TaisyncHandler
{
Q_OBJECT
public:
explicit TaisyncTelemetry (QObject* parent = nullptr);
bool close () override;
bool start () override;
void writeBytes (QByteArray bytes);
signals:
void bytesReady (QByteArray bytes);
private slots:
void _newConnection () override;
void _readBytes () override;
};
/****************************************************************************
*
* (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.
*
****************************************************************************/
#include "TaisyncVideoReceiver.h"
#include "SettingsManager.h"
#include "QGCApplication.h"
#include "VideoManager.h"
//-----------------------------------------------------------------------------
TaisyncVideoReceiver::TaisyncVideoReceiver(QObject* parent)
: TaisyncHandler(parent)
{
}
//-----------------------------------------------------------------------------
bool
TaisyncVideoReceiver::close()
{
if(TaisyncHandler::close() || _udpVideoSocket) {
qCDebug(TaisyncLog) << "Close Taisync Video Receiver";
if(_udpVideoSocket) {
_udpVideoSocket->close();
_udpVideoSocket->deleteLater();
_udpVideoSocket = nullptr;
}
return true;
}
return false;
}
//-----------------------------------------------------------------------------
bool
TaisyncVideoReceiver::start()
{
qCDebug(TaisyncLog) << "Start Taisync Video Receiver";
if(_start(TAISYNC_VIDEO_TCP_PORT)) {
_udpVideoSocket = new QUdpSocket(this);
return true;
}
return false;
}
//-----------------------------------------------------------------------------
void
TaisyncVideoReceiver::_readBytes()
{
if(_udpVideoSocket) {
QByteArray bytesIn = _tcpSocket->read(_tcpSocket->bytesAvailable());
_udpVideoSocket->writeDatagram(bytesIn, QHostAddress::LocalHost, TAISYNC_VIDEO_UDP_PORT);
}
}
/****************************************************************************
*
* (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.
*
****************************************************************************/
#pragma once
#include "TaisyncHandler.h"
#include <QUdpSocket>
class TaisyncVideoReceiver : public TaisyncHandler
{
Q_OBJECT
public:
explicit TaisyncVideoReceiver (QObject* parent = nullptr);
bool start () override;
bool close () override;
private slots:
void _readBytes () override;
private:
QUdpSocket* _udpVideoSocket = nullptr;
};
......@@ -18,7 +18,9 @@
#include "SettingsManager.h"
#include "QGCApplication.h"
#include "VideoManager.h"
#ifdef QGC_GST_TAISYNC_ENABLED
#include "TaisyncHandler.h"
#endif
#include <QDebug>
#include <QUrl>
#include <QDir>
......@@ -218,6 +220,10 @@ VideoReceiver::_timeout()
void
VideoReceiver::start()
{
qCDebug(VideoReceiverLog) << "start():" << _uri;
if(qgcApp()->runningUnitTests()) {
return;
}
if(!_videoSettings->streamEnabled()->rawValue().toBool() ||
!_videoSettings->streamConfigured()) {
qCDebug(VideoReceiverLog) << "start() but not enabled/configured";
......@@ -227,7 +233,17 @@ VideoReceiver::start()
_stop = false;
qCDebug(VideoReceiverLog) << "start()";
if (_uri.isEmpty()) {
#if defined(QGC_GST_TAISYNC_ENABLED) && (defined(__android__) || defined(__ios__))
//-- Taisync on iOS or Android sends a raw h.264 stream
bool isTaisyncUSB = qgcApp()->toolbox()->videoManager()->isTaisync();
#else
bool isTaisyncUSB = false;
#endif
bool isUdp = _uri.contains("udp://") && !isTaisyncUSB;
bool isRtsp = _uri.contains("rtsp://") && !isTaisyncUSB;
bool isTCP = _uri.contains("tcp://") && !isTaisyncUSB;
if (!isTaisyncUSB && _uri.isEmpty()) {
qCritical() << "VideoReceiver::start() failed because URI is not specified";
return;
}
......@@ -242,17 +258,13 @@ VideoReceiver::start()
_starting = true;
bool isUdp = _uri.contains("udp://");
bool isRtsp = _uri.contains("rtsp://");
bool isTCP = _uri.contains("tcp://");
//-- For RTSP and TCP, check to see if server is there first
if(!_serverPresent && (isRtsp || isTCP)) {
_timer.start(100);
return;
}
bool running = false;
bool running = false;
bool pipelineUp = false;
GstElement* dataSource = nullptr;
......@@ -269,7 +281,7 @@ VideoReceiver::start()
break;
}
if(isUdp) {
if(isUdp || isTaisyncUSB) {
dataSource = gst_element_factory_make("udpsrc", "udp-source");
} else if(isTCP) {
dataSource = gst_element_factory_make("tcpclientsrc", "tcpclient-source");
......@@ -287,12 +299,18 @@ VideoReceiver::start()
qCritical() << "VideoReceiver::start() failed. Error with gst_caps_from_string()";
break;
}
g_object_set(G_OBJECT(dataSource), "uri", qPrintable(_uri), "caps", caps, nullptr);
g_object_set(static_cast<gpointer>(dataSource), "uri", qPrintable(_uri), "caps", caps, nullptr);
#if defined(QGC_GST_TAISYNC_ENABLED) && (defined(__android__) || defined(__ios__))
} else if(isTaisyncUSB) {
QString uri = QString("0.0.0.0:%1").arg(TAISYNC_VIDEO_UDP_PORT);
qCDebug(VideoReceiverLog) << "Taisync URI:" << uri;
g_object_set(static_cast<gpointer>(dataSource), "port", TAISYNC_VIDEO_UDP_PORT, nullptr);
#endif
} else if(isTCP) {
QUrl url(_uri);
g_object_set(G_OBJECT(dataSource), "host", qPrintable(url.host()), "port", url.port(), nullptr );
g_object_set(static_cast<gpointer>(dataSource), "host", qPrintable(url.host()), "port", url.port(), nullptr );
} else {
g_object_set(G_OBJECT(dataSource), "location", qPrintable(_uri), "latency", 17, "udp-reconnect", 1, "timeout", _udpReconnect_us, NULL);
g_object_set(static_cast<gpointer>(dataSource), "location", qPrintable(_uri), "latency", 17, "udp-reconnect", 1, "timeout", _udpReconnect_us, NULL);
}
// Currently, we expect H264 when using anything except for TCP. Long term we may want this to be settable
......@@ -302,11 +320,13 @@ VideoReceiver::start()
break;
}
} else {
if ((demux = gst_element_factory_make("rtph264depay", "rtp-h264-depacketizer")) == nullptr) {
if(!isTaisyncUSB) {
if ((demux = gst_element_factory_make("rtph264depay", "rtp-h264-depacketizer")) == nullptr) {
qCritical() << "VideoReceiver::start() failed. Error with gst_element_factory_make('rtph264depay')";
break;
}
}
}
if ((parser = gst_element_factory_make("h264parse", "h264-parser")) == nullptr) {
qCritical() << "VideoReceiver::start() failed. Error with gst_element_factory_make('h264parse')";
......@@ -335,7 +355,11 @@ VideoReceiver::start()
break;
}
gst_bin_add_many(GST_BIN(_pipeline), dataSource, demux, parser, _tee, queue, decoder, queue1, _videoSink, nullptr);
if(isTaisyncUSB) {
gst_bin_add_many(GST_BIN(_pipeline), dataSource, parser, _tee, queue, decoder, queue1, _videoSink, nullptr);
} else {
gst_bin_add_many(GST_BIN(_pipeline), dataSource, demux, parser, _tee, queue, decoder, queue1, _videoSink, nullptr);
}
pipelineUp = true;
if(isUdp) {
......@@ -344,6 +368,12 @@ VideoReceiver::start()
qCritical() << "Unable to link UDP elements.";
break;
}
} else if(isTaisyncUSB) {
// Link the pipeline in front of the tee
if(!gst_element_link_many(dataSource, parser, _tee, queue, decoder, queue1, _videoSink, nullptr)) {
qCritical() << "Unable to link Taisync USB elements.";
break;
}
} else if (isTCP) {
if(!gst_element_link(dataSource, demux)) {
qCritical() << "Unable to link TCP dataSource to Demux.";
......@@ -439,6 +469,9 @@ VideoReceiver::start()
void
VideoReceiver::stop()
{
if(!qgcApp()->runningUnitTests()) {
return;
}
#if defined(QGC_GST_STREAMING)
_stop = true;
qCDebug(VideoReceiverLog) << "stop()";
......@@ -666,7 +699,7 @@ VideoReceiver::startRecording(const QString &videoFile)
}
emit videoFileChanged();
g_object_set(G_OBJECT(_sink->filesink), "location", qPrintable(_videoFile), nullptr);
g_object_set(static_cast<gpointer>(_sink->filesink), "location", qPrintable(_videoFile), nullptr);
qCDebug(VideoReceiverLog) << "New video file:" << _videoFile;
gst_object_ref(_sink->queue);
......
......@@ -29,25 +29,6 @@ class QGCCorePlugin_p
{
public:
QGCCorePlugin_p()
: pGeneral (nullptr)
, pCommLinks (nullptr)
, pOfflineMaps (nullptr)
#if defined(QGC_AIRMAP_ENABLED)
, pAirmap (nullptr)
#endif
, pMAVLink (nullptr)
, pConsole (nullptr)
, pHelp (nullptr)
#if defined(QT_DEBUG)
, pMockLink (nullptr)
, pDebug (nullptr)
#endif
, defaultOptions (nullptr)
, valuesPageWidgetInfo (nullptr)
, cameraPageWidgetInfo (nullptr)
, videoPageWidgetInfo (nullptr)
, healthPageWidgetInfo (nullptr)
, vibrationPageWidgetInfo (nullptr)
{
}
......@@ -59,6 +40,10 @@ public:
delete pCommLinks;
if(pOfflineMaps)
delete pOfflineMaps;
#if defined(QGC_GST_TAISYNC_ENABLED)
if(pTaisync)
delete pTaisync;
#endif
#if defined(QGC_AIRMAP_ENABLED)
if(pAirmap)
delete pAirmap;
......@@ -77,27 +62,31 @@ public:
delete defaultOptions;
}
QmlComponentInfo* pGeneral;
QmlComponentInfo* pCommLinks;
QmlComponentInfo* pOfflineMaps;
QmlComponentInfo* pGeneral = nullptr;
QmlComponentInfo* pCommLinks = nullptr;
QmlComponentInfo* pOfflineMaps = nullptr;
#if defined(QGC_GST_TAISYNC_ENABLED)
QmlComponentInfo* pTaisync = nullptr;
#endif
#if defined(QGC_AIRMAP_ENABLED)
QmlComponentInfo* pAirmap;
QmlComponentInfo* pAirmap = nullptr;
#endif
QmlComponentInfo* pMAVLink;
QmlComponentInfo* pConsole;
QmlComponentInfo* pHelp;
QmlComponentInfo* pMAVLink = nullptr;
QmlComponentInfo* pConsole = nullptr;
QmlComponentInfo* pHelp = nullptr;
#if defined(QT_DEBUG)
QmlComponentInfo* pMockLink;
QmlComponentInfo* pDebug;
QmlComponentInfo* pMockLink = nullptr;
QmlComponentInfo* pDebug = nullptr;
#endif
QVariantList settingsList;
QGCOptions* defaultOptions;
QmlComponentInfo* valuesPageWidgetInfo;
QmlComponentInfo* cameraPageWidgetInfo;
QmlComponentInfo* videoPageWidgetInfo;
QmlComponentInfo* healthPageWidgetInfo;
QmlComponentInfo* vibrationPageWidgetInfo;
QmlComponentInfo* valuesPageWidgetInfo = nullptr;
QmlComponentInfo* cameraPageWidgetInfo = nullptr;
QmlComponentInfo* videoPageWidgetInfo = nullptr;
QmlComponentInfo* healthPageWidgetInfo = nullptr;
QmlComponentInfo* vibrationPageWidgetInfo = nullptr;
QGCOptions* defaultOptions = nullptr;
QVariantList settingsList;
QVariantList instrumentPageWidgetList;
QmlObjectListModel _emptyCustomMapItems;
......@@ -141,6 +130,12 @@ QVariantList &QGCCorePlugin::settingsPages()
QUrl::fromUserInput("qrc:/qml/OfflineMap.qml"),
QUrl::fromUserInput("qrc:/res/waves.svg"));
_p->settingsList.append(QVariant::fromValue(reinterpret_cast<QmlComponentInfo*>(_p->pOfflineMaps)));
#if defined(QGC_GST_TAISYNC_ENABLED)
_p->pTaisync = new QmlComponentInfo(tr("Taisync"),
QUrl::fromUserInput("qrc:/qml/TaisyncSettings.qml"),
QUrl::fromUserInput(""));
_p->settingsList.append(QVariant::fromValue(reinterpret_cast<QmlComponentInfo*>(_p->pTaisync)));
#endif
#if defined(QGC_AIRMAP_ENABLED)
_p->pAirmap = new QmlComponentInfo(tr("AirMap"),
QUrl::fromUserInput("qrc:/qml/AirmapSettings.qml"),
......
......@@ -33,7 +33,7 @@
#define LINK_SETTING_ROOT "LinkConfigurations"
LinkConfiguration::LinkConfiguration(const QString& name)
: _link(NULL)
: _link(nullptr)
, _name(name)
, _dynamic(false)
, _autoConnect(false)
......@@ -80,7 +80,7 @@ const QString LinkConfiguration::settingsRoot()
*/
LinkConfiguration* LinkConfiguration::createSettings(int type, const QString& name)
{
LinkConfiguration* config = NULL;
LinkConfiguration* config = nullptr;
switch(type) {
#ifndef NO_SERIAL_LINK
case LinkConfiguration::TypeSerial:
......@@ -118,7 +118,7 @@ LinkConfiguration* LinkConfiguration::createSettings(int type, const QString& na
*/
LinkConfiguration* LinkConfiguration::duplicateSettings(LinkConfiguration* source)
{
LinkConfiguration* dupe = NULL;
LinkConfiguration* dupe = nullptr;
switch(source->type()) {
#ifndef NO_SERIAL_LINK
case TypeSerial:
......@@ -147,7 +147,6 @@ LinkConfiguration* LinkConfiguration::duplicateSettings(LinkConfiguration* sourc
break;
#endif
case TypeLast:
default:
break;
}
return dupe;
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment