Compare commits

...

7 Commits
v5.17 ... v5.18

Author SHA1 Message Date
Maxim Devaev
b5f814d71e Bump version: 5.17 → 5.18 2022-07-29 15:16:49 +03:00
Maxim Devaev
6eafd4156a us_signum_to_string() 2022-07-29 14:34:41 +03:00
Maxim Devaev
df1e4eaa06 refactoring 2022-07-29 13:44:48 +03:00
Maxim Devaev
d2bef81b03 refactoring 2022-07-29 13:05:47 +03:00
Maxim Devaev
7b3dffd072 refactoring 2022-07-29 12:41:47 +03:00
Maxim Devaev
1a6e9998fb missing destroy 2022-07-29 12:21:13 +03:00
Maxim Devaev
9ab9561803 global variables prefix 2022-07-21 16:29:20 +03:00
18 changed files with 104 additions and 112 deletions

View File

@@ -1,7 +1,7 @@
[bumpversion] [bumpversion]
commit = True commit = True
tag = True tag = True
current_version = 5.17 current_version = 5.18
parse = (?P<major>\d+)\.(?P<minor>\d+) parse = (?P<major>\d+)\.(?P<minor>\d+)
serialize = serialize =
{major}.{minor} {major}.{minor}

View File

@@ -40,6 +40,9 @@ us_queue_s *us_queue_init(unsigned capacity) {
} }
void us_queue_destroy(us_queue_s *queue) { void us_queue_destroy(us_queue_s *queue) {
US_COND_DESTROY(queue->empty_cond);
US_COND_DESTROY(queue->full_cond);
US_MUTEX_DESTROY(queue->mutex);
free(queue->items); free(queue->items);
free(queue); free(queue);
} }
@@ -73,7 +76,7 @@ int us_queue_put(us_queue_s *queue, void *item, long double timeout) {
++queue->in; ++queue->in;
queue->in %= queue->capacity; queue->in %= queue->capacity;
US_MUTEX_UNLOCK(queue->mutex); US_MUTEX_UNLOCK(queue->mutex);
assert(!pthread_cond_broadcast(&queue->empty_cond)); US_COND_BROADCAST(queue->empty_cond);
return 0; return 0;
} }
@@ -85,7 +88,7 @@ int us_queue_get(us_queue_s *queue, void **item, long double timeout) {
++queue->out; ++queue->out;
queue->out %= queue->capacity; queue->out %= queue->capacity;
US_MUTEX_UNLOCK(queue->mutex); US_MUTEX_UNLOCK(queue->mutex);
assert(!pthread_cond_broadcast(&queue->full_cond)); US_COND_BROADCAST(queue->full_cond);
return 0; return 0;
} }

View File

@@ -1,6 +1,6 @@
.\" Manpage for ustreamer-dump. .\" Manpage for ustreamer-dump.
.\" Open an issue or pull request to https://github.com/pikvm/ustreamer to correct errors or typos .\" Open an issue or pull request to https://github.com/pikvm/ustreamer to correct errors or typos
.TH USTREAMER-DUMP 1 "version 5.17" "January 2021" .TH USTREAMER-DUMP 1 "version 5.18" "January 2021"
.SH NAME .SH NAME
ustreamer-dump \- Dump uStreamer's memory sink to file ustreamer-dump \- Dump uStreamer's memory sink to file

View File

@@ -1,6 +1,6 @@
.\" Manpage for ustreamer. .\" Manpage for ustreamer.
.\" Open an issue or pull request to https://github.com/pikvm/ustreamer to correct errors or typos .\" Open an issue or pull request to https://github.com/pikvm/ustreamer to correct errors or typos
.TH USTREAMER 1 "version 5.17" "November 2020" .TH USTREAMER 1 "version 5.18" "November 2020"
.SH NAME .SH NAME
ustreamer \- stream MJPEG video from any V4L2 device to the network ustreamer \- stream MJPEG video from any V4L2 device to the network

View File

@@ -3,7 +3,7 @@
pkgname=ustreamer pkgname=ustreamer
pkgver=5.17 pkgver=5.18
pkgrel=1 pkgrel=1
pkgdesc="Lightweight and fast MJPEG-HTTP streamer" pkgdesc="Lightweight and fast MJPEG-HTTP streamer"
url="https://github.com/pikvm/ustreamer" url="https://github.com/pikvm/ustreamer"

View File

@@ -6,7 +6,7 @@
include $(TOPDIR)/rules.mk include $(TOPDIR)/rules.mk
PKG_NAME:=ustreamer PKG_NAME:=ustreamer
PKG_VERSION:=5.17 PKG_VERSION:=5.18
PKG_RELEASE:=1 PKG_RELEASE:=1
PKG_MAINTAINER:=Maxim Devaev <mdevaev@gmail.com> PKG_MAINTAINER:=Maxim Devaev <mdevaev@gmail.com>

