queue: Allow re-usability after EOS

After EOS, it is possible for a pad to be resetted by sending
either a STREAM_START or SEGMENT event

Mimic the same behaviour when receiving STREAM_START/SEGMENT events
in queue if we are EOS'd

https://bugzilla.gnome.org/show_bug.cgi?id=786056
This commit is contained in:
Sebastian Dröge 2017-08-11 11:12:09 +03:00
parent be8eb436b2
commit 36372a9f4c

View file

@ -922,9 +922,11 @@ gst_queue_handle_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
queue = GST_QUEUE (parent); queue = GST_QUEUE (parent);
GST_CAT_LOG_OBJECT (queue_dataflow, queue, "Received event '%s'",
GST_EVENT_TYPE_NAME (event));
switch (GST_EVENT_TYPE (event)) { switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_FLUSH_START: case GST_EVENT_FLUSH_START:
STATUS (queue, pad, "received flush start event");
/* forward event */ /* forward event */
ret = gst_pad_push_event (queue->srcpad, event); ret = gst_pad_push_event (queue->srcpad, event);
@ -950,7 +952,6 @@ gst_queue_handle_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
GST_QUEUE_MUTEX_UNLOCK (queue); GST_QUEUE_MUTEX_UNLOCK (queue);
break; break;
case GST_EVENT_FLUSH_STOP: case GST_EVENT_FLUSH_STOP:
STATUS (queue, pad, "received flush stop event");
/* forward event */ /* forward event */
ret = gst_pad_push_event (queue->srcpad, event); ret = gst_pad_push_event (queue->srcpad, event);
@ -974,6 +975,14 @@ gst_queue_handle_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
if (GST_EVENT_IS_SERIALIZED (event)) { if (GST_EVENT_IS_SERIALIZED (event)) {
/* serialized events go in the queue */ /* serialized events go in the queue */
GST_QUEUE_MUTEX_LOCK (queue); GST_QUEUE_MUTEX_LOCK (queue);
/* STREAM_START and SEGMENT reset the EOS status of a
* pad. Change the cached sinkpad flow result accordingly */
if (queue->srcresult == GST_FLOW_EOS
&& (GST_EVENT_TYPE (event) == GST_EVENT_STREAM_START
|| GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT))
queue->srcresult = GST_FLOW_OK;
if (queue->srcresult != GST_FLOW_OK) { if (queue->srcresult != GST_FLOW_OK) {
/* Errors in sticky event pushing are no problem and ignored here /* Errors in sticky event pushing are no problem and ignored here
* as they will cause more meaningful errors during data flow. * as they will cause more meaningful errors during data flow.
@ -994,9 +1003,30 @@ gst_queue_handle_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
goto out_flow_error; goto out_flow_error;
} }
} }
/* refuse more events on EOS */
if (queue->eos) /* refuse more events on EOS unless they unset the EOS status */
if (queue->eos) {
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_STREAM_START:
case GST_EVENT_SEGMENT:
/* Restart the loop */
if (GST_PAD_MODE (queue->srcpad) == GST_PAD_MODE_PUSH) {
queue->srcresult = GST_FLOW_OK;
queue->eos = FALSE;
queue->unexpected = FALSE;
gst_pad_start_task (queue->srcpad,
(GstTaskFunction) gst_queue_loop, queue->srcpad, NULL);
} else {
queue->eos = FALSE;
queue->unexpected = FALSE;
}
break;
default:
goto out_eos; goto out_eos;
}
}
gst_queue_locked_enqueue_event (queue, event); gst_queue_locked_enqueue_event (queue, event);
GST_QUEUE_MUTEX_UNLOCK (queue); GST_QUEUE_MUTEX_UNLOCK (queue);
} else { } else {