composition: Rework the seqnum logic to avoid races when setting the new stack seqnum

When we were seeking the same stack without a logic that gurantees that we actually
saw the seek with the new seqnum set, we could have ended up with an EOS set with
the right seqnum even if it was actually not the case.

Co-Authored by: Mathieu Duponchelle <mathieu.duponchelle@opencreed.com>
This commit is contained in:
Thibault Saunier 2014-07-07 22:25:51 +02:00
parent 7b55a91284
commit 7de8b9c16c
4 changed files with 33 additions and 8 deletions

View file

@ -460,11 +460,11 @@ _seek_pipeline_func (SeekData * seekd)
seek_handling (seekd->comp, TRUE, FALSE);
priv->reset_time = TRUE;
GNL_OBJECT (seekd->comp)->wanted_seqnum = gst_event_get_seqnum (seekd->event);
priv->gnl_event_pad_func (GNL_OBJECT (seekd->comp)->srcpad,
GST_OBJECT (seekd->comp), get_new_seek_event (seekd->comp, FALSE, FALSE));
priv->reset_time = FALSE;
GNL_OBJECT (seekd->comp)->seqnum = gst_event_get_seqnum (seekd->event);
beach:
gst_event_unref (seekd->event);
@ -1519,6 +1519,7 @@ gnl_composition_event_handler (GstPad * ghostpad, GstObject * parent,
return TRUE;
}
GNL_OBJECT (comp)->wanted_seqnum = gst_event_get_seqnum (event);
break;
}
case GST_EVENT_QOS:

View file

@ -323,15 +323,31 @@ internalpad_event_function (GstPad * internal, GstObject * parent,
case GST_PAD_SRC:{
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_SEEK:
object->seqnum = gst_event_get_seqnum (event);
GST_INFO_OBJECT (object, "Setting seqnum to %i", object->seqnum);
object->wanted_seqnum = gst_event_get_seqnum (event);
object->seqnum = 0;
GST_DEBUG_OBJECT (object, "Setting wanted_seqnum to %i",
object->wanted_seqnum);
break;
case GST_EVENT_SEGMENT:
if (object->wanted_seqnum == 0) {
g_assert ("All gnlobject should be seeked at one point or another"
" and thus we should always have a wanted_seqnum when getting"
" a new segment" == NULL);
}
GST_DEBUG_OBJECT (object, "Got segment, seqnum-> %i (wanted %i)",
gst_event_get_seqnum (event), object->wanted_seqnum);
object->seqnum = object->wanted_seqnum;
object->wanted_seqnum = 0;
event = translate_outgoing_segment (object, event);
gst_event_set_seqnum (event, object->seqnum);
break;
case GST_EVENT_EOS:
GST_INFO_OBJECT (object, "Tweaking seqnum to %i", object->seqnum);
if (object->seqnum);
gst_event_set_seqnum (event, object->seqnum);
GST_INFO_OBJECT (object, "Tweaking seqnum to %i", object->seqnum);
break;
default:
break;
@ -500,8 +516,9 @@ ghostpad_event_function (GstPad * ghostpad, GstObject * parent,
{
GstPad *target;
GST_ERROR_OBJECT (object, "GOT SEEKD: %" GST_PTR_FORMAT, event);
event = gnl_object_translate_incoming_seek (object, event);
object->wanted_seqnum = gst_event_get_seqnum (event);
object->seqnum = 0;
if (!(target = gst_ghost_pad_get_target (GST_GHOST_PAD (ghostpad)))) {
priv->pending_seek = event;
GST_INFO_OBJECT (ghostpad, "No target set yet, "
@ -520,6 +537,7 @@ ghostpad_event_function (GstPad * ghostpad, GstObject * parent,
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_SEGMENT:
event = translate_incoming_segment (object, event);
gst_event_set_seqnum (event, object->seqnum);
break;
default:
break;

View file

@ -103,9 +103,9 @@ static gboolean
gnl_object_send_event (GstElement * element, GstEvent * event)
{
if (GST_EVENT_TYPE (event) == GST_EVENT_SEEK) {
GNL_OBJECT (element)->seqnum = gst_event_get_seqnum (event);
GST_INFO_OBJECT (element, "Remember seqnum! %i",
GNL_OBJECT (element)->seqnum);
GNL_OBJECT (element)->wanted_seqnum = gst_event_get_seqnum (event);
GST_DEBUG_OBJECT (element, "Remember seqnum! %i",
GNL_OBJECT (element)->wanted_seqnum);
}
@ -426,6 +426,7 @@ gnl_object_cleanup (GnlObject * object)
GST_DEBUG_OBJECT (object, "cleaning-up");
object->seqnum = 0;
object->wanted_seqnum = 0;
if (!(GNL_OBJECT_GET_CLASS (object)->cleanup (object)))
ret = GST_STATE_CHANGE_FAILURE;
@ -663,6 +664,7 @@ gnl_object_reset (GnlObject * object)
GST_INFO_OBJECT (object, "Resetting child timing values to default");
object->seqnum = 0;
object->wanted_seqnum = 0;
object->start = 0;
object->duration = 0;
object->stop = 0;

View file

@ -125,6 +125,10 @@ struct _GnlObject
gint64 segment_start;
gint64 segment_stop;
/* the seqnum we want, will be conciderd as real one right after
* a new segment */
gint wanted_seqnum;
/* The seqnum that we are working with, 0 if not set */
gint seqnum;
};