Camera RCE timestamp

hello,The camera timestamp is unstable, the specific data is as follows
The current camera basic frame rate is 30.01.



The camera usually has an interval of 33322us or 33323us, but there may be longer or shorter intervals. For example, 33327 or 33318 us.
Long-term accumulated offset will have a particularly large impact on our fusion algorithm because we do not know the exact time when the camera receives the sof.
Please take a look, we are in a hurry

Hi,

For the camera basic functionality first needs to check the device and driver configuration.
You can reference to below program guide for the detailed information of device tree and driver implementation.
https://docs.nvidia.com/jetson/archives/r36.3/DeveloperGuide/SD/CameraDevelopment/SensorSoftwareDriverProgramming.html?highlight=programing#sensor-software-driver-programming

Please refer to Applications Using V4L2 IOCTL Directly by using V4L2 IOCTL to verify basic camera functionality.
https://docs.nvidia.com/jetson/archives/r36.3/DeveloperGuide/SD/CameraDevelopment/SensorSoftwareDriverProgramming.html?highlight=programing#to-run-a-v4l2-ctl-test

Once confirm the configure and still failed below link help to get log and some information and some tips for debug.
https://elinux.org/Jetson/l4t/Camera_BringUp#Steps_to_enable_more_debug_messages

Thanks!

Hi carolyuu, the problem I’m having is with the accuracy of the RCE timestamp, not with basic usage.

Please check the timestamp from the vi5_fops.c

Hello, I confirmed it in the .c file you mentioned

Blockquote
wake_up_interruptible(&chan->start_wait);
/* Read SOF from capture descriptor /
ts = ns_to_timespec64((s64)descr->status.sof_timestamp);
trace_tegra_channel_capture_frame(“sof”, &ts);
vb->vb2_buf.timestamp = descr->status.sof_timestamp;
if (frame_err)
buf->vb2_state = VB2_BUF_STATE_ERROR;
else
buf->vb2_state = VB2_BUF_STATE_DONE;
/
Read EOF from capture descriptor */
ts = ns_to_timespec64((s64)descr->status.eof_timestamp);
trace_tegra_channel_capture_frame(“eof”, &ts);

I have currently eliminated the camera instability using an oscilloscope.

  1. When the input signal is 10 frames of camera image data, the time deviation of each frame is about plus or minus 15us.

  2. When the input signal is 30 frames, the deviation of each frame is about 5us. The above deviations are all generated randomly.

So which part records the timestamp of sof or eof? Can we modify it to tsc timestamp (our system will be connected to gptp calibration)? Secondly, I have another doubt. The interrupt priority of mipi related modules is not enough. Can we users bind the core or increase the interrupt priority by ourselves?

Hi ShaneCCC.
Do you have any ideas?

The timestamp is the RCE(RTCPU) system time. I don’t think you have source to modify it. But you can override it from the vi5_fops.c if you need.

Another way is put the put the timestamp in the sensor embedded data.

Thanks

Since the timestamp of v4l2 is us, the rec timestamp will be compressed. To avoid compression, multiply the timestamp by 1000.The purpose is to get a ns timestamp

Blockquote
wake_up_interruptible(&chan->start_wait);
/* Read SOF from capture descriptor */
ts = ns_to_timespec64((s64)descr->status.sof_timestamp);
trace_tegra_channel_capture_frame(“sof”, &ts);
vb->vb2_buf.timestamp = (descr->status.sof_timestamp) * 1000;

I’m currently testing 3 cameras (different types, all at 30fps) at the same time, and I found that the timestamps of the cameras are at the same time, but the frequency is accelerated. You can clearly see the change in the time interval of the 3 cameras around 2079532561748ns.


To sum up, I think it is because the accuracy of orin collecting sof has changed unknowably at this moment, which eventually leads to this result.

You can take a look at my latest comment. I think it is due to some reasons of rtcpu that the timestamp is inaccurate. Secondly, the camera cannot embed time information, it can only embed some parameters such as exposure and frame number. So the sof and eof timestamps are very important to me.

Hello,Do you have no other method here? Because the test shows that there is indeed jitter.

https://docs.nvidia.com/drive/active/5.0.10.3L/nvvib_docs/index.html#page/NVIDIA%2520DRIVE%2520Linux%2520SDK%2520Development%2520Guide%2FAppendix%2FTimeSynchronization_DPX2.html%23wwpID0ENHA
I read a post that said converting the camera’s timestamp into ptp format would be more accurate.

Try get the time interval after wait_for_completion_timeout() in the vi_capture_status() that RTCPU report get the SOF from the sensor instead of check timestamp.

