summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWim Taymans <wim.taymans@collabora.co.uk>2011-02-10 14:50:04 +0100
committerWim Taymans <wim.taymans@collabora.co.uk>2011-02-10 15:21:46 +0100
commitd19f40c7169db209fd71b06d3d2f9c209aacfe5e (patch)
tree38370d8916f0ec78f725f87d1d259097820205d1
parentdad43fa0042bbdbb0e91e17a7735e9527c898fe5 (diff)
basesink: keep track of earliest QoS timestamp
Keep track of the earliest allowed timestamp according to the latest QoS report and drop buffers before that time. Activate this filter when throttling is enabled. We could later also activate this in the other QoS cases. See #638891
-rw-r--r--libs/gst/base/gstbasesink.c17
1 files changed, 16 insertions, 1 deletions
diff --git a/libs/gst/base/gstbasesink.c b/libs/gst/base/gstbasesink.c
index 498b0e9600..046fd11e68 100644
--- a/libs/gst/base/gstbasesink.c
+++ b/libs/gst/base/gstbasesink.c
@@ -257,13 +257,14 @@ struct _GstBaseSinkPrivate
GstStepInfo current_step;
GstStepInfo pending_step;
/* Cached GstClockID */
GstClockID cached_clock_id;
- /* for throttling */
+ /* for throttling and QoS */
+ GstClockTime earliest_in_time;
GstClockTime throttle_time;
};
#define DO_RUNNING_AVG(avg,val,size) (((val) + ((size)-1) * (avg)) / (size))
/* generic running average, this has a neutral window size */
@@ -2487,12 +2488,16 @@ do_step:
priv->current_rstart = rstart;
priv->current_rstop = (GST_CLOCK_TIME_IS_VALID (rstop) ? rstop : rstart);
/* save sync time for eos when the previous object needed sync */
priv->eos_rtime = (do_sync ? priv->current_rstop : GST_CLOCK_TIME_NONE);
+ if (G_UNLIKELY (priv->earliest_in_time != -1
+ && rstart < priv->earliest_in_time))
+ goto qos_dropped;
+
again:
/* first do preroll, this makes sure we commit our state
* to PAUSED and can continue to PLAYING. We cannot perform
* any clock sync in PAUSED because there is no clock. */
ret = gst_base_sink_do_preroll (basesink, obj);
if (G_UNLIKELY (ret != GST_FLOW_OK))
@@ -2573,12 +2578,18 @@ step_skipped:
}
not_syncable:
{
GST_DEBUG_OBJECT (basesink, "non syncable object %p", obj);
return GST_FLOW_OK;
}
+qos_dropped:
+ {
+ GST_DEBUG_OBJECT (basesink, "dropped because of QoS %p", obj);
+ *late = TRUE;
+ return GST_FLOW_OK;
+ }
flushing:
{
GST_DEBUG_OBJECT (basesink, "we are flushing");
return GST_FLOW_WRONG_STATE;
}
preroll_failed:
@@ -2751,12 +2762,13 @@ gst_base_sink_reset_qos (GstBaseSink * sink)
{
GstBaseSinkPrivate *priv;
priv = sink->priv;
priv->last_in_time = GST_CLOCK_TIME_NONE;
+ priv->earliest_in_time = GST_CLOCK_TIME_NONE;
priv->last_left = GST_CLOCK_TIME_NONE;
priv->avg_duration = GST_CLOCK_TIME_NONE;
priv->avg_pt = GST_CLOCK_TIME_NONE;
priv->avg_rate = -1.0;
priv->avg_render = GST_CLOCK_TIME_NONE;
priv->rendered = 0;
@@ -2830,12 +2842,15 @@ gst_base_sink_is_too_late (GstBaseSink * basesink, GstMiniObject * obj,
}
}
done:
if (!late || !GST_CLOCK_TIME_IS_VALID (priv->last_in_time)) {
priv->last_in_time = start;
+ /* the next allowed input timestamp */
+ if (priv->throttle_time > 0)
+ priv->earliest_in_time = start + priv->throttle_time;
}
return late;
/* all is fine */
in_time:
{