mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-06-05 15:08:53 +00:00
libs/gst/base/gstbasesink.c: Separate QoS calculation.
Original commit message from CVS: * libs/gst/base/gstbasesink.c: (gst_base_sink_do_sync), (gst_base_sink_do_qos): Separate QoS calculation. Only drop buffers when lateness is bigger than the duration of the buffer.
This commit is contained in:
parent
e9c4493586
commit
926ef9413a
2 changed files with 103 additions and 41 deletions
|
@ -1,3 +1,11 @@
|
||||||
|
2006-03-14 Wim Taymans <wim@fluendo.com>
|
||||||
|
|
||||||
|
* libs/gst/base/gstbasesink.c: (gst_base_sink_do_sync),
|
||||||
|
(gst_base_sink_do_qos):
|
||||||
|
Separate QoS calculation.
|
||||||
|
Only drop buffers when lateness is bigger than the
|
||||||
|
duration of the buffer.
|
||||||
|
|
||||||
2006-03-13 Wim Taymans <wim@fluendo.com>
|
2006-03-13 Wim Taymans <wim@fluendo.com>
|
||||||
|
|
||||||
* gst/gstpipeline.c: (gst_pipeline_set_property),
|
* gst/gstpipeline.c: (gst_pipeline_set_property),
|
||||||
|
|
|
@ -213,6 +213,9 @@ static gboolean gst_base_sink_activate_push (GstPad * pad, gboolean active);
|
||||||
static gboolean gst_base_sink_activate_pull (GstPad * pad, gboolean active);
|
static gboolean gst_base_sink_activate_pull (GstPad * pad, gboolean active);
|
||||||
static gboolean gst_base_sink_event (GstPad * pad, GstEvent * event);
|
static gboolean gst_base_sink_event (GstPad * pad, GstEvent * event);
|
||||||
|
|
||||||
|
static gboolean gst_base_sink_do_qos (GstBaseSink * basesink,
|
||||||
|
GstMiniObject * obj, GstClockReturn status, GstClockTimeDiff jitter);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_base_sink_base_init (gpointer g_class)
|
gst_base_sink_base_init (gpointer g_class)
|
||||||
{
|
{
|
||||||
|
@ -880,7 +883,6 @@ gst_base_sink_do_sync (GstBaseSink * basesink, GstPad * pad,
|
||||||
GstClockTimeDiff jitter;
|
GstClockTimeDiff jitter;
|
||||||
gboolean syncable;
|
gboolean syncable;
|
||||||
GstClockReturn status = GST_CLOCK_OK;
|
GstClockReturn status = GST_CLOCK_OK;
|
||||||
GstClockTime timestamp;
|
|
||||||
|
|
||||||
/* get timing information for this object */
|
/* get timing information for this object */
|
||||||
start = stop = -1;
|
start = stop = -1;
|
||||||
|
@ -940,47 +942,9 @@ again:
|
||||||
goto again;
|
goto again;
|
||||||
}
|
}
|
||||||
|
|
||||||
*late = FALSE;
|
/* perform QoS */
|
||||||
|
*late = gst_base_sink_do_qos (basesink, obj, status, jitter);
|
||||||
|
|
||||||
/* only do stats for buffers */
|
|
||||||
if (G_UNLIKELY (!GST_IS_BUFFER (obj)))
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
/* did not sync on this object, we don't need to do stats */
|
|
||||||
if (start == -1)
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
/* can't do stats if we don't have a timestamp */
|
|
||||||
if ((timestamp = GST_BUFFER_TIMESTAMP (obj)) == -1)
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
/* FIXME, do stats here in jitter. This could be used to derive
|
|
||||||
* a trend, which should then result in an updated proportion. */
|
|
||||||
|
|
||||||
if (status == GST_CLOCK_EARLY) {
|
|
||||||
if (basesink->abidata.ABI.max_lateness != -1
|
|
||||||
&& jitter > basesink->abidata.ABI.max_lateness) {
|
|
||||||
GstEvent *event;
|
|
||||||
gdouble proportion;
|
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (basesink, "late: jitter!! %" G_GINT64_FORMAT, jitter);
|
|
||||||
*late = TRUE;
|
|
||||||
|
|
||||||
/* generate QoS event, proportion is still silly. */
|
|
||||||
proportion = 0.0;
|
|
||||||
|
|
||||||
GST_CAT_DEBUG_OBJECT (GST_CAT_QOS, basesink,
|
|
||||||
"qos: proportion: %lf, diff %" G_GUINT64_FORMAT ", timestamp %"
|
|
||||||
GST_TIME_FORMAT, proportion, jitter, GST_TIME_ARGS (timestamp));
|
|
||||||
|
|
||||||
event = gst_event_new_qos (proportion, jitter, timestamp);
|
|
||||||
|
|
||||||
/* send upstream */
|
|
||||||
gst_pad_push_event (basesink->sinkpad, event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
done:
|
|
||||||
return GST_FLOW_OK;
|
return GST_FLOW_OK;
|
||||||
|
|
||||||
/* ERRORS */
|
/* ERRORS */
|
||||||
|
@ -1001,6 +965,96 @@ stopping:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* perform QoS on the given object.
|
||||||
|
*
|
||||||
|
* If the object was scheduled later that max_lateness we generate
|
||||||
|
* a QoS message upstream.
|
||||||
|
*
|
||||||
|
* returns TRUE if the buffer was too late.
|
||||||
|
*/
|
||||||
|
static gboolean
|
||||||
|
gst_base_sink_do_qos (GstBaseSink * basesink, GstMiniObject * obj,
|
||||||
|
GstClockReturn status, GstClockTimeDiff jitter)
|
||||||
|
{
|
||||||
|
gboolean late;
|
||||||
|
GstClockTime timestamp, duration;
|
||||||
|
gint64 max_lateness;
|
||||||
|
|
||||||
|
/* only for buffers that are too late */
|
||||||
|
if (status != GST_CLOCK_EARLY)
|
||||||
|
goto in_time;
|
||||||
|
|
||||||
|
/* only do stats for buffers */
|
||||||
|
if (G_UNLIKELY (!GST_IS_BUFFER (obj)))
|
||||||
|
goto not_buffer;
|
||||||
|
|
||||||
|
/* can't do stats if we don't have a timestamp */
|
||||||
|
if (G_UNLIKELY ((timestamp = GST_BUFFER_TIMESTAMP (obj)) == -1))
|
||||||
|
goto no_timestamp;
|
||||||
|
|
||||||
|
/* if the jitter bigger than duration we are too late */
|
||||||
|
if (G_UNLIKELY ((duration = GST_BUFFER_DURATION (obj)) != -1))
|
||||||
|
late = jitter > duration;
|
||||||
|
else
|
||||||
|
late = FALSE;
|
||||||
|
|
||||||
|
/* copy for code clarity */
|
||||||
|
max_lateness = basesink->abidata.ABI.max_lateness;
|
||||||
|
|
||||||
|
/* check if we need to do qos */
|
||||||
|
if (max_lateness == -1 || jitter <= max_lateness)
|
||||||
|
goto no_qos;
|
||||||
|
|
||||||
|
/* FIXME, do stats here in jitter. This could be used to derive
|
||||||
|
* a trend, which should then result in an updated proportion. */
|
||||||
|
{
|
||||||
|
GstEvent *event;
|
||||||
|
gdouble proportion;
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (basesink, "late: jitter!! %" G_GINT64_FORMAT, jitter);
|
||||||
|
|
||||||
|
/* generate QoS event, proportion is still silly. */
|
||||||
|
proportion = 0.0;
|
||||||
|
|
||||||
|
GST_CAT_DEBUG_OBJECT (GST_CAT_QOS, basesink,
|
||||||
|
"qos: proportion: %lf, diff %" G_GUINT64_FORMAT ", timestamp %"
|
||||||
|
GST_TIME_FORMAT, proportion, jitter, GST_TIME_ARGS (timestamp));
|
||||||
|
|
||||||
|
event = gst_event_new_qos (proportion, jitter, timestamp);
|
||||||
|
|
||||||
|
/* if no duration set, we assume lateness here as well. */
|
||||||
|
if (duration == -1)
|
||||||
|
late = TRUE;
|
||||||
|
|
||||||
|
/* send upstream */
|
||||||
|
gst_pad_push_event (basesink->sinkpad, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
return late;
|
||||||
|
|
||||||
|
/* cases where no qos is needed */
|
||||||
|
in_time:
|
||||||
|
{
|
||||||
|
GST_DEBUG_OBJECT (basesink, "object was scheduled in time");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
not_buffer:
|
||||||
|
{
|
||||||
|
GST_DEBUG_OBJECT (basesink, "object is not a buffer");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
no_timestamp:
|
||||||
|
{
|
||||||
|
GST_DEBUG_OBJECT (basesink, "buffer has no timestamp");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
no_qos:
|
||||||
|
{
|
||||||
|
GST_DEBUG_OBJECT (basesink, "qos disabled");
|
||||||
|
return late;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* with STREAM_LOCK, PREROLL_LOCK,
|
/* with STREAM_LOCK, PREROLL_LOCK,
|
||||||
*
|
*
|
||||||
* Synchronize the object on the clock and then render it.
|
* Synchronize the object on the clock and then render it.
|
||||||
|
|
Loading…
Reference in a new issue