Compare commits

...

12 Commits
v5.17 ... v5.20

Author SHA1 Message Date
Maxim Devaev
4ec02d46b9 Bump version: 5.19 → 5.20 2022-08-17 17:59:16 +03:00
Maxim Devaev
527afb66df fixed arch deps 2022-08-17 17:55:59 +03:00
Maxim Devaev
5502758a7e Bump version: 5.18 → 5.19 2022-07-30 13:10:16 +03:00
Maxim Devaev
faa1776407 simplified us_errno_to_string() 2022-07-30 13:05:00 +03:00
Maxim Devaev
3d7fb8c8dd fixed #162: optional sigabbrev_np() 2022-07-30 02:59:21 +03:00
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
20 changed files with 148 additions and 132 deletions

View File

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

View File

@@ -32,7 +32,7 @@
#define US_JLOG_ERROR(x_prefix, x_msg, ...) JANUS_LOG(LOG_ERR, "== %s/%-9s -- " x_msg "\n", US_PLUGIN_NAME, x_prefix, ##__VA_ARGS__)
#define US_JLOG_PERROR(x_prefix, x_msg, ...) { \
char m_perror_buf[1024] = {0}; \
char *m_perror_ptr = us_errno_to_string(errno, m_perror_buf, 1023); \
JANUS_LOG(LOG_ERR, "[%s/%-9s] " x_msg ": %s\n", US_PLUGIN_NAME, x_prefix, ##__VA_ARGS__, m_perror_ptr); \
char *const m_perror_str = us_errno_to_string(errno); \
JANUS_LOG(LOG_ERR, "[%s/%-9s] " x_msg ": %s\n", US_PLUGIN_NAME, x_prefix, ##__VA_ARGS__, m_perror_str); \
free(m_perror_str); \
}

View File

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

View File

@@ -1,6 +1,6 @@
.\" Manpage for ustreamer-dump.
.\" 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.20" "January 2021"
.SH NAME
ustreamer-dump \- Dump uStreamer's memory sink to file

View File

@@ -1,6 +1,6 @@
.\" Manpage for ustreamer.
.\" 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.20" "November 2020"
.SH NAME
ustreamer \- stream MJPEG video from any V4L2 device to the network

View File

@@ -3,7 +3,7 @@
pkgname=ustreamer
pkgver=5.17
pkgver=5.20
pkgrel=1
pkgdesc="Lightweight and fast MJPEG-HTTP streamer"
url="https://github.com/pikvm/ustreamer"
@@ -22,8 +22,8 @@ if [ -e /usr/bin/python3 ]; then
makedepends+=(python-setuptools)
fi
if [ -e /usr/include/janus/plugins/plugin.h ];then
depends+=(janus-gateway-pikvm alsa-lib opus)
makedepends+=(janus-gateway-pikvm alsa-lib opus)
depends+=(janus-gateway alsa-lib opus)
makedepends+=(janus-gateway alsa-lib opus)
_options="$_options WITH_JANUS=1"
fi

View File

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

View File

@@ -19,7 +19,7 @@ def _find_sources(suffix: str) -> List[str]:
if __name__ == "__main__":
setup(
name="ustreamer",
version="5.17",
version="5.20",
description="uStreamer tools",
author="Maxim Devaev",
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_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_PERF: OPT_SET(us_log_level, US_LOG_LEVEL_PERF);
case _O_VERBOSE: OPT_SET(us_log_level, US_LOG_LEVEL_VERBOSE);
case _O_DEBUG: OPT_SET(us_log_level, US_LOG_LEVEL_DEBUG);
case _O_FORCE_LOG_COLORS: OPT_SET(us_log_colored, true);
case _O_NO_LOG_COLORS: OPT_SET(us_log_colored, false);
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_g_log_level, US_LOG_LEVEL_PERF);
case _O_VERBOSE: OPT_SET(us_g_log_level, US_LOG_LEVEL_VERBOSE);
case _O_DEBUG: OPT_SET(us_g_log_level, US_LOG_LEVEL_DEBUG);
case _O_FORCE_LOG_COLORS: OPT_SET(us_g_log_colored, true);
case _O_NO_LOG_COLORS: OPT_SET(us_g_log_colored, false);
case _O_HELP: _help(stdout); return 0;
case _O_VERSION: puts(US_VERSION); return 0;
@@ -195,12 +195,9 @@ int main(int argc, char *argv[]) {
static void _signal_handler(int signum) {
switch (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;
}
char *const name = us_signum_to_string(signum);
US_LOG_INFO_NOLOCK("===== Stopping by %s =====", name);
free(name);
_g_stop = true;
}
@@ -330,7 +327,7 @@ static void _help(FILE *fp) {
SAY(" --log-level <N> ──── Verbosity level of messages from 0 (info) to 3 (debug).");
SAY(" Enabling debugging messages can slow down the program.");
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(" --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");

View File

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

View File

@@ -23,8 +23,8 @@
#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 { \
us_log_level = US_LOG_LEVEL_INFO; \
us_log_colored = isatty(2); \
US_MUTEX_INIT(us_log_mutex); \
us_g_log_level = US_LOG_LEVEL_INFO; \
us_g_log_colored = isatty(2); \
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_UNLOCK US_MUTEX_UNLOCK(us_log_mutex)
#define US_LOGGING_LOCK US_MUTEX_LOCK(us_g_log_mutex)
#define US_LOGGING_UNLOCK US_MUTEX_UNLOCK(us_g_log_mutex)
#define US_COLOR_GRAY "\x1b[30;1m"
@@ -84,7 +84,7 @@ extern pthread_mutex_t us_log_mutex;
}
#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); \
} \
}
@@ -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, ...) { \
char m_tname_buf[US_MAX_THREAD_NAME] = {0}; \
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 \
" [%.03Lf %9s]" " -- " US_COLOR_RESET x_msg_color x_msg US_COLOR_RESET, \
us_get_now_monotonic(), m_tname_buf, ##__VA_ARGS__); \
@@ -116,9 +116,9 @@ extern pthread_mutex_t us_log_mutex;
}
#define US_LOG_PERROR(x_msg, ...) { \
char m_perror_buf[1024] = {0}; \
char *m_perror_ptr = us_errno_to_string(errno, m_perror_buf, 1024); \
US_LOG_ERROR(x_msg ": %s", ##__VA_ARGS__, m_perror_ptr); \
char *const m_perror_str = us_errno_to_string(errno); \
US_LOG_ERROR(x_msg ": %s", ##__VA_ARGS__, m_perror_str); \
free(m_perror_str); \
}
#define US_LOG_INFO(x_msg, ...) { \
@@ -130,33 +130,33 @@ extern pthread_mutex_t us_log_mutex;
}
#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__); \
} \
}
#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__); \
} \
}
#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__); \
} \
}
#define US_LOG_VERBOSE_PERROR(x_msg, ...) { \
if (us_log_level >= US_LOG_LEVEL_VERBOSE) { \
char m_perror_buf[1024] = {0}; \
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); \
if (us_g_log_level >= US_LOG_LEVEL_VERBOSE) { \
char *m_perror_str = us_errno_to_string(errno); \
US_LOG_PRINTF(US_COLOR_BLUE, "VERB ", US_COLOR_BLUE, x_msg ": %s", ##__VA_ARGS__, m_perror_str); \
free(m_perror_str); \
} \
}
#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__); \
} \
}

