diff --git a/src/FlightDisplay/FlightDisplayView.qml b/src/FlightDisplay/FlightDisplayView.qml index 58425335678e7958c138836fb842744aa6f8fdd2..d363af171652dfdbddcfb00891398558f89f51a6 100644 --- a/src/FlightDisplay/FlightDisplayView.qml +++ b/src/FlightDisplay/FlightDisplayView.qml @@ -212,7 +212,23 @@ QGCView { _flightVideo.state = "unpopup" videoWindow.visible = false } + } + /* This timer will startVideo again after the popup window appears and is loaded. + * Such approach was the only one to avoid a crash for windows users + */ + Timer { + id: videoPopUpTimer + interval: 2000; + running: false; + repeat: false + onTriggered: { + // If state is popup, the next one will be popup-finished + if (_flightVideo.state == "popup") { + _flightVideo.state = "popup-finished" + } + QGroundControl.videoManager.startVideo() + } } QGCMapPalette { id: mapPal; lightColors: _mainIsMap ? _flightMap.isSatelliteMap : true } @@ -270,6 +286,20 @@ QGCView { anchors.left: _panel.left anchors.bottom: _panel.bottom visible: QGroundControl.videoManager.hasVideo && (!_mainIsMap || _isPipVisible) + + onParentChanged: { + /* If video comes back from popup + * correct anchors. + * Such thing is not possible with ParentChange. + */ + if(parent == _panel) { + // Do anchors again after popup + anchors.left = _panel.left + anchors.bottom = _panel.bottom + anchors.margins = ScreenTools.defaultFontPixelHeight + } + } + states: [ State { name: "pipMode" @@ -296,36 +326,41 @@ QGCView { State { name: "popup" StateChangeScript { - script: QGroundControl.videoManager.stopVideo() + script: { + // Stop video, restart it again with Timer + // Avoiding crashs if ParentChange is not yet done + QGroundControl.videoManager.stopVideo() + videoPopUpTimer.running = true + } } + PropertyChanges { + target: _flightVideoPipControl + inPopup: true + } + }, + State { + name: "popup-finished" ParentChange { target: _flightVideo parent: videoItem x: 0 y: 0 - width: videoWindow.width - height: videoWindow.height - } - PropertyChanges { - target: _flightVideoPipControl - inPopup: true + width: videoItem.width + height: videoItem.height } }, State { name: "unpopup" StateChangeScript { - script: QGroundControl.videoManager.stopVideo() + script: { + QGroundControl.videoManager.stopVideo() + videoPopUpTimer.running = true + } } ParentChange { target: _flightVideo parent: _panel } - PropertyChanges { - target: _flightVideo - anchors.left: _panel.left - anchors.bottom: _panel.bottom - anchors.margins: ScreenTools.defaultFontPixelHeight - } PropertyChanges { target: _flightVideoPipControl inPopup: false diff --git a/src/FlightDisplay/VideoManager.h b/src/FlightDisplay/VideoManager.h index f419af90a281a1889feba1642979e35ca930dde4..a63d6837abedb3490012dd1d02b4503632ecdf05 100644 --- a/src/FlightDisplay/VideoManager.h +++ b/src/FlightDisplay/VideoManager.h @@ -56,7 +56,7 @@ public: // Override from QGCTool void setToolbox (QGCToolbox *toolbox); - Q_INVOKABLE void startVideo() {_videoReceiver->stop();}; + Q_INVOKABLE void startVideo() {_videoReceiver->start();}; Q_INVOKABLE void stopVideo() {_videoReceiver->stop();}; signals: diff --git a/src/VideoStreaming/VideoReceiver.cc b/src/VideoStreaming/VideoReceiver.cc index 633688e8eca898516feb206ea08e69601cb1bf22..a51638df6097ee856191767ca1503e7b388dc137 100644 --- a/src/VideoStreaming/VideoReceiver.cc +++ b/src/VideoStreaming/VideoReceiver.cc @@ -218,6 +218,7 @@ VideoReceiver::start() return; } #if defined(QGC_GST_STREAMING) + _stop = false; qCDebug(VideoReceiverLog) << "start()"; if (_uri.isEmpty()) { @@ -433,6 +434,7 @@ void VideoReceiver::stop() { #if defined(QGC_GST_STREAMING) + _stop = true; qCDebug(VideoReceiverLog) << "stop()"; if(!_streaming) { _shutdownPipeline(); @@ -870,9 +872,11 @@ VideoReceiver::_updateTimer() } if(elapsed > (time_t)timeout && _videoSurface) { stop(); + // We want to start it back again with _updateTimer + _stop = false; } } else { - if(!running() && !_uri.isEmpty() && _videoSettings->streamEnabled()->rawValue().toBool()) { + if(!_stop && !running() && !_uri.isEmpty() && _videoSettings->streamEnabled()->rawValue().toBool()) { start(); } } diff --git a/src/VideoStreaming/VideoReceiver.h b/src/VideoStreaming/VideoReceiver.h index 76aa3044cf17f4f47399703e6b2f79cd3f2fddc4..7739b23500868ec21a7e2bdbb8a7dff531177922 100644 --- a/src/VideoStreaming/VideoReceiver.h +++ b/src/VideoStreaming/VideoReceiver.h @@ -114,6 +114,7 @@ private: bool _streaming; bool _starting; bool _stopping; + bool _stop; Sink* _sink; GstElement* _tee; diff --git a/src/VideoStreaming/gstqtvideosink/painters/videonode.cpp b/src/VideoStreaming/gstqtvideosink/painters/videonode.cpp index 87b415c15c3c6bf6ce7c40ad87f9d00d38f88c73..1a4cd1ab02bb7e2bdea3636014c2093e691b721f 100644 --- a/src/VideoStreaming/gstqtvideosink/painters/videonode.cpp +++ b/src/VideoStreaming/gstqtvideosink/painters/videonode.cpp @@ -52,14 +52,18 @@ void VideoNode::setMaterialTypeSolidBlack() void VideoNode::setCurrentFrame(GstBuffer* buffer) { - Q_ASSERT (m_materialType == MaterialTypeVideo); + if (m_materialType != MaterialTypeVideo) { + return; + } static_cast(material())->setCurrentFrame(buffer); markDirty(DirtyMaterial); } void VideoNode::updateColors(int brightness, int contrast, int hue, int saturation) { - Q_ASSERT (m_materialType == MaterialTypeVideo); + if (m_materialType != MaterialTypeVideo) { + return; + } static_cast(material())->updateColors(brightness, contrast, hue, saturation); markDirty(DirtyMaterial); }