[{"id":23623,"web_url":"https://patchwork.libcamera.org/comment/23623/","msgid":"<8e244a88a274977de90e6b18b24700b30b7f1655.camel@collabora.com>","date":"2022-06-27T21:00:19","subject":"Re: [libcamera-devel] [PATCH 05/13] gstreamer: Move timestamp\n\tcalculation out of pad loop","submitter":{"id":31,"url":"https://patchwork.libcamera.org/api/people/31/","name":"Nicolas Dufresne","email":"nicolas.dufresne@collabora.com"},"content":"Hi Laurent,\n\nLe vendredi 24 juin 2022 à 02:22 +0300, Laurent Pinchart a écrit :\n> The buffer pts and the pad latency are computed from the framebuffer\n> timestamp, separately for each pad. Use the sensor timestamp provided\n> through the request metadata instead, to compute the values once outside\n> of the pads loop.\n> \n> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> ---\n>  src/gstreamer/gstlibcamerasrc.cpp | 34 ++++++++++++++++++++++---------\n>  1 file changed, 24 insertions(+), 10 deletions(-)\n> \n> diff --git a/src/gstreamer/gstlibcamerasrc.cpp b/src/gstreamer/gstlibcamerasrc.cpp\n> index 700bee2bf877..a1fab71d4f09 100644\n> --- a/src/gstreamer/gstlibcamerasrc.cpp\n> +++ b/src/gstreamer/gstlibcamerasrc.cpp\n> @@ -34,6 +34,7 @@\n>  \n>  #include <libcamera/camera.h>\n>  #include <libcamera/camera_manager.h>\n> +#include <libcamera/control_ids.h>\n>  \n>  #include <gst/base/base.h>\n>  \n> @@ -164,22 +165,35 @@ GstLibcameraSrcState::requestCompleted(Request *request)\n>  \t\treturn;\n>  \t}\n>  \n> +\tGstClockTime latency;\n> +\tGstClockTime pts;\n> +\n> +\tif (GST_ELEMENT_CLOCK(src_)) {\n> +\t\tint64_t timestamp = request->metadata().get(controls::SensorTimestamp);\n> +\n> +\t\tGstClockTime gst_base_time = GST_ELEMENT(src_)->base_time;\n> +\t\tGstClockTime gst_now = gst_clock_get_time(GST_ELEMENT_CLOCK(src_));\n> +\t\t/* \\todo Need to expose which reference clock the timestamp relates to. */\n> +\t\tGstClockTime sys_now = g_get_monotonic_time() * 1000;\n> +\n> +\t\t/* Deduced from: sys_now - sys_base_time == gst_now - gst_base_time */\n> +\t\tGstClockTime sys_base_time = sys_now - (gst_now - gst_base_time);\n> +\t\tpts = timestamp - sys_base_time;\n> +\t\tlatency = sys_now - timestamp;\n> +\t} else {\n> +\t\tlatency = 0;\n> +\t\tpts = 0;\n\nI would like to suggest: \n\n                pts = GST_CLOCK_TIME_NONE;\n\n> +\t}\n> +\n>  \tfor (GstPad *srcpad : srcpads_) {\n>  \t\tStream *stream = gst_libcamera_pad_get_stream(srcpad);\n>  \t\tGstBuffer *buffer = wrap->detachBuffer(stream);\n>  \n>  \t\tFrameBuffer *fb = gst_libcamera_buffer_get_frame_buffer(buffer);\n>  \n> -\t\tif (GST_ELEMENT_CLOCK(src_)) {\n> -\t\t\tGstClockTime gst_base_time = GST_ELEMENT(src_)->base_time;\n> -\t\t\tGstClockTime gst_now = gst_clock_get_time(GST_ELEMENT_CLOCK(src_));\n> -\t\t\t/* \\todo Need to expose which reference clock the timestamp relates to. */\n> -\t\t\tGstClockTime sys_now = g_get_monotonic_time() * 1000;\n> -\n> -\t\t\t/* Deduced from: sys_now - sys_base_time == gst_now - gst_base_time */\n> -\t\t\tGstClockTime sys_base_time = sys_now - (gst_now - gst_base_time);\n> -\t\t\tGST_BUFFER_PTS(buffer) = fb->metadata().timestamp - sys_base_time;\n> -\t\t\tgst_libcamera_pad_set_latency(srcpad, sys_now - fb->metadata().timestamp);\n> +\t\tif (pts) {\n\nAnd then:\n                if (GST_CLOCK_TIME_IS_VALID(pts)) {\n\nConceptually, pts can be 0 even if it will never happen in practice. I'm fine\nwith the change otherwise. This entire block seems complex enough that it could\nbe its own helper function if you feel like it. In long term, when we start\nsupporting \"desync\" streams, we'll be requesting some pads independently, and\nthen we'd start having per pad latency that do differ. Not sure why, but it\nlooks like I prepared the field for bunch of future use cases, and I fail to add\nall the todos.\n\n> +\t\t\tGST_BUFFER_PTS(buffer) = pts;\n> +\t\t\tgst_libcamera_pad_set_latency(srcpad, latency);\n>  \t\t} else {\n>  \t\t\tGST_BUFFER_PTS(buffer) = 0;\n>  \t\t}","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id A152BBE173\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 27 Jun 2022 21:00:30 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id DE6B865635;\n\tMon, 27 Jun 2022 23:00:29 +0200 (CEST)","from madras.collabora.co.uk (madras.collabora.co.uk\n\t[46.235.227.172])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 973086059B\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 27 Jun 2022 23:00:28 +0200 (CEST)","from nicolas-tpx395.localdomain (192-222-136-102.qc.cable.ebox.net\n\t[192.222.136.102])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\tkey-exchange X25519 server-signature RSA-PSS (4096 bits)\n\tserver-digest SHA256)\n\t(No client certificate requested) (Authenticated sender: nicolas)\n\tby madras.collabora.co.uk (Postfix) with ESMTPSA id B08276601605;\n\tMon, 27 Jun 2022 22:00:27 +0100 (BST)"],"DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1656363629;\n\tbh=bySFvv1bm78+HohyAU90IG99PU6RFb0zAEqIigAe6Zk=;\n\th=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc:\n\tFrom;\n\tb=LEpVhtqR9xAFOgZ26aUhVKSQC+3y0oEt8Fpu//jOsqNI20wXk/gz6gMt3c9zPgAvx\n\t49ZOf0LDksr2EIlwmkLt1OavvNcHglkBdlqMfi33HzuUS139IGbf66yjWQF80Aq/ui\n\tK8AIauUkVwuovN3xE/zGcoURLYzaYX5YzfE2HPI9E237Y+fgekWc0bNRMlQ08kJGSN\n\t8Bxwk8c2qMO4JKgA005H0JgQ/gVtLhyqm4uOdxB8QnSd8PsfzsQ4M61KE0hsNTuPLu\n\tyxRegi23FSAZ8upLK6SivH1kAkPpb+F0DPExy3bNpp+tHV4bX2jxcfGhaDL/9gJRZf\n\txL0fLCidEj9IA==","v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com;\n\ts=mail; t=1656363628;\n\tbh=bySFvv1bm78+HohyAU90IG99PU6RFb0zAEqIigAe6Zk=;\n\th=Subject:From:To:Cc:Date:In-Reply-To:References:From;\n\tb=kek26Hug5gYpLy2/xBxD+e3MAjvL/Qqg4Ahg62y/593w66po9aVg0CMkThmJvapvg\n\teewuPsmVLBR1EIfp90kUr8Gk3KDUY/Ajjf7uQ0HGnWC5I7HKnt7KqAvctkMS98riOL\n\tsaScvrpMDA05acf+p6VSwTO1DsN6nTZm7+f4+BLs1+Xf4xn6Uu1fDovmHoNHJWRpQP\n\tAxbWjKOxviHGgJ7U4rO/lIxqduA4sGINGJfyN/9/PegTo/3FYhaADvLTB0Po/TTS6V\n\tdKy4VVX6/U6M3sTBi+0hVvgF90ND5dvEeD73yxoPU/PI65bUDEa7bANmV4n7/j01Ol\n\ttLo92a3V5cJ5A=="],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (2048-bit key; \n\tunprotected) header.d=collabora.com\n\theader.i=@collabora.com\n\theader.b=\"kek26Hug\"; dkim-atps=neutral","Message-ID":"<8e244a88a274977de90e6b18b24700b30b7f1655.camel@collabora.com>","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>, \n\tlibcamera-devel@lists.libcamera.org","Date":"Mon, 27 Jun 2022 17:00:19 -0400","In-Reply-To":"<20220623232210.18742-6-laurent.pinchart@ideasonboard.com>","References":"<20220623232210.18742-1-laurent.pinchart@ideasonboard.com>\n\t<20220623232210.18742-6-laurent.pinchart@ideasonboard.com>","Content-Type":"text/plain; charset=\"UTF-8\"","Content-Transfer-Encoding":"quoted-printable","User-Agent":"Evolution 3.44.2 (3.44.2-1.fc36) ","MIME-Version":"1.0","Subject":"Re: [libcamera-devel] [PATCH 05/13] gstreamer: Move timestamp\n\tcalculation out of pad loop","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","From":"Nicolas Dufresne via libcamera-devel\n\t<libcamera-devel@lists.libcamera.org>","Reply-To":"Nicolas Dufresne <nicolas.dufresne@collabora.com>","Cc":"Vedant Paranjape <vedantparanjape160201@gmail.com>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":23627,"web_url":"https://patchwork.libcamera.org/comment/23627/","msgid":"<YrotuV8ZpHCTgv2H@pendragon.ideasonboard.com>","date":"2022-06-27T22:22:49","subject":"Re: [libcamera-devel] [PATCH 05/13] gstreamer: Move timestamp\n\tcalculation out of pad loop","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Nicolas,\n\nOn Mon, Jun 27, 2022 at 05:00:19PM -0400, Nicolas Dufresne wrote:\n> Le vendredi 24 juin 2022 à 02:22 +0300, Laurent Pinchart a écrit :\n> > The buffer pts and the pad latency are computed from the framebuffer\n> > timestamp, separately for each pad. Use the sensor timestamp provided\n> > through the request metadata instead, to compute the values once outside\n> > of the pads loop.\n> > \n> > Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> > ---\n> >  src/gstreamer/gstlibcamerasrc.cpp | 34 ++++++++++++++++++++++---------\n> >  1 file changed, 24 insertions(+), 10 deletions(-)\n> > \n> > diff --git a/src/gstreamer/gstlibcamerasrc.cpp b/src/gstreamer/gstlibcamerasrc.cpp\n> > index 700bee2bf877..a1fab71d4f09 100644\n> > --- a/src/gstreamer/gstlibcamerasrc.cpp\n> > +++ b/src/gstreamer/gstlibcamerasrc.cpp\n> > @@ -34,6 +34,7 @@\n> >  \n> >  #include <libcamera/camera.h>\n> >  #include <libcamera/camera_manager.h>\n> > +#include <libcamera/control_ids.h>\n> >  \n> >  #include <gst/base/base.h>\n> >  \n> > @@ -164,22 +165,35 @@ GstLibcameraSrcState::requestCompleted(Request *request)\n> >  \t\treturn;\n> >  \t}\n> >  \n> > +\tGstClockTime latency;\n> > +\tGstClockTime pts;\n> > +\n> > +\tif (GST_ELEMENT_CLOCK(src_)) {\n> > +\t\tint64_t timestamp = request->metadata().get(controls::SensorTimestamp);\n> > +\n> > +\t\tGstClockTime gst_base_time = GST_ELEMENT(src_)->base_time;\n> > +\t\tGstClockTime gst_now = gst_clock_get_time(GST_ELEMENT_CLOCK(src_));\n> > +\t\t/* \\todo Need to expose which reference clock the timestamp relates to. */\n> > +\t\tGstClockTime sys_now = g_get_monotonic_time() * 1000;\n> > +\n> > +\t\t/* Deduced from: sys_now - sys_base_time == gst_now - gst_base_time */\n> > +\t\tGstClockTime sys_base_time = sys_now - (gst_now - gst_base_time);\n> > +\t\tpts = timestamp - sys_base_time;\n> > +\t\tlatency = sys_now - timestamp;\n> > +\t} else {\n> > +\t\tlatency = 0;\n> > +\t\tpts = 0;\n> \n> I would like to suggest: \n> \n>                 pts = GST_CLOCK_TIME_NONE;\n> \n> > +\t}\n> > +\n> >  \tfor (GstPad *srcpad : srcpads_) {\n> >  \t\tStream *stream = gst_libcamera_pad_get_stream(srcpad);\n> >  \t\tGstBuffer *buffer = wrap->detachBuffer(stream);\n> >  \n> >  \t\tFrameBuffer *fb = gst_libcamera_buffer_get_frame_buffer(buffer);\n> >  \n> > -\t\tif (GST_ELEMENT_CLOCK(src_)) {\n> > -\t\t\tGstClockTime gst_base_time = GST_ELEMENT(src_)->base_time;\n> > -\t\t\tGstClockTime gst_now = gst_clock_get_time(GST_ELEMENT_CLOCK(src_));\n> > -\t\t\t/* \\todo Need to expose which reference clock the timestamp relates to. */\n> > -\t\t\tGstClockTime sys_now = g_get_monotonic_time() * 1000;\n> > -\n> > -\t\t\t/* Deduced from: sys_now - sys_base_time == gst_now - gst_base_time */\n> > -\t\t\tGstClockTime sys_base_time = sys_now - (gst_now - gst_base_time);\n> > -\t\t\tGST_BUFFER_PTS(buffer) = fb->metadata().timestamp - sys_base_time;\n> > -\t\t\tgst_libcamera_pad_set_latency(srcpad, sys_now - fb->metadata().timestamp);\n> > +\t\tif (pts) {\n> \n> And then:\n>                 if (GST_CLOCK_TIME_IS_VALID(pts)) {\n> \n> Conceptually, pts can be 0 even if it will never happen in practice.\n\nThat was my reasoning too :-) I didn't know about GST_CLOCK_TIME_NONE\nand GST_CLOCK_TIME_IS_VALID, I'll use those.\n\n> I'm fine\n> with the change otherwise. This entire block seems complex enough that it could\n> be its own helper function if you feel like it. In long term, when we start\n> supporting \"desync\" streams, we'll be requesting some pads independently, and\n> then we'd start having per pad latency that do differ. Not sure why, but it\n> looks like I prepared the field for bunch of future use cases, and I fail to add\n> all the todos.\n\nThat will be interesting to implement.\n\n> > +\t\t\tGST_BUFFER_PTS(buffer) = pts;\n> > +\t\t\tgst_libcamera_pad_set_latency(srcpad, latency);\n> >  \t\t} else {\n> >  \t\t\tGST_BUFFER_PTS(buffer) = 0;\n> >  \t\t}","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id B478CBD808\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 27 Jun 2022 22:23:11 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id CD81265635;\n\tTue, 28 Jun 2022 00:23:10 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 0DFB9633A7\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 28 Jun 2022 00:23:08 +0200 (CEST)","from pendragon.ideasonboard.com (62-78-145-57.bb.dnainternet.fi\n\t[62.78.145.57])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 6C6AB55A;\n\tTue, 28 Jun 2022 00:23:07 +0200 (CEST)"],"DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1656368590;\n\tbh=hNl+hG02HXWtvEiQeObRi0UdumXdhPTj0FPoq60I8Q8=;\n\th=Date:To:References:In-Reply-To:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc:\n\tFrom;\n\tb=Rc68ZbSN9k6vGP+jzNO7Pvw1/e5YGzzRRDN19zbTQTBK0+ugj1dVCXgrrSzJXyxsY\n\tcr3Xathaege7jKYK8K+V6hj2SDsLfdYMc/v+JbVG9PNx+3F0gStjBhtha4Sh8KMirv\n\t3p0/tk1AVOWNYzXPEffxLV6QPfOIwph7aqwgUlqAWFwKhBsIL8ZswAh0Fo+QkOkEze\n\tu0fj6Hw9cN5lmrEXFyhQ2zi7Bm1WfMVT4bkNi3th0Gfdm6TNOBGouSl0SgO2CgVRgr\n\tOKwBmpvOiWc8bre+cPKXg61WnkstYOjn/fhF+cGheIAjGYUoW5jLLSf6hOYpB2J5Jr\n\tdpuUSZvrGTUtA==","v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1656368587;\n\tbh=hNl+hG02HXWtvEiQeObRi0UdumXdhPTj0FPoq60I8Q8=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=rdc6lR6SXEGmMVFVKXtOKvD+qbdGTbEFGkpc40tC7BQMCw8wG/OjRJoEKYGUb0zc1\n\t1ubshVw7c9LMTEt5FI0Y8+4vYlnqcV/fKe4WKJnzl7pdgjwFnd+1zO7On+WKYoVKKT\n\tc4dPjOMd+sq4XgmG2a3PM+E1RJ2nXbVYhCu/C3dA="],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key; \n\tunprotected) header.d=ideasonboard.com\n\theader.i=@ideasonboard.com\n\theader.b=\"rdc6lR6S\"; dkim-atps=neutral","Date":"Tue, 28 Jun 2022 01:22:49 +0300","To":"Nicolas Dufresne <nicolas.dufresne@collabora.com>","Message-ID":"<YrotuV8ZpHCTgv2H@pendragon.ideasonboard.com>","References":"<20220623232210.18742-1-laurent.pinchart@ideasonboard.com>\n\t<20220623232210.18742-6-laurent.pinchart@ideasonboard.com>\n\t<8e244a88a274977de90e6b18b24700b30b7f1655.camel@collabora.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","Content-Transfer-Encoding":"8bit","In-Reply-To":"<8e244a88a274977de90e6b18b24700b30b7f1655.camel@collabora.com>","Subject":"Re: [libcamera-devel] [PATCH 05/13] gstreamer: Move timestamp\n\tcalculation out of pad loop","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","From":"Laurent Pinchart via libcamera-devel\n\t<libcamera-devel@lists.libcamera.org>","Reply-To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org,\n\tVedant Paranjape <vedantparanjape160201@gmail.com>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":23664,"web_url":"https://patchwork.libcamera.org/comment/23664/","msgid":"<f089585a-4cb6-15e5-c28f-5c4d31484a0c@ideasonboard.com>","date":"2022-06-29T14:39:16","subject":"Re: [libcamera-devel] [PATCH 05/13] gstreamer: Move timestamp\n\tcalculation out of pad loop","submitter":{"id":86,"url":"https://patchwork.libcamera.org/api/people/86/","name":"Umang Jain","email":"umang.jain@ideasonboard.com"},"content":"Hi Laurent,\n\nOn 6/28/22 03:52, Laurent Pinchart via libcamera-devel wrote:\n> Hi Nicolas,\n>\n> On Mon, Jun 27, 2022 at 05:00:19PM -0400, Nicolas Dufresne wrote:\n>> Le vendredi 24 juin 2022 à 02:22 +0300, Laurent Pinchart a écrit :\n>>> The buffer pts and the pad latency are computed from the framebuffer\n>>> timestamp, separately for each pad. Use the sensor timestamp provided\n>>> through the request metadata instead, to compute the values once outside\n>>> of the pads loop.\n>>>\n>>> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n>>> ---\n>>>   src/gstreamer/gstlibcamerasrc.cpp | 34 ++++++++++++++++++++++---------\n>>>   1 file changed, 24 insertions(+), 10 deletions(-)\n>>>\n>>> diff --git a/src/gstreamer/gstlibcamerasrc.cpp b/src/gstreamer/gstlibcamerasrc.cpp\n>>> index 700bee2bf877..a1fab71d4f09 100644\n>>> --- a/src/gstreamer/gstlibcamerasrc.cpp\n>>> +++ b/src/gstreamer/gstlibcamerasrc.cpp\n>>> @@ -34,6 +34,7 @@\n>>>   \n>>>   #include <libcamera/camera.h>\n>>>   #include <libcamera/camera_manager.h>\n>>> +#include <libcamera/control_ids.h>\n>>>   \n>>>   #include <gst/base/base.h>\n>>>   \n>>> @@ -164,22 +165,35 @@ GstLibcameraSrcState::requestCompleted(Request *request)\n>>>   \t\treturn;\n>>>   \t}\n>>>   \n>>> +\tGstClockTime latency;\n>>> +\tGstClockTime pts;\n>>> +\n>>> +\tif (GST_ELEMENT_CLOCK(src_)) {\n>>> +\t\tint64_t timestamp = request->metadata().get(controls::SensorTimestamp);\n>>> +\n>>> +\t\tGstClockTime gst_base_time = GST_ELEMENT(src_)->base_time;\n>>> +\t\tGstClockTime gst_now = gst_clock_get_time(GST_ELEMENT_CLOCK(src_));\n>>> +\t\t/* \\todo Need to expose which reference clock the timestamp relates to. */\n>>> +\t\tGstClockTime sys_now = g_get_monotonic_time() * 1000;\n>>> +\n>>> +\t\t/* Deduced from: sys_now - sys_base_time == gst_now - gst_base_time */\n>>> +\t\tGstClockTime sys_base_time = sys_now - (gst_now - gst_base_time);\n>>> +\t\tpts = timestamp - sys_base_time;\n>>> +\t\tlatency = sys_now - timestamp;\n>>> +\t} else {\n>>> +\t\tlatency = 0;\n>>> +\t\tpts = 0;\n>> I would like to suggest:\n>>\n>>                  pts = GST_CLOCK_TIME_NONE;\n>>\n>>> +\t}\n>>> +\n>>>   \tfor (GstPad *srcpad : srcpads_) {\n>>>   \t\tStream *stream = gst_libcamera_pad_get_stream(srcpad);\n>>>   \t\tGstBuffer *buffer = wrap->detachBuffer(stream);\n>>>   \n>>>   \t\tFrameBuffer *fb = gst_libcamera_buffer_get_frame_buffer(buffer);\n>>>   \n>>> -\t\tif (GST_ELEMENT_CLOCK(src_)) {\n>>> -\t\t\tGstClockTime gst_base_time = GST_ELEMENT(src_)->base_time;\n>>> -\t\t\tGstClockTime gst_now = gst_clock_get_time(GST_ELEMENT_CLOCK(src_));\n>>> -\t\t\t/* \\todo Need to expose which reference clock the timestamp relates to. */\n>>> -\t\t\tGstClockTime sys_now = g_get_monotonic_time() * 1000;\n>>> -\n>>> -\t\t\t/* Deduced from: sys_now - sys_base_time == gst_now - gst_base_time */\n>>> -\t\t\tGstClockTime sys_base_time = sys_now - (gst_now - gst_base_time);\n>>> -\t\t\tGST_BUFFER_PTS(buffer) = fb->metadata().timestamp - sys_base_time;\n>>> -\t\t\tgst_libcamera_pad_set_latency(srcpad, sys_now - fb->metadata().timestamp);\n>>> +\t\tif (pts) {\n>> And then:\n>>                  if (GST_CLOCK_TIME_IS_VALID(pts)) {\n>>\n>> Conceptually, pts can be 0 even if it will never happen in practice.\n> That was my reasoning too :-) I didn't know about GST_CLOCK_TIME_NONE\n> and GST_CLOCK_TIME_IS_VALID, I'll use those.\n>\n>> I'm fine\n>> with the change otherwise. This entire block seems complex enough that it could\n>> be its own helper function if you feel like it. In long term, when we start\n\n\nAgreed. Can be done on top as well.\n\nReviewed-by: Umang Jain <umang.jain@ideasonboard.com>\n\n>> supporting \"desync\" streams, we'll be requesting some pads independently, and\n>> then we'd start having per pad latency that do differ. Not sure why, but it\n>> looks like I prepared the field for bunch of future use cases, and I fail to add\n>> all the todos.\n> That will be interesting to implement.\n>\n>>> +\t\t\tGST_BUFFER_PTS(buffer) = pts;\n>>> +\t\t\tgst_libcamera_pad_set_latency(srcpad, latency);\n>>>   \t\t} else {\n>>>   \t\t\tGST_BUFFER_PTS(buffer) = 0;\n>>>   \t\t}","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 6046DBE173\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed, 29 Jun 2022 14:39:28 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 58B6065635;\n\tWed, 29 Jun 2022 16:39:27 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 0B46F60412\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 29 Jun 2022 16:39:26 +0200 (CEST)","from [IPV6:2401:4900:1f3f:ca21:e286:106b:5da4:9482] (unknown\n\t[IPv6:2401:4900:1f3f:ca21:e286:106b:5da4:9482])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 2DCB63D7;\n\tWed, 29 Jun 2022 16:39:23 +0200 (CEST)"],"DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1656513567;\n\tbh=r48EYCXOBO7yArcdAhVzp1QFUGYB0tkGQHFF+CWDmhA=;\n\th=Date:To:References:In-Reply-To:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc:\n\tFrom;\n\tb=tMwc9CZKGtwrYDorzT4QJGb9m13W2OC8DRU5mshVvQGRCGdtCiUKdtJY5MNqQrGWm\n\tZmkzVdrdJaBg0Gw2nWRRbknXV9iDzHzxnZkQbOib2ZoJVbsG4h9k8hKIpvXkKdl5xz\n\t/AE1sHRkgBAZQdmtq1kxsmsisRzhVuZVP4j3aSC3ys5fymp2FSPP0NjRb722m/t4ae\n\txBXcPgvWMZUFEPNVocV/puHqtd2XY8PF89rqUVQyb5zDgOTb2ObUyju8H8BCRm50O1\n\t3E+rGQK853K2w7Ll0/tGgeVe3gf1ToQUlAlCR93aMyn74fN4FYGqdtZUlV0iybO1XQ\n\tVl6LhQux2kAVw==","v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1656513565;\n\tbh=r48EYCXOBO7yArcdAhVzp1QFUGYB0tkGQHFF+CWDmhA=;\n\th=Date:Subject:To:Cc:References:From:In-Reply-To:From;\n\tb=rCu4fSZ2AQ8rCjXifTVPTI3GVuWU+He/3wNBrrM82ztlym1sY3Bz9acROE9Ew/Ive\n\t/uXwICuD1ILV45YC5ZYX65I1y5sCUFe/7o+jJS8N5w6cUVgN9PBkn0IYRY+CSWZFDf\n\tIuvNKoV3obvIsfK/s0vQhRnQPd8oMH1I3gf/42pU="],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key; \n\tunprotected) header.d=ideasonboard.com\n\theader.i=@ideasonboard.com\n\theader.b=\"rCu4fSZ2\"; dkim-atps=neutral","Message-ID":"<f089585a-4cb6-15e5-c28f-5c4d31484a0c@ideasonboard.com>","Date":"Wed, 29 Jun 2022 20:09:16 +0530","MIME-Version":"1.0","User-Agent":"Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101\n\tThunderbird/91.4.1","Content-Language":"en-US","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>,\n\tNicolas Dufresne <nicolas.dufresne@collabora.com>","References":"<20220623232210.18742-1-laurent.pinchart@ideasonboard.com>\n\t<20220623232210.18742-6-laurent.pinchart@ideasonboard.com>\n\t<8e244a88a274977de90e6b18b24700b30b7f1655.camel@collabora.com>\n\t<YrotuV8ZpHCTgv2H@pendragon.ideasonboard.com>","In-Reply-To":"<YrotuV8ZpHCTgv2H@pendragon.ideasonboard.com>","Content-Type":"text/plain; charset=UTF-8; format=flowed","Content-Transfer-Encoding":"8bit","Subject":"Re: [libcamera-devel] [PATCH 05/13] gstreamer: Move timestamp\n\tcalculation out of pad loop","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","From":"Umang Jain via libcamera-devel <libcamera-devel@lists.libcamera.org>","Reply-To":"Umang Jain <umang.jain@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org,\n\tVedant Paranjape <vedantparanjape160201@gmail.com>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]