From 3fe66378aa82aed404389c986c77b93815c421b7 Mon Sep 17 00:00:00 2001 From: Kamil Trzcinski Date: Wed, 6 Apr 2022 13:22:49 +0200 Subject: [PATCH] Improve clocks support --- http/http_h264.c | 2 +- http/http_jpeg.c | 4 ++-- hw/buffer_lock.c | 11 ++++++----- hw/buffer_lock.h | 3 ++- hw/links.c | 2 +- hw/links.h | 2 ++ hw/v4l2.c | 16 ++++++++++++++-- hw/v4l2.h | 1 + 8 files changed, 29 insertions(+), 12 deletions(-) diff --git a/http/http_h264.c b/http/http_h264.c index 37384e3..4dae763 100644 --- a/http/http_h264.c +++ b/http/http_h264.c @@ -35,7 +35,7 @@ void http_video(http_worker_t *worker, FILE *stream) buffer_lock_use(&http_h264, 1); while (!feof(stream)) { - buffer_t *buf = buffer_lock_get(&http_h264, 3, &counter); + buffer_t *buf = buffer_lock_get(&http_h264, 0, &counter); if (!buf) { goto error; } diff --git a/http/http_jpeg.c b/http/http_jpeg.c index d88d3d9..d3daa09 100644 --- a/http/http_jpeg.c +++ b/http/http_jpeg.c @@ -43,7 +43,7 @@ void http_snapshot(http_worker_t *worker, FILE *stream) { int counter = 0; buffer_lock_use(&http_jpeg, 1); - buffer_t *buf = buffer_lock_get(&http_jpeg, 1, &counter); + buffer_t *buf = buffer_lock_get(&http_jpeg, 0, &counter); if (!buf) { http_404_header(worker, stream); @@ -68,7 +68,7 @@ void http_stream(http_worker_t *worker, FILE *stream) buffer_lock_use(&http_jpeg, 1); while (!feof(stream)) { - buffer_t *buf = buffer_lock_get(&http_jpeg, 3, &counter); + buffer_t *buf = buffer_lock_get(&http_jpeg, 0, &counter); if (!buf) { fprintf(stream, STREAM_ERROR, -1, "No frames."); diff --git a/hw/buffer_lock.c b/hw/buffer_lock.c index 090bbe6..b5e9479 100644 --- a/hw/buffer_lock.c +++ b/hw/buffer_lock.c @@ -49,14 +49,15 @@ void buffer_lock_capture(buffer_lock_t *buf_lock, buffer_t *buf) pthread_mutex_unlock(&buf_lock->lock); } -buffer_t *buffer_lock_get(buffer_lock_t *buf_lock, int timeout_s, int *counter) +buffer_t *buffer_lock_get(buffer_lock_t *buf_lock, int timeout_ms, int *counter) { buffer_t *buf = NULL; - struct timeval now; struct timespec timeout; - gettimeofday(&now, NULL); - timeout.tv_nsec = now.tv_usec; - timeout.tv_sec = now.tv_sec + timeout_s; + + if(!timeout_ms) + timeout_ms = DEFAULT_BUFFER_LOCK_GET_TIMEOUT; + + get_time_us(CLOCK_REALTIME, &timeout, NULL, timeout_ms * 1000LL * 1000LL); pthread_mutex_lock(&buf_lock->lock); if (*counter == buf_lock->counter || !buf_lock->buf) { diff --git a/hw/buffer_lock.h b/hw/buffer_lock.h index 68cde8b..abc11a1 100644 --- a/hw/buffer_lock.h +++ b/hw/buffer_lock.h @@ -16,6 +16,7 @@ typedef struct buffer_lock_s { } buffer_lock_t; #define DEFAULT_BUFFER_LOCK_TIMEOUT 16 // ~60fps +#define DEFAULT_BUFFER_LOCK_GET_TIMEOUT 2000 // 2s #define DEFINE_BUFFER_LOCK(_name, _timeout_ms) static buffer_lock_t _name = { \ .name = #_name, \ @@ -25,7 +26,7 @@ typedef struct buffer_lock_s { }; void buffer_lock_capture(buffer_lock_t *buf_lock, buffer_t *buf); -buffer_t *buffer_lock_get(buffer_lock_t *buf_lock, int timeout_s, int *counter); +buffer_t *buffer_lock_get(buffer_lock_t *buf_lock, int timeout_ms, int *counter); bool buffer_lock_needs_buffer(buffer_lock_t *buf_lock); void buffer_lock_use(buffer_lock_t *buf_lock, int ref); bool buffer_lock_is_used(buffer_lock_t *buf_lock); diff --git a/hw/links.c b/hw/links.c index 666b0d3..231fe8c 100644 --- a/hw/links.c +++ b/hw/links.c @@ -220,7 +220,7 @@ int links_loop(link_t *all_links, bool *running) } while(*running) { - if (links_step(all_links, 1000) < 0) { + if (links_step(all_links, LINKS_LOOP_INTERVAL) < 0) { links_stream(all_links, false); return -1; } diff --git a/hw/links.h b/hw/links.h index b658b4c..a064311 100644 --- a/hw/links.h +++ b/hw/links.h @@ -2,6 +2,8 @@ #include "v4l2.h" +#define LINKS_LOOP_INTERVAL 100 + typedef struct buffer_s buffer_t; typedef struct buffer_list_s buffer_list_t; diff --git a/hw/v4l2.c b/hw/v4l2.c index 964b6f5..b50dabe 100644 --- a/hw/v4l2.c +++ b/hw/v4l2.c @@ -80,10 +80,17 @@ int shrink_to_block(int size, int block) return size / block * block; } -uint64_t get_monotonic_time_us(struct timespec *ts, struct timeval *tv) +uint64_t get_time_us(clockid_t clock, struct timespec *ts, struct timeval *tv, int64_t delays_us) { struct timespec now; - clock_gettime(CLOCK_MONOTONIC, &now); + clock_gettime(clock, &now); + + if (delays_us > 0) { + now.tv_nsec += delays_us * 1000LL; + now.tv_sec += now.tv_nsec / (1000LL * 1000LL * 1000LL); + now.tv_nsec %= 1000LL * 1000LL * 1000LL; + } + if (ts) { *ts = now; } @@ -93,3 +100,8 @@ uint64_t get_monotonic_time_us(struct timespec *ts, struct timeval *tv) } return now.tv_sec * 1000000LL + now.tv_nsec / 1000; } + +uint64_t get_monotonic_time_us(struct timespec *ts, struct timeval *tv) +{ + return get_time_us(CLOCK_MONOTONIC, ts, tv, 0); +} diff --git a/hw/v4l2.h b/hw/v4l2.h index c4b883e..041732e 100644 --- a/hw/v4l2.h +++ b/hw/v4l2.h @@ -34,6 +34,7 @@ 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); uint64_t get_monotonic_time_us(struct timespec *ts, struct timeval *tv); +uint64_t get_time_us(clockid_t clock, struct timespec *ts, struct timeval *tv, int64_t delays_us); int shrink_to_block(int size, int block); #define E_XIOCTL(dev, _fd, _request, _value, _msg, ...) do { \