diff --git a/src/FlightDisplay/VideoManager.cc b/src/FlightDisplay/VideoManager.cc index a68e880aa97d5ecb774e63f08197ba3b8a9634ab..d920acc4d633e96e5e5360822a18dc212a29979a 100644 --- a/src/FlightDisplay/VideoManager.cc +++ b/src/FlightDisplay/VideoManager.cc @@ -223,6 +223,15 @@ void VideoManager::_updateTimer() _videoRunning = false; _videoSurface->setLastFrame(0); emit videoRunningChanged(); + if(_videoReceiver) { + if(isGStreamer()) { + //-- Stop it + _videoReceiver->stop(); + QThread::msleep(100); + //-- And start over + _videoReceiver->start(); + } + } } } else diff --git a/src/VideoStreaming/VideoReceiver.cc b/src/VideoStreaming/VideoReceiver.cc index 520aa48b279351f84ad9fec61a9be0d7711136a4..594a028f00c5dac93a2d587b7d8973f3c7b88781 100644 --- a/src/VideoStreaming/VideoReceiver.cc +++ b/src/VideoStreaming/VideoReceiver.cc @@ -16,15 +16,21 @@ #include "VideoReceiver.h" #include +#include VideoReceiver::VideoReceiver(QObject* parent) : QObject(parent) #if defined(QGC_GST_STREAMING) , _pipeline(NULL) , _videoSink(NULL) + , _socket(NULL) + , _serverPresent(false) #endif { - +#if defined(QGC_GST_STREAMING) + _timer.setSingleShot(true); + connect(&_timer, &QTimer::timeout, this, &VideoReceiver::_timeout); +#endif } VideoReceiver::~VideoReceiver() @@ -32,6 +38,9 @@ VideoReceiver::~VideoReceiver() #if defined(QGC_GST_STREAMING) stop(); setVideoSink(NULL); + if(_socket) { + delete _socket; + } #endif } @@ -66,6 +75,51 @@ static void newPadCB(GstElement * element, GstPad* pad, gpointer data) } #endif +#if defined(QGC_GST_STREAMING) +void VideoReceiver::_connected() +{ + //-- Server showed up. Now we start the stream. + _timer.stop(); + delete _socket; + _socket = NULL; + _serverPresent = true; + start(); +} +#endif + +#if defined(QGC_GST_STREAMING) +void VideoReceiver::_socketError(QAbstractSocket::SocketError socketError) +{ + Q_UNUSED(socketError); + delete _socket; + _socket = NULL; + //-- Try again in 5 seconds + _timer.start(5000); +} +#endif + +#if defined(QGC_GST_STREAMING) +void VideoReceiver::_timeout() +{ + //-- If socket is live, we got no connection nor a socket error + if(_socket) { + delete _socket; + _socket = NULL; + } + //-- RTSP will try to connect to the server. If it cannot connect, + // it will simply give up and never try again. Instead, we keep + // attempting a connection on this timer. Once a connection is + // found to be working, only then we actually start the stream. + QUrl url(_uri); + _socket = new QTcpSocket; + connect(_socket, static_cast(&QTcpSocket::error), this, &VideoReceiver::_socketError); + connect(_socket, &QTcpSocket::connected, this, &VideoReceiver::_connected); + //qDebug() << "Trying to connect to:" << url.host() << url.port(); + _socket->connectToHost(url.host(), url.port()); + _timer.start(5000); +} +#endif + void VideoReceiver::start() { #if defined(QGC_GST_STREAMING) @@ -78,8 +132,16 @@ void VideoReceiver::start() return; } + bool isUdp = _uri.contains("udp://"); + stop(); + //-- For RTSP, check to see if server is there first + if(!_serverPresent && !isUdp) { + _timer.start(100); + return; + } + bool running = false; GstElement* dataSource = NULL; @@ -88,8 +150,6 @@ void VideoReceiver::start() GstElement* parser = NULL; GstElement* decoder = NULL; - bool isUdp = _uri.contains("udp://"); - do { if ((_pipeline = gst_pipeline_new("receiver")) == NULL) { qCritical() << "VideoReceiver::start() failed. Error with gst_pipeline_new()"; @@ -114,7 +174,7 @@ void VideoReceiver::start() } g_object_set(G_OBJECT(dataSource), "uri", qPrintable(_uri), "caps", caps, NULL); } else { - g_object_set(G_OBJECT(dataSource), "location", qPrintable(_uri), "latency", 0, NULL); + g_object_set(G_OBJECT(dataSource), "location", qPrintable(_uri), "latency", 0, "udp-reconnect", 1, "timeout", 5000000, NULL); } if ((demux = gst_element_factory_make("rtph264depay", "rtp-h264-depacketizer")) == NULL) { @@ -208,6 +268,7 @@ void VideoReceiver::stop() gst_element_set_state(_pipeline, GST_STATE_NULL); gst_object_unref(_pipeline); _pipeline = NULL; + _serverPresent = false; } #endif } diff --git a/src/VideoStreaming/VideoReceiver.h b/src/VideoStreaming/VideoReceiver.h index 0faa58864b804c62a16a4ec256b6fa99644cc862..6069a99a159b63d607361a32d0501a08be0643c6 100644 --- a/src/VideoStreaming/VideoReceiver.h +++ b/src/VideoStreaming/VideoReceiver.h @@ -18,6 +18,9 @@ #define VIDEORECEIVER_H #include +#include +#include + #if defined(QGC_GST_STREAMING) #include #endif @@ -33,10 +36,17 @@ public: void setVideoSink(GstElement* sink); #endif -public Q_SLOTS: - void start (); - void stop (); - void setUri (const QString& uri); +public slots: + void start (); + void stop (); + void setUri (const QString& uri); + +private slots: +#if defined(QGC_GST_STREAMING) + void _timeout (); + void _connected (); + void _socketError (QAbstractSocket::SocketError socketError); +#endif private: @@ -52,6 +62,12 @@ private: GstElement* _videoSink; #endif + //-- Wait for Video Server to show up before starting +#if defined(QGC_GST_STREAMING) + QTimer _timer; + QTcpSocket* _socket; + bool _serverPresent; +#endif }; #endif // VIDEORECEIVER_H