adapter: Add gst_adapter_prev_[pd]ts_at_offset()
authorDavid Schleef <ds@schleef.org>
Tue, 12 Feb 2013 00:42:41 +0000 (16:42 -0800)
committerDavid Schleef <ds@schleef.org>
Tue, 12 Feb 2013 20:16:27 +0000 (12:16 -0800)
Original patch written by Michael Smith <msmith@rdio.com>.

API: gst_adapter_prev_pts_at_offset()
API: gst_adapter_prev_dts_at_offset()

libs/gst/base/gstadapter.c
libs/gst/base/gstadapter.h

index a74030a..935fa20 100644 (file)
  * The adapter will keep track of the timestamps of the buffers
  * that were pushed. The last seen timestamp before the current position
  * can be queried with gst_adapter_prev_pts(). This function can
- * optionally return the amount of bytes between the start of the buffer that
+ * optionally return the number of bytes between the start of the buffer that
  * carried the timestamp and the current adapter position. The distance is
  * useful when dealing with, for example, raw audio samples because it allows
  * you to calculate the timestamp of the current adapter position by using the
- * last seen timestamp and the amount of bytes since.
+ * last seen timestamp and the amount of bytes since.  Additionally, the
+ * gst_adapter_prev_pts_at_offset() can be used to determine the last
+ * seen timestamp at a particular offset in the adapter.
  *
  * A last thing to note is that while GstAdapter is pretty optimized,
  * merging buffers still might be an operation that requires a malloc() and
@@ -949,6 +951,104 @@ gst_adapter_prev_dts (GstAdapter * adapter, guint64 * distance)
 }
 
 /**
+ * gst_adapter_prev_pts_at_offset:
+ * @adapter: a #GstAdapter
+ * @offset: the offset in the adapter at which to get timestamp
+ * @distance: (out) (allow-none): pointer to location for distance, or NULL
+ *
+ * Get the pts that was before the byte at offset @offset in the adapter. When
+ * @distance is given, the amount of bytes between the pts and the current
+ * position is returned.
+ *
+ * The pts is reset to GST_CLOCK_TIME_NONE and the distance is set to 0 when
+ * the adapter is first created or when it is cleared. This also means that before
+ * the first byte with a pts is removed from the adapter, the pts
+ * and distance returned are GST_CLOCK_TIME_NONE and 0 respectively.
+ *
+ * Since: 1.2
+ * Returns: The previously seen pts at given offset.
+ */
+GstClockTime
+gst_adapter_prev_pts_at_offset (GstAdapter * adapter, gsize offset,
+    guint64 * distance)
+{
+  GstBuffer *cur;
+  GSList *g;
+  gsize read_offset = 0;
+  GstClockTime pts = adapter->pts;
+
+  g_return_val_if_fail (GST_IS_ADAPTER (adapter), GST_CLOCK_TIME_NONE);
+  g_return_val_if_fail (offset >= 0, GST_CLOCK_TIME_NONE);
+
+  g = adapter->buflist;
+
+  while (g && read_offset < offset + adapter->skip) {
+    cur = g->data;
+
+    read_offset += gst_buffer_get_size (cur);
+    if (GST_CLOCK_TIME_IS_VALID (GST_BUFFER_PTS (cur))) {
+      pts = GST_BUFFER_PTS (cur);
+    }
+
+    g = g_slist_next (g);
+  }
+
+  if (distance)
+    *distance = adapter->dts_distance + offset;
+
+  return pts;
+}
+
+/**
+ * gst_adapter_prev_dts_at_offset:
+ * @adapter: a #GstAdapter
+ * @offset: the offset in the adapter at which to get timestamp
+ * @distance: (out) (allow-none): pointer to location for distance, or NULL
+ *
+ * Get the dts that was before the byte at offset @offset in the adapter. When
+ * @distance is given, the amount of bytes between the dts and the current
+ * position is returned.
+ *
+ * The dts is reset to GST_CLOCK_TIME_NONE and the distance is set to 0 when
+ * the adapter is first created or when it is cleared. This also means that before
+ * the first byte with a dts is removed from the adapter, the dts
+ * and distance returned are GST_CLOCK_TIME_NONE and 0 respectively.
+ *
+ * Since: 1.2
+ * Returns: The previously seen dts at given offset.
+ */
+GstClockTime
+gst_adapter_prev_dts_at_offset (GstAdapter * adapter, gsize offset,
+    guint64 * distance)
+{
+  GstBuffer *cur;
+  GSList *g;
+  gsize read_offset = 0;
+  GstClockTime dts = adapter->dts;
+
+  g_return_val_if_fail (GST_IS_ADAPTER (adapter), GST_CLOCK_TIME_NONE);
+  g_return_val_if_fail (offset >= 0, GST_CLOCK_TIME_NONE);
+
+  g = adapter->buflist;
+
+  while (g && read_offset < offset + adapter->skip) {
+    cur = g->data;
+
+    read_offset += gst_buffer_get_size (cur);
+    if (GST_CLOCK_TIME_IS_VALID (GST_BUFFER_DTS (cur))) {
+      dts = GST_BUFFER_DTS (cur);
+    }
+
+    g = g_slist_next (g);
+  }
+
+  if (distance)
+    *distance = adapter->dts_distance + offset;
+
+  return dts;
+}
+
+/**
  * gst_adapter_masked_scan_uint32_peek:
  * @adapter: a #GstAdapter
  * @mask: mask to apply to data before matching against @pattern
index ce5b6ca..9625a01 100644 (file)
@@ -65,6 +65,8 @@ gsize                   gst_adapter_available_fast      (GstAdapter *adapter);
 
 GstClockTime            gst_adapter_prev_pts            (GstAdapter *adapter, guint64 *distance);
 GstClockTime            gst_adapter_prev_dts            (GstAdapter *adapter, guint64 *distance);
+GstClockTime            gst_adapter_prev_pts_at_offset  (GstAdapter * adapter, gsize offset, guint64 * distance);
+GstClockTime            gst_adapter_prev_dts_at_offset  (GstAdapter * adapter, gsize offset, guint64 * distance);
 
 gssize                  gst_adapter_masked_scan_uint32  (GstAdapter * adapter, guint32 mask,
                                                          guint32 pattern, gsize offset, gsize size);