From 90b7a5600fa239bf3350e96698d676c3fd98d510 Mon Sep 17 00:00:00 2001 From: Devaev Maxim Date: Sat, 22 Aug 2020 16:15:26 +0300 Subject: [PATCH] Issue #24: disable software framedrop if hw_fps == desired_fps --- src/device.c | 19 ++++++++++++++++--- src/device.h | 1 + src/stream.c | 15 +++++++++++---- 3 files changed, 28 insertions(+), 7 deletions(-) diff --git a/src/device.c b/src/device.c index ecc9cdc..b6e397b 100644 --- a/src/device.c +++ b/src/device.c @@ -501,6 +501,8 @@ static int _device_open_format(struct device_t *dev) { static void _device_open_hw_fps(struct device_t *dev) { struct v4l2_streamparm setfps; + dev->run->hw_fps = 0; + MEMSET_ZERO(setfps); setfps.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; @@ -531,10 +533,21 @@ static void _device_open_hw_fps(struct device_t *dev) { return; } - if (dev->desired_fps != SETFPS_TPF(denominator)) { - LOG_INFO("Using HW FPS: %u -> %u (coerced)", dev->desired_fps, SETFPS_TPF(denominator)); + if (SETFPS_TPF(numerator) != 1) { + LOG_ERROR("Invalid HW FPS numerator: %u != 1", SETFPS_TPF(numerator)); + return; + } + + if (SETFPS_TPF(denominator) == 0) { // Не знаю, бывает ли так, но пускай на всякий случай + LOG_ERROR("Invalid HW FPS denominator: 0"); + return; + } + + dev->run->hw_fps = SETFPS_TPF(denominator); + if (dev->desired_fps != dev->run->hw_fps) { + LOG_INFO("Using HW FPS: %u -> %u (coerced)", dev->desired_fps, dev->run->hw_fps); } else { - LOG_INFO("Using HW FPS: %u", dev->desired_fps); + LOG_INFO("Using HW FPS: %u", dev->run->hw_fps); } # undef SETFPS_TPF diff --git a/src/device.h b/src/device.h index e564bbb..28df5ad 100644 --- a/src/device.h +++ b/src/device.h @@ -60,6 +60,7 @@ struct device_runtime_t { unsigned width; unsigned height; unsigned format; + unsigned hw_fps; size_t raw_size; unsigned n_buffers; unsigned n_workers; diff --git a/src/stream.c b/src/stream.c index b783397..06b6ea7 100644 --- a/src/stream.c +++ b/src/stream.c @@ -350,11 +350,14 @@ static void _stream_expose_picture(struct stream_t *stream, unsigned buf_index, static struct _workers_pool_t *_workers_pool_init(struct stream_t *stream) { struct _workers_pool_t *pool; - LOG_INFO("Creating pool with %u workers ...", stream->dev->run->n_workers); +# define DEV(_next) stream->dev->_next +# define RUN(_next) stream->dev->run->_next + + LOG_INFO("Creating pool with %u workers ...", RUN(n_workers)); A_CALLOC(pool, 1); - pool->n_workers = stream->dev->run->n_workers; + pool->n_workers = RUN(n_workers); A_CALLOC(pool->workers, pool->n_workers); A_MUTEX_INIT(&pool->free_workers_mutex); @@ -362,10 +365,13 @@ static struct _workers_pool_t *_workers_pool_init(struct stream_t *stream) { atomic_init(&pool->workers_stop, false); - if (stream->dev->desired_fps > 0) { - pool->desired_frames_interval = (long double)1 / stream->dev->desired_fps; + if (DEV(desired_fps) > 0 && (DEV(desired_fps) < RUN(hw_fps) || RUN(hw_fps) == 0)) { + pool->desired_frames_interval = (long double)1 / DEV(desired_fps); } +# undef RUN +# undef DEV + for (unsigned number = 0; number < pool->n_workers; ++number) { # define WORKER(_next) pool->workers[number]._next @@ -557,6 +563,7 @@ static long double _workers_pool_get_fluency_delay(struct _workers_pool_t *pool, if (pool->desired_frames_interval > 0 && min_delay > 0 && pool->desired_frames_interval > min_delay) { // Искусственное время задержки на основе желаемого FPS, если включен --desired-fps + // и аппаратный fps не попадает точно в желаемое значение return pool->desired_frames_interval; } return min_delay;