Multiqueue: don't allow dropping SEGMENT_DONE events

https://bugzilla.gnome.org/show_bug.cgi?id=780795
This commit is contained in:
Mathieu Duponchelle 2017-04-01 07:15:22 +02:00
parent f649f0a44f
commit 053f1523ad

View file

@ -150,6 +150,7 @@ struct _GstSingleQueue
GstDataQueueSize max_size, extra_size; GstDataQueueSize max_size, extra_size;
GstClockTime cur_time; GstClockTime cur_time;
gboolean is_eos; gboolean is_eos;
gboolean is_segment_done;
gboolean is_sparse; gboolean is_sparse;
gboolean flushing; gboolean flushing;
gboolean active; gboolean active;
@ -1085,6 +1086,7 @@ gst_single_queue_flush (GstMultiQueue * mq, GstSingleQueue * sq, gboolean flush,
sq->cur_time = 0; sq->cur_time = 0;
sq->max_size.visible = mq->max_size.visible; sq->max_size.visible = mq->max_size.visible;
sq->is_eos = FALSE; sq->is_eos = FALSE;
sq->is_segment_done = FALSE;
sq->nextid = 0; sq->nextid = 0;
sq->oldid = 0; sq->oldid = 0;
sq->last_oldid = G_MAXUINT32; sq->last_oldid = G_MAXUINT32;
@ -1126,7 +1128,8 @@ get_buffering_level (GstSingleQueue * sq)
size.bytes, sq->max_size.bytes, sq->cur_time, sq->max_size.time); size.bytes, sq->max_size.bytes, sq->cur_time, sq->max_size.time);
/* get bytes and time buffer levels and take the max */ /* get bytes and time buffer levels and take the max */
if (sq->is_eos || sq->srcresult == GST_FLOW_NOT_LINKED || sq->is_sparse) { if (sq->is_eos || sq->is_segment_done || sq->srcresult == GST_FLOW_NOT_LINKED
|| sq->is_sparse) {
buffering_level = MAX_BUFFERING_LEVEL; buffering_level = MAX_BUFFERING_LEVEL;
} else { } else {
buffering_level = 0; buffering_level = 0;
@ -1626,6 +1629,9 @@ gst_single_queue_push_one (GstMultiQueue * mq, GstSingleQueue * sq,
event = GST_EVENT_CAST (object); event = GST_EVENT_CAST (object);
switch (GST_EVENT_TYPE (event)) { switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_SEGMENT_DONE:
*allow_drop = FALSE;
break;
case GST_EVENT_EOS: case GST_EVENT_EOS:
result = GST_FLOW_EOS; result = GST_FLOW_EOS;
if (G_UNLIKELY (*allow_drop)) if (G_UNLIKELY (*allow_drop))
@ -2039,7 +2045,7 @@ out_flushing:
* has returned an error flow return. After EOS there * has returned an error flow return. After EOS there
* will be no further buffer which could propagate the * will be no further buffer which could propagate the
* error upstream */ * error upstream */
if (sq->is_eos && sq->srcresult < GST_FLOW_EOS) { if ((sq->is_eos || sq->is_segment_done) && sq->srcresult < GST_FLOW_EOS) {
GST_MULTI_QUEUE_MUTEX_UNLOCK (mq); GST_MULTI_QUEUE_MUTEX_UNLOCK (mq);
GST_ELEMENT_FLOW_ERROR (mq, sq->srcresult); GST_ELEMENT_FLOW_ERROR (mq, sq->srcresult);
} else { } else {
@ -2261,6 +2267,7 @@ gst_multi_queue_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
goto done; goto done;
case GST_EVENT_SEGMENT: case GST_EVENT_SEGMENT:
sq->is_segment_done = FALSE;
sref = gst_event_ref (event); sref = gst_event_ref (event);
break; break;
case GST_EVENT_GAP: case GST_EVENT_GAP:
@ -2312,6 +2319,14 @@ gst_multi_queue_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
/* mark EOS when we received one, we must do that after putting the /* mark EOS when we received one, we must do that after putting the
* buffer in the queue because EOS marks the buffer as filled. */ * buffer in the queue because EOS marks the buffer as filled. */
switch (type) { switch (type) {
case GST_EVENT_SEGMENT_DONE:
sq->is_segment_done = TRUE;
GST_MULTI_QUEUE_MUTEX_LOCK (mq);
update_buffering (mq, sq);
GST_MULTI_QUEUE_MUTEX_UNLOCK (mq);
single_queue_overrun_cb (sq->queue, sq);
gst_multi_queue_post_buffering (mq);
break;
case GST_EVENT_EOS: case GST_EVENT_EOS:
GST_MULTI_QUEUE_MUTEX_LOCK (mq); GST_MULTI_QUEUE_MUTEX_LOCK (mq);
sq->is_eos = TRUE; sq->is_eos = TRUE;
@ -2832,7 +2847,7 @@ single_queue_check_full (GstDataQueue * dataq, guint visible, guint bytes,
sq->max_size.bytes, sq->cur_time, sq->max_size.time); sq->max_size.bytes, sq->cur_time, sq->max_size.time);
/* we are always filled on EOS */ /* we are always filled on EOS */
if (sq->is_eos) if (sq->is_eos || sq->is_segment_done)
return TRUE; return TRUE;
/* we never go past the max visible items unless we are in buffering mode */ /* we never go past the max visible items unless we are in buffering mode */