summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
authorWim Taymans <wim.taymans@gmail.com>2007-09-10 16:50:11 +0000
committerWim Taymans <wim.taymans@gmail.com>2007-09-10 16:50:11 +0000
commit5d57d96af60681db0a28a9e3b8b678e4e3d1dd8a (patch)
treec1c05772a7afd06a7d2f87c7a0e2eefd5515eb1f /libs
parent08708360fdb19f05c2ff361fcbb385d86d4ea49f (diff)
downloadgstreamer-5d57d96af60681db0a28a9e3b8b678e4e3d1dd8a.tar.gz
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()
Diffstat (limited to 'libs')
-rw-r--r--libs/gst/base/gstbasesrc.c101
-rw-r--r--libs/gst/base/gstbasesrc.h3
2 files changed, 94 insertions, 10 deletions
diff --git a/libs/gst/base/gstbasesrc.c b/libs/gst/base/gstbasesrc.c
index b6fb613d3f..043285590d 100644
--- a/libs/gst/base/gstbasesrc.c
+++ b/libs/gst/base/gstbasesrc.c
@@ -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,
diff --git a/libs/gst/base/gstbasesrc.h b/libs/gst/base/gstbasesrc.h
index 4fcefeafc9..efdd1c2a9f 100644
--- a/libs/gst/base/gstbasesrc.h
+++ b/libs/gst/base/gstbasesrc.h
@@ -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__ */