diff --git a/ChangeLog b/ChangeLog index 30da970f3d..67c37aa90c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,21 @@ +2006-03-29 Wim Taymans + + Patch by Tommi Myöhänen + + * plugins/elements/gstqueue.c: (gst_queue_init), + (gst_queue_locked_flush), (gst_queue_handle_sink_event), + (gst_queue_set_property): + * plugins/elements/gstqueue.h: + In queue, when EOS is received, if minimum threshold > max_size - + current_level, there is chance that queue blocks forever in conditional item + del wait. This is because the queue is not emptied completely due to minimum + threshold. + Here is another approach. Instead of setting cur_levels to max in EOS, just + zero all minimum threshold levels. This should make sure that queue gives out + all data. When going to READY (stop) state, just reset the original minimum + threshold levels. + Fixes #336336. + 2006-03-29 Tim-Philipp Müller * plugins/elements/gsttypefindelement.c: (stop_typefinding), diff --git a/plugins/elements/gstqueue.c b/plugins/elements/gstqueue.c index ac2630081b..f4f1a3e5f0 100644 --- a/plugins/elements/gstqueue.c +++ b/plugins/elements/gstqueue.c @@ -374,6 +374,9 @@ gst_queue_init (GstQueue * queue) queue->min_threshold.buffers = 0; /* no threshold */ queue->min_threshold.bytes = 0; /* no threshold */ queue->min_threshold.time = 0; /* no threshold */ + queue->orig_min_threshold.buffers = 0; + queue->orig_min_threshold.bytes = 0; + queue->orig_min_threshold.time = 0; queue->leaky = GST_QUEUE_NO_LEAK; queue->srcresult = GST_FLOW_WRONG_STATE; @@ -494,6 +497,9 @@ gst_queue_locked_flush (GstQueue * queue) queue->cur_level.buffers = 0; queue->cur_level.bytes = 0; queue->cur_level.time = 0; + queue->min_threshold.buffers = queue->orig_min_threshold.buffers; + queue->min_threshold.bytes = queue->orig_min_threshold.bytes; + queue->min_threshold.time = queue->orig_min_threshold.time; /* we deleted something... */ g_cond_signal (queue->item_del); @@ -562,10 +568,11 @@ gst_queue_handle_sink_event (GstPad * pad, GstEvent * event) GST_QUEUE_MUTEX_LOCK (queue); if (have_eos) { - /* FIXME, abusing the cur_level */ - queue->cur_level.buffers = queue->max_size.buffers; - queue->cur_level.bytes = queue->max_size.bytes; - queue->cur_level.time = queue->max_size.time; + /* Zero the thresholds, this makes sure the queue is completely + * filled and we can read all data from the queue. */ + queue->min_threshold.buffers = 0; + queue->min_threshold.bytes = 0; + queue->min_threshold.time = 0; } g_queue_push_tail (queue->queue, event); g_cond_signal (queue->item_add); @@ -1060,12 +1067,15 @@ gst_queue_set_property (GObject * object, break; case ARG_MIN_THRESHOLD_BYTES: queue->min_threshold.bytes = g_value_get_uint (value); + queue->orig_min_threshold.bytes = queue->min_threshold.bytes; break; case ARG_MIN_THRESHOLD_BUFFERS: queue->min_threshold.buffers = g_value_get_uint (value); + queue->orig_min_threshold.buffers = queue->min_threshold.buffers; break; case ARG_MIN_THRESHOLD_TIME: queue->min_threshold.time = g_value_get_uint64 (value); + queue->orig_min_threshold.time = queue->min_threshold.time; break; case ARG_LEAKY: queue->leaky = g_value_get_enum (value); diff --git a/plugins/elements/gstqueue.h b/plugins/elements/gstqueue.h index d121e4d978..ce5aad7d06 100644 --- a/plugins/elements/gstqueue.h +++ b/plugins/elements/gstqueue.h @@ -84,7 +84,8 @@ struct _GstQueue { GstQueueSize cur_level, /* currently in the queue */ max_size, /* max. amount of data allowed in the queue */ - min_threshold; /* min. amount of data required to wake reader */ + min_threshold, /* min. amount of data required to wake reader */ + orig_min_threshold; /* Original min.threshold, for reset in EOS */ /* whether we leak data, and at which end */ gint leaky;