mirror of
https://github.com/pikvm/ustreamer.git
synced 2026-03-01 13:16:32 +00:00
Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
77b5e6eabc | ||
|
|
ca07a9155b | ||
|
|
6cc202133e |
@@ -1,7 +1,7 @@
|
|||||||
[bumpversion]
|
[bumpversion]
|
||||||
commit = True
|
commit = True
|
||||||
tag = True
|
tag = True
|
||||||
current_version = 0.25
|
current_version = 0.26
|
||||||
parse = (?P<major>\d+)\.(?P<minor>\d+)(\.(?P<patch>\d+)(\-(?P<release>[a-z]+))?)?
|
parse = (?P<major>\d+)\.(?P<minor>\d+)(\.(?P<patch>\d+)(\-(?P<release>[a-z]+))?)?
|
||||||
serialize =
|
serialize =
|
||||||
{major}.{minor}
|
{major}.{minor}
|
||||||
|
|||||||
2
PKGBUILD
2
PKGBUILD
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
|
|
||||||
pkgname=ustreamer
|
pkgname=ustreamer
|
||||||
pkgver=0.25
|
pkgver=0.26
|
||||||
pkgrel=1
|
pkgrel=1
|
||||||
pkgdesc="Lightweight and fast MJPG-HTTP streamer"
|
pkgdesc="Lightweight and fast MJPG-HTTP streamer"
|
||||||
url="https://github.com/pi-kvm/ustreamer"
|
url="https://github.com/pi-kvm/ustreamer"
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ AUR has a package for Arch Linux: https://aur.archlinux.org/packages/ustreamer
|
|||||||
|
|
||||||
-----
|
-----
|
||||||
# Usage
|
# Usage
|
||||||
Without arguments, ```ustreamer``` will try to open ```/dev/video0``` with 640x480 resolution and start broadcasting on ```http://localhost:8080```. You can override this behavior using parameters ```--device```, ```--host``` and ```--port```. For example, to broadcast to the world, run:
|
Without arguments, ```ustreamer``` will try to open ```/dev/video0``` with 640x480 resolution and start broadcasting on ```http://127.0.0.1:8080```. You can override this behavior using parameters ```--device```, ```--host``` and ```--port```. For example, to broadcast to the world, run:
|
||||||
```
|
```
|
||||||
# ./ustreamer --device=/dev/video1 --host=0.0.0.0 --port=80
|
# ./ustreamer --device=/dev/video1 --host=0.0.0.0 --port=80
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ $ ./ustreamer --help
|
|||||||
|
|
||||||
-----
|
-----
|
||||||
# Использование
|
# Использование
|
||||||
Будучи запущенным без аргументов, ```ustreamer``` попробует открыть устройство ```/dev/video0``` с разрешением 640x480 и начать трансляцию на ```http://localhost:8080```. Это поведение может быть изменено с помощью опций ```--device```, ```--host``` и ```--port```. Пример вещания на всю сеть по 80-м порту:
|
Будучи запущенным без аргументов, ```ustreamer``` попробует открыть устройство ```/dev/video0``` с разрешением 640x480 и начать трансляцию на ```http://127.0.0.1:8080```. Это поведение может быть изменено с помощью опций ```--device```, ```--host``` и ```--port```. Пример вещания на всю сеть по 80-м порту:
|
||||||
```
|
```
|
||||||
# ./ustreamer --device=/dev/video1 --host=0.0.0.0 --port=80
|
# ./ustreamer --device=/dev/video1 --host=0.0.0.0 --port=80
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -21,4 +21,4 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define VERSION "0.25"
|
#define VERSION "0.26"
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ struct device_t *device_init() {
|
|||||||
dev->n_buffers = max_u(sysconf(_SC_NPROCESSORS_ONLN), 1) + 1;
|
dev->n_buffers = max_u(sysconf(_SC_NPROCESSORS_ONLN), 1) + 1;
|
||||||
dev->n_workers = dev->n_buffers;
|
dev->n_workers = dev->n_buffers;
|
||||||
dev->timeout = 1;
|
dev->timeout = 1;
|
||||||
dev->error_timeout = 1;
|
dev->error_delay = 1;
|
||||||
dev->run = run;
|
dev->run = run;
|
||||||
return dev;
|
return dev;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,8 +74,9 @@ struct device_t {
|
|||||||
unsigned n_workers;
|
unsigned n_workers;
|
||||||
unsigned every_frame;
|
unsigned every_frame;
|
||||||
unsigned min_frame_size;
|
unsigned min_frame_size;
|
||||||
|
bool persistent;
|
||||||
unsigned timeout;
|
unsigned timeout;
|
||||||
unsigned error_timeout;
|
unsigned error_delay;
|
||||||
|
|
||||||
struct device_runtime_t *run;
|
struct device_runtime_t *run;
|
||||||
sig_atomic_t volatile stop;
|
sig_atomic_t volatile stop;
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ struct http_server_t *http_server_init(struct stream_t *stream) {
|
|||||||
run->drop_same_frames_blank = 10;
|
run->drop_same_frames_blank = 10;
|
||||||
|
|
||||||
A_CALLOC(server, 1);
|
A_CALLOC(server, 1);
|
||||||
server->host = "localhost";
|
server->host = "127.0.0.1";
|
||||||
server->port = 8080;
|
server->port = 8080;
|
||||||
server->timeout = 10;
|
server->timeout = 10;
|
||||||
server->run = run;
|
server->run = run;
|
||||||
|
|||||||
13
src/main.c
13
src/main.c
@@ -59,7 +59,8 @@ static const struct option _long_opts[] = {
|
|||||||
{"encoder-omx-use-ijg", required_argument, NULL, 500},
|
{"encoder-omx-use-ijg", required_argument, NULL, 500},
|
||||||
# endif
|
# endif
|
||||||
{"device-timeout", required_argument, NULL, 1000},
|
{"device-timeout", required_argument, NULL, 1000},
|
||||||
{"device-error-timeout", required_argument, NULL, 1001},
|
{"device-persistent", no_argument, NULL, 1001},
|
||||||
|
{"device-error-delay", required_argument, NULL, 1002},
|
||||||
|
|
||||||
{"host", required_argument, NULL, 's'},
|
{"host", required_argument, NULL, 's'},
|
||||||
{"port", required_argument, NULL, 'p'},
|
{"port", required_argument, NULL, 'p'},
|
||||||
@@ -122,8 +123,9 @@ static void _help(struct device_t *dev, struct encoder_t *encoder, struct http_s
|
|||||||
printf(" Default: disabled.\n\n");
|
printf(" Default: disabled.\n\n");
|
||||||
# endif
|
# endif
|
||||||
printf(" --device-timeout <seconds> -- Timeout for device querying. Default: %d\n\n", dev->timeout);
|
printf(" --device-timeout <seconds> -- Timeout for device querying. Default: %d\n\n", dev->timeout);
|
||||||
printf(" --device-error-timeout <seconds> -- Delay before trying to connect to the device again\n");
|
printf(" --device-persistent -- Don't re-initialize device on timeout. Default: disabled.\n\n");
|
||||||
printf(" after a timeout. Default: %d\n\n", dev->error_timeout);
|
printf(" --device-error-delay <seconds> -- Delay before trying to connect to the device again\n");
|
||||||
|
printf(" after a timeout. Default: %d\n\n", dev->error_delay);
|
||||||
printf("HTTP server options:\n");
|
printf("HTTP server options:\n");
|
||||||
printf("--------------------\n");
|
printf("--------------------\n");
|
||||||
printf(" --host <address> -- Listen on Hostname or IP. Default: %s\n\n", server->host);
|
printf(" --host <address> -- Listen on Hostname or IP. Default: %s\n\n", server->host);
|
||||||
@@ -189,8 +191,9 @@ static int _parse_options(int argc, char *argv[], struct device_t *dev, struct e
|
|||||||
# ifdef OMX_ENCODER
|
# ifdef OMX_ENCODER
|
||||||
case 500: OPT_SET(encoder->omx_use_ijg, true);
|
case 500: OPT_SET(encoder->omx_use_ijg, true);
|
||||||
# endif
|
# endif
|
||||||
case 1000: OPT_UNSIGNED(dev->timeout, "--timeout", 1, 60);
|
case 1000: OPT_UNSIGNED(dev->timeout, "--device-timeout", 1, 60);
|
||||||
case 1001: OPT_UNSIGNED(dev->error_timeout, "--error-timeout", 1, 60);
|
case 1001: OPT_SET(dev->persistent, true);
|
||||||
|
case 1002: OPT_UNSIGNED(dev->error_delay, "--device-error-delay", 1, 60);
|
||||||
|
|
||||||
case 's': OPT_SET(server->host, optarg);
|
case 's': OPT_SET(server->host, optarg);
|
||||||
case 'p': OPT_UNSIGNED(server->port, "--port", 1, 65535);
|
case 'p': OPT_UNSIGNED(server->port, "--port", 1, 65535);
|
||||||
|
|||||||
21
src/stream.c
21
src/stream.c
@@ -87,10 +87,13 @@ void stream_loop(struct stream_t *stream) {
|
|||||||
unsigned fluency_passed = 0;
|
unsigned fluency_passed = 0;
|
||||||
unsigned captured_fps_accum = 0;
|
unsigned captured_fps_accum = 0;
|
||||||
long long captured_fps_second = 0;
|
long long captured_fps_second = 0;
|
||||||
|
bool persistent_timeout_reported = false;
|
||||||
|
|
||||||
LOG_DEBUG("Allocation memory for stream picture ...");
|
LOG_DEBUG("Allocation memory for stream picture ...");
|
||||||
A_CALLOC(stream->picture.data, stream->dev->run->max_picture_size);
|
A_CALLOC(stream->picture.data, stream->dev->run->max_picture_size);
|
||||||
|
|
||||||
|
LOG_INFO("Capturing ...");
|
||||||
|
|
||||||
while (!stream->dev->stop) {
|
while (!stream->dev->stop) {
|
||||||
int free_worker_number = -1;
|
int free_worker_number = -1;
|
||||||
|
|
||||||
@@ -154,10 +157,20 @@ void stream_loop(struct stream_t *stream) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
} else if (retval == 0) {
|
} else if (retval == 0) {
|
||||||
LOG_ERROR("Mainloop select() timeout");
|
if (stream->dev->persistent) {
|
||||||
break;
|
if (!persistent_timeout_reported) {
|
||||||
|
LOG_ERROR("Mainloop select() timeout, polling ...")
|
||||||
|
persistent_timeout_reported = true;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
LOG_ERROR("Mainloop select() timeout");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
persistent_timeout_reported = false;
|
||||||
|
|
||||||
if (FD_ISSET(stream->dev->run->fd, &read_fds)) {
|
if (FD_ISSET(stream->dev->run->fd, &read_fds)) {
|
||||||
LOG_DEBUG("Frame is ready");
|
LOG_DEBUG("Frame is ready");
|
||||||
|
|
||||||
@@ -327,8 +340,8 @@ static int _stream_init_loop(struct device_t *dev, struct workers_pool_t *pool)
|
|||||||
LOG_DEBUG("%s: *dev->stop = %d", __FUNCTION__, dev->stop);
|
LOG_DEBUG("%s: *dev->stop = %d", __FUNCTION__, dev->stop);
|
||||||
while (!dev->stop) {
|
while (!dev->stop) {
|
||||||
if ((retval = _stream_init(dev, pool)) < 0) {
|
if ((retval = _stream_init(dev, pool)) < 0) {
|
||||||
LOG_INFO("Sleeping %d seconds before new stream init ...", dev->error_timeout);
|
LOG_INFO("Sleeping %d seconds before new stream init ...", dev->error_delay);
|
||||||
sleep(dev->error_timeout);
|
sleep(dev->error_delay);
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user