identity: Return FLUSHING instead of EOS and don't start waiting for anything if currently flushing

Otherwise we might try unscheduling a clock id (that does not exist
yet), then the streaming thread waits for id and the state change never
continues because the streaming thread is blocked.

Also shutting down and flushing and similar should return FLUSHING, not
EOS. The stream is not over, we're just not accepting any buffers
anymore.
This commit is contained in:
Sebastian Dröge 2017-08-16 22:47:31 +03:00
parent e7996a23d6
commit 82ed369991
2 changed files with 19 additions and 2 deletions

View file

@ -305,9 +305,18 @@ gst_identity_do_sync (GstIdentity * identity, GstClockTime running_time)
GST_OBJECT_LOCK (identity); GST_OBJECT_LOCK (identity);
if (identity->flushing) {
GST_OBJECT_UNLOCK (identity);
return GST_FLOW_FLUSHING;
}
while (identity->blocked) while (identity->blocked)
g_cond_wait (&identity->blocked_cond, GST_OBJECT_GET_LOCK (identity)); g_cond_wait (&identity->blocked_cond, GST_OBJECT_GET_LOCK (identity));
if (identity->flushing) {
GST_OBJECT_UNLOCK (identity);
return GST_FLOW_FLUSHING;
}
if ((clock = GST_ELEMENT (identity)->clock)) { if ((clock = GST_ELEMENT (identity)->clock)) {
GstClockReturn cret; GstClockReturn cret;
@ -336,8 +345,8 @@ gst_identity_do_sync (GstIdentity * identity, GstClockTime running_time)
gst_clock_id_unref (identity->clock_id); gst_clock_id_unref (identity->clock_id);
identity->clock_id = NULL; identity->clock_id = NULL;
} }
if (cret == GST_CLOCK_UNSCHEDULED) if (cret == GST_CLOCK_UNSCHEDULED || identity->flushing)
ret = GST_FLOW_EOS; ret = GST_FLOW_FLUSHING;
} }
GST_OBJECT_UNLOCK (identity); GST_OBJECT_UNLOCK (identity);
} }
@ -430,11 +439,16 @@ gst_identity_sink_event (GstBaseTransform * trans, GstEvent * event)
} else { } else {
if (GST_EVENT_TYPE (event) == GST_EVENT_FLUSH_START) { if (GST_EVENT_TYPE (event) == GST_EVENT_FLUSH_START) {
GST_OBJECT_LOCK (identity); GST_OBJECT_LOCK (identity);
identity->flushing = TRUE;
if (identity->clock_id) { if (identity->clock_id) {
GST_DEBUG_OBJECT (identity, "unlock clock wait"); GST_DEBUG_OBJECT (identity, "unlock clock wait");
gst_clock_id_unschedule (identity->clock_id); gst_clock_id_unschedule (identity->clock_id);
} }
GST_OBJECT_UNLOCK (identity); GST_OBJECT_UNLOCK (identity);
} else if (GST_EVENT_TYPE (event) == GST_EVENT_FLUSH_STOP) {
GST_OBJECT_LOCK (identity);
identity->flushing = FALSE;
GST_OBJECT_UNLOCK (identity);
} }
ret = GST_BASE_TRANSFORM_CLASS (parent_class)->sink_event (trans, event); ret = GST_BASE_TRANSFORM_CLASS (parent_class)->sink_event (trans, event);
@ -917,6 +931,7 @@ gst_identity_change_state (GstElement * element, GstStateChange transition)
break; break;
case GST_STATE_CHANGE_READY_TO_PAUSED: case GST_STATE_CHANGE_READY_TO_PAUSED:
GST_OBJECT_LOCK (identity); GST_OBJECT_LOCK (identity);
identity->flushing = FALSE;
identity->blocked = TRUE; identity->blocked = TRUE;
GST_OBJECT_UNLOCK (identity); GST_OBJECT_UNLOCK (identity);
if (identity->sync) if (identity->sync)
@ -930,6 +945,7 @@ gst_identity_change_state (GstElement * element, GstStateChange transition)
break; break;
case GST_STATE_CHANGE_PAUSED_TO_READY: case GST_STATE_CHANGE_PAUSED_TO_READY:
GST_OBJECT_LOCK (identity); GST_OBJECT_LOCK (identity);
identity->flushing = TRUE;
if (identity->clock_id) { if (identity->clock_id) {
GST_DEBUG_OBJECT (identity, "unlock clock wait"); GST_DEBUG_OBJECT (identity, "unlock clock wait");
gst_clock_id_unschedule (identity->clock_id); gst_clock_id_unschedule (identity->clock_id);

View file

@ -55,6 +55,7 @@ struct _GstIdentity {
/*< private >*/ /*< private >*/
GstClockID clock_id; GstClockID clock_id;
gboolean flushing;
gint error_after; gint error_after;
gfloat drop_probability; gfloat drop_probability;
gint datarate; gint datarate;