From c75bd39e6a9c9f6cb98de48f681b86285570858b Mon Sep 17 00:00:00 2001 From: Devaev Maxim Date: Sun, 10 Jan 2021 19:21:29 +0300 Subject: [PATCH] using hashes to enumerate frames in memsink --- src/libs/memsink.c | 6 +++--- src/libs/memsink.h | 4 ++-- src/libs/tools.h | 49 +++++++++++++++++++++++++++++++++------------- 3 files changed, 40 insertions(+), 19 deletions(-) diff --git a/src/libs/memsink.c b/src/libs/memsink.c index 4d739bb..27a8295 100644 --- a/src/libs/memsink.c +++ b/src/libs/memsink.c @@ -102,7 +102,7 @@ int memsink_server_put(memsink_s *sink, const frame_s *frame) { LOG_VERBOSE("%s sink: >>>>> Exposing new frame ...", sink->name); # define COPY(_field) sink->mem->_field = frame->_field - sink->mem->seq += 1; + sink->mem->id = get_now_id(); COPY(used); COPY(width); COPY(height); @@ -145,11 +145,11 @@ int memsink_client_get(memsink_s *sink, frame_s *frame) { // cppcheck-suppress u bool same = false; - if (sink->client_seq == sink->mem->seq) { + if (sink->mem->id == sink->consumed_id) { same = true; } else { # define COPY(_field) frame->_field = sink->mem->_field - sink->client_seq = sink->mem->seq; + sink->consumed_id = sink->mem->id; COPY(width); COPY(height); COPY(format); diff --git a/src/libs/memsink.h b/src/libs/memsink.h index 2576c75..8dca2ef 100644 --- a/src/libs/memsink.h +++ b/src/libs/memsink.h @@ -46,7 +46,7 @@ typedef struct { - uint64_t seq; + uint64_t id; size_t used; unsigned width; unsigned height; @@ -68,7 +68,7 @@ typedef struct { int fd; memsink_shared_s *mem; - uint64_t client_seq; + uint64_t consumed_id; // Client only } memsink_s; diff --git a/src/libs/tools.h b/src/libs/tools.h index d4d3d4f..946994b 100644 --- a/src/libs/tools.h +++ b/src/libs/tools.h @@ -23,6 +23,7 @@ #pragma once #include +#include #include #include #include @@ -62,12 +63,23 @@ INLINE long long floor_ms(long double now) { return (long long)now - (now < (long long)now); // floor() } -INLINE void get_now(clockid_t clk_id, time_t *sec, long *msec) { - struct timespec spec; +INLINE uint32_t triple_u32(uint32_t x) { + // https://nullprogram.com/blog/2018/07/31/ + x ^= x >> 17; + x *= UINT32_C(0xED5AD4BB); + x ^= x >> 11; + x *= UINT32_C(0xAC4C1B51); + x ^= x >> 15; + x *= UINT32_C(0x31848BAB); + x ^= x >> 14; + return x; +} - assert(!clock_gettime(clk_id, &spec)); - *sec = spec.tv_sec; - *msec = round(spec.tv_nsec / 1.0e6); +INLINE void get_now(clockid_t clk_id, time_t *sec, long *msec) { + struct timespec ts; + assert(!clock_gettime(clk_id, &ts)); + *sec = ts.tv_sec; + *msec = round(ts.tv_nsec / 1.0e6); if (*msec > 999) { *sec += 1; @@ -75,24 +87,33 @@ INLINE void get_now(clockid_t clk_id, time_t *sec, long *msec) { } } +#if defined(CLOCK_MONOTONIC_RAW) +# define X_CLOCK_MONOTONIC CLOCK_MONOTONIC_RAW +#elif defined(CLOCK_MONOTONIC_FAST) +# define X_CLOCK_MONOTONIC CLOCK_MONOTONIC_FAST +#else +# define X_CLOCK_MONOTONIC CLOCK_MONOTONIC +#endif + INLINE long double get_now_monotonic(void) { time_t sec; long msec; - -# if defined(CLOCK_MONOTONIC_RAW) - get_now(CLOCK_MONOTONIC_RAW, &sec, &msec); -# elif defined(CLOCK_MONOTONIC_FAST) - get_now(CLOCK_MONOTONIC_FAST, &sec, &msec); -# else - get_now(CLOCK_MONOTONIC, &sec, &msec); -# endif + get_now(X_CLOCK_MONOTONIC, &sec, &msec); return (long double)sec + ((long double)msec) / 1000; } +INLINE uint64_t get_now_id(void) { + struct timespec ts; + assert(!clock_gettime(X_CLOCK_MONOTONIC, &ts)); + uint64_t now = (uint64_t)(ts.tv_nsec / 1000) + (uint64_t)ts.tv_sec * 1000000; + return (uint64_t)triple_u32(now) | ((uint64_t)triple_u32(now + 12345) << 32); +} + +#undef X_CLOCK_MONOTONIC + INLINE long double get_now_real(void) { time_t sec; long msec; - get_now(CLOCK_REALTIME, &sec, &msec); return (long double)sec + ((long double)msec) / 1000; }