Unverified Commit 6d052668 authored by Gus Grubba's avatar Gus Grubba Committed by GitHub

Merge pull request #6990 from mavlink/rtspUdpTimeout

RTSP UDP timeout
parents 2d186f2a ebcc802d
...@@ -32,8 +32,8 @@ QGC_LOGGING_CATEGORY(VideoManagerLog, "VideoManagerLog") ...@@ -32,8 +32,8 @@ QGC_LOGGING_CATEGORY(VideoManagerLog, "VideoManagerLog")
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
VideoManager::VideoManager(QGCApplication* app, QGCToolbox* toolbox) VideoManager::VideoManager(QGCApplication* app, QGCToolbox* toolbox)
: QGCTool(app, toolbox) : QGCTool(app, toolbox)
, _videoReceiver(NULL) , _videoReceiver(nullptr)
, _videoSettings(NULL) , _videoSettings(nullptr)
, _fullScreen(false) , _fullScreen(false)
{ {
} }
......
...@@ -56,19 +56,20 @@ VideoReceiver::VideoReceiver(QObject* parent) ...@@ -56,19 +56,20 @@ VideoReceiver::VideoReceiver(QObject* parent)
, _streaming(false) , _streaming(false)
, _starting(false) , _starting(false)
, _stopping(false) , _stopping(false)
, _sink(NULL) , _sink(nullptr)
, _tee(NULL) , _tee(nullptr)
, _pipeline(NULL) , _pipeline(nullptr)
, _pipelineStopRec(NULL) , _pipelineStopRec(nullptr)
, _videoSink(NULL) , _videoSink(nullptr)
, _socket(NULL) , _socket(nullptr)
, _serverPresent(false) , _serverPresent(false)
, _rtspTestInterval_ms(5000) , _rtspTestInterval_ms(5000)
, _udpReconnect_us(5000000)
#endif #endif
, _videoSurface(NULL) , _videoSurface(nullptr)
, _videoRunning(false) , _videoRunning(false)
, _showFullScreen(false) , _showFullScreen(false)
, _videoSettings(NULL) , _videoSettings(nullptr)
{ {
_videoSurface = new VideoSurface; _videoSurface = new VideoSurface;
_videoSettings = qgcApp()->toolbox()->settingsManager()->videoSettings(); _videoSettings = qgcApp()->toolbox()->settingsManager()->videoSettings();
...@@ -105,7 +106,7 @@ VideoReceiver::_setVideoSink(GstElement* sink) ...@@ -105,7 +106,7 @@ VideoReceiver::_setVideoSink(GstElement* sink)
{ {
if (_videoSink) { if (_videoSink) {
gst_object_unref(_videoSink); gst_object_unref(_videoSink);
_videoSink = NULL; _videoSink = nullptr;
} }
if (sink) { if (sink) {
_videoSink = sink; _videoSink = sink;
...@@ -149,7 +150,7 @@ VideoReceiver::_connected() ...@@ -149,7 +150,7 @@ VideoReceiver::_connected()
//-- Server showed up. Now we start the stream. //-- Server showed up. Now we start the stream.
_timer.stop(); _timer.stop();
_socket->deleteLater(); _socket->deleteLater();
_socket = NULL; _socket = nullptr;
if(_videoSettings->streamEnabled()->rawValue().toBool()) { if(_videoSettings->streamEnabled()->rawValue().toBool()) {
_serverPresent = true; _serverPresent = true;
start(); start();
...@@ -164,7 +165,7 @@ VideoReceiver::_socketError(QAbstractSocket::SocketError socketError) ...@@ -164,7 +165,7 @@ VideoReceiver::_socketError(QAbstractSocket::SocketError socketError)
{ {
Q_UNUSED(socketError); Q_UNUSED(socketError);
_socket->deleteLater(); _socket->deleteLater();
_socket = NULL; _socket = nullptr;
//-- Try again in a while //-- Try again in a while
if(_videoSettings->streamEnabled()->rawValue().toBool()) { if(_videoSettings->streamEnabled()->rawValue().toBool()) {
_timer.start(_rtspTestInterval_ms); _timer.start(_rtspTestInterval_ms);
...@@ -180,7 +181,7 @@ VideoReceiver::_timeout() ...@@ -180,7 +181,7 @@ VideoReceiver::_timeout()
//-- If socket is live, we got no connection nor a socket error //-- If socket is live, we got no connection nor a socket error
if(_socket) { if(_socket) {
delete _socket; delete _socket;
_socket = NULL; _socket = nullptr;
} }
if(_videoSettings->streamEnabled()->rawValue().toBool()) { if(_videoSettings->streamEnabled()->rawValue().toBool()) {
//-- RTSP will try to connect to the server. If it cannot connect, //-- RTSP will try to connect to the server. If it cannot connect,
...@@ -194,7 +195,7 @@ VideoReceiver::_timeout() ...@@ -194,7 +195,7 @@ VideoReceiver::_timeout()
_socket->setProxy(tempProxy); _socket->setProxy(tempProxy);
connect(_socket, static_cast<void (QTcpSocket::*)(QAbstractSocket::SocketError)>(&QTcpSocket::error), this, &VideoReceiver::_socketError); connect(_socket, static_cast<void (QTcpSocket::*)(QAbstractSocket::SocketError)>(&QTcpSocket::error), this, &VideoReceiver::_socketError);
connect(_socket, &QTcpSocket::connected, this, &VideoReceiver::_connected); connect(_socket, &QTcpSocket::connected, this, &VideoReceiver::_connected);
_socket->connectToHost(url.host(), url.port()); _socket->connectToHost(url.host(), static_cast<uint16_t>(url.port()));
_timer.start(_rtspTestInterval_ms); _timer.start(_rtspTestInterval_ms);
} }
} }
...@@ -226,7 +227,7 @@ VideoReceiver::start() ...@@ -226,7 +227,7 @@ VideoReceiver::start()
qCritical() << "VideoReceiver::start() failed because URI is not specified"; qCritical() << "VideoReceiver::start() failed because URI is not specified";
return; return;
} }
if (_videoSink == NULL) { if (_videoSink == nullptr) {
qCritical() << "VideoReceiver::start() failed because video sink is not set"; qCritical() << "VideoReceiver::start() failed because video sink is not set";
return; return;
} }
...@@ -250,16 +251,16 @@ VideoReceiver::start() ...@@ -250,16 +251,16 @@ VideoReceiver::start()
bool running = false; bool running = false;
bool pipelineUp = false; bool pipelineUp = false;
GstElement* dataSource = NULL; GstElement* dataSource = nullptr;
GstCaps* caps = NULL; GstCaps* caps = nullptr;
GstElement* demux = NULL; GstElement* demux = nullptr;
GstElement* parser = NULL; GstElement* parser = nullptr;
GstElement* queue = NULL; GstElement* queue = nullptr;
GstElement* decoder = NULL; GstElement* decoder = nullptr;
GstElement* queue1 = NULL; GstElement* queue1 = nullptr;
do { do {
if ((_pipeline = gst_pipeline_new("receiver")) == NULL) { if ((_pipeline = gst_pipeline_new("receiver")) == nullptr) {
qCritical() << "VideoReceiver::start() failed. Error with gst_pipeline_new()"; qCritical() << "VideoReceiver::start() failed. Error with gst_pipeline_new()";
break; break;
} }
...@@ -278,64 +279,64 @@ VideoReceiver::start() ...@@ -278,64 +279,64 @@ VideoReceiver::start()
} }
if(isUdp) { if(isUdp) {
if ((caps = gst_caps_from_string("application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)H264")) == NULL) { if ((caps = gst_caps_from_string("application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)H264")) == nullptr) {
qCritical() << "VideoReceiver::start() failed. Error with gst_caps_from_string()"; qCritical() << "VideoReceiver::start() failed. Error with gst_caps_from_string()";
break; break;
} }
g_object_set(G_OBJECT(dataSource), "uri", qPrintable(_uri), "caps", caps, NULL); g_object_set(G_OBJECT(dataSource), "uri", qPrintable(_uri), "caps", caps, nullptr);
} else if(isTCP) { } else if(isTCP) {
QUrl url(_uri); QUrl url(_uri);
g_object_set(G_OBJECT(dataSource), "host", qPrintable(url.host()), "port", url.port(), NULL ); g_object_set(G_OBJECT(dataSource), "host", qPrintable(url.host()), "port", url.port(), nullptr );
} else { } else {
g_object_set(G_OBJECT(dataSource), "location", qPrintable(_uri), "latency", 17, "udp-reconnect", 1, "timeout", static_cast<guint64>(5000000), NULL); g_object_set(G_OBJECT(dataSource), "location", qPrintable(_uri), "latency", 17, "udp-reconnect", 1, "timeout", _udpReconnect_us, NULL);
} }
// Currently, we expect H264 when using anything except for TCP. Long term we may want this to be settable // Currently, we expect H264 when using anything except for TCP. Long term we may want this to be settable
if (isTCP) { if (isTCP) {
if ((demux = gst_element_factory_make("tsdemux", "mpeg2-ts-demuxer")) == NULL) { if ((demux = gst_element_factory_make("tsdemux", "mpeg2-ts-demuxer")) == nullptr) {
qCritical() << "VideoReceiver::start() failed. Error with gst_element_factory_make('tsdemux')"; qCritical() << "VideoReceiver::start() failed. Error with gst_element_factory_make('tsdemux')";
break; break;
} }
} else { } else {
if ((demux = gst_element_factory_make("rtph264depay", "rtp-h264-depacketizer")) == NULL) { if ((demux = gst_element_factory_make("rtph264depay", "rtp-h264-depacketizer")) == nullptr) {
qCritical() << "VideoReceiver::start() failed. Error with gst_element_factory_make('rtph264depay')"; qCritical() << "VideoReceiver::start() failed. Error with gst_element_factory_make('rtph264depay')";
break; break;
} }
} }
if ((parser = gst_element_factory_make("h264parse", "h264-parser")) == NULL) { if ((parser = gst_element_factory_make("h264parse", "h264-parser")) == nullptr) {
qCritical() << "VideoReceiver::start() failed. Error with gst_element_factory_make('h264parse')"; qCritical() << "VideoReceiver::start() failed. Error with gst_element_factory_make('h264parse')";
break; break;
} }
if((_tee = gst_element_factory_make("tee", NULL)) == NULL) { if((_tee = gst_element_factory_make("tee", nullptr)) == nullptr) {
qCritical() << "VideoReceiver::start() failed. Error with gst_element_factory_make('tee')"; qCritical() << "VideoReceiver::start() failed. Error with gst_element_factory_make('tee')";
break; break;
} }
if((queue = gst_element_factory_make("queue", NULL)) == NULL) { if((queue = gst_element_factory_make("queue", nullptr)) == nullptr) {
// TODO: We may want to add queue2 max-size-buffers=1 to get lower latency // TODO: We may want to add queue2 max-size-buffers=1 to get lower latency
// We should compare gstreamer scripts to QGroundControl to determine the need // We should compare gstreamer scripts to QGroundControl to determine the need
qCritical() << "VideoReceiver::start() failed. Error with gst_element_factory_make('queue')"; qCritical() << "VideoReceiver::start() failed. Error with gst_element_factory_make('queue')";
break; break;
} }
if ((decoder = gst_element_factory_make("avdec_h264", "h264-decoder")) == NULL) { if ((decoder = gst_element_factory_make("avdec_h264", "h264-decoder")) == nullptr) {
qCritical() << "VideoReceiver::start() failed. Error with gst_element_factory_make('avdec_h264')"; qCritical() << "VideoReceiver::start() failed. Error with gst_element_factory_make('avdec_h264')";
break; break;
} }
if ((queue1 = gst_element_factory_make("queue", NULL)) == NULL) { if ((queue1 = gst_element_factory_make("queue", nullptr)) == nullptr) {
qCritical() << "VideoReceiver::start() failed. Error with gst_element_factory_make('queue') [1]"; qCritical() << "VideoReceiver::start() failed. Error with gst_element_factory_make('queue') [1]";
break; break;
} }
gst_bin_add_many(GST_BIN(_pipeline), dataSource, demux, parser, _tee, queue, decoder, queue1, _videoSink, NULL); gst_bin_add_many(GST_BIN(_pipeline), dataSource, demux, parser, _tee, queue, decoder, queue1, _videoSink, nullptr);
pipelineUp = true; pipelineUp = true;
if(isUdp) { if(isUdp) {
// Link the pipeline in front of the tee // Link the pipeline in front of the tee
if(!gst_element_link_many(dataSource, demux, parser, _tee, queue, decoder, queue1, _videoSink, NULL)) { if(!gst_element_link_many(dataSource, demux, parser, _tee, queue, decoder, queue1, _videoSink, nullptr)) {
qCritical() << "Unable to link UDP elements."; qCritical() << "Unable to link UDP elements.";
break; break;
} }
...@@ -344,28 +345,28 @@ VideoReceiver::start() ...@@ -344,28 +345,28 @@ VideoReceiver::start()
qCritical() << "Unable to link TCP dataSource to Demux."; qCritical() << "Unable to link TCP dataSource to Demux.";
break; break;
} }
if(!gst_element_link_many(parser, _tee, queue, decoder, queue1, _videoSink, NULL)) { if(!gst_element_link_many(parser, _tee, queue, decoder, queue1, _videoSink, nullptr)) {
qCritical() << "Unable to link TCP pipline to parser."; qCritical() << "Unable to link TCP pipline to parser.";
break; break;
} }
g_signal_connect(demux, "pad-added", G_CALLBACK(newPadCB), parser); g_signal_connect(demux, "pad-added", G_CALLBACK(newPadCB), parser);
} else { } else {
g_signal_connect(dataSource, "pad-added", G_CALLBACK(newPadCB), demux); g_signal_connect(dataSource, "pad-added", G_CALLBACK(newPadCB), demux);
if(!gst_element_link_many(demux, parser, _tee, queue, decoder, _videoSink, NULL)) { if(!gst_element_link_many(demux, parser, _tee, queue, decoder, _videoSink, nullptr)) {
qCritical() << "Unable to link RTSP elements."; qCritical() << "Unable to link RTSP elements.";
break; break;
} }
} }
dataSource = demux = parser = queue = decoder = queue1 = NULL; dataSource = demux = parser = queue = decoder = queue1 = nullptr;
GstBus* bus = NULL; GstBus* bus = nullptr;
if ((bus = gst_pipeline_get_bus(GST_PIPELINE(_pipeline))) != NULL) { if ((bus = gst_pipeline_get_bus(GST_PIPELINE(_pipeline))) != nullptr) {
gst_bus_enable_sync_message_emission(bus); gst_bus_enable_sync_message_emission(bus);
g_signal_connect(bus, "sync-message", G_CALLBACK(_onBusMessage), this); g_signal_connect(bus, "sync-message", G_CALLBACK(_onBusMessage), this);
gst_object_unref(bus); gst_object_unref(bus);
bus = NULL; bus = nullptr;
} }
GST_DEBUG_BIN_TO_DOT_FILE(GST_BIN(_pipeline), GST_DEBUG_GRAPH_SHOW_ALL, "pipeline-paused"); GST_DEBUG_BIN_TO_DOT_FILE(GST_BIN(_pipeline), GST_DEBUG_GRAPH_SHOW_ALL, "pipeline-paused");
...@@ -373,50 +374,50 @@ VideoReceiver::start() ...@@ -373,50 +374,50 @@ VideoReceiver::start()
} while(0); } while(0);
if (caps != NULL) { if (caps != nullptr) {
gst_caps_unref(caps); gst_caps_unref(caps);
caps = NULL; caps = nullptr;
} }
if (!running) { if (!running) {
qCritical() << "VideoReceiver::start() failed"; qCritical() << "VideoReceiver::start() failed";
// In newer versions, the pipeline will clean up all references that are added to it // In newer versions, the pipeline will clean up all references that are added to it
if (_pipeline != NULL) { if (_pipeline != nullptr) {
gst_object_unref(_pipeline); gst_object_unref(_pipeline);
_pipeline = NULL; _pipeline = nullptr;
} }
// If we failed before adding items to the pipeline, then clean up // If we failed before adding items to the pipeline, then clean up
if (!pipelineUp) { if (!pipelineUp) {
if (decoder != NULL) { if (decoder != nullptr) {
gst_object_unref(decoder); gst_object_unref(decoder);
decoder = NULL; decoder = nullptr;
} }
if (parser != NULL) { if (parser != nullptr) {
gst_object_unref(parser); gst_object_unref(parser);
parser = NULL; parser = nullptr;
} }
if (demux != NULL) { if (demux != nullptr) {
gst_object_unref(demux); gst_object_unref(demux);
demux = NULL; demux = nullptr;
} }
if (dataSource != NULL) { if (dataSource != nullptr) {
gst_object_unref(dataSource); gst_object_unref(dataSource);
dataSource = NULL; dataSource = nullptr;
} }
if (_tee != NULL) { if (_tee != nullptr) {
gst_object_unref(_tee); gst_object_unref(_tee);
dataSource = NULL; dataSource = nullptr;
} }
if (queue != NULL) { if (queue != nullptr) {
gst_object_unref(queue); gst_object_unref(queue);
dataSource = NULL; dataSource = nullptr;
} }
} }
...@@ -439,7 +440,7 @@ VideoReceiver::stop() ...@@ -439,7 +440,7 @@ VideoReceiver::stop()
qCDebug(VideoReceiverLog) << "stop()"; qCDebug(VideoReceiverLog) << "stop()";
if(!_streaming) { if(!_streaming) {
_shutdownPipeline(); _shutdownPipeline();
} else if (_pipeline != NULL && !_stopping) { } else if (_pipeline != nullptr && !_stopping) {
qCDebug(VideoReceiverLog) << "Stopping _pipeline"; qCDebug(VideoReceiverLog) << "Stopping _pipeline";
gst_element_send_event(_pipeline, gst_event_new_eos()); gst_element_send_event(_pipeline, gst_event_new_eos());
_stopping = true; _stopping = true;
...@@ -472,18 +473,18 @@ VideoReceiver::_shutdownPipeline() { ...@@ -472,18 +473,18 @@ VideoReceiver::_shutdownPipeline() {
qCDebug(VideoReceiverLog) << "No pipeline"; qCDebug(VideoReceiverLog) << "No pipeline";
return; return;
} }
GstBus* bus = NULL; GstBus* bus = nullptr;
if ((bus = gst_pipeline_get_bus(GST_PIPELINE(_pipeline))) != NULL) { if ((bus = gst_pipeline_get_bus(GST_PIPELINE(_pipeline))) != nullptr) {
gst_bus_disable_sync_message_emission(bus); gst_bus_disable_sync_message_emission(bus);
gst_object_unref(bus); gst_object_unref(bus);
bus = NULL; bus = nullptr;
} }
gst_element_set_state(_pipeline, GST_STATE_NULL); gst_element_set_state(_pipeline, GST_STATE_NULL);
gst_bin_remove(GST_BIN(_pipeline), _videoSink); gst_bin_remove(GST_BIN(_pipeline), _videoSink);
gst_object_unref(_pipeline); gst_object_unref(_pipeline);
_pipeline = NULL; _pipeline = nullptr;
delete _sink; delete _sink;
_sink = NULL; _sink = nullptr;
_serverPresent = false; _serverPresent = false;
_streaming = false; _streaming = false;
_recording = false; _recording = false;
...@@ -535,7 +536,7 @@ gboolean ...@@ -535,7 +536,7 @@ gboolean
VideoReceiver::_onBusMessage(GstBus* bus, GstMessage* msg, gpointer data) VideoReceiver::_onBusMessage(GstBus* bus, GstMessage* msg, gpointer data)
{ {
Q_UNUSED(bus) Q_UNUSED(bus)
Q_ASSERT(msg != NULL && data != NULL); Q_ASSERT(msg != nullptr && data != nullptr);
VideoReceiver* pThis = (VideoReceiver*)data; VideoReceiver* pThis = (VideoReceiver*)data;
switch(GST_MESSAGE_TYPE(msg)) { switch(GST_MESSAGE_TYPE(msg)) {
...@@ -622,7 +623,7 @@ VideoReceiver::startRecording(const QString &videoFile) ...@@ -622,7 +623,7 @@ VideoReceiver::startRecording(const QString &videoFile)
qCDebug(VideoReceiverLog) << "startRecording()"; qCDebug(VideoReceiverLog) << "startRecording()";
// exit immediately if we are already recording // exit immediately if we are already recording
if(_pipeline == NULL || _recording) { if(_pipeline == nullptr || _recording) {
qCDebug(VideoReceiverLog) << "Already recording!"; qCDebug(VideoReceiverLog) << "Already recording!";
return; return;
} }
...@@ -638,10 +639,10 @@ VideoReceiver::startRecording(const QString &videoFile) ...@@ -638,10 +639,10 @@ VideoReceiver::startRecording(const QString &videoFile)
_sink = new Sink(); _sink = new Sink();
_sink->teepad = gst_element_get_request_pad(_tee, "src_%u"); _sink->teepad = gst_element_get_request_pad(_tee, "src_%u");
_sink->queue = gst_element_factory_make("queue", NULL); _sink->queue = gst_element_factory_make("queue", nullptr);
_sink->parse = gst_element_factory_make("h264parse", NULL); _sink->parse = gst_element_factory_make("h264parse", nullptr);
_sink->mux = gst_element_factory_make(kVideoMuxes[muxIdx], NULL); _sink->mux = gst_element_factory_make(kVideoMuxes[muxIdx], nullptr);
_sink->filesink = gst_element_factory_make("filesink", NULL); _sink->filesink = gst_element_factory_make("filesink", nullptr);
_sink->removing = false; _sink->removing = false;
if(!_sink->teepad || !_sink->queue || !_sink->mux || !_sink->filesink || !_sink->parse) { if(!_sink->teepad || !_sink->queue || !_sink->mux || !_sink->filesink || !_sink->parse) {
...@@ -661,7 +662,7 @@ VideoReceiver::startRecording(const QString &videoFile) ...@@ -661,7 +662,7 @@ VideoReceiver::startRecording(const QString &videoFile)
} }
emit videoFileChanged(); emit videoFileChanged();
g_object_set(G_OBJECT(_sink->filesink), "location", qPrintable(_videoFile), NULL); g_object_set(G_OBJECT(_sink->filesink), "location", qPrintable(_videoFile), nullptr);
qCDebug(VideoReceiverLog) << "New video file:" << _videoFile; qCDebug(VideoReceiverLog) << "New video file:" << _videoFile;
gst_object_ref(_sink->queue); gst_object_ref(_sink->queue);
...@@ -669,8 +670,8 @@ VideoReceiver::startRecording(const QString &videoFile) ...@@ -669,8 +670,8 @@ VideoReceiver::startRecording(const QString &videoFile)
gst_object_ref(_sink->mux); gst_object_ref(_sink->mux);
gst_object_ref(_sink->filesink); gst_object_ref(_sink->filesink);
gst_bin_add_many(GST_BIN(_pipeline), _sink->queue, _sink->parse, _sink->mux, _sink->filesink, NULL); gst_bin_add_many(GST_BIN(_pipeline), _sink->queue, _sink->parse, _sink->mux, _sink->filesink, nullptr);
gst_element_link_many(_sink->queue, _sink->parse, _sink->mux, _sink->filesink, NULL); gst_element_link_many(_sink->queue, _sink->parse, _sink->mux, _sink->filesink, nullptr);
gst_element_sync_state_with_parent(_sink->queue); gst_element_sync_state_with_parent(_sink->queue);
gst_element_sync_state_with_parent(_sink->parse); gst_element_sync_state_with_parent(_sink->parse);
...@@ -681,7 +682,7 @@ VideoReceiver::startRecording(const QString &videoFile) ...@@ -681,7 +682,7 @@ VideoReceiver::startRecording(const QString &videoFile)
// When we hit our first keyframe, we can offset the timestamps appropriately according to the first keyframe time // When we hit our first keyframe, we can offset the timestamps appropriately according to the first keyframe time
// This will ensure the first frame is a keyframe at t=0, and decoding can begin immediately on playback // This will ensure the first frame is a keyframe at t=0, and decoding can begin immediately on playback
GstPad* probepad = gst_element_get_static_pad(_sink->queue, "src"); GstPad* probepad = gst_element_get_static_pad(_sink->queue, "src");
gst_pad_add_probe(probepad, (GstPadProbeType)(GST_PAD_PROBE_TYPE_BUFFER /* | GST_PAD_PROBE_TYPE_BLOCK */), _keyframeWatch, this, NULL); // to drop the buffer or to block the buffer? gst_pad_add_probe(probepad, (GstPadProbeType)(GST_PAD_PROBE_TYPE_BUFFER /* | GST_PAD_PROBE_TYPE_BLOCK */), _keyframeWatch, this, nullptr); // to drop the buffer or to block the buffer?
gst_object_unref(probepad); gst_object_unref(probepad);
// Link the recording branch to the pipeline // Link the recording branch to the pipeline
...@@ -706,12 +707,12 @@ VideoReceiver::stopRecording(void) ...@@ -706,12 +707,12 @@ VideoReceiver::stopRecording(void)
#if defined(QGC_GST_STREAMING) #if defined(QGC_GST_STREAMING)
qCDebug(VideoReceiverLog) << "stopRecording()"; qCDebug(VideoReceiverLog) << "stopRecording()";
// exit immediately if we are not recording // exit immediately if we are not recording
if(_pipeline == NULL || !_recording) { if(_pipeline == nullptr || !_recording) {
qCDebug(VideoReceiverLog) << "Not recording!"; qCDebug(VideoReceiverLog) << "Not recording!";
return; return;
} }
// Wait for data block before unlinking // Wait for data block before unlinking
gst_pad_add_probe(_sink->teepad, GST_PAD_PROBE_TYPE_IDLE, _unlinkCallBack, this, NULL); gst_pad_add_probe(_sink->teepad, GST_PAD_PROBE_TYPE_IDLE, _unlinkCallBack, this, nullptr);
#endif #endif
} }
...@@ -732,7 +733,7 @@ VideoReceiver::_shutdownRecordingBranch() ...@@ -732,7 +733,7 @@ VideoReceiver::_shutdownRecordingBranch()
gst_element_set_state(_pipelineStopRec, GST_STATE_NULL); gst_element_set_state(_pipelineStopRec, GST_STATE_NULL);
gst_object_unref(_pipelineStopRec); gst_object_unref(_pipelineStopRec);
_pipelineStopRec = NULL; _pipelineStopRec = nullptr;
gst_element_set_state(_sink->filesink, GST_STATE_NULL); gst_element_set_state(_sink->filesink, GST_STATE_NULL);
gst_element_set_state(_sink->parse, GST_STATE_NULL); gst_element_set_state(_sink->parse, GST_STATE_NULL);
...@@ -745,7 +746,7 @@ VideoReceiver::_shutdownRecordingBranch() ...@@ -745,7 +746,7 @@ VideoReceiver::_shutdownRecordingBranch()
gst_object_unref(_sink->filesink); gst_object_unref(_sink->filesink);
delete _sink; delete _sink;
_sink = NULL; _sink = nullptr;
_recording = false; _recording = false;
emit recordingChanged(); emit recordingChanged();
...@@ -765,7 +766,7 @@ VideoReceiver::_detachRecordingBranch(GstPadProbeInfo* info) ...@@ -765,7 +766,7 @@ VideoReceiver::_detachRecordingBranch(GstPadProbeInfo* info)
Q_UNUSED(info) Q_UNUSED(info)
// Also unlinks and unrefs // Also unlinks and unrefs
gst_bin_remove_many(GST_BIN(_pipeline), _sink->queue, _sink->parse, _sink->mux, _sink->filesink, NULL); gst_bin_remove_many(GST_BIN(_pipeline), _sink->queue, _sink->parse, _sink->mux, _sink->filesink, nullptr);
// Give tee its pad back // Give tee its pad back
gst_element_release_request_pad(_tee, _sink->teepad); gst_element_release_request_pad(_tee, _sink->teepad);
...@@ -775,8 +776,8 @@ VideoReceiver::_detachRecordingBranch(GstPadProbeInfo* info) ...@@ -775,8 +776,8 @@ VideoReceiver::_detachRecordingBranch(GstPadProbeInfo* info)
_pipelineStopRec = gst_pipeline_new("pipeStopRec"); _pipelineStopRec = gst_pipeline_new("pipeStopRec");
// Put our elements from the recording branch into the temporary pipeline // Put our elements from the recording branch into the temporary pipeline
gst_bin_add_many(GST_BIN(_pipelineStopRec), _sink->queue, _sink->parse, _sink->mux, _sink->filesink, NULL); gst_bin_add_many(GST_BIN(_pipelineStopRec), _sink->queue, _sink->parse, _sink->mux, _sink->filesink, nullptr);
gst_element_link_many(_sink->queue, _sink->parse, _sink->mux, _sink->filesink, NULL); gst_element_link_many(_sink->queue, _sink->parse, _sink->mux, _sink->filesink, nullptr);
// Add handler for EOS event // Add handler for EOS event
GstBus* bus = gst_pipeline_get_bus(GST_PIPELINE(_pipelineStopRec)); GstBus* bus = gst_pipeline_get_bus(GST_PIPELINE(_pipelineStopRec));
...@@ -802,8 +803,8 @@ GstPadProbeReturn ...@@ -802,8 +803,8 @@ GstPadProbeReturn
VideoReceiver::_unlinkCallBack(GstPad* pad, GstPadProbeInfo* info, gpointer user_data) VideoReceiver::_unlinkCallBack(GstPad* pad, GstPadProbeInfo* info, gpointer user_data)
{ {
Q_UNUSED(pad); Q_UNUSED(pad);
if(info != NULL && user_data != NULL) { if(info != nullptr && user_data != nullptr) {
VideoReceiver* pThis = (VideoReceiver*)user_data; VideoReceiver* pThis = static_cast<VideoReceiver*>(user_data);
// We will only act once // We will only act once
if(g_atomic_int_compare_and_exchange(&pThis->_sink->removing, FALSE, TRUE)) { if(g_atomic_int_compare_and_exchange(&pThis->_sink->removing, FALSE, TRUE)) {
pThis->_detachRecordingBranch(info); pThis->_detachRecordingBranch(info);
...@@ -819,12 +820,12 @@ GstPadProbeReturn ...@@ -819,12 +820,12 @@ GstPadProbeReturn
VideoReceiver::_keyframeWatch(GstPad* pad, GstPadProbeInfo* info, gpointer user_data) VideoReceiver::_keyframeWatch(GstPad* pad, GstPadProbeInfo* info, gpointer user_data)
{ {
Q_UNUSED(pad); Q_UNUSED(pad);
if(info != NULL && user_data != NULL) { if(info != nullptr && user_data != nullptr) {
GstBuffer* buf = gst_pad_probe_info_get_buffer(info); GstBuffer* buf = gst_pad_probe_info_get_buffer(info);
if(GST_BUFFER_FLAG_IS_SET(buf, GST_BUFFER_FLAG_DELTA_UNIT)) { // wait for a keyframe if(GST_BUFFER_FLAG_IS_SET(buf, GST_BUFFER_FLAG_DELTA_UNIT)) { // wait for a keyframe
return GST_PAD_PROBE_DROP; return GST_PAD_PROBE_DROP;
} else { } else {
VideoReceiver* pThis = (VideoReceiver*)user_data; VideoReceiver* pThis = static_cast<VideoReceiver*>(user_data);
// reset the clock // reset the clock
GstClock* clock = gst_pipeline_get_clock(GST_PIPELINE(pThis->_pipeline)); GstClock* clock = gst_pipeline_get_clock(GST_PIPELINE(pThis->_pipeline));
GstClockTime time = gst_clock_get_time(clock); GstClockTime time = gst_clock_get_time(clock);
...@@ -869,9 +870,9 @@ VideoReceiver::_updateTimer() ...@@ -869,9 +870,9 @@ VideoReceiver::_updateTimer()
time_t elapsed = 0; time_t elapsed = 0;
time_t lastFrame = _videoSurface->lastFrame(); time_t lastFrame = _videoSurface->lastFrame();
if(lastFrame != 0) { if(lastFrame != 0) {
elapsed = time(0) - _videoSurface->lastFrame(); elapsed = time(nullptr) - _videoSurface->lastFrame();
} }
if(elapsed > (time_t)timeout && _videoSurface) { if(elapsed > static_cast<time_t>(timeout) && _videoSurface) {
stop(); stop();
// We want to start it back again with _updateTimer // We want to start it back again with _updateTimer
_stop = false; _stop = false;
......
...@@ -44,7 +44,7 @@ public: ...@@ -44,7 +44,7 @@ public:
Q_PROPERTY(QString videoFile READ videoFile NOTIFY videoFileChanged) Q_PROPERTY(QString videoFile READ videoFile NOTIFY videoFileChanged)
Q_PROPERTY(bool showFullScreen READ showFullScreen WRITE setShowFullScreen NOTIFY showFullScreenChanged) Q_PROPERTY(bool showFullScreen READ showFullScreen WRITE setShowFullScreen NOTIFY showFullScreenChanged)
explicit VideoReceiver(QObject* parent = 0); explicit VideoReceiver(QObject* parent = nullptr);
~VideoReceiver(); ~VideoReceiver();
#if defined(QGC_GST_STREAMING) #if defined(QGC_GST_STREAMING)
...@@ -138,6 +138,9 @@ protected: ...@@ -138,6 +138,9 @@ protected:
bool _serverPresent; bool _serverPresent;
int _rtspTestInterval_ms; int _rtspTestInterval_ms;
//-- RTSP UDP reconnect timeout
uint64_t _udpReconnect_us;
#endif #endif
QString _uri; QString _uri;
......
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