basesink: Remove unused fields and always use the buffer timestamp difference for calculating the QoS proportion

The buffer timestamps are only hints and more often than not have
nothing to do with reality.

https://bugzilla.gnome.org/show_bug.cgi?id=771306
This commit is contained in:
Sebastian Dröge 2016-09-12 17:41:16 +02:00
parent b6e69ffdfb
commit dc0ed9a5eb

View file

@ -201,19 +201,8 @@ struct _GstBaseSinkPrivate
GstClockTime last_left; GstClockTime last_left;
/* running averages go here these are done on running time */ /* running averages go here these are done on running time */
GstClockTime avg_pt; GstClockTime avg_pt, avg_in_diff;
GstClockTime avg_duration; gdouble avg_rate; /* average with infinite window */
gdouble avg_rate;
GstClockTime avg_in_diff;
/* these are done on system time. avg_jitter and avg_render are
* compared to eachother to see if the rendering time takes a
* huge amount of the processing, If so we are flooded with
* buffers. */
GstClockTime last_left_systime;
GstClockTime avg_jitter;
GstClockTime start, stop;
GstClockTime avg_render;
/* number of rendered and dropped frames */ /* number of rendered and dropped frames */
guint64 rendered; guint64 rendered;
@ -2672,12 +2661,7 @@ gst_base_sink_perform_qos (GstBaseSink * sink, gboolean dropped)
* trick mode or key-unit mode. Otherwise the buffer durations will be * trick mode or key-unit mode. Otherwise the buffer durations will be
* meaningless as frames are being dropped in-between without updating the * meaningless as frames are being dropped in-between without updating the
* durations. */ * durations. */
if (GST_CLOCK_TIME_IS_VALID (stop) duration = priv->avg_in_diff;
&& !(sink->segment.flags & (GST_SEGMENT_FLAG_TRICKMODE |
GST_SEGMENT_FLAG_TRICKMODE_KEY_UNITS)) && stop != start)
duration = stop - start;
else
duration = priv->avg_in_diff;
/* if we have the time when the last buffer left us, calculate /* if we have the time when the last buffer left us, calculate
* processing time */ * processing time */
@ -2698,29 +2682,24 @@ gst_base_sink_perform_qos (GstBaseSink * sink, gboolean dropped)
GST_TIME_ARGS (entered), GST_TIME_ARGS (left), GST_TIME_ARGS (pt), GST_TIME_ARGS (entered), GST_TIME_ARGS (left), GST_TIME_ARGS (pt),
GST_TIME_ARGS (duration), jitter); GST_TIME_ARGS (duration), jitter);
GST_CAT_DEBUG_OBJECT (GST_CAT_QOS, sink, "avg_duration: %" GST_TIME_FORMAT GST_CAT_DEBUG_OBJECT (GST_CAT_QOS, sink,
", avg_pt: %" GST_TIME_FORMAT ", avg_rate: %g", "avg_pt: %" GST_TIME_FORMAT ", avg_rate: %g",
GST_TIME_ARGS (priv->avg_duration), GST_TIME_ARGS (priv->avg_pt), GST_TIME_ARGS (priv->avg_pt), priv->avg_rate);
priv->avg_rate);
/* collect running averages. for first observations, we copy the /* collect running averages. for first observations, we copy the
* values */ * values */
if (!GST_CLOCK_TIME_IS_VALID (priv->avg_duration))
priv->avg_duration = duration;
else
priv->avg_duration = UPDATE_RUNNING_AVG (priv->avg_duration, duration);
if (!GST_CLOCK_TIME_IS_VALID (priv->avg_pt)) if (!GST_CLOCK_TIME_IS_VALID (priv->avg_pt))
priv->avg_pt = pt; priv->avg_pt = pt;
else else
priv->avg_pt = UPDATE_RUNNING_AVG (priv->avg_pt, pt); priv->avg_pt = UPDATE_RUNNING_AVG (priv->avg_pt, pt);
if (priv->avg_duration != 0) if (duration != -1 && duration != 0) {
rate = rate =
gst_guint64_to_gdouble (priv->avg_pt) / gst_guint64_to_gdouble (priv->avg_pt) /
gst_guint64_to_gdouble (priv->avg_duration); gst_guint64_to_gdouble (duration);
else } else {
rate = 1.0; rate = 1.0;
}
if (GST_CLOCK_TIME_IS_VALID (priv->last_left)) { if (GST_CLOCK_TIME_IS_VALID (priv->last_left)) {
if (dropped || priv->avg_rate < 0.0) { if (dropped || priv->avg_rate < 0.0) {
@ -2734,9 +2713,8 @@ gst_base_sink_perform_qos (GstBaseSink * sink, gboolean dropped)
} }
GST_CAT_DEBUG_OBJECT (GST_CAT_QOS, sink, GST_CAT_DEBUG_OBJECT (GST_CAT_QOS, sink,
"updated: avg_duration: %" GST_TIME_FORMAT ", avg_pt: %" GST_TIME_FORMAT "updated: avg_pt: %" GST_TIME_FORMAT
", avg_rate: %g", GST_TIME_ARGS (priv->avg_duration), ", avg_rate: %g", GST_TIME_ARGS (priv->avg_pt), priv->avg_rate);
GST_TIME_ARGS (priv->avg_pt), priv->avg_rate);
if (priv->avg_rate >= 0.0) { if (priv->avg_rate >= 0.0) {
@ -2782,10 +2760,8 @@ gst_base_sink_reset_qos (GstBaseSink * sink)
priv->prev_rstart = GST_CLOCK_TIME_NONE; priv->prev_rstart = GST_CLOCK_TIME_NONE;
priv->earliest_in_time = GST_CLOCK_TIME_NONE; priv->earliest_in_time = GST_CLOCK_TIME_NONE;
priv->last_left = 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_pt = GST_CLOCK_TIME_NONE;
priv->avg_rate = -1.0; priv->avg_rate = -1.0;
priv->avg_render = GST_CLOCK_TIME_NONE;
priv->avg_in_diff = GST_CLOCK_TIME_NONE; priv->avg_in_diff = GST_CLOCK_TIME_NONE;
priv->rendered = 0; priv->rendered = 0;
priv->dropped = 0; priv->dropped = 0;
@ -2894,35 +2870,6 @@ no_timestamp:
} }
} }
/* called before and after calling the render vmethod. It keeps track of how
* much time was spent in the render method and is used to check if we are
* flooded */
static void
gst_base_sink_do_render_stats (GstBaseSink * basesink, gboolean start)
{
GstBaseSinkPrivate *priv;
priv = basesink->priv;
if (start) {
priv->start = gst_util_get_timestamp ();
} else {
GstClockTime elapsed;
priv->stop = gst_util_get_timestamp ();
elapsed = GST_CLOCK_DIFF (priv->start, priv->stop);
if (!GST_CLOCK_TIME_IS_VALID (priv->avg_render))
priv->avg_render = elapsed;
else
priv->avg_render = UPDATE_RUNNING_AVG (priv->avg_render, elapsed);
GST_CAT_DEBUG_OBJECT (GST_CAT_QOS, basesink,
"avg_render: %" GST_TIME_FORMAT, GST_TIME_ARGS (priv->avg_render));
}
}
static void static void
gst_base_sink_update_start_time (GstBaseSink * basesink) gst_base_sink_update_start_time (GstBaseSink * basesink)
{ {
@ -3353,7 +3300,6 @@ gst_base_sink_chain_unlocked (GstBaseSink * basesink, GstPad * pad,
GstClockTime start = GST_CLOCK_TIME_NONE, end = GST_CLOCK_TIME_NONE; GstClockTime start = GST_CLOCK_TIME_NONE, end = GST_CLOCK_TIME_NONE;
GstSegment *segment; GstSegment *segment;
GstBuffer *sync_buf; GstBuffer *sync_buf;
gint do_qos;
gboolean late, step_end, prepared = FALSE; gboolean late, step_end, prepared = FALSE;
if (G_UNLIKELY (basesink->flushing)) if (G_UNLIKELY (basesink->flushing))
@ -3519,15 +3465,8 @@ again:
8 * GST_SECOND, priv->max_bitrate); 8 * GST_SECOND, priv->max_bitrate);
} }
/* read once, to get same value before and after */
do_qos = g_atomic_int_get (&priv->qos_enabled);
GST_DEBUG_OBJECT (basesink, "rendering object %p", obj); GST_DEBUG_OBJECT (basesink, "rendering object %p", obj);
/* record rendering time for QoS and stats */
if (do_qos)
gst_base_sink_do_render_stats (basesink, TRUE);
if (!is_list) { if (!is_list) {
/* For buffer lists do not set last buffer for now. */ /* For buffer lists do not set last buffer for now. */
gst_base_sink_set_last_buffer (basesink, GST_BUFFER_CAST (obj)); gst_base_sink_set_last_buffer (basesink, GST_BUFFER_CAST (obj));
@ -3546,9 +3485,6 @@ again:
gst_base_sink_set_last_buffer_list (basesink, buffer_list); gst_base_sink_set_last_buffer_list (basesink, buffer_list);
} }
if (do_qos)
gst_base_sink_do_render_stats (basesink, FALSE);
if (ret == GST_FLOW_STEP) if (ret == GST_FLOW_STEP)
goto again; goto again;