more flexible --soft-fps

This commit is contained in:
Devaev Maxim 2018-11-07 21:04:21 +03:00
parent 020482a05a
commit 3b86e64222
4 changed files with 17 additions and 10 deletions

View File

@ -84,7 +84,7 @@ struct device_t *device_init() {
dev->standard = V4L2_STD_UNKNOWN;
dev->n_buffers = max_u(sysconf(_SC_NPROCESSORS_ONLN), 1) + 1;
dev->n_workers = dev->n_buffers;
dev->soft_fps = 30;
dev->soft_fps = 0;
dev->timeout = 1;
dev->error_delay = 1;
dev->run = run;

View File

@ -118,7 +118,11 @@ int http_server_listen(struct http_server_t *server) {
struct timeval refresh_interval;
refresh_interval.tv_sec = 0;
refresh_interval.tv_usec = 1000000 / (server->run->stream->dev->soft_fps * 2);
if (server->run->stream->dev->soft_fps > 0) {
refresh_interval.tv_usec = 1000000 / (server->run->stream->dev->soft_fps * 2);
} else {
refresh_interval.tv_usec = 16000; // ~60fps
}
assert((server->run->refresh = event_new(server->run->base, -1, EV_PERSIST, _http_exposed_refresh, server)));
assert(!event_add(server->run->refresh, &refresh_interval));

View File

@ -106,7 +106,7 @@ static void _help(struct device_t *dev, struct encoder_t *encoder, struct http_s
printf(" Available: %s; default: YUYV.\n\n", FORMATS_STR);
printf(" -a|--tv-standard <std> -- Force TV standard.\n");
printf(" Available: %s; default: disabled.\n\n", STANDARDS_STR);
printf(" -m|--soft-fps <N> -- Soft FPS limit; default: %u.\n\n", dev->soft_fps);
printf(" -m|--soft-fps <N> -- Soft FPS limit; default: disabled.\n\n");
printf(" -e|--every-frame <N> -- Drop all input frames except specified. Default: disabled.\n\n");
printf(" -z|--min-frame-size <N> -- Drop frames smaller then this limit.\n");
printf(" Useful if the device produces small-sized garbage frames.\n\n");
@ -180,7 +180,7 @@ static int _parse_options(int argc, char *argv[], struct device_t *dev, struct e
case 'f': OPT_PARSE(dev->format, device_parse_format, FORMAT_UNKNOWN, "pixel format");
# pragma GCC diagnostic pop
case 'a': OPT_PARSE(dev->standard, device_parse_standard, STANDARD_UNKNOWN, "TV standard");
case 'm': OPT_UNSIGNED(dev->soft_fps, "--soft-fps", 1, 30);
case 'm': OPT_UNSIGNED(dev->soft_fps, "--soft-fps", 0, 30);
case 'e': OPT_UNSIGNED(dev->every_frame, "--every-frame", 1, 30);
case 'z': OPT_UNSIGNED(dev->min_frame_size, "--min-frame-size", 0, 8192);
case 't': OPT_SET(dev->dv_timings, true);

View File

@ -321,25 +321,28 @@ static void _stream_expose_picture(struct stream_t *stream, unsigned buf_index)
}
static long double _stream_get_fluency_delay(struct device_t *dev, struct workers_pool_t *pool) {
long double comp_time = 0;
long double sum_comp_time = 0;
long double avg_comp_time;
long double min_delay;
long double soft_delay;
for (unsigned number = 0; number < dev->n_workers; ++number) {
A_PTHREAD_M_LOCK(&pool->workers[number].last_comp_time_mutex);
if (pool->workers[number].last_comp_time > 0) {
comp_time += pool->workers[number].last_comp_time;
sum_comp_time += pool->workers[number].last_comp_time;
}
A_PTHREAD_M_UNLOCK(&pool->workers[number].last_comp_time_mutex);
}
comp_time = comp_time / dev->n_workers; // Среднее время работы воркеров
avg_comp_time = sum_comp_time / dev->n_workers; // Среднее время работы воркеров
min_delay = comp_time / dev->n_workers; // Минимальное время работы размазывается на N воркеров
soft_delay = ((long double)1) / dev->soft_fps; // Искусственное время задержки на основе желаемого FPS
min_delay = avg_comp_time / dev->n_workers; // Среднее время работы размазывается на N воркеров
if (min_delay > 0) {
if (dev->soft_fps > 0 && min_delay > 0) {
// Искусственное время задержки на основе желаемого FPS, если включен --soft-fps
soft_delay = ((long double)1) / dev->soft_fps - sum_comp_time;
return (min_delay > soft_delay ? min_delay : soft_delay);
}
return min_delay;
}