View File

@@ -67,7 +67,8 @@
#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_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

View File

@@ -38,6 +38,12 @@
#include <sys/types.h>
#include <sys/file.h>
#if defined(__GLIBC__) && __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 32
# define HAS_SIGABBREV_NP
#else
# include <signal.h>
#endif
#ifdef NDEBUG
# error WTF dude? Asserts are good things!
@@ -181,15 +187,34 @@ INLINE int us_flock_timedwait_monotonic(int fd, long double timeout) {
return retval;
}
INLINE char *us_errno_to_string(int error, char *buf, size_t size) {
assert(buf != NULL);
assert(size > 0);
INLINE char *us_errno_to_string(int error) {
locale_t locale = newlocale(LC_MESSAGES_MASK, "C", NULL);
const char *str = "!!! newlocale() error !!!";
strncpy(buf, (locale ? strerror_l(error, locale) : str), size - 1);
buf[size - 1] = '\0';
char *buf;
if (locale) {
buf = us_strdup(strerror_l(error, locale));
freelocale(locale);
} else {
buf = us_strdup("!!! newlocale() error !!!");
}
return buf;
}
INLINE char *us_signum_to_string(int signum) {
# ifdef HAS_SIGABBREV_NP
const char *const name = sigabbrev_np(signum);
# else
const char *const name = (
signum == SIGTERM ? "TERM" :
signum == SIGINT ? "INT" :
signum == SIGPIPE ? "PIPE" :
NULL
);
# endif
char *buf;
if (name != NULL) {
US_ASPRINTF(buf, "SIG%s", name);
} else {
US_ASPRINTF(buf, "SIG[%d]", signum);
}
return buf;
}

View File

@@ -23,7 +23,7 @@
#include "gpio.h"
us_gpio_s us_gpio = {
us_gpio_s us_g_gpio = {
.path = "/dev/gpiochip0",
.consumer_prefix = "ustreamer",
@@ -51,42 +51,42 @@ static void _gpio_output_destroy(us_gpio_output_s *output);
void us_gpio_init(void) {
assert(us_gpio.chip == NULL);
assert(us_g_gpio.chip == NULL);
if (
us_gpio.prog_running.pin >= 0
|| us_gpio.stream_online.pin >= 0
|| us_gpio.has_http_clients.pin >= 0
us_g_gpio.prog_running.pin >= 0
|| us_g_gpio.stream_online.pin >= 0
|| us_g_gpio.has_http_clients.pin >= 0
) {
US_MUTEX_INIT(us_gpio.mutex);
US_LOG_INFO("GPIO: Using chip device: %s", us_gpio.path);
if ((us_gpio.chip = gpiod_chip_open(us_gpio.path)) != NULL) {
_gpio_output_init(&us_gpio.prog_running);
_gpio_output_init(&us_gpio.stream_online);
_gpio_output_init(&us_gpio.has_http_clients);
US_MUTEX_INIT(us_g_gpio.mutex);
US_LOG_INFO("GPIO: Using chip device: %s", us_g_gpio.path);
if ((us_g_gpio.chip = gpiod_chip_open(us_g_gpio.path)) != NULL) {
_gpio_output_init(&us_g_gpio.prog_running);
_gpio_output_init(&us_g_gpio.stream_online);
_gpio_output_init(&us_g_gpio.has_http_clients);
} 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) {
_gpio_output_destroy(&us_gpio.prog_running);
_gpio_output_destroy(&us_gpio.stream_online);
_gpio_output_destroy(&us_gpio.has_http_clients);
if (us_gpio.chip != NULL) {
gpiod_chip_close(us_gpio.chip);
us_gpio.chip = NULL;
US_MUTEX_DESTROY(us_gpio.mutex);
_gpio_output_destroy(&us_g_gpio.prog_running);
_gpio_output_destroy(&us_g_gpio.stream_online);
_gpio_output_destroy(&us_g_gpio.has_http_clients);
if (us_g_gpio.chip != NULL) {
gpiod_chip_close(us_g_gpio.chip);
us_g_gpio.chip = NULL;
US_MUTEX_DESTROY(us_g_gpio.mutex);
}
}
int us_gpio_inner_set(us_gpio_output_s *output, bool state) {
int retval = 0;
assert(us_gpio.chip != NULL);
assert(us_g_gpio.chip != NULL);
assert(output->line != NULL);
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) { \
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;
}
US_MUTEX_UNLOCK(us_gpio.mutex);
US_MUTEX_UNLOCK(us_g_gpio.mutex);
return retval;
}
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);
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->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) {
US_LOG_PERROR("GPIO: Can't request pin=%d as %s", output->pin, output->consumer);
_gpio_output_destroy(output);

View File

@@ -56,7 +56,7 @@ typedef struct {
} us_gpio_s;
extern us_gpio_s us_gpio;
extern us_gpio_s us_g_gpio;
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) {
SET_STATE(us_gpio.prog_running, state);
SET_STATE(us_g_gpio.prog_running, 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) {
SET_STATE(us_gpio.has_http_clients, state);
SET_STATE(us_g_gpio.has_http_clients, state);
}
#undef SET_STATE

View File

@@ -28,11 +28,11 @@ char *us_bufferevent_format_reason(short what) {
US_CALLOC(reason, 2048);
// evutil_socket_error_to_string() is not thread-safe
char perror_buf[1024] = {0};
const char *perror_ptr = us_errno_to_string(EVUTIL_SOCKET_ERROR(), perror_buf, 1024);
char *const perror_str = us_errno_to_string(EVUTIL_SOCKET_ERROR());
bool first = true;
strcat(reason, perror_ptr);
strcat(reason, perror_str);
free(perror_str);
strcat(reason, " (");
# define FILL_REASON(x_bev, x_name) { \

View File

@@ -40,12 +40,9 @@
#endif
typedef struct {
us_stream_s *stream;
us_server_s *server;
} _main_context_s;
static us_stream_s *_g_stream = NULL;
static us_server_s *_g_server = NULL;
static _main_context_s *_ctx;
static void _block_thread_signals(void) {
sigset_t mask;
@@ -58,25 +55,23 @@ static void _block_thread_signals(void) {
static void *_stream_loop_thread(UNUSED void *arg) {
US_THREAD_RENAME("stream");
_block_thread_signals();
us_stream_loop(_ctx->stream);
us_stream_loop(_g_stream);
return NULL;
}
static void *_server_loop_thread(UNUSED void *arg) {
US_THREAD_RENAME("http");
_block_thread_signals();
us_server_loop(_ctx->server);
us_server_loop(_g_server);
return NULL;
}
static void _signal_handler(int signum) {
switch (signum) {
case SIGTERM: US_LOG_INFO_NOLOCK("===== Stopping by SIGTERM ====="); break;
case SIGINT: US_LOG_INFO_NOLOCK("===== Stopping by SIGINT ====="); break;
default: US_LOG_INFO_NOLOCK("===== Stopping by %d =====", signum); break;
}
us_stream_loop_break(_ctx->stream);
us_server_loop_break(_ctx->server);
char *const name = us_signum_to_string(signum);
US_LOG_INFO_NOLOCK("===== Stopping by %s =====", name);
free(name);
us_stream_loop_break(_g_stream);
us_server_loop_break(_g_server);
}
static void _install_signal_handlers(void) {
@@ -107,22 +102,17 @@ int main(int argc, char *argv[]) {
us_options_s *options = us_options_init(argc, argv);
us_device_s *dev = us_device_init();
us_encoder_s *enc = us_encoder_init();
us_stream_s *stream = us_stream_init(dev, enc);
us_server_s *server = us_server_init(stream);
_g_stream = us_stream_init(dev, enc);
_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
us_gpio_init();
# endif
_install_signal_handlers();
_main_context_s ctx;
ctx.stream = stream;
ctx.server = server;
_ctx = &ctx;
if ((exit_code = us_server_listen(server)) == 0) {
if ((exit_code = us_server_listen(_g_server)) == 0) {
# ifdef WITH_GPIO
us_gpio_set_prog_running(true);
# endif
@@ -141,8 +131,8 @@ int main(int argc, char *argv[]) {
# endif
}
us_server_destroy(server);
us_stream_destroy(stream);
us_server_destroy(_g_server);
us_stream_destroy(_g_stream);
us_encoder_destroy(enc);
us_device_destroy(dev);
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
# ifdef WITH_GPIO
case _O_GPIO_DEVICE: OPT_SET(us_gpio.path, optarg);
case _O_GPIO_CONSUMER_PREFIX: OPT_SET(us_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_STREAM_ONLINE: OPT_NUMBER("--gpio-stream-online", us_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_DEVICE: OPT_SET(us_g_gpio.path, 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_g_gpio.prog_running.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_g_gpio.has_http_clients.pin, 0, 256, 0);
# endif
# ifdef HAS_PDEATHSIG
@@ -457,12 +457,12 @@ int options_parse(us_options_s *options, us_device_s *dev, us_encoder_s *enc, us
# endif
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_PERF: OPT_SET(us_log_level, US_LOG_LEVEL_PERF);
case _O_VERBOSE: OPT_SET(us_log_level, US_LOG_LEVEL_VERBOSE);
case _O_DEBUG: OPT_SET(us_log_level, US_LOG_LEVEL_DEBUG);
case _O_FORCE_LOG_COLORS: OPT_SET(us_log_colored, true);
case _O_NO_LOG_COLORS: OPT_SET(us_log_colored, false);
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_g_log_level, US_LOG_LEVEL_PERF);
case _O_VERBOSE: OPT_SET(us_g_log_level, US_LOG_LEVEL_VERBOSE);
case _O_DEBUG: OPT_SET(us_g_log_level, US_LOG_LEVEL_DEBUG);
case _O_FORCE_LOG_COLORS: OPT_SET(us_g_log_colored, true);
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_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
SAY("GPIO options:");
SAY("═════════════");
SAY(" --gpio-device </dev/path> ───── Path to GPIO character device. Default: %s.\n", us_gpio.path);
SAY(" --gpio-consumer-prefix <str> ── Consumer prefix for GPIO outputs. Default: %s.\n", us_gpio.consumer_prefix);
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_g_gpio.consumer_prefix);
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-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(" Enabling debugging messages can slow down the program.");
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(" --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");

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_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);
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_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);
if (!atomic_load(&wr->pool->stop)) {