V4L2 API を使用して UVC デバイスからフレームを取得しています。フレームのタイムスタンプと現在のクロック時間の間のオフセットを計算して、露光時間を測定したいと考えています。これは私が使用しているコードです:
/* 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__);
}
で設定された 1 秒の露出時間に対してこれが返すものの例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
タイムスタンプとモノトニック クロックの間に奇妙な 30 秒のオフセットがありSRC_SOE
、1 秒の露出溶接が含まれています。V4L2/UVC タイムスタンプは、ktime_get_ts()
. 私が間違っていることは何ですか?
これは Linux 4.4 Gentoo システムで動作します。ウェブカメラは DMK21AU04.AS で、標準の UVC デバイスとして認識されています。