View File

@@ -19,7 +19,7 @@ def _find_sources(suffix: str) -> List[str]:
if __name__ == "__main__": if __name__ == "__main__":
setup( setup(
name="ustreamer", name="ustreamer",
version="5.17", version="5.18",
description="uStreamer tools", description="uStreamer tools",
author="Maxim Devaev", author="Maxim Devaev",
author_email="mdevaev@gmail.com", author_email="mdevaev@gmail.com",

View File

@@ -151,12 +151,12 @@ int main(int argc, char *argv[]) {
case _O_COUNT: OPT_NUMBER("--count", count, 0, LLONG_MAX, 0); case _O_COUNT: OPT_NUMBER("--count", count, 0, LLONG_MAX, 0);
case _O_INTERVAL: OPT_LDOUBLE("--interval", interval, 0, 60); case _O_INTERVAL: OPT_LDOUBLE("--interval", interval, 0, 60);
case _O_LOG_LEVEL: OPT_NUMBER("--log-level", us_log_level, US_LOG_LEVEL_INFO, US_LOG_LEVEL_DEBUG, 0); case _O_LOG_LEVEL: OPT_NUMBER("--log-level", us_g_log_level, US_LOG_LEVEL_INFO, US_LOG_LEVEL_DEBUG, 0);
case _O_PERF: OPT_SET(us_log_level, US_LOG_LEVEL_PERF); case _O_PERF: OPT_SET(us_g_log_level, US_LOG_LEVEL_PERF);
case _O_VERBOSE: OPT_SET(us_log_level, US_LOG_LEVEL_VERBOSE); case _O_VERBOSE: OPT_SET(us_g_log_level, US_LOG_LEVEL_VERBOSE);
case _O_DEBUG: OPT_SET(us_log_level, US_LOG_LEVEL_DEBUG); case _O_DEBUG: OPT_SET(us_g_log_level, US_LOG_LEVEL_DEBUG);
case _O_FORCE_LOG_COLORS: OPT_SET(us_log_colored, true); case _O_FORCE_LOG_COLORS: OPT_SET(us_g_log_colored, true);
case _O_NO_LOG_COLORS: OPT_SET(us_log_colored, false); case _O_NO_LOG_COLORS: OPT_SET(us_g_log_colored, false);
case _O_HELP: _help(stdout); return 0; case _O_HELP: _help(stdout); return 0;
case _O_VERSION: puts(US_VERSION); return 0; case _O_VERSION: puts(US_VERSION); return 0;
@@ -195,12 +195,7 @@ int main(int argc, char *argv[]) {
static void _signal_handler(int signum) { static void _signal_handler(int signum) {
switch (signum) { US_LOG_INFO_NOLOCK("===== Stopping by SIG%s =====", us_signum_to_string(signum));
case SIGTERM: US_LOG_INFO_NOLOCK("===== Stopping by SIGTERM ====="); break;
case SIGINT: US_LOG_INFO_NOLOCK("===== Stopping by SIGINT ====="); break;
case SIGPIPE: US_LOG_INFO_NOLOCK("===== Stopping by SIGPIPE ====="); break;
default: US_LOG_INFO_NOLOCK("===== Stopping by %d =====", signum); break;
}
_g_stop = true; _g_stop = true;
} }
@@ -330,7 +325,7 @@ static void _help(FILE *fp) {
SAY(" --log-level <N> ──── Verbosity level of messages from 0 (info) to 3 (debug)."); SAY(" --log-level <N> ──── Verbosity level of messages from 0 (info) to 3 (debug).");
SAY(" Enabling debugging messages can slow down the program."); SAY(" Enabling debugging messages can slow down the program.");
SAY(" Available levels: 0 (info), 1 (performance), 2 (verbose), 3 (debug)."); SAY(" Available levels: 0 (info), 1 (performance), 2 (verbose), 3 (debug).");
SAY(" Default: %d.\n", us_log_level); SAY(" Default: %d.\n", us_g_log_level);
SAY(" --perf ───────────── Enable performance messages (same as --log-level=1). Default: disabled.\n"); SAY(" --perf ───────────── Enable performance messages (same as --log-level=1). Default: disabled.\n");
SAY(" --verbose ────────── Enable verbose messages and lower (same as --log-level=2). Default: disabled.\n"); SAY(" --verbose ────────── Enable verbose messages and lower (same as --log-level=2). Default: disabled.\n");
SAY(" --debug ──────────── Enable debug messages and lower (same as --log-level=3). Default: disabled.\n"); SAY(" --debug ──────────── Enable debug messages and lower (same as --log-level=3). Default: disabled.\n");

View File

@@ -23,7 +23,7 @@
#pragma once #pragma once
#define US_VERSION_MAJOR 5 #define US_VERSION_MAJOR 5
#define US_VERSION_MINOR 17 #define US_VERSION_MINOR 18
#define US_MAKE_VERSION2(_major, _minor) #_major "." #_minor #define US_MAKE_VERSION2(_major, _minor) #_major "." #_minor
#define US_MAKE_VERSION1(_major, _minor) US_MAKE_VERSION2(_major, _minor) #define US_MAKE_VERSION1(_major, _minor) US_MAKE_VERSION2(_major, _minor)

View File

@@ -23,8 +23,8 @@
#include "logging.h" #include "logging.h"
enum us_log_level_t us_log_level; enum us_log_level_t us_g_log_level;
bool us_log_colored; bool us_g_log_colored;
pthread_mutex_t us_log_mutex; pthread_mutex_t us_g_log_mutex;

View File

@@ -45,23 +45,23 @@ enum us_log_level_t {
}; };
extern enum us_log_level_t us_log_level; extern enum us_log_level_t us_g_log_level;
extern bool us_log_colored; extern bool us_g_log_colored;
extern pthread_mutex_t us_log_mutex; extern pthread_mutex_t us_g_log_mutex;
#define US_LOGGING_INIT { \ #define US_LOGGING_INIT { \
us_log_level = US_LOG_LEVEL_INFO; \ us_g_log_level = US_LOG_LEVEL_INFO; \
us_log_colored = isatty(2); \ us_g_log_colored = isatty(2); \
US_MUTEX_INIT(us_log_mutex); \ US_MUTEX_INIT(us_g_log_mutex); \
} }
#define US_LOGGING_DESTROY US_MUTEX_DESTROY(us_log_mutex) #define US_LOGGING_DESTROY US_MUTEX_DESTROY(us_g_log_mutex)
#define US_LOGGING_LOCK US_MUTEX_LOCK(us_log_mutex) #define US_LOGGING_LOCK US_MUTEX_LOCK(us_g_log_mutex)
#define US_LOGGING_UNLOCK US_MUTEX_UNLOCK(us_log_mutex) #define US_LOGGING_UNLOCK US_MUTEX_UNLOCK(us_g_log_mutex)
#define US_COLOR_GRAY "\x1b[30;1m" #define US_COLOR_GRAY "\x1b[30;1m"
@@ -84,7 +84,7 @@ extern pthread_mutex_t us_log_mutex;
} }
#define US_SEP_DEBUG(x_ch) { \ #define US_SEP_DEBUG(x_ch) { \
if (us_log_level >= US_LOG_LEVEL_DEBUG) { \ if (us_g_log_level >= US_LOG_LEVEL_DEBUG) { \
US_SEP_INFO(x_ch); \ US_SEP_INFO(x_ch); \
} \ } \
} }
@@ -93,7 +93,7 @@ extern pthread_mutex_t us_log_mutex;
#define US_LOG_PRINTF_NOLOCK(x_label_color, x_label, x_msg_color, x_msg, ...) { \ #define US_LOG_PRINTF_NOLOCK(x_label_color, x_label, x_msg_color, x_msg, ...) { \
char m_tname_buf[US_MAX_THREAD_NAME] = {0}; \ char m_tname_buf[US_MAX_THREAD_NAME] = {0}; \
us_thread_get_name(m_tname_buf); \ us_thread_get_name(m_tname_buf); \
if (us_log_colored) { \ if (us_g_log_colored) { \
fprintf(stderr, US_COLOR_GRAY "-- " x_label_color x_label US_COLOR_GRAY \ fprintf(stderr, US_COLOR_GRAY "-- " x_label_color x_label US_COLOR_GRAY \
" [%.03Lf %9s]" " -- " US_COLOR_RESET x_msg_color x_msg US_COLOR_RESET, \ " [%.03Lf %9s]" " -- " US_COLOR_RESET x_msg_color x_msg US_COLOR_RESET, \
us_get_now_monotonic(), m_tname_buf, ##__VA_ARGS__); \ us_get_now_monotonic(), m_tname_buf, ##__VA_ARGS__); \
@@ -130,25 +130,25 @@ extern pthread_mutex_t us_log_mutex;
} }
#define US_LOG_PERF(x_msg, ...) { \ #define US_LOG_PERF(x_msg, ...) { \
if (us_log_level >= US_LOG_LEVEL_PERF) { \ if (us_g_log_level >= US_LOG_LEVEL_PERF) { \
US_LOG_PRINTF(US_COLOR_CYAN, "PERF ", US_COLOR_CYAN, x_msg, ##__VA_ARGS__); \ US_LOG_PRINTF(US_COLOR_CYAN, "PERF ", US_COLOR_CYAN, x_msg, ##__VA_ARGS__); \
} \ } \
} }
#define US_LOG_PERF_FPS(x_msg, ...) { \ #define US_LOG_PERF_FPS(x_msg, ...) { \
if (us_log_level >= US_LOG_LEVEL_PERF) { \ if (us_g_log_level >= US_LOG_LEVEL_PERF) { \
US_LOG_PRINTF(US_COLOR_YELLOW, "PERF ", US_COLOR_YELLOW, x_msg, ##__VA_ARGS__); \ US_LOG_PRINTF(US_COLOR_YELLOW, "PERF ", US_COLOR_YELLOW, x_msg, ##__VA_ARGS__); \
} \ } \
} }
#define US_LOG_VERBOSE(x_msg, ...) { \ #define US_LOG_VERBOSE(x_msg, ...) { \
if (us_log_level >= US_LOG_LEVEL_VERBOSE) { \ if (us_g_log_level >= US_LOG_LEVEL_VERBOSE) { \
US_LOG_PRINTF(US_COLOR_BLUE, "VERB ", US_COLOR_BLUE, x_msg, ##__VA_ARGS__); \ US_LOG_PRINTF(US_COLOR_BLUE, "VERB ", US_COLOR_BLUE, x_msg, ##__VA_ARGS__); \
} \ } \
} }
#define US_LOG_VERBOSE_PERROR(x_msg, ...) { \ #define US_LOG_VERBOSE_PERROR(x_msg, ...) { \
if (us_log_level >= US_LOG_LEVEL_VERBOSE) { \ if (us_g_log_level >= US_LOG_LEVEL_VERBOSE) { \
char m_perror_buf[1024] = {0}; \ char m_perror_buf[1024] = {0}; \
char *m_perror_ptr = us_errno_to_string(errno, m_perror_buf, 1023); \ char *m_perror_ptr = us_errno_to_string(errno, m_perror_buf, 1023); \
US_LOG_PRINTF(US_COLOR_BLUE, "VERB ", US_COLOR_BLUE, x_msg ": %s", ##__VA_ARGS__, m_perror_ptr); \ US_LOG_PRINTF(US_COLOR_BLUE, "VERB ", US_COLOR_BLUE, x_msg ": %s", ##__VA_ARGS__, m_perror_ptr); \
@@ -156,7 +156,7 @@ extern pthread_mutex_t us_log_mutex;
} }
#define US_LOG_DEBUG(x_msg, ...) { \ #define US_LOG_DEBUG(x_msg, ...) { \
if (us_log_level >= US_LOG_LEVEL_DEBUG) { \ if (us_g_log_level >= US_LOG_LEVEL_DEBUG) { \
US_LOG_PRINTF(US_COLOR_GRAY, "DEBUG", US_COLOR_GRAY, x_msg, ##__VA_ARGS__); \ US_LOG_PRINTF(US_COLOR_GRAY, "DEBUG", US_COLOR_GRAY, x_msg, ##__VA_ARGS__); \
} \ } \
} }

