summaryrefslogtreecommitdiff
path: root/src/gstreamer
diff options
context:
space:
mode:
Diffstat (limited to 'src/gstreamer')
-rw-r--r--src/gstreamer/gstlibcamerapad.cpp23
-rw-r--r--src/gstreamer/gstlibcamerapad.h2
-rw-r--r--src/gstreamer/gstlibcamerasrc.cpp20
3 files changed, 45 insertions, 0 deletions
diff --git a/src/gstreamer/gstlibcamerapad.cpp b/src/gstreamer/gstlibcamerapad.cpp
index 840f391c..e184495a 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 9d431297..779f2d13 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 0b4cae79..64077f36 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);
}