From 0e7f614ddc30fb5db710f90a728b72d2a3c3a1f1 Mon Sep 17 00:00:00 2001 From: Gus Grubba Date: Thu, 2 May 2019 16:38:17 -0400 Subject: [PATCH] Initial secondary (thermal) video support --- src/Camera/QGCCameraControl.cc | 85 +++++++++++++-- src/Camera/QGCCameraControl.h | 25 ++++- src/Camera/QGCCameraManager.cc | 12 +++ src/Camera/QGCCameraManager.h | 2 + src/FlightDisplay/FlightDisplayView.qml | 9 +- src/FlightDisplay/FlightDisplayViewVideo.qml | 45 ++++++++ src/FlightDisplay/VideoManager.cc | 104 +++++++++++++++++-- src/FlightDisplay/VideoManager.h | 27 +++-- src/FlightMap/QGCVideoBackground.qml | 6 +- src/FlightMap/Widgets/CameraPageWidget.qml | 47 ++++++++- src/VideoStreaming/VideoReceiver.cc | 2 +- src/VideoStreaming/VideoReceiver.h | 1 - 12 files changed, 327 insertions(+), 38 deletions(-) diff --git a/src/Camera/QGCCameraControl.cc b/src/Camera/QGCCameraControl.cc index 7ddda9ccc..6b9e863f3 100644 --- a/src/Camera/QGCCameraControl.cc +++ b/src/Camera/QGCCameraControl.cc @@ -58,6 +58,8 @@ static const char* kVersion = "version"; static const char* kPhotoMode = "PhotoMode"; static const char* kPhotoLapse = "PhotoLapse"; static const char* kPhotoLapseCount = "PhotoLapseCount"; +static const char* kThermalOpacity = "ThermalOpacity"; +static const char* kThermalMode = "ThermalMode"; //----------------------------------------------------------------------------- // Known Parameters @@ -174,9 +176,11 @@ QGCCameraControl::QGCCameraControl(const mavlink_camera_information_t *info, Veh _initWhenReady(); } QSettings settings; - _photoMode = static_cast(settings.value(kPhotoMode, static_cast(PHOTO_CAPTURE_SINGLE)).toInt()); - _photoLapse = settings.value(kPhotoLapse, 1.0).toDouble(); + _photoMode = static_cast(settings.value(kPhotoMode, static_cast(PHOTO_CAPTURE_SINGLE)).toInt()); + _photoLapse = settings.value(kPhotoLapse, 1.0).toDouble(); _photoLapseCount = settings.value(kPhotoLapseCount, 0).toInt(); + _thermalOpacity = settings.value(kThermalOpacity, 85.0).toDouble(); + _thermalMode = static_cast(settings.value(kThermalMode, static_cast(THERMAL_BLEND)).toUInt()); _recTimer.setSingleShot(false); _recTimer.setInterval(333); connect(&_recTimer, &QTimer::timeout, this, &QGCCameraControl::_recTimerHandler); @@ -498,6 +502,30 @@ QGCCameraControl::setPhotoMode() } } +//----------------------------------------------------------------------------- +void +QGCCameraControl::setThermalMode(ThermalViewMode mode) +{ + QSettings settings; + settings.setValue(kThermalMode, static_cast(mode)); + _thermalMode = mode; + emit thermalModeChanged(); +} + +//----------------------------------------------------------------------------- +void +QGCCameraControl::setThermalOpacity(double val) +{ + if(val < 0.0) val = 0.0; + if(val > 100.0) val = 100.0; + if(fabs(_thermalOpacity - val) > 0.1) { + _thermalOpacity = val; + QSettings settings; + settings.setValue(kThermalOpacity, val); + emit thermalOpacityChanged(); + } +} + //----------------------------------------------------------------------------- void QGCCameraControl::setZoomLevel(qreal level) @@ -1496,10 +1524,14 @@ QGCCameraControl::handleVideoInfo(const mavlink_video_stream_information_t* vi) QGCVideoStreamInfo* pStream = new QGCVideoStreamInfo(this, vi); QQmlEngine::setObjectOwnership(pStream, QQmlEngine::CppOwnership); _streams.append(pStream); - _streamLabels.append(pStream->name()); - emit streamsChanged(); - emit streamLabelsChanged(); - qDebug() << _streamLabels; + //-- Thermal is handled separately and not listed + if(!pStream->isThermal()) { + _streamLabels.append(pStream->name()); + emit streamsChanged(); + emit streamLabelsChanged(); + } else { + emit thermalStreamChanged(); + } } //-- Check for missing count if(_streams.count() < _expectedCount) { @@ -1531,7 +1563,7 @@ QGCCameraControl::handleVideoStatus(const mavlink_video_stream_status_t* vs) void QGCCameraControl::setCurrentStream(int stream) { - if(stream != _currentStream && stream >= 0 && stream < _streams.count()) { + if(stream != _currentStream && stream >= 0 && stream < _streamLabels.count()) { if(_currentStream != stream) { QGCVideoStreamInfo* pInfo = currentStreamInstance(); if(pInfo) { @@ -1606,13 +1638,31 @@ QGCCameraControl::autoStream() QGCVideoStreamInfo* QGCCameraControl::currentStreamInstance() { - if(_currentStream < _streams.count() && _streams.count()) { - QGCVideoStreamInfo* pStream = qobject_cast(_streams[_currentStream]); + if(_currentStream < _streamLabels.count() && _streamLabels.count()) { + QGCVideoStreamInfo* pStream = _findStream(_streamLabels[_currentStream]); return pStream; } return nullptr; } +//----------------------------------------------------------------------------- +QGCVideoStreamInfo* +QGCCameraControl::thermalStreamInstance() +{ + //-- For now, it will return the first thermal listed (if any) + for(int i = 0; i < _streams.count(); i++) { + if(_streams[i]) { + QGCVideoStreamInfo* pStream = qobject_cast(_streams[i]); + if(pStream) { + if(pStream->isThermal()) { + return pStream; + } + } + } + } + return nullptr; +} + //----------------------------------------------------------------------------- void QGCCameraControl::_requestStreamInfo(uint8_t streamID) @@ -1660,6 +1710,23 @@ QGCCameraControl::_findStream(uint8_t id, bool report) return nullptr; } +//----------------------------------------------------------------------------- +QGCVideoStreamInfo* +QGCCameraControl::_findStream(const QString name) +{ + for(int i = 0; i < _streams.count(); i++) { + if(_streams[i]) { + QGCVideoStreamInfo* pStream = qobject_cast(_streams[i]); + if(pStream) { + if(pStream->name() == name) { + return pStream; + } + } + } + } + return nullptr; +} + //----------------------------------------------------------------------------- void QGCCameraControl::_streamTimeout() diff --git a/src/Camera/QGCCameraControl.h b/src/Camera/QGCCameraControl.h index 938009a9c..63e4a6e77 100644 --- a/src/Camera/QGCCameraControl.h +++ b/src/Camera/QGCCameraControl.h @@ -114,10 +114,18 @@ public: PHOTO_CAPTURE_TIMELAPSE, }; + enum ThermalViewMode { + THERMAL_OFF = 0, + THERMAL_BLEND, + THERMAL_FULL, + THERMAL_PIP, + }; + Q_ENUM(CameraMode) Q_ENUM(VideoStatus) Q_ENUM(PhotoStatus) Q_ENUM(PhotoMode) + Q_ENUM(ThermalViewMode) Q_PROPERTY(int version READ version NOTIFY infoChanged) Q_PROPERTY(QString modelName READ modelName NOTIFY infoChanged) @@ -162,9 +170,12 @@ public: Q_PROPERTY(bool autoStream READ autoStream NOTIFY autoStreamChanged) Q_PROPERTY(QmlObjectListModel* streams READ streams NOTIFY streamsChanged) Q_PROPERTY(QGCVideoStreamInfo* currentStreamInstance READ currentStreamInstance NOTIFY currentStreamChanged) + Q_PROPERTY(QGCVideoStreamInfo* thermalStreamInstance READ thermalStreamInstance NOTIFY thermalStreamChanged) Q_PROPERTY(quint32 recordTime READ recordTime NOTIFY recordTimeChanged) Q_PROPERTY(QString recordTimeStr READ recordTimeStr NOTIFY recordTimeChanged) Q_PROPERTY(QStringList streamLabels READ streamLabels NOTIFY streamLabelsChanged) + Q_PROPERTY(ThermalViewMode thermalMode READ thermalMode WRITE setThermalMode NOTIFY thermalModeChanged) + Q_PROPERTY(double thermalOpacity READ thermalOpacity WRITE setThermalOpacity NOTIFY thermalOpacityChanged) Q_INVOKABLE virtual void setVideoMode (); Q_INVOKABLE virtual void setPhotoMode (); @@ -216,6 +227,7 @@ public: virtual QmlObjectListModel* streams () { return &_streams; } virtual QGCVideoStreamInfo* currentStreamInstance(); + virtual QGCVideoStreamInfo* thermalStreamInstance(); virtual int currentStream () { return _currentStream; } virtual void setCurrentStream (int stream); virtual bool autoStream (); @@ -231,7 +243,12 @@ public: virtual Fact* mode (); //-- Stream names to show the user (for selection) - virtual QStringList streamLabels () { return _streamLabels; } + virtual QStringList streamLabels () { return _streamLabels; } + + virtual ThermalViewMode thermalMode () { return _thermalMode; } + virtual void setThermalMode (ThermalViewMode mode); + virtual double thermalOpacity () { return _thermalOpacity; } + virtual void setThermalOpacity (double val); virtual void setZoomLevel (qreal level); virtual void setFocusLevel (qreal level); @@ -282,9 +299,12 @@ signals: void focusLevelChanged (); void streamsChanged (); void currentStreamChanged (); + void thermalStreamChanged (); void autoStreamChanged (); void recordTimeChanged (); void streamLabelsChanged (); + void thermalModeChanged (); + void thermalOpacityChanged (); protected: virtual void _setVideoStatus (VideoStatus status); @@ -293,6 +313,7 @@ protected: virtual void _requestStreamInfo (uint8_t streamID); virtual void _requestStreamStatus (uint8_t streamID); virtual QGCVideoStreamInfo* _findStream (uint8_t streamID, bool report = true); + virtual QGCVideoStreamInfo* _findStream (const QString name); protected slots: virtual void _initWhenReady (); @@ -376,4 +397,6 @@ protected: QTimer _streamStatusTimer; QmlObjectListModel _streams; QStringList _streamLabels; + ThermalViewMode _thermalMode = THERMAL_BLEND; + double _thermalOpacity = 85.0; }; diff --git a/src/Camera/QGCCameraManager.cc b/src/Camera/QGCCameraManager.cc index e61c62f95..5c7c5bb85 100644 --- a/src/Camera/QGCCameraManager.cc +++ b/src/Camera/QGCCameraManager.cc @@ -171,6 +171,18 @@ QGCCameraManager::currentStreamInstance() return nullptr; } +//----------------------------------------------------------------------------- +QGCVideoStreamInfo* +QGCCameraManager::thermalStreamInstance() +{ + QGCCameraControl* pCamera = currentCameraInstance(); + if(pCamera) { + QGCVideoStreamInfo* pInfo = pCamera->thermalStreamInstance(); + return pInfo; + } + return nullptr; +} + //----------------------------------------------------------------------------- QGCCameraControl* QGCCameraManager::_findCamera(int id) diff --git a/src/Camera/QGCCameraManager.h b/src/Camera/QGCCameraManager.h index 9dce02811..4e2c802d7 100644 --- a/src/Camera/QGCCameraManager.h +++ b/src/Camera/QGCCameraManager.h @@ -43,6 +43,8 @@ public: virtual void setCurrentCamera (int sel); //-- Current stream virtual QGCVideoStreamInfo* currentStreamInstance(); + //-- Current thermal stream + virtual QGCVideoStreamInfo* thermalStreamInstance(); signals: void camerasChanged (); diff --git a/src/FlightDisplay/FlightDisplayView.qml b/src/FlightDisplay/FlightDisplayView.qml index aea2f9821..35d260bb8 100644 --- a/src/FlightDisplay/FlightDisplayView.qml +++ b/src/FlightDisplay/FlightDisplayView.qml @@ -7,14 +7,13 @@ * ****************************************************************************/ +import QtQuick 2.11 +import QtQuick.Controls 2.4 +import QtQuick.Dialogs 1.3 +import QtQuick.Layouts 1.11 -import QtQuick 2.3 -import QtQuick.Controls 1.2 -import QtQuick.Controls.Styles 1.4 -import QtQuick.Dialogs 1.2 import QtLocation 5.3 import QtPositioning 5.3 -import QtQuick.Layouts 1.2 import QtQuick.Window 2.2 import QtQml.Models 2.1 diff --git a/src/FlightDisplay/FlightDisplayViewVideo.qml b/src/FlightDisplay/FlightDisplayViewVideo.qml index 927a6910e..734ee1038 100644 --- a/src/FlightDisplay/FlightDisplayViewVideo.qml +++ b/src/FlightDisplay/FlightDisplayViewVideo.qml @@ -33,6 +33,9 @@ Item { property var _camera: _isCamera ? _dynamicCameras.cameras.get(_curCameraIndex) : null property bool _hasZoom: _camera && _camera.hasZoom property int _fitMode: QGroundControl.settingsManager.videoSettings.videoFit.rawValue + + property double _thermalHeightFactor: 0.666 //-- TODO + Rectangle { id: noVideo anchors.fill: parent @@ -72,6 +75,7 @@ Item { //-- Fit Width return _ar != 0.0 ? parent.width * (1 / _ar) : parent.height } + //-- Main Video QGCVideoBackground { id: videoContent height: parent.getHeight() @@ -119,12 +123,53 @@ Item { visible: _showGrid && !QGroundControl.videoManager.fullScreen } } + //-- Thermal Image + Item { + id: thermalItem + width: height * QGroundControl.videoManager.thermalAspectRatio + height: _camera ? (_camera.thermalMode === QGCCameraControl.THERMAL_PIP ? ScreenTools.defaultFontPixelHeight * 12 : parent.height * _thermalHeightFactor) : 0 + anchors.centerIn: parent + visible: QGroundControl.videoManager.hasThermal && _camera.thermalMode !== QGCCameraControl.THERMAL_OFF + function pipOrNot() { + if(_camera) { + if(_camera.thermalMode === QGCCameraControl.THERMAL_PIP) { + anchors.centerIn = undefined + anchors.top = parent.top + anchors.topMargin = mainWindow.header.height + (ScreenTools.defaultFontPixelHeight * 0.5) + anchors.left = parent.left + anchors.leftMargin = ScreenTools.defaultFontPixelWidth * 12 + } else { + anchors.top = undefined + anchors.topMargin = undefined + anchors.left = undefined + anchors.leftMargin = undefined + anchors.centerIn = parent + } + } + } + Connections { + target: _camera + onThermalModeChanged: thermalItem.pipOrNot() + } + onVisibleChanged: { + thermalItem.pipOrNot() + } + QGCVideoBackground { + id: thermalVideo + anchors.fill: parent + receiver: QGroundControl.videoManager.thermalVideoReceiver + display: QGroundControl.videoManager.thermalVideoReceiver ? QGroundControl.videoManager.thermalVideoReceiver.videoSurface : null + opacity: _camera ? (_camera.thermalMode === QGCCameraControl.THERMAL_BLEND ? _camera.thermalOpacity / 100 : 1.0) : 0 + } + } + //-- Full screen toggle MouseArea { anchors.fill: parent onDoubleClicked: { QGroundControl.videoManager.fullScreen = !QGroundControl.videoManager.fullScreen } } + //-- Zoom PinchArea { id: pinchZoom enabled: _hasZoom diff --git a/src/FlightDisplay/VideoManager.cc b/src/FlightDisplay/VideoManager.cc index bd2d7fa40..9ad5accf4 100644 --- a/src/FlightDisplay/VideoManager.cc +++ b/src/FlightDisplay/VideoManager.cc @@ -44,6 +44,9 @@ VideoManager::~VideoManager() if(_videoReceiver) { delete _videoReceiver; } + if(_thermalVideoReceiver) { + delete _thermalVideoReceiver; + } } //----------------------------------------------------------------------------- @@ -74,21 +77,76 @@ VideoManager::setToolbox(QGCToolbox *toolbox) emit isGStreamerChanged(); qCDebug(VideoManagerLog) << "New Video Source:" << videoSource; _videoReceiver = toolbox->corePlugin()->createVideoReceiver(this); + _thermalVideoReceiver = toolbox->corePlugin()->createVideoReceiver(this); _updateSettings(); if(isGStreamer()) { - _videoReceiver->start(); + startVideo(); } else { - _videoReceiver->stop(); + stopVideo(); } #endif } +//----------------------------------------------------------------------------- +void +VideoManager::startVideo() +{ + if(_videoReceiver) _videoReceiver->start(); + if(_thermalVideoReceiver) _thermalVideoReceiver->start(); +} + +//----------------------------------------------------------------------------- +void +VideoManager::stopVideo() +{ + if(_videoReceiver) _videoReceiver->stop(); + if(_thermalVideoReceiver) _thermalVideoReceiver->stop(); +} + //----------------------------------------------------------------------------- double VideoManager::aspectRatio() { if(_activeVehicle && _activeVehicle->dynamicCameras()) { QGCVideoStreamInfo* pInfo = _activeVehicle->dynamicCameras()->currentStreamInstance(); + if(pInfo) { + qCDebug(VideoManagerLog) << "Primary AR: " << pInfo->aspectRatio(); + return pInfo->aspectRatio(); + } + } + return _videoSettings->aspectRatio()->rawValue().toDouble(); +} + +//----------------------------------------------------------------------------- +double VideoManager::thermalAspectRatio() +{ + if(_activeVehicle && _activeVehicle->dynamicCameras()) { + QGCVideoStreamInfo* pInfo = _activeVehicle->dynamicCameras()->thermalStreamInstance(); + if(pInfo) { + qCDebug(VideoManagerLog) << "Thermal AR: " << pInfo->aspectRatio(); + return pInfo->aspectRatio(); + } + } + return 1.0; +} + +//----------------------------------------------------------------------------- +double VideoManager::hfov() +{ + if(_activeVehicle && _activeVehicle->dynamicCameras()) { + QGCVideoStreamInfo* pInfo = _activeVehicle->dynamicCameras()->currentStreamInstance(); + if(pInfo) { + return pInfo->hfov(); + } + } + return 1.0; +} + +//----------------------------------------------------------------------------- +double VideoManager::thermalHfov() +{ + if(_activeVehicle && _activeVehicle->dynamicCameras()) { + QGCVideoStreamInfo* pInfo = _activeVehicle->dynamicCameras()->thermalStreamInstance(); if(pInfo) { return pInfo->aspectRatio(); } @@ -96,6 +154,19 @@ double VideoManager::aspectRatio() return _videoSettings->aspectRatio()->rawValue().toDouble(); } +//----------------------------------------------------------------------------- +bool +VideoManager::hasThermal() +{ + if(_activeVehicle && _activeVehicle->dynamicCameras()) { + QGCVideoStreamInfo* pInfo = _activeVehicle->dynamicCameras()->thermalStreamInstance(); + if(pInfo) { + return true; + } + } + return false; +} + //----------------------------------------------------------------------------- bool VideoManager::autoStreamConfigured() @@ -204,8 +275,9 @@ VideoManager::_updateSettings() return; //-- Auto discovery if(_activeVehicle && _activeVehicle->dynamicCameras()) { - QGCVideoStreamInfo* pInfo = _activeVehicle->dynamicCameras()->currentStreamInstance(); + QGCVideoStreamInfo* pInfo = _activeVehicle->dynamicCameras()->currentStreamInstance(); if(pInfo) { + qCDebug(VideoManagerLog) << "Configure primary stream: " << pInfo->uri(); switch(pInfo->type()) { case VIDEO_STREAM_TYPE_RTSP: case VIDEO_STREAM_TYPE_TCP_MPEG: @@ -221,6 +293,26 @@ VideoManager::_updateSettings() _videoReceiver->setUri(pInfo->uri()); break; } + //-- Thermal stream (if any) + QGCVideoStreamInfo* pTinfo = _activeVehicle->dynamicCameras()->thermalStreamInstance(); + if(pTinfo) { + qCDebug(VideoManagerLog) << "Configure secondary stream: " << pTinfo->uri(); + switch(pTinfo->type()) { + case VIDEO_STREAM_TYPE_RTSP: + case VIDEO_STREAM_TYPE_TCP_MPEG: + _thermalVideoReceiver->setUri(pTinfo->uri()); + break; + case VIDEO_STREAM_TYPE_RTPUDP: + _thermalVideoReceiver->setUri(QStringLiteral("udp://0.0.0.0:%1").arg(pTinfo->uri())); + break; + case VIDEO_STREAM_TYPE_MPEG_TS_H264: + _thermalVideoReceiver->setUri(QStringLiteral("mpegts://0.0.0.0:%1").arg(pTinfo->uri())); + break; + default: + _thermalVideoReceiver->setUri(pTinfo->uri()); + break; + } + } return; } } @@ -241,11 +333,9 @@ VideoManager::_restartVideo() { #if defined(QGC_GST_STREAMING) qCDebug(VideoManagerLog) << "Restart video streaming"; - if(!_videoReceiver) - return; - _videoReceiver->stop(); + stopVideo(); _updateSettings(); - _videoReceiver->start(); + startVideo(); emit aspectRatioChanged(); #endif } diff --git a/src/FlightDisplay/VideoManager.h b/src/FlightDisplay/VideoManager.h index 8ace9fc39..5c8400344 100644 --- a/src/FlightDisplay/VideoManager.h +++ b/src/FlightDisplay/VideoManager.h @@ -42,8 +42,13 @@ public: 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(VideoReceiver* thermalVideoReceiver READ thermalVideoReceiver CONSTANT) Q_PROPERTY(double aspectRatio READ aspectRatio NOTIFY aspectRatioChanged) + Q_PROPERTY(double thermalAspectRatio READ thermalAspectRatio NOTIFY aspectRatioChanged) + Q_PROPERTY(double hfov READ hfov NOTIFY aspectRatioChanged) + Q_PROPERTY(double thermalHfov READ thermalHfov NOTIFY aspectRatioChanged) Q_PROPERTY(bool autoStreamConfigured READ autoStreamConfigured NOTIFY autoStreamConfiguredChanged) + Q_PROPERTY(bool hasThermal READ hasThermal NOTIFY aspectRatioChanged) bool hasVideo (); bool isGStreamer (); @@ -52,9 +57,14 @@ public: bool fullScreen () { return _fullScreen; } QString videoSourceID () { return _videoSourceID; } double aspectRatio (); + double thermalAspectRatio (); + double hfov (); + double thermalHfov (); bool autoStreamConfigured(); + bool hasThermal (); - VideoReceiver* videoReceiver () { return _videoReceiver; } + VideoReceiver* videoReceiver () { return _videoReceiver; } + VideoReceiver* thermalVideoReceiver () { return _thermalVideoReceiver; } #if defined(QGC_DISABLE_UVC) bool uvcEnabled () { return false; } @@ -68,8 +78,8 @@ public: // Override from QGCTool void setToolbox (QGCToolbox *toolbox); - Q_INVOKABLE void startVideo () { _videoReceiver->start(); } - Q_INVOKABLE void stopVideo () { _videoReceiver->stop(); } + Q_INVOKABLE void startVideo (); + Q_INVOKABLE void stopVideo (); signals: void hasVideoChanged (); @@ -95,12 +105,13 @@ private: void _updateSettings (); private: - bool _isTaisync = false; - VideoReceiver* _videoReceiver = nullptr; - VideoSettings* _videoSettings = nullptr; + bool _isTaisync = false; + VideoReceiver* _videoReceiver = nullptr; + VideoReceiver* _thermalVideoReceiver = nullptr; + VideoSettings* _videoSettings = nullptr; QString _videoSourceID; - bool _fullScreen = false; - Vehicle* _activeVehicle = nullptr; + bool _fullScreen = false; + Vehicle* _activeVehicle = nullptr; }; #endif diff --git a/src/FlightMap/QGCVideoBackground.qml b/src/FlightMap/QGCVideoBackground.qml index ee264f6a0..a329db5cb 100644 --- a/src/FlightMap/QGCVideoBackground.qml +++ b/src/FlightMap/QGCVideoBackground.qml @@ -14,9 +14,9 @@ * @author Gus Grubba */ -import QtQuick 2.3 -import QtQuick.Controls 1.2 -import QGroundControl.QgcQtGStreamer 1.0 +import QtQuick 2.11 +import QtQuick.Controls 2.4 +import QGroundControl.QgcQtGStreamer 1.0 VideoItem { id: videoBackground diff --git a/src/FlightMap/Widgets/CameraPageWidget.qml b/src/FlightMap/Widgets/CameraPageWidget.qml index d5ae396c4..303452736 100644 --- a/src/FlightMap/Widgets/CameraPageWidget.qml +++ b/src/FlightMap/Widgets/CameraPageWidget.qml @@ -205,8 +205,8 @@ Column { //------------------------------------------- //-- Camera Selector Row { - visible: _isCamera - spacing: ScreenTools.defaultFontPixelWidth + spacing: ScreenTools.defaultFontPixelWidth + visible: _isCamera && _dynamicCameras.cameraLabels.length > 1 anchors.horizontalCenter: parent.horizontalCenter QGCLabel { text: qsTr("Camera Selector:") @@ -225,6 +225,7 @@ Column { //-- Stream Selector Row { spacing: ScreenTools.defaultFontPixelWidth + visible: _isCamera && _camera.streamLabels.length > 1 anchors.horizontalCenter: parent.horizontalCenter QGCLabel { text: qsTr("Stream Selector:") @@ -238,7 +239,47 @@ Column { currentIndex: _camera ? _camera.currentStream : 0 } } - + //------------------------------------------- + //-- Thermal Modes + Row { + spacing: ScreenTools.defaultFontPixelWidth + anchors.horizontalCenter: parent.horizontalCenter + visible: QGroundControl.videoManager.hasThermal + property var thermalModes: [qsTr("Off"), qsTr("Blend"), qsTr("Full"), qsTr("Picture In Picture")] + QGCLabel { + text: qsTr("Thermal View Mode") + width: _labelFieldWidth + anchors.verticalCenter: parent.verticalCenter + } + QGCComboBox { + width: _editFieldWidth + model: parent.thermalModes + currentIndex: _camera ? _camera.thermalMode : 0 + onActivated: _camera.thermalMode = index + } + } + //------------------------------------------- + //-- Thermal Video Opacity + Row { + spacing: ScreenTools.defaultFontPixelWidth + anchors.horizontalCenter: parent.horizontalCenter + visible: QGroundControl.videoManager.hasThermal && _camera.thermalMode === QGCCameraControl.THERMAL_BLEND + QGCLabel { + text: qsTr("Blend Opacity") + width: _labelFieldWidth + anchors.verticalCenter: parent.verticalCenter + } + Slider { + width: _editFieldWidth + maximumValue: 100 + minimumValue: 0 + value: _camera ? _camera.thermalOpacity : 0 + updateValueWhileDragging: true + onValueChanged: { + _camera.thermalOpacity = value + } + } + } //------------------------------------------- //-- Camera Settings Repeater { diff --git a/src/VideoStreaming/VideoReceiver.cc b/src/VideoStreaming/VideoReceiver.cc index 22fcf2b11..369fb492c 100644 --- a/src/VideoStreaming/VideoReceiver.cc +++ b/src/VideoStreaming/VideoReceiver.cc @@ -567,7 +567,7 @@ void VideoReceiver::_handleStateChanged() { if(_pipeline) { _streaming = GST_STATE(_pipeline) == GST_STATE_PLAYING; - qCDebug(VideoReceiverLog) << "State changed, _streaming:" << _streaming; + //qCDebug(VideoReceiverLog) << "State changed, _streaming:" << _streaming; } } #endif diff --git a/src/VideoStreaming/VideoReceiver.h b/src/VideoStreaming/VideoReceiver.h index 65ee942fb..7e6bb3776 100644 --- a/src/VideoStreaming/VideoReceiver.h +++ b/src/VideoStreaming/VideoReceiver.h @@ -7,7 +7,6 @@ * ****************************************************************************/ - /** * @file * @brief QGC Video Receiver -- 2.22.0