Compare commits

...

10 Commits
v3.1 ... v3.5

Author SHA1 Message Date
Devaev Maxim
66e0bb0a2c Bump version: 3.4 → 3.5 2021-01-15 01:30:17 +03:00
Devaev Maxim
5af18e8b70 fixed segfault on uninitialized mmal 2021-01-15 01:26:13 +03:00
Devaev Maxim
b746bc307c Bump version: 3.3 → 3.4 2021-01-13 17:46:08 +03:00
Devaev Maxim
3fd3aab909 banned option --as-needed from LDFLAGS 2021-01-13 17:45:33 +03:00
Devaev Maxim
2f1afb6044 Bump version: 3.2 → 3.3 2021-01-13 05:35:34 +03:00
Devaev Maxim
a016c1040e compatibility with freebsd install 2021-01-13 05:27:21 +03:00
Devaev Maxim
d4e9948220 Bump version: 3.1 → 3.2 2021-01-13 03:46:30 +03:00
Devaev Maxim
5d1183f5c6 http: zero_data option and X-UStreamer-Latency header 2021-01-13 03:45:45 +03:00
Devaev Maxim
c75863d4bd do not initialize omx on every startup 2021-01-13 03:30:31 +03:00
Devaev Maxim
5576cbb3b8 minor snprintf fixes 2021-01-13 01:26:11 +03:00
14 changed files with 74 additions and 36 deletions

View File

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

View File

@@ -82,10 +82,11 @@ all: $(USTR) $(DUMP)
install: $(USTR) $(DUMP)
install -Dm755 $(USTR) $(DESTDIR)$(PREFIX)/bin/$(USTR)
install -Dm755 $(DUMP) $(DESTDIR)$(PREFIX)/bin/$(DUMP)
install -Dm644 man/$(USTR).1 $(DESTDIR)$(MANPREFIX)/man1/$(USTR).1
install -Dm644 man/$(DUMP).1 $(DESTDIR)$(MANPREFIX)/man1/$(DUMP).1
mkdir -p $(DESTDIR)$(PREFIX)/bin $(DESTDIR)$(MANPREFIX)/man1
install -m755 $(USTR) $(DESTDIR)$(PREFIX)/bin/$(USTR)
install -m755 $(DUMP) $(DESTDIR)$(PREFIX)/bin/$(DUMP)
install -m644 man/$(USTR).1 $(DESTDIR)$(MANPREFIX)/man1/$(USTR).1
install -m644 man/$(DUMP).1 $(DESTDIR)$(MANPREFIX)/man1/$(DUMP).1
gzip $(DESTDIR)$(MANPREFIX)/man1/$(USTR).1
gzip $(DESTDIR)$(MANPREFIX)/man1/$(DUMP).1

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.1" "January 2021"
.TH USTREAMER-DUMP 1 "version 3.5" "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.1" "November 2020"
.TH USTREAMER 1 "version 3.5" "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.1
pkgver=3.5
pkgrel=1
pkgdesc="Lightweight and fast MJPG-HTTP streamer"
url="https://github.com/pikvm/ustreamer"
@@ -25,6 +25,10 @@ build() {
local _options="WITH_GPIO=1"
[ -e /opt/vc/include/IL/OMX_Core.h ] && _options="$_options WITH_OMX=1"
# LD does not link mmal with this option
LDFLAGS="${LDFLAGS//--as-needed/}"
LDFLAGS="${LDFLAGS//,,/,}"
make $_options CFLAGS="$CFLAGS" LDFLAGS="$LDFLAGS" $MAKEFLAGS
}

View File

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

View File

@@ -23,5 +23,5 @@
#pragma once
#ifndef VERSION
# define VERSION "3.1"
# define VERSION "3.5"
#endif

View File