View File

@@ -67,7 +67,8 @@
#define US_COND_INIT(x_cond) assert(!pthread_cond_init(&(x_cond), NULL)) #define US_COND_INIT(x_cond) assert(!pthread_cond_init(&(x_cond), NULL))
#define US_COND_DESTROY(x_cond) assert(!pthread_cond_destroy(&(x_cond))) #define US_COND_DESTROY(x_cond) assert(!pthread_cond_destroy(&(x_cond)))
#define US_COND_SIGNAL(x_cond) assert(!pthread_cond_signal(&(x_cond))) #define US_COND_SIGNAL(x_cond) assert(!pthread_cond_signal(&(x_cond)))
#define US_COND_WAIT_TRUE(x_var, x_cond, x_mutex) { while(!(x_var)) assert(!pthread_cond_wait(&(x_cond), &(x_mutex))); } #define US_COND_BROADCAST(x_cond) assert(!pthread_cond_broadcast(&(x_cond)))
#define US_COND_WAIT_FOR(x_var, x_cond, x_mutex) { while(!(x_var)) assert(!pthread_cond_wait(&(x_cond), &(x_mutex))); }
#ifdef WITH_PTHREAD_NP #ifdef WITH_PTHREAD_NP

View File

@@ -193,3 +193,8 @@ INLINE char *us_errno_to_string(int error, char *buf, size_t size) {
} }
return buf; return buf;
} }
INLINE const char *us_signum_to_string(int signum) {
const char *const str = sigabbrev_np(signum);
return (str == NULL ? "???" : str);
}

