libs/gst/base/gstbasesrc.*: Add property to make the basesrc timestamp buffers based on the current running time.

Original commit message from CVS:
* libs/gst/base/gstbasesrc.c: (gst_base_src_class_init),
(gst_base_src_init), (gst_base_src_set_do_timestamp),
(gst_base_src_get_do_timestamp), (gst_base_src_set_property),
(gst_base_src_get_property), (gst_base_src_do_sync):
* libs/gst/base/gstbasesrc.h:
Add property to make the basesrc timestamp buffers based on the current
running time.
API: GstBaseSrc::do-timestamp
API: gst_base_src_set_do_timestamp()
API: gst_base_src_get_do_timestamp()
This commit is contained in:
Wim Taymans 2007-09-10 16:50:11 +00:00
parent 08708360fd
commit 5d57d96af6
3 changed files with 107 additions and 10 deletions

View file

@ -1,3 +1,16 @@
2007-09-10 Wim Taymans <wim.taymans@gmail.com>
* libs/gst/base/gstbasesrc.c: (gst_base_src_class_init),
(gst_base_src_init), (gst_base_src_set_do_timestamp),
(gst_base_src_get_do_timestamp), (gst_base_src_set_property),
(gst_base_src_get_property), (gst_base_src_do_sync):
* libs/gst/base/gstbasesrc.h:
Add property to make the basesrc timestamp buffers based on the current
running time.
API: GstBaseSrc::do-timestamp
API: gst_base_src_set_do_timestamp()
API: gst_base_src_get_do_timestamp()
2007-09-08 Tim-Philipp Müller <tim at centricular dot net>
* docs/random/release:

View file