@@ -50,6 +50,11 @@
Without this option, when the frame series is completed, WebKit-based browsers<br>
renders the last frame with a delay.
</li>
<br>
<li>
<b>zero_data=1</b><br>
Disables the actual sending of JPEG data and leaves only response headers.
</li>
</ul>
</li>
<br>

View File

@@ -75,6 +75,11 @@ const char *const HTML_INDEX_PAGE = " \
Without this option, when the frame series is completed, WebKit-based browsers<br> \
renders the last frame with a delay. \
</li> \
<br> \
<li> \
<b>zero_data=1</b><br> \
Disables the actual sending of JPEG data and leaves only response headers. \
</li> \
</ul> \
</li> \
<br> \

View File

@@ -250,7 +250,9 @@ static void _h264_encoder_cleanup(h264_encoder_s *enc) {
# undef DISABLE_PORT
enc->wrapper->status = MMAL_SUCCESS; // Это реально надо?
if (enc->wrapper) {
enc->wrapper->status = MMAL_SUCCESS; // Это реально надо?
}
enc->last_online = -1;
enc->ready = false;

View File

@@ -145,7 +145,7 @@ int server_listen(server_s *server) {
char *raw_token;
char *encoded_token = NULL;
A_CALLOC(raw_token, strlen(server->user) + strlen(server->passwd) + 2);
A_CALLOC(raw_token, strlen(server->user) + strlen(server->passwd) + 16);
sprintf(raw_token, "%s:%s", server->user, server->passwd);
base64_encode((uint8_t *)raw_token, strlen(raw_token), &encoded_token, NULL);
free(raw_token);
@@ -368,12 +368,14 @@ static void _http_callback_state(struct evhttp_request *request, void *v_server)
for (stream_client_s * client = RUN(stream_clients); client != NULL; client = client->next) {
assert(evbuffer_add_printf(buf,
"\"%s\": {\"fps\": %u, \"extra_headers\": %s, \"advance_headers\": %s, \"dual_final_frames\": %s}%s",
"\"%s\": {\"fps\": %u, \"extra_headers\": %s, \"advance_headers\": %s,"
" \"dual_final_frames\": %s, \"zero_data\": %s}%s",
client->id,
client->fps,
bool_to_string(client->extra_headers),
bool_to_string(client->advance_headers),
bool_to_string(client->dual_final_frames),
bool_to_string(client->zero_data),
(client->next ? ", " : "")
));
}
@@ -404,12 +406,12 @@ static void _http_callback_snapshot(struct evhttp_request *request, void *v_serv
char header_buf[256];
# define ADD_TIME_HEADER(_key, _value) { \
sprintf(header_buf, "%.06Lf", _value); \
snprintf(header_buf, 255, "%.06Lf", _value); \
ADD_HEADER(_key, header_buf); \
}
# define ADD_UNSIGNED_HEADER(_key, _value) { \
sprintf(header_buf, "%u", _value); \
snprintf(header_buf, 255, "%u", _value); \
ADD_HEADER(_key, header_buf); \
}
@@ -462,10 +464,13 @@ static void _http_callback_stream(struct evhttp_request *request, void *v_server
struct evkeyvalq params;
evhttp_parse_query(evhttp_request_get_uri(request), &params);
client->key = uri_get_string(&params, "key");
client->extra_headers = uri_get_true(&params, "extra_headers");
client->advance_headers = uri_get_true(&params, "advance_headers");
client->dual_final_frames = uri_get_true(&params, "dual_final_frames");
# define PARSE_PARAM(_type, _name) client->_name = uri_get_##_type(&params, #_name)
PARSE_PARAM(string, key);
PARSE_PARAM(true, extra_headers);
PARSE_PARAM(true, advance_headers);
PARSE_PARAM(true, dual_final_frames);
PARSE_PARAM(true, zero_data);
# undef PARSE_PARAM
evhttp_clear_headers(&params);
uuid_t uuid;
@@ -592,7 +597,7 @@ static void _http_callback_stream_write(struct bufferevent *buf_event, void *v_c
"Content-Length: %zu" RN
"X-Timestamp: %.06Lf" RN
"%s",
EX(frame->used),
(!client->zero_data ? EX(frame->used) : 0),
get_now_real(),
(client->extra_headers ? "" : RN)
));
@@ -610,6 +615,7 @@ static void _http_callback_stream_write(struct bufferevent *buf_event, void *v_c
"X-UStreamer-Expose-Cmp-Time: %.06Lf" RN
"X-UStreamer-Expose-End-Time: %.06Lf" RN
"X-UStreamer-Send-Time: %.06Lf" RN
"X-UStreamer-Latency: %.06Lf" RN
RN,
bool_to_string(EX(frame->online)),
EX(dropped),
@@ -622,12 +628,15 @@ static void _http_callback_stream_write(struct bufferevent *buf_event, void *v_c
EX(expose_begin_ts),
EX(expose_cmp_ts),
EX(expose_end_ts),
now
now,
now - EX(frame->grab_ts)
));
}
}
assert(!evbuffer_add(buf, (void *)EX(frame->data), EX(frame->used)));
if (!client->zero_data) {
assert(!evbuffer_add(buf, (void *)EX(frame->data), EX(frame->used)));
}
assert(evbuffer_add_printf(buf, RN "--" BOUNDARY RN));
if (client->advance_headers) {

View File

@@ -81,6 +81,7 @@ typedef struct stream_client_sx {
bool extra_headers;
bool advance_headers;
bool dual_final_frames;
bool zero_data;
char id[37]; // ex. "1b4e28ba-2fa1-11d2-883f-0016d3cca427" + "\0"
bool need_initial;

View File

@@ -32,7 +32,7 @@ char *find_static_file_path(const char *root_path, const char *request_path) {
goto error;
}
A_CALLOC(path, strlen(root_path) + strlen(simplified_path) + 32);
A_CALLOC(path, strlen(root_path) + strlen(simplified_path) + 16);
sprintf(path, "%s/%s", root_path, simplified_path);
struct stat st;

View File

@@ -119,23 +119,31 @@ int main(int argc, char *argv[]) {
LOGGING_INIT;
A_THREAD_RENAME("main");
# ifdef WITH_OMX
bcm_host_init();
OMX_ERRORTYPE omx_error;
if ((omx_error = OMX_Init()) != OMX_ErrorNone) {
LOG_ERROR_OMX(omx_error, "Can't initialize OMX Core");
exit_code = -1;
goto omx_error;
}
# endif
options_s *options = options_init(argc, argv);
device_s *dev = device_init();
encoder_s *enc = encoder_init();
stream_s *stream = stream_init(dev, enc);
server_s *server = server_init(stream);
# ifdef WITH_OMX
bool i_bcm_host = false;
OMX_ERRORTYPE omx_error = OMX_ErrorUndefined;
# endif
if ((exit_code = options_parse(options, dev, enc, stream, server)) == 0) {
# ifdef WITH_OMX
if (enc->type == ENCODER_TYPE_OMX || stream->h264_sink) {
bcm_host_init();
i_bcm_host = true;
}
if (enc->type == ENCODER_TYPE_OMX) {
if ((omx_error = OMX_Init()) != OMX_ErrorNone) {
LOG_ERROR_OMX(omx_error, "Can't initialize OMX Core; forced CPU encoder");
enc->type = ENCODER_TYPE_CPU;
}
}
# endif
# ifdef WITH_GPIO
gpio_init();
# endif
@@ -173,9 +181,12 @@ int main(int argc, char *argv[]) {
options_destroy(options);
# ifdef WITH_OMX
OMX_Deinit();
omx_error:
bcm_host_deinit();
if (omx_error == OMX_ErrorNone) {
OMX_Deinit();
}
if (i_bcm_host) {
bcm_host_deinit();
}
# endif
if (exit_code == 0) {