View File

@@ -23,7 +23,7 @@
#include "gpio.h" #include "gpio.h"
us_gpio_s us_gpio = { us_gpio_s us_g_gpio = {
.path = "/dev/gpiochip0", .path = "/dev/gpiochip0",
.consumer_prefix = "ustreamer", .consumer_prefix = "ustreamer",
@@ -51,42 +51,42 @@ static void _gpio_output_destroy(us_gpio_output_s *output);
void us_gpio_init(void) { void us_gpio_init(void) {
assert(us_gpio.chip == NULL); assert(us_g_gpio.chip == NULL);
if ( if (
us_gpio.prog_running.pin >= 0 us_g_gpio.prog_running.pin >= 0
|| us_gpio.stream_online.pin >= 0 || us_g_gpio.stream_online.pin >= 0
|| us_gpio.has_http_clients.pin >= 0 || us_g_gpio.has_http_clients.pin >= 0
) { ) {
US_MUTEX_INIT(us_gpio.mutex); US_MUTEX_INIT(us_g_gpio.mutex);
US_LOG_INFO("GPIO: Using chip device: %s", us_gpio.path); US_LOG_INFO("GPIO: Using chip device: %s", us_g_gpio.path);
if ((us_gpio.chip = gpiod_chip_open(us_gpio.path)) != NULL) { if ((us_g_gpio.chip = gpiod_chip_open(us_g_gpio.path)) != NULL) {
_gpio_output_init(&us_gpio.prog_running); _gpio_output_init(&us_g_gpio.prog_running);
_gpio_output_init(&us_gpio.stream_online); _gpio_output_init(&us_g_gpio.stream_online);
_gpio_output_init(&us_gpio.has_http_clients); _gpio_output_init(&us_g_gpio.has_http_clients);
} else { } else {
US_LOG_PERROR("GPIO: Can't initialize chip device %s", us_gpio.path); US_LOG_PERROR("GPIO: Can't initialize chip device %s", us_g_gpio.path);
} }
} }
} }
void us_gpio_destroy(void) { void us_gpio_destroy(void) {
_gpio_output_destroy(&us_gpio.prog_running); _gpio_output_destroy(&us_g_gpio.prog_running);
_gpio_output_destroy(&us_gpio.stream_online); _gpio_output_destroy(&us_g_gpio.stream_online);
_gpio_output_destroy(&us_gpio.has_http_clients); _gpio_output_destroy(&us_g_gpio.has_http_clients);
if (us_gpio.chip != NULL) { if (us_g_gpio.chip != NULL) {
gpiod_chip_close(us_gpio.chip); gpiod_chip_close(us_g_gpio.chip);
us_gpio.chip = NULL; us_g_gpio.chip = NULL;
US_MUTEX_DESTROY(us_gpio.mutex); US_MUTEX_DESTROY(us_g_gpio.mutex);
} }
} }
int us_gpio_inner_set(us_gpio_output_s *output, bool state) { int us_gpio_inner_set(us_gpio_output_s *output, bool state) {
int retval = 0; int retval = 0;
assert(us_gpio.chip != NULL); assert(us_g_gpio.chip != NULL);
assert(output->line != NULL); assert(output->line != NULL);
assert(output->state != state); // Must be checked in macro for the performance assert(output->state != state); // Must be checked in macro for the performance
US_MUTEX_LOCK(us_gpio.mutex); US_MUTEX_LOCK(us_g_gpio.mutex);
if (gpiod_line_set_value(output->line, (int)state) < 0) { \ if (gpiod_line_set_value(output->line, (int)state) < 0) { \
US_LOG_PERROR("GPIO: Can't write value %d to line %s (will be disabled)", state, output->consumer); \ US_LOG_PERROR("GPIO: Can't write value %d to line %s (will be disabled)", state, output->consumer); \
@@ -94,18 +94,18 @@ int us_gpio_inner_set(us_gpio_output_s *output, bool state) {
retval = -1; retval = -1;
} }
US_MUTEX_UNLOCK(us_gpio.mutex); US_MUTEX_UNLOCK(us_g_gpio.mutex);
return retval; return retval;
} }
static void _gpio_output_init(us_gpio_output_s *output) { static void _gpio_output_init(us_gpio_output_s *output) {
assert(us_gpio.chip != NULL); assert(us_g_gpio.chip != NULL);
assert(output->line == NULL); assert(output->line == NULL);
US_ASPRINTF(output->consumer, "%s::%s", us_gpio.consumer_prefix, output->role); US_ASPRINTF(output->consumer, "%s::%s", us_g_gpio.consumer_prefix, output->role);
if (output->pin >= 0) { if (output->pin >= 0) {
if ((output->line = gpiod_chip_get_line(us_gpio.chip, output->pin)) != NULL) { if ((output->line = gpiod_chip_get_line(us_g_gpio.chip, output->pin)) != NULL) {
if (gpiod_line_request_output(output->line, output->consumer, 0) < 0) { if (gpiod_line_request_output(output->line, output->consumer, 0) < 0) {
US_LOG_PERROR("GPIO: Can't request pin=%d as %s", output->pin, output->consumer); US_LOG_PERROR("GPIO: Can't request pin=%d as %s", output->pin, output->consumer);
_gpio_output_destroy(output); _gpio_output_destroy(output);

View File

@@ -56,7 +56,7 @@ typedef struct {
} us_gpio_s; } us_gpio_s;
extern us_gpio_s us_gpio; extern us_gpio_s us_g_gpio;
void us_gpio_init(void); void us_gpio_init(void);
@@ -73,15 +73,15 @@ int us_gpio_inner_set(us_gpio_output_s *output, bool state);
} }
INLINE void us_gpio_set_prog_running(bool state) { INLINE void us_gpio_set_prog_running(bool state) {
SET_STATE(us_gpio.prog_running, state); SET_STATE(us_g_gpio.prog_running, state);
} }
INLINE void us_gpio_set_stream_online(bool state) { INLINE void us_gpio_set_stream_online(bool state) {
SET_STATE(us_gpio.stream_online, state); SET_STATE(us_g_gpio.stream_online, state);
} }
INLINE void us_gpio_set_has_http_clients(bool state) { INLINE void us_gpio_set_has_http_clients(bool state) {
SET_STATE(us_gpio.has_http_clients, state); SET_STATE(us_g_gpio.has_http_clients, state);
} }
#undef SET_STATE #undef SET_STATE

View File

@@ -40,12 +40,9 @@
#endif #endif
typedef struct { static us_stream_s *_g_stream = NULL;
us_stream_s *stream; static us_server_s *_g_server = NULL;
us_server_s *server;
} _main_context_s;
static _main_context_s *_ctx;
static void _block_thread_signals(void) { static void _block_thread_signals(void) {
sigset_t mask; sigset_t mask;
@@ -58,25 +55,21 @@ static void _block_thread_signals(void) {
static void *_stream_loop_thread(UNUSED void *arg) { static void *_stream_loop_thread(UNUSED void *arg) {
US_THREAD_RENAME("stream"); US_THREAD_RENAME("stream");
_block_thread_signals(); _block_thread_signals();
us_stream_loop(_ctx->stream); us_stream_loop(_g_stream);
return NULL; return NULL;
} }
static void *_server_loop_thread(UNUSED void *arg) { static void *_server_loop_thread(UNUSED void *arg) {
US_THREAD_RENAME("http"); US_THREAD_RENAME("http");
_block_thread_signals(); _block_thread_signals();
us_server_loop(_ctx->server); us_server_loop(_g_server);
return NULL; return NULL;
} }
static void _signal_handler(int signum) { static void _signal_handler(int signum) {
switch (signum) { US_LOG_INFO_NOLOCK("===== Stopping by SIG%s =====", us_signum_to_string(signum));
case SIGTERM: US_LOG_INFO_NOLOCK("===== Stopping by SIGTERM ====="); break; us_stream_loop_break(_g_stream);
case SIGINT: US_LOG_INFO_NOLOCK("===== Stopping by SIGINT ====="); break; us_server_loop_break(_g_server);
default: US_LOG_INFO_NOLOCK("===== Stopping by %d =====", signum); break;
}
us_stream_loop_break(_ctx->stream);
us_server_loop_break(_ctx->server);
} }
static void _install_signal_handlers(void) { static void _install_signal_handlers(void) {
@@ -107,22 +100,17 @@ int main(int argc, char *argv[]) {
us_options_s *options = us_options_init(argc, argv); us_options_s *options = us_options_init(argc, argv);
us_device_s *dev = us_device_init(); us_device_s *dev = us_device_init();
us_encoder_s *enc = us_encoder_init(); us_encoder_s *enc = us_encoder_init();
us_stream_s *stream = us_stream_init(dev, enc); _g_stream = us_stream_init(dev, enc);
us_server_s *server = us_server_init(stream); _g_server = us_server_init(_g_stream);
if ((exit_code = options_parse(options, dev, enc, stream, server)) == 0) { if ((exit_code = options_parse(options, dev, enc, _g_stream, _g_server)) == 0) {
# ifdef WITH_GPIO # ifdef WITH_GPIO
us_gpio_init(); us_gpio_init();
# endif # endif
_install_signal_handlers(); _install_signal_handlers();
_main_context_s ctx; if ((exit_code = us_server_listen(_g_server)) == 0) {
ctx.stream = stream;
ctx.server = server;
_ctx = &ctx;
if ((exit_code = us_server_listen(server)) == 0) {
# ifdef WITH_GPIO # ifdef WITH_GPIO
us_gpio_set_prog_running(true); us_gpio_set_prog_running(true);
# endif # endif
@@ -141,8 +129,8 @@ int main(int argc, char *argv[]) {
# endif # endif
} }
us_server_destroy(server); us_server_destroy(_g_server);
us_stream_destroy(stream); us_stream_destroy(_g_stream);
us_encoder_destroy(enc); us_encoder_destroy(enc);
us_device_destroy(dev); us_device_destroy(dev);
us_options_destroy(options); us_options_destroy(options);

View File

@@ -437,11 +437,11 @@ int options_parse(us_options_s *options, us_device_s *dev, us_encoder_s *enc, us
# undef ADD_SINK # undef ADD_SINK
# ifdef WITH_GPIO # ifdef WITH_GPIO
case _O_GPIO_DEVICE: OPT_SET(us_gpio.path, optarg); case _O_GPIO_DEVICE: OPT_SET(us_g_gpio.path, optarg);
case _O_GPIO_CONSUMER_PREFIX: OPT_SET(us_gpio.consumer_prefix, optarg); case _O_GPIO_CONSUMER_PREFIX: OPT_SET(us_g_gpio.consumer_prefix, optarg);
case _O_GPIO_PROG_RUNNING: OPT_NUMBER("--gpio-prog-running", us_gpio.prog_running.pin, 0, 256, 0); case _O_GPIO_PROG_RUNNING: OPT_NUMBER("--gpio-prog-running", us_g_gpio.prog_running.pin, 0, 256, 0);
case _O_GPIO_STREAM_ONLINE: OPT_NUMBER("--gpio-stream-online", us_gpio.stream_online.pin, 0, 256, 0); case _O_GPIO_STREAM_ONLINE: OPT_NUMBER("--gpio-stream-online", us_g_gpio.stream_online.pin, 0, 256, 0);
case _O_GPIO_HAS_HTTP_CLIENTS: OPT_NUMBER("--gpio-has-http-clients", us_gpio.has_http_clients.pin, 0, 256, 0); case _O_GPIO_HAS_HTTP_CLIENTS: OPT_NUMBER("--gpio-has-http-clients", us_g_gpio.has_http_clients.pin, 0, 256, 0);
# endif # endif
# ifdef HAS_PDEATHSIG # ifdef HAS_PDEATHSIG
@@ -457,12 +457,12 @@ int options_parse(us_options_s *options, us_device_s *dev, us_encoder_s *enc, us
# endif # endif
case _O_NOTIFY_PARENT: OPT_SET(server->notify_parent, true); case _O_NOTIFY_PARENT: OPT_SET(server->notify_parent, true);
case _O_LOG_LEVEL: OPT_NUMBER("--log-level", us_log_level, US_LOG_LEVEL_INFO, US_LOG_LEVEL_DEBUG, 0); case _O_LOG_LEVEL: OPT_NUMBER("--log-level", us_g_log_level, US_LOG_LEVEL_INFO, US_LOG_LEVEL_DEBUG, 0);
case _O_PERF: OPT_SET(us_log_level, US_LOG_LEVEL_PERF); case _O_PERF: OPT_SET(us_g_log_level, US_LOG_LEVEL_PERF);
case _O_VERBOSE: OPT_SET(us_log_level, US_LOG_LEVEL_VERBOSE); case _O_VERBOSE: OPT_SET(us_g_log_level, US_LOG_LEVEL_VERBOSE);
case _O_DEBUG: OPT_SET(us_log_level, US_LOG_LEVEL_DEBUG); case _O_DEBUG: OPT_SET(us_g_log_level, US_LOG_LEVEL_DEBUG);
case _O_FORCE_LOG_COLORS: OPT_SET(us_log_colored, true); case _O_FORCE_LOG_COLORS: OPT_SET(us_g_log_colored, true);
case _O_NO_LOG_COLORS: OPT_SET(us_log_colored, false); case _O_NO_LOG_COLORS: OPT_SET(us_g_log_colored, false);
case _O_HELP: _help(stdout, dev, enc, stream, server); return 1; case _O_HELP: _help(stdout, dev, enc, stream, server); return 1;
case _O_VERSION: puts(US_VERSION); return 1; case _O_VERSION: puts(US_VERSION); return 1;
@@ -676,8 +676,8 @@ static void _help(FILE *fp, us_device_s *dev, us_encoder_s *enc, us_stream_s *st
# ifdef WITH_GPIO # ifdef WITH_GPIO
SAY("GPIO options:"); SAY("GPIO options:");
SAY("═════════════"); SAY("═════════════");
SAY(" --gpio-device </dev/path> ───── Path to GPIO character device. Default: %s.\n", us_gpio.path); SAY(" --gpio-device </dev/path> ───── Path to GPIO character device. Default: %s.\n", us_g_gpio.path);
SAY(" --gpio-consumer-prefix <str> ── Consumer prefix for GPIO outputs. Default: %s.\n", us_gpio.consumer_prefix); SAY(" --gpio-consumer-prefix <str> ── Consumer prefix for GPIO outputs. Default: %s.\n", us_g_gpio.consumer_prefix);
SAY(" --gpio-prog-running <pin> ───── Set 1 on GPIO pin while uStreamer is running. Default: disabled.\n"); SAY(" --gpio-prog-running <pin> ───── Set 1 on GPIO pin while uStreamer is running. Default: disabled.\n");
SAY(" --gpio-stream-online <pin> ──── Set 1 while streaming. Default: disabled.\n"); SAY(" --gpio-stream-online <pin> ──── Set 1 while streaming. Default: disabled.\n");
SAY(" --gpio-has-http-clients <pin> ─ Set 1 while stream has at least one client. Default: disabled.\n"); SAY(" --gpio-has-http-clients <pin> ─ Set 1 while stream has at least one client. Default: disabled.\n");
@@ -702,7 +702,7 @@ static void _help(FILE *fp, us_device_s *dev, us_encoder_s *enc, us_stream_s *st
SAY(" --log-level <N> ──── Verbosity level of messages from 0 (info) to 3 (debug)."); SAY(" --log-level <N> ──── Verbosity level of messages from 0 (info) to 3 (debug).");
SAY(" Enabling debugging messages can slow down the program."); SAY(" Enabling debugging messages can slow down the program.");
SAY(" Available levels: 0 (info), 1 (performance), 2 (verbose), 3 (debug)."); SAY(" Available levels: 0 (info), 1 (performance), 2 (verbose), 3 (debug).");
SAY(" Default: %d.\n", us_log_level); SAY(" Default: %d.\n", us_g_log_level);
SAY(" --perf ───────────── Enable performance messages (same as --log-level=1). Default: disabled.\n"); SAY(" --perf ───────────── Enable performance messages (same as --log-level=1). Default: disabled.\n");
SAY(" --verbose ────────── Enable verbose messages and lower (same as --log-level=2). Default: disabled.\n"); SAY(" --verbose ────────── Enable verbose messages and lower (same as --log-level=2). Default: disabled.\n");
SAY(" --debug ──────────── Enable debug messages and lower (same as --log-level=3). Default: disabled.\n"); SAY(" --debug ──────────── Enable debug messages and lower (same as --log-level=3). Default: disabled.\n");

View File

@@ -104,7 +104,7 @@ us_worker_s *us_workers_pool_wait(us_workers_pool_s *pool) {
us_worker_s *ready_wr = NULL; us_worker_s *ready_wr = NULL;
US_MUTEX_LOCK(pool->free_workers_mutex); US_MUTEX_LOCK(pool->free_workers_mutex);
US_COND_WAIT_TRUE(pool->free_workers, pool->free_workers_cond, pool->free_workers_mutex); US_COND_WAIT_FOR(pool->free_workers, pool->free_workers_cond, pool->free_workers_mutex);
US_MUTEX_UNLOCK(pool->free_workers_mutex); US_MUTEX_UNLOCK(pool->free_workers_mutex);
if (pool->oldest_wr && !atomic_load(&pool->oldest_wr->has_job)) { if (pool->oldest_wr && !atomic_load(&pool->oldest_wr->has_job)) {
@@ -185,7 +185,7 @@ static void *_worker_thread(void *v_worker) {
US_LOG_DEBUG("Worker %s waiting for a new job ...", wr->name); US_LOG_DEBUG("Worker %s waiting for a new job ...", wr->name);
US_MUTEX_LOCK(wr->has_job_mutex); US_MUTEX_LOCK(wr->has_job_mutex);
US_COND_WAIT_TRUE(atomic_load(&wr->has_job), wr->has_job_cond, wr->has_job_mutex); US_COND_WAIT_FOR(atomic_load(&wr->has_job), wr->has_job_cond, wr->has_job_mutex);
US_MUTEX_UNLOCK(wr->has_job_mutex); US_MUTEX_UNLOCK(wr->has_job_mutex);
if (!atomic_load(&wr->pool->stop)) { if (!atomic_load(&wr->pool->stop)) {