Where does v4l2_buffer->timestamp value starts cou

2020-06-23 07:44发布

I am trying to use v4l2_buffer's timestamp value (type timeval) to synchronize images captured from a UVC webcam to external events.

However the timestamp is not the same as the system time, or the up time, etc:

printf("image captured at %ld, %ld\n",
   buffer->timestamp.tv_sec, 
   buffer->timestamp.tv_usec);

struct timeval tv;
gettimeofday(&tv, 0);
printf("current time %ld, %ld\n", tv.tv_sec, tv.tv_usec);

Results in

image captured at 367746, 476270
current time 1335083395, 11225

My uptime is 10 days.

标签: v4l2
2条回答
做自己的国王
2楼-- · 2020-06-23 07:48

According to http://comments.gmane.org/gmane.linux.drivers.video-input-infrastructure/39892 some v4l2 drivers (including the UVC one) do not use the realtime clock (wall time) but rather a monotonic clock that counts from a not specified point in time. On Linux, this is the boot time (i.e. uptime), however (and I suspect this is the cause of your mismatch) only the time that the computer was actually running (i.e. this clock does not run when the computer is suspended).

查看更多
神经病院院长
3楼-- · 2020-06-23 08:14

If you have the OP's problem, and you're trying to get to epoch timestamps for each frame, you can use the code snippet below to do so.

#include <time.h>
#include <math.h>

//////////////////////
//setup: 

    long getEpochTimeShift(){
        struct timeval epochtime;
        struct timespec  vsTime;

        gettimeofday(&epochtime, NULL);
        clock_gettime(CLOCK_MONOTONIC, &vsTime);

        long uptime_ms = vsTime.tv_sec* 1000 + (long)  round( vsTime.tv_nsec/ 1000000.0);
        long epoch_ms =  epochtime.tv_sec * 1000  + (long) round( epochtime.tv_usec/1000.0);
        return epoch_ms - uptime_ms;
    }

    //stick this somewhere so that it runs once, on the startup of your capture process
    //  noting, if you hibernate a laptop, you might need to recalc this if you don't restart 
    //  the process after dehibernation
    long toEpochOffset_ms = getEpochTimeShift();


//////////////////////
//...somewhere in your capture loop: 

    struct v4l2_buffer buf;

    //make the v4l call to  xioctl(fd, VIDIOC_DQBUF, &buf)

    //then: 
    long temp_ms = 1000 * buf.timestamp.tv_sec + (long) round(  buf.timestamp.tv_usec / 1000.0);
    long epochTimeStamp_ms = temp_ms + toEpochOffset_ms ;

    printf( "the frame's timestamp in epoch ms is: %ld", epochTimeStamp_ms);
查看更多
登录 后发表回答