Commit 17a591ac authored by Matej Frančeškin's avatar Matej Frančeškin Committed by Andrew Voznytsa

Fix video start/stop/restart on error

parent 42c15ee2
...@@ -20,10 +20,10 @@ CustomVideoManager::CustomVideoManager(QGCApplication* app, QGCToolbox* toolbox) ...@@ -20,10 +20,10 @@ CustomVideoManager::CustomVideoManager(QGCApplication* app, QGCToolbox* toolbox)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void void
CustomVideoManager::_updateSettings() CustomVideoManager::_updateSettings(unsigned id)
{ {
if(!_videoSettings || !_videoReceiver) if(!_videoSettings || !_videoReceiver)
return; return;
VideoManager::_updateSettings(); VideoManager::_updateSettings(id);
} }
...@@ -23,6 +23,6 @@ public: ...@@ -23,6 +23,6 @@ public:
CustomVideoManager (QGCApplication* app, QGCToolbox* toolbox); CustomVideoManager (QGCApplication* app, QGCToolbox* toolbox);
protected: protected:
void _updateSettings (); void _updateSettings (unsigned id);
}; };
...@@ -64,16 +64,18 @@ VideoManager::VideoManager(QGCApplication* app, QGCToolbox* toolbox) ...@@ -64,16 +64,18 @@ VideoManager::VideoManager(QGCApplication* app, QGCToolbox* toolbox)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
VideoManager::~VideoManager() VideoManager::~VideoManager()
{ {
delete _videoReceiver; for (int i = 0; i < 2; i++) {
_videoReceiver = nullptr; if (_videoReceiver[i] != nullptr) {
delete _thermalVideoReceiver; delete _videoReceiver[i];
_thermalVideoReceiver = nullptr; _videoReceiver[i] = nullptr;
}
#if defined(QGC_GST_STREAMING) #if defined(QGC_GST_STREAMING)
GStreamer::releaseVideoSink(_thermalVideoSink); if (_videoSink[i] != nullptr) {
_thermalVideoSink = nullptr; GStreamer::releaseVideoSink(_videoSink[i]);
GStreamer::releaseVideoSink(_videoSink); _videoSink[i] = nullptr;
_videoSink = nullptr; }
#endif #endif
}
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
...@@ -106,27 +108,43 @@ VideoManager::setToolbox(QGCToolbox *toolbox) ...@@ -106,27 +108,43 @@ VideoManager::setToolbox(QGCToolbox *toolbox)
emit isGStreamerChanged(); emit isGStreamerChanged();
qCDebug(VideoManagerLog) << "New Video Source:" << videoSource; qCDebug(VideoManagerLog) << "New Video Source:" << videoSource;
#if defined(QGC_GST_STREAMING) #if defined(QGC_GST_STREAMING)
_videoReceiver = toolbox->corePlugin()->createVideoReceiver(this); _videoReceiver[0] = toolbox->corePlugin()->createVideoReceiver(this);
_thermalVideoReceiver = toolbox->corePlugin()->createVideoReceiver(this); _videoReceiver[1] = toolbox->corePlugin()->createVideoReceiver(this);
connect(_videoReceiver, &VideoReceiver::timeout, this, [this](){ connect(_videoReceiver[0], &VideoReceiver::timeout, this, [this](){
if (!_enableVideoRestart) return; _restartVideo(0);
_startReceiver(0);
}); });
connect(_videoReceiver, &VideoReceiver::streamingChanged, this, [this](bool active){ connect(_videoReceiver[0], &VideoReceiver::streamingChanged, this, [this](bool active){
_streaming = active; _streaming = active;
emit streamingChanged(); emit streamingChanged();
if (!_enableVideoRestart || active) return; _restartVideo(0);
});
connect(_videoReceiver[0], &VideoReceiver::onStartComplete, this, [this](VideoReceiver::STATUS status) {
if (status == VideoReceiver::STATUS_OK) {
_videoStarted[0] = true;
_videoReceiver[0]->startDecoding(_videoSink[0]);
} else if (status == VideoReceiver::STATUS_INVALID_URL) {
// Invalid URL - don't restart
} else if (status == VideoReceiver::STATUS_INVALID_STATE) {
// Already running
} else {
_restartVideo(0);
}
});
connect(_videoReceiver[0], &VideoReceiver::onStopComplete, this, [this](VideoReceiver::STATUS) {
_videoStarted[0] = false;
_startReceiver(0); _startReceiver(0);
}); });
connect(_videoReceiver, &VideoReceiver::decodingChanged, this, [this](bool active){ connect(_videoReceiver[0], &VideoReceiver::decodingChanged, this, [this](bool active){
_decoding = active; _decoding = active;
emit decodingChanged(); emit decodingChanged();
}); });
connect(_videoReceiver, &VideoReceiver::recordingChanged, this, [this](bool active){ connect(_videoReceiver[0], &VideoReceiver::recordingChanged, this, [this](bool active){
_recording = active; _recording = active;
if (!active) { if (!active) {
_subtitleWriter.stopCapturingTelemetry(); _subtitleWriter.stopCapturingTelemetry();
...@@ -134,35 +152,52 @@ VideoManager::setToolbox(QGCToolbox *toolbox) ...@@ -134,35 +152,52 @@ VideoManager::setToolbox(QGCToolbox *toolbox)
emit recordingChanged(); emit recordingChanged();
}); });
connect(_videoReceiver, &VideoReceiver::recordingStarted, this, [this](){ connect(_videoReceiver[0], &VideoReceiver::recordingStarted, this, [this](){
_subtitleWriter.startCapturingTelemetry(_videoFile); _subtitleWriter.startCapturingTelemetry(_videoFile);
}); });
connect(_videoReceiver, &VideoReceiver::videoSizeChanged, this, [this](QSize size){ connect(_videoReceiver[0], &VideoReceiver::videoSizeChanged, this, [this](QSize size){
_videoSize = ((quint32)size.width() << 16) | (quint32)size.height(); _videoSize = ((quint32)size.width() << 16) | (quint32)size.height();
emit videoSizeChanged(); emit videoSizeChanged();
}); });
connect(_videoReceiver, &VideoReceiver::onTakeScreenshotComplete, this, [this](VideoReceiver::STATUS status){ //connect(_videoReceiver, &VideoReceiver::onTakeScreenshotComplete, this, [this](VideoReceiver::STATUS status){
if (status == VideoReceiver::STATUS_OK) { // if (status == VideoReceiver::STATUS_OK) {
} // }
}); //});
// FIXME: AV: I believe _thermalVideoReceiver should be handled just like _videoReceiver in terms of event // FIXME: AV: I believe _thermalVideoReceiver should be handled just like _videoReceiver in terms of event
// and I expect that it will be changed during multiple video stream activity // and I expect that it will be changed during multiple video stream activity
if (_thermalVideoReceiver != nullptr) { if (_videoReceiver[1] != nullptr) {
connect(_thermalVideoReceiver, &VideoReceiver::timeout, this, [this](){ connect(_videoReceiver[1], &VideoReceiver::timeout, this, [this](){
if (!_enableVideoRestart) return; _restartVideo(1);
_startReceiver(1); });
connect(_videoReceiver[1], &VideoReceiver::streamingChanged, this, [this](bool active){
_restartVideo(1);
});
connect(_videoReceiver[1], &VideoReceiver::onStartComplete, this, [this](VideoReceiver::STATUS status) {
if (status == VideoReceiver::STATUS_OK) {
_videoStarted[1] = true;
_videoReceiver[1]->startDecoding(_videoSink[1]);
} else if (status == VideoReceiver::STATUS_INVALID_URL) {
// Invalid URL - don't restart
} else if (status == VideoReceiver::STATUS_INVALID_STATE) {
// Already running
} else {
_restartVideo(1);
}
}); });
connect(_thermalVideoReceiver, &VideoReceiver::streamingChanged, this, [this](bool active){ connect(_videoReceiver[1], &VideoReceiver::onStopComplete, this, [this](VideoReceiver::STATUS) {
if (!_enableVideoRestart || active) return; _videoStarted[1] = false;
_startReceiver(1); _startReceiver(1);
}); });
} }
#endif #endif
_updateSettings(); _updateSettings(0);
_updateSettings(1);
if(isGStreamer()) { if(isGStreamer()) {
startVideo(); startVideo();
} else { } else {
...@@ -226,8 +261,6 @@ VideoManager::startVideo() ...@@ -226,8 +261,6 @@ VideoManager::startVideo()
return; return;
} }
_enableVideoRestart = true;
_startReceiver(0); _startReceiver(0);
_startReceiver(1); _startReceiver(1);
} }
...@@ -240,8 +273,6 @@ VideoManager::stopVideo() ...@@ -240,8 +273,6 @@ VideoManager::stopVideo()
return; return;
} }
_enableVideoRestart = false;
_stopReceiver(1); _stopReceiver(1);
_stopReceiver(0); _stopReceiver(0);
} }
...@@ -253,7 +284,7 @@ VideoManager::startRecording(const QString& videoFile) ...@@ -253,7 +284,7 @@ VideoManager::startRecording(const QString& videoFile)
return; return;
} }
#if defined(QGC_GST_STREAMING) #if defined(QGC_GST_STREAMING)
if (!_videoReceiver) { if (!_videoReceiver[0]) {
qgcApp()->showAppMessage(tr("Video receiver is not ready.")); qgcApp()->showAppMessage(tr("Video receiver is not ready."));
return; return;
} }
...@@ -279,7 +310,7 @@ VideoManager::startRecording(const QString& videoFile) ...@@ -279,7 +310,7 @@ VideoManager::startRecording(const QString& videoFile)
+ (videoFile.isEmpty() ? QDateTime::currentDateTime().toString("yyyy-MM-dd_hh.mm.ss") : videoFile) + (videoFile.isEmpty() ? QDateTime::currentDateTime().toString("yyyy-MM-dd_hh.mm.ss") : videoFile)
+ "." + kFileExtension[fileFormat - VideoReceiver::FILE_FORMAT_MIN]; + "." + kFileExtension[fileFormat - VideoReceiver::FILE_FORMAT_MIN];
_videoReceiver->startRecording(_videoFile, fileFormat); _videoReceiver[0]->startRecording(_videoFile, fileFormat);
#else #else
Q_UNUSED(videoFile) Q_UNUSED(videoFile)
#endif #endif
...@@ -292,11 +323,11 @@ VideoManager::stopRecording() ...@@ -292,11 +323,11 @@ VideoManager::stopRecording()
return; return;
} }
#if defined(QGC_GST_STREAMING) #if defined(QGC_GST_STREAMING)
if (!_videoReceiver) { if (!_videoReceiver[0]) {
return; return;
} }
_videoReceiver->stopRecording(); _videoReceiver[0]->stopRecording();
#endif #endif
} }
...@@ -307,7 +338,7 @@ VideoManager::grabImage(const QString& imageFile) ...@@ -307,7 +338,7 @@ VideoManager::grabImage(const QString& imageFile)
return; return;
} }
#if defined(QGC_GST_STREAMING) #if defined(QGC_GST_STREAMING)
if (!_videoReceiver) { if (!_videoReceiver[0]) {
return; return;
} }
...@@ -315,7 +346,7 @@ VideoManager::grabImage(const QString& imageFile) ...@@ -315,7 +346,7 @@ VideoManager::grabImage(const QString& imageFile)
emit imageFileChanged(); emit imageFileChanged();
_videoReceiver->takeScreenshot(_imageFile); _videoReceiver[0]->takeScreenshot(_imageFile);
#else #else
Q_UNUSED(imageFile) Q_UNUSED(imageFile)
#endif #endif
...@@ -433,28 +464,28 @@ VideoManager::_videoSourceChanged() ...@@ -433,28 +464,28 @@ VideoManager::_videoSourceChanged()
emit hasVideoChanged(); emit hasVideoChanged();
emit isGStreamerChanged(); emit isGStreamerChanged();
emit isAutoStreamChanged(); emit isAutoStreamChanged();
_restartVideo(); _restartVideo(0);
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void void
VideoManager::_udpPortChanged() VideoManager::_udpPortChanged()
{ {
_restartVideo(); _restartVideo(0);
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void void
VideoManager::_rtspUrlChanged() VideoManager::_rtspUrlChanged()
{ {
_restartVideo(); _restartVideo(0);
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void void
VideoManager::_tcpUrlChanged() VideoManager::_tcpUrlChanged()
{ {
_restartVideo(); _restartVideo(0);
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
...@@ -516,6 +547,7 @@ VideoManager::setfullScreen(bool f) ...@@ -516,6 +547,7 @@ VideoManager::setfullScreen(bool f)
emit fullScreenChanged(); emit fullScreenChanged();
} }
//-----------------------------------------------------------------------------
void void
VideoManager::_initVideo() VideoManager::_initVideo()
{ {
...@@ -529,10 +561,9 @@ VideoManager::_initVideo() ...@@ -529,10 +561,9 @@ VideoManager::_initVideo()
QQuickItem* widget = root->findChild<QQuickItem*>("videoContent"); QQuickItem* widget = root->findChild<QQuickItem*>("videoContent");
if (widget != nullptr && _videoReceiver != nullptr) { if (widget != nullptr && _videoReceiver[0] != nullptr) {
if ((_videoSink = qgcApp()->toolbox()->corePlugin()->createVideoSink(this, widget)) != nullptr) { _videoSink[0] = qgcApp()->toolbox()->corePlugin()->createVideoSink(this, widget);
_videoReceiver->startDecoding(_videoSink); if (_videoSink[0] == nullptr) {
} else {
qCDebug(VideoManagerLog) << "createVideoSink() failed"; qCDebug(VideoManagerLog) << "createVideoSink() failed";
} }
} else { } else {
...@@ -541,10 +572,9 @@ VideoManager::_initVideo() ...@@ -541,10 +572,9 @@ VideoManager::_initVideo()
widget = root->findChild<QQuickItem*>("thermalVideo"); widget = root->findChild<QQuickItem*>("thermalVideo");
if (widget != nullptr && _thermalVideoReceiver != nullptr) { if (widget != nullptr && _videoReceiver[1] != nullptr) {
if ((_thermalVideoSink = qgcApp()->toolbox()->corePlugin()->createVideoSink(this, widget)) != nullptr) { _videoSink[1] = qgcApp()->toolbox()->corePlugin()->createVideoSink(this, widget);
_thermalVideoReceiver->startDecoding(_thermalVideoSink); if (_videoSink[1] == nullptr) {
} else {
qCDebug(VideoManagerLog) << "createVideoSink() failed"; qCDebug(VideoManagerLog) << "createVideoSink() failed";
} }
} else { } else {
...@@ -555,7 +585,7 @@ VideoManager::_initVideo() ...@@ -555,7 +585,7 @@ VideoManager::_initVideo()
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
bool bool
VideoManager::_updateSettings() VideoManager::_updateSettings(unsigned id)
{ {
if(!_videoSettings) if(!_videoSettings)
return false; return false;
...@@ -564,135 +594,134 @@ VideoManager::_updateSettings() ...@@ -564,135 +594,134 @@ VideoManager::_updateSettings()
QGCVideoStreamInfo* pInfo = _activeVehicle->dynamicCameras()->currentStreamInstance(); QGCVideoStreamInfo* pInfo = _activeVehicle->dynamicCameras()->currentStreamInstance();
if(pInfo) { if(pInfo) {
bool status = false; bool status = false;
qCDebug(VideoManagerLog) << "Configure primary stream: " << pInfo->uri(); if (id == 0) {
switch(pInfo->type()) { qCDebug(VideoManagerLog) << "Configure primary stream:" << pInfo->uri();
case VIDEO_STREAM_TYPE_RTSP: switch(pInfo->type()) {
if (status = _updateVideoUri(pInfo->uri())) {
_toolbox->settingsManager()->videoSettings()->videoSource()->setRawValue(VideoSettings::videoSourceRTSP);
}
break;
case VIDEO_STREAM_TYPE_TCP_MPEG:
if (status = _updateVideoUri(pInfo->uri())) {
_toolbox->settingsManager()->videoSettings()->videoSource()->setRawValue(VideoSettings::videoSourceTCP);
}
break;
case VIDEO_STREAM_TYPE_RTPUDP:
if (status = _updateVideoUri(QStringLiteral("udp://0.0.0.0:%1").arg(pInfo->uri()))) {
_toolbox->settingsManager()->videoSettings()->videoSource()->setRawValue(VideoSettings::videoSourceUDPH264);
}
break;
case VIDEO_STREAM_TYPE_MPEG_TS_H264:
if (status = _updateVideoUri(QStringLiteral("mpegts://0.0.0.0:%1").arg(pInfo->uri()))) {
_toolbox->settingsManager()->videoSettings()->videoSource()->setRawValue(VideoSettings::videoSourceMPEGTS);
}
break;
default:
status = _updateVideoUri(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_RTSP:
if ((status = _updateVideoUri(id, pInfo->uri()))) {
_toolbox->settingsManager()->videoSettings()->videoSource()->setRawValue(VideoSettings::videoSourceRTSP);
}
break;
case VIDEO_STREAM_TYPE_TCP_MPEG: case VIDEO_STREAM_TYPE_TCP_MPEG:
status |= _updateThermalVideoUri(pTinfo->uri()); if ((status = _updateVideoUri(id, pInfo->uri()))) {
_toolbox->settingsManager()->videoSettings()->videoSource()->setRawValue(VideoSettings::videoSourceTCP);
}
break; break;
case VIDEO_STREAM_TYPE_RTPUDP: case VIDEO_STREAM_TYPE_RTPUDP:
status |= _updateThermalVideoUri(QStringLiteral("udp://0.0.0.0:%1").arg(pTinfo->uri())); if ((status = _updateVideoUri(id, QStringLiteral("udp://0.0.0.0:%1").arg(pInfo->uri())))) {
_toolbox->settingsManager()->videoSettings()->videoSource()->setRawValue(VideoSettings::videoSourceUDPH264);
}
break; break;
case VIDEO_STREAM_TYPE_MPEG_TS_H264: case VIDEO_STREAM_TYPE_MPEG_TS_H264:
status |= _updateThermalVideoUri(QStringLiteral("mpegts://0.0.0.0:%1").arg(pTinfo->uri())); if ((status = _updateVideoUri(id, QStringLiteral("mpegts://0.0.0.0:%1").arg(pInfo->uri())))) {
_toolbox->settingsManager()->videoSettings()->videoSource()->setRawValue(VideoSettings::videoSourceMPEGTS);
}
break; break;
default: default:
status |= _updateThermalVideoUri(pTinfo->uri()); status = _updateVideoUri(id, pInfo->uri());
break; break;
} }
} }
else if (id == 1) { //-- 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:
status |= _updateVideoUri(id, pTinfo->uri());
break;
case VIDEO_STREAM_TYPE_RTPUDP:
status |= _updateVideoUri(id, QStringLiteral("udp://0.0.0.0:%1").arg(pTinfo->uri()));
break;
case VIDEO_STREAM_TYPE_MPEG_TS_H264:
status |= _updateVideoUri(id, QStringLiteral("mpegts://0.0.0.0:%1").arg(pTinfo->uri()));
break;
default:
status |= _updateVideoUri(id, pTinfo->uri());
break;
}
}
}
return status; return status;
} }
} }
QString source = _videoSettings->videoSource()->rawValue().toString(); QString source = _videoSettings->videoSource()->rawValue().toString();
if (source == VideoSettings::videoSourceUDPH264) if (source == VideoSettings::videoSourceUDPH264)
return _updateVideoUri(QStringLiteral("udp://0.0.0.0:%1").arg(_videoSettings->udpPort()->rawValue().toInt())); return _updateVideoUri(0, QStringLiteral("udp://0.0.0.0:%1").arg(_videoSettings->udpPort()->rawValue().toInt()));
else if (source == VideoSettings::videoSourceUDPH265) else if (source == VideoSettings::videoSourceUDPH265)
return _updateVideoUri(QStringLiteral("udp265://0.0.0.0:%1").arg(_videoSettings->udpPort()->rawValue().toInt())); return _updateVideoUri(0, QStringLiteral("udp265://0.0.0.0:%1").arg(_videoSettings->udpPort()->rawValue().toInt()));
else if (source == VideoSettings::videoSourceMPEGTS) else if (source == VideoSettings::videoSourceMPEGTS)
return _updateVideoUri(QStringLiteral("mpegts://0.0.0.0:%1").arg(_videoSettings->udpPort()->rawValue().toInt())); return _updateVideoUri(0, QStringLiteral("mpegts://0.0.0.0:%1").arg(_videoSettings->udpPort()->rawValue().toInt()));
else if (source == VideoSettings::videoSourceRTSP) else if (source == VideoSettings::videoSourceRTSP)
return _updateVideoUri(_videoSettings->rtspUrl()->rawValue().toString()); return _updateVideoUri(0, _videoSettings->rtspUrl()->rawValue().toString());
else if (source == VideoSettings::videoSourceTCP) else if (source == VideoSettings::videoSourceTCP)
return _updateVideoUri(QStringLiteral("tcp://%1").arg(_videoSettings->tcpUrl()->rawValue().toString())); return _updateVideoUri(0, QStringLiteral("tcp://%1").arg(_videoSettings->tcpUrl()->rawValue().toString()));
}
bool
VideoManager::_updateVideoUri(const QString& uri)
{
#if defined(QGC_GST_TAISYNC_ENABLED) && (defined(__android__) || defined(__ios__))
//-- Taisync on iOS or Android sends a raw h.264 stream
if (isTaisync()) {
return _updateVideoUri(QString("tsusb://0.0.0.0:%1").arg(TAISYNC_VIDEO_UDP_PORT));
}
#endif
if (uri == _videoUri) {
return false;
}
_videoUri = uri;
return true; return false;
} }
//-----------------------------------------------------------------------------
bool bool
VideoManager::_updateThermalVideoUri(const QString& uri) VideoManager::_updateVideoUri(unsigned id, const QString& uri)
{ {
#if defined(QGC_GST_TAISYNC_ENABLED) && (defined(__android__) || defined(__ios__)) #if defined(QGC_GST_TAISYNC_ENABLED) && (defined(__android__) || defined(__ios__))
//-- Taisync on iOS or Android sends a raw h.264 stream //-- Taisync on iOS or Android sends a raw h.264 stream
if (isTaisync()) { if (isTaisync()) {
// FIXME: AV: TAISYNC_VIDEO_UDP_PORT is used by video stream, thermal stream should go via its own proxy if (id == 0) {
if (!_thermalVideoUri.isEmpty()) { return _updateVideoUri(0, QString("tsusb://0.0.0.0:%1").arg(TAISYNC_VIDEO_UDP_PORT));
_thermalVideoUri.clear(); } if (id == 1) {
return true; // FIXME: AV: TAISYNC_VIDEO_UDP_PORT is used by video stream, thermal stream should go via its own proxy
} else { if (!_videoUri[1].isEmpty()) {
return false; _videoUri[1].clear();
return true;
} else {
return false;
}
} }
} }
#endif #endif
if (uri == _thermalVideoUri) { if (uri == _videoUri[id]) {
return false; return false;
} }
_thermalVideoUri = uri; _videoUri[id] = uri;
return true; return true;
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void void
VideoManager::_restartVideo() VideoManager::_restartVideo(unsigned id)
{ {
#if defined(QGC_GST_STREAMING) #if defined(QGC_GST_STREAMING)
if (!_updateSettings()) { QString oldUri = _videoUri[id];
qCDebug(VideoManagerLog) << "No sense to restart video streaming, skipped"; _updateSettings(id);
QString newUri = _videoUri[id];
if (oldUri == newUri && _videoStarted[id]) {
qCDebug(VideoManagerLog) << "No sense to restart video streaming, skipped" << id;
return; return;
} }
qCDebug(VideoManagerLog) << "Restart video streaming"; qCDebug(VideoManagerLog) << "Restart video streaming" << id;
if (!_enableVideoRestart) { if (_videoStarted[id]) {
_enableVideoRestart = true; _stopReceiver(id);
_startReceiver(0);
_startReceiver(1);
} else { } else {
_stopReceiver(1); _startReceiver(id);
_stopReceiver(0);
} }
// emit aspectRatioChanged();
#endif #endif
} }
//-----------------------------------------------------------------------------
void
VideoManager::_restartAllVideos()
{
_restartVideo(0);
_restartVideo(1);
}
//---------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------
void void
VideoManager::_startReceiver(unsigned id) VideoManager::_startReceiver(unsigned id)
...@@ -700,18 +729,12 @@ VideoManager::_startReceiver(unsigned id) ...@@ -700,18 +729,12 @@ VideoManager::_startReceiver(unsigned id)
#if defined(QGC_GST_STREAMING) #if defined(QGC_GST_STREAMING)
const unsigned timeout = _videoSettings->rtspTimeout()->rawValue().toUInt(); const unsigned timeout = _videoSettings->rtspTimeout()->rawValue().toUInt();
if (id == 0 && _videoReceiver != nullptr) { if (id > 1) {
_videoReceiver->start(_videoUri, timeout);
if (_videoSink != nullptr) {
_videoReceiver->startDecoding(_videoSink);
}
} else if (id == 1 && _thermalVideoReceiver != nullptr) {
_thermalVideoReceiver->start(_thermalVideoUri, timeout);
if (_thermalVideoSink != nullptr) {
_thermalVideoReceiver->startDecoding(_thermalVideoSink);
}
} else if (id > 1) {
qCDebug(VideoManagerLog) << "Unsupported receiver id" << id; qCDebug(VideoManagerLog) << "Unsupported receiver id" << id;
} else if (_videoReceiver[id] != nullptr && _videoSink[id] != nullptr) {
if (!_videoUri[id].isEmpty()) {
_videoReceiver[id]->start(_videoUri[id], timeout);
}
} }
#endif #endif
} }
...@@ -721,12 +744,10 @@ void ...@@ -721,12 +744,10 @@ void
VideoManager::_stopReceiver(unsigned id) VideoManager::_stopReceiver(unsigned id)
{ {
#if defined(QGC_GST_STREAMING) #if defined(QGC_GST_STREAMING)
if (id == 0 && _videoReceiver != nullptr) { if (id > 1) {
_videoReceiver->stop();
} else if (id == 1 && _thermalVideoReceiver != nullptr){
_thermalVideoReceiver->stop();
} else if (id > 1) {
qCDebug(VideoManagerLog) << "Unsupported receiver id" << id; qCDebug(VideoManagerLog) << "Unsupported receiver id" << id;
} else if (_videoReceiver[id] != nullptr) {
_videoReceiver[id]->stop();
} }
#endif #endif
} }
...@@ -742,14 +763,14 @@ VideoManager::_setActiveVehicle(Vehicle* vehicle) ...@@ -742,14 +763,14 @@ VideoManager::_setActiveVehicle(Vehicle* vehicle)
if(pCamera) { if(pCamera) {
pCamera->stopStream(); pCamera->stopStream();
} }
disconnect(_activeVehicle->dynamicCameras(), &QGCCameraManager::streamChanged, this, &VideoManager::_restartVideo); disconnect(_activeVehicle->dynamicCameras(), &QGCCameraManager::streamChanged, this, &VideoManager::_restartAllVideos);
} }
} }
_activeVehicle = vehicle; _activeVehicle = vehicle;
if(_activeVehicle) { if(_activeVehicle) {
connect(_activeVehicle, &Vehicle::connectionLostChanged, this, &VideoManager::_connectionLostChanged); connect(_activeVehicle, &Vehicle::connectionLostChanged, this, &VideoManager::_connectionLostChanged);
if(_activeVehicle->dynamicCameras()) { if(_activeVehicle->dynamicCameras()) {
connect(_activeVehicle->dynamicCameras(), &QGCCameraManager::streamChanged, this, &VideoManager::_restartVideo); connect(_activeVehicle->dynamicCameras(), &QGCCameraManager::streamChanged, this, &VideoManager::_restartAllVideos);
QGCCameraControl* pCamera = _activeVehicle->dynamicCameras()->currentCameraInstance(); QGCCameraControl* pCamera = _activeVehicle->dynamicCameras()->currentCameraInstance();
if(pCamera) { if(pCamera) {
pCamera->resumeStream(); pCamera->resumeStream();
...@@ -760,7 +781,7 @@ VideoManager::_setActiveVehicle(Vehicle* vehicle) ...@@ -760,7 +781,7 @@ VideoManager::_setActiveVehicle(Vehicle* vehicle)
setfullScreen(false); setfullScreen(false);
} }
emit autoStreamConfiguredChanged(); emit autoStreamConfiguredChanged();
_restartVideo(); _restartAllVideos();
} }
//---------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------
......
...@@ -88,8 +88,8 @@ public: ...@@ -88,8 +88,8 @@ public:
// FIXME: AV: they should be removed after finishing multiple video stream support // FIXME: AV: they should be removed after finishing multiple video stream support
// new arcitecture does not assume direct access to video receiver from QML side, even if it works for now // new arcitecture does not assume direct access to video receiver from QML side, even if it works for now
virtual VideoReceiver* videoReceiver () { return _videoReceiver; } virtual VideoReceiver* videoReceiver () { return _videoReceiver[0]; }
virtual VideoReceiver* thermalVideoReceiver () { return _thermalVideoReceiver; } virtual VideoReceiver* thermalVideoReceiver () { return _videoReceiver[1]; }
#if defined(QGC_DISABLE_UVC) #if defined(QGC_DISABLE_UVC)
virtual bool uvcEnabled () { return false; } virtual bool uvcEnabled () { return false; }
...@@ -142,11 +142,11 @@ protected: ...@@ -142,11 +142,11 @@ protected:
friend class FinishVideoInitialization; friend class FinishVideoInitialization;
void _initVideo (); void _initVideo ();
bool _updateSettings (); bool _updateSettings (unsigned id);
bool _updateVideoUri (const QString& uri); bool _updateVideoUri (unsigned id, const QString& uri);
bool _updateThermalVideoUri (const QString& uri);
void _cleanupOldVideos (); void _cleanupOldVideos ();
void _restartVideo (); void _restartAllVideos ();
void _restartVideo (unsigned id);
void _startReceiver (unsigned id); void _startReceiver (unsigned id);
void _stopReceiver (unsigned id); void _stopReceiver (unsigned id);
...@@ -155,18 +155,15 @@ protected: ...@@ -155,18 +155,15 @@ protected:
QString _imageFile; QString _imageFile;
SubtitleWriter _subtitleWriter; SubtitleWriter _subtitleWriter;
bool _isTaisync = false; bool _isTaisync = false;
VideoReceiver* _videoReceiver = nullptr; VideoReceiver* _videoReceiver[2] = { nullptr, nullptr };
void* _videoSink[2] = { nullptr, nullptr };
QString _videoUri[2];
bool _videoStarted[2] = { false, false };
QAtomicInteger<bool> _streaming = false; QAtomicInteger<bool> _streaming = false;
QAtomicInteger<bool> _decoding = false; QAtomicInteger<bool> _decoding = false;
QAtomicInteger<bool> _recording = false; QAtomicInteger<bool> _recording = false;
QAtomicInteger<quint32> _videoSize = 0; QAtomicInteger<quint32> _videoSize = 0;
VideoReceiver* _thermalVideoReceiver = nullptr;
bool _enableVideoRestart = false;
void* _videoSink = nullptr;
void* _thermalVideoSink = nullptr;
VideoSettings* _videoSettings = nullptr; VideoSettings* _videoSettings = nullptr;
QString _videoUri;
QString _thermalVideoUri;
QString _videoSourceID; QString _videoSourceID;
bool _fullScreen = false; bool _fullScreen = false;
Vehicle* _activeVehicle = nullptr; Vehicle* _activeVehicle = nullptr;
......
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