From 9439e73eec54d6f9fd0637f9a5a01c4eb9918107 Mon Sep 17 00:00:00 2001 From: Mark Nauwelaerts Date: Wed, 5 Sep 2012 15:37:13 +0200 Subject: [PATCH] collectpads: handle GAP event --- libs/gst/base/gstcollectpads.c | 72 +++++++++++++++++++++++++--------- 1 file changed, 54 insertions(+), 18 deletions(-) diff --git a/libs/gst/base/gstcollectpads.c b/libs/gst/base/gstcollectpads.c index 19c24f221f..03b19f0c7c 100644 --- a/libs/gst/base/gstcollectpads.c +++ b/libs/gst/base/gstcollectpads.c @@ -1370,6 +1370,7 @@ gst_collect_pads_recalculate_waiting (GstCollectPads * pads) for (collected = pads->data; collected; collected = g_slist_next (collected)) { GstCollectData *data = (GstCollectData *) collected->data; int cmp_res; + GstClockTime comp_time; /* check if pad has a segment */ if (data->segment.format == GST_FORMAT_UNDEFINED) { @@ -1386,7 +1387,8 @@ gst_collect_pads_recalculate_waiting (GstCollectPads * pads) } /* check if the waiting state should be changed */ - cmp_res = pads->priv->compare_func (pads, data, data->segment.start, + comp_time = MAX (data->segment.start, data->segment.position); + cmp_res = pads->priv->compare_func (pads, data, comp_time, pads->priv->earliest_data, pads->priv->earliest_time, pads->priv->compare_user_data); if (cmp_res > 0) @@ -1561,6 +1563,35 @@ gst_collect_pads_default_compare_func (GstCollectPads * pads, return 0; } +/* called with STREAM_LOCK */ +static void +gst_collect_pads_handle_position_update (GstCollectPads * pads, + GstCollectData * data, GstClockTime new_pos) +{ + gint cmp_res; + + /* If oldest time is not known, or current pad got newsegment; + * recalculate the state */ + if (!pads->priv->earliest_data || pads->priv->earliest_data == data) { + gst_collect_pads_recalculate_full (pads); + goto exit; + } + + /* Check if the waiting state of the pad should change. */ + cmp_res = + pads->priv->compare_func (pads, data, new_pos, + pads->priv->earliest_data, pads->priv->earliest_time, + pads->priv->compare_user_data); + + if (cmp_res > 0) + /* Stop waiting */ + gst_collect_pads_set_waiting (pads, data, FALSE); + +exit: + return; + +} + /** * gst_collect_pads_event_default: * @pads: the collectspads to use @@ -1664,7 +1695,6 @@ gst_collect_pads_event_default (GstCollectPads * pads, GstCollectData * data, case GST_EVENT_SEGMENT: { GstSegment seg; - gint cmp_res; GST_COLLECT_PADS_STREAM_LOCK (pads); @@ -1672,6 +1702,9 @@ gst_collect_pads_event_default (GstCollectPads * pads, GstCollectData * data, GST_DEBUG_OBJECT (data->pad, "got segment %" GST_SEGMENT_FORMAT, &seg); + /* sanitize to make sure; reasonably so at start */ + seg.position = seg.start; + /* default collection can not handle other segment formats than time */ if (buffer_func && seg.format != GST_FORMAT_TIME) { GST_WARNING_OBJECT (pads, "GstCollectPads default collecting " @@ -1686,22 +1719,7 @@ gst_collect_pads_event_default (GstCollectPads * pads, GstCollectData * data, if (!buffer_func) goto newsegment_done; - /* If oldest time is not known, or current pad got newsegment; - * recalculate the state */ - if (!pads->priv->earliest_data || pads->priv->earliest_data == data) { - gst_collect_pads_recalculate_full (pads); - goto newsegment_done; - } - - /* Check if the waiting state of the pad should change. */ - cmp_res = - pads->priv->compare_func (pads, data, seg.start, - pads->priv->earliest_data, pads->priv->earliest_time, - pads->priv->compare_user_data); - - if (cmp_res > 0) - /* Stop waiting */ - gst_collect_pads_set_waiting (pads, data, FALSE); + gst_collect_pads_handle_position_update (pads, data, seg.start); newsegment_done: GST_COLLECT_PADS_STREAM_UNLOCK (pads); @@ -1709,6 +1727,24 @@ gst_collect_pads_event_default (GstCollectPads * pads, GstCollectData * data, * accumulated and this is certainly not what we want. */ goto eat; } + case GST_EVENT_GAP: + { + GstClockTime start, duration; + + GST_COLLECT_PADS_STREAM_LOCK (pads); + + gst_event_parse_gap (event, &start, &duration); + if (GST_CLOCK_TIME_IS_VALID (duration)) + start += duration; + /* we do not expect another buffer until after gap, + * so that is our position now */ + data->segment.position = start; + + gst_collect_pads_handle_position_update (pads, data, start); + + GST_COLLECT_PADS_STREAM_UNLOCK (pads); + goto eat; + } case GST_EVENT_STREAM_START: /* let the only the first one go through */ if (!pads->priv->stream_started) {