Compare commits

..

11 Commits
test ... v5.51

Author SHA1 Message Date
Maxim Devaev
f0e070be5b Bump version: 5.50 → 5.51 2024-02-19 00:40:14 +02:00
Maxim Devaev
aa05c470b3 string fixes 2024-02-19 00:22:45 +02:00
Maxim Devaev
13af11a3a6 Using strerror_r() instead of strerror_l() for better compatibility 2024-02-18 18:41:33 +02:00
Maxim Devaev
41330940c6 Bump version: 5.49 → 5.50 2024-02-16 17:15:26 +02:00
Maxim Devaev
46e630d2f6 using (void) instead of UNUSED 2024-02-16 01:51:36 +02:00
Maxim Devaev
63d87f0526 add instance_id to stream_client cookie name 2024-02-15 15:52:03 +02:00
Maxim Devaev
b578e9897e notes about libcamerify 2024-02-03 20:14:19 +02:00
Maxim Devaev
b2ebcf99c8 Bump version: 5.48 → 5.49 2024-02-02 22:53:48 +02:00
Maxim Devaev
6a6b910869 refactoring 2024-02-02 22:41:45 +02:00
Maxim Devaev
4e8acf371f Issue #252: YVYU support 2024-02-02 22:41:45 +02:00
Thomer Gil
c4cb8288c7 Fix it's vs its typo (#255)
Co-authored-by: Thomer Gil <thomer@thomer.com>
2024-01-30 18:28:32 +02:00
24 changed files with 98 additions and 104 deletions

View File

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

View File

