Add method to allow sinks to specify additional delay between the sync times and the actual rendering of the data.

Original commit message from CVS:
* docs/libs/gstreamer-libs-sections.txt:
* libs/gst/base/gstbasesink.c: (gst_base_sink_init),
(gst_base_sink_query_latency), (gst_base_sink_set_render_delay),
(gst_base_sink_get_render_delay), (gst_base_sink_wait_eos),
(gst_base_sink_do_sync):
* libs/gst/base/gstbasesink.h:
* win32/common/libgstbase.def:
Add method to allow sinks to specify additional delay between the sync
times and the actual rendering of the data.
API: gst_base_sink_set_render_delay()
API: gst_base_sink_get_render_delay()
This commit is contained in:
Wim Taymans 2008-06-20 08:54:45 +00:00
parent 1b6d2e1ecf
commit 6624a8de12
5 changed files with 103 additions and 5 deletions

View file

@ -1,3 +1,17 @@
2008-06-20 Wim Taymans <wim.taymans@collabora.co.uk>
* docs/libs/gstreamer-libs-sections.txt:
* libs/gst/base/gstbasesink.c: (gst_base_sink_init),
(gst_base_sink_query_latency), (gst_base_sink_set_render_delay),
(gst_base_sink_get_render_delay), (gst_base_sink_wait_eos),
(gst_base_sink_do_sync):
* libs/gst/base/gstbasesink.h:
* win32/common/libgstbase.def:
Add method to allow sinks to specify additional delay between the sync
times and the actual rendering of the data.
API: gst_base_sink_set_render_delay()
API: gst_base_sink_get_render_delay()
2008-06-20 Jan Schmidt <jan.schmidt@sun.com> 2008-06-20 Jan Schmidt <jan.schmidt@sun.com>
* configure.ac: * configure.ac:

View file

@ -270,6 +270,8 @@ gst_base_sink_set_async_enabled
gst_base_sink_is_async_enabled gst_base_sink_is_async_enabled
gst_base_sink_set_ts_offset gst_base_sink_set_ts_offset
gst_base_sink_get_ts_offset gst_base_sink_get_ts_offset
gst_base_sink_set_render_delay
gst_base_sink_get_render_delay
gst_base_sink_get_last_buffer gst_base_sink_get_last_buffer
GST_BASE_SINK_PAD GST_BASE_SINK_PAD

View file