@ -219,6 +219,7 @@ enum
#define DEFAULT_BLOCKSIZE 4096
#define DEFAULT_NUM_BUFFERS -1
#define DEFAULT_TYPEFIND FALSE
#define DEFAULT_DO_TIMESTAMP FALSE
enum
{
@ -226,6 +227,7 @@ enum
PROP_BLOCKSIZE,
PROP_NUM_BUFFERS,
PROP_TYPEFIND,
PROP_DO_TIMESTAMP
};
#define GST_BASE_SRC_GET_PRIVATE(obj) \
@ -245,6 +247,8 @@ struct _GstBaseSrcPrivate
* the first BUFFER with running_time 0. This value is included in the latency
* reporting. */
GstClockTime startup_latency;
gboolean do_timestamp;
};
static GstElementClass *parent_class = NULL;
@ -353,6 +357,10 @@ gst_base_src_class_init (GstBaseSrcClass * klass)
g_param_spec_boolean ("typefind", "Typefind",
"Run typefind before negotiating", DEFAULT_TYPEFIND,
G_PARAM_READWRITE));
g_object_class_install_property (gobject_class, PROP_DO_TIMESTAMP,
g_param_spec_boolean ("do-timestamp", "Do timestamp",
"Apply current stream time to buffers", DEFAULT_DO_TIMESTAMP,
G_PARAM_READWRITE));
gstelement_class->change_state =
GST_DEBUG_FUNCPTR (gst_base_src_change_state);
@ -421,6 +429,7 @@ gst_base_src_init (GstBaseSrc * basesrc, gpointer g_class)
/* we operate in BYTES by default */
gst_base_src_set_format (basesrc, GST_FORMAT_BYTES);
basesrc->data.ABI.typefind = DEFAULT_TYPEFIND;
basesrc->priv->do_timestamp = DEFAULT_DO_TIMESTAMP;
GST_OBJECT_FLAG_UNSET (basesrc, GST_BASE_SRC_STARTED);
@ -606,6 +615,47 @@ gst_base_src_query_latency (GstBaseSrc * src, gboolean * live,
return TRUE;
}
/**
* gst_base_src_set_do_timestamp:
* @src: the source
* @timestamp: enable or disable timestamping
*
* Configure @src to automatically timestamp outgoing buffers based on the
* current running_time of the pipeline. This property is mostly useful for live
* sources.
*
* Since: 0.10.15
*/
void
gst_base_src_set_do_timestamp (GstBaseSrc * src, gboolean timestamp)
{
GST_OBJECT_LOCK (src);
src->priv->do_timestamp = timestamp;
GST_OBJECT_UNLOCK (src);
}
/**
* gst_base_src_get_do_timestamp:
* @src: the source
*
* Query if @src timestamps outgoing buffers based on the current running_time.
*
* Returns: %TRUE if the base class will automatically timestamp outgoing buffers.
*
* Since: 0.10.15
*/
gboolean
gst_base_src_get_do_timestamp (GstBaseSrc * src)
{
gboolean res;
GST_OBJECT_LOCK (src);
res = src->priv->do_timestamp;
GST_OBJECT_UNLOCK (src);
return res;
}
static gboolean
gst_base_src_setcaps (GstPad * pad, GstCaps * caps)
{
@ -1362,6 +1412,9 @@ gst_base_src_set_property (GObject * object, guint prop_id,
case PROP_TYPEFIND:
src->data.ABI.typefind = g_value_get_boolean (value);
break;
case PROP_DO_TIMESTAMP:
src->priv->do_timestamp = g_value_get_boolean (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -1386,6 +1439,9 @@ gst_base_src_get_property (GObject * object, guint prop_id, GValue * value,
case PROP_TYPEFIND:
g_value_set_boolean (value, src->data.ABI.typefind);
break;
case PROP_DO_TIMESTAMP:
g_value_set_boolean (value, src->priv->do_timestamp);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -1425,6 +1481,8 @@ gst_base_src_do_sync (GstBaseSrc * basesrc, GstBuffer * buffer)
GstBaseSrcClass *bclass;
GstClockTime base_time;
GstClock *clock;
GstClockTime now = -1, timestamp;
gboolean do_timestamp;
bclass = GST_BASE_SRC_GET_CLASS (basesrc);
@ -1436,14 +1494,18 @@ gst_base_src_do_sync (GstBaseSrc * basesrc, GstBuffer * buffer)
* latency. */
GST_OBJECT_LOCK (basesrc);
base_time = GST_ELEMENT_CAST (basesrc)->base_time;
/* get clock, if no clock, we can't sync or get the latency */
if ((clock = GST_ELEMENT_CLOCK (basesrc)) == NULL)
goto no_clock;
base_time = GST_ELEMENT_CAST (basesrc)->base_time;
do_timestamp = basesrc->priv->do_timestamp;
timestamp = GST_BUFFER_TIMESTAMP (buffer);
/* first buffer, calculate the startup latency */
if (basesrc->priv->startup_latency == -1) {
GstClockTime now = gst_clock_get_time (clock);
now = gst_clock_get_time (clock);
/* startup latency is the diff between when we went to PLAYING (base_time)
* and the current clock time */
@ -1454,19 +1516,38 @@ gst_base_src_do_sync (GstBaseSrc * basesrc, GstBuffer * buffer)
GST_LOG_OBJECT (basesrc, "startup latency: %" GST_TIME_FORMAT,
GST_TIME_ARGS (basesrc->priv->startup_latency));
if (!GST_CLOCK_TIME_IS_VALID (timestamp)) {
if (do_timestamp)
timestamp = now - base_time;
else
timestamp = 0;
GST_BUFFER_TIMESTAMP (buffer) = timestamp;
}
/* we have a timestamp, we can subtract it from the startup_latency when it is
* smaller. If the timestamp is bigger, there is no startup latency. */
if (GST_CLOCK_TIME_IS_VALID (timestamp)) {
if (timestamp < basesrc->priv->startup_latency)
basesrc->priv->startup_latency -= timestamp;
else
basesrc->priv->startup_latency = 0;
}
} else {
/* not the first buffer, the timestamp is the diff between the clock and
* base_time */
if (do_timestamp && !GST_CLOCK_TIME_IS_VALID (timestamp)) {
now = gst_clock_get_time (clock);
GST_BUFFER_TIMESTAMP (buffer) = now - base_time;
}
}
/* if we don't have a buffer timestamp, we don't sync */
if (!GST_CLOCK_TIME_IS_VALID (start))
goto invalid_start;
/* we have a timestamp, we can subtract it from the startup_latency when it is
* smaller. If the timestamp is bigger, there is no startup latency. */
if (start < basesrc->priv->startup_latency)
basesrc->priv->startup_latency -= start;
else
basesrc->priv->startup_latency = 0;
GST_LOG_OBJECT (basesrc,
"waiting for clock, base time %" GST_TIME_FORMAT
", stream_start %" GST_TIME_FORMAT,

View file

@ -241,6 +241,9 @@ gboolean gst_base_src_query_latency (GstBaseSrc *src, gboolean * live,
GstClockTime * min_latency,
GstClockTime * max_latency);
void gst_base_src_set_do_timestamp (GstBaseSrc *src, gboolean live);
gboolean gst_base_src_get_do_timestamp (GstBaseSrc *src);
G_END_DECLS
#endif /* __GST_BASE_SRC_H__ */