mirror of
https://github.com/pikvm/ustreamer.git
synced 2026-03-10 09:33:43 +00:00
jpeg sink
This commit is contained in:
13
Makefile
13
Makefile
@@ -21,11 +21,12 @@ LINTERS_IMAGE ?= $(USTR)-linters
|
|||||||
# =====
|
# =====
|
||||||
override CFLAGS += -c -std=c11 -Wall -Wextra -D_GNU_SOURCE
|
override CFLAGS += -c -std=c11 -Wall -Wextra -D_GNU_SOURCE
|
||||||
|
|
||||||
_COMMON_LIBS = -lm -ljpeg -pthread
|
_COMMON_LIBS = -lm -ljpeg -pthread -lrt
|
||||||
|
|
||||||
_USTR_LIBS = $(_COMMON_LIBS) -levent -levent_pthreads -luuid
|
_USTR_LIBS = $(_COMMON_LIBS) -levent -levent_pthreads -luuid
|
||||||
_USTR_SRCS = $(shell ls \
|
_USTR_SRCS = $(shell ls \
|
||||||
src/libs/common/*.c \
|
src/libs/common/*.c \
|
||||||
|
src/libs/memsink/*.c \
|
||||||
src/ustreamer/*.c \
|
src/ustreamer/*.c \
|
||||||
src/ustreamer/http/*.c \
|
src/ustreamer/http/*.c \
|
||||||
src/ustreamer/data/*.c \
|
src/ustreamer/data/*.c \
|
||||||
@@ -33,7 +34,7 @@ _USTR_SRCS = $(shell ls \
|
|||||||
src/ustreamer/encoders/hw/*.c \
|
src/ustreamer/encoders/hw/*.c \
|
||||||
)
|
)
|
||||||
|
|
||||||
_REC_LIBS = $(_COMMON_LIBS) -lrt
|
_REC_LIBS = $(_COMMON_LIBS)
|
||||||
_REC_SRCS = $(shell ls \
|
_REC_SRCS = $(shell ls \
|
||||||
src/libs/common/*.c \
|
src/libs/common/*.c \
|
||||||
src/libs/memsink/*.c \
|
src/libs/memsink/*.c \
|
||||||
@@ -47,10 +48,9 @@ endef
|
|||||||
|
|
||||||
|
|
||||||
ifneq ($(call optbool,$(WITH_OMX)),)
|
ifneq ($(call optbool,$(WITH_OMX)),)
|
||||||
_USTR_LIBS += -lrt -lbcm_host -lvcos -lopenmaxil -lmmal -lmmal_core -lmmal_util -lmmal_vc_client -lmmal_components -L$(RPI_VC_LIBS)
|
_USTR_LIBS += -lbcm_host -lvcos -lopenmaxil -lmmal -lmmal_core -lmmal_util -lmmal_vc_client -lmmal_components -L$(RPI_VC_LIBS)
|
||||||
override CFLAGS += -DWITH_OMX -DOMX_SKIP64BIT -I$(RPI_VC_HEADERS)
|
override CFLAGS += -DWITH_OMX -DOMX_SKIP64BIT -I$(RPI_VC_HEADERS)
|
||||||
_USTR_SRCS += $(shell ls \
|
_USTR_SRCS += $(shell ls \
|
||||||
src/libs/memsink/*.c \
|
|
||||||
src/ustreamer/encoders/omx/*.c \
|
src/ustreamer/encoders/omx/*.c \
|
||||||
src/ustreamer/h264/*.c \
|
src/ustreamer/h264/*.c \
|
||||||
)
|
)
|
||||||
@@ -122,7 +122,6 @@ $(USTR): $(_USTR_SRCS:%.c=$(BUILD)/%.o)
|
|||||||
$(info :: LDFLAGS = $(LDFLAGS))
|
$(info :: LDFLAGS = $(LDFLAGS))
|
||||||
|
|
||||||
|
|
||||||
ifneq ($(call optbool,$(WITH_OMX)),)
|
|
||||||
$(REC): $(_REC_SRCS:%.c=$(BUILD)/%.o)
|
$(REC): $(_REC_SRCS:%.c=$(BUILD)/%.o)
|
||||||
$(info ========================================)
|
$(info ========================================)
|
||||||
$(info == LD $@)
|
$(info == LD $@)
|
||||||
@@ -131,10 +130,6 @@ $(REC): $(_REC_SRCS:%.c=$(BUILD)/%.o)
|
|||||||
$(info :: LIBS = $(_REC_LIBS))
|
$(info :: LIBS = $(_REC_LIBS))
|
||||||
$(info :: CFLAGS = $(CFLAGS))
|
$(info :: CFLAGS = $(CFLAGS))
|
||||||
$(info :: LDFLAGS = $(LDFLAGS))
|
$(info :: LDFLAGS = $(LDFLAGS))
|
||||||
else
|
|
||||||
$(REC):
|
|
||||||
@ true
|
|
||||||
endif
|
|
||||||
|
|
||||||
|
|
||||||
$(BUILD)/%.o: %.c
|
$(BUILD)/%.o: %.c
|
||||||
|
|||||||
@@ -82,12 +82,16 @@ enum _OPT_VALUES {
|
|||||||
_O_TCP_NODELAY,
|
_O_TCP_NODELAY,
|
||||||
_O_SERVER_TIMEOUT,
|
_O_SERVER_TIMEOUT,
|
||||||
|
|
||||||
#ifdef WITH_OMX
|
# define ADD_SINK(_upper) \
|
||||||
_O_H264_SINK,
|
_O_##_upper##_SINK, \
|
||||||
_O_H264_SINK_MODE,
|
_O_##_upper##_SINK_MODE, \
|
||||||
_O_H264_SINK_RM,
|
_O_##_upper##_SINK_RM, \
|
||||||
_O_H264_SINK_TIMEOUT,
|
_O_##_upper##_SINK_TIMEOUT,
|
||||||
#endif
|
ADD_SINK(JPEG)
|
||||||
|
# ifdef WITH_OMX
|
||||||
|
ADD_SINK(H264)
|
||||||
|
# endif
|
||||||
|
# undef ADD_SINK
|
||||||
|
|
||||||
#ifdef WITH_GPIO
|
#ifdef WITH_GPIO
|
||||||
_O_GPIO_DEVICE,
|
_O_GPIO_DEVICE,
|
||||||
@@ -167,12 +171,16 @@ static const struct option _LONG_OPTS[] = {
|
|||||||
{"tcp-nodelay", no_argument, NULL, _O_TCP_NODELAY},
|
{"tcp-nodelay", no_argument, NULL, _O_TCP_NODELAY},
|
||||||
{"server-timeout", required_argument, NULL, _O_SERVER_TIMEOUT},
|
{"server-timeout", required_argument, NULL, _O_SERVER_TIMEOUT},
|
||||||
|
|
||||||
#ifdef WITH_OMX
|
# define ADD_SINK(_lower, _upper) \
|
||||||
{"h264-sink", required_argument, NULL, _O_H264_SINK},
|
{#_lower "-sink", required_argument, NULL, _O_##_upper##_SINK}, \
|
||||||
{"h264-sink-mode", required_argument, NULL, _O_H264_SINK_MODE},
|
{#_lower "-sink-mode", required_argument, NULL, _O_##_upper##_SINK_MODE}, \
|
||||||
{"h264-sink-rm", no_argument, NULL, _O_H264_SINK_RM},
|
{#_lower "-sink-rm", no_argument, NULL, _O_##_upper##_SINK_RM}, \
|
||||||
{"h264-sink-timeout", required_argument, NULL, _O_H264_SINK_TIMEOUT},
|
{#_lower "-sink-timeout", required_argument, NULL, _O_##_upper##_SINK_TIMEOUT},
|
||||||
#endif
|
ADD_SINK(jpeg, JPEG)
|
||||||
|
# ifdef WITH_OMX
|
||||||
|
ADD_SINK(h264, H264)
|
||||||
|
# endif
|
||||||
|
# undef ADD_SINK
|
||||||
|
|
||||||
#ifdef WITH_GPIO
|
#ifdef WITH_GPIO
|
||||||
{"gpio-device", required_argument, NULL, _O_GPIO_DEVICE},
|
{"gpio-device", required_argument, NULL, _O_GPIO_DEVICE},
|
||||||
@@ -225,18 +233,26 @@ options_s *options_init(unsigned argc, char *argv[]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void options_destroy(options_s *options) {
|
void options_destroy(options_s *options) {
|
||||||
|
# define ADD_SINK(_lower) { \
|
||||||
|
if (options->_lower##_sink) { \
|
||||||
|
memsink_destroy(options->_lower##_sink); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
ADD_SINK(jpeg);
|
||||||
# ifdef WITH_OMX
|
# ifdef WITH_OMX
|
||||||
if (options->h264_sink) {
|
ADD_SINK(h264);
|
||||||
memsink_destroy(options->h264_sink);
|
|
||||||
}
|
|
||||||
# endif
|
# endif
|
||||||
|
# undef ADD_SINK
|
||||||
|
|
||||||
if (options->blank) {
|
if (options->blank) {
|
||||||
frame_destroy(options->blank);
|
frame_destroy(options->blank);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned index = 0; index < options->argc; ++index) {
|
for (unsigned index = 0; index < options->argc; ++index) {
|
||||||
free(options->argv_copy[index]);
|
free(options->argv_copy[index]);
|
||||||
}
|
}
|
||||||
free(options->argv_copy);
|
free(options->argv_copy);
|
||||||
|
|
||||||
free(options);
|
free(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -310,12 +326,16 @@ int options_parse(options_s *options, device_s *dev, encoder_s *enc, stream_s *s
|
|||||||
|
|
||||||
char *blank_path = NULL;
|
char *blank_path = NULL;
|
||||||
|
|
||||||
|
# define ADD_SINK(_lower) \
|
||||||
|
char *_lower##_sink_name = NULL; \
|
||||||
|
mode_t _lower##_sink_mode = 0660; \
|
||||||
|
bool _lower##_sink_rm = false; \
|
||||||
|
unsigned _lower##_sink_timeout = 1;
|
||||||
|
ADD_SINK(jpeg);
|
||||||
# ifdef WITH_OMX
|
# ifdef WITH_OMX
|
||||||
char *h264_sink_name = NULL;
|
ADD_SINK(h264);
|
||||||
mode_t h264_sink_mode = 0660;
|
|
||||||
bool h264_sink_rm = false;
|
|
||||||
unsigned h264_sink_timeout = 1;
|
|
||||||
# endif
|
# endif
|
||||||
|
# undef ADD_SINK
|
||||||
|
|
||||||
# ifdef WITH_SETPROCTITLE
|
# ifdef WITH_SETPROCTITLE
|
||||||
char *process_name_prefix = NULL;
|
char *process_name_prefix = NULL;
|
||||||
@@ -403,12 +423,16 @@ int options_parse(options_s *options, device_s *dev, encoder_s *enc, stream_s *s
|
|||||||
case _O_TCP_NODELAY: OPT_SET(server->tcp_nodelay, true);
|
case _O_TCP_NODELAY: OPT_SET(server->tcp_nodelay, true);
|
||||||
case _O_SERVER_TIMEOUT: OPT_NUMBER("--server-timeout", server->timeout, 1, 60, 0);
|
case _O_SERVER_TIMEOUT: OPT_NUMBER("--server-timeout", server->timeout, 1, 60, 0);
|
||||||
|
|
||||||
|
# define ADD_SINK(_lower, _upper) \
|
||||||
|
case _O_##_upper##_SINK: OPT_SET(_lower##_sink_name, optarg); \
|
||||||
|
case _O_##_upper##_SINK_MODE: OPT_NUMBER("--" #_lower "-sink-mode", _lower##_sink_mode, INT_MIN, INT_MAX, 8); \
|
||||||
|
case _O_##_upper##_SINK_RM: OPT_SET(_lower##_sink_rm, true); \
|
||||||
|
case _O_##_upper##_SINK_TIMEOUT: OPT_NUMBER("--" #_lower "-sink-timeout", _lower##_sink_timeout, 1, 60, 0);
|
||||||
|
ADD_SINK(jpeg, JPEG)
|
||||||
# ifdef WITH_OMX
|
# ifdef WITH_OMX
|
||||||
case _O_H264_SINK: OPT_SET(h264_sink_name, optarg);
|
ADD_SINK(h264, H264)
|
||||||
case _O_H264_SINK_MODE: OPT_NUMBER("--h264-sink-mode", h264_sink_mode, INT_MIN, INT_MAX, 8);
|
|
||||||
case _O_H264_SINK_RM: OPT_SET(h264_sink_rm, true);
|
|
||||||
case _O_H264_SINK_TIMEOUT: OPT_NUMBER("--h264-sink-timeout", h264_sink_timeout, 1, 60, 0);
|
|
||||||
# endif
|
# endif
|
||||||
|
# undef ADD_SINK
|
||||||
|
|
||||||
# ifdef WITH_GPIO
|
# ifdef WITH_GPIO
|
||||||
case _O_GPIO_DEVICE: OPT_SET(gpio.path, optarg);
|
case _O_GPIO_DEVICE: OPT_SET(gpio.path, optarg);
|
||||||
@@ -449,19 +473,24 @@ int options_parse(options_s *options, device_s *dev, encoder_s *enc, stream_s *s
|
|||||||
options->blank = blank_frame_init(blank_path);
|
options->blank = blank_frame_init(blank_path);
|
||||||
stream->blank = options->blank;
|
stream->blank = options->blank;
|
||||||
|
|
||||||
|
# define ADD_SINK(_lower, _upper) { \
|
||||||
|
if (_lower##_sink_name && _lower##_sink_name[0] != '\0') { \
|
||||||
|
options->_lower##_sink = memsink_init( \
|
||||||
|
#_lower, \
|
||||||
|
_lower##_sink_name, \
|
||||||
|
true, \
|
||||||
|
_lower##_sink_mode, \
|
||||||
|
_lower##_sink_rm, \
|
||||||
|
_lower##_sink_timeout \
|
||||||
|
); \
|
||||||
|
} \
|
||||||
|
stream->_lower##_sink = options->_lower##_sink; \
|
||||||
|
}
|
||||||
|
ADD_SINK(jpeg, JPEG);
|
||||||
# ifdef WITH_OMX
|
# ifdef WITH_OMX
|
||||||
if (h264_sink_name && h264_sink_name[0] != '\0') {
|
ADD_SINK(h264, H264);
|
||||||
options->h264_sink = memsink_init(
|
|
||||||
"h264",
|
|
||||||
h264_sink_name,
|
|
||||||
true,
|
|
||||||
h264_sink_mode,
|
|
||||||
h264_sink_rm,
|
|
||||||
h264_sink_timeout
|
|
||||||
);
|
|
||||||
}
|
|
||||||
stream->h264_sink = options->h264_sink;
|
|
||||||
# endif
|
# endif
|
||||||
|
# undef ADD_SINK
|
||||||
|
|
||||||
# ifdef WITH_SETPROCTITLE
|
# ifdef WITH_SETPROCTITLE
|
||||||
if (process_name_prefix != NULL) {
|
if (process_name_prefix != NULL) {
|
||||||
@@ -623,15 +652,18 @@ static void _help(FILE *fp, device_s *dev, encoder_s *enc, stream_s *stream, ser
|
|||||||
SAY(" Default: disabled.\n");
|
SAY(" Default: disabled.\n");
|
||||||
SAY(" --allow-origin <str> ─────── Set Access-Control-Allow-Origin header. Default: disabled.\n");
|
SAY(" --allow-origin <str> ─────── Set Access-Control-Allow-Origin header. Default: disabled.\n");
|
||||||
SAY(" --server-timeout <sec> ───── Timeout for client connections. Default: %u.\n", server->timeout);
|
SAY(" --server-timeout <sec> ───── Timeout for client connections. Default: %u.\n", server->timeout);
|
||||||
|
# define ADD_SINK(_lower, _upper) \
|
||||||
|
SAY(#_upper " sink options:"); \
|
||||||
|
SAY("══════════════════"); \
|
||||||
|
SAY(" --" #_lower "-sink <name> ──────── Use the shared memory to sink " #_upper " frames. Default: disabled."); \
|
||||||
|
SAY(" --" #_lower "-sink-mode <mode> ─── Set " #_upper " sink permissions (like 777). Default: 660.\n"); \
|
||||||
|
SAY(" --" #_lower "-sink-rm ──────────── Remove shared memory on stop. Default: disabled.\n"); \
|
||||||
|
SAY(" --" #_lower "-sink-timeout <sec> ─ Timeout for lock. Default: 1.\n");
|
||||||
|
ADD_SINK(jpeg, JPEG)
|
||||||
# ifdef WITH_OMX
|
# ifdef WITH_OMX
|
||||||
SAY("H264 sink options:");
|
ADD_SINK(h264, H264)
|
||||||
SAY("═════════════════");
|
|
||||||
SAY(" --h264-sink <name> ──────── Use the shared memory to sink H264 frames encoded by MMAL.");
|
|
||||||
SAY(" Most likely you will never need it. Default: disabled.\n");
|
|
||||||
SAY(" --h264-sink-mode <mode> ─── Set H264 sink permissions (like 777). Default: 660.\n");
|
|
||||||
SAY(" --h264-sink-rm ──────────── Remove shared memory on stop. Default: disabled.\n");
|
|
||||||
SAY(" --h264-sink-timeout <sec> ─ Timeout for lock. Default: 1.\n");
|
|
||||||
# endif
|
# endif
|
||||||
|
# undef ADD_SINK
|
||||||
# ifdef WITH_GPIO
|
# ifdef WITH_GPIO
|
||||||
SAY("GPIO options:");
|
SAY("GPIO options:");
|
||||||
SAY("═════════════");
|
SAY("═════════════");
|
||||||
|
|||||||
@@ -37,9 +37,7 @@
|
|||||||
#include "../libs/common/logging.h"
|
#include "../libs/common/logging.h"
|
||||||
#include "../libs/common/process.h"
|
#include "../libs/common/process.h"
|
||||||
#include "../libs/common/frame.h"
|
#include "../libs/common/frame.h"
|
||||||
#ifdef WITH_OMX
|
#include "../libs/memsink/memsink.h"
|
||||||
# include "../libs/memsink/memsink.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "device.h"
|
#include "device.h"
|
||||||
#include "encoder.h"
|
#include "encoder.h"
|
||||||
@@ -56,6 +54,7 @@ typedef struct {
|
|||||||
char **argv;
|
char **argv;
|
||||||
char **argv_copy;
|
char **argv_copy;
|
||||||
frame_s *blank;
|
frame_s *blank;
|
||||||
|
memsink_s *jpeg_sink;
|
||||||
# ifdef WITH_OMX
|
# ifdef WITH_OMX
|
||||||
memsink_s *h264_sink;
|
memsink_s *h264_sink;
|
||||||
# endif
|
# endif
|
||||||
|
|||||||
@@ -112,6 +112,9 @@ void stream_loop(stream_s *stream) {
|
|||||||
if (!ready_wr->job_failed) {
|
if (!ready_wr->job_failed) {
|
||||||
if (ready_wr->job_timely) {
|
if (ready_wr->job_timely) {
|
||||||
_stream_expose_frame(stream, ready_job->dest, captured_fps);
|
_stream_expose_frame(stream, ready_job->dest, captured_fps);
|
||||||
|
if (stream->jpeg_sink) {
|
||||||
|
memsink_server_put(stream->jpeg_sink, ready_job->dest);
|
||||||
|
}
|
||||||
LOG_PERF("##### Encoded frame exposed; worker=%s", ready_wr->name);
|
LOG_PERF("##### Encoded frame exposed; worker=%s", ready_wr->name);
|
||||||
} else {
|
} else {
|
||||||
LOG_PERF("----- Encoded frame dropped; worker=%s", ready_wr->name);
|
LOG_PERF("----- Encoded frame dropped; worker=%s", ready_wr->name);
|
||||||
@@ -242,6 +245,9 @@ static workers_pool_s *_stream_init_loop(stream_s *stream) {
|
|||||||
|
|
||||||
while (!atomic_load(&stream->proc->stop)) {
|
while (!atomic_load(&stream->proc->stop)) {
|
||||||
if (_stream_expose_frame(stream, NULL, 0)) {
|
if (_stream_expose_frame(stream, NULL, 0)) {
|
||||||
|
if (stream->jpeg_sink) {
|
||||||
|
memsink_server_put(stream->jpeg_sink, stream->blank);
|
||||||
|
}
|
||||||
# ifdef WITH_OMX
|
# ifdef WITH_OMX
|
||||||
if (stream->h264) {
|
if (stream->h264) {
|
||||||
_h264_stream_process(stream->h264, stream->blank);
|
_h264_stream_process(stream->h264, stream->blank);
|
||||||
|
|||||||
@@ -36,6 +36,7 @@
|
|||||||
#include "../libs/common/threading.h"
|
#include "../libs/common/threading.h"
|
||||||
#include "../libs/common/logging.h"
|
#include "../libs/common/logging.h"
|
||||||
#include "../libs/common/frame.h"
|
#include "../libs/common/frame.h"
|
||||||
|
#include "../libs/memsink/memsink.h"
|
||||||
|
|
||||||
#include "blank.h"
|
#include "blank.h"
|
||||||
#include "device.h"
|
#include "device.h"
|
||||||
@@ -43,7 +44,6 @@
|
|||||||
#include "workers.h"
|
#include "workers.h"
|
||||||
#ifdef WITH_OMX
|
#ifdef WITH_OMX
|
||||||
# include "h264/encoder.h"
|
# include "h264/encoder.h"
|
||||||
# include "../libs/memsink/memsink.h"
|
|
||||||
#endif
|
#endif
|
||||||
#ifdef WITH_GPIO
|
#ifdef WITH_GPIO
|
||||||
# include "gpio/gpio.h"
|
# include "gpio/gpio.h"
|
||||||
@@ -78,6 +78,7 @@ typedef struct {
|
|||||||
device_s *dev;
|
device_s *dev;
|
||||||
encoder_s *enc;
|
encoder_s *enc;
|
||||||
frame_s *blank;
|
frame_s *blank;
|
||||||
|
memsink_s *jpeg_sink;
|
||||||
# ifdef WITH_OMX
|
# ifdef WITH_OMX
|
||||||
memsink_s *h264_sink;
|
memsink_s *h264_sink;
|
||||||
# endif
|
# endif
|
||||||
|
|||||||
Reference in New Issue
Block a user