[libcamera-devel] [PATCH v2 23/27] gst: libcamerasrc: Implement timestamp support

Nicolas Dufresne nicolas.dufresne at collabora.com
Thu Feb 27 21:04:03 CET 2020


This is an experimental patch adding timestamp support to the libcamerasrc
element. This patch currently assume that the driver timestamp are relative to
the system monotonic clock. Without a reference clock source, the timestamp are
otherwise unusable, and without timestamp only minor use case can be achieved.

Signed-off-by: Nicolas Dufresne <nicolas.dufresne at collabora.com>
---
 src/gstreamer/gstlibcamerapad.cpp | 23 +++++++++++++++++++++++
 src/gstreamer/gstlibcamerapad.h   |  2 ++
 src/gstreamer/gstlibcamerasrc.cpp | 20 ++++++++++++++++++++
 3 files changed, 45 insertions(+)

diff --git a/src/gstreamer/gstlibcamerapad.cpp b/src/gstreamer/gstlibcamerapad.cpp
index 2cf1630..31d3edd 100644
--- a/src/gstreamer/gstlibcamerapad.cpp
+++ b/src/gstreamer/gstlibcamerapad.cpp
@@ -62,9 +62,24 @@ gst_libcamera_pad_get_property(GObject *object, guint prop_id, GValue *value,
 	}
 }
 
+static gboolean
+gst_libcamera_pad_query(GstPad *pad, GstObject *parent, GstQuery *query)
+{
+	auto *self = GST_LIBCAMERA_PAD(pad);
+
+	if (query->type != GST_QUERY_LATENCY)
+		return gst_pad_query_default(pad, parent, query);
+
+	/* TRUE here means live, we assumes that max latency is the same as min
+	 * as we have no idea that duration of frames. */
+	gst_query_set_latency(query, TRUE, self->latency, self->latency);
+	return TRUE;
+}
+
 static void
 gst_libcamera_pad_init(GstLibcameraPad *self)
 {
+	GST_PAD_QUERYFUNC(self) = gst_libcamera_pad_query;
 }
 
 static GType
@@ -172,3 +187,11 @@ gst_libcamera_pad_has_pending(GstPad *pad)
 	GLibLocker lock(GST_OBJECT(self));
 	return (self->pending_buffers.length > 0);
 }
+
+void
+gst_libcamera_pad_set_latency(GstPad *pad, GstClockTime latency)
+{
+	auto *self = GST_LIBCAMERA_PAD(pad);
+	GLibLocker lock(GST_OBJECT(self));
+	self->latency = latency;
+}
diff --git a/src/gstreamer/gstlibcamerapad.h b/src/gstreamer/gstlibcamerapad.h
index eb24000..a3291e8 100644
--- a/src/gstreamer/gstlibcamerapad.h
+++ b/src/gstreamer/gstlibcamerapad.h
@@ -32,4 +32,6 @@ GstFlowReturn gst_libcamera_pad_push_pending(GstPad *pad);
 
 bool gst_libcamera_pad_has_pending(GstPad *pad);
 
+void gst_libcamera_pad_set_latency(GstPad *pad, GstClockTime latency);
+
 #endif /* __GST_LIBCAMERA_PAD_H__ */
diff --git a/src/gstreamer/gstlibcamerasrc.cpp b/src/gstreamer/gstlibcamerasrc.cpp
index 70f2048..73a1360 100644
--- a/src/gstreamer/gstlibcamerasrc.cpp
+++ b/src/gstreamer/gstlibcamerasrc.cpp
@@ -151,6 +151,26 @@ GstLibcameraSrcState::requestCompleted(Request *request)
 	for (GstPad *srcpad : this->srcpads) {
 		Stream *stream = gst_libcamera_pad_get_stream(srcpad);
 		buffer = wrap->detachBuffer(stream);
+
+		FrameBuffer *fb = gst_libcamera_buffer_get_frame_buffer(buffer);
+
+		if (GST_ELEMENT_CLOCK(this->src)) {
+			GstClockTime gst_base_time = GST_ELEMENT(this->src)->base_time;
+			GstClockTime gst_now = gst_clock_get_time(GST_ELEMENT_CLOCK(this->src));
+			/* \todo Need to expose which reference clock the timestamp relates to. */
+			GstClockTime sys_now = g_get_monotonic_time() * 1000;
+
+			/* Deduced from: sys_now - sys_base_time == gst_now - gst_bae_time */
+			GstClockTime sys_base_time = sys_now - (gst_now - gst_base_time);
+			GST_BUFFER_PTS(buffer) = fb->metadata().timestamp - sys_base_time;
+			gst_libcamera_pad_set_latency(srcpad, sys_now - fb->metadata().timestamp);
+		} else {
+			GST_BUFFER_PTS(buffer) = 0;
+		}
+
+		GST_BUFFER_OFFSET(buffer) = fb->metadata().sequence;
+		GST_BUFFER_OFFSET_END(buffer) = fb->metadata().sequence;
+
 		gst_libcamera_pad_queue_buffer(srcpad, buffer);
 	}
 
-- 
2.24.1



More information about the libcamera-devel mailing list