2016-10-30 11 views
1

Ich nehme Frames von einem UVC-Gerät mit der V4L2-API. Ich möchte die Belichtungszeit messen, indem ich den Offset zwischen dem Timestamp des Frames und der aktuellen Uhrzeit berechne. Dies ist der Code Ich verwende:Systematischer Offset auf V4L2-Frames

/* Control code snipped */ 
struct v4l2_buffer buf = {0} 
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 
buf.memory = V4L2_MEMORY_MMAP; 
ioctl(fd, VIDIOC_DQBUF, &buf); 

switch(buf.flags & V4L2_BUF_FLAG_TIMESTAMP_MASK) 
{ 
    case V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC: 
    { 
     struct timespec uptime = {0}; 
     clock_gettime(CLOCK_MONOTONIC,&uptime); 

     float const secs = 
      (buf.timestamp.tv_sec - uptime.tv_sec) + 
      (buf.timestamp.tv_usec - uptime.tv_nsec/1000.0f)/1000.0f; 

     if(V4L2_BUF_FLAG_TSTAMP_SRC_SOE == (buf.flags & V4L2_BUF_FLAG_TSTAMP_SRC_MASK)) 
      printf("%s: frame exposure started %.03f seconds ago\n",__FUNCTION__,-secs); 
     else if(V4L2_BUF_FLAG_TSTAMP_SRC_EOF == (buf.flags & V4L2_BUF_FLAG_TSTAMP_SRC_MASK)) 
      printf("%s: frame finished capturing %.03f seconds ago\n",__FUNCTION__,-secs); 
     else printf("%s: unsupported timestamp in frame\n",__FUNCTION__); 

     break; 
    } 

    case V4L2_BUF_FLAG_TIMESTAMP_UNKNOWN: 
    case V4L2_BUF_FLAG_TIMESTAMP_COPY: 
    default: 
     printf("%s: no usable timestamp found in frame\n",__FUNCTION__); 
} 

Beispiele von dem, was diese zurückkehren für eine Belichtungszeit von 1 Sekunde Satz mit VIDIOC_S_CTRL:

read_frame: frame exposure started 28.892 seconds ago 
read_frame: frame exposure started 28.944 seconds ago 
read_frame: frame exposure started 28.895 seconds ago 
read_frame: frame exposure started 29.037 seconds ago 

Ich bin immer so seltsam 30-Sekunden-Versatz zwischen der SRC_SOE Zeitstempel und die monotone Uhr, wobei die 1-Sekunden-Belichtung eingeschweißt wird. Der V4L2/UVC-Zeitstempel soll aus dem Ergebnis ktime_get_ts() berechnet werden. Irgendeine Idee, was ich falsch mache?

Dies läuft auf einem Linux 4.4 Gentoo System. Die Webcam ist ein DMK21AU04.AS, das als Standard-UVC-Gerät erkannt wird.

Antwort

2

die Sache ist ...

1 s = 1000 ms,
1 ms = 1000US,
1 us = 1000ns.

so ...

es sollte wie sein ...

float const secs = 
     (buf.timestamp.tv_sec - uptime.tv_sec) + 
     (buf.timestamp.tv_usec - uptime.tv_nsec/1000.0f)/1000000.0f; 
+0

und danke @TallFurryMan, tatsächlich Ihr Code-Snippet stellt sich heraus, sehr hilfreich für mich sein ... Ich kann –

+0

Ich glaube, ich habe so lange auf die Antwort gestarrt, ohne es zu sehen :) – TallFurryMan