[libcamera-devel] [PATCH 05/13] gstreamer: Move timestamp calculation out of pad loop
Laurent Pinchart
laurent.pinchart at ideasonboard.com
Tue Jun 28 00:22:49 CEST 2022
Hi Nicolas,
On Mon, Jun 27, 2022 at 05:00:19PM -0400, Nicolas Dufresne wrote:
> Le vendredi 24 juin 2022 à 02:22 +0300, Laurent Pinchart a écrit :
> > The buffer pts and the pad latency are computed from the framebuffer
> > timestamp, separately for each pad. Use the sensor timestamp provided
> > through the request metadata instead, to compute the values once outside
> > of the pads loop.
> >
> > Signed-off-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
> > ---
> > src/gstreamer/gstlibcamerasrc.cpp | 34 ++++++++++++++++++++++---------
> > 1 file changed, 24 insertions(+), 10 deletions(-)
> >
> > diff --git a/src/gstreamer/gstlibcamerasrc.cpp b/src/gstreamer/gstlibcamerasrc.cpp
> > index 700bee2bf877..a1fab71d4f09 100644
> > --- a/src/gstreamer/gstlibcamerasrc.cpp
> > +++ b/src/gstreamer/gstlibcamerasrc.cpp
> > @@ -34,6 +34,7 @@
> >
> > #include <libcamera/camera.h>
> > #include <libcamera/camera_manager.h>
> > +#include <libcamera/control_ids.h>
> >
> > #include <gst/base/base.h>
> >
> > @@ -164,22 +165,35 @@ GstLibcameraSrcState::requestCompleted(Request *request)
> > return;
> > }
> >
> > + GstClockTime latency;
> > + GstClockTime pts;
> > +
> > + if (GST_ELEMENT_CLOCK(src_)) {
> > + int64_t timestamp = request->metadata().get(controls::SensorTimestamp);
> > +
> > + 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);
> > + pts = timestamp - sys_base_time;
> > + latency = sys_now - timestamp;
> > + } else {
> > + latency = 0;
> > + pts = 0;
>
> I would like to suggest:
>
> pts = GST_CLOCK_TIME_NONE;
>
> > + }
> > +
> > for (GstPad *srcpad : srcpads_) {
> > Stream *stream = gst_libcamera_pad_get_stream(srcpad);
> > GstBuffer *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);
> > + if (pts) {
>
> And then:
> if (GST_CLOCK_TIME_IS_VALID(pts)) {
>
> Conceptually, pts can be 0 even if it will never happen in practice.
That was my reasoning too :-) I didn't know about GST_CLOCK_TIME_NONE
and GST_CLOCK_TIME_IS_VALID, I'll use those.
> I'm fine
> with the change otherwise. This entire block seems complex enough that it could
> be its own helper function if you feel like it. In long term, when we start
> supporting "desync" streams, we'll be requesting some pads independently, and
> then we'd start having per pad latency that do differ. Not sure why, but it
> looks like I prepared the field for bunch of future use cases, and I fail to add
> all the todos.
That will be interesting to implement.
> > + GST_BUFFER_PTS(buffer) = pts;
> > + gst_libcamera_pad_set_latency(srcpad, latency);
> > } else {
> > GST_BUFFER_PTS(buffer) = 0;
> > }
--
Regards,
Laurent Pinchart
More information about the libcamera-devel
mailing list