Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Q
qgroundcontrol
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Valentin Platzgummer
qgroundcontrol
Commits
62a4ba77
Commit
62a4ba77
authored
Jan 13, 2017
by
Jacob Walser
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Always shutdown streaming pipeline correctly, and call VideoReceiver start/stop appropriately
parent
4fb068fc
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
89 additions
and
58 deletions
+89
-58
VideoManager.cc
src/FlightDisplay/VideoManager.cc
+27
-28
VideoReceiver.cc
src/VideoStreaming/VideoReceiver.cc
+55
-29
VideoReceiver.h
src/VideoStreaming/VideoReceiver.h
+7
-1
No files found.
src/FlightDisplay/VideoManager.cc
View file @
62a4ba77
...
...
@@ -224,38 +224,37 @@ VideoManager::videoSourceList()
void
VideoManager
::
_updateTimer
()
{
#if defined(QGC_GST_STREAMING)
if
(
_videoRunning
)
{
time_t
elapsed
=
0
;
if
(
_videoSurface
)
{
elapsed
=
time
(
0
)
-
_videoSurface
->
lastFrame
();
}
if
(
elapsed
>
2
&&
_videoSurface
)
{
_videoRunning
=
false
;
_videoSurface
->
setLastFrame
(
0
);
emit
videoRunningChanged
();
if
(
_videoReceiver
)
{
if
(
isGStreamer
())
{
//-- Stop it
_videoReceiver
->
stop
();
QThread
::
msleep
(
100
);
//-- And start over
_videoReceiver
->
start
();
}
}
if
(
_videoReceiver
&&
_videoSurface
)
{
if
(
_videoReceiver
->
stopping
()
||
_videoReceiver
->
starting
())
{
return
;
}
}
else
{
if
(
_videoSurface
&&
_videoReceiver
->
streaming
())
{
qDebug
()
<<
_videoSurface
->
lastFrame
();
if
(
!
_videoRunning
)
{
if
(
_videoReceiver
->
streaming
())
{
if
(
!
_videoRunning
)
{
_videoSurface
->
setLastFrame
(
0
);
_videoRunning
=
true
;
emit
videoRunningChanged
();
}
}
else
{
if
(
_videoRunning
)
{
_videoRunning
=
false
;
emit
videoRunningChanged
();
}
}
if
(
_videoRunning
)
{
time_t
elapsed
=
0
;
time_t
lastFrame
=
_videoSurface
->
lastFrame
();
if
(
lastFrame
!=
0
)
{
elapsed
=
time
(
0
)
-
_videoSurface
->
lastFrame
();
}
if
(
elapsed
>
2
&&
_videoSurface
)
{
_videoReceiver
->
stop
();
}
}
else
{
if
(
!
_videoReceiver
->
running
())
{
_videoReceiver
->
start
();
}
}
}
#endif
...
...
src/VideoStreaming/VideoReceiver.cc
View file @
62a4ba77
...
...
@@ -31,12 +31,12 @@ void VideoReceiver::_eosCB(GstMessage* message)
{
Q_UNUSED
(
message
)
gst_bin_remove
(
GST_BIN
(
_pipeline
2
),
_sink
->
queue
);
gst_bin_remove
(
GST_BIN
(
_pipeline
2
),
_sink
->
mux
);
gst_bin_remove
(
GST_BIN
(
_pipeline
2
),
_sink
->
filesink
);
gst_bin_remove
(
GST_BIN
(
_pipeline
StopRec
),
_sink
->
queue
);
gst_bin_remove
(
GST_BIN
(
_pipeline
StopRec
),
_sink
->
mux
);
gst_bin_remove
(
GST_BIN
(
_pipeline
StopRec
),
_sink
->
filesink
);
gst_element_set_state
(
_pipeline
2
,
GST_STATE_NULL
);
gst_object_unref
(
_pipeline
2
);
gst_element_set_state
(
_pipeline
StopRec
,
GST_STATE_NULL
);
gst_object_unref
(
_pipeline
StopRec
);
gst_element_set_state
(
_sink
->
filesink
,
GST_STATE_NULL
);
gst_element_set_state
(
_sink
->
mux
,
GST_STATE_NULL
);
...
...
@@ -51,6 +51,7 @@ void VideoReceiver::_eosCB(GstMessage* message)
_recording
=
false
;
emit
recordingChanged
();
qCDebug
(
VideoReceiverLog
)
<<
"Recording Stopped"
;
}
#endif
...
...
@@ -71,27 +72,27 @@ void VideoReceiver::_unlinkCB(GstPadProbeInfo* info)
gst_object_unref
(
_sink
->
teepad
);
// Create temporary pipeline
_pipeline
2
=
gst_pipeline_new
(
"pipe2
"
);
_pipeline
StopRec
=
gst_pipeline_new
(
"pipeStopRec
"
);
// Put our elements from the recording branch into the temporary pipeline
gst_bin_add_many
(
GST_BIN
(
_pipeline
2
),
_sink
->
queue
,
_sink
->
mux
,
_sink
->
filesink
,
NULL
);
gst_bin_add_many
(
GST_BIN
(
_pipeline
StopRec
),
_sink
->
queue
,
_sink
->
mux
,
_sink
->
filesink
,
NULL
);
gst_element_link_many
(
_sink
->
queue
,
_sink
->
mux
,
_sink
->
filesink
,
NULL
);
// Add watch for EOS event
GstBus
*
bus
=
gst_pipeline_get_bus
(
GST_PIPELINE
(
_pipeline
2
));
GstBus
*
bus
=
gst_pipeline_get_bus
(
GST_PIPELINE
(
_pipeline
StopRec
));
gst_bus_add_signal_watch
(
bus
);
g_signal_connect
(
bus
,
"message::eos"
,
G_CALLBACK
(
_eosCallBack
),
this
);
gst_object_unref
(
bus
);
if
(
gst_element_set_state
(
_pipeline
2
,
GST_STATE_PLAYING
)
==
GST_STATE_CHANGE_FAILURE
)
{
qCDebug
(
VideoReceiverLog
)
<<
"problem starting
pipeline2
"
;
if
(
gst_element_set_state
(
_pipeline
StopRec
,
GST_STATE_PLAYING
)
==
GST_STATE_CHANGE_FAILURE
)
{
qCDebug
(
VideoReceiverLog
)
<<
"problem starting
_pipelineStopRec
"
;
}
// Send EOS at the beginning of the pipeline
GstPad
*
sinkpad
=
gst_element_get_static_pad
(
_sink
->
queue
,
"sink"
);
gst_pad_send_event
(
sinkpad
,
gst_event_new_eos
());
gst_object_unref
(
sinkpad
);
qCDebug
(
VideoReceiverLog
)
<<
"Recording branch unlinked"
;
}
#endif
...
...
@@ -135,8 +136,10 @@ GstPadProbeReturn VideoReceiver::_unlinkCallBack(GstPad* pad, GstPadProbeInfo* i
void
VideoReceiver
::
startRecording
(
void
)
{
#if defined(QGC_GST_STREAMING)
qCDebug
(
VideoReceiverLog
)
<<
"startRecording()"
;
// exit immediately if we are already recording
if
(
_pipeline
==
NULL
||
_recording
)
{
qCDebug
(
VideoReceiverLog
)
<<
"Already recording!"
;
return
;
}
...
...
@@ -174,17 +177,19 @@ void VideoReceiver::startRecording(void)
_recording
=
true
;
emit
recordingChanged
();
qCDebug
(
VideoReceiverLog
)
<<
"Recording started"
;
#endif
}
void
VideoReceiver
::
stopRecording
(
void
)
{
#if defined(QGC_GST_STREAMING)
qCDebug
(
VideoReceiverLog
)
<<
"stopRecording()"
;
// exit immediately if we are not recording
if
(
_pipeline
==
NULL
||
!
_recording
)
{
qCDebug
(
VideoReceiverLog
)
<<
"Not recording!"
;
return
;
}
// Wait for data block before unlinking
gst_pad_add_probe
(
_sink
->
teepad
,
GST_PAD_PROBE_TYPE_IDLE
,
_unlinkCallBack
,
this
,
NULL
);
#endif
...
...
@@ -192,13 +197,16 @@ void VideoReceiver::stopRecording(void)
VideoReceiver
::
VideoReceiver
(
QObject
*
parent
)
:
QObject
(
parent
)
,
_running
(
false
)
,
_recording
(
false
)
,
_streaming
(
false
)
,
_starting
(
false
)
,
_stopping
(
false
)
#if defined(QGC_GST_STREAMING)
,
_sink
(
NULL
)
,
_tee
(
NULL
)
,
_pipeline
(
NULL
)
,
_pipeline
2
(
NULL
)
,
_pipeline
StopRec
(
NULL
)
,
_videoSink
(
NULL
)
,
_socket
(
NULL
)
,
_serverPresent
(
false
)
...
...
@@ -214,7 +222,6 @@ VideoReceiver::~VideoReceiver()
{
#if defined(QGC_GST_STREAMING)
stop
();
setVideoSink
(
NULL
);
if
(
_socket
)
{
delete
_socket
;
}
...
...
@@ -309,6 +316,8 @@ void VideoReceiver::_timeout()
void
VideoReceiver
::
start
()
{
#if defined(QGC_GST_STREAMING)
qCDebug
(
VideoReceiverLog
)
<<
"start()"
;
if
(
_uri
.
isEmpty
())
{
qCritical
()
<<
"VideoReceiver::start() failed because URI is not specified"
;
return
;
...
...
@@ -317,10 +326,14 @@ void VideoReceiver::start()
qCritical
()
<<
"VideoReceiver::start() failed because video sink is not set"
;
return
;
}
if
(
_running
)
{
qCDebug
(
VideoReceiverLog
)
<<
"Already running!"
;
return
;
}
bool
isUdp
=
_uri
.
contains
(
"udp://"
)
;
_starting
=
true
;
stop
(
);
bool
isUdp
=
_uri
.
contains
(
"udp://"
);
//-- For RTSP, check to see if server is there first
if
(
!
_serverPresent
&&
!
isUdp
)
{
...
...
@@ -334,7 +347,7 @@ void VideoReceiver::start()
GstCaps
*
caps
=
NULL
;
GstElement
*
demux
=
NULL
;
GstElement
*
parser
=
NULL
;
GstElement
*
queue
=
NULL
;
GstElement
*
queue
=
NULL
;
GstElement
*
decoder
=
NULL
;
do
{
...
...
@@ -389,7 +402,7 @@ void VideoReceiver::start()
}
if
((
queue
=
gst_element_factory_make
(
"queue"
,
NULL
))
==
NULL
)
{
qCritical
()
<<
"VideoReceiver::start() failed. Error with gst_element_factory_make('queue
1
')"
;
qCritical
()
<<
"VideoReceiver::start() failed. Error with gst_element_factory_make('queue')"
;
break
;
}
...
...
@@ -465,28 +478,30 @@ void VideoReceiver::start()
_pipeline
=
NULL
;
}
}
qCDebug
(
VideoReceiverLog
)
<<
"Video Receiver started."
;
_starting
=
false
;
_running
=
true
;
qCDebug
(
VideoReceiverLog
)
<<
"Running"
;
#endif
}
void
VideoReceiver
::
stop
()
{
#if defined(QGC_GST_STREAMING)
if
(
_pipeline
!=
NULL
)
{
qCDebug
(
VideoReceiverLog
)
<<
"Stopping pipeline"
;
stopRecording
();
gst_element_set_state
(
_pipeline
,
GST_STATE_NULL
);
gst_object_unref
(
_pipeline
);
_pipeline
=
NULL
;
_serverPresent
=
false
;
_streaming
=
false
;
qCDebug
(
VideoReceiverLog
)
<<
"stop()"
;
if
(
_pipeline
!=
NULL
&&
!
_stopping
)
{
qCDebug
(
VideoReceiverLog
)
<<
"Stopping _pipeline"
;
gst_element_send_event
(
_pipeline
,
gst_event_new_eos
());
_stopping
=
true
;
GstBus
*
bus
=
gst_pipeline_get_bus
(
GST_PIPELINE
(
_pipeline
));
GstMessage
*
message
=
gst_bus_timed_pop_filtered
(
bus
,
GST_CLOCK_TIME_NONE
,
GST_MESSAGE_EOS
);
gst_object_unref
(
bus
);
_onBusMessage
(
message
);
}
#endif
}
void
VideoReceiver
::
setUri
(
const
QString
&
uri
)
{
stop
();
_uri
=
uri
;
}
...
...
@@ -501,7 +516,18 @@ void VideoReceiver::_onBusMessage(GstMessage* msg)
{
switch
(
GST_MESSAGE_TYPE
(
msg
))
{
case
GST_MESSAGE_EOS
:
stop
();
gst_element_set_state
(
_pipeline
,
GST_STATE_NULL
);
gst_bin_remove
(
GST_BIN
(
_pipeline
),
_videoSink
);
gst_object_unref
(
_pipeline
);
_pipeline
=
NULL
;
_serverPresent
=
false
;
_streaming
=
false
;
_recording
=
false
;
_stopping
=
false
;
_running
=
false
;
emit
recordingChanged
();
emit
streamingChanged
();
qCDebug
(
VideoReceiverLog
)
<<
"Stopped"
;
break
;
case
GST_MESSAGE_ERROR
:
do
{
...
...
src/VideoStreaming/VideoReceiver.h
View file @
62a4ba77
...
...
@@ -42,8 +42,11 @@ public:
void
setVideoSink
(
GstElement
*
_sink
);
#endif
bool
running
()
{
return
_running
;
}
bool
recording
()
{
return
_recording
;
}
bool
streaming
()
{
return
_streaming
;
}
bool
starting
()
{
return
_starting
;
}
bool
stopping
()
{
return
_stopping
;
}
signals:
void
recordingChanged
();
...
...
@@ -76,8 +79,11 @@ private:
gboolean
removing
;
}
Sink
;
bool
_running
;
bool
_recording
;
bool
_streaming
;
bool
_starting
;
bool
_stopping
;
Sink
*
_sink
;
GstElement
*
_tee
;
...
...
@@ -95,7 +101,7 @@ private:
#if defined(QGC_GST_STREAMING)
GstElement
*
_pipeline
;
GstElement
*
_pipeline
2
;
GstElement
*
_pipeline
StopRec
;
GstElement
*
_videoSink
;
#endif
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment