[libcamera-devel] [PATCH v3 23/27] gst: libcamerasrc: Implement timestamp support
Nicolas Dufresne
nicolas at ndufresne.ca
Fri Mar 6 21:26:33 CET 2020
From: Nicolas Dufresne <nicolas.dufresne at collabora.com>
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>
Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.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 840f391..e184495 100644
--- a/src/gstreamer/gstlibcamerapad.cpp
+++ b/src/gstreamer/gstlibcamerapad.cpp
@@ -63,9 +63,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
@@ -173,3 +188,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 9d43129..779f2d1 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 e3718db..b04e9f1 100644
--- a/src/gstreamer/gstlibcamerasrc.cpp
+++ b/src/gstreamer/gstlibcamerasrc.cpp
@@ -154,6 +154,26 @@ GstLibcameraSrcState::requestCompleted(Request *request)
for (GstPad *srcpad : 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(src_)) {
+ GstClockTime gst_base_time = GST_ELEMENT(src_)->base_time;
+ GstClockTime gst_now = gst_clock_get_time(GST_ELEMENT_CLOCK(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_base_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