@@ -151,7 +151,7 @@ Add `-e EDID=1` to set HDMI EDID before starting ustreamer. Use together with `-
-----
# Raspberry Pi Camera Example
Example usage for the Raspberry Pi v3 camera (required `libcamerify` which is located in `libcamera-tools` on Raspbian):
Example usage for the Raspberry Pi v3 camera (required `libcamerify` which is located in `libcamera-tools` and `libcamera-v4l2` (install both) on Raspbian):
```
$ sudo modprobe bcm2835-v4l2
$ libcamerify ./ustreamer --host :: --encoder=m2m-image
@@ -180,7 +180,7 @@ $ modprobe bcm2835-v4l2 max_video_width=2592 max_video_height=1944
µStreamer supports bandwidth-efficient streaming using [H.264 compression](https://en.wikipedia.org/wiki/Advanced_Video_Coding) and the Janus WebRTC server. See the [Janus integration guide](docs/h264.md) for full details.
## Nginx
When uStreamer is behind an Nginx proxy, it's buffering behavior introduces latency into the video stream. It's possible to disable Nginx's buffering to eliminate the additional latency:
When uStreamer is behind an Nginx proxy, its buffering behavior introduces latency into the video stream. It's possible to disable Nginx's buffering to eliminate the additional latency:
```nginx
location /stream {

View File

@@ -99,7 +99,9 @@ static atomic_bool _g_key_required = false;
janus_plugin *create(void);
static void *_video_rtp_thread(UNUSED void *arg) {
static void *_video_rtp_thread(void *arg) {
(void)arg;
US_THREAD_RENAME("us_video_rtp");
atomic_store(&_g_video_rtp_tid_created, true);
@@ -116,7 +118,9 @@ static void *_video_rtp_thread(UNUSED void *arg) {
return NULL;
}
static void *_video_sink_thread(UNUSED void *arg) {
static void *_video_sink_thread(void *arg) {
(void)arg;
US_THREAD_RENAME("us_video_sink");
atomic_store(&_g_video_sink_tid_created, true);
@@ -178,7 +182,9 @@ static void *_video_sink_thread(UNUSED void *arg) {
return NULL;
}
static void *_audio_thread(UNUSED void *arg) {
static void *_audio_thread(void *arg) {
(void)arg;
US_THREAD_RENAME("us_audio");
atomic_store(&_g_audio_tid_created, true);
assert(_g_config->audio_dev_name != NULL);
@@ -344,7 +350,8 @@ static json_t *_plugin_query_session(janus_plugin_session *session) {
return info;
}
static void _set_transmit(janus_plugin_session *session, UNUSED const char *msg, bool transmit) {
static void _set_transmit(janus_plugin_session *session, const char *msg, bool transmit) {
(void)msg;
_IF_DISABLED({ return; });
_LOCK_ALL;
bool found = false;
@@ -503,7 +510,9 @@ static struct janus_plugin_result *_plugin_handle_message(
# undef FREE_MSG_JSEP
}
static void _plugin_incoming_rtcp(UNUSED janus_plugin_session *handle, UNUSED janus_plugin_rtcp *packet) {
static void _plugin_incoming_rtcp(janus_plugin_session *handle, janus_plugin_rtcp *packet) {
(void)handle;
(void)packet;
if (packet->video && janus_rtcp_has_pli(packet->buffer, packet->length)) {
// US_JLOG_INFO("main", "Got video PLI");
atomic_store(&_g_key_required, true);

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.48" "January 2021"
.TH USTREAMER-DUMP 1 "version 5.51" "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.48" "November 2020"
.TH USTREAMER 1 "version 5.51" "November 2020"
.SH NAME
ustreamer \- stream MJPEG video from any V4L2 device to the network
@@ -52,7 +52,7 @@ Initial image resolution. Default: 640x480.
.TP
.BR \-m\ \fIfmt ", " \-\-format\ \fIfmt
Image format.
Available: YUYV, UYVY, RGB565, RGB24, JPEG; default: YUYV.
Available: YUYV, YVYU, UYVY, RGB565, RGB24, JPEG; default: YUYV.
.TP
.BR \-a\ \fIstd ", " \-\-tv\-standard\ \fIstd
Force TV standard.

View File

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

View File

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

View File

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

View File

@@ -99,7 +99,7 @@ static int _MemsinkObject_init(_MemsinkObject *self, PyObject *args, PyObject *k
static PyObject *_MemsinkObject_repr(_MemsinkObject *self) {
char repr[1024];
snprintf(repr, 1023, "<Memsink(%s)>", self->obj);
US_SNPRINTF(repr, 1023, "<Memsink(%s)>", self->obj);
return Py_BuildValue("s", repr);
}

View File

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

View File

@@ -73,6 +73,7 @@ unsigned us_frame_get_padding(const us_frame_s *frame) {
unsigned bytes_per_pixel = 0;
switch (frame->format) {
case V4L2_PIX_FMT_YUYV:
case V4L2_PIX_FMT_YVYU:
case V4L2_PIX_FMT_UYVY:
case V4L2_PIX_FMT_RGB565: bytes_per_pixel = 2; break;
case V4L2_PIX_FMT_BGR24:

View File

@@ -91,7 +91,7 @@ extern pthread_mutex_t us_g_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}; \
char m_tname_buf[US_THREAD_NAME_SIZE] = {0}; \
us_thread_get_name(m_tname_buf); \
if (us_g_log_colored) { \
fprintf(stderr, US_COLOR_GRAY "-- " x_label_color x_label US_COLOR_GRAY \

View File

@@ -41,9 +41,9 @@
#ifdef PTHREAD_MAX_NAMELEN_NP
# define US_MAX_THREAD_NAME ((size_t)(PTHREAD_MAX_NAMELEN_NP))
# define US_THREAD_NAME_SIZE ((size_t)(PTHREAD_MAX_NAMELEN_NP))
#else
# define US_MAX_THREAD_NAME ((size_t)16)
# define US_THREAD_NAME_SIZE ((size_t)16)
#endif
#define US_THREAD_CREATE(x_tid, x_func, x_arg) assert(!pthread_create(&(x_tid), NULL, (x_func), (x_arg)))
@@ -51,8 +51,8 @@
#ifdef WITH_PTHREAD_NP
# define US_THREAD_RENAME(x_fmt, ...) { \
char m_new_tname_buf[US_MAX_THREAD_NAME] = {0}; \
assert(snprintf(m_new_tname_buf, US_MAX_THREAD_NAME, (x_fmt), ##__VA_ARGS__) > 0); \
char m_new_tname_buf[US_THREAD_NAME_SIZE] = {0}; \
US_SNPRINTF(m_new_tname_buf, (US_THREAD_NAME_SIZE - 1), (x_fmt), ##__VA_ARGS__); \
us_thread_set_name(m_new_tname_buf); \
}
#else
@@ -89,12 +89,12 @@ INLINE void us_thread_get_name(char *name) { // Always required for logging
#ifdef WITH_PTHREAD_NP
int retval = -1;
# if defined(__linux__) || defined (__NetBSD__)
retval = pthread_getname_np(pthread_self(), name, US_MAX_THREAD_NAME);
retval = pthread_getname_np(pthread_self(), name, US_THREAD_NAME_SIZE - 1);
# elif \
(defined(__FreeBSD__) && defined(__FreeBSD_version) && __FreeBSD_version >= 1103500) \
|| (defined(__OpenBSD__) && defined(OpenBSD) && OpenBSD >= 201905) \
|| defined(__DragonFly__)
pthread_get_name_np(pthread_self(), name, US_MAX_THREAD_NAME);
pthread_get_name_np(pthread_self(), name, US_THREAD_NAME_SIZE - 1);
if (name[0] != '\0') {
retval = 0;
}
@@ -118,7 +118,7 @@ INLINE void us_thread_get_name(char *name) { // Always required for logging
const pid_t tid = 0; // Makes cppcheck happy
# warning gettid() not implemented
#endif
assert(snprintf(name, US_MAX_THREAD_NAME, "tid=%d", tid) > 0);
US_SNPRINTF(name, (US_THREAD_NAME_SIZE - 1), "tid=%d", tid);
#ifdef WITH_PTHREAD_NP
}

View File

@@ -29,7 +29,6 @@
#include <string.h>
#include <unistd.h>
#include <limits.h>
#include <locale.h>
#include <errno.h>
#include <math.h>
#include <time.h>
@@ -57,14 +56,14 @@
#define RN "\r\n"
#define INLINE inline __attribute__((always_inline))
#define UNUSED __attribute__((unused))
#define US_CALLOC(x_dest, x_nmemb) assert(((x_dest) = calloc((x_nmemb), sizeof(*(x_dest)))) != NULL)
#define US_REALLOC(x_dest, x_nmemb) assert(((x_dest) = realloc((x_dest), (x_nmemb) * sizeof(*(x_dest)))) != NULL)
#define US_DELETE(x_dest, x_free) { if (x_dest) { x_free(x_dest); } }
#define US_MEMSET_ZERO(x_obj) memset(&(x_obj), 0, sizeof(x_obj))
#define US_ASPRINTF(x_dest, x_fmt, ...) assert(asprintf(&(x_dest), (x_fmt), ##__VA_ARGS__) >= 0)
#define US_SNPRINTF(x_dest, x_size, x_fmt, ...) assert(snprintf((x_dest), (x_size), (x_fmt), ##__VA_ARGS__) > 0)
#define US_ASPRINTF(x_dest, x_fmt, ...) assert(asprintf(&(x_dest), (x_fmt), ##__VA_ARGS__) > 0)
INLINE char *us_strdup(const char *str) {
@@ -178,15 +177,16 @@ INLINE int us_flock_timedwait_monotonic(int fd, long double timeout) {
}
INLINE char *us_errno_to_string(int error) {
locale_t locale = newlocale(LC_MESSAGES_MASK, "C", NULL);
char *buf;
if (locale) {
buf = us_strdup(strerror_l(error, locale));
freelocale(locale);
} else {
buf = us_strdup("!!! newlocale() error !!!");
char buf[2048];
const size_t max_len = sizeof(buf) - 1;
# if (_POSIX_C_SOURCE >= 200112L) && ! _GNU_SOURCE
if (strerror_r(error, buf, max_len) != 0) {
US_SNPRINTF(buf, max_len, "Errno = %d", error);
}
return buf;
return us_strdup(buf);
# else
return us_strdup(strerror_r(error, buf, max_len));
# endif
}
INLINE char *us_signum_to_string(int signum) {

View File

@@ -38,6 +38,7 @@ static const struct {
const unsigned format; // cppcheck-suppress unusedStructMember
} _FORMATS[] = {
{"YUYV", V4L2_PIX_FMT_YUYV},
{"YVYU", V4L2_PIX_FMT_YVYU},
{"UYVY", V4L2_PIX_FMT_UYVY},
{"RGB565", V4L2_PIX_FMT_RGB565},
{"RGB24", V4L2_PIX_FMT_RGB24},

View File

@@ -61,7 +61,7 @@
#define US_STANDARDS_STR "PAL, NTSC, SECAM"
#define US_FORMAT_UNKNOWN -1
#define US_FORMATS_STR "YUYV, UYVY, RGB565, RGB24, BGR24, MJPEG, JPEG"
#define US_FORMATS_STR "YUYV, YVYU, UYVY, RGB565, RGB24, BGR24, MJPEG, JPEG"
#define US_IO_METHOD_UNKNOWN -1
#define US_IO_METHODS_STR "MMAP, USERPTR"

View File

@@ -120,7 +120,7 @@ us_workers_pool_s *us_encoder_workers_pool_init(us_encoder_s *enc, us_device_s *
for (; _ER(n_m2ms) < n_workers; ++_ER(n_m2ms)) {
// Начинаем с нуля и доинициализируем на следующих заходах при необходимости
char name[32];
snprintf(name, 32, "JPEG-%u", _ER(n_m2ms));
US_SNPRINTF(name, 31, "JPEG-%u", _ER(n_m2ms));
if (type == US_ENCODER_TYPE_M2M_VIDEO) {
_ER(m2ms[_ER(n_m2ms)]) = us_m2m_mjpeg_encoder_init(name, enc->m2m_path, quality);
} else {

View File

@@ -37,8 +37,7 @@ typedef struct {
static void _jpeg_set_dest_frame(j_compress_ptr jpeg, us_frame_s *frame);
static void _jpeg_write_scanlines_yuyv(struct jpeg_compress_struct *jpeg, const us_frame_s *frame);
static void _jpeg_write_scanlines_uyvy(struct jpeg_compress_struct *jpeg, const us_frame_s *frame);
static void _jpeg_write_scanlines_yuv(struct jpeg_compress_struct *jpeg, const us_frame_s *frame);
static void _jpeg_write_scanlines_rgb565(struct jpeg_compress_struct *jpeg, const us_frame_s *frame);
static void _jpeg_write_scanlines_rgb24(struct jpeg_compress_struct *jpeg, const us_frame_s *frame);
static void _jpeg_write_scanlines_bgr24(struct jpeg_compress_struct *jpeg, const us_frame_s *frame);
@@ -71,21 +70,17 @@ void us_cpu_encoder_compress(const us_frame_s *src, us_frame_s *dest, unsigned q
jpeg_start_compress(&jpeg, TRUE);
# define WRITE_SCANLINES(x_format, x_func) \
case x_format: { x_func(&jpeg, src); break; }
switch (src->format) {
// https://www.fourcc.org/yuv.php
WRITE_SCANLINES(V4L2_PIX_FMT_YUYV, _jpeg_write_scanlines_yuyv);
WRITE_SCANLINES(V4L2_PIX_FMT_UYVY, _jpeg_write_scanlines_uyvy);
WRITE_SCANLINES(V4L2_PIX_FMT_RGB565, _jpeg_write_scanlines_rgb565);
WRITE_SCANLINES(V4L2_PIX_FMT_RGB24, _jpeg_write_scanlines_rgb24);
WRITE_SCANLINES(V4L2_PIX_FMT_BGR24, _jpeg_write_scanlines_bgr24);
default: assert(0 && "Unsupported input format for CPU encoder");
case V4L2_PIX_FMT_YUYV:
case V4L2_PIX_FMT_YVYU:
case V4L2_PIX_FMT_UYVY: _jpeg_write_scanlines_yuv(&jpeg, src); break;
case V4L2_PIX_FMT_RGB565: _jpeg_write_scanlines_rgb565(&jpeg, src); break;
case V4L2_PIX_FMT_RGB24: _jpeg_write_scanlines_rgb24(&jpeg, src); break;
case V4L2_PIX_FMT_BGR24: _jpeg_write_scanlines_bgr24(&jpeg, src); break;
default: assert(0 && "Unsupported input format for CPU encoder"); return;
}
# undef WRITE_SCANLINES
jpeg_finish_compress(&jpeg);
jpeg_destroy_compress(&jpeg);
@@ -108,40 +103,7 @@ static void _jpeg_set_dest_frame(j_compress_ptr jpeg, us_frame_s *frame) {
frame->used = 0;
}
static void _jpeg_write_scanlines_yuyv(struct jpeg_compress_struct *jpeg, const us_frame_s *frame) {
uint8_t *line_buf;
US_CALLOC(line_buf, frame->width * 3);
const unsigned padding = us_frame_get_padding(frame);
const uint8_t *data = frame->data;
while (jpeg->next_scanline < frame->height) {
uint8_t *ptr = line_buf;
for (unsigned x = 0; x < frame->width; ++x) {
// See also: https://www.kernel.org/doc/html/v4.8/media/uapi/v4l/pixfmt-yuyv.html
const bool is_odd_pixel = x & 1;
const uint8_t y = data[is_odd_pixel ? 2 : 0];
const uint8_t u = data[1];
const uint8_t v = data[3];
ptr[0] = y;
ptr[1] = u;
ptr[2] = v;
ptr += 3;
data += (is_odd_pixel ? 4: 0);
}
data += padding;
JSAMPROW scanlines[1] = {line_buf};
jpeg_write_scanlines(jpeg, scanlines, 1);
}
free(line_buf);
}
static void _jpeg_write_scanlines_uyvy(struct jpeg_compress_struct *jpeg, const us_frame_s *frame) {
static void _jpeg_write_scanlines_yuv(struct jpeg_compress_struct *jpeg, const us_frame_s *frame) {
uint8_t *line_buf;
US_CALLOC(line_buf, frame->width * 3);
@@ -154,9 +116,23 @@ static void _jpeg_write_scanlines_uyvy(struct jpeg_compress_struct *jpeg, const
for (unsigned x = 0; x < frame->width; ++x) {
// See also: https://www.kernel.org/doc/html/v4.8/media/uapi/v4l/pixfmt-uyvy.html
const bool is_odd_pixel = x & 1;
const uint8_t y = data[is_odd_pixel ? 3 : 1];
const uint8_t u = data[0];
const uint8_t v = data[2];
uint8_t y, u, v;
if (frame->format == V4L2_PIX_FMT_YUYV) {
y = data[is_odd_pixel ? 2 : 0];
u = data[1];
v = data[3];
} else if (frame->format == V4L2_PIX_FMT_YVYU) {
y = data[is_odd_pixel ? 2 : 0];
u = data[3];
v = data[1];
} else if (frame->format == V4L2_PIX_FMT_UYVY) {
y = data[is_odd_pixel ? 3 : 1];
u = data[0];
v = data[2];
} else {
assert(0 && "Unsupported pixel format");
return; // Makes linter happy
}
ptr[0] = y;
ptr[1] = u;

View File

@@ -31,7 +31,7 @@ char *us_bufferevent_format_reason(short what) {
char *const perror_str = us_errno_to_string(EVUTIL_SOCKET_ERROR());
bool first = true;
strcat(reason, perror_str);
strncat(reason, perror_str, 1023);
free(perror_str);
strcat(reason, " (");

View File

@@ -502,12 +502,12 @@ static void _http_callback_snapshot(struct evhttp_request *request, void *v_serv
char header_buf[256];
# define ADD_TIME_HEADER(x_key, x_value) { \
snprintf(header_buf, 255, "%.06Lf", x_value); \
US_SNPRINTF(header_buf, 255, "%.06Lf", x_value); \
ADD_HEADER(x_key, header_buf); \
}
# define ADD_UNSIGNED_HEADER(x_key, x_value) { \
snprintf(header_buf, 255, "%u", x_value); \
US_SNPRINTF(header_buf, 255, "%u", x_value); \
ADD_HEADER(x_key, header_buf); \
}
@@ -667,10 +667,12 @@ static void _http_callback_stream_write(struct bufferevent *buf_event, void *v_c
"Cache-Control: no-store, no-cache, must-revalidate, proxy-revalidate, pre-check=0, post-check=0, max-age=0" RN
"Pragma: no-cache" RN
"Expires: Mon, 3 Jan 2000 12:34:56 GMT" RN
"Set-Cookie: stream_client=%s/%" PRIx64 "; path=/; max-age=30" RN
"Set-Cookie: stream_client%s%s=%s/%" PRIx64 "; path=/; max-age=30" RN
"Content-Type: multipart/x-mixed-replace;boundary=" BOUNDARY RN
RN
"--" BOUNDARY RN,
(server->instance_id[0] == '\0' ? "" : "_"),
server->instance_id,
(client->key != NULL ? client->key : "0"),
client->id
);
@@ -745,7 +747,10 @@ static void _http_callback_stream_write(struct bufferevent *buf_event, void *v_c
# undef BOUNDARY
}
static void _http_callback_stream_error(UNUSED struct bufferevent *buf_event, UNUSED short what, void *v_client) {
static void _http_callback_stream_error(struct bufferevent *buf_event, short what, void *v_client) {
(void)buf_event;
(void)what;
us_stream_client_s *const client = (us_stream_client_s *)v_client;
us_server_s *const server = client->server;
@@ -823,7 +828,10 @@ static void _http_queue_send_stream(us_server_s *server, bool stream_updated, bo
}
}
static void _http_request_watcher(UNUSED int fd, UNUSED short what, void *v_server) {
static void _http_request_watcher(int fd, short what, void *v_server) {
(void)fd;
(void)what;
us_server_s *server = (us_server_s *)v_server;
const long double now = us_get_now_monotonic();
@@ -837,7 +845,10 @@ static void _http_request_watcher(UNUSED int fd, UNUSED short what, void *v_serv
}
}
static void _http_refresher(UNUSED int fd, UNUSED short what, void *v_server) {
static void _http_refresher(int fd, short what, void *v_server) {
(void)fd;
(void)what;
us_server_s *server = (us_server_s *)v_server;
bool stream_updated = false;
bool frame_updated = false;

View File

@@ -33,7 +33,7 @@ char *us_find_static_file_path(const char *root_path, const char *request_path)
}
US_CALLOC(path, strlen(root_path) + strlen(simplified_path) + 16); // + reserved for /index.html
sprintf(path, "%s/%s", root_path, simplified_path);
assert(sprintf(path, "%s/%s", root_path, simplified_path) > 0);
struct stat st;
# define LOAD_STAT { \

View File

@@ -26,6 +26,7 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <assert.h>
#include <sys/stat.h>

View File

@@ -441,14 +441,7 @@ static int _m2m_encoder_compress_raw(us_m2m_encoder_s *enc, const us_frame_s *sr
// Для не-DMA отправка буфера по факту являтся освобождением этого буфера
bool input_released = !_RUN(dma);
const long double deadline_ts = us_get_now_monotonic() + 1;
while (true) {
if (us_get_now_monotonic() > deadline_ts) {
_E_LOG_ERROR("The encoder wait is too long");
goto error;
}
struct pollfd enc_poll = {_RUN(fd), POLLIN, 0};
_E_LOG_DEBUG("Polling encoder ...");

View File

@@ -52,14 +52,16 @@ static void _block_thread_signals(void) {
assert(!pthread_sigmask(SIG_BLOCK, &mask, NULL));
}
static void *_stream_loop_thread(UNUSED void *arg) {
static void *_stream_loop_thread(void *arg) {
(void)arg;
US_THREAD_RENAME("stream");
_block_thread_signals();
us_stream_loop(_g_stream);
return NULL;
}
static void *_server_loop_thread(UNUSED void *arg) {
static void *_server_loop_thread(void *arg) {
(void)arg;
US_THREAD_RENAME("http");
_block_thread_signals();
us_server_loop(_g_server);