Blockquot
int vi_capture_status(
struct tegra_vi_channel *chan,
int32_t timeout_ms)
{
struct vi_capture *capture = chan->capture_data;
int ret = 0;
nv_camera_log(chan->ndev,
__arch_counter_get_cntvct(),
NVHOST_CAMERA_VI_CAPTURE_STATUS);
if (capture == NULL) {
dev_err(chan->dev,
“%s: vi capture uninitialized\n”, func);
return -ENODEV;
}
if (capture->channel_id == CAPTURE_CHANNEL_INVALID_ID) {
dev_err(chan->dev,
“%s: setup channel first\n”, func);
return -ENODEV;
}
dev_dbg(chan->dev, “%s: waiting for status, timeout:%d ms\n”,
func, timeout_ms);
if (timeout_ms < 0) {
wait_for_completion(&capture->capture_resp);
} else {
ret = wait_for_completion_timeout(
&capture->capture_resp,
msecs_to_jiffies(timeout_ms));
if (ret == 0) {
dev_dbg(chan->dev,
“capture status timed out\n”);
return -ETIMEDOUT;
}
}

Are you referring to this code? If you record the timestamp here, the timestamp will be affected by the system scheduling and the difference will be huge.

Try boost the clocks to try.

sudo jetson_clocks
sudo su
echo 1 > /sys/kernel/debug/bpmp/debug/clk/vi/mrq_rate_locked
echo 1 > /sys/kernel/debug/bpmp/debug/clk/isp/mrq_rate_locked
echo 1 > /sys/kernel/debug/bpmp/debug/clk/nvcsi/mrq_rate_locked
echo 1 > /sys/kernel/debug/bpmp/debug/clk/emc/mrq_rate_locked
cat /sys/kernel/debug/bpmp/debug/clk/vi/max_rate |tee /sys/kernel/debug/bpmp/debug/clk/vi/rate
cat /sys/kernel/debug/bpmp/debug/clk/isp/max_rate | tee  /sys/kernel/debug/bpmp/debug/clk/isp/rate
cat /sys/kernel/debug/bpmp/debug/clk/nvcsi/max_rate | tee /sys/kernel/debug/bpmp/debug/clk/nvcsi/rate
cat /sys/kernel/debug/bpmp/debug/clk/emc/max_rate | tee /sys/kernel/debug/bpmp/debug/clk/emc/rate

I have tried it and the problem is the same. Can you check it locally?

How does rtcpu timestamp the camera? In an interrupt? Or in a thread?

Hi,shaneCCC
Here are two logs, I hope they will be helpful in analyzing the problem
last_1_5min.txt (244.1 KB)
traceAndApp.log (40.9 KB)

@ShaneCCC
I found a problem while calculating the timestamp, and I’ll take the attached log as an example.
Frame start
[2024-11-19 15:11:36.181] [video6dbg] [debug] 81720766354
Frame end
[2024-11-19 15:13:15.319] [video6dbg] [debug] 81819912945
The first part is the timestamp of the application layer, and we can calculate an interval
15:13:15.319 - 15:11:36.181 = 1:39.138 = 99.138s
81819912945 – 81720766354 = 99.146591s
The result is an incomprehensible result, which is 8ms faster. So I captured a large section of time, nearly two hours,

Frame start
[2024-11-19 15:00:00.017] [video6dbg] [debug] 81024525215,
Frame end
[2024-11-19 17:00:00.020] [video6dbg] [debug] 88224690900
17:00:00.020 - 15:00:00.017 = 2:0:0.003 = 7200.003s
88224690900 – 81024525215 = 7200.165685
Nearly 165ms faster

I don’t understand the experiment.
How to figurate out the 8ms and165ms?

When running the program, only one 640x512 camera is working. There are no other programs.

In user mode, I have a program that reads camera data based on v4l2. The program will record the SOF timestamp in the v4l2buffer of the current image (that is, the SOF timestamp of RCE) and also print a system timestamp synchronized by PTP.
The program runs for two hours and prints the head and tail of the log.

Frame start
utc time ---------------------------------------------------v4l2 timestamp
[2024-11-19 15:00:00.017] [video6dbg] [debug] 81024525215,

Frame end
utc time ---------------------------------------------------v4l2 timestamp
[2024-11-19 17:00:00.020] [video6dbg] [debug] 88224690900

utc end time - utc start time
17:00:00.020 - 15:00:00.017 = 2:0:0.003 = 7200.003s
v4l2 end time - v4l2 start time
88224690900 – 81024525215 = 7200.165685

Get v4l2 time
void sample_code()
{
-----------------
ret = ioctl(fd, VIDIOC_DQBUF, &readbuf);
if(ret < 0) {
break;
}
log(“%d-%d-%d %d:%d:%d.%ld\n”, 1900+t->tm_year, 1+t->tm_mon, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec, tv.tv_usec);
log("%d%d\n"readbuf->timestamp.tv_sec, readbuf->timestamp.tv_usec);
ret = ioctl(fd, VIDIOC_QBUF, &readbuf);
if(ret < 0) {
break;
}
-----------------
}