diff --git a/cmd/camera.c b/cmd/camera.c index 011127e..98e95fa 100644 --- a/cmd/camera.c +++ b/cmd/camera.c @@ -56,6 +56,7 @@ camera_t *camera_open(camera_options_t *options) if (device_open_buffer_list(camera->camera, true, camera->options.width, camera->options.height, camera->options.format, 0, camera->options.nbufs, true) < 0) { goto error; } + camera->camera->capture_list->do_timestamps = true; switch (camera->camera->capture_list->fmt_format) { case V4L2_PIX_FMT_YUYV: diff --git a/hw/buffer.h b/hw/buffer.h index 482a346..a8d5d31 100644 --- a/hw/buffer.h +++ b/hw/buffer.h @@ -17,7 +17,6 @@ typedef struct buffer_s { int mmap_reflinks; struct buffer_s *mmap_source; bool enqueued; - uint64_t enqueued_time_us; } buffer_t; buffer_t *buffer_open(const char *name, struct buffer_list_s *buf_list, int buffer); diff --git a/hw/buffer_list.h b/hw/buffer_list.h index 05a44ed..ef01e24 100644 --- a/hw/buffer_list.h +++ b/hw/buffer_list.h @@ -16,6 +16,7 @@ typedef struct buffer_list_s { bool do_capture; unsigned fmt_width, fmt_height, fmt_format, fmt_bytesperline; + bool do_timestamps; bool streaming; int frames; diff --git a/hw/buffer_lock.c b/hw/buffer_lock.c index 0b4bffa..b391edd 100644 --- a/hw/buffer_lock.c +++ b/hw/buffer_lock.c @@ -44,7 +44,10 @@ void buffer_lock_capture(buffer_lock_t *buf_lock, buffer_t *buf) buf_lock->buf = buf; buf_lock->counter++; buf_lock->buf_time_us = get_monotonic_time_us(NULL, NULL); - E_LOG_DEBUG(buf_lock, "Captured buffer %s (refs=%d), frame=%d", dev_name(buf), buf ? buf->mmap_reflinks : 0, buf_lock->counter); + uint64_t captured_time_s = get_time_us(CLOCK_FROM_PARAMS, NULL, &buf->v4l2_buffer.timestamp, 0); + E_LOG_DEBUG(buf_lock, "Captured buffer %s (refs=%d), frame=%d, delay=%llus", + dev_name(buf), buf ? buf->mmap_reflinks : 0, buf_lock->counter, + buf_lock->buf_time_us - captured_time_s); pthread_cond_broadcast(&buf_lock->cond_wait); pthread_mutex_unlock(&buf_lock->lock); } diff --git a/hw/buffer_queue.c b/hw/buffer_queue.c index ee55987..6c88905 100644 --- a/hw/buffer_queue.c +++ b/hw/buffer_queue.c @@ -51,7 +51,11 @@ bool buffer_consumed(buffer_t *buf, const char *who) buf->length, buf->mmap_source ? buf->mmap_source->name : NULL, who); - buf->enqueued_time_us = get_monotonic_time_us(NULL, &buf->v4l2_buffer.timestamp); + + if (buf->buf_list->do_timestamps && !buf->buf_list->do_capture) { + get_monotonic_time_us(NULL, &buf->v4l2_buffer.timestamp); + } + E_XIOCTL(buf, buf->buf_list->device->fd, VIDIOC_QBUF, &buf->v4l2_buffer, "Can't queue buffer."); buf->enqueued = true; } @@ -116,6 +120,7 @@ int buffer_list_enqueue(buffer_list_t *buf_list, buffer_t *dma_buf) buf->v4l2_buffer.flags = 0; buf->v4l2_buffer.flags &= ~V4L2_BUF_FLAG_KEYFRAME; buf->v4l2_buffer.flags |= dma_buf->v4l2_buffer.flags & V4L2_BUF_FLAG_KEYFRAME; + buf->v4l2_buffer.timestamp = dma_buf->v4l2_buffer.timestamp; if (buf_list->do_mmap) { if (dma_buf->used > buf->length) { @@ -175,21 +180,25 @@ buffer_t *buffer_list_dequeue(buffer_list_t *buf_list) } buf->v4l2_buffer.flags = v4l2_buf.flags; + if (buf_list->do_timestamps && buf_list->do_capture) { + get_monotonic_time_us(NULL, &buf->v4l2_buffer.timestamp); + } else { + buf->v4l2_buffer.timestamp = v4l2_buf.timestamp; + } + if (buf->mmap_reflinks > 0) { E_LOG_PERROR(buf, "Buffer appears to be enqueued? (links=%d)", buf->mmap_reflinks); } buf->enqueued = false; buf->mmap_reflinks = 1; - uint64_t enqueued_time_us = get_monotonic_time_us(NULL, NULL) - buf->enqueued_time_us; - E_LOG_DEBUG(buf_list, "Grabbed mmap buffer=%u, bytes=%d, used=%d, frame=%d, linked=%s, enqueued_time_us=%lluus, flags=%08x", + E_LOG_DEBUG(buf_list, "Grabbed mmap buffer=%u, bytes=%d, used=%d, frame=%d, linked=%s, flags=%08x", buf->index, buf->length, buf->used, buf_list->frames, buf->mmap_source ? buf->mmap_source->name : NULL, - enqueued_time_us, buf->v4l2_buffer.flags); if (buf->mmap_source) { diff --git a/hw/v4l2.c b/hw/v4l2.c index a1ec14c..b68cdb8 100644 --- a/hw/v4l2.c +++ b/hw/v4l2.c @@ -83,7 +83,17 @@ int shrink_to_block(int size, int block) uint64_t get_time_us(clockid_t clock, struct timespec *ts, struct timeval *tv, int64_t delays_us) { struct timespec now; - clock_gettime(clock, &now); + + if (clock != CLOCK_FROM_PARAMS) { + clock_gettime(clock, &now); + } else if (ts) { + now = *ts; + } else if (tv) { + now.tv_sec = tv->tv_sec; + now.tv_nsec = tv->tv_usec * 1000; + } else { + return -1; + } if (delays_us > 0) { #define NS_IN_S (1000LL * 1000LL * 1000LL) diff --git a/hw/v4l2.h b/hw/v4l2.h index 041732e..d6d6681 100644 --- a/hw/v4l2.h +++ b/hw/v4l2.h @@ -30,6 +30,8 @@ typedef struct { char buf[10]; } fourcc_string; +#define CLOCK_FROM_PARAMS -1 + fourcc_string fourcc_to_string(unsigned format); unsigned fourcc_to_stride(unsigned width, unsigned format); int xioctl(const char *name, int fd, int request, void *arg);