streaming via unix socket

This commit is contained in:
Devaev Maxim
2018-12-06 13:21:03 +03:00
parent 3666d92819
commit 9c8d87412e
5 changed files with 64 additions and 7 deletions

1
.gitignore vendored
View File

@@ -5,4 +5,5 @@
/ustreamer-*.pkg.tar.xz
/vgcore.*
/ustreamer
/*.sock
*.o

View File

@@ -59,5 +59,5 @@ push:
clean-all: clean
clean:
rm -f src/*.o src/{jpeg,omx}/*.o vgcore.* $(PROG)
rm -f src/*.o src/{jpeg,omx}/*.o vgcore.* *.sock $(PROG)
rm -rf pkg src/$(PROG)-* src/v*.tar.gz v*.tar.gz $(PROG)-*.pkg.tar.xz

View File

@@ -23,8 +23,13 @@
#include <stdbool.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>
#include <fcntl.h>
#include <assert.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <event2/event.h>
#include <event2/thread.h>
#include <event2/http.h>
@@ -105,6 +110,9 @@ void http_server_destroy(struct http_server_t *server) {
}
evhttp_free(server->run->http);
if (server->run->unix_fd) {
close(server->run->unix_fd);
}
event_base_free(server->run->base);
libevent_global_shutdown();
@@ -128,15 +136,53 @@ int http_server_listen(struct http_server_t *server) {
server->run->drop_same_frames_blank = max_u(server->drop_same_frames, server->run->drop_same_frames_blank);
LOG_DEBUG("Binding HTTP to [%s]:%d ...", server->host, server->port);
evhttp_set_timeout(server->run->http, server->timeout);
if (evhttp_bind_socket(server->run->http, server->host, server->port) < 0) {
LOG_PERROR("Can't listen HTTP on [%s]:%d", server->host, server->port)
return -1;
if (server->unix_path) {
struct sockaddr_un unix_addr;
int unix_fd_flags;
LOG_DEBUG("Binding HTTP to UNIX socket '%s' ...", server->unix_path);
assert((server->run->unix_fd = socket(AF_UNIX, SOCK_STREAM, 0)));
assert((unix_fd_flags = fcntl(server->run->unix_fd, F_GETFL)) >= 0);
unix_fd_flags |= O_NONBLOCK;
assert(fcntl(server->run->unix_fd, F_SETFL, unix_fd_flags) >= 0);
strncpy(unix_addr.sun_path, server->unix_path, 107);
unix_addr.sun_path[107] = '\0';
unix_addr.sun_family = AF_UNIX;
if (server->unix_path && server->unix_rm && unlink(server->unix_path) < 0) {
if (errno != ENOENT) {
LOG_PERROR("Can't remove old UNIX socket '%s'", server->unix_path);
return -1;
}
}
if (bind(server->run->unix_fd, (struct sockaddr *)&unix_addr, sizeof(struct sockaddr_un)) < 0) {
LOG_PERROR("Can't bind HTTP to UNIX socket '%s'", server->unix_path);
return -1;
}
if (listen(server->run->unix_fd, 128) < 0) {
LOG_PERROR("Can't listen UNIX socket '%s'", server->unix_path);
return -1;
}
if (evhttp_accept_socket(server->run->http, server->run->unix_fd) < 0) {
LOG_PERROR("Can't evhttp_accept_socket() UNIX socket '%s'", server->unix_path);
return -1;
}
LOG_INFO("Listening HTTP on UNIX socket '%s'", server->unix_path);
} else {
LOG_DEBUG("Binding HTTP to [%s]:%d ...", server->host, server->port);
if (evhttp_bind_socket(server->run->http, server->host, server->port) < 0) {
LOG_PERROR("Can't bind HTTP on [%s]:%d", server->host, server->port)
return -1;
}
LOG_INFO("Listening HTTP on [%s]:%d", server->host, server->port);
}
LOG_INFO("Listening HTTP on [%s]:%d", server->host, server->port);
return 0;
}

View File

@@ -23,6 +23,7 @@
#include <event2/event.h>
#include <event2/http.h>
#include <event2/util.h>
#include "tools.h"
#include "stream.h"
@@ -65,6 +66,7 @@ struct exposed_t {
struct http_server_runtime_t {
struct event_base *base;
struct evhttp *http;
evutil_socket_t unix_fd;
struct event *refresh;
struct stream_t *stream;
struct exposed_t *exposed;
@@ -76,6 +78,8 @@ struct http_server_runtime_t {
struct http_server_t {
char *host;
unsigned port;
char *unix_path;
bool unix_rm;
unsigned drop_same_frames;
unsigned fake_width;
unsigned fake_height;

View File

@@ -40,7 +40,7 @@
#include "http.h"
static const char _short_opts[] = "d:i:x:y:f:a:z:tn:w:q:c:s:p:r:h";
static const char _short_opts[] = "d:i:x:y:f:a:z:tn:w:q:c:s:p:u:er:h";
static const struct option _long_opts[] = {
{"device", required_argument, NULL, 'd'},
{"input", required_argument, NULL, 'i'},
@@ -61,6 +61,8 @@ static const struct option _long_opts[] = {
{"host", required_argument, NULL, 's'},
{"port", required_argument, NULL, 'p'},
{"unix", required_argument, NULL, 'u'},
{"unix-rm", no_argument, NULL, 'e'},
{"drop-same-frames", required_argument, NULL, 'r'},
{"fake-width", required_argument, NULL, 2001},
{"fake-height", required_argument, NULL, 2002},
@@ -122,6 +124,8 @@ static void _help(struct device_t *dev, struct encoder_t *encoder, struct http_s
printf("--------------------\n");
printf(" --host <address> -- Listen on Hostname or IP. Default: %s\n\n", server->host);
printf(" --port <N> -- Bind to this TCP port. Default: %d\n\n", server->port);
printf(" --unix <path> -- Bind to UNIX domain socket. Default: disabled\n\n");
printf(" --unix-rm -- Try to remove old UNIX socket file before binding. Default: disabled\n\n");
printf(" --drop-same-frames <N> -- Don't send same frames to clients, but no more than specified number.\n");
printf(" It can significantly reduce the outgoing traffic, but will increase\n");
printf(" the CPU loading. Don't use this option with analog signal sources\n");
@@ -184,6 +188,8 @@ static int _parse_options(int argc, char *argv[], struct device_t *dev, struct e
case 's': OPT_SET(server->host, optarg);
case 'p': OPT_UNSIGNED(server->port, "--port", 1, 65535);
case 'u': OPT_SET(server->unix_path, optarg);
case 'e': OPT_SET(server->unix_rm, true);
case 'r': OPT_UNSIGNED(server->drop_same_frames, "--drop-same-frames", 0, 30);
case 2001: OPT_UNSIGNED(server->fake_width, "--fake-width", 0, 1920);
case 2002: OPT_UNSIGNED(server->fake_height, "--fake-height", 0, 1200);