mirror of
https://github.com/pikvm/ustreamer.git
synced 2026-03-15 12:03:41 +00:00
refactoring
This commit is contained in:
@@ -21,9 +21,9 @@
|
|||||||
|
|
||||||
|
|
||||||
static long double _capture_get_fluency_delay(struct device_t *dev, struct workers_pool_t *pool);
|
static long double _capture_get_fluency_delay(struct device_t *dev, struct workers_pool_t *pool);
|
||||||
static int _capture_init_loop(struct device_t *dev, struct workers_pool_t *pool, sig_atomic_t *volatile global_stop);
|
static int _capture_init_loop(struct device_t *dev, struct workers_pool_t *pool);
|
||||||
static int _capture_init(struct device_t *dev, struct workers_pool_t *pool, sig_atomic_t *volatile global_stop);
|
static int _capture_init(struct device_t *dev, struct workers_pool_t *pool);
|
||||||
static void _capture_init_workers(struct device_t *dev, struct workers_pool_t *pool, sig_atomic_t *volatile global_stop);
|
static void _capture_init_workers(struct device_t *dev, struct workers_pool_t *pool);
|
||||||
static void *_capture_worker_thread(void *v_ctx);
|
static void *_capture_worker_thread(void *v_ctx);
|
||||||
static void _capture_destroy_workers(struct device_t *dev, struct workers_pool_t *pool);
|
static void _capture_destroy_workers(struct device_t *dev, struct workers_pool_t *pool);
|
||||||
static int _capture_control(struct device_t *dev, const bool enable);
|
static int _capture_control(struct device_t *dev, const bool enable);
|
||||||
@@ -68,17 +68,17 @@ static void _capture_dump(struct captured_picture_t *captured) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void capture_loop(struct device_t *dev, struct captured_picture_t *captured, sig_atomic_t *volatile global_stop) {
|
void capture_loop(struct device_t *dev, struct captured_picture_t *captured) {
|
||||||
struct workers_pool_t pool;
|
struct workers_pool_t pool;
|
||||||
volatile sig_atomic_t workers_stop;
|
bool workers_stop;
|
||||||
|
|
||||||
MEMSET_ZERO(pool);
|
MEMSET_ZERO(pool);
|
||||||
pool.workers_stop = (sig_atomic_t *volatile)&workers_stop;
|
pool.workers_stop = &workers_stop;
|
||||||
|
|
||||||
LOG_INFO("Using V4L2 device: %s", dev->path);
|
LOG_INFO("Using V4L2 device: %s", dev->path);
|
||||||
LOG_INFO("Using JPEG quality: %d%%", dev->jpeg_quality);
|
LOG_INFO("Using JPEG quality: %d%%", dev->jpeg_quality);
|
||||||
|
|
||||||
while (_capture_init_loop(dev, &pool, global_stop) == 0) {
|
while (_capture_init_loop(dev, &pool) == 0) {
|
||||||
struct worker_t *last_worker = NULL;
|
struct worker_t *last_worker = NULL;
|
||||||
unsigned frames_count = 0;
|
unsigned frames_count = 0;
|
||||||
long double grab_after = 0;
|
long double grab_after = 0;
|
||||||
@@ -92,7 +92,7 @@ void capture_loop(struct device_t *dev, struct captured_picture_t *captured, sig
|
|||||||
captured->width = dev->run->width;
|
captured->width = dev->run->width;
|
||||||
captured->height = dev->run->height;
|
captured->height = dev->run->height;
|
||||||
|
|
||||||
while (!*global_stop) {
|
while (!dev->stop) {
|
||||||
SEP_DEBUG('-');
|
SEP_DEBUG('-');
|
||||||
|
|
||||||
LOG_DEBUG("Waiting for workers ...");
|
LOG_DEBUG("Waiting for workers ...");
|
||||||
@@ -118,7 +118,7 @@ void capture_loop(struct device_t *dev, struct captured_picture_t *captured, sig
|
|||||||
# endif
|
# endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*global_stop) {
|
if (dev->stop) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -250,6 +250,10 @@ void capture_loop(struct device_t *dev, struct captured_picture_t *captured, sig
|
|||||||
device_close(dev);
|
device_close(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void capture_loop_break(struct device_t *dev) {
|
||||||
|
dev->stop = 1;
|
||||||
|
}
|
||||||
|
|
||||||
static long double _capture_get_fluency_delay(struct device_t *dev, struct workers_pool_t *pool) {
|
static long double _capture_get_fluency_delay(struct device_t *dev, struct workers_pool_t *pool) {
|
||||||
long double delay = 0;
|
long double delay = 0;
|
||||||
|
|
||||||
@@ -264,12 +268,12 @@ static long double _capture_get_fluency_delay(struct device_t *dev, struct worke
|
|||||||
return delay / dev->run->n_buffers / dev->run->n_buffers;
|
return delay / dev->run->n_buffers / dev->run->n_buffers;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _capture_init_loop(struct device_t *dev, struct workers_pool_t *pool, sig_atomic_t *volatile global_stop) {
|
static int _capture_init_loop(struct device_t *dev, struct workers_pool_t *pool) {
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
|
|
||||||
LOG_DEBUG("%s: global_stop = %d", __FUNCTION__, *global_stop);
|
LOG_DEBUG("%s: *dev->stop = %d", __FUNCTION__, dev->stop);
|
||||||
while (!*global_stop) {
|
while (!dev->stop) {
|
||||||
if ((retval = _capture_init(dev, pool, global_stop)) < 0) {
|
if ((retval = _capture_init(dev, pool)) < 0) {
|
||||||
LOG_INFO("Sleeping %d seconds before new capture init ...", dev->error_timeout);
|
LOG_INFO("Sleeping %d seconds before new capture init ...", dev->error_timeout);
|
||||||
sleep(dev->error_timeout);
|
sleep(dev->error_timeout);
|
||||||
} else {
|
} else {
|
||||||
@@ -279,7 +283,7 @@ static int _capture_init_loop(struct device_t *dev, struct workers_pool_t *pool,
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _capture_init(struct device_t *dev, struct workers_pool_t *pool, sig_atomic_t *volatile global_stop) {
|
static int _capture_init(struct device_t *dev, struct workers_pool_t *pool) {
|
||||||
SEP_INFO('=');
|
SEP_INFO('=');
|
||||||
|
|
||||||
_capture_destroy_workers(dev, pool);
|
_capture_destroy_workers(dev, pool);
|
||||||
@@ -292,7 +296,7 @@ static int _capture_init(struct device_t *dev, struct workers_pool_t *pool, sig_
|
|||||||
if (_capture_control(dev, true) < 0) {
|
if (_capture_control(dev, true) < 0) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
_capture_init_workers(dev, pool, global_stop);
|
_capture_init_workers(dev, pool);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@@ -301,7 +305,7 @@ static int _capture_init(struct device_t *dev, struct workers_pool_t *pool, sig_
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _capture_init_workers(struct device_t *dev, struct workers_pool_t *pool, sig_atomic_t *volatile global_stop) {
|
static void _capture_init_workers(struct device_t *dev, struct workers_pool_t *pool) {
|
||||||
LOG_DEBUG("Spawning %d workers ...", dev->run->n_buffers);
|
LOG_DEBUG("Spawning %d workers ...", dev->run->n_buffers);
|
||||||
|
|
||||||
*pool->workers_stop = false;
|
*pool->workers_stop = false;
|
||||||
@@ -316,7 +320,7 @@ static void _capture_init_workers(struct device_t *dev, struct workers_pool_t *p
|
|||||||
|
|
||||||
pool->workers[index].ctx.index = index;
|
pool->workers[index].ctx.index = index;
|
||||||
pool->workers[index].ctx.dev = dev;
|
pool->workers[index].ctx.dev = dev;
|
||||||
pool->workers[index].ctx.global_stop = global_stop;
|
pool->workers[index].ctx.dev_stop = (sig_atomic_t *volatile)&dev->stop;
|
||||||
pool->workers[index].ctx.workers_stop = pool->workers_stop;
|
pool->workers[index].ctx.workers_stop = pool->workers_stop;
|
||||||
|
|
||||||
pool->workers[index].ctx.last_comp_time_mutex = &pool->workers[index].last_comp_time_mutex;
|
pool->workers[index].ctx.last_comp_time_mutex = &pool->workers[index].last_comp_time_mutex;
|
||||||
@@ -339,7 +343,7 @@ static void *_capture_worker_thread(void *v_ctx) {
|
|||||||
|
|
||||||
LOG_DEBUG("Hello! I am a worker #%d ^_^", ctx->index);
|
LOG_DEBUG("Hello! I am a worker #%d ^_^", ctx->index);
|
||||||
|
|
||||||
while (!*ctx->global_stop && !*ctx->workers_stop) {
|
while (!*ctx->dev_stop && !*ctx->workers_stop) {
|
||||||
A_PTHREAD_M_LOCK(ctx->has_free_workers_mutex);
|
A_PTHREAD_M_LOCK(ctx->has_free_workers_mutex);
|
||||||
*ctx->has_free_workers = true;
|
*ctx->has_free_workers = true;
|
||||||
A_PTHREAD_M_UNLOCK(ctx->has_free_workers_mutex);
|
A_PTHREAD_M_UNLOCK(ctx->has_free_workers_mutex);
|
||||||
|
|||||||
@@ -13,8 +13,8 @@ struct worker_context_t {
|
|||||||
int index;
|
int index;
|
||||||
struct device_t *dev;
|
struct device_t *dev;
|
||||||
struct v4l2_buffer buf_info;
|
struct v4l2_buffer buf_info;
|
||||||
sig_atomic_t *volatile global_stop;
|
sig_atomic_t *volatile dev_stop;
|
||||||
sig_atomic_t *volatile workers_stop;
|
bool *workers_stop;
|
||||||
|
|
||||||
pthread_mutex_t *last_comp_time_mutex;
|
pthread_mutex_t *last_comp_time_mutex;
|
||||||
long double *last_comp_time;
|
long double *last_comp_time;
|
||||||
@@ -44,7 +44,7 @@ struct worker_t {
|
|||||||
|
|
||||||
struct workers_pool_t {
|
struct workers_pool_t {
|
||||||
struct worker_t *workers;
|
struct worker_t *workers;
|
||||||
sig_atomic_t *volatile workers_stop;
|
bool *workers_stop;
|
||||||
|
|
||||||
pthread_mutex_t has_free_workers_mutex;
|
pthread_mutex_t has_free_workers_mutex;
|
||||||
bool has_free_workers;
|
bool has_free_workers;
|
||||||
@@ -63,4 +63,5 @@ struct captured_picture_t {
|
|||||||
struct captured_picture_t *captured_picture_init();
|
struct captured_picture_t *captured_picture_init();
|
||||||
void captured_picture_destroy(struct captured_picture_t *captured);
|
void captured_picture_destroy(struct captured_picture_t *captured);
|
||||||
|
|
||||||
void capture_loop(struct device_t *dev, struct captured_picture_t *captured, sig_atomic_t *volatile global_stop);
|
void capture_loop(struct device_t *dev, struct captured_picture_t *capture);
|
||||||
|
void capture_loop_break(struct device_t *dev);
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <signal.h>
|
||||||
#include <linux/videodev2.h>
|
#include <linux/videodev2.h>
|
||||||
|
|
||||||
|
|
||||||
@@ -45,7 +46,8 @@ struct device_t {
|
|||||||
unsigned timeout;
|
unsigned timeout;
|
||||||
unsigned error_timeout;
|
unsigned error_timeout;
|
||||||
|
|
||||||
struct device_runtime_t *run;
|
struct device_runtime_t *run;
|
||||||
|
sig_atomic_t volatile stop;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
#include <signal.h>
|
|
||||||
|
|
||||||
#include "capture.h"
|
#include "capture.h"
|
||||||
#include "tools.h"
|
#include "tools.h"
|
||||||
#include "http.h"
|
#include "http.h"
|
||||||
@@ -23,6 +21,11 @@ void http_server_destroy(struct http_server_t *server) {
|
|||||||
free(server);
|
free(server);
|
||||||
}
|
}
|
||||||
|
|
||||||
void http_server_loop(struct http_server_t *server, struct captured_picture_t *captured, sig_atomic_t *volatile global_stop) {
|
void http_server_loop(struct http_server_t *server, struct captured_picture_t *captured) {
|
||||||
// TODO: implement server here
|
// TODO: implement server here
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void http_server_loop_break(struct http_server_t *server) {
|
||||||
|
// TODO: implement stop here
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
#include <signal.h>
|
|
||||||
|
|
||||||
#include "tools.h"
|
#include "tools.h"
|
||||||
#include "capture.h"
|
#include "capture.h"
|
||||||
|
|
||||||
@@ -13,4 +11,5 @@ struct http_server_t {
|
|||||||
struct http_server_t *http_server_init();
|
struct http_server_t *http_server_init();
|
||||||
void http_server_destroy(struct http_server_t *server);
|
void http_server_destroy(struct http_server_t *server);
|
||||||
|
|
||||||
void http_server_loop(struct http_server_t *server, struct captured_picture_t *captured, sig_atomic_t *volatile global_stop);
|
void http_server_loop(struct http_server_t *server, struct captured_picture_t *captured);
|
||||||
|
void http_server_loop_break(struct http_server_t *server);
|
||||||
|
|||||||
24
src/main.c
24
src/main.c
@@ -103,13 +103,13 @@ static int _parse_options(int argc, char *argv[], struct device_t *dev, struct h
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct thread_context {
|
struct main_context_t {
|
||||||
struct device_t *dev;
|
struct device_t *dev;
|
||||||
struct captured_picture_t *captured;
|
struct captured_picture_t *captured;
|
||||||
struct http_server_t *server;
|
struct http_server_t *server;
|
||||||
};
|
};
|
||||||
|
|
||||||
static volatile sig_atomic_t _global_stop = 0;
|
static struct main_context_t *_ctx;
|
||||||
|
|
||||||
static void _block_thread_signals() {
|
static void _block_thread_signals() {
|
||||||
sigset_t mask;
|
sigset_t mask;
|
||||||
@@ -119,23 +119,22 @@ static void _block_thread_signals() {
|
|||||||
assert(!pthread_sigmask(SIG_BLOCK, &mask, NULL));
|
assert(!pthread_sigmask(SIG_BLOCK, &mask, NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *_capture_loop_thread(void *v_ctx) {
|
static void *_capture_loop_thread(UNUSED void *_) {
|
||||||
struct thread_context *ctx = (struct thread_context *)v_ctx;
|
|
||||||
_block_thread_signals();
|
_block_thread_signals();
|
||||||
capture_loop(ctx->dev, ctx->captured, (sig_atomic_t *volatile)&_global_stop);
|
capture_loop(_ctx->dev, _ctx->captured);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *_server_loop_thread(void *v_ctx) {
|
static void *_server_loop_thread(UNUSED void *_) {
|
||||||
struct thread_context *ctx = (struct thread_context *)v_ctx;
|
|
||||||
_block_thread_signals();
|
_block_thread_signals();
|
||||||
http_server_loop(ctx->server, ctx->captured, (sig_atomic_t *volatile)&_global_stop);
|
http_server_loop(_ctx->server, _ctx->captured);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _signal_handler(int signum) {
|
static void _signal_handler(int signum) {
|
||||||
LOG_INFO("===== Stopping by %s =====", strsignal(signum));
|
LOG_INFO("===== Stopping by %s =====", strsignal(signum));
|
||||||
_global_stop = 1;
|
capture_loop_break(_ctx->dev);
|
||||||
|
http_server_loop_break(_ctx->server);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _install_signal_handlers() {
|
static void _install_signal_handlers() {
|
||||||
@@ -168,14 +167,15 @@ int main(int argc, char *argv[]) {
|
|||||||
|
|
||||||
pthread_t capture_loop_tid;
|
pthread_t capture_loop_tid;
|
||||||
pthread_t server_loop_tid;
|
pthread_t server_loop_tid;
|
||||||
struct thread_context ctx;
|
struct main_context_t ctx;
|
||||||
|
|
||||||
ctx.dev = dev;
|
ctx.dev = dev;
|
||||||
ctx.captured = captured;
|
ctx.captured = captured;
|
||||||
ctx.server = server;
|
ctx.server = server;
|
||||||
|
_ctx = &ctx;
|
||||||
|
|
||||||
A_PTHREAD_CREATE(&capture_loop_tid, _capture_loop_thread, (void *)&ctx);
|
A_PTHREAD_CREATE(&capture_loop_tid, _capture_loop_thread, NULL);
|
||||||
A_PTHREAD_CREATE(&server_loop_tid, _server_loop_thread, (void *)&ctx);
|
A_PTHREAD_CREATE(&server_loop_tid, _server_loop_thread, NULL);
|
||||||
A_PTHREAD_JOIN(capture_loop_tid);
|
A_PTHREAD_JOIN(capture_loop_tid);
|
||||||
A_PTHREAD_JOIN(server_loop_tid);
|
A_PTHREAD_JOIN(server_loop_tid);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -72,6 +72,8 @@ unsigned log_level;
|
|||||||
|
|
||||||
|
|
||||||
#define INLINE inline __attribute__((always_inline))
|
#define INLINE inline __attribute__((always_inline))
|
||||||
|
#define UNUSED __attribute__((unused))
|
||||||
|
|
||||||
|
|
||||||
#define XIOCTL_RETRIES 4
|
#define XIOCTL_RETRIES 4
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user