diff --git a/libs/gst/base/gstadapter.c b/libs/gst/base/gstadapter.c index a74030a7de..935fa20418 100644 --- a/libs/gst/base/gstadapter.c +++ b/libs/gst/base/gstadapter.c @@ -84,11 +84,13 @@ * 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 @@ -948,6 +950,104 @@ gst_adapter_prev_dts (GstAdapter * adapter, guint64 * distance) return adapter->dts; } +/** + * 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 diff --git a/libs/gst/base/gstadapter.h b/libs/gst/base/gstadapter.h index ce5b6ca79b..9625a015db 100644 --- a/libs/gst/base/gstadapter.h +++ b/libs/gst/base/gstadapter.h @@ -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);