Camera SOF timestamp in the future

Board: AGX Orin
L4T: 36.4.0

Hello, I have an issue, where the camera start of frame timestamp is in the future.

First, I get the camera SOF timestamp like so:

  IArgusCaptureMetadata *iArgusCaptureMetadata =
      interface_cast<IArgusCaptureMetadata>(frame);

  CaptureMetadata *metadata = iArgusCaptureMetadata->getMetadata();

  const Ext::ISensorTimestampTsc *iSensorTimestampTsc =
      interface_cast<const Ext::ISensorTimestampTsc>(metadata);

  uint64_t SENSOR_SOF_WITH_OFFSET = iSensorTimestampTsc->getSensorSofTimestampTsc()

Then I get the TSC offset like so:
(From: How to get the clock source offset_ns on Jetpack 6 - #4 by ShaneCCC)

uint64_t getTscOffsetNs() {
  unsigned long raw_nsec, tsc_ns;
  unsigned long cycles, frq;
  struct timespec tp;

  asm volatile("mrs %0, cntfrq_el0" : "=r"(frq));
  asm volatile("mrs %0, cntvct_el0" : "=r"(cycles));

  clock_gettime(CLOCK_MONOTONIC_RAW, &tp);

  tsc_ns = (cycles / frq) * 1000000000;
  raw_nsec = tp.tv_sec * 1000000000 + tp.tv_nsec;

  uint64_t offset_ns = llabs(tsc_ns-raw_nsec);

  return offset_ns;
}

Then I get the CLOCK_MONOTONIC_RAW & CLOCK_REALTIME and timestamps in ns:

  timespec t0;
  clock_gettime(CLOCK_MONOTONIC_RAW, &t0);
  uint64_t CLOCK_MONOTONIC_RAW = t0.tv_sec * 1e9l + t0.tv_nsec;

  timespec t1;
  clock_gettime(CLOCK_REALTIME, &t1);
  uint64_t CLOCK_REALTIME = t1.tv_sec * 1e9l + t1.tv_nsec;

Here are example values I got once:

Name Value
TSC_OFFSET 21000334912
SENSOR_SOF_WITH_OFFSET 996834000000
CLOCK_MONOTONIC_RAW 974999629152
CLOCK_REALTIME 1743608425941978927

I can then calculate the sensor SOF timestamp without offset:

SENSOR_SOF_MONO_RAW = SENSOR_SOF_WITH_OFFSET - TSC_OFFSET 
                    = 996834000000 - 21000334912
                    = 975833665088

But there’s a big problem now. The sensor SOF timestamp without the offset is bigger than the current time in CLOCK_MONOTONIC_RAW clock !

What is the issue? thanks!

Will take time to check it.

1 Like

I suspect that the following line has a critical accuracy issue

  tsc_ns = (cycles / frq) * 1000000000;
  • cycles / frq truncates
  • Dividing first then multiplying by a large number magnifies the truncation error

Hello ShaneCCC,

We’ve encountered the same issue, is there a solution available now?

Using

        tsc_ns = (cycles * 100 / (frq / 10000)) * 1000;
        raw_nsec = tp.tv_sec * 1000000000 + tp.tv_nsec;

mitigated the isue for us, but maybe theres a better solution.

2 Likes