mirror of
https://github.com/pikvm/ustreamer.git
synced 2026-02-19 16:26:30 +00:00
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
848f52c69e | ||
|
|
2dddb879bc | ||
|
|
4d92dc662c | ||
|
|
3cb649d97c | ||
|
|
d9b5f2b03d | ||
|
|
2997906d98 | ||
|
|
bcd3deaa13 |
@@ -1,7 +1,7 @@
|
||||
[bumpversion]
|
||||
commit = True
|
||||
tag = True
|
||||
current_version = 5.46
|
||||
current_version = 5.48
|
||||
parse = (?P<major>\d+)\.(?P<minor>\d+)
|
||||
serialize =
|
||||
{major}.{minor}
|
||||
|
||||
14
Makefile
14
Makefile
@@ -9,9 +9,6 @@ PY ?= python3
|
||||
CFLAGS ?= -O3
|
||||
LDFLAGS ?=
|
||||
|
||||
RPI_VC_HEADERS ?= /opt/vc/include
|
||||
RPI_VC_LIBS ?= /opt/vc/lib
|
||||
|
||||
export
|
||||
|
||||
_LINTERS_IMAGE ?= ustreamer-linters
|
||||
@@ -22,6 +19,9 @@ define optbool
|
||||
$(filter $(shell echo $(1) | tr A-Z a-z), yes on 1)
|
||||
endef
|
||||
|
||||
ifeq ($(V),)
|
||||
ECHO = @
|
||||
endif
|
||||
|
||||
# =====
|
||||
all:
|
||||
@@ -36,18 +36,18 @@ endif
|
||||
|
||||
apps:
|
||||
$(MAKE) -C src
|
||||
@ ln -sf src/ustreamer.bin ustreamer
|
||||
@ ln -sf src/ustreamer-dump.bin ustreamer-dump
|
||||
$(ECHO) ln -sf src/ustreamer.bin ustreamer
|
||||
$(ECHO) ln -sf src/ustreamer-dump.bin ustreamer-dump
|
||||
|
||||
|
||||
python:
|
||||
$(MAKE) -C python
|
||||
@ ln -sf python/build/lib.*/*.so .
|
||||
$(ECHO) ln -sf python/build/lib.*/*.so .
|
||||
|
||||
|
||||
janus:
|
||||
$(MAKE) -C janus
|
||||
@ ln -sf janus/*.so .
|
||||
$(ECHO) ln -sf janus/*.so .
|
||||
|
||||
|
||||
install: all
|
||||
|
||||
@@ -31,13 +31,13 @@ endif
|
||||
# =====
|
||||
$(_PLUGIN): $(_SRCS:%.c=$(_BUILD)/%.o)
|
||||
$(info == SO $@)
|
||||
@ $(CC) $^ -o $@ $(_LDFLAGS)
|
||||
$(ECHO) $(CC) $^ -o $@ $(_LDFLAGS)
|
||||
|
||||
|
||||
$(_BUILD)/%.o: %.c
|
||||
$(info -- CC $<)
|
||||
@ mkdir -p $(dir $@) || true
|
||||
@ $(CC) $< -o $@ $(_CFLAGS)
|
||||
$(ECHO) mkdir -p $(dir $@) || true
|
||||
$(ECHO) $(CC) $< -o $@ $(_CFLAGS)
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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.46" "January 2021"
|
||||
.TH USTREAMER-DUMP 1 "version 5.48" "January 2021"
|
||||
|
||||
.SH NAME
|
||||
ustreamer-dump \- Dump uStreamer's memory sink to 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.46" "November 2020"
|
||||
.TH USTREAMER 1 "version 5.48" "November 2020"
|
||||
|
||||
.SH NAME
|
||||
ustreamer \- stream MJPEG video from any V4L2 device to the network
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
|
||||
pkgname=ustreamer
|
||||
pkgver=5.46
|
||||
pkgver=5.48
|
||||
pkgrel=1
|
||||
pkgdesc="Lightweight and fast MJPEG-HTTP streamer"
|
||||
url="https://github.com/pikvm/ustreamer"
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=ustreamer
|
||||
PKG_VERSION:=5.46
|
||||
PKG_VERSION:=5.48
|
||||
PKG_RELEASE:=1
|
||||
PKG_MAINTAINER:=Maxim Devaev <mdevaev@gmail.com>
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ PY ?= python3
|
||||
# =====
|
||||
all:
|
||||
$(info == PY_BUILD ustreamer-*.so)
|
||||
@ $(PY) setup.py build
|
||||
$(ECHO) $(PY) setup.py build
|
||||
|
||||
|
||||
install:
|
||||
|
||||
@@ -17,7 +17,7 @@ def _find_sources(suffix: str) -> list[str]:
|
||||
if __name__ == "__main__":
|
||||
setup(
|
||||
name="ustreamer",
|
||||
version="5.46",
|
||||
version="5.48",
|
||||
description="uStreamer tools",
|
||||
author="Maxim Devaev",
|
||||
author_email="mdevaev@gmail.com",
|
||||
|
||||
10
src/Makefile
10
src/Makefile
@@ -42,7 +42,7 @@ endef
|
||||
|
||||
ifneq ($(call optbool,$(WITH_GPIO)),)
|
||||
_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)
|
||||
endif
|
||||
|
||||
@@ -86,18 +86,18 @@ install-strip: install
|
||||
|
||||
$(_USTR): $(_USTR_SRCS:%.c=$(_BUILD)/%.o)
|
||||
$(info == LD $@)
|
||||
@ $(CC) $^ -o $@ $(_LDFLAGS) $(_USTR_LIBS)
|
||||
$(ECHO) $(CC) $^ -o $@ $(_LDFLAGS) $(_USTR_LIBS)
|
||||
|
||||
|
||||
$(_DUMP): $(_DUMP_SRCS:%.c=$(_BUILD)/%.o)
|
||||
$(info == LD $@)
|
||||
@ $(CC) $^ -o $@ $(_LDFLAGS) $(_DUMP_LIBS)
|
||||
$(ECHO) $(CC) $^ -o $@ $(_LDFLAGS) $(_DUMP_LIBS)
|
||||
|
||||
|
||||
$(_BUILD)/%.o: %.c
|
||||
$(info -- CC $<)
|
||||
@ mkdir -p $(dir $@) || true
|
||||
@ $(CC) $< -o $@ $(_CFLAGS)
|
||||
$(ECHO) mkdir -p $(dir $@) || true
|
||||
$(ECHO) $(CC) $< -o $@ $(_CFLAGS)
|
||||
|
||||
|
||||
clean:
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#pragma once
|
||||
|
||||
#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_VERSION1(_major, _minor) US_MAKE_VERSION2(_major, _minor)
|
||||
|
||||
@@ -34,24 +34,26 @@ us_gpio_s us_g_gpio = {
|
||||
.line = NULL, \
|
||||
.state = false \
|
||||
}
|
||||
|
||||
.prog_running = MAKE_OUTPUT("prog-running"),
|
||||
.stream_online = MAKE_OUTPUT("stream-online"),
|
||||
.has_http_clients = MAKE_OUTPUT("has-http-clients"),
|
||||
|
||||
# undef MAKE_OUTPUT
|
||||
|
||||
// mutex uninitialized
|
||||
.chip = NULL
|
||||
# ifndef HAVE_GPIOD2
|
||||
.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);
|
||||
|
||||
|
||||
void us_gpio_init(void) {
|
||||
# ifndef HAVE_GPIOD2
|
||||
assert(us_g_gpio.chip == NULL);
|
||||
# endif
|
||||
if (
|
||||
us_g_gpio.prog_running.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_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);
|
||||
struct gpiod_chip *chip;
|
||||
if ((chip = gpiod_chip_open(us_g_gpio.path)) != NULL) {
|
||||
_gpio_output_init(&us_g_gpio.prog_running, chip);
|
||||
_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 {
|
||||
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.stream_online);
|
||||
_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);
|
||||
us_g_gpio.chip = NULL;
|
||||
# endif
|
||||
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 retval = 0;
|
||||
|
||||
# ifndef HAVE_GPIOD2
|
||||
assert(us_g_gpio.chip != NULL);
|
||||
# endif
|
||||
assert(output->line != NULL);
|
||||
assert(output->state != state); // Must be checked in macro for the performance
|
||||
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); \
|
||||
# ifdef HAVE_GPIOD2
|
||||
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);
|
||||
retval = -1;
|
||||
}
|
||||
@@ -98,14 +116,42 @@ int us_gpio_inner_set(us_gpio_output_s *output, bool state) {
|
||||
return retval;
|
||||
}
|
||||
|
||||
static void _gpio_output_init(us_gpio_output_s *output) {
|
||||
assert(us_g_gpio.chip != NULL);
|
||||
static void _gpio_output_init(us_gpio_output_s *output, struct gpiod_chip *chip) {
|
||||
assert(output->line == NULL);
|
||||
|
||||
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_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) {
|
||||
US_LOG_PERROR("GPIO: Can't request pin=%d as %s", output->pin, output->consumer);
|
||||
_gpio_output_destroy(output);
|
||||
@@ -113,12 +159,17 @@ static void _gpio_output_init(us_gpio_output_s *output) {
|
||||
} else {
|
||||
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) {
|
||||
if (output->line != NULL) {
|
||||
# ifdef HAVE_GPIOD2
|
||||
gpiod_line_request_release(output->line);
|
||||
# else
|
||||
gpiod_line_release(output->line);
|
||||
# endif
|
||||
output->line = NULL;
|
||||
}
|
||||
if (output->consumer != NULL) {
|
||||
|
||||
@@ -36,11 +36,15 @@
|
||||
|
||||
|
||||
typedef struct {
|
||||
int pin;
|
||||
const char *role;
|
||||
char *consumer;
|
||||
struct gpiod_line *line;
|
||||
bool state;
|
||||
int pin;
|
||||
const char *role;
|
||||
char *consumer;
|
||||
# ifdef HAVE_GPIOD2
|
||||
struct gpiod_line_request *line;
|
||||
# else
|
||||
struct gpiod_line *line;
|
||||
# endif
|
||||
bool state;
|
||||
} us_gpio_output_s;
|
||||
|
||||
typedef struct {
|
||||
@@ -52,7 +56,11 @@ typedef struct {
|
||||
us_gpio_output_s has_http_clients;
|
||||
|
||||
pthread_mutex_t mutex;
|
||||
|
||||
# ifndef HAVE_GPIOD2
|
||||
struct gpiod_chip *chip;
|
||||
# endif
|
||||
bool initialized;
|
||||
} us_gpio_s;
|
||||
|
||||
|
||||
|
||||
@@ -441,7 +441,14 @@ 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 ...");
|
||||
|
||||
Reference in New Issue
Block a user