Commit 9dba67b9 authored by Gus Grubba's avatar Gus Grubba

Initial work on video stream discovery

parent cafc8cee
......@@ -22,7 +22,7 @@ import QGroundControl.Controllers 1.0
Item {
id: root
property double _ar: QGroundControl.settingsManager.videoSettings.aspectRatio.rawValue
property double _ar: QGroundControl.videoManager.aspectRatio
property bool _showGrid: QGroundControl.settingsManager.videoSettings.gridLines.rawValue > 0
property var _videoReceiver: QGroundControl.videoManager.videoReceiver
property var _activeVehicle: QGroundControl.multiVehicleManager.activeVehicle
......
......@@ -25,7 +25,9 @@
#include "QGCToolbox.h"
#include "QGCCorePlugin.h"
#include "QGCOptions.h"
#include "MultiVehicleManager.h"
#include "Settings/SettingsManager.h"
#include "Vehicle.h"
QGC_LOGGING_CATEGORY(VideoManagerLog, "VideoManagerLog")
......@@ -35,6 +37,7 @@ VideoManager::VideoManager(QGCApplication* app, QGCToolbox* toolbox)
, _videoReceiver(nullptr)
, _videoSettings(nullptr)
, _fullScreen(false)
, _activeVehicle(nullptr)
{
}
......@@ -61,6 +64,9 @@ VideoManager::setToolbox(QGCToolbox *toolbox)
connect(_videoSettings->udpPort(), &Fact::rawValueChanged, this, &VideoManager::_udpPortChanged);
connect(_videoSettings->rtspUrl(), &Fact::rawValueChanged, this, &VideoManager::_rtspUrlChanged);
connect(_videoSettings->tcpUrl(), &Fact::rawValueChanged, this, &VideoManager::_tcpUrlChanged);
connect(_videoSettings->aspectRatio(), &Fact::rawValueChanged, this, &VideoManager::_aspectRatioChanged);
MultiVehicleManager *manager = qgcApp()->toolbox()->multiVehicleManager();
connect(manager, &MultiVehicleManager::activeVehicleChanged, this, &VideoManager::_setActiveVehicle);
#if defined(QGC_GST_STREAMING)
#ifndef QGC_DISABLE_UVC
......@@ -81,6 +87,19 @@ VideoManager::setToolbox(QGCToolbox *toolbox)
#endif
}
//-----------------------------------------------------------------------------
double VideoManager::aspectRatio()
{
if(isAutoStream()) {
if(_streamInfo.resolution_h && _streamInfo.resolution_v) {
return static_cast<double>(_streamInfo.resolution_h) / static_cast<double>(_streamInfo.resolution_v);
}
return 1.0;
} else {
return _videoSettings->aspectRatio()->rawValue().toDouble();
}
}
//-----------------------------------------------------------------------------
void
VideoManager::_updateUVC()
......@@ -106,6 +125,7 @@ VideoManager::_videoSourceChanged()
_updateUVC();
emit hasVideoChanged();
emit isGStreamerChanged();
emit isAutoStreamChanged();
_restartVideo();
}
......@@ -144,7 +164,23 @@ VideoManager::isGStreamer()
{
#if defined(QGC_GST_STREAMING)
QString videoSource = _videoSettings->videoSource()->rawValue().toString();
return videoSource == VideoSettings::videoSourceUDP || videoSource == VideoSettings::videoSourceRTSP || videoSource == VideoSettings::videoSourceTCP;
return
videoSource == VideoSettings::videoSourceUDP ||
videoSource == VideoSettings::videoSourceRTSP ||
videoSource == VideoSettings::videoSourceAuto ||
videoSource == VideoSettings::videoSourceTCP;
#else
return false;
#endif
}
//-----------------------------------------------------------------------------
bool
VideoManager::isAutoStream()
{
#if defined(QGC_GST_STREAMING)
QString videoSource = _videoSettings->videoSource()->rawValue().toString();
return videoSource == VideoSettings::videoSourceAuto;
#else
return false;
#endif
......@@ -171,6 +207,8 @@ VideoManager::_updateSettings()
_videoReceiver->setUri(_videoSettings->rtspUrl()->rawValue().toString());
else if (_videoSettings->videoSource()->rawValue().toString() == VideoSettings::videoSourceTCP)
_videoReceiver->setUri(QStringLiteral("tcp://%1").arg(_videoSettings->tcpUrl()->rawValue().toString()));
else if (isAutoStream())
_videoReceiver->setUri(QString(_streamInfo.uri));
}
//-----------------------------------------------------------------------------
......@@ -185,3 +223,45 @@ VideoManager::_restartVideo()
_videoReceiver->start();
#endif
}
//----------------------------------------------------------------------------------------
void
VideoManager::_setActiveVehicle(Vehicle* vehicle)
{
if(_activeVehicle) {
disconnect(_activeVehicle, &Vehicle::mavlinkMessageReceived, this, &VideoManager::_vehicleMessageReceived);
}
_activeVehicle = vehicle;
if(_activeVehicle) {
if(isAutoStream()) {
_videoReceiver->stop();
}
//-- Video Stream Discovery
connect(_activeVehicle, &Vehicle::mavlinkMessageReceived, this, &VideoManager::_vehicleMessageReceived);
_activeVehicle->sendMavCommand(
0, // Target component
MAV_CMD_REQUEST_VIDEO_STREAM_INFORMATION, // Command id
false, // ShowError
1, // First camera only
0); // Reserved (Set to 0)
}
}
//----------------------------------------------------------------------------------------
void
VideoManager::_vehicleMessageReceived(const mavlink_message_t& message)
{
//-- For now we only handle one stream. There is no UI to pick different streams.
if(message.msgid == MAVLINK_MSG_ID_VIDEO_STREAM_INFORMATION) {
mavlink_msg_video_stream_information_decode(&message, &_streamInfo);
_restartVideo();
emit aspectRatioChanged();
}
}
//----------------------------------------------------------------------------------------
void
VideoManager::_aspectRatioChanged()
{
emit aspectRatioChanged();
}
......@@ -15,6 +15,7 @@
#include <QTimer>
#include <QUrl>
#include "QGCMAVLink.h"
#include "QGCLoggingCategory.h"
#include "VideoReceiver.h"
#include "QGCToolbox.h"
......@@ -22,6 +23,7 @@
Q_DECLARE_LOGGING_CATEGORY(VideoManagerLog)
class VideoSettings;
class Vehicle;
class VideoManager : public QGCTool
{
......@@ -33,15 +35,20 @@ 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(QString videoSourceID READ videoSourceID NOTIFY videoSourceIDChanged)
Q_PROPERTY(bool uvcEnabled READ uvcEnabled CONSTANT)
Q_PROPERTY(bool fullScreen READ fullScreen WRITE setfullScreen NOTIFY fullScreenChanged)
Q_PROPERTY(VideoReceiver* videoReceiver READ videoReceiver CONSTANT)
Q_PROPERTY(double aspectRatio READ aspectRatio NOTIFY aspectRatioChanged)
bool hasVideo ();
bool isGStreamer ();
bool isAutoStream ();
bool fullScreen () { return _fullScreen; }
QString videoSourceID () { return _videoSourceID; }
QString autoURL () { return QString(_streamInfo.uri); }
double aspectRatio ();
VideoReceiver* videoReceiver () { return _videoReceiver; }
......@@ -64,6 +71,8 @@ signals:
void isGStreamerChanged ();
void videoSourceIDChanged ();
void fullScreenChanged ();
void isAutoStreamChanged ();
void aspectRatioChanged ();
private slots:
void _videoSourceChanged ();
......@@ -71,6 +80,9 @@ private slots:
void _rtspUrlChanged ();
void _tcpUrlChanged ();
void _updateUVC ();
void _aspectRatioChanged ();
void _setActiveVehicle (Vehicle* vehicle);
void _vehicleMessageReceived (const mavlink_message_t& message);
private:
void _updateSettings ();
......@@ -80,6 +92,8 @@ private:
VideoSettings* _videoSettings;
QString _videoSourceID;
bool _fullScreen;
Vehicle* _activeVehicle;
mavlink_video_stream_information_t _streamInfo;
};
#endif
......@@ -8,6 +8,8 @@
****************************************************************************/
#include "VideoSettings.h"
#include "QGCApplication.h"
#include "VideoManager.h"
#include <QQmlEngine>
#include <QtQml>
......@@ -17,14 +19,12 @@
#include <QCameraInfo>
#endif
const char* VideoSettings::videoSourceNoVideo = "No Video Available";
const char* VideoSettings::videoDisabled = "Video Stream Disabled";
const char* VideoSettings::videoSourceUDP = "UDP Video Stream";
const char* VideoSettings::videoSourceRTSP = "RTSP Video Stream";
const char* VideoSettings::videoSourceTCP = "TCP-MPEG2 Video Stream";
#ifdef QGC_GST_TAISYNC_USB
const char* VideoSettings::videoSourceTaiSyncUSB = "Taisync USB";
#endif
const char* VideoSettings::videoSourceNoVideo = "No Video Available";
const char* VideoSettings::videoDisabled = "Video Stream Disabled";
const char* VideoSettings::videoSourceAuto = "Automatic Video Stream";
const char* VideoSettings::videoSourceRTSP = "RTSP Video Stream";
const char* VideoSettings::videoSourceUDP = "UDP Video Stream";
const char* VideoSettings::videoSourceTCP = "TCP-MPEG2 Video Stream";
DECLARE_SETTINGGROUP(Video, "Video")
{
......@@ -34,14 +34,12 @@ DECLARE_SETTINGGROUP(Video, "Video")
// Setup enum values for videoSource settings into meta data
QStringList videoSourceList;
#ifdef QGC_GST_STREAMING
videoSourceList.append(videoSourceAuto);
videoSourceList.append(videoSourceRTSP);
#ifndef NO_UDP_VIDEO
videoSourceList.append(videoSourceUDP);
#endif
videoSourceList.append(videoSourceRTSP);
videoSourceList.append(videoSourceTCP);
#ifdef QGC_GST_TAISYNC_USB
videoSourceList.append(videoSourceTaiSyncUSB);
#endif
#endif
#ifndef QGC_DISABLE_UVC
QList<QCameraInfo> cameras = QCameraInfo::availableCameras();
......@@ -60,7 +58,6 @@ DECLARE_SETTINGGROUP(Video, "Video")
videoSourceVarList.append(QVariant::fromValue(videoSource));
}
_nameToMetaDataMap[videoSourceName]->setEnumInfo(videoSourceList, videoSourceVarList);
// Set default value for videoSource
_setDefaults();
}
......@@ -138,11 +135,6 @@ bool VideoSettings::streamConfigured(void)
if(vSource == videoSourceNoVideo || vSource == videoDisabled) {
return false;
}
#ifdef QGC_GST_TAISYNC_USB
if(vSource == videoSourceTaiSyncUSB) {
return true;
}
#endif
//-- If UDP, check if port is set
if(vSource == videoSourceUDP) {
return udpPort()->rawValue().toInt() != 0;
......@@ -151,9 +143,13 @@ bool VideoSettings::streamConfigured(void)
if(vSource == videoSourceRTSP) {
return !rtspUrl()->rawValue().toString().isEmpty();
}
//-- If TCP, check for URL
//-- If Auto, check for URL
if(vSource == videoSourceAuto) {
return !rtspUrl()->rawValue().toString().isEmpty();
}
//-- If Auto, check for received URL
if(vSource == videoSourceTCP) {
return !tcpUrl()->rawValue().toString().isEmpty();
return !qgcApp()->toolbox()->videoManager()->autoURL().isEmpty();
}
return false;
}
......
......@@ -35,18 +35,24 @@ public:
DEFINE_SETTINGFACT(streamEnabled)
DEFINE_SETTINGFACT(disableWhenDisarmed)
Q_PROPERTY(bool streamConfigured READ streamConfigured NOTIFY streamConfiguredChanged)
Q_PROPERTY(bool streamConfigured READ streamConfigured NOTIFY streamConfiguredChanged)
Q_PROPERTY(QString autoVideoSource READ autoVideoSource CONSTANT)
Q_PROPERTY(QString rtspVideoSource READ rtspVideoSource CONSTANT)
Q_PROPERTY(QString udpVideoSource READ udpVideoSource CONSTANT)
Q_PROPERTY(QString tcpVideoSource READ tcpVideoSource CONSTANT)
bool streamConfigured ();
bool streamConfigured ();
QString autoVideoSource () { return videoSourceAuto; }
QString rtspVideoSource () { return videoSourceRTSP; }
QString udpVideoSource () { return videoSourceUDP; }
QString tcpVideoSource () { return videoSourceTCP; }
static const char* videoSourceNoVideo;
static const char* videoDisabled;
static const char* videoSourceUDP;
static const char* videoSourceRTSP;
static const char* videoSourceAuto;
static const char* videoSourceTCP;
#ifdef QGC_GST_TAISYNC_USB
static const char* videoSourceTaiSyncUSB;
#endif
signals:
void streamConfiguredChanged ();
......
......@@ -501,7 +501,7 @@ public:
Vehicle(MAV_AUTOPILOT firmwareType,
MAV_TYPE vehicleType,
FirmwarePluginManager* firmwarePluginManager,
QObject* parent = NULL);
QObject* parent = nullptr);
~Vehicle();
......@@ -892,9 +892,9 @@ public:
QString formatedMessages ();
QString formatedMessage () { return _formatedMessage; }
QString latestError () { return _latestError; }
float latitude () { return _coordinate.latitude(); }
float longitude () { return _coordinate.longitude(); }
bool mavPresent () { return _mav != NULL; }
float latitude () { return static_cast<float>(_coordinate.latitude()); }
float longitude () { return static_cast<float>(_coordinate.longitude()); }
bool mavPresent () { return _mav != nullptr; }
int rcRSSI () { return _rcRSSI; }
bool px4Firmware () const { return _firmwareType == MAV_AUTOPILOT_PX4; }
bool apmFirmware () const { return _firmwareType == MAV_AUTOPILOT_ARDUPILOTMEGA; }
......@@ -990,8 +990,19 @@ public:
void sendMavCommandInt(int component, MAV_CMD command, MAV_FRAME frame, bool showError, float param1, float param2, float param3, float param4, double param5, double param6, float param7);
/// Same as sendMavCommand but available from Qml.
Q_INVOKABLE void sendCommand(int component, int command, bool showError, double param1 = 0.0f, double param2 = 0.0f, double param3 = 0.0f, double param4 = 0.0f, double param5 = 0.0f, double param6 = 0.0f, double param7 = 0.0f)
{ sendMavCommand(component, (MAV_CMD)command, showError, param1, param2, param3, param4, param5, param6, param7); }
Q_INVOKABLE void sendCommand(int component, int command, bool showError, double param1 = 0.0, double param2 = 0.0, double param3 = 0.0, double param4 = 0.0, double param5 = 0.0, double param6 = 0.0, double param7 = 0.0)
{
sendMavCommand(
component, static_cast<MAV_CMD>(command),
showError,
static_cast<float>(param1),
static_cast<float>(param2),
static_cast<float>(param3),
static_cast<float>(param4),
static_cast<float>(param5),
static_cast<float>(param6),
static_cast<float>(param7));
}
int firmwareMajorVersion(void) const { return _firmwareMajorVersion; }
int firmwareMinorVersion(void) const { return _firmwareMinorVersion; }
......
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