@ -160,6 +160,7 @@ struct _GstBaseSinkPrivate
gint qos_enabled; /* ATOMIC */ gint qos_enabled; /* ATOMIC */
gboolean async_enabled; gboolean async_enabled;
GstClockTimeDiff ts_offset; GstClockTimeDiff ts_offset;
GstClockTime render_delay;
/* start, stop of current buffer, stream time, used to report position */ /* start, stop of current buffer, stream time, used to report position */
GstClockTime current_sstart; GstClockTime current_sstart;
@ -551,6 +552,7 @@ gst_base_sink_init (GstBaseSink * basesink, gpointer g_class)
g_atomic_int_set (&priv->qos_enabled, DEFAULT_QOS); g_atomic_int_set (&priv->qos_enabled, DEFAULT_QOS);
priv->async_enabled = DEFAULT_ASYNC; priv->async_enabled = DEFAULT_ASYNC;
priv->ts_offset = DEFAULT_TS_OFFSET; priv->ts_offset = DEFAULT_TS_OFFSET;
priv->render_delay = 0;
GST_OBJECT_FLAG_SET (basesink, GST_ELEMENT_IS_SINK); GST_OBJECT_FLAG_SET (basesink, GST_ELEMENT_IS_SINK);
} }
@ -899,7 +901,7 @@ gst_base_sink_query_latency (GstBaseSink * sink, gboolean * live,
GstClockTime * max_latency) GstClockTime * max_latency)
{ {
gboolean l, us_live, res, have_latency; gboolean l, us_live, res, have_latency;
GstClockTime min, max; GstClockTime min, max, render_delay;
GstQuery *query; GstQuery *query;
GstClockTime us_min, us_max; GstClockTime us_min, us_max;
@ -907,6 +909,7 @@ gst_base_sink_query_latency (GstBaseSink * sink, gboolean * live,
GST_OBJECT_LOCK (sink); GST_OBJECT_LOCK (sink);
l = sink->sync; l = sink->sync;
have_latency = sink->priv->have_latency; have_latency = sink->priv->have_latency;
render_delay = sink->priv->render_delay;
GST_OBJECT_UNLOCK (sink); GST_OBJECT_UNLOCK (sink);
/* assume no latency */ /* assume no latency */
@ -931,6 +934,13 @@ gst_base_sink_query_latency (GstBaseSink * sink, gboolean * live,
min = us_min; min = us_min;
max = us_max; max = us_max;
} }
if (l) {
/* we need to add the render delay if we are live */
if (min != -1)
min += render_delay;
if (max != -1)
max += render_delay;
}
} }
gst_query_unref (query); gst_query_unref (query);
} else { } else {
@ -965,6 +975,60 @@ gst_base_sink_query_latency (GstBaseSink * sink, gboolean * live,
return res; return res;
} }
/**
* gst_base_sink_set_render_delay:
* @sink: a #GstBaseSink
* @delay: the new delay
*
* Set the render delay in @sink to @delay. The render delay is the time
* between actual rendering of a buffer and its synchronisation time. Some
* devices might delay media rendering which can be compensated for with this
* function.
*
* After calling this function, this sink will report additional latency and
* other sinks will adjust their latency to delay the rendering of their media.
*
* This function is usually called by subclasses.
*
* Since: 0.10.21
*/
void
gst_base_sink_set_render_delay (GstBaseSink * sink, GstClockTime delay)
{
g_return_if_fail (GST_IS_BASE_SINK (sink));
GST_OBJECT_LOCK (sink);
sink->priv->render_delay = delay;
GST_LOG_OBJECT (sink, "set render delay to %" GST_TIME_FORMAT,
GST_TIME_ARGS (delay));
GST_OBJECT_UNLOCK (sink);
}
/**
* gst_base_sink_get_render_delay:
* @sink: a #GstBaseSink
*
* Get the render delay of @sink. see gst_base_sink_set_render_delay() for more
* information about the render delay.
*
* Returns: the render delay of @sink.
*
* Since: 0.10.21
*/
GstClockTime
gst_base_sink_get_render_delay (GstBaseSink * sink)
{
GstClockTimeDiff res;
g_return_val_if_fail (GST_IS_BASE_SINK (sink), 0);
GST_OBJECT_LOCK (sink);
res = sink->priv->render_delay;
GST_OBJECT_UNLOCK (sink);
return res;
}
static void static void
gst_base_sink_set_property (GObject * object, guint prop_id, gst_base_sink_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec) const GValue * value, GParamSpec * pspec)
@ -1611,7 +1675,7 @@ gst_base_sink_wait_eos (GstBaseSink * sink, GstClockTime time,
GST_DEBUG_OBJECT (sink, "possibly waiting for clock to reach %" GST_DEBUG_OBJECT (sink, "possibly waiting for clock to reach %"
GST_TIME_FORMAT, GST_TIME_ARGS (time)); GST_TIME_FORMAT, GST_TIME_ARGS (time));
/* compensate for latency and ts_offset. We don't adjust for device latency /* compensate for latency and ts_offset. We don't adjust for render delay
* because we don't interact with the device on EOS normally. */ * because we don't interact with the device on EOS normally. */
stime = gst_base_sink_adjust_time (sink, time); stime = gst_base_sink_adjust_time (sink, time);
@ -1733,13 +1797,24 @@ again:
if (!do_sync) if (!do_sync)
goto done; goto done;
/* adjust for latency */
stime = gst_base_sink_adjust_time (basesink, rstart);
/* adjust for render-delay, avoid underflows */
if (stime != -1) {
if (stime > priv->render_delay)
stime -= priv->render_delay;
else
stime = 0;
}
/* preroll done, we can sync since we are in PLAYING now. */ /* preroll done, we can sync since we are in PLAYING now. */
GST_DEBUG_OBJECT (basesink, "possibly waiting for clock to reach %" GST_DEBUG_OBJECT (basesink, "possibly waiting for clock to reach %"
GST_TIME_FORMAT, GST_TIME_ARGS (rstart)); GST_TIME_FORMAT ", adjusted %" GST_TIME_FORMAT,
GST_TIME_ARGS (rstart), GST_TIME_ARGS (stime));
/* this function will return immediatly if start == -1, no clock /* This function will return immediatly if start == -1, no clock
* or sync is disabled with GST_CLOCK_BADTIME. */ * or sync is disabled with GST_CLOCK_BADTIME. */
stime = gst_base_sink_adjust_time (basesink, rstart);
status = gst_base_sink_wait_clock (basesink, stime, &jitter); status = gst_base_sink_wait_clock (basesink, stime, &jitter);
GST_DEBUG_OBJECT (basesink, "clock returned %d", status); GST_DEBUG_OBJECT (basesink, "clock returned %d", status);

View file

@ -217,6 +217,11 @@ gboolean gst_base_sink_query_latency (GstBaseSink *sink, gboolean *live, gboole
GstClockTime *min_latency, GstClockTime *max_latency); GstClockTime *min_latency, GstClockTime *max_latency);
GstClockTime gst_base_sink_get_latency (GstBaseSink *sink); GstClockTime gst_base_sink_get_latency (GstBaseSink *sink);
/* render delay */
void gst_base_sink_set_render_delay (GstBaseSink *sink, GstClockTime delay);
GstClockTime gst_base_sink_get_render_delay (GstBaseSink *sink);
GstClockReturn gst_base_sink_wait_clock (GstBaseSink * basesink, GstClockTime time, GstClockReturn gst_base_sink_wait_clock (GstBaseSink * basesink, GstClockTime time,
GstClockTimeDiff * jitter); GstClockTimeDiff * jitter);
GstFlowReturn gst_base_sink_wait_eos (GstBaseSink *sink, GstClockTime time, GstFlowReturn gst_base_sink_wait_eos (GstBaseSink *sink, GstClockTime time,

View file

@ -10,6 +10,7 @@ EXPORTS
gst_adapter_push gst_adapter_push
gst_adapter_take gst_adapter_take
gst_adapter_take_buffer gst_adapter_take_buffer
gst_base_sink_get_render_delay
gst_base_sink_get_last_buffer gst_base_sink_get_last_buffer
gst_base_sink_get_latency gst_base_sink_get_latency
gst_base_sink_get_max_lateness gst_base_sink_get_max_lateness
@ -20,6 +21,7 @@ EXPORTS
gst_base_sink_is_qos_enabled gst_base_sink_is_qos_enabled
gst_base_sink_query_latency gst_base_sink_query_latency
gst_base_sink_set_async_enabled gst_base_sink_set_async_enabled
gst_base_sink_set_render_delay
gst_base_sink_set_max_lateness gst_base_sink_set_max_lateness
gst_base_sink_set_qos_enabled gst_base_sink_set_qos_enabled
gst_base_sink_set_sync gst_base_sink_set_sync