mirror of
https://github.com/pikvm/ustreamer.git
synced 2026-05-26 15:26:12 +00:00
approx_comp_time
This commit is contained in:
40
src/stream.c
40
src/stream.c
@@ -53,7 +53,6 @@ struct _worker_t {
|
|||||||
atomic_bool *proc_stop;
|
atomic_bool *proc_stop;
|
||||||
atomic_bool *workers_stop;
|
atomic_bool *workers_stop;
|
||||||
|
|
||||||
pthread_mutex_t last_comp_time_mutex;
|
|
||||||
long double last_comp_time;
|
long double last_comp_time;
|
||||||
|
|
||||||
pthread_mutex_t has_job_mutex;
|
pthread_mutex_t has_job_mutex;
|
||||||
@@ -81,6 +80,8 @@ struct _workers_pool_t {
|
|||||||
struct _worker_t *oldest_worker;
|
struct _worker_t *oldest_worker;
|
||||||
struct _worker_t *latest_worker;
|
struct _worker_t *latest_worker;
|
||||||
|
|
||||||
|
long double approx_comp_time;
|
||||||
|
|
||||||
pthread_mutex_t free_workers_mutex;
|
pthread_mutex_t free_workers_mutex;
|
||||||
unsigned free_workers;
|
unsigned free_workers;
|
||||||
pthread_cond_t free_workers_cond;
|
pthread_cond_t free_workers_cond;
|
||||||
@@ -102,7 +103,7 @@ static void *__worker_thread(void *v_worker);
|
|||||||
|
|
||||||
static struct _worker_t *_workers_pool_wait(struct _workers_pool_t *pool);
|
static struct _worker_t *_workers_pool_wait(struct _workers_pool_t *pool);
|
||||||
static void _workers_pool_assign(struct _workers_pool_t *pool, struct _worker_t *ready_worker, unsigned buf_index);
|
static void _workers_pool_assign(struct _workers_pool_t *pool, struct _worker_t *ready_worker, unsigned buf_index);
|
||||||
static long double _workers_pool_get_fluency_delay(struct _workers_pool_t *pool);
|
static long double _workers_pool_get_fluency_delay(struct _workers_pool_t *pool, struct _worker_t *ready_worker);
|
||||||
|
|
||||||
|
|
||||||
struct stream_t *stream_init(struct device_t *dev, struct encoder_t *encoder) {
|
struct stream_t *stream_init(struct device_t *dev, struct encoder_t *encoder) {
|
||||||
@@ -238,7 +239,7 @@ void stream_loop(struct stream_t *stream) {
|
|||||||
}
|
}
|
||||||
captured_fps_accum += 1;
|
captured_fps_accum += 1;
|
||||||
|
|
||||||
long double fluency_delay = _workers_pool_get_fluency_delay(pool);
|
long double fluency_delay = _workers_pool_get_fluency_delay(pool, ready_worker);
|
||||||
|
|
||||||
grab_after = now + fluency_delay;
|
grab_after = now + fluency_delay;
|
||||||
LOG_VERBOSE("Fluency: delay=%.03Lf, grab_after=%.03Lf", fluency_delay, grab_after);
|
LOG_VERBOSE("Fluency: delay=%.03Lf, grab_after=%.03Lf", fluency_delay, grab_after);
|
||||||
@@ -381,8 +382,6 @@ static struct _workers_pool_t *_workers_pool_init(struct stream_t *stream) {
|
|||||||
WORKER(proc_stop) = &stream->proc->stop;
|
WORKER(proc_stop) = &stream->proc->stop;
|
||||||
WORKER(workers_stop) = &pool->workers_stop;
|
WORKER(workers_stop) = &pool->workers_stop;
|
||||||
|
|
||||||
A_MUTEX_INIT(&WORKER(last_comp_time_mutex));
|
|
||||||
|
|
||||||
WORKER(free_workers_mutex) = &pool->free_workers_mutex;
|
WORKER(free_workers_mutex) = &pool->free_workers_mutex;
|
||||||
WORKER(free_workers) = &pool->free_workers;
|
WORKER(free_workers) = &pool->free_workers;
|
||||||
WORKER(free_workers_cond) = &pool->free_workers_cond;
|
WORKER(free_workers_cond) = &pool->free_workers_cond;
|
||||||
@@ -415,8 +414,6 @@ static void _workers_pool_destroy(struct _workers_pool_t *pool) {
|
|||||||
A_MUTEX_DESTROY(&WORKER(has_job_mutex));
|
A_MUTEX_DESTROY(&WORKER(has_job_mutex));
|
||||||
A_COND_DESTROY(&WORKER(has_job_cond));
|
A_COND_DESTROY(&WORKER(has_job_cond));
|
||||||
|
|
||||||
A_MUTEX_DESTROY(&WORKER(last_comp_time_mutex));
|
|
||||||
|
|
||||||
# undef WORKER
|
# undef WORKER
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -466,14 +463,10 @@ static void *__worker_thread(void *v_worker) {
|
|||||||
worker->job_start_time = PICTURE(encode_begin_time);
|
worker->job_start_time = PICTURE(encode_begin_time);
|
||||||
atomic_store(&worker->has_job, false);
|
atomic_store(&worker->has_job, false);
|
||||||
|
|
||||||
long double last_comp_time = PICTURE(encode_end_time) - worker->job_start_time;
|
worker->last_comp_time = PICTURE(encode_end_time) - worker->job_start_time;
|
||||||
|
|
||||||
A_MUTEX_LOCK(&worker->last_comp_time_mutex);
|
|
||||||
worker->last_comp_time = last_comp_time;
|
|
||||||
A_MUTEX_UNLOCK(&worker->last_comp_time_mutex);
|
|
||||||
|
|
||||||
LOG_VERBOSE("Compressed new JPEG: size=%zu, time=%0.3Lf, worker=%u, buffer=%u",
|
LOG_VERBOSE("Compressed new JPEG: size=%zu, time=%0.3Lf, worker=%u, buffer=%u",
|
||||||
PICTURE(used), last_comp_time, worker->number, worker->buf_index);
|
PICTURE(used), worker->last_comp_time, worker->number, worker->buf_index);
|
||||||
} else {
|
} else {
|
||||||
worker->job_failed = true;
|
worker->job_failed = true;
|
||||||
atomic_store(&worker->has_job, false);
|
atomic_store(&worker->has_job, false);
|
||||||
@@ -552,29 +545,22 @@ static void _workers_pool_assign(struct _workers_pool_t *pool, struct _worker_t
|
|||||||
LOG_DEBUG("Assigned new frame in buffer %u to worker %u", buf_index, ready_worker->number);
|
LOG_DEBUG("Assigned new frame in buffer %u to worker %u", buf_index, ready_worker->number);
|
||||||
}
|
}
|
||||||
|
|
||||||
static long double _workers_pool_get_fluency_delay(struct _workers_pool_t *pool) {
|
static long double _workers_pool_get_fluency_delay(struct _workers_pool_t *pool, struct _worker_t *ready_worker) {
|
||||||
long double sum_comp_time = 0;
|
long double approx_comp_time;
|
||||||
long double avg_comp_time;
|
|
||||||
long double min_delay;
|
long double min_delay;
|
||||||
|
|
||||||
for (unsigned number = 0; number < pool->n_workers; ++number) {
|
approx_comp_time = pool->approx_comp_time * 0.9 + ready_worker->last_comp_time * 0.1;
|
||||||
# define WORKER(_next) pool->workers[number]._next
|
|
||||||
|
|
||||||
A_MUTEX_LOCK(&WORKER(last_comp_time_mutex));
|
LOG_VERBOSE("Correcting approx_comp_time: %.3Lf -> %.3Lf (last_comp_time=%.3Lf)",
|
||||||
sum_comp_time += WORKER(last_comp_time);
|
pool->approx_comp_time, approx_comp_time, ready_worker->last_comp_time);
|
||||||
A_MUTEX_UNLOCK(&WORKER(last_comp_time_mutex));
|
|
||||||
|
|
||||||
# undef WORKER
|
pool->approx_comp_time = approx_comp_time;
|
||||||
}
|
|
||||||
|
|
||||||
avg_comp_time = sum_comp_time / pool->n_workers; // Среднее время работы воркеров
|
min_delay = pool->approx_comp_time / pool->n_workers; // Среднее время работы размазывается на N воркеров
|
||||||
|
|
||||||
min_delay = avg_comp_time / pool->n_workers; // Среднее время работы размазывается на N воркеров
|
|
||||||
|
|
||||||
if (pool->desired_frames_interval > 0 && min_delay > 0 && pool->desired_frames_interval > min_delay) {
|
if (pool->desired_frames_interval > 0 && min_delay > 0 && pool->desired_frames_interval > min_delay) {
|
||||||
// Искусственное время задержки на основе желаемого FPS, если включен --desired-fps
|
// Искусственное время задержки на основе желаемого FPS, если включен --desired-fps
|
||||||
return pool->desired_frames_interval;
|
return pool->desired_frames_interval;
|
||||||
}
|
}
|
||||||
|
|
||||||
return min_delay;
|
return min_delay;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user