diff --git a/src/rawsink/rawsink.c b/src/rawsink/rawsink.c index d54c3e0..340ab1d 100644 --- a/src/rawsink/rawsink.c +++ b/src/rawsink/rawsink.c @@ -129,7 +129,7 @@ void rawsink_destroy(rawsink_s *rawsink) { free(rawsink); } -void rawsink_server_put( +int rawsink_server_put( rawsink_s *rawsink, const uint8_t *data, size_t size, unsigned format, unsigned width, unsigned height, @@ -139,13 +139,9 @@ void rawsink_server_put( assert(rawsink->server); - if (rawsink->server_failed) { - return; - } - if (size > RAWSINK_MAX_DATA) { LOG_ERROR("RAWSINK: Can't put RAW frame: is too big (%zu > %zu)", size, RAWSINK_MAX_DATA); - return; + return 0; // -2 } if (_flock_timedwait_monotonic(rawsink->fd, 1) == 0) { @@ -153,7 +149,7 @@ void rawsink_server_put( if (sem_trywait(rawsink->sig_sem) < 0 && errno != EAGAIN) { LOG_PERROR("RAWSINK: Can't wait signal semaphore"); - goto error; + return -1; } # define COPY(_field) rawsink->mem->_field = _field @@ -167,11 +163,11 @@ void rawsink_server_put( if (sem_post(rawsink->sig_sem) < 0) { LOG_PERROR("RAWSINK: Can't post signal semaphore"); - goto error; + return -1; } if (flock(rawsink->fd, LOCK_UN) < 0) { LOG_PERROR("RAWSINK: Can't unlock memory"); - goto error; + return -1; } LOG_VERBOSE("RAWSINK: Exposed new frame; full exposition time = %Lf", get_now_monotonic() - now); @@ -180,14 +176,9 @@ void rawsink_server_put( } else { LOG_PERROR("RAWSINK: Can't lock memory"); - goto error; + return -1; } - - return; - - error: - LOG_ERROR("RAW sink completely disabled due error"); - rawsink->server_failed = true; + return 0; } int rawsink_client_get( diff --git a/src/rawsink/rawsink.h b/src/rawsink/rawsink.h index 8b7e4b7..cfcdd36 100644 --- a/src/rawsink/rawsink.h +++ b/src/rawsink/rawsink.h @@ -65,15 +65,13 @@ typedef struct { int fd; rawsink_shared_s *mem; sem_t *sig_sem; - - bool server_failed; } rawsink_s; rawsink_s *rawsink_init(const char *name, bool server, mode_t mode, bool rm, unsigned timeout); void rawsink_destroy(rawsink_s *rawsink); -void rawsink_server_put( +int rawsink_server_put( rawsink_s *rawsink, const uint8_t *data, size_t size, unsigned format, unsigned witdh, unsigned height, diff --git a/src/ustreamer/options.c b/src/ustreamer/options.c index 53443dd..50e9dc9 100644 --- a/src/ustreamer/options.c +++ b/src/ustreamer/options.c @@ -230,6 +230,11 @@ options_s *options_init(int argc, char *argv[]) { } void options_destroy(options_s *options) { +# ifdef WITH_RAWSINK + if (options->rawsink) { + rawsink_destroy(options->rawsink); + } +# endif if (options->blank) { frame_destroy(options->blank); } @@ -312,7 +317,16 @@ int options_parse(options_s *options, device_s *dev, encoder_s *encoder, stream_ int short_index; int opt_index; char short_opts[1024] = {0}; + char *blank_path = NULL; + +# ifdef WITH_RAWSINK + char *rawsink_name = NULL; + mode_t rawsink_mode = 0660; + bool rawsink_rm = false; + unsigned rawsink_timeout = 1; +# endif + # ifdef WITH_SETPROCTITLE char *process_name_prefix = NULL; # endif @@ -402,10 +416,10 @@ int options_parse(options_s *options, device_s *dev, encoder_s *encoder, stream_ case _O_SERVER_TIMEOUT: OPT_NUMBER("--server-timeout", server->timeout, 1, 60, 0); # ifdef WITH_RAWSINK - case _O_RAWSINK: OPT_SET(stream->rawsink_name, optarg); - case _O_RAWSINK_MODE: OPT_NUMBER("--raw-sink-mode", stream->rawsink_mode, INT_MIN, INT_MAX, 8); - case _O_RAWSINK_RM: OPT_SET(stream->rawsink_rm, true); - case _O_RAWSINK_TIMEOUT: OPT_NUMBER("--raw-sink-timeout", server->timeout, 1, 60, 0); + case _O_RAWSINK: OPT_SET(rawsink_name, optarg); + case _O_RAWSINK_MODE: OPT_NUMBER("--raw-sink-mode", rawsink_mode, INT_MIN, INT_MAX, 8); + case _O_RAWSINK_RM: OPT_SET(rawsink_rm, true); + case _O_RAWSINK_TIMEOUT: OPT_NUMBER("--raw-sink-timeout", rawsink_timeout, 1, 60, 0); # endif # ifdef WITH_GPIO @@ -447,6 +461,19 @@ int options_parse(options_s *options, device_s *dev, encoder_s *encoder, stream_ options->blank = blank_frame_init(blank_path); stream->blank = options->blank; +# ifdef WITH_RAWSINK + if (rawsink_name && rawsink_name[0] != '\0') { + options->rawsink = rawsink_init( + rawsink_name, + true, + rawsink_mode, + rawsink_rm, + rawsink_timeout + ); + } + stream->rawsink = options->rawsink; +# endif + # ifdef WITH_SETPROCTITLE if (process_name_prefix != NULL) { process_set_name_prefix(options->argc, options->argv, process_name_prefix); @@ -671,9 +698,9 @@ static void _help(device_s *dev, encoder_s *encoder, stream_s *stream, server_s printf("═════════════════\n"); printf(" --raw-sink ──────── Use the shared memory to sink RAW frames before encoding.\n"); printf(" Most likely you will never need it. Default: disabled.\n\n"); - printf(" --raw-sink-mode ─── Set RAW sink permissions (like 777). Default: %o.\n\n", stream->rawsink_mode); + printf(" --raw-sink-mode ─── Set RAW sink permissions (like 777). Default: 660.\n\n"); printf(" --raw-sink-rm ──────────── Remove shared memory on stop. Default: disabled.\n\n"); - printf(" --raw-sink-timeout ─ Timeout for lock. Default: %u.\n\n", stream->rawsink_timeout); + printf(" --raw-sink-timeout ─ Timeout for lock. Default: 1.\n\n"); #endif #ifdef WITH_GPIO printf("GPIO options:\n"); diff --git a/src/ustreamer/options.h b/src/ustreamer/options.h index c51bb67..f0b4e78 100644 --- a/src/ustreamer/options.h +++ b/src/ustreamer/options.h @@ -36,6 +36,9 @@ #include "../common/config.h" #include "../common/logging.h" #include "../common/process.h" +#ifdef WITH_RAWSINK +# include "../rawsink/rawsink.h" +#endif #include "device.h" #include "frame.h" @@ -49,10 +52,13 @@ typedef struct { - int argc; - char **argv; - char **argv_copy; - frame_s *blank; + int argc; + char **argv; + char **argv_copy; + frame_s *blank; +# ifdef WITH_RAWSINK + rawsink_s *rawsink; +# endif } options_s; diff --git a/src/ustreamer/stream.c b/src/ustreamer/stream.c index 681aa19..3fd9a2e 100644 --- a/src/ustreamer/stream.c +++ b/src/ustreamer/stream.c @@ -100,11 +100,6 @@ stream_s *stream_init(device_s *dev, encoder_s *encoder) { A_CALLOC(stream, 1); stream->last_as_blank = -1; stream->error_delay = 1; -# ifdef WITH_RAWSINK - stream->rawsink_name = ""; - stream->rawsink_mode = 0660; - stream->rawsink_timeout = 1; -# endif stream->proc = proc; stream->video = video; stream->dev = dev; @@ -127,19 +122,6 @@ void stream_loop(stream_s *stream) { LOG_INFO("Using V4L2 device: %s", DEV(path)); LOG_INFO("Using desired FPS: %u", DEV(desired_fps)); -# ifdef WITH_RAWSINK - rawsink_s *rawsink = NULL; - if (stream->rawsink_name[0] != '\0') { - rawsink = rawsink_init( - stream->rawsink_name, - true, - stream->rawsink_mode, - stream->rawsink_rm, - stream->rawsink_timeout - ); - } -# endif - while ((pool = _stream_init_loop(stream)) != NULL) { long double grab_after = 0; unsigned fluency_passed = 0; @@ -228,8 +210,12 @@ void stream_loop(stream_s *stream) { # ifdef WITH_RAWSINK # define HW(_next) DEV(run->hw_buffers[buf_index]._next) - if (rawsink) { - rawsink_server_put(rawsink, HW(data), HW(used), HW(format), HW(width), HW(height), HW(grab_ts)); + if (stream->rawsink && rawsink_server_put( + stream->rawsink, HW(data), HW(used), HW(format), + HW(width), HW(height), HW(grab_ts) + ) < 0) { + stream->rawsink = NULL; + LOG_ERROR("RAW sink completely disabled due error"); } # undef HW # endif @@ -264,12 +250,6 @@ void stream_loop(stream_s *stream) { # endif } -# ifdef WITH_RAWSINK - if (rawsink) { - rawsink_destroy(rawsink); - } -# endif - # undef DEV } diff --git a/src/ustreamer/stream.h b/src/ustreamer/stream.h index c642387..bb285b4 100644 --- a/src/ustreamer/stream.h +++ b/src/ustreamer/stream.h @@ -65,16 +65,13 @@ typedef struct { typedef struct { int last_as_blank; unsigned error_delay; -# ifdef WITH_RAWSINK - char *rawsink_name; - mode_t rawsink_mode; - bool rawsink_rm; - unsigned rawsink_timeout; -# endif device_s *dev; encoder_s *encoder; frame_s *blank; +# ifdef WITH_RAWSINK + rawsink_s *rawsink; +# endif process_s *proc; video_s *video;