Compare commits

..

7 Commits
v5.46 ... test

Author SHA1 Message Date
Maxim Devaev
848f52c69e issue #253: m2m polling limit 2024-01-21 04:19:34 +02:00
Maxim Devaev
2dddb879bc Bump version: 5.47 → 5.48 2024-01-09 00:12:23 +02:00
Maxim Devaev
4d92dc662c removed some checks in gpio 2024-01-09 00:11:11 +02:00
Maxim Devaev
3cb649d97c Bump version: 5.46 → 5.47 2024-01-07 04:48:07 +02:00
Maxim Devaev
d9b5f2b03d Issue #255: libgpiod 2.0 API supported
Thanks for @jpalus for #249 with compatibility code
2024-01-07 04:36:53 +02:00
Jan Palus
2997906d98 add option to make verbose builds (#251)
if V=1 is passed to make echo invoked command verbosely
2024-01-02 02:27:12 +02:00
Jan Palus
bcd3deaa13 remove remainings of rpi vc paths (#250)
accidently left after Makefile split and subsequently switching to v4l2
based encoding
2024-01-02 02:24:37 +02:00
14 changed files with 109 additions and 43 deletions

View File

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

View File

@@ -9,9 +9,6 @@ PY ?= python3
CFLAGS ?= -O3 CFLAGS ?= -O3
LDFLAGS ?= LDFLAGS ?=
RPI_VC_HEADERS ?= /opt/vc/include
RPI_VC_LIBS ?= /opt/vc/lib
export export
_LINTERS_IMAGE ?= ustreamer-linters _LINTERS_IMAGE ?= ustreamer-linters
@@ -22,6 +19,9 @@ define optbool
$(filter $(shell echo $(1) | tr A-Z a-z), yes on 1) $(filter $(shell echo $(1) | tr A-Z a-z), yes on 1)
endef endef
ifeq ($(V),)
ECHO = @
endif
# ===== # =====
all: all:
@@ -36,18 +36,18 @@ endif
apps: apps:
$(MAKE) -C src $(MAKE) -C src
@ ln -sf src/ustreamer.bin ustreamer $(ECHO) ln -sf src/ustreamer.bin ustreamer
@ ln -sf src/ustreamer-dump.bin ustreamer-dump $(ECHO) ln -sf src/ustreamer-dump.bin ustreamer-dump
python: python:
$(MAKE) -C python $(MAKE) -C python
@ ln -sf python/build/lib.*/*.so . $(ECHO) ln -sf python/build/lib.*/*.so .
janus: janus:
$(MAKE) -C janus $(MAKE) -C janus
@ ln -sf janus/*.so . $(ECHO) ln -sf janus/*.so .
install: all install: all

View File

@@ -31,13 +31,13 @@ endif
# ===== # =====
$(_PLUGIN): $(_SRCS:%.c=$(_BUILD)/%.o) $(_PLUGIN): $(_SRCS:%.c=$(_BUILD)/%.o)
$(info == SO $@) $(info == SO $@)
@ $(CC) $^ -o $@ $(_LDFLAGS) $(ECHO) $(CC) $^ -o $@ $(_LDFLAGS)
$(_BUILD)/%.o: %.c $(_BUILD)/%.o: %.c
$(info -- CC $<) $(info -- CC $<)
@ mkdir -p $(dir $@) || true $(ECHO) mkdir -p $(dir $@) || true
@ $(CC) $< -o $@ $(_CFLAGS) $(ECHO) $(CC) $< -o $@ $(_CFLAGS)

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.46" "January 2021" .TH USTREAMER-DUMP 1 "version 5.48" "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.46" "November 2020" .TH USTREAMER 1 "version 5.48" "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.46 pkgver=5.48
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.46 PKG_VERSION:=5.48
PKG_RELEASE:=1 PKG_RELEASE:=1
PKG_MAINTAINER:=Maxim Devaev <mdevaev@gmail.com> PKG_MAINTAINER:=Maxim Devaev <mdevaev@gmail.com>

View File

@@ -9,7 +9,7 @@ PY ?= python3
# ===== # =====
all: all:
$(info == PY_BUILD ustreamer-*.so) $(info == PY_BUILD ustreamer-*.so)
@ $(PY) setup.py build $(ECHO) $(PY) setup.py build
install: install:

View File

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

View File

@@ -42,7 +42,7 @@ endef
ifneq ($(call optbool,$(WITH_GPIO)),) ifneq ($(call optbool,$(WITH_GPIO)),)
_USTR_LIBS += -lgpiod _USTR_LIBS += -lgpiod
override _CFLAGS += -DWITH_GPIO override _CFLAGS += -DWITH_GPIO $(shell pkg-config --atleast-version=2 libgpiod 2> /dev/null && echo -DHAVE_GPIOD2)
_USTR_SRCS += $(shell ls ustreamer/gpio/*.c) _USTR_SRCS += $(shell ls ustreamer/gpio/*.c)
endif endif
@@ -86,18 +86,18 @@ install-strip: install
$(_USTR): $(_USTR_SRCS:%.c=$(_BUILD)/%.o) $(_USTR): $(_USTR_SRCS:%.c=$(_BUILD)/%.o)
$(info == LD $@) $(info == LD $@)
@ $(CC) $^ -o $@ $(_LDFLAGS) $(_USTR_LIBS) $(ECHO) $(CC) $^ -o $@ $(_LDFLAGS) $(_USTR_LIBS)
$(_DUMP): $(_DUMP_SRCS:%.c=$(_BUILD)/%.o) $(_DUMP): $(_DUMP_SRCS:%.c=$(_BUILD)/%.o)
$(info == LD $@) $(info == LD $@)
@ $(CC) $^ -o $@ $(_LDFLAGS) $(_DUMP_LIBS) $(ECHO) $(CC) $^ -o $@ $(_LDFLAGS) $(_DUMP_LIBS)
$(_BUILD)/%.o: %.c $(_BUILD)/%.o: %.c
$(info -- CC $<) $(info -- CC $<)
@ mkdir -p $(dir $@) || true $(ECHO) mkdir -p $(dir $@) || true
@ $(CC) $< -o $@ $(_CFLAGS) $(ECHO) $(CC) $< -o $@ $(_CFLAGS)
clean: clean:

View File

@@ -23,7 +23,7 @@
#pragma once #pragma once
#define US_VERSION_MAJOR 5 #define US_VERSION_MAJOR 5
#define US_VERSION_MINOR 46 #define US_VERSION_MINOR 48
#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

@@ -34,24 +34,26 @@ us_gpio_s us_g_gpio = {
.line = NULL, \ .line = NULL, \
.state = false \ .state = false \
} }
.prog_running = MAKE_OUTPUT("prog-running"), .prog_running = MAKE_OUTPUT("prog-running"),
.stream_online = MAKE_OUTPUT("stream-online"), .stream_online = MAKE_OUTPUT("stream-online"),
.has_http_clients = MAKE_OUTPUT("has-http-clients"), .has_http_clients = MAKE_OUTPUT("has-http-clients"),
# undef MAKE_OUTPUT # undef MAKE_OUTPUT
// mutex uninitialized # ifndef HAVE_GPIOD2
.chip = NULL .chip = NULL,
# endif
.initialized = false,
}; };
static void _gpio_output_init(us_gpio_output_s *output); static void _gpio_output_init(us_gpio_output_s *output, struct gpiod_chip *chip);
static void _gpio_output_destroy(us_gpio_output_s *output); static void _gpio_output_destroy(us_gpio_output_s *output);
void us_gpio_init(void) { void us_gpio_init(void) {
# ifndef HAVE_GPIOD2
assert(us_g_gpio.chip == NULL); assert(us_g_gpio.chip == NULL);
# endif
if ( if (
us_g_gpio.prog_running.pin >= 0 us_g_gpio.prog_running.pin >= 0
|| us_g_gpio.stream_online.pin >= 0 || us_g_gpio.stream_online.pin >= 0
@@ -59,10 +61,17 @@ void us_gpio_init(void) {
) { ) {
US_MUTEX_INIT(us_g_gpio.mutex); US_MUTEX_INIT(us_g_gpio.mutex);
US_LOG_INFO("GPIO: Using chip device: %s", us_g_gpio.path); 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) { struct gpiod_chip *chip;
_gpio_output_init(&us_g_gpio.prog_running); if ((chip = gpiod_chip_open(us_g_gpio.path)) != NULL) {
_gpio_output_init(&us_g_gpio.stream_online); _gpio_output_init(&us_g_gpio.prog_running, chip);
_gpio_output_init(&us_g_gpio.has_http_clients); _gpio_output_init(&us_g_gpio.stream_online, chip);
_gpio_output_init(&us_g_gpio.has_http_clients, chip);
# ifdef HAVE_GPIOD2
gpiod_chip_close(chip);
# else
us_g_gpio.chip = chip;
# endif
us_g_gpio.initialized = true;
} else { } else {
US_LOG_PERROR("GPIO: Can't initialize chip device %s", us_g_gpio.path); US_LOG_PERROR("GPIO: Can't initialize chip device %s", us_g_gpio.path);
} }
@@ -73,23 +82,32 @@ void us_gpio_destroy(void) {
_gpio_output_destroy(&us_g_gpio.prog_running); _gpio_output_destroy(&us_g_gpio.prog_running);
_gpio_output_destroy(&us_g_gpio.stream_online); _gpio_output_destroy(&us_g_gpio.stream_online);
_gpio_output_destroy(&us_g_gpio.has_http_clients); _gpio_output_destroy(&us_g_gpio.has_http_clients);
if (us_g_gpio.chip != NULL) { if (us_g_gpio.initialized) {
# ifndef HAVE_GPIOD2
gpiod_chip_close(us_g_gpio.chip); gpiod_chip_close(us_g_gpio.chip);
us_g_gpio.chip = NULL; us_g_gpio.chip = NULL;
# endif
US_MUTEX_DESTROY(us_g_gpio.mutex); US_MUTEX_DESTROY(us_g_gpio.mutex);
us_g_gpio.initialized = false;
} }
} }
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;
# ifndef HAVE_GPIOD2
assert(us_g_gpio.chip != NULL); assert(us_g_gpio.chip != NULL);
# endif
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_g_gpio.mutex); US_MUTEX_LOCK(us_g_gpio.mutex);
if (gpiod_line_set_value(output->line, (int)state) < 0) { \ # ifdef HAVE_GPIOD2
US_LOG_PERROR("GPIO: Can't write value %d to line %s (will be disabled)", state, output->consumer); \ if (gpiod_line_request_set_value(output->line, output->pin, state) < 0) {
# else
if (gpiod_line_set_value(output->line, (int)state) < 0) {
# endif
US_LOG_PERROR("GPIO: Can't write value %d to line %s", state, output->consumer); \
_gpio_output_destroy(output); _gpio_output_destroy(output);
retval = -1; retval = -1;
} }
@@ -98,14 +116,42 @@ int us_gpio_inner_set(us_gpio_output_s *output, bool state) {
return retval; return retval;
} }
static void _gpio_output_init(us_gpio_output_s *output) { static void _gpio_output_init(us_gpio_output_s *output, struct gpiod_chip *chip) {
assert(us_g_gpio.chip != NULL);
assert(output->line == NULL); assert(output->line == NULL);
US_ASPRINTF(output->consumer, "%s::%s", us_g_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_g_gpio.chip, output->pin)) != NULL) { # ifdef HAVE_GPIOD2
struct gpiod_line_settings *line_settings;
assert(line_settings = gpiod_line_settings_new());
assert(!gpiod_line_settings_set_direction(line_settings, GPIOD_LINE_DIRECTION_OUTPUT));
assert(!gpiod_line_settings_set_output_value(line_settings, false));
struct gpiod_line_config *line_config;
assert(line_config = gpiod_line_config_new());
const unsigned offset = output->pin;
assert(!gpiod_line_config_add_line_settings(line_config, &offset, 1, line_settings));
struct gpiod_request_config *request_config;
assert(request_config = gpiod_request_config_new());
gpiod_request_config_set_consumer(request_config, output->consumer);
if ((output->line = gpiod_chip_request_lines(chip, request_config, line_config)) == NULL) {
US_LOG_PERROR("GPIO: Can't request pin=%d as %s", output->pin, output->consumer);
}
gpiod_request_config_free(request_config);
gpiod_line_config_free(line_config);
gpiod_line_settings_free(line_settings);
if (output->line == NULL) {
_gpio_output_destroy(output);
}
# else
if ((output->line = gpiod_chip_get_line(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);
@@ -113,12 +159,17 @@ static void _gpio_output_init(us_gpio_output_s *output) {
} else { } else {
US_LOG_PERROR("GPIO: Can't get pin=%d as %s", output->pin, output->consumer); US_LOG_PERROR("GPIO: Can't get pin=%d as %s", output->pin, output->consumer);
} }
# endif
} }
} }
static void _gpio_output_destroy(us_gpio_output_s *output) { static void _gpio_output_destroy(us_gpio_output_s *output) {
if (output->line != NULL) { if (output->line != NULL) {
# ifdef HAVE_GPIOD2
gpiod_line_request_release(output->line);
# else
gpiod_line_release(output->line); gpiod_line_release(output->line);
# endif
output->line = NULL; output->line = NULL;
} }
if (output->consumer != NULL) { if (output->consumer != NULL) {

View File

@@ -36,11 +36,15 @@
typedef struct { typedef struct {
int pin; int pin;
const char *role; const char *role;
char *consumer; char *consumer;
struct gpiod_line *line; # ifdef HAVE_GPIOD2
bool state; struct gpiod_line_request *line;
# else
struct gpiod_line *line;
# endif
bool state;
} us_gpio_output_s; } us_gpio_output_s;
typedef struct { typedef struct {
@@ -52,7 +56,11 @@ typedef struct {
us_gpio_output_s has_http_clients; us_gpio_output_s has_http_clients;
pthread_mutex_t mutex; pthread_mutex_t mutex;
# ifndef HAVE_GPIOD2
struct gpiod_chip *chip; struct gpiod_chip *chip;
# endif
bool initialized;
} us_gpio_s; } us_gpio_s;

View File

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