From: Sebastian Dröge Date: Mon, 5 Mar 2012 13:41:12 +0000 (+0100) Subject: baseparse: Fix handling of multiple newsegment events X-Git-Tag: RELEASE-0.11.3~1^2~12 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=495aca4905a971e91f219b5d39a9e37746c8713d;p=platform%2Fupstream%2Fgstreamer.git baseparse: Fix handling of multiple newsegment events Previously only the last would be pushed, which would cause invalid running times downstream. This also fixes the handling of update newsegment events. --- diff --git a/libs/gst/base/gstbaseparse.c b/libs/gst/base/gstbaseparse.c index bcb2a9a..851ec1d 100644 --- a/libs/gst/base/gstbaseparse.c +++ b/libs/gst/base/gstbaseparse.c @@ -276,8 +276,6 @@ struct _GstBaseParsePrivate guint max_bitrate; guint posted_avg_bitrate; - GList *pending_events; - /* frames/buffers that are queued and ready to go on OK */ GQueue queued_frames; @@ -316,9 +314,10 @@ struct _GstBaseParsePrivate GstClockTime last_ts; gint64 last_offset; + /* Pending serialized events */ + GList *pending_events; /* Newsegment event to be sent after SEEK */ - GstEvent *pending_segment; - + gboolean pending_segment; /* Segment event that closes the running segment prior to SEEK */ GstEvent *close_segment; @@ -466,8 +465,8 @@ gst_base_parse_clear_queues (GstBaseParse * parse) g_list_foreach (parse->priv->pending_events, (GFunc) gst_event_unref, NULL); g_list_free (parse->priv->pending_events); parse->priv->pending_events = NULL; + parse->priv->pending_segment = FALSE; - gst_event_replace (&parse->priv->pending_segment, NULL); gst_event_replace (&parse->priv->close_segment, NULL); } @@ -479,10 +478,6 @@ gst_base_parse_finalize (GObject * object) g_object_unref (parse->priv->adapter); - if (parse->priv->pending_segment) { - p_ev = &parse->priv->pending_segment; - gst_event_replace (p_ev, NULL); - } if (parse->priv->close_segment) { p_ev = &parse->priv->close_segment; gst_event_replace (p_ev, NULL); @@ -497,6 +492,7 @@ gst_base_parse_finalize (GObject * object) NULL); g_list_free (parse->priv->pending_events); parse->priv->pending_events = NULL; + parse->priv->pending_segment = FALSE; if (parse->priv->index) { gst_object_unref (parse->priv->index); @@ -766,15 +762,11 @@ gst_base_parse_reset (GstBaseParse * parse) parse->priv->last_ts = GST_CLOCK_TIME_NONE; parse->priv->last_offset = 0; - if (parse->priv->pending_segment) { - gst_event_unref (parse->priv->pending_segment); - parse->priv->pending_segment = NULL; - } - g_list_foreach (parse->priv->pending_events, (GFunc) gst_mini_object_unref, NULL); g_list_free (parse->priv->pending_events); parse->priv->pending_events = NULL; + parse->priv->pending_segment = FALSE; gst_event_replace (&parse->priv->close_segment, NULL); @@ -937,7 +929,6 @@ gst_base_parse_sink_event (GstPad * pad, GstEvent * event) g_list_append (parse->priv->pending_events, event); ret = TRUE; } else { - if (GST_EVENT_TYPE (event) == GST_EVENT_EOS && parse->priv->framecount < MIN_FRAMES_TO_POST_BITRATE) /* We've not posted bitrate tags yet - do so now */ @@ -974,7 +965,6 @@ static gboolean gst_base_parse_sink_eventfunc (GstBaseParse * parse, GstEvent * event) { gboolean handled = FALSE; - GstEvent **eventp; switch (GST_EVENT_TYPE (event)) { case GST_EVENT_NEWSEGMENT: @@ -1065,9 +1055,9 @@ gst_base_parse_sink_eventfunc (GstBaseParse * parse, GstEvent * event) /* save the segment for later, right before we push a new buffer so that * the caps are fixed and the next linked element can receive * the segment. */ - eventp = &parse->priv->pending_segment; - gst_event_replace (eventp, event); - gst_event_unref (event); + parse->priv->pending_events = + g_list_append (parse->priv->pending_events, event); + parse->priv->pending_segment = TRUE; handled = TRUE; /* but finish the current segment */ @@ -1119,10 +1109,16 @@ gst_base_parse_sink_eventfunc (GstBaseParse * parse, GstEvent * event) GST_ELEMENT_ERROR (parse, STREAM, WRONG_TYPE, ("No valid frames found before end of stream"), (NULL)); } - /* newsegment before eos */ - if (parse->priv->pending_segment) { - gst_pad_push_event (parse->srcpad, parse->priv->pending_segment); - parse->priv->pending_segment = NULL; + /* newsegment and other serialized events before eos */ + if (G_UNLIKELY (parse->priv->pending_events)) { + GList *l; + + for (l = parse->priv->pending_events; l != NULL; l = l->next) { + gst_pad_push_event (parse->srcpad, GST_EVENT (l->data)); + } + g_list_free (parse->priv->pending_events); + parse->priv->pending_events = NULL; + parse->priv->pending_segment = FALSE; } break; @@ -1839,6 +1835,11 @@ gst_base_parse_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame) /* should have caps by now */ g_return_val_if_fail (GST_PAD_CAPS (parse->srcpad), GST_FLOW_ERROR); + if (G_UNLIKELY (parse->priv->pending_segment)) { + /* have caps; check identity */ + gst_base_parse_check_media (parse); + } + /* and should then also be linked downstream, so safe to send some events */ if (G_UNLIKELY (parse->priv->close_segment)) { /* only set up by loop */ @@ -1846,20 +1847,8 @@ gst_base_parse_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame) gst_pad_push_event (parse->srcpad, parse->priv->close_segment); parse->priv->close_segment = NULL; } - if (G_UNLIKELY (parse->priv->pending_segment)) { - GstEvent *pending_segment; - - pending_segment = parse->priv->pending_segment; - parse->priv->pending_segment = NULL; - - GST_DEBUG_OBJECT (parse, "%s push pending segment", - parse->priv->pad_mode == GST_ACTIVATE_PULL ? "loop" : "chain"); - gst_pad_push_event (parse->srcpad, pending_segment); - - /* have caps; check identity */ - gst_base_parse_check_media (parse); - } + /* Push pending events, including NEWSEGMENT events */ if (G_UNLIKELY (parse->priv->pending_events)) { GList *l; @@ -1868,6 +1857,7 @@ gst_base_parse_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame) } g_list_free (parse->priv->pending_events); parse->priv->pending_events = NULL; + parse->priv->pending_segment = FALSE; } /* segment adjustment magic; only if we are running the whole show */ @@ -2880,11 +2870,18 @@ pause: push_eos = TRUE; } if (push_eos) { - /* newsegment before eos */ - if (parse->priv->pending_segment) { - gst_pad_push_event (parse->srcpad, parse->priv->pending_segment); - parse->priv->pending_segment = NULL; + /* Push pending events, including NEWSEGMENT events */ + if (G_UNLIKELY (parse->priv->pending_events)) { + GList *l; + + for (l = parse->priv->pending_events; l != NULL; l = l->next) { + gst_pad_push_event (parse->srcpad, GST_EVENT (l->data)); + } + g_list_free (parse->priv->pending_events); + parse->priv->pending_events = NULL; + parse->priv->pending_segment = FALSE; } + gst_pad_push_event (parse->srcpad, gst_event_new_eos ()); } gst_object_unref (parse); @@ -2981,9 +2978,15 @@ gst_base_parse_sink_activate_pull (GstPad * sinkpad, gboolean active) if (result) { if (active) { - parse->priv->pending_segment = gst_event_new_new_segment (FALSE, + GstEvent *event; + + event = gst_event_new_new_segment (FALSE, parse->segment.rate, parse->segment.format, parse->segment.start, parse->segment.stop, parse->segment.last_stop); + parse->priv->pending_events = + g_list_append (parse->priv->pending_events, event); + parse->priv->pending_segment = TRUE; + result &= gst_pad_start_task (sinkpad, (GstTaskFunction) gst_base_parse_loop, sinkpad); @@ -3834,14 +3837,11 @@ gst_base_parse_handle_seek (GstBaseParse * parse, GstEvent * event) memcpy (&parse->segment, &seeksegment, sizeof (GstSegment)); /* store the newsegment event so it can be sent from the streaming thread. */ - if (parse->priv->pending_segment) - gst_event_unref (parse->priv->pending_segment); - - /* This will be sent later in _loop() */ - parse->priv->pending_segment = + parse->priv->pending_segment = TRUE; + parse->priv->pending_events = g_list_append (parse->priv->pending_events, gst_event_new_new_segment (FALSE, parse->segment.rate, - parse->segment.format, parse->segment.start, - parse->segment.stop, parse->segment.start); + parse->segment.format, parse->segment.start, + parse->segment.stop, parse->segment.start)); GST_DEBUG_OBJECT (parse, "Created newseg format %d, " "start = %" GST_TIME_FORMAT ", stop = %" GST_TIME_FORMAT