diff options
-rw-r--r-- | src/gstreamer/gstlibcamerapad.cpp | 23 | ||||
-rw-r--r-- | src/gstreamer/gstlibcamerapad.h | 2 | ||||
-rw-r--r-- | src/gstreamer/gstlibcamerasrc.cpp | 20 |
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); } |