From a7b298889a2184f96d5b4f89f17b57e80165f119 Mon Sep 17 00:00:00 2001 From: Julian Stirling Date: Sat, 18 Jul 2026 13:38:26 -0300 Subject: [PATCH 1/2] Re-calculate time offset from CPU time to real time on each frame --- .../things/camera/picamera.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/openflexure_microscope_server/things/camera/picamera.py b/src/openflexure_microscope_server/things/camera/picamera.py index f3f0ff1d..b8de8442 100644 --- a/src/openflexure_microscope_server/things/camera/picamera.py +++ b/src/openflexure_microscope_server/things/camera/picamera.py @@ -86,8 +86,6 @@ class PicameraStreamOutput(Output): Output.__init__(self) self.stream = stream self.encoder = encoder - # The difference between unix time and the CPU time - self.cpu_dt = time.time() - time.monotonic() def outputframe( self, @@ -101,10 +99,13 @@ class PicameraStreamOutput(Output): if timestamp is None or self.encoder.firsttimestamp is None: frame_timestamp = None else: + # The difference between unix time and the CPU time. Do not cache this + # number as it can change with clock slew or other time adjustments. + cpu_dt = time.time() - time.monotonic() # Reconstruct full CPU time of the frame in us timestamp += self.encoder.firsttimestamp # Convert to datetime - frame_timestamp = datetime.fromtimestamp(self.cpu_dt + timestamp / 1e6) + frame_timestamp = datetime.fromtimestamp(cpu_dt + timestamp / 1e6) self.stream.add_frame(frame, frame_timestamp) From faa20801ffc53d21f3596a0c0d2e71f18e98eaa1 Mon Sep 17 00:00:00 2001 From: Julian Stirling Date: Mon, 20 Jul 2026 14:29:32 +0100 Subject: [PATCH 2/2] update picamera coverage zip --- picamera_coverage.zip | Bin 54038 -> 54038 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/picamera_coverage.zip b/picamera_coverage.zip index 95a69c4b118181ac436d21f7a9bf463370b436a2..7133573c9186706c5374a1477e0e8d3577a8ccc9 100644 GIT binary patch delta 315 zcmbQXjCtBJW}yIYW)=|!5HK$O62mijY1~F3zFsCdhRI63hV@^$O@Bw5%{#c6ub@e? z?}FHaSsDKQ-@a#m`2Mm!orB^1UOg*`_z%|@K5V~N?#KTmnqkVX_xIaNe{8XJi2k*= zVXiC#ivx2*B0Ix3V}(C~+y~g$)-c|A!1kd2AOiy%$WjJo1_lWRwgP5@AGhMS>BfKD z`1IakGX@3*gGMe6*3FlCGn_a;4m%QCwRf`9g^LwmWF8-DMm>t uDTb-3MrLM-<_4x|=Emm6NvY=MDN3~g-i%Bl%%}k}x%ZL(~vDRkxl delta 315 zcmbQXjCtBJW}yIYW)=|!5XcFA74wg&OJt)EUoVrL_hhAB!}_cGv;OKzpMMa^ZgG&u zJ%hWzcgueF-@i?N{Qk1vn5E%+oVaX{enmFJkLdT-%h^BaGI;&{{{FC4%`LeFx_{#i zoa19)TEKW<12e;KNr8VWSQD6;uQB8mFn`#ez`(!^vb2Gbfq{pCc?Y9J&0GE3)7JmE zQS?4hnt_2qqLGV(b@Qd(3?~kd!(xNV3MM;UxTuk4oMw=gW|(4@mX?^3XlP-UVw7f_ zYHpg8lwxj?W@=_^VQiXYnq)Nj!UdbjYkfo~_gp+|XKb8knv#-eVP=w=oMe_{V3?9< tY+;^iX>MYfm}qX2l$4y7W|op-s#F``&B!Fej2a-5doNia9C7xNCjk4Ha?Ah#