Compare commits

...

6 Commits
v3.20 ... v3.22

Author SHA1 Message Date
Devaev Maxim
3b7cbc62c4 Bump version: 3.21 → 3.22 2021-03-22 07:07:56 +03:00
Devaev Maxim
dff49d8e7b h264 mmal brokes on 0 fps and 640x480 2021-03-22 07:07:21 +03:00
Maxim Devaev
b23883e65f Update README.md 2021-03-21 17:57:37 +03:00
Maxim Devaev
c2e30c7fc4 Update README.ru.md 2021-03-21 17:57:01 +03:00
Devaev Maxim
37216250b8 Bump version: 3.20 → 3.21 2021-03-21 03:58:35 +03:00
Devaev Maxim
dc82894038 Issue #100: handle X-Forwarded-For 2021-03-21 03:35:47 +03:00
12 changed files with 62 additions and 31 deletions

View File

@@ -1,7 +1,7 @@
[bumpversion]
commit = True
tag = True
current_version = 3.20
current_version = 3.22
parse = (?P<major>\d+)\.(?P<minor>\d+)(\.(?P<patch>\d+)(\-(?P<release>[a-z]+))?)?
serialize =
{major}.{minor}

View File

@@ -38,8 +38,7 @@ You'll need ```make```, ```gcc```, ```libevent``` with ```pthreads``` support,
* Arch: `sudo pacman -S libevent libjpeg-turbo libutil-linux libbsd`.
* Raspbian: `sudo apt install libevent-dev libjpeg8-dev libbsd-dev`. Add `libraspberrypi-dev` for `WITH_OMX=1` and `libgpiod` for `WITH_GPIO=1`.
* Debian: `sudo apt install build-essential libevent-dev libjpeg62-turbo-dev libbsd-dev`.
* Ubuntu 20.04 x86_64: `sudo apt install build-essential libevent-dev libjpeg-dev libjpeg62-dev libbsd-dev make gcc libjpeg8 libjpeg-turbo8 libbsd0`.
* Debian/Ubuntu: `sudo apt install build-essential libevent-dev libjpeg-dev libbsd-dev`.
On Raspberry Pi you can build the program with OpenMAX IL. To do this pass option ```WITH_OMX=1``` to ```make```. To enable GPIO support install [libgpiod](https://git.kernel.org/pub/scm/libs/libgpiod/libgpiod.git/about) and pass option ```WITH_GPIO=1```. If the compiler reports about a missing function ```pthread_get_name_np()``` (or similar), add option ```WITH_PTHREAD_NP=0``` (it's enabled by default). For the similar error with ```setproctitle()``` add option ```WITH_SETPROCTITLE=0```.

View File

@@ -38,8 +38,7 @@
* Arch: `sudo pacman -S libevent libjpeg-turbo libutil-linux libbsd`.
* Raspbian: `sudo apt install libevent-dev libjpeg8-dev libbsd-dev`. Добавьте `libraspberrypi-dev` для сборки с `WITH_OMX=1` и `libgpiod` для `WITH_GPIO=1`.
* Debian: `sudo apt install build-essential libevent-dev libjpeg62-turbo-dev libbsd-dev`.
* Ubuntu 20.04 x86_64: `sudo apt install build-essential libevent-dev libjpeg-dev libjpeg62-dev libbsd-dev make gcc libjpeg8 libjpeg-turbo8 libbsd0`.
* Debian/Ubuntu: `sudo apt install build-essential libevent-dev libjpeg-dev libbsd-dev`.
На Raspberry Pi программу можно собрать с поддержкой OpenMAX IL. Для этого передайте ```make``` параметр ```WITH_OMX=1```. Для включения сборки с поддержкой GPIO установите [libgpiod](https://git.kernel.org/pub/scm/libs/libgpiod/libgpiod.git/about) и добавьте параметр ```WITH_GPIO=1```. Если при сборке компилятор ругается на отсутствие функции ```pthread_get_name_np()``` или другой подобной, добавьте параметр ```WITH_PTHREAD_NP=0``` (по умолчанию он включен). При аналогичной ошибке с функцией ```setproctitle()``` добавьте параметр ```WITH_SETPROCTITLE=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 3.20" "January 2021"
.TH USTREAMER-DUMP 1 "version 3.22" "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 3.20" "November 2020"
.TH USTREAMER 1 "version 3.22" "November 2020"
.SH NAME
ustreamer \- stream MJPG video from any V4L2 device to the network

View File

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

View File

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

View File

@@ -6,7 +6,7 @@ from distutils.core import setup
if __name__ == "__main__":
setup(
name="ustreamer",
version="3.20",
version="3.22",
description="uStreamer tools",
author="Maxim Devaev",
author_email="mdevaev@gmail.com",

View File

@@ -23,5 +23,5 @@
#pragma once
#ifndef VERSION
# define VERSION "3.20"
# define VERSION "3.22"
#endif

View File

@@ -31,8 +31,10 @@ h264_stream_s *h264_stream_init(memsink_s *sink, unsigned bitrate, unsigned gop)
h264->dest = frame_init("h264_dest");
atomic_init(&h264->online, false);
// FIXME: 30 or 0? https://github.com/6by9/yavta/blob/master/yavta.c#L210
if ((h264->enc = h264_encoder_init(bitrate, gop, 0)) == NULL) {
// FIXME: 30 or 0? https://github.com/6by9/yavta/blob/master/yavta.c#L2100
// По логике вещей правильно 0, но почему-то на низких разрешениях типа 640x480
// енкодер через несколько секунд перестает производить корректные фреймы.
if ((h264->enc = h264_encoder_init(bitrate, gop, 30)) == NULL) {
goto error;
}

View File

@@ -39,6 +39,8 @@ static void _http_queue_send_stream(server_s *server, bool stream_updated, bool
static bool _expose_new_frame(server_s *server);
static char *_http_get_client_hostport(struct evhttp_request *request);
#define RUN(_next) server->run->_next
#define STREAM(_next) RUN(stream->_next)
@@ -94,6 +96,7 @@ void server_destroy(server_s *server) {
for (stream_client_s *client = RUN(stream_clients); client != NULL;) {
stream_client_s *next = client->next;
free(client->key);
free(client->hostport);
free(client);
client = next;
}
@@ -473,6 +476,7 @@ static void _http_callback_stream(struct evhttp_request *request, void *v_server
# undef PARSE_PARAM
evhttp_clear_headers(&params);
client->hostport = _http_get_client_hostport(request);
client->id = get_now_id();
if (RUN(stream_clients) == NULL) {
@@ -493,23 +497,18 @@ static void _http_callback_stream(struct evhttp_request *request, void *v_server
# endif
}
char *client_addr;
unsigned short client_port;
evhttp_connection_get_peer(conn, &client_addr, &client_port);
LOG_INFO("HTTP: Registered client: [%s]:%u, id=%" PRIx64 "; clients now: %u",
client_addr, client_port, client->id, RUN(stream_clients_count));
LOG_INFO("HTTP: Registered client: %s, id=%" PRIx64 "; clients now: %u",
client->hostport, client->id, RUN(stream_clients_count));
struct bufferevent *buf_event = evhttp_connection_get_bufferevent(conn);
if (server->tcp_nodelay && !RUN(unix_fd)) {
evutil_socket_t fd;
int on = 1;
LOG_DEBUG("HTTP: Setting up TCP_NODELAY to the client [%s]:%u ...", client_addr, client_port);
LOG_DEBUG("HTTP: Setting up TCP_NODELAY to the client %s ...", client->hostport);
assert((fd = bufferevent_getfd(buf_event)) >= 0);
if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (void *)&on, sizeof(on)) != 0) {
LOG_PERROR("HTTP: Can't set TCP_NODELAY to the client [%s]:%u", client_addr, client_port);
LOG_PERROR("HTTP: Can't set TCP_NODELAY to the client %s", client->hostport);
}
}
bufferevent_setcb(buf_event, NULL, NULL, _http_callback_stream_error, (void *)client);
@@ -668,17 +667,10 @@ static void _http_callback_stream_error(UNUSED struct bufferevent *buf_event, UN
# endif
}
char *client_addr = "???";
unsigned short client_port = 0;
LOG_INFO("HTTP: Disconnected client: %s, id=%" PRIx64 ", %s; clients now: %u",
client->hostport, client->id, reason, RUN(stream_clients_count));
struct evhttp_connection *conn = evhttp_request_get_connection(client->request);
if (conn) {
evhttp_connection_get_peer(conn, &client_addr, &client_port);
}
LOG_INFO("HTTP: Disconnected client: [%s]:%u, id=%" PRIx64 ", %s; clients now: %u",
client_addr, client_port, client->id, reason, RUN(stream_clients_count));
if (conn) {
evhttp_connection_free(conn);
}
@@ -692,6 +684,7 @@ static void _http_callback_stream_error(UNUSED struct bufferevent *buf_event, UN
client->next->prev = client->prev;
}
free(client->key);
free(client->hostport);
free(client);
free(reason);
@@ -834,3 +827,40 @@ static bool _expose_new_frame(server_s *server) {
#undef VID
#undef STREAM
#undef RUN
static char *_http_get_client_hostport(struct evhttp_request *request) {
char *addr = NULL;
unsigned short port = 0;
struct evhttp_connection *conn = evhttp_request_get_connection(request);
if (conn) {
char *peer;
evhttp_connection_get_peer(conn, &peer, &port);
assert(addr = strdup(peer));
}
const char *xff = evhttp_find_header(evhttp_request_get_input_headers(request), "X-Forwarded-For");
if (xff) {
if (addr) {
free(addr);
}
assert(addr = strndup(xff, 1024));
for (unsigned index = 0; addr[index]; ++index) {
if (addr[index] == ',') {
addr[index] = '\0';
break;
}
}
}
if (addr == NULL) {
assert(addr = strdup("???"));
}
char *hostport;
size_t hostport_len = strlen(addr) + 64;
A_CALLOC(hostport, hostport_len);
snprintf(hostport, hostport_len, "[%s]:%u", addr, port);
free(addr);
return hostport;
}

View File

@@ -82,6 +82,7 @@ typedef struct stream_client_sx {
bool dual_final_frames;
bool zero_data;
char *hostport;
uint64_t id;
bool need_initial;
bool need_first_frame;